Freeciv-3.1
Loading...
Searching...
No Matches
tab_enablers.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// Qt
19#include <QGridLayout>
20#include <QLineEdit>
21#include <QListWidget>
22#include <QMenu>
23#include <QMessageBox>
24#include <QPushButton>
25#include <QToolButton>
26
27// utility
28#include "fcintl.h"
29#include "log.h"
30
31// common
32#include "game.h"
33#include "government.h"
34
35// ruledit
36#include "ruledit.h"
37#include "ruledit_qt.h"
38#include "validity.h"
39
40#include "tab_enablers.h"
41
43{
44public:
45 explicit fix_enabler_item(struct action_enabler *enabler);
46 virtual ~fix_enabler_item();
47 void close();
48
49 const void *item();
50 void *item_working_copy();
51 const char *name();
55 int num_vectors();
58 bool vector_in_item(const struct requirement_vector *vec);
59
60private:
63 QString my_name;
64};
65
66/**********************************************************************/
73{
74 struct req_vec_problem *problem = action_enabler_suggest_repair(enabler);
75
76 if (problem != NULL) {
77 req_vec_problem_free(problem);
78 return RVPS_REPAIR;
79 }
80
81 problem = action_enabler_suggest_improvement(enabler);
82 if (problem != NULL) {
83 req_vec_problem_free(problem);
84 return RVPS_IMPROVE;
85 }
86
87 return RVPS_NO_PROBLEM;
88}
89
90/**********************************************************************/
94{
95 QVBoxLayout *main_layout = new QVBoxLayout(this);
96 QGridLayout *enabler_layout = new QGridLayout();
97 QLabel *label;
98 QPushButton *add_button;
99
100 ui = ui_in;
101 connect(ui, SIGNAL(req_vec_may_have_changed(const requirement_vector *)),
102 this, SLOT(incoming_req_vec_change(const requirement_vector *)));
103
104 selected = 0;
105
106 enabler_list = new QListWidget(this);
107
108 connect(enabler_list, SIGNAL(itemSelectionChanged()), this, SLOT(select_enabler()));
109 main_layout->addWidget(enabler_list);
110
111 enabler_layout->setSizeConstraint(QLayout::SetMaximumSize);
112
113 label = new QLabel(QString::fromUtf8(R__("Type")));
114 label->setParent(this);
115 enabler_layout->addWidget(label, 0, 0);
116
117 type_button = new QToolButton();
118 type_menu = new QMenu();
119
120 action_iterate(act) {
121 type_menu->addAction(action_id_rule_name(act));
123
124 connect(type_menu, SIGNAL(triggered(QAction *)),
125 this, SLOT(edit_type(QAction *)));
126
127 type_button->setToolButtonStyle(Qt::ToolButtonTextOnly);
128 type_button->setPopupMode(QToolButton::MenuButtonPopup);
129
130 type_button->setMenu(type_menu);
131 type_button->setText(R__("None"));
132
133 type_button->setEnabled(false);
134 enabler_layout->addWidget(type_button, 0, 2);
135
137 = new QPushButton(QString::fromUtf8(R__("Actor Requirements")), this);
138 connect(act_reqs_button, SIGNAL(pressed()),
139 this, SLOT(edit_actor_reqs()));
140 act_reqs_button->setEnabled(false);
141 enabler_layout->addWidget(act_reqs_button, 1, 2);
142
144 = new QPushButton(QString::fromUtf8(R__("Target Requirements")),
145 this);
146 connect(tgt_reqs_button, SIGNAL(pressed()),
147 this, SLOT(edit_target_reqs()));
148 tgt_reqs_button->setEnabled(false);
149 enabler_layout->addWidget(tgt_reqs_button, 2, 2);
150
151 add_button = new QPushButton(QString::fromUtf8(R__("Add Enabler")), this);
152 connect(add_button, SIGNAL(pressed()), this, SLOT(add_now()));
153 enabler_layout->addWidget(add_button, 3, 0);
154 show_experimental(add_button);
155
156 delete_button = new QPushButton(QString::fromUtf8(R__("Remove this Enabler")), this);
157 connect(delete_button, SIGNAL(pressed()), this, SLOT(delete_now()));
158 delete_button->setEnabled(false);
159 enabler_layout->addWidget(delete_button, 3, 2);
161
162 repair_button = new QPushButton(this);
163 connect(repair_button, SIGNAL(pressed()), this, SLOT(repair_now()));
164 repair_button->setEnabled(false);
165 repair_button->setText(QString::fromUtf8(R__("Enabler Issues")));
166 enabler_layout->addWidget(repair_button, 3, 1);
167
168 refresh();
169
170 main_layout->addLayout(enabler_layout);
171
172 setLayout(main_layout);
173}
174
175/**********************************************************************/
179{
180 int n = 0;
181
182 enabler_list->clear();
183
184 action_enablers_iterate(enabler) {
185 if (!enabler->ruledit_disabled) {
186 char buffer[512];
187 QListWidgetItem *item;
188
189 fc_snprintf(buffer, sizeof(buffer), "#%d: %s", n,
191
192 item = new QListWidgetItem(QString::fromUtf8(buffer));
193
194 enabler_list->insertItem(n++, item);
195
197
198 item->setSelected(enabler == selected);
199 }
201}
202
203/**********************************************************************/
207{
208 int i = 0;
209
210 selected = enabler;
211
212 if (selected != nullptr) {
213 QString dispn = QString::fromUtf8(action_rule_name(enabler_get_action(enabler)));
214
215 type_button->setText(dispn);
216
217 type_button->setEnabled(true);
218 act_reqs_button->setEnabled(true);
219 tgt_reqs_button->setEnabled(true);
220
221 delete_button->setEnabled(true);
222
224 case RVPS_REPAIR:
225 /* Offer to repair the enabler if it has a problem. */
226 /* TRANS: Fix an error in an action enabler. */
227 repair_button->setText(QString::fromUtf8(R__("Repair Enabler")));
228 repair_button->setEnabled(TRUE);
229 break;
230 case RVPS_IMPROVE:
231 /* TRANS: Fix a non error issue in an action enabler. */
232 repair_button->setText(QString::fromUtf8(R__("Improve Enabler")));
233 repair_button->setEnabled(true);
234 break;
235 case RVPS_NO_PROBLEM:
236 repair_button->setText(QString::fromUtf8(R__("Enabler Issues")));
237 repair_button->setEnabled(false);
238 break;
239 }
240 } else {
241 type_button->setText(R__("None"));
242 type_button->setEnabled(false);
243
244 act_reqs_button->setEnabled(false);
245 tgt_reqs_button->setEnabled(false);
246
247 repair_button->setEnabled(false);
248 repair_button->setText(QString::fromUtf8(R__("Enabler Issues")));
249
250 delete_button->setEnabled(false);
251 }
252
253 /* The enabler may have gotten (rid of) a problem. */
254 action_enablers_iterate(other_enabler) {
255 QListWidgetItem *item = enabler_list->item(i++);
256
257 if (item == nullptr) {
258 continue;
259 }
260
261 mark_item(item, enabler_problem_level(other_enabler));
263}
264
265/**********************************************************************/
269{
270 int i = 0;
271
272 action_enablers_iterate(enabler) {
273 QListWidgetItem *item = enabler_list->item(i++);
274
275 if (item != nullptr && item->isSelected()) {
276 update_enabler_info(enabler);
277 }
279}
280
281/**********************************************************************/
285{
286 if (selected != nullptr) {
289
290 refresh();
291 update_enabler_info(nullptr);
292 }
293}
294
295/**********************************************************************/
299{
300 return true;
301}
302
303/**********************************************************************/
307{
308 struct action_enabler *new_enabler;
309
310 // Try to reuse freed enabler slot
311 action_enablers_iterate(enabler) {
312 if (enabler->ruledit_disabled) {
313 if (initialize_new_enabler(enabler)) {
314 enabler->ruledit_disabled = false;
315 update_enabler_info(enabler);
316 refresh();
317 }
318 return;
319 }
321
322 // Try to add completely new enabler
323 new_enabler = action_enabler_new();
324
327 new_enabler->action = (NUM_ACTIONS - 1);
328
329 action_enabler_add(new_enabler);
330
331 update_enabler_info(new_enabler);
332 refresh();
333}
334
335/**********************************************************************/
339{
340 if (selected == nullptr) {
341 /* Nothing to repair */
342 return;
343 }
344
346}
347
348/**********************************************************************/
352void tab_enabler::incoming_req_vec_change(const requirement_vector *vec)
353{
354 action_enablers_iterate(enabler) {
355 if (&enabler->actor_reqs == vec || &enabler->target_reqs == vec) {
356 update_enabler_info(enabler);
357 }
359}
360
361/**********************************************************************/
365{
366 struct action *paction;
367 QByteArray an_bytes;
368
369 an_bytes = action->text().toUtf8();
370 paction = action_by_rule_name(an_bytes.data());
371
372 if (selected != nullptr && paction != nullptr) {
373 /* Must remove and add back because enablers are stored by action. */
375 selected->action = paction->id;
377
378 /* Show the changes. */
380 refresh();
381 }
382}
383
384/**********************************************************************/
388{
389 if (selected != nullptr) {
390 ui->open_req_edit(QString::fromUtf8(R__("Enabler (target)")),
392 }
393}
394
395/**********************************************************************/
399{
400 if (selected != nullptr) {
401 ui->open_req_edit(QString::fromUtf8(R__("Enabler (actor)")),
403 }
404}
405
406/**********************************************************************/
411{
412 char buf[MAX_LEN_NAME * 2];
413 struct action *paction = action_by_number(enabler->action);
414
415 fc_assert_ret(paction);
416
417 /* Can't use QString::asprintf() as msys libintl.h defines asprintf()
418 * as a macro */
419 fc_snprintf(buf, sizeof(buf),
420 R__("action enabler for %s"), action_rule_name(paction));
421
422 /* Don't modify the original until the user accepts */
424 current_enabler = enabler;
425
426 /* As precise a title as possible */
427 my_name = QString(buf);
428}
429
430/**********************************************************************/
437
438/********************************************************************/
442{
443 delete this;
444}
445
446/********************************************************************/
451{
452 return current_enabler;
453}
454
455/********************************************************************/
463
464/**********************************************************************/
471{
472 return my_name.toUtf8().data();
473}
474
475/**********************************************************************/
482{
484
485 if (out != NULL) {
486 return out;
487 }
488
490}
491
492/**********************************************************************/
499{
500 /* The user has approved the solution */
502 requirement_vector_copy(&current_enabler->actor_reqs,
504 requirement_vector_copy(&current_enabler->target_reqs,
506}
507
508/**********************************************************************/
514{
515 /* The user has rejected all solutions */
517 requirement_vector_copy(&local_copy->actor_reqs,
519 requirement_vector_copy(&local_copy->target_reqs,
521}
522
523/********************************************************************/
528{
529 return 2;
530}
531
532/********************************************************************/
542
543/********************************************************************/
553
554/**********************************************************************/
559bool fix_enabler_item::vector_in_item(const struct requirement_vector *vec)
560{
561 return (&current_enabler->actor_reqs == vec
562 || &current_enabler->target_reqs == vec);
563}
struct req_vec_problem * action_enabler_suggest_repair(const struct action_enabler *enabler)
Definition actions.c:2838
struct req_vec_problem * action_enabler_suggest_improvement(const struct action_enabler *enabler)
Definition actions.c:2904
const char * action_enabler_vector_by_number_name(req_vec_num_in_item vec)
Definition actions.c:3015
struct action * action_by_rule_name(const char *name)
Definition actions.c:1708
const char * action_rule_name(const struct action *action)
Definition actions.c:1876
const char * action_id_rule_name(action_id act_id)
Definition actions.c:1899
void action_enabler_free(struct action_enabler *enabler)
Definition actions.c:2415
void action_enabler_add(struct action_enabler *enabler)
Definition actions.c:2442
struct action_enabler * action_enabler_new(void)
Definition actions.c:2396
bool action_id_exists(const action_id act_id)
Definition actions.c:1697
bool action_enabler_remove(struct action_enabler *enabler)
Definition actions.c:2459
struct action_enabler * action_enabler_copy(const struct action_enabler *original)
Definition actions.c:2427
struct requirement_vector * action_enabler_vector_by_number(const void *enabler, req_vec_num_in_item number)
Definition actions.c:2991
#define action_enablers_iterate_end
Definition actions.h:526
#define enabler_get_action(_enabler_)
Definition actions.h:450
static struct action * action_by_number(action_id act_id)
Definition actions.h:638
#define NUM_ACTIONS
Definition actions.h:297
#define action_iterate_end
Definition actions.h:472
#define action_enablers_iterate(_enabler_)
Definition actions.h:520
#define action_iterate(_act_)
Definition actions.h:467
#define n
Definition astring.c:77
fix_enabler_item(struct action_enabler *enabler)
void apply_accepted_changes()
struct req_vec_problem * find_next_problem(void)
bool vector_in_item(const struct requirement_vector *vec)
requirement_vector_namer vector_namer()
virtual ~fix_enabler_item()
struct action_enabler * local_copy
const void * item()
struct action_enabler * current_enabler
requirement_vector_by_number vector_getter()
void * item_working_copy()
const char * name()
void open_req_vec_fix(req_vec_fix_item *item_info)
void open_req_edit(QString target, struct requirement_vector *preqs)
ruledit_gui * ui
void incoming_req_vec_change(const requirement_vector *vec)
void edit_type(QAction *action)
struct action_enabler * selected
QPushButton * act_reqs_button
QToolButton * type_button
void edit_actor_reqs()
tab_enabler(ruledit_gui *ui_in)
QPushButton * tgt_reqs_button
QMenu * type_menu
void edit_target_reqs()
void select_enabler()
QListWidget * enabler_list
QPushButton * delete_button
bool initialize_new_enabler(struct action_enabler *enabler)
QPushButton * repair_button
void update_enabler_info(struct action_enabler *enabler)
#define MAX_LEN_NAME
Definition fc_types.h:66
#define R__(String)
Definition fcintl.h:75
#define fc_assert_ret(condition)
Definition log.h:191
void mark_item(QListWidgetItem *item, enum req_vec_problem_seriousness problem_level)
req_vec_problem_seriousness
Definition req_vec_fix.h:35
@ RVPS_NO_PROBLEM
Definition req_vec_fix.h:36
@ RVPS_REPAIR
Definition req_vec_fix.h:38
@ RVPS_IMPROVE
Definition req_vec_fix.h:37
void req_vec_problem_free(struct req_vec_problem *issue)
const char *(* requirement_vector_namer)(req_vec_num_in_item number)
struct requirement_vector *(* requirement_vector_by_number)(const void *parent_item, req_vec_num_in_item number)
void show_experimental(QWidget *wdg)
Definition ruledit.cpp:216
bool ruledit_disabled
Definition actions.h:445
action_id action
Definition actions.h:439
struct requirement_vector actor_reqs
Definition actions.h:440
struct requirement_vector target_reqs
Definition actions.h:441
action_id id
Definition actions.h:380
Definition climisc.h:82
struct universal item
Definition climisc.h:83
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:969
#define TRUE
Definition support.h:46
static enum req_vec_problem_seriousness enabler_problem_level(struct action_enabler *enabler)