Freeciv21
Develop your civilization from humble roots to a global empire
diplodlg.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 #include "diplodlg.h"
12 
13 #include <limits>
14 
15 // Qt
16 #include <QApplication>
17 #include <QCloseEvent>
18 #include <QGridLayout>
19 #include <QHeaderView>
20 #include <QLabel>
21 #include <QPainter>
22 #include <QPushButton>
23 #include <QSpinBox>
24 #include <QTableWidget>
25 // utility
26 #include "fcintl.h"
27 // common
28 #include "climisc.h"
29 #include "game.h"
30 #include "government.h"
31 #include "nation.h"
32 #include "player.h"
33 #include "research.h"
34 // client
35 #include "client_main.h"
36 #include "colors_common.h"
37 #include "diplodlg_g.h"
38 #include "fc_client.h"
39 #include "icons.h"
40 #include "page_game.h"
41 #include "tileset/sprite.h"
42 #include "top_bar.h"
43 #include "views/view_nations.h"
44 
48 diplo_wdg::diplo_wdg(int counterpart, int initiated_from)
49  : QWidget(), active_menu(0), curr_player(0), index(0)
50 {
51  QString text;
52  QString text2;
53  QString text_tooltip;
54  QLabel *plr1_label;
55  QLabel *plr2_label;
56  QLabel *label;
57  QLabel *label2;
58  QLabel *label3;
59  QLabel *label4;
60  QLabel *goldlab1;
61  QLabel *goldlab2;
62  QPushButton *add_clause1;
63  QPushButton *add_clause2;
64  const QPixmap *sprite, *sprite2;
65  char plr_buf[4 * MAX_LEN_NAME];
66  const struct player_diplstate *state;
67  QHeaderView *header;
68  QColor textcolors[2] = {get_color(tileset, COLOR_MAPVIEW_CITYTEXT),
69  get_color(tileset, COLOR_MAPVIEW_CITYTEXT_DARK)};
70  if (counterpart == initiated_from) {
71  initiated_from = client_player_number();
72  }
73  p1_accept = false;
74  p2_accept = false;
75  player1 = initiated_from;
76  player2 = counterpart;
77  layout = new QGridLayout;
78 
79  init_treaty(&treaty, player_by_number(counterpart),
80  player_by_number(initiated_from));
83  text_tooltip = QString(diplstate_type_translated_name(state->type));
84  if (state->turns_left > 0) {
85  text_tooltip = text_tooltip + " (";
86  text_tooltip =
87  text_tooltip
88  + QString(PL_("%1 turn left", "%1 turns left", state->turns_left))
89  .arg(state->turns_left);
90  text_tooltip = text_tooltip + ")";
91  }
92  label3 = new QLabel;
93  text =
94  "<b><h3><center>"
95  + QString(nation_plural_for_player(player_by_number(initiated_from)))
96  .toHtmlEscaped()
97  + "</center></h3></b>";
98  auto color = get_player_color(tileset, player_by_number(initiated_from));
99  text =
100  "<style>h3{background-color: " + color.name() + ";" + "color: "
101  + color_best_contrast(color, textcolors, ARRAY_SIZE(textcolors)).name()
102  + "}</style>" + text;
103  label3->setText(text);
104  label3->setMinimumWidth(300);
105  label4 = new QLabel;
106  text = "<b><h3><center>"
107  + QString(nation_plural_for_player(player_by_number(counterpart)))
108  .toHtmlEscaped()
109  + "</center></h3></b></body>";
110  color = get_player_color(tileset, player_by_number(counterpart));
111  text =
112  "<style>h3{background-color: " + color.name() + ";" + "color: "
113  + color_best_contrast(color, textcolors, ARRAY_SIZE(textcolors)).name()
114  + "}</style>" + text;
115  label4->setMinimumWidth(300);
116  label4->setText(text);
117  layout->addWidget(label3, 0, 5);
118  layout->addWidget(label4, 5, 5);
119  plr1_label = new QLabel;
120  label = new QLabel;
121  sprite = get_nation_flag_sprite(
122  tileset, nation_of_player(player_by_number(initiated_from)));
123  if (sprite != nullptr) {
124  plr1_label->setPixmap(*sprite);
125  } else {
126  plr1_label->setText(QStringLiteral("FLAG MISSING"));
127  }
128  text = ruler_title_for_player(player_by_number(initiated_from), plr_buf,
129  sizeof(plr_buf));
130  text = "<b><center>" + text.toHtmlEscaped() + "</center></b>";
131  label->setText(text);
132  plr1_accept = new QLabel;
133  layout->addWidget(plr1_label, 1, 0);
134  layout->addWidget(label, 1, 5);
135  layout->addWidget(plr1_accept, 1, 10);
136  label2 = new QLabel;
137  sprite2 = get_nation_flag_sprite(
138  tileset, nation_of_player(player_by_number(counterpart)));
139  plr2_label = new QLabel;
140  if (sprite2 != nullptr) {
141  plr2_label->setPixmap(*sprite2);
142  } else {
143  plr2_label->setText(QStringLiteral("FLAG MISSING"));
144  }
145  text2 = ruler_title_for_player(player_by_number(counterpart), plr_buf,
146  sizeof(plr_buf));
147  text2 = "<b><center>" + text2.toHtmlEscaped() + "</center></b>";
148  label2->setText(text2);
149  plr2_accept = new QLabel;
150  layout->addWidget(plr2_label, 6, 0);
151  layout->addWidget(label2, 6, 5);
152  layout->addWidget(plr2_accept, 6, 10);
153  goldlab1 = new QLabel(_("Gold:"));
154  goldlab1->setAlignment(Qt::AlignRight);
155  goldlab2 = new QLabel(_("Gold:"));
156  goldlab2->setAlignment(Qt::AlignRight);
157  gold_edit1 = new QSpinBox;
158  gold_edit2 = new QSpinBox;
159  gold_edit1->setMinimum(0);
160  gold_edit2->setMinimum(0);
161  gold_edit1->setMaximum(std::numeric_limits<std::int32_t>::max());
162  gold_edit2->setMaximum(std::numeric_limits<std::int32_t>::max());
163  gold_edit1->setFocusPolicy(Qt::ClickFocus);
164  gold_edit2->setFocusPolicy(Qt::ClickFocus);
165  gold_edit1->setEnabled(game.info.trading_gold);
166  gold_edit2->setEnabled(game.info.trading_gold);
167  connect(gold_edit1, qOverload<int>(&QSpinBox::valueChanged), this,
169  connect(gold_edit2, qOverload<int>(&QSpinBox::valueChanged), this,
171  add_clause1 = new QPushButton(style()->standardIcon(QStyle::SP_ArrowRight),
172  _("Add Clause..."));
173  add_clause2 = new QPushButton(style()->standardIcon(QStyle::SP_ArrowRight),
174  _("Add Clause..."));
175  add_clause1->setFocusPolicy(Qt::ClickFocus);
176  add_clause2->setFocusPolicy(Qt::ClickFocus);
177  connect(add_clause1, &QAbstractButton::clicked, this,
179  connect(add_clause2, &QAbstractButton::clicked, this,
181  layout->addWidget(goldlab1, 7, 4);
182  layout->addWidget(goldlab2, 3, 4);
183  layout->addWidget(gold_edit1, 7, 5);
184  layout->addWidget(gold_edit2, 3, 5);
185  layout->addWidget(add_clause1, 7, 6);
186  layout->addWidget(add_clause2, 3, 6);
187 
188  text_edit = new QTableWidget();
189  text_edit->setColumnCount(1);
190  text_edit->setProperty("showGrid", "false");
191  text_edit->setProperty("selectionBehavior", "SelectRows");
192  text_edit->setEditTriggers(QAbstractItemView::NoEditTriggers);
193  text_edit->verticalHeader()->setVisible(false);
194  text_edit->horizontalHeader()->setVisible(false);
195  text_edit->setSelectionMode(QAbstractItemView::SingleSelection);
196  text_edit->setFocusPolicy(Qt::NoFocus);
197  header = text_edit->horizontalHeader();
198  header->setStretchLastSection(true);
199  connect(text_edit, &QTableWidget::itemDoubleClicked, this,
201  text_edit->clearContents();
202  text_edit->setRowCount(0);
203  layout->addWidget(text_edit, 9, 0, 8, 11);
204  accept_treaty = new QPushButton(
205  style()->standardIcon(QStyle::SP_DialogYesButton), _("Accept treaty"));
206  cancel_treaty = new QPushButton(
207  style()->standardIcon(QStyle::SP_DialogNoButton), _("Cancel meeting"));
208  connect(accept_treaty, &QAbstractButton::clicked, this,
210  connect(cancel_treaty, &QAbstractButton::clicked, this,
212  layout->addWidget(accept_treaty, 17, 5);
213  layout->addWidget(cancel_treaty, 17, 6);
214 
215  if (client_player_number() != counterpart) {
216  label4->setToolTip(text_tooltip);
217  plr2_label->setToolTip(text_tooltip);
218  }
219  if (client_player_number() != initiated_from) {
220  label3->setToolTip(text_tooltip);
221  plr1_label->setToolTip(text_tooltip);
222  }
223 
224  accept_treaty->setAutoDefault(true);
225  accept_treaty->setDefault(true);
226  cancel_treaty->setAutoDefault(true);
227  setLayout(layout);
228  update_wdg();
229 }
230 
234 diplo_wdg::~diplo_wdg() = default;
235 
239 void diplo_wdg::dbl_click(QTableWidgetItem *item)
240 {
241  int i, r;
242 
243  r = item->row();
244  i = 0;
246  {
247  if (i == r) {
248  dsend_packet_diplomacy_remove_clause_req(
250  player_number(pclause->from), pclause->type, pclause->value);
251  return;
252  }
253  i++;
254  }
256 }
257 
261 void diplo_wdg::closeEvent(QCloseEvent *event)
262 {
263  if (C_S_RUNNING == client_state()) {
264  response_cancel();
265  }
266  event->accept();
267 }
268 
273 {
274  dsend_packet_diplomacy_create_clause_req(&client.conn, player2, player2,
275  CLAUSE_GOLD, val);
276 }
277 
282 {
283  dsend_packet_diplomacy_create_clause_req(&client.conn, player2, player1,
284  CLAUSE_GOLD, val);
285 }
286 
291 {
292  int other_player;
293  struct player *pgiver, *pother;
294  enum diplstate_type ds;
295  QAction *all_advancs;
296  QAction *some_action;
297  QAction *world_map, *sea_map;
298  QMap<QString, int> city_list;
302  QMenu *map_menu, *adv_menu, *city_menu, *pacts_menu;
303  QMenu *menu = new QMenu(this);
304  int id;
305 
307  if (curr_player == player1) {
308  other_player = player2;
309  } else {
310  other_player = player1;
311  }
312  pgiver = player_by_number(player);
313  pother = player_by_number(other_player);
314 
315  // Maps
316  map_menu = menu->addMenu(_("Maps"));
317  world_map = new QAction(_("World-map"), this);
318  connect(world_map, &QAction::triggered, this,
320  map_menu->addAction(world_map);
321  sea_map = new QAction(_("Sea-map"), this);
322  connect(sea_map, &QAction::triggered, this, &diplo_wdg::sea_map_clause);
323  map_menu->addAction(sea_map);
324 
325  // Trading: advances
326  if (game.info.trading_tech) {
327  const struct research *gresearch = research_get(pgiver);
328  const struct research *oresearch = research_get(pother);
329  adv_menu = menu->addMenu(_("Advances"));
330  advance_iterate(A_FIRST, padvance)
331  {
332  Tech_type_id i = advance_number(padvance);
333 
334  if (research_invention_state(gresearch, i) == TECH_KNOWN
335  && research_invention_gettable(oresearch, i,
336  game.info.tech_trade_allow_holes)
337  && (research_invention_state(oresearch, i) == TECH_UNKNOWN
338  || research_invention_state(oresearch, i)
339  == TECH_PREREQS_KNOWN)) {
340  adv_list.insert(advance_name_translation(padvance), i);
341  }
342  }
344 
345  // All advances
346  all_advancs = new QAction(_("All advances"), this);
347  connect(all_advancs, &QAction::triggered, this,
349  adv_menu->addAction(all_advancs);
350  adv_menu->addSeparator();
351 
352  // QMap is sorted by default when iterating
353  adv_iter = adv_list.constBegin();
354  if (adv_list.count() > 0) {
355  while (adv_iter != adv_list.constEnd()) {
356  id = adv_iter.value();
357  some_action = adv_menu->addAction(adv_iter.key());
358  connect(some_action, &QAction::triggered, this,
359  [=]() { give_advance(id); });
360  ++adv_iter;
361  }
362  } else {
363  adv_menu->setDisabled(true);
364  }
365  }
366 
367  // Trading: cities.
368  if (game.info.trading_city) {
369  city_menu = menu->addMenu(_("Cities"));
370 
371  city_list_iterate(pgiver->cities, pcity)
372  {
373  if (!is_capital(pcity)) {
374  city_list.insert(pcity->name, pcity->id);
375  }
376  }
378  city_iter = city_list.constBegin();
379  if (city_list.count() > 0) {
380  while (city_iter != city_list.constEnd()) {
381  id = city_iter.value();
382  some_action = city_menu->addAction(city_iter.key());
383  connect(some_action, &QAction::triggered, this,
384  [=]() { give_city(id); });
385  ++city_iter;
386  }
387  } else {
388  city_menu->setDisabled(true);
389  }
390  }
391  some_action = new QAction(_("Give shared vision"), this);
392  connect(some_action, &QAction::triggered, this,
394  menu->addAction(some_action);
395  if (gives_shared_vision(pgiver, pother)) {
396  some_action->setDisabled(true);
397  }
398  some_action = new QAction(_("Give embassy"), this);
399  connect(some_action, &QAction::triggered, this, &diplo_wdg::give_embassy);
400  menu->addAction(some_action);
401  if (player_has_real_embassy(pother, pgiver)) {
402  some_action->setDisabled(true);
403  }
404 
405  // Pacts
407  pacts_menu = menu->addMenu(_("Pacts"));
408  ds = player_diplstate_get(pgiver, pother)->type;
409  some_action = new QAction(Q_("?diplomatic_state:Cease-fire"), this);
410  connect(some_action, &QAction::triggered, this,
412  pacts_menu->addAction(some_action);
413  if (ds == DS_CEASEFIRE || ds == DS_TEAM) {
414  some_action->setDisabled(true);
415  }
416  some_action = new QAction(Q_("?diplomatic_state:Peace"), this);
417  connect(some_action, &QAction::triggered, this, &diplo_wdg::pact_peace);
418  pacts_menu->addAction(some_action);
419  if (ds == DS_PEACE || ds == DS_TEAM) {
420  some_action->setDisabled(true);
421  }
422  some_action = new QAction(Q_("?diplomatic_state:Alliance"), this);
423  connect(some_action, &QAction::triggered, this,
425  pacts_menu->addAction(some_action);
426  if (ds == DS_ALLIANCE || ds == DS_TEAM) {
427  some_action->setDisabled(true);
428  }
429  }
430 
431  // Check user response for not defined responses in slots
432  menu->setAttribute(Qt::WA_DeleteOnClose);
433  menu->popup(QCursor::pos());
434 }
435 
440 {
441  dsend_packet_diplomacy_create_clause_req(&client.conn,
443  curr_player, CLAUSE_EMBASSY, 0);
444 }
445 
450 {
451  dsend_packet_diplomacy_create_clause_req(&client.conn,
453  curr_player, CLAUSE_VISION, 0);
454 }
455 
460 {
461  dsend_packet_diplomacy_create_clause_req(&client.conn,
463  curr_player, CLAUSE_ALLIANCE, 0);
464 }
465 
470 {
471  dsend_packet_diplomacy_create_clause_req(&client.conn,
473  curr_player, CLAUSE_CEASEFIRE, 0);
474 }
475 
480 {
481  dsend_packet_diplomacy_create_clause_req(&client.conn,
483  curr_player, CLAUSE_PEACE, 0);
484 }
485 
490 {
491  dsend_packet_diplomacy_create_clause_req(&client.conn,
493  curr_player, CLAUSE_SEAMAP, 0);
494 }
495 
500 {
501  dsend_packet_diplomacy_create_clause_req(
502  &client.conn, player_number(treaty.plr0), curr_player, CLAUSE_MAP, 0);
503 }
504 
508 void diplo_wdg::give_city(int city_num)
509 {
510  int giver, dest, other;
511 
512  giver = curr_player;
513  if (curr_player == player1) {
514  dest = player2;
515  } else {
516  dest = player1;
517  }
518 
519  if (player_by_number(giver) == client_player()) {
520  other = dest;
521  } else {
522  other = giver;
523  }
524 
525  dsend_packet_diplomacy_create_clause_req(&client.conn, other, giver,
526  CLAUSE_CITY, city_num);
527 }
528 
533 {
534  int giver, dest, other;
535 
536  giver = curr_player;
537  if (curr_player == player1) {
538  dest = player2;
539  } else {
540  dest = player1;
541  }
542 
543  if (player_by_number(giver) == client_player()) {
544  other = dest;
545  } else {
546  other = giver;
547  }
548 
549  dsend_packet_diplomacy_create_clause_req(&client.conn, other, giver,
550  CLAUSE_ADVANCE, tech);
551 }
552 
557 {
558  int giver, dest, other;
559  const struct research *dresearch, *gresearch;
560 
561  giver = curr_player;
562  if (curr_player == player1) {
563  dest = player2;
564  } else {
565  dest = player1;
566  }
567 
568  if (player_by_number(giver) == client_player()) {
569  other = dest;
570  } else {
571  other = giver;
572  }
573 
574  // All techs.
575  struct player *pgiver = player_by_number(giver);
576  struct player *pdest = player_by_number(dest);
577 
578  fc_assert_ret(nullptr != pgiver);
579  fc_assert_ret(nullptr != pdest);
580 
581  dresearch = research_get(pdest);
582  gresearch = research_get(pgiver);
583 
584  advance_iterate(A_FIRST, padvance)
585  {
586  Tech_type_id i = advance_number(padvance);
587 
588  if (research_invention_state(gresearch, i) == TECH_KNOWN
589  && research_invention_gettable(dresearch, i,
590  game.info.tech_trade_allow_holes)
591  && (research_invention_state(dresearch, i) == TECH_UNKNOWN
592  || research_invention_state(dresearch, i)
593  == TECH_PREREQS_KNOWN)) {
594  dsend_packet_diplomacy_create_clause_req(&client.conn, other, giver,
595  CLAUSE_ADVANCE, i);
596  }
597  }
599 }
600 
605 
610 
614 void diplo_wdg::set_index(int ind) { index = ind; }
615 
619 int diplo_wdg::get_index() { return index; }
620 
625 {
626  bool blank;
627  int i;
628  QTableWidgetItem *qitem;
629 
630  blank = true;
631  text_edit->clearContents();
632  text_edit->setRowCount(0);
633  i = 0;
635  {
636  char buf[128];
637  client_diplomacy_clause_string(buf, sizeof(buf), pclause);
638  text_edit->insertRow(i);
639  qitem = new QTableWidgetItem();
640  qitem->setText(buf);
641  qitem->setTextAlignment(Qt::AlignLeft);
642  text_edit->setItem(i, 0, qitem);
643  blank = false;
644  i++;
645  }
647 
648  if (blank) {
649  text_edit->insertRow(0);
650  qitem = new QTableWidgetItem();
651  qitem->setText(_("--- This treaty is blank. "
652  "Please add some clauses. ---"));
653  qitem->setTextAlignment(Qt::AlignLeft);
654  text_edit->setItem(0, 0, qitem);
655  }
656 
658  if (sprite != nullptr) {
659  plr1_accept->setPixmap(*sprite);
660  } else {
661  plr1_accept->setText(QStringLiteral("PIXMAP MISSING"));
662  }
663 
665  if (sprite != nullptr) {
666  plr2_accept->setPixmap(*sprite);
667  } else {
668  plr2_accept->setText(QStringLiteral("PIXMAP MISSING"));
669  }
670 }
671 
676 {
677  queen()->sw_diplo->setIcon(
678  fcIcons::instance()->getIcon(QStringLiteral("nations")));
679  queen()->sw_diplo->update();
680 }
681 
686 {
687  restore_pixmap();
688  dsend_packet_diplomacy_accept_treaty_req(&client.conn,
690 }
691 
696 {
697  restore_pixmap();
698  dsend_packet_diplomacy_cancel_meeting_req(&client.conn,
700 }
701 
705 diplo_dlg::diplo_dlg(int counterpart, int initiated_from) : QTabWidget()
706 {
707  add_widget(counterpart, initiated_from);
708  setFocusPolicy(Qt::ClickFocus);
709 }
710 
714 void diplo_dlg::add_widget(int counterpart, int initiated_from)
715 {
716  diplo_wdg *dw;
717  int i;
718 
719  dw = new diplo_wdg(counterpart, initiated_from);
720  treaty_list.insert(counterpart, dw);
721  i = addTab(dw, nation_plural_for_player(player_by_number(counterpart)));
722  dw->set_index(i);
723  auto sprite = get_nation_flag_sprite(
724  tileset, nation_of_player(player_by_number(counterpart)));
725  if (sprite != nullptr) {
726  setTabIcon(i, QIcon(*sprite));
727  }
728 }
729 
733 void diplo_dlg::make_active(int party)
734 {
735  QWidget *w;
736 
737  w = find_widget(party);
738  if (w == nullptr) {
739  return;
740  }
741  setCurrentWidget(w);
742 }
743 
747 bool diplo_dlg::init(bool raise)
748 {
749  Q_UNUSED(raise)
750  if (!can_client_issue_orders()) {
751  return false;
752  }
753  if (!is_human(client.conn.playing)) {
754  return false;
755  }
756  setAttribute(Qt::WA_DeleteOnClose);
757  queen()->gimmePlace(this, QStringLiteral("DDI"));
758  index = queen()->addGameTab(this);
759  queen()->game_tab_widget->setCurrentIndex(index);
760 
761  return true;
762 }
763 
768 {
769  QMapIterator<int, diplo_wdg *> i(treaty_list);
770  diplo_wdg *dw;
771 
772  while (i.hasNext()) {
773  i.next();
774  dw = i.value();
775  dw->close();
776  removeTab(dw->get_index());
777  dw->deleteLater();
778  }
779  queen()->removeRepoDlg(QStringLiteral("DDI"));
781 }
782 
787 {
788  return treaty_list.value(counterpart);
789 }
790 
794 void diplo_dlg::close_widget(int counterpart)
795 {
796  diplo_wdg *dw;
797 
798  dw = treaty_list.take(counterpart);
799  removeTab(dw->get_index());
800  dw->deleteLater();
801  if (treaty_list.isEmpty()) {
802  close();
803  }
804 }
805 
810 {
811  QMapIterator<int, diplo_wdg *> i(treaty_list);
812  diplo_wdg *dw;
813 
814  while (i.hasNext()) {
815  i.next();
816  dw = i.value();
817  dw->update_wdg();
818  }
819 }
820 
825 void handle_diplomacy_accept_treaty(int counterpart, bool I_accepted,
826  bool other_accepted)
827 {
828  int i;
829  diplo_dlg *dd;
830  diplo_wdg *dw;
831  QWidget *w;
832 
833  if (!queen()->isRepoDlgOpen(QStringLiteral("DDI"))) {
835  return;
836  }
837  i = queen()->gimmeIndexOf(QStringLiteral("DDI"));
838  fc_assert(i != -1);
839  w = queen()->game_tab_widget->widget(i);
840  dd = qobject_cast<diplo_dlg *>(w);
841  dw = dd->find_widget(counterpart);
842  dw->treaty.accept0 = I_accepted;
843  dw->treaty.accept1 = other_accepted;
844  dw->update_wdg();
845  update_top_bar_diplomacy_status(dd->count() > 0);
846 }
847 
852 void handle_diplomacy_init_meeting(int counterpart, int initiated_from)
853 {
854  int i;
855  diplo_dlg *dd;
856  QWidget *w;
857  QWidget *fw;
858 
859  if (client_is_observer()) {
860  return;
861  }
862 
863  if (king()->current_page() != PAGE_GAME) {
864  king()->switch_page(PAGE_GAME);
865  }
866 
867  if (!queen()->isRepoDlgOpen(QStringLiteral("DDI"))) {
868  dd = new diplo_dlg(counterpart, initiated_from);
869 
870  if (!dd->init(false)) {
871  delete dd;
872  return;
873  }
874  dd->update_dlg();
875  dd->make_active(counterpart);
876  }
877  i = queen()->gimmeIndexOf(QStringLiteral("DDI"));
878  fc_assert(i != -1);
879  w = queen()->game_tab_widget->widget(i);
880  dd = qobject_cast<diplo_dlg *>(w);
881  fw = dd->find_widget(counterpart);
882  if (fw == nullptr) {
883  dd->add_widget(counterpart, initiated_from);
884  queen()->game_tab_widget->setCurrentIndex(i);
885  }
886  dd->make_active(counterpart);
887 
888  // Bring it to front if user requested meeting
889  if (player_by_number(initiated_from) == client.conn.playing) {
890  queen()->game_tab_widget->setCurrentIndex(i);
891  }
892  update_top_bar_diplomacy_status(dd->count() > 0);
893 }
894 
898 void handle_diplomacy_create_clause(int counterpart, int giver,
899  enum clause_type type, int value)
900 {
901  int i;
902  diplo_dlg *dd;
903  diplo_wdg *dw;
904  QWidget *w;
905 
906  if (!queen()->isRepoDlgOpen(QStringLiteral("DDI"))) {
908  return;
909  }
910  i = queen()->gimmeIndexOf(QStringLiteral("DDI"));
911  fc_assert(i != -1);
912  w = queen()->game_tab_widget->widget(i);
913  dd = qobject_cast<diplo_dlg *>(w);
914  dw = dd->find_widget(counterpart);
915  add_clause(&dw->treaty, player_by_number(giver), type, value);
916  dw->update_wdg();
917 }
918 
923 void handle_diplomacy_cancel_meeting(int counterpart, int initiated_from)
924 {
925  int i;
926  diplo_dlg *dd;
927  QWidget *w;
928 
929  if (!queen()->isRepoDlgOpen(QStringLiteral("DDI"))) {
931  return;
932  }
933  i = queen()->gimmeIndexOf(QStringLiteral("DDI"));
934  fc_assert(i != -1);
935  w = queen()->game_tab_widget->widget(i);
936  dd = qobject_cast<diplo_dlg *>(w);
937  dd->close_widget(counterpart);
938  update_top_bar_diplomacy_status(dd->count() > 0);
939 }
940 
944 void handle_diplomacy_remove_clause(int counterpart, int giver,
945  enum clause_type type, int value)
946 {
947  int i;
948  diplo_dlg *dd;
949  diplo_wdg *dw;
950  QWidget *w;
951 
952  if (!queen()->isRepoDlgOpen(QStringLiteral("DDI"))) {
954  return;
955  }
956  i = queen()->gimmeIndexOf(QStringLiteral("DDI"));
957  fc_assert(i != -1);
958  w = queen()->game_tab_widget->widget(i);
959  dd = qobject_cast<diplo_dlg *>(w);
960  dw = dd->find_widget(counterpart);
961  remove_clause(&dw->treaty, player_by_number(giver), type, value);
962  dw->update_wdg();
963 }
964 
971 {
972  int i;
973  diplo_dlg *dd;
974  QWidget *w;
975 
976  qApp->alert(king()->central_wdg);
977  if (!queen()->isRepoDlgOpen(QStringLiteral("DDI"))) {
979  return;
980  }
981  i = queen()->gimmeIndexOf(QStringLiteral("DDI"));
982  fc_assert(i != -1);
983  w = queen()->game_tab_widget->widget(i);
984  dd = qobject_cast<diplo_dlg *>(w);
986  dd->close();
987  delete dd;
988 }
bool is_capital(const struct city *pcity)
Return TRUE iff this city is its nation's capital.
Definition: city.cpp:1495
#define city_list_iterate(citylist, pcity)
Definition: city.h:482
#define city_list_iterate_end
Definition: city.h:484
QMap< int, diplo_wdg * > treaty_list
Definition: diplodlg.h:88
void make_active(int party)
Sets given widget as active in current dialog.
Definition: diplodlg.cpp:733
~diplo_dlg() override
Destructor for diplomacy dialog.
Definition: diplodlg.cpp:767
diplo_dlg(int counterpart, int initiated_from)
Constructor for diplomacy dialog.
Definition: diplodlg.cpp:705
void close_widget(int counterpart)
Closes given diplomacy widget.
Definition: diplodlg.cpp:794
void update_dlg()
Updates all diplomacy widgets in current dialog.
Definition: diplodlg.cpp:809
void add_widget(int counterpart, int initiated_from)
Creates new diplomacy widget and adds to diplomacy dialog.
Definition: diplodlg.cpp:714
diplo_wdg * find_widget(int counterpart)
Finds diplomacy widget in current dialog.
Definition: diplodlg.cpp:786
bool init(bool raise)
Initializes some data for diplomacy dialog.
Definition: diplodlg.cpp:747
int index
Definition: diplodlg.h:101
void response_accept()
Button 'Accept treaty' has been clicked.
Definition: diplodlg.cpp:685
void pact_ceasfire()
Ceasefire pact menu activated.
Definition: diplodlg.cpp:469
bool p2_accept
Definition: diplodlg.h:79
QSpinBox * gold_edit1
Definition: diplodlg.h:37
void show_menu_p1()
Show menu for first player.
Definition: diplodlg.cpp:609
void give_embassy()
Give embassy menu activated.
Definition: diplodlg.cpp:439
~diplo_wdg() override
Destructor for diplomacy widget.
QLabel * plr2_accept
Definition: diplodlg.h:34
void show_menu(int player)
Shows popup menu with available clauses to create.
Definition: diplodlg.cpp:290
void gold_changed1(int val)
Gold changed on first spinner.
Definition: diplodlg.cpp:272
void world_map_clause()
World map menu activated.
Definition: diplodlg.cpp:499
void gold_changed2(int val)
Gold changed on second spinner.
Definition: diplodlg.cpp:281
QTableWidget * text_edit
Definition: diplodlg.h:39
int get_index()
Sets index in QTabWidget.
Definition: diplodlg.cpp:619
void pact_allianze()
Create alliance menu activated.
Definition: diplodlg.cpp:459
int player1
Definition: diplodlg.h:74
void all_advances()
Give all advances menu activated.
Definition: diplodlg.cpp:556
QPushButton * cancel_treaty
Definition: diplodlg.h:36
void closeEvent(QCloseEvent *event) override
Received event about diplomacy widget being closed.
Definition: diplodlg.cpp:261
void sea_map_clause()
Sea map menu activated.
Definition: diplodlg.cpp:489
void give_shared_vision()
Give shared vision menu activated.
Definition: diplodlg.cpp:449
QSpinBox * gold_edit2
Definition: diplodlg.h:38
void give_city(int city_num)
Give city menu activated.
Definition: diplodlg.cpp:508
void response_cancel()
Button 'Cancel treaty' has been clicked.
Definition: diplodlg.cpp:695
void dbl_click(QTableWidgetItem *item)
Double click on treaty list - it removes clicked clause from list.
Definition: diplodlg.cpp:239
void show_menu_p2()
Show menu for second player.
Definition: diplodlg.cpp:604
void update_wdg()
Updates diplomacy widget - updates clauses and redraws pixmaps.
Definition: diplodlg.cpp:624
int curr_player
Definition: diplodlg.h:77
int index
Definition: diplodlg.h:80
void restore_pixmap()
Restores original nations pixmap.
Definition: diplodlg.cpp:675
bool p1_accept
Definition: diplodlg.h:78
diplo_wdg(int id, int id2)
Constructor for diplomacy widget.
Definition: diplodlg.cpp:48
QPushButton * accept_treaty
Definition: diplodlg.h:35
int player2
Definition: diplodlg.h:75
void give_advance(int tech)
Give advance menu activated.
Definition: diplodlg.cpp:532
QGridLayout * layout
Definition: diplodlg.h:32
void pact_peace()
Peace pact menu activated.
Definition: diplodlg.cpp:479
void set_index(int ind)
Sets index in QTabWidget.
Definition: diplodlg.cpp:614
struct Treaty treaty
Definition: diplodlg.h:47
QLabel * plr1_accept
Definition: diplodlg.h:33
static fcIcons * instance()
Returns instance of fc_icons.
Definition: icons.cpp:36
void switch_page(int i)
Switch from one client page to another.
Definition: fc_client.cpp:180
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
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
top_bar_widget * sw_diplo
Definition: page_game.h:86
enum client_states client_state()
Return current client state.
int client_player_number()
Returns number of player attached to client.
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.
@ C_S_RUNNING
Definition: client_main.h:43
void client_diplomacy_clause_string(char *buf, int bufsiz, struct Clause *pclause)
Copy a string that describes the given clause into the return buffer.
Definition: climisc.cpp:213
QColor color_best_contrast(const QColor &subject, const QColor *candidates, int ncandidates)
Find the colour from 'candidates' with the best perceptual contrast from 'subject'.
QColor get_color(const struct tileset *t, enum color_std stdcolor)
Return a pointer to the given "standard" color.
QColor get_player_color(const struct tileset *t, const struct player *pplayer)
Return the color of the player.
void handle_diplomacy_init_meeting(int counterpart, int initiated_from)
Handle the start of a diplomacy meeting - usually by poping up a diplomacy dialog.
Definition: diplodlg.cpp:852
void handle_diplomacy_cancel_meeting(int counterpart, int initiated_from)
Update the diplomacy dialog when the meeting is canceled (the dialog should be closed).
Definition: diplodlg.cpp:923
void handle_diplomacy_create_clause(int counterpart, int giver, enum clause_type type, int value)
Update the diplomacy dialog by adding a clause.
Definition: diplodlg.cpp:898
void handle_diplomacy_remove_clause(int counterpart, int giver, enum clause_type type, int value)
Update the diplomacy dialog by removing a clause.
Definition: diplodlg.cpp:944
void close_all_diplomacy_dialogs()
Close all open diplomacy dialogs.
Definition: diplodlg.cpp:970
void handle_diplomacy_accept_treaty(int counterpart, bool I_accepted, bool other_accepted)
Update a player's acceptance status of a treaty (traditionally shown with the thumbs-up/thumbs-down s...
Definition: diplodlg.cpp:825
bool add_clause(struct Treaty *ptreaty, struct player *pfrom, enum clause_type type, int val)
Add clause to treaty.
Definition: diptreaty.cpp:134
void init_treaty(struct Treaty *ptreaty, struct player *plr0, struct player *plr1)
Initialize treaty structure between two players.
Definition: diptreaty.cpp:87
bool remove_clause(struct Treaty *ptreaty, struct player *pfrom, enum clause_type type, int val)
Remove clause from treaty.
Definition: diptreaty.cpp:110
#define clause_list_iterate_end
Definition: diptreaty.h:61
#define clause_list_iterate(clauselist, pclause)
Definition: diptreaty.h:59
enum event_type event
Definition: events.cpp:68
class fc_client * king()
Return fc_client instance.
Definition: gui_main.cpp:58
int Tech_type_id
Definition: fc_types.h:294
#define MAX_LEN_NAME
Definition: fc_types.h:61
#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 * ruler_title_for_player(const struct player *pplayer, char *buf, size_t buf_len)
Return the ruler title of the player (translated).
Definition: government.cpp:366
#define fc_assert_ret(condition)
Definition: log.h:112
#define fc_assert(condition)
Definition: log.h:89
const char * nation_plural_for_player(const struct player *pplayer)
Return the (translated) plural noun of the given nation of a player.
Definition: nation.cpp:155
struct nation_type * nation_of_player(const struct player *pplayer)
Return the nation of a player.
Definition: nation.cpp:419
pageGame * queen()
Return game instandce.
Definition: page_game.cpp:557
struct player * player_by_number(const int player_id)
Return struct player pointer for the given player index.
Definition: player.cpp:768
int player_number(const struct player *pplayer)
Return the player index/number/id.
Definition: player.cpp:756
bool player_has_real_embassy(const struct player *pplayer, const struct player *pplayer2)
Returns whether pplayer has a real embassy with pplayer2, established from a diplomat,...
Definition: player.cpp:206
bool gives_shared_vision(const struct player *me, const struct player *them)
Return TRUE iff the player me gives shared vision to player them.
Definition: player.cpp:1414
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Returns diplomatic state type between two players.
Definition: player.cpp:288
#define is_human(plr)
Definition: player.h:226
struct research * research_get(const struct player *pplayer)
Returns the research structure associated with the player.
Definition: research.cpp:110
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
bool research_invention_gettable(const struct research *presearch, const Tech_type_id tech, bool allow_holes)
Returns TRUE iff the given tech can be given to the players sharing the research immediately.
Definition: research.cpp:686
#define ARRAY_SIZE(x)
Definition: shared.h:79
struct player * plr0
Definition: diptreaty.h:70
bool accept0
Definition: diptreaty.h:71
bool accept1
Definition: diptreaty.h:71
struct clause_list * clauses
Definition: diptreaty.h:72
struct packet_game_info info
Definition: game.h:80
struct connection conn
Definition: client_main.h:89
struct player * playing
Definition: connection.h:142
Definition: climisc.h:66
enum diplstate_type type
Definition: player.h:193
Definition: player.h:231
struct city_list * cities
Definition: player.h:263
Tech_type_id advance_number(const struct advance *padvance)
Return the advance index.
Definition: tech.cpp:85
const char * advance_name_translation(const struct advance *padvance)
Return the (translated) name of the given advance/technology.
Definition: tech.cpp:274
#define advance_iterate(_start, _p)
Definition: tech.h:232
#define A_FIRST
Definition: tech.h:37
#define advance_iterate_end
Definition: tech.h:238
const QPixmap * get_nation_flag_sprite(const struct tileset *t, const struct nation_type *pnation)
Return the sprite for the nation.
Definition: tilespec.cpp:3367
const QPixmap * get_treaty_thumb_sprite(const struct tileset *t, bool on_off)
Return a thumbs-up/thumbs-down sprite to show treaty approval or disapproval.
Definition: tilespec.cpp:3495
void top_bar_show_map()
Callback to show map.
Definition: top_bar.cpp:448
void update_top_bar_diplomacy_status(bool notify)
Function to update the top bar button.