mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-23 18:06:26 -07:00
Compare commits
5 commits
6c8fcf7d19
...
b2cdf44bbd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b2cdf44bbd | ||
|
|
60ee81cfbe | ||
|
|
3de7882f0c | ||
|
|
fe53f9c3eb | ||
|
|
f466a25893 |
13 changed files with 139 additions and 16 deletions
|
|
@ -14,6 +14,8 @@
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
#include <QUrl>
|
||||||
|
#include <QUrlQuery>
|
||||||
#include <libcockatrice/card/database/card_database_manager.h>
|
#include <libcockatrice/card/database/card_database_manager.h>
|
||||||
#include <libcockatrice/network/server/remote/user_level.h>
|
#include <libcockatrice/network/server/remote/user_level.h>
|
||||||
#include <libcockatrice/settings/chat_settings.h>
|
#include <libcockatrice/settings/chat_settings.h>
|
||||||
|
|
@ -49,7 +51,7 @@ ChatView::ChatView(TabSupervisor *_tabSupervisor, AbstractGame *_game, bool _sho
|
||||||
|
|
||||||
viewport()->setCursor(Qt::IBeamCursor);
|
viewport()->setCursor(Qt::IBeamCursor);
|
||||||
setReadOnly(true);
|
setReadOnly(true);
|
||||||
setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse);
|
setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard);
|
||||||
setOpenLinks(false);
|
setOpenLinks(false);
|
||||||
connect(this, &ChatView::anchorClicked, this, &ChatView::openLink);
|
connect(this, &ChatView::anchorClicked, this, &ChatView::openLink);
|
||||||
|
|
||||||
|
|
@ -219,6 +221,46 @@ void ChatView::appendUrlTag(QTextCursor &cursor, QString url)
|
||||||
cursor.setCharFormat(oldFormat);
|
cursor.setCharFormat(oldFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChatView::appendGameLinkTag(QTextCursor &cursor, const QString &url)
|
||||||
|
{
|
||||||
|
const QUrl gameUrl(url);
|
||||||
|
const QUrlQuery query(gameUrl);
|
||||||
|
const QString hostname = query.queryItemValue("hostname");
|
||||||
|
// FullyDecoded undoes every %XX escape, so a description that itself
|
||||||
|
// contains "%" cannot end up displayed as "%25" in the label.
|
||||||
|
const QString description = query.queryItemValue("game", QUrl::FullyDecoded);
|
||||||
|
const int gameId = query.queryItemValue("gameid").toInt();
|
||||||
|
|
||||||
|
QString label;
|
||||||
|
if (gameId > 0 && !hostname.isEmpty()) {
|
||||||
|
// Links built before the description was embedded stay readable: the
|
||||||
|
// id + server fallback below is identical to the old anchor text.
|
||||||
|
if (!description.isEmpty()) {
|
||||||
|
// Multi-arg .arg() replaces all placeholders in a single pass, so a
|
||||||
|
// description containing "%…" cannot corrupt later placeholders.
|
||||||
|
label = tr("Join game \"%1\" (#%2) on %3").arg(description, QString::number(gameId), hostname);
|
||||||
|
} else {
|
||||||
|
label = tr("Join game #%1 on %2").arg(QString::number(gameId), hostname);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
label = tr("Join game");
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextCharFormat oldFormat = cursor.charFormat();
|
||||||
|
QTextCharFormat gameLinkFormat = oldFormat;
|
||||||
|
gameLinkFormat.setForeground(linkColor);
|
||||||
|
gameLinkFormat.setFontWeight(QFont::Bold);
|
||||||
|
gameLinkFormat.setAnchor(true);
|
||||||
|
gameLinkFormat.setAnchorHref(url);
|
||||||
|
QColor background = palette().highlight().color();
|
||||||
|
background.setAlpha(40);
|
||||||
|
gameLinkFormat.setBackground(background);
|
||||||
|
|
||||||
|
cursor.setCharFormat(gameLinkFormat);
|
||||||
|
cursor.insertText(label);
|
||||||
|
cursor.setCharFormat(oldFormat);
|
||||||
|
}
|
||||||
|
|
||||||
void ChatView::appendMessage(QString message,
|
void ChatView::appendMessage(QString message,
|
||||||
RoomMessageTypeFlags messageType,
|
RoomMessageTypeFlags messageType,
|
||||||
const ServerInfo_User &userInfo,
|
const ServerInfo_User &userInfo,
|
||||||
|
|
@ -503,6 +545,17 @@ void ChatView::checkWord(QTextCursor &cursor, QString &message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fullWordUpToSpaceOrEnd.startsWith("cockatrice://", Qt::CaseInsensitive)) {
|
||||||
|
// Only links to a game (cockatrice://joingame) become invite buttons;
|
||||||
|
// any other cockatrice:// scheme falls through to plain text below.
|
||||||
|
const QUrl gameLink(fullWordUpToSpaceOrEnd);
|
||||||
|
if (gameLink.host().compare("joingame", Qt::CaseInsensitive) == 0) {
|
||||||
|
appendGameLinkTag(cursor, fullWordUpToSpaceOrEnd);
|
||||||
|
cursor.insertText(rest, defaultFormat);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check word mentions
|
// check word mentions
|
||||||
for (const QString &word : highlightedWords) {
|
for (const QString &word : highlightedWords) {
|
||||||
if (fullWordUpToSpaceOrEnd.compare(word, Qt::CaseInsensitive) == 0) {
|
if (fullWordUpToSpaceOrEnd.compare(word, Qt::CaseInsensitive) == 0) {
|
||||||
|
|
@ -724,6 +777,11 @@ void ChatView::mouseReleaseEvent(QMouseEvent *event)
|
||||||
|
|
||||||
void ChatView::openLink(const QUrl &link)
|
void ChatView::openLink(const QUrl &link)
|
||||||
{
|
{
|
||||||
|
if (link.scheme() == "cockatrice") {
|
||||||
|
emit cockatriceLinkActivated(link.toString(QUrl::FullyEncoded));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ((link.scheme() == "card") || (link.scheme() == "user")) {
|
if ((link.scheme() == "card") || (link.scheme() == "user")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@ private:
|
||||||
void scrollToBottom();
|
void scrollToBottom();
|
||||||
void appendCardTag(QTextCursor &cursor, const QString &cardName);
|
void appendCardTag(QTextCursor &cursor, const QString &cardName);
|
||||||
void appendUrlTag(QTextCursor &cursor, QString url);
|
void appendUrlTag(QTextCursor &cursor, QString url);
|
||||||
|
void appendGameLinkTag(QTextCursor &cursor, const QString &url);
|
||||||
static QColor getCustomMentionColor();
|
static QColor getCustomMentionColor();
|
||||||
static QColor getCustomHighlightColor();
|
static QColor getCustomHighlightColor();
|
||||||
void showSystemPopup(const QString &userName);
|
void showSystemPopup(const QString &userName);
|
||||||
|
|
@ -121,6 +122,7 @@ signals:
|
||||||
void addMentionTag(QString mentionTag);
|
void addMentionTag(QString mentionTag);
|
||||||
void messageClickedSignal();
|
void messageClickedSignal();
|
||||||
void showMentionPopup(const QString &userName);
|
void showMentionPopup(const QString &userName);
|
||||||
|
void cockatriceLinkActivated(const QString &url);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -336,11 +336,12 @@ constexpr int UserInfo = Qt::UserRole + 2;
|
||||||
// rows (UserListTWI, which uses QTreeWidgetItem::Type) by this item type.
|
// rows (UserListTWI, which uses QTreeWidgetItem::Type) by this item type.
|
||||||
constexpr int SectionItemType = QTreeWidgetItem::UserType + 1;
|
constexpr int SectionItemType = QTreeWidgetItem::UserType + 1;
|
||||||
|
|
||||||
UserListItemDelegate::UserListItemDelegate(QTreeWidget *tree,
|
UserListItemDelegate::UserListItemDelegate(UserListWidget *owner,
|
||||||
|
QTreeWidget *tree,
|
||||||
const QMap<QString, QPixmap> *avatarCache,
|
const QMap<QString, QPixmap> *avatarCache,
|
||||||
const QMap<QString, QPixmap> *cardArtCache,
|
const QMap<QString, QPixmap> *cardArtCache,
|
||||||
const QMap<QString, CardArtParams> *cardArtParamsMap)
|
const QMap<QString, CardArtParams> *cardArtParamsMap)
|
||||||
: QStyledItemDelegate(tree), tree(tree), avatarCache(avatarCache), cardArtCache(cardArtCache),
|
: QStyledItemDelegate(tree), tree(tree), owner(owner), avatarCache(avatarCache), cardArtCache(cardArtCache),
|
||||||
cardArtParamsMap(cardArtParamsMap)
|
cardArtParamsMap(cardArtParamsMap)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -353,7 +354,7 @@ bool UserListItemDelegate::editorEvent(QEvent *event,
|
||||||
if ((event->type() == QEvent::MouseButtonPress) && index.isValid()) {
|
if ((event->type() == QEvent::MouseButtonPress) && index.isValid()) {
|
||||||
QMouseEvent *const mouseEvent = static_cast<QMouseEvent *>(event);
|
QMouseEvent *const mouseEvent = static_cast<QMouseEvent *>(event);
|
||||||
if (mouseEvent->button() == Qt::RightButton) {
|
if (mouseEvent->button() == Qt::RightButton) {
|
||||||
static_cast<UserListWidget *>(parent())->showContextMenu(mouseEvent->globalPosition().toPoint(), index);
|
owner->showContextMenu(mouseEvent->globalPosition().toPoint(), index);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -593,8 +594,8 @@ UserListWidget::UserListWidget(TabSupervisor *_tabSupervisor,
|
||||||
userTree->setHeaderHidden(true);
|
userTree->setHeaderHidden(true);
|
||||||
userTree->setRootIsDecorated(false);
|
userTree->setRootIsDecorated(false);
|
||||||
userTree->setIconSize(QSize(20, 18));
|
userTree->setIconSize(QSize(20, 18));
|
||||||
itemDelegate =
|
itemDelegate = new UserListItemDelegate(this, userTree, &avatarProvider->cache(), &cardArtProvider->cache(),
|
||||||
new UserListItemDelegate(userTree, &avatarProvider->cache(), &cardArtProvider->cache(), &cardArtParamsMap);
|
&cardArtParamsMap);
|
||||||
userTree->setItemDelegate(itemDelegate);
|
userTree->setItemDelegate(itemDelegate);
|
||||||
userTree->setAlternatingRowColors(true);
|
userTree->setAlternatingRowColors(true);
|
||||||
userTree->hideColumn(1);
|
userTree->hideColumn(1);
|
||||||
|
|
@ -1638,15 +1639,27 @@ void UserListWidget::updateSectionDivider(Section section)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int visible = 0;
|
int visible = 0;
|
||||||
|
int online = 0;
|
||||||
for (int i = 0; i < divider->childCount(); ++i) {
|
for (int i = 0; i < divider->childCount(); ++i) {
|
||||||
if (!divider->child(i)->isHidden()) {
|
QTreeWidgetItem *child = divider->child(i);
|
||||||
|
if (!child->isHidden()) {
|
||||||
++visible;
|
++visible;
|
||||||
|
if (child->data(0, UserListRoles::Online).toBool()) {
|
||||||
|
++online;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// The tree draws no branches (rows are flush), so the divider carries its
|
// The tree draws no branches (rows are flush), so the divider carries its
|
||||||
// own collapse arrow glyph.
|
// own collapse arrow glyph.
|
||||||
const QString arrow = divider->isExpanded() ? QStringLiteral("\u25BE") : QStringLiteral("\u25B8");
|
const QString arrow = divider->isExpanded() ? QStringLiteral("\u25BE") : QStringLiteral("\u25B8");
|
||||||
divider->setText(0, tr("%1 %2 (%3)").arg(arrow, sectionTitle(section)).arg(visible));
|
if (section == Section::Buddy) {
|
||||||
|
// The buddy divider reports how many of the shown buddies are online,
|
||||||
|
// mirroring the "Buddies online: %1 / %2" title of the non-sectioned
|
||||||
|
// buddy list.
|
||||||
|
divider->setText(0, tr("%1 %2 (%3/%4)").arg(arrow, sectionTitle(section)).arg(online).arg(visible));
|
||||||
|
} else {
|
||||||
|
divider->setText(0, tr("%1 %2 (%3)").arg(arrow, sectionTitle(section)).arg(visible));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserListWidget::handleSectionExpansion(QTreeWidgetItem *item, bool expanded)
|
void UserListWidget::handleSectionExpansion(QTreeWidgetItem *item, bool expanded)
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ class QPlainTextEdit;
|
||||||
class Response;
|
class Response;
|
||||||
class CommandContainer;
|
class CommandContainer;
|
||||||
class UserContextMenu;
|
class UserContextMenu;
|
||||||
|
class UserListWidget;
|
||||||
class QShowEvent;
|
class QShowEvent;
|
||||||
|
|
||||||
class BanDialog : public QDialog
|
class BanDialog : public QDialog
|
||||||
|
|
@ -105,12 +106,14 @@ public:
|
||||||
class UserListItemDelegate : public QStyledItemDelegate
|
class UserListItemDelegate : public QStyledItemDelegate
|
||||||
{
|
{
|
||||||
QTreeWidget *tree;
|
QTreeWidget *tree;
|
||||||
|
UserListWidget *owner;
|
||||||
const QMap<QString, QPixmap> *avatarCache;
|
const QMap<QString, QPixmap> *avatarCache;
|
||||||
const QMap<QString, QPixmap> *cardArtCache;
|
const QMap<QString, QPixmap> *cardArtCache;
|
||||||
const QMap<QString, CardArtParams> *cardArtParamsMap;
|
const QMap<QString, CardArtParams> *cardArtParamsMap;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit UserListItemDelegate(QTreeWidget *tree,
|
explicit UserListItemDelegate(UserListWidget *owner,
|
||||||
|
QTreeWidget *tree,
|
||||||
const QMap<QString, QPixmap> *avatarCache,
|
const QMap<QString, QPixmap> *avatarCache,
|
||||||
const QMap<QString, QPixmap> *cardArtCache,
|
const QMap<QString, QPixmap> *cardArtCache,
|
||||||
const QMap<QString, CardArtParams> *cardArtParamsMap);
|
const QMap<QString, CardArtParams> *cardArtParamsMap);
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ class Tab : public QMainWindow
|
||||||
signals:
|
signals:
|
||||||
void userEvent(bool globalEvent = true);
|
void userEvent(bool globalEvent = true);
|
||||||
void tabTextChanged(Tab *tab, const QString &newTabText);
|
void tabTextChanged(Tab *tab, const QString &newTabText);
|
||||||
|
void cockatriceLinkActivated(const QString &url);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TabSupervisor *tabSupervisor;
|
TabSupervisor *tabSupervisor;
|
||||||
|
|
|
||||||
|
|
@ -1292,6 +1292,7 @@ void TabGame::createMessageDock(bool bReplay)
|
||||||
qOverload<const QString &>(&CardInfoFrameWidget::setCard));
|
qOverload<const QString &>(&CardInfoFrameWidget::setCard));
|
||||||
connect(messageLog, &MessageLogWidget::showCardInfoPopup, this, &TabGame::showCardInfoPopup);
|
connect(messageLog, &MessageLogWidget::showCardInfoPopup, this, &TabGame::showCardInfoPopup);
|
||||||
connect(messageLog, &MessageLogWidget::deleteCardInfoPopup, this, &TabGame::deleteCardInfoPopup);
|
connect(messageLog, &MessageLogWidget::deleteCardInfoPopup, this, &TabGame::deleteCardInfoPopup);
|
||||||
|
connect(messageLog, &MessageLogWidget::cockatriceLinkActivated, this, &TabGame::cockatriceLinkActivated);
|
||||||
|
|
||||||
if (!bReplay) {
|
if (!bReplay) {
|
||||||
connect(messageLog, &MessageLogWidget::openMessageDialog, this, &TabGame::openMessageDialog);
|
connect(messageLog, &MessageLogWidget::openMessageDialog, this, &TabGame::openMessageDialog);
|
||||||
|
|
|
||||||
|
|
@ -23,14 +23,16 @@
|
||||||
TabMessage::TabMessage(TabSupervisor *_tabSupervisor,
|
TabMessage::TabMessage(TabSupervisor *_tabSupervisor,
|
||||||
AbstractClient *_client,
|
AbstractClient *_client,
|
||||||
const ServerInfo_User &_ownUserInfo,
|
const ServerInfo_User &_ownUserInfo,
|
||||||
const ServerInfo_User &_otherUserInfo)
|
const ServerInfo_User &_otherUserInfo,
|
||||||
|
bool _userOnline)
|
||||||
: Tab(_tabSupervisor), client(_client), ownUserInfo(new ServerInfo_User(_ownUserInfo)),
|
: Tab(_tabSupervisor), client(_client), ownUserInfo(new ServerInfo_User(_ownUserInfo)),
|
||||||
otherUserInfo(new ServerInfo_User(_otherUserInfo)), userOnline(true)
|
otherUserInfo(new ServerInfo_User(_otherUserInfo)), userOnline(_userOnline)
|
||||||
{
|
{
|
||||||
chatView = new ChatView(tabSupervisor, 0, true);
|
chatView = new ChatView(tabSupervisor, 0, true);
|
||||||
connect(chatView, &ChatView::showCardInfoPopup, this, &TabMessage::showCardInfoPopup);
|
connect(chatView, &ChatView::showCardInfoPopup, this, &TabMessage::showCardInfoPopup);
|
||||||
connect(chatView, &ChatView::deleteCardInfoPopup, this, &TabMessage::deleteCardInfoPopup);
|
connect(chatView, &ChatView::deleteCardInfoPopup, this, &TabMessage::deleteCardInfoPopup);
|
||||||
connect(chatView, &ChatView::addMentionTag, this, &TabMessage::addMentionTag);
|
connect(chatView, &ChatView::addMentionTag, this, &TabMessage::addMentionTag);
|
||||||
|
connect(chatView, &ChatView::cockatriceLinkActivated, this, &TabMessage::cockatriceLinkActivated);
|
||||||
sayEdit = new LineEditUnfocusable;
|
sayEdit = new LineEditUnfocusable;
|
||||||
sayEdit->setMaxLength(MAX_TEXT_LENGTH);
|
sayEdit->setMaxLength(MAX_TEXT_LENGTH);
|
||||||
connect(sayEdit, &LineEditUnfocusable::returnPressed, this, &TabMessage::sendMessage);
|
connect(sayEdit, &LineEditUnfocusable::returnPressed, this, &TabMessage::sendMessage);
|
||||||
|
|
@ -96,7 +98,14 @@ void TabMessage::closeEvent(QCloseEvent *event)
|
||||||
|
|
||||||
void TabMessage::sendMessage()
|
void TabMessage::sendMessage()
|
||||||
{
|
{
|
||||||
if (sayEdit->text().isEmpty() || !userOnline) {
|
if (sayEdit->text().isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!userOnline) {
|
||||||
|
// Keep the draft: the user may be back momentarily, and the typed text
|
||||||
|
// should not be lost to a transient offline spell.
|
||||||
|
notifyUserOffline();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -105,17 +114,27 @@ void TabMessage::sendMessage()
|
||||||
cmd.set_message(sayEdit->text().toStdString());
|
cmd.set_message(sayEdit->text().toStdString());
|
||||||
|
|
||||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||||
|
pend->setExtraData(sayEdit->text());
|
||||||
connect(pend, &PendingCommand::finished, this, &TabMessage::messageSent);
|
connect(pend, &PendingCommand::finished, this, &TabMessage::messageSent);
|
||||||
client->sendCommand(pend);
|
client->sendCommand(pend);
|
||||||
|
|
||||||
sayEdit->clear();
|
sayEdit->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabMessage::messageSent(const Response &response)
|
void TabMessage::messageSent(const Response &response,
|
||||||
|
const CommandContainer & /*commandContainer*/,
|
||||||
|
const QVariant &extraData)
|
||||||
{
|
{
|
||||||
if (response.response_code() == Response::RespInIgnoreList) {
|
if (response.response_code() == Response::RespInIgnoreList) {
|
||||||
chatView->appendMessage(tr(
|
chatView->appendMessage(tr(
|
||||||
"This user is ignoring you, they cannot see your messages in main chat and you cannot join their games."));
|
"This user is ignoring you, they cannot see your messages in main chat and you cannot join their games."));
|
||||||
|
} else if (response.response_code() == Response::RespNameNotFound) {
|
||||||
|
// The recipient went offline before the command reached the server: restore the draft.
|
||||||
|
userOnline = false;
|
||||||
|
if (sayEdit->text().isEmpty()) {
|
||||||
|
sayEdit->setText(extraData.toString());
|
||||||
|
}
|
||||||
|
notifyUserOffline();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -175,3 +194,8 @@ void TabMessage::processUserJoined(const ServerInfo_User &_userInfo)
|
||||||
userOnline = true;
|
userOnline = true;
|
||||||
*otherUserInfo = _userInfo;
|
*otherUserInfo = _userInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TabMessage::notifyUserOffline()
|
||||||
|
{
|
||||||
|
chatView->appendMessage(tr("Message not sent — %1 is offline.").arg(QString::fromStdString(otherUserInfo->name())));
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ class LineEditUnfocusable;
|
||||||
class Event_UserMessage;
|
class Event_UserMessage;
|
||||||
class Response;
|
class Response;
|
||||||
class ServerInfo_User;
|
class ServerInfo_User;
|
||||||
|
class CommandContainer;
|
||||||
|
|
||||||
class TabMessage : public Tab
|
class TabMessage : public Tab
|
||||||
{
|
{
|
||||||
|
|
@ -39,7 +40,7 @@ signals:
|
||||||
void maximizeClient();
|
void maximizeClient();
|
||||||
private slots:
|
private slots:
|
||||||
void sendMessage();
|
void sendMessage();
|
||||||
void messageSent(const Response &response);
|
void messageSent(const Response &response, const CommandContainer &commandContainer, const QVariant &extraData);
|
||||||
void addMentionTag(QString mentionTag);
|
void addMentionTag(QString mentionTag);
|
||||||
void messageClicked();
|
void messageClicked();
|
||||||
|
|
||||||
|
|
@ -50,7 +51,8 @@ public:
|
||||||
TabMessage(TabSupervisor *_tabSupervisor,
|
TabMessage(TabSupervisor *_tabSupervisor,
|
||||||
AbstractClient *_client,
|
AbstractClient *_client,
|
||||||
const ServerInfo_User &_ownUserInfo,
|
const ServerInfo_User &_ownUserInfo,
|
||||||
const ServerInfo_User &_otherUserInfo);
|
const ServerInfo_User &_otherUserInfo,
|
||||||
|
bool _userOnline);
|
||||||
~TabMessage() override;
|
~TabMessage() override;
|
||||||
void retranslateUi() override;
|
void retranslateUi() override;
|
||||||
void tabActivated() override;
|
void tabActivated() override;
|
||||||
|
|
@ -65,6 +67,7 @@ public:
|
||||||
private:
|
private:
|
||||||
bool shouldShowSystemPopup(const Event_UserMessage &event);
|
bool shouldShowSystemPopup(const Event_UserMessage &event);
|
||||||
void showSystemPopup(const Event_UserMessage &event);
|
void showSystemPopup(const Event_UserMessage &event);
|
||||||
|
void notifyUserOffline();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ TabRoom::TabRoom(TabSupervisor *_tabSupervisor,
|
||||||
connect(chatView, &ChatView::showMentionPopup, this, &TabRoom::actShowMentionPopup);
|
connect(chatView, &ChatView::showMentionPopup, this, &TabRoom::actShowMentionPopup);
|
||||||
connect(chatView, &ChatView::messageClickedSignal, this, &TabRoom::focusTab);
|
connect(chatView, &ChatView::messageClickedSignal, this, &TabRoom::focusTab);
|
||||||
connect(chatView, &ChatView::openMessageDialog, this, &TabRoom::openMessageDialog);
|
connect(chatView, &ChatView::openMessageDialog, this, &TabRoom::openMessageDialog);
|
||||||
|
connect(chatView, &ChatView::cockatriceLinkActivated, this, &TabRoom::cockatriceLinkActivated);
|
||||||
connect(chatView, &ChatView::showCardInfoPopup, this, &TabRoom::showCardInfoPopup);
|
connect(chatView, &ChatView::showCardInfoPopup, this, &TabRoom::showCardInfoPopup);
|
||||||
connect(chatView, &ChatView::deleteCardInfoPopup, this, &TabRoom::deleteCardInfoPopup);
|
connect(chatView, &ChatView::deleteCardInfoPopup, this, &TabRoom::deleteCardInfoPopup);
|
||||||
connect(chatView, &ChatView::addMentionTag, this, &TabRoom::addMentionTag);
|
connect(chatView, &ChatView::addMentionTag, this, &TabRoom::addMentionTag);
|
||||||
|
|
|
||||||
|
|
@ -406,6 +406,7 @@ int TabSupervisor::myAddTab(Tab *tab, QAction *manager)
|
||||||
{
|
{
|
||||||
connect(tab, &TabGame::userEvent, this, &TabSupervisor::tabUserEvent);
|
connect(tab, &TabGame::userEvent, this, &TabSupervisor::tabUserEvent);
|
||||||
connect(tab, &TabGame::tabTextChanged, this, &TabSupervisor::updateTabText);
|
connect(tab, &TabGame::tabTextChanged, this, &TabSupervisor::updateTabText);
|
||||||
|
connect(tab, &TabGame::cockatriceLinkActivated, this, &TabSupervisor::cockatriceLinkActivated);
|
||||||
|
|
||||||
QString tabText = tab->getTabText();
|
QString tabText = tab->getTabText();
|
||||||
int idx = addTab(tab, sanitizeTabName(tabText));
|
int idx = addTab(tab, sanitizeTabName(tabText));
|
||||||
|
|
@ -851,6 +852,7 @@ void TabSupervisor::addRoomTab(const ServerInfo_Room &info, bool setCurrent)
|
||||||
connect(tab, &TabRoom::maximizeClient, this, &TabSupervisor::maximizeMainWindow);
|
connect(tab, &TabRoom::maximizeClient, this, &TabSupervisor::maximizeMainWindow);
|
||||||
connect(tab, &TabRoom::roomClosing, this, &TabSupervisor::roomLeft);
|
connect(tab, &TabRoom::roomClosing, this, &TabSupervisor::roomLeft);
|
||||||
connect(tab, &TabRoom::openMessageDialog, this, &TabSupervisor::addMessageTab);
|
connect(tab, &TabRoom::openMessageDialog, this, &TabSupervisor::addMessageTab);
|
||||||
|
connect(tab, &TabRoom::cockatriceLinkActivated, this, &TabSupervisor::cockatriceLinkActivated);
|
||||||
myAddTab(tab);
|
myAddTab(tab);
|
||||||
roomTabs.insert(info.room_id(), tab);
|
roomTabs.insert(info.room_id(), tab);
|
||||||
if (setCurrent) {
|
if (setCurrent) {
|
||||||
|
|
@ -904,8 +906,10 @@ TabMessage *TabSupervisor::addMessageTab(const QString &receiverName, bool focus
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerInfo_User otherUser;
|
ServerInfo_User otherUser;
|
||||||
|
bool userOnline = false;
|
||||||
if (auto user = userListManager->getOnlineUser(receiverName)) {
|
if (auto user = userListManager->getOnlineUser(receiverName)) {
|
||||||
otherUser = ServerInfo_User(*user);
|
otherUser = ServerInfo_User(*user);
|
||||||
|
userOnline = true;
|
||||||
} else {
|
} else {
|
||||||
otherUser.set_name(receiverName.toStdString());
|
otherUser.set_name(receiverName.toStdString());
|
||||||
}
|
}
|
||||||
|
|
@ -919,9 +923,10 @@ TabMessage *TabSupervisor::addMessageTab(const QString &receiverName, bool focus
|
||||||
return tab;
|
return tab;
|
||||||
}
|
}
|
||||||
|
|
||||||
tab = new TabMessage(this, client, *userInfo, otherUser);
|
tab = new TabMessage(this, client, *userInfo, otherUser, userOnline);
|
||||||
connect(tab, &TabMessage::talkClosing, this, &TabSupervisor::talkLeft);
|
connect(tab, &TabMessage::talkClosing, this, &TabSupervisor::talkLeft);
|
||||||
connect(tab, &TabMessage::maximizeClient, this, &TabSupervisor::maximizeMainWindow);
|
connect(tab, &TabMessage::maximizeClient, this, &TabSupervisor::maximizeMainWindow);
|
||||||
|
connect(tab, &TabMessage::cockatriceLinkActivated, this, &TabSupervisor::cockatriceLinkActivated);
|
||||||
myAddTab(tab);
|
myAddTab(tab);
|
||||||
messageTabs.insert(receiverName, tab);
|
messageTabs.insert(receiverName, tab);
|
||||||
if (focus) {
|
if (focus) {
|
||||||
|
|
|
||||||
|
|
@ -169,6 +169,7 @@ signals:
|
||||||
void localGameEnded();
|
void localGameEnded();
|
||||||
void adminLockChanged(bool lock);
|
void adminLockChanged(bool lock);
|
||||||
void showWindowIfHidden();
|
void showWindowIfHidden();
|
||||||
|
void cockatriceLinkActivated(const QString &url);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void openDeckInNewTab(const LoadedDeck &deckToOpen);
|
void openDeckInNewTab(const LoadedDeck &deckToOpen);
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@
|
||||||
#include "intents/intent_connect_to_server.h"
|
#include "intents/intent_connect_to_server.h"
|
||||||
#include "intents/intent_login.h"
|
#include "intents/intent_login.h"
|
||||||
#include "intents/intent_open_server_room_by_name.h"
|
#include "intents/intent_open_server_room_by_name.h"
|
||||||
|
#include "intents/url_parser.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "version_string.h"
|
#include "version_string.h"
|
||||||
#include "widgets/dialogs/dlg_connect.h"
|
#include "widgets/dialogs/dlg_connect.h"
|
||||||
|
|
@ -497,6 +498,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
pixmapCacheSizeChanged(SettingsCache::instance().cacheStorage().getPixmapCacheSize());
|
pixmapCacheSizeChanged(SettingsCache::instance().cacheStorage().getPixmapCacheSize());
|
||||||
|
|
||||||
connectionController = new ConnectionController(this, this);
|
connectionController = new ConnectionController(this, this);
|
||||||
|
urlParser = new IntentUrlParser(this, this);
|
||||||
|
|
||||||
createActions();
|
createActions();
|
||||||
createMenus();
|
createMenus();
|
||||||
|
|
@ -508,6 +510,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
connect(tabSupervisor, &TabSupervisor::setMenu, this, &MainWindow::updateTabMenu);
|
connect(tabSupervisor, &TabSupervisor::setMenu, this, &MainWindow::updateTabMenu);
|
||||||
connect(tabSupervisor, &TabSupervisor::localGameEnded, this, &MainWindow::localGameEnded);
|
connect(tabSupervisor, &TabSupervisor::localGameEnded, this, &MainWindow::localGameEnded);
|
||||||
connect(tabSupervisor, &TabSupervisor::showWindowIfHidden, this, &MainWindow::showWindowIfHidden);
|
connect(tabSupervisor, &TabSupervisor::showWindowIfHidden, this, &MainWindow::showWindowIfHidden);
|
||||||
|
connect(tabSupervisor, &TabSupervisor::cockatriceLinkActivated, this, &MainWindow::handleCockatriceLink);
|
||||||
connect(connectionController, &ConnectionController::tabSupervisorStartRequested, tabSupervisor,
|
connect(connectionController, &ConnectionController::tabSupervisorStartRequested, tabSupervisor,
|
||||||
&TabSupervisor::start);
|
&TabSupervisor::start);
|
||||||
connect(connectionController, &ConnectionController::tabSupervisorStopRequested, tabSupervisor,
|
connect(connectionController, &ConnectionController::tabSupervisorStopRequested, tabSupervisor,
|
||||||
|
|
@ -861,6 +864,11 @@ void MainWindow::showWindowIfHidden()
|
||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::handleCockatriceLink(const QString &url)
|
||||||
|
{
|
||||||
|
urlParser->handle(url);
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::cardDatabaseLoadingFailed()
|
void MainWindow::cardDatabaseLoadingFailed()
|
||||||
{
|
{
|
||||||
if (askedForDbUpdater) {
|
if (askedForDbUpdater) {
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ class TabSupervisor;
|
||||||
class WndSets;
|
class WndSets;
|
||||||
class DlgTipOfTheDay;
|
class DlgTipOfTheDay;
|
||||||
struct ContextConnectToServer;
|
struct ContextConnectToServer;
|
||||||
|
class IntentUrlParser;
|
||||||
|
|
||||||
class MainWindow : public QMainWindow
|
class MainWindow : public QMainWindow
|
||||||
{
|
{
|
||||||
|
|
@ -84,6 +85,7 @@ private slots:
|
||||||
void actOpenSettingsFolder();
|
void actOpenSettingsFolder();
|
||||||
void actShow();
|
void actShow();
|
||||||
void showWindowIfHidden();
|
void showWindowIfHidden();
|
||||||
|
void handleCockatriceLink(const QString &url);
|
||||||
|
|
||||||
void cardUpdateError(QProcess::ProcessError err);
|
void cardUpdateError(QProcess::ProcessError err);
|
||||||
void cardUpdateFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
void cardUpdateFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||||
|
|
@ -139,6 +141,7 @@ private:
|
||||||
*aOpenSettingsFolder;
|
*aOpenSettingsFolder;
|
||||||
|
|
||||||
TabSupervisor *tabSupervisor;
|
TabSupervisor *tabSupervisor;
|
||||||
|
IntentUrlParser *urlParser;
|
||||||
WndSets *wndSets;
|
WndSets *wndSets;
|
||||||
ConnectionController *connectionController;
|
ConnectionController *connectionController;
|
||||||
LocalServer *localServer;
|
LocalServer *localServer;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue