mirror of
https://github.com/ModOrganizer2/modorganizer.git
synced 2026-07-27 13:58:24 -07:00
conflicts tab: run exes unhooked by default
This commit is contained in:
+2
-1
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user