summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorisanae <14251494+isanae@users.noreply.github.com>2019-05-18 03:53:20 -0400
committerisanae <14251494+isanae@users.noreply.github.com>2019-05-18 03:53:20 -0400
commit6c470aff829bed12853321c25262b84934242098 (patch)
treef097fe3305c59554efc2ec16bb320dc1ea5efec5 /src
parent47cca19109d47ccdb70c49f2bdc2e8170cd95ce3 (diff)
changed the top conflict treeview to support multiple selection
this required making some changes to both trees because they were sharing m_ConflictsContextItem that was set on right clicks; both trees are now independent hide/unhide is always shown on multiple selection to avoid scanning all the selected items
Diffstat (limited to 'src')
-rw-r--r--src/modinfodialog.cpp237
-rw-r--r--src/modinfodialog.h18
-rw-r--r--src/modinfodialog.ui3
3 files changed, 200 insertions, 58 deletions
diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp
index 0e41b10e..b0035c02 100644
--- a/src/modinfodialog.cpp
+++ b/src/modinfodialog.cpp
@@ -1233,18 +1233,38 @@ bool ModInfoDialog::unhideFile(const QString &oldName)
}
-void ModInfoDialog::hideConflictFile()
+void ModInfoDialog::hideConflictFiles()
{
- if (hideFile(m_ConflictsContextItem->data(0, Qt::UserRole).toString())) {
+ bool changed = false;
+
+ for (const auto* item : ui->overwriteTree->selectedItems()) {
+ if (canHide(item)) {
+ if (hideFile(item->data(0, Qt::UserRole).toString())) {
+ changed = true;
+ }
+ }
+ }
+
+ if (changed) {
emit originModified(m_Origin->getID());
refreshLists();
}
}
-void ModInfoDialog::unhideConflictFile()
+void ModInfoDialog::unhideConflictFiles()
{
- if (unhideFile(m_ConflictsContextItem->data(0, Qt::UserRole).toString())) {
+ bool changed = false;
+
+ for (const auto* item : ui->overwriteTree->selectedItems()) {
+ if (canUnhide(item)) {
+ if (unhideFile(item->data(0, Qt::UserRole).toString())) {
+ changed = true;
+ }
+ }
+ }
+
+ if (changed) {
emit originModified(m_Origin->getID());
refreshLists();
}
@@ -1309,33 +1329,75 @@ int ModInfoDialog::getBinaryExecuteInfo(const QFileInfo &targetInfo, QFileInfo &
}
}
-void ModInfoDialog::openDataFile()
+void ModInfoDialog::previewOverwriteDataFile()
{
- if (m_ConflictsContextItem != nullptr) {
- QFileInfo targetInfo(m_ConflictsContextItem->data(0, Qt::UserRole).toString());
- QFileInfo binaryInfo;
- QString arguments;
- switch (getBinaryExecuteInfo(targetInfo, binaryInfo, arguments)) {
- case 1: {
- m_OrganizerCore->spawnBinaryDirect(
- binaryInfo, arguments, m_OrganizerCore->currentProfile()->name(),
- targetInfo.absolutePath(), "", "");
- } break;
- case 2: {
- ::ShellExecuteW(nullptr, L"open",
- ToWString(targetInfo.absoluteFilePath()).c_str(),
- nullptr, nullptr, SW_SHOWNORMAL);
- } break;
- default: {
- // nop
- } break;
- }
+ // the menu item is only shown for a single selection, but check just in case
+ const auto selection = ui->overwriteTree->selectedItems();
+ if (!selection.empty()) {
+ previewDataFile(selection[0]);
+ }
+}
+
+void ModInfoDialog::openOverwriteDataFile()
+{
+ // the menu item is only shown for a single selection, but check just in case
+ const auto selection = ui->overwriteTree->selectedItems();
+ if (!selection.empty()) {
+ openDataFile(selection[0]);
+ }
+}
+
+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]);
+ }
+}
+
+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::openDataFile(const QTreeWidgetItem* item)
+{
+ if (!item) {
+ return;
+ }
+
+ QFileInfo targetInfo(item->data(0, Qt::UserRole).toString());
+ QFileInfo binaryInfo;
+ QString arguments;
+ switch (getBinaryExecuteInfo(targetInfo, binaryInfo, arguments)) {
+ case 1: {
+ m_OrganizerCore->spawnBinaryDirect(
+ binaryInfo, arguments, m_OrganizerCore->currentProfile()->name(),
+ targetInfo.absolutePath(), "", "");
+ } break;
+ case 2: {
+ ::ShellExecuteW(nullptr, L"open",
+ ToWString(targetInfo.absoluteFilePath()).c_str(),
+ nullptr, nullptr, SW_SHOWNORMAL);
+ } break;
+ default: {
+ // nop
+ } break;
}
}
-void ModInfoDialog::previewDataFile()
+void ModInfoDialog::previewDataFile(const QTreeWidgetItem* item)
{
- QString fileName = QDir::fromNativeSeparators(m_ConflictsContextItem->data(0, Qt::UserRole).toString());
+ if (!item) {
+ return;
+ }
+
+ QString fileName = QDir::fromNativeSeparators(item->data(0, Qt::UserRole).toString());
// what we have is an absolute path to the file in its actual location (for the primary origin)
// what we want is the path relative to the virtual data directory
@@ -1395,54 +1457,125 @@ void ModInfoDialog::previewDataFile()
}
}
+bool ModInfoDialog::canHide(const QTreeWidgetItem* item) const
+{
+ if (item->data(1, Qt::UserRole + 2).toBool()) {
+ // can't hide files from archives
+ return false;
+ }
+
+ if (item->text(0).endsWith(ModInfo::s_HiddenExt)) {
+ // already hidden
+ return false;
+ }
-void ModInfoDialog::on_overwriteTree_customContextMenuRequested(const QPoint &pos)
+ return true;
+}
+
+bool ModInfoDialog::canUnhide(const QTreeWidgetItem* item) const
{
- m_ConflictsContextItem = ui->overwriteTree->itemAt(pos.x(), pos.y());
+ if (item->data(1, Qt::UserRole + 2).toBool()) {
+ // can't unhide files from archives
+ return false;
+ }
- if (m_ConflictsContextItem != nullptr) {
- // offer to hide/unhide file, but not for files from archives
- if (!m_ConflictsContextItem->data(1, Qt::UserRole + 2).toBool()) {
- QMenu menu;
- if (m_ConflictsContextItem->text(0).endsWith(ModInfo::s_HiddenExt)) {
- menu.addAction(tr("Un-Hide"), this, SLOT(unhideConflictFile()));
- } else {
- menu.addAction(tr("Hide"), this, SLOT(hideConflictFile()));
- }
+ if (!item->text(0).endsWith(ModInfo::s_HiddenExt)) {
+ // already visible
+ return false;
+ }
+
+ return true;
+}
+
+bool ModInfoDialog::canPreview(const QTreeWidgetItem* item) const
+{
+ const QString fileName = item->data(0, Qt::UserRole).toString();
+ if (!m_PluginContainer->previewGenerator().previewSupported(QFileInfo(fileName).suffix())) {
+ return false;
+ }
- menu.addAction(tr("Open/Execute"), this, SLOT(openDataFile()));
+ return true;
+}
- QString fileName = m_ConflictsContextItem->data(0, Qt::UserRole).toString();
- if (m_PluginContainer->previewGenerator().previewSupported(QFileInfo(fileName).suffix())) {
- menu.addAction(tr("Preview"), this, SLOT(previewDataFile()));
- }
+void ModInfoDialog::on_overwriteTree_customContextMenuRequested(const QPoint &pos)
+{
+ const auto selection = ui->overwriteTree->selectedItems();
+ if (selection.empty()) {
+ return;
+ }
- menu.exec(ui->overwriteTree->mapToGlobal(pos));
+ // for a single selection, hide/unhide is not shown for files from
+ // archives and whether the action is hide or unhide depends on the current
+ // state
+ //
+ // for multiple selection, both actions are shown unconditionally and
+ // handled in hideConflictFiles() and unhideConflictFiles()
+ bool enableHide = true;
+ bool enableUnhide = true;
+ bool enableOpen = true;
+ bool enablePreview = true;
+
+ if (selection.size() == 1) {
+ // this is a single selection
+ const auto* item = selection[0];
+ if (!item) {
+ return;
}
+
+ enableHide = canHide(item);
+ enableUnhide = canUnhide(item);
+ enablePreview = canPreview(item);
+ // open is always enabled
+ }
+ else {
+ // this is a multiple selection, don't show open/preview so users don't open
+ // a thousand files, but always enable hide/unhide to avoid potentially
+ // scanning hundreds of selected files to check their state
+ enableOpen = false;
+ enablePreview = false;
+ }
+
+
+ QMenu menu;
+
+ if (enableHide) {
+ menu.addAction(tr("Hide"), this, SLOT(hideConflictFiles()));
+ }
+
+ if (enableUnhide) {
+ menu.addAction(tr("Un-Hide"), this, SLOT(unhideConflictFiles()));
+ }
+
+ if (enableOpen) {
+ menu.addAction(tr("Open/Execute"), this, SLOT(openOverwriteDataFile()));
+ }
+
+ if (enablePreview) {
+ menu.addAction(tr("Preview"), this, SLOT(previewOverwriteDataFile()));
}
+
+ menu.exec(ui->overwriteTree->viewport()->mapToGlobal(pos));
}
void ModInfoDialog::on_overwrittenTree_customContextMenuRequested(const QPoint &pos)
{
- m_ConflictsContextItem = ui->overwrittenTree->itemAt(pos.x(), pos.y());
+ auto* item = ui->overwrittenTree->itemAt(pos.x(), pos.y());
- if (m_ConflictsContextItem != nullptr) {
- if (!m_ConflictsContextItem->data(1, Qt::UserRole + 2).toBool()) {
+ if (item != nullptr) {
+ if (!item->data(1, Qt::UserRole + 2).toBool()) {
QMenu menu;
- menu.addAction(tr("Open/Execute"), this, SLOT(openDataFile()));
+ menu.addAction(tr("Open/Execute"), this, SLOT(openOverwrittenDataFile()));
- QString fileName = m_ConflictsContextItem->data(0, Qt::UserRole).toString();
- if (m_PluginContainer->previewGenerator().previewSupported(QFileInfo(fileName).suffix())) {
- menu.addAction(tr("Preview"), this, SLOT(previewDataFile()));
+ if (canPreview(item)) {
+ menu.addAction(tr("Preview"), this, SLOT(previewOverwrittenDataFile()));
}
- menu.exec(ui->overwrittenTree->mapToGlobal(pos));
+ menu.exec(ui->overwrittenTree->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 4c731c00..45745471 100644
--- a/src/modinfodialog.h
+++ b/src/modinfodialog.h
@@ -156,12 +156,14 @@ private:
private slots:
- void hideConflictFile();
- void unhideConflictFile();
+ void hideConflictFiles();
+ void unhideConflictFiles();
+ void previewOverwriteDataFile();
+ void openOverwriteDataFile();
int getBinaryExecuteInfo(const QFileInfo &targetInfo, QFileInfo &binaryInfo, QString &arguments);
- void previewDataFile();
- void openDataFile();
+ void previewOverwrittenDataFile();
+ void openOverwrittenDataFile();
void thumbnailClicked(const QString &fileName);
void linkClicked(const QUrl &url);
@@ -241,13 +243,17 @@ private:
QAction *m_HideAction;
QAction *m_UnhideAction;
- QTreeWidgetItem *m_ConflictsContextItem;
-
const MOShared::DirectoryEntry *m_Directory;
MOShared::FilesOrigin *m_Origin;
std::map<int, int> m_RealTabPos;
+ bool canHide(const QTreeWidgetItem* item) const;
+ bool canUnhide(const QTreeWidgetItem* item) const;
+ bool canPreview(const QTreeWidgetItem* item) const;
+
+ void previewDataFile(const QTreeWidgetItem* item);
+ void openDataFile(const QTreeWidgetItem* item);
};
#endif // MODINFODIALOG_H
diff --git a/src/modinfodialog.ui b/src/modinfodialog.ui
index 0211e704..39173a14 100644
--- a/src/modinfodialog.ui
+++ b/src/modinfodialog.ui
@@ -430,6 +430,9 @@ Most mods do not have optional esps, so chances are good you are looking at an e
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
+ <property name="selectionMode">
+ <enum>QAbstractItemView::ExtendedSelection</enum>
+ </property>
<property name="textElideMode">
<enum>Qt::ElideLeft</enum>
</property>