Fixed the way Qt-client popup_terrain_info() checks for empty string.
[freeciv.git] / client / gui-qt / hudwidget.cpp
blob87531cadb19dc87d7c2d7ebd8c2a901e9e37bae4
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.
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 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 // Qt
19 #include <QAction>
20 #include <QApplication>
21 #include <QComboBox>
22 #include <QDialogButtonBox>
23 #include <QGridLayout>
24 #include <QHBoxLayout>
25 #include <QHeaderView>
26 #include <QLineEdit>
27 #include <QPainter>
28 #include <QPaintEvent>
29 #include <QRadioButton>
30 #include <QSpacerItem>
31 #include <QVBoxLayout>
33 // common
34 #include "movement.h"
35 #include "research.h"
36 #include "unitlist.h"
37 #include "tile.h"
38 #include "unit.h"
40 // client
41 #include "text.h"
43 //gui-qt
44 #include "hudwidget.h"
45 #include "fonts.h"
46 #include "qtg_cxxside.h"
47 #include "sprite.h"
49 extern "C" {
50 const char *calendar_text(void);
52 static QString popup_terrain_info(struct tile *ptile);
54 /***************************************************************************
55 Returns true if player has any unit of unit_type
56 ***************************************************************************/
57 bool has_player_unit_type(Unit_type_id utype)
59 unit_list_iterate(client.conn.playing->units, punit) {
60 if (utype_number(punit->utype) == utype) {
61 return true;
63 } unit_list_iterate_end;
65 return false;
68 /****************************************************************************
69 Custom message box constructor
70 ****************************************************************************/
71 hud_message_box::hud_message_box(QWidget *parent): QMessageBox(parent)
73 int size;
74 setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Dialog
75 | Qt::FramelessWindowHint);
76 f_text = *fc_font::instance()->get_font(fonts::default_font);
77 f_title = *fc_font::instance()->get_font(fonts::default_font);
79 size = f_text.pointSize();
80 if (size > 0) {
81 f_text.setPointSize(size * 4 / 3);
82 f_title.setPointSize(size * 3 / 2);
83 } else {
84 size = f_text.pixelSize();
85 f_text.setPixelSize(size * 4 / 3);
86 f_title.setPointSize(size * 3 / 2);
88 f_title.setBold(true);
89 f_title.setCapitalization(QFont::SmallCaps);
90 fm_text = new QFontMetrics(f_text);
91 fm_title = new QFontMetrics(f_title);
92 top = 0;
93 m_animate_step = 0;
94 hide();
95 mult = 1;
98 /****************************************************************************
99 Custom message box destructor
100 ****************************************************************************/
101 hud_message_box::~hud_message_box()
103 delete fm_text;
104 delete fm_title;
106 /****************************************************************************
107 Key press event for hud message box
108 ****************************************************************************/
109 void hud_message_box::keyPressEvent(QKeyEvent *event)
111 if (event->key() == Qt::Key_Escape) {
112 close();
113 destroy();
114 event->accept();
116 QWidget::keyPressEvent(event);
119 /****************************************************************************
120 Sets text and title and shows message box
121 ****************************************************************************/
122 void hud_message_box::set_text_title(QString s1, QString s2)
124 QSpacerItem *spacer;
125 QGridLayout *layout;
126 int w, w2, h;
127 QPoint p;
129 if (s1.contains('\n')) {
130 int i;
131 i = s1.indexOf('\n');
132 cs1 = s1.left(i);
133 cs2 = s1.right(s1.count() - i);
134 mult = 2;
135 w2 = qMax(fm_text->width(cs1), fm_text->width(cs2));
136 w = qMax(w2, fm_title->width(s2));
137 } else {
138 w = qMax(fm_text->width(s1), fm_title->width(s2));
140 w = w + 20;
141 h = mult * (fm_text->height() * 3 / 2) + 2 * fm_title->height();
142 top = 2 * fm_title->height();
143 spacer = new QSpacerItem(w, 0, QSizePolicy::Minimum,
144 QSizePolicy::Expanding);
145 layout = (QGridLayout *)this->layout();
146 layout->addItem(spacer, layout->rowCount(), 0, 1, layout->columnCount());
147 spacer = new QSpacerItem(0, h, QSizePolicy::Expanding,
148 QSizePolicy::Minimum);
149 layout->addItem(spacer, 0, 0, 1, layout->columnCount());
151 text = s1;
152 title = s2;
154 p = QPoint((parentWidget()->width() - w) / 2,
155 (parentWidget()->height() - h) / 2);
156 p = parentWidget()->mapToGlobal(p);
157 move(p);
158 show();
159 m_timer.start();
160 startTimer(45);
163 /****************************************************************************
164 Timer event used to animate message box
165 ****************************************************************************/
166 void hud_message_box::timerEvent(QTimerEvent *event)
168 m_animate_step = m_timer.elapsed() / 40;
169 update();
172 /****************************************************************************
173 Paint event for custom message box
174 ****************************************************************************/
175 void hud_message_box::paintEvent(QPaintEvent *event)
177 QPainter p;
178 QRect rx, ry, rfull;
179 QLinearGradient g;
180 QColor c1;
181 QColor c2;
182 int step;
184 step = m_animate_step % 300;
185 if (step > 150) {
186 step = step - 150;
187 step = 150 - step;
189 step = step + 30;
191 rfull = QRect(2 , 2, width() - 4 , height() - 4);
192 rx = QRect(2 , 2, width() - 4 , top);
193 ry = QRect(2 , top, width() - 4, height() - top - 4);
195 c1 = QColor(palette().color(QPalette::Highlight));
196 c2 = QColor(palette().color(QPalette::AlternateBase));
197 step = qMax(0, step);
198 step = qMin(255, step);
199 c1.setAlpha(step);
200 c2.setAlpha(step);
202 g = QLinearGradient(0 , 0, width(), height());
203 g.setColorAt(0, c1);
204 g.setColorAt(1, c2);
206 p.begin(this);
207 p.fillRect(rx, QColor(palette().color(QPalette::Highlight)));
208 p.fillRect(ry, QColor(palette().color(QPalette::AlternateBase)));
209 p.fillRect(rfull, g);
210 p.setFont(f_title);
211 p.drawText((width() - fm_title->width(title)) / 2,
212 fm_title->height() * 4 / 3, title);
213 p.setFont(f_text);
214 if (mult == 1) {
215 p.drawText((width() - fm_text->width(text)) / 2,
216 2 * fm_title->height() + fm_text->height() * 4 / 3, text);
217 } else {
218 p.drawText((width() - fm_text->width(cs1)) / 2,
219 2 * fm_title->height() + fm_text->height() * 4 / 3, cs1);
220 p.drawText((width() - fm_text->width(cs2)) / 2,
221 2 * fm_title->height() + fm_text->height() * 8 / 3, cs2);
223 p.end();
224 event->accept();
227 /****************************************************************************
228 Hud text constructor takes text to display and time
229 ****************************************************************************/
230 hud_text::hud_text(QString s, int time_secs,
231 QWidget *parent) : QWidget(parent)
233 int size;
235 text = s;
236 timeout = time_secs;
238 setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
239 f_text = *fc_font::instance()->get_font(fonts::default_font);
240 f_text.setBold(true);
241 f_text.setCapitalization(QFont::SmallCaps);
242 size = f_text.pointSize();
243 if (size > 0) {
244 f_text.setPointSize(size * 2);
245 } else {
246 size = f_text.pixelSize();
247 f_text.setPixelSize(size * 2);
249 fm_text = new QFontMetrics(f_text);
250 m_animate_step = 0;
251 m_timer.start();
252 startTimer(46);
253 setAttribute(Qt::WA_TranslucentBackground);
254 setAttribute(Qt::WA_ShowWithoutActivating);
255 setAttribute(Qt::WA_TransparentForMouseEvents);
256 setFocusPolicy(Qt::NoFocus);
259 /****************************************************************************
260 Shows hud text
261 ****************************************************************************/
262 void hud_text::show_me()
264 show();
265 center_me();
268 /****************************************************************************
269 Moves to top center parent widget and sets size new size
270 ****************************************************************************/
271 void hud_text::center_me()
273 int w;
274 QPoint p;
275 w = width();
276 if (bound_rect.isEmpty() == false) {
277 setFixedSize(bound_rect.width(), bound_rect.height());
279 p = QPoint((parentWidget()->width() - w) / 2,
280 parentWidget()->height() / 20);
281 move(p);
284 /****************************************************************************
285 Destructor for hud text
286 ****************************************************************************/
287 hud_text::~hud_text()
289 delete fm_text;
292 /****************************************************************************
293 Timer event, closes widget after timeout
294 ****************************************************************************/
295 void hud_text::timerEvent(QTimerEvent *event)
297 m_animate_step = m_timer.elapsed() / 40;
298 if (m_timer.elapsed() > timeout * 1000) {
299 close();
300 deleteLater();
302 update();
305 /****************************************************************************
306 Paint event for custom hud_text
307 ****************************************************************************/
308 void hud_text::paintEvent(QPaintEvent *event)
310 QPainter p;
311 QRect rfull;
312 QColor c1;
313 QColor c2;
314 float opacity;
316 center_me();
317 if (m_timer.elapsed() < timeout * 500) {
318 opacity = static_cast<float>(m_timer.elapsed())/(timeout * 300);
319 } else {
320 opacity = static_cast<float>(5000 - m_timer.elapsed())/(timeout * 200);
322 opacity = qMin(1.0f, opacity);
323 opacity = qMax(0.0f, opacity);
324 rfull = QRect(0 , 0, width(), height());
325 c1 = QColor(Qt::white);
326 c2 = QColor(35, 35, 35, 175);
327 c1.setAlphaF(c1.alphaF() * opacity);
328 c2.setAlphaF(c2.alphaF() * opacity);
329 p.begin(this);
330 p.setBrush(c2);
331 p.drawRoundedRect(rfull, height() / 6 , height() / 6);
332 p.setFont(f_text);
333 p.setPen(c1);
334 p.drawText(rfull, Qt::AlignCenter, text, &bound_rect);
336 p.end();
339 /****************************************************************************
340 Custom input box constructor
341 ****************************************************************************/
342 hud_input_box::hud_input_box(QWidget *parent): QDialog(parent)
344 int size;
346 setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Dialog
347 | Qt::FramelessWindowHint);
349 f_text = *fc_font::instance()->get_font(fonts::default_font);
350 f_title = *fc_font::instance()->get_font(fonts::default_font);
352 size = f_text.pointSize();
353 if (size > 0) {
354 f_text.setPointSize(size * 4 / 3);
355 f_title.setPointSize(size * 3 / 2);
356 } else {
357 size = f_text.pixelSize();
358 f_text.setPixelSize(size * 4 / 3);
359 f_title.setPointSize(size * 3 / 2);
361 f_title.setBold(true);
362 f_title.setCapitalization(QFont::SmallCaps);
363 fm_text = new QFontMetrics(f_text);
364 fm_title = new QFontMetrics(f_title);
365 top = 0;
366 m_animate_step = 0;
367 hide();
368 mult = 1;
371 /****************************************************************************
372 Custom input box destructor
373 ****************************************************************************/
374 hud_input_box::~hud_input_box()
376 delete fm_text;
377 delete fm_title;
379 /****************************************************************************
380 Sets text, title and default text and shows input box
381 ****************************************************************************/
382 void hud_input_box::set_text_title_definput(QString s1, QString s2,
383 QString def_input)
385 QSpacerItem *spacer;
386 QVBoxLayout *layout;
387 int w, w2, h;
388 QDialogButtonBox *button_box;
389 QPoint p;
391 button_box = new QDialogButtonBox(QDialogButtonBox::Ok
392 | QDialogButtonBox::Cancel,
393 Qt::Horizontal, this);
394 layout = new QVBoxLayout;
395 if (s1.contains('\n')) {
396 int i;
397 i = s1.indexOf('\n');
398 cs1 = s1.left(i);
399 cs2 = s1.right(s1.count() - i);
400 mult = 2;
401 w2 = qMax(fm_text->width(cs1), fm_text->width(cs2));
402 w = qMax(w2, fm_title->width(s2));
403 } else {
404 w = qMax(fm_text->width(s1), fm_title->width(s2));
406 w = w + 20;
407 h = mult * (fm_text->height() * 3 / 2) + 2 * fm_title->height();
408 top = 2 * fm_title->height();
410 spacer = new QSpacerItem(w, h, QSizePolicy::Expanding,
411 QSizePolicy::Minimum);
412 layout->addItem(spacer);
413 layout->addWidget(&input_edit);
414 layout->addWidget(button_box);
415 input_edit.setFont(f_text);
416 input_edit.setText(def_input);
417 setLayout(layout);
418 QObject::connect(button_box, SIGNAL(accepted()), this, SLOT(accept()));
419 QObject::connect(button_box, SIGNAL(rejected()), this, SLOT(reject()));
421 text = s1;
422 title = s2;
423 p = QPoint((parentWidget()->width() - w) / 2,
424 (parentWidget()->height() - h) / 2);
425 p = parentWidget()->mapToGlobal(p);
426 move(p);
427 input_edit.activateWindow();
428 input_edit.setFocus();
429 m_timer.start();
430 startTimer(41);
431 show();
432 update();
435 /****************************************************************************
436 Timer event used to animate input box
437 ****************************************************************************/
438 void hud_input_box::timerEvent(QTimerEvent *event)
440 m_animate_step = m_timer.elapsed() / 40;
441 update();
445 /****************************************************************************
446 Paint event for custom input box
447 ****************************************************************************/
448 void hud_input_box::paintEvent(QPaintEvent *event)
450 QPainter p;
451 QRect rx, ry;
452 QLinearGradient g;
453 QColor c1;
454 QColor c2;
455 QColor c3;
456 int step;
457 float fstep;
460 step = m_animate_step % 300;
461 if (step > 150) {
462 step = step - 150;
463 step = 150 - step;
465 step = step + 10;
466 rx = QRect(2 , 2, width() - 4 , top);
467 ry = QRect(2 , top, width() - 4, height() - top - 4);
469 c1 = QColor(palette().color(QPalette::Highlight));
470 c2 = QColor(Qt::transparent);
471 c3 = QColor(palette().color(QPalette::Highlight)).lighter(145);
472 step = qMax(0, step);
473 step = qMin(255, step);
474 c1.setAlpha(step);
475 c2.setAlpha(step);
476 c3.setAlpha(step);
478 fstep = static_cast<float>(step) / 400;
479 g = QLinearGradient(0 , 0, width(), height());
480 g.setColorAt(0, c2);
481 g.setColorAt(fstep, c3);
482 g.setColorAt(1, c2);
484 p.begin(this);
485 p.fillRect(rx, QColor(palette().color(QPalette::Highlight)));
486 p.fillRect(ry, QColor(palette().color(QPalette::AlternateBase)));
487 p.fillRect(rx, g);
488 p.setFont(f_title);
489 p.drawText((width() - fm_title->width(title)) / 2,
490 fm_title->height() * 4 / 3, title);
491 p.setFont(f_text);
492 if (mult == 1) {
493 p.drawText((width() - fm_text->width(text)) / 2,
494 2 * fm_title->height() + fm_text->height() * 4 / 3, text);
495 } else {
496 p.drawText((width() - fm_text->width(cs1)) / 2,
497 2 * fm_title->height() + fm_text->height() * 4 / 3, cs1);
498 p.drawText((width() - fm_text->width(cs2)) / 2,
499 2 * fm_title->height() + fm_text->height() * 8 / 3, cs2);
501 p.end();
502 event->accept();
505 /****************************************************************************
506 Constructor for hud_units (holds layout for whole uunits info)
507 ****************************************************************************/
508 hud_units::hud_units(QWidget *parent) : QFrame(parent)
510 QVBoxLayout *vbox;
511 QVBoxLayout *unit_lab;
512 QSpacerItem *sp;
513 setParent(parent);
515 main_layout = new QHBoxLayout;
516 sp = new QSpacerItem(50, 2);
517 vbox = new QVBoxLayout;
518 unit_lab = new QVBoxLayout;
519 unit_lab->setContentsMargins(6, 9, 0, 3);
520 vbox->setSpacing(0);
521 unit_lab->addWidget(&unit_label);
522 main_layout->addLayout(unit_lab);
523 main_layout->addWidget(&tile_label);
524 unit_icons = new unit_actions(this, nullptr);
525 vbox->addSpacerItem(sp);
526 vbox->addWidget(&text_label);
527 vbox->addWidget(unit_icons);
528 main_layout->addLayout(vbox);
529 main_layout->setSpacing(0);
530 main_layout->setSpacing(3);
531 main_layout->setContentsMargins(0, 0, 0, 0);
532 vbox->setSpacing(3);
533 vbox->setContentsMargins(0, 0, 0, 0);
534 setLayout(main_layout);
535 mw = new move_widget(this);
536 setFocusPolicy(Qt::ClickFocus);
540 /****************************************************************************
541 Hud_units destructor
542 ****************************************************************************/
543 hud_units::~hud_units()
548 /****************************************************************************
549 Move Event for hud_units, used to save position
550 ****************************************************************************/
551 void hud_units::moveEvent(QMoveEvent *event)
553 if (event->pos().x() != 0) {
554 gui()->qt_settings.unit_info_pos_x = 1 + (event->pos().x() * 1000)
555 / gui()->mapview_wdg->width();
556 } else {
557 gui()->qt_settings.unit_info_pos_x = 0;
559 if (event->pos().y() != 0) {
560 gui()->qt_settings.unit_info_pos_y = 1 + (event->pos().y() * 1000)
561 / gui()->mapview_wdg->height();
562 } else {
563 gui()->qt_settings.unit_info_pos_y = 0;
568 /****************************************************************************
569 Update possible action for given units
570 ****************************************************************************/
571 void hud_units::update_actions(unit_list *punits)
573 int num;
574 int wwidth;
575 QFont font = *fc_font::instance()->get_font(fonts::notify_label);
576 QFontMetrics *fm;
577 QImage cropped_img;
578 QImage img;
579 QPainter p;
580 QPixmap pix, pix2;
581 QRect crop;
582 QString mp;
583 QString snum;
584 QString text_str;
585 struct canvas *tile_pixmap;
586 struct canvas *unit_pixmap;
587 struct city *pcity;
588 struct player *owner;
589 struct unit *punit;
591 punit = head_of_units_in_focus();
592 if (punit == nullptr) {
593 hide();
594 return;
597 font.setCapitalization(QFont::AllUppercase);
598 font.setBold(true);
599 setFixedHeight(parentWidget()->height() / 12);
600 text_label.setFixedHeight((height() * 2) / 10);
601 move((gui()->mapview_wdg->width()
602 * gui()->qt_settings.unit_info_pos_x) / 1000,
603 (gui()->mapview_wdg->height()
604 * gui()->qt_settings.unit_info_pos_y) / 1000);
605 unit_icons->setFixedHeight((height() * 8) / 10);
607 setUpdatesEnabled(false);
609 text_str = QString(unit_name_translation(punit));
610 owner = punit->owner;
611 pcity = player_city_by_number(owner, punit->homecity);
612 if (pcity != NULL) {
613 text_str = QString(("%1(%2)"))
614 .arg(unit_name_translation(punit), city_name_get(pcity));
616 text_str = text_str + " ";
617 mp = QString(move_points_text(punit->moves_left, false));
618 if (utype_fuel(unit_type_get(punit))) {
619 mp = mp + QString("(") + QString(move_points_text((
620 unit_type_get(punit)->move_rate
621 * ((punit->fuel) - 1)
622 + punit->moves_left), false))
623 + QString(")");
625 /* TRANS: MP = Movement points */
626 mp = QString(_("MP: ")) + mp;
627 text_str = text_str + mp + " ";
628 text_str += QString(_("HP:%1/%2")).arg(
629 QString::number(punit->hp),
630 QString::number(unit_type_get(punit)->hp));
631 num = unit_list_size(punit->tile->units);
632 snum = QString::number(unit_list_size(punit->tile->units) - 1);
633 if (unit_list_size(get_units_in_focus()) > 1) {
634 text_str = text_str + QString(_(" (Selected %1 units)"))
635 .arg(unit_list_size(get_units_in_focus()));
636 } else if (num > 2) {
637 text_str = text_str + QString(_(" +%1 units"))
638 .arg(snum.toLocal8Bit().data());
639 } else if (num == 2) {
640 text_str = text_str + QString(_(" +1 unit"));
642 text_label.setText(text_str);
643 font.setPixelSize((text_label.height() * 9) / 10);
644 text_label.setFont(font);
645 fm = new QFontMetrics(font);
646 text_label.setFixedWidth(fm->width(text_str) + 20);
647 delete fm;
649 unit_pixmap = qtg_canvas_create(tileset_unit_width(tileset),
650 tileset_unit_height(tileset));
651 unit_pixmap->map_pixmap.fill(Qt::transparent);
652 put_unit(punit, unit_pixmap, 1, 0, 0);
653 img = unit_pixmap->map_pixmap.toImage();
654 crop = zealous_crop_rect(img);
655 cropped_img = img.copy(crop);
656 img = cropped_img.scaledToHeight(height(), Qt::SmoothTransformation);
657 pix = QPixmap::fromImage(img);
658 /* add transparent borders if image is too slim */
659 if (pix.width() < tileset_unit_width(tileset)) {
660 int px = tileset_full_tile_width(tileset);
661 pix2 = QPixmap(px, pix.height());
662 pix2.fill(Qt::transparent);
663 p.begin(&pix2);
664 p.drawPixmap(px / 2 - pix.width() / 2, 0, pix);
665 p.end();
666 pix = pix2;
668 wwidth = 2 * 3 + pix.width();
669 unit_label.setPixmap(pix);
670 if (tileset_is_isometric(tileset)) {
671 tile_pixmap = qtg_canvas_create(tileset_full_tile_width(tileset),
672 tileset_tile_height(tileset) * 2);
673 } else {
674 tile_pixmap = qtg_canvas_create(tileset_full_tile_width(tileset),
675 tileset_tile_height(tileset));
677 tile_pixmap->map_pixmap.fill(QColor(0 , 0 , 0 , 0));
678 put_terrain(punit->tile, tile_pixmap, 1.0, 0, 0);
679 img = tile_pixmap->map_pixmap.toImage();
680 crop = zealous_crop_rect(img);
681 cropped_img = img.copy(crop);
682 if (cropped_img.height() > height() - 5 ||
683 cropped_img.height() < height() / 3) {
684 img = cropped_img.scaledToHeight(height() - 5,
685 Qt::SmoothTransformation);
686 } else {
687 img = cropped_img;
689 pix = QPixmap::fromImage(img);
690 tile_label.setPixmap(pix);
691 unit_label.setToolTip(popup_info_text(punit->tile));
692 tile_label.setToolTip(popup_terrain_info(punit->tile));
693 wwidth = wwidth + pix.width();
694 qtg_canvas_free(tile_pixmap);
695 qtg_canvas_free(unit_pixmap);
697 setFixedWidth(wwidth + qMax(unit_icons->update_actions() * (height() * 8)
698 / 10, text_label.width()));
699 mw->put_to_corner();
700 setUpdatesEnabled(true);
701 updateGeometry();
702 update();
704 show();
707 /****************************************************************************
708 Custom label with extra mouse events
709 ****************************************************************************/
710 click_label::click_label() : QLabel()
712 connect(this, SIGNAL(left_clicked()), SLOT(on_clicked()));
715 /****************************************************************************
716 Mouse event for click_label
717 ****************************************************************************/
718 void click_label::mousePressEvent(QMouseEvent *e)
720 if (e->button() == Qt::LeftButton) {
721 emit left_clicked();
725 /****************************************************************************
726 Centers on current unit
727 ****************************************************************************/
728 void click_label::on_clicked()
730 gui()->game_tab_widget->setCurrentIndex(0);
731 request_center_focus_unit();
734 /****************************************************************************
735 Hud action constructor, used to show one action
736 ****************************************************************************/
737 hud_action::hud_action(QWidget *parent) : QWidget(parent)
739 connect(this, SIGNAL(left_clicked()), SLOT(on_clicked()));
740 setFocusPolicy(Qt::ClickFocus);
741 focus = false;
742 action_pixmap = nullptr;
745 /****************************************************************************
746 Sets given pixmap for hud_action
747 ****************************************************************************/
748 void hud_action::set_pixmap(QPixmap *p)
750 action_pixmap = p;
753 /****************************************************************************
754 Custom painting for hud_action
755 ****************************************************************************/
756 void hud_action::paintEvent(QPaintEvent *event)
758 QRect rx, ry, rz;
759 QPainter p;
761 rx = QRect(0, 0, width(), height());
762 ry = QRect(0, 0, action_pixmap->width(), action_pixmap->height());
763 rz = QRect(0, 0, width() - 1, height() - 3);
764 p.begin(this);
765 p.setCompositionMode(QPainter::CompositionMode_Source);
766 p.setRenderHint(QPainter::SmoothPixmapTransform);
767 p.drawPixmap(rx, *action_pixmap, ry);
768 p.setPen(QColor(palette().color(QPalette::Text)));
769 p.drawRect(rz);
770 if (focus == true) {
771 p.setCompositionMode(QPainter::CompositionMode_DestinationOver);
772 p.fillRect(rx, QColor(palette().color(QPalette::Highlight)));
774 p.end();
778 /****************************************************************************
779 Hud action destructor
780 ****************************************************************************/
781 hud_action::~hud_action()
783 if (action_pixmap) {
784 delete action_pixmap;
788 /****************************************************************************
789 Mouse press event for hud_action
790 ****************************************************************************/
791 void hud_action::mousePressEvent(QMouseEvent *e)
793 if (e->button() == Qt::RightButton) {
794 emit right_clicked();
795 } else if (e->button() == Qt::LeftButton) {
796 emit left_clicked();
800 /****************************************************************************
801 Leave event for hud_action, used to get status of pixmap higlight
802 ****************************************************************************/
803 void hud_action::leaveEvent(QEvent *event)
805 focus = false;
806 update();
807 QWidget::leaveEvent(event);
810 /****************************************************************************
811 Enter event for hud_action, used to get status of pixmap higlight
812 ****************************************************************************/
813 void hud_action::enterEvent(QEvent *event)
815 focus = true;
816 update();
817 QWidget::enterEvent(event);
820 /****************************************************************************
821 Right click event for hud_action
822 ****************************************************************************/
823 void hud_action::on_right_clicked()
827 /****************************************************************************
828 Left click event for hud_action
829 ****************************************************************************/
830 void hud_action::on_clicked()
832 gui()->menu_bar->execute_shortcut(action_shortcut);
835 /****************************************************************************
836 Units action contructor, holds possible hud_actions
837 ****************************************************************************/
838 unit_actions::unit_actions(QWidget *parent, unit *punit) : QWidget(parent)
840 layout = new QHBoxLayout(this);
841 layout->setSpacing(3);
842 layout->setContentsMargins(0, 0, 0, 0);
843 current_unit = punit;
844 init_layout();
845 setFocusPolicy(Qt::ClickFocus);
850 /****************************************************************************
851 Destructor for unit_actions
852 ****************************************************************************/
853 unit_actions::~unit_actions()
855 qDeleteAll(actions);
856 actions.clear();
860 /****************************************************************************
861 Initiazlizes layout ( layout needs to be changed after adding units )
862 ****************************************************************************/
863 void unit_actions::init_layout()
865 QSizePolicy size_fixed_policy(QSizePolicy::MinimumExpanding,
866 QSizePolicy::Fixed,
867 QSizePolicy::Frame);
868 setSizePolicy(size_fixed_policy);
869 layout->setSpacing(0);
870 setLayout(layout);
874 /****************************************************************************
875 Updates avaialable actions, returns actions count
876 ****************************************************************************/
877 int unit_actions::update_actions()
879 hud_action *a;
881 current_unit = head_of_units_in_focus();
883 if (current_unit == nullptr) {
884 clear_layout();
885 hide();
886 return 0;
888 hide();
889 clear_layout();
890 setUpdatesEnabled(false);
893 foreach (a, actions) {
894 delete a;
896 qDeleteAll(actions);
897 actions.clear();
899 /* Create possible actions */
901 if (unit_can_build_city(current_unit)) {
902 a = new hud_action(this);
903 a->action_shortcut = SC_BUILDCITY;
904 a->set_pixmap(fc_icons::instance()->get_pixmap("home"));
905 actions.append(a);
909 if (can_unit_do_activity(current_unit, ACTIVITY_MINE)) {
910 struct terrain *pterrain = tile_terrain(unit_tile(current_unit));
911 a = new hud_action(this);
912 a->action_shortcut = SC_BUILDMINE;
913 actions.append(a);
914 if (pterrain->mining_result != T_NONE
915 && pterrain->mining_result != pterrain) {
916 if (!strcmp(terrain_rule_name(pterrain), "Jungle")
917 || !strcmp(terrain_rule_name(pterrain), "Plains")
918 || !strcmp(terrain_rule_name(pterrain), "Grassland")
919 || !strcmp(terrain_rule_name(pterrain), "Swamp")) {
920 a->set_pixmap(fc_icons::instance()->get_pixmap("plantforest"));
921 } else {
922 a->set_pixmap(fc_icons::instance()->get_pixmap("transform"));
924 } else {
925 a->set_pixmap(fc_icons::instance()->get_pixmap("mine"));
929 if (can_unit_do_activity(current_unit, ACTIVITY_IRRIGATE)) {
930 struct terrain *pterrain = tile_terrain(unit_tile(current_unit));
931 a = new hud_action(this);
932 a->action_shortcut = SC_BUILDIRRIGATION;
933 if (pterrain->irrigation_result != T_NONE
934 && pterrain->irrigation_result != pterrain) {
935 if ((!strcmp(terrain_rule_name(pterrain), "Forest") ||
936 !strcmp(terrain_rule_name(pterrain), "Jungle"))) {
937 a->set_pixmap(fc_icons::instance()->get_pixmap("chopchop"));
938 } else {
939 a->set_pixmap(fc_icons::instance()->get_pixmap("transform"));
941 } else {
942 a->set_pixmap(fc_icons::instance()->get_pixmap("irrigation"));
944 actions.append(a);
947 if (can_unit_do_activity(current_unit, ACTIVITY_TRANSFORM)) {
948 a = new hud_action(this);
949 a->action_shortcut = SC_TRANSFORM;
950 a->set_pixmap(fc_icons::instance()->get_pixmap("transform"));
951 actions.append(a);
954 /* Road */
956 bool ok = false;
957 extra_type_by_cause_iterate(EC_ROAD, pextra) {
958 struct road_type *proad = extra_road_get(pextra);
959 if (can_build_road(proad, current_unit, unit_tile(current_unit))) {
960 ok = true;
963 extra_type_by_cause_iterate_end;
964 if (ok) {
965 a = new hud_action(this);
966 a->action_shortcut = SC_BUILDROAD;
967 a->set_pixmap(fc_icons::instance()->get_pixmap("buildroad"));
968 actions.append(a);
971 /* Goto */
972 a = new hud_action(this);
973 a->action_shortcut = SC_GOTO;
974 a->set_pixmap(fc_icons::instance()->get_pixmap("goto"));
975 actions.append(a);
978 if (can_unit_do_activity(current_unit, ACTIVITY_FORTIFYING)) {
979 a = new hud_action(this);
980 a->action_shortcut = SC_FORTIFY;
981 a->set_pixmap(fc_icons::instance()->get_pixmap("fortify"));
982 actions.append(a);
986 if (can_unit_do_activity(current_unit, ACTIVITY_SENTRY)) {
987 a = new hud_action(this);
988 a->action_shortcut = SC_SENTRY;
989 a->set_pixmap(fc_icons::instance()->get_pixmap("sentry"));
990 actions.append(a);
992 /* Load */
993 if (unit_can_load(current_unit)) {
994 a = new hud_action(this);
995 a->action_shortcut = SC_LOAD;
996 a->set_pixmap(fc_icons::instance()->get_pixmap("load"));
997 actions.append(a);
999 /* Set homecity */
1000 if (tile_city(unit_tile(current_unit))) {
1001 if (can_unit_change_homecity_to(current_unit,
1002 tile_city(unit_tile(current_unit)))) {
1003 a = new hud_action(this);
1004 a->action_shortcut = SC_SETHOME;
1005 a->set_pixmap(fc_icons::instance()->get_pixmap("set_homecity"));
1006 actions.append(a);
1009 /* Upgrade */
1010 if (UU_OK == unit_upgrade_test(current_unit, FALSE)) {
1011 a = new hud_action(this);
1012 a->action_shortcut = SC_UPGRADE_UNIT;
1013 a->set_pixmap(fc_icons::instance()->get_pixmap("upgrade"));
1014 actions.append(a);
1016 /* Automate */
1017 if (can_unit_do_autosettlers(current_unit)) {
1018 a = new hud_action(this);
1019 a->action_shortcut = SC_AUTOMATE;
1020 a->set_pixmap(fc_icons::instance()->get_pixmap("automate"));
1021 actions.append(a);
1023 /* Paradrop */
1024 if (unit_has_type_flag(current_unit, UTYF_PARATROOPERS)) {
1025 a = new hud_action(this);
1026 a->action_shortcut = SC_PARADROP;
1027 a->set_pixmap(fc_icons::instance()->get_pixmap("paradrop"));
1028 actions.append(a);
1030 /* Clean pollution */
1031 if (can_unit_do_activity(current_unit, ACTIVITY_POLLUTION)) {
1032 a = new hud_action(this);
1033 a->action_shortcut = SC_PARADROP;
1034 a->set_pixmap(fc_icons::instance()->get_pixmap("pollution"));
1035 actions.append(a);
1037 /* Unload */
1038 if (unit_transported(current_unit)
1039 && can_unit_unload(current_unit, unit_transport_get(current_unit))
1040 && can_unit_exist_at_tile(current_unit, unit_tile(current_unit))) {
1041 a = new hud_action(this);
1042 a->action_shortcut = SC_UNLOAD;
1043 a->set_pixmap(fc_icons::instance()->get_pixmap("unload"));
1044 actions.append(a);
1046 /* Nuke */
1047 if (unit_has_type_flag(current_unit, UTYF_NUCLEAR)) {
1048 a = new hud_action(this);
1049 a->action_shortcut = SC_NUKE;
1050 a->set_pixmap(fc_icons::instance()->get_pixmap("nuke"));
1051 actions.append(a);
1054 /* Wait */
1055 a = new hud_action(this);
1056 a->action_shortcut = SC_WAIT;
1057 a->set_pixmap(fc_icons::instance()->get_pixmap("wait"));
1058 actions.append(a);
1060 /* Done moving */
1061 a = new hud_action(this);
1062 a->action_shortcut = SC_DONE_MOVING;
1063 a->set_pixmap(fc_icons::instance()->get_pixmap("done"));
1064 actions.append(a);
1067 foreach (a, actions) {
1068 a->setToolTip(gui()->menu_bar->shortcut_2_menustring(a->action_shortcut));
1069 a->setFixedHeight(height());
1070 a->setFixedWidth(height());
1071 layout->addWidget(a);
1074 setFixedWidth(actions.count() * height());
1075 setUpdatesEnabled(true);
1076 show();
1077 layout->update();
1078 updateGeometry();
1079 return actions.count();
1082 /****************************************************************************
1083 Cleans layout - run it before layout initialization
1084 ****************************************************************************/
1085 void unit_actions::clear_layout()
1087 int i = actions.count();
1088 hud_action *ui;
1089 int j;
1091 setUpdatesEnabled(false);
1092 for (j = 0; j < i; j++) {
1093 ui = actions[j];
1094 layout->removeWidget(ui);
1095 delete ui;
1097 while (!actions.empty()) {
1098 actions.removeFirst();
1100 setUpdatesEnabled(true);
1103 /****************************************************************************
1104 Constructor for widget allowing loading units on transports
1105 ****************************************************************************/
1106 hud_unit_loader::hud_unit_loader(struct unit *pcargo, struct tile *ptile)
1108 setProperty("showGrid", "false");
1109 setProperty("selectionBehavior", "SelectRows");
1110 setEditTriggers(QAbstractItemView::NoEditTriggers);
1111 setSelectionMode(QAbstractItemView::SingleSelection);
1112 verticalHeader()->setVisible(false);
1113 horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
1114 horizontalHeader()->setVisible(false);
1115 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1116 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1117 connect(selectionModel(),
1118 SIGNAL(selectionChanged(const QItemSelection &,
1119 const QItemSelection &)), this,
1120 SLOT(selection_changed(const QItemSelection &,
1121 const QItemSelection &)));
1122 cargo = pcargo;
1123 qtile = ptile;
1127 /****************************************************************************
1128 Destructor for units loader
1129 ****************************************************************************/
1130 hud_unit_loader::~hud_unit_loader()
1135 /****************************************************************************
1136 Shows unit loader, adds possible tranportsand units to table
1137 Calculates table size
1138 ****************************************************************************/
1139 void hud_unit_loader::show_me()
1141 QTableWidgetItem *new_item;
1142 int max_size = 0;
1143 int i, j;
1144 int w,h;
1145 sprite *spite;
1147 unit_list_iterate(qtile->units, ptransport) {
1148 if (can_unit_transport(ptransport, cargo)
1149 && get_transporter_occupancy(ptransport)
1150 < get_transporter_capacity(ptransport)) {
1151 transports.append(ptransport);
1152 max_size = qMax(max_size, get_transporter_occupancy(ptransport));
1154 } unit_list_iterate_end;
1156 setRowCount(transports.count());
1157 setColumnCount(max_size + 1);
1158 for (i = 0 ; i < transports.count(); i++) {
1159 QString str;
1160 spite = get_unittype_sprite(tileset, transports.at(i)->utype,
1161 direction8_invalid(), true);
1162 str = utype_rule_name(transports.at(i)->utype);
1163 /* TRANS: MP - just movement points */
1164 str = str + " ("
1165 + QString(move_points_text(transports.at(i)->moves_left, false))
1166 + _("MP") + ")";
1167 new_item = new QTableWidgetItem(QIcon(*spite->pm), str);
1168 setItem(i, 0, new_item);
1169 j = 1;
1170 unit_list_iterate(transports.at(i)->transporting, tunit) {
1171 spite = get_unittype_sprite(tileset, tunit->utype,
1172 direction8_invalid(), true);
1173 new_item = new QTableWidgetItem(QIcon(*spite->pm), "");
1174 setItem(i, j, new_item);
1175 j++;
1176 } unit_list_iterate_end;
1179 w = verticalHeader()->width() + 4;
1180 for (i = 0; i < columnCount(); i++) {
1181 w += columnWidth(i);
1183 h = horizontalHeader()->height() + 4;
1184 for (i = 0; i < rowCount(); i++) {
1185 h += rowHeight(i);
1188 resize(w, h);
1189 setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Dialog
1190 | Qt::FramelessWindowHint);
1191 show();
1194 /****************************************************************************
1195 Selects given tranport and closes widget
1196 ****************************************************************************/
1197 void hud_unit_loader::selection_changed(const QItemSelection& s1,
1198 const QItemSelection& s2)
1200 int curr_row;
1202 curr_row = s1.indexes().at(0).row();
1203 request_unit_load(cargo, transports.at(curr_row), qtile);
1204 close();
1207 /****************************************************************************
1208 Constructor for unit_hud_selector
1209 ****************************************************************************/
1210 unit_hud_selector::unit_hud_selector(QWidget *parent) : QFrame(parent)
1212 QHBoxLayout *hbox, *hibox;
1213 Unit_type_id utype_id;
1214 QGroupBox *no_name;
1215 QVBoxLayout *groupbox_layout;
1217 hide();
1218 struct unit *punit = head_of_units_in_focus();
1220 setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Dialog
1221 | Qt::FramelessWindowHint);
1222 main_layout = new QVBoxLayout(this);
1224 unit_sel_type = new QComboBox();
1226 unit_type_iterate(utype) {
1227 utype_id = utype_index(utype);
1228 if (has_player_unit_type(utype_id)) {
1229 unit_sel_type->addItem(utype_name_translation(utype), utype_id);
1232 unit_type_iterate_end;
1234 if (punit) {
1235 int i;
1236 i = unit_sel_type->findText(utype_name_translation(punit->utype));
1237 unit_sel_type->setCurrentIndex(i);
1239 no_name = new QGroupBox();
1240 no_name->setTitle(_("Unit type"));
1241 this_type = new QRadioButton(_("Selected type"), no_name);
1242 this_type->setChecked(true);
1243 any_type = new QRadioButton(_("All types"), no_name);
1244 connect(unit_sel_type, SIGNAL(currentIndexChanged(int)), this,
1245 SLOT(select_units(int)));
1246 connect(this_type, SIGNAL(toggled(bool)), this, SLOT(select_units(bool)));
1247 connect(any_type, SIGNAL(toggled(bool)), this, SLOT(select_units(bool)));
1248 groupbox_layout = new QVBoxLayout;
1249 groupbox_layout->addWidget(unit_sel_type);
1250 groupbox_layout->addWidget(this_type);
1251 groupbox_layout->addWidget(any_type);
1252 no_name->setLayout(groupbox_layout);
1253 hibox = new QHBoxLayout;
1254 hibox->addWidget(no_name);
1256 no_name = new QGroupBox();
1257 no_name->setTitle(_("Unit activity"));
1258 any_activity = new QRadioButton(_("Any activity"), no_name);
1259 any_activity->setChecked(true);
1260 fortified = new QRadioButton(_("Fortified"), no_name);
1261 idle = new QRadioButton(_("Idle"), no_name);
1262 sentried = new QRadioButton(_("Sentried"), no_name);
1263 connect(any_activity, SIGNAL(toggled(bool)), this, SLOT(select_units(bool)));
1264 connect(idle, SIGNAL(toggled(bool)), this, SLOT(select_units(bool)));
1265 connect(fortified, SIGNAL(toggled(bool)), this, SLOT(select_units(bool)));
1266 connect(sentried, SIGNAL(toggled(bool)), this, SLOT(select_units(bool)));
1267 groupbox_layout = new QVBoxLayout;
1268 groupbox_layout->addWidget(any_activity);
1269 groupbox_layout->addWidget(idle);
1270 groupbox_layout->addWidget(fortified);
1271 groupbox_layout->addWidget(sentried);
1272 no_name->setLayout(groupbox_layout);
1273 hibox->addWidget(no_name);
1274 main_layout->addLayout(hibox);
1276 no_name = new QGroupBox();
1277 no_name->setTitle(_("Unit HP and MP"));
1278 any = new QRadioButton(_("Any unit"), no_name);
1279 full_hp = new QRadioButton(_("Full HP"), no_name);
1280 full_mp = new QRadioButton(_("Full MP"), no_name);
1281 full_hp_mp = new QRadioButton(_("Full HP and MP"), no_name);
1282 full_hp_mp->setChecked(true);
1283 connect(any, SIGNAL(toggled(bool)), this, SLOT(select_units(bool)));
1284 connect(full_hp, SIGNAL(toggled(bool)), this, SLOT(select_units(bool)));
1285 connect(full_mp, SIGNAL(toggled(bool)), this, SLOT(select_units(bool)));
1286 connect(full_hp_mp, SIGNAL(toggled(bool)), this, SLOT(select_units(bool)));
1287 groupbox_layout = new QVBoxLayout;
1288 groupbox_layout->addWidget(any);
1289 groupbox_layout->addWidget(full_hp);
1290 groupbox_layout->addWidget(full_mp);
1291 groupbox_layout->addWidget(full_hp_mp);
1292 no_name->setLayout(groupbox_layout);
1293 hibox = new QHBoxLayout;
1294 hibox->addWidget(no_name);
1296 no_name = new QGroupBox();
1297 no_name->setTitle(_("Location"));
1298 everywhere = new QRadioButton(_("Everywhere"), no_name);
1299 this_tile = new QRadioButton(_("Current tile"), no_name);
1300 this_continent = new QRadioButton(_("Current continent"), no_name);
1301 main_continent = new QRadioButton(_("Main continent"), no_name);
1302 groupbox_layout = new QVBoxLayout;
1304 if (punit) {
1305 this_tile->setChecked(true);
1306 } else {
1307 this_tile->setDisabled(true);
1308 this_continent->setDisabled(true);
1309 main_continent->setChecked(true);
1312 groupbox_layout->addWidget(this_tile);
1313 groupbox_layout->addWidget(this_continent);
1314 groupbox_layout->addWidget(main_continent);
1315 groupbox_layout->addWidget(everywhere);
1317 no_name->setLayout(groupbox_layout);
1318 hibox->addWidget(no_name);
1319 main_layout->addLayout(hibox);
1321 select = new QPushButton(_("Select"));
1322 cancel = new QPushButton(_("Cancel"));
1323 connect(everywhere, SIGNAL(toggled(bool)), this, SLOT(select_units(bool)));
1324 connect(this_tile, SIGNAL(toggled(bool)), this, SLOT(select_units(bool)));
1325 connect(this_continent, SIGNAL(toggled(bool)), this,
1326 SLOT(select_units(bool)));
1327 connect(main_continent, SIGNAL(toggled(bool)), this,
1328 SLOT(select_units(bool)));
1329 connect(select, SIGNAL(clicked()), this, SLOT(uhs_select()));
1330 connect(cancel, SIGNAL(clicked()), this, SLOT(uhs_cancel()));
1331 hbox = new QHBoxLayout;
1332 hbox->addWidget(cancel);
1333 hbox->addWidget(select);
1335 result_label.setAlignment(Qt::AlignCenter);
1336 main_layout->addWidget(&result_label, Qt::AlignHCenter);
1337 main_layout->addLayout(hbox);
1338 setLayout(main_layout);
1342 /****************************************************************************
1343 Shows and moves to center unit_hud_selector
1344 ****************************************************************************/
1345 void unit_hud_selector::show_me()
1347 QPoint p;
1349 p = QPoint((parentWidget()->width() - sizeHint().width()) / 2,
1350 (parentWidget()->height() - sizeHint().height()) / 2);
1351 p = parentWidget()->mapToGlobal(p);
1352 move(p);
1353 setVisible(true);
1354 show();
1355 select_units();
1358 /****************************************************************************
1359 Unit_hud_selector destructor
1360 ****************************************************************************/
1361 unit_hud_selector::~unit_hud_selector()
1366 /****************************************************************************
1367 Selects and closes widget
1368 ****************************************************************************/
1369 void unit_hud_selector::uhs_select()
1371 const struct player *pplayer;
1373 pplayer = client_player();
1375 unit_list_iterate(pplayer->units, punit) {
1376 if (activity_filter(punit) && hp_filter(punit)
1377 && island_filter(punit) && type_filter(punit)) {
1378 unit_focus_add(punit);
1380 } unit_list_iterate_end;
1381 close();
1384 /****************************************************************************
1385 Closes current widget
1386 ****************************************************************************/
1387 void unit_hud_selector::uhs_cancel()
1389 close();
1392 /****************************************************************************
1393 Shows number of selected units on label
1394 ****************************************************************************/
1395 void unit_hud_selector::select_units(int x)
1397 int num = 0;
1398 const struct player *pplayer;
1400 pplayer = client_player();
1402 unit_list_iterate(pplayer->units, punit) {
1403 if (activity_filter(punit) && hp_filter(punit)
1404 && island_filter(punit) && type_filter(punit)) {
1405 num++;
1407 } unit_list_iterate_end;
1408 result_label.setText(QString(PL_("%1 unit", "%1 units", num)).arg(num));
1411 /****************************************************************************
1412 Convinient slot for ez connect
1413 ****************************************************************************/
1414 void unit_hud_selector::select_units(bool x)
1416 select_units(0);
1419 /****************************************************************************
1420 Key press event for unit_hud_selector
1421 ****************************************************************************/
1422 void unit_hud_selector::keyPressEvent(QKeyEvent *event)
1424 if ((event->key() == Qt::Key_Return)
1425 || (event->key() == Qt::Key_Enter)) {
1426 uhs_select();
1428 if (event->key() == Qt::Key_Escape) {
1429 close();
1430 event->accept();
1432 QWidget::keyPressEvent(event);
1435 /****************************************************************************
1436 Filter by activity
1437 ****************************************************************************/
1438 bool unit_hud_selector::activity_filter(struct unit *punit)
1440 if ((punit->activity == ACTIVITY_FORTIFIED && fortified->isChecked())
1441 || (punit->activity == ACTIVITY_SENTRY && sentried->isChecked())
1442 || (punit->activity == ACTIVITY_IDLE && idle->isChecked())
1443 || any_activity->isChecked()) {
1444 return true;
1446 return false;
1449 /****************************************************************************
1450 Filter by hp/mp
1451 ****************************************************************************/
1452 bool unit_hud_selector::hp_filter(struct unit *punit)
1454 if ((any->isChecked()
1455 || (full_mp->isChecked()
1456 && punit->moves_left >= punit->utype->move_rate)
1457 || (full_hp->isChecked() && punit->hp >= punit->utype->hp)
1458 || (full_hp_mp->isChecked() && punit->hp >= punit->utype->hp
1459 && punit->moves_left >= punit->utype->move_rate))) {
1460 return true;
1462 return false;
1465 /****************************************************************************
1466 Filter by location
1467 ****************************************************************************/
1468 bool unit_hud_selector::island_filter(struct unit *punit)
1470 int island = -1;
1471 struct unit *cunit = head_of_units_in_focus();
1473 if (this_tile->isChecked() && cunit) {
1474 if (punit->tile == cunit->tile) {
1475 return true;
1479 if (main_continent->isChecked() && player_capital(client_player())) {
1480 island = player_capital(client_player())->tile->continent;
1481 } else if (this_continent->isChecked() && cunit) {
1482 island = cunit->tile->continent;
1485 if (island > -1) {
1486 if (punit->tile->continent == island) {
1487 return true;
1491 if (everywhere->isChecked()) {
1492 return true;
1494 return false;
1497 /****************************************************************************
1498 Filter by type
1499 ****************************************************************************/
1500 bool unit_hud_selector::type_filter(struct unit *punit)
1502 QVariant qvar;
1503 Unit_type_id utype_id;
1505 if (this_type->isChecked()) {
1506 qvar = unit_sel_type->currentData();
1507 utype_id = qvar.toInt();
1508 if (utype_id == utype_index(punit->utype)) {
1509 return true;
1510 } else {
1511 return false;
1514 if (any_type->isChecked()) {
1515 return true;
1517 return false;
1520 /****************************************************************************
1521 Tooltip text for terrain information
1522 ****************************************************************************/
1523 QString popup_terrain_info(struct tile *ptile)
1525 QString ret, t;
1526 struct terrain *terr;
1528 terr = ptile->terrain;
1529 ret = QString(_("Terrain: %1\n")).arg(tile_get_info_text(ptile, TRUE, 0));
1530 ret = ret + QString(_("Food/Prod/Trade: %1\n"))
1531 .arg(get_tile_output_text(ptile));
1532 t = get_infrastructure_text(ptile->extras);
1533 if (t != "") {
1534 ret = ret + QString(_("Infrastructure: %1\n")).arg(t);
1536 ret = ret + QString(_("Defence bonus: %1%")).arg(terr->defense_bonus);
1537 return ret;
1540 /****************************************************************************
1541 Shows new turn information with big font
1542 ****************************************************************************/
1543 void show_new_turn_info()
1545 QString s;
1546 hud_text *ht;
1547 QList<hud_text *> close_list;
1548 struct research *research;
1549 int i;
1551 if (client_has_player() == false
1552 || gui()->qt_settings.show_new_turn_text == false) {
1553 return;
1555 close_list = gui()->mapview_wdg->findChildren<hud_text *>();
1556 for (i = 0; i < close_list.size(); ++i) {
1557 close_list.at(i)->close();
1558 close_list.at(i)->deleteLater();
1560 research = research_get(client_player());
1561 s = QString(_("Year: %1 (Turn: %2)"))
1562 .arg(calendar_text()).arg(game.info.turn) + "\n";
1563 s = s + QString(nation_plural_for_player(client_player()));
1564 s = s + " - " + QString(_("Population: %1"))
1565 .arg(population_to_text(civ_population(client.conn.playing)));
1566 if (research->researching != A_UNKNOWN
1567 && research->researching != A_UNSET
1568 && research->researching != A_NONE) {
1569 s = s + "\n" + QString(research_advance_name_translation(research,
1570 research->researching)) +
1571 " (" + QString::number(research->bulbs_researched) + "/"
1572 + QString::number(research->client.researching_cost) + ")";
1574 s = s + "\n" + science_dialog_text() + "\n";
1575 s = s + QString(_("Gold: %1 (+%2)"))
1576 .arg(client.conn.playing->economic.gold)
1577 .arg(player_get_expected_income(client.conn.playing));
1578 ht = new hud_text(s, 5, gui()->mapview_wdg);
1579 ht->show_me();