Freeciv21
Develop your civilization from humble roots to a global empire
tab_good.cpp
Go to the documentation of this file.
1 /*__ ___ ***************************************
2 / \ / \ Copyright (c) 1996-2020 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 // Qt
15 #include <QGridLayout>
16 #include <QLineEdit>
17 #include <QListWidget>
18 #include <QMenu>
19 #include <QPushButton>
20 #include <QRadioButton>
21 
22 // utility
23 #include "fcintl.h"
24 
25 // common
26 #include "game.h"
27 #include "improvement.h"
28 
29 // ruledit
30 #include "req_edit.h"
31 #include "ruledit.h"
32 #include "ruledit_qt.h"
33 #include "validity.h"
34 
35 #include "tab_good.h"
36 
40 tab_good::tab_good(ruledit_gui *ui_in) : QWidget()
41 {
42  QVBoxLayout *main_layout = new QVBoxLayout(this);
43  QGridLayout *good_layout = new QGridLayout();
44  QLabel *label;
45  QPushButton *effects_button;
46  QPushButton *add_button;
47  QPushButton *delete_button;
48  QPushButton *reqs_button;
49 
50  ui = ui_in;
51  selected = 0;
52 
53  good_list = new QListWidget(this);
54 
55  connect(good_list, &QListWidget::itemSelectionChanged, this,
57  main_layout->addWidget(good_list);
58 
59  good_layout->setSizeConstraint(QLayout::SetMaximumSize);
60 
61  label = new QLabel(QString::fromUtf8(R__("Rule Name")));
62  label->setParent(this);
63  rname = new QLineEdit(this);
64  rname->setText(QStringLiteral("None"));
65  connect(rname, &QLineEdit::returnPressed, this, &tab_good::name_given);
66  good_layout->addWidget(label, 0, 0);
67  good_layout->addWidget(rname, 0, 2);
68 
69  label = new QLabel(QString::fromUtf8(R__("Name")));
70  label->setParent(this);
71  same_name = new QRadioButton();
72  connect(same_name, &QAbstractButton::toggled, this,
74  name = new QLineEdit(this);
75  name->setText(QStringLiteral("None"));
76  connect(name, &QLineEdit::returnPressed, this, &tab_good::name_given);
77  good_layout->addWidget(label, 1, 0);
78  good_layout->addWidget(same_name, 1, 1);
79  good_layout->addWidget(name, 1, 2);
80 
81  reqs_button =
82  new QPushButton(QString::fromUtf8(R__("Requirements")), this);
83  connect(reqs_button, &QAbstractButton::pressed, this,
85  good_layout->addWidget(reqs_button, 2, 2);
86 
87  effects_button = new QPushButton(QString::fromUtf8(R__("Effects")), this);
88  connect(effects_button, &QAbstractButton::pressed, this,
90  good_layout->addWidget(effects_button, 3, 2);
91 
92  add_button = new QPushButton(QString::fromUtf8(R__("Add Good")), this);
93  connect(add_button, &QAbstractButton::pressed, this, &tab_good::add_now);
94  good_layout->addWidget(add_button, 4, 0);
95  show_experimental(add_button);
96 
97  delete_button =
98  new QPushButton(QString::fromUtf8(R__("Remove this Good")), this);
99  connect(delete_button, &QAbstractButton::pressed, this,
101  good_layout->addWidget(delete_button, 4, 2);
102  show_experimental(delete_button);
103 
104  refresh();
105 
106  main_layout->addLayout(good_layout);
107 
108  setLayout(main_layout);
109 }
110 
115 {
116  good_list->clear();
117 
118  goods_type_iterate(pgood)
119  {
120  if (!pgood->ruledit_disabled) {
121  QListWidgetItem *item =
122  new QListWidgetItem(QString::fromUtf8(goods_rule_name(pgood)));
123 
124  good_list->insertItem(goods_index(pgood), item);
125  }
126  }
128 }
129 
134 {
135  selected = pgood;
136 
137  if (selected != 0) {
138  QString dispn = QString::fromUtf8(untranslated_name(&(pgood->name)));
139  QString rulen = QString::fromUtf8(goods_rule_name(pgood));
140 
141  name->setText(dispn);
142  rname->setText(rulen);
143  if (dispn == rulen) {
144  name->setEnabled(false);
145  same_name->setChecked(true);
146  } else {
147  same_name->setChecked(false);
148  name->setEnabled(true);
149  }
150  } else {
151  name->setText(QStringLiteral("None"));
152  rname->setText(QStringLiteral("None"));
153  same_name->setChecked(true);
154  name->setEnabled(false);
155  }
156 }
157 
162 {
163  QList<QListWidgetItem *> select_list = good_list->selectedItems();
164 
165  if (!select_list.isEmpty()) {
166  QByteArray gn_bytes;
167 
168  gn_bytes = select_list.at(0)->text().toUtf8();
169  update_good_info(goods_by_rule_name(gn_bytes.data()));
170  }
171 }
172 
177 {
178  if (selected != nullptr) {
179  QByteArray name_bytes;
180  QByteArray rname_bytes;
181 
182  goods_type_iterate(pgood)
183  {
184  if (pgood != selected && !pgood->ruledit_disabled) {
185  rname_bytes = rname->text().toUtf8();
186  if (!strcmp(goods_rule_name(pgood), rname_bytes.data())) {
187  ui->display_msg(R__("A good with that rule name already exists!"));
188  return;
189  }
190  }
191  }
193 
194  if (same_name->isChecked()) {
195  name->setText(rname->text());
196  }
197 
198  name_bytes = name->text().toUtf8();
199  rname_bytes = rname->text().toUtf8();
200  names_set(&(selected->name), 0, name_bytes.data(), rname_bytes.data());
201  refresh();
202  }
203 }
204 
209 {
210  if (selected != 0) {
211  requirers_dlg *requirers;
212 
215  return;
216  }
217 
218  selected->ruledit_disabled = true;
219 
220  refresh();
221  update_good_info(nullptr);
222  }
223 }
224 
229 {
230  if (goods_by_rule_name("New Good") != nullptr) {
231  return false;
232  }
233 
234  name_set(&(pgood->name), 0, "New Good");
235 
236  return true;
237 }
238 
243 {
244  struct goods_type *new_good;
245 
246  // Try to reuse freed good slot
247  goods_type_iterate(pgood)
248  {
249  if (pgood->ruledit_disabled) {
250  if (initialize_new_good(pgood)) {
251  pgood->ruledit_disabled = false;
252  update_good_info(pgood);
253  refresh();
254  }
255  return;
256  }
257  }
259 
260  // Try to add completely new good
261  if (game.control.num_goods_types >= MAX_GOODS_TYPES) {
262  return;
263  }
264 
265  // num_good_types must be big enough to hold new good or
266  // good_by_number() fails.
267  game.control.num_goods_types++;
268  new_good = goods_by_number(game.control.num_goods_types - 1);
269  if (initialize_new_good(new_good)) {
270  update_good_info(new_good);
271 
272  refresh();
273  } else {
274  game.control.num_goods_types--; // Restore
275  }
276 }
277 
281 void tab_good::same_name_toggle(bool checked)
282 {
283  name->setEnabled(!checked);
284  if (checked) {
285  name->setText(rname->text());
286  }
287 }
288 
293 {
294  if (selected != nullptr) {
295  req_edit *redit = new req_edit(
296  ui, QString::fromUtf8(goods_rule_name(selected)), &selected->reqs);
297 
298  redit->show();
299  }
300 }
301 
306 {
307  if (selected != nullptr) {
308  struct universal uni;
309 
310  uni.value.good = selected;
311  uni.kind = VUT_GOOD;
312 
313  ui->open_effect_edit(QString::fromUtf8(goods_rule_name(selected)), &uni,
314  EFMC_NORMAL);
315  }
316 }
void display_msg(const char *msg)
Display status message.
Definition: ruledit_qt.cpp:240
requirers_dlg * create_requirers(const char *title)
Create requirers dlg.
Definition: ruledit_qt.cpp:248
void open_effect_edit(const QString &target, struct universal *uni, enum effect_filter_main_class efmc)
Open effect_edit dialog.
Definition: ruledit_qt.cpp:350
QListWidget * good_list
Definition: tab_good.h:42
void edit_effects()
User wants to edit effects.
Definition: tab_good.cpp:305
struct goods_type * selected
Definition: tab_good.h:45
bool initialize_new_good(struct goods_type *pgood)
Initialize new good for use.
Definition: tab_good.cpp:228
QLineEdit * name
Definition: tab_good.h:40
tab_good(ruledit_gui *ui_in)
Setup tab_good object.
Definition: tab_good.cpp:40
QRadioButton * same_name
Definition: tab_good.h:43
void refresh()
Refresh the information.
Definition: tab_good.cpp:114
void select_good()
User selected good from the list.
Definition: tab_good.cpp:161
QLineEdit * rname
Definition: tab_good.h:41
void delete_now()
User requested good deletion.
Definition: tab_good.cpp:208
void name_given()
User entered name for the good.
Definition: tab_good.cpp:176
void edit_reqs()
User wants to edit reqs.
Definition: tab_good.cpp:292
void update_good_info(struct goods_type *pgood)
Update info of the good.
Definition: tab_good.cpp:133
void add_now()
User requested new good.
Definition: tab_good.cpp:242
ruledit_gui * ui
Definition: tab_good.h:36
void same_name_toggle(bool checked)
Toggled whether rule_name and name should be kept identical.
Definition: tab_good.cpp:281
@ EFMC_NORMAL
Definition: effect_edit.h:32
#define MAX_GOODS_TYPES
Definition: fc_types.h:45
#define R__(String)
Definition: fcintl.h:58
struct civ_game game
Definition: game.cpp:47
static void name_set(struct name_translation *ptrans, const char *domain, const char *vernacular_name)
static const char * untranslated_name(const struct name_translation *ptrans)
static void names_set(struct name_translation *ptrans, const char *domain, const char *vernacular_name, const char *rule_name)
void show_experimental(QWidget *wdg)
Show widget if experimental features enabled, hide otherwise.
Definition: ruledit.cpp:163
void ruledit_qt_display_requirers(const char *msg, void *data)
Display requirer list.
Definition: ruledit_qt.cpp:67
struct packet_ruleset_control control
Definition: game.h:74
struct requirement_vector reqs
Definition: traderoutes.h:185
bool ruledit_disabled
Definition: traderoutes.h:183
struct name_translation name
Definition: traderoutes.h:182
Definition: climisc.h:66
enum universals_n kind
Definition: fc_types.h:740
universals_u value
Definition: fc_types.h:739
struct goods_type * goods_by_number(Goods_type_id id)
Return goods type of given id.
const char * goods_rule_name(struct goods_type *pgood)
Return untranslated name of this goods type.
struct goods_type * goods_by_rule_name(const char *name)
Returns goods type matching rule name or nullptr if there is no goods type with such name.
Goods_type_id goods_index(const struct goods_type *pgood)
Return the goods index.
#define goods_type_iterate_end
Definition: traderoutes.h:224
#define goods_type_iterate(_p)
Definition: traderoutes.h:218
struct goods_type * good
Definition: fc_types.h:591
bool is_good_needed(struct goods_type *pgood, requirers_cb cb, void *data)
Check if anything in ruleset needs goods type.
Definition: validity.cpp:242