summaryrefslogtreecommitdiff
path: root/src/mainwindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mainwindow.cpp')
-rw-r--r--src/mainwindow.cpp172
1 files changed, 113 insertions, 59 deletions
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 0fdbdfad..a15da6a4 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -318,6 +318,14 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, Organize
installTranslator(QFileInfo(fileName).baseName());
}
+ for (IPluginTool *toolPlugin : m_PluginContainer.plugins<IPluginTool>()) {
+ registerPluginTool(toolPlugin);
+ }
+
+ for (IPluginModPage *modPagePlugin : m_PluginContainer.plugins<IPluginModPage>()) {
+ registerModPage(modPagePlugin);
+ }
+
ui->profileBox->setCurrentText(m_OrganizerCore.currentProfile()->getName());
refreshExecutablesList();
@@ -919,7 +927,6 @@ void MainWindow::toolPluginInvoke()
}
}
-
void MainWindow::modPagePluginInvoke()
{
QAction *triggeredAction = qobject_cast<QAction*>(sender());
@@ -932,7 +939,6 @@ void MainWindow::modPagePluginInvoke()
}
}
-
void MainWindow::registerPluginTool(IPluginTool *tool)
{
QAction *action = new QAction(tool->icon(), tool->displayName(), ui->toolBar);
@@ -944,7 +950,6 @@ void MainWindow::registerPluginTool(IPluginTool *tool)
toolBtn->menu()->addAction(action);
}
-
void MainWindow::registerModPage(IPluginModPage *modPage)
{
// turn the browser action into a drop-down menu if necessary
@@ -1409,11 +1414,11 @@ void MainWindow::updateBSAList(const QStringList &defaultArchives, const QString
subItem->setExpanded(true);
}
- checkBSAList();
+ checkBSAList(defaultArchives);
}
-void MainWindow::checkBSAList()
+void MainWindow::checkBSAList(const QStringList &defaultArchives)
{
ui->bsaList->blockSignals(true);
@@ -1429,7 +1434,7 @@ void MainWindow::checkBSAList()
item->setToolTip(0, QString());
if (item->checkState(0) == Qt::Unchecked) {
- if (m_DefaultArchives.contains(filename)) {
+ if (defaultArchives.contains(filename)) {
item->setIcon(0, QIcon(":/MO/gui/warning"));
item->setToolTip(0, tr("This bsa is enabled in the ini file so it may be required!"));
modWarning = true;
@@ -1458,7 +1463,7 @@ void MainWindow::saveModMetas()
ModInfo::Ptr modInfo = ModInfo::getByIndex(i);
modInfo->saveMeta();
}
- }
+}
void MainWindow::fixCategories()
@@ -1619,7 +1624,7 @@ void MainWindow::installMod(QString fileName)
if (fileName.isEmpty()) {
return;
} else {
- m_OrganizerCore.installMod(fileName);
+ m_OrganizerCore.installMod(fileName, QString());
}
} catch (const std::exception &e) {
reportError(e.what());
@@ -1662,7 +1667,6 @@ static HRESULT CreateShortcut(LPCWSTR targetFileName, LPCWSTR arguments,
qCritical("failed to create IShellLink instance");
return result;
}
- if (!SUCCEEDED(result)) return result;
result = shellLink->SetPath(targetFileName);
if (!SUCCEEDED(result)) {
@@ -1670,6 +1674,7 @@ static HRESULT CreateShortcut(LPCWSTR targetFileName, LPCWSTR arguments,
shellLink->Release();
return result;
}
+
result = shellLink->SetArguments(arguments);
if (!SUCCEEDED(result)) {
qCritical("failed to set arguments: %ls", arguments);
@@ -1695,7 +1700,7 @@ static HRESULT CreateShortcut(LPCWSTR targetFileName, LPCWSTR arguments,
}
}
- IPersistFile* persistFile;
+ IPersistFile *persistFile;
result = shellLink->QueryInterface(IID_IPersistFile, (LPVOID*)&persistFile);
if (SUCCEEDED(result)) {
wchar_t linkFileNameW[MAX_PATH];
@@ -1881,8 +1886,7 @@ void MainWindow::modorder_changed()
void MainWindow::modInstalled(const QString &modName)
{
QModelIndexList posList =
- m_OrganizerCore.modList()->match(m_OrganizerCore.modList()->index(0, 0),
- Qt::DisplayRole, static_cast<const QString&>(modName));
+ m_OrganizerCore.modList()->match(m_OrganizerCore.modList()->index(0, 0), Qt::DisplayRole, modName);
if (posList.count() == 1) {
ui->modList->scrollTo(posList.at(0));
}
@@ -1976,7 +1980,6 @@ void MainWindow::modRenamed(const QString &oldName, const QString &newName)
QFile modList(modlistName);
if (modList.exists()) {
- qDebug("rewrite modlist %s", QDir::toNativeSeparators(modlistName).toUtf8().constData());
renameModInList(modList, oldName, newName);
}
}
@@ -2233,13 +2236,13 @@ void MainWindow::reinstallMod_clicked()
if (fileInfo.exists()) {
fullInstallationFile = installationFile;
} else {
- fullInstallationFile = m_OrganizerCore.downloadManager()->getOutputDirectory().append("/").append(fileInfo.fileName());
+ fullInstallationFile = m_OrganizerCore.downloadManager()->getOutputDirectory() + "/" + fileInfo.fileName();
}
} else {
- fullInstallationFile = m_OrganizerCore.downloadManager()->getOutputDirectory().append("/").append(installationFile);
+ fullInstallationFile = m_OrganizerCore.downloadManager()->getOutputDirectory() + "/" + installationFile;
}
if (QFile::exists(fullInstallationFile)) {
- installMod(fullInstallationFile);
+ m_OrganizerCore.installMod(fullInstallationFile, modInfo->name());
} else {
QMessageBox::information(this, tr("Failed"), tr("Installation file no longer exists"));
}
@@ -2258,7 +2261,7 @@ void MainWindow::resumeDownload(int downloadIndex)
QString username, password;
if (m_OrganizerCore.settings().getNexusLogin(username, password)) {
//m_PostLoginTasks.push_back(boost::bind(&MainWindow::resumeDownload, _1, downloadIndex));
- m_OrganizerCore.doAfterLogin([&] () { this->resumeDownload(downloadIndex); });
+ m_OrganizerCore.doAfterLogin([this, downloadIndex] () { this->resumeDownload(downloadIndex); });
NexusInterface::instance()->getAccessManager()->login(username, password);
} else {
MessageDialog::showMessage(tr("You need to be logged in with Nexus to resume a download"), this);
@@ -2301,7 +2304,7 @@ void MainWindow::unendorse_clicked()
ModInfo::getByIndex(m_ContextRow)->endorse(false);
} else {
if (m_OrganizerCore.settings().getNexusLogin(username, password)) {
- m_OrganizerCore.doAfterLogin([&] () { this->unendorse_clicked(); });
+ m_OrganizerCore.doAfterLogin([this] () { this->unendorse_clicked(); });
NexusInterface::instance()->getAccessManager()->login(username, password);
} else {
MessageDialog::showMessage(tr("You need to be logged in with Nexus to endorse"), this);
@@ -2495,17 +2498,7 @@ void MainWindow::information_clicked()
}
}
-void MainWindow::syncOverwrite()
-{
- ModInfo::Ptr modInfo = ModInfo::getByIndex(m_ContextRow);
- SyncOverwriteDialog syncDialog(modInfo->absolutePath(), m_OrganizerCore.directoryStructure(), this);
- if (syncDialog.exec() == QDialog::Accepted) {
- syncDialog.apply(QDir::fromNativeSeparators(m_OrganizerCore.settings().getModDirectory()));
- modInfo->testValid();
- m_OrganizerCore.refreshDirectoryStructure();
- }
-}
void MainWindow::createModFromOverwrite()
{
@@ -2533,7 +2526,11 @@ void MainWindow::createModFromOverwrite()
return;
}
- ModInfo::Ptr overwriteInfo = ModInfo::getByIndex(m_ContextRow);
+ unsigned int overwriteIndex = ModInfo::findMod([](ModInfo::Ptr mod) -> bool {
+ std::vector<ModInfo::EFlag> flags = mod->getFlags();
+ return std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end(); });
+
+ ModInfo::Ptr overwriteInfo = ModInfo::getByIndex(overwriteIndex);
shellMove(QStringList(QDir::toNativeSeparators(overwriteInfo->absolutePath()) + "\\*"),
QStringList(QDir::toNativeSeparators(newMod->absolutePath())), this);
@@ -2783,7 +2780,7 @@ void MainWindow::checkModsForUpdates()
} else {
QString username, password;
if (m_OrganizerCore.settings().getNexusLogin(username, password)) {
- m_OrganizerCore.doAfterLogin([this] () {this->checkModsForUpdates();});
+ m_OrganizerCore.doAfterLogin([this] () { this->checkModsForUpdates(); });
NexusInterface::instance()->getAccessManager()->login(username, password);
} else { // otherwise there will be no endorsement info
m_ModsToUpdate = ModInfo::checkAllForUpdate(this);
@@ -2980,7 +2977,7 @@ void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos)
std::vector<ModInfo::EFlag> flags = info->getFlags();
if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end()) {
if (QDir(info->absolutePath()).count() > 2) {
- menu->addAction(tr("Sync to Mods..."), this, SLOT(syncOverwrite()));
+ menu->addAction(tr("Sync to Mods..."), &m_OrganizerCore, SLOT(syncOverwrite()));
menu->addAction(tr("Create Mod..."), this, SLOT(createModFromOverwrite()));
}
} else if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_BACKUP) != flags.end()) {
@@ -3020,22 +3017,24 @@ void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos)
menu->addAction(tr("Rename Mod..."), this, SLOT(renameMod_clicked()));
menu->addAction(tr("Remove Mod..."), this, SLOT(removeMod_clicked()));
menu->addAction(tr("Reinstall Mod"), this, SLOT(reinstallMod_clicked()));
- switch (info->endorsedState()) {
- case ModInfo::ENDORSED_TRUE: {
- menu->addAction(tr("Un-Endorse"), this, SLOT(unendorse_clicked()));
- } break;
- case ModInfo::ENDORSED_FALSE: {
- menu->addAction(tr("Endorse"), this, SLOT(endorse_clicked()));
- menu->addAction(tr("Won't endorse"), this, SLOT(dontendorse_clicked()));
- } break;
- case ModInfo::ENDORSED_NEVER: {
- menu->addAction(tr("Endorse"), this, SLOT(endorse_clicked()));
- } break;
- default: {
- QAction *action = new QAction(tr("Endorsement state unknown"), menu);
- action->setEnabled(false);
- menu->addAction(action);
- } break;
+ if (info->getNexusID() > 0) {
+ switch (info->endorsedState()) {
+ case ModInfo::ENDORSED_TRUE: {
+ menu->addAction(tr("Un-Endorse"), this, SLOT(unendorse_clicked()));
+ } break;
+ case ModInfo::ENDORSED_FALSE: {
+ menu->addAction(tr("Endorse"), this, SLOT(endorse_clicked()));
+ menu->addAction(tr("Won't endorse"), this, SLOT(dontendorse_clicked()));
+ } break;
+ case ModInfo::ENDORSED_NEVER: {
+ menu->addAction(tr("Endorse"), this, SLOT(endorse_clicked()));
+ } break;
+ default: {
+ QAction *action = new QAction(tr("Endorsement state unknown"), menu);
+ action->setEnabled(false);
+ menu->addAction(action);
+ } break;
+ }
}
std::vector<ModInfo::EFlag> flags = info->getFlags();
if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_INVALID) != flags.end()) {
@@ -3260,6 +3259,7 @@ void MainWindow::linkDesktop()
.arg(selectedExecutable.m_Arguments));
std::wstring description = ToWString(selectedExecutable.m_BinaryInfo.fileName());
std::wstring currentDirectory = ToWString(QDir::toNativeSeparators(exeInfo.absolutePath()));
+
if (CreateShortcut(targetFile.c_str()
, parameter.c_str()
, linkName.toUtf8().constData()
@@ -3398,9 +3398,6 @@ void MainWindow::languageChange(const QString &newLanguage)
updateProblemsButton();
ui->listOptionsBtn->setMenu(modListContextMenu());
-}
-
-
void MainWindow::writeDataToFile(QFile &file, const QString &directory, const DirectoryEntry &directoryEntry)
{
{ // list files
@@ -3452,18 +3449,19 @@ void MainWindow::writeDataToFile()
}
-int MainWindow::getBinaryExecuteInfo(const QFileInfo &targetInfo,
- QFileInfo &binaryInfo, QString &arguments)
+int MainWindow::getBinaryExecuteInfo(const QFileInfo &targetInfo, QFileInfo &binaryInfo, QString &arguments)
{
QString extension = targetInfo.completeSuffix();
- if ((extension == "exe") ||
- (extension == "cmd") ||
- (extension == "com") ||
- (extension == "bat")) {
+ if ((extension.compare("cmd", Qt::CaseInsensitive)) ||
+ (extension.compare("com", Qt::CaseInsensitive)) ||
+ (extension.compare("bat", Qt::CaseInsensitive))) {
binaryInfo = QFileInfo("C:\\Windows\\System32\\cmd.exe");
arguments = QString("/C \"%1\"").arg(QDir::toNativeSeparators(targetInfo.absoluteFilePath()));
return 1;
- } else if (extension == "jar") {
+ } 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;
@@ -4288,6 +4286,62 @@ void MainWindow::processLOOTOut(const std::string &lootOut, std::string &errorMe
}
}
}
+bool MainWindow::waitForProcessOrJob(HANDLE handle, LPDWORD exitCode)
+{
+ LockedDialog *dialog = new LockedDialog(this);
+ dialog->show();
+ setEnabled(false);
+ ON_BLOCK_EXIT([&] () { dialog->hide(); dialog->deleteLater(); setEnabled(true); });
+
+ DWORD retLen;
+ JOBOBJECT_BASIC_PROCESS_ID_LIST info;
+
+ bool isJobHandle = true;
+
+ ULONG lastProcessID = ULONG_MAX;
+ HANDLE processHandle = handle;
+
+ DWORD res = ::MsgWaitForMultipleObjects(1, &handle, false, 500, QS_KEY | QS_MOUSE);
+ while ((res != WAIT_FAILED) && (res != WAIT_OBJECT_0) && !dialog->unlockClicked()) {
+ if (isJobHandle) {
+ if (::QueryInformationJobObject(handle, JobObjectBasicProcessIdList, &info, sizeof(info), &retLen) > 0) {
+ if (info.NumberOfProcessIdsInList == 0) {
+ // fake signaled state
+ res = WAIT_OBJECT_0;
+ break;
+ } else {
+ // this is indeed a job handle. Figure out one of the process handles as well.
+ if (lastProcessID != info.ProcessIdList[0]) {
+ lastProcessID = info.ProcessIdList[0];
+ if (processHandle != handle) {
+ ::CloseHandle(processHandle);
+ }
+ processHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, lastProcessID);
+ }
+ }
+ } else {
+ // the info-object I passed only provides space for 1 process id. but since this code only cares about whether there
+ // is more than one that's good enough. ERROR_MORE_DATA simply signals there are at least two processes running.
+ // any other error probably means the handle is a regular process handle, probably caused by running MO in a job without
+ // the right to break out.
+ if (::GetLastError() != ERROR_MORE_DATA) {
+ isJobHandle = false;
+ }
+ }
+ }
+
+ // keep processing events so the app doesn't appear dead
+ QCoreApplication::processEvents();
+
+ res = ::MsgWaitForMultipleObjects(1, &handle, false, 500, QS_KEY | QS_MOUSE);
+ }
+
+ if (exitCode != NULL) {
+ ::GetExitCodeProcess(processHandle, exitCode);
+ }
+ ::CloseHandle(processHandle);
+
+ return res == WAIT_OBJECT_0;
}
void MainWindow::on_bossButton_clicked()
@@ -4300,8 +4354,8 @@ void MainWindow::on_bossButton_clicked()
bool success = false;
try {
- this->setEnabled(false);
- ON_BLOCK_EXIT([&] () { this->setEnabled(true); });
+ setEnabled(false);
+ ON_BLOCK_EXIT([&] () { setEnabled(true); });
QProgressDialog dialog(this);
dialog.setLabelText(tr("Please wait while LOOT is running"));
dialog.setMaximum(0);