Freeciv21
Develop your civilization from humble roots to a global empire
options.cpp
Go to the documentation of this file.
1 /*__ ___ ***************************************
2 / \ / \ Copyright (c) 1996-2023 Freeciv21 and Freeciv
3 \_ \ / __/ contributors. This file is part of Freeciv21.
4  _\ \ / /__ Freeciv21 is free software: you can redistribute it
5  \___ \____/ __/ and/or modify it under the terms of the GNU General
6  \_ _/ Public License as published by the Free Software
7  | @ @ \_ Foundation, either version 3 of the License,
8  | or (at your option) any later version.
9  _/ /\ You should have received a copy of the GNU
10  /o) (o/\ \_ General Public License along with Freeciv21.
11  \_____/ / If not, see https://www.gnu.org/licenses/.
12  \____/ ********************************************************/
13 
14 #include <fc_config.h>
15 
16 #include <cstring>
17 #include <qglobal.h>
18 #include <sys/stat.h>
19 
20 // Qt
21 #include <QDir>
22 #include <QHash>
23 #include <QUrl>
24 
25 // utility
26 #include "deprecations.h"
27 #include "fcintl.h"
28 #include "log.h"
29 #include "registry.h"
30 #include "registry_ini.h"
31 #include "shared.h"
32 #include "support.h"
33 
34 // generated
35 #include "fc_version.h"
36 
37 // common
38 #include "events.h"
39 #include "version.h"
40 
41 /* client/include */
42 #include "gui_main_g.h"
43 #include "menu_g.h"
44 #include "optiondlg_g.h"
45 #include "repodlgs_g.h"
46 #include "voteinfo_bar_g.h"
47 
48 // client
49 #include "audio/audio.h"
50 #include "chatline_common.h"
51 #include "citybar.h"
52 #include "client_main.h"
53 #include "climisc.h"
54 #include "connectdlg_common.h"
55 #include "global_worklist.h"
56 #include "governor.h"
57 #include "mapctrl_common.h"
58 #include "music.h"
59 #include "options.h"
60 #include "overview_common.h"
61 #include "packhand_gen.h"
62 #include "qtg_cxxside.h"
63 #include "themes_common.h"
64 #include "tileset/tilespec.h"
65 #include "views/view_cities_data.h"
66 #include "views/view_map_common.h"
68 
69 const char *const TILESET_OPTIONS_PREFIX = "tileset_";
70 
71 typedef QHash<QString, QString> optionsHash;
72 typedef QHash<QString, intptr_t> dialOptionsHash;
73 
75 
76 /* Set to TRUE after the first call to options_init(), to avoid the usage
77  * of non-initialized datas when calling the changed callback. */
78 static bool options_fully_initialized = false;
79 
80 /* See #2237
81 static const QVector<QString> *
82 get_mapimg_format_list(const struct option *poption);
83 */
84 
88 struct option_set {
89  struct option *(*option_by_number)(int);
90  struct option *(*option_first)();
91 
92  int (*category_number)();
93  const char *(*category_name)(int);
94 };
95 
100  int id)
101 {
102  fc_assert_ret_val(nullptr != poptset, nullptr);
103 
104  return poptset->option_by_number(id);
105 }
106 
111  const char *name)
112 {
113  fc_assert_ret_val(nullptr != poptset, nullptr);
114 
115  options_iterate(poptset, poption)
116  {
117  if (0 == strcmp(option_name(poption), name)) {
118  return poption;
119  }
120  }
122  return nullptr;
123 }
124 
129 {
130  fc_assert_ret_val(nullptr != poptset, nullptr);
131 
132  return poptset->option_first();
133 }
134 
138 const char *optset_category_name(const struct option_set *poptset,
139  int category)
140 {
141  fc_assert_ret_val(nullptr != poptset, nullptr);
142 
143  return poptset->category_name(category);
144 }
145 
147  int (*number)(const struct option *);
148  const char *(*name)(const struct option *);
149  const char *(*description)(const struct option *);
150  const char *(*help_text)(const struct option *);
151  int (*category)(const struct option *);
152  bool (*is_changeable)(const struct option *);
153  struct option *(*next)(const struct option *);
154 };
155 
157  bool (*get)(const struct option *);
158  bool (*def)(const struct option *);
159  bool (*set)(struct option *, bool);
160 };
161 
163  int (*get)(const struct option *);
164  int (*def)(const struct option *);
165  int (*minimum)(const struct option *);
166  int (*maximum)(const struct option *);
167  bool (*set)(struct option *, int);
168 };
169 // Specific string accessors (OT_STRING == type).
171  const char *(*get)(const struct option *);
172  const char *(*def)(const struct option *);
173  const QVector<QString> *(*values)(const struct option *);
174  bool (*set)(struct option *, const char *);
175 };
176 // Specific enum accessors (OT_ENUM == type).
178  int (*get)(const struct option *);
179  int (*def)(const struct option *);
180  const QVector<QString> *(*values)(const struct option *);
181  bool (*set)(struct option *, int);
182  int (*cmp)(const char *, const char *);
183 };
184 // Specific bitwise accessors (OT_BITWISE == type).
186  unsigned (*get)(const struct option *);
187  unsigned (*def)(const struct option *);
188  const QVector<QString> *(*values)(const struct option *);
189  bool (*set)(struct option *, unsigned);
190 };
191 // Specific font accessors (OT_FONT == type).
193  QFont (*get)(const struct option *);
194  QFont (*def)(const struct option *);
195  void (*set_def)(const struct option *, const QFont &font);
196  QString (*target)(const struct option *);
197  bool (*set)(struct option *, const QFont &);
198 };
199 // Specific color accessors (OT_COLOR == type).
201  struct ft_color (*get)(const struct option *);
202  struct ft_color (*def)(const struct option *);
203  bool (*set)(struct option *, struct ft_color);
204 };
205 
209 struct option {
210  // A link to the option set.
211  const struct option_set *poptset;
212  // Type of the option.
213  enum option_type type;
214 
215  // Common accessors.
216  // Common accessors.
218  // Specific typed accessors.
219  union {
220  // Specific boolean accessors (OT_BOOLEAN == type).
222  // Specific integer accessors (OT_INTEGER == type).
224  // Specific string accessors (OT_STRING == type).
226  // Specific enum accessors (OT_ENUM == type).
228  // Specific bitwise accessors (OT_BITWISE == type).
230  // Specific font accessors (OT_FONT == type).
232  // Specific color accessors (OT_COLOR == type).
234  };
235  // Called after the value changed.
236  void (*changed_callback)(struct option *option);
237 
239 
240  // Volatile.
241  void *gui_data;
242 };
243 
244 #define OPTION(poption) ((struct option *) (poption))
245 
246 #define OPTION_INIT(optset, spec_type, spec_table_var, common_table, \
247  spec_table, changed_cb, cb_data) \
248  { \
249  .poptset = optset, .type = spec_type, .common_vtable = &common_table, \
250  .spec_table_var = &spec_table, .changed_callback = changed_cb, \
251  .callback_data = cb_data, .gui_data = nullptr \
252  }
253 #define OPTION_BOOL_INIT(optset, common_table, bool_table, changed_cb) \
254  OPTION_INIT(optset, OT_BOOLEAN, bool_vtable, common_table, bool_table, \
255  changed_cb, 0)
256 #define OPTION_INT_INIT(optset, common_table, int_table, changed_cb) \
257  OPTION_INIT(optset, OT_INTEGER, int_vtable, common_table, int_table, \
258  changed_cb, 0)
259 #define OPTION_STR_INIT(optset, common_table, str_table, changed_cb, \
260  cb_data) \
261  OPTION_INIT(optset, OT_STRING, str_vtable, common_table, str_table, \
262  changed_cb, cb_data)
263 #define OPTION_ENUM_INIT(optset, common_table, enum_table, changed_cb) \
264  OPTION_INIT(optset, OT_ENUM, enum_vtable, common_table, enum_table, \
265  changed_cb, 0)
266 #define OPTION_BITWISE_INIT(optset, common_table, bitwise_table, \
267  changed_cb) \
268  OPTION_INIT(optset, OT_BITWISE, bitwise_vtable, common_table, \
269  bitwise_table, changed_cb, 0)
270 #define OPTION_FONT_INIT(optset, common_table, font_table, changed_cb) \
271  OPTION_INIT(optset, OT_FONT, font_vtable, common_table, font_table, \
272  changed_cb, 0)
273 #define OPTION_COLOR_INIT(optset, common_table, color_table, changed_cb) \
274  OPTION_INIT(optset, OT_COLOR, color_vtable, common_table, color_table, \
275  changed_cb, 0)
276 
280 const struct option_set *option_optset(const struct option *poption)
281 {
282  fc_assert_ret_val(nullptr != poption, nullptr);
283 
284  return poption->poptset;
285 }
286 
290 int option_number(const struct option *poption)
291 {
292  fc_assert_ret_val(nullptr != poption, 0);
293 
294  return poption->common_vtable->number(poption);
295 }
296 
300 const char *option_name(const struct option *poption)
301 {
302  fc_assert_ret_val(nullptr != poption, nullptr);
303 
304  return poption->common_vtable->name(poption);
305 }
306 
310 const char *option_description(const struct option *poption)
311 {
312  fc_assert_ret_val(nullptr != poption, nullptr);
313 
314  return poption->common_vtable->description(poption);
315 }
316 
320 QString option_help_text(const struct option *poption)
321 {
322  fc_assert_ret_val(nullptr != poption, nullptr);
323 
324  return poption->common_vtable->help_text(poption);
325 }
326 
330 enum option_type option_type(const struct option *poption)
331 {
332  fc_assert_ret_val(nullptr != poption, static_cast<enum option_type>(0));
333 
334  return poption->type;
335 }
336 
340 QString option_category_name(const struct option *poption)
341 {
342  fc_assert_ret_val(nullptr != poption, nullptr);
343 
344  return optset_category_name(poption->poptset,
345  poption->common_vtable->category(poption));
346 }
347 
351 bool option_is_changeable(const struct option *poption)
352 {
353  fc_assert_ret_val(nullptr != poption, false);
354 
355  return poption->common_vtable->is_changeable(poption);
356 }
357 
361 struct option *option_next(const struct option *poption)
362 {
363  fc_assert_ret_val(nullptr != poption, nullptr);
364 
365  return poption->common_vtable->next(poption);
366 }
367 
371 bool option_reset(struct option *poption)
372 {
373  fc_assert_ret_val(nullptr != poption, false);
374 
375  switch (option_type(poption)) {
376  case OT_BOOLEAN:
377  return option_bool_set(poption, option_bool_def(poption));
378  case OT_INTEGER:
379  return option_int_set(poption, option_int_def(poption));
380  case OT_STRING:
381  return option_str_set(poption, option_str_def(poption));
382  case OT_ENUM:
383  return option_enum_set_int(poption, option_enum_def_int(poption));
384  case OT_BITWISE:
385  return option_bitwise_set(poption, option_bitwise_def(poption));
386  case OT_FONT:
387  return option_font_set(poption, option_font_def(poption));
388  case OT_COLOR:
389  return option_color_set(poption, option_color_def(poption));
390  }
391  return false;
392 }
393 
397 void option_set_changed_callback(struct option *poption,
398  void (*callback)(struct option *))
399 {
400  fc_assert_ret(nullptr != poption);
401 
402  poption->changed_callback = callback;
403 }
404 
408 void option_changed(struct option *poption)
409 {
410  fc_assert_ret(nullptr != poption);
411 
413  // Prevent to use non-initialized datas.
414  return;
415  }
416 
417  if (poption->changed_callback) {
418  poption->changed_callback(poption);
419  }
420 
421  option_gui_update(poption);
422 }
423 
427 void option_set_gui_data(struct option *poption, void *data)
428 {
429  fc_assert_ret(nullptr != poption);
430 
431  poption->gui_data = data;
432 }
433 
437 void *option_get_gui_data(const struct option *poption)
438 {
439  fc_assert_ret_val(nullptr != poption, nullptr);
440 
441  return poption->gui_data;
442 }
443 
447 int option_get_cb_data(const struct option *poption)
448 {
449  fc_assert_ret_val(nullptr != poption, 0);
450 
451  return poption->callback_data;
452 }
453 
457 bool option_bool_get(const struct option *poption)
458 {
459  fc_assert_ret_val(nullptr != poption, false);
460  fc_assert_ret_val(OT_BOOLEAN == poption->type, false);
461 
462  return poption->bool_vtable->get(poption);
463 }
464 
468 bool option_bool_def(const struct option *poption)
469 {
470  fc_assert_ret_val(nullptr != poption, false);
471  fc_assert_ret_val(OT_BOOLEAN == poption->type, false);
472 
473  return poption->bool_vtable->def(poption);
474 }
475 
479 bool option_bool_set(struct option *poption, bool val)
480 {
481  fc_assert_ret_val(nullptr != poption, false);
482  fc_assert_ret_val(OT_BOOLEAN == poption->type, false);
483 
484  if (poption->bool_vtable->set(poption, val)) {
485  option_changed(poption);
486  return true;
487  }
488  return false;
489 }
490 
494 int option_int_get(const struct option *poption)
495 {
496  fc_assert_ret_val(nullptr != poption, 0);
497  fc_assert_ret_val(OT_INTEGER == poption->type, 0);
498 
499  return poption->int_vtable->get(poption);
500 }
501 
505 int option_int_def(const struct option *poption)
506 {
507  fc_assert_ret_val(nullptr != poption, 0);
508  fc_assert_ret_val(OT_INTEGER == poption->type, 0);
509 
510  return poption->int_vtable->def(poption);
511 }
512 
516 int option_int_min(const struct option *poption)
517 {
518  fc_assert_ret_val(nullptr != poption, 0);
519  fc_assert_ret_val(OT_INTEGER == poption->type, 0);
520 
521  return poption->int_vtable->minimum(poption);
522 }
523 
527 int option_int_max(const struct option *poption)
528 {
529  fc_assert_ret_val(nullptr != poption, 0);
530  fc_assert_ret_val(OT_INTEGER == poption->type, 0);
531 
532  return poption->int_vtable->maximum(poption);
533 }
534 
538 bool option_int_set(struct option *poption, int val)
539 {
540  fc_assert_ret_val(nullptr != poption, false);
541  fc_assert_ret_val(OT_INTEGER == poption->type, false);
542 
543  if (poption->int_vtable->set(poption, val)) {
544  option_changed(poption);
545  return true;
546  }
547  return false;
548 }
549 
553 const char *option_str_get(const struct option *poption)
554 {
555  fc_assert_ret_val(nullptr != poption, nullptr);
556  fc_assert_ret_val(OT_STRING == poption->type, nullptr);
557 
558  return poption->str_vtable->get(poption);
559 }
560 
564 const char *option_str_def(const struct option *poption)
565 {
566  fc_assert_ret_val(nullptr != poption, nullptr);
567  fc_assert_ret_val(OT_STRING == poption->type, nullptr);
568 
569  return poption->str_vtable->def(poption);
570 }
571 
575 const QVector<QString> *option_str_values(const struct option *poption)
576 {
577  fc_assert_ret_val(nullptr != poption, nullptr);
578  fc_assert_ret_val(OT_STRING == poption->type, nullptr);
579 
580  return poption->str_vtable->values(poption);
581 }
582 
586 bool option_str_set(struct option *poption, const char *str)
587 {
588  fc_assert_ret_val(nullptr != poption, false);
589  fc_assert_ret_val(OT_STRING == poption->type, false);
590  fc_assert_ret_val(nullptr != str, false);
591 
592  if (poption->str_vtable->set(poption, str)) {
593  option_changed(poption);
594  return true;
595  }
596  return false;
597 }
598 
603 int option_enum_str_to_int(const struct option *poption, const char *str)
604 {
605  const QVector<QString> *values;
606  int val;
607 
608  fc_assert_ret_val(nullptr != poption, 0);
609  fc_assert_ret_val(OT_ENUM == poption->type, 0);
610  values = poption->enum_vtable->values(poption);
611  fc_assert_ret_val(nullptr != values, 0);
612 
613  for (val = 0; val < values->count(); val++) {
614  if (0
615  == poption->enum_vtable->cmp(qUtf8Printable(values->at(val)), str)) {
616  return val;
617  }
618  }
619  return -1;
620 }
621 
626 QString option_enum_int_to_str(const struct option *poption, int val)
627 {
628  const QVector<QString> *values;
629 
630  fc_assert_ret_val(nullptr != poption, nullptr);
631  fc_assert_ret_val(OT_ENUM == poption->type, nullptr);
632  values = poption->enum_vtable->values(poption);
633  fc_assert_ret_val(nullptr != values, nullptr);
634  if (val < values->count()) {
635  // TODO bug here - val is bigger than vector size
636  return values->at(val);
637  } else {
638  return nullptr;
639  }
640 }
641 
645 int option_enum_get_int(const struct option *poption)
646 {
647  fc_assert_ret_val(nullptr != poption, -1);
648  fc_assert_ret_val(OT_ENUM == poption->type, -1);
649 
650  return poption->enum_vtable->get(poption);
651 }
652 
656 int option_enum_def_int(const struct option *poption)
657 {
658  fc_assert_ret_val(nullptr != poption, -1);
659  fc_assert_ret_val(OT_ENUM == poption->type, -1);
660 
661  return poption->enum_vtable->def(poption);
662 }
663 
667 bool option_enum_set_int(struct option *poption, int val)
668 {
669  fc_assert_ret_val(nullptr != poption, false);
670  fc_assert_ret_val(OT_ENUM == poption->type, false);
671 
672  if (poption->enum_vtable->set(poption, val)) {
673  option_changed(poption);
674  return true;
675  }
676  return false;
677 }
678 
682 unsigned option_bitwise_get(const struct option *poption)
683 {
684  fc_assert_ret_val(nullptr != poption, 0);
685  fc_assert_ret_val(OT_BITWISE == poption->type, 0);
686 
687  return poption->bitwise_vtable->get(poption);
688 }
689 
693 unsigned option_bitwise_def(const struct option *poption)
694 {
695  fc_assert_ret_val(nullptr != poption, 0);
696  fc_assert_ret_val(OT_BITWISE == poption->type, 0);
697 
698  return poption->bitwise_vtable->def(poption);
699 }
700 
704 unsigned option_bitwise_mask(const struct option *poption)
705 {
706  const QVector<QString> *values;
707 
708  fc_assert_ret_val(nullptr != poption, 0);
709  fc_assert_ret_val(OT_BITWISE == poption->type, 0);
710 
711  values = poption->bitwise_vtable->values(poption);
712  fc_assert_ret_val(nullptr != values, 0);
713 
714  return (1 << values->count()) - 1;
715 }
716 
721 const QVector<QString> *option_bitwise_values(const struct option *poption)
722 {
723  fc_assert_ret_val(nullptr != poption, nullptr);
724  fc_assert_ret_val(OT_BITWISE == poption->type, nullptr);
725 
726  return poption->bitwise_vtable->values(poption);
727 }
728 
732 bool option_bitwise_set(struct option *poption, unsigned val)
733 {
734  fc_assert_ret_val(nullptr != poption, false);
735  fc_assert_ret_val(OT_BITWISE == poption->type, false);
736 
737  if (0 != (val & ~option_bitwise_mask(poption))
738  || !poption->bitwise_vtable->set(poption, val)) {
739  return false;
740  }
741 
742  option_changed(poption);
743  return true;
744 }
745 
749 QFont option_font_get(const struct option *poption)
750 {
751  fc_assert_ret_val(nullptr != poption, QFont());
752  fc_assert_ret_val(OT_FONT == poption->type, QFont());
753 
754  return poption->font_vtable->get(poption);
755 }
756 
760 QFont option_font_def(const struct option *poption)
761 {
762  fc_assert_ret_val(nullptr != poption, QFont());
763  fc_assert_ret_val(OT_FONT == poption->type, QFont());
764 
765  return poption->font_vtable->def(poption);
766 }
767 
771 void option_font_set_default(const struct option *poption, const QFont &font)
772 {
773  fc_assert_ret(nullptr != poption);
774  fc_assert_ret(OT_FONT == poption->type);
775 
776  poption->font_vtable->set_def(poption, font);
777 }
778 
782 QString option_font_target(const struct option *poption)
783 {
784  fc_assert_ret_val(nullptr != poption, QString());
785  fc_assert_ret_val(OT_FONT == poption->type, QString());
786 
787  return poption->font_vtable->target(poption);
788 }
789 
793 bool option_font_set(struct option *poption, const QFont &font)
794 {
795  fc_assert_ret_val(nullptr != poption, false);
796  fc_assert_ret_val(OT_FONT == poption->type, false);
797 
798  if (poption->font_vtable->set(poption, font)) {
799  option_changed(poption);
800  return true;
801  }
802  return false;
803 }
804 
808 struct ft_color option_color_get(const struct option *poption)
809 {
810  fc_assert_ret_val(nullptr != poption,
811  ft_color_construct(nullptr, nullptr));
812  fc_assert_ret_val(OT_COLOR == poption->type,
813  ft_color_construct(nullptr, nullptr));
814 
815  return poption->color_vtable->get(poption);
816 }
817 
821 struct ft_color option_color_def(const struct option *poption)
822 {
823  fc_assert_ret_val(nullptr != poption,
824  ft_color_construct(nullptr, nullptr));
825  fc_assert_ret_val(OT_COLOR == poption->type,
826  ft_color_construct(nullptr, nullptr));
827 
828  return poption->color_vtable->def(poption);
829 }
830 
835 bool option_color_set(struct option *poption, struct ft_color color)
836 {
837  fc_assert_ret_val(nullptr != poption, false);
838  fc_assert_ret_val(OT_COLOR == poption->type, false);
839 
840  if (poption->color_vtable->set(poption, color)) {
841  option_changed(poption);
842  return true;
843  }
844  return false;
845 }
846 
850 static struct option *client_optset_option_by_number(int id);
851 static struct option *client_optset_option_first();
852 static int client_optset_category_number();
853 static const char *client_optset_category_name(int category);
854 
855 static struct option_set client_optset_static = {
857  .option_first = client_optset_option_first,
858  .category_number = client_optset_category_number,
859  .category_name = client_optset_category_name};
861 
863  const char *support; /* Untranslated long support name, used
864  * for saving. */
865  const char *pretty; /* Translated, used to display to the
866  * users. */
867 };
868 
872 static int client_option_number(const struct option *poption);
873 static const char *client_option_name(const struct option *poption);
874 static const char *client_option_description(const struct option *poption);
875 static const char *client_option_help_text(const struct option *poption);
876 static int client_option_category(const struct option *poption);
877 static bool client_option_is_changeable(const struct option *poption);
878 static struct option *client_option_next(const struct option *poption);
879 
882  .name = client_option_name,
883  .description = client_option_description,
884  .help_text = client_option_help_text,
885  .category = client_option_category,
886  .is_changeable = client_option_is_changeable,
887  .next = client_option_next};
888 
889 static bool client_option_bool_get(const struct option *poption);
890 static bool client_option_bool_def(const struct option *poption);
891 static bool client_option_bool_set(struct option *poption, bool val);
892 
893 static const struct option_bool_vtable client_option_bool_vtable = {
895  .def = client_option_bool_def,
896  .set = client_option_bool_set};
897 
898 static int client_option_int_get(const struct option *poption);
899 static int client_option_int_def(const struct option *poption);
900 static int client_option_int_min(const struct option *poption);
901 static int client_option_int_max(const struct option *poption);
902 static bool client_option_int_set(struct option *poption, int val);
903 
904 static const struct option_int_vtable client_option_int_vtable = {
906  .def = client_option_int_def,
907  .minimum = client_option_int_min,
908  .maximum = client_option_int_max,
909  .set = client_option_int_set};
910 
911 static const char *client_option_str_get(const struct option *poption);
912 static const char *client_option_str_def(const struct option *poption);
913 static const QVector<QString> *
914 client_option_str_values(const struct option *poption);
915 static bool client_option_str_set(struct option *poption, const char *str);
916 
917 static const struct option_str_vtable client_option_str_vtable = {
919  .def = client_option_str_def,
920  .values = client_option_str_values,
921  .set = client_option_str_set};
922 
923 static QFont client_option_font_get(const struct option *poption);
924 static QFont client_option_font_def(const struct option *poption);
925 static void client_option_font_set_def(const struct option *poption,
926  const QFont &font);
927 static QString client_option_font_target(const struct option *poption);
928 static bool client_option_font_set(struct option *poption,
929  const QFont &font);
930 
931 static const struct option_font_vtable client_option_font_vtable = {
933  .def = client_option_font_def,
934  .set_def = client_option_font_set_def,
935  .target = client_option_font_target,
936  .set = client_option_font_set};
937 
938 static struct ft_color client_option_color_get(const struct option *poption);
939 static struct ft_color client_option_color_def(const struct option *poption);
940 static bool client_option_color_set(struct option *poption,
941  struct ft_color color);
942 
943 static const struct option_color_vtable client_option_color_vtable = {
946  .set = client_option_color_set};
947 
956  COC_MAX
957 };
958 
963  struct option base_option; // Base structure, must be the first!
964 
965  const char *name; // Short name - used as an identifier
966  const char *description; // One-line description
967  const char *help_text; // Paragraph-length help text
969 
970  struct {
971  // OT_BOOLEAN type option.
972  struct {
973  bool *pvalue;
974  bool def;
976  // OT_INTEGER type option.
977  struct {
978  int *pvalue;
979  int def, min, max;
981  // OT_STRING type option.
982  struct {
983  char *pvalue;
984  size_t size;
985  const char *def;
986  /*
987  * A function to return a string vector of possible string values,
988  * or nullptr for none.
989  */
990  const QVector<QString> *(*val_accessor)(const struct option *);
992  // OT_ENUM type option.
993  struct {
994  int *pvalue;
995  int def;
997  const struct copt_val_name *(*name_accessor)(int value);
999  // OT_BITWISE type option.
1000  struct {
1001  unsigned *pvalue;
1002  unsigned def;
1003  QVector<QString> *support_names, *pretty_names; // untranslated
1004  const struct copt_val_name *(*name_accessor)(int value);
1006  // OT_FONT type option.
1007  struct {
1008  QFont *value;
1009  QFont def;
1010  QString target;
1011  } font;
1012  // OT_COLOR type option.
1013  struct {
1014  struct ft_color *pvalue;
1015  struct ft_color def;
1017  } u;
1018 };
1019 
1020 #define CLIENT_OPTION(poption) ((struct client_option *) (poption))
1021 
1022 /*
1023  * Generate a client option of type OT_BOOLEAN.
1024  *
1025  * oname: The option data. Note it is used as name to be loaded or saved.
1026  * So, you shouldn't change the name of this variable in any case.
1027  * odesc: A short description of the client option. Should be used with the
1028  * N_() macro.
1029  * ohelp: The help text for the client option. Should be used with the N_()
1030  * macro.
1031  * ocat: The client_option_class of this client option.
1032  * ospec: A gui_type enumerator which determin for what particular client
1033  * gui this option is for. Sets to GUI_STUB for common options.
1034  * odef: The default value of this client option (FALSE or TRUE).
1035  * ocb: A callback function of type void (*)(struct option *) called when
1036  * the option changed.
1037  */
1038 #define GEN_BOOL_OPTION(oname, odesc, ohelp, ocat, odef, ocb) \
1039  client_option \
1040  { \
1041  .base_option = OPTION_BOOL_INIT(&client_optset_static, \
1042  client_option_common_vtable, \
1043  client_option_bool_vtable, ocb), \
1044  .name = #oname, .description = odesc, .help_text = ohelp, \
1045  .category = ocat, \
1046  .u = \
1047  {.boolean = { \
1048  .pvalue = &gui_options->oname, \
1049  .def = odef, \
1050  } } \
1051  }
1052 
1053 /*
1054  * Generate a client option of type OT_INTEGER.
1055  *
1056  * oname: The option data. Note it is used as name to be loaded or saved.
1057  * So, you shouldn't change the name of this variable in any case.
1058  * odesc: A short description of the client option. Should be used with the
1059  * N_() macro.
1060  * ohelp: The help text for the client option. Should be used with the N_()
1061  * macro.
1062  * ocat: The client_option_class of this client option.
1063  * odef: The default value of this client option.
1064  * omin: The minimal value of this client option.
1065  * omax: The maximal value of this client option.
1066  * ocb: A callback function of type void (*)(struct option *) called when
1067  * the option changed.
1068  */
1069 #define GEN_INT_OPTION(oname, odesc, ohelp, ocat, odef, omin, omax, ocb) \
1070  client_option \
1071  { \
1072  .base_option = \
1073  OPTION_INT_INIT(&client_optset_static, client_option_common_vtable, \
1074  client_option_int_vtable, ocb), \
1075  .name = #oname, .description = odesc, .help_text = ohelp, \
1076  .category = ocat, .u = { \
1077  .integer = {.pvalue = &gui_options->oname, \
1078  .def = odef, \
1079  .min = omin, \
1080  .max = omax} \
1081  } \
1082  }
1083 
1084 /*
1085  * Generate a client option of type OT_STRING.
1086  *
1087  * oname: The option data. Note it is used as name to be loaded or saved.
1088  * So, you shouldn't change the name of this variable in any case.
1089  * Be sure to pass the array variable and not a pointer to it because
1090  * the size is calculated with sizeof().
1091  * odesc: A short description of the client option. Should be used with the
1092  * N_() macro.
1093  * ohelp: The help text for the client option. Should be used with the N_()
1094  * macro.
1095  * ocat: The client_option_class of this client option.
1096  * odef: The default string for this client option.
1097  * ocb: A callback function of type void (*)(struct option *) called when
1098  * the option changed.
1099  */
1100 #define GEN_STR_OPTION(oname, odesc, ohelp, ocat, odef, ocb, cbd) \
1101  client_option \
1102  { \
1103  .base_option = \
1104  OPTION_STR_INIT(&client_optset_static, client_option_common_vtable, \
1105  client_option_str_vtable, ocb, cbd), \
1106  .name = #oname, .description = odesc, .help_text = ohelp, \
1107  .category = ocat, .u = { \
1108  .string = {.pvalue = gui_options->oname, \
1109  .size = sizeof(gui_options->oname), \
1110  .def = odef, \
1111  .val_accessor = nullptr} \
1112  } \
1113  }
1114 
1115 /*
1116  * Generate a client option of type OT_STRING with a string accessor
1117  * function.
1118  *
1119  * oname: The option data. Note it is used as name to be loaded or saved.
1120  * So, you shouldn't change the name of this variable in any case.
1121  * Be sure to pass the array variable and not a pointer to it because
1122  * the size is calculated with sizeof().
1123  * odesc: A short description of the client option. Should be used with the
1124  * N_() macro.
1125  * ohelp: The help text for the client option. Should be used with the N_()
1126  * macro.
1127  * ocat: The client_option_class of this client option.
1128  * odef: The default string for this client option.
1129  * oacc: The string accessor where to find the allowed values of type
1130  * 'const struct strvec * (*) (void)'.
1131  * ocb: A callback function of type void (*)(struct option *) called when
1132  * the option changed.
1133  */
1134 #define GEN_STR_LIST_OPTION(oname, odesc, ohelp, ocat, odef, oacc, ocb, \
1135  cbd) \
1136  client_option \
1137  { \
1138  .base_option = \
1139  OPTION_STR_INIT(&client_optset_static, client_option_common_vtable, \
1140  client_option_str_vtable, ocb, cbd), \
1141  .name = #oname, .description = odesc, .help_text = ohelp, \
1142  .category = ocat, .u = { \
1143  .string = {.pvalue = gui_options->oname, \
1144  .size = sizeof(gui_options->oname), \
1145  .def = odef, \
1146  .val_accessor = oacc} \
1147  } \
1148  }
1149 
1150 /*
1151  * Generate a client option of type OT_ENUM.
1152  *
1153  * oname: The option data. Note it is used as name to be loaded or saved.
1154  * So, you shouldn't change the name of this variable in any case.
1155  * odesc: A short description of the client option. Should be used with the
1156  * N_() macro.
1157  * ohelp: The help text for the client option. Should be used with the N_()
1158  * macro.
1159  * ocat: The client_option_class of this client option.
1160  * odef: The default value for this client option.
1161  * oacc: The name accessor of type 'const struct copt_val_name * (*) (int)'.
1162  * ocb: A callback function of type void (*) (struct option *) called when
1163  * the option changed.
1164  */
1165 #define GEN_ENUM_OPTION(oname, odesc, ohelp, ocat, odef, oacc, ocb) \
1166  client_option \
1167  { \
1168  .base_option = OPTION_ENUM_INIT(&client_optset_static, \
1169  client_option_common_vtable, \
1170  client_option_enum_vtable, ocb), \
1171  .name = #oname, .description = odesc, .help_text = ohelp, \
1172  .category = ocat, .u = { \
1173  .enumerator = {.pvalue = (int *) &gui_options->oname, \
1174  .def = odef, \
1175  .support_names = nullptr, /* Set in options_init(). */ \
1176  .pretty_names = nullptr, \
1177  .name_accessor = oacc} \
1178  } \
1179  }
1180 
1181 /*
1182  * Generate a client option of type OT_BITWISE.
1183  *
1184  * oname: The option data. Note it is used as name to be loaded or saved.
1185  * So, you shouldn't change the name of this variable in any case.
1186  * odesc: A short description of the client option. Should be used with the
1187  * N_() macro.
1188  * ohelp: The help text for the client option. Should be used with the N_()
1189  * macro.
1190  * ocat: The client_option_class of this client option.
1191  * odef: The default value for this client option.
1192  * oacc: The name accessor of type 'const struct copt_val_name * (*) (int)'.
1193  * ocb: A callback function of type void (*) (struct option *) called when
1194  * the option changed.
1195  */
1196 #define GEN_BITWISE_OPTION(oname, odesc, ohelp, ocat, odef, oacc, ocb) \
1197  client_option \
1198  { \
1199  .base_option = OPTION_BITWISE_INIT(&client_optset_static, \
1200  client_option_common_vtable, \
1201  client_option_bitwise_vtable, ocb), \
1202  .name = #oname, .description = odesc, .help_text = ohelp, \
1203  .category = ocat, .u = { \
1204  .bitwise = {.pvalue = &gui_options->oname, \
1205  .def = odef, \
1206  .support_names = nullptr, /* Set in options_init(). */ \
1207  .pretty_names = nullptr, \
1208  .name_accessor = oacc} \
1209  } \
1210  }
1211 
1212 /*
1213  * Generate a client option of type OT_FONT.
1214  *
1215  * oname: The option data. Note it is used as name to be loaded or saved.
1216  * So, you shouldn't change the name of this variable in any case.
1217  * Be sure to pass the array variable and not a pointer to it because
1218  * the size is calculated with sizeof().
1219  * otgt: The target widget style.
1220  * odesc: A short description of the client option. Should be used with the
1221  * N_() macro.
1222  * ohelp: The help text for the client option. Should be used with the N_()
1223  * macro.
1224  * ocat: The client_option_class of this client option.
1225  * ocb: A callback function of type void (*)(struct option *) called when
1226  * the option changed.
1227  */
1228 #define GEN_FONT_OPTION(oname, otgt, odesc, ohelp, ocat, ocb) \
1229  client_option \
1230  { \
1231  .base_option = OPTION_FONT_INIT(&client_optset_static, \
1232  client_option_common_vtable, \
1233  client_option_font_vtable, ocb), \
1234  .name = #oname, .description = odesc, .help_text = ohelp, \
1235  .category = ocat, \
1236  .u = \
1237  {.font = { \
1238  .value = &gui_options->oname, \
1239  .def = QFont(), \
1240  .target = otgt, \
1241  } } \
1242  }
1243 
1244 /*
1245  * Generate a client option of type OT_COLOR.
1246  *
1247  * oname: The option data. Note it is used as name to be loaded or saved.
1248  * So, you shouldn't change the name of this variable in any case.
1249  * odesc: A short description of the client option. Should be used with the
1250  * N_() macro.
1251  * ohelp: The help text for the client option. Should be used with the N_()
1252  * macro.
1253  * ocat: The client_option_class of this client option.
1254  * odef_fg, odef_bg: The default values for this client option.
1255  * ocb: A callback function of type void (*)(struct option *) called when
1256  * the option changed.
1257  */
1258 #define GEN_COLOR_OPTION(oname, odesc, ohelp, ocat, odef_fg, odef_bg, ocb) \
1259  client_option \
1260  { \
1261  .base_option = OPTION_COLOR_INIT(&client_optset_static, \
1262  client_option_common_vtable, \
1263  client_option_color_vtable, ocb), \
1264  .name = #oname, .description = odesc, .help_text = ohelp, \
1265  .category = ocat, .u = { \
1266  .color = {.pvalue = &gui_options->oname, \
1267  .def = FT_COLOR(odef_fg, odef_bg)} \
1268  } \
1269  }
1270 
1275 // Some changed callbacks.
1276 static void reqtree_show_icons_callback(struct option *poption);
1277 static void view_option_changed_callback(struct option *poption);
1278 static void manual_turn_done_callback(struct option *poption);
1279 static void voteinfo_bar_callback(struct option *poption);
1280 static void font_changed_callback(struct option *poption);
1281 static void allfont_changed_callback(struct option *poption);
1282 /* See #2237
1283 static void mapimg_changed_callback(struct option *poption);
1284 */
1285 static void game_music_enable_callback(struct option *poption);
1286 static void menu_music_enable_callback(struct option *poption);
1287 static void sound_volume_callback(struct option *poption);
1288 
1289 static std::vector<client_option> client_options;
1290 static void init_client_options()
1291 {
1292  client_options = {
1294  default_user_name, N_("Login name"),
1295  N_("This is the default login username that will be used "
1296  "in the connection dialogs or with the -a command-line "
1297  "parameter."),
1298  COC_NETWORK, nullptr, nullptr, 0),
1300  use_prev_server, N_("Default to previously used server"),
1301  N_("Automatically update \"Server\" and \"Server port\" "
1302  "options to match your latest connection, so by "
1303  "default you connect to the same server you used "
1304  "on the previous run. You should enable "
1305  "saving options on exit too, so that the automatic "
1306  "updates to the options get saved too."),
1307  COC_NETWORK, false, nullptr),
1309  default_server_host, N_("Server"),
1310  N_("This is the default server hostname that will be used "
1311  "in the connection dialogs or with the -a command-line "
1312  "parameter."),
1313  COC_NETWORK, "localhost", nullptr, 0),
1315  default_server_port, N_("Server port"),
1316  N_("This is the default server port that will be used "
1317  "in the connection dialogs or with the -a command-line "
1318  "parameter."),
1319  COC_NETWORK, DEFAULT_SOCK_PORT, 0, 65535, nullptr),
1321  default_metaserver, N_("Metaserver"),
1322  N_("The metaserver is a host that the client contacts to "
1323  "find out about games on the internet. Don't change "
1324  "this from its default value unless you know what "
1325  "you're doing."),
1326  COC_NETWORK, DEFAULT_METASERVER_OPTION, nullptr, 0),
1328  heartbeat_enabled, N_("Send heartbeat messages to server"),
1329  N_("Periodically send an empty heartbeat message to the "
1330  "server to probe whether the connection is still up. "
1331  "This can help to make it obvious when the server has "
1332  "cut the connection due to a connectivity outage, if "
1333  "the client would otherwise sit idle for a long period."),
1334  COC_NETWORK, true, nullptr),
1336  default_sound_set_name, N_("Soundset"),
1337  N_("This is the soundset that will be used. Changing "
1338  "this is the same as using the -S command-line "
1339  "parameter."),
1340  COC_SOUND, "stdsounds", get_soundset_list, nullptr, 0),
1342  default_music_set_name, N_("Musicset"),
1343  N_("This is the musicset that will be used. Changing "
1344  "this is the same as using the -m command-line "
1345  "parameter."),
1346  COC_SOUND, "stdmusic", get_musicset_list,
1349  default_sound_plugin_name, N_("Sound plugin"),
1350  N_("If you have a problem with sound, try changing "
1351  "the sound plugin. The new plugin won't take "
1352  "effect until you restart Freeciv21. Changing this "
1353  "is the same as using the -P command-line option."),
1354  COC_SOUND, "", get_soundplugin_list, nullptr, 0),
1355  GEN_STR_OPTION(default_chat_logfile, N_("The chat log file"),
1356  N_("The name of the chat log file."), COC_INTERFACE,
1357  "freeciv-chat.log", nullptr, 0),
1358  GEN_STR_LIST_OPTION(gui_qt_default_theme_name, N_("Theme"),
1359  N_("By changing this option you change the "
1360  "active theme."),
1363 
1364  /* It's important to give empty string instead of nullptr as as default
1365  * value. For nullptr value it would default to assigning first value
1366  * from the tileset list returned by get_tileset_list() as default
1367  * tileset. We don't want default tileset assigned at all here, but
1368  * leave it to tilespec code that can handle tileset priority. */
1370  default_tileset_square_name, N_("Tileset (Square)"),
1371  N_("Select the tileset used with Square based maps. "
1372  "This may change the currently active tileset, if "
1373  "you are playing on such a map, in which "
1374  "case this is the same as using the -t "
1375  "command-line parameter."),
1378  default_tileset_hex_name, N_("Tileset (Hex)"),
1379  N_("Select the tileset used with Hex maps. "
1380  "This may change the currently active tileset, if "
1381  "you are playing on such a map, in which "
1382  "case this is the same as using the -t "
1383  "command-line parameter."),
1385  TF_HEX),
1387  default_tileset_isohex_name, N_("Tileset (Iso-Hex)"),
1388  N_("Select the tileset used with Iso-Hex maps. "
1389  "This may change the currently active tileset, if "
1390  "you are playing on such a map, in which "
1391  "case this is the same as using the -t "
1392  "command-line parameter."),
1394  TF_ISO | TF_HEX),
1395 
1396  GEN_STR_LIST_OPTION(default_city_bar_style_name, N_("City bar style"),
1397  N_("Selects the style of the city bar."),
1398  COC_GRAPHICS, "Polished",
1401 
1402  GEN_BOOL_OPTION(draw_city_outlines, N_("Draw city outlines"),
1403  N_("Setting this option will draw a line at the city "
1404  "workable limit."),
1407  draw_city_output, N_("Draw city output"),
1408  N_("Setting this option will draw city output for every "
1409  "citizen."),
1412  draw_map_grid, N_("Draw the map grid"),
1413  N_("Setting this option will draw a grid over the map."),
1416  draw_city_names, N_("Draw the city names"),
1417  N_("Setting this option will draw the names of the cities "
1418  "on the map."),
1421  draw_city_growth, N_("Draw the city growth"),
1422  N_("Setting this option will draw in how many turns the "
1423  "cities will grow or shrink."),
1425  GEN_BOOL_OPTION(draw_city_productions, N_("Draw the city productions"),
1426  N_("Setting this option will draw what the cities are "
1427  "currently building on the map."),
1429  GEN_BOOL_OPTION(draw_city_buycost, N_("Draw the city buy costs"),
1430  N_("Setting this option will draw how much gold is "
1431  "needed to buy the production of the cities."),
1433  GEN_BOOL_OPTION(draw_city_trade_routes,
1434  N_("Draw the city trade routes"),
1435  N_("Setting this option will draw trade route lines "
1436  "between cities which have trade routes."),
1439  draw_coastline, N_("Draw the coast line"),
1440  N_("Setting this option will draw a line to separate the "
1441  "land from the ocean."),
1443  GEN_BOOL_OPTION(draw_roads_rails,
1444  N_("Draw the roads and the railroads"),
1445  N_("Setting this option will draw the roads and the "
1446  "railroads on the map."),
1449  draw_irrigation, N_("Draw the irrigation"),
1450  N_("Setting this option will draw the irrigation systems "
1451  "on the map."),
1454  draw_mines, N_("Draw the mines"),
1455  N_("Setting this option will draw the mines on the map."),
1458  draw_fortress_airbase, N_("Draw the bases"),
1459  N_("Setting this option will draw the bases on the map."),
1462  draw_specials, N_("Draw the resources"),
1463  N_("Setting this option will draw the resources on the "
1464  "map."),
1466  GEN_BOOL_OPTION(draw_huts, N_("Draw the huts"),
1467  N_("Setting this option will draw the huts on the "
1468  "map."),
1470  GEN_BOOL_OPTION(draw_pollution,
1471  N_("Draw the pollution/nuclear fallout"),
1472  N_("Setting this option will draw pollution and "
1473  "nuclear fallout on the map."),
1476  draw_cities, N_("Draw the cities"),
1477  N_("Setting this option will draw the cities on the map."),
1480  draw_units, N_("Draw the units"),
1481  N_("Setting this option will draw the units on the map."),
1483  GEN_BOOL_OPTION(solid_color_behind_units,
1484  N_("Solid unit background color"),
1485  N_("Setting this option will cause units on the map "
1486  "view to be drawn with a solid background color "
1487  "instead of the flag backdrop."),
1490  draw_unit_shields, N_("Draw shield graphics for units"),
1491  N_("Setting this option will draw a shield icon "
1492  "as the flags on units. If unset, the full flag will "
1493  "be drawn."),
1496  draw_focus_unit, N_("Draw the units in focus"),
1497  N_("Setting this option will cause the currently focused "
1498  "unit(s) to always be drawn, even if units are not "
1499  "otherwise being drawn (for instance if 'Draw the units' "
1500  "is unset)."),
1502  GEN_BOOL_OPTION(draw_fog_of_war, N_("Draw the fog of war"),
1503  N_("Setting this option will draw the fog of war."),
1506  draw_borders, N_("Draw the borders"),
1507  N_("Setting this option will draw the national borders."),
1510  draw_native,
1511  N_("Draw whether tiles are native to "
1512  "selected unit"),
1513  N_("Setting this option will highlight tiles that the "
1514  "currently selected unit cannot enter unaided due to "
1515  "non-native terrain. (If multiple units are selected, "
1516  "only tiles that all of them can enter are indicated.)"),
1518  GEN_BOOL_OPTION(player_dlg_show_dead_players,
1519  N_("Show dead players in Nations report"),
1520  N_("This option controls whether defeated nations are "
1521  "shown on the Nations report page."),
1523  GEN_BOOL_OPTION(zoom_scale_fonts, N_("Scale fonts when zooming"),
1524  N_("When this option is set, the fonts and city "
1525  "descriptions will be "
1526  "scaled when the map is zoomed."),
1529  sound_bell_at_new_turn, N_("Sound bell at new turn"),
1530  N_("Set this option to have a \"bell\" event be generated "
1531  "at the start of a new turn. You can control the "
1532  "behavior of the \"bell\" event by editing the message "
1533  "options."),
1534  COC_SOUND, false, nullptr),
1536  smooth_move_unit_msec,
1537  N_("Unit movement animation time (milliseconds)"),
1538  N_("This option controls how long unit \"animation\" takes "
1539  "when a unit moves on the map view. Set it to 0 to "
1540  "disable animation entirely."),
1541  COC_GRAPHICS, 30, 0, 2000, nullptr),
1543  smooth_center_slide_msec,
1544  N_("Mapview recentering time (milliseconds)"),
1545  N_("When the map view is recentered, it will slide "
1546  "smoothly over the map to its new position. This "
1547  "option controls how long this slide lasts. Set it to "
1548  "0 to disable mapview sliding entirely."),
1549  COC_GRAPHICS, 200, 0, 5000, nullptr),
1551  smooth_combat_step_msec,
1552  N_("Combat animation step time (milliseconds)"),
1553  N_("This option controls the speed of combat animation "
1554  "between units on the mapview. Set it to 0 to disable "
1555  "animation entirely."),
1556  COC_GRAPHICS, 10, 0, 100, nullptr),
1557  GEN_BOOL_OPTION(reqtree_show_icons,
1558  N_("Show icons in the technology tree"),
1559  N_("Setting this option will display icons "
1560  "on the technology tree diagram. Turning "
1561  "this option off makes the technology tree "
1562  "more compact."),
1564  GEN_BOOL_OPTION(reqtree_curved_lines,
1565  N_("Use curved lines in the technology tree"),
1566  N_("Setting this option make the technology tree "
1567  "diagram use curved lines to show technology "
1568  "relations. Turning this option off causes "
1569  "the lines to be drawn straight."),
1572  highlight_our_names,
1573  N_("Color to highlight your player/user name"),
1574  N_("If set, your player and user name in the new chat "
1575  "messages will be highlighted using this color as "
1576  "background. If not set, it will just not highlight "
1577  "anything."),
1578  COC_GRAPHICS, "#000000", "#FFFF00", nullptr),
1579  GEN_BOOL_OPTION(ai_manual_turn_done, N_("Manual Turn Done in AI mode"),
1580  N_("Disable this option if you do not want to "
1581  "press the Turn Done button manually when watching "
1582  "an AI player."),
1584  GEN_BOOL_OPTION(auto_center_on_unit, N_("Auto center on units"),
1585  N_("Set this option to have the active unit centered "
1586  "automatically when the unit focus changes."),
1587  COC_INTERFACE, true, nullptr),
1588  GEN_BOOL_OPTION(auto_center_on_automated, N_("Show automated units"),
1589  N_("Disable this option if you do not want to see "
1590  "automated units autocentered and animated."),
1591  COC_INTERFACE, true, nullptr),
1593  auto_center_on_combat, N_("Auto center on combat"),
1594  N_("Set this option to have any combat be centered "
1595  "automatically. Disabling this will speed up the time "
1596  "between turns but may cause you to miss combat "
1597  "entirely."),
1598  COC_INTERFACE, false, nullptr),
1599  GEN_BOOL_OPTION(auto_center_each_turn, N_("Auto center on new turn"),
1600  N_("Set this option to have the client automatically "
1601  "recenter the map on a suitable location at the "
1602  "start of each turn."),
1603  COC_INTERFACE, true, nullptr),
1604  GEN_BOOL_OPTION(wakeup_focus, N_("Focus on awakened units"),
1605  N_("Set this option to have newly awoken units be "
1606  "focused automatically."),
1607  COC_INTERFACE, true, nullptr),
1609  keyboardless_goto, N_("Keyboardless goto"),
1610  N_("If this option is set then a goto may be initiated "
1611  "by left-clicking and then holding down the mouse "
1612  "button while dragging the mouse onto a different "
1613  "tile."),
1614  COC_INTERFACE, false, nullptr),
1616  goto_into_unknown, N_("Allow goto into the unknown"),
1617  N_("Setting this option will make the game consider "
1618  "moving into unknown tiles. If not, then goto routes "
1619  "will detour around or be blocked by unknown tiles."),
1620  COC_INTERFACE, true, nullptr),
1621  GEN_BOOL_OPTION(center_when_popup_city,
1622  N_("Center map when popup city"),
1623  N_("Setting this option makes the mapview center on a "
1624  "city when its city dialog is popped up."),
1625  COC_INTERFACE, true, nullptr),
1627  show_previous_turn_messages,
1628  N_("Show messages from previous turn"),
1629  N_("Message Window shows messages also from previous turn. "
1630  "This makes sure you don't miss messages received in the end "
1631  "of "
1632  "the turn, just before the window gets cleared."),
1633  COC_INTERFACE, true, nullptr),
1635  concise_city_production, N_("Concise city production"),
1636  N_("Set this option to make the city production (as shown "
1637  "in the city dialog) to be more compact."),
1638  COC_INTERFACE, false, nullptr),
1640  auto_turn_done, N_("End turn when done moving"),
1641  N_("Setting this option makes your turn end automatically "
1642  "when all your units are done moving."),
1643  COC_INTERFACE, false, nullptr),
1645  ask_city_name, N_("Prompt for city names"),
1646  N_("Disabling this option will make the names of newly "
1647  "founded cities be chosen automatically by the server."),
1648  COC_INTERFACE, true, nullptr),
1649  GEN_BOOL_OPTION(popup_new_cities,
1650  N_("Pop up city dialog for new cities"),
1651  N_("Setting this option will pop up a newly-founded "
1652  "city's city dialog automatically."),
1653  COC_INTERFACE, true, nullptr),
1655  popup_actor_arrival, N_("Pop up caravan and spy actions"),
1656  N_("If this option is enabled, when a unit arrives at "
1657  "a city where it can perform an action like "
1658  "establishing a trade route, helping build a wonder, or "
1659  "establishing an embassy, a window will pop up asking "
1660  "which action should be performed. "
1661  "Disabling this option means you will have to do the "
1662  "action manually by pressing either 'r' (for a trade "
1663  "route), 'b' (for building a wonder) or 'd' (for a "
1664  "spy action) when the unit is in the city."),
1665  COC_INTERFACE, true, nullptr),
1667  popup_attack_actions, N_("Pop up attack questions"),
1668  N_("If this option is enabled, when a unit arrives at a "
1669  "target it can attack, a window will pop up asking "
1670  "which action should be performed even if an attack "
1671  "action is legal and no other interesting action are. "
1672  "This allows you to change your mind or to select an "
1673  "uninteresting action."),
1674  COC_INTERFACE, true, nullptr),
1676  popup_last_move_to_allied,
1677  N_("Pop up actions last move to allied"),
1678  N_("If this option is enabled the final move in a unit's"
1679  " orders to a tile with allied units or cities it can"
1680  " perform an action to is interpreted as an attempted"
1681  " action. This makes the action selection dialog pop up"
1682  " while the unit is at the adjacent tile."
1683  " This can, in cases where the action requires that"
1684  " the actor unit has moves left, save a turn."
1685  " The down side is that the unit remains adjacent to"
1686  " rather than inside the protection of an allied city"
1687  " or unit stack."),
1688  COC_INTERFACE, true, nullptr),
1689  GEN_BOOL_OPTION(enable_cursor_changes, N_("Enable cursor changing"),
1690  N_("This option controls whether the client should "
1691  "try to change the mouse cursor depending on what "
1692  "is being pointed at, as well as to indicate "
1693  "changes in the client or server state."),
1694  COC_INTERFACE, true, nullptr),
1696  separate_unit_selection, N_("Select cities before units"),
1697  N_("If this option is enabled, when both cities and "
1698  "units are present in the selection rectangle, only "
1699  "cities will be selected. See the help on Controls."),
1700  COC_INTERFACE, false, nullptr),
1702  unit_selection_clears_orders, N_("Clear unit orders on selection"),
1703  N_("Enabling this option will cause unit orders to be "
1704  "cleared as soon as one or more units are selected. If "
1705  "this option is disabled, busy units will not stop "
1706  "their current activity when selected. Giving them "
1707  "new orders will clear their current ones; pressing "
1708  "<space> once will clear their orders and leave them "
1709  "selected, and pressing <space> a second time will "
1710  "dismiss them."),
1711  COC_INTERFACE, true, nullptr),
1712  GEN_BOOL_OPTION(voteinfo_bar_use, N_("Enable vote bar"),
1713  N_("If this option is turned on, the vote bar will be "
1714  "displayed to show vote information."),
1717  voteinfo_bar_always_show, N_("Always display the vote bar"),
1718  N_("If this option is turned on, the vote bar will never "
1719  "be hidden, even if there is no running vote."),
1722  voteinfo_bar_hide_when_not_player,
1723  N_("Do not show vote bar if not a player"),
1724  N_("If this option is enabled, the client won't show the "
1725  "vote bar if you are not a player."),
1727  GEN_BOOL_OPTION(voteinfo_bar_new_at_front,
1728  N_("Set new votes at front"),
1729  N_("If this option is enabled, then new votes will go "
1730  "to the front of the vote list."),
1733  autoaccept_tileset_suggestion,
1734  N_("Autoaccept tileset suggestions"),
1735  N_("If this option is enabled, any tileset suggested by "
1736  "the ruleset is automatically used; otherwise you "
1737  "are prompted to change tileset."),
1738  COC_GRAPHICS, false, nullptr),
1739 
1740  GEN_BOOL_OPTION(sound_enable_effects, N_("Enable sound effects"),
1741  N_("Play sound effects, assuming there's suitable "
1742  "sound plugin and soundset with the sounds."),
1743  COC_SOUND, true, nullptr),
1745  sound_enable_game_music, N_("Enable in-game music"),
1746  N_("Play music during the game, assuming there's suitable "
1747  "sound plugin and musicset with in-game tracks."),
1750  sound_enable_menu_music, N_("Enable menu music"),
1751  N_("Play music while not in actual game, "
1752  "assuming there's suitable "
1753  "sound plugin and musicset with menu music tracks."),
1755  GEN_INT_OPTION(sound_effects_volume, N_("Sound volume"),
1756  N_("Volume scale from 0-100"), COC_SOUND, 100, 0, 100,
1758 
1760  autoaccept_soundset_suggestion,
1761  N_("Autoaccept soundset suggestions"),
1762  N_("If this option is enabled, any soundset suggested by "
1763  "the ruleset is automatically used."),
1764  COC_SOUND, false, nullptr),
1766  autoaccept_musicset_suggestion,
1767  N_("Autoaccept musicset suggestions"),
1768  N_("If this option is enabled, any musicset suggested by "
1769  "the ruleset is automatically used."),
1770  COC_SOUND, false, nullptr),
1771 
1773  N_("Background layer"),
1774  N_("The background layer of the overview shows just "
1775  "ocean and land."),
1776  COC_OVERVIEW, true, nullptr),
1778  N_("Terrain relief map layer"),
1779  N_("The relief layer shows all terrains on the map."),
1782  overview.layers[OLAYER_BORDERS], N_("Borders layer"),
1783  N_("The borders layer of the overview shows which tiles "
1784  "are owned by each player."),
1787  N_("Borders layer on ocean tiles"),
1788  N_("The borders layer of the overview are drawn on "
1789  "ocean tiles as well (this may look ugly with many "
1790  "islands). This option is only of interest if you "
1791  "have set the option \"Borders layer\" already."),
1793  GEN_BOOL_OPTION(overview.layers[OLAYER_UNITS], N_("Units layer"),
1794  N_("Enabling this will draw units on the overview."),
1796  GEN_BOOL_OPTION(overview.layers[OLAYER_CITIES], N_("Cities layer"),
1797  N_("Enabling this will draw cities on the overview."),
1799  GEN_BOOL_OPTION(overview.fog, N_("Overview fog of war"),
1800  N_("Enabling this will show fog of war on the "
1801  "overview."),
1803 
1804  /* See #2237
1805  // options for map images
1806  GEN_STR_LIST_OPTION(mapimg_format, N_("Image format"),
1807  N_("The image toolkit and file format used for "
1808  "map images."),
1809  COC_MAPIMG, nullptr, get_mapimg_format_list,
1810  nullptr, 0),
1811  GEN_INT_OPTION(mapimg_zoom, N_("Zoom factor for map images"),
1812  N_("The magnification used for map images."),
1813  COC_MAPIMG, 2, 1, 5, mapimg_changed_callback),
1814  GEN_BOOL_OPTION(mapimg_layer[MAPIMG_LAYER_AREA],
1815  N_("Show area within borders"),
1816  N_("If set, the territory of each nation is shown "
1817  "on the saved image."),
1818  COC_MAPIMG, false, mapimg_changed_callback),
1819  GEN_BOOL_OPTION(mapimg_layer[MAPIMG_LAYER_BORDERS], N_("Show borders"),
1820  N_("If set, the border of each nation is shown on the "
1821  "saved image."),
1822  COC_MAPIMG, true, mapimg_changed_callback),
1823  GEN_BOOL_OPTION(mapimg_layer[MAPIMG_LAYER_CITIES], N_("Show cities"),
1824  N_("If set, cities are shown on the saved image."),
1825  COC_MAPIMG, true, mapimg_changed_callback),
1826  GEN_BOOL_OPTION(mapimg_layer[MAPIMG_LAYER_FOGOFWAR],
1827  N_("Show fog of war"),
1828  N_("If set, the extent of fog of war is shown on the "
1829  "saved image."),
1830  COC_MAPIMG, true, mapimg_changed_callback),
1831  GEN_BOOL_OPTION(
1832  mapimg_layer[MAPIMG_LAYER_TERRAIN], N_("Show full terrain"),
1833  N_("If set, terrain relief is shown with different colors "
1834  "in the saved image; otherwise, only land and water are "
1835  "distinguished."),
1836  COC_MAPIMG, true, mapimg_changed_callback),
1837  GEN_BOOL_OPTION(mapimg_layer[MAPIMG_LAYER_UNITS], N_("Show units"),
1838  N_("If set, units are shown in the saved image."),
1839  COC_MAPIMG, true, mapimg_changed_callback),
1840  GEN_STR_OPTION(
1841  mapimg_filename, N_("Map image file name"),
1842  N_("The base part of the filename for saved map images. "
1843  "A string identifying the game turn and map options will "
1844  "be appended."),
1845  COC_MAPIMG, GUI_DEFAULT_MAPIMG_FILENAME, nullptr, 0),
1846  */
1847 
1848  GEN_BOOL_OPTION(gui_qt_fullscreen, N_("Fullscreen"),
1849  N_("If this option is set the client will use the "
1850  "whole screen area for drawing."),
1851  COC_INTERFACE, true, nullptr),
1853  gui_qt_show_titlebar, N_("Show titlebar"),
1854  N_("If this option is set the client will show a titlebar. "
1855  "If disabled, then no titlebar will be shown, and "
1856  "minimize/maximize/etc buttons will be placed on the "
1857  "menu bar."),
1858  COC_INTERFACE, true, nullptr),
1859  GEN_INT_OPTION(gui_qt_increase_fonts, N_("Change all fonts size"),
1860  N_("Change size of all fonts at once by given percent. "
1861  "This option cannot be saved. Hit the Apply button "
1862  "after changing this."),
1863  COC_FONT, 0, -100, 100, allfont_changed_callback),
1864  GEN_FONT_OPTION(gui_qt_font_default, "default_font",
1865  N_("Default font"), N_("This is default font"),
1868  gui_qt_font_notify_label, "notify_label", N_("Notify Label"),
1869  N_("This font is used to display server reports such "
1870  "as the demographic report or historian publications."),
1873  gui_qt_font_help_label, "help_label", N_("Help Label"),
1874  N_("This font is used to display the help labels in the "
1875  "help window."),
1878  gui_qt_font_help_text, "help_text", N_("Help Text"),
1879  N_("This font is used to display the help body text in "
1880  "the help window."),
1882  GEN_FONT_OPTION(gui_qt_font_chatline, "chatline", N_("Chatline Area"),
1883  N_("This font is used to display the text in the "
1884  "chatline area."),
1886  GEN_FONT_OPTION(gui_qt_font_city_names, "city_names", N_("City Names"),
1887  N_("This font is used to the display the city names "
1888  "on the map."),
1890  GEN_FONT_OPTION(gui_qt_font_city_productions, "city_productions",
1891  N_("City Productions"),
1892  N_("This font is used to display the city production "
1893  "on the map."),
1896  gui_qt_font_reqtree_text, "reqtree_text", N_("Requirement Tree"),
1897  N_("This font is used to the display the requirement tree "
1898  "in the Research report."),
1900  GEN_BOOL_OPTION(gui_qt_show_preview, N_("Show savegame information"),
1901  N_("If this option is set the client will show "
1902  "information and map preview of current savegame."),
1903  COC_GRAPHICS, true, nullptr),
1904  };
1905 }
1906 
1910 static struct client_option *
1912 {
1913  return (poption < &client_options.back() ? poption : nullptr);
1914 }
1915 
1920 {
1921  if (id < 0 || id >= client_options.size()) {
1922  return nullptr;
1923  }
1924  return OPTION(&client_options[id]);
1925 }
1926 
1931 {
1933 }
1934 
1938 static int client_optset_category_number() { return COC_MAX; }
1939 
1943 static const char *client_optset_category_name(int category)
1944 {
1945  switch (category) {
1946  case COC_GRAPHICS:
1947  return _("Graphics");
1948  case COC_OVERVIEW:
1949  // TRANS: Options section for the minimap
1950  return _("Minimap");
1951  case COC_SOUND:
1952  return _("Sound");
1953  case COC_INTERFACE:
1954  return _("Interface");
1955  case COC_MAPIMG:
1956  return _("Map Image");
1957  case COC_NETWORK:
1958  return _("Network");
1959  case COC_FONT:
1960  return _("Font");
1961  case COC_MAX:
1962  break;
1963  }
1964 
1965  qCritical("%s: invalid option category number %d.", __FUNCTION__,
1966  category);
1967  return nullptr;
1968 }
1969 
1973 static int client_option_number(const struct option *poption)
1974 {
1975  return CLIENT_OPTION(poption) - &client_options.front();
1976 }
1977 
1981 static const char *client_option_name(const struct option *poption)
1982 {
1983  return CLIENT_OPTION(poption)->name;
1984 }
1985 
1989 static const char *client_option_description(const struct option *poption)
1990 {
1991  return _(CLIENT_OPTION(poption)->description);
1992 }
1993 
1997 static const char *client_option_help_text(const struct option *poption)
1998 {
1999  return _(CLIENT_OPTION(poption)->help_text);
2000 }
2001 
2005 static int client_option_category(const struct option *poption)
2006 {
2007  return CLIENT_OPTION(poption)->category;
2008 }
2009 
2013 static bool client_option_is_changeable(const struct option *poption)
2014 {
2015  Q_UNUSED(poption)
2016  return true;
2017 }
2018 
2022 static struct option *client_option_next(const struct option *poption)
2023 {
2024  return OPTION(client_option_next_valid(CLIENT_OPTION(poption) + 1));
2025 }
2026 
2030 static bool client_option_bool_get(const struct option *poption)
2031 {
2032  return *(CLIENT_OPTION(poption)->u.boolean.pvalue);
2033 }
2034 
2038 static bool client_option_bool_def(const struct option *poption)
2039 {
2040  return CLIENT_OPTION(poption)->u.boolean.def;
2041 }
2042 
2047 static bool client_option_bool_set(struct option *poption, bool val)
2048 {
2049  struct client_option *pcoption = CLIENT_OPTION(poption);
2050 
2051  if (*pcoption->u.boolean.pvalue == val) {
2052  return false;
2053  }
2054 
2055  *pcoption->u.boolean.pvalue = val;
2056  return true;
2057 }
2058 
2062 static int client_option_int_get(const struct option *poption)
2063 {
2064  return *(CLIENT_OPTION(poption)->u.integer.pvalue);
2065 }
2066 
2070 static int client_option_int_def(const struct option *poption)
2071 {
2072  return CLIENT_OPTION(poption)->u.integer.def;
2073 }
2074 
2078 static int client_option_int_min(const struct option *poption)
2079 {
2080  return CLIENT_OPTION(poption)->u.integer.min;
2081 }
2082 
2086 static int client_option_int_max(const struct option *poption)
2087 {
2088  return CLIENT_OPTION(poption)->u.integer.max;
2089 }
2090 
2095 static bool client_option_int_set(struct option *poption, int val)
2096 {
2097  struct client_option *pcoption = CLIENT_OPTION(poption);
2098 
2099  if (val < pcoption->u.integer.min || val > pcoption->u.integer.max
2100  || *pcoption->u.integer.pvalue == val) {
2101  return false;
2102  }
2103 
2104  *pcoption->u.integer.pvalue = val;
2105  return true;
2106 }
2107 
2111 static const char *client_option_str_get(const struct option *poption)
2112 {
2113  return CLIENT_OPTION(poption)->u.string.pvalue;
2114 }
2115 
2119 static const char *client_option_str_def(const struct option *poption)
2120 {
2121  return CLIENT_OPTION(poption)->u.string.def;
2122 }
2123 
2128 static const QVector<QString> *
2129 client_option_str_values(const struct option *poption)
2130 {
2131  return (CLIENT_OPTION(poption)->u.string.val_accessor
2132  ? CLIENT_OPTION(poption)->u.string.val_accessor(poption)
2133  : nullptr);
2134 }
2135 
2140 static bool client_option_str_set(struct option *poption, const char *str)
2141 {
2142  struct client_option *pcoption = CLIENT_OPTION(poption);
2143 
2144  if (strlen(str) >= pcoption->u.string.size
2145  || 0 == strcmp(pcoption->u.string.pvalue, str)) {
2146  return false;
2147  }
2148 
2149  const auto allowed_values = client_option_str_values(poption);
2150  if (allowed_values && !allowed_values->contains(str)) {
2151  qWarning() << "Unrecognized value for option" << option_name(poption)
2152  << ":" << QString(str);
2153  return false;
2154  }
2155 
2156  fc_strlcpy(pcoption->u.string.pvalue, str, pcoption->u.string.size);
2157  return true;
2158 }
2159 
2166  int val)
2167 {
2168  const QVector<QString> *names =
2169  CLIENT_OPTION(data)->u.enumerator.support_names;
2170 
2171  return (0 <= val && val < names->count() ? qUtf8Printable(names->at(val))
2172  : nullptr);
2173 }
2174 
2181  int val)
2182 {
2183  const QVector<QString> *names =
2184  CLIENT_OPTION(data)->u.bitwise.support_names;
2185 
2186  return (0 <= val && val < names->count() ? qUtf8Printable(names->at(val))
2187  : nullptr);
2188 }
2189 
2193 static QFont client_option_font_get(const struct option *poption)
2194 {
2195  return *CLIENT_OPTION(poption)->u.font.value;
2196 }
2197 
2201 static QFont client_option_font_def(const struct option *poption)
2202 {
2203  return CLIENT_OPTION(poption)->u.font.def;
2204 }
2205 
2209 static void client_option_font_set_def(const struct option *poption,
2210  const QFont &font)
2211 {
2212  CLIENT_OPTION(poption)->u.font.def = font;
2213 }
2214 
2218 static QString client_option_font_target(const struct option *poption)
2219 {
2220  return CLIENT_OPTION(poption)->u.font.target;
2221 }
2222 
2227 static bool client_option_font_set(struct option *poption, const QFont &font)
2228 {
2229  struct client_option *pcoption = CLIENT_OPTION(poption);
2230 
2231  if (*pcoption->u.font.value == font) {
2232  return false;
2233  }
2234 
2235  *pcoption->u.font.value = font;
2236  return true;
2237 }
2238 
2242 static struct ft_color client_option_color_get(const struct option *poption)
2243 {
2244  return *CLIENT_OPTION(poption)->u.color.pvalue;
2245 }
2246 
2250 static struct ft_color client_option_color_def(const struct option *poption)
2251 {
2252  return CLIENT_OPTION(poption)->u.color.def;
2253 }
2254 
2259 static bool client_option_color_set(struct option *poption,
2260  struct ft_color color)
2261 {
2262  struct ft_color *pcolor = CLIENT_OPTION(poption)->u.color.pvalue;
2263  bool changed = false;
2264 
2265 #define color_set(color_tgt, color) \
2266  if (nullptr == color_tgt) { \
2267  if (nullptr != color) { \
2268  color_tgt = fc_strdup(color); \
2269  changed = true; \
2270  } \
2271  } else { \
2272  if (nullptr == color) { \
2273  delete[] color_tgt; \
2274  color_tgt = nullptr; \
2275  changed = true; \
2276  } else if (0 != strcmp(color_tgt, color)) { \
2277  delete[] color_tgt; \
2278  color_tgt = fc_strdup(color); \
2279  changed = true; \
2280  } \
2281  }
2282 
2283  color_set(pcolor->foreground, color.foreground);
2284  color_set(pcolor->background, color.background);
2285 
2286 #undef color_set
2287 
2288  return changed;
2289 }
2290 
2294 static bool client_option_load(struct option *poption,
2295  struct section_file *sf)
2296 {
2297  fc_assert_ret_val(nullptr != poption, false);
2298  fc_assert_ret_val(nullptr != sf, false);
2299 
2300  switch (option_type(poption)) {
2301  case OT_BOOLEAN: {
2302  bool value;
2303 
2304  return (
2305  secfile_lookup_bool(sf, &value, "client.%s", option_name(poption))
2306  && option_bool_set(poption, value));
2307  }
2308  case OT_INTEGER: {
2309  int value;
2310 
2311  return (secfile_lookup_int(sf, &value, "client.%s", option_name(poption))
2312  && option_int_set(poption, value));
2313  }
2314  case OT_STRING: {
2315  const char *string;
2316 
2317  return (
2318  (string = secfile_lookup_str(sf, "client.%s", option_name(poption)))
2319  && option_str_set(poption, string));
2320  }
2321  case OT_ENUM: {
2322  int value;
2323 
2324  return (secfile_lookup_enum_data(sf, &value, false,
2326  "client.%s", option_name(poption))
2327  && option_enum_set_int(poption, value));
2328  }
2329  case OT_BITWISE: {
2330  int value;
2331 
2332  return (secfile_lookup_enum_data(
2333  sf, &value, true, client_option_bitwise_secfile_str, poption,
2334  "client.%s", option_name(poption))
2335  && option_bitwise_set(poption, value));
2336  }
2337  case OT_FONT: {
2338  const char *string =
2339  secfile_lookup_str(sf, "client.%s", option_name(poption));
2340  if (!string) {
2341  return false;
2342  }
2343 
2344  QFont font;
2345  return font.fromString(string) && option_font_set(poption, font);
2346  }
2347  case OT_COLOR: {
2348  struct ft_color color;
2349 
2350  return ((color.foreground = secfile_lookup_str(
2351  sf, "client.%s.foreground", option_name(poption)))
2352  && (color.background = secfile_lookup_str(
2353  sf, "client.%s.background", option_name(poption)))
2354  && option_color_set(poption, color));
2355  }
2356  }
2357  return false;
2358 }
2359 
2363 static void client_option_save(struct option *poption,
2364  struct section_file *sf)
2365 {
2366  fc_assert_ret(nullptr != poption);
2367  fc_assert_ret(nullptr != sf);
2368 
2369  switch (option_type(poption)) {
2370  case OT_BOOLEAN:
2371  secfile_insert_bool(sf, option_bool_get(poption), "client.%s",
2372  option_name(poption));
2373  break;
2374  case OT_INTEGER:
2375  secfile_insert_int(sf, option_int_get(poption), "client.%s",
2376  option_name(poption));
2377  break;
2378  case OT_STRING:
2379  secfile_insert_str(sf, option_str_get(poption), "client.%s",
2380  option_name(poption));
2381  break;
2382  case OT_ENUM:
2383  secfile_insert_enum_data(sf, option_enum_get_int(poption), false,
2385  "client.%s", option_name(poption));
2386  break;
2387  case OT_BITWISE:
2388  secfile_insert_enum_data(sf, option_bitwise_get(poption), true,
2390  "client.%s", option_name(poption));
2391  break;
2392  case OT_FONT:
2393  secfile_insert_str(sf,
2394  qUtf8Printable(option_font_get(poption).toString()),
2395  "client.%s", option_name(poption));
2396  break;
2397  case OT_COLOR: {
2398  struct ft_color color = option_color_get(poption);
2399 
2400  secfile_insert_str(sf, color.foreground, "client.%s.foreground",
2401  option_name(poption));
2402  secfile_insert_str(sf, color.background, "client.%s.background",
2403  option_name(poption));
2404  } break;
2405  }
2406 }
2407 
2411 static char **server_options_categories = nullptr;
2412 static struct server_option *server_options = nullptr;
2413 
2415 static int server_options_num = 0;
2416 
2420 static struct option *server_optset_option_by_number(int id);
2421 static struct option *server_optset_option_first();
2422 static int server_optset_category_number();
2423 static const char *server_optset_category_name(int category);
2424 
2425 static struct option_set server_optset_static = {
2427  .option_first = server_optset_option_first,
2428  .category_number = server_optset_category_number,
2429  .category_name = server_optset_category_name};
2431 
2435 static int server_option_number(const struct option *poption);
2436 static const char *server_option_name(const struct option *poption);
2437 static const char *server_option_description(const struct option *poption);
2438 static const char *server_option_help_text(const struct option *poption);
2439 static int server_option_category(const struct option *poption);
2440 static bool server_option_is_changeable(const struct option *poption);
2441 static struct option *server_option_next(const struct option *poption);
2442 
2443 static const struct option_common_vtable server_option_common_vtable = {
2445  .name = server_option_name,
2446  .description = server_option_description,
2447  .help_text = server_option_help_text,
2448  .category = server_option_category,
2449  .is_changeable = server_option_is_changeable,
2450  .next = server_option_next};
2451 
2452 static bool server_option_bool_get(const struct option *poption);
2453 static bool server_option_bool_def(const struct option *poption);
2454 static bool server_option_bool_set(struct option *poption, bool val);
2455 
2456 static const struct option_bool_vtable server_option_bool_vtable = {
2458  .def = server_option_bool_def,
2459  .set = server_option_bool_set};
2460 
2461 static int server_option_int_get(const struct option *poption);
2462 static int server_option_int_def(const struct option *poption);
2463 static int server_option_int_min(const struct option *poption);
2464 static int server_option_int_max(const struct option *poption);
2465 static bool server_option_int_set(struct option *poption, int val);
2466 
2467 static const struct option_int_vtable server_option_int_vtable = {
2469  .def = server_option_int_def,
2470  .minimum = server_option_int_min,
2471  .maximum = server_option_int_max,
2472  .set = server_option_int_set};
2473 
2474 static const char *server_option_str_get(const struct option *poption);
2475 static const char *server_option_str_def(const struct option *poption);
2476 static const QVector<QString> *
2477 server_option_str_values(const struct option *poption);
2478 static bool server_option_str_set(struct option *poption, const char *str);
2479 
2480 static const struct option_str_vtable server_option_str_vtable = {
2482  .def = server_option_str_def,
2483  .values = server_option_str_values,
2484  .set = server_option_str_set};
2485 
2486 static int server_option_enum_get(const struct option *poption);
2487 static int server_option_enum_def(const struct option *poption);
2488 static const QVector<QString> *
2489 server_option_enum_pretty(const struct option *poption);
2490 static bool server_option_enum_set(struct option *poption, int val);
2491 
2492 static const struct option_enum_vtable server_option_enum_vtable = {
2494  .def = server_option_enum_def,
2495  .values = server_option_enum_pretty,
2496  .set = server_option_enum_set,
2497  .cmp = strcmp};
2498 
2499 static unsigned server_option_bitwise_get(const struct option *poption);
2500 static unsigned server_option_bitwise_def(const struct option *poption);
2501 static const QVector<QString> *
2502 server_option_bitwise_pretty(const struct option *poption);
2503 static bool server_option_bitwise_set(struct option *poption, unsigned val);
2504 
2508  .values = server_option_bitwise_pretty,
2509  .set = server_option_bitwise_set};
2510 
2515  struct option base_option; // Base structure, must be the first!
2516 
2517  char *name; // Short name - used as an identifier
2518  char *description; // One-line description
2519  char *help_text; // Paragraph-length help text
2520  unsigned char category;
2525 
2526  union {
2527  // OT_BOOLEAN type option.
2528  struct {
2529  bool value;
2530  bool def;
2532  // OT_INTEGER type option.
2533  struct {
2534  int value;
2535  int def, min, max;
2537  // OT_STRING type option.
2538  struct {
2539  char *value;
2540  char *def;
2542  // OT_ENUM type option.
2543  struct {
2544  int value;
2545  int def;
2547  QVector<QString> *pretty_names; // untranslated
2549  // OT_BITWISE type option.
2550  struct {
2551  unsigned value;
2552  unsigned def;
2554  QVector<QString> *pretty_names; // untranslated
2556  };
2557 };
2558 
2559 #define SERVER_OPTION(poption) ((struct server_option *) (poption))
2560 
2561 static void desired_settable_option_send(struct option *poption);
2562 
2567 {
2569  fc_assert(nullptr == server_options);
2572 }
2573 
2577 static void server_option_free(struct server_option *poption)
2578 {
2579  switch (poption->base_option.type) {
2580  case OT_STRING:
2581  delete[] poption->string.value;
2582  delete[] poption->string.def;
2583  poption->string.value = nullptr;
2584  poption->string.def = nullptr;
2585  break;
2586 
2587  case OT_ENUM:
2588  delete poption->enumerator.support_names;
2589  delete poption->enumerator.pretty_names;
2590  poption->enumerator.support_names = nullptr;
2591  poption->enumerator.pretty_names = nullptr;
2592  break;
2593 
2594  case OT_BITWISE:
2595  delete poption->bitwise.support_names;
2596  delete poption->bitwise.pretty_names;
2597  poption->bitwise.support_names = nullptr;
2598  poption->bitwise.pretty_names = nullptr;
2599  break;
2600 
2601  case OT_BOOLEAN:
2602  case OT_INTEGER:
2603  case OT_FONT:
2604  case OT_COLOR:
2605  break;
2606  }
2607 
2608  delete[] poption->name;
2609  delete[] poption->description;
2610  delete[] poption->help_text;
2611  poption->name = nullptr;
2612  poption->description = nullptr;
2613  poption->help_text = nullptr;
2614 }
2615 
2620 {
2621  int i;
2622 
2623  // Don't keep this dialog open.
2625 
2626  // Free the options themselves.
2627  if (nullptr != server_options) {
2628  for (i = 0; i < server_options_num; i++) {
2630  }
2631  delete[] server_options;
2632  server_options = nullptr;
2633  server_options_num = 0;
2634  }
2635 
2636  // Free the categories.
2637  if (nullptr != server_options_categories) {
2638  for (i = 0; i < server_options_categories_num; i++) {
2639  if (nullptr != server_options_categories[i]) {
2640  delete[] server_options_categories[i];
2641  server_options_categories[i] = nullptr;
2642  }
2643  }
2644  delete[] server_options_categories;
2645  server_options_categories = nullptr;
2647  }
2648 }
2649 
2654  const struct packet_server_setting_control *packet)
2655 {
2656  int i;
2657 
2658  // This packet should be received only once.
2660  fc_assert_ret(nullptr == server_options);
2663 
2664  // Allocate server option categories.
2665  if (0 < packet->categories_num) {
2666  server_options_categories_num = packet->categories_num;
2668 
2669  for (i = 0; i < server_options_categories_num; i++) {
2670  // NB: Translate now.
2671  server_options_categories[i] = fc_strdup(_(packet->category_names[i]));
2672  }
2673  }
2674 
2675  // Allocate server options.
2676  if (0 < packet->settings_num) {
2677  server_options_num = packet->settings_num;
2679  }
2680 }
2681 
2686  const struct packet_server_setting_const *packet)
2687 {
2688  struct option *poption = server_optset_option_by_number(packet->id);
2689  struct server_option *psoption = SERVER_OPTION(poption);
2690 
2691  fc_assert_ret(nullptr != poption);
2692 
2693  fc_assert(nullptr == psoption->name);
2694  psoption->name = fc_strdup(packet->name);
2695  fc_assert(nullptr == psoption->description);
2696  // NB: Translate now.
2697  psoption->description = fc_strdup(_(packet->short_help));
2698  fc_assert(nullptr == psoption->help_text);
2699  // NB: Translate now.
2700  psoption->help_text = fc_strdup(_(packet->extra_help));
2701  psoption->category = packet->category;
2702 }
2703 
2707 #define handle_server_setting_common(psoption, packet) \
2708  psoption->is_changeable = packet->is_changeable; \
2709  psoption->setdef = packet->setdef; \
2710  psoption->is_visible = packet->is_visible; \
2711  \
2712  if (!psoption->desired_sent && psoption->is_visible \
2713  && psoption->is_changeable && is_server_running() \
2714  && packet->initial_setting) { \
2715  /* Only send our private settings if we are running \
2716  * on a forked local server, i.e. started by the \
2717  * client with the "Start New Game" button. \
2718  * Do now override settings that are already saved to savegame \
2719  * and now loaded. */ \
2720  desired_settable_option_send(OPTION(poption)); \
2721  psoption->desired_sent = true; \
2722  } \
2723  \
2724  /* Update the GUI. */ \
2725  option_gui_update(poption);
2731  const struct packet_server_setting_bool *packet)
2732 {
2733  struct option *poption = server_optset_option_by_number(packet->id);
2734  struct server_option *psoption = SERVER_OPTION(poption);
2735 
2736  fc_assert_ret(nullptr != poption);
2737 
2738  if (nullptr == poption->common_vtable) {
2739  // Not initialized yet.
2740  poption->poptset = server_optset;
2742  poption->type = OT_BOOLEAN;
2744  }
2745  fc_assert_ret_msg(OT_BOOLEAN == poption->type,
2746  "Server setting \"%s\" (nb %d) has type %s (%d), "
2747  "expected %s (%d)",
2748  option_name(poption), option_number(poption),
2749  option_type_name(poption->type), poption->type,
2750  option_type_name(OT_BOOLEAN), OT_BOOLEAN);
2751 
2752  if (packet->is_visible) {
2753  psoption->boolean.value = packet->val;
2754  psoption->boolean.def = packet->default_val;
2755  }
2756 
2757  handle_server_setting_common(psoption, packet);
2758 }
2764  const struct packet_server_setting_int *packet)
2765 {
2766  struct option *poption = server_optset_option_by_number(packet->id);
2767  struct server_option *psoption = SERVER_OPTION(poption);
2768 
2769  fc_assert_ret(nullptr != poption);
2770 
2771  if (nullptr == poption->common_vtable) {
2772  // Not initialized yet.
2773  poption->poptset = server_optset;
2775  poption->type = OT_INTEGER;
2777  }
2778  fc_assert_ret_msg(OT_INTEGER == poption->type,
2779  "Server setting \"%s\" (nb %d) has type %s (%d), "
2780  "expected %s (%d)",
2781  option_name(poption), option_number(poption),
2782  option_type_name(poption->type), poption->type,
2783  option_type_name(OT_INTEGER), OT_INTEGER);
2784 
2785  if (packet->is_visible) {
2786  psoption->integer.value = packet->val;
2787  psoption->integer.def = packet->default_val;
2788  psoption->integer.min = packet->min_val;
2789  psoption->integer.max = packet->max_val;
2790  }
2791 
2792  handle_server_setting_common(psoption, packet);
2793 }
2799  const struct packet_server_setting_str *packet)
2800 {
2801  struct option *poption = server_optset_option_by_number(packet->id);
2802  struct server_option *psoption = SERVER_OPTION(poption);
2803 
2804  fc_assert_ret(nullptr != poption);
2805 
2806  if (nullptr == poption->common_vtable) {
2807  // Not initialized yet.
2808  poption->poptset = server_optset;
2810  poption->type = OT_STRING;
2812  }
2813  fc_assert_ret_msg(OT_STRING == poption->type,
2814  "Server setting \"%s\" (nb %d) has type %s (%d), "
2815  "expected %s (%d)",
2816  option_name(poption), option_number(poption),
2817  option_type_name(poption->type), poption->type,
2818  option_type_name(OT_STRING), OT_STRING);
2819 
2820  if (packet->is_visible) {
2821  if (nullptr == psoption->string.value) {
2822  psoption->string.value = fc_strdup(packet->val);
2823  } else if (0 != strcmp(packet->val, psoption->string.value)) {
2824  delete[] psoption->string.value;
2825  psoption->string.value = fc_strdup(packet->val);
2826  }
2827  if (nullptr == psoption->string.def) {
2828  psoption->string.def = fc_strdup(packet->default_val);
2829  } else if (0 != strcmp(packet->default_val, psoption->string.def)) {
2830  delete[] psoption->string.def;
2831  psoption->string.def = fc_strdup(packet->default_val);
2832  }
2833  }
2834 
2835  handle_server_setting_common(psoption, packet);
2836 }
2842  const struct packet_server_setting_enum *packet)
2843 {
2844  struct option *poption = server_optset_option_by_number(packet->id);
2845  struct server_option *psoption = SERVER_OPTION(poption);
2846 
2847  fc_assert_ret(nullptr != poption);
2848 
2849  if (nullptr == poption->common_vtable) {
2850  // Not initialized yet.
2851  poption->poptset = server_optset;
2853  poption->type = OT_ENUM;
2855  }
2856  fc_assert_ret_msg(OT_ENUM == poption->type,
2857  "Server setting \"%s\" (nb %d) has type %s (%d), "
2858  "expected %s (%d)",
2859  option_name(poption), option_number(poption),
2860  option_type_name(poption->type), poption->type,
2861  option_type_name(OT_ENUM), OT_ENUM);
2862 
2863  if (packet->is_visible) {
2864  int i;
2865 
2866  psoption->enumerator.value = packet->val;
2867  psoption->enumerator.def = packet->default_val;
2868 
2869  if (nullptr == psoption->enumerator.support_names) {
2870  // First time we get this packet.
2871  fc_assert(nullptr == psoption->enumerator.pretty_names);
2872  psoption->enumerator.support_names = new QVector<QString>;
2873  psoption->enumerator.support_names->resize(packet->values_num);
2874  psoption->enumerator.pretty_names = new QVector<QString>;
2875  psoption->enumerator.pretty_names->resize(packet->values_num);
2876  for (i = 0; i < packet->values_num; i++) {
2877  psoption->enumerator.support_names->replace(
2878  i, packet->support_names[i]);
2879  // Store untranslated string from server.
2880  psoption->enumerator.pretty_names->replace(i,
2881  packet->pretty_names[i]);
2882  }
2883  } else if (psoption->enumerator.support_names->count()
2884  != packet->values_num) {
2885  fc_assert(psoption->enumerator.support_names->count()
2886  == psoption->enumerator.pretty_names->count());
2887  /* The number of values have changed, we need to reset the list
2888  * of possible values. */
2889  psoption->enumerator.support_names->resize(packet->values_num);
2890  psoption->enumerator.pretty_names->resize(packet->values_num);
2891  for (i = 0; i < packet->values_num; i++) {
2892  psoption->enumerator.support_names->replace(
2893  i, packet->support_names[i]);
2894  // Store untranslated string from server.
2895  psoption->enumerator.pretty_names->replace(i,
2896  packet->pretty_names[i]);
2897  }
2898  } else {
2899  /* Check if a value changed, then we need to reset the list
2900  * of possible values. */
2901  QString str;
2902 
2903  for (i = 0; i < packet->values_num; i++) {
2904  str = psoption->enumerator.pretty_names->at(i);
2905  if (str.isEmpty() || (str == packet->pretty_names[i])) {
2906  // Store untranslated string from server.
2907  psoption->enumerator.pretty_names->replace(
2908  i, packet->pretty_names[i]);
2909  }
2910  /* Support names are not visible, we don't need to check if it
2911  * has changed. */
2912  psoption->enumerator.support_names->replace(
2913  i, packet->support_names[i]);
2914  }
2915  }
2916  }
2917 
2918  handle_server_setting_common(psoption, packet);
2919 }
2925  const struct packet_server_setting_bitwise *packet)
2926 {
2927  struct option *poption = server_optset_option_by_number(packet->id);
2928  struct server_option *psoption = SERVER_OPTION(poption);
2929 
2930  fc_assert_ret(nullptr != poption);
2931 
2932  if (nullptr == poption->common_vtable) {
2933  // Not initialized yet.
2934  poption->poptset = server_optset;
2936  poption->type = OT_BITWISE;
2938  }
2939  fc_assert_ret_msg(OT_BITWISE == poption->type,
2940  "Server setting \"%s\" (nb %d) has type %s (%d), "
2941  "expected %s (%d)",
2942  option_name(poption), option_number(poption),
2943  option_type_name(poption->type), poption->type,
2944  option_type_name(OT_BITWISE), OT_BITWISE);
2945 
2946  if (packet->is_visible) {
2947  int i;
2948 
2949  psoption->bitwise.value = packet->val;
2950  psoption->bitwise.def = packet->default_val;
2951 
2952  if (nullptr == psoption->bitwise.support_names) {
2953  // First time we get this packet.
2954  fc_assert(nullptr == psoption->bitwise.pretty_names);
2955  psoption->bitwise.support_names = new QVector<QString>;
2956  psoption->bitwise.support_names->resize(packet->bits_num);
2957  psoption->bitwise.pretty_names = new QVector<QString>;
2958  psoption->bitwise.pretty_names->resize(packet->bits_num);
2959  for (i = 0; i < packet->bits_num; i++) {
2960  psoption->bitwise.support_names->replace(i,
2961  packet->support_names[i]);
2962  // Store untranslated string from server.
2963  psoption->bitwise.pretty_names->replace(i, packet->pretty_names[i]);
2964  }
2965  } else if (psoption->bitwise.support_names->count()
2966  != packet->bits_num) {
2967  fc_assert(psoption->bitwise.support_names->count()
2968  == psoption->bitwise.pretty_names->count());
2969  /* The number of values have changed, we need to reset the list
2970  * of possible values. */
2971  psoption->bitwise.support_names->resize(packet->bits_num);
2972  psoption->bitwise.pretty_names->resize(packet->bits_num);
2973  for (i = 0; i < packet->bits_num; i++) {
2974  psoption->bitwise.support_names->replace(i,
2975  packet->support_names[i]);
2976  // Store untranslated string from server.
2977  psoption->bitwise.pretty_names->replace(i, packet->pretty_names[i]);
2978  }
2979  } else {
2980  /* Check if a value changed, then we need to reset the list
2981  * of possible values. */
2982  QString str;
2983 
2984  for (i = 0; i < packet->bits_num; i++) {
2985  str = psoption->bitwise.pretty_names->at(i);
2986  if (str.isEmpty() || (str != packet->pretty_names[i])) {
2987  // Store untranslated string from server.
2988  psoption->bitwise.pretty_names->replace(i,
2989  packet->pretty_names[i]);
2990  }
2991  /* Support names are not visible, we don't need to check if it
2992  * has changed. */
2993  psoption->bitwise.support_names->replace(i,
2994  packet->support_names[i]);
2995  }
2996  }
2997  }
2998 
2999  handle_server_setting_common(psoption, packet);
3000 }
3001 
3005 static struct server_option *
3006 server_option_next_valid(struct server_option *poption)
3007 {
3008  const struct server_option *const max =
3010 
3011  while (nullptr != poption && poption < max && !poption->is_visible) {
3012  poption++;
3013  }
3014 
3015  return (poption < max ? poption : nullptr);
3016 }
3021 struct option *server_optset_option_by_number(int id)
3022 {
3023  if (0 > id || id > server_options_num) {
3024  return nullptr;
3025  }
3026  return OPTION(server_options + id);
3027 }
3033 {
3035 }
3045 const char *server_optset_category_name(int category)
3046 {
3047  if (0 > category || category >= server_options_categories_num) {
3048  return nullptr;
3049  }
3050 
3051  return server_options_categories[category];
3052 }
3057 static int server_option_number(const struct option *poption)
3058 {
3059  return SERVER_OPTION(poption) - server_options;
3060 }
3065 static const char *server_option_name(const struct option *poption)
3066 {
3067  return SERVER_OPTION(poption)->name;
3068 }
3073 static const char *server_option_description(const struct option *poption)
3074 {
3075  return SERVER_OPTION(poption)->description;
3076 }
3081 static const char *server_option_help_text(const struct option *poption)
3082 {
3083  return SERVER_OPTION(poption)->help_text;
3084 }
3089 static int server_option_category(const struct option *poption)
3090 {
3091  return SERVER_OPTION(poption)->category;
3092 }
3097 static bool server_option_is_changeable(const struct option *poption)
3098 {
3099  return SERVER_OPTION(poption)->is_changeable;
3100 }
3105 static struct option *server_option_next(const struct option *poption)
3106 {
3107  return OPTION(server_option_next_valid(SERVER_OPTION(poption) + 1));
3108 }
3113 static bool server_option_bool_get(const struct option *poption)
3114 {
3115  return SERVER_OPTION(poption)->boolean.value;
3116 }
3121 static bool server_option_bool_def(const struct option *poption)
3122 {
3123  return SERVER_OPTION(poption)->boolean.def;
3124 }
3125 
3130 static bool server_option_bool_set(struct option *poption, bool val)
3131 {
3132  struct server_option *psoption = SERVER_OPTION(poption);
3133 
3134  if (psoption->boolean.value == val) {
3135  return false;
3136  }
3137 
3138  send_chat_printf("/set %s %s", psoption->name,
3139  val ? "enabled" : "disabled");
3140  return true;
3141 }
3146 static int server_option_int_get(const struct option *poption)
3147 {
3148  return SERVER_OPTION(poption)->integer.value;
3149 }
3154 static int server_option_int_def(const struct option *poption)
3155 {
3156  return SERVER_OPTION(poption)->integer.def;
3157 }
3162 static int server_option_int_min(const struct option *poption)
3163 {
3164  return SERVER_OPTION(poption)->integer.min;
3165 }
3170 static int server_option_int_max(const struct option *poption)
3171 {
3172  return SERVER_OPTION(poption)->integer.max;
3173 }
3174 
3179 static bool server_option_int_set(struct option *poption, int val)
3180 {
3181  struct server_option *psoption = SERVER_OPTION(poption);
3182 
3183  if (val < psoption->integer.min || val > psoption->integer.max
3184  || psoption->integer.value == val) {
3185  return false;
3186  }
3187 
3188  send_chat_printf("/set %s %d", psoption->name, val);
3189  return true;
3190 }
3195 static const char *server_option_str_get(const struct option *poption)
3196 {
3197  return SERVER_OPTION(poption)->string.value;
3198 }
3203 static const char *server_option_str_def(const struct option *poption)
3204 {
3205  return SERVER_OPTION(poption)->string.def;
3206 }
3207 
3212 static const QVector<QString> *
3213 server_option_str_values(const struct option *poption)
3214 {
3215  Q_UNUSED(poption)
3216  return nullptr;
3217 }
3218 
3223 static bool server_option_str_set(struct option *poption, const char *str)
3224 {
3225  struct server_option *psoption = SERVER_OPTION(poption);
3226 
3227  if (0 == strcmp(psoption->string.value, str)) {
3228  return false;
3229  }
3230 
3231  send_chat_printf("/set %s \"%s\"", psoption->name, str);
3232  return true;
3233 }
3238 static int server_option_enum_get(const struct option *poption)
3239 {
3240  return SERVER_OPTION(poption)->enumerator.value;
3241 }
3246 static int server_option_enum_def(const struct option *poption)
3247 {
3248  return SERVER_OPTION(poption)->enumerator.def;
3249 }
3250 
3255 static const QVector<QString> *
3256 server_option_enum_pretty(const struct option *poption)
3257 {
3258  return SERVER_OPTION(poption)->enumerator.pretty_names;
3259 }
3260 
3265 static bool server_option_enum_set(struct option *poption, int val)
3266 {
3267  struct server_option *psoption = SERVER_OPTION(poption);
3268 
3269  if (val == psoption->enumerator.value
3270  || val >= psoption->enumerator.support_names->size()) {
3271  return false;
3272  }
3273 
3275  "/set %s \"%s\"", psoption->name,
3276  qUtf8Printable(psoption->enumerator.support_names->at(val)));
3277  return true;
3278 }
3279 
3284 static void server_option_enum_support_name(const struct option *poption,
3285  QString *pvalue,
3286  QString *pdefault)
3287 {
3288  const struct server_option *psoption = SERVER_OPTION(poption);
3289  const QVector<QString> *values = psoption->enumerator.support_names;
3290 
3291  if (nullptr != pvalue) {
3292  *pvalue = values->at(psoption->enumerator.value);
3293  }
3294  if (nullptr != pdefault) {
3295  *pdefault = values->at(psoption->enumerator.def);
3296  }
3297 }
3302 static unsigned server_option_bitwise_get(const struct option *poption)
3303 {
3304  return SERVER_OPTION(poption)->bitwise.value;
3305 }
3310 static unsigned server_option_bitwise_def(const struct option *poption)
3311 {
3312  return SERVER_OPTION(poption)->bitwise.def;
3313 }
3314 
3319 static const QVector<QString> *
3320 server_option_bitwise_pretty(const struct option *poption)
3321 {
3322  return SERVER_OPTION(poption)->bitwise.pretty_names;
3323 }
3324 
3328 static void
3330  unsigned val, char *buf, size_t buf_len)
3331 {
3332  int bit;
3333 
3334  buf[0] = '\0';
3335  for (bit = 0; bit < values->count(); bit++) {
3336  if ((1 << bit) & val) {
3337  if ('\0' != buf[0]) {
3338  fc_strlcat(buf, "|", buf_len);
3339  }
3340  fc_strlcat(buf, qUtf8Printable(values->at(bit)), buf_len);
3341  }
3342  }
3343 }
3344 
3349 static bool server_option_bitwise_set(struct option *poption, unsigned val)
3350 {
3351  struct server_option *psoption = SERVER_OPTION(poption);
3352  char name[MAX_LEN_MSG];
3353 
3354  if (val == psoption->bitwise.value) {
3355  return false;
3356  }
3357 
3358  server_option_bitwise_support_base(psoption->bitwise.support_names, val,
3359  name, sizeof(name));
3360  send_chat_printf("/set %s \"%s\"", psoption->name, name);
3361  return true;
3362 }
3363 
3368 static void server_option_bitwise_support_name(const struct option *poption,
3369  char *val_buf, size_t val_len,
3370  char *def_buf, size_t def_len)
3371 {
3372  const struct server_option *psoption = SERVER_OPTION(poption);
3373  const QVector<QString> *values = psoption->bitwise.support_names;
3374 
3375  if (nullptr != val_buf && 0 < val_len) {
3376  server_option_bitwise_support_base(values, psoption->bitwise.value,
3377  val_buf, val_len);
3378  }
3379  if (nullptr != def_buf && 0 < def_len) {
3380  server_option_bitwise_support_base(values, psoption->bitwise.def,
3381  def_buf, def_len);
3382  }
3384 
3387 int messages_where[E_COUNT];
3388 
3393 static void message_options_init()
3394 {
3395  int none[] = {E_IMP_BUY,
3396  E_IMP_SOLD,
3397  E_UNIT_BUY,
3398  E_GAME_START,
3399  E_CITY_BUILD,
3400  E_NEXT_YEAR,
3401  E_CITY_PRODUCTION_CHANGED,
3402  E_CITY_MAY_SOON_GROW,
3403  E_WORKLIST,
3404  E_AI_DEBUG};
3405  int out_only[] = {
3406  E_NATION_SELECTED, E_CHAT_MSG, E_CHAT_ERROR, E_CONNECTION,
3407  E_LOG_ERROR, E_SETTING, E_VOTE_NEW, E_VOTE_RESOLVED,
3408  E_VOTE_ABORTED, E_UNIT_LOST_ATT, E_UNIT_WIN_ATT,
3409  };
3410  int all[] = {E_LOG_FATAL, E_SCRIPT, E_DEPRECATION_WARNING, E_MESSAGE_WALL};
3411  int i;
3412 
3413  for (i = 0; i <= event_type_max(); i++) {
3414  // Include possible undefined values.
3416  }
3417  for (i = 0; i < ARRAY_SIZE(none); i++) {
3418  messages_where[none[i]] = 0;
3419  }
3420  for (i = 0; i < ARRAY_SIZE(out_only); i++) {
3421  messages_where[out_only[i]] = MW_OUTPUT;
3422  }
3423  for (i = 0; i < ARRAY_SIZE(all); i++) {
3424  messages_where[all[i]] = MW_MESSAGES | MW_POPUP;
3425  }
3426 
3427  events_init();
3428 }
3433 static void message_options_free() { events_free(); }
3434 
3439 static void message_options_load(struct section_file *file,
3440  const char *prefix)
3441 {
3442  enum event_type event;
3443  int i, num_events;
3444  const char *p;
3445 
3446  if (!secfile_lookup_int(file, &num_events, "messages.count")) {
3447  // version < 2.2
3448  // Order of the events in 2.1.
3449  const enum event_type old_events[] = {E_CITY_CANTBUILD,
3450  E_CITY_LOST,
3451  E_CITY_LOVE,
3452  E_CITY_DISORDER,
3453  E_CITY_FAMINE,
3454  E_CITY_FAMINE_FEARED,
3455  E_CITY_GROWTH,
3456  E_CITY_MAY_SOON_GROW,
3457  E_CITY_IMPROVEMENT,
3458  E_CITY_IMPROVEMENT_BLDG,
3459  E_CITY_NORMAL,
3460  E_CITY_NUKED,
3461  E_CITY_CMA_RELEASE,
3462  E_CITY_GRAN_THROTTLE,
3463  E_CITY_TRANSFER,
3464  E_CITY_BUILD,
3465  E_CITY_PRODUCTION_CHANGED,
3466  E_WORKLIST,
3467  E_UPRISING,
3468  E_CIVIL_WAR,
3469  E_ANARCHY,
3470  E_FIRST_CONTACT,
3471  E_NEW_GOVERNMENT,
3472  E_LOW_ON_FUNDS,
3473  E_POLLUTION,
3474  E_REVOLT_DONE,
3475  E_REVOLT_START,
3476  E_SPACESHIP,
3477  E_MY_DIPLOMAT_BRIBE,
3478  E_DIPLOMATIC_INCIDENT,
3479  E_MY_DIPLOMAT_ESCAPE,
3480  E_MY_DIPLOMAT_EMBASSY,
3481  E_MY_DIPLOMAT_FAILED,
3482  E_MY_DIPLOMAT_INCITE,
3483  E_MY_DIPLOMAT_POISON,
3484  E_MY_DIPLOMAT_SABOTAGE,
3485  E_MY_DIPLOMAT_THEFT,
3486  E_ENEMY_DIPLOMAT_BRIBE,
3487  E_ENEMY_DIPLOMAT_EMBASSY,
3488  E_ENEMY_DIPLOMAT_FAILED,
3489  E_ENEMY_DIPLOMAT_INCITE,
3490  E_ENEMY_DIPLOMAT_POISON,
3491  E_ENEMY_DIPLOMAT_SABOTAGE,
3492  E_ENEMY_DIPLOMAT_THEFT,
3493  E_CARAVAN_ACTION,
3494  E_SCRIPT,
3495  E_BROADCAST_REPORT,
3496  E_GAME_END,
3497  E_GAME_START,
3498  E_NATION_SELECTED,
3499  E_DESTROYED,
3500  E_REPORT,
3501  E_TURN_BELL,
3502  E_NEXT_YEAR,
3503  E_GLOBAL_ECO,
3504  E_NUKE,
3505  E_HUT_BARB,
3506  E_HUT_CITY,
3507  E_HUT_GOLD,
3508  E_HUT_BARB_KILLED,
3509  E_HUT_MERC,
3510  E_HUT_SETTLER,
3511  E_HUT_TECH,
3512  E_HUT_BARB_CITY_NEAR,
3513  E_IMP_BUY,
3514  E_IMP_BUILD,
3515  E_IMP_AUCTIONED,
3516  E_IMP_AUTO,
3517  E_IMP_SOLD,
3518  E_TECH_GAIN,
3519  E_TECH_LEARNED,
3520  E_TREATY_ALLIANCE,
3521  E_TREATY_BROKEN,
3522  E_TREATY_CEASEFIRE,
3523  E_TREATY_PEACE,
3524  E_TREATY_SHARED_VISION,
3525  E_UNIT_LOST_ATT,
3526  E_UNIT_WIN_ATT,
3527  E_UNIT_BUY,
3528  E_UNIT_BUILT,
3529  E_UNIT_LOST_DEF,
3530  E_UNIT_WIN_DEF,
3531  E_UNIT_BECAME_VET,
3532  E_UNIT_UPGRADED,
3533  E_UNIT_RELOCATED,
3534  E_UNIT_ORDERS,
3535  E_UNIT_WAKE,
3536  E_WONDER_BUILD,
3537  E_WONDER_OBSOLETE,
3538  E_WONDER_STARTED,
3539  E_WONDER_STOPPED,
3540  E_WONDER_WILL_BE_BUILT,
3541  E_DIPLOMACY,
3542  E_TREATY_EMBASSY,
3543  E_BAD_COMMAND,
3544  E_SETTING,
3545  E_CHAT_MSG,
3546  E_MESSAGE_WALL,
3547  E_CHAT_ERROR,
3548  E_CONNECTION,
3549  E_AI_DEBUG};
3550  const size_t old_events_num = ARRAY_SIZE(old_events);
3551 
3552  for (i = 0; i < old_events_num; i++) {
3553  messages_where[old_events[i]] =
3554  secfile_lookup_int_default(file, messages_where[old_events[i]],
3555  "%s.message_where_%02d", prefix, i);
3556  }
3557  return;
3558  }
3559 
3560  for (i = 0; i < num_events; i++) {
3561  p = secfile_lookup_str(file, "messages.event%d.name", i);
3562  if (nullptr == p) {
3563  qCritical("Corruption in file %s: %s", secfile_name(file),
3564  secfile_error());
3565  continue;
3566  }
3567  // Compatibility: Before 3.0 E_UNIT_WIN_DEF was called E_UNIT_WIN.
3568  if (!fc_strcasecmp("E_UNIT_WIN", p)) {
3569  qCWarning(deprecations_category,
3570  _("Deprecated event type E_UNIT_WIN in client options."));
3571  p = "E_UNIT_WIN_DEF";
3572  }
3573  // Compatibility: Before 3.1 E_CITY_IMPROVEMENT was called
3574  // E_CITY_AQUEDUCT
3575  if (!fc_strcasecmp("E_CITY_AQUEDUCT", p)) {
3576  qCWarning(
3577  deprecations_category,
3578  _("Deprecated event type E_CITY_AQUEDUCT in client options."));
3579  p = "E_CITY_IMPROVEMENT";
3580  }
3581  // Compatibility: Before 3.1 E_CITY_IMPROVEMENT_BLDG was called
3582  // E_CITY_AQ_BUILDING
3583  if (!fc_strcasecmp("E_CITY_AQ_BUILDING", p)) {
3584  qCWarning(
3585  deprecations_category,
3586  _("Deprecated event type E_CITY_AQ_BUILDING in client options."));
3587  p = "E_CITY_IMPROVEMENT_BLDG";
3588  }
3589  event = event_type_by_name(p, strcmp);
3590  if (!event_type_is_valid(event)) {
3591  qCritical("Event not supported: %s", p);
3592  continue;
3593  }
3594 
3596  "messages.event%d.where", i)) {
3597  qCritical("Corruption in file %s: %s", secfile_name(file),
3598  secfile_error());
3599  }
3600  }
3601 }
3602 
3607 static void message_options_save(struct section_file *file,
3608  const char *prefix)
3609 {
3610  Q_UNUSED(prefix)
3611  enum event_type event;
3612  int i = 0;
3613 
3614  for (event = event_type_begin(); event != event_type_end();
3615  event = event_type_next(event)) {
3616  secfile_insert_str(file, event_type_name(event), "messages.event%d.name",
3617  i);
3618  secfile_insert_int(file, messages_where[i], "messages.event%d.where", i);
3619  i++;
3620  }
3621 
3622  secfile_insert_int(file, i, "messages.count");
3623 }
3628 static void load_cma_preset(struct section_file *file, int i)
3629 {
3630  struct cm_parameter parameter;
3631  const char *name =
3632  secfile_lookup_str_default(file, "preset", "cma.preset%d.name", i);
3633 
3635  {
3636  parameter.minimal_surplus[o] =
3637  secfile_lookup_int_default(file, 0, "cma.preset%d.minsurp%d", i, o);
3638  parameter.factor[o] =
3639  secfile_lookup_int_default(file, 0, "cma.preset%d.factor%d", i, o);
3640  }
3642  parameter.max_growth =
3643  secfile_lookup_bool_default(file, false, "cma.preset%d.max_growth", i);
3644  parameter.require_happy =
3645  secfile_lookup_bool_default(file, false, "cma.preset%d.reqhappy", i);
3646  parameter.happy_factor =
3647  secfile_lookup_int_default(file, 0, "cma.preset%d.happyfactor", i);
3649  file, false, "cma.preset%d.allow_disorder", i);
3651  file, true, "cma.preset%d.allow_specialists", i);
3652 
3653  cmafec_preset_add(name, &parameter);
3654 }
3659 static void save_cma_preset(struct section_file *file, int i)
3660 {
3661  const struct cm_parameter *const pparam = cmafec_preset_get_parameter(i);
3662  char *name = cmafec_preset_get_descr(i);
3663 
3664  secfile_insert_str(file, name, "cma.preset%d.name", i);
3665 
3667  {
3668  secfile_insert_int(file, pparam->minimal_surplus[o],
3669  "cma.preset%d.minsurp%d", i, o);
3670  secfile_insert_int(file, pparam->factor[o], "cma.preset%d.factor%d", i,
3671  o);
3672  }
3674  secfile_insert_bool(file, pparam->require_happy, "cma.preset%d.reqhappy",
3675  i);
3676  secfile_insert_int(file, pparam->happy_factor, "cma.preset%d.happyfactor",
3677  i);
3678  secfile_insert_bool(file, pparam->max_growth, "cma.preset%d.max_growth",
3679  i);
3680  secfile_insert_bool(file, pparam->allow_disorder,
3681  "cma.preset%d.allow_disorder", i);
3682  secfile_insert_bool(file, pparam->allow_specialists,
3683  "cma.preset%d.allow_specialists", i);
3684 }
3689 static void save_cma_presets(struct section_file *file)
3690 {
3691  int i;
3692 
3694  _("If you add a preset by hand,"
3695  " also update \"number_of_presets\""),
3696  "cma.number_of_presets");
3697  for (i = 0; i < cmafec_preset_num(); i++) {
3698  save_cma_preset(file, i);
3699  }
3700 }
3702 // Old rc file name.
3703 #define OLD_OPTION_FILE_NAME ".civclientrc"
3704 // New rc file name.
3705 #define MID_OPTION_FILE_NAME ".freeciv-client-rc-%d.%d"
3706 #define NEW_OPTION_FILE_NAME "freeciv-client-rc-%d.%d"
3707 #if MINOR_VERSION >= 90
3708 #define MAJOR_NEW_OPTION_FILE_NAME (MAJOR_VERSION + 1)
3709 #define MINOR_NEW_OPTION_FILE_NAME 0
3710 #else // MINOR_VERSION < 90
3711 #define MAJOR_NEW_OPTION_FILE_NAME MAJOR_VERSION
3712 #if IS_DEVEL_VERSION
3713 #define MINOR_NEW_OPTION_FILE_NAME (MINOR_VERSION + 1)
3714 #else
3715 #define MINOR_NEW_OPTION_FILE_NAME MINOR_VERSION
3716 #endif // IS_DEVEL_VERSION
3717 #endif // MINOR_VERSION >= 90
3718 // The first version the new option name appeared (2.6).
3719 #define FIRST_MAJOR_NEW_OPTION_FILE_NAME 2
3720 #define FIRST_MINOR_NEW_OPTION_FILE_NAME 6
3721 // The first version the mid option name appeared (2.2).
3722 #define FIRST_MAJOR_MID_OPTION_FILE_NAME 2
3723 #define FIRST_MINOR_MID_OPTION_FILE_NAME 2
3724 // The first version the new boolean values appeared (2.3).
3725 #define FIRST_MAJOR_NEW_BOOLEAN 2
3726 #define FIRST_MINOR_NEW_BOOLEAN 3
3727 
3735 static const char *get_current_option_file_name()
3736 {
3737  static char name_buffer[256];
3738 
3739  auto name = QString::fromLocal8Bit(qgetenv("FREECIV_OPT"));
3740 
3741  if (!name.isEmpty()) {
3742  sz_strlcpy(name_buffer, qUtf8Printable(name));
3743  } else {
3744 #ifdef OPTION_FILE_NAME
3745  fc_strlcpy(name_buffer, OPTION_FILE_NAME, sizeof(name_buffer));
3746 #else
3748  if (name.isEmpty()) {
3749  qCritical(_("Cannot find Freeciv21 storage directory"));
3750  return nullptr;
3751  }
3752  fc_snprintf(name_buffer, sizeof(name_buffer),
3753  "%s/freeciv-client-rc-%d.%d", qUtf8Printable(name),
3755 #endif // OPTION_FILE_NAME
3756  }
3757  qDebug("settings file is %s", name_buffer);
3758  return name_buffer;
3759 }
3760 
3769 static const char *get_last_option_file_name(bool *allow_digital_boolean)
3770 {
3771  static char name_buffer[256];
3772  static int last_minors[] = {
3773  0, // There was no 0.x releases
3774  14, // 1.14
3775  7 // 2.7
3776  };
3777 
3778 #if MINOR_VERSION >= 90
3779  FC_STATIC_ASSERT(MAJOR_VERSION < sizeof(last_minors) / sizeof(int),
3780  missing_last_minor);
3781 #else
3782  FC_STATIC_ASSERT(MAJOR_VERSION <= sizeof(last_minors) / sizeof(int),
3783  missing_last_minor);
3784 #endif
3785 
3786  *allow_digital_boolean = false;
3787 
3788  auto name = QString::fromLocal8Bit(qgetenv("FREECIV_OPT"));
3789 
3790  if (!name.isEmpty()) {
3791  sz_strlcpy(name_buffer, qUtf8Printable(name));
3792  } else {
3793 #ifdef OPTION_FILE_NAME
3794  fc_strlcpy(name_buffer, OPTION_FILE_NAME, sizeof(name_buffer));
3795 #else
3796  int major, minor;
3797  struct stat buf;
3798 
3800  if (name.isEmpty()) {
3801  qCritical(_("Cannot find Freeciv21 storage directory"));
3802 
3803  return nullptr;
3804  }
3805 
3806  for (major = MAJOR_NEW_OPTION_FILE_NAME,
3808  major >= FIRST_MAJOR_NEW_OPTION_FILE_NAME; major--) {
3809  for (; (major == FIRST_MAJOR_NEW_OPTION_FILE_NAME
3811  : minor >= 0);
3812  minor--) {
3813  fc_snprintf(name_buffer, sizeof(name_buffer),
3814  "%s/freeciv-client-rc-%d.%d", qUtf8Printable(name),
3815  major, minor);
3816  if (0 == fc_stat(name_buffer, &buf)) {
3817  if (MAJOR_NEW_OPTION_FILE_NAME != major
3818  || MINOR_NEW_OPTION_FILE_NAME != minor) {
3819  qInfo(_("Didn't find '%s' option file, "
3820  "loading from '%s' instead."),
3821  get_current_option_file_name(), name_buffer);
3822  }
3823 
3824  return name_buffer;
3825  }
3826  }
3827  minor = last_minors[major - 1];
3828  }
3829 
3830  /* minor having max value of FIRST_MINOR_NEW_OPTION_FILE_NAME
3831  * works since MID versioning scheme was used within major version 2
3832  * only (2.2 - 2.6) so the last minor is bigger than any earlier minor.
3833  */
3834  for (major = FIRST_MAJOR_MID_OPTION_FILE_NAME,
3836  minor >= FIRST_MINOR_MID_OPTION_FILE_NAME; minor--) {
3837  fc_snprintf(name_buffer, sizeof(name_buffer),
3838  "%s/.freeciv-client-rc-%d.%d",
3839  qUtf8Printable(QDir::homePath()), major, minor);
3840  if (0 == fc_stat(name_buffer, &buf)) {
3841  qInfo(_("Didn't find '%s' option file, "
3842  "loading from '%s' instead."),
3844  + qstrlen(qUtf8Printable(QDir::homePath())) + 1,
3845  name_buffer);
3846 
3847  if (FIRST_MINOR_NEW_BOOLEAN > minor) {
3848  *allow_digital_boolean = true;
3849  }
3850  return name_buffer;
3851  }
3852  }
3853 
3854  // Try with the old one.
3855  fc_snprintf(name_buffer, sizeof(name_buffer), "%s/%s",
3856  qUtf8Printable(name), OLD_OPTION_FILE_NAME);
3857  if (0 == fc_stat(name_buffer, &buf)) {
3858  qInfo(_("Didn't find '%s' option file, "
3859  "loading from '%s' instead."),
3861  *allow_digital_boolean = true;
3862  return name_buffer;
3863  } else {
3864  return nullptr;
3865  }
3866 #endif // OPTION_FILE_NAME
3867  }
3868  qDebug("settings file is %s", name_buffer);
3869  return name_buffer;
3870 }
3871 #undef OLD_OPTION_FILE_NAME
3872 #undef MID_OPTION_FILE_NAME
3873 #undef NEW_OPTION_FILE_NAME
3874 #undef FIRST_MAJOR_NEW_OPTION_FILE_NAME
3875 #undef FIRST_MINOR_NEW_OPTION_FILE_NAME
3876 #undef FIRST_MAJOR_MID_OPTION_FILE_NAME
3877 #undef FIRST_MINOR_MID_OPTION_FILE_NAME
3878 #undef FIRST_MINOR_NEW_BOOLEAN
3879 
3880 Q_GLOBAL_STATIC(optionsHash, settable_options)
3881 
3882 
3888 static void
3890 {
3891  for (auto &name : {options->default_tileset_iso_name,
3892  options->default_tileset_isohex_name,
3893  options->default_tileset_square_name}) {
3894  if (name == QStringLiteral("cimpletoon")) {
3895  fc_strlcpy(name, "amplio2", sizeof(name));
3896  options->tileset_options[QStringLiteral("amplio2")]
3897  [QStringLiteral("cimpletoon")] = true;
3898  } else if (name == QStringLiteral("toonhex")) {
3899  fc_strlcpy(name, "hexemplio", sizeof(name));
3900  options->tileset_options[QStringLiteral("hexemplio")]
3901  [QStringLiteral("cimpletoon")] = true;
3902  }
3903  }
3904 }
3905 
3913 static void tileset_options_load(struct section_file *sf,
3914  struct client_options *options)
3915 {
3916  // Gather all tileset_xxx sections
3917  auto sections =
3919  if (!sections) {
3920  return;
3921  }
3922 
3923  section_list_iterate(sections, psection)
3924  {
3925  // Extract the tileset name from the name of the section.
3926  auto tileset_name =
3927  section_name(psection) + strlen(TILESET_OPTIONS_PREFIX);
3928 
3929  // Get all values from the section and fill a map with them.
3930  auto entries = section_entries(psection);
3931  auto settings = std::map<QString, bool>();
3932  entry_list_iterate(entries, pentry)
3933  {
3934  bool value = true;
3935  if (entry_bool_get(pentry, &value)) {
3936  settings[entry_name(pentry)] = value;
3937  } else {
3938  // Ignore options we can't convert to a bool, but warn the user.
3939  qWarning("Could not load option %s for tileset %s",
3940  entry_name(pentry), tileset_name);
3941  }
3942  }
3944 
3945  // Store the loaded options for later use.
3946  options->tileset_options[tileset_name] = settings;
3947  }
3949 }
3950 
3956 static void tileset_options_save(struct section_file *sf,
3957  const struct client_options *options)
3958 {
3959  for (const auto &[tileset, settings] : options->tileset_options) {
3960  for (const auto &[name, value] : settings) {
3961  secfile_insert_bool(sf, value, "%s%s.%s", TILESET_OPTIONS_PREFIX,
3962  qUtf8Printable(tileset), qUtf8Printable(name));
3963  }
3964  }
3965 }
3970 static void settable_options_load(struct section_file *sf)
3971 {
3972  char buf[64];
3973  const struct section *psection;
3974  const struct entry_list *entries;
3975  const char *string;
3976  bool bval;
3977  int ival;
3978 
3979  settable_options->clear();
3980 
3981  psection = secfile_section_by_name(sf, "server");
3982  if (nullptr == psection) {
3983  // Does not exist!
3984  return;
3985  }
3986 
3987  entries = section_entries(psection);
3988  entry_list_iterate(entries, pentry)
3989  {
3990  string = nullptr;
3991  switch (entry_type_get(pentry)) {
3992  case ENTRY_BOOL:
3993  if (entry_bool_get(pentry, &bval)) {
3994  fc_strlcpy(buf, bval ? "enabled" : "disabled", sizeof(buf));
3995  string = buf;
3996  }
3997  break;
3998 
3999  case ENTRY_INT:
4000  if (entry_int_get(pentry, &ival)) {
4001  fc_snprintf(buf, sizeof(buf), "%d", ival);
4002  string = buf;
4003  }
4004  break;
4005 
4006  case ENTRY_STR:
4007  (void) entry_str_get(pentry, &string);
4008  break;
4009 
4010  case ENTRY_FLOAT:
4011  case ENTRY_FILEREFERENCE:
4012  // Not supported yet
4013  break;
4014  case ENTRY_ILLEGAL:
4016  break;
4017  }
4018 
4019  if (nullptr == string) {
4020  qCritical("Entry type variant of \"%s.%s\" is not supported.",
4021  section_name(psection), entry_name(pentry));
4022  continue;
4023  }
4024 
4025  settable_options->insert(entry_name(pentry), string);
4026  }
4028 }
4033 static void settable_options_save(struct section_file *sf)
4034 {
4035  optionsHash::const_iterator it = settable_options->constBegin();
4036  while (it != settable_options->constEnd()) {
4037  if (!it.key().compare(QLatin1String("gameseed"))
4038  || !it.key().compare(QLatin1String("mapseed"))) {
4039  // Do not save mapseed or gameseed.
4040  it++;
4041  continue;
4042  }
4043  if (!it.key().compare(QLatin1String("topology"))) {
4044  /* client_start_server() sets topology based on tileset. Don't store
4045  * its choice. The tileset is already stored. Storing topology leads
4046  * to all sort of breakage:
4047  * - it breaks ruleset default topology.
4048  * - it interacts badly with tileset ruleset change, ruleset tileset
4049  * change and topology tileset change.
4050  * - its value is probably based on what tileset was loaded when
4051  * client_start_server() decided to set topology, not on player
4052  * choice.
4053  */
4054  it++;
4055  continue;
4056  }
4057  QByteArray qkey = it.key().toLocal8Bit();
4058  QByteArray qval = it.value().toLocal8Bit();
4059  secfile_insert_str(sf, qval.data(), "server.%s", qkey.data());
4060  it++; // IT comes 4 U
4061  }
4062 }
4063 
4069 {
4070  char val_buf[1024], def_buf[1024];
4071  QString value, def_val;
4072 
4073  options_iterate(server_optset, poption)
4074  {
4075  switch (option_type(poption)) {
4076  case OT_BOOLEAN:
4077  fc_strlcpy(val_buf, option_bool_get(poption) ? "enabled" : "disabled",
4078  sizeof(val_buf));
4079  value = val_buf;
4080  fc_strlcpy(def_buf, option_bool_def(poption) ? "enabled" : "disabled",
4081  sizeof(def_buf));
4082  def_val = def_buf;
4083  break;
4084  case OT_INTEGER:
4085  fc_snprintf(val_buf, sizeof(val_buf), "%d", option_int_get(poption));
4086  value = val_buf;
4087  fc_snprintf(def_buf, sizeof(def_buf), "%d", option_int_def(poption));
4088  def_val = def_buf;
4089  break;
4090  case OT_STRING:
4091  value = option_str_get(poption);
4092  def_val = option_str_def(poption);
4093  break;
4094  case OT_ENUM:
4095  server_option_enum_support_name(poption, &value, &def_val);
4096  break;
4097  case OT_BITWISE:
4098  server_option_bitwise_support_name(poption, val_buf, sizeof(val_buf),
4099  def_buf, sizeof(def_buf));
4100  value = val_buf;
4101  def_val = def_buf;
4102  break;
4103  case OT_FONT:
4104  case OT_COLOR:
4105  break;
4106  }
4107 
4108  if (nullptr == value || nullptr == def_val) {
4109  qCritical("Option type %s (%d) not supported for '%s'.",
4110  option_type_name(option_type(poption)), option_type(poption),
4111  option_name(poption));
4112  continue;
4113  }
4114 
4115  if (value == def_val) {
4116  // Not set, using default...
4117  settable_options->remove(option_name(poption));
4118  } else {
4119  // Really desired.
4120  settable_options->insert(option_name(poption), value);
4121  }
4122  }
4124 }
4125 
4130 void desired_settable_option_update(const char *op_name,
4131  const char *op_value, bool allow_replace)
4132 {
4133  Q_UNUSED(allow_replace)
4134  settable_options->insert(op_name, op_value);
4135 }
4136 
4141 static bool settable_option_upgrade_value(const struct option *poption,
4142  int old_value, char *buf,
4143  size_t buf_len)
4144 {
4145  const char *name = option_name(poption);
4146 
4147 #define SETTING_CASE(ARG_name, ...) \
4148  if (0 == strcmp(ARG_name, name)) { \
4149  static const char *values[] = {__VA_ARGS__}; \
4150  if (0 <= old_value && old_value < ARRAY_SIZE(values) \
4151  && nullptr != values[old_value]) { \
4152  fc_strlcpy(buf, values[old_value], buf_len); \
4153  return true; \
4154  } else { \
4155  return false; \
4156  } \
4157  }
4158 
4159  SETTING_CASE("topology", "", "WRAPX", "WRAPY", "WRAPX|WRAPY", "ISO",
4160  "WRAPX|ISO", "WRAPY|ISO", "WRAPX|WRAPY|ISO", "HEX",
4161  "WRAPX|HEX", "WRAPY|HEX", "WRAPX|WRAPY|HEX", "ISO|HEX",
4162  "WRAPX|ISO|HEX", "WRAPY|ISO|HEX", "WRAPX|WRAPY|ISO|HEX");
4163  SETTING_CASE("generator", nullptr, "RANDOM", "FRACTAL", "ISLAND");
4164  SETTING_CASE("startpos", "DEFAULT", "SINGLE", "2or3", "ALL", "VARIABLE");
4165  SETTING_CASE("borders", "DISABLED", "ENABLED", "SEE_INSIDE", "EXPAND");
4166  SETTING_CASE("diplomacy", "ALL", "HUMAN", "AI", "TEAM", "DISABLED");
4167  SETTING_CASE("citynames", "NO_RESTRICTIONS", "PLAYER_UNIQUE",
4168  "GLOBAL_UNIQUE", "NO_STEALING");
4169  SETTING_CASE("barbarians", "DISABLED", "HUTS_ONLY", "NORMAL", "FREQUENT",
4170  "HORDES");
4171  SETTING_CASE("phasemode", "ALL", "PLAYER", "TEAM");
4172  SETTING_CASE("compresstype", "PLAIN", "LIBZ", "BZIP2");
4173 
4174 #undef SETTING_CASE
4175  return false;
4176 }
4181 static void desired_settable_option_send(struct option *poption)
4182 {
4183  const char *desired;
4184  int value;
4185 
4186  if (!settable_options->contains(option_name(poption))) {
4187  // No change explicitly desired.
4188  return;
4189  }
4190  QByteArray qval =
4191  settable_options->value(option_name(poption)).toLocal8Bit();
4192  desired = qval.data();
4193  switch (option_type(poption)) {
4194  case OT_BOOLEAN:
4195  if ((0 == fc_strcasecmp("enabled", desired)
4196  || (str_to_int(desired, &value) && 1 == value))
4197  && !option_bool_get(poption)) {
4198  send_chat_printf("/set %s enabled", option_name(poption));
4199  } else if ((0 == fc_strcasecmp("disabled", desired)
4200  || (str_to_int(desired, &value) && 0 == value))
4201  && option_bool_get(poption)) {
4202  send_chat_printf("/set %s disabled", option_name(poption));
4203  }
4204  return;
4205  case OT_INTEGER:
4206  if (str_to_int(desired, &value) && value != option_int_get(poption)) {
4207  send_chat_printf("/set %s %d", option_name(poption), value);
4208  }
4209  return;
4210  case OT_STRING:
4211  if (0 != strcmp(desired, option_str_get(poption))) {
4212  send_chat_printf("/set %s \"%s\"", option_name(poption), desired);
4213  }
4214  return;
4215  case OT_ENUM: {
4216  char desired_buf[256];
4217 
4218  // Handle old values.
4219  if (str_to_int(desired, &value)
4220  && settable_option_upgrade_value(poption, value, desired_buf,
4221  sizeof(desired_buf))) {
4222  desired = desired_buf;
4223  }
4224 
4225  QString value_str;
4226  server_option_enum_support_name(poption, &value_str, nullptr);
4227  if (desired == value_str) {
4228  send_chat_printf("/set %s \"%s\"", option_name(poption), desired);
4229  }
4230  }
4231  return;
4232  case OT_BITWISE: {
4233  char desired_buf[256], value_buf[256];
4234 
4235  // Handle old values.
4236  if (str_to_int(desired, &value)
4237  && settable_option_upgrade_value(poption, value, desired_buf,
4238  sizeof(desired_buf))) {
4239  desired = desired_buf;
4240  }
4241 
4242  server_option_bitwise_support_name(poption, value_buf, sizeof(value_buf),
4243  nullptr, 0);
4244  if (0 != strcmp(desired, value_buf)) {
4245  send_chat_printf("/set %s \"%s\"", option_name(poption), desired);
4246  }
4247  }
4248  return;
4249  case OT_FONT:
4250  case OT_COLOR:
4251  break;
4252  }
4253 
4254  qCritical("Option type %s (%d) not supported for '%s'.",
4255  option_type_name(option_type(poption)), option_type(poption),
4256  option_name(poption));
4257 }
4258 
4259 Q_GLOBAL_STATIC(dialOptionsHash, dialog_options)
4261 
4264 static void options_dialogs_load(struct section_file *sf)
4265 {
4266  const struct entry_list *entries;
4267  const char *prefixes[] = {"player_dlg_", "city_report_", nullptr};
4268  const char **prefix;
4269  bool visible;
4270 
4271  entries = section_entries(secfile_section_by_name(sf, "client"));
4272 
4273  if (nullptr != entries) {
4274  entry_list_iterate(entries, pentry)
4275  {
4276  for (prefix = prefixes; nullptr != *prefix; prefix++) {
4277  if (0 == strncmp(*prefix, entry_name(pentry), qstrlen(*prefix))
4278  && secfile_lookup_bool(sf, &visible, "client.%s",
4279  entry_name(pentry))) {
4280  dialog_options->insert(entry_name(pentry), visible);
4281  break;
4282  }
4283  }
4284  }
4286  }
4287 }
4292 static void options_dialogs_save(struct section_file *sf)
4293 {
4294  fc_assert_ret(nullptr != dialog_options);
4295 
4297  dialOptionsHash::const_iterator it = dialog_options->constBegin();
4298  while (it != dialog_options->constEnd()) {
4299  QByteArray qba = it.key().toLocal8Bit();
4300  secfile_insert_bool(sf, (bool) it.value(), "client.%s", qba.data());
4301  it++;
4302  }
4303 }
4304 
4311 {
4312  char buf[64];
4313  int i;
4314 
4315  fc_assert_ret(nullptr != dialog_options);
4316 
4317  // Player report dialog options.
4318  for (i = 1; i < num_player_dlg_columns; i++) {
4319  fc_snprintf(buf, sizeof(buf), "player_dlg_%s",
4320  player_dlg_columns[i].tagname);
4321  dialog_options->insert(buf, player_dlg_columns[i].show);
4322  }
4323 
4324  // City report dialog options.
4325  for (i = 0; i < num_city_report_spec(); i++) {
4326  fc_snprintf(buf, sizeof(buf), "city_report_%s",
4328  dialog_options->insert(buf, *city_report_spec_show_ptr(i));
4329  }
4330 }
4331 
4336 void options_dialogs_set()
4337 {
4338  char buf[64];
4339  int i;
4340 
4341  // Player report dialog options.
4342  for (i = 1; i < num_player_dlg_columns; i++) {
4343  fc_snprintf(buf, sizeof(buf), "player_dlg_%s",
4344  player_dlg_columns[i].tagname);
4345  if (dialog_options->contains(buf)) {
4346  player_dlg_columns[i].show = dialog_options->value(buf);
4347  }
4348  }
4349 
4350  // City report dialog options.
4351  for (i = 0; i < num_city_report_spec(); i++) {
4352  fc_snprintf(buf, sizeof(buf), "city_report_%s",
4354  if (dialog_options->contains(buf)) {
4355  *city_report_spec_show_ptr(i) = dialog_options->value(buf);
4356  }
4357  }
4358 }
4359 
4366 void options_load()
4367 {
4368  struct section_file *sf;
4369  bool allow_digital_boolean;
4370  int i, num;
4371  const char *name;
4372  const char *const prefix = "client";
4373  const char *str;
4374 
4375  // Ensure all options start with their default value
4376  for (auto &option : client_options) {
4378  }
4379 
4381  if (!name) {
4382  qInfo(_("Didn't find the option file. Creating a new one."));
4385  gui_options->first_boot = true;
4386  return;
4387  }
4388  if (!(sf = secfile_load(name, true))) {
4389  log_debug("Error loading option file '%s':\n%s", name, secfile_error());
4390  // try to create the rc file
4391  sf = secfile_new(true);
4392  secfile_insert_str(sf, freeciv21_version(), "client.version");
4393 
4395  gui_options->first_boot = true;
4396  save_cma_presets(sf);
4397 
4398  // FIXME: need better messages
4399  if (!secfile_save(sf, name)) {
4400  qCritical(_("Save failed, cannot write to file %s"), name);
4401  } else {
4402  qInfo(_("Saved settings to file %s"), name);
4403  }
4404  secfile_destroy(sf);
4406  return;
4407  }
4409 
4410  // a "secret" option for the lazy. TODO: make this saveable
4411  if (client_url().password().isEmpty()) {
4412  client_url().setPassword(
4413  secfile_lookup_str_default(sf, "", "%s.password", prefix));
4414  }
4415 
4418  "%s.save_options_on_exit", prefix);
4420  sf, gui_options->migrate_fullscreen, "%s.fullscreen_mode", prefix);
4421 
4422  str = secfile_lookup_str_default(sf, nullptr,
4423  "client.default_tileset_overhead_name");
4424  if (str != nullptr) {
4426  }
4427  str = secfile_lookup_str_default(sf, nullptr,
4428  "client.default_tileset_iso_name");
4429  if (str != nullptr) {
4431  }
4432 
4433  bool draw_full_citybar =
4434  secfile_lookup_bool_default(sf, true, "client.draw_full_citybar");
4435  if (draw_full_citybar) {
4438  } else {
4441  }
4442 
4443  /* Backwards compatibility for removed options replaced by entirely "new"
4444  * options. The equivalent "new" option will override these, if set. */
4445 
4446  // Renamed in 2.6
4448  sf, true, "%s.popup_caravan_arrival", prefix);
4449 
4450  // Load all the regular options
4451  for (auto &option : client_options) {
4453  }
4454 
4455  /* More backwards compatibility, for removed options that had been
4456  * folded into then-existing options. Here, the backwards-compatibility
4457  * behaviour overrides the "destination" option. */
4458 
4459  // Removed in 2.4
4460  if (!secfile_lookup_bool_default(sf, true, "%s.do_combat_animation",
4461  prefix)) {
4463  }
4464 
4465  message_options_load(sf, prefix);
4467 
4468  /* Load cma presets. If cma.number_of_presets doesn't exist, don't load
4469  * any, the order here should be reversed to keep the order the same */
4470  if (secfile_lookup_int(sf, &num, "cma.number_of_presets")) {
4471  for (i = num - 1; i >= 0; i--) {
4472  load_cma_preset(sf, i);
4473  }
4474  } else {
4476  }
4477 
4482 
4483  secfile_destroy(sf);
4485 }
4490 static void option_save_output_window_callback(QtMsgType lvl,
4491  const QString &msg)
4492 {
4493  Q_UNUSED(lvl)
4494  output_window_append(ftc_client, qUtf8Printable(msg));
4495 }
4501 {
4502  struct section_file *sf;
4503  const char *name = get_current_option_file_name();
4504  char dir_name[2048];
4505  int i;
4506 
4507  if (log_cb == nullptr) {
4508  // Default callback
4510  }
4511 
4512  if (!name) {
4513  log_cb(LOG_ERROR, _("Save failed, cannot find a filename."));
4514  return;
4515  }
4516 
4517  sf = secfile_new(true);
4518  secfile_insert_str(sf, freeciv21_version(), "client.version");
4519 
4521  "client.save_options_on_exit");
4523  "deprecated", "client.fullscreen_mode");
4524 
4525  // prevent saving that option
4526  gui_options->gui_qt_increase_fonts = 0; // gui-enabled options
4527  for (const auto &option : client_options) {
4529  }
4530 
4531  message_options_save(sf, "client");
4533 
4534  // Tileset options
4536 
4537  // server settings
4538  save_cma_presets(sf);
4540 
4541  // insert global worklists
4543 
4544  // Directory name
4545  sz_strlcpy(dir_name, name);
4546  for (i = qstrlen(dir_name) - 1; i >= 0 && dir_name[i] != '/'; i--) {
4547  // Nothing
4548  }
4549  if (i > 0) {
4550  dir_name[i] = '\0';
4551  make_dir(dir_name);
4552  }
4553 
4554  // save to disk
4555  if (!secfile_save(sf, name)) {
4556  log_cb(LOG_ERROR, QString::asprintf(
4557  _("Save failed, cannot write to file %s"), name));
4558  } else {
4559  log_cb(LOG_VERBOSE,
4560  QString::asprintf(_("Saved settings to file %s"), name));
4561  }
4562  secfile_destroy(sf);
4563 }
4568 static void options_init_names(const struct copt_val_name *(*acc)(int),
4569  QVector<QString> **support,
4570  QVector<QString> **pretty)
4571 {
4572  int val;
4573  const struct copt_val_name *name;
4574  fc_assert_ret(nullptr != acc);
4575  *support = new QVector<QString>;
4576  *pretty = new QVector<QString>;
4577  for (val = 0; (name = acc(val)); val++) {
4578  (*support)->append(name->support);
4579  (*pretty)->append(name->pretty);
4580  }
4581 }
4586 void options_init()
4587 {
4588  gui_options = new struct client_options;
4590 
4594 
4595  for (auto &option : client_options) {
4596  auto *poption = OPTION(&option);
4597  auto *pcoption = CLIENT_OPTION(&option);
4598 
4599  switch (option_type(poption)) {
4600  case OT_INTEGER:
4601  if (option_int_def(poption) < option_int_min(poption)
4602  || option_int_def(poption) > option_int_max(poption)) {
4603  int new_default =
4604  MAX(MIN(option_int_def(poption), option_int_max(poption)),
4605  option_int_min(poption));
4606 
4607  qCritical("option %s has default value of %d, which is "
4608  "out of its range [%d; %d], changing to %d.",
4609  option_name(poption), option_int_def(poption),
4610  option_int_min(poption), option_int_max(poption),
4611  new_default);
4612  *(const_cast<int *>(&(pcoption->u.integer.def))) = new_default;
4613  }
4614  break;
4615 
4616  case OT_STRING:
4617  if (gui_options->default_user_name == option_str_get(poption)) {
4618  // Hack to get a default value.
4619  *(const_cast<const char **>(&(pcoption->u.string.def))) =
4621  }
4622 
4623  if (nullptr == option_str_def(poption)) {
4624  const QVector<QString> *values = option_str_values(poption);
4625 
4626  if (nullptr == values || values->count() == 0) {
4627  qCritical("Invalid nullptr default string for option %s.",
4628  option_name(poption));
4629  } else {
4630  *(const_cast<const char **>(&(pcoption->u.string.def))) =
4631  qstrdup(qUtf8Printable(values->at(0)));
4632  }
4633  }
4634  break;
4635 
4636  case OT_ENUM:
4637  fc_assert(nullptr == pcoption->u.enumerator.support_names);
4638  fc_assert(nullptr == pcoption->u.enumerator.pretty_names);
4639  options_init_names(pcoption->u.enumerator.name_accessor,
4640  &pcoption->u.enumerator.support_names,
4641  &pcoption->u.enumerator.pretty_names);
4642  fc_assert(nullptr != pcoption->u.enumerator.support_names);
4643  fc_assert(nullptr != pcoption->u.enumerator.pretty_names);
4644  break;
4645 
4646  case OT_BITWISE:
4647  fc_assert(nullptr == pcoption->u.bitwise.support_names);
4648  fc_assert(nullptr == pcoption->u.bitwise.pretty_names);
4649  options_init_names(pcoption->u.bitwise.name_accessor,
4650  &pcoption->u.bitwise.support_names,
4651  &pcoption->u.bitwise.pretty_names);
4652  fc_assert(nullptr != pcoption->u.bitwise.support_names);
4653  fc_assert(nullptr != pcoption->u.bitwise.pretty_names);
4654  break;
4655 
4656  case OT_COLOR: {
4657  // Duplicate the string pointers.
4658  struct ft_color *pcolor = pcoption->u.color.pvalue;
4659 
4660  if (nullptr != pcolor->foreground) {
4661  pcolor->foreground = fc_strdup(pcolor->foreground);
4662  }
4663  if (nullptr != pcolor->background) {
4664  pcolor->background = fc_strdup(pcolor->background);
4665  }
4666  }
4667 
4668  case OT_BOOLEAN:
4669  case OT_FONT:
4670  break;
4671  }
4672 
4673  // Set to default.
4674  option_reset(poption);
4675  }
4676 }
4681 void options_free()
4682 {
4683  for (auto option : client_options) {
4684  auto *poption = OPTION(&option);
4685  auto *pcoption = CLIENT_OPTION(&option);
4686 
4687  switch (option_type(poption)) {
4688  case OT_ENUM:
4689  fc_assert_action(nullptr != pcoption->u.enumerator.support_names,
4690  break);
4691  delete pcoption->u.enumerator.support_names;
4692  pcoption->u.enumerator.support_names = nullptr;
4693  fc_assert_action(nullptr != pcoption->u.enumerator.pretty_names,
4694  break);
4695  delete pcoption->u.enumerator.pretty_names;
4696  pcoption->u.enumerator.pretty_names = nullptr;
4697  break;
4698 
4699  case OT_BITWISE:
4700  fc_assert_action(nullptr != pcoption->u.bitwise.support_names, break);
4701  delete pcoption->u.bitwise.support_names;
4702  pcoption->u.bitwise.support_names = nullptr;
4703  fc_assert_action(nullptr != pcoption->u.bitwise.pretty_names, break);
4704  delete pcoption->u.bitwise.pretty_names;
4705  pcoption->u.bitwise.pretty_names = nullptr;
4706  break;
4707 
4708  case OT_BOOLEAN:
4709  case OT_INTEGER:
4710  case OT_STRING:
4711  case OT_FONT:
4712  case OT_COLOR:
4713  break;
4714  }
4715  }
4716 
4717  settable_options->clear();
4718  dialog_options->clear();
4719 
4722 
4723  delete gui_options;
4724 }
4725 
4730 static void reqtree_show_icons_callback(struct option *poption)
4731 {
4732  Q_UNUSED(poption)
4734 }
4739 static void view_option_changed_callback(struct option *poption)
4740 {
4741  Q_UNUSED(poption)
4742  menus_init();
4744 }
4749 static void manual_turn_done_callback(struct option *poption)
4750 {
4751  Q_UNUSED(poption)
4753 
4755  const player *pplayer = client_player();
4756  if (pplayer != nullptr && is_ai(pplayer) && can_end_turn()) {
4757  user_ended_turn();
4758  }
4759  }
4760 }
4765 static void sound_volume_callback(struct option *poption)
4766 {
4767  Q_UNUSED(poption)
4769 }
4774 static void voteinfo_bar_callback(struct option *poption)
4775 {
4776  Q_UNUSED(poption)
4778 }
4783 static void allfont_changed_callback(struct option *poption)
4784 {
4785  Q_UNUSED(poption)
4787 }
4792 static void font_changed_callback(struct option *poption)
4793 {
4794  fc_assert_ret(OT_FONT == option_type(OPTION(poption)));
4796 }
4797 
4801 /* See #2237
4802 static void mapimg_changed_callback(struct option *poption)
4803 {
4804  if (!mapimg_client_define()) {
4805  bool success;
4806 
4807  qInfo("Error setting the value for %s (%s). Restoring the default "
4808  "value.",
4809  option_name(poption), mapimg_error());
4810 
4811  // Reset the value to the default value.
4812  success = option_reset(poption);
4813  fc_assert_msg(success == true, "Failed to reset the option \"%s\".",
4814  option_name(poption));
4815  success = mapimg_client_define();
4816  fc_assert_msg(success == true,
4817  "Failed to restore mapimg definition for option \"%s\".",
4818  option_name(poption));
4819  }
4820 }
4821 */
4826 static void game_music_enable_callback(struct option *poption)
4827 {
4828  Q_UNUSED(poption)
4829  if (client_state() == C_S_RUNNING) {
4832  } else {
4833  stop_style_music();
4834  }
4835  }
4836 }
4841 static void menu_music_enable_callback(struct option *poption)
4842 {
4843  Q_UNUSED(poption)
4844  if (client_state() != C_S_RUNNING) {
4846  start_menu_music(QStringLiteral("music_menu"), nullptr);
4847  } else {
4848  stop_menu_music();
4849  }
4850  }
4851 }
4852 
4856 /* See #2237
4857 static const QVector<QString> *
4858 get_mapimg_format_list(const struct option *poption)
4859 {
4860  Q_UNUSED(poption)
4861  return mapimg_get_format_list();
4862 }
4863 */
4868 const char *tileset_name_for_topology(int topology_id)
4869 {
4870  const char *tsn = nullptr;
4871 
4872  switch (topology_id & (TF_ISO | TF_HEX)) {
4873  case 0:
4874  case TF_ISO:
4876  break;
4877  case TF_HEX:
4879  break;
4880  case TF_ISO | TF_HEX:
4882  break;
4883  }
4884 
4885  return tsn;
4886 }
4891 static bool is_ts_option_unset(const char *optname)
4892 {
4893  struct option *opt;
4894  const char *val;
4895 
4896  opt = optset_option_by_name(client_optset, optname);
4897 
4898  if (opt == nullptr) {
4899  return true;
4900  }
4901 
4902  val = opt->str_vtable->get(opt);
4903 
4904  return val == nullptr || val[0] == '\0';
4905 }
4910 void fill_topo_ts_default()
4911 {
4912  if (is_ts_option_unset("default_tileset_square_name")) {
4913  if (gui_options->default_tileset_iso_name[0] != '\0') {
4917  } else if (gui_options->default_tileset_overhead_name[0] != '\0') {
4921  } else {
4922  log_debug("Setting tileset for square topologies.");
4923  tilespec_try_read(QString(), false, 0);
4927  }
4928  }
4929  if (is_ts_option_unset("default_tileset_hex_name")) {
4930  log_debug("Setting tileset for hex topology.");
4931  tilespec_try_read(QString(), false, TF_HEX);
4935  }
4936  if (is_ts_option_unset("default_tileset_isohex_name")) {
4937  log_debug("Setting tileset for isohex topology.");
4938  tilespec_try_read(QString(), false, TF_ISO | TF_HEX);
4942  }
4943 }
const QVector< QString > * get_musicset_list(const struct option *poption)
Returns a static string vector of musicsets available on the system.
Definition: audio.cpp:96
void audio_set_volume(double volume)
Set sound volume to use.
Definition: audio.cpp:591
const QVector< QString > * get_soundset_list(const struct option *poption)
Returns a static string vector of soundsets available on the system.
Definition: audio.cpp:84
const QVector< QString > * get_soundplugin_list(const struct option *poption)
Returns a static string vector of all sound plugins available on the system.
Definition: audio.cpp:70
int send_chat_printf(const char *format,...)
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.
#define output_type_iterate(output)
Definition: city.h:764
#define output_type_iterate_end
Definition: city.h:771
static void option_changed(option *opt)
Called by the option code when the option has changed.
Definition: citybar.cpp:286
static const QVector< QString > * available_vector(const option *)
Returns the list of all available city bar styles.
Definition: citybar.cpp:271
enum client_states client_state()
Return current client state.
QUrl & client_url()
Returns the URL that this client connects to.
struct player * client_player()
Either controlling or observing.
void user_ended_turn()
Handle user ending his/her turn.
@ C_S_RUNNING
Definition: client_main.h:43
enum event_type event
Definition: events.cpp:68
void events_init()
Initialize events.
Definition: events.cpp:283
void events_free()
Free events.
Definition: events.cpp:330
setting_default_level
Definition: fc_types.h:1147
#define _(String)
Definition: fcintl.h:50
#define N_(String)
Definition: fcintl.h:52
const struct ft_color ftc_client
static struct ft_color ft_color_construct(const char *foreground, const char *background)
void global_worklists_free()
Free the client global worklists.
void global_worklists_load(struct section_file *file)
Load all global worklist from a section file.
static bool static void void global_worklists_init()
Initialize the client global worklists.
void global_worklists_save(struct section_file *file)
Save all global worklist into a section file.
int cmafec_preset_num()
Returns the total number of presets.
Definition: governor.cpp:769
const struct cm_parameter * cmafec_preset_get_parameter(int idx)
Returns the indexed preset's parameter.
Definition: governor.cpp:738
void create_default_cma_presets()
Create default cma presets for a new user (or without configuration file)
Definition: governor.cpp:804
char * cmafec_preset_get_descr(int idx)
Returns the indexed preset's description.
Definition: governor.cpp:725
void cmafec_preset_add(const char *descr_name, const cm_parameter *pparam)
Adds a preset.
Definition: governor.cpp:692
void gui_update_allfonts()
Definition: gui_main.cpp:284
void options_extra_init()
Extra initializers for client options.
Definition: gui_main.cpp:92
void gui_update_font(const QString &font_name, const QFont &font)
Updates a gui font style.
Definition: gui_main.cpp:277
const char * name
Definition: inputfile.cpp:118
#define fc_assert_ret(condition)
Definition: log.h:112
constexpr auto LOG_ERROR
Definition: log.h:23
constexpr auto LOG_VERBOSE
Definition: log.h:26
#define fc_assert(condition)
Definition: log.h:89
#define fc_assert_ret_msg(condition, message,...)
Definition: log.h:129
#define fc_assert_ret_val(condition, val)
Definition: log.h:114
#define fc_assert_action(condition, action)
Definition: log.h:104
#define log_debug(message,...)
Definition: log.h:65
#define FC_STATIC_ASSERT(cond, tag)
Definition: log.h:158
void update_turn_done_button_state()
Update the turn done button state.
bool can_end_turn()
Return TRUE iff client can end turn.
void menus_init()
void start_style_music()
Start music suitable for current game situation.
Definition: music.cpp:27
void musicspec_reread_callback(struct option *poption)
Musicset changed in options.
Definition: music.cpp:106
void start_menu_music(const QString &tag, const QString &alt_tag)
Start menu music.
Definition: music.cpp:78
void stop_menu_music()
Stop menu music completely.
Definition: music.cpp:88
void stop_style_music()
Stop style music completely.
Definition: music.cpp:73
const char *const help_text
Definition: fonts.h:21
void option_dialog_popdown(const struct option_set *poptset)
Popdown the option dialog for the option set.
Definition: optiondlg.cpp:798
void option_gui_update(struct option *poption)
Update the GUI for the option.
Definition: optiondlg.cpp:812
static void options_init_names(const struct copt_val_name *(*acc)(int), QVector< QString > **support, QVector< QString > **pretty)
Initialize lists of names for a client option.
Definition: options.cpp:4564
QHash< QString, QString > optionsHash
Definition: options.cpp:71
static const QVector< QString > * client_option_str_values(const struct option *poption)
Returns the possible string values of this client option of type OT_STRING.
Definition: options.cpp:2129
void handle_server_setting_const(const struct packet_server_setting_const *packet)
Receive a server setting info packet.
Definition: options.cpp:2685
void handle_server_setting_int(const struct packet_server_setting_int *packet)
Receive a integer server setting info packet.
Definition: options.cpp:2759
static const QVector< QString > * server_option_enum_pretty(const struct option *poption)
Returns the user-visible, translatable (but untranslated) "pretty" names of this server option of typ...
Definition: options.cpp:3252
static int server_option_int_max(const struct option *poption)
Returns the maximal value for this server option of type OT_INTEGER.
Definition: options.cpp:3166
unsigned option_bitwise_mask(const struct option *poption)
Returns the mask of this bitwise option.
Definition: options.cpp:704
void desired_settable_options_update()
Update the desired settable options hash table from the current setting configuration.
Definition: options.cpp:4064
#define FIRST_MAJOR_MID_OPTION_FILE_NAME
Definition: options.cpp:3718
static void allfont_changed_callback(struct option *poption)
Callback for font options.
Definition: options.cpp:4779
static void desired_settable_option_send(struct option *poption)
Send the desired server options to the server.
Definition: options.cpp:4177
static const char * client_option_name(const struct option *poption)
Returns the name of this client option.
Definition: options.cpp:1981
static unsigned server_option_bitwise_def(const struct option *poption)
Returns the default value of this server option of type OT_BITWISE.
Definition: options.cpp:3306
#define FIRST_MAJOR_NEW_OPTION_FILE_NAME
Definition: options.cpp:3715
static void server_option_bitwise_support_base(const QVector< QString > *values, unsigned val, char *buf, size_t buf_len)
Compute the long support names of a value.
Definition: options.cpp:3325
const char * option_str_def(const struct option *poption)
Returns the default value of this string option.
Definition: options.cpp:564
void option_changed(struct option *poption)
Force to use the option changed callback.
Definition: options.cpp:408
static void tileset_options_migrate_cimpletoon(struct client_options *options)
Migrate players using cimpletoon/toonhex to amplio2/hexemplio with the cimpletoon option enabled.
Definition: options.cpp:3885
static void menu_music_enable_callback(struct option *poption)
Callback for music enabling option.
Definition: options.cpp:4837
static bool options_fully_initialized
Definition: options.cpp:78
void options_free()
Free the option module.
Definition: options.cpp:4677
static const struct option_str_vtable client_option_str_vtable
Definition: options.cpp:917
unsigned option_bitwise_def(const struct option *poption)
Returns the default value of this bitwise option.
Definition: options.cpp:693
int option_enum_str_to_int(const struct option *poption, const char *str)
Returns the value corresponding to the user-visible (translatable but not translated) string.
Definition: options.cpp:603
static const char * client_option_description(const struct option *poption)
Returns the description of this client option.
Definition: options.cpp:1989
int option_int_min(const struct option *poption)
Returns the minimal value of this integer option.
Definition: options.cpp:516
static void message_options_save(struct section_file *file, const char *prefix)
Save the message options; use the function defined by specnum.h (see also events.h).
Definition: options.cpp:3603
bool option_bool_def(const struct option *poption)
Returns the default value of this boolean option.
Definition: options.cpp:468
static struct option * client_option_next(const struct option *poption)
Returns the next valid option pointer for the current gui type.
Definition: options.cpp:2022
static QFont client_option_font_get(const struct option *poption)
Returns the value of this client option of type OT_FONT.
Definition: options.cpp:2193
static const char * server_option_name(const struct option *poption)
Returns the name of this server option.
Definition: options.cpp:3061
void options_init()
Initialize the option module.
Definition: options.cpp:4582
static void server_option_enum_support_name(const struct option *poption, QString *pvalue, QString *pdefault)
Returns the long support names of the values of the server option of type OT_ENUM.
Definition: options.cpp:3280
const char * option_name(const struct option *poption)
Returns the name of the option.
Definition: options.cpp:300
static bool server_option_str_set(struct option *poption, const char *str)
Set the value of this server option of type OT_STRING.
Definition: options.cpp:3219
static const char * server_optset_category_name(int category)
Returns the name (translated) of the server option category.
Definition: options.cpp:3041
const struct option_set * server_optset
Definition: options.cpp:2430
static void view_option_changed_callback(struct option *poption)
Callback for when any view option is changed.
Definition: options.cpp:4735
const char * option_str_get(const struct option *poption)
Returns the current value of this string option.
Definition: options.cpp:553
static const char * server_option_description(const struct option *poption)
Returns the (translated) description of this server option.
Definition: options.cpp:3069
static unsigned server_option_bitwise_get(const struct option *poption)
Returns the current value of this server option of type OT_BITWISE.
Definition: options.cpp:3298
static bool client_option_is_changeable(const struct option *poption)
Returns TRUE if this client option can be modified.
Definition: options.cpp:2013
static const char * client_option_enum_secfile_str(secfile_data_t data, int val)
Returns the "support" name of the value for this client option of type OT_ENUM (a string suitable for...
Definition: options.cpp:2165
static int server_option_int_min(const struct option *poption)
Returns the minimal value for this server option of type OT_INTEGER.
Definition: options.cpp:3158
static const char * client_optset_category_name(int category)
Returns the name (translated) of the option class.
Definition: options.cpp:1943
static struct option * server_option_next(const struct option *poption)
Returns the next valid (visible) option pointer.
Definition: options.cpp:3101
#define SERVER_OPTION(poption)
Definition: options.cpp:2559
void options_dialogs_set()
This set the city and player report dialog options.
Definition: options.cpp:4332
#define OLD_OPTION_FILE_NAME
Definition: options.cpp:3699
static const QVector< QString > * server_option_bitwise_pretty(const struct option *poption)
Returns the user-visible, translatable (but untranslated) "pretty" names of this server option of typ...
Definition: options.cpp:3316
static void settable_options_save(struct section_file *sf)
Save the desired server options.
Definition: options.cpp:4029
static bool server_option_bool_get(const struct option *poption)
Returns the value of this server option of type OT_BOOLEAN.
Definition: options.cpp:3109
bool option_reset(struct option *poption)
Set the option to its default value.
Definition: options.cpp:371
const QVector< QString > * option_str_values(const struct option *poption)
Returns the possible string values of this string option.
Definition: options.cpp:575
static void message_options_free()
Free resources allocated for message options system.
Definition: options.cpp:3429
static const char * get_last_option_file_name(bool *allow_digital_boolean)
Check the last option file we saved.
Definition: options.cpp:3765
static int server_option_enum_def(const struct option *poption)
Returns the default value of this server option of type OT_ENUM.
Definition: options.cpp:3242
static int server_option_int_def(const struct option *poption)
Returns the default value of this server option of type OT_INTEGER.
Definition: options.cpp:3150
static int client_option_int_min(const struct option *poption)
Returns the minimal value for this client option of type OT_INTEGER.
Definition: options.cpp:2078
static int server_options_categories_num
Definition: options.cpp:2414
static struct ft_color client_option_color_def(const struct option *poption)
Returns the default value of this client option of type OT_COLOR.
Definition: options.cpp:2250
static bool server_option_enum_set(struct option *poption, int val)
Set the value of this server option of type OT_ENUM.
Definition: options.cpp:3261
static void save_cma_presets(struct section_file *file)
Insert all cma presets.
Definition: options.cpp:3685
struct ft_color option_color_get(const struct option *poption)
Returns the current value of this color option.
Definition: options.cpp:808
client_options * gui_options
Definition: options.cpp:74
static int client_option_int_get(const struct option *poption)
Returns the value of this client option of type OT_INTEGER.
Definition: options.cpp:2062
static char ** server_options_categories
Server options variables.
Definition: options.cpp:2411
int option_enum_get_int(const struct option *poption)
Returns the current value of this enum option (as an integer).
Definition: options.cpp:645
static void settable_options_load(struct section_file *sf)
Load the server options.
Definition: options.cpp:3966
void options_dialogs_update()
This set the city and player report dialog options to the current ones.
Definition: options.cpp:4306
const char *const TILESET_OPTIONS_PREFIX
Definition: options.cpp:69
int option_number(const struct option *poption)
Returns the number of the option.
Definition: options.cpp:290
static void tileset_options_load(struct section_file *sf, struct client_options *options)
Load tileset options.
Definition: options.cpp:3909
static struct server_option * server_options
Definition: options.cpp:2412
static const struct option_int_vtable server_option_int_vtable
Definition: options.cpp:2467
static void options_dialogs_save(struct section_file *sf)
Save the city and player report dialog options.
Definition: options.cpp:4288
#define GEN_STR_OPTION(oname, odesc, ohelp, ocat, odef, ocb, cbd)
Definition: options.cpp:1100
static struct option_set client_optset_static
Definition: options.cpp:855
static int client_optset_category_number()
Returns the number of client option categories.
Definition: options.cpp:1938
static bool client_option_color_set(struct option *poption, struct ft_color color)
Set the value of this client option of type OT_COLOR.
Definition: options.cpp:2259
static struct client_option * client_option_next_valid(struct client_option *poption)
Returns the next valid option pointer for the current gui type.
Definition: options.cpp:1911
static void save_cma_preset(struct section_file *file, int i)
Does heavy lifting for inserting a preset.
Definition: options.cpp:3655
static const char * client_option_str_def(const struct option *poption)
Returns the default value of this client option of type OT_STRING.
Definition: options.cpp:2119
void server_options_free()
Free the server options, if already received.
Definition: options.cpp:2619
void handle_server_setting_bitwise(const struct packet_server_setting_bitwise *packet)
Receive a bitwise server setting info packet.
Definition: options.cpp:2920
static const struct option_font_vtable client_option_font_vtable
Definition: options.cpp:931
void desired_settable_option_update(const char *op_name, const char *op_value, bool allow_replace)
Update a desired settable option in the hash table from a value which can be different of the current...
Definition: options.cpp:4126
#define GEN_INT_OPTION(oname, odesc, ohelp, ocat, odef, omin, omax, ocb)
Definition: options.cpp:1069
struct option * option_next(const struct option *poption)
Returns the next option or nullptr if this is the last.
Definition: options.cpp:361
static void tileset_options_save(struct section_file *sf, const struct client_options *options)
Save tileset options.
Definition: options.cpp:3952
#define GEN_FONT_OPTION(oname, otgt, odesc, ohelp, ocat, ocb)
Definition: options.cpp:1228
QString option_font_target(const struct option *poption)
Returns the target style name of this font option.
Definition: options.cpp:782
bool option_str_set(struct option *poption, const char *str)
Sets the value of this string option.
Definition: options.cpp:586
void handle_server_setting_bool(const struct packet_server_setting_bool *packet)
Receive a boolean server setting info packet.
Definition: options.cpp:2726
const struct option_set * client_optset
Definition: options.cpp:860
static const struct option_bool_vtable server_option_bool_vtable
Definition: options.cpp:2456
static const struct option_bitwise_vtable server_option_bitwise_vtable
Definition: options.cpp:2505
#define GEN_COLOR_OPTION(oname, odesc, ohelp, ocat, odef_fg, odef_bg, ocb)
Definition: options.cpp:1258
static const char * client_option_help_text(const struct option *poption)
Returns the help text for this client option.
Definition: options.cpp:1997
struct option * optset_option_first(const struct option_set *poptset)
Returns the first option of this option set.
Definition: options.cpp:128
static const QVector< QString > * server_option_str_values(const struct option *poption)
Returns the possible string values of this server option of type OT_STRING.
Definition: options.cpp:3209
static int client_option_number(const struct option *poption)
Virtuals tables for the client options.
Definition: options.cpp:1973
void handle_server_setting_str(const struct packet_server_setting_str *packet)
Receive a string server setting info packet.
Definition: options.cpp:2794
int option_int_get(const struct option *poption)
Returns the current value of this integer option.
Definition: options.cpp:494
static void client_option_save(struct option *poption, struct section_file *sf)
Save the option to a file.
Definition: options.cpp:2363
bool option_font_set(struct option *poption, const QFont &font)
Sets the value of this font option.
Definition: options.cpp:793
static int client_option_int_def(const struct option *poption)
Returns the default value of this client option of type OT_INTEGER.
Definition: options.cpp:2070
const char * optset_category_name(const struct option_set *poptset, int category)
Returns the name (translated) of the category of this option set.
Definition: options.cpp:138
static int server_option_category(const struct option *poption)
Returns the category of this server option.
Definition: options.cpp:3085
#define FIRST_MINOR_MID_OPTION_FILE_NAME
Definition: options.cpp:3719
static const struct option_str_vtable server_option_str_vtable
Definition: options.cpp:2480
static int server_options_num
Definition: options.cpp:2415
#define handle_server_setting_common(psoption, packet)
Common part of handle_server_setting_*() functions.
Definition: options.cpp:2707
static const struct option_color_vtable client_option_color_vtable
Definition: options.cpp:943
struct option * optset_option_by_name(const struct option_set *poptset, const char *name)
Returns the option corresponding of the name in this option set.
Definition: options.cpp:110
static void server_option_bitwise_support_name(const struct option *poption, char *val_buf, size_t val_len, char *def_buf, size_t def_len)
Compute the long support names of the values of the server option of type OT_BITWISE.
Definition: options.cpp:3364
bool option_color_set(struct option *poption, struct ft_color color)
Sets the value of this color option.
Definition: options.cpp:835
#define SETTING_CASE(ARG_name,...)
QString option_enum_int_to_str(const struct option *poption, int val)
Returns the user-visible (translatable but not translated) string corresponding to the value.
Definition: options.cpp:626
#define MAJOR_NEW_OPTION_FILE_NAME
Definition: options.cpp:3707
static bool is_ts_option_unset(const char *optname)
Does topology-specific tileset option lack value?
Definition: options.cpp:4887
void option_set_changed_callback(struct option *poption, void(*callback)(struct option *))
Set the function to call every time this option changes.
Definition: options.cpp:397
#define OPTION(poption)
Definition: options.cpp:244
const QVector< QString > * option_bitwise_values(const struct option *poption)
Returns a vector of strings describing every bit of this option, as user-visible (translatable but no...
Definition: options.cpp:721
static bool server_option_bool_set(struct option *poption, bool val)
Set the value of this server option of type OT_BOOLEAN.
Definition: options.cpp:3126
bool option_bool_set(struct option *poption, bool val)
Sets the value of this boolean option.
Definition: options.cpp:479
bool option_is_changeable(const struct option *poption)
Returns TRUE if this option can be modified.
Definition: options.cpp:351
static int server_option_number(const struct option *poption)
Virtuals tables for the client options.
Definition: options.cpp:3053
#define FIRST_MINOR_NEW_BOOLEAN
Definition: options.cpp:3722
static const char * server_option_str_get(const struct option *poption)
Returns the value of this server option of type OT_STRING.
Definition: options.cpp:3191
static struct option * server_optset_option_first()
Returns the first valid (visible) option pointer.
Definition: options.cpp:3028
void option_set_gui_data(struct option *poption, void *data)
Set the gui data for this option.
Definition: options.cpp:427
#define FIRST_MINOR_NEW_OPTION_FILE_NAME
Definition: options.cpp:3716
static bool client_option_bool_get(const struct option *poption)
Returns the value of this client option of type OT_BOOLEAN.
Definition: options.cpp:2030
const char * option_description(const struct option *poption)
Returns the description (translated) of the option.
Definition: options.cpp:310
static const char * server_option_str_def(const struct option *poption)
Returns the default value of this server option of type OT_STRING.
Definition: options.cpp:3199
static const struct option_common_vtable client_option_common_vtable
Definition: options.cpp:880
static bool settable_option_upgrade_value(const struct option *poption, int old_value, char *buf, size_t buf_len)
Convert old integer to new values (Freeciv 2.2.x to Freeciv 2.3.x).
Definition: options.cpp:4137
static void sound_volume_callback(struct option *poption)
Callback for changing music volume.
Definition: options.cpp:4761
bool option_enum_set_int(struct option *poption, int val)
Sets the value of this enum option.
Definition: options.cpp:667
bool option_bool_get(const struct option *poption)
Returns the current value of this boolean option.
Definition: options.cpp:457
#define color_set(color_tgt, color)
static bool client_option_bool_def(const struct option *poption)
Returns the default value of this client option of type OT_BOOLEAN.
Definition: options.cpp:2038
enum option_type option_type(const struct option *poption)
Returns the type of the option.
Definition: options.cpp:330
static const char * get_current_option_file_name()
Returns pointer to static memory containing name of the current option file.
Definition: options.cpp:3731
int option_get_cb_data(const struct option *poption)
Returns the callback data of this option.
Definition: options.cpp:447
static void options_dialogs_load(struct section_file *sf)
Load the city and player report dialog options.
Definition: options.cpp:4260
static int server_option_enum_get(const struct option *poption)
Returns the current value of this server option of type OT_ENUM.
Definition: options.cpp:3234
QHash< QString, intptr_t > dialOptionsHash
Definition: options.cpp:72
struct option * optset_option_by_number(const struct option_set *poptset, int id)
Returns the option corresponding of the number in this option set.
Definition: options.cpp:99
static struct option * client_optset_option_by_number(int id)
Client option set.
Definition: options.cpp:1919
static void font_changed_callback(struct option *poption)
Callback for font options.
Definition: options.cpp:4788
void option_font_set_default(const struct option *poption, const QFont &font)
Returns the default value of this font option.
Definition: options.cpp:771
int option_int_max(const struct option *poption)
Returns the maximal value of this integer option.
Definition: options.cpp:527
static const char * client_option_bitwise_secfile_str(secfile_data_t data, int val)
Returns the "support" name of a single value for this client option of type OT_BITWISE (a string suit...
Definition: options.cpp:2180
static void option_save_output_window_callback(QtMsgType lvl, const QString &msg)
Write messages from option saving to the output window.
Definition: options.cpp:4486
static const char * client_option_str_get(const struct option *poption)
Returns the value of this client option of type OT_STRING.
Definition: options.cpp:2111
QString option_category_name(const struct option *poption)
Returns the name (translated) of the category of the option.
Definition: options.cpp:340
static const struct option_common_vtable server_option_common_vtable
Definition: options.cpp:2443
static bool client_option_bool_set(struct option *poption, bool val)
Set the value of this client option of type OT_BOOLEAN.
Definition: options.cpp:2047
static const char * server_option_help_text(const struct option *poption)
Returns the (translated) help text for this server option.
Definition: options.cpp:3077
static const struct option_bool_vtable client_option_bool_vtable
Definition: options.cpp:893
void fill_topo_ts_default()
Fill default tilesets for topology-specific settings.
Definition: options.cpp:4906
static bool client_option_load(struct option *poption, struct section_file *sf)
Load the option from a file.
Definition: options.cpp:2294
static QFont client_option_font_def(const struct option *poption)
Returns the default value of this client option of type OT_FONT.
Definition: options.cpp:2201
static bool server_option_bitwise_set(struct option *poption, unsigned val)
Set the value of this server option of type OT_BITWISE.
Definition: options.cpp:3345
#define GEN_BOOL_OPTION(oname, odesc, ohelp, ocat, odef, ocb)
Definition: options.cpp:1038
#define MINOR_NEW_OPTION_FILE_NAME
Definition: options.cpp:3711
static struct server_option * server_option_next_valid(struct server_option *poption)
Returns the next valid option pointer for the current gui type.
Definition: options.cpp:3002
static void voteinfo_bar_callback(struct option *poption)
Callback for when any voteinfo bar option is changed.
Definition: options.cpp:4770
static struct option * server_optset_option_by_number(int id)
Server option set.
Definition: options.cpp:3017
void * option_get_gui_data(const struct option *poption)
Returns the gui data of this option.
Definition: options.cpp:437
void options_save(option_save_log_callback log_cb)
Save all options.
Definition: options.cpp:4496
static bool client_option_font_set(struct option *poption, const QFont &font)
Set the value of this client option of type OT_FONT.
Definition: options.cpp:2227
static void init_client_options()
Definition: options.cpp:1290
static const struct option_enum_vtable server_option_enum_vtable
Definition: options.cpp:2492
static std::vector< client_option > client_options
Definition: options.cpp:1289
static bool server_option_int_set(struct option *poption, int val)
Set the value of this server option of type OT_INTEGER.
Definition: options.cpp:3175
int messages_where[E_COUNT]
Message Options:
Definition: options.cpp:3383
static void message_options_load(struct section_file *file, const char *prefix)
Load the message options; use the function defined by specnum.h (see also events.h).
Definition: options.cpp:3435
QFont option_font_get(const struct option *poption)
Returns the current value of this font option.
Definition: options.cpp:749
static void message_options_init()
These could be a static table initialisation, except its easier to do it this way.
Definition: options.cpp:3389
static void server_option_free(struct server_option *poption)
Free one server option.
Definition: options.cpp:2577
static void client_option_font_set_def(const struct option *poption, const QFont &font)
Returns the default value of this client option of type OT_FONT.
Definition: options.cpp:2209
#define CLIENT_OPTION(poption)
Definition: options.cpp:1020
static struct option * client_optset_option_first()
Returns the first valid option pointer for the current gui type.
Definition: options.cpp:1930
static struct option_set server_optset_static
Definition: options.cpp:2425
void handle_server_setting_control(const struct packet_server_setting_control *packet)
Allocate the server options and categories.
Definition: options.cpp:2653
void options_load()
Load from the rc file any options that are not ruleset specific.
Definition: options.cpp:4362
bool option_bitwise_set(struct option *poption, unsigned val)
Sets the value of this bitwise option.
Definition: options.cpp:732
QString option_help_text(const struct option *poption)
Returns the help text (translated) of the option.
Definition: options.cpp:320
static int server_option_int_get(const struct option *poption)
Returns the value of this server option of type OT_INTEGER.
Definition: options.cpp:3142
static void manual_turn_done_callback(struct option *poption)
Callback for when ai_manual_turn_done is changed.
Definition: options.cpp:4745
const char * tileset_name_for_topology(int topology_id)
Option framework wrapper for mapimg_get_format_list()
Definition: options.cpp:4864
static void reqtree_show_icons_callback(struct option *poption)
Enumerator name accessors.
Definition: options.cpp:4726
static void load_cma_preset(struct section_file *file, int i)
Does heavy lifting for looking up a preset.
Definition: options.cpp:3624
static bool client_option_str_set(struct option *poption, const char *str)
Set the value of this client option of type OT_STRING.
Definition: options.cpp:2140
void handle_server_setting_enum(const struct packet_server_setting_enum *packet)
Receive an enumerator server setting info packet.
Definition: options.cpp:2837
struct ft_color option_color_def(const struct option *poption)
Returns the default value of this color option.
Definition: options.cpp:821
static int client_option_int_max(const struct option *poption)
Returns the maximal value for this client option of type OT_INTEGER.
Definition: options.cpp:2086
client_option_category
Definition: options.cpp:948
@ COC_MAX
Definition: options.cpp:956
@ COC_SOUND
Definition: options.cpp:951
@ COC_NETWORK
Definition: options.cpp:954
@ COC_INTERFACE
Definition: options.cpp:952
@ COC_GRAPHICS
Definition: options.cpp:949
@ COC_OVERVIEW
Definition: options.cpp:950
@ COC_FONT
Definition: options.cpp:955
@ COC_MAPIMG
Definition: options.cpp:953
static int server_optset_category_number()
Returns the number of server option categories.
Definition: options.cpp:3036
unsigned option_bitwise_get(const struct option *poption)
Returns the current value of this bitwise option.
Definition: options.cpp:682
static bool server_option_is_changeable(const struct option *poption)
Returns TRUE if this client option can be modified.
Definition: options.cpp:3093
static struct ft_color client_option_color_get(const struct option *poption)
Returns the value of this client option of type OT_COLOR.
Definition: options.cpp:2242
int option_enum_def_int(const struct option *poption)
Returns the default value of this enum option (as an integer).
Definition: options.cpp:656
static bool client_option_int_set(struct option *poption, int val)
Set the value of this client option of type OT_INTEGER.
Definition: options.cpp:2095
bool option_int_set(struct option *poption, int val)
Sets the value of this integer option.
Definition: options.cpp:538
QFont option_font_def(const struct option *poption)
Returns the default value of this font option.
Definition: options.cpp:760
void server_options_init()
Initialize the server options (not received yet).
Definition: options.cpp:2566
static const struct option_int_vtable client_option_int_vtable
Definition: options.cpp:904
const struct option_set * option_optset(const struct option *poption)
Returns the option set owner of this option.
Definition: options.cpp:280
#define GEN_STR_LIST_OPTION(oname, odesc, ohelp, ocat, odef, oacc, ocb, cbd)
Definition: options.cpp:1134
static void game_music_enable_callback(struct option *poption)
Callback for mapimg options.
Definition: options.cpp:4822
int option_int_def(const struct option *poption)
Returns the default value of this integer option.
Definition: options.cpp:505
static QString client_option_font_target(const struct option *poption)
Returns the default value of this client option of type OT_FONT.
Definition: options.cpp:2218
static bool server_option_bool_def(const struct option *poption)
Returns the default value of this server option of type OT_BOOLEAN.
Definition: options.cpp:3117
#define MW_POPUP
Definition: options.h:317
#define FC_QT_DEFAULT_THEME_NAME
Definition: options.h:163
#define options_iterate(poptset, poption)
Definition: options.h:292
#define DEFAULT_METASERVER_OPTION
Definition: options.h:20
void(* option_save_log_callback)(QtMsgType lvl, const QString &msg)
Definition: options.h:201
#define MW_OUTPUT
Definition: options.h:315
#define options_iterate_end
Definition: options.h:297
#define MW_MESSAGES
Definition: options.h:316
@ OLAYER_BORDERS
Definition: options.h:25
@ OLAYER_BACKGROUND
Definition: options.h:23
@ OLAYER_CITIES
Definition: options.h:28
@ OLAYER_BORDERS_ON_OCEAN
Definition: options.h:26
@ OLAYER_UNITS
Definition: options.h:27
@ OLAYER_RELIEF
Definition: options.h:24
void overview_redraw_callback(struct option *option)
Callback to be called when an overview option is changed.
#define MAX_LEN_MSG
Definition: packets.h:37
#define is_ai(plr)
Definition: player.h:227
struct section_file * secfile_load(const QString &filename, bool allow_duplicates)
Create a section file from a file.
Definition: registry.cpp:21
const char * secfile_error()
Returns the last error which occurred in a string.
struct section_file * secfile_new(bool allow_duplicates)
Create a new empty section file.
void secfile_allow_digital_boolean(struct section_file *secfile, bool allow_digital_boolean)
Set if we could consider values 0 and 1 as boolean.
const char * section_name(const struct section *psection)
Returns the section name.
void secfile_destroy(struct section_file *secfile)
Free a section file.
bool secfile_save(const struct section_file *secfile, QString filename)
Save the previously filled in section_file to disk.
bool entry_bool_get(const struct entry *pentry, bool *value)
Gets an boolean value.
bool secfile_lookup_int(const struct section_file *secfile, int *ival, const char *path,...)
Lookup a integer value in the secfile.
bool secfile_lookup_enum_data(const struct section_file *secfile, int *pvalue, bool bitwise, secfile_enum_name_data_fn_t name_fn, secfile_data_t data, const char *path,...)
Lookup a value saved as string in the secfile.
const char * entry_name(const struct entry *pentry)
Returns the name of this entry.
const char * secfile_lookup_str(const struct section_file *secfile, const char *path,...)
Lookup a string value in the secfile.
bool entry_str_get(const struct entry *pentry, const char **value)
Gets an string value.
const char * secfile_name(const struct section_file *secfile)
Return the filename the section file was loaded as, or "(anonymous)" if this sectionfile was created ...
struct section * secfile_section_by_name(const struct section_file *secfile, const QString &name)
Returns the first section matching the name.
bool secfile_lookup_bool_default(const struct section_file *secfile, bool def, const char *path,...)
Lookup a boolean value in the secfile.
const char * secfile_lookup_str_default(const struct section_file *secfile, const char *def, const char *path,...)
Lookup a string value in the secfile.
int secfile_lookup_int_default(const struct section_file *secfile, int def, const char *path,...)
Lookup a integer value in the secfile.
bool entry_int_get(const struct entry *pentry, int *value)
Gets an integer value.
struct section_list * secfile_sections_by_name_prefix(const struct section_file *secfile, const char *prefix)
Returns the list of sections which match the name prefix.
const struct entry_list * section_entries(const struct section *psection)
Returns a list containing all the entries.
bool secfile_lookup_bool(const struct section_file *secfile, bool *bval, const char *path,...)
Lookup a boolean value in the secfile.
enum entry_type entry_type_get(const struct entry *pentry)
Returns the type of this entry or ENTRY_ILLEGAL or error.
#define secfile_insert_int(secfile, value, path,...)
Definition: registry_ini.h:116
#define secfile_insert_bool_comment(secfile, value, comment, path,...)
Definition: registry_ini.h:82
@ ENTRY_FILEREFERENCE
Definition: registry_ini.h:538
@ ENTRY_INT
Definition: registry_ini.h:535
@ ENTRY_FLOAT
Definition: registry_ini.h:536
@ ENTRY_STR
Definition: registry_ini.h:537
@ ENTRY_ILLEGAL
Definition: registry_ini.h:539
@ ENTRY_BOOL
Definition: registry_ini.h:534
#define section_list_iterate(seclist, psection)
Definition: registry_ini.h:46
#define entry_list_iterate_end
Definition: registry_ini.h:58
#define secfile_insert_str(secfile, string, path,...)
Definition: registry_ini.h:167
#define secfile_insert_bool(secfile, value, path,...)
Definition: registry_ini.h:79
#define section_list_iterate_end
Definition: registry_ini.h:48
#define entry_list_iterate(entlist, pentry)
Definition: registry_ini.h:56
#define secfile_insert_enum_data(secfile, value, bitwise, name_fn, data, path,...)
Definition: registry_ini.h:318
#define secfile_insert_int_comment(secfile, value, comment, path,...)
Definition: registry_ini.h:119
const void * secfile_data_t
Definition: registry_ini.h:28
void science_report_dialog_redraw(void)
Resize and redraw the requirement tree.
Q_GLOBAL_STATIC(QVector< QString >, future_name_translation)
static struct setting settings[]
Definition: settings.cpp:1338
bool str_to_int(const char *str, int *pint)
Convert 'str' to it's int reprentation if possible.
Definition: shared.cpp:384
bool make_dir(const QString &pathname)
If the directory "pathname" does not exist, recursively create all directories until it does.
Definition: shared.cpp:1115
QString freeciv_storage_dir()
Returns string which gives freeciv storage dir.
Definition: shared.cpp:419
#define ARRAY_SIZE(x)
Definition: shared.h:79
#define MIN(x, y)
Definition: shared.h:49
#define MAX(x, y)
Definition: shared.h:48
Derived class client option, inherinting of base class option.
Definition: options.cpp:962
QVector< QString > * support_names
Definition: options.cpp:996
const char * def
Definition: options.cpp:985
const char * description
Definition: options.cpp:966
struct client_option::@126::@130 enumerator
unsigned def
Definition: options.cpp:1002
unsigned * pvalue
Definition: options.cpp:1001
struct client_option::@126::@129 string
struct client_option::@126::@128 integer
size_t size
Definition: options.cpp:984
QString target
Definition: options.cpp:1010
char * pvalue
Definition: options.cpp:983
struct client_option::@126::@131 bitwise
struct client_option::@126::@133 color
struct option base_option
Definition: options.cpp:963
bool * pvalue
Definition: options.cpp:973
struct client_option::@126::@132 font
int * pvalue
Definition: options.cpp:978
const char * help_text
Definition: options.cpp:967
struct client_option::@126 u
struct client_option::@126::@127 boolean
enum client_option_category category
Definition: options.cpp:968
QFont * value
Definition: options.cpp:1008
QVector< QString > * pretty_names
Definition: options.cpp:996
const char * name
Definition: options.cpp:965
int gui_qt_increase_fonts
Definition: options.h:167
bool sound_enable_menu_music
Definition: options.h:116
char default_tileset_hex_name[512]
Definition: options.h:56
std::map< QString, std::map< QString, bool > > tileset_options
Saved tileset options.
Definition: options.h:183
char default_tileset_iso_name[512]
Definition: options.h:72
char default_tileset_overhead_name[512]
Definition: options.h:69
char default_tileset_square_name[512]
Definition: options.h:55
bool save_options_on_exit
Definition: options.h:64
int sound_effects_volume
Definition: options.h:118
bool ai_manual_turn_done
Definition: options.h:84
int smooth_combat_step_msec
Definition: options.h:83
bool first_boot
Migrations.
Definition: options.h:67
char default_tileset_isohex_name[512]
Definition: options.h:57
bool popup_actor_arrival
Definition: options.h:97
char default_city_bar_style_name[512]
Definition: options.h:58
bool sound_enable_game_music
Definition: options.h:117
bool migrate_fullscreen
Definition: options.h:75
char default_user_name[512]
Definition: options.h:49
bool allow_disorder
Definition: cm.h:20
int factor[O_LAST]
Definition: cm.h:23
bool max_growth
Definition: cm.h:18
bool allow_specialists
Definition: cm.h:21
bool require_happy
Definition: cm.h:19
int minimal_surplus[O_LAST]
Definition: cm.h:17
int happy_factor
Definition: cm.h:24
const char * support
Definition: options.cpp:863
const char * pretty
Definition: options.cpp:865
const char * background
const char * foreground
bool(* set)(struct option *, unsigned)
Definition: options.cpp:189
unsigned(* get)(const struct option *)
Definition: options.cpp:186
const QVector< QString > *(* values)(const struct option *)
Definition: options.cpp:188
unsigned(* def)(const struct option *)
Definition: options.cpp:187
bool(* set)(struct option *, bool)
Definition: options.cpp:159
bool(* def)(const struct option *)
Definition: options.cpp:158
bool(* get)(const struct option *)
Definition: options.cpp:157
bool(* set)(struct option *, struct ft_color)
Definition: options.cpp:203
struct ft_color(* def)(const struct option *)
Definition: options.cpp:202
struct ft_color(* get)(const struct option *)
Definition: options.cpp:201
const char *(* name)(const struct option *)
Definition: options.cpp:148
struct option *(* next)(const struct option *)
Definition: options.cpp:153
const char *(* help_text)(const struct option *)
Definition: options.cpp:150
bool(* is_changeable)(const struct option *)
Definition: options.cpp:152
int(* number)(const struct option *)
Definition: options.cpp:147
int(* category)(const struct option *)
Definition: options.cpp:151
const char *(* description)(const struct option *)
Definition: options.cpp:149
bool(* set)(struct option *, int)
Definition: options.cpp:181
int(* cmp)(const char *, const char *)
Definition: options.cpp:182
int(* def)(const struct option *)
Definition: options.cpp:179
int(* get)(const struct option *)
Definition: options.cpp:178
const QVector< QString > *(* values)(const struct option *)
Definition: options.cpp:180
QFont(* def)(const struct option *)
Definition: options.cpp:194
QFont(* get)(const struct option *)
Definition: options.cpp:193
QString(* target)(const struct option *)
Definition: options.cpp:196
void(* set_def)(const struct option *, const QFont &font)
Definition: options.cpp:195
bool(* set)(struct option *, const QFont &)
Definition: options.cpp:197
int(* maximum)(const struct option *)
Definition: options.cpp:166
int(* get)(const struct option *)
Definition: options.cpp:163
bool(* set)(struct option *, int)
Definition: options.cpp:167
int(* def)(const struct option *)
Definition: options.cpp:164
int(* minimum)(const struct option *)
Definition: options.cpp:165
Option set structure.
Definition: options.cpp:88
int(* category_number)()
Definition: options.cpp:92
const char *(* category_name)(int)
Definition: options.cpp:93
struct option *(* option_by_number)(int)
Definition: options.cpp:89
struct option *(* option_first)()
Definition: options.cpp:90
const char *(* def)(const struct option *)
Definition: options.cpp:172
const char *(* get)(const struct option *)
Definition: options.cpp:171
bool(* set)(struct option *, const char *)
Definition: options.cpp:174
const QVector< QString > *(* values)(const struct option *)
Definition: options.cpp:173
The base class for options.
Definition: options.cpp:209
const struct option_str_vtable * str_vtable
Definition: options.cpp:225
enum option_type type
Definition: options.cpp:213
const struct option_set * poptset
Definition: options.cpp:211
const struct option_common_vtable * common_vtable
Definition: options.cpp:217
const struct option_font_vtable * font_vtable
Definition: options.cpp:231
const struct option_enum_vtable * enum_vtable
Definition: options.cpp:227
const struct option_bool_vtable * bool_vtable
Definition: options.cpp:221
int callback_data
Definition: options.cpp:238
const struct option_color_vtable * color_vtable
Definition: options.cpp:233
const struct option_bitwise_vtable * bitwise_vtable
Definition: options.cpp:229
void(* changed_callback)(struct option *option)
Definition: options.cpp:236
void * gui_data
Definition: options.cpp:241
const struct option_int_vtable * int_vtable
Definition: options.cpp:223
bool fog
Definition: options.h:44
bool layers[OLAYER_COUNT]
Definition: options.h:45
Definition: player.h:231
bool allow_digital_boolean
Definition: section_file.h:46
Derived class server option, inheriting from base class option.
Definition: options.cpp:2514
unsigned value
Definition: options.cpp:2551
struct server_option::@134::@140 bitwise
char * help_text
Definition: options.cpp:2519
QVector< QString > * pretty_names
Definition: options.cpp:2547
struct server_option::@134::@139 enumerator
QVector< QString > * support_names
Definition: options.cpp:2546
char * description
Definition: options.cpp:2518
unsigned char category
Definition: options.cpp:2520
struct server_option::@134::@137 integer
struct server_option::@134::@138 string
enum setting_default_level setdef
Definition: options.cpp:2524
unsigned def
Definition: options.cpp:2552
bool is_changeable
Definition: options.cpp:2522
struct server_option::@134::@136 boolean
char * value
Definition: options.cpp:2539
struct option base_option
Definition: options.cpp:2515
bool desired_sent
Definition: options.cpp:2521
int fc_snprintf(char *str, size_t n, const char *format,...)
See also fc_utf8_snprintf_trunc(), fc_utf8_snprintf_rep().
Definition: support.cpp:537
size_t fc_strlcpy(char *dest, const char *src, size_t n)
fc_strlcpy() provides utf-8 version of (non-standard) function strlcpy() It is intended as more user-...
Definition: support.cpp:412
int fc_strcasecmp(const char *str0, const char *str1)
Compare strings like strcmp(), but ignoring case.
Definition: support.cpp:89
size_t fc_strlcat(char *dest, const char *src, size_t n)
fc_strlcat() provides utf-8 version of (non-standard) function strlcat() It is intended as more user-...
Definition: support.cpp:448
int fc_stat(const char *filename, struct stat *buf)
Wrapper function for stat() with filename conversion to local encoding on Windows.
Definition: support.cpp:293
#define sz_strlcpy(dest, src)
Definition: support.h:140
#define fc_strdup(str)
Definition: support.h:111
void theme_reread_callback(struct option *poption)
Wrapper for load_theme.
const QVector< QString > * get_themes_list(const struct option *poption)
Return a static string vector of useable theme names.
const char * tileset_basename(const struct tileset *t)
Return the name of the given tileset.
Definition: tilespec.cpp:331
const QVector< QString > * get_tileset_list(const struct option *poption)
Returns a static list of tilesets available on the system by searching all data directories for files...
Definition: tilespec.cpp:725
void tilespec_reread_callback(struct option *poption)
This is merely a wrapper for tilespec_reread (above) for use in options.c and the client local option...
Definition: tilespec.cpp:1063
bool tilespec_try_read(const QString &tileset_name, bool verbose, int topo_id)
Read a new tilespec in when first starting the game.
Definition: tilespec.cpp:860
const char * freeciv21_version()
Returns the raw version string.
Definition: version.cpp:29
const char * city_report_spec_tagname(int i)
Simple wrapper for city_report_specs.tagname.
int num_city_report_spec()
Simple wrapper for num_creport_cols()
bool * city_report_spec_show_ptr(int i)
Simple wrapper for city_report_specs.show.
void update_map_canvas_visible()
Schedules an update of (only) the visible part of the map at the next unqueue_mapview_update().
struct player_dlg_column player_dlg_columns[]
...
const int num_player_dlg_columns
void voteinfo_gui_update(void)
Refresh all vote related GUI widgets.