From a2b1f6a3604d8a2e4bc47c2b91fb58e6d5b45af6 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Mon, 20 May 2019 16:11:10 -0400 Subject: added third tree with non-conflicting files --- src/modinfodialog.cpp | 11 ++++++++++- src/modinfodialog.ui | 50 +++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 49 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp index 555b62db..3c68f4e8 100644 --- a/src/modinfodialog.cpp +++ b/src/modinfodialog.cpp @@ -501,6 +501,7 @@ void ModInfoDialog::refreshLists() ui->overwriteTree->clear(); ui->overwrittenTree->clear(); + ui->noconflictTree->clear(); if (m_Origin != nullptr) { std::vector files = m_Origin->getFiles(); @@ -535,7 +536,15 @@ void ModInfoDialog::refreshLists() } ui->overwriteTree->addTopLevelItem(item); ++numOverwrite; - } else {// otherwise don't display the file + } else {// otherwise, put the file in the nonconflict tree + QTreeWidgetItem *item = new QTreeWidgetItem(QStringList({relativeName})); + item->setData(0, Qt::UserRole, fileName); + if (archive) { + QFont font = item->font(0); + font.setItalic(true); + item->setFont(0, font); + } + ui->noconflictTree->addTopLevelItem(item); ++numNonConflicting; } } else { diff --git a/src/modinfodialog.ui b/src/modinfodialog.ui index 39173a14..25fce40c 100644 --- a/src/modinfodialog.ui +++ b/src/modinfodialog.ui @@ -526,22 +526,50 @@ Most mods do not have optional esps, so chances are good you are looking at an e - + - - - Non-Conflicted files - - + + + + + <html><head/><body><p>The following files have no conflicts</p></body></html> + + + + + + + QFrame::Sunken + + + QLCDNumber::Flat + + + + - - - QFrame::Sunken + + + Qt::CustomContextMenu - - QLCDNumber::Flat + + Qt::ElideLeft + + + true + + + true + + + 1 + + + File + + -- cgit v1.3.1 From 00f8cbff05c3f548baba59b0cb525205cc1d80e3 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Mon, 20 May 2019 17:38:17 -0400 Subject: expandable sections in the conflict tab --- src/modinfodialog.cpp | 65 ++++++++++++++- src/modinfodialog.h | 21 +++++ src/modinfodialog.ui | 218 +++++++++++++++++++++++++++++++++++--------------- 3 files changed, 237 insertions(+), 67 deletions(-) (limited to 'src') diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp index 3c68f4e8..3f8b58a9 100644 --- a/src/modinfodialog.cpp +++ b/src/modinfodialog.cpp @@ -265,6 +265,61 @@ bool FileRenamer::renameFailed(const QString& oldName, const QString& newName) } +ExpanderWidget::ExpanderWidget() + : m_button(nullptr), m_content(nullptr) +{ +} + +ExpanderWidget::ExpanderWidget(QToolButton* button, QWidget* content) + : ExpanderWidget() +{ + set(button, content); +} + +void ExpanderWidget::set(QToolButton* button, QWidget* content, bool o) +{ + m_button = button; + m_content = content; + + m_button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + m_button->setCheckable(true); + + if (o) + open(); + else + close(); + + QObject::connect(m_button, &QToolButton::clicked, [&]{ toggle(); }); +} + +void ExpanderWidget::open() +{ + m_button->setArrowType(Qt::DownArrow); + m_button->setChecked(false); + m_content->show(); +} + +void ExpanderWidget::close() +{ + m_button->setArrowType(Qt::RightArrow); + m_button->setChecked(false); + m_content->hide(); +} + +void ExpanderWidget::toggle() +{ + if (opened()) + close(); + else + open(); +} + +bool ExpanderWidget::opened() const +{ + return m_content->isVisible(); +} + + 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), m_ThumbnailMapper(this), m_RequestStarted(false), @@ -378,6 +433,10 @@ ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directo if (ui->tabWidget->currentIndex() == TAB_NEXUS) { activateNexusTab(); } + + m_overwriteExpander.set(ui->overwriteExpander, ui->overwriteTree, true); + m_overwrittenExpander.set(ui->overwrittenExpander, ui->overwrittenTree, true); + m_nonconflictExpander.set(ui->noConflictExpander, ui->noConflictTree); } @@ -501,7 +560,7 @@ void ModInfoDialog::refreshLists() ui->overwriteTree->clear(); ui->overwrittenTree->clear(); - ui->noconflictTree->clear(); + ui->noConflictTree->clear(); if (m_Origin != nullptr) { std::vector files = m_Origin->getFiles(); @@ -520,7 +579,7 @@ void ModInfoDialog::refreshLists() } altString << m_Directory->getOriginByID(altIter->first).getName(); } - QStringList fields(relativeName.prepend("...")); + QStringList fields(relativeName); fields.append(ToQString(altString.str())); QTreeWidgetItem *item = new QTreeWidgetItem(fields); @@ -544,7 +603,7 @@ void ModInfoDialog::refreshLists() font.setItalic(true); item->setFont(0, font); } - ui->noconflictTree->addTopLevelItem(item); + ui->noConflictTree->addTopLevelItem(item); ++numNonConflicting; } } else { diff --git a/src/modinfodialog.h b/src/modinfodialog.h index 66c50be5..731611d2 100644 --- a/src/modinfodialog.h +++ b/src/modinfodialog.h @@ -183,6 +183,25 @@ private: }; +class ExpanderWidget +{ +public: + ExpanderWidget(); + ExpanderWidget(QToolButton* button, QWidget* content); + + void set(QToolButton* button, QWidget* content, bool opened=false); + + void open(); + void close(); + void toggle(); + bool opened() const; + +private: + QToolButton* m_button; + QWidget* m_content; +}; + + /** * this is a larger dialog used to visualise information abount the mod. * @todo this would probably a good place for a plugin-system @@ -383,6 +402,8 @@ private: std::map m_RealTabPos; + ExpanderWidget m_overwriteExpander, m_overwrittenExpander, m_nonconflictExpander; + bool canHideConflictItem(const QTreeWidgetItem* item) const; bool canUnhideConflictItem(const QTreeWidgetItem* item) const; bool canPreviewConflictItem(const QTreeWidgetItem* item) const; diff --git a/src/modinfodialog.ui b/src/modinfodialog.ui index 25fce40c..0d96f621 100644 --- a/src/modinfodialog.ui +++ b/src/modinfodialog.ui @@ -400,28 +400,57 @@ Most mods do not have optional esps, so chances are good you are looking at an e Conflicts - + + + 0 + - + - - - The following conflicted files are provided by this mod - - - - - - - QFrame::Sunken - - - 1 - - - QLCDNumber::Flat - - + + + + + + 0 + 0 + + + + border: none + + + The following conflicted files are provided by this mod + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QFrame::Sunken + + + 1 + + + QLCDNumber::Flat + + + + @@ -470,23 +499,49 @@ Most mods do not have optional esps, so chances are good you are looking at an e - - - - - The following conflicted files are provided by other mods - - - + - - - QFrame::Sunken - - - QLCDNumber::Flat - - + + + + + + 0 + 0 + + + + border: none + + + The following conflicted files are provided by other mods + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QFrame::Sunken + + + QLCDNumber::Flat + + + + @@ -526,16 +581,38 @@ Most mods do not have optional esps, so chances are good you are looking at an e - + - + - + + + + 0 + 0 + + + + border: none; + - <html><head/><body><p>The following files have no conflicts</p></body></html> + The following files have no conflicts + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -548,32 +625,45 @@ Most mods do not have optional esps, so chances are good you are looking at an e - - - - Qt::CustomContextMenu - - - Qt::ElideLeft - - - true - - - true - - - 1 - - - - File - - - - + + + + Qt::CustomContextMenu + + + Qt::ElideLeft + + + true + + + true + + + 1 + + + + File + + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + -- cgit v1.3.1 From c5f61733850d6737814041f645a009e1cc60a7ed Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Mon, 20 May 2019 17:58:00 -0400 Subject: made expander use the full width context menu for noconflict tree --- src/modinfodialog.cpp | 37 +++++++++++++++++++++++++++++++++-- src/modinfodialog.h | 4 ++++ src/modinfodialog.ui | 54 +++++++++------------------------------------------ 3 files changed, 48 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp index 3f8b58a9..d32b112f 100644 --- a/src/modinfodialog.cpp +++ b/src/modinfodialog.cpp @@ -1732,7 +1732,6 @@ void ModInfoDialog::openOverwriteDataFile() void ModInfoDialog::previewOverwrittenDataFile() { - // the overwritten tree only supports single selection, but check just in case const auto selection = ui->overwrittenTree->selectedItems(); if (!selection.empty()) { previewDataFile(selection[0]); @@ -1741,13 +1740,28 @@ void ModInfoDialog::previewOverwrittenDataFile() void ModInfoDialog::openOverwrittenDataFile() { - // the overwritten tree only supports single selection, but check just in case const auto selection = ui->overwrittenTree->selectedItems(); if (!selection.empty()) { openDataFile(selection[0]); } } +void ModInfoDialog::previewNoConflictDataFile() +{ + const auto selection = ui->noConflictTree->selectedItems(); + if (!selection.empty()) { + previewDataFile(selection[0]); + } +} + +void ModInfoDialog::openNoConflictDataFile() +{ + const auto selection = ui->noConflictTree->selectedItems(); + if (!selection.empty()) { + openDataFile(selection[0]); + } +} + void ModInfoDialog::openDataFile(const QTreeWidgetItem* item) { if (!item) { @@ -1992,6 +2006,25 @@ void ModInfoDialog::on_overwrittenTree_customContextMenuRequested(const QPoint & } } +void ModInfoDialog::on_noConflictTree_customContextMenuRequested(const QPoint &pos) +{ + auto* item = ui->noConflictTree->itemAt(pos.x(), pos.y()); + + if (item != nullptr) { + if (!item->data(1, Qt::UserRole + 2).toBool()) { + QMenu menu; + + menu.addAction(tr("Open/Execute"), this, SLOT(openNoConflictDataFile())); + + if (canPreviewConflictItem(item)) { + menu.addAction(tr("Preview"), this, SLOT(previewNoConflictDataFile())); + } + + menu.exec(ui->noConflictTree->viewport()->mapToGlobal(pos)); + } + } +} + void ModInfoDialog::on_overwrittenTree_itemDoubleClicked(QTreeWidgetItem *item, int) { emit modOpen(item->data(1, Qt::UserRole).toString(), TAB_CONFLICTS); diff --git a/src/modinfodialog.h b/src/modinfodialog.h index 731611d2..32efa210 100644 --- a/src/modinfodialog.h +++ b/src/modinfodialog.h @@ -319,6 +319,9 @@ private slots: void previewOverwrittenDataFile(); void openOverwrittenDataFile(); + void previewNoConflictDataFile(); + void openNoConflictDataFile(); + void thumbnailClicked(const QString &fileName); void linkClicked(const QUrl &url); void linkClicked(QString url); @@ -355,6 +358,7 @@ private slots: 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_fileTree_customContextMenuRequested(const QPoint &pos); void on_refreshButton_clicked(); diff --git a/src/modinfodialog.ui b/src/modinfodialog.ui index 0d96f621..1187de87 100644 --- a/src/modinfodialog.ui +++ b/src/modinfodialog.ui @@ -407,7 +407,7 @@ Most mods do not have optional esps, so chances are good you are looking at an e - + @@ -417,26 +417,14 @@ Most mods do not have optional esps, so chances are good you are looking at an e - border: none + border: none; +text-align: left; The following conflicted files are provided by this mod - - - - Qt::Horizontal - - - - 40 - 20 - - - - @@ -501,7 +489,7 @@ Most mods do not have optional esps, so chances are good you are looking at an e - + @@ -511,26 +499,14 @@ Most mods do not have optional esps, so chances are good you are looking at an e - border: none + border: none; +text-align: left; The following conflicted files are provided by other mods - - - - Qt::Horizontal - - - - 40 - 20 - - - - @@ -583,7 +559,7 @@ Most mods do not have optional esps, so chances are good you are looking at an e - + @@ -593,26 +569,14 @@ Most mods do not have optional esps, so chances are good you are looking at an e - border: none; + border: none; +text-align: left; The following files have no conflicts - - - - Qt::Horizontal - - - - 40 - 20 - - - - -- cgit v1.3.1 From 513eaaa3556bc08c7ac9d03944ee35deff9d7ceb Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Mon, 20 May 2019 18:33:50 -0400 Subject: added const version of Settings::directInterface() for restoring states added top-level saveState() and restoreState() to ModInfoDialog that are called from MainWindow, because it now also has to handle expander states in the conflict tab added internal opened state to expander widget instead of using widget visibility so it can be saved even after the dialog is closed --- src/mainwindow.cpp | 4 +-- src/modinfodialog.cpp | 86 ++++++++++++++++++++++++++++++++++++++------------- src/modinfodialog.h | 16 +++++++--- src/settings.h | 1 + 4 files changed, 78 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 9108464f..89cb9f56 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2983,7 +2983,7 @@ void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index, dialog.openTab(tab); } - dialog.restoreTabState(m_OrganizerCore.settings().directInterface().value("mod_info_tabs").toByteArray()); + dialog.restoreState(m_OrganizerCore.settings()); QSettings &settings = m_OrganizerCore.settings().directInterface(); QString key = QString("geometry/%1").arg(dialog.objectName()); if (settings.contains(key)) { @@ -3001,7 +3001,7 @@ void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index, } dialog.exec(); - m_OrganizerCore.settings().directInterface().setValue("mod_info_tabs", dialog.saveTabState()); + dialog.saveState(m_OrganizerCore.settings()); settings.setValue(key, dialog.saveGeometry()); modInfo->saveMeta(); diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp index d32b112f..ca09aaa0 100644 --- a/src/modinfodialog.cpp +++ b/src/modinfodialog.cpp @@ -266,7 +266,7 @@ bool FileRenamer::renameFailed(const QString& oldName, const QString& newName) ExpanderWidget::ExpanderWidget() - : m_button(nullptr), m_content(nullptr) + : m_button(nullptr), m_content(nullptr), opened_(false) { } @@ -284,39 +284,41 @@ void ExpanderWidget::set(QToolButton* button, QWidget* content, bool o) m_button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); m_button->setCheckable(true); - if (o) - open(); - else - close(); - + toggle(o); QObject::connect(m_button, &QToolButton::clicked, [&]{ toggle(); }); } -void ExpanderWidget::open() +void ExpanderWidget::toggle() { - m_button->setArrowType(Qt::DownArrow); - m_button->setChecked(false); - m_content->show(); + if (opened()) { + toggle(false); + } + else { + toggle(true); + } } -void ExpanderWidget::close() +void ExpanderWidget::toggle(bool b) { - m_button->setArrowType(Qt::RightArrow); - m_button->setChecked(false); - m_content->hide(); -} + if (b) { + m_button->setArrowType(Qt::DownArrow); + m_button->setChecked(false); + m_content->show(); + } else { + m_button->setArrowType(Qt::RightArrow); + m_button->setChecked(false); + m_content->hide(); + } -void ExpanderWidget::toggle() -{ - if (opened()) - close(); - else - open(); + // the state has to be remembered instead of using m_content's visibility + // because saving the state in saveConflictExpandersState() happens after the + // dialog is closed, which marks all the widgets hidden + opened_ = b; } bool ExpanderWidget::opened() const { - return m_content->isVisible(); + return opened_; } @@ -507,6 +509,18 @@ int ModInfoDialog::tabIndex(const QString &tabId) } +void ModInfoDialog::saveState(Settings& s) const +{ + s.directInterface().setValue("mod_info_tabs", saveTabState()); + s.directInterface().setValue("mod_info_conflict_expanders", saveConflictExpandersState()); +} + +void ModInfoDialog::restoreState(const Settings& s) +{ + restoreTabState(s.directInterface().value("mod_info_tabs").toByteArray()); + restoreConflictExpandersState(s.directInterface().value("mod_info_conflict_expanders").toByteArray()); +} + void ModInfoDialog::restoreTabState(const QByteArray &state) { QDataStream stream(state); @@ -538,6 +552,22 @@ void ModInfoDialog::restoreTabState(const QByteArray &state) ui->tabWidget->blockSignals(false); } +void ModInfoDialog::restoreConflictExpandersState(const QByteArray &state) +{ + QDataStream stream(state); + + bool overwriteExpanded = false; + bool overwrittenExpanded = false; + bool noConflictExpanded = false; + + stream >> overwriteExpanded >> overwrittenExpanded >> noConflictExpanded; + + if (stream.status() == QDataStream::Ok) { + m_overwriteExpander.toggle(overwriteExpanded); + m_overwrittenExpander.toggle(overwrittenExpanded); + m_nonconflictExpander.toggle(noConflictExpanded); + } +} QByteArray ModInfoDialog::saveTabState() const { @@ -551,6 +581,18 @@ QByteArray ModInfoDialog::saveTabState() const return result; } +QByteArray ModInfoDialog::saveConflictExpandersState() const +{ + QByteArray result; + QDataStream stream(&result, QIODevice::WriteOnly); + + stream + << m_overwriteExpander.opened() + << m_overwrittenExpander.opened() + << m_nonconflictExpander.opened(); + + return result; +} void ModInfoDialog::refreshLists() { diff --git a/src/modinfodialog.h b/src/modinfodialog.h index 32efa210..3ce76740 100644 --- a/src/modinfodialog.h +++ b/src/modinfodialog.h @@ -191,14 +191,14 @@ public: void set(QToolButton* button, QWidget* content, bool opened=false); - void open(); - void close(); void toggle(); + void toggle(bool b); bool opened() const; private: QToolButton* m_button; QWidget* m_content; + bool opened_; }; @@ -257,9 +257,8 @@ public: **/ void openTab(int tab); - void restoreTabState(const QByteArray &state); - - QByteArray saveTabState() const; + void saveState(Settings& s) const; + void restoreState(const Settings& s); signals: @@ -408,6 +407,13 @@ private: ExpanderWidget m_overwriteExpander, m_overwrittenExpander, m_nonconflictExpander; + + void restoreTabState(const QByteArray &state); + void restoreConflictExpandersState(const QByteArray &state); + + QByteArray saveTabState() const; + QByteArray saveConflictExpandersState() const; + bool canHideConflictItem(const QTreeWidgetItem* item) const; bool canUnhideConflictItem(const QTreeWidgetItem* item) const; bool canPreviewConflictItem(const QTreeWidgetItem* item) const; diff --git a/src/settings.h b/src/settings.h index ed49a1bc..04a0646e 100644 --- a/src/settings.h +++ b/src/settings.h @@ -306,6 +306,7 @@ public: * @return the wrapped QSettings object */ QSettings &directInterface() { return m_Settings; } + const QSettings &directInterface() const { return m_Settings; } /** * @brief retrieve a setting for one of the installed plugins -- cgit v1.3.1 From 0088ee963b25495e6cce790005dcf1356a73e7b8 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Mon, 20 May 2019 18:44:41 -0400 Subject: documented ExpanderWidget, removed checkable stuff because the state is kept internally --- src/modinfodialog.cpp | 5 +---- src/modinfodialog.h | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp index ca09aaa0..cff1387c 100644 --- a/src/modinfodialog.cpp +++ b/src/modinfodialog.cpp @@ -282,10 +282,9 @@ void ExpanderWidget::set(QToolButton* button, QWidget* content, bool o) m_content = content; m_button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - m_button->setCheckable(true); + QObject::connect(m_button, &QToolButton::clicked, [&]{ toggle(); }); toggle(o); - QObject::connect(m_button, &QToolButton::clicked, [&]{ toggle(); }); } void ExpanderWidget::toggle() @@ -302,11 +301,9 @@ void ExpanderWidget::toggle(bool b) { if (b) { m_button->setArrowType(Qt::DownArrow); - m_button->setChecked(false); m_content->show(); } else { m_button->setArrowType(Qt::RightArrow); - m_button->setChecked(false); m_content->hide(); } diff --git a/src/modinfodialog.h b/src/modinfodialog.h index 3ce76740..dc04deb3 100644 --- a/src/modinfodialog.h +++ b/src/modinfodialog.h @@ -183,16 +183,38 @@ private: }; +/* Takes a QToolButton and a widget and creates an expandable widget. + **/ class ExpanderWidget { public: + /** empty expander, use set() + **/ ExpanderWidget(); + + /** see set() + **/ ExpanderWidget(QToolButton* button, QWidget* content); + /** @brief sets the button and content widgets to use + * the button will be given an arrow icon, clicking it will toggle the + * visibility of the given widget + * @param button the button that toggles the content + * @param content the widget that will be shown or hidden + * @param opened initial state, defaults to closed + **/ void set(QToolButton* button, QWidget* content, bool opened=false); + /** either opens or closes the expander depending on the current state + **/ void toggle(); + + /** sets the current state of the expander + **/ void toggle(bool b); + + /** returns whether the expander is currently opened + **/ bool opened() const; private: -- cgit v1.3.1