summaryrefslogtreecommitdiff
path: root/src/mainwindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mainwindow.cpp')
-rw-r--r--src/mainwindow.cpp125
1 files changed, 102 insertions, 23 deletions
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 9cbe9c40..ce5ae865 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -168,6 +168,9 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget
{
ui->setupUi(this);
this->setWindowTitle(ToQString(GameInfo::instance().getGameName()) + " Mod Organizer v" + m_Updater.getVersion().displayString());
+
+ languageChange(m_Settings.language());
+
ui->logList->setModel(LogBuffer::instance());
ui->logList->setColumnWidth(0, 100);
ui->logList->setAutoScroll(true);
@@ -277,6 +280,7 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget
connect(&m_ModList, SIGNAL(requestColumnSelect(QPoint)), this, SLOT(displayColumnSelection(QPoint)));
connect(&m_ModList, SIGNAL(fileMoved(QString, QString, QString)), this, SLOT(fileMoved(QString, QString, QString)));
connect(ui->modList, SIGNAL(dropModeUpdate(bool)), &m_ModList, SLOT(dropModeUpdate(bool)));
+ connect(ui->modList->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(modlistSelectionChanged(QModelIndex,QModelIndex)));
connect(m_ModListSortProxy, SIGNAL(filterActive(bool)), this, SLOT(modFilterActive(bool)));
connect(ui->modFilterEdit, SIGNAL(textChanged(QString)), m_ModListSortProxy, SLOT(updateFilter(QString)));
@@ -310,7 +314,7 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget
connect(NexusInterface::instance(), SIGNAL(needLogin()), this, SLOT(nexusLogin()));
connect(&TutorialManager::instance(), SIGNAL(windowTutorialFinished(QString)), this, SLOT(windowTutorialFinished(QString)));
-
+ connect(ui->modList->header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(modListSortIndicatorChanged(int,Qt::SortOrder)));
connect(ui->toolBar, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(toolBar_customContextMenuRequested(QPoint)));
connect(&m_IntegratedBrowser, SIGNAL(requestDownload(QUrl,QNetworkReply*)), this, SLOT(requestDownload(QUrl,QNetworkReply*)));
@@ -615,6 +619,10 @@ void MainWindow::createHelpWidget()
{
QToolButton *toolBtn = qobject_cast<QToolButton*>(ui->toolBar->widgetForAction(ui->actionHelp));
QMenu *buttonMenu = toolBtn->menu();
+ if (buttonMenu == NULL) {
+ return;
+ }
+ buttonMenu->clear();
QAction *helpAction = new QAction(tr("Help on UI"), buttonMenu);
connect(helpAction, SIGNAL(triggered()), this, SLOT(helpTriggered()));
@@ -1155,6 +1163,7 @@ bool MainWindow::registerPlugin(QObject *plugin, const QString &fileName)
}
plugin->setProperty("filename", fileName);
m_Settings.registerPlugin(pluginObj);
+ installTranslator(QFileInfo(fileName).baseName());
}
{ // diagnosis plugins
@@ -1380,11 +1389,35 @@ void MainWindow::spawnBinary(const QFileInfo &binary, const QString &arguments,
QCoreApplication::processEvents();
- while ((::WaitForSingleObject(processHandle, 100) == WAIT_TIMEOUT) &&
- !dialog->unlockClicked()) {
+ DWORD retLen;
+ JOBOBJECT_BASIC_PROCESS_ID_LIST info;
+
+ bool isJobHandle = true;
+
+ DWORD res = ::MsgWaitForMultipleObjects(1, &processHandle, false, 1000, QS_KEY | QS_MOUSE);
+ while ((res != WAIT_FAILED) && (res != WAIT_OBJECT_0) && !dialog->unlockClicked()) {
+ if (isJobHandle) {
+ if (::QueryInformationJobObject(processHandle, JobObjectBasicProcessIdList, &info, sizeof(info), &retLen) > 0) {
+ if (info.NumberOfProcessIdsInList == 0) {
+ break;
+ }
+ } 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, &processHandle, false, 1000, QS_KEY | QS_MOUSE);
}
+ ::CloseHandle(processHandle);
this->setEnabled(true);
refreshDirectoryStructure();
@@ -2061,7 +2094,6 @@ void MainWindow::readSettings()
setCategoryListVisible(filtersVisible);
ui->displayCategoriesBtn->setChecked(filtersVisible);
- languageChange(m_Settings.language());
int selectedExecutable = settings.value("selected_executable").toInt();
setExecutableIndex(selectedExecutable);
@@ -3028,6 +3060,21 @@ void MainWindow::modlistChanged(const QModelIndex&, int)
m_CurrentProfile->writeModlist();
}
+void MainWindow::modlistSelectionChanged(const QModelIndex &current, const QModelIndex&)
+{
+ ModInfo::Ptr selectedMod = ModInfo::getByIndex(current.data(Qt::UserRole + 1).toInt());
+ m_ModList.setOverwriteMarkers(selectedMod->getModOverwrite(), selectedMod->getModOverwritten());
+ if (m_ModListSortProxy != NULL) {
+ m_ModListSortProxy->invalidate();
+ }
+ ui->modList->verticalScrollBar()->repaint();
+}
+
+void MainWindow::modListSortIndicatorChanged(int, Qt::SortOrder)
+{
+ ui->modList->verticalScrollBar()->repaint();
+}
+
void MainWindow::removeMod_clicked()
{
try {
@@ -3185,6 +3232,7 @@ void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index,
connect(dialog, SIGNAL(finished(int)), this, SLOT(overwriteClosed(int)));
} else {
modInfo->saveMeta();
+qDebug("%s - %d", qPrintable(modInfo->name()), modInfo->hasFlag(ModInfo::FLAG_FOREIGN));
ModInfoDialog dialog(modInfo, m_DirectoryStructure, modInfo->hasFlag(ModInfo::FLAG_FOREIGN), this);
connect(&dialog, SIGNAL(nexusLinkActivated(QString)), this, SLOT(nexusLinkActivated(QString)));
connect(&dialog, SIGNAL(downloadRequest(QString)), this, SLOT(downloadRequestedNXM(QString)));
@@ -4191,6 +4239,9 @@ void MainWindow::downloadRequested(QNetworkReply *reply, int modID, const QStrin
void MainWindow::installTranslator(const QString &name)
{
+ if (m_CurrentLanguage == "en_US") {
+ return;
+ }
QTranslator *translator = new QTranslator(this);
QString fileName = name + "_" + m_CurrentLanguage;
if (!translator->load(fileName, qApp->applicationDirPath() + "/translations")) {
@@ -4212,26 +4263,19 @@ void MainWindow::languageChange(const QString &newLanguage)
m_CurrentLanguage = newLanguage;
- if (newLanguage != "en_US") {
- installTranslator("qt");
- installTranslator(ToQString(AppConfig::translationPrefix()));
- foreach(IPlugin *plugin, m_Settings.plugins()) {
- QObject *pluginObj = dynamic_cast<QObject*>(plugin);
- if (pluginObj != NULL) {
- QVariant fileNameVariant = pluginObj->property("filename");
- if (fileNameVariant.isValid()) {
- QString fileName = QFileInfo(fileNameVariant.toString()).baseName();
- installTranslator(fileName);
- }
- }
- }
- }
+ installTranslator("qt");
+ installTranslator(ToQString(AppConfig::translationPrefix()));
ui->retranslateUi(this);
+ qDebug("loaded language %s", qPrintable(newLanguage));
+
ui->profileBox->setItemText(0, QObject::tr("<Manage...>"));
-// ui->toolBar->addWidget(createHelpWidget(ui->toolBar));
+
+ createHelpWidget();
updateDownloadListDelegate();
updateProblemsButton();
+
+ ui->listOptionsBtn->setMenu(modListContextMenu());
}
@@ -5110,6 +5154,9 @@ void MainWindow::on_espList_customContextMenuRequested(const QPoint &pos)
void MainWindow::on_groupCombo_currentIndexChanged(int index)
{
+ if (m_ModListSortProxy == NULL) {
+ return;
+ }
QAbstractProxyModel *newModel = NULL;
switch (index) {
case 1: {
@@ -5322,16 +5369,46 @@ void MainWindow::on_bossButton_clicked()
m_PluginList.clearAdditionalInformation();
+ DWORD retLen;
+ JOBOBJECT_BASIC_PROCESS_ID_LIST info;
+ bool isJobHandle = true;
+
if (loot != INVALID_HANDLE_VALUE) {
- while (::WaitForSingleObject(loot, 100) == WAIT_TIMEOUT) {
- // keep processing events so the app doesn't appear dead
- QCoreApplication::processEvents();
+ DWORD res = ::MsgWaitForMultipleObjects(1, &loot, false, 1000, QS_KEY | QS_MOUSE);
+ while ((res != WAIT_FAILED) && (res != WAIT_OBJECT_0)) {
+ if (isJobHandle) {
+ if (::QueryInformationJobObject(loot, JobObjectBasicProcessIdList, &info, sizeof(info), &retLen) > 0) {
+ if (info.NumberOfProcessIdsInList == 0) {
+ qDebug("no more processes in job");
+ break;
+ }
+ } 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;
+ }
+ }
+ }
+
if (dialog.wasCanceled()) {
- ::TerminateProcess(loot, 1);
+ if (isJobHandle) {
+ ::TerminateJobObject(loot, 1);
+ } else {
+ ::TerminateProcess(loot, 1);
+ }
}
+
+ // keep processing events so the app doesn't appear dead
+ QCoreApplication::processEvents();
std::string lootOut = readFromPipe(stdOutRead);
processLOOTOut(lootOut, reportURL, errorMessages, dialog);
+
+ res = ::MsgWaitForMultipleObjects(1, &loot, false, 1000, QS_KEY | QS_MOUSE);
}
+
std::string remainder = readFromPipe(stdOutRead).c_str();
if (remainder.length() > 0) {
processLOOTOut(remainder, reportURL, errorMessages, dialog);
@@ -5344,6 +5421,8 @@ void MainWindow::on_bossButton_clicked()
} else {
success = true;
}
+ } else {
+ reportError(tr("failed to start loot"));
}
} catch (const std::exception &e) {
reportError(tr("failed to run loot: %1").arg(e.what()));