summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAl <gabriel.cortesi@outlook.com>2019-05-21 11:23:08 +0200
committerGitHub <noreply@github.com>2019-05-21 11:23:08 +0200
commit0078fd12d0fb2de4fab6f9726b0c64cf5fa8da00 (patch)
tree4cd3e4b51b3ea43a866aa74c3e11bb9b5f0d30b0 /src
parentf966e7db9363230673ce5a85dd1ab53846f73521 (diff)
parent0088ee963b25495e6cce790005dcf1356a73e7b8 (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.cpp4
-rw-r--r--src/modinfodialog.cpp148
-rw-r--r--src/modinfodialog.h59
-rw-r--r--src/modinfodialog.ui186
-rw-r--r--src/settings.h1
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