diff options
| author | Tannin <devnull@localhost> | 2014-07-15 20:45:29 +0200 |
|---|---|---|
| committer | Tannin <devnull@localhost> | 2014-07-15 20:45:29 +0200 |
| commit | 0a152ceadfc90650359b15dc448751f702e1070c (patch) | |
| tree | 02e468fb58330d25fd765974e48ab681bf360cab /src/mainwindow.cpp | |
| parent | d412060d59b1597ae1d11d793662610e90863fc9 (diff) | |
| parent | 5718af351034c1936a91a3782651733dfecdc4e5 (diff) | |
Merge
Diffstat (limited to 'src/mainwindow.cpp')
| -rw-r--r-- | src/mainwindow.cpp | 171 |
1 files changed, 130 insertions, 41 deletions
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 81ef5880..19cefa89 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())); @@ -1154,6 +1162,7 @@ bool MainWindow::registerPlugin(QObject *plugin, const QString &fileName) } plugin->setProperty("filename", fileName); m_Settings.registerPlugin(pluginObj); + installTranslator(QFileInfo(fileName).baseName()); } { // diagnosis plugins @@ -1379,11 +1388,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(); @@ -2060,7 +2093,6 @@ void MainWindow::readSettings() setCategoryListVisible(filtersVisible); ui->displayCategoriesBtn->setChecked(filtersVisible); - languageChange(m_Settings.language()); int selectedExecutable = settings.value("selected_executable").toInt(); setExecutableIndex(selectedExecutable); @@ -3027,6 +3059,21 @@ void MainWindow::modlistChanged(const QModelIndex&, int) m_CurrentProfile->writeModlist(); } +void MainWindow::modlistSelectionChanged(const QModelIndex ¤t, 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 { @@ -3883,26 +3930,34 @@ void MainWindow::on_categoriesList_itemSelectionChanged() void MainWindow::deleteSavegame_clicked() { - QListWidgetItem *selectedItem = ui->savegameList->item(m_SelectedSaveGame); - if (selectedItem == NULL) { - return; - } + QModelIndexList selectedIndexes = ui->savegameList->selectionModel()->selectedIndexes(); + + QString savesMsgLabel; + QStringList deleteFiles; - QString fileName = selectedItem->data(Qt::UserRole).toString(); + foreach (const QModelIndex &idx, selectedIndexes) { + QString name = idx.data().toString(); + SaveGame *save = new SaveGame(this, idx.data(Qt::UserRole).toString()); - if (QMessageBox::question(this, tr("Confirm"), tr("Really delete \"%1\"?").arg(selectedItem->text()), + savesMsgLabel += "<li>" + QFileInfo(name).completeBaseName() + "</li>"; + + deleteFiles << save->saveFiles(); + } + + if (QMessageBox::question(this, tr("Confirm"), tr("Are you sure you want to remove the following %n save(s)?<br><ul>%1</ul><br>Removed saves will be sent to the Recycle Bin.", "", selectedIndexes.count()) + .arg(savesMsgLabel), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { - shellDelete(QStringList() << fileName); + shellDelete(deleteFiles, true); // recycle bin delete. } } void MainWindow::fixMods_clicked() { - QListWidgetItem *selectedItem = ui->savegameList->item(m_SelectedSaveGame); - if (selectedItem == NULL) { + QListWidgetItem *selectedItem = ui->savegameList->currentItem(); + + if (selectedItem == NULL) return; - } // if required, parse the save game if (selectedItem->data(Qt::UserRole).isNull()) { @@ -3993,16 +4048,19 @@ void MainWindow::fixMods_clicked() void MainWindow::on_savegameList_customContextMenuRequested(const QPoint &pos) { - QListWidgetItem *selectedItem = ui->savegameList->itemAt(pos); - if (selectedItem == NULL) { - return; - } + QItemSelectionModel *selection = ui->savegameList->selectionModel(); - m_SelectedSaveGame = ui->savegameList->row(selectedItem); + if (!selection->hasSelection()) + return; QMenu menu; - menu.addAction(tr("Fix Mods..."), this, SLOT(fixMods_clicked())); - menu.addAction(tr("Delete"), this, SLOT(deleteSavegame_clicked())); + + if (!(selection->selectedIndexes().count() > 1)) + menu.addAction(tr("Fix Mods..."), this, SLOT(fixMods_clicked())); + + QString deleteMenuLabel = tr("Delete %n save(s)", "", selection->selectedIndexes().count()); + + menu.addAction(deleteMenuLabel, this, SLOT(deleteSavegame_clicked())); menu.exec(ui->savegameList->mapToGlobal(pos)); } @@ -4190,10 +4248,13 @@ 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")) { - if (m_CurrentLanguage != "en-US") { + if (m_CurrentLanguage != "en_US") { qWarning("localization file %s not found", qPrintable(fileName)); } // we don't actually expect localization files for english } @@ -4211,26 +4272,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()); } @@ -5109,6 +5163,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: { @@ -5321,16 +5378,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); @@ -5343,6 +5430,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())); |
