diff options
| author | Al <gabriel.cortesi@outlook.com> | 2019-05-21 11:23:08 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-05-21 11:23:08 +0200 |
| commit | 0078fd12d0fb2de4fab6f9726b0c64cf5fa8da00 (patch) | |
| tree | 4cd3e4b51b3ea43a866aa74c3e11bb9b5f0d30b0 /src | |
| parent | f966e7db9363230673ce5a85dd1ab53846f73521 (diff) | |
| parent | 0088ee963b25495e6cce790005dcf1356a73e7b8 (diff) | |
Merge pull request #726 from isanae/Develop
adds a no-conflict list in the conflicts tab, makes all three lists collapsible
Diffstat (limited to 'src')
| -rw-r--r-- | src/mainwindow.cpp | 4 | ||||
| -rw-r--r-- | src/modinfodialog.cpp | 148 | ||||
| -rw-r--r-- | src/modinfodialog.h | 59 | ||||
| -rw-r--r-- | src/modinfodialog.ui | 186 | ||||
| -rw-r--r-- | src/settings.h | 1 |
5 files changed, 337 insertions, 61 deletions
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 555b62db..cff1387c 100644 --- a/src/modinfodialog.cpp +++ b/src/modinfodialog.cpp @@ -265,6 +265,60 @@ bool FileRenamer::renameFailed(const QString& oldName, const QString& newName) } +ExpanderWidget::ExpanderWidget() + : m_button(nullptr), m_content(nullptr), opened_(false) +{ +} + +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); + QObject::connect(m_button, &QToolButton::clicked, [&]{ toggle(); }); + + toggle(o); +} + +void ExpanderWidget::toggle() +{ + if (opened()) { + toggle(false); + } + else { + toggle(true); + } +} + +void ExpanderWidget::toggle(bool b) +{ + if (b) { + m_button->setArrowType(Qt::DownArrow); + m_content->show(); + } else { + m_button->setArrowType(Qt::RightArrow); + m_content->hide(); + } + + // 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 opened_; +} + + 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 +432,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); } @@ -448,6 +506,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); @@ -479,6 +549,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 { @@ -492,6 +578,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() { @@ -501,6 +599,7 @@ void ModInfoDialog::refreshLists() ui->overwriteTree->clear(); ui->overwrittenTree->clear(); + ui->noConflictTree->clear(); if (m_Origin != nullptr) { std::vector<FileEntry::Ptr> files = m_Origin->getFiles(); @@ -519,7 +618,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); @@ -535,7 +634,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 { @@ -1664,7 +1771,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]); @@ -1673,13 +1779,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) { @@ -1924,6 +2045,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 66c50be5..dc04deb3 100644 --- a/src/modinfodialog.h +++ b/src/modinfodialog.h @@ -183,6 +183,47 @@ 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:
+ QToolButton* m_button;
+ QWidget* m_content;
+ bool opened_;
+};
+
+
/**
* this is a larger dialog used to visualise information abount the mod.
* @todo this would probably a good place for a plugin-system
@@ -238,9 +279,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:
@@ -300,6 +340,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);
@@ -336,6 +379,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();
@@ -383,6 +427,15 @@ private: std::map<int, int> m_RealTabPos;
+ 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/modinfodialog.ui b/src/modinfodialog.ui index 39173a14..1187de87 100644 --- a/src/modinfodialog.ui +++ b/src/modinfodialog.ui @@ -400,28 +400,45 @@ Most mods do not have optional esps, so chances are good you are looking at an e <attribute name="title">
<string>Conflicts</string>
</attribute>
- <layout class="QVBoxLayout" name="verticalLayout_8">
+ <layout class="QVBoxLayout" name="verticalLayout_8" stretch="0,1,0,1,0,1,0">
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout_10" stretch="1,0">
- <item>
- <widget class="QLabel" name="label_7">
- <property name="text">
- <string>The following conflicted files are provided by this mod</string>
- </property>
- </widget>
- </item>
+ <layout class="QVBoxLayout" name="overwriteRoot">
<item>
- <widget class="QLCDNumber" name="overwriteCount">
- <property name="frameShadow">
- <enum>QFrame::Sunken</enum>
- </property>
- <property name="lineWidth">
- <number>1</number>
- </property>
- <property name="segmentStyle">
- <enum>QLCDNumber::Flat</enum>
- </property>
- </widget>
+ <layout class="QHBoxLayout" name="overwriteHeader" stretch="1,0">
+ <item>
+ <widget class="QToolButton" name="overwriteExpander">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">border: none;
+text-align: left;</string>
+ </property>
+ <property name="text">
+ <string>The following conflicted files are provided by this mod</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLCDNumber" name="overwriteCount">
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <property name="lineWidth">
+ <number>1</number>
+ </property>
+ <property name="segmentStyle">
+ <enum>QLCDNumber::Flat</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
</layout>
</item>
@@ -470,23 +487,37 @@ Most mods do not have optional esps, so chances are good you are looking at an e </widget>
</item>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout_9" stretch="1,0">
+ <layout class="QVBoxLayout" name="overwrittenRoot">
<item>
- <widget class="QLabel" name="label_8">
- <property name="text">
- <string>The following conflicted files are provided by other mods</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLCDNumber" name="overwrittenCount">
- <property name="frameShadow">
- <enum>QFrame::Sunken</enum>
- </property>
- <property name="segmentStyle">
- <enum>QLCDNumber::Flat</enum>
- </property>
- </widget>
+ <layout class="QHBoxLayout" name="overwrittenHeader" stretch="1,0">
+ <item>
+ <widget class="QToolButton" name="overwrittenExpander">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">border: none;
+text-align: left;</string>
+ </property>
+ <property name="text">
+ <string>The following conflicted files are provided by other mods</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLCDNumber" name="overwrittenCount">
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <property name="segmentStyle">
+ <enum>QLCDNumber::Flat</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
</layout>
</item>
@@ -526,26 +557,77 @@ Most mods do not have optional esps, so chances are good you are looking at an e </widget>
</item>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout_8" stretch="1,0">
+ <layout class="QVBoxLayout" name="noConflictRoot">
<item>
- <widget class="QLabel" name="label_9">
- <property name="text">
- <string>Non-Conflicted files</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLCDNumber" name="noConflictCount">
- <property name="frameShadow">
- <enum>QFrame::Sunken</enum>
- </property>
- <property name="segmentStyle">
- <enum>QLCDNumber::Flat</enum>
- </property>
- </widget>
+ <layout class="QHBoxLayout" name="noConflictHeader" stretch="1,0">
+ <item>
+ <widget class="QToolButton" name="noConflictExpander">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">border: none;
+text-align: left;</string>
+ </property>
+ <property name="text">
+ <string>The following files have no conflicts</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLCDNumber" name="noConflictCount">
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <property name="segmentStyle">
+ <enum>QLCDNumber::Flat</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
</layout>
</item>
+ <item>
+ <widget class="QTreeWidget" name="noConflictTree">
+ <property name="contextMenuPolicy">
+ <enum>Qt::CustomContextMenu</enum>
+ </property>
+ <property name="textElideMode">
+ <enum>Qt::ElideLeft</enum>
+ </property>
+ <property name="sortingEnabled">
+ <bool>true</bool>
+ </property>
+ <property name="animated">
+ <bool>true</bool>
+ </property>
+ <property name="columnCount">
+ <number>1</number>
+ </property>
+ <column>
+ <property name="text">
+ <string>File</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
</layout>
</widget>
<widget class="QWidget" name="tabCategories">
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 |
