mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-22 09:35:08 -07:00
[DeckShare] Create temporary share links for local and server decks
This commit is contained in:
parent
45fec7fc74
commit
d91fe34d20
26 changed files with 967 additions and 15 deletions
|
|
@ -19,6 +19,7 @@
|
|||
#include "../interface/widgets/dialogs/dlg_load_deck.h"
|
||||
#include "../interface/widgets/dialogs/dlg_load_deck_from_clipboard.h"
|
||||
#include "../interface/widgets/dialogs/dlg_load_deck_from_website.h"
|
||||
#include "../interface/widgets/dialogs/dlg_share_deck.h"
|
||||
#include "../utility/visibility_change_listener.h"
|
||||
#include "tab_supervisor.h"
|
||||
|
||||
|
|
@ -382,6 +383,20 @@ bool AbstractTabDeckEditor::actSaveDeckAs()
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Opens the deck share dialog with the current deck preselected.
|
||||
*/
|
||||
void AbstractTabDeckEditor::actShareDeck()
|
||||
{
|
||||
const QSharedPointer<DeckList> deck = deckStateManager->getDeckListShared();
|
||||
if (deck->isBlankDeck()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DlgShareDeck shareDialog(tabSupervisor->getClient(), deck, this);
|
||||
shareDialog.exec();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Callback for remote deck save completion.
|
||||
* @param response Server response.
|
||||
|
|
|
|||
|
|
@ -214,6 +214,9 @@ protected slots:
|
|||
/** @brief Saves the current deck under a new name. */
|
||||
virtual bool actSaveDeckAs();
|
||||
|
||||
/** @brief Opens the deck share dialog for the current deck. */
|
||||
void actShareDeck();
|
||||
|
||||
/** @brief Loads a deck from the clipboard. */
|
||||
virtual void actLoadDeckFromClipboard();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,20 +1,31 @@
|
|||
#include "tab_deck_storage.h"
|
||||
|
||||
#include "../../../client/settings/cache_settings.h"
|
||||
#include "../../../main.h"
|
||||
#include "../../deck_loader/deck_loader.h"
|
||||
#include "../../pixel_map_generator.h"
|
||||
#include "../deck_share/share_bar_widget.h"
|
||||
#include "../interface/widgets/server/remote/remote_decklist_tree_widget.h"
|
||||
#include "../interface/widgets/utility/get_text_with_max.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include <QDesktopServices>
|
||||
#include <QFileSystemModel>
|
||||
#include <QGroupBox>
|
||||
#include <QGuiApplication>
|
||||
#include <QHBoxLayout>
|
||||
#include <QHeaderView>
|
||||
#include <QInputDialog>
|
||||
#include <QLineEdit>
|
||||
#include <QMainWindow>
|
||||
#include <QMessageBox>
|
||||
#include <QStatusBar>
|
||||
#include <QSystemTrayIcon>
|
||||
#include <QTimeZone>
|
||||
#include <QToolBar>
|
||||
#include <QTreeView>
|
||||
#include <QUrl>
|
||||
|
|
@ -24,9 +35,11 @@
|
|||
#include <libcockatrice/protocol/pb/command_deck_del_dir.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_deck_download.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_deck_new_dir.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_deck_share_create.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_deck_upload.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response_deck_download.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response_deck_share_create.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response_deck_upload.pb.h>
|
||||
#include <libcockatrice/protocol/pending_command.h>
|
||||
#include <libcockatrice/settings/paths_settings.h>
|
||||
|
|
@ -92,8 +105,17 @@ TabDeckStorage::TabDeckStorage(TabSupervisor *_tabSupervisor,
|
|||
serverDirView = new RemoteDeckList_TreeWidget(client);
|
||||
|
||||
connect(serverDirView, &QTreeView::doubleClicked, this, &TabDeckStorage::actRemoteDoubleClick);
|
||||
connect(serverDirView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
||||
[this] { onServerSelectionChanged(); });
|
||||
|
||||
// Share bar for creating a share link from the selected server decks/folders.
|
||||
shareBar = new ShareBarWidget(this);
|
||||
connect(shareBar, &ShareBarWidget::createRequested, this, &TabDeckStorage::actShareSelection);
|
||||
connect(shareBar, &ShareBarWidget::cancelRequested, this, &TabDeckStorage::cancelShareDecks);
|
||||
shareBar->setVisible(false);
|
||||
|
||||
QVBoxLayout *rightVbox = new QVBoxLayout;
|
||||
rightVbox->addWidget(shareBar);
|
||||
rightVbox->addWidget(serverDirView);
|
||||
rightVbox->addLayout(rightToolBarLayout);
|
||||
rightGroupBox = new QGroupBox;
|
||||
|
|
@ -139,6 +161,10 @@ TabDeckStorage::TabDeckStorage(TabSupervisor *_tabSupervisor,
|
|||
aDeleteRemoteDeck->setIcon(themePixmap(QStringLiteral("icons/remove_row")));
|
||||
connect(aDeleteRemoteDeck, &QAction::triggered, this, &TabDeckStorage::actDeleteRemoteDeck);
|
||||
|
||||
aShareDecks = new QAction(this);
|
||||
aShareDecks->setIcon(QPixmap("theme:icons/share"));
|
||||
connect(aShareDecks, &QAction::triggered, this, &TabDeckStorage::actShareDecks);
|
||||
|
||||
// Add actions to toolbars
|
||||
leftToolBar->addAction(aOpenLocalDeck);
|
||||
leftToolBar->addAction(aRenameLocal);
|
||||
|
|
@ -150,6 +176,7 @@ TabDeckStorage::TabDeckStorage(TabSupervisor *_tabSupervisor,
|
|||
|
||||
rightToolBar->addAction(aOpenRemoteDeck);
|
||||
rightToolBar->addAction(aDownload);
|
||||
rightToolBar->addAction(aShareDecks);
|
||||
rightToolBar->addAction(aNewFolder);
|
||||
rightToolBar->addAction(aDeleteRemoteDeck);
|
||||
|
||||
|
|
@ -178,7 +205,9 @@ void TabDeckStorage::retranslateUi()
|
|||
aNewFolder->setText(tr("New folder"));
|
||||
aDeleteLocalDeck->setText(tr("Delete"));
|
||||
aDeleteRemoteDeck->setText(tr("Delete"));
|
||||
aShareDecks->setText(tr("Share decks"));
|
||||
aOpenDecksFolder->setText(tr("Open decks folder"));
|
||||
shareBar->retranslateUi();
|
||||
}
|
||||
|
||||
QString TabDeckStorage::getTargetPath() const
|
||||
|
|
@ -626,3 +655,120 @@ void TabDeckStorage::deleteFolderFinished(const Response &response, const Comman
|
|||
serverDirView->removeNode(toDelete);
|
||||
}
|
||||
}
|
||||
|
||||
void TabDeckStorage::actShareDecks()
|
||||
{
|
||||
setShareModeEnabled(true);
|
||||
}
|
||||
|
||||
void TabDeckStorage::cancelShareDecks()
|
||||
{
|
||||
setShareModeEnabled(false);
|
||||
}
|
||||
|
||||
void TabDeckStorage::setShareModeEnabled(bool enabled)
|
||||
{
|
||||
shareBar->setVisible(enabled);
|
||||
if (enabled) {
|
||||
shareBar->setName(tr("Shared decks"));
|
||||
onServerSelectionChanged();
|
||||
shareBar->focusName();
|
||||
} else {
|
||||
serverDirView->clearSelection();
|
||||
}
|
||||
}
|
||||
|
||||
void TabDeckStorage::onServerSelectionChanged()
|
||||
{
|
||||
if (!shareBar->isVisible()) {
|
||||
return;
|
||||
}
|
||||
const auto selection = serverDirView->getCurrentSelection();
|
||||
int folders = 0;
|
||||
int files = 0;
|
||||
for (const auto *node : selection) {
|
||||
if (dynamic_cast<const RemoteDeckList_TreeModel::DirectoryNode *>(node)) {
|
||||
++folders;
|
||||
} else {
|
||||
++files;
|
||||
}
|
||||
}
|
||||
QStringList parts;
|
||||
if (folders > 0) {
|
||||
parts << tr("%n folder(s)", "", folders);
|
||||
}
|
||||
if (files > 0) {
|
||||
parts << tr("%n deck(s)", "", files);
|
||||
}
|
||||
shareBar->setCountText(parts.isEmpty() ? tr("No decks selected") : tr("Selected: %1").arg(parts.join(tr(", "))));
|
||||
}
|
||||
|
||||
void TabDeckStorage::actShareSelection()
|
||||
{
|
||||
const auto selection = serverDirView->getCurrentSelection();
|
||||
|
||||
Command_DeckShareCreate cmd;
|
||||
cmd.set_name(shareBar->name().toStdString());
|
||||
if (cmd.name().empty()) {
|
||||
cmd.set_name(tr("Shared decks").toStdString());
|
||||
}
|
||||
|
||||
// Sharing a folder is exclusive with sharing individual decks (matches the picker's rule).
|
||||
for (const auto *node : selection) {
|
||||
if (const auto *dirNode = dynamic_cast<const RemoteDeckList_TreeModel::DirectoryNode *>(node)) {
|
||||
const QString path = dirNode->getPath();
|
||||
if (path.isEmpty()) {
|
||||
continue; // the root folder cannot be shared
|
||||
}
|
||||
cmd.set_folder_path(path.toStdString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd.folder_path().empty()) {
|
||||
for (const auto *node : selection) {
|
||||
if (const auto *fileNode = dynamic_cast<const RemoteDeckList_TreeModel::FileNode *>(node)) {
|
||||
DeckShareItem *item = cmd.add_items();
|
||||
item->set_deck_id(fileNode->getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd.items_size() == 0 && cmd.folder_path().empty()) {
|
||||
showShareNotice(tr("Select decks to share."));
|
||||
return;
|
||||
}
|
||||
|
||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||
connect(pend, &PendingCommand::finished, this, &TabDeckStorage::shareFromTreeFinished);
|
||||
client->sendCommand(pend);
|
||||
}
|
||||
|
||||
void TabDeckStorage::shareFromTreeFinished(const Response &response, const CommandContainer & /*commandContainer*/)
|
||||
{
|
||||
if (response.response_code() != Response::RespOk) {
|
||||
qWarning() << "failed to create deck share:" << response.response_code();
|
||||
showShareNotice(tr("Failed to create the share link (server response code %1).")
|
||||
.arg(QString::number(static_cast<int>(response.response_code()))));
|
||||
return;
|
||||
}
|
||||
const Response_DeckShareCreate &resp = response.GetExtension(Response_DeckShareCreate::ext);
|
||||
const QString token = QString::fromStdString(resp.token());
|
||||
const QDateTime expiry = QDateTime::fromSecsSinceEpoch(resp.expires_at(), QTimeZone::UTC).toLocalTime();
|
||||
|
||||
const QString link = QString("cockatrice://opendeck?share=%1&hostname=%2&port=%3")
|
||||
.arg(token, client->serverName(), QString::number(client->serverPort()));
|
||||
QGuiApplication::clipboard()->setText(link);
|
||||
|
||||
showShareNotice(tr("Share link copied to the clipboard.\nExpires on %1.").arg(expiry.toString()));
|
||||
setShareModeEnabled(false);
|
||||
}
|
||||
|
||||
void TabDeckStorage::showShareNotice(const QString &message)
|
||||
{
|
||||
if (trayIcon && trayIcon->isVisible()) {
|
||||
trayIcon->showMessage(tr("Deck share"), message);
|
||||
} else if (auto *mainWindow = qobject_cast<QMainWindow *>(window())) {
|
||||
mainWindow->statusBar()->showMessage(message, 10000);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ class QTreeWidgetItem;
|
|||
class QGroupBox;
|
||||
class CommandContainer;
|
||||
class Response;
|
||||
class ShareBarWidget;
|
||||
|
||||
class TabDeckStorage : public Tab
|
||||
{
|
||||
|
|
@ -35,14 +36,19 @@ private:
|
|||
QToolBar *leftToolBar, *rightToolBar;
|
||||
RemoteDeckList_TreeWidget *serverDirView;
|
||||
QGroupBox *leftGroupBox, *rightGroupBox;
|
||||
ShareBarWidget *shareBar;
|
||||
|
||||
QAction *aOpenLocalDeck, *aRenameLocal, *aUpload, *aNewLocalFolder, *aDeleteLocalDeck;
|
||||
QAction *aOpenDecksFolder;
|
||||
QAction *aOpenRemoteDeck, *aDownload, *aNewFolder, *aDeleteRemoteDeck;
|
||||
QAction *aOpenRemoteDeck, *aDownload, *aShareDecks, *aNewFolder, *aDeleteRemoteDeck;
|
||||
QString getTargetPath() const;
|
||||
|
||||
void setRemoteEnabled(bool enabled);
|
||||
|
||||
void showShareNotice(const QString &message);
|
||||
|
||||
void setShareModeEnabled(bool enabled);
|
||||
|
||||
void uploadDeck(const QString &filePath, const QString &targetPath);
|
||||
void deleteRemoteDeck(const RemoteDeckList_TreeModel::Node *node);
|
||||
|
||||
|
|
@ -75,6 +81,12 @@ private slots:
|
|||
void actNewFolder();
|
||||
void newFolderFinished(const Response &response, const CommandContainer &commandContainer);
|
||||
|
||||
void actShareDecks();
|
||||
void actShareSelection();
|
||||
void cancelShareDecks();
|
||||
void onServerSelectionChanged();
|
||||
void shareFromTreeFinished(const Response &r, const CommandContainer &commandContainer);
|
||||
|
||||
void actDeleteRemoteDeck();
|
||||
void deleteFolderFinished(const Response &response, const CommandContainer &commandContainer);
|
||||
void deleteDeckFinished(const Response &response, const CommandContainer &commandContainer);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,23 @@
|
|||
#include "tab_deck_storage_visual.h"
|
||||
|
||||
#include "../../../../main.h"
|
||||
#include "../../../deck_loader/deck_loader.h"
|
||||
#include "../../cards/additional_info/deck_color_identity.h"
|
||||
#include "../../deck_share/deck_share_utils.h"
|
||||
#include "../../interface/widgets/visual_deck_storage/visual_deck_storage_widget.h"
|
||||
#include "../tab_supervisor.h"
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QMessageBox>
|
||||
#include <libcockatrice/protocol/pb/command_deck_del.pb.h>
|
||||
#include <QStatusBar>
|
||||
#include <QSystemTrayIcon>
|
||||
#include <QVBoxLayout>
|
||||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
#include <libcockatrice/network/client/abstract/abstract_client.h>
|
||||
#include <libcockatrice/protocol/pb/command_deck_share_create.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response_deck_share_create.pb.h>
|
||||
#include <libcockatrice/protocol/pending_command.h>
|
||||
|
||||
TabDeckStorageVisual::TabDeckStorageVisual(TabSupervisor *_tabSupervisor)
|
||||
: Tab(_tabSupervisor), visualDeckStorageWidget(new VisualDeckStorageWidget(this))
|
||||
|
|
@ -14,12 +27,42 @@ TabDeckStorageVisual::TabDeckStorageVisual(TabSupervisor *_tabSupervisor)
|
|||
&TabDeckStorageVisual::actOpenLocalDeck);
|
||||
connect(visualDeckStorageWidget, &VisualDeckStorageWidget::openDeckEditor, this,
|
||||
&TabDeckStorageVisual::openDeckEditor);
|
||||
connect(visualDeckStorageWidget, &VisualDeckStorageWidget::shareDeckRequested, this,
|
||||
&TabDeckStorageVisual::actShareDeck);
|
||||
connect(visualDeckStorageWidget, &VisualDeckStorageWidget::shareSelectionChanged, this,
|
||||
&TabDeckStorageVisual::onShareSelectionChanged);
|
||||
connect(visualDeckStorageWidget, &VisualDeckStorageWidget::shareRequested, this, [this] {
|
||||
if (shareDeckAvailable) {
|
||||
enterShareMode();
|
||||
}
|
||||
});
|
||||
|
||||
AbstractClient *client = tabSupervisor->getClient();
|
||||
connect(client, &AbstractClient::statusChanged, this, &TabDeckStorageVisual::handleConnectionChanged);
|
||||
shareDeckAvailable = (client->getStatus() == StatusLoggedIn);
|
||||
visualDeckStorageWidget->setShareAvailable(shareDeckAvailable);
|
||||
|
||||
auto *widget = new QWidget(this);
|
||||
auto *layout = new QVBoxLayout(widget);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->setSpacing(0);
|
||||
widget->setLayout(layout);
|
||||
this->setCentralWidget(widget);
|
||||
layout->addWidget(visualDeckStorageWidget);
|
||||
|
||||
shareBar = new ShareBarWidget(this);
|
||||
connect(shareBar, &ShareBarWidget::createRequested, this, &TabDeckStorageVisual::actShareSelected);
|
||||
connect(shareBar, &ShareBarWidget::cancelRequested, this, &TabDeckStorageVisual::exitShareMode);
|
||||
|
||||
layout->insertWidget(0, shareBar);
|
||||
shareBar->setVisible(false);
|
||||
|
||||
retranslateUi();
|
||||
}
|
||||
|
||||
void TabDeckStorageVisual::retranslateUi()
|
||||
{
|
||||
shareBar->retranslateUi();
|
||||
}
|
||||
|
||||
void TabDeckStorageVisual::actOpenLocalDeck(const QString &filePath)
|
||||
|
|
@ -33,3 +76,118 @@ void TabDeckStorageVisual::actOpenLocalDeck(const QString &filePath)
|
|||
|
||||
emit openDeckEditor(deckOpt.value());
|
||||
}
|
||||
|
||||
void TabDeckStorageVisual::enterShareMode(const QStringList &preselectFiles)
|
||||
{
|
||||
if (!shareDeckAvailable) {
|
||||
return; // sharing is gated on being logged in
|
||||
}
|
||||
visualDeckStorageWidget->setShareSelectable(true);
|
||||
visualDeckStorageWidget->setShareSelectedFiles(preselectFiles);
|
||||
shareBar->setName(tr("Shared decks"));
|
||||
shareBar->setVisible(true);
|
||||
updateShareHint();
|
||||
shareBar->focusName();
|
||||
}
|
||||
|
||||
void TabDeckStorageVisual::exitShareMode()
|
||||
{
|
||||
visualDeckStorageWidget->setShareSelectable(false);
|
||||
visualDeckStorageWidget->clearShareSelection();
|
||||
shareBar->setVisible(false);
|
||||
}
|
||||
|
||||
void TabDeckStorageVisual::actShareDeck(const QString &filePath)
|
||||
{
|
||||
enterShareMode({filePath});
|
||||
}
|
||||
|
||||
void TabDeckStorageVisual::onShareSelectionChanged()
|
||||
{
|
||||
if (shareBar->isVisible()) {
|
||||
updateShareHint();
|
||||
}
|
||||
}
|
||||
|
||||
void TabDeckStorageVisual::updateShareHint()
|
||||
{
|
||||
const int count = visualDeckStorageWidget->selectedFilePaths().size();
|
||||
shareBar->setCountText(tr("%n deck(s)", "", count));
|
||||
if (count == 0) {
|
||||
shareBar->setHintText(tr("Click deck tiles to select the decks you want to share."), true);
|
||||
} else {
|
||||
shareBar->setHintText(tr("%n deck(s) selected. Create the link to share %1 with other players.", "", count)
|
||||
.arg(count == 1 ? tr("it") : tr("them")),
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
void TabDeckStorageVisual::actShareSelected()
|
||||
{
|
||||
const QStringList filePaths = visualDeckStorageWidget->selectedFilePaths();
|
||||
if (filePaths.isEmpty()) {
|
||||
QMessageBox::warning(this, tr("Share decks"), tr("Select at least one deck to share."));
|
||||
return;
|
||||
}
|
||||
|
||||
Command_DeckShareCreate cmd;
|
||||
cmd.set_name(shareBar->name().toStdString());
|
||||
if (cmd.name().empty()) {
|
||||
cmd.set_name(tr("Shared decks").toStdString());
|
||||
}
|
||||
|
||||
for (const QString &filePath : filePaths) {
|
||||
std::optional<LoadedDeck> deckOpt =
|
||||
DeckLoader::loadFromFile(filePath, DeckFileFormat::getFormatFromName(filePath), true);
|
||||
if (!deckOpt) {
|
||||
QMessageBox::warning(this, tr("Share decks"), tr("Unable to load deck file %1").arg(filePath));
|
||||
return;
|
||||
}
|
||||
DeckShareItem *item = cmd.add_items();
|
||||
item->set_deck_list(deckOpt->deckList.writeToString_Native().toStdString());
|
||||
item->set_color_identity(getDeckColorIdentity(deckOpt->deckList).toStdString());
|
||||
}
|
||||
|
||||
PendingCommand *pend = tabSupervisor->getClient()->prepareSessionCommand(cmd);
|
||||
connect(pend, &PendingCommand::finished, this, &TabDeckStorageVisual::shareFinished);
|
||||
tabSupervisor->getClient()->sendCommand(pend);
|
||||
}
|
||||
|
||||
void TabDeckStorageVisual::shareFinished(const Response &response, const CommandContainer & /*commandContainer*/)
|
||||
{
|
||||
if (response.response_code() != Response::RespOk) {
|
||||
showShareNotice(tr("Failed to create the share link (server response code %1).")
|
||||
.arg(QString::number(static_cast<int>(response.response_code()))));
|
||||
exitShareMode();
|
||||
return;
|
||||
}
|
||||
|
||||
const Response_DeckShareCreate &resp = response.GetExtension(Response_DeckShareCreate::ext);
|
||||
const QString token = QString::fromStdString(resp.token());
|
||||
const QDateTime expiry = QDateTime::fromSecsSinceEpoch(resp.expires_at(), QTimeZone::UTC);
|
||||
|
||||
const QString link = DeckShareUtils::buildShareLink(tabSupervisor->getClient(), token);
|
||||
DeckShareUtils::copyShareLinkToClipboard(link);
|
||||
|
||||
showShareNotice(
|
||||
tr("Share link copied to the clipboard.\nExpires on %1.").arg(DeckShareUtils::formatShareExpiry(expiry)));
|
||||
exitShareMode();
|
||||
}
|
||||
|
||||
void TabDeckStorageVisual::handleConnectionChanged(ClientStatus status)
|
||||
{
|
||||
shareDeckAvailable = (status == StatusLoggedIn);
|
||||
visualDeckStorageWidget->setShareAvailable(shareDeckAvailable);
|
||||
if (!shareDeckAvailable && shareBar->isVisible()) {
|
||||
exitShareMode();
|
||||
}
|
||||
}
|
||||
|
||||
void TabDeckStorageVisual::showShareNotice(const QString &message)
|
||||
{
|
||||
if (trayIcon && trayIcon->isVisible()) {
|
||||
trayIcon->showMessage(tr("Deck share"), message);
|
||||
} else if (auto *mainWindow = qobject_cast<QMainWindow *>(window())) {
|
||||
mainWindow->statusBar()->showMessage(message, 10000);
|
||||
}
|
||||
}
|
||||
|
|
@ -7,8 +7,12 @@
|
|||
#ifndef TAB_DECK_STORAGE_VISUAL_H
|
||||
#define TAB_DECK_STORAGE_VISUAL_H
|
||||
|
||||
#include "../../deck_share/share_bar_widget.h"
|
||||
#include "../tab.h"
|
||||
|
||||
#include <QStringList>
|
||||
#include <libcockatrice/network/client/abstract/abstract_client.h>
|
||||
|
||||
struct LoadedDeck;
|
||||
class AbstractClient;
|
||||
class CommandContainer;
|
||||
|
|
@ -27,22 +31,49 @@ class TabDeckStorageVisual final : public Tab
|
|||
Q_OBJECT
|
||||
public:
|
||||
explicit TabDeckStorageVisual(TabSupervisor *_tabSupervisor);
|
||||
void retranslateUi() override
|
||||
{
|
||||
}
|
||||
void retranslateUi() override;
|
||||
|
||||
[[nodiscard]] QString getTabText() const override
|
||||
{
|
||||
return tr("Visual Deck Storage");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enters share-selection mode, optionally preselecting the given deck files.
|
||||
*/
|
||||
void enterShareMode(const QStringList &preselectFiles = {});
|
||||
|
||||
/**
|
||||
* @brief Leaves share-selection mode and clears the selection.
|
||||
*/
|
||||
void exitShareMode();
|
||||
|
||||
[[nodiscard]] bool isShareModeActive() const
|
||||
{
|
||||
return shareBar->isVisible();
|
||||
}
|
||||
|
||||
public slots:
|
||||
void actOpenLocalDeck(const QString &filePath);
|
||||
void actShareDeck(const QString &filePath);
|
||||
|
||||
signals:
|
||||
void openDeckEditor(const LoadedDeck &deck);
|
||||
|
||||
private slots:
|
||||
void actShareSelected();
|
||||
void shareFinished(const Response &response, const CommandContainer &commandContainer);
|
||||
void onShareSelectionChanged();
|
||||
void handleConnectionChanged(ClientStatus status);
|
||||
|
||||
private:
|
||||
void showShareNotice(const QString &message);
|
||||
void updateShareHint();
|
||||
|
||||
VisualDeckStorageWidget *visualDeckStorageWidget;
|
||||
|
||||
ShareBarWidget *shareBar;
|
||||
bool shareDeckAvailable = false;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue