Make all tabs closable; add tabs menu (#5451)

* make closeRequest call close by default

* make all tabs closable by default

* closeRequest instead of deleteLater on stop

* null out pointer on destroy

* no need to manually null out the tabs anymore

* comment

* pass tabsMenu into ctor

* comment

* implement tabs menu

* fix segfault on close (again)

* remove deck editor action from WindowMain
This commit is contained in:
RickyRister 2025-01-12 13:15:19 -08:00 committed by GitHub
parent e4611a8616
commit 9bd024d39f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 259 additions and 85 deletions

View file

@ -4,6 +4,7 @@
#include "./tab_supervisor.h" #include "./tab_supervisor.h"
#include <QApplication> #include <QApplication>
#include <QCloseEvent>
#include <QDebug> #include <QDebug>
#include <QScreen> #include <QScreen>
@ -42,3 +43,17 @@ void Tab::deleteCardInfoPopup(const QString &cardName)
} }
} }
} }
/**
* Overrides the closeEvent in order to emit a close signal
*/
void Tab::closeEvent(QCloseEvent *event)
{
emit closed();
event->accept();
}
void Tab::closeRequest(bool /*forced*/)
{
close();
}

View file

@ -13,6 +13,12 @@ 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);
/**
* Emitted when the tab is closed (because Qt doesn't provide a built-in close signal)
* This signal is emitted from this class's overridden Tab::closeEvent method.
* Make sure any subclasses that override closeEvent still emit this signal from there.
*/
void closed();
protected: protected:
TabSupervisor *tabSupervisor; TabSupervisor *tabSupervisor;
@ -23,6 +29,7 @@ protected:
protected slots: protected slots:
void showCardInfoPopup(const QPoint &pos, const QString &cardName, const QString &providerId); void showCardInfoPopup(const QPoint &pos, const QString &cardName, const QString &providerId);
void deleteCardInfoPopup(const QString &cardName); void deleteCardInfoPopup(const QString &cardName);
void closeEvent(QCloseEvent *event) override;
private: private:
QString currentCardName, currentProviderId; QString currentCardName, currentProviderId;
@ -56,9 +63,7 @@ public:
* *
* @param forced whether this close request was initiated by the user or forced by the server. * @param forced whether this close request was initiated by the user or forced by the server.
*/ */
virtual void closeRequest(bool /*forced*/ = false) virtual void closeRequest(bool forced = false);
{
}
virtual void tabActivated() virtual void tabActivated()
{ {
} }

View file

