14 #include <QActionGroup>
15 #include <QApplication>
18 #include <QGridLayout>
21 #include <QPushButton>
24 #include <QToolButton>
54 QHash<QString, QString> color_mapping;
76 const struct text_tag_list *)
96 if (
message.startsWith(QLatin1String(
"/take "))) {
97 s = s.remove(QStringLiteral(
"/take "));
100 splayer = QString(pplayer->name);
101 splayer =
"\"" + splayer +
"\"";
103 if (!splayer.compare(s)) {
104 if (
is_ai(pplayer)) {
150 return QLatin1String(
"");
155 return QLatin1String(
"");
189 QStringList word_list;
192 word_list << QStringLiteral(
"/start");
193 word_list << QStringLiteral(
"/help");
194 word_list << QStringLiteral(
"/list colors");
195 word_list << QStringLiteral(
"/list connections");
196 word_list << QStringLiteral(
"/list delegations");
197 word_list << QStringLiteral(
"/list ignored users");
198 word_list << QStringLiteral(
"/list map image definitions");
199 word_list << QStringLiteral(
"/list players");
200 word_list << QStringLiteral(
"/list rulesets");
201 word_list << QStringLiteral(
"/list scenarios");
202 word_list << QStringLiteral(
"/list nationsets");
203 word_list << QStringLiteral(
"/list teams");
204 word_list << QStringLiteral(
"/list votes");
205 word_list << QStringLiteral(
"/quit");
206 word_list <<
_(
"/cut <connection-name>");
207 word_list <<
_(
"/explain <option-name>");
208 word_list <<
_(
"/show <option-name>");
209 word_list << QStringLiteral(
"/show all");
210 word_list << QStringLiteral(
"/show vital");
211 word_list << QStringLiteral(
"/show situational");
212 word_list << QStringLiteral(
"/show rare");
213 word_list << QStringLiteral(
"/show changed");
214 word_list << QStringLiteral(
"/show locked");
215 word_list << QStringLiteral(
"/show rulesetdir");
216 word_list <<
_(
"/wall <message>");
217 word_list <<
_(
"/connectmsg <message>");
218 word_list <<
_(
"/vote yes|no|abstain [vote number]");
219 word_list <<
_(
"/debug diplomacy <player>");
220 word_list <<
_(
"/debug ferries");
221 word_list <<
_(
"/debug tech <player>");
222 word_list <<
_(
"/debug city <x> <y>");
223 word_list <<
_(
"/debug units <x> <y>");
224 word_list <<
_(
"/debug unit <id>");
225 word_list << QStringLiteral(
"/debug timing");
226 word_list << QStringLiteral(
"/debug info");
227 word_list <<
_(
"/set <option-name> <value>");
228 word_list <<
_(
"/team <player> <team>");
229 word_list <<
_(
"/rulesetdir <directory>");
230 word_list <<
_(
"/metamessage <meta-line>");
231 word_list <<
_(
"/metapatches <meta-line>");
232 word_list << QStringLiteral(
"/metaconnection up|down|?");
233 word_list <<
_(
"/metaserver <address>");
234 word_list <<
_(
"/aitoggle <player-name>");
235 word_list <<
_(
"/take <player-name>");
236 word_list <<
_(
"/observe <player-name>");
237 word_list <<
_(
"/detach <connection-name>");
238 word_list <<
_(
"/create <player-name> [ai type]");
239 word_list << QStringLiteral(
"/away");
240 word_list <<
_(
"/handicapped <player-name>");
241 word_list <<
_(
"/novice <player-name>");
242 word_list <<
_(
"/easy <player-name>");
243 word_list <<
_(
"/normal <player-name>");
244 word_list <<
_(
"/hard <player-name>");
245 word_list <<
_(
"/cheating <player-name>");
246 word_list <<
_(
"/experimental <player-name>");
247 word_list << QStringLiteral(
"/cmdlevel none|info|basic|ctrl|admin|hack");
248 word_list << QStringLiteral(
"/first");
249 word_list << QStringLiteral(
"/timeoutshow");
250 word_list <<
_(
"/timeoutset <time>");
251 word_list <<
_(
"/timeoutadd <time>");
252 word_list <<
_(
"/timeoutincrease <turn> <turninc> <value> <valuemult>");
253 word_list <<
_(
"/cancelvote <vote number>");
254 word_list <<
_(
"/ignore [type=]<pattern>");
255 word_list <<
_(
"/unignore <range>");
256 word_list <<
_(
"/playercolor <player-name> <color>");
257 word_list <<
_(
"/playernation <player-name> [nation] [is-male] [leader] "
259 word_list << QStringLiteral(
"/endgame");
260 word_list << QStringLiteral(
"/surrender");
261 word_list <<
_(
"/remove <player-name>");
262 word_list <<
_(
"/save <file-name>");
263 word_list <<
_(
"/scensave <file-name>");
264 word_list <<
_(
"/load <file-name>");
265 word_list <<
_(
"/read <file-name>");
266 word_list <<
_(
"/write <file-name>");
267 word_list << QStringLiteral(
"/reset game|ruleset|script|default");
268 word_list <<
_(
"/default <option name>");
269 word_list <<
_(
"/lua cmd <script line>");
270 word_list <<
_(
"/lua unsafe-cmd <script line>");
271 word_list <<
_(
"/lua file <script file>");
272 word_list <<
_(
"/lua unsafe-file <script file>");
273 word_list <<
_(
"/kick <user>");
274 word_list <<
_(
"/delegate to <username>");
275 word_list << QStringLiteral(
"/delegate cancel");
276 word_list <<
_(
"/delegate take <player-name>");
277 word_list << QStringLiteral(
"/delegate restore");
278 word_list <<
_(
"/delegate show <player-name>");
279 word_list <<
_(
"/aicmd <player> <command>");
280 word_list <<
_(
"/fcdb lua <script>");
281 word_list <<
_(
"/mapimg define <mapdef>");
282 word_list <<
_(
"/mapimg show <id>|all");
283 word_list <<
_(
"/mapimg create <id>|all");
284 word_list <<
_(
"/mapimg delete <id>|all");
285 word_list << QStringLiteral(
"/mapimg colortest");
286 word_list << QStringLiteral(
"/rfcstyle");
287 word_list << QStringLiteral(
"/serverid");
291 if (pconn->playing) {
292 word_list << pconn->playing->name;
293 word_list << pconn->playing->username;
295 word_list << pconn->username;
305 auto cmplt =
new QCompleter(word_list,
this);
306 cmplt->setCaseSensitivity(Qt::CaseInsensitive);
307 cmplt->setCompletionMode(QCompleter::InlineCompletion);
316 if (
event->type() == QEvent::KeyPress) {
317 QKeyEvent *keyEvent =
static_cast<QKeyEvent *
>(
event);
318 switch (keyEvent->key()) {
336 QLineEdit::focusInEvent(
event);
346 setMinimumSize(200, 100);
347 setResizable(Qt::LeftEdge | Qt::RightEdge | Qt::TopEdge | Qt::BottomEdge);
349 gl =
new QGridLayout;
350 gl->setVerticalSpacing(0);
351 gl->setContentsMargins(QMargins());
354 cb =
new QToolButton;
355 cb->setFixedSize(QSize(25, 25));
356 cb->setIconSize(QSize(24, 24));
357 cb->setToolTip(
_(
"Set who can see your messages by default."));
359 const auto current_icon = [] {
361 ? QStringLiteral(
"private")
362 : QStringLiteral(
"public"));
364 cb->setIcon(current_icon());
368 cb->setPopupMode(QToolButton::InstantPopup);
371 auto group =
new QActionGroup(
cb_menu);
375 action->setCheckable(
true);
377 connect(
action, &QAction::triggered,
cb, [=] {
379 cb->setIcon(current_icon());
385 action->setCheckable(
true);
387 connect(
action, &QAction::triggered,
cb, [=] {
389 cb->setIcon(current_icon());
425 auto title =
new QLabel(
_(
"Chat"));
426 title->setAlignment(Qt::AlignCenter);
427 title->setMouseTracking(
true);
429 gl->addWidget(
mw, 0, 0, Qt::AlignLeft | Qt::AlignTop);
430 gl->addWidget(title, 0, 1, 1, 2);
431 gl->setColumnStretch(1, 100);
435 gl->addWidget(
cb, 2, 2);
438 connect(
chat_output, &QTextBrowser::anchorClicked,
this,
442 connect(
show_hide, &QAbstractButton::toggled,
this,
444 setMouseTracking(
true);
467 auto geo = geometry();
470 setMinimumSize(200, 100);
474 setMinimumSize(200, 0);
483 int h = visible ? qRound(parentWidget()->
size().height()
484 *
king()->qt_settings.chat_fheight)
485 : sizeHint().height();
489 (y() > parentWidget()->height() - y() - (visible ? h : height()));
491 QString icon_name = (expand_up ^ visible) ? QLatin1String(
"expand-up")
492 : QLatin1String(
"expand-down");
496 geo.setTop(std::max(geo.bottom() - h, 0));
499 if (geo.bottom() > parentWidget()->height()) {
500 geo.translate(0, parentWidget()->height() - geo.bottom());
503 geo.setBottom(std::min(geo.top() + h, parentWidget()->height()));
516 chat_line->setFocus(Qt::ShortcutFocusReason);
541 sl = link.toString().split(QStringLiteral(
","));
542 n = sl.at(0).toInt();
543 id = sl.at(1).toInt();
546 struct tile *ptile =
nullptr;
562 _(
"This tile doesn't exist in this game!"));
587 const struct text_tag_list *tags)
589 QColor col =
chat_output->palette().color(QPalette::Text);
599 chat_output->verticalScrollBar()->setSliderPosition(
611 style()->drawPrimitive(QStyle::PE_Widget, &opt, &p,
this);
626 if (
event->type() == QEvent::KeyPress) {
627 QKeyEvent *keyEvent =
static_cast<QKeyEvent *
>(
event);
628 if (keyEvent->key() == Qt::Key_Escape) {
633 if (
event->type() == QEvent::ShortcutOverride) {
634 event->setAccepted(
true);
637 return QObject::eventFilter(obj,
event);
667 while (qtb.isValid()) {
668 line_count = line_count + qtb.layout()->lineCount();
672 if (line_count == 0) {
676 line_height = (
chat_output->document()->size().height()
710 QString
apply_tags(QString str,
const struct text_tag_list *tags,
713 if (tags ==
nullptr) {
718 const auto qba = str.toUtf8();
744 html_tags[start] += QStringLiteral(
"<b>");
748 html_tags[start] += QStringLiteral(
"<i>");
752 html_tags[start] += QStringLiteral(
"<s>");
756 html_tags[start] += QStringLiteral(
"<u>");
763 if (color_mapping.find(color) != color_mapping.end()) {
764 color = color_mapping[color];
766 if (QColor::isValidColor(color)) {
767 style += QStringLiteral(
"color:%1;").arg(color);
772 if (color_mapping.find(color) != color_mapping.end()) {
773 color = color_mapping[color];
775 if (QColor::isValidColor(color)) {
776 style += QStringLiteral(
"background-color:%1;").arg(color);
779 html_tags[start] += QStringLiteral(
"<span style=\"%1\">").arg(style);
800 const auto color = pcolor.name(QColor::HexRgb);
801 html_tags[start] += QStringLiteral(
"<font color=\"%1\">").arg(color);
802 html_tags[start] += QString(
"<a href=%1,%2>")
806 html_tags[stop].prepend(QStringLiteral(
"</a></font>"));
815 auto html = QStringLiteral();
816 int last_position = 0;
817 for (
auto &[position, tags_to_insert] :
html_tags) {
818 html += QString(qba.mid(last_position, position - last_position))
820 html += tags_to_insert;
821 last_position = position;
823 html += QString(qba.mid(last_position)).toHtmlEscaped();
853 s1 = pconn->username;
854 if (s1.length() < i) {
857 if (!QString::compare(s1.left(i), str, Qt::CaseInsensitive)) {
865 if (s1.length() < i) {
868 if (!QString::compare(s1.left(i), str, Qt::CaseInsensitive)) {
882 const text_tag_list *tags)
887 qApp->alert(
king()->central_wdg);
#define CHAT_DIRECT_PREFIX
#define CHAT_ALLIES_PREFIX
#define SERVER_COMMAND_PREFIX
void real_output_window_append(const QString &astring, const text_tag_list *tags)
Appends the string to the chat output window.
void version_message(const QString &vertext)
Got version message from metaserver.
void set_chat_colors(const QHash< QString, QString > &colors)
Sets color substitution map.
static bool is_plain_public_message(const QString &s)
Copyright (c) 1996-2023 Freeciv21 and Freeciv contributors.
QString apply_tags(QString str, const struct text_tag_list *tags, QColor bg_color)
Applies tags to text.
int send_chat(const char *message)
Send the message as a chat to the server.
void output_window_append(const struct ft_color color, const char *featured_text)
Add a line of text to the output ("chatline") window, like puts() would do it in the console.
struct tag_types html_tags
static const int HISTORY_END
QString forward_in_history()
Goes forward one position in history, and returns the message at the new position.
void send_chat_message(const QString &message)
Sends commands to server, but first searches for custom keys, if it finds then it makes custom action...
void reset_history_position()
Go to the end of the history.
QString back_in_history()
Goes back one position in history, and returns the message at the new position.
static QStringList history
chat_listener()
Constructor.
virtual void chat_message_received(const QString &, const struct text_tag_list *)
Called whenever a message is received.
static fcFont * instance()
Returns instance of fc_font.
QIcon getIcon(const QString &id)
Returns icon by given name.
static fcIcons * instance()
Returns instance of fc_icons.
void set_status_bar(const QString &str, int timeout=20000)
Sets application status bar for given time in miliseconds.
static void invoke(_member_fct_ function, _args_ &&...args)
void center_on_tile(tile *tile, bool animate=true)
Centers the view on a tile.
void mouseDoubleClickEvent(QMouseEvent *event) override
enum client_states client_state()
Return current client state.
struct tile * client_city_tile(const struct city *pcity)
Client variant of city_tile().
QColor get_color(const struct tileset *t, enum color_std stdcolor)
Return a pointer to the given "standard" color.
bool is_server_running()
The general chain of events:
#define conn_list_iterate(connlist, pconn)
#define conn_list_iterate_end
unit * find_visible_unit(const ::tile *ptile)
Return a pointer to a visible unit, if there is one.
class fc_client * king()
Return fc_client instance.
enum text_link_type text_tag_link_type(const struct text_tag *ptag)
Return the link target type suggested by this text tag.
const char * tile_link(const struct tile *ptile)
Get a text link to a tile.
QString text_tag_color_background(const struct text_tag *ptag)
Return the background color suggested by this text tag.
QString text_tag_color_foreground(const struct text_tag *ptag)
Return the foreground color suggested by this text tag.
ft_offset_t text_tag_stop_offset(const struct text_tag *ptag)
Return the stop offset (in bytes) of this text tag.
const struct ft_color ftc_client
const char * city_link(const struct city *pcity)
Get a text link to a city.
int text_tag_link_id(const struct text_tag *ptag)
Return the link target id suggested by this text tag (city id, tile index or unit id).
ft_offset_t text_tag_start_offset(const struct text_tag *ptag)
Return the start offset (in bytes) of this text tag.
const char * unit_link(const struct unit *punit)
Get a text link to an unit.
#define text_tag_list_iterate_end
#define text_tag_list_iterate(tags, ptag)
struct unit * game_unit_by_number(int id)
Find unit out of all units in game: now uses fast idex method, instead of looking through all units o...
struct city * game_city_by_number(int id)
Often used function to get a city pointer from a city ID.
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Return the tile for the given index position.
const char *const chatline
client_options * gui_options
pageGame * queen()
Return game instandce.
#define players_iterate_end
#define players_iterate(_pplayer)
struct conn_list * est_connections
struct conn_list * all_connections
bool gui_qt_allied_chat_only
char username[MAX_LEN_NAME]
struct city * tile_city(const struct tile *ptile)
Return the city on this tile (or nullptr), checking for city center.
void link_mark_restore(enum text_link_type type, int id)
Add a visible link for 1 turn.
void link_marks_clear_all()
Clear all visible links.