Freeciv21
Develop your civilization from humble roots to a global empire
view_research.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 1996-2023 Freeciv21 and Freeciv contributors. This file is
3  part of Freeciv21. Freeciv21 is free software: you can redistribute it
4  and/or modify it under the terms of the GNU General Public License as
5  published by the Free Software Foundation, either version 3 of the
6  License, or (at your option) any later version. You should have received
7  a copy of the GNU General Public License along with Freeciv21. If not,
8  see https://www.gnu.org/licenses/.
9  */
10 
11 /*
12  * This file contains functions to generate the GUI for the research view
13  * (formally known as the science dialog).
14  */
15 
16 // Qt
17 #include <QComboBox>
18 #include <QGridLayout>
19 #include <QMouseEvent>
20 #include <QPainter>
21 #include <QPushButton>
22 #include <QScrollArea>
23 #include <QStringLiteral>
24 #include <QTimer>
25 #include <QToolButton>
26 #include <QToolTip>
27 
28 // common
29 #include "fc_types.h"
30 #include "game.h"
31 #include "government.h"
32 #include "icons.h"
33 #include "research.h"
34 
35 // client
36 #include "citydlg.h"
37 #include "client_main.h"
38 #include "climisc.h"
39 #include "fc_client.h"
40 #include "helpdlg.h"
41 #include "page_game.h"
42 #include "text.h"
43 #include "tileset/sprite.h"
44 #include "tooltips.h"
45 #include "top_bar.h"
46 #include "views/view_research.h"
48 
49 extern QString split_text(const QString &text, bool cut);
50 extern QString cut_helptext(const QString &text);
51 extern QString get_tooltip_improvement(impr_type *building,
52  struct city *pcity, bool ext);
53 extern QString get_tooltip_unit(struct unit_type *unit, bool ext);
54 
58 bool comp_less_than(const qlist_item &q1, const qlist_item &q2)
59 {
60  return (q1.tech_str < q2.tech_str);
61 }
62 
66 research_diagram::research_diagram(QWidget *parent) : QWidget(parent)
67 {
68  pcanvas = nullptr;
69  req = nullptr;
70  reset();
71  setMouseTracking(true);
72  setAttribute(Qt::WA_StyledBackground);
73 }
74 
79 {
80  delete tt_help;
81  delete pcanvas;
83 }
84 
89 {
90  reset();
91  delete tt_help;
92  tt_help = draw_reqtree(req, pcanvas, 0, 0, 0, 0, width, height);
93  update();
94 }
95 
100 {
101  timer_active = false;
102  if (req != nullptr) {
104  }
105 
106  delete pcanvas;
107  req = create_reqtree(client_player(), true);
109  pcanvas = new QPixmap(width, height);
110  pcanvas->fill(Qt::transparent);
111  resize(width, height);
112 }
113 
120 {
121  return get_position_on_reqtree(req, id, x, y);
122 }
123 
128 {
129  Tech_type_id tech = get_tech_on_reqtree(req, event->x(), event->y());
130  req_tooltip_help *rttp;
131  int i;
132 
133  if (event->button() == Qt::LeftButton && can_client_issue_orders()) {
135  case TECH_PREREQS_KNOWN:
136  dsend_packet_player_research(&client.conn, tech);
137  break;
138  case TECH_UNKNOWN:
139  dsend_packet_player_tech_goal(&client.conn, tech);
140  break;
141  case TECH_KNOWN:
142  break;
143  }
144  } else if (event->button() == Qt::RightButton) {
145  for (i = 0; i < tt_help->count(); i++) {
146  rttp = tt_help->at(i);
147  if (rttp->rect.contains(event->pos())) {
148  if (rttp->tech_id != -1) {
150  qUtf8Printable(research_advance_name_translation(
151  research_get(client_player()), rttp->tech_id)),
152  HELP_TECH);
153  } else if (rttp->timpr != nullptr) {
157  } else if (rttp->tunit != nullptr) {
159  HELP_UNIT);
160  } else if (rttp->tgov != nullptr) {
163  } else {
164  return;
165  }
166  }
167  }
168  }
169 }
170 
175 {
176  req_tooltip_help *rttp;
177  int i;
178  QString tt_text;
179  QString def_str;
180  char buffer[8192];
181  char buf2[1];
182 
183  buf2[0] = '\0';
184  for (i = 0; i < tt_help->count(); i++) {
185  rttp = tt_help->at(i);
186  if (rttp->rect.contains(event->pos())) {
187  if (rttp->tech_id != -1) {
188  helptext_advance(buffer, sizeof(buffer), client.conn.playing, buf2,
190  tt_text = QString(buffer);
191  def_str = "<p style='white-space:pre'><b>"
192  + QString(advance_name_translation(
193  advance_by_number(rttp->tech_id)))
194  .toHtmlEscaped()
195  + "</b>\n";
196  } else if (rttp->timpr != nullptr) {
197  def_str = get_tooltip_improvement(rttp->timpr, nullptr);
198  tt_text = helptext_building(
199  buffer, sizeof(buffer), client.conn.playing, nullptr,
201  tt_text = cut_helptext(tt_text);
202  } else if (rttp->tunit != nullptr) {
203  def_str = get_tooltip_unit(rttp->tunit);
204  tt_text +=
205  helptext_unit(buffer, sizeof(buffer), client.conn.playing, buf2,
207  tt_text = cut_helptext(tt_text);
208  } else if (rttp->tgov != nullptr) {
209  helptext_government(buffer, sizeof(buffer), client.conn.playing,
210  buf2, rttp->tgov);
211  tt_text = QString(buffer);
212  tt_text = cut_helptext(tt_text);
213  def_str = "<p style='white-space:pre'><b>"
214  + QString(government_name_translation(rttp->tgov))
215  .toHtmlEscaped()
216  + "</b>\n";
217  } else {
218  return;
219  }
220  tt_text = split_text(tt_text, true);
221  tt_text = def_str + tt_text.toHtmlEscaped();
222  tooltip_text = tt_text.trimmed();
223  tooltip_rect = rttp->rect;
224  tooltip_pos = event->globalPos();
225  if (!timer_active) {
226  timer_active = true;
227  QTimer::singleShot(500, this, &research_diagram::show_tooltip);
228  }
229  }
230  }
231 }
232 
237 {
238  QPoint cp;
239 
240  timer_active = false;
241  cp = QCursor::pos();
242  if (qAbs(cp.x() - tooltip_pos.x()) < 4
243  && qAbs(cp.y() - tooltip_pos.y()) < 4) {
244  QToolTip::showText(cp, tooltip_text, this, tooltip_rect);
245  }
246 }
247 
252 {
253  QWidget::paintEvent(event);
254 
255  QPainter painter;
256  painter.begin(this);
257  painter.drawPixmap(0, 0, width, height, *pcanvas);
258  painter.end();
259 }
260 
265 {
266  QSize s;
267 
268  s.setWidth(width);
269  ;
270  s.setHeight(height);
271  return s;
272 }
273 
278 {
279  QSize size;
280  QSizePolicy size_expanding_policy(QSizePolicy::Expanding,
281  QSizePolicy::Expanding);
282  QSizePolicy size_fixed_policy(QSizePolicy::Minimum, QSizePolicy::Minimum);
283 
284  goal_combo = new QComboBox();
285  info_label = new QLabel();
286  progress = new progress_bar(this);
287  progress_label = new QLabel();
288  researching_combo = new QComboBox();
289  auto sci_layout = new QGridLayout();
290  res_diag = new research_diagram();
291  scroll = new QScrollArea();
292  refresh_but = new QPushButton();
293  refresh_but->setText(_("Refresh"));
294  refresh_but->setToolTip(_("Press to refresh currently researched "
295  "technology calculation again."));
296  refresh_but->setDisabled(true);
297 
298  locate_researching_but = new QToolButton();
299  locate_researching_but->setIcon(
300  fcIcons::instance()->getIcon(QStringLiteral("crosshair")));
301  locate_researching_but->setIconSize(
302  QSize(locate_researching_but->fontInfo().pixelSize(),
303  locate_researching_but->fontInfo().pixelSize()));
304  locate_researching_but->setToolTip(
305  _("Press to locate currently researched "
306  "technology in tree."));
307  locate_researching_but->setDisabled(true);
308 
309  locate_goal_but = new QToolButton();
310  locate_goal_but->setIcon(
311  fcIcons::instance()->getIcon(QStringLiteral("crosshair")));
312  locate_goal_but->setIconSize(
313  QSize(locate_researching_but->fontInfo().pixelSize(),
314  locate_researching_but->fontInfo().pixelSize()));
315  locate_goal_but->setToolTip(_("Press to locate technology goal in tree."));
316  locate_goal_but->setDisabled(true);
317 
318  progress->setTextVisible(true);
319  progress_label->setSizePolicy(size_fixed_policy);
320  sci_layout->addWidget(progress_label, 0, 0, 1, 9);
321  sci_layout->addWidget(researching_combo, 1, 0, 1, 3);
322  researching_combo->setSizePolicy(size_fixed_policy);
323  sci_layout->addWidget(locate_researching_but, 1, 3, 1, 1);
324  sci_layout->addWidget(refresh_but, 1, 4, 1, 1);
325  refresh_but->setSizePolicy(size_fixed_policy);
326  sci_layout->addWidget(progress, 1, 6, 1, 4);
327  progress->setSizePolicy(size_fixed_policy);
328  sci_layout->addWidget(goal_combo, 2, 0, 1, 3);
329  goal_combo->setSizePolicy(size_fixed_policy);
330  sci_layout->addWidget(locate_goal_but, 2, 3, 1, 1);
331  sci_layout->addWidget(info_label, 2, 6, 1, 4);
332  info_label->setSizePolicy(size_fixed_policy);
333 
334  size = res_diag->size();
335  res_diag->setMinimumSize(size);
336  scroll->setAutoFillBackground(true);
337  scroll->setPalette(QPalette(QColor(215, 215, 215)));
338  scroll->setWidget(res_diag);
339  scroll->setSizePolicy(size_expanding_policy);
340  sci_layout->addWidget(scroll, 4, 0, 1, 10);
341 
342  QObject::connect(researching_combo,
343  QOverload<int>::of(&QComboBox::currentIndexChanged), this,
345 
346  QObject::connect(refresh_but, &QAbstractButton::pressed, this,
348 
349  QObject::connect(locate_goal_but, &QAbstractButton::pressed, this,
351 
352  QObject::connect(locate_researching_but, &QAbstractButton::pressed, this,
354 
355  QObject::connect(goal_combo,
356  QOverload<int>::of(&QComboBox::currentIndexChanged), this,
358 
359  setLayout(sci_layout);
360 }
361 
368 {
369  delete curr_list;
370  delete goal_list;
371  queen()->removeRepoDlg(QStringLiteral("SCI"));
372 }
373 
379 void science_report::init(bool raise)
380 {
381  Q_UNUSED(raise)
382  queen()->gimmePlace(this, QStringLiteral("SCI"));
383  index = queen()->addGameTab(this);
384  queen()->game_tab_widget->setCurrentIndex(index);
385  update_report();
386 }
387 
391 void science_report::redraw() { update(); }
392 
397 {
398  QSize size;
399  res_diag->reset();
400  size = res_diag->size();
401  res_diag->setMinimumSize(size);
402  update();
403 }
404 
409 {
410  delete curr_list;
411  delete goal_list;
412  curr_list = nullptr;
413  goal_list = nullptr;
414 
416  if (!research) {
417  // Global observer
418  goal_combo->clear();
419  researching_combo->clear();
420  info_label->setText(QString());
421  progress_label->setText(QString());
422  res_diag->reset();
423  return;
424  }
425 
426  int total;
427  int done = research->bulbs_researched;
428  QVariant qvar, qres;
430 
431  if (research->researching != A_UNSET) {
432  total = research->client.researching_cost;
433  } else {
434  total = -1;
435  }
436 
437  curr_list = new QList<qlist_item>;
438  goal_list = new QList<qlist_item>;
440  progress_label->setAlignment(Qt::AlignHCenter);
441  info_label->setAlignment(Qt::AlignHCenter);
443  progress->setFormat(get_science_target_text());
444  progress->setMinimum(0);
445  progress->setMaximum(total);
446  progress->set_pixmap(static_cast<int>(research->researching));
447 
448  if (done <= total) {
449  progress->setValue(done);
450  } else {
451  done = total;
452  progress->setValue(done);
453  }
454 
457  {
458  if (TECH_PREREQS_KNOWN == research->inventions[i].state) {
459  item.tech_str =
460  QString::fromUtf8(advance_name_translation(advance_by_number(i)));
461  item.id = i;
462  curr_list->append(item);
463  }
464  }
466 
469  {
471  && TECH_KNOWN != research->inventions[i].state
472  && (i == research->tech_goal
473  || 10 >= research->inventions[i].num_required_techs)) {
474  item.tech_str =
475  QString::fromUtf8(advance_name_translation(advance_by_number(i)));
476  item.id = i;
477  goal_list->append(item);
478  }
479  }
481 
483  std::sort(goal_list->begin(), goal_list->end(), comp_less_than);
484  std::sort(curr_list->begin(), curr_list->end(), comp_less_than);
485 
487  researching_combo->blockSignals(true);
488  goal_combo->blockSignals(true);
489 
490  researching_combo->clear();
491  goal_combo->clear();
492  for (int i = 0; i < curr_list->count(); i++) {
493  QIcon ic;
494 
495  auto sp = get_tech_sprite(tileset, curr_list->at(i).id);
496  if (sp) {
497  ic = QIcon(*sp);
498  }
499  qvar = curr_list->at(i).id;
500  researching_combo->insertItem(i, ic, curr_list->at(i).tech_str, qvar);
501  }
502 
503  for (int i = 0; i < goal_list->count(); i++) {
504  QIcon ic;
505 
506  auto sp = get_tech_sprite(tileset, goal_list->at(i).id);
507  if (sp) {
508  ic = QIcon(*sp);
509  }
510  qvar = goal_list->at(i).id;
511  goal_combo->insertItem(i, ic, goal_list->at(i).tech_str, qvar);
512  }
513 
515  qres = research->researching;
516  if (qres == A_UNSET || is_future_tech(research->researching)) {
517  researching_combo->insertItem(
518  0,
520  A_UNSET);
521  researching_combo->setCurrentIndex(0);
522  } else {
523  for (int i = 0; i < researching_combo->count(); i++) {
524  qvar = researching_combo->itemData(i);
525 
526  if (qvar == qres) {
527  researching_combo->setCurrentIndex(i);
528  }
529  }
530  }
531 
532  qres = research->tech_goal;
533 
534  if (qres == A_UNSET) {
535  goal_combo->insertItem(0, Q_("?tech:None"), A_UNSET);
536  goal_combo->setCurrentIndex(0);
537  } else {
538  for (int i = 0; i < goal_combo->count(); i++) {
539  qvar = goal_combo->itemData(i);
540 
541  if (qvar == qres) {
542  goal_combo->setCurrentIndex(i);
543  }
544  }
545  }
546 
547  researching_combo->blockSignals(false);
548  goal_combo->blockSignals(false);
549 
550  if (client_is_observer()) {
551  researching_combo->setDisabled(true);
552  goal_combo->setDisabled(true);
553  } else {
554  researching_combo->setDisabled(false);
555  goal_combo->setDisabled(false);
556  }
557 
558  // If tech leak happens we enable a button to force/push a refresh.
559  if (done >= total) {
560  refresh_but->setDisabled(false);
561  }
562 
563  // Update locate buttons
565  locate_goal_but->setDisabled(research->tech_goal == A_UNSET);
566 
567  update_reqtree();
568 }
569 
574 
579 {
580  int x, y;
581  if (res_diag->get_tech_position(id, &x, &y)) {
582  scroll->ensureVisible(x, y, scroll->width() / 2, scroll->height() / 2);
583  }
584 }
585 
590 {
591  QVariant qvar;
592 
593  qvar = researching_combo->itemData(changed_index);
594 
595  if (researching_combo->hasFocus()) {
596  if (can_client_issue_orders()) {
597  dsend_packet_player_research(&client.conn, qvar.toInt());
598  }
599  }
600 }
601 
605 void science_report::goal_tech_changed(int changed_index)
606 {
607  QVariant qvar;
608 
609  qvar = goal_combo->itemData(changed_index);
610 
611  if (goal_combo->hasFocus()) {
612  if (can_client_issue_orders()) {
613  dsend_packet_player_tech_goal(&client.conn, qvar.toInt());
614  }
615  }
616 }
617 
623 {
624  if (can_client_issue_orders()) {
626  dsend_packet_player_research(&client.conn, research->researching);
627  }
628 }
629 
634 {
636  if (!research) {
637  return;
638  }
639 
641 }
642 
648 {
650  if (!research) {
651  return;
652  }
653 
655 }
656 
661 {
662  Q_UNUSED(unused)
663  int i;
664  science_report *sci_rep;
665  bool blk = false;
666  QWidget *w;
667  QString str;
668 
669  if (nullptr != client.conn.playing) {
671  if (research->researching == A_UNSET) {
672  str = QString(_("none"));
673  } else {
674  str =
676  str += QStringLiteral("\n");
677 
678  const int per_turn = get_bulbs_per_turn(nullptr, nullptr, nullptr);
679  const int when = turns_to_research_done(research, per_turn);
680  if (when >= 0) {
681  // TRANS: current(+surplus)/total (number of turns)
682  str += QString(PL_("%1(+%2)/%3 (%4 turn)", "%1(+%2)/%3 (%4 turns)",
683  when))
685  .arg(per_turn)
686  .arg(research->client.researching_cost)
687  .arg(when);
688  } else {
689  // TRANS: current(+surplus)/total (number of turns)
690  str += QString(_("%1(+%2)/%3 (never)"))
692  .arg(per_turn)
693  .arg(research->client.researching_cost);
694  }
695  }
697  && research->techs_researched < game.control.num_tech_types) {
698  blk = true;
699  }
700  }
701 
702  if (blk) {
703  queen()->sw_science->keep_blinking = true;
705  queen()->sw_science->sblink();
706  } else {
707  queen()->sw_science->keep_blinking = false;
709  queen()->sw_science->update();
710  }
712 
713  if (queen()->isRepoDlgOpen(QStringLiteral("SCI"))
715  i = queen()->gimmeIndexOf(QStringLiteral("SCI"));
716  fc_assert(i != -1);
717  w = queen()->game_tab_widget->widget(i);
718  sci_rep = reinterpret_cast<science_report *>(w);
719  sci_rep->update_report();
720  }
721 }
722 
727 {
728  int i;
729  science_report *sci_rep;
730  QWidget *w;
731 
732  if (queen()->isRepoDlgOpen(QStringLiteral("SCI"))) {
733  i = queen()->gimmeIndexOf(QStringLiteral("SCI"));
734  fc_assert(i != -1);
735  w = queen()->game_tab_widget->widget(i);
736  sci_rep = reinterpret_cast<science_report *>(w);
737  sci_rep->deleteLater();
738  }
739 }
740 
745 {
746  int i;
747  science_report *sci_rep;
748  QWidget *w;
749 
750  if (queen()->isRepoDlgOpen(QStringLiteral("SCI"))) {
751  i = queen()->gimmeIndexOf(QStringLiteral("SCI"));
752  if (queen()->game_tab_widget->currentIndex() == i) {
753  w = queen()->game_tab_widget->widget(i);
754  sci_rep = reinterpret_cast<science_report *>(w);
755  sci_rep->redraw();
756  }
757  }
758 }
759 
765 {
766  science_report *sci_rep;
767  int i;
768  QWidget *w;
769 
771  return;
772  }
773  if (!queen()->isRepoDlgOpen(QStringLiteral("SCI"))) {
774  sci_rep = new science_report;
775  sci_rep->init(raise);
776  } else {
777  i = queen()->gimmeIndexOf(QStringLiteral("SCI"));
778  w = queen()->game_tab_widget->widget(i);
779  sci_rep = reinterpret_cast<science_report *>(w);
780  if (queen()->game_tab_widget->currentIndex() == i) {
781  sci_rep->redraw();
782  } else if (raise) {
783  queen()->game_tab_widget->setCurrentWidget(sci_rep);
784  }
785  }
786 }
static fcIcons * instance()
Returns instance of fc_icons.
Definition: icons.cpp:36
int gimmeIndexOf(const QString &str)
Returns index on game tab page of given report dialog.
Definition: page_game.cpp:706
int addGameTab(QWidget *widget)
Inserts tab widget to game view page.
Definition: page_game.cpp:670
void removeRepoDlg(const QString &str)
Removes report dialog string from the list marking it as closed.
Definition: page_game.cpp:723
top_bar_widget * sw_science
Definition: page_game.h:88
void updateSidebarTooltips()
Updates top bar tooltips.
Definition: page_game.cpp:340
void gimmePlace(QWidget *widget, const QString &str)
Finds not used index on game_view_tab and returns it.
Definition: page_game.cpp:690
fc_game_tab_widget * game_tab_widget
Definition: page_game.h:72
void set_pixmap(struct universal *target)
Sets pixmap from given universal for custom progressbar.
Definition: citydlg.cpp:264
struct government * tgov
struct unit_type * tunit
struct impr_type * timpr
void show_tooltip()
Slot for timer used to show tooltip.
QPixmap * pcanvas
Definition: view_research.h:49
void reset()
Initializes research diagram.
~research_diagram() override
Destructor for research diagram.
QSize size()
Returns size of research_diagram.
bool get_tech_position(Tech_type_id id, int *x, int *y)
Find the center of a node, identified by tech id, and return true if the node was found; false otherw...
void paintEvent(QPaintEvent *event) override
Paint event for research_diagram.
void mousePressEvent(QMouseEvent *event) override
Mouse handler for research_diagram.
struct reqtree * req
Definition: view_research.h:50
QString tooltip_text
Definition: view_research.h:56
QList< req_tooltip_help * > * tt_help
Definition: view_research.h:54
void mouseMoveEvent(QMouseEvent *event) override
Mouse move handler for research_diagram - for showing tooltips.
research_diagram(QWidget *parent=0)
Constructor for research diagram.
void update_reqtree()
Recreates whole diagram and schedules update.
void locate_researching()
Locate the currently researched technology in tree and scroll so that it is visible.
QLabel * progress_label
Definition: view_research.h:84
void locate_goal()
Locate technology goal in tree and scroll so that it is visible.
QPushButton * refresh_but
Definition: view_research.h:79
QToolButton * locate_goal_but
Definition: view_research.h:81
progress_bar * progress
Definition: view_research.h:82
science_report()
Consctructor for science_report.
void push_research()
Push (redo) research when qty bulbs researched is greater than the number needed.
QScrollArea * scroll
Definition: view_research.h:76
QComboBox * goal_combo
Definition: view_research.h:77
QList< qlist_item > * curr_list
Definition: view_research.h:85
QLabel * info_label
Definition: view_research.h:83
QToolButton * locate_researching_but
Definition: view_research.h:80
research_diagram * res_diag
Definition: view_research.h:87
void scroll_reqtree_to_tech(Tech_type_id id)
Scroll the science tree to display the technology identified by tech id.
QList< qlist_item > * goal_list
Definition: view_research.h:86
void update_report()
Updates all important widgets on science_report.
void redraw()
Schedules paint event in some qt queue.
void init(bool raise)
Updates science_report and marks it as opened It has to be called soon after constructor.
void update_reqtree()
Calls update for research_diagram.
void reset_tree()
Recalculates research diagram again and updates science report.
void current_tech_changed(int index)
Slot used when combo box with current tech changes.
void goal_tech_changed(int index)
Slot used when combo box with goal have been changed.
QComboBox * researching_combo
Definition: view_research.h:78
~science_report() override
Destructor for science report Removes "SCI" string marking it as closed And frees given index on list...
void sblink()
Blinks current top_bar widget.
Definition: top_bar.cpp:302
bool keep_blinking
Definition: top_bar.h:83
void setCustomLabels(const QString &)
Sets custom text visible on top of sidewidget.
Definition: top_bar.cpp:223
bool client_is_global_observer()
Returns whether client is global observer.
struct player * client_player()
Either controlling or observing.
struct civclient client
bool can_client_issue_orders()
Returns TRUE iff the client can issue orders (such as giving unit commands).
bool client_is_observer()
Returns whether client is observer.
struct nation_set * client_current_nation_set()
Returns the nation set in use.
Definition: climisc.cpp:1190
enum event_type event
Definition: events.cpp:68
int Tech_type_id
Definition: fc_types.h:294
#define Q_(String)
Definition: fcintl.h:53
#define PL_(String1, String2, n)
Definition: fcintl.h:54
#define _(String)
Definition: fcintl.h:50
struct civ_game game
Definition: game.cpp:47
const char * government_name_translation(const struct government *pgovern)
Return the (translated) name of the given government.
Definition: government.cpp:136
void helptext_advance(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, int i, const nation_set *nations_to_show)
Append misc dynamic text for advance/technology.
Definition: helpdata.cpp:2886
void helptext_government(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, struct government *gov)
Append text for government.
Definition: helpdata.cpp:3942
char * helptext_unit(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, const struct unit_type *utype, const nation_set *nations_to_show)
Append misc dynamic text for units.
Definition: helpdata.cpp:1639
char * helptext_building(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, const struct impr_type *pimprove, const nation_set *nations_to_show)
FIXME: Also, in principle these could be auto-generated once, inserted into pitem->text,...
Definition: helpdata.cpp:1181
@ HELP_IMPROVEMENT
Definition: helpdata.h:24
@ HELP_UNIT
Definition: helpdata.h:23
@ HELP_GOVERNMENT
Definition: helpdata.h:31
@ HELP_WONDER
Definition: helpdata.h:25
@ HELP_TECH
Definition: helpdata.h:26
void popup_help_dialog_typed(const char *item, enum help_page_type htype)
Popup the help dialog to display help on the given string topic from the given section.
Definition: helpdlg.cpp:56
bool is_great_wonder(const struct impr_type *pimprove)
Is this building a great wonder?
const char * improvement_name_translation(const struct impr_type *pimprove)
Return the (translated) name of the given improvement.
#define fc_assert(condition)
Definition: log.h:89
pageGame * queen()
Return game instandce.
Definition: page_game.cpp:557
bool research_invention_reachable(const struct research *presearch, const Tech_type_id tech)
Returns TRUE iff the given tech is ever reachable via research by the players sharing the research by...
Definition: research.cpp:659
struct research * research_get(const struct player *pplayer)
Returns the research structure associated with the player.
Definition: research.cpp:110
QString research_advance_name_translation(const struct research *presearch, Tech_type_id tech)
Store the translated name of the given tech (including A_FUTURE) in 'buf'.
Definition: research.cpp:257
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Returns state of the tech for current research.
Definition: research.cpp:609
size_t size
Definition: specvec.h:64
Definition: city.h:291
struct packet_ruleset_control control
Definition: game.h:74
struct connection conn
Definition: client_main.h:89
struct player * playing
Definition: connection.h:142
Definition: climisc.h:66
QString tech_str
Definition: view_research.h:64
enum tech_state state
Definition: research.h:66
Tech_type_id researching
Definition: research.h:45
struct research::@71::@73 client
Tech_type_id tech_goal
Definition: research.h:78
int techs_researched
Definition: research.h:35
struct research::research_invention inventions[A_LAST]
int bulbs_researched
Definition: research.h:46
Definition: unit.h:134
bool is_future_tech(Tech_type_id tech)
Is the given tech a future tech.
Definition: tech.cpp:268
struct advance * advance_by_number(const Tech_type_id atype)
Return the advance for the given advance index.
Definition: tech.cpp:94
const char * advance_name_translation(const struct advance *padvance)
Return the (translated) name of the given advance/technology.
Definition: tech.cpp:274
#define advance_index_iterate_end
Definition: tech.h:226
#define A_FIRST
Definition: tech.h:37
#define A_UNSET
Definition: tech.h:41
#define advance_index_iterate(_start, _index)
Definition: tech.h:221
const QString science_dialog_text()
Returns the text to display in the science dialog.
Definition: text.cpp:812
const QString get_science_target_text()
Get the short science-target text.
Definition: text.cpp:887
int get_bulbs_per_turn(int *pours, bool *pteam, int *ptheirs)
Return total expected bulbs.
Definition: text.cpp:714
int turns_to_research_done(const struct research *presearch, int per_turn)
Return turns until research complete.
Definition: text.cpp:761
const QString get_science_goal_text(Tech_type_id goal)
Set the science-goal-label text as if we're researching the given goal.
Definition: text.cpp:927
const QPixmap * get_tech_sprite(const struct tileset *t, Tech_type_id tech)
Return the sprite for the technology/advance.
Definition: tilespec.cpp:3385
const char * utype_name_translation(const struct unit_type *punittype)
Return the (translated) name of the unit type.
Definition: unittype.cpp:1256
void science_report_dialog_popup(bool raise)
Display the science report.
QString get_tooltip_improvement(impr_type *building, struct city *pcity, bool ext)
QString cut_helptext(const QString &text)
Remove some text from given text(help text) to show as tooltip.
Definition: optiondlg.cpp:87
bool comp_less_than(const qlist_item &q1, const qlist_item &q2)
Compare unit_items (used for techs) by name.
QString split_text(const QString &text, bool cut)
Splits long text to 80 characters.
Definition: optiondlg.cpp:45
void popdown_science_report()
Closes science report.
void science_report_dialog_redraw(void)
Resize and redraw the requirement tree.
QString get_tooltip_unit(struct unit_type *unit, bool ext)
void real_science_report_dialog_update(void *unused)
Update the science report.
void get_reqtree_dimensions(struct reqtree *reqtree, int *width, int *height)
Give the dimensions of the reqtree.
struct reqtree * create_reqtree(struct player *pplayer, bool show_all)
Generate optimized tech_tree from current ruleset.
QList< req_tooltip_help * > * draw_reqtree(struct reqtree *tree, QPixmap *pcanvas, int canvas_x, int canvas_y, int tt_x, int tt_y, int w, int h)
Draw the reqtree diagram!
Tech_type_id get_tech_on_reqtree(struct reqtree *tree, int x, int y)
Return the tech ID at the given position of the reqtree (or A_NONE).
void destroy_reqtree(struct reqtree *tree)
Free all memory used by tech_tree struct.
bool get_position_on_reqtree(struct reqtree *tree, Tech_type_id tech, int *x, int *y)
Find the center of a node, identified by tech id in a given reqtree and return true if the node was f...