diff options
| author | isanae <14251494+isanae@users.noreply.github.com> | 2019-05-18 03:53:20 -0400 |
|---|---|---|
| committer | isanae <14251494+isanae@users.noreply.github.com> | 2019-05-18 03:53:20 -0400 |
| commit | 6c470aff829bed12853321c25262b84934242098 (patch) | |
| tree | f097fe3305c59554efc2ec16bb320dc1ea5efec5 /src | |
| parent | 47cca19109d47ccdb70c49f2bdc2e8170cd95ce3 (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.cpp | 237 | ||||
| -rw-r--r-- | src/modinfodialog.h | 18 | ||||
| -rw-r--r-- | src/modinfodialog.ui | 3 |
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>
|
