Freeciv-3.1
Loading...
Searching...
No Matches
tab_misc.cpp
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#ifdef FREECIV_MSWINDOWS
19#include <shlobj.h>
20#endif
21
22// Qt
23#include <QCheckBox>
24#include <QGridLayout>
25#include <QHeaderView>
26#include <QLineEdit>
27#include <QMessageBox>
28#include <QPushButton>
29#include <QTableWidget>
30
31// utility
32#include "fcintl.h"
33#include "log.h"
34#include "registry.h"
35
36// common
37#include "achievements.h"
38#include "game.h"
39#include "government.h"
40#include "specialist.h"
41
42// server
43#include "rssanity.h"
44
45// ruledit
46#include "conversion_log.h"
47#include "ruledit.h"
48#include "ruledit_qt.h"
49#include "rulesave.h"
50
51#include "tab_misc.h"
52
53/**********************************************************************/
57{
58 QGridLayout *main_layout = new QGridLayout(this);
59 QLabel *save_label;
60 QLabel *save_ver_label;
61 QLabel *label;
62 QLabel *name_label;
63 QLabel *version_label;
64 QPushButton *button;
65 int row = 0;
66 QTableWidgetItem *item;
67 char ttbuf[2048];
68
69 ui = ui_in;
70
71 main_layout->setSizeConstraint(QLayout::SetMaximumSize);
72
73 name_label = new QLabel(QString::fromUtf8(R__("Ruleset name")));
74 name_label->setParent(this);
75 main_layout->addWidget(name_label, row, 0);
76 name = new QLineEdit(this);
77 main_layout->addWidget(name, row++, 1);
78 version_label = new QLabel(QString::fromUtf8(R__("Ruleset version")));
79 version_label->setParent(this);
80 main_layout->addWidget(version_label, row, 0);
81 version = new QLineEdit(this);
82 main_layout->addWidget(version, row++, 1);
83 save_label = new QLabel(QString::fromUtf8(R__("Save to directory")));
84 save_label->setParent(this);
85 main_layout->addWidget(save_label, row, 0);
86 savedir = new QLineEdit(this);
87
88#ifdef FREECIV_MSWINDOWS
89 PWSTR folder_path;
90
91 if (SHGetKnownFolderPath(FOLDERID_Documents, KF_FLAG_DEFAULT,
92 NULL, &folder_path) == S_OK) {
93 savedir->setText(QString::fromWCharArray(folder_path) + "\\ruledit-tmp");
94 } else {
95 savedir->setText("ruledit-tmp");
96 }
97
98#else // FREECIV_MSWINDOWS
99 savedir->setText("ruledit-tmp");
100#endif // FREECIV_MSWINDOWS
101
102 /* TRANS: %s%s%s -> path + directory separator ('/' or '\') + path
103 * Do not translate command '/rulesetdir' name. */
104 fc_snprintf(ttbuf, sizeof(ttbuf),
105 R__("If you want to be able to load the ruleset directly "
106 "to freeciv, place it as a subdirectory under %s%s%s\n"
107 "Use server command \"/rulesetdir <subdirectory>\" "
108 "to load it to freeciv."),
109 freeciv_storage_dir(), DIR_SEPARATOR, DATASUBDIR);
110 savedir->setToolTip(ttbuf);
111
112 savedir->setFocus();
113 main_layout->addWidget(savedir, row++, 1);
114 save_ver_label = new QLabel(QString::fromUtf8(R__("Version suffix to directory name")));
115 save_ver_label->setParent(this);
116 main_layout->addWidget(save_ver_label, row, 0);
117 savedir_version = new QCheckBox(this);
118 main_layout->addWidget(savedir_version, row++, 1);
119 button = new QPushButton(QString::fromUtf8(R__("Save now")), this);
120 connect(button, SIGNAL(pressed()), this, SLOT(save_now()));
121 main_layout->addWidget(button, row++, 1);
122
123 label = new QLabel(QString::fromUtf8(R__("Description from file")));
124 label->setParent(this);
125 main_layout->addWidget(label, row, 0);
126 desc_via_file = new QCheckBox(this);
127 connect(desc_via_file, SIGNAL(toggled(bool)), this, SLOT(desc_file_toggle(bool)));
128 main_layout->addWidget(desc_via_file, row++, 1);
129
130 label = new QLabel(QString::fromUtf8(R__("Description file")));
131 label->setParent(this);
132 main_layout->addWidget(label, row, 0);
133 desc_file = new QLineEdit(this);
134 main_layout->addWidget(desc_file, row++, 1);
135
136 button = new QPushButton(QString::fromUtf8(R__("Sanity check rules")), this);
137 connect(button, SIGNAL(pressed()), this, SLOT(sanity_check()));
138 main_layout->addWidget(button, row++, 1);
139
140 button = new QPushButton(QString::fromUtf8(R__("Always active Effects")), this);
141 connect(button, SIGNAL(pressed()), this, SLOT(edit_aae_effects()));
142 main_layout->addWidget(button, row++, 1);
143 button = new QPushButton(QString::fromUtf8(R__("All Effects")), this);
144 connect(button, SIGNAL(pressed()), this, SLOT(edit_all_effects()));
145 main_layout->addWidget(button, row++, 1);
146
147 stats = new QTableWidget(this);
148 stats->setColumnCount(8);
149 stats->setRowCount(7);
150 item = new QTableWidgetItem(QString::fromUtf8(RQ_("?stat:Terrains")));
151 stats->setItem(0, 0, item);
152 item = new QTableWidgetItem("-");
153 stats->setItem(0, 1, item);
154 item = new QTableWidgetItem(QString::fromUtf8(RQ_("?stat:Resources")));
155 stats->setItem(1, 0, item);
156 item = new QTableWidgetItem("-");
157 stats->setItem(1, 1, item);
158 item = new QTableWidgetItem(QString::fromUtf8(RQ_("?stat:Tech Classes")));
159 stats->setItem(2, 0, item);
160 item = new QTableWidgetItem("-");
161 stats->setItem(2, 1, item);
162 item = new QTableWidgetItem(QString::fromUtf8(RQ_("?stat:Techs")));
163 stats->setItem(3, 0, item);
164 item = new QTableWidgetItem("-");
165 stats->setItem(3, 1, item);
166 item = new QTableWidgetItem(QString::fromUtf8(RQ_("?stat:Unit Classes")));
167 stats->setItem(4, 0, item);
168 item = new QTableWidgetItem("-");
169 stats->setItem(4, 1, item);
170 item = new QTableWidgetItem(QString::fromUtf8(RQ_("?stat:Unit Types")));
171 stats->setItem(5, 0, item);
172 item = new QTableWidgetItem("-");
173 stats->setItem(5, 1, item);
174 item = new QTableWidgetItem(QString::fromUtf8(RQ_("?stat:Enablers")));
175 stats->setItem(6, 0, item);
176 item = new QTableWidgetItem("-");
177 stats->setItem(6, 1, item);
178 item = new QTableWidgetItem(QString::fromUtf8(RQ_("?stat:Buildings")));
179 stats->setItem(0, 3, item);
180 item = new QTableWidgetItem("-");
181 stats->setItem(0, 4, item);
182 item = new QTableWidgetItem(QString::fromUtf8(RQ_("?stat:Nations")));
183 stats->setItem(1, 3, item);
184 item = new QTableWidgetItem("-");
185 stats->setItem(1, 4, item);
186 item = new QTableWidgetItem(QString::fromUtf8(RQ_("?stat:Styles")));
187 stats->setItem(2, 3, item);
188 item = new QTableWidgetItem("-");
189 stats->setItem(2, 4, item);
190 item = new QTableWidgetItem(QString::fromUtf8(RQ_("?stat:Specialists")));
191 stats->setItem(3, 3, item);
192 item = new QTableWidgetItem("-");
193 stats->setItem(3, 4, item);
194 item = new QTableWidgetItem(QString::fromUtf8(RQ_("?stat:Governments")));
195 stats->setItem(4, 3, item);
196 item = new QTableWidgetItem("-");
197 stats->setItem(4, 4, item);
198 item = new QTableWidgetItem(QString::fromUtf8(RQ_("?stat:Disasters")));
199 stats->setItem(5, 3, item);
200 item = new QTableWidgetItem("-");
201 stats->setItem(5, 4, item);
202 item = new QTableWidgetItem(QString::fromUtf8(RQ_("?stat:Achievements")));
203 stats->setItem(0, 6, item);
204 item = new QTableWidgetItem("-");
205 stats->setItem(0, 7, item);
206 item = new QTableWidgetItem(QString::fromUtf8(RQ_("?stat:Extras")));
207 stats->setItem(1, 6, item);
208 item = new QTableWidgetItem("-");
209 stats->setItem(1, 7, item);
210 item = new QTableWidgetItem(QString::fromUtf8(RQ_("?stat:Bases")));
211 stats->setItem(2, 6, item);
212 item = new QTableWidgetItem("-");
213 stats->setItem(2, 7, item);
214 item = new QTableWidgetItem(QString::fromUtf8(RQ_("?stat:Roads")));
215 stats->setItem(3, 6, item);
216 item = new QTableWidgetItem("-");
217 stats->setItem(3, 7, item);
218 item = new QTableWidgetItem(QString::fromUtf8(RQ_("?stat:Goods")));
219 stats->setItem(4, 6, item);
220 item = new QTableWidgetItem("-");
221 stats->setItem(4, 7, item);
222 item = new QTableWidgetItem(QString::fromUtf8(RQ_("?stat:Multipliers")));
223 stats->setItem(5, 6, item);
224 item = new QTableWidgetItem("-");
225 stats->setItem(5, 7, item);
226 item = new QTableWidgetItem(QString::fromUtf8(RQ_("?stat:Effects")));
227 stats->setItem(6, 6, item);
228 item = new QTableWidgetItem("-");
229 stats->setItem(6, 7, item);
230 stats->verticalHeader()->setVisible(false);
231 stats->horizontalHeader()->setVisible(false);
232 stats->setEditTriggers(QAbstractItemView::NoEditTriggers);
233 main_layout->addWidget(stats, row++, 0, 1, 2);
234 button = new QPushButton(QString::fromUtf8(R__("Refresh Stats")), this);
235 connect(button, SIGNAL(pressed()), this, SLOT(refresh_stats()));
236 main_layout->addWidget(button, row++, 0, 1, 2);
237
238 refresh();
239
240 setLayout(main_layout);
241}
242
243/**********************************************************************/
247{
248 if (game.server.ruledit.description_file != NULL) {
249 desc_via_file->setChecked(true);
251 } else {
252 desc_file->setEnabled(false);
253 }
254
255 refresh();
256}
257
258/**********************************************************************/
262{
263 name->setText(game.control.name);
264 version->setText(game.control.version);
266}
267
268/**********************************************************************/
272{
273 char nameUTF8[MAX_LEN_NAME];
274 QString full_dir;
275 QByteArray ba_bytes;
276
277 ui->flush_widgets();
278
279 ba_bytes = name->text().toUtf8();
280 strncpy(nameUTF8, ba_bytes.data(), sizeof(nameUTF8) - 1);
281
282 if (nameUTF8[0] != '\0') {
283 strncpy(game.control.name, nameUTF8, sizeof(game.control.name));
284 }
285
286 ba_bytes = version->text().toUtf8();
287 strncpy(game.control.version, ba_bytes.data(),
288 sizeof(game.control.version) - 1);
289
291 QMessageBox *box = new QMessageBox();
292
293 box->setText("Current data fails sanity checks. Save anyway?");
294 box->setStandardButtons(QMessageBox::Yes | QMessageBox::No);
295 box->exec();
296
297 if (box->result() != QMessageBox::Yes) {
298 return;
299 }
300 }
301
302 if (savedir_version->isChecked()) {
303 full_dir = savedir->text() + "-" + version->text();
304 } else {
305 full_dir = savedir->text();
306 }
307
308 ba_bytes = full_dir.toUtf8();
309 save_ruleset(ba_bytes.data(), nameUTF8,
310 &(ui->data));
311
312 ui->display_msg(R__("Ruleset saved"));
313}
314
315/**********************************************************************/
322static bool effect_counter(struct effect *peff, void *data)
323{
324 (*(int *)data)++;
325
326 return TRUE;
327}
328
329/**********************************************************************/
333{
334 int row = 0;
335 int count;
336 int base_count;
337 int road_count;
338
339 count = 0;
341 count++;
343 stats->item(row++, 1)->setText(QString::number(count));
344
345 stats->item(row++, 1)->setText(QString::number(game.control.num_resource_types));
346
347 count = 0;
349 count++;
351 stats->item(row++, 1)->setText(QString::number(count));
352
353 count = 0;
355 count++;
357 stats->item(row++, 1)->setText(QString::number(count));
358
359 count = 0;
361 count++;
363 stats->item(row++, 1)->setText(QString::number(count));
364
365 count = 0;
367 count++;
369 stats->item(row++, 1)->setText(QString::number(count));
370
371 count = 0;
372 action_iterate(act) {
374 count++;
377 stats->item(row++, 1)->setText(QString::number(count));
378
379 // Second column
380 row = 0;
381 count = 0;
383 count++;
385 stats->item(row++, 4)->setText(QString::number(count));
386
387 stats->item(row++, 4)->setText(QString::number(game.control.nation_count));
388
389 count = 0;
391 count++;
393 stats->item(row++, 4)->setText(QString::number(count));
394
395 count = 0;
397 count++;
399 stats->item(row++, 4)->setText(QString::number(count));
400
401 count = 0;
403 count++;
405 stats->item(row++, 4)->setText(QString::number(count));
406
407 stats->item(row++, 4)->setText(QString::number(game.control.num_disaster_types));
408
409 // Third column
410 row = 0;
411
412 count = 0;
414 count++;
416 stats->item(row++, 7)->setText(QString::number(count));
417
418 count = 0;
419 base_count = 0;
420 road_count = 0;
422 count++;
423 if (is_extra_caused_by(pextra, EC_BASE)) {
424 base_count++;
425 }
426 if (is_extra_caused_by(pextra, EC_ROAD)) {
427 road_count++;
428 }
430 stats->item(row++, 7)->setText(QString::number(count));
431 stats->item(row++, 7)->setText(QString::number(base_count));
432 stats->item(row++, 7)->setText(QString::number(road_count));
433
434 count = 0;
436 count++;
438 stats->item(row++, 7)->setText(QString::number(count));
439
440 count = 0;
442 count++;
444 stats->item(row++, 7)->setText(QString::number(count));
445
446 count = 0;
448 stats->item(row++, 7)->setText(QString::number(count));
449
450 stats->resizeColumnsToContents();
451}
452
453/**********************************************************************/
457{
458 ui->open_effect_edit(QString::fromUtf8(R__("Always active")),
459 nullptr, EFMC_NONE);
460}
461
463
464/**********************************************************************/
467static void sanity_log_cb(const char *msg)
468{
469 sanitylog->add(msg);
470}
471
472/**********************************************************************/
476{
477 struct rscompat_info compat_info;
478
479 sanitylog = new conversion_log(QString::fromUtf8(R__("Sanity Check")));
480
481 rscompat_init_info(&compat_info);
482 compat_info.compat_mode = FALSE;
483 compat_info.log_cb = sanity_log_cb;
484
485 if (!sanity_check_ruleset_data(&compat_info)) {
486 ui->display_msg(R__("Sanity check failed!"));
487 } else {
488 ui->display_msg(R__("Sanity check success"));
489 }
490}
491
492/**********************************************************************/
496{
497 ui->open_effect_edit(QString::fromUtf8(R__("All effects")),
498 nullptr, EFMC_ALL);
499}
500
501/**********************************************************************/
505{
506 if (desc_via_file->isChecked()) {
507 QByteArray df_bytes;
508
509 df_bytes = desc_file->text().toUtf8();
510 game.server.ruledit.description_file = fc_strdup(df_bytes.data());
511 } else {
512 if (game.server.ruledit.description_file != NULL) {
514 }
516 }
517}
518
519/**********************************************************************/
523{
524 desc_file->setEnabled(checked);
525}
#define achievements_re_active_iterate(_p)
#define achievements_re_active_iterate_end
struct action_enabler_list * action_enablers_for_action(action_id action)
Definition actions.c:2475
#define action_enabler_list_re_iterate_end
Definition actions.h:463
#define action_enabler_list_re_iterate(action_enabler_list, aenabler)
Definition actions.h:459
#define action_iterate_end
Definition actions.h:472
#define action_iterate(_act_)
Definition actions.h:467
Base_type_id base_count(void)
Definition base.c:109
void add(const char *msg)
void flush_widgets()
struct rule_data data
Definition ruledit_qt.h:117
void display_msg(const char *msg)
void open_effect_edit(QString target, struct universal *uni, enum effect_filter_main_class efmc)
void edit_aae_effects()
Definition tab_misc.cpp:456
ruledit_gui * ui
Definition tab_misc.h:45
void desc_file_toggle(bool checked)
Definition tab_misc.cpp:522
QLineEdit * savedir
Definition tab_misc.h:48
void save_now()
Definition tab_misc.cpp:271
QLineEdit * name
Definition tab_misc.h:46
QLineEdit * desc_file
Definition tab_misc.h:52
QCheckBox * desc_via_file
Definition tab_misc.h:51
void edit_all_effects()
Definition tab_misc.cpp:495
void flush_widgets()
Definition tab_misc.cpp:504
void refresh_stats()
Definition tab_misc.cpp:332
QCheckBox * savedir_version
Definition tab_misc.h:49
void ruleset_loaded()
Definition tab_misc.cpp:246
QTableWidget * stats
Definition tab_misc.h:50
QLineEdit * version
Definition tab_misc.h:47
tab_misc(ruledit_gui *ui_in)
Definition tab_misc.cpp:56
void sanity_check()
Definition tab_misc.cpp:475
void refresh()
Definition tab_misc.cpp:261
@ EFMC_ALL
Definition effect_edit.h:35
@ EFMC_NONE
Definition effect_edit.h:34
bool iterate_effect_cache(iec_cb cb, void *data)
Definition effects.c:1245
#define is_extra_caused_by(e, c)
Definition extras.h:196
#define extra_type_re_active_iterate_end
Definition extras.h:305
#define extra_type_re_active_iterate(_p)
Definition extras.h:301
#define MAX_LEN_NAME
Definition fc_types.h:66
#define RQ_(String)
Definition fcintl.h:76
#define R__(String)
Definition fcintl.h:75
struct civ_game game
Definition game.c:57
#define governments_re_active_iterate(_p)
Definition government.h:126
#define governments_re_active_iterate_end
Definition government.h:130
#define improvement_re_active_iterate_end
#define improvement_re_active_iterate(_p)
#define fc_strdup(str)
Definition mem.h:43
#define multipliers_re_active_iterate(_mul_)
Definition multipliers.h:71
#define multipliers_re_active_iterate_end
Definition multipliers.h:75
Road_type_id road_count(void)
Definition road.c:50
void rscompat_init_info(struct rscompat_info *info)
Definition rscompat.c:56
bool sanity_check_ruleset_data(struct rscompat_info *compat)
Definition rssanity.c:861
bool autoadjust_ruleset_data(void)
Definition rssanity.c:1542
bool save_ruleset(const char *path, const char *name, struct rule_data *data)
Definition rulesave.c:3131
char * freeciv_storage_dir(void)
Definition shared.c:672
#define DIR_SEPARATOR
Definition shared.h:127
#define specialist_type_re_active_iterate_end
Definition specialist.h:88
#define specialist_type_re_active_iterate(_p)
Definition specialist.h:83
struct civ_game::@30::@34 server
char * description_file
Definition game.h:273
struct packet_ruleset_control control
Definition game.h:83
struct civ_game::@30::@34::@39 ruledit
Definition climisc.h:82
char version[MAX_LEN_NAME]
char name[MAX_LEN_NAME]
bool compat_mode
Definition rscompat.h:30
rs_conversion_logger log_cb
Definition rscompat.h:31
#define styles_re_active_iterate_end
Definition style.h:60
#define styles_re_active_iterate(_p)
Definition style.h:56
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:969
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
static conversion_log * sanitylog
Definition tab_misc.cpp:462
static void sanity_log_cb(const char *msg)
Definition tab_misc.cpp:467
static bool effect_counter(struct effect *peff, void *data)
Definition tab_misc.cpp:322
#define advance_re_active_iterate(_p)
Definition tech.h:275
#define tech_class_re_active_iterate(_p)
Definition tech.h:208
#define advance_re_active_iterate_end
Definition tech.h:279
#define tech_class_re_active_iterate_end
Definition tech.h:212
#define terrain_re_active_iterate_end
Definition terrain.h:373
#define terrain_re_active_iterate(_p)
Definition terrain.h:369
#define goods_type_re_active_iterate_end
#define goods_type_re_active_iterate(_p)
#define unit_type_re_active_iterate(_p)
Definition unittype.h:853
#define unit_class_re_active_iterate_end
Definition unittype.h:895
#define unit_class_re_active_iterate(_p)
Definition unittype.h:891
#define unit_type_re_active_iterate_end
Definition unittype.h:857