summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/modinfodialog.cpp444
-rw-r--r--src/modinfodialog.h62
-rw-r--r--src/modinfodialogconflicts.cpp441
-rw-r--r--src/modinfodialogconflicts.h80
-rw-r--r--src/modinfodialogesps.cpp30
-rw-r--r--src/modinfodialogesps.h5
-rw-r--r--src/modinfodialogimages.cpp2
-rw-r--r--src/modinfodialogimages.h4
-rw-r--r--src/modinfodialogtextfiles.cpp17
-rw-r--r--src/modinfodialogtextfiles.h13
10 files changed, 616 insertions, 482 deletions
diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp
index c24176b3..d52103b9 100644
--- a/src/modinfodialog.cpp
+++ b/src/modinfodialog.cpp
@@ -63,20 +63,8 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
using namespace MOBase;
using namespace MOShared;
+const int max_scan_for_context_menu = 50;
-std::vector<std::unique_ptr<ModInfoDialogTab>> ModInfoDialogTab::createTabs(
- Ui::ModInfoDialog* ui)
-{
- std::vector<std::unique_ptr<ModInfoDialogTab>> v;
-
- v.push_back(std::make_unique<TextFilesTab>(ui));
- v.push_back(std::make_unique<IniFilesTab>(ui));
- v.push_back(std::make_unique<ImagesTab>(ui));
- v.push_back(std::make_unique<ESPsTab>(ui));
- v.push_back(std::make_unique<ConflictsTab>(ui));
-
- return v;
-}
bool ModInfoDialogTab::canClose()
{
@@ -93,6 +81,26 @@ void ModInfoDialogTab::restoreState(const Settings& s)
// no-op
}
+void ModInfoDialogTab::setMod(ModInfo::Ptr, MOShared::FilesOrigin*)
+{
+ // no-op
+}
+
+void ModInfoDialogTab::update()
+{
+ // no-op
+}
+
+void ModInfoDialogTab::emitOriginModified(int originID)
+{
+ emit originModified(originID);
+}
+
+void ModInfoDialogTab::emitModOpen(QString name)
+{
+ emit modOpen(name);
+}
+
class ModFileListWidget : public QListWidgetItem {
friend bool operator<(const ModFileListWidget &LHS, const ModFileListWidget &RHS);
@@ -109,20 +117,16 @@ static bool operator<(const ModFileListWidget &LHS, const ModFileListWidget &RHS
return LHS.m_SortValue < RHS.m_SortValue;
}
-// if there are more than 50 selected items in the conflict tree or filetree,
-// don't bother checking whether menu items apply to them, just show all of them
-const int max_scan_for_context_menu = 50;
-
bool canPreviewFile(
- PluginContainer* pluginContainer, bool isArchive, const QString& filename)
+ PluginContainer& pluginContainer, bool isArchive, const QString& filename)
{
if (isArchive) {
return false;
}
const auto ext = QFileInfo(filename).suffix();
- return pluginContainer->previewGenerator().previewSupported(ext);
+ return pluginContainer.previewGenerator().previewSupported(ext);
}
bool canOpenFile(bool isArchive, const QString&)
@@ -161,6 +165,18 @@ bool canUnhideFile(bool isArchive, const QString& filename)
return true;
}
+FileRenamer::RenameResults hideFile(FileRenamer& renamer, const QString &oldName)
+{
+ const QString newName = oldName + ModInfo::s_HiddenExt;
+ return renamer.rename(oldName, newName);
+}
+
+FileRenamer::RenameResults unhideFile(FileRenamer& renamer, const QString &oldName)
+{
+ QString newName = oldName.left(oldName.length() - ModInfo::s_HiddenExt.length());
+ return renamer.rename(oldName, newName);
+}
+
ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directory, bool unmanaged, OrganizerCore *organizerCore, PluginContainer *pluginContainer, QWidget *parent)
: TutorableDialog("ModInfoDialog", parent), ui(new Ui::ModInfoDialog), m_ModInfo(modInfo),
@@ -172,7 +188,20 @@ ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directo
{
ui->setupUi(this);
- m_tabs = ModInfoDialogTab::createTabs(ui);
+ m_tabs = createTabs();
+
+ for (std::size_t i=0; i<m_tabs.size(); ++i) {
+ connect(
+ m_tabs[i].get(), &ModInfoDialogTab::originModified,
+ [&](int originID){ emit originModified(originID); });
+
+ connect(
+ m_tabs[i].get(), &ModInfoDialogTab::modOpen,
+ [&](const QString& name){
+ close();
+ emit modOpen(name, static_cast<int>(i));
+ });
+ }
this->setWindowTitle(modInfo->name());
this->setWindowModality(Qt::WindowModal);
@@ -223,12 +252,6 @@ ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directo
}
}
- // refresh everything but the conflict lists, which are done in exec() because
- // they depend on restoring the state to some widgets; this refresh has to be
- // done here because some of the checks below depend on the ui to decide which
- // tabs to enable
- refreshFiles();
-
if (modInfo->hasFlag(ModInfo::FLAG_SEPARATOR))
{
ui->tabWidget->setTabEnabled(TAB_TEXTFILES, false);
@@ -283,8 +306,11 @@ ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directo
if (ui->tabWidget->currentIndex() == TAB_NEXUS) {
activateNexusTab();
}
-}
+ for (auto& tab : m_tabs) {
+ tab->setMod(m_ModInfo, m_Origin);
+ }
+}
ModInfoDialog::~ModInfoDialog()
{
@@ -301,11 +327,23 @@ ModInfoDialog::~ModInfoDialog()
delete m_Settings;
}
+std::vector<std::unique_ptr<ModInfoDialogTab>> ModInfoDialog::createTabs()
+{
+ std::vector<std::unique_ptr<ModInfoDialogTab>> v;
+
+ v.push_back(std::make_unique<TextFilesTab>(this, ui));
+ v.push_back(std::make_unique<IniFilesTab>(this, ui));
+ v.push_back(std::make_unique<ImagesTab>(this, ui));
+ v.push_back(std::make_unique<ESPsTab>(this, ui));
+ v.push_back(std::make_unique<ConflictsTab>(
+ this, ui, *m_OrganizerCore, *m_PluginContainer));
+
+ return v;
+}
int ModInfoDialog::exec()
{
- // no need to refresh the other stuff, that was done in the constructor
- refreshConflictLists(true, true);
+ refreshLists();
return TutorableDialog::exec();
}
@@ -412,17 +450,15 @@ QByteArray ModInfoDialog::saveTabState() const
void ModInfoDialog::refreshLists()
{
- refreshConflictLists(true, true);
+ for (auto& tab : m_tabs) {
+ tab->update();
+ }
+
refreshFiles();
}
void ModInfoDialog::refreshFiles()
{
- // clearing
- for (auto& tab : m_tabs) {
- tab->clear();
- }
-
if (m_RootPath.length() > 0) {
QDirIterator dirIterator(m_RootPath, QDir::Files, QDirIterator::Subdirectories);
while (dirIterator.hasNext()) {
@@ -936,7 +972,7 @@ void ModInfoDialog::on_fileTree_customContextMenuRequested(const QPoint &pos)
const QString fileName = m_FileSystemModel->fileName(m_FileSelection.at(0));
- if (!canPreviewFile(m_PluginContainer, false, fileName)) {
+ if (!canPreviewFile(*m_PluginContainer, false, fileName)) {
enablePreview = false;
}
@@ -1054,342 +1090,6 @@ void ModInfoDialog::on_primaryCategoryBox_currentIndexChanged(int index)
}
}
-FileRenamer::RenameResults ModInfoDialog::hideFile(FileRenamer& renamer, const QString &oldName)
-{
- const QString newName = oldName + ModInfo::s_HiddenExt;
- return renamer.rename(oldName, newName);
-}
-
-FileRenamer::RenameResults ModInfoDialog::unhideFile(FileRenamer& renamer, const QString &oldName)
-{
- QString newName = oldName.left(oldName.length() - ModInfo::s_HiddenExt.length());
- return renamer.rename(oldName, newName);
-}
-
-void ModInfoDialog::changeConflictItemsVisibility(
- const QList<QTreeWidgetItem*>& items, bool visible)
-{
- bool changed = false;
- bool stop = false;
-
- qDebug().nospace()
- << (visible ? "unhiding" : "hiding") << " "
- << items.size() << " conflict files";
-
- QFlags<FileRenamer::RenameFlags> flags =
- (visible ? FileRenamer::UNHIDE : FileRenamer::HIDE);
-
- if (items.size() > 1) {
- flags |= FileRenamer::MULTIPLE;
- }
-
- FileRenamer renamer(this, flags);
-
- for (const auto* item : items) {
- if (stop) {
- break;
- }
-
- const auto* ci = dynamic_cast<const ConflictItem*>(item);
- if (!ci) {
- continue;
- }
-
- auto result = FileRenamer::RESULT_CANCEL;
-
- if (visible) {
- if (!ci->canUnhide()) {
- qDebug().nospace() << "cannot unhide " << item->text(0) << ", skipping";
- continue;
- }
- result = unhideFile(renamer, ci->fileName());
-
- } else {
- if (!ci->canHide()) {
- qDebug().nospace() << "cannot hide " << item->text(0) << ", skipping";
- continue;
- }
- result = hideFile(renamer, ci->fileName());
- }
-
- switch (result) {
- case FileRenamer::RESULT_OK: {
- // will trigger a refresh at the end
- changed = true;
- break;
- }
-
- case FileRenamer::RESULT_SKIP: {
- // nop
- break;
- }
-
- case FileRenamer::RESULT_CANCEL: {
- // stop right now, but make sure to refresh if needed
- stop = true;
- break;
- }
- }
- }
-
- qDebug().nospace() << (visible ? "unhiding" : "hiding") << " conflict files done";
-
- if (changed) {
- qDebug().nospace() << "triggering refresh";
- if (m_Origin) {
- emit originModified(m_Origin->getID());
- }
- refreshLists();
- }
-}
-
-void ModInfoDialog::openConflictItems(const QList<QTreeWidgetItem*>& items)
-{
- // the menu item is only shown for a single selection, but handle all of them
- // in case this changes
- for (auto* item : items) {
- if (auto* ci=dynamic_cast<ConflictItem*>(item)) {
- m_OrganizerCore->executeFileVirtualized(this, ci->fileName());
- }
- }
-}
-
-void ModInfoDialog::previewConflictItems(const QList<QTreeWidgetItem*>& items)
-{
- // the menu item is only shown for a single selection, but handle all of them
- // in case this changes
- for (auto* item : items) {
- if (auto* ci=dynamic_cast<ConflictItem*>(item)) {
- m_OrganizerCore->previewFileWithAlternatives(this, ci->fileName());
- }
- }
-}
-
-void ModInfoDialog::on_overwriteTree_customContextMenuRequested(const QPoint &pos)
-{
- showConflictMenu(pos, ui->overwriteTree);
-}
-
-void ModInfoDialog::on_overwrittenTree_customContextMenuRequested(const QPoint &pos)
-{
- showConflictMenu(pos, ui->overwrittenTree);
-}
-
-void ModInfoDialog::on_noConflictTree_customContextMenuRequested(const QPoint &pos)
-{
- showConflictMenu(pos, ui->noConflictTree);
-}
-
-void ModInfoDialog::on_conflictsAdvancedList_customContextMenuRequested(const QPoint &pos)
-{
- showConflictMenu(pos, ui->conflictsAdvancedList);
-}
-
-void ModInfoDialog::showConflictMenu(const QPoint &pos, QTreeWidget* tree)
-{
- auto actions = createConflictMenuActions(tree->selectedItems());
-
- QMenu menu;
-
- // open
- if (actions.open) {
- connect(actions.open, &QAction::triggered, [&]{
- openConflictItems(tree->selectedItems());
- });
-
- menu.addAction(actions.open);
- }
-
- // preview
- if (actions.preview) {
- connect(actions.preview, &QAction::triggered, [&]{
- previewConflictItems(tree->selectedItems());
- });
-
- menu.addAction(actions.preview);
- }
-
- // hide
- if (actions.hide) {
- connect(actions.hide, &QAction::triggered, [&]{
- changeConflictItemsVisibility(tree->selectedItems(), false);
- });
-
- menu.addAction(actions.hide);
- }
-
- // unhide
- if (actions.unhide) {
- connect(actions.unhide, &QAction::triggered, [&]{
- changeConflictItemsVisibility(tree->selectedItems(), true);
- });
-
- menu.addAction(actions.unhide);
- }
-
- // goto
- if (actions.gotoMenu) {
- menu.addMenu(actions.gotoMenu);
-
- for (auto* a : actions.gotoActions) {
- connect(a, &QAction::triggered, [&, name=a->text()]{
- close();
- emit modOpen(name, TAB_CONFLICTS);
- });
-
- actions.gotoMenu->addAction(a);
- }
- }
-
- if (!menu.isEmpty()) {
- menu.exec(tree->viewport()->mapToGlobal(pos));
- }
-}
-
-ModInfoDialog::ConflictActions ModInfoDialog::createConflictMenuActions(
- const QList<QTreeWidgetItem*>& selection)
-{
- if (selection.empty()) {
- return {};
- }
-
- bool enableHide = true;
- bool enableUnhide = true;
- bool enableOpen = true;
- bool enablePreview = true;
- bool enableGoto = true;
-
- if (selection.size() == 1) {
- // this is a single selection
- const auto* ci = dynamic_cast<const ConflictItem*>(selection[0]);
- if (!ci) {
- return {};
- }
-
- enableHide = ci->canHide();
- enableUnhide = ci->canUnhide();
- enableOpen = ci->canOpen();
- enablePreview = ci->canPreview(m_PluginContainer);
- enableGoto = ci->hasAlts();
- }
- else {
- // this is a multiple selection, don't show open/preview so users don't open
- // a thousand files
- enableOpen = false;
- enablePreview = false;
-
- // don't bother with this on multiple selection, at least for now
- enableGoto = false;
-
- if (selection.size() < max_scan_for_context_menu) {
- // if the number of selected items is low, checking them to accurately
- // show the menu items is worth it
- enableHide = false;
- enableUnhide = false;
-
- for (const auto* item : selection) {
- if (const auto* ci=dynamic_cast<const ConflictItem*>(item)) {
- if (ci->canHide()) {
- enableHide = true;
- }
-
- if (ci->canUnhide()) {
- enableUnhide = true;
- }
-
- if (enableHide && enableUnhide && enableGoto) {
- // found all, no need to check more
- break;
- }
- }
- }
- }
- }
-
- ConflictActions actions;
-
- actions.hide = new QAction(tr("Hide"), this);
- actions.hide->setEnabled(enableHide);
-
- // note that it is possible for hidden files to appear if they override other
- // hidden files from another mod
- actions.unhide = new QAction(tr("Unhide"), this);
- actions.unhide->setEnabled(enableUnhide);
-
- actions.open = new QAction(tr("Open/Execute"), this);
- actions.open->setEnabled(enableOpen);
-
- actions.preview = new QAction(tr("Preview"), this);
- actions.preview->setEnabled(enablePreview);
-
- actions.gotoMenu = new QMenu(tr("Go to..."), this);
- actions.gotoMenu->setEnabled(enableGoto);
-
- if (enableGoto) {
- actions.gotoActions = createGotoActions(selection);
- }
-
- return actions;
-}
-
-std::vector<QAction*> ModInfoDialog::createGotoActions(const QList<QTreeWidgetItem*>& selection)
-{
- if (!m_Origin || selection.size() != 1) {
- return {};
- }
-
- const auto* item = dynamic_cast<const ConflictItem*>(selection[0]);
- if (!item) {
- return {};
- }
-
- auto file = m_Origin->findFile(item->fileIndex());
- if (!file) {
- return {};
- }
-
-
- std::vector<QString> mods;
-
- // add all alternatives
- for (const auto& alt : file->getAlternatives()) {
- const auto& o = m_Directory->getOriginByID(alt.first);
- if (o.getID() != m_Origin->getID()) {
- mods.push_back(ToQString(o.getName()));
- }
- }
-
- // add the real origin if different from this mod
- const FilesOrigin& realOrigin = m_Directory->getOriginByID(file->getOrigin());
- if (realOrigin.getID() != m_Origin->getID()) {
- mods.push_back(ToQString(realOrigin.getName()));
- }
-
- std::sort(mods.begin(), mods.end(), [](const auto& a, const auto& b) {
- return (QString::localeAwareCompare(a, b) < 0);
- });
-
- std::vector<QAction*> actions;
-
- for (const auto& name : mods) {
- actions.push_back(new QAction(name, this));
- }
-
- return actions;
-}
-
-void ModInfoDialog::on_overwrittenTree_itemDoubleClicked(QTreeWidgetItem *item, int)
-{
- if (const auto* ci=dynamic_cast<ConflictItem*>(item)) {
- const auto origin = ci->altOrigin();
-
- if (!origin.isEmpty()) {
- close();
- emit modOpen(origin, TAB_CONFLICTS);
- }
- }
-}
-
void ModInfoDialog::on_refreshButton_clicked()
{
if (m_ModInfo->getNexusID() > 0) {
diff --git a/src/modinfodialog.h b/src/modinfodialog.h
index 53b5d94a..2a3ee2d8 100644
--- a/src/modinfodialog.h
+++ b/src/modinfodialog.h
@@ -54,12 +54,11 @@ class CategoryFactory;
class TextEditor;
-class ModInfoDialogTab
+class ModInfoDialogTab : public QObject
{
-public:
- static std::vector<std::unique_ptr<ModInfoDialogTab>> createTabs(
- Ui::ModInfoDialog* ui);
+ Q_OBJECT;
+public:
ModInfoDialogTab() = default;
ModInfoDialogTab(const ModInfoDialogTab&) = delete;
ModInfoDialogTab& operator=(const ModInfoDialogTab&) = delete;
@@ -72,6 +71,17 @@ public:
virtual bool canClose();
virtual void saveState(Settings& s);
virtual void restoreState(const Settings& s);
+
+ virtual void setMod(ModInfo::Ptr mod, MOShared::FilesOrigin* origin);
+ virtual void update();
+
+signals:
+ void originModified(int originID);
+ void modOpen(QString name);
+
+protected:
+ void emitOriginModified(int originID);
+ void emitModOpen(QString name);
};
@@ -89,11 +99,14 @@ protected:
};
-bool canPreviewFile(PluginContainer* pluginContainer, bool isArchive, const QString& filename);
+bool canPreviewFile(PluginContainer& pluginContainer, bool isArchive, const QString& filename);
bool canOpenFile(bool isArchive, const QString& filename);
bool canHideFile(bool isArchive, const QString& filename);
bool canUnhideFile(bool isArchive, const QString& filename);
+FileRenamer::RenameResults hideFile(FileRenamer& renamer, const QString &oldName);
+FileRenamer::RenameResults unhideFile(FileRenamer& renamer, const QString &oldName);
+
/**
* this is a larger dialog used to visualise information about the mod.
@@ -185,8 +198,6 @@ private:
bool recursiveDelete(const QModelIndex &index);
void deleteFile(const QModelIndex &index);
void saveCategories(QTreeWidgetItem *currentNode);
- FileRenamer::RenameResults hideFile(FileRenamer& renamer, const QString &oldName);
- FileRenamer::RenameResults unhideFile(FileRenamer& renamer, const QString &oldName);
void addCheckedCategories(QTreeWidgetItem *tree);
void refreshPrimaryCategoriesBox();
@@ -216,12 +227,6 @@ private slots:
void on_tabWidget_currentChanged(int index);
void on_primaryCategoryBox_currentIndexChanged(int index);
void on_categoriesTree_itemChanged(QTreeWidgetItem *item, int column);
- void on_overwriteTree_itemDoubleClicked(QTreeWidgetItem *item, int column);
- void on_overwrittenTree_itemDoubleClicked(QTreeWidgetItem *item, int column);
- void on_overwriteTree_customContextMenuRequested(const QPoint &pos);
- void on_overwrittenTree_customContextMenuRequested(const QPoint &pos);
- void on_noConflictTree_customContextMenuRequested(const QPoint &pos);
- void on_conflictsAdvancedList_customContextMenuRequested(const QPoint &pos);
void on_fileTree_customContextMenuRequested(const QPoint &pos);
void on_refreshButton_clicked();
@@ -235,22 +240,6 @@ private slots:
private:
using FileEntry = MOShared::FileEntry;
- struct ConflictActions
- {
- QAction* hide;
- QAction* unhide;
- QAction* open;
- QAction* preview;
- QMenu* gotoMenu;
- std::vector<QAction*> gotoActions;
-
- ConflictActions() :
- hide(nullptr), unhide(nullptr), open(nullptr), preview(nullptr),
- gotoMenu(nullptr)
- {
- }
- };
-
Ui::ModInfoDialog *ui;
ModInfo::Ptr m_ModInfo;
@@ -285,27 +274,14 @@ private:
std::map<int, int> m_RealTabPos;
+ std::vector<std::unique_ptr<ModInfoDialogTab>> createTabs();
- void refreshConflictLists(bool refreshGeneral, bool refreshAdvanced);
void refreshFiles();
void restoreTabState(const QByteArray &state);
QByteArray saveTabState() const;
void changeFiletreeVisibility(bool visible);
-
- void openConflictItems(const QList<QTreeWidgetItem*>& items);
- void previewConflictItems(const QList<QTreeWidgetItem*>& items);
- void changeConflictItemsVisibility(
- const QList<QTreeWidgetItem*>& items, bool visible);
-
- void showConflictMenu(const QPoint &pos, QTreeWidget* tree);
-
- ConflictActions createConflictMenuActions(
- const QList<QTreeWidgetItem*>& selection);
-
- std::vector<QAction*> createGotoActions(
- const QList<QTreeWidgetItem*>& selection);
};
#endif // MODINFODIALOG_H
diff --git a/src/modinfodialogconflicts.cpp b/src/modinfodialogconflicts.cpp
index 17313436..22306d0c 100644
--- a/src/modinfodialogconflicts.cpp
+++ b/src/modinfodialogconflicts.cpp
@@ -5,6 +5,11 @@
using namespace MOShared;
using namespace MOBase;
+// if there are more than 50 selected items in the conflict tree or filetree,
+// don't bother checking whether menu items apply to them, just show all of them
+const int max_scan_for_context_menu = 50;
+
+
int naturalCompare(const QString& a, const QString& b)
{
static QCollator c = []{
@@ -89,7 +94,7 @@ public:
return canOpenFile(isArchive(), fileName());
}
- bool canPreview(PluginContainer* pluginContainer) const
+ bool canPreview(PluginContainer& pluginContainer) const
{
return canPreviewFile(pluginContainer, isArchive(), fileName());
}
@@ -109,9 +114,45 @@ public:
};
-ConflictsTab::ConflictsTab(Ui::ModInfoDialog* ui, OrganizerCore& oc)
- : ui(ui), m_general(ui, oc), m_advanced(ui, oc)
+ConflictsTab::ConflictsTab(
+ QWidget* parent, Ui::ModInfoDialog* ui,
+ OrganizerCore& oc, PluginContainer& plugin) :
+ m_parent(parent), ui(ui), m_core(oc), m_plugin(plugin),
+ m_origin(nullptr), m_general(this, ui, oc), m_advanced(this, ui, oc)
+{
+ connect(
+ &m_general, &GeneralConflictsTab::modOpen,
+ [&](const QString& name){ emitModOpen(name); });
+
+ connect(
+ &m_advanced, &AdvancedConflictsTab::modOpen,
+ [&](const QString& name){ emitModOpen(name); });
+}
+
+void ConflictsTab::setMod(ModInfo::Ptr mod, MOShared::FilesOrigin* origin)
+{
+ m_mod = mod;
+ m_origin = origin;
+
+ m_general.setMod(mod, origin);
+ m_advanced.setMod(mod, origin);
+}
+
+void ConflictsTab::update()
+{
+ m_general.update();
+ m_advanced.update();
+}
+
+void ConflictsTab::clear()
+{
+ m_general.clear();
+ m_advanced.clear();
+}
+
+bool ConflictsTab::feedFile(const QString&, const QString&)
{
+ return false;
}
void ConflictsTab::saveState(Settings& s)
@@ -132,9 +173,307 @@ void ConflictsTab::restoreState(const Settings& s)
m_advanced.restoreState(s);
}
+void ConflictsTab::changeItemsVisibility(
+ const QList<QTreeWidgetItem*>& items, bool visible)
+{
+ bool changed = false;
+ bool stop = false;
+
+ qDebug().nospace()
+ << (visible ? "unhiding" : "hiding") << " "
+ << items.size() << " conflict files";
+
+ QFlags<FileRenamer::RenameFlags> flags =
+ (visible ? FileRenamer::UNHIDE : FileRenamer::HIDE);
+
+ if (items.size() > 1) {
+ flags |= FileRenamer::MULTIPLE;
+ }
+
+ FileRenamer renamer(m_parent, flags);
+
+ for (const auto* item : items) {
+ if (stop) {
+ break;
+ }
+
+ const auto* ci = dynamic_cast<const ConflictItem*>(item);
+ if (!ci) {
+ continue;
+ }
+
+ auto result = FileRenamer::RESULT_CANCEL;
+
+ if (visible) {
+ if (!ci->canUnhide()) {
+ qDebug().nospace() << "cannot unhide " << item->text(0) << ", skipping";
+ continue;
+ }
+
+ result = unhideFile(renamer, ci->fileName());
+
+ } else {
+ if (!ci->canHide()) {
+ qDebug().nospace() << "cannot hide " << item->text(0) << ", skipping";
+ continue;
+ }
+
+ result = hideFile(renamer, ci->fileName());
+ }
+
+ switch (result) {
+ case FileRenamer::RESULT_OK: {
+ // will trigger a refresh at the end
+ changed = true;
+ break;
+ }
+
+ case FileRenamer::RESULT_SKIP: {
+ // nop
+ break;
+ }
+
+ case FileRenamer::RESULT_CANCEL: {
+ // stop right now, but make sure to refresh if needed
+ stop = true;
+ break;
+ }
+ }
+ }
+
+ qDebug().nospace() << (visible ? "unhiding" : "hiding") << " conflict files done";
+
+ if (changed) {
+ qDebug().nospace() << "triggering refresh";
+
+ if (m_origin) {
+ emit originModified(m_origin->getID());
+ }
+
+ update();
+ }
+}
+
+void ConflictsTab::openItems(const QList<QTreeWidgetItem*>& items)
+{
+ // the menu item is only shown for a single selection, but handle all of them
+ // in case this changes
+ for (auto* item : items) {
+ if (auto* ci=dynamic_cast<ConflictItem*>(item)) {
+ m_core.executeFileVirtualized(m_parent, ci->fileName());
+ }
+ }
+}
+
+void ConflictsTab::previewItems(const QList<QTreeWidgetItem*>& items)
+{
+ // the menu item is only shown for a single selection, but handle all of them
+ // in case this changes
+ for (auto* item : items) {
+ if (auto* ci=dynamic_cast<ConflictItem*>(item)) {
+ m_core.previewFileWithAlternatives(m_parent, ci->fileName());
+ }
+ }
+}
+
+void ConflictsTab::showContextMenu(const QPoint &pos, QTreeWidget* tree)
+{
+ auto actions = createMenuActions(tree->selectedItems());
+
+ QMenu menu;
+
+ // open
+ if (actions.open) {
+ connect(actions.open, &QAction::triggered, [&]{
+ openItems(tree->selectedItems());
+ });
+
+ menu.addAction(actions.open);
+ }
+
+ // preview
+ if (actions.preview) {
+ connect(actions.preview, &QAction::triggered, [&]{
+ previewItems(tree->selectedItems());
+ });
+
+ menu.addAction(actions.preview);
+ }
+
+ // hide
+ if (actions.hide) {
+ connect(actions.hide, &QAction::triggered, [&]{
+ changeItemsVisibility(tree->selectedItems(), false);
+ });
+
+ menu.addAction(actions.hide);
+ }
+
+ // unhide
+ if (actions.unhide) {
+ connect(actions.unhide, &QAction::triggered, [&]{
+ changeItemsVisibility(tree->selectedItems(), true);
+ });
+
+ menu.addAction(actions.unhide);
+ }
+
+ // goto
+ if (actions.gotoMenu) {
+ menu.addMenu(actions.gotoMenu);
+
+ for (auto* a : actions.gotoActions) {
+ connect(a, &QAction::triggered, [&, name=a->text()]{
+ emitModOpen(name);
+ });
+
+ actions.gotoMenu->addAction(a);
+ }
+ }
+
+ if (!menu.isEmpty()) {
+ menu.exec(tree->viewport()->mapToGlobal(pos));
+ }
+}
+
+ConflictsTab::Actions ConflictsTab::createMenuActions(
+ const QList<QTreeWidgetItem*>& selection)
+{
+ if (selection.empty()) {
+ return {};
+ }
+
+ bool enableHide = true;
+ bool enableUnhide = true;
+ bool enableOpen = true;
+ bool enablePreview = true;
+ bool enableGoto = true;
+
+ if (selection.size() == 1) {
+ // this is a single selection
+ const auto* ci = dynamic_cast<const ConflictItem*>(selection[0]);
+ if (!ci) {
+ return {};
+ }
+
+ enableHide = ci->canHide();
+ enableUnhide = ci->canUnhide();
+ enableOpen = ci->canOpen();
+ enablePreview = ci->canPreview(m_plugin);
+ enableGoto = ci->hasAlts();
+ }
+ else {
+ // this is a multiple selection, don't show open/preview so users don't open
+ // a thousand files
+ enableOpen = false;
+ enablePreview = false;
+
+ // don't bother with this on multiple selection, at least for now
+ enableGoto = false;
+
+ if (selection.size() < max_scan_for_context_menu) {
+ // if the number of selected items is low, checking them to accurately
+ // show the menu items is worth it
+ enableHide = false;
+ enableUnhide = false;
+
+ for (const auto* item : selection) {
+ if (const auto* ci=dynamic_cast<const ConflictItem*>(item)) {
+ if (ci->canHide()) {
+ enableHide = true;
+ }
+
+ if (ci->canUnhide()) {
+ enableUnhide = true;
+ }
+
+ if (enableHide && enableUnhide && enableGoto) {
+ // found all, no need to check more
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ Actions actions;
+
+ actions.hide = new QAction(tr("Hide"), m_parent);
+ actions.hide->setEnabled(enableHide);
+
+ // note that it is possible for hidden files to appear if they override other
+ // hidden files from another mod
+ actions.unhide = new QAction(tr("Unhide"), m_parent);
+ actions.unhide->setEnabled(enableUnhide);
+
+ actions.open = new QAction(tr("Open/Execute"), m_parent);
+ actions.open->setEnabled(enableOpen);
+
+ actions.preview = new QAction(tr("Preview"), m_parent);
+ actions.preview->setEnabled(enablePreview);
+
+ actions.gotoMenu = new QMenu(tr("Go to..."), m_parent);
+ actions.gotoMenu->setEnabled(enableGoto);
+
+ if (enableGoto) {
+ actions.gotoActions = createGotoActions(selection);
+ }
+
+ return actions;
+}
+
+std::vector<QAction*> ConflictsTab::createGotoActions(
+ const QList<QTreeWidgetItem*>& selection)
+{
+ if (!m_origin || selection.size() != 1) {
+ return {};
+ }
+
+ const auto* item = dynamic_cast<const ConflictItem*>(selection[0]);
+ if (!item) {
+ return {};
+ }
+
+ auto file = m_origin->findFile(item->fileIndex());
+ if (!file) {
+ return {};
+ }
+
+
+ std::vector<QString> mods;
+ const auto& ds = *m_core.directoryStructure();
-GeneralConflictsTab::GeneralConflictsTab(Ui::ModInfoDialog* ui, OrganizerCore& oc)
- : ui(ui), m_core(oc), m_origin(nullptr)
+ // add all alternatives
+ for (const auto& alt : file->getAlternatives()) {
+ const auto& o = ds.getOriginByID(alt.first);
+ if (o.getID() != m_origin->getID()) {
+ mods.push_back(ToQString(o.getName()));
+ }
+ }
+
+ // add the real origin if different from this mod
+ const FilesOrigin& realOrigin = ds.getOriginByID(file->getOrigin());
+ if (realOrigin.getID() != m_origin->getID()) {
+ mods.push_back(ToQString(realOrigin.getName()));
+ }
+
+ std::sort(mods.begin(), mods.end(), [](const auto& a, const auto& b) {
+ return (QString::localeAwareCompare(a, b) < 0);
+ });
+
+ std::vector<QAction*> actions;
+
+ for (const auto& name : mods) {
+ actions.push_back(new QAction(name, m_parent));
+ }
+
+ return actions;
+}
+
+
+GeneralConflictsTab::GeneralConflictsTab(
+ ConflictsTab* tab, Ui::ModInfoDialog* ui, OrganizerCore& oc)
+ : m_tab(tab), ui(ui), m_core(oc), m_origin(nullptr)
{
m_expanders.overwrite.set(ui->overwriteExpander1, ui->overwriteTree1, true);
m_expanders.overwritten.set(ui->overwrittenExpander1, ui->overwrittenTree1, true);
@@ -143,6 +482,33 @@ GeneralConflictsTab::GeneralConflictsTab(Ui::ModInfoDialog* ui, OrganizerCore& o
QObject::connect(
ui->overwriteTree1, &QTreeWidget::itemDoubleClicked,
[&](auto* item, int col){ onOverwriteActivated(item, col); });
+
+ QObject::connect(
+ ui->overwrittenTree1, &QTreeWidget::itemDoubleClicked,
+ [&](auto* item, int col){ onOverwrittenActivated(item, col); });
+
+ QObject::connect(
+ ui->overwriteTree1, &QTreeWidget::customContextMenuRequested,
+ [&](const QPoint& p){ m_tab->showContextMenu(p, ui->overwriteTree1); });
+
+ QObject::connect(
+ ui->overwrittenTree1, &QTreeWidget::customContextMenuRequested,
+ [&](const QPoint& p){ m_tab->showContextMenu(p, ui->overwrittenTree1); });
+
+ QObject::connect(
+ ui->noConflictTree1, &QTreeWidget::customContextMenuRequested,
+ [&](const QPoint& p){ m_tab->showContextMenu(p, ui->noConflictTree1); });
+}
+
+void GeneralConflictsTab::clear()
+{
+ ui->overwriteTree1->clear();
+ ui->overwrittenTree1->clear();
+ ui->noConflictTree1->clear();
+
+ ui->overwriteCount1->display(0);
+ ui->overwrittenCount1->display(0);
+ ui->noConflictCount1->display(0);
}
void GeneralConflictsTab::saveState(Settings& s)
@@ -198,24 +564,20 @@ void GeneralConflictsTab::restoreState(const Settings& s)
.value("mod_info_conflicts_general_overwritten").toByteArray());
}
-void GeneralConflictsTab::rebuild(ModInfo::Ptr mod, FilesOrigin* origin)
+void GeneralConflictsTab::setMod(ModInfo::Ptr mod, FilesOrigin* origin)
{
m_mod = mod;
m_origin = origin;
-
- update();
}
void GeneralConflictsTab::update()
{
+ clear();
+
int numNonConflicting = 0;
int numOverwrite = 0;
int numOverwritten = 0;
- ui->overwriteTree1->clear();
- ui->overwrittenTree1->clear();
- ui->noConflictTree1->clear();
-
if (m_origin != nullptr) {
const auto rootPath = m_mod->absolutePath();
@@ -307,15 +669,26 @@ void GeneralConflictsTab::onOverwriteActivated(QTreeWidgetItem *item, int)
const auto origin = ci->altOrigin();
if (!origin.isEmpty()) {
- close();
- emit modOpen(origin, TAB_CONFLICTS);
+ emit modOpen(origin);
+ }
+ }
+}
+
+void GeneralConflictsTab::onOverwrittenActivated(QTreeWidgetItem *item, int)
+{
+ if (const auto* ci=dynamic_cast<ConflictItem*>(item)) {
+ const auto origin = ci->altOrigin();
+
+ if (!origin.isEmpty()) {
+ emit modOpen(origin);
}
}
}
-AdvancedConflictsTab::AdvancedConflictsTab(Ui::ModInfoDialog* ui, OrganizerCore& oc)
- : ui(ui), m_core(oc), m_origin(nullptr)
+AdvancedConflictsTab::AdvancedConflictsTab(
+ ConflictsTab* tab, Ui::ModInfoDialog* ui, OrganizerCore& oc)
+ : m_tab(tab), ui(ui), m_core(oc), m_origin(nullptr)
{
// left-elide the overwrites column so that the nearest are visible
ui->conflictsAdvancedList1->setItemDelegateForColumn(
@@ -327,22 +700,31 @@ AdvancedConflictsTab::AdvancedConflictsTab(Ui::ModInfoDialog* ui, OrganizerCore&
// don't elide the overwritten by column so that the nearest are visible
- QObject::connect(ui->conflictsAdvancedShowNoConflict1, &QCheckBox::clicked, [&] {
- update();
- });
+ QObject::connect(
+ ui->conflictsAdvancedShowNoConflict1, &QCheckBox::clicked,
+ [&]{ update(); });
- QObject::connect(ui->conflictsAdvancedShowAll1, &QRadioButton::clicked, [&] {
- update();
- });
+ QObject::connect(
+ ui->conflictsAdvancedShowAll1, &QRadioButton::clicked,
+ [&]{ update(); });
- QObject::connect(ui->conflictsAdvancedShowNearest1, &QRadioButton::clicked, [&] {
- update();
- });
+ QObject::connect(
+ ui->conflictsAdvancedShowNearest1, &QRadioButton::clicked,
+ [&]{ update(); });
+
+ QObject::connect(
+ ui->conflictsAdvancedList1, &QTreeWidget::customContextMenuRequested,
+ [&](const QPoint& p){ m_tab->showContextMenu(p, ui->conflictsAdvancedList1); });
m_filter.set(ui->conflictsAdvancedFilter1);
m_filter.changed = [&]{ update(); };
}
+void AdvancedConflictsTab::clear()
+{
+ ui->conflictsAdvancedList1->clear();
+}
+
void AdvancedConflictsTab::saveState(Settings& s)
{
s.directInterface().setValue(
@@ -358,8 +740,7 @@ void AdvancedConflictsTab::saveState(Settings& s)
<< ui->conflictsAdvancedShowNearest1->isChecked();
s.directInterface().setValue(
- "mod_info_conflicts_advanced_options",
- ui->conflictsAdvancedList1->header()->saveState());
+ "mod_info_conflicts_advanced_options", result);
}
void AdvancedConflictsTab::restoreState(const Settings& s)
@@ -383,17 +764,15 @@ void AdvancedConflictsTab::restoreState(const Settings& s)
}
}
-void AdvancedConflictsTab::rebuild(ModInfo::Ptr mod, MOShared::FilesOrigin* origin)
+void AdvancedConflictsTab::setMod(ModInfo::Ptr mod, MOShared::FilesOrigin* origin)
{
m_mod = mod;
m_origin = origin;
-
- update();
}
void AdvancedConflictsTab::update()
{
- ui->conflictsAdvancedList1->clear();
+ clear();
if (m_origin != nullptr) {
const auto rootPath = m_mod->absolutePath();
diff --git a/src/modinfodialogconflicts.h b/src/modinfodialogconflicts.h
index 894f9dd4..5843884a 100644
--- a/src/modinfodialogconflicts.h
+++ b/src/modinfodialogconflicts.h
@@ -4,23 +4,33 @@
#include "modinfodialog.h"
#include "expanderwidget.h"
-class GeneralConflictsTab
+class ConflictsTab;
+
+class GeneralConflictsTab : public QObject
{
+ Q_OBJECT;
+
public:
- GeneralConflictsTab(Ui::ModInfoDialog* ui, OrganizerCore& oc);
+ GeneralConflictsTab(
+ ConflictsTab* tab, Ui::ModInfoDialog* ui, OrganizerCore& oc);
+ void clear();
void saveState(Settings& s);
void restoreState(const Settings& s);
- void rebuild(ModInfo::Ptr mod, MOShared::FilesOrigin* origin);
+ void setMod(ModInfo::Ptr mod, MOShared::FilesOrigin* origin);
void update();
+signals:
+ void modOpen(QString name);
+
private:
struct Expanders
{
ExpanderWidget overwrite, overwritten, nonconflict;
};
+ ConflictsTab* m_tab;
Ui::ModInfoDialog* ui;
OrganizerCore& m_core;
ModInfo::Ptr m_mod;
@@ -41,21 +51,34 @@ private:
const QString& fileName, const QString& relativeName);
void onOverwriteActivated(QTreeWidgetItem* item, int);
+ void onOverwrittenActivated(QTreeWidgetItem *item, int);
+
+ void onOverwriteTreeContext(const QPoint &pos);
+ void onOverwrittenTreeContext(const QPoint &pos);
+ void onNoConflictTreeContext(const QPoint &pos);
};
-class AdvancedConflictsTab
+class AdvancedConflictsTab : public QObject
{
+ Q_OBJECT;
+
public:
- AdvancedConflictsTab(Ui::ModInfoDialog* ui, OrganizerCore& oc);
+ AdvancedConflictsTab(
+ ConflictsTab* tab, Ui::ModInfoDialog* ui, OrganizerCore& oc);
+ void clear();
void saveState(Settings& s);
void restoreState(const Settings& s);
- void rebuild(ModInfo::Ptr mod, MOShared::FilesOrigin* origin);
+ void setMod(ModInfo::Ptr mod, MOShared::FilesOrigin* origin);
void update();
+signals:
+ void modOpen(QString name);
+
private:
+ ConflictsTab* m_tab;
Ui::ModInfoDialog* ui;
OrganizerCore& m_core;
ModInfo::Ptr m_mod;
@@ -71,16 +94,59 @@ private:
class ConflictsTab : public ModInfoDialogTab
{
+ Q_OBJECT;
+
public:
- ConflictsTab(Ui::ModInfoDialog* ui, OrganizerCore& oc);
+ ConflictsTab(
+ QWidget* parent, Ui::ModInfoDialog* ui,
+ OrganizerCore& oc, PluginContainer& plugin);
+
+ void setMod(ModInfo::Ptr mod, MOShared::FilesOrigin* origin) override;
+ void update() override;
+ void clear() override;
+ bool feedFile(const QString& rootPath, const QString& filename) override;
void saveState(Settings& s) override;
void restoreState(const Settings& s) override;
+ void openItems(const QList<QTreeWidgetItem*>& items);
+ void previewItems(const QList<QTreeWidgetItem*>& items);
+
+ void changeItemsVisibility(
+ const QList<QTreeWidgetItem*>& items, bool visible);
+
+ void showContextMenu(const QPoint &pos, QTreeWidget* tree);
+
private:
+ struct Actions
+ {
+ QAction* hide;
+ QAction* unhide;
+ QAction* open;
+ QAction* preview;
+ QMenu* gotoMenu;
+ std::vector<QAction*> gotoActions;
+
+ Actions() :
+ hide(nullptr), unhide(nullptr), open(nullptr), preview(nullptr),
+ gotoMenu(nullptr)
+ {
+ }
+ };
+
+ QWidget* m_parent;
Ui::ModInfoDialog* ui;
+ OrganizerCore& m_core;
+ PluginContainer& m_plugin;
+ ModInfo::Ptr m_mod;
+ MOShared::FilesOrigin* m_origin;
GeneralConflictsTab m_general;
AdvancedConflictsTab m_advanced;
+
+ Actions createMenuActions(const QList<QTreeWidgetItem*>& selection);
+
+ std::vector<QAction*> createGotoActions(
+ const QList<QTreeWidgetItem*>& selection);
};
#endif // MODINFODIALOGCONFLICTS_H
diff --git a/src/modinfodialogesps.cpp b/src/modinfodialogesps.cpp
index 32dcdb35..6c87b10d 100644
--- a/src/modinfodialogesps.cpp
+++ b/src/modinfodialogesps.cpp
@@ -123,20 +123,20 @@ private:
};
-ESPsTab::ESPsTab(Ui::ModInfoDialog* ui)
- : ui(ui)
+ESPsTab::ESPsTab(QWidget* parent, Ui::ModInfoDialog* ui)
+ : m_parent(parent), ui(ui)
{
QObject::connect(
- ui->activateESP1, &QToolButton::clicked, [&]{ onActivate(); });
+ ui->activateESP, &QToolButton::clicked, [&]{ onActivate(); });
QObject::connect(
- ui->deactivateESP1, &QToolButton::clicked, [&]{ onDeactivate(); });
+ ui->deactivateESP, &QToolButton::clicked, [&]{ onDeactivate(); });
}
void ESPsTab::clear()
{
- ui->inactiveESPList1->clear();
- ui->activeESPList1->clear();
+ ui->inactiveESPList->clear();
+ ui->activeESPList->clear();
}
bool ESPsTab::feedFile(const QString& rootPath, const QString& fullPath)
@@ -152,9 +152,9 @@ bool ESPsTab::feedFile(const QString& rootPath, const QString& fullPath)
auto* item = new ESPItem({rootPath, relativePath});
if (item->esp().isActive()) {
- ui->activeESPList1->addItem(item);
+ ui->activeESPList->addItem(item);
} else {
- ui->inactiveESPList1->addItem(item);
+ ui->inactiveESPList->addItem(item);
}
return true;
@@ -188,7 +188,7 @@ void ESPsTab::onActivate()
bool okClicked = false;
newName = QInputDialog::getText(
- ui->tabESPs,
+ m_parent,
QObject::tr("File Exists"),
QObject::tr("A file with that name exists, please enter a new one"),
QLineEdit::Normal, file.fileName(), &okClicked);
@@ -203,8 +203,8 @@ void ESPsTab::onActivate()
}
if (esp.activate(newName)) {
- ui->inactiveESPList1->takeItem(ui->inactiveESPList1->row(item));
- ui->activeESPList1->addItem(item);
+ ui->inactiveESPList->takeItem(ui->inactiveESPList->row(item));
+ ui->activeESPList->addItem(item);
item->setESP(esp);
} else {
reportError(QObject::tr("Failed to move file"));
@@ -246,8 +246,8 @@ void ESPsTab::onDeactivate()
}
if (esp.deactivate(newName)) {
- ui->activeESPList1->takeItem(ui->activeESPList1->row(item));
- ui->inactiveESPList1->addItem(item);
+ ui->activeESPList->takeItem(ui->activeESPList->row(item));
+ ui->inactiveESPList->addItem(item);
item->setESP(esp);
} else {
reportError(QObject::tr("Failed to move file"));
@@ -256,7 +256,7 @@ void ESPsTab::onDeactivate()
ESPItem* ESPsTab::selectedInactive()
{
- auto* item = ui->inactiveESPList1->currentItem();
+ auto* item = ui->inactiveESPList->currentItem();
if (!item) {
return nullptr;
}
@@ -272,7 +272,7 @@ ESPItem* ESPsTab::selectedInactive()
ESPItem* ESPsTab::selectedActive()
{
- auto* item = ui->activeESPList1->currentItem();
+ auto* item = ui->activeESPList->currentItem();
if (!item) {
return nullptr;
}
diff --git a/src/modinfodialogesps.h b/src/modinfodialogesps.h
index a46677cb..8da70377 100644
--- a/src/modinfodialogesps.h
+++ b/src/modinfodialogesps.h
@@ -7,13 +7,16 @@ class ESPItem;
class ESPsTab : public ModInfoDialogTab
{
+ Q_OBJECT;
+
public:
- ESPsTab(Ui::ModInfoDialog* ui);
+ ESPsTab(QWidget* parent, Ui::ModInfoDialog* ui);
void clear() override;
bool feedFile(const QString& rootPath, const QString& fullPath) override;
private:
+ QWidget* m_parent;
Ui::ModInfoDialog* ui;
void onActivate();
diff --git a/src/modinfodialogimages.cpp b/src/modinfodialogimages.cpp
index 1659bed3..752c8d0c 100644
--- a/src/modinfodialogimages.cpp
+++ b/src/modinfodialogimages.cpp
@@ -80,7 +80,7 @@ void ScalableImage::mousePressEvent(QMouseEvent* e)
}
-ImagesTab::ImagesTab(Ui::ModInfoDialog* ui)
+ImagesTab::ImagesTab(QWidget*, Ui::ModInfoDialog* ui)
: ui(ui), m_image(new ScalableImage)
{
ui->imagesImage->layout()->addWidget(m_image);
diff --git a/src/modinfodialogimages.h b/src/modinfodialogimages.h
index 73fb5936..a40904f7 100644
--- a/src/modinfodialogimages.h
+++ b/src/modinfodialogimages.h
@@ -31,8 +31,10 @@ private:
class ImagesTab : public ModInfoDialogTab
{
+ Q_OBJECT;
+
public:
- ImagesTab(Ui::ModInfoDialog* ui);
+ ImagesTab(QWidget* parent, Ui::ModInfoDialog* ui);
void clear() override;
bool feedFile(const QString& rootPath, const QString& fullPath) override;
diff --git a/src/modinfodialogtextfiles.cpp b/src/modinfodialogtextfiles.cpp
index cf800aa6..0dd6f06e 100644
--- a/src/modinfodialogtextfiles.cpp
+++ b/src/modinfodialogtextfiles.cpp
@@ -21,8 +21,9 @@ private:
};
-GenericFilesTab::GenericFilesTab(QListWidget* list, QSplitter* sp, TextEditor* e)
- : m_list(list), m_editor(e)
+GenericFilesTab::GenericFilesTab(
+ QWidget* parent, QListWidget* list, QSplitter* sp, TextEditor* e)
+ : m_parent(parent), m_list(list), m_editor(e)
{
m_editor->setupToolbar();
@@ -48,7 +49,7 @@ bool GenericFilesTab::canClose()
}
const int res = QMessageBox::question(
- m_list,
+ m_parent,
QObject::tr("Save changes?"),
QObject::tr("Save changes to \"%1\"?").arg(m_editor->filename()),
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
@@ -108,8 +109,9 @@ void GenericFilesTab::select(FileListItem* item)
}
-TextFilesTab::TextFilesTab(Ui::ModInfoDialog* ui)
- : GenericFilesTab(ui->textFileList, ui->tabTextSplitter, ui->textFileEditor)
+TextFilesTab::TextFilesTab(QWidget* parent, Ui::ModInfoDialog* ui)
+ : GenericFilesTab(
+ parent, ui->textFileList, ui->tabTextSplitter, ui->textFileEditor)
{
}
@@ -128,8 +130,9 @@ bool TextFilesTab::wantsFile(const QString& rootPath, const QString& fullPath) c
return false;
}
-IniFilesTab::IniFilesTab(Ui::ModInfoDialog* ui)
- : GenericFilesTab(ui->iniFileList, ui->tabIniSplitter, ui->iniFileEditor)
+IniFilesTab::IniFilesTab(QWidget* parent, Ui::ModInfoDialog* ui)
+ : GenericFilesTab(
+ parent, ui->iniFileList, ui->tabIniSplitter, ui->iniFileEditor)
{
}
diff --git a/src/modinfodialogtextfiles.h b/src/modinfodialogtextfiles.h
index 8725ea09..d30e20d7 100644
--- a/src/modinfodialogtextfiles.h
+++ b/src/modinfodialogtextfiles.h
@@ -10,17 +10,22 @@ class TextEditor;
class GenericFilesTab : public ModInfoDialogTab
{
-public:
- GenericFilesTab(QListWidget* list, QSplitter* splitter, TextEditor* editor);
+ Q_OBJECT;
+public:
void clear() override;
bool canClose() override;
bool feedFile(const QString& rootPath, const QString& fullPath) override;
protected:
+ QWidget* m_parent;
QListWidget* m_list;
TextEditor* m_editor;
+ GenericFilesTab(
+ QWidget* parent,
+ QListWidget* list, QSplitter* splitter, TextEditor* editor);
+
virtual bool wantsFile(const QString& rootPath, const QString& fullPath) const = 0;
private:
@@ -32,7 +37,7 @@ private:
class TextFilesTab : public GenericFilesTab
{
public:
- TextFilesTab(Ui::ModInfoDialog* ui);
+ TextFilesTab(QWidget* parent, Ui::ModInfoDialog* ui);
protected:
bool wantsFile(const QString& rootPath, const QString& fullPath) const override;
@@ -42,7 +47,7 @@ protected:
class IniFilesTab : public GenericFilesTab
{
public:
- IniFilesTab(Ui::ModInfoDialog* ui);
+ IniFilesTab(QWidget* parent, Ui::ModInfoDialog* ui);
protected:
bool wantsFile(const QString& rootPath, const QString& fullPath) const override;