mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-13 05:20:00 -08:00
The games list in the profile hover card offered "Join game" and "Spectate", but UserInfoPopup::joinGameRequested was only forwarded to an identical UserListWidget::joinGameRequested signal that nothing connected to. Clicking either entry sent no command, opened no tab and showed no error. Route the request to TabSupervisor, which owns the join flow. The popup's games list spans every room the user is in, so the target room may not be open yet; IntentJoinServerGame already joins the room first and retries, which is why this goes through the intent rather than straight to GameSelector. Extract the intent construction that joinReportGame already had into a shared joinGameByIntent helper instead of duplicating it. Also stop disabling "Join game" for games that are full or already running. GameSelector::joinGame() offers to join as a spectator in that case, so a greyed-out entry read as a dead button; GameSelector's own context menu never disables it either. Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
260 lines
8.2 KiB
C++
260 lines
8.2 KiB
C++
/**
|
|
* @file tab_supervisor.h
|
|
* @ingroup Core
|
|
* @ingroup Tabs
|
|
*/
|
|
//! \todo Document this file.
|
|
|
|
#ifndef TAB_SUPERVISOR_H
|
|
#define TAB_SUPERVISOR_H
|
|
|
|
#include "../../deck_loader/deck_loader.h"
|
|
#include "../interface/widgets/server/game_link.h"
|
|
#include "../interface/widgets/server/user/user_list_proxy.h"
|
|
#include "abstract_tab_deck_editor.h"
|
|
#include "api/archidekt/tab_archidekt.h"
|
|
#include "api/edhrec/tab_edhrec.h"
|
|
#include "api/edhrec/tab_edhrec_main.h"
|
|
#include "tab_visual_database_display.h"
|
|
#include "visual_deck_editor/tab_deck_editor_visual.h"
|
|
#include "visual_deck_storage/tab_deck_storage_visual.h"
|
|
|
|
#include <QAbstractButton>
|
|
#include <QLoggingCategory>
|
|
#include <QMap>
|
|
#include <QProxyStyle>
|
|
#include <QTabWidget>
|
|
#include <libcockatrice/network/client/abstract/latency_tracker.h>
|
|
|
|
class TabCardArtRules;
|
|
inline Q_LOGGING_CATEGORY(TabSupervisorLog, "tab_supervisor");
|
|
|
|
class UserListManager;
|
|
class QMenu;
|
|
class AbstractClient;
|
|
class Tab;
|
|
class TabServer;
|
|
class TabRoom;
|
|
class TabHome;
|
|
class TabGame;
|
|
class TabDeckStorage;
|
|
class TabReplays;
|
|
class TabAdmin;
|
|
class TabMessage;
|
|
class TabReport;
|
|
class TabModeration;
|
|
class TabAccount;
|
|
class TabDeckEditor;
|
|
class TabDeveloper;
|
|
class TabLog;
|
|
class TabPublicDecks;
|
|
class RoomEvent;
|
|
class GameEventContainer;
|
|
class Event_GameJoined;
|
|
class Event_UserMessage;
|
|
class Event_NotifyUser;
|
|
class ServerInfo_Room;
|
|
class ServerInfo_User;
|
|
class GameReplay;
|
|
class DeckList;
|
|
|
|
class MacOSTabFixStyle : public QProxyStyle
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
QRect subElementRect(SubElement, const QStyleOption *, const QWidget *) const override;
|
|
};
|
|
|
|
class CloseButton : public QAbstractButton
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
explicit CloseButton(QWidget *parent = nullptr);
|
|
[[nodiscard]] QSize sizeHint() const override;
|
|
[[nodiscard]] QSize minimumSizeHint() const override
|
|
{
|
|
return sizeHint();
|
|
}
|
|
|
|
protected:
|
|
void enterEvent(QEnterEvent *event) override;
|
|
void leaveEvent(QEvent *event) override;
|
|
void paintEvent(QPaintEvent *event) override;
|
|
};
|
|
|
|
class TabSupervisor : public QTabWidget
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
enum DeckEditorType
|
|
{
|
|
ClassicDeckEditor,
|
|
VisualDeckEditor
|
|
};
|
|
|
|
private:
|
|
ServerInfo_User *userInfo;
|
|
AbstractClient *client;
|
|
UserListManager *userListManager;
|
|
QList<AbstractClient *> localClients;
|
|
QMenu *tabsMenu;
|
|
TabHome *tabHome;
|
|
TabDeckStorageVisual *tabVisualDeckStorage;
|
|
TabServer *tabServer;
|
|
TabAccount *tabAccount;
|
|
TabDeckStorage *tabDeckStorage;
|
|
TabReplays *tabReplays;
|
|
TabAdmin *tabAdmin;
|
|
TabCardArtRules *tabCardArtRules;
|
|
TabLog *tabLog;
|
|
TabReport *tabReport;
|
|
TabModeration *tabModeration;
|
|
TabDeveloper *tabDeveloper;
|
|
QMap<int, TabRoom *> roomTabs;
|
|
QMap<int, TabGame *> gameTabs;
|
|
QList<TabGame *> replayTabs;
|
|
QMap<QString, TabMessage *> messageTabs;
|
|
QMap<QString, TabPublicDecks *> publicDecksTabs;
|
|
QList<AbstractTabDeckEditor *> deckEditorTabs;
|
|
bool isLocalGame;
|
|
|
|
QAction *aTabHome, *aTabDeckEditor, *aTabVisualDeckEditor, *aTabEdhRec, *aTabArchidekt, *aTabVisualDeckStorage,
|
|
*aTabVisualDatabaseDisplay, *aTabServer, *aTabAccount, *aTabDeckStorage, *aTabReplays, *aTabAdmin,
|
|
*aTabCardArtRules, *aTabLog, *aTabReport, *aTabModeration, *aTabDeveloper;
|
|
|
|
int myAddTab(Tab *tab, QAction *manager = nullptr);
|
|
void addCloseButtonToTab(Tab *tab, int tabIndex, QAction *manager);
|
|
static QString sanitizeTabName(QString dirty);
|
|
static QString sanitizeHtml(QString dirty);
|
|
void resetTabsMenu();
|
|
/** Shared join/spectate driver behind the report tab and the profile hover card. */
|
|
void joinGameByIntent(int gameId, int roomId, bool asSpectator);
|
|
|
|
public:
|
|
explicit TabSupervisor(AbstractClient *_client, QMenu *tabsMenu, QWidget *parent = nullptr);
|
|
~TabSupervisor() override;
|
|
void retranslateUi();
|
|
void initStartupTabs();
|
|
void start(const ServerInfo_User &userInfo);
|
|
void startLocal(const QList<AbstractClient *> &_clients);
|
|
void stop();
|
|
[[nodiscard]] bool getIsLocalGame() const
|
|
{
|
|
return isLocalGame;
|
|
}
|
|
[[nodiscard]] int getGameCount() const
|
|
{
|
|
return gameTabs.size();
|
|
}
|
|
[[nodiscard]] TabAccount *getTabAccount() const
|
|
{
|
|
return tabAccount;
|
|
}
|
|
[[nodiscard]] ServerInfo_User *getUserInfo() const
|
|
{
|
|
return userInfo;
|
|
}
|
|
[[nodiscard]] AbstractClient *getClient() const;
|
|
[[nodiscard]] AbstractClient *getServerClient() const
|
|
{
|
|
return client;
|
|
}
|
|
[[nodiscard]] UserListManager *getUserListManager() const
|
|
{
|
|
return userListManager;
|
|
}
|
|
[[nodiscard]] TabServer *getTabServer() const
|
|
{
|
|
return tabServer;
|
|
}
|
|
[[nodiscard]] const QMap<int, TabRoom *> &getRoomTabs() const
|
|
{
|
|
return roomTabs;
|
|
}
|
|
[[nodiscard]] QList<AbstractTabDeckEditor *> getDeckEditorTabs() const
|
|
{
|
|
return deckEditorTabs;
|
|
}
|
|
[[nodiscard]] QList<GameInviteOption> getGameInviteLinksForRoom(int roomId) const;
|
|
void sendInviteToUser(const QString &userName, const QString &inviteText);
|
|
[[nodiscard]] bool getAdminLocked() const;
|
|
[[nodiscard]] bool canOverrideGameRestrictions() const;
|
|
void closeEvent(QCloseEvent *event) override;
|
|
bool switchToGameTabIfAlreadyExists(const int gameId);
|
|
static void actShowPopup(const QString &message);
|
|
signals:
|
|
void setMenu(const QList<QMenu *> &newMenuList = QList<QMenu *>());
|
|
void localGameEnded();
|
|
void adminLockChanged(bool lock);
|
|
void showWindowIfHidden();
|
|
void cockatriceLinkActivated(const QString &url);
|
|
|
|
public slots:
|
|
void openDeckInNewTab(const LoadedDeck &deckToOpen);
|
|
TabDeckEditor *addDeckEditorTab(const LoadedDeck &deckToOpen);
|
|
TabDeckEditorVisual *addVisualDeckEditorTab(const LoadedDeck &deckToOpen);
|
|
TabVisualDatabaseDisplay *addVisualDatabaseDisplayTab();
|
|
TabEdhRecMain *addEdhrecMainTab();
|
|
TabArchidekt *addArchidektTab();
|
|
TabEdhRec *addEdhrecTab(const CardInfoPtr &cardToQuery, bool isCommander = false);
|
|
void openReplay(GameReplay *replay);
|
|
void joinReportGame(int gameId, int roomId);
|
|
/** Joins or spectates a game listed on a user's profile hover card. */
|
|
void joinGameFromUserCard(int gameId, int roomId, bool asSpectator);
|
|
void openTabModeration(const QString &userName = {});
|
|
void switchToFirstAvailableNetworkTab();
|
|
void maximizeMainWindow();
|
|
void actTabVisualDeckStorage(bool checked);
|
|
void actTabReplays(bool checked);
|
|
void openTabServer();
|
|
void addRoomTab(const ServerInfo_Room &info, bool setCurrent);
|
|
void openTabPublicDecks(const QString &userName);
|
|
private slots:
|
|
void refreshShortcuts();
|
|
|
|
void actTabHome(bool checked);
|
|
void actTabServer(bool checked);
|
|
void actTabAccount(bool checked);
|
|
void actTabDeckStorage(bool checked);
|
|
void actTabAdmin(bool checked);
|
|
void actTabLog(bool checked);
|
|
void actTabReport(bool checked);
|
|
void actTabModeration(bool checked);
|
|
void actTabDeveloper(bool checked);
|
|
|
|
void openTabVisualDeckStorage();
|
|
void openTabHome();
|
|
void openTabAccount();
|
|
void openTabDeckStorage();
|
|
void openTabReplays();
|
|
void openTabAdmin();
|
|
void actTabCardArtRules(bool checked);
|
|
void openTabCardArtRules();
|
|
void openTabLog();
|
|
void openTabReport();
|
|
void openTabDeveloper();
|
|
|
|
void updateCurrent(int index);
|
|
void updatePingTime(int value, int max);
|
|
void updateLatencyTooltip(const LatencyTracker::Stats &stats);
|
|
void gameJoined(const Event_GameJoined &event);
|
|
void localGameJoined(const Event_GameJoined &event);
|
|
void gameLeft(TabGame *tab);
|
|
void roomLeft(TabRoom *tab);
|
|
void publicDecksClosed(TabPublicDecks *tab);
|
|
TabMessage *addMessageTab(const QString &userName, bool focus);
|
|
void replayLeft(TabGame *tab);
|
|
void processUserLeft(const QString &userName);
|
|
void processUserJoined(const ServerInfo_User &userInfo);
|
|
void talkLeft(TabMessage *tab);
|
|
void deckEditorClosed(AbstractTabDeckEditor *tab);
|
|
void tabUserEvent(bool globalEvent);
|
|
void updateTabText(Tab *tab, const QString &newTabText);
|
|
void processRoomEvent(const RoomEvent &event);
|
|
void processGameEventContainer(const GameEventContainer &cont);
|
|
void processUserMessageEvent(const Event_UserMessage &event);
|
|
void processNotifyUserEvent(const Event_NotifyUser &event);
|
|
};
|
|
|
|
#endif
|