summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorisanae <14251494+isanae@users.noreply.github.com>2019-12-08 11:33:03 -0500
committerisanae <14251494+isanae@users.noreply.github.com>2019-12-08 11:33:03 -0500
commitc9049bb07274aaefa79c9751ec40910bf8daf0ca (patch)
tree48aada30a7c0ee4111422a9cfc84275a8f2bbf8d
parent2c59d13be645bb8c12adae883938c9a8652f3dee (diff)
conflicts tab: run exes unhooked by default
-rw-r--r--src/mainwindow.cpp3
-rw-r--r--src/modinfodialogconflicts.cpp72
-rw-r--r--src/modinfodialogconflicts.h5
-rw-r--r--src/modinfodialogfiletree.cpp3
-rw-r--r--src/processrunner.cpp70
-rw-r--r--src/processrunner.h8
6 files changed, 97 insertions, 64 deletions
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 43d5b820..532d8502 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -5425,7 +5425,8 @@ void MainWindow::runDataFileHooked()
const QFileInfo targetInfo(path);
m_OrganizerCore.processRunner()
- .setFromFile(this, targetInfo, true)
+ .setFromFile(this, targetInfo)
+ .setHooked(true)
.setWaitForCompletion(ProcessRunner::Refresh)
.run();
}
diff --git a/src/modinfodialogconflicts.cpp b/src/modinfodialogconflicts.cpp
index 9c7ccc8c..81e8c7a3 100644
--- a/src/modinfodialogconflicts.cpp
+++ b/src/modinfodialogconflicts.cpp
@@ -542,45 +542,32 @@ void ConflictsTab::activateItems(QTreeView* tree)
if (tryPreview && canPreviewFile(plugin(), item->isArchive(), path)) {
previewItem(item);
} else {
- openItem(item);
+ openItem(item, false);
}
return true;
});
}
-void ConflictsTab::openItems(QTreeView* tree)
+void ConflictsTab::openItems(QTreeView* tree, bool hooked)
{
// the menu item is only shown for a single selection, but handle all of them
// in case this changes
for_each_in_selection(tree, [&](const ConflictItem* item) {
- openItem(item);
+ openItem(item, hooked);
return true;
});
}
-void ConflictsTab::openItem(const ConflictItem* item)
+void ConflictsTab::openItem(const ConflictItem* item, bool hooked)
{
core().processRunner()
.setFromFile(parentWidget(), item->fileName())
+ .setHooked(hooked)
.setWaitForCompletion()
.run();
}
-void ConflictsTab::runItemsHooked(QTreeView* tree)
-{
- // the menu item is only shown for a single selection, but handle all of them
- // in case this changes
- for_each_in_selection(tree, [&](const ConflictItem* item) {
- core().processRunner()
- .setFromFile(parentWidget(), item->fileName(), true)
- .setWaitForCompletion()
- .run();
-
- return true;
- });
-}
-
void ConflictsTab::previewItems(QTreeView* tree)
{
// the menu item is only shown for a single selection, but handle all of them
@@ -615,30 +602,44 @@ void ConflictsTab::showContextMenu(const QPoint &pos, QTreeView* tree)
// open
if (actions.open) {
connect(actions.open, &QAction::triggered, [&]{
- openItems(tree);
+ openItems(tree, false);
});
+ }
- menu.addAction(actions.open);
+ // preview
+ if (actions.preview) {
+ connect(actions.preview, &QAction::triggered, [&]{
+ previewItems(tree);
+ });
+ }
+
+ if ((actions.open && actions.open->isEnabled()) && (actions.preview && actions.preview->isEnabled())) {
+ if (Settings::instance().interface().doubleClicksOpenPreviews()) {
+ menu.addAction(actions.preview);
+ menu.addAction(actions.open);
+ } else {
+ menu.addAction(actions.open);
+ menu.addAction(actions.preview);
+ }
+ } else {
+ if (actions.open) {
+ menu.addAction(actions.open);
+ }
+
+ if (actions.preview) {
+ menu.addAction(actions.preview);
+ }
}
// run hooked
if (actions.runHooked) {
connect(actions.runHooked, &QAction::triggered, [&]{
- runItemsHooked(tree);
+ openItems(tree, true);
});
menu.addAction(actions.runHooked);
}
- // preview
- if (actions.preview) {
- connect(actions.preview, &QAction::triggered, [&]{
- previewItems(tree);
- });
-
- menu.addAction(actions.preview);
- }
-
// goto
if (actions.gotoMenu) {
menu.addMenu(actions.gotoMenu);
@@ -681,9 +682,15 @@ void ConflictsTab::showContextMenu(const QPoint &pos, QTreeView* tree)
menu.addAction(actions.unhide);
}
- setDefaultActivationActionForFile(actions.open, actions.preview);
-
if (!menu.isEmpty()) {
+ if (actions.open || actions.preview || actions.runHooked) {
+ // bold the first option
+ auto* top = menu.actions()[0];
+ auto f = top->font();
+ f.setBold(true);
+ top->setFont(f);
+ }
+
menu.exec(tree->viewport()->mapToGlobal(pos));
}
}
@@ -769,6 +776,7 @@ ConflictsTab::Actions ConflictsTab::createMenuActions(QTreeView* tree)
if (enableRun) {
actions.open = new QAction(tr("&Execute"), parentWidget());
+ actions.runHooked = new QAction(tr("Execute with &VFS"), parentWidget());
} else if (enableOpen) {
actions.open = new QAction(tr("&Open"), parentWidget());
actions.runHooked = new QAction(tr("Open with &VFS"), parentWidget());
diff --git a/src/modinfodialogconflicts.h b/src/modinfodialogconflicts.h
index 3ac8de23..1297e536 100644
--- a/src/modinfodialogconflicts.h
+++ b/src/modinfodialogconflicts.h
@@ -108,12 +108,11 @@ public:
bool canHandleUnmanaged() const override;
void activateItems(QTreeView* tree);
- void openItems(QTreeView* tree);
- void runItemsHooked(QTreeView* tree);
+ void openItems(QTreeView* tree, bool hooked);
void previewItems(QTreeView* tree);
void exploreItems(QTreeView* tree);
- void openItem(const ConflictItem* item);
+ void openItem(const ConflictItem* item, bool hooked);
void previewItem(const ConflictItem* item);
void changeItemsVisibility(QTreeView* tree, bool visible);
diff --git a/src/modinfodialogfiletree.cpp b/src/modinfodialogfiletree.cpp
index d1ae3823..0b9e8da4 100644
--- a/src/modinfodialogfiletree.cpp
+++ b/src/modinfodialogfiletree.cpp
@@ -183,7 +183,8 @@ void FileTreeTab::onRunHooked()
}
core().processRunner()
- .setFromFile(parentWidget(), m_fs->filePath(selection), true)
+ .setFromFile(parentWidget(), m_fs->filePath(selection))
+ .setHooked(true)
.setWaitForCompletion()
.run();
}
diff --git a/src/processrunner.cpp b/src/processrunner.cpp
index 46065d69..19aae632 100644
--- a/src/processrunner.cpp
+++ b/src/processrunner.cpp
@@ -421,8 +421,8 @@ ProcessRunner::ProcessRunner(OrganizerCore& core, IUserInterface* ui) :
m_core(core), m_ui(ui), m_lockReason(UILocker::NoReason),
m_waitFlags(NoFlags), m_handle(INVALID_HANDLE_VALUE), m_exitCode(-1)
{
- // all processes started in ProcessRunner are hooked
- m_sp.hooked = true;
+ // all processes started in ProcessRunner are hooked by default
+ setHooked(true);
}
ProcessRunner& ProcessRunner::setBinary(const QFileInfo &binary)
@@ -475,8 +475,14 @@ ProcessRunner& ProcessRunner::setWaitForCompletion(
return *this;
}
+ProcessRunner& ProcessRunner::setHooked(bool b)
+{
+ m_sp.hooked = b;
+ return *this;
+}
+
ProcessRunner& ProcessRunner::setFromFile(
- QWidget* parent, const QFileInfo& targetInfo, bool forceHook)
+ QWidget* parent, const QFileInfo& targetInfo)
{
if (!parent && m_ui) {
parent = m_ui->qtWidget();
@@ -500,24 +506,8 @@ ProcessRunner& ProcessRunner::setFromFile(
case spawn::FileExecutionTypes::Other: // fall-through
default:
{
- if (forceHook) {
- auto assoc = env::getAssociation(targetInfo);
- if (!assoc.executable.filePath().isEmpty()) {
- setBinary(assoc.executable);
- setArguments(assoc.formattedCommandLine);
- setCurrentDirectory(assoc.executable.absoluteDir());
-
- return *this;
- }
-
- // if it fails, just use the regular shell open
- }
-
- m_shellOpen = targetInfo.absoluteFilePath();
-
- // picked up by postRun()
- m_sp.hooked = false;
-
+ m_shellOpen = targetInfo;
+ setHooked(false);
break;
}
}
@@ -649,11 +639,41 @@ ProcessRunner& ProcessRunner::setFromFileOrExecutable(
return *this;
}
+bool ProcessRunner::shouldRunShell() const
+{
+ return !m_shellOpen.filePath().isEmpty();
+}
+
ProcessRunner::Results ProcessRunner::run()
{
+ // check if setHooked() was called after setFromFile(); this needs to
+ // modify the settings to run the associated executable instead of using
+ // shell::Open()
+
+ if (shouldRunShell() && m_sp.hooked) {
+ // this is a non-executable file, but it should be hooked; the associated
+ // executable needs to be retrieved and run instead
+ auto assoc = env::getAssociation(m_shellOpen);
+ if (!assoc.executable.filePath().isEmpty()) {
+ setBinary(assoc.executable);
+ setArguments(assoc.formattedCommandLine);
+ setCurrentDirectory(assoc.executable.absoluteDir());
+ m_shellOpen = {};
+ } else {
+ // if it fails, just use the regular shell open
+ log::error("failed to get the associated executable, running unhooked");
+ m_sp.hooked = false;
+ }
+ } else if (!shouldRunShell() && !m_sp.hooked) {
+ // this is an executable that should not be hooked; just run it through
+ // the shell
+ m_shellOpen = m_sp.binary;
+ }
+
+
std::optional<Results> r;
- if (!m_shellOpen.isEmpty()) {
+ if (shouldRunShell()) {
r = runShell();
} else {
r = runBinary();
@@ -669,9 +689,11 @@ ProcessRunner::Results ProcessRunner::run()
std::optional<ProcessRunner::Results> ProcessRunner::runShell()
{
- log::debug("executing from shell: '{}'", m_shellOpen);
+ const auto file = m_shellOpen.absoluteFilePath();
+
+ log::debug("executing from shell: '{}'", file);
- auto r = shell::Open(m_shellOpen);
+ auto r = shell::Open(file);
if (!r.success()) {
return Error;
}
diff --git a/src/processrunner.h b/src/processrunner.h
index d576216a..1bfdc465 100644
--- a/src/processrunner.h
+++ b/src/processrunner.h
@@ -67,6 +67,7 @@ public:
ProcessRunner& setProfileName(const QString& profileName);
ProcessRunner& setWaitForCompletion(
WaitFlags flags=NoFlags, UILocker::Reasons reason=UILocker::LockUI);
+ ProcessRunner& setHooked(bool b);
// - if the target is an executable file, runs it hooked
// - if the target is a file:
@@ -74,8 +75,7 @@ public:
// - if forceHook is true, gets the executable associated with the file
// and runs that hooked by passing the file as an argument
//
- ProcessRunner& setFromFile(
- QWidget* parent, const QFileInfo& targetInfo, bool forceHook = false);
+ ProcessRunner& setFromFile(QWidget* parent, const QFileInfo& targetInfo);
ProcessRunner& setFromExecutable(const Executable& exe);
ProcessRunner& setFromShortcut(const MOShortcut& shortcut);
@@ -150,11 +150,13 @@ private:
QString m_profileName;
UILocker::Reasons m_lockReason;
WaitFlags m_waitFlags;
- QString m_shellOpen;
+ QFileInfo m_shellOpen;
env::HandlePtr m_handle;
DWORD m_exitCode;
+ bool shouldRunShell() const;
+
// runs the command in m_shellOpen; returns empty if it can be waited for
//
std::optional<Results> runShell();