Freeciv21
Develop your civilization from humble roots to a global empire
messagewin.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 1996-2023 Freeciv21 and Freeciv contributors. This file is
3  part of Freeciv21. Freeciv21 is free software: you can redistribute it
4  and/or modify it under the terms of the GNU General Public License as
5  published by the Free Software Foundation, either version 3 of the
6  License, or (at your option) any later version. You should have received
7  a copy of the GNU General Public License along with Freeciv21. If not,
8  see https://www.gnu.org/licenses/.
9  */
10 
11 #include "messagewin.h"
12 
13 // Qt
14 #include <QApplication>
15 #include <QGridLayout>
16 #include <QHeaderView>
17 #include <QListWidget>
18 #include <QMouseEvent>
19 #include <QPainter>
20 #include <QPushButton>
21 
22 // client
23 #include "client_main.h"
24 #include "fc_client.h"
25 #include "messagewin_common.h"
26 #include "page_game.h"
27 #include "tileset/sprite.h"
28 #include "update_queue.h"
29 #include "views/view_map.h"
30 
35 {
36  setParent(parent);
37  setMinimumSize(200, 100);
38  layout = new QGridLayout;
39  layout->setContentsMargins(2, 2, 2, 2);
40  setLayout(layout);
41  setResizable(Qt::LeftEdge | Qt::BottomEdge);
42 
43  auto title = new QLabel(_("Messages"));
44  title->setAlignment(Qt::AlignCenter);
45  title->setMouseTracking(true);
46  layout->addWidget(title, 0, 1);
47  layout->setColumnStretch(1, 100);
48 
49  mesg_table = new QListWidget;
50  mesg_table->setEditTriggers(QAbstractItemView::NoEditTriggers);
51  mesg_table->setSelectionMode(QAbstractItemView::SingleSelection);
52  mesg_table->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
53  mesg_table->setTextElideMode(Qt::ElideNone);
54  mesg_table->setWordWrap(true);
55  layout->addWidget(mesg_table, 1, 0, 1, 3);
56 
57  connect(mesg_table->selectionModel(),
58  &QItemSelectionModel::selectionChanged, this,
60  setMouseTracking(true);
61 }
62 
66 void message_widget::item_selected(const QItemSelection &sl,
67  const QItemSelection &ds)
68 {
69  const struct message *pmsg;
70  int i, j;
71  QFont f;
72  QModelIndex index;
73  QModelIndexList indexes = sl.indexes();
74  QListWidgetItem *item;
75 
76  if (indexes.isEmpty()) {
77  return;
78  }
79  index = indexes.at(0);
80  i = index.row();
81  pmsg = meswin_get_message(i);
82  if (i > -1 && pmsg != nullptr) {
83  if (QApplication::mouseButtons() == Qt::LeftButton
84  || QApplication::mouseButtons() == Qt::RightButton) {
85  meswin_set_visited_state(i, true);
86  item = mesg_table->item(i);
87  f = item->font();
88  f.setItalic(true);
89  item->setFont(f);
90  }
91  if (QApplication::mouseButtons() == Qt::LeftButton
92  && pmsg->location_ok) {
93  meswin_goto(i);
94  }
95  if (QApplication::mouseButtons() == Qt::RightButton && pmsg->city_ok) {
97  }
98  if (QApplication::mouseButtons() == Qt::RightButton
99  && pmsg->event == E_DIPLOMACY) {
100  j = queen()->gimmeIndexOf(QStringLiteral("DDI"));
101  queen()->game_tab_widget->setCurrentIndex(j);
102  }
103  }
104  mesg_table->clearSelection();
105 }
106 
111 {
112  setCursor(Qt::ArrowCursor);
113 }
114 
119 {
120  setCursor(Qt::ArrowCursor);
121 }
122 
127 {
128  QStyleOption opt;
129  opt.init(this);
130  QPainter p(this);
131  style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
132 }
133 
137 void message_widget::clr() { mesg_table->clear(); }
138 
142 void message_widget::msg(const struct message *pmsg)
143 {
144  auto item = new QListWidgetItem;
145  item->setText(pmsg->descr);
146  mesg_table->addItem(item);
147  if (pmsg->visited) {
148  auto f = item->font();
149  f.setItalic(true);
150  item->setFont(f);
151  }
152  auto icon = get_event_sprite(tileset, pmsg->event);
153  if (icon != nullptr) {
154  item->setIcon(QIcon(*icon));
155  }
156  emit add_msg();
157 }
158 
163 {
164  const auto num = meswin_get_num_messages();
165  if (num < mesg_table->count()) {
166  // Fewer messages than before... no way to know which were removed, clear
167  // all and start from scratch.
168  mesg_table->clear();
169  }
170  for (int i = mesg_table->count(); i < num; i++) {
172  }
173 
174  // Scroll down to make sure the latest message is visible.
175  if (client.conn.client.request_id_of_currently_handled_packet == 0) {
176  mesg_table->scrollToBottom();
177  } else {
178  // Scroll only once to avoid laying out text repeately.
180  client.conn.client.request_id_of_currently_handled_packet,
181  scroll_to_bottom, (void *) this);
182  }
183 }
184 
185 /*
186  * Callback used to makes sure that the lastest message is visible.
187  */
189 {
190  static_cast<message_widget *>(self)->mesg_table->scrollToBottom();
191 }
192 
196 void real_meswin_dialog_update(void *unused)
197 {
198  if (queen()->message == nullptr) {
199  return;
200  }
201  queen()->message->msg_update();
202 }
QGridLayout * layout
Definition: messagewin.h:43
void msg(const struct message *pmsg)
Adds news message to mesg_table.
Definition: messagewin.cpp:142
void paintEvent(QPaintEvent *event) override
Paint event for message_widget.
Definition: messagewin.cpp:126
static void scroll_to_bottom(void *)
Definition: messagewin.cpp:188
message_widget(QWidget *parent)
message_widget constructor
Definition: messagewin.cpp:34
QListWidget * mesg_table
Definition: messagewin.h:42
void item_selected(const QItemSelection &sl, const QItemSelection &ds)
Slot executed when selection on meg_table has changed.
Definition: messagewin.cpp:66
void msg_update()
Updates mesg_table painting.
Definition: messagewin.cpp:162
void leaveEvent(QEvent *event) override
Mouse left message_widget.
Definition: messagewin.cpp:118
void clr()
Clears and removes mesg_table all items.
Definition: messagewin.cpp:137
void enterEvent(QEvent *event) override
Mouse entered message_widget.
Definition: messagewin.cpp:110
int gimmeIndexOf(const QString &str)
Returns index on game tab page of given report dialog.
Definition: page_game.cpp:706
message_widget * message
Definition: page_game.h:78
fc_game_tab_widget * game_tab_widget
Definition: page_game.h:72
void setResizable(Qt::Edges edges)
Set resizable flags.
static update_queue * uq()
void connect_processing_finished_unique(int request_id, uq_callback_t cb, void *data)
Connects the callback to the end of the processing (in server side) of the request.
struct civclient client
enum event_type event
Definition: events.cpp:68
#define _(String)
Definition: fcintl.h:50
void real_meswin_dialog_update(void *unused)
Do the work of updating (populating) the message dialog.
Definition: messagewin.cpp:196
void meswin_popup_city(int message_index)
Called from messagewin.c if the user clicks on the popup-city button.
void meswin_goto(int message_index)
Called from messagewin.c if the user clicks on the goto button.
int meswin_get_num_messages()
Returns the number of message in the window.
const struct message * meswin_get_message(int message_index)
Returns the pointer to a message.
void meswin_set_visited_state(int message_index, bool state)
Sets the visited-state of a message.
pageGame * queen()
Return game instandce.
Definition: page_game.cpp:557
struct connection conn
Definition: client_main.h:89
struct connection::@55::@60 client
Definition: climisc.h:66
char * descr
enum event_type event
bool location_ok
const QPixmap * get_event_sprite(const struct tileset *t, enum event_type event)
Return event icon sprite.
Definition: tilespec.cpp:3469