@ -100,9 +100,9 @@ void CloseButton::paintEvent(QPaintEvent * /*event*/)
style()->drawPrimitive(QStyle::PE_IndicatorTabClose, &opt, &p, this); style()->drawPrimitive(QStyle::PE_IndicatorTabClose, &opt, &p, this);
} }
TabSupervisor::TabSupervisor(AbstractClient *_client, QWidget *parent) TabSupervisor::TabSupervisor(AbstractClient *_client, QMenu *tabsMenu, QWidget *parent)
: QTabWidget(parent), userInfo(0), client(_client), tabServer(0), tabUserLists(0), tabDeckStorage(0), tabReplays(0), : QTabWidget(parent), userInfo(0), client(_client), tabsMenu(tabsMenu), tabServer(0), tabUserLists(0),
tabAdmin(0), tabLog(0) tabDeckStorage(0), tabReplays(0), tabAdmin(0), tabLog(0)
{ {
setElideMode(Qt::ElideRight); setElideMode(Qt::ElideRight);
setMovable(true); setMovable(true);
@ -114,8 +114,10 @@ TabSupervisor::TabSupervisor(AbstractClient *_client, QWidget *parent)
tabBar()->setStyle(new MacOSTabFixStyle); tabBar()->setStyle(new MacOSTabFixStyle);
#endif #endif
// connect tab changes
connect(this, &TabSupervisor::currentChanged, this, &TabSupervisor::updateCurrent); connect(this, &TabSupervisor::currentChanged, this, &TabSupervisor::updateCurrent);
// connect client
connect(client, &AbstractClient::roomEventReceived, this, &TabSupervisor::processRoomEvent); connect(client, &AbstractClient::roomEventReceived, this, &TabSupervisor::processRoomEvent);
connect(client, &AbstractClient::gameEventContainerReceived, this, &TabSupervisor::processGameEventContainer); connect(client, &AbstractClient::gameEventContainerReceived, this, &TabSupervisor::processGameEventContainer);
connect(client, &AbstractClient::gameJoinedEventReceived, this, &TabSupervisor::gameJoined); connect(client, &AbstractClient::gameJoinedEventReceived, this, &TabSupervisor::gameJoined);
@ -123,6 +125,40 @@ TabSupervisor::TabSupervisor(AbstractClient *_client, QWidget *parent)
connect(client, &AbstractClient::maxPingTime, this, &TabSupervisor::updatePingTime); connect(client, &AbstractClient::maxPingTime, this, &TabSupervisor::updatePingTime);
connect(client, &AbstractClient::notifyUserEventReceived, this, &TabSupervisor::processNotifyUserEvent); connect(client, &AbstractClient::notifyUserEventReceived, this, &TabSupervisor::processNotifyUserEvent);
// create tabs menu actions
aTabDeckEditor = new QAction(this);
connect(aTabDeckEditor, &QAction::triggered, this, [this] { addDeckEditorTab(nullptr); });
aTabServer = new QAction(this);
aTabServer->setCheckable(true);
connect(aTabServer, &QAction::toggled, this, &TabSupervisor::actTabServer);
aTabUserLists = new QAction(this);
aTabUserLists->setCheckable(true);
connect(aTabUserLists, &QAction::toggled, this, &TabSupervisor::actTabUserLists);
aTabDeckStorage = new QAction(this);
aTabDeckStorage->setCheckable(true);
connect(aTabDeckStorage, &QAction::toggled, this, &TabSupervisor::actTabDeckStorage);
aTabReplays = new QAction(this);
aTabReplays->setCheckable(true);
connect(aTabReplays, &QAction::toggled, this, &TabSupervisor::actTabReplays);
aTabAdmin = new QAction(this);
aTabAdmin->setCheckable(true);
connect(aTabAdmin, &QAction::toggled, this, &TabSupervisor::actTabAdmin);
aTabLog = new QAction(this);
aTabLog->setCheckable(true);
connect(aTabLog, &QAction::toggled, this, &TabSupervisor::actTabLog);
connect(&SettingsCache::instance().shortcuts(), &ShortcutsSettings::shortCutChanged, this,
&TabSupervisor::refreshShortcuts);
refreshShortcuts();
resetTabsMenu();
retranslateUi(); retranslateUi();
} }
@ -133,6 +169,16 @@ TabSupervisor::~TabSupervisor()
void TabSupervisor::retranslateUi() void TabSupervisor::retranslateUi()
{ {
// tab menu actions
aTabDeckEditor->setText(tr("Deck Editor"));
aTabServer->setText(tr("Server"));
aTabUserLists->setText(tr("Account"));
aTabDeckStorage->setText(tr("Deck storage"));
aTabReplays->setText(tr("Game replays"));
aTabAdmin->setText(tr("Administration"));
aTabLog->setText(tr("Logs"));
// tabs
QList<Tab *> tabs; QList<Tab *> tabs;
tabs.append(tabServer); tabs.append(tabServer);
tabs.append(tabReplays); tabs.append(tabReplays);
@ -166,6 +212,12 @@ void TabSupervisor::retranslateUi()
} }
} }
void TabSupervisor::refreshShortcuts()
{
ShortcutsSettings &shortcuts = SettingsCache::instance().shortcuts();
aTabDeckEditor->setShortcuts(shortcuts.getShortcut("MainWindow/aDeckEditor"));
}
bool TabSupervisor::closeRequest() bool TabSupervisor::closeRequest()
{ {
if (getGameCount()) { if (getGameCount()) {
@ -208,49 +260,51 @@ int TabSupervisor::myAddTab(Tab *tab)
int idx = addTab(tab, sanitizeTabName(tabText)); int idx = addTab(tab, sanitizeTabName(tabText));
setTabToolTip(idx, sanitizeHtml(tabText)); setTabToolTip(idx, sanitizeHtml(tabText));
addCloseButtonToTab(tab, idx);
return idx; return idx;
} }
/**
* Resets the tabs menu to the tabs that are always available
*/
void TabSupervisor::resetTabsMenu()
{
tabsMenu->clear();
tabsMenu->addAction(aTabDeckEditor);
}
void TabSupervisor::start(const ServerInfo_User &_userInfo) void TabSupervisor::start(const ServerInfo_User &_userInfo)
{ {
isLocalGame = false; isLocalGame = false;
userInfo = new ServerInfo_User(_userInfo); userInfo = new ServerInfo_User(_userInfo);
tabServer = new TabServer(this, client); resetTabsMenu();
connect(tabServer, &TabServer::roomJoined, this, &TabSupervisor::addRoomTab);
myAddTab(tabServer);
tabUserLists = new TabUserLists(this, client, *userInfo); tabsMenu->addSeparator();
connect(tabUserLists, &TabUserLists::openMessageDialog, this, &TabSupervisor::addMessageTab); tabsMenu->addAction(aTabServer);
connect(tabUserLists, &TabUserLists::userJoined, this, &TabSupervisor::processUserJoined); tabsMenu->addAction(aTabUserLists);
connect(tabUserLists, &TabUserLists::userLeft, this, &TabSupervisor::processUserLeft);
myAddTab(tabUserLists); aTabServer->setChecked(true);
aTabUserLists->setChecked(true);
updatePingTime(0, -1); updatePingTime(0, -1);
if (userInfo->user_level() & ServerInfo_User::IsRegistered) { if (userInfo->user_level() & ServerInfo_User::IsRegistered) {
tabDeckStorage = new TabDeckStorage(this, client); tabsMenu->addAction(aTabDeckStorage);
connect(tabDeckStorage, &TabDeckStorage::openDeckEditor, this, &TabSupervisor::addDeckEditorTab); tabsMenu->addAction(aTabReplays);
myAddTab(tabDeckStorage);
tabReplays = new TabReplays(this, client); aTabDeckStorage->setChecked(true);
connect(tabReplays, &TabReplays::openReplay, this, &TabSupervisor::openReplay); aTabReplays->setChecked(true);
myAddTab(tabReplays);
} else {
tabDeckStorage = 0;
tabReplays = 0;
} }
if (userInfo->user_level() & ServerInfo_User::IsModerator) { if (userInfo->user_level() & ServerInfo_User::IsModerator) {
tabAdmin = new TabAdmin(this, client, (userInfo->user_level() & ServerInfo_User::IsAdmin)); tabsMenu->addSeparator();
connect(tabAdmin, &TabAdmin::adminLockChanged, this, &TabSupervisor::adminLockChanged); tabsMenu->addAction(aTabAdmin);
myAddTab(tabAdmin); tabsMenu->addAction(aTabLog);
tabLog = new TabLog(this, client); aTabAdmin->setChecked(true);
myAddTab(tabLog); aTabLog->setChecked(true);
} else {
tabAdmin = 0;
tabLog = 0;
} }
retranslateUi(); retranslateUi();
@ -258,6 +312,8 @@ void TabSupervisor::start(const ServerInfo_User &_userInfo)
void TabSupervisor::startLocal(const QList<AbstractClient *> &_clients) void TabSupervisor::startLocal(const QList<AbstractClient *> &_clients)
{ {
resetTabsMenu();
tabUserLists = 0; tabUserLists = 0;
tabDeckStorage = 0; tabDeckStorage = 0;
tabReplays = 0; tabReplays = 0;
@ -272,11 +328,16 @@ void TabSupervisor::startLocal(const QList<AbstractClient *> &_clients)
connect(localClients.first(), &AbstractClient::gameJoinedEventReceived, this, &TabSupervisor::localGameJoined); connect(localClients.first(), &AbstractClient::gameJoinedEventReceived, this, &TabSupervisor::localGameJoined);
} }
/**
* Call this when Cockatrice disconnects from the server in order to clean up.
*/
void TabSupervisor::stop() void TabSupervisor::stop()
{ {
if ((!client) && localClients.isEmpty()) if ((!client) && localClients.isEmpty())
return; return;
resetTabsMenu();
if (!localClients.isEmpty()) { if (!localClients.isEmpty()) {
for (int i = 0; i < localClients.size(); ++i) for (int i = 0; i < localClients.size(); ++i)
localClients[i]->deleteLater(); localClients[i]->deleteLater();
@ -284,42 +345,39 @@ void TabSupervisor::stop()
emit localGameEnded(); emit localGameEnded();
} else { } else {
if (tabUserLists) if (tabUserLists) {
tabUserLists->deleteLater(); tabUserLists->closeRequest(true);
if (tabServer) }
tabServer->deleteLater(); if (tabServer) {
if (tabDeckStorage) tabServer->closeRequest(true);
tabDeckStorage->deleteLater(); }
if (tabReplays) if (tabDeckStorage) {
tabReplays->deleteLater(); tabDeckStorage->closeRequest(true);
if (tabAdmin) }
tabAdmin->deleteLater(); if (tabReplays) {
if (tabLog) tabReplays->closeRequest(true);
tabLog->deleteLater(); }
if (tabAdmin) {
tabAdmin->closeRequest(true);
}
if (tabLog) {
tabLog->closeRequest(true);
}
} }
tabUserLists = 0;
tabServer = 0;
tabDeckStorage = 0;
tabReplays = 0;
tabAdmin = 0;
tabLog = 0;
QList<Tab *> tabsToDelete; QList<Tab *> tabsToDelete;
for (auto i = roomTabs.cbegin(), end = roomTabs.cend(); i != end; ++i) { for (auto i = roomTabs.cbegin(), end = roomTabs.cend(); i != end; ++i) {
tabsToDelete << i.value(); tabsToDelete << i.value();
} }
roomTabs.clear();
for (auto i = gameTabs.cbegin(), end = gameTabs.cend(); i != end; ++i) { for (auto i = gameTabs.cbegin(), end = gameTabs.cend(); i != end; ++i) {
tabsToDelete << i.value(); tabsToDelete << i.value();
} }
gameTabs.clear();
for (auto i = messageTabs.cbegin(), end = messageTabs.cend(); i != end; ++i) { for (auto i = messageTabs.cbegin(), end = messageTabs.cend(); i != end; ++i) {
tabsToDelete << i.value(); tabsToDelete << i.value();
} }
messageTabs.clear();
for (const auto tab : tabsToDelete) { for (const auto tab : tabsToDelete) {
tab->closeRequest(true); tab->closeRequest(true);
@ -329,6 +387,97 @@ void TabSupervisor::stop()
userInfo = 0; userInfo = 0;
} }
void TabSupervisor::actTabServer(bool checked)
{
if (checked && !tabServer) {
tabServer = new TabServer(this, client);
connect(tabServer, &TabServer::roomJoined, this, &TabSupervisor::addRoomTab);
myAddTab(tabServer);
connect(tabServer, &Tab::closed, this, [this] {
tabServer = nullptr;
aTabServer->setChecked(false);
});
} else if (!checked && tabServer) {
tabServer->closeRequest();
}
}
void TabSupervisor::actTabUserLists(bool checked)
{
if (checked && !tabUserLists) {
tabUserLists = new TabUserLists(this, client, *userInfo);
connect(tabUserLists, &TabUserLists::openMessageDialog, this, &TabSupervisor::addMessageTab);
connect(tabUserLists, &TabUserLists::userJoined, this, &TabSupervisor::processUserJoined);
connect(tabUserLists, &TabUserLists::userLeft, this, &TabSupervisor::processUserLeft);
myAddTab(tabUserLists);
connect(tabUserLists, &Tab::closed, this, [this] {
tabUserLists = nullptr;
aTabUserLists->setChecked(false);
});
} else if (!checked && tabUserLists) {
tabUserLists->closeRequest();
}
}
void TabSupervisor::actTabDeckStorage(bool checked)
{
if (checked && !tabDeckStorage) {
tabDeckStorage = new TabDeckStorage(this, client);
connect(tabDeckStorage, &TabDeckStorage::openDeckEditor, this, &TabSupervisor::addDeckEditorTab);
myAddTab(tabDeckStorage);
connect(tabDeckStorage, &Tab::closed, this, [this] {
tabDeckStorage = nullptr;
aTabDeckStorage->setChecked(false);
});
} else if (!checked && tabDeckStorage) {
tabDeckStorage->closeRequest();
}
}
void TabSupervisor::actTabReplays(bool checked)
{
if (checked && !tabReplays) {
tabReplays = new TabReplays(this, client);
connect(tabReplays, &TabReplays::openReplay, this, &TabSupervisor::openReplay);
myAddTab(tabReplays);
connect(tabReplays, &Tab::closed, this, [this] {
tabReplays = nullptr;
aTabReplays->setChecked(false);
});
} else if (!checked && tabReplays) {
tabReplays->closeRequest();
}
}
void TabSupervisor::actTabAdmin(bool checked)
{
if (checked && !tabAdmin) {
tabAdmin = new TabAdmin(this, client, (userInfo->user_level() & ServerInfo_User::IsAdmin));
connect(tabAdmin, &TabAdmin::adminLockChanged, this, &TabSupervisor::adminLockChanged);
myAddTab(tabAdmin);
connect(tabAdmin, &Tab::closed, this, [this] {
tabAdmin = nullptr;
aTabAdmin->setChecked(false);
});
} else if (!checked && tabAdmin) {
tabAdmin->closeRequest();
}
}
void TabSupervisor::actTabLog(bool checked)
{
if (checked && !tabLog) {
tabLog = new TabLog(this, client);
myAddTab(tabLog);
connect(tabLog, &Tab::closed, this, [this] {
tabLog = nullptr;
aTabAdmin->setChecked(false);
});
} else if (!checked && tabLog) {
tabLog->closeRequest();
}
}
void TabSupervisor::updatePingTime(int value, int max) void TabSupervisor::updatePingTime(int value, int max)
{ {
if (!tabServer) if (!tabServer)
@ -363,8 +512,7 @@ void TabSupervisor::gameJoined(const Event_GameJoined &event)
connect(tab, &TabGame::gameClosing, this, &TabSupervisor::gameLeft); connect(tab, &TabGame::gameClosing, this, &TabSupervisor::gameLeft);
connect(tab, &TabGame::openMessageDialog, this, &TabSupervisor::addMessageTab); connect(tab, &TabGame::openMessageDialog, this, &TabSupervisor::addMessageTab);
connect(tab, &TabGame::openDeckEditor, this, &TabSupervisor::addDeckEditorTab); connect(tab, &TabGame::openDeckEditor, this, &TabSupervisor::addDeckEditorTab);
int tabIndex = myAddTab(tab); myAddTab(tab);
addCloseButtonToTab(tab, tabIndex);
gameTabs.insert(event.game_info().game_id(), tab); gameTabs.insert(event.game_info().game_id(), tab);
setCurrentWidget(tab); setCurrentWidget(tab);
} }
@ -374,8 +522,7 @@ void TabSupervisor::localGameJoined(const Event_GameJoined &event)
TabGame *tab = new TabGame(this, localClients, event, QMap<int, QString>()); TabGame *tab = new TabGame(this, localClients, event, QMap<int, QString>());
connect(tab, &TabGame::gameClosing, this, &TabSupervisor::gameLeft); connect(tab, &TabGame::gameClosing, this, &TabSupervisor::gameLeft);
connect(tab, &TabGame::openDeckEditor, this, &TabSupervisor::addDeckEditorTab); connect(tab, &TabGame::openDeckEditor, this, &TabSupervisor::addDeckEditorTab);
int tabIndex = myAddTab(tab); myAddTab(tab);
addCloseButtonToTab(tab, tabIndex);
gameTabs.insert(event.game_info().game_id(), tab); gameTabs.insert(event.game_info().game_id(), tab);
setCurrentWidget(tab); setCurrentWidget(tab);
@ -404,8 +551,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);
int tabIndex = myAddTab(tab); myAddTab(tab);
addCloseButtonToTab(tab, tabIndex);
roomTabs.insert(info.room_id(), tab); roomTabs.insert(info.room_id(), tab);
if (setCurrent) if (setCurrent)
setCurrentWidget(tab); setCurrentWidget(tab);
@ -424,8 +570,7 @@ void TabSupervisor::openReplay(GameReplay *replay)
{ {
TabGame *replayTab = new TabGame(this, replay); TabGame *replayTab = new TabGame(this, replay);
connect(replayTab, &TabGame::gameClosing, this, &TabSupervisor::replayLeft); connect(replayTab, &TabGame::gameClosing, this, &TabSupervisor::replayLeft);
int tabIndex = myAddTab(replayTab); myAddTab(replayTab);
addCloseButtonToTab(replayTab, tabIndex);
replayTabs.append(replayTab); replayTabs.append(replayTab);
setCurrentWidget(replayTab); setCurrentWidget(replayTab);
} }
@ -461,8 +606,7 @@ TabMessage *TabSupervisor::addMessageTab(const QString &receiverName, bool focus
tab = new TabMessage(this, client, *userInfo, otherUser); tab = new TabMessage(this, client, *userInfo, otherUser);
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);
int tabIndex = myAddTab(tab); myAddTab(tab);
addCloseButtonToTab(tab, tabIndex);
messageTabs.insert(receiverName, tab); messageTabs.insert(receiverName, tab);
if (focus) if (focus)
setCurrentWidget(tab); setCurrentWidget(tab);
@ -490,8 +634,7 @@ TabDeckEditor *TabSupervisor::addDeckEditorTab(const DeckLoader *deckToOpen)
tab->setDeck(new DeckLoader(*deckToOpen)); tab->setDeck(new DeckLoader(*deckToOpen));
connect(tab, &TabDeckEditor::deckEditorClosing, this, &TabSupervisor::deckEditorClosed); connect(tab, &TabDeckEditor::deckEditorClosing, this, &TabSupervisor::deckEditorClosed);
connect(tab, &TabDeckEditor::openDeckEditor, this, &TabSupervisor::addDeckEditorTab); connect(tab, &TabDeckEditor::openDeckEditor, this, &TabSupervisor::addDeckEditorTab);
int tabIndex = myAddTab(tab); myAddTab(tab);
addCloseButtonToTab(tab, tabIndex);
deckEditorTabs.append(tab); deckEditorTabs.append(tab);
setCurrentWidget(tab); setCurrentWidget(tab);
return tab; return tab;
@ -500,8 +643,7 @@ TabDeckEditor *TabSupervisor::addDeckEditorTab(const DeckLoader *deckToOpen)
TabDeckStorageVisual *TabSupervisor::addVisualDeckStorageTab() TabDeckStorageVisual *TabSupervisor::addVisualDeckStorageTab()
{ {
TabDeckStorageVisual *tab = new TabDeckStorageVisual(this, client); TabDeckStorageVisual *tab = new TabDeckStorageVisual(this, client);
int tabIndex = myAddTab(tab); myAddTab(tab);
addCloseButtonToTab(tab, tabIndex);
setCurrentWidget(tab); setCurrentWidget(tab);
return tab; return tab;
} }

View file

@ -69,6 +69,7 @@ private:
ServerInfo_User *userInfo; ServerInfo_User *userInfo;
AbstractClient *client; AbstractClient *client;
QList<AbstractClient *> localClients; QList<AbstractClient *> localClients;
QMenu *tabsMenu;
TabServer *tabServer; TabServer *tabServer;
TabUserLists *tabUserLists; TabUserLists *tabUserLists;
TabDeckStorage *tabDeckStorage; TabDeckStorage *tabDeckStorage;
@ -80,14 +81,18 @@ private:
QList<TabGame *> replayTabs; QList<TabGame *> replayTabs;
QMap<QString, TabMessage *> messageTabs; QMap<QString, TabMessage *> messageTabs;
QList<TabDeckEditor *> deckEditorTabs; QList<TabDeckEditor *> deckEditorTabs;
bool isLocalGame;
QAction *aTabDeckEditor, *aTabServer, *aTabUserLists, *aTabDeckStorage, *aTabReplays, *aTabAdmin, *aTabLog;
int myAddTab(Tab *tab); int myAddTab(Tab *tab);
void addCloseButtonToTab(Tab *tab, int tabIndex); void addCloseButtonToTab(Tab *tab, int tabIndex);
QString sanitizeTabName(QString dirty) const; QString sanitizeTabName(QString dirty) const;
QString sanitizeHtml(QString dirty) const; QString sanitizeHtml(QString dirty) const;
bool isLocalGame; void resetTabsMenu();
public: public:
explicit TabSupervisor(AbstractClient *_client, QWidget *parent = nullptr); explicit TabSupervisor(AbstractClient *_client, QMenu *tabsMenu, QWidget *parent = nullptr);
~TabSupervisor() override; ~TabSupervisor() override;
void retranslateUi(); void retranslateUi();
void start(const ServerInfo_User &userInfo); void start(const ServerInfo_User &userInfo);
@ -135,6 +140,15 @@ public slots:
void openReplay(GameReplay *replay); void openReplay(GameReplay *replay);
void maximizeMainWindow(); void maximizeMainWindow();
private slots: private slots:
void refreshShortcuts();
void actTabServer(bool checked);
void actTabUserLists(bool checked);
void actTabDeckStorage(bool checked);
void actTabReplays(bool checked);
void actTabAdmin(bool checked);
void actTabLog(bool checked);
void updateCurrent(int index); void updateCurrent(int index);
void updatePingTime(int value, int max); void updatePingTime(int value, int max);
void gameJoined(const Event_GameJoined &event); void gameJoined(const Event_GameJoined &event);

View file

@ -82,6 +82,11 @@ const QString MainWindow::appName = "Cockatrice";
const QStringList MainWindow::fileNameFilters = QStringList() << QObject::tr("Cockatrice card database (*.xml)") const QStringList MainWindow::fileNameFilters = QStringList() << QObject::tr("Cockatrice card database (*.xml)")
<< QObject::tr("All files (*.*)"); << QObject::tr("All files (*.*)");
/**
* Replaces the tab-specific menus that are shown in the menuBar.
*
* @param newMenuList The tab-specific menus to show in the menuBar
*/
void MainWindow::updateTabMenu(const QList<QMenu *> &newMenuList) void MainWindow::updateTabMenu(const QList<QMenu *> &newMenuList)
{ {
for (auto &tabMenu : tabMenus) for (auto &tabMenu : tabMenus)
@ -285,11 +290,6 @@ void MainWindow::localGameEnded()
aSinglePlayer->setEnabled(true); aSinglePlayer->setEnabled(true);
} }
void MainWindow::actDeckEditor()
{
tabSupervisor->addDeckEditorTab(nullptr);
}
void MainWindow::actVisualDeckStorage() void MainWindow::actVisualDeckStorage()
{ {
tabSupervisor->addVisualDeckStorageTab(); tabSupervisor->addVisualDeckStorageTab();
@ -664,7 +664,6 @@ void MainWindow::retranslateUi()
aDisconnect->setText(tr("&Disconnect")); aDisconnect->setText(tr("&Disconnect"));
aSinglePlayer->setText(tr("Start &local game...")); aSinglePlayer->setText(tr("Start &local game..."));
aWatchReplay->setText(tr("&Watch replay...")); aWatchReplay->setText(tr("&Watch replay..."));
aDeckEditor->setText(tr("&Deck editor"));
aVisualDeckStorage->setText(tr("&Visual Deck storage")); aVisualDeckStorage->setText(tr("&Visual Deck storage"));
aFullScreen->setText(tr("&Full screen")); aFullScreen->setText(tr("&Full screen"));
aRegister->setText(tr("&Register to server...")); aRegister->setText(tr("&Register to server..."));
@ -687,6 +686,8 @@ void MainWindow::retranslateUi()
aAddCustomSet->setText(tr("Add custom sets/cards")); aAddCustomSet->setText(tr("Add custom sets/cards"));
aReloadCardDatabase->setText(tr("Reload card database")); aReloadCardDatabase->setText(tr("Reload card database"));
tabsMenu->setTitle(tr("Tabs"));
helpMenu->setTitle(tr("&Help")); helpMenu->setTitle(tr("&Help"));
aAbout->setText(tr("&About Cockatrice")); aAbout->setText(tr("&About Cockatrice"));
aTips->setText(tr("&Tip of the Day")); aTips->setText(tr("&Tip of the Day"));
@ -711,8 +712,6 @@ void MainWindow::createActions()
connect(aSinglePlayer, &QAction::triggered, this, &MainWindow::actSinglePlayer); connect(aSinglePlayer, &QAction::triggered, this, &MainWindow::actSinglePlayer);
aWatchReplay = new QAction(this); aWatchReplay = new QAction(this);
connect(aWatchReplay, &QAction::triggered, this, &MainWindow::actWatchReplay); connect(aWatchReplay, &QAction::triggered, this, &MainWindow::actWatchReplay);
aDeckEditor = new QAction(this);
connect(aDeckEditor, &QAction::triggered, this, &MainWindow::actDeckEditor);
aVisualDeckStorage = new QAction(this); aVisualDeckStorage = new QAction(this);
connect(aVisualDeckStorage, &QAction::triggered, this, &MainWindow::actVisualDeckStorage); connect(aVisualDeckStorage, &QAction::triggered, this, &MainWindow::actVisualDeckStorage);
aFullScreen = new QAction(this); aFullScreen = new QAction(this);
@ -801,7 +800,6 @@ void MainWindow::createMenus()
cockatriceMenu->addAction(aSinglePlayer); cockatriceMenu->addAction(aSinglePlayer);
cockatriceMenu->addAction(aWatchReplay); cockatriceMenu->addAction(aWatchReplay);
cockatriceMenu->addSeparator(); cockatriceMenu->addSeparator();
cockatriceMenu->addAction(aDeckEditor);
cockatriceMenu->addAction(aVisualDeckStorage); cockatriceMenu->addAction(aVisualDeckStorage);
cockatriceMenu->addSeparator(); cockatriceMenu->addSeparator();
cockatriceMenu->addAction(aFullScreen); cockatriceMenu->addAction(aFullScreen);
@ -819,6 +817,8 @@ void MainWindow::createMenus()
dbMenu->addSeparator(); dbMenu->addSeparator();
dbMenu->addAction(aReloadCardDatabase); dbMenu->addAction(aReloadCardDatabase);
tabsMenu = menuBar()->addMenu(QString());
helpMenu = menuBar()->addMenu(QString()); helpMenu = menuBar()->addMenu(QString());
helpMenu->addAction(aAbout); helpMenu->addAction(aAbout);
helpMenu->addAction(aTips); helpMenu->addAction(aTips);
@ -866,7 +866,7 @@ MainWindow::MainWindow(QWidget *parent)
createActions(); createActions();
createMenus(); createMenus();
tabSupervisor = new TabSupervisor(client, this); tabSupervisor = new TabSupervisor(client, tabsMenu, this);
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);
@ -1283,7 +1283,6 @@ void MainWindow::refreshShortcuts()
aDisconnect->setShortcuts(shortcuts.getShortcut("MainWindow/aDisconnect")); aDisconnect->setShortcuts(shortcuts.getShortcut("MainWindow/aDisconnect"));
aSinglePlayer->setShortcuts(shortcuts.getShortcut("MainWindow/aSinglePlayer")); aSinglePlayer->setShortcuts(shortcuts.getShortcut("MainWindow/aSinglePlayer"));
aWatchReplay->setShortcuts(shortcuts.getShortcut("MainWindow/aWatchReplay")); aWatchReplay->setShortcuts(shortcuts.getShortcut("MainWindow/aWatchReplay"));
aDeckEditor->setShortcuts(shortcuts.getShortcut("MainWindow/aDeckEditor"));
aFullScreen->setShortcuts(shortcuts.getShortcut("MainWindow/aFullScreen")); aFullScreen->setShortcuts(shortcuts.getShortcut("MainWindow/aFullScreen"));
aRegister->setShortcuts(shortcuts.getShortcut("MainWindow/aRegister")); aRegister->setShortcuts(shortcuts.getShortcut("MainWindow/aRegister"));
aSettings->setShortcuts(shortcuts.getShortcut("MainWindow/aSettings")); aSettings->setShortcuts(shortcuts.getShortcut("MainWindow/aSettings"));

View file

@ -73,7 +73,6 @@ private slots:
void actDisconnect(); void actDisconnect();
void actSinglePlayer(); void actSinglePlayer();
void actWatchReplay(); void actWatchReplay();
void actDeckEditor();
void actVisualDeckStorage(); void actVisualDeckStorage();
void actFullScreen(bool checked); void actFullScreen(bool checked);
void actRegister(); void actRegister();
@ -131,11 +130,11 @@ private:
void startLocalGame(int numberPlayers); void startLocalGame(int numberPlayers);
QList<QMenu *> tabMenus; QList<QMenu *> tabMenus;
QMenu *cockatriceMenu, *dbMenu, *helpMenu, *trayIconMenu; QMenu *cockatriceMenu, *dbMenu, *tabsMenu, *helpMenu, *trayIconMenu;
QAction *aConnect, *aDisconnect, *aSinglePlayer, *aWatchReplay, *aDeckEditor, *aVisualDeckStorage, *aFullScreen, QAction *aConnect, *aDisconnect, *aSinglePlayer, *aWatchReplay, *aVisualDeckStorage, *aFullScreen, *aSettings,
*aSettings, *aExit, *aAbout, *aTips, *aCheckCardUpdates, *aRegister, *aForgotPassword, *aUpdate, *aViewLog, *aExit, *aAbout, *aTips, *aCheckCardUpdates, *aRegister, *aForgotPassword, *aUpdate, *aViewLog, *aManageSets,
*aManageSets, *aEditTokens, *aOpenCustomFolder, *aOpenCustomsetsFolder, *aAddCustomSet, *aReloadCardDatabase, *aEditTokens, *aOpenCustomFolder, *aOpenCustomsetsFolder, *aAddCustomSet, *aReloadCardDatabase, *aShow,
*aShow, *aOpenSettingsFolder; *aOpenSettingsFolder;
TabSupervisor *tabSupervisor; TabSupervisor *tabSupervisor;
WndSets *wndSets; WndSets *wndSets;