diff options
| author | Brian Munro <brian.alexander.munro@gmail.com> | 2018-04-13 11:56:36 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-04-13 11:56:36 +0200 |
| commit | bc75009169ecbf378fa90891dc8183a8cb3ef499 (patch) | |
| tree | 221f74cbaeea3750bd705a6a37ff8242e4cef192 /src/modinfodialog.cpp | |
| parent | d6aab781ee1d5b927ccf06100e74539a980ee83f (diff) | |
| parent | 8be73d2e3b0af9cb99616d31418a0d9c74aca466 (diff) | |
Merge pull request #294 from Modorganizer2/Develop
Release 2.1.2
Diffstat (limited to 'src/modinfodialog.cpp')
| -rw-r--r-- | src/modinfodialog.cpp | 186 |
1 files changed, 184 insertions, 2 deletions
diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp index ccd2a122..6a53d915 100644 --- a/src/modinfodialog.cpp +++ b/src/modinfodialog.cpp @@ -20,6 +20,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include "modinfodialog.h"
#include "ui_modinfodialog.h"
#include "descriptionpage.h"
+#include "mainwindow.h"
#include "iplugingame.h"
#include "nexusinterface.h"
@@ -30,6 +31,10 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include "questionboxmemory.h"
#include "settings.h"
#include "categories.h"
+#include "organizercore.h"
+#include "pluginlistsortproxy.h"
+#include "previewgenerator.h"
+#include "previewdialog.h"
#include <QDir>
#include <QDirIterator>
@@ -40,6 +45,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include <QFileSystemModel>
#include <QInputDialog>
#include <QPointer>
+#include <QFileDialog>
#include <Shlwapi.h>
@@ -66,11 +72,12 @@ static bool operator<(const ModFileListWidget &LHS, const ModFileListWidget &RHS }
-ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directory, bool unmanaged, QWidget *parent)
+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_DeleteAction(nullptr), m_RenameAction(nullptr), m_OpenAction(nullptr),
- m_Directory(directory), m_Origin(nullptr)
+ m_Directory(directory), m_Origin(nullptr),
+ m_OrganizerCore(organizerCore), m_PluginContainer(pluginContainer)
{
ui->setupUi(this);
this->setWindowTitle(modInfo->name());
@@ -293,7 +300,9 @@ void ModInfoDialog::refreshLists() QStringList fields(relativeName);
fields.append(ToQString(realOrigin.getName()));
QTreeWidgetItem *item = new QTreeWidgetItem(fields);
+ item->setData(0, Qt::UserRole, fileName);
item->setData(1, Qt::UserRole, ToQString(realOrigin.getName()));
+ item->setData(1, Qt::UserRole + 2, archive);
ui->overwrittenTree->addTopLevelItem(item);
++numOverwritten;
}
@@ -1197,6 +1206,151 @@ void ModInfoDialog::unhideConflictFile() }
}
+int ModInfoDialog::getBinaryExecuteInfo(const QFileInfo &targetInfo, QFileInfo &binaryInfo, QString &arguments)
+{
+ QString extension = targetInfo.suffix();
+ if ((extension.compare("cmd", Qt::CaseInsensitive) == 0) ||
+ (extension.compare("com", Qt::CaseInsensitive) == 0) ||
+ (extension.compare("bat", Qt::CaseInsensitive) == 0)) {
+ binaryInfo = QFileInfo("C:\\Windows\\System32\\cmd.exe");
+ arguments = QString("/C \"%1\"").arg(QDir::toNativeSeparators(targetInfo.absoluteFilePath()));
+ return 1;
+ }
+ else if (extension.compare("exe", Qt::CaseInsensitive) == 0) {
+ binaryInfo = targetInfo;
+ return 1;
+ }
+ else if (extension.compare("jar", Qt::CaseInsensitive) == 0) {
+ // types that need to be injected into
+ std::wstring targetPathW = ToWString(targetInfo.absoluteFilePath());
+ QString binaryPath;
+
+ { // try to find java automatically
+ WCHAR buffer[MAX_PATH];
+ if (::FindExecutableW(targetPathW.c_str(), nullptr, buffer) > (HINSTANCE)32) {
+ DWORD binaryType = 0UL;
+ if (!::GetBinaryTypeW(buffer, &binaryType)) {
+ qDebug("failed to determine binary type of \"%ls\": %lu", buffer, ::GetLastError());
+ }
+ else if (binaryType == SCS_32BIT_BINARY) {
+ binaryPath = ToQString(buffer);
+ }
+ }
+ }
+ if (binaryPath.isEmpty() && (extension == "jar")) {
+ // second attempt: look to the registry
+ QSettings javaReg("HKEY_LOCAL_MACHINE\\Software\\JavaSoft\\Java Runtime Environment", QSettings::NativeFormat);
+ if (javaReg.contains("CurrentVersion")) {
+ QString currentVersion = javaReg.value("CurrentVersion").toString();
+ binaryPath = javaReg.value(QString("%1/JavaHome").arg(currentVersion)).toString().append("\\bin\\javaw.exe");
+ }
+ }
+ if (binaryPath.isEmpty()) {
+ binaryPath = QFileDialog::getOpenFileName(this, tr("Select binary"), QString(), tr("Binary") + " (*.exe)");
+ }
+ if (binaryPath.isEmpty()) {
+ return 0;
+ }
+ binaryInfo = QFileInfo(binaryPath);
+ if (extension == "jar") {
+ arguments = QString("-jar \"%1\"").arg(QDir::toNativeSeparators(targetInfo.absoluteFilePath()));
+ }
+ else {
+ arguments = QString("\"%1\"").arg(QDir::toNativeSeparators(targetInfo.absoluteFilePath()));
+ }
+ return 1;
+ }
+ else {
+ return 2;
+ }
+}
+
+void ModInfoDialog::openDataFile()
+{
+ 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;
+ }
+ }
+}
+
+void ModInfoDialog::previewDataFile()
+{
+ QString fileName = QDir::fromNativeSeparators(m_ConflictsContextItem->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 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(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) {
+ preview.exec();
+ }
+ else {
+ QMessageBox::information(this, tr("Sorry"), tr("Sorry, can't preview anything. This function currently does not support extracting from bsas."));
+ }
+}
+
void ModInfoDialog::on_overwriteTree_customContextMenuRequested(const QPoint &pos)
{
@@ -1211,11 +1365,39 @@ void ModInfoDialog::on_overwriteTree_customContextMenuRequested(const QPoint &po } else {
menu.addAction(tr("Hide"), this, SLOT(hideConflictFile()));
}
+
+ menu.addAction(tr("Open/Execute"), this, SLOT(openDataFile()));
+
+ QString fileName = m_ConflictsContextItem->data(0, Qt::UserRole).toString();
+ if (m_PluginContainer->previewGenerator().previewSupported(QFileInfo(fileName).suffix())) {
+ menu.addAction(tr("Preview"), this, SLOT(previewDataFile()));
+ }
+
menu.exec(ui->overwriteTree->mapToGlobal(pos));
}
}
}
+void ModInfoDialog::on_overwrittenTree_customContextMenuRequested(const QPoint &pos)
+{
+ m_ConflictsContextItem = ui->overwrittenTree->itemAt(pos.x(), pos.y());
+
+ if (m_ConflictsContextItem != nullptr) {
+ if (!m_ConflictsContextItem->data(1, Qt::UserRole + 2).toBool()) {
+ QMenu menu;
+
+ menu.addAction(tr("Open/Execute"), this, SLOT(openDataFile()));
+
+ QString fileName = m_ConflictsContextItem->data(0, Qt::UserRole).toString();
+ if (m_PluginContainer->previewGenerator().previewSupported(QFileInfo(fileName).suffix())) {
+ menu.addAction(tr("Preview"), this, SLOT(previewDataFile()));
+ }
+
+ menu.exec(ui->overwrittenTree->mapToGlobal(pos));
+ }
+ }
+}
+
void ModInfoDialog::on_overwrittenTree_itemDoubleClicked(QTreeWidgetItem *item, int)
{
|
