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)
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 ***********************************************************************/
15 #include <fc_config.h>
20 #include <QHeaderView>
21 #include <QMessageBox>
22 #include <QRadioButton>
23 #include <QTableWidgetItem>
33 #include "government.h"
34 #include "improvement.h"
48 #include "qtg_cxxside.h"
51 static void diplomat_keep_moving(QVariant data1
, QVariant data2
);
52 static void diplomat_incite(QVariant data1
, QVariant data2
);
53 static void spy_request_sabotage_list(QVariant data1
, QVariant data2
);
54 static void spy_sabotage(QVariant data1
, QVariant data2
);
55 static void spy_steal(QVariant data1
, QVariant data2
);
56 static void spy_steal_something(QVariant data1
, QVariant data2
);
57 static void diplomat_steal(QVariant data1
, QVariant data2
);
58 static void spy_poison(QVariant data1
, QVariant data2
);
59 static void diplomat_embassy(QVariant data1
, QVariant data2
);
60 static void spy_sabotage_unit(QVariant data1
, QVariant data2
);
61 static void diplomat_investigate(QVariant data1
, QVariant data2
);
62 static void diplomat_sabotage(QVariant data1
, QVariant data2
);
63 static void diplomat_bribe(QVariant data1
, QVariant data2
);
64 static void caravan_establish_trade(QVariant data1
, QVariant data2
);
65 static void caravan_help_build(QVariant data1
, QVariant data2
);
66 static void keep_moving(QVariant data1
, QVariant data2
);
67 static void caravan_keep_moving(QVariant data1
, QVariant data2
);
68 static void pillage_something(QVariant data1
, QVariant data2
);
70 static int caravan_city_id
= 0;
71 static int caravan_unit_id
= 0;
72 static bool caravan_dialog_open
= false;
73 static bool is_showing_pillage_dialog
= false;
74 static choice_dialog
*caravan_dialog
= NULL
;
75 static races_dialog
* race_dialog
;
76 static bool is_race_dialog_open
= false;
78 /***************************************************************************
79 Constructor for selecting nations
80 ***************************************************************************/
81 races_dialog::races_dialog(struct player
*pplayer
, QWidget
* parent
):QDialog(parent
)
83 struct nation_group
*group
;
85 QGridLayout
*qgroupbox_layout
;
88 QTableWidgetItem
*item
;
94 setAttribute(Qt::WA_DeleteOnClose
);
95 is_race_dialog_open
= true;
96 main_layout
= new QGridLayout
;
97 nation_tabs
= new QToolBox(parent
);
98 selected_nation_tabs
= new QTableWidget
;
99 city_styles
= new QTableWidget
;
100 ok_button
= new QPushButton
;
103 selected_nation
= -1;
106 setWindowTitle(_("Select Nation"));
107 selected_nation_tabs
->setRowCount(0);
108 selected_nation_tabs
->setColumnCount(1);
109 selected_nation_tabs
->setSelectionMode(QAbstractItemView::SingleSelection
);
110 selected_nation_tabs
->verticalHeader()->setVisible(false);
111 selected_nation_tabs
->horizontalHeader()->setVisible(false);
112 selected_nation_tabs
->setProperty("showGrid", "true");
113 selected_nation_tabs
->setEditTriggers(QAbstractItemView::NoEditTriggers
);
115 city_styles
->setRowCount(0);
116 city_styles
->setColumnCount(2);
117 city_styles
->setSelectionMode(QAbstractItemView::SingleSelection
);
118 city_styles
->verticalHeader()->setVisible(false);
119 city_styles
->horizontalHeader()->setVisible(false);
120 city_styles
->setProperty("showGrid", "false");
121 city_styles
->setProperty("selectionBehavior", "SelectRows");
122 city_styles
->setEditTriggers(QAbstractItemView::NoEditTriggers
);
124 qgroupbox_layout
= new QGridLayout
;
125 no_name
= new QGroupBox(parent
);
126 leader_name
= new QComboBox(no_name
);
127 is_male
= new QRadioButton(no_name
);
128 is_female
= new QRadioButton(no_name
);
130 leader_name
->setEditable(true);
131 qgroupbox_layout
->addWidget(leader_name
, 1, 0, 1, 2);
132 qgroupbox_layout
->addWidget(is_male
, 2, 1);
133 qgroupbox_layout
->addWidget(is_female
, 2, 0);
134 is_female
->setText(_("Female"));
135 is_male
->setText(_("Male"));
136 no_name
->setLayout(qgroupbox_layout
);
138 description
= new QTextEdit
;
139 description
->setReadOnly(true);
140 description
->setText(_("Choose nation"));
141 no_name
->setTitle(_("Your leader name"));
144 * Fill city styles, no need to update them later
147 for (i
= 0; i
< game
.control
.styles_count
; i
++) {
148 if (city_style_has_requirements(&::city_styles
[i
])) {
151 item
= new QTableWidgetItem
;
152 city_styles
->insertRow(i
);
153 pix
= get_sample_city_sprite(tileset
, i
)->pm
;
154 item
->setData(Qt::DecorationRole
, *pix
);
155 item
->setData(Qt::UserRole
, i
);
156 size
.setWidth(pix
->width());
157 size
.setHeight(pix
->height());
158 item
->setSizeHint(size
);
159 city_styles
->setItem(i
, 0, item
);
160 item
= new QTableWidgetItem
;
161 item
->setText(city_style_name_translation(i
));
162 city_styles
->setItem(i
, 1, item
);
164 header
= city_styles
->horizontalHeader();
165 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
166 header
->setSectionResizeMode(QHeaderView::Stretch
);
168 header
->setResizeMode(QHeaderView::Stretch
);
170 header
->resizeSections(QHeaderView::ResizeToContents
);
171 header
= city_styles
->verticalHeader();
172 header
->resizeSections(QHeaderView::ResizeToContents
);
173 tab_widget
= new QWidget();
174 nation_tabs
->addItem(tab_widget
, _("All Nations"));
175 for (i
= 0; i
< nation_group_count(); i
++) {
176 group
= nation_group_by_number(i
);
177 tab_widget
= new QWidget();
178 nation_tabs
->addItem(tab_widget
, nation_group_name_translation(group
));
180 connect(nation_tabs
, SIGNAL(currentChanged(int)), SLOT(set_index(int)));
181 connect(city_styles
->selectionModel(),
182 SIGNAL(selectionChanged(const QItemSelection
&,
183 const QItemSelection
&)),
184 SLOT(style_selected(const QItemSelection
&,
185 const QItemSelection
&)));
186 connect(selected_nation_tabs
->selectionModel(),
187 SIGNAL(selectionChanged(const QItemSelection
&,
188 const QItemSelection
&)),
189 SLOT(nation_selected(const QItemSelection
&,
190 const QItemSelection
&)));
191 connect(leader_name
, SIGNAL(currentIndexChanged(int)),
192 SLOT(leader_selected(int)));
194 ok_button
= new QPushButton
;
195 ok_button
->setText(_("Cancel"));
196 connect(ok_button
, SIGNAL(pressed()), SLOT(cancel_pressed()));
197 main_layout
->addWidget(ok_button
, 8, 1, 1, 1);
198 random_button
= new QPushButton
;
199 random_button
->setText(_("Random"));
200 connect(random_button
, SIGNAL(pressed()), SLOT(random_pressed()));
201 main_layout
->addWidget(random_button
, 8, 0, 1, 1);
202 ok_button
= new QPushButton
;
203 ok_button
->setText(_("Ok"));
204 connect(ok_button
, SIGNAL(pressed()), SLOT(ok_pressed()));
205 main_layout
->addWidget(ok_button
, 8, 2, 1, 1);
206 main_layout
->addWidget(no_name
, 0, 2, 2, 1);
207 main_layout
->addWidget(nation_tabs
, 0, 0, 6, 1);
208 main_layout
->addWidget(city_styles
, 2, 2, 4, 1);
209 main_layout
->addWidget(description
, 6, 0, 2, 3);
210 main_layout
->addWidget(selected_nation_tabs
, 0, 1, 6, 1);
212 setLayout(main_layout
);
216 if (C_S_RUNNING
== client_state()) {
217 title
= _("Edit Nation");
218 } else if (NULL
!= pplayer
&& pplayer
== client
.conn
.playing
) {
219 title
= _("What Nation Will You Be?");
221 title
= _("Pick Nation");
224 setWindowTitle(title
);
227 /***************************************************************************
228 Destructor for races dialog
229 ***************************************************************************/
230 races_dialog::~races_dialog()
232 ::is_race_dialog_open
= false;
235 /***************************************************************************
236 Sets new nations' group by given index
237 ***************************************************************************/
238 void races_dialog::set_index(int index
)
240 QTableWidgetItem
*item
;
242 struct nation_group
*group
;
247 selected_nation_tabs
->clearContents();
248 selected_nation_tabs
->setRowCount(0);
250 group
= nation_group_by_number(index
- 1);
251 nations_iterate(pnation
) {
252 if (!is_nation_playable(pnation
) || !is_nation_pickable(pnation
)) {
255 if (!nation_is_in_group(pnation
, group
) && index
!= 0) {
258 item
= new QTableWidgetItem
;
259 selected_nation_tabs
->insertRow(i
);
260 s
= get_nation_flag_sprite(tileset
, pnation
);
262 item
->setData(Qt::DecorationRole
, *pix
);
263 item
->setData(Qt::UserRole
, nation_number(pnation
));
264 item
->setText(nation_adjective_translation(pnation
));
265 selected_nation_tabs
->setItem(i
, 0, item
);
266 } nations_iterate_end
;
268 selected_nation_tabs
->sortByColumn(0, Qt::AscendingOrder
);
269 header
= selected_nation_tabs
->horizontalHeader();
270 header
->resizeSections(QHeaderView::Stretch
);
271 header
= selected_nation_tabs
->verticalHeader();
272 header
->resizeSections(QHeaderView::ResizeToContents
);
275 /***************************************************************************
276 Sets selected nation and updates style and leaders selector
277 ***************************************************************************/
278 void races_dialog::nation_selected(const QItemSelection
&selected
,
279 const QItemSelection
&deselcted
)
284 QModelIndexList indexes
= selected
.indexes();
286 QTableWidgetItem
*item
;
289 if (indexes
.isEmpty()) {
293 index
= indexes
.at(0);
294 if (indexes
.isEmpty()){
297 qvar
= index
.data(Qt::UserRole
);
298 selected_nation
= qvar
.toInt();
300 helptext_nation(buf
, sizeof(buf
), nation_by_number(selected_nation
), NULL
);
301 description
->setText(buf
);
302 leader_name
->clear();
303 nation_leader_list_iterate(nation_leaders(nation_by_number
304 (selected_nation
)), pleader
) {
305 str
= QString::fromUtf8(nation_leader_name(pleader
));
306 leader_name
->addItem(str
, nation_leader_is_male(pleader
));
307 } nation_leader_list_iterate_end
;
310 * select style for nation
313 style
= city_style_of_nation(nation_by_number(selected_nation
));
314 qvar
= qvar
.fromValue
<int>(style
);
315 item
= new QTableWidgetItem
;
317 for (ind
= 0; ind
< city_styles
->rowCount(); ind
++) {
318 item
= city_styles
->item(ind
, 0);
320 if (item
->data(Qt::UserRole
) == qvar
) {
321 city_styles
->selectRow(ind
);
326 /***************************************************************************
328 ***************************************************************************/
329 void races_dialog::style_selected(const QItemSelection
&selected
,
330 const QItemSelection
&deselcted
)
334 QModelIndexList indexes
= selected
.indexes();
336 if (indexes
.isEmpty()) {
340 index
= indexes
.at(0);
341 qvar
= index
.data(Qt::UserRole
);
342 selected_style
= qvar
.toInt();
345 /***************************************************************************
347 ***************************************************************************/
348 void races_dialog::leader_selected(int index
)
350 if (leader_name
->itemData(index
).toBool())
352 is_male
->setChecked(true);
353 is_female
->setChecked(false);
356 is_male
->setChecked(false);
357 is_female
->setChecked(true);
362 /***************************************************************************
363 Button accepting all selection has been pressed, closes dialog if
365 ***************************************************************************/
366 void races_dialog::ok_pressed()
369 if (selected_nation
== -1) {
373 if (selected_sex
== -1) {
374 output_window_append(ftc_client
, _("You must select your sex."));
378 if (selected_style
== -1) {
379 output_window_append(ftc_client
, _("You must select your city style."));
383 if (leader_name
->currentText().length() == 0) {
384 output_window_append(ftc_client
, _("You must type a legal name."));
387 dsend_packet_nation_select_req(&client
.conn
, player_number(tplayer
),
388 selected_nation
, selected_sex
,
389 leader_name
->currentText().toUtf8().data(),
394 /***************************************************************************
395 Constructor for notify dialog
396 ***************************************************************************/
397 notify_dialog::notify_dialog(const char *caption
, const char *headline
,
398 const char *lines
, QWidget
*parent
)
404 setCursor(Qt::ArrowCursor
);
406 setFrameStyle(QFrame::Box
);
407 setWindowOpacity(0.5);
408 cw
= new close_widget(this);
411 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
412 qcaption
= QString::fromLatin1(caption
);
413 qheadline
= QString::fromLatin1(headline
);
414 qlines
= QString::fromLatin1(lines
);
416 qcaption
= QString::fromAscii(caption
);
417 qheadline
= QString::fromAscii(headline
);
418 qlines
= QString::fromAscii(lines
);
420 qlist
= qlines
.split("\n");
421 small_font
=::gui()->fc_fonts
.get_font("gui_qt_font_notify_label");
426 gui()->mapview_wdg
->find_place(gui()->mapview_wdg
->width() - x
- 4, 4,
429 was_destroyed
= false;
432 /***************************************************************************
433 Calculates size of notify dialog
434 ***************************************************************************/
435 void notify_dialog::calc_size(int &x
, int &y
)
437 QFontMetrics
fm(*small_font
);
439 QStringList str_list
;
442 str_list
<< qcaption
<< qheadline
;
444 for (i
= 0; i
< str_list
.count(); i
++) {
445 x
= qMax(x
, fm
.width(str_list
.at(i
)));
446 y
= y
+ 3 + fm
.height();
451 /***************************************************************************
452 Paint Event for notify dialog
453 ***************************************************************************/
454 void notify_dialog::paintEvent(QPaintEvent
* paint_event
)
456 QPainter
painter(this);
459 QFontMetrics
fm(*small_font
);
463 pen
.setColor(QColor(232, 255, 0));
464 painter
.setBrush(QColor(0, 0, 0, 175));
465 painter
.drawRect(0, 0, width(), height());
466 painter
.setFont(*small_font
);
468 painter
.drawText(10, fm
.height() + 3, qcaption
);
469 painter
.drawText(10, 2 * fm
.height() + 6, qheadline
);
470 for (i
= 0; i
< qlist
.count(); i
++) {
471 painter
.drawText(10, 3 + (fm
.height() + 3) * (i
+ 3), qlist
[i
]);
473 painter
.drawLine(0,0,width(),0);
474 painter
.drawLine(0,height()-1,width(),height()-1);
475 painter
.drawLine(0,0,0,height());
476 painter
.drawLine(width()-1,0,width()-1,height());
480 /**************************************************************************
481 Called when mouse button was pressed, just to close on right click
482 **************************************************************************/
483 void notify_dialog::mousePressEvent(QMouseEvent
*event
)
485 cursor
= event
->globalPos() - geometry().topLeft();
486 if (event
->button() == Qt::RightButton
){
487 was_destroyed
= true;
492 /**************************************************************************
493 Called when mouse button was pressed and moving around
494 **************************************************************************/
495 void notify_dialog::mouseMoveEvent(QMouseEvent
*event
)
497 move(event
->globalPos() - cursor
);
498 setCursor(Qt::SizeAllCursor
);
501 /**************************************************************************
502 Called when mouse button unpressed. Restores cursor.
503 **************************************************************************/
504 void notify_dialog::mouseReleaseEvent(QMouseEvent
*event
)
506 setCursor(Qt::ArrowCursor
);
509 /***************************************************************************
510 Called when close button was pressed
511 ***************************************************************************/
512 void notify_dialog::update_menu()
514 was_destroyed
= true;
518 /***************************************************************************
519 Destructor for notify dialog, notice that somehow object is not destroyed
520 immediately, so it can be still visible for parent, check boolean
521 was_destroyed if u suspect it could not be destroyed yet
522 ***************************************************************************/
523 notify_dialog::~notify_dialog()
525 was_destroyed
= true;
529 /***************************************************************************
530 Button canceling all selections has been pressed.
531 ***************************************************************************/
532 void races_dialog::cancel_pressed()
537 /***************************************************************************
539 ***************************************************************************/
540 void races_dialog::random_pressed()
542 dsend_packet_nation_select_req(&client
.conn
,player_number(tplayer
),-1,
547 /**************************************************************************
548 Popup a dialog to display information about an event that has a
549 specific location. The user should be given the option to goto that
551 **************************************************************************/
552 void popup_notify_goto_dialog(const char *headline
, const char *lines
,
553 const struct text_tag_list
*tags
,
559 /**************************************************************************
560 Popup a dialog to display connection message from server.
561 **************************************************************************/
562 void popup_connect_msg(const char *headline
, const char *message
)
567 /**************************************************************************
568 Popup a generic dialog to display some generic information.
569 **************************************************************************/
570 void popup_notify_dialog(const char *caption
, const char *headline
,
573 notify_dialog
*nd
= new notify_dialog(caption
, headline
, lines
,
578 /**************************************************************************
579 Popup the nation selection dialog.
580 **************************************************************************/
581 void popup_races_dialog(struct player
*pplayer
)
583 race_dialog
= new races_dialog(pplayer
);
587 /**************************************************************************
588 Close the nation selection dialog. This should allow the user to
589 (at least) select a unit to activate.
590 **************************************************************************/
591 void popdown_races_dialog(void)
593 if (is_race_dialog_open
){
594 race_dialog
->close();
595 is_race_dialog_open
= false;
599 /**************************************************************************
600 Popup a dialog window to select units on a particular tile.
601 **************************************************************************/
602 void unit_select_dialog_popup(struct tile
*ptile
)
604 if(ptile
!= NULL
&& unit_list_size(ptile
->units
) > 1){
605 gui()->toggle_unit_sel_widget(ptile
);
609 /**************************************************************************
610 Update the dialog window to select units on a particular tile.
611 **************************************************************************/
612 void unit_select_dialog_update_real(void)
614 gui()->update_unit_sel();
617 /**************************************************************************
618 The server has changed the set of selectable nations.
619 **************************************************************************/
620 void races_update_pickable(void)
622 /* FIXME handle this properly */
623 popdown_races_dialog();
626 /**************************************************************************
627 In the nation selection dialog, make already-taken nations unavailable.
628 This information is contained in the packet_nations_used packet.
629 **************************************************************************/
630 void races_toggles_set_sensitive(void)
633 /* maybe just emit signal about chosen toolbox ? */
636 /**************************************************************************
637 Popup a dialog asking if the player wants to start a revolution.
638 **************************************************************************/
639 void popup_revolution_dialog(struct government
*government
)
641 QMessageBox
ask(gui()->central_wdg
);
644 if (0 > client
.conn
.playing
->revolution_finishes
) {
645 ask
.setText(_("You say you wanna revolution?"));
646 ask
.setStandardButtons(QMessageBox::Cancel
| QMessageBox::Ok
);
647 ask
.setDefaultButton(QMessageBox::Cancel
);
648 ask
.setIcon(QMessageBox::Warning
);
649 ask
.setWindowTitle(_("Revolution!"));
653 case QMessageBox::Cancel
:
655 case QMessageBox::Ok
:
656 revolution_response(government
);
660 revolution_response(government
);
664 /***************************************************************************
665 Constructor for choice_dialog
666 ***************************************************************************/
667 choice_dialog::choice_dialog(const QString title
, const QString text
,
668 QWidget
*parent
): QWidget(parent
)
670 QLabel
*l
= new QLabel(text
);
672 signal_mapper
= new QSignalMapper(this);
673 layout
= new QVBoxLayout(this);
675 layout
->addWidget(l
);
676 setWindowFlags(Qt::Dialog
);
677 setWindowTitle(title
);
678 setAttribute(Qt::WA_DeleteOnClose
);
679 gui()->set_diplo_dialog(this);
683 /***************************************************************************
684 Destructor for choice dialog
685 ***************************************************************************/
686 choice_dialog::~choice_dialog()
690 delete signal_mapper
;
691 gui()->set_diplo_dialog(NULL
);
695 /***************************************************************************
696 Sets layout for choice dialog
697 ***************************************************************************/
698 void choice_dialog::set_layout()
700 connect(signal_mapper
, SIGNAL(mapped(const int &)),
701 this, SLOT(execute_action(const int &)));
705 /***************************************************************************
706 Adds new action for choice dialog
707 ***************************************************************************/
708 void choice_dialog::add_item(QString title
, pfcn_void func
, QVariant data1
,
711 QPushButton
*button
= new QPushButton(title
);
712 connect(button
, SIGNAL(clicked()), signal_mapper
, SLOT(map()));
713 signal_mapper
->setMapping(button
, func_list
.count());
714 func_list
.append(func
);
715 data1_list
.append(data1
);
716 data2_list
.append(data2
);
717 layout
->addWidget(button
);
720 /***************************************************************************
722 ***************************************************************************/
723 void choice_dialog::show_me()
727 p
= mapFromGlobal(QCursor::pos());
728 p
.setY(p
.y()-this->height());
729 p
.setX(p
.x()-this->width());
734 /***************************************************************************
735 Returns layout in choice dialog
736 ***************************************************************************/
737 QVBoxLayout
*choice_dialog::get_layout()
742 /***************************************************************************
743 Run chosen action and close dialog
744 ***************************************************************************/
745 void choice_dialog::execute_action(const int action
)
747 pfcn_void func
= func_list
.at(action
);
748 func(data1_list
.at(action
), data2_list
.at(action
));
752 /***************************************************************************
753 Action establish trade for choice dialog
754 ***************************************************************************/
755 static void caravan_establish_trade(QVariant data1
, QVariant data2
)
757 dsend_packet_unit_establish_trade(&client
.conn
, data2
.toInt());
758 caravan_dialog_open
= false;
759 process_caravan_arrival(NULL
);
762 /***************************************************************************
763 Action help build wonder for choice dialog
764 ***************************************************************************/
765 static void caravan_help_build(QVariant data1
, QVariant data2
)
767 dsend_packet_unit_help_build_wonder(&client
.conn
, data2
.toInt());
768 caravan_dialog_open
= false;
769 process_caravan_arrival(NULL
);
772 /***************************************************************************
773 Action 'do nothing' with caravan for choice dialog
774 ***************************************************************************/
775 static void caravan_keep_moving(QVariant data1
, QVariant data2
)
777 caravan_dialog_open
= false;
778 process_caravan_arrival(NULL
);
781 /***************************************************************************
782 Empty action for choice dialog (just do nothing)
783 ***************************************************************************/
784 static void keep_moving(QVariant data1
, QVariant data2
)
787 /***************************************************************************
788 Starts revolution with targeted government as target or anarchy otherwise
789 ***************************************************************************/
790 void revolution_response(struct government
*government
)
795 set_government_choice(government
);
798 /**************************************************************************
799 Popup a dialog giving a player choices when their caravan arrives at
800 a city (other than its home city). Example:
801 - Establish trade route.
804 **************************************************************************/
805 void popup_caravan_dialog(struct unit
*punit
,
806 struct city
*phomecity
, struct city
*pdestcity
)
808 char title_buf
[128], buf
[128], buf2
[1024];
809 bool can_establish
, can_trade
, can_wonder
;
810 struct city
* destcity
;
811 struct unit
* caravan
;
817 fc_snprintf(title_buf
, sizeof(title_buf
),
818 /* TRANS: %s is a unit type */
819 _("Your %s Has Arrived"), unit_name_translation(punit
));
820 fc_snprintf(buf
, sizeof(buf
),
821 _("Your %s from %s reaches the city of %s.\nWhat now?"),
822 unit_name_translation(punit
),
823 city_name(phomecity
), city_name(pdestcity
));
825 caravan_dialog
= new choice_dialog(QString(title_buf
),
827 gui()->game_tab_widget
);
828 caravan_dialog_open
= true;
831 caravan_city_id
= pdestcity
->id
;
832 caravan_unit_id
= punit
->id
;
833 can_trade
= can_cities_trade(phomecity
, pdestcity
);
834 can_establish
= can_trade
835 && can_establish_trade_route(phomecity
, pdestcity
);
836 destcity
= game_city_by_number(pdestcity
->id
);
837 caravan
= game_unit_by_number(punit
->id
);
839 if (destcity
&& caravan
&& unit_can_help_build_wonder(caravan
, destcity
)) {
841 fc_snprintf(buf2
, sizeof(buf2
), _("Help build _Wonder (%d remaining)"),
842 impr_build_shield_cost(destcity
->production
.value
.building
)
843 - destcity
->shield_stock
);
844 wonder
= QString(buf2
);
847 wonder
= QString(_("Help build _Wonder"));
851 func
= caravan_establish_trade
;
852 str
= can_establish
? QString(_("Establish _Trade route")) :
853 QString(_("Enter Marketplace"));
854 caravan_dialog
->add_item(str
, func
, qv1
, qv2
);
857 func
= caravan_help_build
;
858 caravan_dialog
->add_item(wonder
, func
, qv1
, qv2
);
860 func
= caravan_keep_moving
;
861 caravan_dialog
->add_item(QString(_("Keep moving")), func
, qv1
, qv2
);
863 caravan_dialog
->set_layout();
864 caravan_dialog
->show_me();
867 /**************************************************************************
868 Is there currently a caravan dialog open? This is important if there
869 can be only one such dialog at a time; otherwise return false.
870 **************************************************************************/
871 bool caravan_dialog_is_open(int *unit_id
, int *city_id
)
874 *unit_id
= caravan_unit_id
;
877 *city_id
= caravan_city_id
;
879 return caravan_dialog_open
;
882 /**************************************************************************
883 Popup a dialog giving a diplomatic unit some options when moving into
885 **************************************************************************/
886 void popup_diplomat_dialog(struct unit
*punit
, struct tile
*dest_tile
)
890 struct astring title
= ASTRING_INIT
, text
= ASTRING_INIT
;
892 int diplomat_target_id
;
896 if ((pcity
= tile_city(dest_tile
))) {
897 /* Spy/Diplomat acting against a city */
898 diplomat_target_id
= pcity
->id
;
899 diplomat_id
= punit
->id
;
900 gui()->set_current_unit(diplomat_id
, diplomat_target_id
);
902 /* TRANS: %s is a unit name, e.g., Spy */
903 _("Choose Your %s's Strategy"), unit_name_translation(punit
));
905 _("Your %s has arrived at %s.\nWhat is your command?"),
906 unit_name_translation(punit
),
908 choice_dialog
*cd
= new choice_dialog(astr_str(&title
),
910 gui()->game_tab_widget
);
913 cd
->unit_id
= diplomat_id
;
914 if (diplomat_can_do_action(punit
, DIPLOMAT_EMBASSY
, dest_tile
)) {
915 func
= diplomat_embassy
;
916 cd
->add_item(QString(_("Establish Embassy")),
919 if (diplomat_can_do_action(punit
, DIPLOMAT_INVESTIGATE
, dest_tile
)) {
920 func
= diplomat_investigate
;
921 cd
->add_item(QString(_("Investigate City")), func
, qv1
, qv2
);
923 if (!unit_has_type_flag(punit
, UTYF_SPY
)) {
924 if (diplomat_can_do_action(punit
, DIPLOMAT_SABOTAGE
, dest_tile
)) {
925 func
= diplomat_sabotage
;
926 cd
->add_item(QString(_("Sabotage City")), func
, qv1
, qv2
);
928 if (diplomat_can_do_action(punit
, DIPLOMAT_STEAL
, dest_tile
)) {
929 func
= diplomat_steal
;
930 cd
->add_item(QString(_("Steal Technology")),
933 if (diplomat_can_do_action(punit
, DIPLOMAT_INCITE
, dest_tile
)) {
934 func
= diplomat_incite
;
935 cd
->add_item(QString(_("Incite a Revolt")), func
, qv1
, qv2
);
937 if (diplomat_can_do_action(punit
, DIPLOMAT_MOVE
, dest_tile
)) {
938 func
= diplomat_keep_moving
;
939 cd
->add_item(QString(_("Keep moving")), func
, qv1
, qv2
);
942 if (diplomat_can_do_action(punit
, SPY_POISON
, dest_tile
)) {
944 cd
->add_item(QString(_("Poison City")), func
, qv1
, qv2
);
946 if (diplomat_can_do_action(punit
, DIPLOMAT_SABOTAGE
, dest_tile
)) {
947 func
= spy_request_sabotage_list
;
948 cd
->add_item(QString(_("Industrial Sabotage")),
951 if (diplomat_can_do_action(punit
, DIPLOMAT_STEAL
, dest_tile
)) {
953 cd
->add_item(QString(_("Steal Technology")),
956 if (diplomat_can_do_action(punit
, DIPLOMAT_INCITE
, dest_tile
)) {
957 func
= diplomat_incite
;
958 cd
->add_item(QString(_("Incite a Revolt")), func
, qv1
, qv2
);
960 if (diplomat_can_do_action(punit
, DIPLOMAT_MOVE
, dest_tile
)) {
961 func
= diplomat_keep_moving
;
962 cd
->add_item(QString(_("Keep moving")), func
, qv1
, qv2
);
968 if ((ptunit
= unit_list_get(dest_tile
->units
, 0))) {
969 /* Spy/Diplomat acting against a unit */
971 diplomat_target_id
= ptunit
->id
;
972 diplomat_id
= punit
->id
;
973 gui()->set_current_unit(diplomat_id
, diplomat_target_id
);
975 /* TRANS: %s is a unit name, e.g., Diplomat, Spy */
976 _("Your %s is waiting for your command."),
977 unit_name_translation(punit
));
978 choice_dialog
*cd
= new choice_dialog(_("Subvert Enemy Unit"),
980 gui()->game_tab_widget
);
983 if (diplomat_can_do_action(punit
, DIPLOMAT_BRIBE
, dest_tile
)) {
984 func
= diplomat_bribe
;
985 cd
->add_item(QString(_("Bribe Enemy Unit")), func
, qv1
, qv2
);
987 if (diplomat_can_do_action(punit
, SPY_SABOTAGE_UNIT
, dest_tile
)) {
988 func
= spy_sabotage_unit
;
989 cd
->add_item(QString(_("Sabotage Enemy Unit")),
993 cd
->add_item(QString(_("Do nothing")), func
, qv1
, qv2
);
1002 /***************************************************************************
1003 Action bribe unit for choice dialog
1004 ***************************************************************************/
1005 static void diplomat_bribe(QVariant data1
, QVariant data2
)
1007 int diplomat_id
= data1
.toInt();
1008 int diplomat_target_id
= data2
.toInt();
1010 if (NULL
!= game_unit_by_number(diplomat_id
)
1011 && NULL
!= game_unit_by_number(diplomat_target_id
)) {
1012 request_diplomat_answer(DIPLOMAT_BRIBE
, diplomat_id
,
1013 diplomat_target_id
, 0);
1017 /***************************************************************************
1018 Action sabotage unit for choice dialog
1019 ***************************************************************************/
1020 static void spy_sabotage_unit(QVariant data1
, QVariant data2
)
1022 int diplomat_id
= data1
.toInt();
1023 int diplomat_target_id
= data2
.toInt();
1025 request_diplomat_action(SPY_SABOTAGE_UNIT
, diplomat_id
,
1026 diplomat_target_id
, 0);
1029 /***************************************************************************
1030 Action steal tech with spy for choice dialog
1031 ***************************************************************************/
1032 static void spy_steal(QVariant data1
, QVariant data2
)
1037 int diplomat_id
= data1
.toInt();
1038 int diplomat_target_id
= data2
.toInt();
1039 struct city
*pvcity
= game_city_by_number(diplomat_target_id
);
1040 struct player
*pvictim
= NULL
;
1045 pvictim
= city_owner(pvcity
);
1047 cd
= gui()->get_diplo_dialog();
1051 struct astring stra
= ASTRING_INIT
;
1052 cd
= new choice_dialog(_("_Steal"), _("Steal Technology"),
1053 gui()->game_tab_widget
);
1055 struct player
*pplayer
= client
.conn
.playing
;
1057 advance_index_iterate(A_FIRST
, i
) {
1058 if (player_invention_state(pvictim
, i
) == TECH_KNOWN
&&
1059 (player_invention_state(pplayer
, i
) == TECH_UNKNOWN
||
1060 player_invention_state(pplayer
, i
) == TECH_PREREQS_KNOWN
)) {
1061 func
= spy_steal_something
;
1062 str
= advance_name_for_player(client
.conn
.playing
, i
);
1063 cd
->add_item(str
, func
, qv1
, i
);
1066 } advance_index_iterate_end
;
1067 astr_set(&stra
, _("At %s's Discretion"),
1068 unit_name_translation(game_unit_by_number(diplomat_id
)));
1069 func
= spy_steal_something
;
1070 str
= astr_str(&stra
);
1071 cd
->add_item(str
, func
, qv1
, A_UNSET
);
1078 /***************************************************************************
1079 Action steal given tech for choice dialog
1080 ***************************************************************************/
1081 static void spy_steal_something(QVariant data1
, QVariant data2
)
1084 int diplomat_target_id
;
1086 gui()->get_current_unit(&diplomat_id
, &diplomat_target_id
);
1087 if (NULL
!= game_unit_by_number(diplomat_id
)
1088 && NULL
!= game_city_by_number(diplomat_target_id
)) {
1089 request_diplomat_action(DIPLOMAT_STEAL
, diplomat_id
,
1090 diplomat_target_id
, data2
.toInt());
1094 /***************************************************************************
1095 Action request sabotage list for choice dialog
1096 ***************************************************************************/
1097 static void spy_request_sabotage_list(QVariant data1
, QVariant data2
)
1099 int diplomat_id
= data1
.toInt();
1100 int diplomat_target_id
= data2
.toInt();
1102 if (NULL
!= game_unit_by_number(diplomat_id
)
1103 && NULL
!= game_city_by_number(diplomat_target_id
)) {
1104 request_diplomat_answer(DIPLOMAT_SABOTAGE
, diplomat_id
,
1105 diplomat_target_id
, 0);
1109 /***************************************************************************
1110 Action poison city for choice dialog
1111 ***************************************************************************/
1112 static void spy_poison(QVariant data1
, QVariant data2
)
1114 int diplomat_id
= data1
.toInt();
1115 int diplomat_target_id
= data2
.toInt();
1117 if (NULL
!= game_unit_by_number(diplomat_id
)
1118 && NULL
!= game_city_by_number(diplomat_target_id
)) {
1119 request_diplomat_action(SPY_POISON
, diplomat_id
, diplomat_target_id
, 0);
1123 /***************************************************************************
1124 Action establish embassy for choice dialog
1125 ***************************************************************************/
1126 static void diplomat_embassy(QVariant data1
, QVariant data2
)
1128 int diplomat_id
= data1
.toInt();
1129 int diplomat_target_id
= data2
.toInt();
1131 if (NULL
!= game_unit_by_number(diplomat_id
)
1132 && NULL
!= game_city_by_number(diplomat_target_id
)) {
1133 request_diplomat_action(DIPLOMAT_EMBASSY
, diplomat_id
,
1134 diplomat_target_id
, 0);
1138 /***************************************************************************
1139 Action investigate city for choice dialog
1140 ***************************************************************************/
1141 static void diplomat_investigate(QVariant data1
, QVariant data2
)
1143 int diplomat_id
= data1
.toInt();
1144 int diplomat_target_id
= data2
.toInt();
1146 if (NULL
!= game_city_by_number(diplomat_target_id
)
1147 && NULL
!= game_unit_by_number(diplomat_id
)) {
1148 request_diplomat_action(DIPLOMAT_INVESTIGATE
, diplomat_id
,
1149 diplomat_target_id
, 0);
1153 /***************************************************************************
1154 Action sabotage for choice dialog
1155 ***************************************************************************/
1156 static void diplomat_sabotage(QVariant data1
, QVariant data2
)
1158 int diplomat_id
= data1
.toInt();
1159 int diplomat_target_id
= data2
.toInt();
1161 if (NULL
!= game_unit_by_number(diplomat_id
)
1162 && NULL
!= game_city_by_number(diplomat_target_id
)) {
1163 request_diplomat_action(DIPLOMAT_SABOTAGE
, diplomat_id
,
1164 diplomat_target_id
, B_LAST
+ 1);
1168 /***************************************************************************
1169 Action steal with diplomat for choice dialog
1170 ***************************************************************************/
1171 static void diplomat_steal(QVariant data1
, QVariant data2
)
1173 int diplomat_id
= data1
.toInt();
1174 int diplomat_target_id
= data2
.toInt();
1176 if (NULL
!= game_unit_by_number(diplomat_id
)
1177 && NULL
!= game_city_by_number(diplomat_target_id
)) {
1178 request_diplomat_action(DIPLOMAT_STEAL
, diplomat_id
,
1179 diplomat_target_id
, A_UNSET
);
1183 /***************************************************************************
1184 Action incite revolt for choice dialog
1185 ***************************************************************************/
1186 static void diplomat_incite(QVariant data1
, QVariant data2
)
1188 int diplomat_id
= data1
.toInt();
1189 int diplomat_target_id
= data2
.toInt();
1191 if (NULL
!= game_unit_by_number(diplomat_id
)
1192 && NULL
!= game_city_by_number(diplomat_target_id
)) {
1193 request_diplomat_answer(DIPLOMAT_INCITE
, diplomat_id
,
1194 diplomat_target_id
, 0);
1198 /***************************************************************************
1199 Action keep moving with diplomat for choice dialog
1200 ***************************************************************************/
1201 static void diplomat_keep_moving(QVariant data1
, QVariant data2
)
1205 int diplomat_id
= data1
.toInt();
1206 int diplomat_target_id
= data2
.toInt();
1208 if ((punit
= game_unit_by_number(diplomat_id
))
1209 && (pcity
= game_city_by_number(diplomat_target_id
))
1210 && !same_pos(unit_tile(punit
), city_tile(pcity
))) {
1211 request_diplomat_action(DIPLOMAT_MOVE
, diplomat_id
,
1212 diplomat_target_id
, 0);
1216 /**************************************************************************
1217 Popup a window asking a diplomatic unit if it wishes to incite the
1219 **************************************************************************/
1220 void popup_incite_dialog(struct unit
*actor
, struct city
*pcity
, int cost
)
1226 int diplomat_target_id
;
1228 fc_snprintf(buf
, ARRAY_SIZE(buf
), PL_("Treasury contains %d gold.",
1229 "Treasury contains %d gold.",
1230 client_player()->economic
.gold
),
1231 client_player()->economic
.gold
);
1233 if (INCITE_IMPOSSIBLE_COST
== cost
) {
1234 QMessageBox incite_impossible
;
1236 fc_snprintf(buf2
, ARRAY_SIZE(buf2
),
1237 _("You can't incite a revolt in %s."), city_name(pcity
));
1238 incite_impossible
.setText(QString(buf2
));
1239 incite_impossible
.exec();
1240 } else if (cost
<= client_player()->economic
.gold
) {
1243 fc_snprintf(buf2
, ARRAY_SIZE(buf2
),
1244 PL_("Incite a revolt for %d gold?\n%s",
1245 "Incite a revolt for %d gold?\n%s", cost
), cost
, buf
);
1246 ask
.setText(QString(buf2
));
1247 ask
.setStandardButtons(QMessageBox::Cancel
| QMessageBox::Ok
);
1248 ask
.setDefaultButton(QMessageBox::Cancel
);
1249 ask
.setIcon(QMessageBox::Question
);
1250 ask
.setWindowTitle(_("Incite a Revolt!"));
1253 case QMessageBox::Cancel
:
1256 case QMessageBox::Ok
:
1257 gui()->get_current_unit(&diplomat_id
, &diplomat_target_id
);
1258 request_diplomat_action(DIPLOMAT_INCITE
, diplomat_id
,
1259 diplomat_target_id
, 0);
1263 QMessageBox too_much
;
1265 fc_snprintf(buf2
, ARRAY_SIZE(buf2
),
1266 PL_("Inciting a revolt costs %d gold.\n%s",
1267 "Inciting a revolt costs %d gold.\n%s", cost
), cost
,
1269 too_much
.setText(QString(buf2
));
1274 /**************************************************************************
1275 Popup a dialog asking a diplomatic unit if it wishes to bribe the
1277 **************************************************************************/
1278 void popup_bribe_dialog(struct unit
*actor
, struct unit
*punit
, int cost
)
1286 int diplomat_target_id
;
1288 gui()->get_current_unit(&diplomat_id
, &diplomat_target_id
);
1289 fc_snprintf(buf
, ARRAY_SIZE(buf
), PL_("Treasury contains %d gold.",
1290 "Treasury contains %d gold.",
1291 client_player()->economic
.gold
),
1292 client_player()->economic
.gold
);
1293 if (unit_has_type_flag(punit
, UTYF_UNBRIBABLE
)) {
1294 ask
.setWindowTitle(_("Ooops..."));
1295 ask
.setText(_("This unit cannot be bribed!"));
1300 ask
.setWindowTitle(QString(_("Bribe Enemy Unit")));
1301 if (cost
<= client_player()->economic
.gold
) {
1302 fc_snprintf(buf2
, ARRAY_SIZE(buf2
), PL_("Bribe unit for %d gold?\n%s",
1303 "Bribe unit for %d gold?\n%s",
1305 ask
.setText(QString(buf2
));
1306 ask
.setStandardButtons(QMessageBox::Cancel
| QMessageBox::Ok
);
1307 ask
.setDefaultButton(QMessageBox::Cancel
);
1308 ask
.setIcon(QMessageBox::Question
);
1311 case QMessageBox::Cancel
:
1313 case QMessageBox::Ok
:
1314 request_diplomat_action(DIPLOMAT_BRIBE
, diplomat_id
,
1315 diplomat_target_id
, 0);
1321 fc_snprintf(buf2
, ARRAY_SIZE(buf2
),
1322 PL_("Bribing the unit costs %d gold.\n%s",
1323 "Bribing the unit costs %d gold.\n%s", cost
), cost
, buf
);
1324 ask
.setWindowTitle(_("Traitors Demand Too Much!"));
1329 /***************************************************************************
1330 Action pillage for choice dialog
1331 ***************************************************************************/
1332 static void pillage_something(QVariant data1
, QVariant data2
)
1338 what
= data1
.toInt();
1339 punit_id
= data2
.toInt();
1340 punit
= game_unit_by_number(punit_id
);
1341 struct act_tgt target
;
1343 if (what
>= S_LAST
+ game
.control
.num_base_types
) {
1344 target
.type
= ATT_ROAD
;
1345 target
.obj
.road
= what
- S_LAST
- game
.control
.num_base_types
;
1346 } else if (what
>= S_LAST
) {
1347 target
.type
= ATT_BASE
;
1348 target
.obj
.base
= what
- S_LAST
;
1350 target
.type
= ATT_SPECIAL
;
1351 target
.obj
.spe
= static_cast<tile_special_type
>(what
);
1354 request_new_unit_activity_targeted(punit
, ACTIVITY_PILLAGE
,
1356 ::is_showing_pillage_dialog
= false;
1359 /***************************************************************************
1360 Action sabotage with spy for choice dialog
1361 ***************************************************************************/
1362 static void spy_sabotage(QVariant data1
, QVariant data2
)
1365 int diplomat_target_id
;
1367 gui()->get_current_unit(&diplomat_id
, &diplomat_target_id
);
1368 if (NULL
!= game_unit_by_number(diplomat_id
)
1369 && NULL
!= game_city_by_number(diplomat_target_id
)) {
1370 request_diplomat_action(DIPLOMAT_SABOTAGE
, diplomat_id
,
1371 diplomat_target_id
, data2
.toInt()+1);
1375 /**************************************************************************
1376 Popup a dialog asking a diplomatic unit if it wishes to sabotage the
1378 **************************************************************************/
1379 void popup_sabotage_dialog(struct unit
*actor
, struct city
*pcity
)
1385 int diplomat_target_id
;
1387 choice_dialog
*cd
= new choice_dialog(_("_Sabotage"),
1388 _("Select Improvement to Sabotage"),
1389 gui()->game_tab_widget
);
1391 struct astring stra
= ASTRING_INIT
;
1393 gui()->get_current_unit(&diplomat_id
, &diplomat_target_id
);
1395 func
= spy_sabotage
;
1396 cd
->add_item(QString(_("City Production")), func
, qv1
, -1);
1397 city_built_iterate(pcity
, pimprove
) {
1398 if (pimprove
->sabotage
> 0) {
1399 func
= spy_sabotage
;
1400 str
= city_improvement_name_translation(pcity
, pimprove
);
1402 cd
->add_item(str
, func
, qv1
, improvement_number(pimprove
));
1405 } city_built_iterate_end
;
1406 astr_set(&stra
, _("At %s's Discretion"),
1407 unit_name_translation(game_unit_by_number(diplomat_id
)));
1408 func
= spy_sabotage
;
1409 str
= astr_str(&stra
);
1410 cd
->add_item(str
, func
, qv1
, B_LAST
);
1416 /**************************************************************************
1417 Popup a dialog asking the unit which improvement they would like to
1419 **************************************************************************/
1420 void popup_pillage_dialog(struct unit
*punit
, bv_special spe
,
1421 bv_bases bases
, bv_roads roads
)
1429 if (is_showing_pillage_dialog
){
1432 cd
= new choice_dialog(_("What To Pillage"), _("Select what to pillage:"),
1433 gui()->game_tab_widget
);
1435 while (get_preferred_pillage(&tgt
, spe
, bases
, roads
)) {
1437 bv_special what_spe
;
1441 BV_CLR_ALL(what_spe
);
1442 BV_CLR_ALL(what_base
);
1443 BV_CLR_ALL(what_road
);
1447 BV_SET(what_spe
, tgt
.obj
.spe
);
1449 clear_special(&spe
, tgt
.obj
.spe
);
1452 BV_SET(what_base
, tgt
.obj
.base
);
1453 what
= tgt
.obj
.base
+ S_LAST
;
1454 BV_CLR(bases
, tgt
.obj
.base
);
1457 BV_SET(what_road
, tgt
.obj
.road
);
1458 what
= tgt
.obj
.road
+ S_LAST
+ game
.control
.num_base_types
;
1459 BV_CLR(roads
, tgt
.obj
.road
);
1462 func
= pillage_something
;
1463 str
= get_infrastructure_text(what_spe
, what_base
, what_road
);
1465 cd
->add_item(str
, func
, qv1
,qv2
);
1471 /****************************************************************************
1472 Pops up a dialog to confirm disband of the unit(s).
1473 ****************************************************************************/
1474 void popup_disband_dialog(struct unit_list
*punits
)
1480 if (!punits
|| unit_list_size(punits
) == 0) {
1483 if (unit_list_size(punits
) == 1) {
1484 ask
.setText(_("Are you sure you want to disband that unit?"));
1487 QString(_("Are you sure you want to disband those %1 units?")).arg
1488 (unit_list_size(punits
));
1491 ask
.setWindowTitle(_("Disband"));
1492 ask
.setStandardButtons(QMessageBox::Cancel
| QMessageBox::Ok
);
1493 ask
.setDefaultButton(QMessageBox::Cancel
);
1494 ask
.setIcon(QMessageBox::Question
);
1495 ask
.setWindowTitle(_("Disband unit(s)"));
1499 case QMessageBox::Cancel
:
1502 case QMessageBox::Ok
:
1503 unit_list_iterate(punits
, punit
) {
1504 if (!unit_has_type_flag(punit
, UTYF_UNDISBANDABLE
)) {
1505 request_unit_disband(punit
);
1507 } unit_list_iterate_end
;
1512 /**************************************************************************
1513 Ruleset (modpack) has suggested loading certain tileset. Confirm from
1515 **************************************************************************/
1516 void popup_tileset_suggestion_dialog(void)
1518 qDebug() << Q_FUNC_INFO
<< "PORTME";
1521 /****************************************************************
1522 Ruleset (modpack) has suggested loading certain soundset. Confirm from
1524 *****************************************************************/
1525 void popup_soundset_suggestion_dialog(void)
1527 qDebug() << Q_FUNC_INFO
<< "PORTME";
1530 /**************************************************************************
1531 Tileset (modpack) has suggested loading certain theme. Confirm from
1533 **************************************************************************/
1534 bool popup_theme_suggestion_dialog(const char *theme_name
)
1540 /**************************************************************************
1541 This function is called when the client disconnects or the game is
1542 over. It should close all dialog windows for that game.
1543 **************************************************************************/
1544 void popdown_all_game_dialogs(void)
1547 QList
<choice_dialog
*> cd_list
;
1549 cd_list
= gui()->game_tab_widget
->findChildren
<choice_dialog
*>();
1550 for (i
= 0; i
< cd_list
.count(); i
++) {
1551 cd_list
[i
]->close();
1555 /****************************************************************
1556 Returns id of a diplomat currently handled in diplomat dialog
1557 *****************************************************************/
1558 int diplomat_handled_in_diplomat_dialog(void)
1560 choice_dialog
*cd
= gui()->get_diplo_dialog();
1569 /****************************************************************
1570 Closes the diplomat dialog
1571 ****************************************************************/
1572 void close_diplomat_dialog(void)
1576 cd
= gui()->get_diplo_dialog();
1580 gui()->set_current_unit(-1, -1);
1583 /****************************************************************
1584 Updates caravan dialog
1585 ****************************************************************/
1586 void caravan_dialog_update(void)
1589 struct city
*destcity
;
1590 struct unit
*caravan
;
1596 QVBoxLayout
*layout
;
1599 if (caravan_dialog
== NULL
) {
1602 destcity
= game_city_by_number(caravan_city_id
);
1603 caravan
= game_unit_by_number(caravan_unit_id
);
1605 layout
= caravan_dialog
->get_layout();
1606 foreach (func
, caravan_dialog
->func_list
) {
1607 if (func
== caravan_help_build
) {
1608 if (destcity
&& caravan
1609 && unit_can_help_build_wonder(caravan
, destcity
)) {
1610 fc_snprintf(buf2
, sizeof(buf2
),
1611 _("Help build _Wonder (%d remaining)"),
1612 impr_build_shield_cost(destcity
->production
.value
.building
)
1613 - destcity
->shield_stock
);
1614 wonder
= QString(buf2
);
1616 wonder
= QString(_("Help build _Wonder"));
1618 qpb
= qobject_cast
<QPushButton
*>(layout
->itemAt(i
+ 1)->widget());
1619 qpb
->setText(wonder
);
1625 /****************************************************************
1626 Player has gained a new tech.
1627 *****************************************************************/
1628 void show_tech_gained_dialog(Tech_type_id tech
)
1632 /****************************************************************
1633 Show tileset error dialog.
1634 *****************************************************************/
1635 void show_tileset_error(const char *msg
)
1640 /****************************************************************
1641 Popup dialog for upgrade units
1642 *****************************************************************/
1643 void popup_upgrade_dialog(struct unit_list
*punits
)
1649 if (!punits
|| unit_list_size(punits
) == 0) {
1652 if (!get_units_upgrade_info(buf
, sizeof(buf
), punits
)) {
1653 ask
.setText(QString(buf
));
1654 ask
.setWindowTitle(_("Upgrade Unit!"));
1656 ask
.setWindowTitle(_("Upgrade Obsolete Units"));
1657 ask
.setStandardButtons(QMessageBox::Cancel
| QMessageBox::Ok
);
1658 ask
.setDefaultButton(QMessageBox::Cancel
);
1659 ask
.setIcon(QMessageBox::Question
);
1663 case QMessageBox::Cancel
:
1666 case QMessageBox::Ok
:
1667 unit_list_iterate(punits
, punit
) {
1668 request_unit_upgrade(punit
);
1669 } unit_list_iterate_end
;
1675 /****************************************************************
1676 Contructor for unit_select
1677 *****************************************************************/
1678 unit_select::unit_select(tile
*ptile
, QWidget
*parent
)
1688 ufont
->setItalic(true);
1689 info_font
= gui()->fc_fonts
.get_font("gui_qt_font_notify_label");
1693 p
= mapFromGlobal(QCursor::pos());
1694 setMouseTracking(true);
1695 final_p
.setX(p
.x());
1696 final_p
.setY(p
.y());
1697 if (p
.x() + width() > parentWidget()->width()) {
1698 final_p
.setX(parentWidget()->width() - width());
1700 if (p
.y() - height() < 0) {
1701 final_p
.setY(height());
1703 move(final_p
.x(), final_p
.y() - height());
1705 /****************************************************************
1706 Destructor for unit select
1707 *****************************************************************/
1708 unit_select::~unit_select()
1715 /****************************************************************
1716 Create pixmap of whole widget except borders (pix)
1717 *****************************************************************/
1718 void unit_select::create_pixmap()
1722 struct canvas
*unit_pixmap
;
1723 QList
<QPixmap
*>pix_list
;
1730 QFontMetrics
fm(*info_font
);
1737 if (unit_list
.count() > 0) {
1738 punit
= unit_list
.at(0);
1739 item_size
.setWidth(tileset_full_tile_width(tileset
));
1740 item_size
.setHeight(tileset_tile_height(tileset
) * 3 / 2);
1742 if (h_pix
== NULL
) {
1743 h_pix
= new QPixmap(item_size
.width(), item_size
.height());
1744 h_pix
->fill(QColor(100, 100, 100, 140));
1746 if (unit_list
.size() < 5) {
1748 pix
= new QPixmap((unit_list
.size()) * item_size
.width(),
1749 item_size
.height());
1750 } else if (unit_list
.size() < 9) {
1752 pix
= new QPixmap(4 * item_size
.width(), 2 * item_size
.height());
1755 if (unit_list_size(utile
->units
) > unit_list
.size() - 1) {
1758 pix
= new QPixmap(4 * item_size
.width(), 3 * item_size
.height());
1760 pix
->fill(Qt::transparent
);
1761 foreach(punit
, unit_list
) {
1762 unit_pixmap
= qtg_canvas_create(tileset_full_tile_width(tileset
),
1763 tileset_tile_height(tileset
) * 3 / 2);
1764 unit_pixmap
->map_pixmap
.fill(Qt::transparent
);
1765 put_unit(punit
, unit_pixmap
, 0, 0);
1766 pix_list
.push_back(&unit_pixmap
->map_pixmap
);
1768 a
= qMin(item_size
.width() / 4, 12);
1769 x
= 0, y
= -item_size
.height(), i
= -1;
1771 ufont
->setPixelSize(a
);
1773 pen
.setColor(QColor(232, 255, 0));
1776 while (!pix_list
.isEmpty()) {
1777 tmp_pix
= pix_list
.takeFirst();
1781 y
= y
+ item_size
.height();
1783 punit
= unit_list
.at(i
);
1784 Q_ASSERT(punit
!= NULL
);
1785 rate
= unit_type(punit
)->move_rate
;
1786 f
= ((punit
->fuel
) - 1);
1787 if (i
== highligh_num
) {
1788 p
.drawPixmap(x
, y
, *h_pix
);
1789 p
.drawPixmap(x
, y
, *tmp_pix
);
1791 p
.drawPixmap(x
, y
, *tmp_pix
);
1794 if (utype_fuel(unit_type(punit
))) {
1795 str
= QString(move_points_text((rate
* f
) + punit
->moves_left
, false));
1797 str
= QString(move_points_text(punit
->moves_left
, false));
1799 /* TRANS: MP = Movement points */
1800 str
= QString(_("MP:")) + str
;
1801 p
.drawText(x
, y
+ item_size
.height() - 4, str
);
1803 x
= x
+ item_size
.width();
1807 setFixedWidth(pix
->width() + 20);
1808 setFixedHeight(pix
->height() + 2 * (fm
.height() + 6));
1809 qDeleteAll(pix_list
.begin(), pix_list
.end());
1813 /****************************************************************
1814 Event for mouse moving around unit_select
1815 *****************************************************************/
1816 void unit_select::mouseMoveEvent(QMouseEvent
*event
)
1820 QFontMetrics
fm(*info_font
);
1822 old_h
= highligh_num
;
1824 if (event
->x() > width() - 11
1825 || event
->y() > height() - fm
.height() - 5
1826 || event
->y() < fm
.height() + 3 || event
->x() < 11) {
1827 /** do nothing if mouse is on border, just skip next if */
1828 } else if (row_count
> 0) {
1829 a
= (event
->x() - 10) / item_size
.width();
1830 b
= (event
->y() - fm
.height() - 3) / item_size
.height();
1831 highligh_num
= b
* 4 + a
;
1833 if (old_h
!= highligh_num
) {
1839 /****************************************************************
1840 Mouse pressed event for unit_select.
1841 Left Button - chooses units
1842 Right Button - closes widget
1843 *****************************************************************/
1844 void unit_select::mousePressEvent(QMouseEvent
*event
)
1847 if (event
->button() == Qt::RightButton
) {
1848 was_destroyed
= true;
1852 if (event
->button() == Qt::LeftButton
&& highligh_num
!= -1
1853 && highligh_num
< unit_list
.count()) {
1854 punit
= unit_list
.at(highligh_num
);
1855 unit_focus_set(punit
);
1856 was_destroyed
= true;
1862 /****************************************************************
1863 Redirected paint event
1864 *****************************************************************/
1865 void unit_select::paint(QPainter
*painter
, QPaintEvent
*event
)
1867 QFontMetrics
fm(*info_font
);
1873 int point_size
= info_font
->pointSize();
1874 int pixel_size
= info_font
->pixelSize();
1876 if (point_size
< 0) {
1877 f_size
= &pixel_size
;
1879 f_size
= &point_size
;
1881 if (highligh_num
!= -1 && highligh_num
< unit_list
.count()) {
1882 punit
= unit_list
.at(highligh_num
);
1883 str2
= QString(unit_activity_text(punit
))
1884 + QString(" ") + QString(_("HP")) + QString(": ")
1885 + QString::number(punit
->hp
) + QString("/")
1886 + QString::number(unit_type(punit
)->hp
);
1888 str
= QString::number(unit_list_size(utile
->units
)) + " "
1889 + QString(_("units"));
1890 for (i
= *f_size
; i
> 4; i
--) {
1891 if (point_size
< 0) {
1892 info_font
->setPixelSize(i
);
1894 info_font
->setPointSize(i
);
1896 QFontMetrics
qfm(*info_font
);
1897 if (10 + qfm
.width(str2
) < width()) {
1902 painter
->setBrush(QColor(0, 0, 0, 135));
1903 painter
->drawRect(0, 0, width(), height());
1905 painter
->drawPixmap(10, h
+ 3, *pix
);
1906 pen
.setColor(QColor(232, 255, 0));
1907 painter
->setPen(pen
);
1908 painter
->setFont(*info_font
);
1909 painter
->drawText(10, h
, str
);
1910 if (highligh_num
!= -1 && highligh_num
< unit_list
.count()) {
1911 painter
->drawText(10, height() - 5, str2
);
1914 if (point_size
< 0) {
1915 info_font
->setPixelSize(*f_size
);
1917 info_font
->setPointSize(*f_size
);
1920 /****************************************************************
1921 Paint event, redirects to paint(...)
1922 *****************************************************************/
1923 void unit_select::paintEvent(QPaintEvent
*event
)
1927 painter
.begin(this);
1928 paint(&painter
, event
);
1932 /****************************************************************
1933 Function from abstract fcwidget to update menu, its not needed
1934 cause widget is easy closable via right mouse click
1935 *****************************************************************/
1936 void unit_select::update_menu()
1940 /****************************************************************
1941 Updates unit list on tile
1942 *****************************************************************/
1943 void unit_select::update_units()
1947 if (utile
== NULL
) {
1948 struct unit
*punit
= head_of_units_in_focus();
1950 utile
= unit_tile(punit
);
1954 unit_list_iterate(utile
->units
, punit
) {
1955 if (i
> show_line
* 4)
1956 unit_list
.push_back(punit
);
1958 } unit_list_iterate_end
;
1961 /****************************************************************
1962 Mouse wheel event for unit_select
1963 *****************************************************************/
1964 void unit_select::wheelEvent(QWheelEvent
*event
)
1968 if (more
== false && utile
== NULL
) {
1971 nr
= qCeil(static_cast<qreal
>(unit_list_size(utile
->units
)) / 4) - 3;
1972 if (event
->delta() < 0) {
1974 show_line
= qMin(show_line
, nr
);
1977 show_line
= qMax(0, show_line
);
1985 /***************************************************************************
1986 Set current unit handled in diplo dialog
1987 ***************************************************************************/
1988 void fc_client::set_current_unit(int curr
, int target
)
1990 current_unit_id
= curr
;
1991 current_unit_target_id
= target
;
1994 /***************************************************************************
1995 Get current unit handled in diplo dialog
1996 ***************************************************************************/
1997 void fc_client::get_current_unit(int *curr
, int *target
)
1999 *curr
= current_unit_id
;
2000 *target
= current_unit_target_id
;
2003 /***************************************************************************
2004 Set current diplo dialog
2005 ***************************************************************************/
2006 void fc_client::set_diplo_dialog(choice_dialog
*widget
)
2008 opened_dialog
= widget
;
2011 /***************************************************************************
2012 Get current diplo dialog
2013 ***************************************************************************/
2014 choice_dialog
* fc_client::get_diplo_dialog()
2016 return opened_dialog
;