Freeciv-3.1
Loading...
Searching...
No Matches
plrdlg.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 <QApplication>
20#include <QHBoxLayout>
21#include <QHeaderView>
22#include <QMouseEvent>
23#include <QPainter>
24#include <QPushButton>
25#include <QSplitter>
26#include <QVBoxLayout>
27
28// gui-qt
29#include "fc_client.h"
30#include "gui_main.h"
31#include "plrdlg.h"
32
33/**********************************************************************/
36static QRect check_box_rect(const QStyleOptionViewItem
37 &view_item_style_options)
38{
39 QStyleOptionButton cbso;
40 QRect check_box_rect = QApplication::style()->subElementRect(
41 QStyle::SE_CheckBoxIndicator, &cbso);
42 QPoint check_box_point(view_item_style_options.rect.x() +
43 view_item_style_options.rect.width() / 2 -
44 check_box_rect.width() / 2,
45 view_item_style_options.rect.y() +
46 view_item_style_options.rect.height() / 2 -
47 check_box_rect.height() / 2);
48
49 return QRect(check_box_point, check_box_rect.size());
50}
51
52/**********************************************************************/
55QSize plr_item_delegate::sizeHint(const QStyleOptionViewItem &option,
56 const QModelIndex &index) const
57{
58 QSize r;
59
60 r = QItemDelegate::sizeHint(option, index);
61 r.setHeight(r.height() + 4);
62
63 return r;
64}
65
66/**********************************************************************/
69void plr_item_delegate::paint(QPainter *painter, const QStyleOptionViewItem
70 &option, const QModelIndex &index) const
71{
72 QStyleOptionButton but;
73 QStyleOptionButton cbso;
74 bool b;
75 QString str;
76 QRect rct;
77 QPixmap pix(16, 16);
78 QStyleOptionViewItem opt = QItemDelegate::setOptions(index, option);
79 QFontMetrics *fm;
80 QFont f;
81 QPixmap pm;
82
83 painter->save();
84 switch (player_dlg_columns[index.column()].type) {
85 case COL_FLAG:
86 QItemDelegate::drawBackground(painter, opt, index);
87 pm = index.data().value<QPixmap>();
89 fm = new QFontMetrics(f);
90
91 // We used to do the scaling on index.data() side,
92 // but it was scaling the original flag, needed in the
93 // full size for other uses.
94 pm = pm.scaledToHeight(fm->height());
95 delete fm;
96 QItemDelegate::drawDecoration(painter, opt, option.rect, pm);
97 break;
98 case COL_COLOR:
99 pix.fill(index.data().value <QColor> ());
100 QItemDelegate::drawBackground(painter, opt, index);
101 QItemDelegate::drawDecoration(painter, opt, option.rect, pix);
102 break;
103 case COL_BOOLEAN:
104 b = index.data().toBool();
105 QItemDelegate::drawBackground(painter, opt, index);
106 cbso.state |= QStyle::State_Enabled;
107 if (b) {
108 cbso.state |= QStyle::State_On;
109 } else {
110 cbso.state |= QStyle::State_Off;
111 }
112 cbso.rect = check_box_rect(option);
113
114 QApplication::style()->drawControl(QStyle::CE_CheckBox, &cbso, painter);
115 break;
116 case COL_TEXT:
117 QItemDelegate::paint(painter, option, index);
118 break;
119 case COL_RIGHT_TEXT:
120 QItemDelegate::drawBackground(painter, opt, index);
121 opt.displayAlignment = Qt::AlignRight;
122 rct = option.rect;
123 rct.setTop((rct.top() + rct.bottom()) / 2
124 - opt.fontMetrics.height() / 2);
125 rct.setBottom((rct.top()+rct.bottom()) / 2
126 + opt.fontMetrics.height() / 2);
127 if (index.data().toInt() == -1) {
128 str = "?";
129 } else {
130 str = index.data().toString();
131 }
132 QItemDelegate::drawDisplay(painter, opt, rct, str);
133 break;
134 default:
135 QItemDelegate::paint(painter, option, index);
136 }
137 painter->restore();
138}
139
140/**********************************************************************/
143plr_item::plr_item(struct player *pplayer): QObject()
144{
145 ipplayer = pplayer;
146}
147
148/**********************************************************************/
151bool plr_item::setData(int column, const QVariant &value, int role)
152{
153 return false;
154}
155
156/**********************************************************************/
159QVariant plr_item::data(int column, int role) const
160{
161 QFont f;
162 QString str;
163 struct player_dlg_column *pdc;
164
165 if (role == Qt::UserRole) {
166 return QVariant::fromValue((void *)ipplayer);
167 }
168 if (role != Qt::DisplayRole) {
169 return QVariant();
170 }
171 pdc = &player_dlg_columns[column];
172 switch (player_dlg_columns[column].type) {
173 case COL_FLAG:
175 break;
176 case COL_COLOR:
178 break;
179 case COL_BOOLEAN:
180 return pdc->bool_func(ipplayer);
181 break;
182 case COL_TEXT:
183 return pdc->func(ipplayer);
184 break;
185 case COL_RIGHT_TEXT:
186 str = pdc->func(ipplayer);
187 if (str.toInt() != 0) {
188 return str.toInt();
189 } else if (str == "?") {
190 return -1;
191 }
192 return str;
193 default:
194 return QVariant();
195 }
196}
197
198/**********************************************************************/
201plr_model::plr_model(QObject *parent): QAbstractListModel(parent)
202{
203 populate();
204}
205
206/**********************************************************************/
210{
211 qDeleteAll(plr_list);
212 plr_list.clear();
213}
214
215/**********************************************************************/
218QVariant plr_model::data(const QModelIndex &index, int role) const
219{
220 if (!index.isValid()) {
221 return QVariant();
222 }
223
224 if (index.row() >= 0 && index.row() < rowCount() && index.column() >= 0
225 && index.column() < columnCount()) {
226 return plr_list[index.row()]->data(index.column(), role);
227 }
228
229 return QVariant();
230}
231
232/**********************************************************************/
235QVariant plr_model::headerData(int section, Qt::Orientation orientation,
236 int role) const
237{
238 struct player_dlg_column *pcol;
239
240 if (orientation == Qt::Horizontal && section < num_player_dlg_columns) {
241 if (role == Qt::DisplayRole) {
243
244 return pcol->title;
245 }
246 }
247
248 return QVariant();
249}
250
251/**********************************************************************/
254bool plr_model::setData(const QModelIndex &index, const QVariant &value,
255 int role)
256{
257 if (!index.isValid() || role != Qt::DisplayRole) {
258 return false;
259 }
260
261 if (index.row() >= 0 && index.row() < rowCount() && index.column() >= 0
262 && index.column() < columnCount()) {
263 bool change = plr_list[index.row()]->setData(index.column(), value, role);
264
265 if (change) {
266 notify_plr_changed(index.row());
267 }
268
269 return change;
270 }
271
272 return false;
273}
274
275/**********************************************************************/
279{
280 emit dataChanged(index(row, 0), index(row, columnCount() - 1));
281}
282
283/**********************************************************************/
287{
288 plr_item *pi;
289
290 qDeleteAll(plr_list);
291 plr_list.clear();
292 beginResetModel();
293
294 // This is duplicated at plr_sorter::lessThan() for
295 // index <-> player mapping to match
296 players_iterate(pplayer) {
297 if ((is_barbarian(pplayer))) {
298 continue;
299 }
300 pi = new plr_item(pplayer);
301 plr_list << pi;
303
304 endResetModel();
305}
306
307/**********************************************************************/
310plr_sorter::plr_sorter(QObject *parent) : QSortFilterProxyModel(parent)
311{
312}
313
314/**********************************************************************/
320
321/**********************************************************************/
324bool plr_sorter::lessThan(const QModelIndex &left,
325 const QModelIndex &right) const
326{
327 struct player_dlg_column *column = &(player_dlg_columns[left.column()]);
328
329 if (column->sort_func != NULL) {
330 int li = left.row();
331 int ri = right.row();
332 int i = 0;
333 struct player *lplr = NULL;
334 struct player *rplr = NULL;
335
336 // Duplicates populate() logic to find player matching index
337 players_iterate(pplayer) {
338 if ((is_barbarian(pplayer))) {
339 continue;
340 }
341
342 if (i == li) {
343 lplr = pplayer;
344 }
345 if (i++ == ri) {
346 rplr = pplayer;
347 }
349
350 // Convert three-state (left better, equal, right better)
351 // return from sort_func() to lessThan() boolean
352 return column->sort_func(lplr, rplr) < 0;
353 }
354
355 // Use default sort when no sort function defined
356 return QSortFilterProxyModel::lessThan(left, right);
357}
358
359/**********************************************************************/
363{
364 plr = pr;
365 other_player = NULL;
366 selected_player = nullptr;
367 pid = new plr_item_delegate(this);
368 setItemDelegate(pid);
369 list_model = new plr_model(this);
370 filter_model = new plr_sorter(this);
371 filter_model->setDynamicSortFilter(true);
372 filter_model->setSourceModel(list_model);
373 filter_model->setFilterRole(Qt::DisplayRole);
374 setModel(filter_model);
375 setRootIsDecorated(false);
376 setAllColumnsShowFocus(true);
377 setSortingEnabled(true);
378 setSelectionMode(QAbstractItemView::SingleSelection);
379 setItemsExpandable(false);
380 setAutoScroll(true);
381 setAlternatingRowColors(true);
382 header()->setContextMenuPolicy(Qt::CustomContextMenu);
383 hide_columns();
384 connect(header(), &QWidget::customContextMenuRequested,
386 connect(selectionModel(),
387 SIGNAL(selectionChanged(const QItemSelection &,
388 const QItemSelection &)),
389 SLOT(nation_selected(const QItemSelection &,
390 const QItemSelection &)));
391}
392
393/**********************************************************************/
397{
398 QItemSelection selection;
399 QModelIndex i;
400 struct player *pplayer;
401 QVariant qvar;
402
403 if (selected_player == nullptr) {
404 return;
405 }
406
407 for (int j = 0; j < filter_model->rowCount(); j++) {
408 i = filter_model->index(j, 0);
409 qvar = i.data(Qt::UserRole);
410 if (qvar.isNull()) {
411 continue;
412 }
413 pplayer = reinterpret_cast<struct player *>(qvar.value<void *>());
414 if (selected_player == pplayer) {
415 selection.append(QItemSelectionRange(i));
416 }
417 }
418 selectionModel()->select(selection, QItemSelectionModel::Rows
419 | QItemSelectionModel::SelectCurrent);
420}
421
422/**********************************************************************/
426{
427 QMenu *hideshow_column = new QMenu(this);
428 QList<QAction *> actions;
429
430 hideshow_column->setTitle(_("Column visibility"));
431
432 for (int i = 0; i < list_model->columnCount(); ++i) {
433 QAction *myAct = hideshow_column->addAction(
434 list_model->headerData(i, Qt::Horizontal,
435 Qt::DisplayRole).toString());
436 myAct->setCheckable(true);
437 myAct->setChecked(!isColumnHidden(i));
438 actions.append(myAct);
439 }
440
441 hideshow_column->setAttribute(Qt::WA_DeleteOnClose);
442 connect(hideshow_column, &QMenu::triggered, this,
443 CAPTURE_DEFAULT_THIS (QAction *act) {
444 int col;
445 struct player_dlg_column *pcol;
446
447 if (!act) {
448 return;
449 }
450
451 col = actions.indexOf(act);
452 fc_assert_ret(col >= 0);
453 pcol = &player_dlg_columns[col];
454 pcol->show = !pcol->show;
455 setColumnHidden(col, !isColumnHidden(col));
456 if (!isColumnHidden(col) && columnWidth(col) <= 5)
457 setColumnWidth(col, 100);
458 });
459
460 hideshow_column->popup(QCursor::pos());
461}
462
463/**********************************************************************/
466QVariant plr_model::hide_data(int section) const
467{
468 struct player_dlg_column *pcol;
469
471
472 return pcol->show;
473}
474
475/**********************************************************************/
479{
480 int col;
481
482 for (col = 0; col < list_model->columnCount(); col++) {
483 if (!list_model->hide_data(col).toBool()) {
484 setColumnHidden(col, !isColumnHidden(col));
485 }
486 }
487}
488
489/**********************************************************************/
492void plr_widget::nation_selected(const QItemSelection &sl,
493 const QItemSelection &ds)
494{
495 QModelIndex index;
496 QVariant qvar;
497 QModelIndexList indexes = sl.indexes();
498 struct city *pcity;
499 const struct player_diplstate *state;
500 struct research *my_research, *research;
501 char tbuf[256];
502 QString res;
503 QString sp = " ";
504 QString etax, esci, elux, egold, egov;
505 QString cult;
506 QString nl = "<br>";
507 QStringList sorted_list_a;
508 QStringList sorted_list_b;
509 struct player *pplayer;
510 int a, b;
511 bool added;
512 bool entry_exist = false;
513 struct player *me;
514 Tech_type_id tech_id;
515 bool global_observer = client_is_global_observer();
516 QString rule;
517 bool intel;
518
519 other_player = NULL;
520 intel_str.clear();
521 tech_str.clear();
522 ally_str.clear();
523 wonder_str.clear();
524
525 if (indexes.isEmpty()) {
526 selected_player = nullptr;
527 plr->update_report(false);
528 return;
529 }
530
531 index = indexes.at(0);
532 qvar = index.data(Qt::UserRole);
533 pplayer = reinterpret_cast<player *>(qvar.value<void *>());
534 selected_player = pplayer;
535 other_player = pplayer;
536
537 if (!pplayer->is_alive) {
538 plr->update_report(false);
539 return;
540 }
541
542 me = client_player();
543 pcity = player_primary_capital(pplayer);
544 research = research_get(pplayer);
545
546 switch (research->researching) {
547 case A_UNKNOWN:
548 res = _("(Unknown)");
549 break;
550 case A_UNSET:
551 if (global_observer || team_has_embassy(me->team, pplayer)) {
552 res = _("(none)");
553 } else {
554 res = _("(Unknown)");
555 }
556 break;
557 default:
560 + sp + "(" + QString::number(research->bulbs_researched) + "/"
561 + QString::number(research->client.researching_cost) + ")";
562 break;
563 }
564 if (global_observer || team_has_embassy(me->team, pplayer)) {
565 etax = QString::number(pplayer->economic.tax) + "%";
566 esci = QString::number(pplayer->economic.science) + "%";
567 elux = QString::number(pplayer->economic.luxury) + "%";
568 cult = QString::number(pplayer->client.culture);
569 } else {
570 etax = _("(Unknown)");
571 esci = _("(Unknown)");
572 elux = _("(Unknown)");
573 cult = _("(Unknown)");
574 }
575
576 intel = global_observer || could_intel_with_player(me, pplayer);
577
578 if (intel || pplayer == me) {
579 egold = QString::number(pplayer->economic.gold);
580 egov = QString(government_name_for_player(pplayer));
581 } else {
582 egold = _("(Unknown)");
583 egov = _("(Unknown)");
584 }
586 intel_str =
587 /* TRANS: this and similar literal strings interpreted as (Qt) HTML */
588 QString("<table><tr><td><b>") + _("Nation") + QString("</b></td><td>")
589 + QString(nation_adjective_for_player(pplayer)).toHtmlEscaped()
590 + QString("</td><tr><td><b>") + _("Ruler:") + QString("</b></td><td>")
591 + QString(title_for_player(pplayer, tbuf, sizeof(tbuf)))
592 .toHtmlEscaped()
593 + QString("</td></tr><tr><td><b>") + _("Government:")
594 + QString("</b></td><td>") + egov.toHtmlEscaped()
595 + QString("</td></tr><tr><td><b>") + _("Capital:")
596 + QString("</b></td><td>")
597 + QString(((!pcity) ? _("(Unknown)") : city_name_get(pcity)))
598 .toHtmlEscaped()
599 + QString("</td></tr><tr><td><b>") + _("Gold:")
600 + QString("</b></td><td>") + egold.toHtmlEscaped()
601 + QString("</td></tr><tr><td><b>") + _("Tax:")
602 + QString("</b></td><td>") + etax.toHtmlEscaped()
603 + QString("</td></tr><tr><td><b>") + _("Science:")
604 + QString("</b></td><td>") + esci.toHtmlEscaped()
605 + QString("</td></tr><tr><td><b>") + _("Luxury:")
606 + QString("</b></td><td>") + elux.toHtmlEscaped()
607 + QString("</td></tr><tr><td><b>") + _("Researching:")
608 + QString("</b></td><td>") + res.toHtmlEscaped()
609 + QString("<td></tr><tr><td><b>") + _("Culture:")
610 + QString("</b></td><td>") + cult.toHtmlEscaped()
611
612 // HACK: Reserve extra line of space in case some line wraps to two later
613 + QString("</td>\u200B<td>")
614 + QString("</td></table>");
615
616 for (int i = 0; i < static_cast<int>(DS_LAST); i++) {
617 added = false;
618 if (entry_exist) {
619 ally_str += "<br>";
620 }
621 entry_exist = false;
622 players_iterate_alive(other) {
623 if (other == pplayer || is_barbarian(other)) {
624 continue;
625 }
626 state = player_diplstate_get(pplayer, other);
627 if (static_cast<int>(state->type) == i && intel) {
628 if (!added) {
629 ally_str = ally_str + QString("<b>")
630 + QString(diplstate_type_translated_name(
631 static_cast<diplstate_type>(i)))
632 .toHtmlEscaped()
633 + ": " + QString("</b>") + nl;
634 added = true;
635 }
636 if (gives_shared_vision(pplayer, other)) {
637 ally_str = ally_str + "(◐‿◑)";
638 }
640 + QString(nation_plural_for_player(other)).toHtmlEscaped()
641 + ", ";
642 entry_exist = true;
643 }
645 if (entry_exist) {
646 ally_str.replace(ally_str.lastIndexOf(","), 1, ".");
647 }
648 }
649 my_research = research_get(me);
650
651 if (!global_observer) {
652 if (team_has_embassy(me->team, pplayer) && me != pplayer) {
653 a = 0;
654 b = 0;
655 techs_known = QString(_("<b>Techs unknown by %1:</b>")).
656 arg(QString(nation_plural_for_player(pplayer))
657 .toHtmlEscaped());
658 techs_unknown = QString(_("<b>Techs unknown by you :</b>"));
659
660 advance_iterate(A_FIRST, padvance) {
661 tech_id = advance_number(padvance);
662 if (research_invention_state(my_research, tech_id) == TECH_KNOWN
664 != TECH_KNOWN)) {
665 a++;
667 tech_id);
668 }
669 if (research_invention_state(my_research, tech_id) != TECH_KNOWN
670 && (research_invention_state(research, tech_id) == TECH_KNOWN)) {
671 b++;
673 tech_id);
674 }
676 sorted_list_a.sort(Qt::CaseInsensitive);
677 sorted_list_b.sort(Qt::CaseInsensitive);
678 foreach (res, sorted_list_a) {
679 techs_known = techs_known + QString("<i>")
680 + res.toHtmlEscaped() + ","
681 + QString("</i>") + sp;
682 }
683 foreach (res, sorted_list_b) {
684 techs_unknown = techs_unknown + QString("<i>")
685 + res.toHtmlEscaped() + ","
686 + QString("</i>") + sp;
687 }
688 if (a == 0) {
689 techs_known = techs_known + QString("<i>") + sp
690 + QString(Q_("?tech:None")) + QString("</i>");
691 } else {
692 techs_known.replace(techs_known.lastIndexOf(","), 1, ".");
693 }
694 if (b == 0) {
695 techs_unknown = techs_unknown + QString("<i>") + sp
696 + QString(Q_("?tech:None")) + QString("</i>");
697 } else {
698 techs_unknown.replace(techs_unknown.lastIndexOf(","), 1, ".");
699 }
701 }
702 } else {
703 tech_str = QString(_("<b>Techs known by %1:</b>")).
704 arg(QString(nation_plural_for_player(pplayer)).toHtmlEscaped());
705 advance_iterate(A_FIRST, padvance) {
706 tech_id = advance_number(padvance);
707 if (research_invention_state(research, tech_id) == TECH_KNOWN) {
708 sorted_list_a << research_advance_name_translation(research, tech_id);
709 }
711 sorted_list_a.sort(Qt::CaseInsensitive);
712 foreach (res, sorted_list_a) {
713 tech_str = tech_str + QString("<i>") + res.toHtmlEscaped() + ","
714 + QString("</i>") + sp;
715 }
716 }
717
719 case WV_ALWAYS:
720 rule = _("All Wonders are known");
721 break;
722 case WV_NEVER:
723 rule = _("Small Wonders not known");
724 break;
725 }
726
727 wonder_str = "<b>"
728 + QString(_("Wonders of %1 Empire")).arg(QString(nation_plural_for_player(pplayer)).toHtmlEscaped())
729 + "</b>" + nl + QString(_("Rule: ")) + rule + nl;
730
731 improvement_iterate(impr) {
732 if (is_wonder(impr)) {
733 const char *cityname;
734 QString notes;
735 QString wonstr;
736
737 if (wonder_is_built(pplayer, impr)) {
738 struct city *wcity = city_from_wonder(pplayer, impr);
739
740 if (wcity != NULL) {
741 cityname = city_name_get(wcity);
742 } else {
743 cityname = _("(unknown city)");
744 }
745 if (improvement_obsolete(pplayer, impr, NULL)) {
746 notes = _(" (obsolete)");
747 }
748 } else if (wonder_is_lost(pplayer, impr)) {
749 cityname = _("(lost)");
750 } else {
751 continue;
752 }
753
754 if (is_great_wonder(impr)) {
755 wonstr = QString("<b>") + improvement_name_translation(impr) + QString("</b>");
756 } else {
757 wonstr = improvement_name_translation(impr);
758 }
759
760 wonder_str += wonstr + QString(" ") + cityname + notes + nl;
761 }
763
764 plr->update_report(false);
765}
766
767/**********************************************************************/
771{
772 return list_model;
773}
774
775/**********************************************************************/
779{
780 delete pid;
781 delete list_model;
782 delete filter_model;
783 gui()->qt_settings.player_repo_sort_col = header()->sortIndicatorSection();
784 gui()->qt_settings.player_report_sort = header()->sortIndicatorOrder();
785}
786
787/**********************************************************************/
791{
792 QFrame *line;
793
794 v_splitter = new QSplitter(Qt::Vertical);
795 h_splitter = new QSplitter(Qt::Horizontal);
796 layout = new QVBoxLayout;
797 hlayout = new QHBoxLayout;
798 plr_wdg = new plr_widget(this);
799 plr_label = new QLabel;
800 plr_label->setFrameStyle(QFrame::StyledPanel);
801 plr_label->setAlignment(Qt::AlignTop | Qt::AlignLeft);
802 plr_label->setWordWrap(true);
803 plr_label->setTextFormat(Qt::RichText);
804 ally_label = new QLabel;
805 ally_label->setFrameStyle(QFrame::StyledPanel);
806 ally_label->setTextFormat(Qt::RichText);
807 ally_label->setAlignment(Qt::AlignTop | Qt::AlignLeft);
808 ally_label->setWordWrap(true);
809 tech_label = new QLabel;
810 tech_label->setTextFormat(Qt::RichText);
811 tech_label->setFrameStyle(QFrame::StyledPanel);
812 tech_label->setAlignment(Qt::AlignTop | Qt::AlignLeft);
813 tech_label->setWordWrap(true);
814 wonder_label = new QLabel;
815 wonder_label->setFrameStyle(QFrame::StyledPanel);
816 wonder_label->setAlignment(Qt::AlignTop | Qt::AlignLeft);
817 wonder_label->setWordWrap(true);
818 wonder_label->setTextFormat(Qt::RichText);
819 meet_but = new QPushButton;
820 meet_but->setText(_("Meet"));
821 cancel_but = new QPushButton;
822 cancel_but->setText(_("Cancel Treaty"));
823 withdraw_but = new QPushButton;
824 withdraw_but->setText(_("Withdraw Vision"));
825 toggle_ai_but = new QPushButton;
826 toggle_ai_but->setText(_("AI Mode"));
827 show_relations = new QPushButton;
828 show_relations->setText(_("Hide Relations"));
829 show_techs = new QPushButton;
830 show_techs->setText(_("Hide Techs"));
831 show_wonders = new QPushButton;
832 show_wonders->setText(_("Hide Wonders"));
833 meet_but->setDisabled(true);
834 cancel_but->setDisabled(true);
835 withdraw_but->setDisabled(true);
836 v_splitter->addWidget(plr_wdg);
837 h_splitter->addWidget(plr_label);
838 h_splitter->addWidget(ally_label);
839 h_splitter->addWidget(tech_label);
840 h_splitter->addWidget(wonder_label);
841 v_splitter->addWidget(h_splitter);
842 layout->addWidget(v_splitter);
843 hlayout->addWidget(meet_but);
844 hlayout->addWidget(cancel_but);
845 hlayout->addWidget(withdraw_but);
846 hlayout->addWidget(toggle_ai_but);
847 line = new QFrame();
848 line->setFrameShape(QFrame::VLine);
849 hlayout->addWidget(line);
850 hlayout->addWidget(show_relations);
851 hlayout->addWidget(show_techs);
852 hlayout->addWidget(show_wonders);
853 hlayout->addStretch();
854 layout->addLayout(hlayout);
855 connect(meet_but, &QAbstractButton::pressed, this, &plr_report::req_meeeting);
856 connect(cancel_but, &QAbstractButton::pressed, this, &plr_report::req_caancel_threaty);
857 connect(withdraw_but, &QAbstractButton::pressed, this, &plr_report::req_wiithdrw_vision);
858 connect(toggle_ai_but, &QAbstractButton::pressed, this, &plr_report::toggle_ai_mode);
859 connect(show_relations, &QAbstractButton::pressed, this, &plr_report::show_relations_toggle);
860 connect(show_techs, &QAbstractButton::pressed, this, &plr_report::show_techs_toggle);
861 connect(show_wonders, &QAbstractButton::pressed, this, &plr_report::show_wonders_toggle);
862 setLayout(layout);
863
864 if (gui()->qt_settings.player_repo_sort_col != -1) {
865 plr_wdg->sortByColumn(gui()->qt_settings.player_repo_sort_col,
866 gui()->qt_settings.player_report_sort);
867 }
868}
869
870/**********************************************************************/
874{
875 gui()->remove_repo_dlg("PLR");
876}
877
878/**********************************************************************/
882{
883 gui()->gimme_place(this, "PLR");
884 index = gui()->add_game_tab(this);
885 gui()->game_tab_widget->setCurrentIndex(index);
886}
887
888/**********************************************************************/
892{
893 if (meet_but->isEnabled()) {
894 req_meeeting();
895 }
896}
897
898/**********************************************************************/
908
909/**********************************************************************/
917
918/**********************************************************************/
927
928/**********************************************************************/
932{
934 send_chat_printf("/away \"%s\"",
936 return;
937 } else {
938 QMenu *ai_menu = new QMenu(this);
939 QAction *toggle_ai_act;
940 int level;
941
942 toggle_ai_act = new QAction(_("Toggle AI Mode"), nullptr);
943 ai_menu->addAction(toggle_ai_act);
944
945 ai_menu->addSeparator();
946 for (level = 0; level < AI_LEVEL_COUNT; level++) {
947 if (is_settable_ai_level(static_cast<ai_level>(level))) {
948 QAction *ai_level_act;
949 QString ln = ai_level_translated_name(static_cast<ai_level>(level));
950
951 ai_level_act = new QAction(ln, nullptr);
952 ai_level_act->setData(QVariant::fromValue(level));
953 ai_menu->addAction(ai_level_act);
954 }
955 }
956
957 ai_menu->setAttribute(Qt::WA_DeleteOnClose);
958 connect(ai_menu, &QMenu::triggered,
959 CAPTURE_DEFAULT_THIS (QAction *act) {
960 int lvl;
961
962 if (act == toggle_ai_act) {
963 send_chat_printf("/aitoggle \"%s\"",
965 return;
966 }
967
968 if (act && act->isVisible()) {
969 lvl = act->data().toInt();
971 send_chat_printf("/aitoggle \"%s\"",
973 }
974 send_chat_printf("/%s %s", ai_level_cmd(static_cast<ai_level>(lvl)),
976 }
977 });
978
979 ai_menu->popup(QCursor::pos());
980 }
981}
982
983/**********************************************************************/
987{
988 if (ally_label->isVisible()) {
989 ally_label->hide();
990 show_relations->setText(_("Show Relations"));
991 } else {
992 ally_label->show();
993 show_relations->setText(_("Hide Relations"));
994 }
995}
996
997/**********************************************************************/
1001{
1002 if (tech_label->isVisible()) {
1003 tech_label->hide();
1004 show_techs->setText(_("Show Techs"));
1005 } else {
1006 tech_label->show();
1007 show_techs->setText(_("Hide Techs"));
1008 }
1009}
1010
1011/**********************************************************************/
1015{
1016 if (wonder_label->isVisible()) {
1017 wonder_label->hide();
1018 show_wonders->setText(_("Show Wonders"));
1019 } else {
1020 wonder_label->show();
1021 show_wonders->setText(_("Hide Wonders"));
1022 }
1023}
1024
1025/**********************************************************************/
1029{
1030 QModelIndex index = this->indexAt(event->pos());
1031
1032 if (index.isValid() && event->button() == Qt::RightButton
1034 plr->call_meeting();
1035 }
1036
1037 QTreeView::mousePressEvent(event);
1038}
1039
1040/**********************************************************************/
1043void plr_report::update_report(bool update_selection)
1044{
1045 QModelIndex qmi;
1046 int player_count = 0;
1047
1048 /* First make sure number of rows is correct - there can be new
1049 * nations because of civil war. We don't want our actions to
1050 * trigger automatic sorting of the model while number of rows
1051 * is not correct. */
1052 players_iterate(pplayer) {
1053 if ((is_barbarian(pplayer))) {
1054 continue;
1055 }
1056 player_count++;
1058
1059 if (player_count != plr_wdg->get_model()->rowCount()) {
1061 }
1062
1063 /* Force updating selected player information */
1064 if (update_selection) {
1065 qmi = plr_wdg->currentIndex();
1066 if (qmi.isValid()) {
1067 plr_wdg->clearSelection();
1068 plr_wdg->setCurrentIndex(qmi);
1069 }
1070 }
1071
1072 plr_wdg->header()->resizeSections(QHeaderView::ResizeToContents);
1073 meet_but->setDisabled(true);
1074 cancel_but->setDisabled(true);
1075 withdraw_but->setDisabled(true);
1076 plr_label->setText(plr_wdg->intel_str);
1077 ally_label->setText(plr_wdg->ally_str);
1078 tech_label->setText(plr_wdg->tech_str);
1079 wonder_label->setText(plr_wdg->wonder_str);
1081 if (other_player == NULL || !can_client_issue_orders()) {
1082 return;
1083 }
1084 if (NULL != client.conn.playing) {
1086
1087 // We keep button sensitive in case of DIPL_SENATE_BLOCKING, so that player
1088 // can request server side to check requirements of those effects with omniscience
1090 cancel_but->setEnabled(true);
1091 }
1092 toggle_ai_but->setText(_("AI Mode"));
1093 } else {
1094 toggle_ai_but->setText(_("Away Mode"));
1095 }
1096 } else {
1097 toggle_ai_but->setText(_("AI Mode"));
1098 }
1101 withdraw_but->setEnabled(true);
1102 }
1104 meet_but->setEnabled(true);
1105 }
1107}
1108
1109/**********************************************************************/
1112void popup_players_dialog(bool raise)
1113{
1114 int i;
1115 QWidget *w;
1116
1117 if (!gui()->is_repo_dlg_open("PLR")) {
1118 plr_report *pr = new plr_report;
1119
1120 pr->init();
1121 pr->update_report();
1122 } else {
1123 plr_report *pr;
1124
1125 i = gui()->gimme_index_of("PLR");
1126 w = gui()->game_tab_widget->widget(i);
1127 if (w->isVisible()) {
1128 gui()->game_tab_widget->setCurrentIndex(0);
1129 return;
1130 }
1131 pr = reinterpret_cast<plr_report*>(w);
1132 gui()->game_tab_widget->setCurrentWidget(pr);
1133 pr->update_report();
1134 }
1135}
1136
1137/**********************************************************************/
1141{
1142 int i;
1143 plr_report *pr;
1144 QWidget *w;
1145
1146 if (gui()->is_repo_dlg_open("PLR")) {
1147 i = gui()->gimme_index_of("PLR");
1148 if (gui()->game_tab_widget->currentIndex() == i) {
1149 w = gui()->game_tab_widget->widget(i);
1150 pr = reinterpret_cast<plr_report *>(w);
1151 pr->update_report();
1152 }
1153 }
1154}
1155
1156/**********************************************************************/
1160{
1161 int i;
1162 plr_report *pr;
1163 QWidget *w;
1164
1165 if (gui()->is_repo_dlg_open("PLR")) {
1166 i = gui()->gimme_index_of("PLR");
1167 fc_assert(i != -1);
1168 w = gui()->game_tab_widget->widget(i);
1169 pr = reinterpret_cast<plr_report *>(w);
1170 pr->deleteLater();
1171 }
1172}
static struct action * actions[MAX_NUM_ACTIONS]
Definition actions.c:96
#define str
Definition astring.c:76
int send_chat_printf(const char *format,...)
const char * city_name_get(const struct city *pcity)
Definition city.c:1115
static fc_font * instance()
Definition fonts.cpp:41
QFont * get_font(QString name)
Definition fonts.cpp:63
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
Definition plrdlg.cpp:55
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
Definition plrdlg.cpp:69
bool setData(int column, const QVariant &value, int role=Qt::DisplayRole)
Definition plrdlg.cpp:151
QVariant data(int column, int role=Qt::DisplayRole) const
Definition plrdlg.cpp:159
struct player * ipplayer
Definition plrdlg.h:76
plr_item(struct player *pplayer)
Definition plrdlg.cpp:143
plr_model(QObject *parent=0)
Definition plrdlg.cpp:201
int rowCount(const QModelIndex &index=QModelIndex()) const
Definition plrdlg.h:88
QVariant headerData(int section, Qt::Orientation orientation, int role) const
Definition plrdlg.cpp:235
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::DisplayRole)
Definition plrdlg.cpp:254
void populate()
Definition plrdlg.cpp:286
QVariant hide_data(int section) const
Definition plrdlg.cpp:466
QList< plr_item * > plr_list
Definition plrdlg.h:106
void notify_plr_changed(int row)
Definition plrdlg.cpp:278
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const
Definition plrdlg.cpp:218
int columnCount(const QModelIndex &parent=QModelIndex()) const
Definition plrdlg.h:92
void req_caancel_threaty()
Definition plrdlg.cpp:902
QLabel * wonder_label
Definition plrdlg.h:168
void call_meeting()
Definition plrdlg.cpp:891
void update_report(bool update_selection=true)
Definition plrdlg.cpp:1043
QVBoxLayout * layout
Definition plrdlg.h:178
int index
Definition plrdlg.h:188
struct player * other_player
Definition plrdlg.h:187
void toggle_ai_mode()
Definition plrdlg.cpp:931
QPushButton * toggle_ai_but
Definition plrdlg.h:174
QPushButton * cancel_but
Definition plrdlg.h:172
void show_wonders_toggle()
Definition plrdlg.cpp:1014
QSplitter * v_splitter
Definition plrdlg.h:169
plr_widget * plr_wdg
Definition plrdlg.h:164
QLabel * tech_label
Definition plrdlg.h:167
void req_meeeting()
Definition plrdlg.cpp:912
QLabel * plr_label
Definition plrdlg.h:165
void show_relations_toggle()
Definition plrdlg.cpp:986
QPushButton * withdraw_but
Definition plrdlg.h:173
void init()
Definition plrdlg.cpp:881
QPushButton * show_techs
Definition plrdlg.h:176
QLabel * ally_label
Definition plrdlg.h:166
QPushButton * show_relations
Definition plrdlg.h:175
QSplitter * h_splitter
Definition plrdlg.h:170
void req_wiithdrw_vision()
Definition plrdlg.cpp:921
QPushButton * show_wonders
Definition plrdlg.h:177
void show_techs_toggle()
Definition plrdlg.cpp:1000
QHBoxLayout * hlayout
Definition plrdlg.h:179
QPushButton * meet_but
Definition plrdlg.h:171
plr_sorter(QObject *parent)
Definition plrdlg.cpp:310
bool lessThan(const QModelIndex &left, const QModelIndex &right) const
Definition plrdlg.cpp:324
void nation_selected(const QItemSelection &sl, const QItemSelection &ds)
Definition plrdlg.cpp:492
QString techs_known
Definition plrdlg.h:136
struct player * selected_player
Definition plrdlg.h:138
plr_widget(plr_report *pr)
Definition plrdlg.cpp:362
plr_report * plr
Definition plrdlg.h:135
plr_model * list_model
Definition plrdlg.h:132
plr_item_delegate * pid
Definition plrdlg.h:134
QString tech_str
Definition plrdlg.h:146
plr_model * get_model() const
Definition plrdlg.cpp:770
QString intel_str
Definition plrdlg.h:144
QString wonder_str
Definition plrdlg.h:147
struct player * other_player
Definition plrdlg.h:148
void display_header_menu(const QPoint &)
Definition plrdlg.cpp:425
plr_sorter * filter_model
Definition plrdlg.h:133
QString ally_str
Definition plrdlg.h:145
QString techs_unknown
Definition plrdlg.h:137
void hide_columns()
Definition plrdlg.cpp:478
void restore_selection()
Definition plrdlg.cpp:396
void mousePressEvent(QMouseEvent *event)
Definition plrdlg.cpp:1028
bool client_is_global_observer(void)
bool can_meet_with_player(const struct player *pplayer)
struct civclient client
bool can_client_issue_orders(void)
const char * title_for_player(const struct player *pplayer, char *buf, size_t buf_len)
#define client_player()
struct color * get_player_color(const struct tileset *t, const struct player *pplayer)
bool could_intel_with_player(const struct player *pplayer, const struct player *aplayer)
Definition diptreaty.c:81
enum event_type event
Definition events.c:81
int Tech_type_id
Definition fc_types.h:347
#define Q_(String)
Definition fcintl.h:70
#define _(String)
Definition fcintl.h:67
struct civ_game game
Definition game.c:57
const char * government_name_for_player(const struct player *pplayer)
Definition government.c:153
GType type
Definition repodlgs.c:1312
@ COL_TEXT
Definition unitselect.c:50
#define CAPTURE_DEFAULT_THIS
Definition gui_main.h:23
bool wonder_is_lost(const struct player *pplayer, const struct impr_type *pimprove)
bool wonder_is_built(const struct player *pplayer, const struct impr_type *pimprove)
struct city * city_from_wonder(const struct player *pplayer, const struct impr_type *pimprove)
bool is_wonder(const struct impr_type *pimprove)
bool is_great_wonder(const struct impr_type *pimprove)
bool improvement_obsolete(const struct player *pplayer, const struct impr_type *pimprove, const struct city *pcity)
const char * improvement_name_translation(const struct impr_type *pimprove)
#define improvement_iterate_end
#define improvement_iterate(_p)
#define fc_assert_ret(condition)
Definition log.h:191
#define fc_assert(condition)
Definition log.h:176
static mpgui * gui
Definition mpgui_qt.cpp:52
const char *const default_font
Definition fonts.h:27
const char * nation_adjective_for_player(const struct player *pplayer)
Definition nation.c:168
struct nation_type * nation_of_player(const struct player *pplayer)
Definition nation.c:443
const char * nation_plural_for_player(const struct player *pplayer)
Definition nation.c:177
int dsend_packet_diplomacy_cancel_pact(struct connection *pc, int other_player_id, enum clause_type clause)
int dsend_packet_diplomacy_init_meeting_req(struct connection *pc, int counterpart)
bool is_settable_ai_level(enum ai_level level)
Definition player.c:1883
bool players_on_same_team(const struct player *pplayer1, const struct player *pplayer2)
Definition player.c:1452
int player_count(void)
Definition player.c:808
int player_number(const struct player *pplayer)
Definition player.c:828
const char * player_name(const struct player *pplayer)
Definition player.c:886
bool team_has_embassy(const struct team *pteam, const struct player *tgt_player)
Definition player.c:214
struct city * player_primary_capital(const struct player *pplayer)
Definition player.c:1313
enum dipl_reason pplayer_can_cancel_treaty(const struct player *p1, const struct player *p2)
Definition player.c:92
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Definition player.c:317
bool gives_shared_vision(const struct player *me, const struct player *them)
Definition player.c:1461
#define ai_level_cmd(_level_)
Definition player.h:565
#define players_iterate_end
Definition player.h:535
@ DIPL_ERROR
Definition player.h:195
#define players_iterate(_pplayer)
Definition player.h:530
static bool is_barbarian(const struct player *pplayer)
Definition player.h:488
#define players_iterate_alive_end
Definition player.h:545
#define is_human(plr)
Definition player.h:233
#define players_iterate_alive(_pplayer)
Definition player.h:540
void popdown_players_report()
Definition plrdlg.cpp:1159
void real_players_dialog_update(void *unused)
Definition plrdlg.cpp:1140
void popup_players_dialog(bool raise)
Definition plrdlg.cpp:1112
static QRect check_box_rect(const QStyleOptionViewItem &view_item_style_options)
Definition plrdlg.cpp:36
struct player_dlg_column player_dlg_columns[]
const int num_player_dlg_columns
@ COL_BOOLEAN
@ COL_FLAG
@ COL_RIGHT_TEXT
@ COL_COLOR
const char * research_advance_name_translation(const struct research *presearch, Tech_type_id tech)
Definition research.c:271
struct research * research_get(const struct player *pplayer)
Definition research.c:126
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Definition research.c:616
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:183
Definition city.h:309
struct packet_game_info info
Definition game.h:89
struct connection conn
Definition client_main.h:96
QColor qcolor
Definition colors.h:25
struct player * playing
Definition connection.h:156
enum wonder_visib_type small_wonder_visibility
enum diplstate_type type
Definition player.h:201
bool(* bool_func)(const struct player *)
plr_dlg_sort_func sort_func
const char *(* func)(const struct player *)
const char * title
enum player_dlg_column_type type
struct player::@69::@72 client
struct team * team
Definition player.h:261
bool is_alive
Definition player.h:268
struct player_economic economic
Definition player.h:284
int culture
Definition player.h:367
Tech_type_id researching
Definition research.h:52
struct research::@75::@77 client
int researching_cost
Definition research.h:98
int bulbs_researched
Definition research.h:53
QPixmap * pm
Definition sprite.h:25
Tech_type_id advance_number(const struct advance *padvance)
Definition tech.c:98
#define advance_iterate(_start, _p)
Definition tech.h:264
#define A_FIRST
Definition tech.h:44
#define A_UNSET
Definition tech.h:48
#define advance_iterate_end
Definition tech.h:270
#define A_UNKNOWN
Definition tech.h:49
struct sprite * get_nation_flag_sprite(const struct tileset *t, const struct nation_type *pnation)
Definition tilespec.c:6467