conflicts tab: run exes unhooked by default

This commit is contained in:
isanae
2019-12-08 11:33:03 -05:00
parent 2c59d13be6
commit c9049bb072
6 changed files with 98 additions and 65 deletions
+2 -1
View File
@@ -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();
}
+41 -33
View File
@@ -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,19 +602,8 @@ 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);
}
// run hooked
if (actions.runHooked) {
connect(actions.runHooked, &QAction::triggered, [&]{
runItemsHooked(tree);
});
menu.addAction(actions.runHooked);
}
// preview
@@ -635,8 +611,33 @@ void ConflictsTab::showContextMenu(const QPoint &pos, QTreeView* tree)
connect(actions.preview, &QAction::triggered, [&]{
previewItems(tree);
});
}
menu.addAction(actions.preview);
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, [&]{
openItems(tree, true);
});
menu.addAction(actions.runHooked);
}
// goto
@@ -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());
+2 -3
View File
@@ -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);
+2 -1
View File
@@ -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();
}
+46 -24
View File
@@ -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();
auto r = shell::Open(m_shellOpen);
log::debug("executing from shell: '{}'", file);
auto r = shell::Open(file);
if (!r.success()) {
return Error;
}
+5 -3
View File
@@ -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();