Freeciv21
Develop your civilization from humble roots to a global empire
req_edit.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 <QLabel>
17 #include <QLineEdit>
18 #include <QMenu>
19 #include <QPushButton>
20 
21 // utility
22 #include "fcintl.h"
23 
24 // common
25 #include "reqtext.h"
26 #include "requirements.h"
27 
28 // ruledit
29 #include "ruledit.h"
30 #include "ruledit_qt.h"
31 #include "univ_value.h"
32 
33 #include "req_edit.h"
34 
38 req_edit::req_edit(ruledit_gui *ui_in, const QString &target,
39  struct requirement_vector *preqs)
40  : QDialog()
41 {
42  QVBoxLayout *main_layout = new QVBoxLayout(this);
43  QGridLayout *reqedit_layout = new QGridLayout();
44  QHBoxLayout *active_layout = new QHBoxLayout();
45  QPushButton *close_button;
46  QPushButton *add_button;
47  QPushButton *delete_button;
48  QMenu *menu;
49  QLabel *lbl;
50 
51  ui = ui_in;
54 
56  req_vector = preqs;
57 
58  req_list = new QListWidget(this);
59 
60  connect(req_list, &QListWidget::itemSelectionChanged, this,
62  main_layout->addWidget(req_list);
63 
64  lbl = new QLabel(R__("Type:"));
65  active_layout->addWidget(lbl, 0);
66  edit_type_button = new QToolButton();
67  menu = new QMenu();
68  edit_type_button->setToolButtonStyle(Qt::ToolButtonTextOnly);
69  edit_type_button->setPopupMode(QToolButton::MenuButtonPopup);
70  connect(menu, &QMenu::triggered, this, &req_edit::req_type_menu);
71  edit_type_button->setMenu(menu);
72  universals_iterate(univ_id)
73  {
74  struct universal dummy;
75 
76  dummy.kind = univ_id;
77  if (universal_value_initial(&dummy)) {
78  menu->addAction(universals_n_name(univ_id));
79  }
80  }
82  active_layout->addWidget(edit_type_button, 1);
83 
84  lbl = new QLabel(R__("Value:"));
85  active_layout->addWidget(lbl, 2);
86  edit_value_enum_button = new QToolButton();
87  edit_value_enum_menu = new QMenu();
88  edit_value_enum_button->setToolButtonStyle(Qt::ToolButtonTextOnly);
89  edit_value_enum_button->setPopupMode(QToolButton::MenuButtonPopup);
90  connect(edit_value_enum_menu, &QMenu::triggered, this,
93  edit_value_enum_menu->setVisible(false);
94  active_layout->addWidget(edit_value_enum_button, 3);
95  edit_value_nbr_field = new QLineEdit();
96  edit_value_nbr_field->setVisible(false);
97  connect(edit_value_nbr_field, &QLineEdit::returnPressed, this,
99  active_layout->addWidget(edit_value_nbr_field, 4);
100 
101  lbl = new QLabel(R__("Range:"));
102  active_layout->addWidget(lbl, 5);
103  edit_range_button = new QToolButton();
104  menu = new QMenu();
105  edit_range_button->setToolButtonStyle(Qt::ToolButtonTextOnly);
106  edit_range_button->setPopupMode(QToolButton::MenuButtonPopup);
107  connect(menu, &QMenu::triggered, this, &req_edit::req_range_menu);
108  edit_range_button->setMenu(menu);
109  req_range_iterate(range_id) { menu->addAction(req_range_name(range_id)); }
111  active_layout->addWidget(edit_range_button, 6);
112 
113  edit_present_button = new QToolButton();
114  menu = new QMenu();
115  edit_present_button->setToolButtonStyle(Qt::ToolButtonTextOnly);
116  edit_present_button->setPopupMode(QToolButton::MenuButtonPopup);
117  connect(menu, &QMenu::triggered, this, &req_edit::req_present_menu);
118  edit_present_button->setMenu(menu);
119  menu->addAction(QStringLiteral("Allows"));
120  menu->addAction(QStringLiteral("Prevents"));
121  active_layout->addWidget(edit_present_button, 7);
122 
123  main_layout->addLayout(active_layout);
124 
125  add_button =
126  new QPushButton(QString::fromUtf8(R__("Add Requirement")), this);
127  connect(add_button, &QAbstractButton::pressed, this, &req_edit::add_now);
128  reqedit_layout->addWidget(add_button, 0, 0);
129 
130  delete_button =
131  new QPushButton(QString::fromUtf8(R__("Delete Requirement")), this);
132  connect(delete_button, &QAbstractButton::pressed, this,
134  reqedit_layout->addWidget(delete_button, 1, 0);
135 
136  close_button = new QPushButton(QString::fromUtf8(R__("Close")), this);
137  connect(close_button, &QAbstractButton::pressed, this,
139  reqedit_layout->addWidget(close_button, 2, 0);
140 
141  refresh();
142 
143  main_layout->addLayout(reqedit_layout);
144 
145  setLayout(main_layout);
146  setWindowTitle(target);
147 }
148 
153 {
154  int i = 0;
155 
156  req_list->clear();
157 
159  {
160  char buf[512];
161  QListWidgetItem *item;
162 
163  buf[0] = '\0';
164  if (!req_text_insert(buf, sizeof(buf), nullptr, preq, VERB_ACTUAL, "")) {
165  if (preq->present) {
166  universal_name_translation(&preq->source, buf, sizeof(buf));
167  } else {
168  char buf2[256];
169 
170  universal_name_translation(&preq->source, buf2, sizeof(buf2));
171  fc_snprintf(buf, sizeof(buf), "%s prevents", buf2);
172  }
173  }
174  item = new QListWidgetItem(QString::fromUtf8(buf));
175  req_list->insertItem(i++, item);
176  if (selected == preq) {
177  item->setSelected(true);
178  }
179  }
181 
182  fill_active();
183 }
184 
189 {
190  if (selected != nullptr) {
192  }
193 }
194 
199 {
200  selected = nullptr;
201 
202  selected_values.source.kind = VUT_NONE;
204  selected_values.range = REQ_RANGE_LOCAL;
205  selected_values.present = true;
206  selected_values.survives = false;
207  selected_values.quiet = false;
208 }
209 
214 {
215  ui->unregister_req_edit(this);
216  done(0);
217 }
218 
223 {
224  int i = 0;
225 
227  {
228  QListWidgetItem *item = req_list->item(i++);
229 
230  if (item != nullptr && item->isSelected()) {
231  selected = preq;
232  update_selected();
233  fill_active();
234  return;
235  }
236  }
238 }
239 
240 struct uvb_data {
241  QLineEdit *number;
242  QToolButton *enum_button;
243  QMenu *menu;
244  struct universal *univ;
245 };
246 
250 static void universal_value_cb(const char *value, bool current, void *cbdata)
251 {
252  struct uvb_data *data = (struct uvb_data *) cbdata;
253 
254  if (value == nullptr) {
255  int kind, val;
256 
257  universal_extraction(data->univ, &kind, &val);
258  data->number->setText(QString::number(val));
259  data->number->setVisible(true);
260  } else {
261  data->enum_button->setVisible(true);
262  data->menu->addAction(value);
263  if (current) {
264  data->enum_button->setText(value);
265  }
266  }
267 }
268 
273 {
274  if (selected != nullptr) {
275  struct uvb_data data;
276 
277  edit_type_button->setText(universals_n_name(selected->source.kind));
280  data.menu = edit_value_enum_menu;
281  data.univ = &selected->source;
282  edit_value_enum_menu->clear();
283  edit_value_enum_button->setVisible(false);
284  edit_value_nbr_field->setVisible(false);
286  edit_range_button->setText(req_range_name(selected->range));
287  if (selected->present) {
288  edit_present_button->setText(QStringLiteral("Allows"));
289  } else {
290  edit_present_button->setText(QStringLiteral("Prevents"));
291  }
292  }
293 }
294 
299 {
300  QByteArray un_bytes = action->text().toUtf8();
301  enum universals_n univ =
302  universals_n_by_name(un_bytes.data(), fc_strcasecmp);
303 
304  if (selected != nullptr) {
307  update_selected();
308  }
309 
310  refresh();
311 
313 }
314 
319 {
320  QByteArray un_bytes = action->text().toUtf8();
321  enum req_range range = req_range_by_name(un_bytes.data(), fc_strcasecmp);
322 
323  if (selected != nullptr) {
324  selected->range = range;
325  update_selected();
326  }
327 
328  refresh();
329 
331 }
332 
337 {
338  if (selected != nullptr) {
339  selected->present = action->text() != QLatin1String("Prevents");
340  update_selected();
341  }
342 
343  refresh();
344 
346 }
347 
352 {
353  if (selected != nullptr) {
354  QByteArray un_bytes = action->text().toUtf8();
355 
356  universal_value_from_str(&selected->source, un_bytes.data());
357 
358  update_selected();
359  refresh();
360 
362  }
363 }
364 
369 {
370  if (selected != nullptr) {
371  QByteArray num_bytes = edit_value_nbr_field->text().toUtf8();
372 
373  universal_value_from_str(&selected->source, num_bytes.data());
374 
375  update_selected();
376  refresh();
377 
379  }
380 }
381 
386 {
387  struct requirement new_req;
388 
389  new_req =
390  req_from_values(VUT_NONE, REQ_RANGE_LOCAL, false, true, false, 0);
391 
392  requirement_vector_append(req_vector, new_req);
393 
394  refresh();
395 
397 }
398 
403 {
404  if (selected != nullptr) {
405  size_t i;
406 
407  for (i = 0; i < requirement_vector_size(req_vector); i++) {
408  if (requirement_vector_get(req_vector, i) == selected) {
409  requirement_vector_remove(req_vector, i);
410  break;
411  }
412  }
413 
414  clear_selected();
415 
416  refresh();
417 
419  }
420 }
421 
426 void req_edit::incoming_rec_vec_change(const requirement_vector *vec)
427 {
428  if (req_vector == vec) {
429  // The selected requirement may be gone
430 
431  selected = nullptr;
433  {
435  selected = preq;
436  break;
437  }
438  }
440 
441  if (selected == nullptr) {
442  // The currently selected requirement was deleted.
443  clear_selected();
444  }
445 
446  refresh();
447  }
448 }
449 
453 void req_edit::closeEvent(QCloseEvent *event)
454 {
455  ui->unregister_req_edit(this);
456 }
struct requirement_vector * req_vector
Definition: req_edit.h:38
ruledit_gui * ui
Definition: req_edit.h:48
void req_present_menu(QAction *action)
User selected 'present' value for the requirement.
Definition: req_edit.cpp:336
void delete_now()
User requested requirement deletion.
Definition: req_edit.cpp:402
QToolButton * edit_value_enum_button
Definition: req_edit.h:58
QToolButton * edit_present_button
Definition: req_edit.h:62
void refresh()
Refresh the information.
Definition: req_edit.cpp:152
struct requirement selected_values
Definition: req_edit.h:53
void univ_value_enum_menu(QAction *action)
User selected value for the requirement.
Definition: req_edit.cpp:351
QLineEdit * edit_value_nbr_field
Definition: req_edit.h:60
void close_now()
User pushed close button.
Definition: req_edit.cpp:213
void rec_vec_may_have_changed(const requirement_vector *vec)
A requirement vector may have been changed.
QToolButton * edit_range_button
Definition: req_edit.h:61
void fill_active()
Fill active menus from selected req.
Definition: req_edit.cpp:272
struct requirement * selected
Definition: req_edit.h:52
req_edit(ruledit_gui *ui_in, const QString &target, struct requirement_vector *preqs)
Setup req_edit object.
Definition: req_edit.cpp:38
QMenu * edit_value_enum_menu
Definition: req_edit.h:59
void req_type_menu(QAction *action)
User selected type for the requirement.
Definition: req_edit.cpp:298
void univ_value_edit()
User entered numerical requirement value.
Definition: req_edit.cpp:368
void update_selected()
The selected requirement has changed.
Definition: req_edit.cpp:188
void select_req()
User selected requirement from the list.
Definition: req_edit.cpp:222
void incoming_rec_vec_change(const requirement_vector *vec)
The requirement vector may have been changed.
Definition: req_edit.cpp:426
QToolButton * edit_type_button
Definition: req_edit.h:57
void clear_selected()
Unselect the currently selected requirement.
Definition: req_edit.cpp:198
void req_range_menu(QAction *action)
User selected range for the requirement.
Definition: req_edit.cpp:318
QListWidget * req_list
Definition: req_edit.h:50
void closeEvent(QCloseEvent *event) override
User clicked windows close button.
Definition: req_edit.cpp:453
void add_now()
User requested new requirement.
Definition: req_edit.cpp:385
void rec_vec_may_have_changed(const requirement_vector *vec)
A requirement vector may have been changed.
void unregister_req_edit(class req_edit *redit)
Unregisted closed req_edit dialog.
Definition: ruledit_qt.cpp:305
enum event_type event
Definition: events.cpp:68
#define R__(String)
Definition: fcintl.h:58
static void universal_value_cb(const char *value, bool current, void *cbdata)
Callback for filling menu values.
Definition: req_edit.cpp:250
bool req_text_insert(char *buf, size_t bufsz, struct player *pplayer, const struct requirement *preq, enum rt_verbosity verb, const char *prefix)
Append text for the requirement.
Definition: reqtext.cpp:41
@ VERB_ACTUAL
Definition: reqtext.h:15
void universal_extraction(const struct universal *source, int *kind, int *value)
Extract universal structure into its components for serialization; the opposite of universal_by_numbe...
bool are_requirements_equal(const struct requirement *req1, const struct requirement *req2)
Returns TRUE if req1 and req2 are equal.
void universal_value_from_str(struct universal *source, const char *value)
Parse requirement value strings into a universal structure.
struct requirement req_from_values(int type, int range, bool survives, bool present, bool quiet, int value)
Set the values of a req from serializable integers.
const char * universal_name_translation(const struct universal *psource, char *buf, size_t bufsz)
Make user-friendly text for the source.
#define universals_iterate(_univ_)
Definition: requirements.h:269
#define requirement_vector_iterate_end
Definition: requirements.h:80
#define req_range_iterate_end
Definition: requirements.h:57
#define req_range_iterate(_range_)
Definition: requirements.h:51
#define requirement_vector_iterate(req_vec, preq)
Definition: requirements.h:78
#define universals_iterate_end
Definition: requirements.h:275
Definition: climisc.h:66
enum req_range range
Definition: requirements.h:69
struct universal source
Definition: requirements.h:68
enum universals_n kind
Definition: fc_types.h:740
universals_u value
Definition: fc_types.h:739
QLineEdit * number
Definition: req_edit.cpp:241
QMenu * menu
Definition: req_edit.cpp:243
QToolButton * enum_button
Definition: req_edit.cpp:242
struct universal * univ
Definition: req_edit.cpp:244
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
int fc_strcasecmp(const char *str0, const char *str1)
Compare strings like strcmp(), but ignoring case.
Definition: support.cpp:89
struct advance * advance
Definition: fc_types.h:577
bool universal_value_initial(struct universal *src)
Initialize universal value with a value suitable for the kind.
Definition: univ_value.cpp:36
void universal_kind_values(struct universal *univ, univ_kind_values_cb cb, void *data)
Call cb for each value possible for the universal kind.
Definition: univ_value.cpp:231