From ebb855dc1421e89813a1f4a74a4963d76aba9747 Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Sat, 25 May 2019 03:10:37 -0400
Subject: ExploreFile() will select the file in explorer when the path is a
file replaced more ShellExecute() calls with ExploreFile()
---
src/overwriteinfodialog.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
(limited to 'src/overwriteinfodialog.cpp')
diff --git a/src/overwriteinfodialog.cpp b/src/overwriteinfodialog.cpp
index 3d82cf17..e9d7ce06 100644
--- a/src/overwriteinfodialog.cpp
+++ b/src/overwriteinfodialog.cpp
@@ -21,6 +21,7 @@ along with Mod Organizer. If not, see .
#include "ui_overwriteinfodialog.h"
#include "report.h"
#include "utility.h"
+#include "organizercore.h"
#include
#include
#include
@@ -263,7 +264,7 @@ void OverwriteInfoDialog::createDirectoryTriggered()
void OverwriteInfoDialog::on_explorerButton_clicked()
{
- ::ShellExecuteW(nullptr, L"explore", ToWString(m_ModInfo->absolutePath()).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
+ ExploreFile(m_ModInfo->absolutePath());
}
void OverwriteInfoDialog::on_filesView_customContextMenuRequested(const QPoint &pos)
--
cgit v1.3.1
From 76708b9694070bcaa5775a097ae73ffc163ca31b Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Sat, 25 May 2019 08:34:52 -0400
Subject: put explore and open functions in namespace shell previewDataFile()
was duplicated in both MainWindow and ModInfoDialog, moved to OrganizerCore
added preview menu item to filetree better logging when shell operations fail
---
src/downloadmanager.cpp | 8 +-
src/mainwindow.cpp | 98 ++++---------------
src/modinfodialog.cpp | 133 ++++++++++----------------
src/modinfodialog.h | 12 ++-
src/organizercore.cpp | 228 +++++++++++++++++++++++++++++++++++++++++---
src/organizercore.h | 15 ++-
src/overwriteinfodialog.cpp | 2 +-
7 files changed, 311 insertions(+), 185 deletions(-)
(limited to 'src/overwriteinfodialog.cpp')
diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp
index 686092b5..1412df51 100644
--- a/src/downloadmanager.cpp
+++ b/src/downloadmanager.cpp
@@ -1037,7 +1037,7 @@ void DownloadManager::openFile(int index)
return;
}
- ExploreFile(m_OutputDirectory);
+ shell::ExploreFile(m_OutputDirectory);
return;
}
@@ -1051,18 +1051,18 @@ void DownloadManager::openInDownloadsFolder(int index)
const auto path = getFilePath(index);
if (QFile::exists(path)) {
- ExploreFile(path);
+ shell::ExploreFile(path);
return;
}
else {
const auto unfinished = path + ".unfinished";
if (QFile::exists(unfinished)) {
- ExploreFile(unfinished);
+ shell::ExploreFile(unfinished);
return;
}
}
- ExploreFile(m_OutputDirectory);
+ shell::ExploreFile(m_OutputDirectory);
}
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index ce6620c0..94cbe9b1 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -3241,12 +3241,12 @@ void MainWindow::openExplorer_clicked()
if (selection->hasSelection() && selection->selectedRows().count() > 1) {
for (QModelIndex idx : selection->selectedRows()) {
ModInfo::Ptr info = ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt());
- ExploreFile(info->absolutePath());
+ shell::ExploreFile(info->absolutePath());
}
}
else {
ModInfo::Ptr modInfo = ModInfo::getByIndex(m_ContextRow);
- ExploreFile(modInfo->absolutePath());
+ shell::ExploreFile(modInfo->absolutePath());
}
}
@@ -3261,14 +3261,14 @@ void MainWindow::openOriginExplorer_clicked()
continue;
}
ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex);
- ExploreFile(modInfo->absolutePath());
+ shell::ExploreFile(modInfo->absolutePath());
}
}
else {
QModelIndex idx = selection->currentIndex();
QString fileName = idx.data().toString();
ModInfo::Ptr modInfo = ModInfo::getByIndex(ModInfo::getIndex(m_OrganizerCore.pluginList()->origin(fileName)));
- ExploreFile(modInfo->absolutePath());
+ shell::ExploreFile(modInfo->absolutePath());
}
}
@@ -3283,7 +3283,7 @@ void MainWindow::openExplorer_activated()
std::vector flags = modInfo->getFlags();
if (modInfo->isRegular() || (std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end())) {
- ExploreFile(modInfo->absolutePath());
+ shell::ExploreFile(modInfo->absolutePath());
}
}
@@ -3304,7 +3304,7 @@ void MainWindow::openExplorer_activated()
std::vector flags = modInfo->getFlags();
if (modInfo->isRegular() || (std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end())) {
- ExploreFile(modInfo->absolutePath());
+ shell::ExploreFile(modInfo->absolutePath());
}
}
}
@@ -4271,61 +4271,61 @@ void MainWindow::disableVisibleMods()
void MainWindow::openInstanceFolder()
{
QString dataPath = qApp->property("dataPath").toString();
- ExploreFile(dataPath);
+ shell::ExploreFile(dataPath);
}
void MainWindow::openLogsFolder()
{
QString logsPath = qApp->property("dataPath").toString() + "/" + QString::fromStdWString(AppConfig::logPath());
- ExploreFile(logsPath);
+ shell::ExploreFile(logsPath);
}
void MainWindow::openInstallFolder()
{
- ExploreFile(qApp->applicationDirPath());
+ shell::ExploreFile(qApp->applicationDirPath());
}
void MainWindow::openPluginsFolder()
{
QString pluginsPath = QCoreApplication::applicationDirPath() + "/" + ToQString(AppConfig::pluginPath());
- ExploreFile(pluginsPath);
+ shell::ExploreFile(pluginsPath);
}
void MainWindow::openProfileFolder()
{
- ExploreFile(m_OrganizerCore.currentProfile()->absolutePath());
+ shell::ExploreFile(m_OrganizerCore.currentProfile()->absolutePath());
}
void MainWindow::openIniFolder()
{
if (m_OrganizerCore.currentProfile()->localSettingsEnabled())
{
- ExploreFile(m_OrganizerCore.currentProfile()->absolutePath());
+ shell::ExploreFile(m_OrganizerCore.currentProfile()->absolutePath());
}
else {
- ExploreFile(m_OrganizerCore.managedGame()->documentsDirectory());
+ shell::ExploreFile(m_OrganizerCore.managedGame()->documentsDirectory());
}
}
void MainWindow::openDownloadsFolder()
{
- ExploreFile(m_OrganizerCore.settings().getDownloadDirectory());
+ shell::ExploreFile(m_OrganizerCore.settings().getDownloadDirectory());
}
void MainWindow::openModsFolder()
{
- ExploreFile(m_OrganizerCore.settings().getModDirectory());
+ shell::ExploreFile(m_OrganizerCore.settings().getModDirectory());
}
void MainWindow::openGameFolder()
{
- ExploreFile(m_OrganizerCore.managedGame()->gameDirectory());
+ shell::ExploreFile(m_OrganizerCore.managedGame()->gameDirectory());
}
void MainWindow::openMyGamesFolder()
{
- ExploreFile(m_OrganizerCore.managedGame()->documentsDirectory());
+ shell::ExploreFile(m_OrganizerCore.managedGame()->documentsDirectory());
}
@@ -5304,67 +5304,7 @@ void MainWindow::disableSelectedMods_clicked()
void MainWindow::previewDataFile()
{
QString fileName = QDir::fromNativeSeparators(m_ContextItem->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
-
- // we need to look in the virtual directory for the file to make sure the info is up to date.
-
- // check if the file comes from the actual data folder instead of a mod
- QDir gameDirectory = m_OrganizerCore.managedGame()->dataDirectory().absolutePath();
- QString relativePath = gameDirectory.relativeFilePath(fileName);
- QDir dirRelativePath = gameDirectory.relativeFilePath(fileName);
- // if the file is on a different drive the dirRelativePath will actually be an absolute path so we make sure that is not the case
- if (!dirRelativePath.isAbsolute() && !relativePath.startsWith("..")) {
- fileName = relativePath;
- }
- else {
- // crude: we search for the next slash after the base mod directory to skip everything up to the data-relative directory
- int offset = m_OrganizerCore.settings().getModDirectory().size() + 1;
- offset = fileName.indexOf("/", offset);
- fileName = fileName.mid(offset + 1);
- }
-
-
-
- const FileEntry::Ptr file = m_OrganizerCore.directoryStructure()->searchFile(ToWString(fileName), nullptr);
-
- if (file.get() == nullptr) {
- reportError(tr("file not found: %1").arg(qUtf8Printable(fileName)));
- return;
- }
-
- // set up preview dialog
- PreviewDialog preview(fileName);
- auto addFunc = [&] (int originId) {
- FilesOrigin &origin = m_OrganizerCore.directoryStructure()->getOriginByID(originId);
- QString filePath = QDir::fromNativeSeparators(ToQString(origin.getPath())) + "/" + fileName;
- if (QFile::exists(filePath)) {
- // it's very possible the file doesn't exist, because it's inside an archive. we don't support that
- QWidget *wid = m_PluginContainer.previewGenerator().genPreview(filePath);
- if (wid == nullptr) {
- reportError(tr("failed to generate preview for %1").arg(filePath));
- } else {
- preview.addVariant(ToQString(origin.getName()), wid);
- }
- }
- };
-
- addFunc(file->getOrigin());
- for (auto alt : file->getAlternatives()) {
- addFunc(alt.first);
- }
- if (preview.numVariants() > 0) {
- QSettings &settings = m_OrganizerCore.settings().directInterface();
- QString key = QString("geometry/%1").arg(preview.objectName());
- if (settings.contains(key)) {
- preview.restoreGeometry(settings.value(key).toByteArray());
- }
- preview.exec();
- settings.setValue(key, preview.saveGeometry());
- } else {
- QMessageBox::information(this, tr("Sorry"), tr("Sorry, can't preview anything. This function currently does not support extracting from bsas."));
- }
+ m_OrganizerCore.previewFileWithAlternatives(this, fileName);
}
void MainWindow::openDataFile()
@@ -5374,7 +5314,7 @@ void MainWindow::openDataFile()
}
QFileInfo targetInfo(m_ContextItem->data(0, Qt::UserRole).toString());
- m_OrganizerCore.executeFile(this, targetInfo);
+ m_OrganizerCore.executeFileVirtualized(this, targetInfo);
}
diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp
index 9bd36f7e..c3ef7c47 100644
--- a/src/modinfodialog.cpp
+++ b/src/modinfodialog.cpp
@@ -322,9 +322,9 @@ bool ExpanderWidget::opened() const
ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directory, bool unmanaged, OrganizerCore *organizerCore, PluginContainer *pluginContainer, QWidget *parent)
: TutorableDialog("ModInfoDialog", parent), ui(new Ui::ModInfoDialog), m_ModInfo(modInfo),
m_ThumbnailMapper(this), m_RequestStarted(false),
- m_NewFolderAction(nullptr), m_OpenAction(nullptr), m_RenameAction(nullptr),
- m_DeleteAction(nullptr), m_HideAction(nullptr), m_UnhideAction(nullptr),
- m_Directory(directory), m_Origin(nullptr),
+ m_NewFolderAction(nullptr), m_OpenAction(nullptr), m_PreviewAction(nullptr),
+ m_RenameAction(nullptr), m_DeleteAction(nullptr), m_HideAction(nullptr),
+ m_UnhideAction(nullptr), m_Directory(directory), m_Origin(nullptr),
m_OrganizerCore(organizerCore), m_PluginContainer(pluginContainer)
{
ui->setupUi(this);
@@ -483,16 +483,18 @@ void ModInfoDialog::initFiletree(ModInfo::Ptr modInfo)
m_NewFolderAction = new QAction(tr("&New Folder"), ui->fileTree);
m_OpenAction = new QAction(tr("&Open"), ui->fileTree);
+ m_PreviewAction = new QAction(tr("&Preview"), ui->fileTree);
m_RenameAction = new QAction(tr("&Rename"), ui->fileTree);
m_DeleteAction = new QAction(tr("&Delete"), ui->fileTree);
m_HideAction = new QAction(tr("&Hide"), ui->fileTree);
m_UnhideAction = new QAction(tr("&Unhide"), ui->fileTree);
- QObject::connect(m_NewFolderAction, SIGNAL(triggered()), this, SLOT(createDirectoryTriggered()));
- QObject::connect(m_OpenAction, SIGNAL(triggered()), this, SLOT(openTriggered()));
- QObject::connect(m_RenameAction, SIGNAL(triggered()), this, SLOT(renameTriggered()));
- QObject::connect(m_DeleteAction, SIGNAL(triggered()), this, SLOT(deleteTriggered()));
- QObject::connect(m_HideAction, SIGNAL(triggered()), this, SLOT(hideTriggered()));
+ connect(m_NewFolderAction, SIGNAL(triggered()), this, SLOT(createDirectoryTriggered()));
+ connect(m_OpenAction, SIGNAL(triggered()), this, SLOT(openTriggered()));
+ connect(m_PreviewAction, SIGNAL(triggered()), this, SLOT(previewTriggered()));
+ connect(m_RenameAction, SIGNAL(triggered()), this, SLOT(renameTriggered()));
+ connect(m_DeleteAction, SIGNAL(triggered()), this, SLOT(deleteTriggered()));
+ connect(m_HideAction, SIGNAL(triggered()), this, SLOT(hideTriggered()));
connect(m_UnhideAction, SIGNAL(triggered()), this, SLOT(unhideTriggered()));
}
@@ -1244,12 +1246,11 @@ bool ModInfoDialog::recursiveDelete(const QModelIndex &index)
void ModInfoDialog::on_openInExplorerButton_clicked()
{
- ExploreFile(m_ModInfo->absolutePath());
+ shell::ExploreFile(m_ModInfo->absolutePath());
}
void ModInfoDialog::deleteFile(const QModelIndex &index)
{
-
bool res = m_FileSystemModel->isDir(index) ? recursiveDelete(index)
: m_FileSystemModel->remove(index);
if (!res) {
@@ -1406,21 +1407,29 @@ void ModInfoDialog::changeFiletreeVisibility(bool hide)
}
-void ModInfoDialog::openFile(const QModelIndex &index)
+void ModInfoDialog::openTriggered()
{
- QString fileName = m_FileSystemModel->filePath(index);
+ if (m_FileSelection.size() == 1) {
+ const auto index = m_FileSelection.at(0);
+ if (!index.isValid()) {
+ return;
+ }
- HINSTANCE res = ::ShellExecuteW(nullptr, L"open", ToWString(fileName).c_str(), nullptr, nullptr, SW_SHOW);
- if ((unsigned long long)res <= 32) {
- qCritical("failed to invoke %s: %d", qUtf8Printable(fileName), res);
+ QString fileName = m_FileSystemModel->filePath(index);
+ shell::OpenFile(fileName);
}
}
-
-void ModInfoDialog::openTriggered()
+void ModInfoDialog::previewTriggered()
{
- foreach(QModelIndex idx, m_FileSelection) {
- openFile(idx);
+ if (m_FileSelection.size() == 1) {
+ const auto index = m_FileSelection.at(0);
+ if (!index.isValid()) {
+ return;
+ }
+
+ QString fileName = m_FileSystemModel->filePath(index);
+ m_OrganizerCore->previewFile(this, m_ModInfo->name(), fileName);
}
}
@@ -1464,6 +1473,7 @@ void ModInfoDialog::on_fileTree_customContextMenuRequested(const QPoint &pos)
if (selectionModel->hasSelection()) {
bool enableOpen = true;
+ bool enablePreview = true;
bool enableRename = true;
bool enableDelete = true;
bool enableHide = true;
@@ -1484,10 +1494,15 @@ void ModInfoDialog::on_fileTree_customContextMenuRequested(const QPoint &pos)
if (!hasFiles) {
enableOpen = false;
+ enablePreview = false;
}
const QString fileName = m_FileSystemModel->fileName(m_FileSelection.at(0));
+ if (!canPreviewFile(false, fileName)) {
+ enablePreview = false;
+ }
+
if (!canHideFile(false, fileName)) {
enableHide = false;
}
@@ -1499,6 +1514,7 @@ void ModInfoDialog::on_fileTree_customContextMenuRequested(const QPoint &pos)
// this is a multiple selection, don't show open action so users don't open
// a thousand files
enableOpen = false;
+ enablePreview = false;
enableRename = false;
if (m_FileSelection.size() < max_scan_for_visibility) {
@@ -1530,6 +1546,10 @@ void ModInfoDialog::on_fileTree_customContextMenuRequested(const QPoint &pos)
menu.addAction(m_OpenAction);
}
+ if (enablePreview) {
+ menu.addAction(m_PreviewAction);
+ }
+
if (enableRename) {
menu.addAction(m_RenameAction);
}
@@ -1755,7 +1775,7 @@ void ModInfoDialog::openDataFile(const QTreeWidgetItem* item)
}
QFileInfo targetInfo(item->data(0, Qt::UserRole).toString());
- m_OrganizerCore->executeFile(this, targetInfo);
+ m_OrganizerCore->executeFileVirtualized(this, targetInfo);
}
void ModInfoDialog::previewDataFile(const QTreeWidgetItem* item)
@@ -1765,63 +1785,17 @@ void ModInfoDialog::previewDataFile(const QTreeWidgetItem* item)
}
QString fileName = QDir::fromNativeSeparators(item->data(0, Qt::UserRole).toString());
+ m_OrganizerCore->previewFileWithAlternatives(this, fileName);
+}
- // 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
-
- // we need to look in the virtual directory for the file to make sure the info is up to date.
-
- // check if the file comes from the actual data folder instead of a mod
- QDir gameDirectory = m_OrganizerCore->managedGame()->dataDirectory().absolutePath();
- QString relativePath = gameDirectory.relativeFilePath(fileName);
- QDir direRelativePath = gameDirectory.relativeFilePath(fileName);
- // if the file is on a different drive the dirRelativePath will actually be an absolute path so we make sure that is not the case
- if (!direRelativePath.isAbsolute() && !relativePath.startsWith("..")) {
- fileName = relativePath;
- }
- else {
- // crude: we search for the next slash after the base mod directory to skip everything up to the data-relative directory
- int offset = m_OrganizerCore->settings().getModDirectory().size() + 1;
- offset = fileName.indexOf("/", offset);
- fileName = fileName.mid(offset + 1);
- }
-
-
-
- const FileEntry::Ptr file = m_OrganizerCore->directoryStructure()->searchFile(ToWString(fileName), nullptr);
-
- if (file.get() == nullptr) {
- reportError(tr("file not found: %1").arg(qUtf8Printable(fileName)));
- return;
- }
-
- // set up preview dialog
- PreviewDialog preview(fileName);
- auto addFunc = [&](int originId) {
- FilesOrigin &origin = m_OrganizerCore->directoryStructure()->getOriginByID(originId);
- QString filePath = QDir::fromNativeSeparators(ToQString(origin.getPath())) + "/" + fileName;
- if (QFile::exists(filePath)) {
- // it's very possible the file doesn't exist, because it's inside an archive. we don't support that
- QWidget *wid = m_PluginContainer->previewGenerator().genPreview(filePath);
- if (wid == nullptr) {
- reportError(tr("failed to generate preview for %1").arg(filePath));
- }
- else {
- preview.addVariant(ToQString(origin.getName()), wid);
- }
- }
- };
+bool ModInfoDialog::canPreviewFile(bool isArchive, const QString& filename) const
+{
+ if (isArchive) {
+ return false;
+ }
- addFunc(file->getOrigin());
- for (auto alt : file->getAlternatives()) {
- addFunc(alt.first);
- }
- if (preview.numVariants() > 0) {
- preview.exec();
- }
- else {
- QMessageBox::information(this, tr("Sorry"), tr("Sorry, can't preview anything. This function currently does not support extracting from bsas."));
- }
+ const auto ext = QFileInfo(filename).suffix();
+ return m_PluginContainer->previewGenerator().previewSupported(ext);
}
bool ModInfoDialog::canHideFile(bool isArchive, const QString& filename) const
@@ -1866,12 +1840,9 @@ bool ModInfoDialog::canUnhideConflictItem(const QTreeWidgetItem* item) const
bool ModInfoDialog::canPreviewConflictItem(const QTreeWidgetItem* item) const
{
- const QString fileName = item->data(0, Qt::UserRole).toString();
- if (!m_PluginContainer->previewGenerator().previewSupported(QFileInfo(fileName).suffix())) {
- return false;
- }
-
- return true;
+ return canPreviewFile(
+ item->data(1, Qt::UserRole + 2).toBool(),
+ item->data(0, Qt::UserRole).toString());
}
void ModInfoDialog::on_overwriteTree_customContextMenuRequested(const QPoint &pos)
diff --git a/src/modinfodialog.h b/src/modinfodialog.h
index 6bf30a52..c0730afa 100644
--- a/src/modinfodialog.h
+++ b/src/modinfodialog.h
@@ -313,7 +313,6 @@ private:
QString getFileCategory(int categoryID);
bool recursiveDelete(const QModelIndex &index);
void deleteFile(const QModelIndex &index);
- void openFile(const QModelIndex &index);
void saveIniTweaks();
void saveCategories(QTreeWidgetItem *currentNode);
void saveCurrentTextFile();
@@ -348,10 +347,11 @@ private slots:
void delete_activated();
- void deleteTriggered();
- void renameTriggered();
- void openTriggered();
void createDirectoryTriggered();
+ void openTriggered();
+ void previewTriggered();
+ void renameTriggered();
+ void deleteTriggered();
void hideTriggered();
void unhideTriggered();
@@ -416,6 +416,7 @@ private:
QAction *m_NewFolderAction;
QAction *m_OpenAction;
+ QAction *m_PreviewAction;
QAction *m_RenameAction;
QAction *m_DeleteAction;
QAction *m_HideAction;
@@ -439,11 +440,12 @@ private:
bool canUnhideConflictItem(const QTreeWidgetItem* item) const;
bool canPreviewConflictItem(const QTreeWidgetItem* item) const;
- void previewDataFile(const QTreeWidgetItem* item);
void openDataFile(const QTreeWidgetItem* item);
+ void previewDataFile(const QTreeWidgetItem* item);
void changeConflictFilesVisibility(bool hide);
void changeFiletreeVisibility(bool hide);
+ bool canPreviewFile(bool isArchive, const QString& filename) const;
bool canHideFile(bool isArchive, const QString& filename) const;
bool canUnhideFile(bool isArchive, const QString& filename) const;
};
diff --git a/src/organizercore.cpp b/src/organizercore.cpp
index d228dfe1..3a6b810e 100644
--- a/src/organizercore.cpp
+++ b/src/organizercore.cpp
@@ -35,6 +35,7 @@
#include "instancemanager.h"
#include
#include "helper.h"
+#include "previewdialog.h"
#include
#include
@@ -331,16 +332,103 @@ bool GetFileExecutionContext(
}
-bool ExploreDirectory(const QFileInfo& info)
+const char* ShellExecuteError(int i)
{
- const auto path = QDir::toNativeSeparators(info.absoluteFilePath());
- const auto ws_path = path.toStdWString();
+ switch (i) {
+ case 0:
+ return "The operating system is out of memory or resources";
+
+ case ERROR_FILE_NOT_FOUND:
+ return "The specified file was not found";
+
+ case ERROR_PATH_NOT_FOUND:
+ return "The specified path was not found";
+
+ case ERROR_BAD_FORMAT:
+ return "The .exe file is invalid (non-Win32 .exe or error in .exe image)";
+
+ case SE_ERR_ACCESSDENIED:
+ return "The operating system denied access to the specified file";
+
+ case SE_ERR_ASSOCINCOMPLETE:
+ return "The file name association is incomplete or invalid";
+
+ case SE_ERR_DDEBUSY:
+ return "The DDE transaction could not be completed because other DDE "
+ "transactions were being processed";
+
+ case SE_ERR_DDEFAIL:
+ return "The DDE transaction failed";
+
+ case SE_ERR_DDETIMEOUT:
+ return "The DDE transaction could not be completed because the request "
+ "timed out";
+
+ case SE_ERR_DLLNOTFOUND:
+ return "The specified DLL was not found";
+
+ case SE_ERR_NOASSOC:
+ return "There is no application associated with the given file name "
+ "extension";
+
+ case SE_ERR_OOM:
+ return "There was not enough memory to complete the operation";
+
+ case SE_ERR_SHARE:
+ return "A sharing violation occurred";
+
+ default:
+ return "Unknown error";
+ }
+}
+
+void LogShellFailure(
+ const wchar_t* operation, const wchar_t* file, const wchar_t* params,
+ HINSTANCE h)
+{
+ const auto code = static_cast(reinterpret_cast(h));
+
+ QString s = "failed to invoke";
+
+ if (operation) {
+ s += " " + QString::fromWCharArray(operation);
+ }
+
+ if (file) {
+ s += " " + QString::fromWCharArray(file);
+ }
+ if (params) {
+ s += " " + QString::fromWCharArray(params);
+ }
+
+ qCritical(
+ "failed to invoke %s: %s (error %d)",
+ s, ShellExecuteError(code), code);
+}
+
+bool ShellExecuteWrapper(
+ const wchar_t* operation, const wchar_t* file, const wchar_t* params)
+{
const auto h = ::ShellExecuteW(
- nullptr, L"explore", ws_path.c_str(), nullptr, nullptr, SW_SHOWNORMAL);
+ 0, operation, file, params, nullptr, SW_SHOWNORMAL);
// anything <= 32 is not an actual HINSTANCE and signals failure
- return (h > reinterpret_cast(32));
+ if (h <= reinterpret_cast(32))
+ {
+ LogShellFailure(operation, file, params, h);
+ return false;
+ }
+
+ return true;
+}
+
+bool ExploreDirectory(const QFileInfo& info)
+{
+ const auto path = QDir::toNativeSeparators(info.absoluteFilePath());
+ const auto ws_path = path.toStdWString();
+
+ return ShellExecuteWrapper(L"explore", ws_path.c_str(), nullptr);
}
bool ExploreFileInDirectory(const QFileInfo& info)
@@ -349,14 +437,13 @@ bool ExploreFileInDirectory(const QFileInfo& info)
const auto params = "/select,\"" + path + "\"";
const auto ws_params = params.toStdWString();
- const auto h = ::ShellExecuteW(
- nullptr, nullptr, L"explorer", ws_params.c_str(), nullptr, SW_SHOWNORMAL);
-
- // anything <= 32 is not an actual HINSTANCE and signals failure
- return (h > reinterpret_cast(32));
+ return ShellExecuteWrapper(nullptr, L"explorer", ws_params.c_str());
}
+namespace shell
+{
+
bool ExploreFile(const QFileInfo& info)
{
if (info.isFile()) {
@@ -385,6 +472,14 @@ bool ExploreFile(const QDir& dir)
return ExploreFile(QFileInfo(dir.absolutePath()));
}
+bool OpenFile(const QString& path)
+{
+ const auto ws_path = path.toStdWString();
+ return ShellExecuteWrapper(L"open", ws_path.c_str(), nullptr);
+}
+
+} // namespace shell
+
OrganizerCore::OrganizerCore(const QSettings &initSettings)
: m_UserInterface(nullptr)
@@ -1339,7 +1434,8 @@ QStringList OrganizerCore::modsSortedByProfilePriority() const
return res;
}
-bool OrganizerCore::executeFile(QWidget* parent, const QFileInfo& targetInfo)
+bool OrganizerCore::executeFileVirtualized(
+ QWidget* parent, const QFileInfo& targetInfo)
{
QFileInfo binaryInfo;
QString arguments;
@@ -1372,6 +1468,116 @@ bool OrganizerCore::executeFile(QWidget* parent, const QFileInfo& targetInfo)
return false;
}
+bool OrganizerCore::previewFileWithAlternatives(
+ QWidget* parent, QString fileName)
+{
+ // 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
+
+ // we need to look in the virtual directory for the file to make sure the info is up to date.
+
+ // check if the file comes from the actual data folder instead of a mod
+ QDir gameDirectory = managedGame()->dataDirectory().absolutePath();
+ QString relativePath = gameDirectory.relativeFilePath(fileName);
+ QDir dirRelativePath = gameDirectory.relativeFilePath(fileName);
+
+ // if the file is on a different drive the dirRelativePath will actually be an
+ // absolute path so we make sure that is not the case
+ if (!dirRelativePath.isAbsolute() && !relativePath.startsWith("..")) {
+ fileName = relativePath;
+ }
+ else {
+ // crude: we search for the next slash after the base mod directory to skip
+ // everything up to the data-relative directory
+ int offset = settings().getModDirectory().size() + 1;
+ offset = fileName.indexOf("/", offset);
+ fileName = fileName.mid(offset + 1);
+ }
+
+
+
+ const FileEntry::Ptr file = directoryStructure()->searchFile(ToWString(fileName), nullptr);
+
+ if (file.get() == nullptr) {
+ reportError(tr("file not found: %1").arg(qUtf8Printable(fileName)));
+ return false;
+ }
+
+ // set up preview dialog
+ PreviewDialog preview(fileName);
+ auto addFunc = [&](int originId) {
+ FilesOrigin &origin = directoryStructure()->getOriginByID(originId);
+ QString filePath = QDir::fromNativeSeparators(ToQString(origin.getPath())) + "/" + fileName;
+ if (QFile::exists(filePath)) {
+ // it's very possible the file doesn't exist, because it's inside an archive. we don't support that
+ QWidget *wid = m_PluginContainer->previewGenerator().genPreview(filePath);
+ if (wid == nullptr) {
+ reportError(tr("failed to generate preview for %1").arg(filePath));
+ }
+ else {
+ preview.addVariant(ToQString(origin.getName()), wid);
+ }
+ }
+ };
+
+ addFunc(file->getOrigin());
+ for (auto alt : file->getAlternatives()) {
+ addFunc(alt.first);
+ }
+
+ if (preview.numVariants() > 0) {
+ QSettings &s = settings().directInterface();
+ QString key = QString("geometry/%1").arg(preview.objectName());
+ if (s.contains(key)) {
+ preview.restoreGeometry(s.value(key).toByteArray());
+ }
+
+ preview.exec();
+
+ s.setValue(key, preview.saveGeometry());
+
+ return true;
+ }
+ else {
+ QMessageBox::information(
+ parent, tr("Sorry"),
+ tr("Sorry, can't preview anything. This function currently does not support extracting from bsas."));
+
+ return false;
+ }
+}
+
+bool OrganizerCore::previewFile(
+ QWidget* parent, const QString& originName, const QString& path)
+{
+ if (!QFile::exists(path)) {
+ reportError(tr("File '%1' not found.").arg(path));
+ return false;
+ }
+
+ PreviewDialog preview(path);
+
+ QWidget *wid = m_PluginContainer->previewGenerator().genPreview(path);
+ if (wid == nullptr) {
+ reportError(tr("Failed to generate preview for %1").arg(path));
+ return false;
+ }
+
+ preview.addVariant(originName, wid);
+
+ QSettings &s = settings().directInterface();
+ QString key = QString("geometry/%1").arg(preview.objectName());
+ if (s.contains(key)) {
+ preview.restoreGeometry(s.value(key).toByteArray());
+ }
+
+ preview.exec();
+
+ s.setValue(key, preview.saveGeometry());
+
+ return true;
+}
+
void OrganizerCore::spawnBinary(const QFileInfo &binary,
const QString &arguments,
const QDir ¤tDirectory,
diff --git a/src/organizercore.h b/src/organizercore.h
index 3f773277..41f0fd46 100644
--- a/src/organizercore.h
+++ b/src/organizercore.h
@@ -67,9 +67,14 @@ bool GetFileExecutionContext(
QWidget* parent, const QFileInfo &targetInfo,
QFileInfo &binaryInfo, QString &arguments, FileExecutionTypes& type);
-bool ExploreFile(const QFileInfo& info);
-bool ExploreFile(const QString& path);
-bool ExploreFile(const QDir& dir);
+namespace shell
+{
+ bool ExploreFile(const QFileInfo& info);
+ bool ExploreFile(const QString& path);
+ bool ExploreFile(const QDir& dir);
+
+ bool OpenFile(const QString& path);
+}
class OrganizerCore : public QObject, public MOBase::IPluginDiagnose
@@ -156,7 +161,9 @@ public:
void doAfterLogin(const std::function &function) { m_PostLoginTasks.append(function); }
- bool executeFile(QWidget* parent, const QFileInfo& targetInfo);
+ bool executeFileVirtualized(QWidget* parent, const QFileInfo& targetInfo);
+ bool previewFileWithAlternatives(QWidget* parent, QString filename);
+ bool previewFile(QWidget* parent, const QString& originName, const QString& path);
void spawnBinary(const QFileInfo &binary, const QString &arguments = "",
const QDir ¤tDirectory = QDir(),
diff --git a/src/overwriteinfodialog.cpp b/src/overwriteinfodialog.cpp
index e9d7ce06..d6764852 100644
--- a/src/overwriteinfodialog.cpp
+++ b/src/overwriteinfodialog.cpp
@@ -264,7 +264,7 @@ void OverwriteInfoDialog::createDirectoryTriggered()
void OverwriteInfoDialog::on_explorerButton_clicked()
{
- ExploreFile(m_ModInfo->absolutePath());
+ shell::ExploreFile(m_ModInfo->absolutePath());
}
void OverwriteInfoDialog::on_filesView_customContextMenuRequested(const QPoint &pos)
--
cgit v1.3.1
From c82c7af678c088a6b94fc8a4a0f31fc9498e8220 Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Sun, 26 May 2019 04:00:54 -0400
Subject: changed rest of ShellExecuteW() calls to use shell::Execute(),
shell::OpenLink() or shell::OpenFile()
---
src/downloadmanager.cpp | 4 ++--
src/modinfodialog.cpp | 3 +--
src/motddialog.cpp | 3 ++-
src/organizercore.cpp | 14 ++++++++++++++
src/organizercore.h | 3 +++
src/overwriteinfodialog.cpp | 7 +------
src/problemsdialog.cpp | 3 ++-
src/selfupdater.cpp | 19 ++++++-------------
src/settings.cpp | 23 ++++++++++++-----------
9 files changed, 43 insertions(+), 36 deletions(-)
(limited to 'src/overwriteinfodialog.cpp')
diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp
index 1412df51..ecc3cfd6 100644
--- a/src/downloadmanager.cpp
+++ b/src/downloadmanager.cpp
@@ -1030,10 +1030,10 @@ void DownloadManager::openFile(int index)
reportError(tr("OpenFile: invalid download index %1").arg(index));
return;
}
+
QDir path = QDir(m_OutputDirectory);
if (path.exists(getFileName(index))) {
-
- ::ShellExecuteW(nullptr, L"open", ToWString(QDir::toNativeSeparators(getFilePath(index))).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
+ shell::OpenFile(getFilePath(index));
return;
}
diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp
index c3ef7c47..19a03ea7 100644
--- a/src/modinfodialog.cpp
+++ b/src/modinfodialog.cpp
@@ -1075,10 +1075,9 @@ void ModInfoDialog::linkClicked(const QUrl &url)
//Ideally we'd ask the mod for the game and the web service then pass the game
//and URL to the web service
if (NexusInterface::instance(m_PluginContainer)->isURLGameRelated(url)) {
-
emit linkActivated(url.toString());
} else {
- ::ShellExecuteW(nullptr, L"open", ToWString(url.toString()).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
+ shell::OpenLink(url);
}
}
diff --git a/src/motddialog.cpp b/src/motddialog.cpp
index 96d88542..9be41d96 100644
--- a/src/motddialog.cpp
+++ b/src/motddialog.cpp
@@ -21,6 +21,7 @@ along with Mod Organizer. If not, see .
#include "bbcode.h"
#include "utility.h"
#include "ui_motddialog.h"
+#include "organizercore.h"
#include
MotDDialog::MotDDialog(const QString &message, QWidget *parent)
@@ -43,5 +44,5 @@ void MotDDialog::on_okButton_clicked()
void MotDDialog::linkClicked(const QUrl &url)
{
- ::ShellExecuteW(nullptr, L"open", MOBase::ToWString(url.toString()).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
+ shell::OpenLink(url);
}
diff --git a/src/organizercore.cpp b/src/organizercore.cpp
index 3a6b810e..a10c23d7 100644
--- a/src/organizercore.cpp
+++ b/src/organizercore.cpp
@@ -478,6 +478,20 @@ bool OpenFile(const QString& path)
return ShellExecuteWrapper(L"open", ws_path.c_str(), nullptr);
}
+bool OpenLink(const QUrl& url)
+{
+ const auto ws_url = url.toString().toStdWString();
+ return ShellExecuteWrapper(L"open", ws_url.c_str(), nullptr);
+}
+
+bool Execute(const QString& program, const QString& params)
+{
+ const auto program_ws = program.toStdWString();
+ const auto params_ws = params.toStdWString();
+
+ return ShellExecuteWrapper(L"open", program_ws.c_str(), params_ws.c_str());
+}
+
} // namespace shell
diff --git a/src/organizercore.h b/src/organizercore.h
index 41f0fd46..c9434e92 100644
--- a/src/organizercore.h
+++ b/src/organizercore.h
@@ -74,6 +74,9 @@ namespace shell
bool ExploreFile(const QDir& dir);
bool OpenFile(const QString& path);
+ bool OpenLink(const QUrl& url);
+
+ bool Execute(const QString& program, const QString& params);
}
diff --git a/src/overwriteinfodialog.cpp b/src/overwriteinfodialog.cpp
index d6764852..9b3e55df 100644
--- a/src/overwriteinfodialog.cpp
+++ b/src/overwriteinfodialog.cpp
@@ -218,12 +218,7 @@ void OverwriteInfoDialog::renameTriggered()
void OverwriteInfoDialog::openFile(const QModelIndex &index)
{
- QString fileName = m_FileSystemModel->filePath(index);
-
- HINSTANCE res = ::ShellExecuteW(nullptr, L"open", ToWString(fileName).c_str(), nullptr, nullptr, SW_SHOW);
- if ((INT_PTR)res <= 32) {
- qCritical("failed to invoke %s: %d", qUtf8Printable(fileName), res);
- }
+ shell::OpenFile(m_FileSystemModel->filePath(index));
}
diff --git a/src/problemsdialog.cpp b/src/problemsdialog.cpp
index 795baab0..56109d34 100644
--- a/src/problemsdialog.cpp
+++ b/src/problemsdialog.cpp
@@ -1,5 +1,6 @@
#include "problemsdialog.h"
#include "ui_problemsdialog.h"
+#include "organizercore.h"
#include
#include
#include
@@ -87,5 +88,5 @@ void ProblemsDialog::startFix()
void ProblemsDialog::urlClicked(const QUrl &url)
{
- ::ShellExecuteW(nullptr, L"open", ToWString(url.toString()).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
+ shell::OpenLink(url);
}
diff --git a/src/selfupdater.cpp b/src/selfupdater.cpp
index 4c0f9a8d..271c621b 100644
--- a/src/selfupdater.cpp
+++ b/src/selfupdater.cpp
@@ -31,6 +31,7 @@ along with Mod Organizer. If not, see .
#include "settings.h"
#include "bbcode.h"
#include "plugincontainer.h"
+#include "organizercore.h"
#include
#include
#include
@@ -178,7 +179,7 @@ void SelfUpdater::startUpdate()
tr("New update available (%1)")
.arg(m_UpdateCandidate["tag_name"].toString()), tr("Do you want to install update? All your mods and setup will be left untouched.\nSelect Show Details option to see the full change-log."),
QMessageBox::Yes | QMessageBox::Cancel, m_Parent);
-
+
query.setDetailedText(m_UpdateCandidate["body"].toString());
query.button(QMessageBox::Yes)->setText(tr("Install"));
@@ -329,22 +330,14 @@ void SelfUpdater::downloadCancel()
void SelfUpdater::installUpdate()
{
- const QString mopath
- = QDir::fromNativeSeparators(qApp->property("dataPath").toString());
-
- std::wstring parameters = ToWString("/DIR=\"" + qApp->applicationDirPath() + "\" ");
+ const QString parameters = "/DIR=\"" + qApp->applicationDirPath() + "\" ";
- HINSTANCE res = ::ShellExecuteW(
- nullptr, L"open", m_UpdateFile.fileName().toStdWString().c_str(), parameters.c_str(),
- nullptr, SW_SHOW);
-
- if (res > (HINSTANCE)32) {
+ if (shell::Execute(m_UpdateFile.fileName(), parameters)) {
QCoreApplication::quit();
} else {
- reportError(tr("Failed to start %1: %2")
- .arg(m_UpdateFile.fileName())
- .arg((INT_PTR)res));
+ reportError(tr("Failed to start %1").arg(m_UpdateFile.fileName()));
}
+
m_UpdateFile.remove();
}
diff --git a/src/settings.cpp b/src/settings.cpp
index 231487bb..a844fdc9 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -130,18 +130,19 @@ bool Settings::pluginBlacklisted(const QString &fileName) const
void Settings::registerAsNXMHandler(bool force)
{
- std::wstring nxmPath = ToWString(QCoreApplication::applicationDirPath() + "/nxmhandler.exe");
- std::wstring executable = ToWString(QCoreApplication::applicationFilePath());
- std::wstring mode = force ? L"forcereg" : L"reg";
- std::wstring parameters = mode + L" " + m_GamePlugin->gameShortName().toStdWString();
- for (QString altGame : m_GamePlugin->validShortNames()) {
- parameters += L"," + altGame.toStdWString();
+ const auto nxmPath = QCoreApplication::applicationDirPath() + "/nxmhandler.exe";
+ const auto executable = QCoreApplication::applicationFilePath();
+
+ QString mode = force ? "forcereg" : "reg";
+ QString parameters = mode + " " + m_GamePlugin->gameShortName();
+ for (const QString& altGame : m_GamePlugin->validShortNames()) {
+ parameters += "," + altGame;
}
- parameters += L" \"" + executable + L"\"";
- HINSTANCE res = ::ShellExecuteW(nullptr, L"open", nxmPath.c_str(), parameters.c_str(), nullptr, SW_SHOWNORMAL);
- if ((INT_PTR)res <= 32) {
- QMessageBox::critical(nullptr, tr("Failed"),
- tr("Sorry, failed to start the helper application"));
+ parameters += " \"" + executable + "\"";
+
+ if (!shell::Execute(nxmPath, parameters)) {
+ QMessageBox::critical(
+ nullptr, tr("Failed"), tr("Failed to start the helper application"));
}
}
--
cgit v1.3.1
From 724fad7cb62a0ee4913ed41bde45c7564183c7af Mon Sep 17 00:00:00 2001
From: Matte A
Date: Sun, 23 Jun 2019 04:38:36 +0200
Subject: Correcting minor spelling mistakes in the UI + add contributor
---
src/aboutdialog.ui | 4 ++--
src/instancemanager.cpp | 2 +-
src/mainwindow.cpp | 4 ++--
src/mainwindow.ui | 4 ++--
src/moapplication.cpp | 4 ++--
src/modinfodialog.cpp | 8 ++++----
src/modinfodialog.ui | 8 ++++----
src/organizercore.cpp | 6 +++---
src/overwriteinfodialog.cpp | 8 ++++----
src/settingsdialog.ui | 4 ++--
src/spawn.cpp | 2 +-
src/tutorials/tutorial_conflictresolution_main.js | 2 +-
src/tutorials/tutorial_firststeps_main.js | 2 +-
src/tutorials/tutorial_firststeps_modinfo.js | 2 +-
14 files changed, 30 insertions(+), 30 deletions(-)
(limited to 'src/overwriteinfodialog.cpp')
diff --git a/src/aboutdialog.ui b/src/aboutdialog.ui
index 86b95c83..1b3f0ad2 100644
--- a/src/aboutdialog.ui
+++ b/src/aboutdialog.ui
@@ -337,7 +337,7 @@
-
- Jax (Swedish)
+ Jax, Nubbie (Swedish)
-
@@ -361,7 +361,7 @@
-
- Other Supporters && Contributors
+ Other Supporters & Contributors
-
diff --git a/src/instancemanager.cpp b/src/instancemanager.cpp
index 5b57827a..b5130e8b 100644
--- a/src/instancemanager.cpp
+++ b/src/instancemanager.cpp
@@ -102,7 +102,7 @@ QString InstanceManager::manageInstances(const QStringList &instanceList) const
SelectionDialog selection(
QString("
%1
%2")
.arg(QObject::tr("Choose Instance to Delete"))
- .arg(QObject::tr("Be Carefull! Deleting an Instance will remove all your files for that Instance (mods, downloads, profiles, configuration, ...). Custom paths outside of the instance folder for downloads, mods, etc. will be left untoched.")),
+ .arg(QObject::tr("Be Careful! Deleting an Instance will remove all your files for that Instance (mods, downloads, profiles, configuration, ...). Custom paths outside of the instance folder for downloads, mods, etc. will be left untoched.")),
nullptr);
for (const QString &instance : instanceList)
{
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index e383006b..da7c721d 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -6796,7 +6796,7 @@ void MainWindow::on_bossButton_clicked()
}
if (errorMessages.length() > 0) {
- QMessageBox *warn = new QMessageBox(QMessageBox::Warning, tr("Errors occured"), errorMessages.c_str(), QMessageBox::Ok, this);
+ QMessageBox *warn = new QMessageBox(QMessageBox::Warning, tr("Errors occurred"), errorMessages.c_str(), QMessageBox::Ok, this);
warn->setModal(false);
warn->show();
}
@@ -6899,7 +6899,7 @@ void MainWindow::on_saveModsButton_clicked()
m_OrganizerCore.currentProfile()->writeModlistNow(true);
QDateTime now = QDateTime::currentDateTime();
if (createBackup(m_OrganizerCore.currentProfile()->getModlistFileName(), now)) {
- MessageDialog::showMessage(tr("Backup of modlist created"), this);
+ MessageDialog::showMessage(tr("Backup of mod list created"), this);
}
}
diff --git a/src/mainwindow.ui b/src/mainwindow.ui
index 0ee74239..6a816262 100644
--- a/src/mainwindow.ui
+++ b/src/mainwindow.ui
@@ -221,8 +221,8 @@
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Create profiles here. Each profile contains its own list of active mods and esps. This way you can quickly switch between setups for different play throughs.</span></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Please note that right now your esp load order is not kept seperate for different profiles.</span></p></body></html>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Create profiles here. Each profile contains its own list of active mods and esps. This way you can quickly switch between setups for different playthroughs.</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Please note that right now your esp load order is not kept separate for different profiles.</span></p></body></html>
diff --git a/src/moapplication.cpp b/src/moapplication.cpp
index 3a791827..5652833a 100644
--- a/src/moapplication.cpp
+++ b/src/moapplication.cpp
@@ -116,12 +116,12 @@ bool MOApplication::notify(QObject *receiver, QEvent *event)
} catch (const std::exception &e) {
qCritical("uncaught exception in handler (object %s, eventtype %d): %s",
receiver->objectName().toUtf8().constData(), event->type(), e.what());
- reportError(tr("an error occured: %1").arg(e.what()));
+ reportError(tr("an error occurred: %1").arg(e.what()));
return false;
} catch (...) {
qCritical("uncaught non-std exception in handler (object %s, eventtype %d)",
receiver->objectName().toUtf8().constData(), event->type());
- reportError(tr("an error occured"));
+ reportError(tr("an error occurred"));
return false;
}
}
diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp
index 2be8e481..188ea956 100644
--- a/src/modinfodialog.cpp
+++ b/src/modinfodialog.cpp
@@ -1670,13 +1670,13 @@ void ModInfoDialog::delete_activated()
}
else if (selection->selectedRows().count() == 1) {
QString fileName = m_FileSystemModel->fileName(selection->selectedRows().at(0));
- if (QMessageBox::question(this, tr("Confirm"), tr("Are sure you want to delete \"%1\"?").arg(fileName),
+ if (QMessageBox::question(this, tr("Confirm"), tr("Are you sure you want to delete \"%1\"?").arg(fileName),
QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
return;
}
}
else {
- if (QMessageBox::question(this, tr("Confirm"), tr("Are sure you want to delete the selected files?"),
+ if (QMessageBox::question(this, tr("Confirm"), tr("Are you sure you want to delete the selected files?"),
QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
return;
}
@@ -1695,12 +1695,12 @@ void ModInfoDialog::deleteTriggered()
return;
} else if (m_FileSelection.count() == 1) {
QString fileName = m_FileSystemModel->fileName(m_FileSelection.at(0));
- if (QMessageBox::question(this, tr("Confirm"), tr("Are sure you want to delete \"%1\"?").arg(fileName),
+ if (QMessageBox::question(this, tr("Confirm"), tr("Are you sure you want to delete \"%1\"?").arg(fileName),
QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
return;
}
} else {
- if (QMessageBox::question(this, tr("Confirm"), tr("Are sure you want to delete the selected files?"),
+ if (QMessageBox::question(this, tr("Confirm"), tr("Are you sure you want to delete the selected files?"),
QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
return;
}
diff --git a/src/modinfodialog.ui b/src/modinfodialog.ui
index e009a599..eed4e31f 100644
--- a/src/modinfodialog.ui
+++ b/src/modinfodialog.ui
@@ -136,7 +136,7 @@
This is a list of ini tweaks (ini modifications that can be toggled).
- This is a list of ini tweaks. Ini Tweaks are (usually small) fragments of ini files that are applied over existing settings in skyrim.ini/skyrimprefs.ini. Each tweak can be toggled individually. You should check the description of the mod wether the tweaks are really optional.
+ This is a list of ini tweaks. Ini Tweaks are (usually small) fragments of ini files that are applied over existing settings in skyrim.ini/skyrimprefs.ini. Each tweak can be toggled individually. You should check the description of the mod whether the tweaks are really optional.
@@ -383,7 +383,7 @@ Most mods do not have optional esps, so chances are good you are looking at an e
ESPs in the data directory and thus visible to the game.
- These are the mod files that are in the (virtual) data directory of your game and will thus be selecteable in the esp list in the main window.
+ These are the mod files that are in the (virtual) data directory of your game and will thus be selectable in the esp list in the main window.
@@ -897,7 +897,7 @@ text-align: left;
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:400; font-style:normal;">
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Mod ID for this mod on Nexus. This is filled in automatically if you downloaded and installed the mod from inside MO. Otherwise you can enter it manually. To find the correct id, find the mod on nexus. The URL will look like this: <a href=" https://www.nexusmods.com/skyrimspecialedition/mods/6194"><span style=" text-decoration: underline; color:#0000ff;">https://www.nexusmods.com/skyrimspecialedition/mods/6194</span></a>. In this example, 6194 is the id you're looking for. Besides: The above is the link to Mod Organizer2 on Nexus. Why not go there now and endorse us?</p></body></html>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Mod ID for this mod on Nexus. This is filled in automatically if you downloaded and installed the mod from inside MO. Otherwise you can enter it manually. To find the correct id, find the mod on nexus. The URL will look like this: <a href=" https://www.nexusmods.com/skyrimspecialedition/mods/6194"><span style=" text-decoration: underline; color:#0000ff;">https://www.nexusmods.com/skyrimspecialedition/mods/6194</span></a>. In this example, 6194 is the id you're looking for. Besides: The above is the link to Mod Organizer 2 on Nexus. Why not go there now and endorse us?</p></body></html>
@@ -1067,7 +1067,7 @@ p, li { white-space: pre-wrap; }
-
- Web page URL (only used if invalid NexusID) :
+ Web page URL (only used if invalid Nexus ID) :
diff --git a/src/organizercore.cpp b/src/organizercore.cpp
index c724e57f..2cad9ce8 100644
--- a/src/organizercore.cpp
+++ b/src/organizercore.cpp
@@ -391,7 +391,7 @@ void OrganizerCore::storeSettings()
if (!shellCopy(iniFile, iniFile + ".new", true, qApp->activeWindow())) {
QMessageBox::critical(
qApp->activeWindow(), tr("Failed to write settings"),
- tr("An error occured trying to update MO settings to %1: %2")
+ tr("An error occurred trying to update MO settings to %1: %2")
.arg(iniFile, windowsErrorString(::GetLastError())));
return;
}
@@ -418,7 +418,7 @@ void OrganizerCore::storeSettings()
: tr("Unknown error %1").arg(result);
QMessageBox::critical(
qApp->activeWindow(), tr("Failed to write settings"),
- tr("An error occured trying to write back MO settings to %1: %2")
+ tr("An error occurred trying to write back MO settings to %1: %2")
.arg(writeTarget, reason));
}
}
@@ -1570,7 +1570,7 @@ HANDLE OrganizerCore::spawnBinaryProcess(const QFileInfo &binary,
tr("MO was denied access to the Steam process. This normally indicates that "
"Steam is being run as administrator while MO is not. This can cause issues "
"launching the game. It is recommended to not run Steam as administrator unless "
- "absolutely neccessary.\n\n"
+ "absolutely necessary.\n\n"
"Restart MO as administrator?"),
QDialogButtonBox::Yes | QDialogButtonBox::No | QDialogButtonBox::Cancel);
if (result == QDialogButtonBox::Yes) {
diff --git a/src/overwriteinfodialog.cpp b/src/overwriteinfodialog.cpp
index 9b3e55df..0a884ac9 100644
--- a/src/overwriteinfodialog.cpp
+++ b/src/overwriteinfodialog.cpp
@@ -162,13 +162,13 @@ void OverwriteInfoDialog::delete_activated()
}
else if (selection->selectedRows().count() == 1) {
QString fileName = m_FileSystemModel->fileName(selection->selectedRows().at(0));
- if (QMessageBox::question(this, tr("Confirm"), tr("Are sure you want to delete \"%1\"?").arg(fileName),
+ if (QMessageBox::question(this, tr("Confirm"), tr("Are you sure you want to delete \"%1\"?").arg(fileName),
QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
return;
}
}
else {
- if (QMessageBox::question(this, tr("Confirm"), tr("Are sure you want to delete the selected files?"),
+ if (QMessageBox::question(this, tr("Confirm"), tr("Are you sure you want to delete the selected files?"),
QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
return;
}
@@ -187,12 +187,12 @@ void OverwriteInfoDialog::deleteTriggered()
return;
} else if (m_FileSelection.count() == 1) {
QString fileName = m_FileSystemModel->fileName(m_FileSelection.at(0));
- if (QMessageBox::question(this, tr("Confirm"), tr("Are sure you want to delete \"%1\"?").arg(fileName),
+ if (QMessageBox::question(this, tr("Confirm"), tr("Are you sure you want to delete \"%1\"?").arg(fileName),
QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
return;
}
} else {
- if (QMessageBox::question(this, tr("Confirm"), tr("Are sure you want to delete the selected files?"),
+ if (QMessageBox::question(this, tr("Confirm"), tr("Are you sure you want to delete the selected files?"),
QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
return;
}
diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui
index 08c8d9f2..faaf1653 100644
--- a/src/settingsdialog.ui
+++ b/src/settingsdialog.ui
@@ -441,7 +441,7 @@ If you use pre-releases, never contact me directly by e-mail or via private mess
-
- Important: All directories have to be writeable!
+ Important: All directories have to be writable!
@@ -1297,7 +1297,7 @@ programs you are intentionally running.
Decides the amount of data printed to "ModOrganizer.log".
- "Debug" produces very useful information for finding problems. There is usually no noteworthy performance impact but the file may become rather large. If this is a problem you may prefer the "Info" level for regluar use. On the "Error" level the log file usually remains empty.
+ "Debug" produces very useful information for finding problems. There is usually no noteworthy performance impact but the file may become rather large. If this is a problem you may prefer the "Info" level for regular use. On the "Error" level the log file usually remains empty.
-
diff --git a/src/spawn.cpp b/src/spawn.cpp
index d7d5efc2..f77da35f 100644
--- a/src/spawn.cpp
+++ b/src/spawn.cpp
@@ -150,7 +150,7 @@ HANDLE startBinary(const QFileInfo &binary,
if (e.getErrorCode() == ERROR_ELEVATION_REQUIRED) {
if (QMessageBox::question(QApplication::activeModalWidget(), QObject::tr("Elevation required"),
QObject::tr("This process requires elevation to run.\n"
- "This is a potential security risk so I highly advice you to investigate if\n"
+ "This is a potential security risk so I highly advise you to investigate if\n"
"\"%1\"\n"
"can be installed to work without elevation.\n\n"
"Restart Mod Organizer as an elevated process?\n"
diff --git a/src/tutorials/tutorial_conflictresolution_main.js b/src/tutorials/tutorial_conflictresolution_main.js
index 3c782af2..404afe5d 100644
--- a/src/tutorials/tutorial_conflictresolution_main.js
+++ b/src/tutorials/tutorial_conflictresolution_main.js
@@ -56,7 +56,7 @@ function getTutorialSteps() {
waitForClick()
},
function() {
- tutorial.text = qsTr("
indicates that the mod is completely overwrtten by another. You could as well disable it.");
+ tutorial.text = qsTr("
indicates that the mod is completely overwritten by another. You could as well disable it.");
waitForClick()
},
function() {
diff --git a/src/tutorials/tutorial_firststeps_main.js b/src/tutorials/tutorial_firststeps_main.js
index ee97766b..35d1aa11 100644
--- a/src/tutorials/tutorial_firststeps_main.js
+++ b/src/tutorials/tutorial_firststeps_main.js
@@ -137,7 +137,7 @@ function getTutorialSteps()
function() {
tutorial.text = qsTr("A single mod may contain zero, one or multiple esps. Some or all may be optional. "
- + "If in doubt, please consult the documentation of the indiviual mod. "
+ + "If in doubt, please consult the documentation of the individual mod. "
+ "To do so, right-click the mod and select \"Information\".")
highlightItem("modList", true)
manager.activateTutorial("ModInfoDialog", "tutorial_firststeps_modinfo.js")
diff --git a/src/tutorials/tutorial_firststeps_modinfo.js b/src/tutorials/tutorial_firststeps_modinfo.js
index 50c38345..1ed0dab7 100644
--- a/src/tutorials/tutorial_firststeps_modinfo.js
+++ b/src/tutorials/tutorial_firststeps_modinfo.js
@@ -16,7 +16,7 @@ function getTutorialSteps()
},
function() {
unhighlight()
- tutorial.text = qsTr("We may re-visit this screen in later tutorials.")
+ tutorial.text = qsTr("We may revisit this screen in later tutorials.")
waitForClick()
}
]
--
cgit v1.3.1
From 9c00d7b7f648fe6a7a84a66714641bd18abf6989 Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Sat, 6 Jul 2019 20:05:27 -0400
Subject: fixed context menu being offset vertically in the overwrite dialog
---
src/overwriteinfodialog.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
(limited to 'src/overwriteinfodialog.cpp')
diff --git a/src/overwriteinfodialog.cpp b/src/overwriteinfodialog.cpp
index 0a884ac9..5ee8d76c 100644
--- a/src/overwriteinfodialog.cpp
+++ b/src/overwriteinfodialog.cpp
@@ -290,5 +290,6 @@ void OverwriteInfoDialog::on_filesView_customContextMenuRequested(const QPoint &
m_FileSelection.clear();
m_FileSelection.append(m_FileSystemModel->index(m_FileSystemModel->rootPath(), 0));
}
- menu.exec(ui->filesView->mapToGlobal(pos));
+
+ menu.exec(ui->filesView->viewport()->mapToGlobal(pos));
}
--
cgit v1.3.1