Freeciv-3.2: /fast/freeciv/nightly/S3_2/tools/ruledit/tab_tech.cpp Source File

Freeciv-3.2

Loading...
Searching...
No Matches
tab_tech.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 <QCheckBox>
20#include <QGridLayout>
21#include <QLineEdit>
22#include <QListWidget>
23#include <QMenu>
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 "tech.h"
34
35// ruledit
36#include "edit_tech.h"
37#include "ruledit.h"
38#include "ruledit_qt.h"
39#include "validity.h"
40
41#include "tab_tech.h"
42
43/**********************************************************************/
46tab_tech::tab_tech(ruledit_gui *ui_in) : QWidget()
47{
48 QVBoxLayout *main_layout = new QVBoxLayout(this);
49 QGridLayout *tech_layout = new QGridLayout();
50 QLabel *label;
51 QPushButton *effects_button;
52 QPushButton *add_button;
53 QPushButton *delete_button;
54 QPushButton *edit_button;
55 int row = 0;
56
57 ui = ui_in;
58 selected = 0;
59
60 tech_list = new QListWidget(this);
61
62 connect(tech_list, SIGNAL(itemSelectionChanged()), this, SLOT(select_tech()));
63 main_layout->addWidget(tech_list);
64
65 tech_layout->setSizeConstraint(QLayout::SetMaximumSize);
66
67 label = new QLabel(QString::fromUtf8(R__("Rule Name")));
68 label->setParent(this);
69 rname = new QLineEdit(this);
70 rname->setText(R__("None"));
71 connect(rname, SIGNAL(returnPressed()), this, SLOT(name_given()));
72 tech_layout->addWidget(label, row, 0);
73 tech_layout->addWidget(rname, row++, 2);
74
75 label = new QLabel(QString::fromUtf8(R__("Name")));
76 label->setParent(this);
77 same_name = new QCheckBox();
78 connect(same_name, SIGNAL(toggled(bool)), this, SLOT(same_name_toggle(bool)));
79 name = new QLineEdit(this);
80 name->setText(R__("None"));
81 connect(name, SIGNAL(returnPressed()), this, SLOT(name_given()));
82 tech_layout->addWidget(label, row, 0);
83 tech_layout->addWidget(same_name, row, 1);
84 tech_layout->addWidget(name, row++, 2);
85
86 edit_button = new QPushButton(QString::fromUtf8(R__("Edit Values")), this);
87 connect(edit_button, SIGNAL(pressed()), this, SLOT(edit_now()));
88 tech_layout->addWidget(edit_button, row++, 2);
89
90 label = new QLabel(QString::fromUtf8(R__("Req1")));
91 label->setParent(this);
92 req1_button = new QToolButton();
93 req1_button->setParent(this);
94 req1 = prepare_req_button(req1_button, AR_ONE);
95 connect(req1_button, SIGNAL(pressed()), this, SLOT(req1_jump()));
96 tech_layout->addWidget(label, row, 0);
97 tech_layout->addWidget(req1_button, row++, 2);
98
99 label = new QLabel(QString::fromUtf8(R__("Req2")));
100 label->setParent(this);
101 req2_button = new QToolButton();
102 req2 = prepare_req_button(req2_button, AR_TWO);
103 connect(req2_button, SIGNAL(pressed()), this, SLOT(req2_jump()));
104 tech_layout->addWidget(label, row, 0);
105 tech_layout->addWidget(req2_button, row++, 2);
106
107 label = new QLabel(QString::fromUtf8(R__("Root Req")));
108 label->setParent(this);
109 root_req_button = new QToolButton();
110 root_req_button->setParent(this);
111 root_req = prepare_req_button(root_req_button, AR_ROOT);
112 connect(root_req_button, SIGNAL(pressed()), this, SLOT(root_req_jump()));
113 tech_layout->addWidget(label, row, 0);
114 tech_layout->addWidget(root_req_button, row++, 2);
115
116 effects_button = new QPushButton(QString::fromUtf8(R__("Effects")), this);
117 connect(effects_button, SIGNAL(pressed()), this, SLOT(edit_effects()));
118 tech_layout->addWidget(effects_button, row++, 2);
119
120 add_button = new QPushButton(QString::fromUtf8(R__("Add tech")), this);
121 connect(add_button, SIGNAL(pressed()), this, SLOT(add_now()));
122 tech_layout->addWidget(add_button, row++, 0);
123 show_experimental(add_button);
124
125 delete_button = new QPushButton(QString::fromUtf8(R__("Remove this tech")), this);
126 connect(delete_button, SIGNAL(pressed()), this, SLOT(delete_now()));
127 tech_layout->addWidget(delete_button, row++, 2);
128 show_experimental(delete_button);
129
130 refresh();
131 update_tech_info(nullptr);
132
133 main_layout->addLayout(tech_layout);
134
135 setLayout(main_layout);
136}
137
138/**********************************************************************/
141 void tab_tech::refresh()
142{
143 tech_list->clear();
144
145 advance_re_active_iterate(padv) {
146 QListWidgetItem *item = new QListWidgetItem(advance_rule_name(padv));
147
148 tech_list->insertItem(advance_index(padv), item);
149 } advance_re_active_iterate_end;
150
151 techs_to_menu(req1);
152 techs_to_menu(req2);
153 techs_to_menu(root_req);
154}
155
156/**********************************************************************/
159QMenu *tab_tech::prepare_req_button(QToolButton *button, enum tech_req rn)
160{
161 QMenu *menu = new QMenu();
162
163 button->setToolButtonStyle(Qt::ToolButtonTextOnly);
164 button->setPopupMode(QToolButton::MenuButtonPopup);
165
166 switch (rn) {
167 case AR_ONE:
168 connect(menu, SIGNAL(triggered(QAction *)), this, SLOT(req1_menu(QAction *)));
169 break;
170 case AR_TWO:
171 connect(menu, SIGNAL(triggered(QAction *)), this, SLOT(req2_menu(QAction *)));
172 break;
173 case AR_ROOT:
174 connect(menu, SIGNAL(triggered(QAction *)), this, SLOT(root_req_menu(QAction *)));
175 break;
176 case AR_SIZE:
177 fc_assert(rn != AR_SIZE);
178 break;
179 }
180
181 button->setMenu(menu);
182
183 return menu;
184}
185
186/**********************************************************************/
189 void tab_tech::techs_to_menu(QMenu *fill_menu)
190{
191 fill_menu->clear();
192
193 advance_iterate_all(padv) {
194 fill_menu->addAction(tech_name(padv));
195 } advance_iterate_all_end;
196}
197
198/**********************************************************************/
201 QString tab_tech::tech_name(struct advance *padv)
202{
203 if (padv == A_NEVER) {
204 return QString::fromUtf8(R__("Never"));
205 }
206
207 return QString::fromUtf8(advance_rule_name(padv));
208}
209
210/**********************************************************************/
213 void tab_tech::update_tech_info(struct advance *adv)
214{
215 selected = adv;
216
217 if (selected != nullptr) {
218 QString dispn = QString::fromUtf8(untranslated_name(&(adv->name)));
219 QString rulen = QString::fromUtf8(rule_name_get(&(adv->name)));
220
221 name->setText(dispn);
222 rname->setText(rulen);
223
224 if (dispn == rulen) {
225 name->setEnabled(false);
226 same_name->setChecked(true);
227 } else {
228 same_name->setChecked(false);
229 name->setEnabled(true);
230 }
231
232 req1_button->setText(tech_name(adv->require[AR_ONE]));
233 req2_button->setText(tech_name(adv->require[AR_TWO]));
234 root_req_button->setText(tech_name(adv->require[AR_ROOT]));
235 } else {
236 name->setText(R__("None"));
237 rname->setText(R__("None"));
238 // FIXME: Could these be translated, or do we depend on
239 // them matching English rule_name of tech "None"?
240 req1_button->setText("None");
241 req2_button->setText("None");
242 root_req_button->setText("None");
243 same_name->setChecked(true);
244 name->setEnabled(false);
245 }
246}
247
248/**********************************************************************/
251 void tab_tech::select_tech()
252{
253 QList<QListWidgetItem *> select_list = tech_list->selectedItems();
254
255 if (!select_list.isEmpty()) {
256 QByteArray tn_bytes;
257
258 tn_bytes = select_list.at(0)->text().toUtf8();
259 update_tech_info(advance_by_rule_name(tn_bytes.data()));
260 }
261}
262
263/**********************************************************************/
266 void tab_tech::req1_jump()
267{
268 if (selected != 0 && advance_number(selected->require[AR_ONE]) != A_NONE) {
269 update_tech_info(selected->require[AR_ONE]);
270 }
271}
272
273/**********************************************************************/
276 void tab_tech::req2_jump()
277{
278 if (selected != 0 && advance_number(selected->require[AR_TWO]) != A_NONE) {
279 update_tech_info(selected->require[AR_TWO]);
280 }
281}
282
283/**********************************************************************/
286 void tab_tech::root_req_jump()
287{
288 if (selected != 0 && advance_number(selected->require[AR_ROOT]) != A_NONE) {
289 update_tech_info(selected->require[AR_ROOT]);
290 }
291}
292
293/**********************************************************************/
296 void tab_tech::req1_menu(QAction *action)
297{
298 struct advance *padv;
299 QByteArray an_bytes;
300
301 an_bytes = action->text().toUtf8();
302 padv = advance_by_rule_name(an_bytes.data());
303
304 if (padv != 0 && selected != 0) {
305 selected->require[AR_ONE] = padv;
306
307 update_tech_info(selected);
308 }
309}
310
311/**********************************************************************/
314 void tab_tech::req2_menu(QAction *action)
315{
316 struct advance *padv;
317 QByteArray an_bytes;
318
319 an_bytes = action->text().toUtf8();
320 padv = advance_by_rule_name(an_bytes.data());
321
322 if (padv != 0 && selected != 0) {
323 selected->require[AR_TWO] = padv;
324
325 update_tech_info(selected);
326 }
327}
328
329/**********************************************************************/
332 void tab_tech::root_req_menu(QAction *action)
333{
334 struct advance *padv;
335 QByteArray an_bytes;
336
337 an_bytes = action->text().toUtf8();
338 padv = advance_by_rule_name(an_bytes.data());
339
340 if (padv != 0 && selected != 0) {
341 selected->require[AR_ROOT] = padv;
342
343 update_tech_info(selected);
344 }
345}
346
347/**********************************************************************/
350 void tab_tech::name_given()
351{
352 if (selected != nullptr) {
353 QByteArray name_bytes;
354 QByteArray rname_bytes;
355
356 advance_iterate(padv) {
357 if (padv != selected
358 && padv->require[AR_ONE] != A_NEVER) {
359 rname_bytes = rname->text().toUtf8();
360 if (!strcmp(advance_rule_name(padv), rname_bytes.data())) {
361 ui->display_msg(R__("A tech with that rule name already exists!"));
362 return;
363 }
364 }
365 } advance_iterate_end;
366
367 if (same_name->isChecked()) {
368 name->setText(rname->text());
369 }
370
371 name_bytes = name->text().toUtf8();
372 rname_bytes = rname->text().toUtf8();
373 names_set(&(selected->name), 0,
374 name_bytes.data(),
375 rname_bytes.data());
376 refresh();
377 }
378}
379
380/**********************************************************************/
383 void tab_tech::delete_now()
384{
385 if (selected != 0) {
386 requirers_dlg *requirers;
387
388 requirers = ui->create_requirers(advance_rule_name(selected));
389 if (is_tech_needed(selected, &ruledit_qt_display_requirers, requirers)) {
390 return;
391 }
392
393 selected->require[AR_ONE] = A_NEVER;
394
395 if (selected->ruledit_dlg != nullptr) {
396 ((edit_tech *)selected->ruledit_dlg)->done(0);
397 }
398
399 refresh();
400 update_tech_info(nullptr);
401 }
402}
403
404/**********************************************************************/
407 bool tab_tech::initialize_new_tech(struct advance *padv)
408{
409 struct advance *none = advance_by_number(A_NONE);
410
411 if (advance_by_rule_name("New Tech") != nullptr) {
412 return false;
413 }
414
415 padv->require[AR_ONE] = none;
416 padv->require[AR_TWO] = none;
417 padv->require[AR_ROOT] = none;
418 name_set(&(padv->name), 0, "New Tech");
419 BV_CLR_ALL(padv->flags);
420
421 return true;
422}
423
424/**********************************************************************/
427 void tab_tech::add_now()
428{
429 struct advance *new_adv;
430
431 // Try to reuse freed tech slot
432 advance_iterate(padv) {
433 if (padv->require[AR_ONE] == A_NEVER) {
434 if (initialize_new_tech(padv)) {
435 update_tech_info(padv);
436 refresh();
437 }
438 return;
439 }
440 } advance_iterate_end;
441
442 // Try to add completely new tech
443 if (game.control.num_tech_types >= A_LAST) {
444 return;
445 }
446
447 // num_tech_types must be big enough to hold new tech or
448 // advance_by_number() fails.
449 game.control.num_tech_types++;
450 new_adv = advance_by_number(game.control.num_tech_types - 1);
451 if (initialize_new_tech(new_adv)) {
452 update_tech_info(new_adv);
453 refresh();
454 } else {
455 game.control.num_tech_types--; // Restore
456 }
457}
458
459/**********************************************************************/
462 void tab_tech::same_name_toggle(bool checked)
463{
464 name->setEnabled(!checked);
465 if (checked) {
466 name->setText(rname->text());
467 }
468}
469
470/**********************************************************************/
473 void tab_tech::edit_effects()
474{
475 if (selected != nullptr) {
476 struct universal uni;
477
478 uni.value.advance = selected;
479 uni.kind = VUT_ADVANCE;
480
481 ui->open_effect_edit(QString::fromUtf8(advance_rule_name(selected)),
482 &uni, EFMC_NORMAL);
483 }
484}
485
486/**********************************************************************/
489 void tab_tech::edit_now()
490{
491 if (selected != nullptr) {
492 if (selected->ruledit_dlg == nullptr) {
493 edit_tech *edit = new edit_tech(ui, selected);
494
495 edit->show();
496 selected->ruledit_dlg = edit;
497 } else {
498 ((edit_tech *)selected->ruledit_dlg)->raise();
499 }
500 }
501}
BV_CLR_ALL
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
edit_tech
Definition edit_tech.h:35
requirers_dlg
Definition requirers_dlg.h:28
ruledit_gui
Definition ruledit_qt.h:97
ruledit_gui::display_msg
void display_msg(const char *msg)
Definition ruledit_qt.cpp:293
ruledit_gui::create_requirers
requirers_dlg * create_requirers(const char *title)
Definition ruledit_qt.cpp:301
ruledit_gui::open_effect_edit
void open_effect_edit(QString target, struct universal *uni, enum effect_filter_main_class efmc)
Definition ruledit_qt.cpp:404
tab_tech::same_name
QCheckBox * same_name
Definition tab_tech.h:62
tab_tech::root_req_button
QToolButton * root_req_button
Definition tab_tech.h:57
tab_tech::ui
ruledit_gui * ui
Definition tab_tech.h:48
tab_tech::edit_now
void edit_now()
Definition tab_tech.cpp:489
tab_tech::same_name_toggle
void same_name_toggle(bool checked)
Definition tab_tech.cpp:462
tab_tech::initialize_new_tech
bool initialize_new_tech(struct advance *padv)
Definition tab_tech.cpp:407
tab_tech::select_tech
void select_tech()
Definition tab_tech.cpp:251
tab_tech::req1_button
QToolButton * req1_button
Definition tab_tech.h:55
tab_tech::rname
QLineEdit * rname
Definition tab_tech.h:54
tab_tech::req1_menu
void req1_menu(QAction *action)
Definition tab_tech.cpp:296
tab_tech::edit_effects
void edit_effects()
Definition tab_tech.cpp:473
tab_tech::refresh
void refresh()
Definition tab_tech.cpp:141
tab_tech::selected
struct advance * selected
Definition tab_tech.h:64
tab_tech::delete_now
void delete_now()
Definition tab_tech.cpp:383
tab_tech::req1
QMenu * req1
Definition tab_tech.h:58
tab_tech::techs_to_menu
static void techs_to_menu(QMenu *fill_menu)
Definition tab_tech.cpp:189
tab_tech::name
QLineEdit * name
Definition tab_tech.h:53
tab_tech::add_now
void add_now()
Definition tab_tech.cpp:427
tab_tech::prepare_req_button
QMenu * prepare_req_button(QToolButton *button, enum tech_req rn)
Definition tab_tech.cpp:159
tab_tech::req2_jump
void req2_jump()
Definition tab_tech.cpp:276
tab_tech::req2_menu
void req2_menu(QAction *action)
Definition tab_tech.cpp:314
tab_tech::root_req_menu
void root_req_menu(QAction *action)
Definition tab_tech.cpp:332
tab_tech::req1_jump
void req1_jump()
Definition tab_tech.cpp:266
tab_tech::root_req_jump
void root_req_jump()
Definition tab_tech.cpp:286
tab_tech::name_given
void name_given()
Definition tab_tech.cpp:350
tab_tech::req2_button
QToolButton * req2_button
Definition tab_tech.h:56
tab_tech::root_req
QMenu * root_req
Definition tab_tech.h:60
tab_tech::tab_tech
tab_tech(ruledit_gui *ui_in)
Definition tab_tech.cpp:46
tab_tech::tech_name
static QString tech_name(struct advance *padv)
Definition tab_tech.cpp:201
tab_tech::tech_list
QListWidget * tech_list
Definition tab_tech.h:61
tab_tech::req2
QMenu * req2
Definition tab_tech.h:59
tab_tech::update_tech_info
void update_tech_info(struct advance *adv)
Definition tab_tech.cpp:213
incite_cost
char * incite_cost
Definition comments.c:74
edit_tech.h
EFMC_NORMAL
@ EFMC_NORMAL
Definition effect_edit.h:34
fcintl.h
R__
#define R__(String)
Definition fcintl.h:75
game
struct civ_game game
Definition game.c:62
game.h
edit
#define edit(pedit)
Definition widget_edit.h:34
log.h
fc_assert
#define fc_assert(condition)
Definition log.h:176
name_set
static void name_set(struct name_translation *ptrans, const char *domain, const char *vernacular_name)
Definition name_translation.h:88
rule_name_get
static const char * rule_name_get(const struct name_translation *ptrans)
Definition name_translation.h:112
untranslated_name
static const char * untranslated_name(const struct name_translation *ptrans)
Definition name_translation.h:104
names_set
static void names_set(struct name_translation *ptrans, const char *domain, const char *vernacular_name, const char *rule_name)
Definition name_translation.h:60
show_experimental
void show_experimental(QWidget *wdg)
Definition ruledit.cpp:237
ruledit.h
ruledit_qt_display_requirers
void ruledit_qt_display_requirers(const char *msg, void *data)
Definition ruledit_qt.cpp:97
ruledit_qt.h
action
Definition actions.h:360
advance
Definition tech.h:124
advance::ruledit_dlg
void * ruledit_dlg
Definition tech.h:127
advance::require
struct advance * require[AR_SIZE]
Definition tech.h:132
advance::name
struct name_translation name
Definition tech.h:126
civ_game::control
struct packet_ruleset_control control
Definition game.h:83
item
Definition climisc.h:80
packet_ruleset_control::num_tech_types
int num_tech_types
Definition packets_gen.h:1453
universal
Definition fc_types.h:901
universal::kind
enum universals_n kind
Definition fc_types.h:903
universal::value
universals_u value
Definition fc_types.h:902
tab_tech.h
advance_by_number
struct advance * advance_by_number(const Tech_type_id atype)
Definition tech.c:107
advance_rule_name
const char * advance_rule_name(const struct advance *padvance)
Definition tech.c:299
advance_index
Tech_type_id advance_index(const struct advance *padvance)
Definition tech.c:89
advance_by_rule_name
struct advance * advance_by_rule_name(const char *name)
Definition tech.c:200
advance_number
Tech_type_id advance_number(const struct advance *padvance)
Definition tech.c:98
tech.h
advance_re_active_iterate
#define advance_re_active_iterate(_p)
Definition tech.h:281
A_NEVER
#define A_NEVER
Definition tech.h:51
advance_iterate_all_end
#define advance_iterate_all_end
Definition tech.h:279
tech_req
tech_req
Definition tech.h:110
AR_TWO
@ AR_TWO
Definition tech.h:112
AR_ROOT
@ AR_ROOT
Definition tech.h:113
AR_ONE
@ AR_ONE
Definition tech.h:111
AR_SIZE
@ AR_SIZE
Definition tech.h:114
advance_re_active_iterate_end
#define advance_re_active_iterate_end
Definition tech.h:285
advance_iterate_all
#define advance_iterate_all(_p)
Definition tech.h:278
A_NONE
#define A_NONE
Definition tech.h:43
advance_iterate
#define advance_iterate(_p)
Definition tech.h:275
advance_iterate_end
#define advance_iterate_end
Definition tech.h:276
A_LAST
#define A_LAST
Definition tech.h:45
universals_u::advance
struct advance * advance
Definition fc_types.h:714
is_tech_needed
bool is_tech_needed(struct advance *padv, requirers_cb cb, void *data)
Definition validity.c:199
validity.h