mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-08 02:53:25 -08:00
[Client] Settings: open Settings as a tab
Add a singleton TabSettings hosting the shared SettingsView and retarget the menu action, tray entry, shortcut and room chat deep-link to TabSupervisor::openTabSettings. Close validation moves from DlgSettings::closeEvent to TabSettings::closeRequest with tr() contexts preserved as DlgSettings. The modal stays but is no longer referenced.
This commit is contained in:
parent
77a0253242
commit
8572ac65e6
7 changed files with 214 additions and 12 deletions
|
|
@ -408,6 +408,7 @@ set(cockatrice_SOURCES
|
||||||
src/interface/widgets/tabs/tab_replays.cpp
|
src/interface/widgets/tabs/tab_replays.cpp
|
||||||
src/interface/widgets/tabs/tab_room.cpp
|
src/interface/widgets/tabs/tab_room.cpp
|
||||||
src/interface/widgets/tabs/tab_server.cpp
|
src/interface/widgets/tabs/tab_server.cpp
|
||||||
|
src/interface/widgets/tabs/tab_settings.cpp
|
||||||
src/interface/widgets/tabs/tab_supervisor.cpp
|
src/interface/widgets/tabs/tab_supervisor.cpp
|
||||||
src/interface/widgets/tabs/tab_visual_database_display.cpp
|
src/interface/widgets/tabs/tab_visual_database_display.cpp
|
||||||
src/interface/widgets/tabs/visual_deck_editor/tab_deck_editor_visual.cpp
|
src/interface/widgets/tabs/visual_deck_editor/tab_deck_editor_visual.cpp
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
#include "../../../client/settings/cache_settings.h"
|
#include "../../../client/settings/cache_settings.h"
|
||||||
#include "../../../client/settings/shortcuts_settings.h"
|
#include "../../../client/settings/shortcuts_settings.h"
|
||||||
#include "../../pixel_map_generator.h"
|
#include "../../pixel_map_generator.h"
|
||||||
#include "../interface/widgets/dialogs/dlg_settings.h"
|
#include "../interface/widgets/dialogs/settings_view.h"
|
||||||
#include "../interface/widgets/server/chat_view/chat_view.h"
|
#include "../interface/widgets/server/chat_view/chat_view.h"
|
||||||
#include "../interface/widgets/server/game_link.h"
|
#include "../interface/widgets/server/game_link.h"
|
||||||
#include "../interface/widgets/server/game_selector.h"
|
#include "../interface/widgets/server/game_selector.h"
|
||||||
|
|
@ -272,9 +272,7 @@ void TabRoom::actClearChat()
|
||||||
|
|
||||||
void TabRoom::actOpenChatSettings()
|
void TabRoom::actOpenChatSettings()
|
||||||
{
|
{
|
||||||
DlgSettings settings(this);
|
tabSupervisor->openTabSettings(SettingsView::MessagesPage);
|
||||||
settings.setTab(DlgSettings::MessagesPage);
|
|
||||||
settings.exec();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabRoom::actCompleterChanged()
|
void TabRoom::actCompleterChanged()
|
||||||
|
|
|
||||||
129
cockatrice/src/interface/widgets/tabs/tab_settings.cpp
Normal file
129
cockatrice/src/interface/widgets/tabs/tab_settings.cpp
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
/**
|
||||||
|
* @file tab_settings.cpp
|
||||||
|
* @ingroup Tabs
|
||||||
|
*/
|
||||||
|
#include "tab_settings.h"
|
||||||
|
|
||||||
|
#include "../../client/settings/cache_settings.h"
|
||||||
|
#include "../dialogs/settings_view.h"
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <libcockatrice/card/database/card_database.h>
|
||||||
|
#include <libcockatrice/card/database/card_database_loader.h>
|
||||||
|
#include <libcockatrice/card/database/card_database_manager.h>
|
||||||
|
#include <libcockatrice/settings/paths_settings.h>
|
||||||
|
|
||||||
|
inline Q_LOGGING_CATEGORY(TabSettingsLog, "tab_settings");
|
||||||
|
|
||||||
|
TabSettings::TabSettings(TabSupervisor *_tabSupervisor, int pageIndex) : Tab(_tabSupervisor)
|
||||||
|
{
|
||||||
|
settingsView = new SettingsView(this);
|
||||||
|
setCentralWidget(settingsView);
|
||||||
|
if (pageIndex >= 0) {
|
||||||
|
settingsView->setTab(pageIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabSettings::setTab(int pageIndex)
|
||||||
|
{
|
||||||
|
settingsView->setTab(pageIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabSettings::retranslateUi()
|
||||||
|
{
|
||||||
|
// Nothing to do: SettingsView retranslates itself via langChanged and the
|
||||||
|
// TabSupervisor refreshes the tab title from getTabText().
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Validates paths and card database before the tab closes
|
||||||
|
*
|
||||||
|
* Moved verbatim from DlgSettings::closeEvent. The "DlgSettings" translation
|
||||||
|
* context below is deliberate and preserves the existing translations.
|
||||||
|
*
|
||||||
|
* @return False when the user wants to go back and fix a setting, true otherwise
|
||||||
|
*/
|
||||||
|
bool TabSettings::closeRequest()
|
||||||
|
{
|
||||||
|
// NOTE: "DlgSettings" contexts are intentional (translation continuity, see SettingsView).
|
||||||
|
bool showLoadError = true;
|
||||||
|
QString loadErrorMessage = QCoreApplication::translate("DlgSettings", "Unknown Error loading card database");
|
||||||
|
LoadStatus loadStatus = CardDatabaseManager::getInstance()->getLoadStatus();
|
||||||
|
qCInfo(TabSettingsLog) << "Card Database load status: " << loadStatus;
|
||||||
|
switch (loadStatus) {
|
||||||
|
case Ok:
|
||||||
|
showLoadError = false;
|
||||||
|
break;
|
||||||
|
case Invalid:
|
||||||
|
loadErrorMessage = QCoreApplication::translate(
|
||||||
|
"DlgSettings", "Your card database is invalid.\n\n"
|
||||||
|
"Cockatrice may not function correctly with an invalid database\n\n"
|
||||||
|
"You may need to rerun Oracle to update your card database.\n\n"
|
||||||
|
"Would you like to change your database location setting?");
|
||||||
|
break;
|
||||||
|
case VersionTooOld:
|
||||||
|
loadErrorMessage = QCoreApplication::translate(
|
||||||
|
"DlgSettings", "Your card database version is too old.\n\n"
|
||||||
|
"This can cause problems loading card information or images\n\n"
|
||||||
|
"Usually this can be fixed by rerunning Oracle to to update your card database.\n\n"
|
||||||
|
"Would you like to change your database location setting?");
|
||||||
|
break;
|
||||||
|
case NotLoaded:
|
||||||
|
loadErrorMessage = QCoreApplication::translate(
|
||||||
|
"DlgSettings", "Your card database did not finish loading\n\n"
|
||||||
|
"Please file a ticket at https://github.com/Cockatrice/Cockatrice/issues with your "
|
||||||
|
"cards.xml attached\n\n"
|
||||||
|
"Would you like to change your database location setting?");
|
||||||
|
break;
|
||||||
|
case FileError:
|
||||||
|
loadErrorMessage = QCoreApplication::translate(
|
||||||
|
"DlgSettings", "File Error loading your card database.\n\n"
|
||||||
|
"Would you like to change your database location setting?");
|
||||||
|
break;
|
||||||
|
case NoCards:
|
||||||
|
loadErrorMessage = QCoreApplication::translate(
|
||||||
|
"DlgSettings", "Your card database was loaded but contains no cards.\n\n"
|
||||||
|
"Would you like to change your database location setting?");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
loadErrorMessage = QCoreApplication::translate(
|
||||||
|
"DlgSettings", "Unknown card database load status\n\n"
|
||||||
|
"Please file a ticket at https://github.com/Cockatrice/Cockatrice/issues\n\n"
|
||||||
|
"Would you like to change your database location setting?");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showLoadError) {
|
||||||
|
if (QMessageBox::critical(this, QCoreApplication::translate("DlgSettings", "Error"), loadErrorMessage,
|
||||||
|
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!QDir(SettingsCache::instance().paths().getDeckPath()).exists() ||
|
||||||
|
SettingsCache::instance().paths().getDeckPath().isEmpty()) {
|
||||||
|
if (QMessageBox::critical(this, QCoreApplication::translate("DlgSettings", "Error"),
|
||||||
|
QCoreApplication::translate(
|
||||||
|
"DlgSettings", "The path to your deck directory is invalid. Would you like to "
|
||||||
|
"go back and set the correct path?"),
|
||||||
|
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!QDir(SettingsCache::instance().paths().getPicsPath()).exists() ||
|
||||||
|
SettingsCache::instance().paths().getPicsPath().isEmpty()) {
|
||||||
|
if (QMessageBox::critical(
|
||||||
|
this, QCoreApplication::translate("DlgSettings", "Error"),
|
||||||
|
QCoreApplication::translate("DlgSettings", "The path to your card pictures directory is invalid. "
|
||||||
|
"Would you like to go back and set the correct path?"),
|
||||||
|
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return close();
|
||||||
|
}
|
||||||
46
cockatrice/src/interface/widgets/tabs/tab_settings.h
Normal file
46
cockatrice/src/interface/widgets/tabs/tab_settings.h
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
/**
|
||||||
|
* @file tab_settings.h
|
||||||
|
* @brief Settings tab hosting the shared SettingsView
|
||||||
|
* @ingroup Tabs
|
||||||
|
*/
|
||||||
|
#ifndef TAB_SETTINGS_H
|
||||||
|
#define TAB_SETTINGS_H
|
||||||
|
|
||||||
|
#include "tab.h"
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <qtmetamacros.h>
|
||||||
|
|
||||||
|
class SettingsView;
|
||||||
|
class TabSupervisor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Singleton settings tab owned by the TabSupervisor
|
||||||
|
*
|
||||||
|
* Thin Tab frame around SettingsView: page selection, tab title and the close
|
||||||
|
* validation live here. All settings content is owned by SettingsView.
|
||||||
|
*/
|
||||||
|
class TabSettings : public Tab
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
private:
|
||||||
|
SettingsView *settingsView;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit TabSettings(TabSupervisor *_tabSupervisor, int pageIndex = -1);
|
||||||
|
/** @brief Selects the given SettingsView page (range-checked, no-op when out of range) */
|
||||||
|
void setTab(int pageIndex);
|
||||||
|
/** @brief The hosted settings content */
|
||||||
|
[[nodiscard]] SettingsView *getSettingsView() const
|
||||||
|
{
|
||||||
|
return settingsView;
|
||||||
|
}
|
||||||
|
void retranslateUi() override;
|
||||||
|
[[nodiscard]] QString getTabText() const override
|
||||||
|
{
|
||||||
|
return tr("Settings");
|
||||||
|
}
|
||||||
|
bool closeRequest() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TAB_SETTINGS_H
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
#include "tab_report.h"
|
#include "tab_report.h"
|
||||||
#include "tab_room.h"
|
#include "tab_room.h"
|
||||||
#include "tab_server.h"
|
#include "tab_server.h"
|
||||||
|
#include "tab_settings.h"
|
||||||
#include "tab_visual_database_display.h"
|
#include "tab_visual_database_display.h"
|
||||||
#include "user_level.h"
|
#include "user_level.h"
|
||||||
#include "visual_deck_editor/tab_deck_editor_visual.h"
|
#include "visual_deck_editor/tab_deck_editor_visual.h"
|
||||||
|
|
@ -154,9 +155,9 @@ void CloseButton::paintEvent(QPaintEvent * /*event*/)
|
||||||
|
|
||||||
TabSupervisor::TabSupervisor(AbstractClient *_client, QMenu *tabsMenu, QWidget *parent)
|
TabSupervisor::TabSupervisor(AbstractClient *_client, QMenu *tabsMenu, QWidget *parent)
|
||||||
: QTabWidget(parent), userInfo(nullptr), client(_client), tabsMenu(tabsMenu), tabHome(nullptr),
|
: QTabWidget(parent), userInfo(nullptr), client(_client), tabsMenu(tabsMenu), tabHome(nullptr),
|
||||||
tabVisualDeckStorage(nullptr), tabServer(nullptr), tabAccount(nullptr), tabDeckStorage(nullptr),
|
tabVisualDeckStorage(nullptr), tabServer(nullptr), tabSettings(nullptr), tabAccount(nullptr),
|
||||||
tabReplays(nullptr), tabAdmin(nullptr), tabCardArtRules(nullptr), tabLog(nullptr), tabReport(nullptr),
|
tabDeckStorage(nullptr), tabReplays(nullptr), tabAdmin(nullptr), tabCardArtRules(nullptr), tabLog(nullptr),
|
||||||
tabModeration(nullptr), tabDeveloper(nullptr), isLocalGame(false)
|
tabReport(nullptr), tabModeration(nullptr), tabDeveloper(nullptr), isLocalGame(false)
|
||||||
{
|
{
|
||||||
setElideMode(Qt::ElideRight);
|
setElideMode(Qt::ElideRight);
|
||||||
setMovable(true);
|
setMovable(true);
|
||||||
|
|
@ -293,6 +294,7 @@ void TabSupervisor::retranslateUi()
|
||||||
// tabs
|
// tabs
|
||||||
QList<Tab *> tabs;
|
QList<Tab *> tabs;
|
||||||
tabs.append(tabServer);
|
tabs.append(tabServer);
|
||||||
|
tabs.append(tabSettings);
|
||||||
tabs.append(tabReplays);
|
tabs.append(tabReplays);
|
||||||
tabs.append(tabDeckStorage);
|
tabs.append(tabDeckStorage);
|
||||||
tabs.append(tabAdmin);
|
tabs.append(tabAdmin);
|
||||||
|
|
@ -753,6 +755,25 @@ void TabSupervisor::openTabServer()
|
||||||
aTabServer->setChecked(true);
|
aTabServer->setChecked(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Opens the singleton settings tab, creating it on first use
|
||||||
|
*
|
||||||
|
* @param pageIndex Initial SettingsView page, or -1 to keep the current page
|
||||||
|
* @return The settings tab
|
||||||
|
*/
|
||||||
|
TabSettings *TabSupervisor::openTabSettings(int pageIndex)
|
||||||
|
{
|
||||||
|
if (!tabSettings) {
|
||||||
|
tabSettings = new TabSettings(this, pageIndex);
|
||||||
|
myAddTab(tabSettings, nullptr);
|
||||||
|
connect(tabSettings, &QObject::destroyed, this, [this] { tabSettings = nullptr; });
|
||||||
|
} else if (pageIndex >= 0) {
|
||||||
|
tabSettings->setTab(pageIndex);
|
||||||
|
}
|
||||||
|
setCurrentWidget(tabSettings);
|
||||||
|
return tabSettings;
|
||||||
|
}
|
||||||
|
|
||||||
void TabSupervisor::actTabAccount(bool checked)
|
void TabSupervisor::actTabAccount(bool checked)
|
||||||
{
|
{
|
||||||
SettingsCache::instance().tabs().setTabAccountOpen(checked);
|
SettingsCache::instance().tabs().setTabAccountOpen(checked);
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ class UserListManager;
|
||||||
class AbstractClient;
|
class AbstractClient;
|
||||||
class Tab;
|
class Tab;
|
||||||
class TabServer;
|
class TabServer;
|
||||||
|
class TabSettings;
|
||||||
class TabRoom;
|
class TabRoom;
|
||||||
class TabHome;
|
class TabHome;
|
||||||
class TabGame;
|
class TabGame;
|
||||||
|
|
@ -108,6 +109,7 @@ private:
|
||||||
TabHome *tabHome;
|
TabHome *tabHome;
|
||||||
TabDeckStorageVisual *tabVisualDeckStorage;
|
TabDeckStorageVisual *tabVisualDeckStorage;
|
||||||
TabServer *tabServer;
|
TabServer *tabServer;
|
||||||
|
TabSettings *tabSettings;
|
||||||
TabAccount *tabAccount;
|
TabAccount *tabAccount;
|
||||||
TabDeckStorage *tabDeckStorage;
|
TabDeckStorage *tabDeckStorage;
|
||||||
TabReplays *tabReplays;
|
TabReplays *tabReplays;
|
||||||
|
|
@ -214,6 +216,7 @@ public slots:
|
||||||
void actTabVisualDeckStorage(bool checked);
|
void actTabVisualDeckStorage(bool checked);
|
||||||
void actTabReplays(bool checked);
|
void actTabReplays(bool checked);
|
||||||
void openTabServer();
|
void openTabServer();
|
||||||
|
TabSettings *openTabSettings(int pageIndex = -1);
|
||||||
void addRoomTab(const ServerInfo_Room &info, bool setCurrent);
|
void addRoomTab(const ServerInfo_Room &info, bool setCurrent);
|
||||||
void openTabPublicDecks(const QString &userName);
|
void openTabPublicDecks(const QString &userName);
|
||||||
private slots:
|
private slots:
|
||||||
|
|
|
||||||
|
|
@ -26,14 +26,15 @@
|
||||||
#include "../interface/widgets/dialogs/dlg_edit_tokens.h"
|
#include "../interface/widgets/dialogs/dlg_edit_tokens.h"
|
||||||
#include "../interface/widgets/dialogs/dlg_local_game_options.h"
|
#include "../interface/widgets/dialogs/dlg_local_game_options.h"
|
||||||
#include "../interface/widgets/dialogs/dlg_manage_sets.h"
|
#include "../interface/widgets/dialogs/dlg_manage_sets.h"
|
||||||
#include "../interface/widgets/dialogs/dlg_settings.h"
|
|
||||||
#include "../interface/widgets/dialogs/dlg_startup_card_check.h"
|
#include "../interface/widgets/dialogs/dlg_startup_card_check.h"
|
||||||
#include "../interface/widgets/dialogs/dlg_tip_of_the_day.h"
|
#include "../interface/widgets/dialogs/dlg_tip_of_the_day.h"
|
||||||
#include "../interface/widgets/dialogs/dlg_update.h"
|
#include "../interface/widgets/dialogs/dlg_update.h"
|
||||||
#include "../interface/widgets/dialogs/dlg_view_log.h"
|
#include "../interface/widgets/dialogs/dlg_view_log.h"
|
||||||
|
#include "../interface/widgets/dialogs/settings_view.h"
|
||||||
#include "../interface/widgets/onboarding/first_run_wizard.h"
|
#include "../interface/widgets/onboarding/first_run_wizard.h"
|
||||||
#include "../interface/widgets/settings_page/general_settings_page.h"
|
#include "../interface/widgets/settings_page/general_settings_page.h"
|
||||||
#include "../interface/widgets/tabs/tab_server.h"
|
#include "../interface/widgets/tabs/tab_server.h"
|
||||||
|
#include "../interface/widgets/tabs/tab_settings.h"
|
||||||
#include "../interface/widgets/tabs/tab_supervisor.h"
|
#include "../interface/widgets/tabs/tab_supervisor.h"
|
||||||
#include "../main.h"
|
#include "../main.h"
|
||||||
#include "abstract_client.h"
|
#include "abstract_client.h"
|
||||||
|
|
@ -271,10 +272,13 @@ void MainWindow::actFullScreen(bool checked)
|
||||||
|
|
||||||
void MainWindow::actSettings()
|
void MainWindow::actSettings()
|
||||||
{
|
{
|
||||||
DlgSettings dlg(this);
|
TabSettings *settingsTab = tabSupervisor->openTabSettings();
|
||||||
auto *generalPage = qobject_cast<GeneralSettingsPage *>(dlg.page(DlgSettings::GeneralPage));
|
auto *generalPage =
|
||||||
connect(generalPage, &GeneralSettingsPage::cardDatabaseUpdateRequested, this, &MainWindow::actCheckCardUpdates);
|
qobject_cast<GeneralSettingsPage *>(settingsTab->getSettingsView()->page(SettingsView::GeneralPage));
|
||||||
dlg.exec();
|
if (generalPage) {
|
||||||
|
connect(generalPage, &GeneralSettingsPage::cardDatabaseUpdateRequested, this, &MainWindow::actCheckCardUpdates,
|
||||||
|
Qt::UniqueConnection);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::actExit()
|
void MainWindow::actExit()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue