#include "tab_deck_editor.h" #include "../../../client/settings/cache_settings.h" #include "../deck_editor/deck_state_manager.h" #include "../filters/filter_builder.h" #include "../interface/pixel_map_generator.h" #include "../interface/widgets/cards/card_info_frame_widget.h" #include "../interface/widgets/deck_editor/deck_editor_filter_dock_widget.h" #include "../interface/widgets/menus/deck_editor_menu.h" #include "tab_supervisor.h" #include #include #include #include #include #include #include #include #include #include #include #include #include /** * @brief Constructs a new TabDeckEditor object. * Sets up menus, translations, shortcuts, and loads the layout. * @param _tabSupervisor Pointer to parent TabSupervisor. */ TabDeckEditor::TabDeckEditor(TabSupervisor *_tabSupervisor) : AbstractTabDeckEditor(_tabSupervisor) { setObjectName("TabDeckEditor"); TabDeckEditor::createMenus(); installEventFilter(this); TabDeckEditor::retranslateUi(); TabDeckEditor::refreshShortcuts(); TabDeckEditor::loadLayout(); } /** * @brief Creates menus for deck editing and view customization. * * Adds DeckEditorMenu, view menus, and actions for dock visibility and floating. */ void TabDeckEditor::createMenus() { deckMenu = new DeckEditorMenu(this); addTabMenu(deckMenu); viewMenu = new QMenu(this); registerDockWidget(cardInfoDockWidget); registerDockWidget(cardDatabaseDockWidget); registerDockWidget(deckDockWidget); registerDockWidget(filterDockWidget); registerDockWidget(printingSelectorDockWidget); if (SettingsCache::instance().getOverrideAllCardArtWithPersonalPreference()) { dockToActions[printingSelectorDockWidget].menu->setEnabled(false); } connect(&SettingsCache::instance(), &SettingsCache::overrideAllCardArtWithPersonalPreferenceChanged, this, [this](bool enabled) { dockToActions[printingSelectorDockWidget].menu->setEnabled(!enabled); }); viewMenu->addSeparator(); aResetLayout = viewMenu->addAction(QString()); connect(aResetLayout, &QAction::triggered, this, &TabDeckEditor::restartLayout); viewMenu->addAction(aResetLayout); deckMenu->setSaveStatus(false); addTabMenu(viewMenu); } /** * @brief Returns the text to display in the tab. * Prepends "*" if the deck is modified. * @return Tab text including modified mark. */ QString TabDeckEditor::getTabText() const { QString result = tr("Deck: %1").arg(deckStateManager->getSimpleDeckName()); if (deckStateManager->isModified()) result.prepend("* "); return result; } /** @brief Updates text of menus and actions for localization. */ void TabDeckEditor::retranslateUi() { deckMenu->retranslateUi(); cardInfoDockWidget->retranslateUi(); cardDatabaseDockWidget->retranslateUi(); deckDockWidget->retranslateUi(); filterDockWidget->retranslateUi(); printingSelectorDockWidget->retranslateUi(); viewMenu->setTitle(tr("&View")); dockToActions[cardInfoDockWidget].menu->setTitle(tr("Card Info")); dockToActions[cardDatabaseDockWidget].menu->setTitle(tr("Card Database")); dockToActions[deckDockWidget].menu->setTitle(tr("Deck")); dockToActions[filterDockWidget].menu->setTitle(tr("Filters")); dockToActions[printingSelectorDockWidget].menu->setTitle(tr("Printing")); for (auto &actions : dockToActions.values()) { actions.aVisible->setText(tr("Visible")); actions.aFloating->setText(tr("Floating")); } aResetLayout->setText(tr("Reset layout")); } /** @brief Refreshes shortcuts for deck editor menu actions. */ void TabDeckEditor::refreshShortcuts() { ShortcutsSettings &shortcuts = SettingsCache::instance().shortcuts(); aResetLayout->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aResetLayout")); } /** * @brief Displays the printing selector dock with the current card. */ void TabDeckEditor::showPrintingSelector() { printingSelectorDockWidget->printingSelector->setCard(cardInfoDockWidget->cardInfo->getCard().getCardPtr()); printingSelectorDockWidget->printingSelector->updateDisplay(); dockToActions[printingSelectorDockWidget].aVisible->setChecked(true); printingSelectorDockWidget->setVisible(true); } /** * @brief Loads deck editor layout from settings or resets to default. */ void TabDeckEditor::loadLayout() { LayoutsSettings &layouts = SettingsCache::instance().layouts(); auto &layoutState = layouts.getDeckEditorLayoutState(); if (layoutState.isNull()) restartLayout(); else { restoreState(layoutState); restoreGeometry(layouts.getDeckEditorGeometry()); } if (SettingsCache::instance().getOverrideAllCardArtWithPersonalPreference()) { if (!printingSelectorDockWidget->isHidden()) { printingSelectorDockWidget->setHidden(true); dockToActions[printingSelectorDockWidget].aVisible->setChecked(true); } } for (auto it = dockToActions.begin(); it != dockToActions.end(); ++it) { QDockWidget *dockWidget = it.key(); const DockActions &actions = it.value(); actions.aVisible->setChecked(!dockWidget->isHidden()); actions.aFloating->setEnabled(actions.aVisible->isChecked()); actions.aFloating->setChecked(dockWidget->isFloating()); } // special case for cardDatabaseDock auto &actions = dockToActions[cardDatabaseDockWidget]; actions.aFloating->setChecked(actions.aVisible->isChecked()); cardInfoDockWidget->setMinimumSize(layouts.getDeckEditorCardSize()); cardInfoDockWidget->setMaximumSize(layouts.getDeckEditorCardSize()); filterDockWidget->setMinimumSize(layouts.getDeckEditorFilterSize()); filterDockWidget->setMaximumSize(layouts.getDeckEditorFilterSize()); deckDockWidget->setMinimumSize(layouts.getDeckEditorDeckSize()); deckDockWidget->setMaximumSize(layouts.getDeckEditorDeckSize()); printingSelectorDockWidget->setMinimumSize(layouts.getDeckEditorPrintingSelectorSize()); printingSelectorDockWidget->setMaximumSize(layouts.getDeckEditorPrintingSelectorSize()); QTimer::singleShot(100, this, &TabDeckEditor::freeDocksSize); } /** * @brief Resets all dock widgets to default layout. */ void TabDeckEditor::restartLayout() { // Update menu checkboxes for (auto it = dockToActions.begin(); it != dockToActions.end(); ++it) { QDockWidget *dockWidget = it.key(); const DockActions &actions = it.value(); actions.aVisible->setEnabled(true); actions.aFloating->setEnabled(false); // Show/hide and reset floating dockWidget->setVisible(true); dockWidget->setFloating(false); } // Printing selector special case dockToActions[printingSelectorDockWidget].aVisible->setChecked( !SettingsCache::instance().getOverrideAllCardArtWithPersonalPreference()); printingSelectorDockWidget->setVisible(!SettingsCache::instance().getOverrideAllCardArtWithPersonalPreference()); addDockWidget(Qt::LeftDockWidgetArea, cardDatabaseDockWidget); addDockWidget(Qt::RightDockWidgetArea, deckDockWidget); addDockWidget(Qt::RightDockWidgetArea, cardInfoDockWidget); addDockWidget(Qt::RightDockWidgetArea, filterDockWidget); addDockWidget(Qt::RightDockWidgetArea, printingSelectorDockWidget); splitDockWidget(cardInfoDockWidget, printingSelectorDockWidget, Qt::Horizontal); splitDockWidget(printingSelectorDockWidget, deckDockWidget, Qt::Horizontal); splitDockWidget(cardInfoDockWidget, printingSelectorDockWidget, Qt::Horizontal); splitDockWidget(cardInfoDockWidget, filterDockWidget, Qt::Vertical); QTimer::singleShot(100, this, &TabDeckEditor::freeDocksSize); } /** @brief Frees dock sizes to allow flexible resizing. */ void TabDeckEditor::freeDocksSize() { const QSize minSize(100, 100); const QSize maxSize(5000, 5000); for (auto dockWidget : dockToActions.keys()) { dockWidget->setMinimumSize(minSize); dockWidget->setMaximumSize(maxSize); } } /** @brief Handles dock visibility toggling from menu actions. */ void TabDeckEditor::dockVisibleTriggered() { QObject *o = sender(); for (auto it = dockToActions.begin(); it != dockToActions.end(); ++it) { QDockWidget *dockWidget = it.key(); const DockActions &actions = it.value(); if (o == actions.aVisible) { dockWidget->setHidden(!actions.aVisible->isChecked()); actions.aFloating->setEnabled(actions.aVisible->isChecked()); return; } } } /** @brief Handles dock floating toggling from menu actions. */ void TabDeckEditor::dockFloatingTriggered() { QObject *o = sender(); for (auto it = dockToActions.begin(); it != dockToActions.end(); ++it) { QDockWidget *dockWidget = it.key(); const DockActions &actions = it.value(); if (o == actions.aFloating) { dockWidget->setFloating(actions.aFloating->isChecked()); return; } } } /** @brief Syncs menu state with dock floating changes. */ void TabDeckEditor::dockTopLevelChanged(bool topLevel) { QObject *o = sender(); auto dockWidget = qobject_cast(o); if (dockToActions.contains(dockWidget)) { DockActions actions = dockToActions.value(dockWidget); actions.aFloating->setChecked(topLevel); } } /** * @brief Handles close/hide events to update menu state and save layout. * @param o Object sending the event. * @param e Event. * @return Always returns false. */ bool TabDeckEditor::eventFilter(QObject *o, QEvent *e) { if (e->type() == QEvent::Close) { auto dockWidget = qobject_cast(o); if (dockToActions.contains(dockWidget)) { DockActions actions = dockToActions.value(dockWidget); actions.aVisible->setChecked(false); actions.aFloating->setEnabled(false); } } if (o == this && e->type() == QEvent::Hide) { LayoutsSettings &layouts = SettingsCache::instance().layouts(); layouts.setDeckEditorLayoutState(saveState()); layouts.setDeckEditorGeometry(saveGeometry()); layouts.setDeckEditorCardSize(cardInfoDockWidget->size()); layouts.setDeckEditorFilterSize(filterDockWidget->size()); layouts.setDeckEditorDeckSize(deckDockWidget->size()); layouts.setDeckEditorPrintingSelectorSize(printingSelectorDockWidget->size()); } return false; }