From 500ab7f706bdc8d4eb94db22ab60f882b2670dde Mon Sep 17 00:00:00 2001 From: Tannin Date: Mon, 16 Sep 2013 22:32:42 +0200 Subject: - bugfix: testing for missing masters at the wrong time seems to have caused crashes - bugfix: mod list is now written to a temporary file first. Only on success is the original file overwritten - bugfix: moving a mod priority to just above the overwrite could cause a crash or error message - bugfix: versions with a release candidate number weren't sorted correctly (woops) - bugfix: staging script didn't include archive.dll and dlls.manifest - installation time on overwrite no longer updates constantly --- src/mainwindow.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mainwindow.ui') diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 54611235..923df17c 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -786,7 +786,7 @@ BSAs checked here are loaded in such a way that your installation order is obeye - <html><head/><body><p>Marked Archives (<img src=":/MO/gui/resources/dialog-warning_16.png"/>) are still loaded on Skyrim but the <a href="http://forums.bethsoft.com/topic/1354395-update-bsas-and-you/"><span style=" text-decoration: underline; color:#0000ff;">regular file override</span></a> mechanism will apply: Loose files override BSAs, no matter the mod/plugin priority.</p></body></html> + <html><head/><body><p>Marked Archives (<img src=":/MO/gui/warning_16"/>) are still loaded on Skyrim but the <a href="http://forums.bethsoft.com/topic/1354395-update-bsas-and-you/"><span style=" text-decoration: underline; color:#0000ff;">regular file override</span></a> mechanism will apply: Loose files override BSAs, no matter the mod/plugin priority.</p></body></html> true -- cgit v1.3.1 From 54c7131a5e2fa282369e25344ac190d51676c383 Mon Sep 17 00:00:00 2001 From: Tannin Date: Thu, 10 Oct 2013 19:32:01 +0200 Subject: - new toggle to display hidden downloads - hidden downloads can be un-hidden - the installation manager now more thoroughly cleans up the temporary directory after installation - added SkyrimLauncher.exe to the list of auto-detected executables - bugfix: shutting down MO while downloads where active in some occasions didn't work - bugfix: when canceling the only active download the taskbar icon didn't return to normal --- src/downloadlistwidget.cpp | 20 ++++++++--- src/downloadlistwidget.h | 2 ++ src/downloadlistwidgetcompact.cpp | 20 ++++++++--- src/downloadlistwidgetcompact.h | 2 ++ src/downloadmanager.cpp | 58 ++++++++++++++++++++++++++----- src/downloadmanager.h | 24 ++++++++++++- src/installationmanager.cpp | 72 +++++++++++++-------------------------- src/installationmanager.h | 5 +-- src/main.cpp | 5 ++- src/mainwindow.cpp | 6 ++++ src/mainwindow.h | 1 + src/mainwindow.ui | 9 ++++- src/moapplication.cpp | 6 +++- src/moapplication.h | 60 ++++++++++++++++---------------- src/shared/skyriminfo.cpp | 1 + src/version.rc | 4 +-- 16 files changed, 189 insertions(+), 106 deletions(-) (limited to 'src/mainwindow.ui') diff --git a/src/downloadlistwidget.cpp b/src/downloadlistwidget.cpp index b657ca69..b4d40799 100644 --- a/src/downloadlistwidget.cpp +++ b/src/downloadlistwidget.cpp @@ -208,6 +208,11 @@ void DownloadListWidgetDelegate::issueRemoveFromView() emit removeDownload(m_ContextRow, false); } +void DownloadListWidgetDelegate::issueRestoreToView() +{ + emit restoreDownload(m_ContextRow); +} + void DownloadListWidgetDelegate::issueCancel() { emit cancelDownload(m_ContextRow); @@ -277,13 +282,18 @@ bool DownloadListWidgetDelegate::editorEvent(QEvent *event, QAbstractItemModel * QMenu menu(m_View); m_ContextRow = qobject_cast(model)->mapToSource(index).row(); DownloadManager::DownloadState state = m_Manager->getState(m_ContextRow); + bool hidden = m_Manager->isHidden(m_ContextRow); if (state >= DownloadManager::STATE_READY) { menu.addAction(tr("Install"), this, SLOT(issueInstall())); if (m_Manager->isInfoIncomplete(m_ContextRow)) { menu.addAction(tr("Query Info"), this, SLOT(issueQueryInfo())); } menu.addAction(tr("Delete"), this, SLOT(issueDelete())); - menu.addAction(tr("Remove from View"), this, SLOT(issueRemoveFromView())); + if (hidden) { + menu.addAction(tr("Un-Hide"), this, SLOT(issueRestoreToView())); + } else { + menu.addAction(tr("Remove from View"), this, SLOT(issueRemoveFromView())); + } } else if (state == DownloadManager::STATE_DOWNLOADING){ menu.addAction(tr("Cancel"), this, SLOT(issueCancel())); menu.addAction(tr("Pause"), this, SLOT(issuePause())); @@ -295,9 +305,11 @@ bool DownloadListWidgetDelegate::editorEvent(QEvent *event, QAbstractItemModel * menu.addSeparator(); menu.addAction(tr("Delete Installed..."), this, SLOT(issueDeleteCompleted())); menu.addAction(tr("Delete All..."), this, SLOT(issueDeleteAll())); - menu.addSeparator(); - menu.addAction(tr("Remove Installed..."), this, SLOT(issueRemoveFromViewCompleted())); - menu.addAction(tr("Remove All..."), this, SLOT(issueRemoveFromViewAll())); + if (!hidden) { + menu.addSeparator(); + menu.addAction(tr("Remove Installed..."), this, SLOT(issueRemoveFromViewCompleted())); + menu.addAction(tr("Remove All..."), this, SLOT(issueRemoveFromViewAll())); + } menu.exec(mouseEvent->globalPos()); event->accept(); diff --git a/src/downloadlistwidget.h b/src/downloadlistwidget.h index c80200fb..f5bfdbaa 100644 --- a/src/downloadlistwidget.h +++ b/src/downloadlistwidget.h @@ -65,6 +65,7 @@ signals: void installDownload(int index); void queryInfo(int index); void removeDownload(int index, bool deleteFile); + void restoreDownload(int index); void cancelDownload(int index); void pauseDownload(int index); void resumeDownload(int index); @@ -83,6 +84,7 @@ private slots: void issueInstall(); void issueDelete(); void issueRemoveFromView(); + void issueRestoreToView(); void issueCancel(); void issuePause(); void issueResume(); diff --git a/src/downloadlistwidgetcompact.cpp b/src/downloadlistwidgetcompact.cpp index 8dd6e275..d2a71dd5 100644 --- a/src/downloadlistwidgetcompact.cpp +++ b/src/downloadlistwidgetcompact.cpp @@ -195,6 +195,11 @@ void DownloadListWidgetCompactDelegate::issueRemoveFromView() emit removeDownload(m_ContextIndex.row(), false); } +void DownloadListWidgetCompactDelegate::issueRestoreToView() +{ + emit restoreDownload(m_ContextIndex.row()); +} + void DownloadListWidgetCompactDelegate::issueCancel() { emit cancelDownload(m_ContextIndex.row()); @@ -265,13 +270,18 @@ bool DownloadListWidgetCompactDelegate::editorEvent(QEvent *event, QAbstractItem QMenu menu; m_ContextIndex = qobject_cast(model)->mapToSource(index); DownloadManager::DownloadState state = m_Manager->getState(m_ContextIndex.row()); + bool hidden = m_Manager->isHidden(m_ContextIndex.row()); if (state >= DownloadManager::STATE_READY) { menu.addAction(tr("Install"), this, SLOT(issueInstall())); if (m_Manager->isInfoIncomplete(m_ContextIndex.row())) { menu.addAction(tr("Query Info"), this, SLOT(issueQueryInfo())); } menu.addAction(tr("Delete"), this, SLOT(issueDelete())); - menu.addAction(tr("Remove from View"), this, SLOT(issueRemoveFromView())); + if (hidden) { + menu.addAction(tr("Un-Hide"), this, SLOT(issueRestoreToView())); + } else { + menu.addAction(tr("Remove from View"), this, SLOT(issueRemoveFromView())); + } } else if (state == DownloadManager::STATE_DOWNLOADING){ menu.addAction(tr("Cancel"), this, SLOT(issueCancel())); menu.addAction(tr("Pause"), this, SLOT(issuePause())); @@ -283,9 +293,11 @@ bool DownloadListWidgetCompactDelegate::editorEvent(QEvent *event, QAbstractItem menu.addSeparator(); menu.addAction(tr("Delete Installed..."), this, SLOT(issueDeleteCompleted())); menu.addAction(tr("Delete All..."), this, SLOT(issueDeleteAll())); - menu.addSeparator(); - menu.addAction(tr("Remove Installed..."), this, SLOT(issueRemoveFromViewCompleted())); - menu.addAction(tr("Remove All..."), this, SLOT(issueRemoveFromViewAll())); + if (!hidden) { + menu.addSeparator(); + menu.addAction(tr("Remove Installed..."), this, SLOT(issueRemoveFromViewCompleted())); + menu.addAction(tr("Remove All..."), this, SLOT(issueRemoveFromViewAll())); + } menu.exec(mouseEvent->globalPos()); event->accept(); diff --git a/src/downloadlistwidgetcompact.h b/src/downloadlistwidgetcompact.h index 78f51840..05d00b9d 100644 --- a/src/downloadlistwidgetcompact.h +++ b/src/downloadlistwidgetcompact.h @@ -65,6 +65,7 @@ signals: void installDownload(int index); void queryInfo(int index); void removeDownload(int index, bool deleteFile); + void restoreDownload(int index); void cancelDownload(int index); void pauseDownload(int index); void resumeDownload(int index); @@ -83,6 +84,7 @@ private slots: void issueInstall(); void issueDelete(); void issueRemoveFromView(); + void issueRestoreToView(); void issueCancel(); void issuePause(); void issueResume(); diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp index b965d598..eca5600a 100644 --- a/src/downloadmanager.cpp +++ b/src/downloadmanager.cpp @@ -69,14 +69,16 @@ DownloadManager::DownloadInfo *DownloadManager::DownloadInfo::createNew(const Ne return info; } -DownloadManager::DownloadInfo *DownloadManager::DownloadInfo::createFromMeta(const QString &filePath) +DownloadManager::DownloadInfo *DownloadManager::DownloadInfo::createFromMeta(const QString &filePath, bool showHidden) { DownloadInfo *info = new DownloadInfo; QString metaFileName = filePath + ".meta"; QSettings metaFile(metaFileName, QSettings::IniFormat); - if (metaFile.value("removed", false).toBool()) { + if (!showHidden && metaFile.value("removed", false).toBool()) { return NULL; + } else { + info->m_Hidden = metaFile.value("removed", false).toBool(); } QString fileName = QFileInfo(filePath).fileName(); @@ -151,7 +153,7 @@ QString DownloadManager::DownloadInfo::currentURL() DownloadManager::DownloadManager(NexusInterface *nexusInterface, QObject *parent) - : IDownloadManager(parent), m_NexusInterface(nexusInterface), m_DirWatcher() + : IDownloadManager(parent), m_NexusInterface(nexusInterface), m_DirWatcher(), m_ShowHidden(false) { connect(&m_DirWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(directoryChanged(QString))); } @@ -188,13 +190,15 @@ void DownloadManager::pauseAll() ::Sleep(100); bool done = false; + QTime startTime = QTime::currentTime(); // further loops: busy waiting for all downloads to complete. This could be neater... - while (!done) { + while (!done && (startTime.secsTo(QTime::currentTime()) < 5)) { QCoreApplication::processEvents(); done = true; foreach (DownloadInfo *info, m_ActiveDownloads) { if ((info->m_State < STATE_CANCELED) || - (info->m_State != STATE_FETCHINGFILEINFO) || (info->m_State != STATE_FETCHINGMODINFO)) { + (info->m_State == STATE_FETCHINGFILEINFO) || + (info->m_State == STATE_FETCHINGMODINFO)) { done = false; break; } @@ -230,6 +234,12 @@ void DownloadManager::setSupportedExtensions(const QStringList &extensions) refreshList(); } +void DownloadManager::setShowHidden(bool showHidden) +{ + m_ShowHidden = showHidden; + refreshList(); +} + void DownloadManager::refreshList() { // remove finished downloads @@ -267,7 +277,7 @@ void DownloadManager::refreshList() QString fileName = QDir::fromNativeSeparators(m_OutputDirectory) + "/" + file; - DownloadInfo *info = DownloadInfo::createFromMeta(fileName); + DownloadInfo *info = DownloadInfo::createFromMeta(fileName, m_ShowHidden); if (info != NULL) { m_ActiveDownloads.push_front(info); } @@ -437,6 +447,22 @@ void DownloadManager::refreshAlphabeticalTranslation() } +void DownloadManager::restoreDownload(int index) +{ + if ((index < 0) || (index >= m_ActiveDownloads.size())) { + throw MyException(tr("invalid index")); + } + + DownloadInfo *download = m_ActiveDownloads.at(index); + download->m_Hidden = false; + + QString filePath = m_OutputDirectory + "/" + download->m_FileName; + + QSettings metaSettings(filePath.append(".meta"), QSettings::IniFormat); + metaSettings.setValue("removed", false); +} + + void DownloadManager::removeDownload(int index, bool deleteFile) { try { @@ -492,9 +518,13 @@ void DownloadManager::pauseDownload(int index) return; } - if (m_ActiveDownloads.at(index)->m_State == STATE_DOWNLOADING) { - setState(m_ActiveDownloads.at(index), STATE_PAUSING); - qDebug("pausing %d - %s", index, m_ActiveDownloads[index]->m_FileName.toUtf8().constData()); + DownloadInfo *info = m_ActiveDownloads.at(index); + + if (info->m_State == STATE_DOWNLOADING) { + setState(info, STATE_PAUSING); + qDebug("pausing %d - %s", index, info->m_FileName.toUtf8().constData()); + } else if ((info->m_State == STATE_FETCHINGMODINFO) || (info->m_State == STATE_FETCHINGFILEINFO)) { + setState(info, STATE_READY); } } @@ -671,6 +701,14 @@ int DownloadManager::getModID(int index) const return m_ActiveDownloads.at(index)->m_ModID; } +bool DownloadManager::isHidden(int index) const +{ + if ((index < 0) || (index >= m_ActiveDownloads.size())) { + throw MyException(tr("invalid index")); + } + return m_ActiveDownloads.at(index)->m_Hidden; +} + NexusInfo DownloadManager::getNexusInfo(int index) const { @@ -843,6 +881,7 @@ void DownloadManager::createMetaFile(DownloadInfo *info) metaFile.setValue("uninstalled", info->m_State == DownloadManager::STATE_UNINSTALLED); metaFile.setValue("paused", (info->m_State == DownloadManager::STATE_PAUSED) || (info->m_State == DownloadManager::STATE_ERROR)); + metaFile.setValue("removed", info->m_Hidden); // slightly hackish... for (int i = 0; i < m_ActiveDownloads.size(); ++i) { @@ -1110,6 +1149,7 @@ void DownloadManager::downloadFinished() QByteArray data = info->m_Reply->readAll(); info->m_Output.write(data); info->m_Output.close(); + TaskProgressManager::instance().forgetMe(info->m_TaskProgressId); bool error = false; diff --git a/src/downloadmanager.h b/src/downloadmanager.h index 0d49aa35..a42ac073 100644 --- a/src/downloadmanager.h +++ b/src/downloadmanager.h @@ -102,8 +102,10 @@ private: NexusInfo m_NexusInfo; + bool m_Hidden; + static DownloadInfo *createNew(const NexusInfo &nexusInfo, int modID, int fileID, const QStringList &URLs); - static DownloadInfo *createFromMeta(const QString &filePath); + static DownloadInfo *createFromMeta(const QString &filePath, bool showHidden); /** * @brief rename the file @@ -168,6 +170,11 @@ public: */ void setSupportedExtensions(const QStringList &extensions); + /** + * @brief sets whether hidden files are to be shown after all + */ + void setShowHidden(bool showHidden); + /** * @brief download from an already open network connection * @@ -263,6 +270,13 @@ public: **/ int getModID(int index) const; + /** + * @brief determine if the specified file is supposed to be hidden + * @param index index of the file to look up + * @return true if the specified file is supposed to be hidden + */ + bool isHidden(int index) const; + /** * @brief retrieve all nexus info of the download specified by index * @@ -352,6 +366,12 @@ public slots: **/ void removeDownload(int index, bool deleteFile); + /** + * @brief restores the specified download to view (which was previously hidden + * @param index index of the download to restore + */ + void restoreDownload(int index); + /** * @brief cancel the specified download. This will lead to the corresponding file to be deleted * @@ -436,6 +456,8 @@ private: std::map m_DownloadFails; + bool m_ShowHidden; + }; #endif // DOWNLOADMANAGER_H diff --git a/src/installationmanager.cpp b/src/installationmanager.cpp index 87efecf1..6b430eea 100644 --- a/src/installationmanager.cpp +++ b/src/installationmanager.cpp @@ -184,11 +184,7 @@ bool InstallationManager::unpackSingleFile(const QString &fileName) QString InstallationManager::extractFile(const QString &fileName) { if (unpackSingleFile(fileName)) { - QString tempFileName = QDir::tempPath().append("/").append(QFileInfo(fileName).fileName()); - - m_FilesToDelete.insert(tempFileName); - - return tempFileName; + return QDir::tempPath().append("/").append(QFileInfo(fileName).fileName()); } else { return QString(); } @@ -571,49 +567,36 @@ bool InstallationManager::doInstall(GuessedValue &modName, int modID, } -void InstallationManager::openFile(const QString &fileName) +bool InstallationManager::wasCancelled() { - unpackSingleFile(fileName); + return m_CurrentArchive->getLastError() == Archive::ERROR_EXTRACT_CANCELLED; +} - QString tempFileName = QDir::tempPath().append("/").append(QFileInfo(fileName).fileName()); - SHELLEXECUTEINFOW execInfo; - memset(&execInfo, 0, sizeof(SHELLEXECUTEINFOW)); - execInfo.cbSize = sizeof(SHELLEXECUTEINFOW); - execInfo.fMask = SEE_MASK_NOCLOSEPROCESS; - execInfo.lpVerb = L"open"; - std::wstring fileNameW = ToWString(tempFileName); - execInfo.lpFile = fileNameW.c_str(); - execInfo.nShow = SW_SHOWNORMAL; - if (!::ShellExecuteExW(&execInfo)) { - qCritical("failed to spawn %s: %d", tempFileName.toUtf8().constData(), ::GetLastError()); - } +void InstallationManager::postInstallCleanup() const +{ + m_CurrentArchive->close(); - m_FilesToDelete.insert(tempFileName); -} + // directories we may want to remove. sorted from longest to shortest to ensure we remove subdirectories first. + auto longestFirst = [](const QString &LHS, const QString &RHS) -> bool { + if (LHS.size() != RHS.size()) return LHS.size() > RHS.size(); + else return LHS < RHS; + }; + std::set> directoriesToRemove(longestFirst); -// copy and pasted from mo_dll -bool EndsWith(LPCWSTR string, LPCWSTR subString) -{ - size_t slen = wcslen(string); - size_t len = wcslen(subString); - if (slen < len) { - return false; + // clean up temp files + // TODO: this doesn't yet remove directories. Also, the files may be left there if this point isn't reached + foreach (const QString &tempFile, m_TempFilesToDelete) { + QFileInfo fileInfo(QDir::tempPath() + "/" + tempFile); + QFile::remove(fileInfo.absoluteFilePath()); + directoriesToRemove.insert(fileInfo.absolutePath()); } - for (size_t i = 0; i < len; ++i) { - if (towlower(string[slen - len + i]) != towlower(subString[i])) { - return false; - } + // try to delete each directory we had temporary files in. the call fails for non-empty directories which is ok + foreach (const QString &dir, directoriesToRemove) { + QDir().rmdir(dir); } - return true; -} - - -bool InstallationManager::wasCancelled() -{ - return m_CurrentArchive->getLastError() == Archive::ERROR_EXTRACT_CANCELLED; } @@ -675,9 +658,7 @@ bool InstallationManager::install(const QString &fileName, GuessedValue bool archiveOpen = m_CurrentArchive->open(ToWString(QDir::toNativeSeparators(fileName)).c_str(), new MethodCallback(this, &InstallationManager::queryPassword)); - ON_BLOCK_EXIT([this] { - this->m_CurrentArchive->close(); - }); + ON_BLOCK_EXIT(std::bind(&InstallationManager::postInstallCleanup, this)); QScopedPointer filesTree(archiveOpen ? createFilesTree() : NULL); IPluginInstaller::EInstallResult installResult = IPluginInstaller::RESULT_NOTATTEMPTED; @@ -729,13 +710,6 @@ bool InstallationManager::install(const QString &fileName, GuessedValue qPrintable(installer->name()), e.what()); } - // clean up temp files - // TODO: this doesn't yet remove directories. Also, the files may be left there if this point isn't reached - foreach (const QString &tempFile, m_TempFilesToDelete) { - QFile::remove(QDir::tempPath() + "/" + tempFile); - } - - // act upon the installation result. at this point the files have already been // extracted to the correct location switch (installResult) { diff --git a/src/installationmanager.h b/src/installationmanager.h index 0e43a15d..1c6f9f19 100644 --- a/src/installationmanager.h +++ b/src/installationmanager.h @@ -168,9 +168,7 @@ private: bool ensureValidModName(MOBase::GuessedValue &name) const; -private slots: - - void openFile(const QString &fileName); + void postInstallCleanup() const; private: @@ -202,7 +200,6 @@ private: QProgressDialog m_InstallationProgress; - std::set m_FilesToDelete; std::set m_TempFilesToDelete; }; diff --git a/src/main.cpp b/src/main.cpp index c4431ac4..7c2a9b0e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -433,7 +433,10 @@ int main(int argc, char *argv[]) qDebug("initializing tutorials"); TutorialManager::init(QDir::fromNativeSeparators(ToQString(GameInfo::instance().getTutorialDir())).append("/")); - application.setStyleFile(settings.value("Settings/style", "").toString()); + if (!application.setStyleFile(settings.value("Settings/style", "").toString())) { + // disable invalid stylesheet + settings.setValue("Settings/style", ""); + } int res = 1; { // scope to control lifetime of mainwindow diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 57201db9..33dc75ed 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -4265,6 +4265,7 @@ void MainWindow::updateDownloadListDelegate() connect(ui->downloadView->itemDelegate(), SIGNAL(installDownload(int)), this, SLOT(installDownload(int))); connect(ui->downloadView->itemDelegate(), SIGNAL(queryInfo(int)), &m_DownloadManager, SLOT(queryInfo(int))); connect(ui->downloadView->itemDelegate(), SIGNAL(removeDownload(int, bool)), &m_DownloadManager, SLOT(removeDownload(int, bool))); + connect(ui->downloadView->itemDelegate(), SIGNAL(restoreDownload(int)), &m_DownloadManager, SLOT(restoreDownload(int))); connect(ui->downloadView->itemDelegate(), SIGNAL(cancelDownload(int)), &m_DownloadManager, SLOT(cancelDownload(int))); connect(ui->downloadView->itemDelegate(), SIGNAL(pauseDownload(int)), &m_DownloadManager, SLOT(pauseDownload(int))); connect(ui->downloadView->itemDelegate(), SIGNAL(resumeDownload(int)), &m_DownloadManager, SLOT(resumeDownload(int))); @@ -4735,3 +4736,8 @@ void MainWindow::on_linkButton_pressed() ui->linkButton->menu()->actions().at(1)->setIcon(linkDesktopFile.exists() ? removeIcon : addIcon); ui->linkButton->menu()->actions().at(2)->setIcon(linkMenuFile.exists() ? removeIcon : addIcon); } + +void MainWindow::on_showHiddenBox_toggled(bool checked) +{ + m_DownloadManager.setShowHidden(checked); +} diff --git a/src/mainwindow.h b/src/mainwindow.h index dfec5f49..ad4ed82e 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -502,6 +502,7 @@ private slots: // ui slots void on_groupCombo_currentIndexChanged(int index); void on_categoriesList_itemSelectionChanged(); void on_linkButton_pressed(); + void on_showHiddenBox_toggled(bool checked); }; #endif // MAINWINDOW_H diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 923df17c..b29136ff 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -968,7 +968,7 @@ p, li { white-space: pre-wrap; } - + @@ -976,6 +976,13 @@ p, li { white-space: pre-wrap; } + + + + Show Hidden + + + diff --git a/src/moapplication.cpp b/src/moapplication.cpp index efb0b615..ac660c6c 100644 --- a/src/moapplication.cpp +++ b/src/moapplication.cpp @@ -32,7 +32,7 @@ MOApplication::MOApplication(int argc, char **argv) } -void MOApplication::setStyleFile(const QString &styleName) +bool MOApplication::setStyleFile(const QString &styleName) { // remove all files from watch QStringList currentWatch = m_StyleWatcher.files(); @@ -42,11 +42,15 @@ void MOApplication::setStyleFile(const QString &styleName) // set new stylesheet or clear it if (styleName.length() != 0) { QString styleSheetName = applicationDirPath() + "/" + MOBase::ToQString(AppConfig::stylesheetsPath()) + "/" + styleName; + if (!QFile::exists(styleSheetName)) { + return false; + } m_StyleWatcher.addPath(styleSheetName); updateStyle(styleSheetName); } else { setStyleSheet(""); } + return true; } diff --git a/src/moapplication.h b/src/moapplication.h index 3d74031d..dd7f5eab 100644 --- a/src/moapplication.h +++ b/src/moapplication.h @@ -17,33 +17,33 @@ You should have received a copy of the GNU General Public License along with Mod Organizer. If not, see . */ -#ifndef MOAPPLICATION_H -#define MOAPPLICATION_H - -#include -#include - - -class MOApplication : public QApplication { -Q_OBJECT -public: - - MOApplication(int argc, char **argv); - - virtual bool notify (QObject *receiver, QEvent *event); - -public slots: - - void setStyleFile(const QString &style); - -private slots: - - void updateStyle(const QString &fileName); - -private: - - QFileSystemWatcher m_StyleWatcher; -}; - - -#endif // MOAPPLICATION_H +#ifndef MOAPPLICATION_H +#define MOAPPLICATION_H + +#include +#include + + +class MOApplication : public QApplication { +Q_OBJECT +public: + + MOApplication(int argc, char **argv); + + virtual bool notify (QObject *receiver, QEvent *event); + +public slots: + + bool setStyleFile(const QString &style); + +private slots: + + void updateStyle(const QString &fileName); + +private: + + QFileSystemWatcher m_StyleWatcher; +}; + + +#endif // MOAPPLICATION_H diff --git a/src/shared/skyriminfo.cpp b/src/shared/skyriminfo.cpp index 8c6b79ef..71d791f5 100644 --- a/src/shared/skyriminfo.cpp +++ b/src/shared/skyriminfo.cpp @@ -295,6 +295,7 @@ std::vector SkyrimInfo::getExecutables() result.push_back(ExecutableInfo(L"SKSE", L"skse_loader.exe", L"", L"", DEFAULT_CLOSE)); result.push_back(ExecutableInfo(L"SBW", L"SBW.exe", L"", L"", DEFAULT_CLOSE)); result.push_back(ExecutableInfo(L"Skyrim", L"TESV.exe", L"", L"", DEFAULT_CLOSE)); + result.push_back(ExecutableInfo(L"Skyrim Launcher", L"SkyrimLauncher.exe", L"", L"", DEFAULT_CLOSE)); result.push_back(ExecutableInfo(L"BOSS", L"BOSS/BOSS.exe", L"", L"", DEFAULT_STAY)); result.push_back(ExecutableInfo(L"Creation Kit", L"CreationKit.exe", L"", L"", DEFAULT_STAY, L"202480")); diff --git a/src/version.rc b/src/version.rc index 16669011..e71bc1b5 100644 --- a/src/version.rc +++ b/src/version.rc @@ -1,7 +1,7 @@ #include "Winver.h" -#define VER_FILEVERSION 1,0,4,0 -#define VER_FILEVERSION_STR "1,0,4,0\0" +#define VER_FILEVERSION 1,0,5,0 +#define VER_FILEVERSION_STR "1,0,5,0\0" VS_VERSION_INFO VERSIONINFO FILEVERSION VER_FILEVERSION -- cgit v1.3.1 From 09bd3dbead9afd6a57684908e77aba6960ad464d Mon Sep 17 00:00:00 2001 From: Tannin Date: Sat, 26 Oct 2013 15:02:31 +0200 Subject: - text files encoded in system encoding should now be correctly recognized in the mod info dialog - archive-list can be user-sorted again (within one mod) --- src/mainwindow.cpp | 11 ++++++----- src/mainwindow.h | 2 +- src/mainwindow.ui | 26 ++++++++++++++++---------- src/modinfodialog.cpp | 30 +++++++++++++++++++----------- 4 files changed, 42 insertions(+), 27 deletions(-) (limited to 'src/mainwindow.ui') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index cf8e355f..967a3842 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -205,7 +205,6 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget resizeLists(initSettings.contains("mod_list_state"), initSettings.contains("plugin_list_state")); - QMenu *linkMenu = new QMenu(this); linkMenu->addAction(QIcon(":/MO/gui/link"), tr("Toolbar"), this, SLOT(linkToolbar())); linkMenu->addAction(QIcon(":/MO/gui/link"), tr("Desktop"), this, SLOT(linkDesktop())); @@ -247,6 +246,8 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget connect(ui->espFilterEdit, SIGNAL(textChanged(QString)), this, SLOT(espFilterChanged(QString))); connect(&m_PluginList, SIGNAL(saveTimer()), this, SLOT(savePluginList())); + connect(ui->bsaList, SIGNAL(itemsMoved()), this, SLOT(on_bsaList_itemMoved())); + connect(ui->bsaWarning, SIGNAL(linkActivated(QString)), this, SLOT(linkClicked(QString))); connect(&m_DirectoryRefresher, SIGNAL(refreshed()), this, SLOT(directory_refreshed())); @@ -681,7 +682,7 @@ bool MainWindow::saveCurrentLists() reportError(tr("failed to save load order: %1").arg(e.what())); } - // ensure the archive list exists + // save only if the file doesn't exist at all, changes made in the ui are saved immediately if (!QFile::exists(m_CurrentProfile->getArchivesFileName())) { saveArchiveList(); } @@ -883,8 +884,7 @@ void MainWindow::hideSaveGameInfo() } } - -bool MainWindow::eventFilter(QObject* object, QEvent *event) +bool MainWindow::eventFilter(QObject *object, QEvent *event) { if ((object == ui->savegameList) && ((event->type() == QEvent::Leave) || (event->type() == QEvent::WindowDeactivate))) { @@ -1802,6 +1802,7 @@ void MainWindow::refreshBSAList() subItem = items.at(0); } else { subItem = new QTreeWidgetItem(QStringList(ToQString(origin.getName()))); + subItem->setFlags(subItem->flags() & ~Qt::ItemIsDragEnabled); ui->bsaList->addTopLevelItem(subItem); } subItem->addChild(iter->second); @@ -4649,7 +4650,7 @@ void MainWindow::on_bsaList_customContextMenuRequested(const QPoint &pos) menu.exec(ui->bsaList->mapToGlobal(pos)); } -void MainWindow::on_bsaList_itemChanged(QTreeWidgetItem*, int) +void MainWindow::on_bsaList_itemMoved() { saveArchiveList(); m_CheckBSATimer.start(500); diff --git a/src/mainwindow.h b/src/mainwindow.h index a96e5fcf..93a6af80 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -510,7 +510,7 @@ private slots: // ui slots void on_actionEndorseMO_triggered(); void on_bsaList_customContextMenuRequested(const QPoint &pos); - void on_bsaList_itemChanged(QTreeWidgetItem *item, int column); + void on_bsaList_itemMoved(); void on_btnRefreshData_clicked(); void on_categoriesList_customContextMenuRequested(const QPoint &pos); void on_compactBox_toggled(bool checked); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index b29136ff..73ca868e 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -577,7 +577,7 @@ p, li { white-space: pre-wrap; } QTabWidget::Rounded - 0 + 1 @@ -725,7 +725,7 @@ p, li { white-space: pre-wrap; } 6 - + Qt::CustomContextMenu @@ -742,7 +742,7 @@ BSAs checked here are loaded in such a way that your installation order is obeye QAbstractItemView::NoEditTriggers - false + true false @@ -751,10 +751,10 @@ BSAs checked here are loaded in such a way that your installation order is obeye false - QAbstractItemView::NoDragDrop + QAbstractItemView::DragDrop - Qt::IgnoreAction + Qt::MoveAction QAbstractItemView::SingleSelection @@ -768,6 +768,12 @@ BSAs checked here are loaded in such a way that your installation order is obeye true + + 1 + + + false + 200 @@ -776,11 +782,6 @@ BSAs checked here are loaded in such a way that your installation order is obeye File - - - Mod - - @@ -1224,6 +1225,11 @@ Right now this has very limited functionality QTreeView
modlistview.h
+ + MOBase::SortableTreeWidget + QTreeWidget +
sortabletreewidget.h
+
diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp index b4ae57ea..fae21cc4 100644 --- a/src/modinfodialog.cpp +++ b/src/modinfodialog.cpp @@ -254,17 +254,19 @@ void ModInfoDialog::refreshLists() } else if ((fileName.endsWith(".png", Qt::CaseInsensitive)) || (fileName.endsWith(".jpg", Qt::CaseInsensitive))) { QImage image = QImage(fileName); - if (static_cast(image.width()) / static_cast(image.height()) > 1.34) { - image = image.scaledToWidth(128); - } else { - image = image.scaledToHeight(96); - } + if (!image.isNull()) { + if (static_cast(image.width()) / static_cast(image.height()) > 1.34) { + image = image.scaledToWidth(128); + } else { + image = image.scaledToHeight(96); + } - QPushButton *thumbnailButton = new QPushButton(QPixmap::fromImage(image), ""); - thumbnailButton->setIconSize(QSize(image.width(), image.height())); - connect(thumbnailButton, SIGNAL(clicked()), &m_ThumbnailMapper, SLOT(map())); - m_ThumbnailMapper.setMapping(thumbnailButton, fileName); - ui->thumbnailArea->addWidget(thumbnailButton); + QPushButton *thumbnailButton = new QPushButton(QPixmap::fromImage(image), ""); + thumbnailButton->setIconSize(QSize(image.width(), image.height())); + connect(thumbnailButton, SIGNAL(clicked()), &m_ThumbnailMapper, SLOT(map())); + m_ThumbnailMapper.setMapping(thumbnailButton, fileName); + ui->thumbnailArea->addWidget(thumbnailButton); + } } } @@ -400,7 +402,13 @@ void ModInfoDialog::openTextFile(const QString &fileName) textFile.open(QIODevice::ReadOnly); QByteArray buffer = textFile.readAll(); QTextCodec *codec = QTextCodec::codecForUtfText(buffer, m_UTF8Codec); - ui->textFileView->setText(codec->toUnicode(buffer)); + QString text = codec->toUnicode(buffer); + if (codec->fromUnicode(text) != buffer) { + qDebug("conversion failed assuming local encoding"); + codec = QTextCodec::codecForLocale(); + text = codec->toUnicode(buffer); + } + ui->textFileView->setText(text); ui->textFileView->setProperty("currentFile", fileName); ui->textFileView->setProperty("encoding", codec->name()); ui->saveTXTButton->setEnabled(false); -- cgit v1.3.1 From f010c22a3b2ec31bc4ebc3f577ac4455c5de5dfb Mon Sep 17 00:00:00 2001 From: Tannin Date: Wed, 6 Nov 2013 18:35:27 +0100 Subject: - diagnosis plugins can now request to be re-evaluated - main application now contains means for plugins to react on some changes (to be extended) - plugins can now retrieve more information about a mod - user-agent sent to nexus now automatically contains the current MO version - included updated russian translation - problems dialog now refreshes itself after a fix was applied - fixed new esp/asset ordering diagnosis. May be fully functional now - bugfix: restoring locked load order could leave MO in an endless loop (not sure if this fix is correct yet) - bugfix: plugin list was not visually updated after some changes - bugfix: nmm importer threw away mod ordering --- src/downloadlistwidget.ui | 4 +- src/main.cpp | 2 +- src/mainwindow.cpp | 9 +- src/mainwindow.ui | 57 +- src/modinfo.cpp | 9 + src/modinfo.h | 1 + src/modinfodialog.ui | 33 +- src/modlist.cpp | 49 +- src/modlist.h | 21 +- src/nexusinterface.cpp | 15 +- src/nexusinterface.h | 1 + src/organizer_ru.qm | Bin 53312 -> 188628 bytes src/organizer_ru.ts | 3256 ++++++++++++++++++++--------------------- src/overwriteinfodialog.cpp | 4 +- src/overwriteinfodialog.h | 100 +- src/pluginlist.cpp | 28 +- src/pluginlist.h | 10 +- src/problemsdialog.cpp | 31 +- src/problemsdialog.h | 4 + src/settingsdialog.ui | 2 +- src/shared/directoryentry.cpp | 2 +- src/version.rc | 4 +- 22 files changed, 1838 insertions(+), 1804 deletions(-) (limited to 'src/mainwindow.ui') diff --git a/src/downloadlistwidget.ui b/src/downloadlistwidget.ui index 01b2ee07..106ac922 100644 --- a/src/downloadlistwidget.ui +++ b/src/downloadlistwidget.ui @@ -7,7 +7,7 @@ 0 0 315 - 75 + 81 @@ -78,7 +78,7 @@ - 0 + 0 diff --git a/src/main.cpp b/src/main.cpp index 90cf9e0e..5053d21d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -140,7 +140,7 @@ bool bootstrap() QObject::tr("The current user account doesn't have the required access rights to run " "Mod Organizer. The neccessary changes can be made automatically (the MO directory " "will be made writable for the current user account). You will be asked to run " - "\"helper.exe\" with administrative rights)."), + "\"helper.exe\" with administrative rights."), QMessageBox::Yes | QMessageBox::Cancel) == QMessageBox::Yes) { if (!Helper::init(GameInfo::instance().getOrganizerDirectory())) { return false; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 774c99f5..f726757c 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -487,6 +487,7 @@ void MainWindow::updateProblemsButton() ui->actionProblems->setIconText(tr("Problems")); ui->actionProblems->setToolTip(tr("There are potential problems with your setup")); } else { + ui->actionProblems->setEnabled(false); ui->actionProblems->setIconText(tr("No Problems")); ui->actionProblems->setToolTip(tr("Everything seems to be in order")); } @@ -983,6 +984,7 @@ bool MainWindow::registerPlugin(QObject *plugin) IPluginDiagnose *diagnose = qobject_cast(plugin); if (diagnose != NULL) { m_DiagnosisPlugins.push_back(diagnose); + diagnose->onInvalidated([&] () { this->updateProblemsButton(); }); } } { // tool plugins @@ -2178,7 +2180,7 @@ QString MainWindow::fullDescription(unsigned int key) const { switch (key) { case PROBLEM_PLUGINSNOTLOADED: { - QString result = tr("The following Plugins could not be loaded. The reason may be missing dependencies (i.e. python) or an outdated version:
    "); + QString result = tr("The following plugins could not be loaded. The reason may be missing dependencies (i.e. python) or an outdated version:") + "
      "; foreach (const QString &plugin, m_UnloadedPlugins) { result += "
    • " + plugin + "
    • "; } @@ -2985,8 +2987,9 @@ void MainWindow::unendorse_clicked() void MainWindow::overwriteClosed(int) { - QDialog *dialog = this->findChild("__overwriteDialog"); + OverwriteInfoDialog *dialog = this->findChild("__overwriteDialog"); if (dialog != NULL) { + m_ModList.modInfoChanged(dialog->modInfo()); dialog->deleteLater(); } } @@ -2994,6 +2997,7 @@ void MainWindow::overwriteClosed(int) void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index, int tab) { + m_ModList.modInfoAboutToChange(modInfo); std::vector flags = modInfo->getFlags(); if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end()) { QDialog *dialog = this->findChild("__overwriteDialog"); @@ -3019,6 +3023,7 @@ void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index, dialog.exec(); modInfo->saveMeta(); emit modInfoDisplayed(); + m_ModList.modInfoChanged(modInfo); } if (m_CurrentProfile->modEnabled(index)) { diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 73ca868e..bc7dc212 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -31,7 +31,16 @@ 4 - + + 6 + + + 6 + + + 6 + + 6 @@ -577,7 +586,7 @@ p, li { white-space: pre-wrap; } QTabWidget::Rounded - 1 + 0 @@ -721,7 +730,16 @@ p, li { white-space: pre-wrap; } Archives - + + 6 + + + 6 + + + 6 + + 6 @@ -801,7 +819,16 @@ BSAs checked here are loaded in such a way that your installation order is obeye Data - + + 6 + + + 6 + + + 6 + + 6 @@ -871,7 +898,16 @@ BSAs checked here are loaded in such a way that your installation order is obeye Saves - + + 6 + + + 6 + + + 6 + + 6 @@ -900,7 +936,16 @@ p, li { white-space: pre-wrap; } Downloads - + + 2 + + + 2 + + + 2 + + 2 diff --git a/src/modinfo.cpp b/src/modinfo.cpp index faf8c95b..f436eba8 100644 --- a/src/modinfo.cpp +++ b/src/modinfo.cpp @@ -827,6 +827,15 @@ ModInfoOverwrite::ModInfoOverwrite() } +bool ModInfoOverwrite::isEmpty() const +{ + QDirIterator iter(absolutePath(), QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs); + if (!iter.hasNext()) return true; + iter.next(); + if ((iter.fileName() == "meta.ini") && !iter.hasNext()) return true; + return false; +} + QString ModInfoOverwrite::absolutePath() const { return QDir::fromNativeSeparators(ToQString(GameInfo::instance().getOverwriteDir())); diff --git a/src/modinfo.h b/src/modinfo.h index 71c8de55..6de0275b 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -866,6 +866,7 @@ public: virtual void setNeverEndorse() {} virtual bool remove() { return false; } virtual void endorse(bool) {} + virtual bool isEmpty() const; virtual QString name() const { return "Overwrite"; } virtual QString notes() const { return ""; } virtual QDateTime creationTime() const { return m_StartupTime; } diff --git a/src/modinfodialog.ui b/src/modinfodialog.ui index 7e06745d..2fdbe5f3 100644 --- a/src/modinfodialog.ui +++ b/src/modinfodialog.ui @@ -209,7 +209,7 @@ 0 0 - 676 + 668 126 @@ -217,17 +217,22 @@ Images located in the mod. - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<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;">This lists all the images (.jpg and .png) in the mod directory, like screenshots and such. Click one to get a larger view.</span></p></body></html> + This lists all the images (.jpg and .png) in the mod directory, like screenshots and such. Click one to get a larger view. 0 - + + 0 + + + 0 + + + 0 + + 0 @@ -254,14 +259,10 @@ p, li { white-space: pre-wrap; } List of esps and esms that can not be loaded by the game. - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<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;">List of esps and esms contained in this plugin that currently can not be loaded by the game. They will not even appear in the esp-list in the main MO-window.</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;">They usually contain optional functionality, see the readme.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></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;">Most mods do not have optional esps, so chances are good you are looking at an empty list.</span></p></body></html> + List of esps and esms contained in this plugin that currently can not be loaded by the game. They will not even appear in the esp-list in the main MO-window. +They usually contain optional functionality, see the readme. + +Most mods do not have optional esps, so chances are good you are looking at an empty list. @@ -659,7 +660,7 @@ p, li { white-space: pre-wrap; } <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:7.8pt; font-weight:400; font-style:normal;"> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p></body></html> diff --git a/src/modlist.cpp b/src/modlist.cpp index 541e1e6e..446946dc 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -551,19 +551,49 @@ void ModList::changeModPriority(int sourceIndex, int newPriority) emit modorder_changed(); } -IModList::ModState ModList::state(const QString &name) const +void ModList::modInfoAboutToChange(ModInfo::Ptr info) { - unsigned int modIndex = ModInfo::getIndex(name); - if (modIndex == UINT_MAX) { - return IModList::STATE_MISSING; + m_ChangeInfo.name = info->name(); + m_ChangeInfo.state = state(info->name()); +} + +void ModList::modInfoChanged(ModInfo::Ptr info) +{ + if (info->name() == m_ChangeInfo.name) { + IModList::ModStates newState = state(info->name()); + if (m_ChangeInfo.state != newState) { + m_ModStateChanged(info->name(), newState); + } } else { + qCritical("modInfoChanged not called after modInfoAboutToChange"); + } +} + +IModList::ModStates ModList::state(const QString &name) const +{ + ModStates result; + unsigned int modIndex = ModInfo::getIndex(name); + if (modIndex != UINT_MAX) { + result |= IModList::STATE_EXISTS; ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex); + if (modInfo->isEmpty()) { + result |= IModList::STATE_EMPTY; + } + if (modInfo->endorsedState() == ModInfo::ENDORSED_TRUE) { + result |= IModList::STATE_ENDORSED; + } + if (modInfo->isValid()) { + result |= IModList::STATE_VALID; + } if (modInfo->canBeEnabled()) { - return m_Profile->modEnabled(modIndex) ? IModList::STATE_ACTIVE : IModList::STATE_INACTIVE; + if (m_Profile->modEnabled(modIndex)) { + result |= IModList::STATE_ACTIVE; + } } else { - return IModList::STATE_NOTOPTIONAL; + result |= IModList::STATE_ESSENTIAL; } } + return result; } int ModList::priority(const QString &name) const @@ -592,6 +622,13 @@ bool ModList::setPriority(const QString &name, int newPriority) } } + +bool ModList::onModStateChanged(const std::function &func) +{ + auto conn = m_ModStateChanged.connect(func); + return conn.connected(); +} + bool ModList::dropURLs(const QMimeData *mimeData, int row, const QModelIndex &parent) { QStringList source; diff --git a/src/modlist.h b/src/modlist.h index cdaa24ca..8cab7f3e 100644 --- a/src/modlist.h +++ b/src/modlist.h @@ -32,7 +32,7 @@ along with Mod Organizer. If not, see . #include #include #include - +#include #include #include #include @@ -61,6 +61,8 @@ public: COL_LASTCOLUMN = COL_PRIORITY }; + typedef boost::signals2::signal SignalModStateChanged; + public: /** @@ -94,10 +96,13 @@ public: void changeModPriority(int sourceIndex, int newPriority); + void modInfoAboutToChange(ModInfo::Ptr info); + void modInfoChanged(ModInfo::Ptr info); + public: /// \copydoc MOBase::IModList::state - virtual ModState state(const QString &name) const; + virtual ModStates state(const QString &name) const; /// \copydoc MOBase::IModList::priority virtual int priority(const QString &name) const; @@ -105,6 +110,9 @@ public: /// \copydoc MOBase::IModList::setPriority virtual bool setPriority(const QString &name, int newPriority); + /// \copydoc MOBase::IModList::onModStateChanged + virtual bool onModStateChanged(const std::function &func); + public: // implementation of virtual functions of QAbstractItemModel virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; @@ -245,6 +253,11 @@ private: unsigned int categoryOrder; }; + struct TModInfoChange { + QString name; + QFlags state; + }; + private: Profile *m_Profile; @@ -258,6 +271,10 @@ private: bool m_DropOnItems; + TModInfoChange m_ChangeInfo; + + SignalModStateChanged m_ModStateChanged; + }; #endif // MODLIST_H diff --git a/src/nexusinterface.cpp b/src/nexusinterface.cpp index 936ff400..6a4ae046 100644 --- a/src/nexusinterface.cpp +++ b/src/nexusinterface.cpp @@ -22,8 +22,10 @@ along with Mod Organizer. If not, see . #include "utility.h" #include "json.h" #include "selectiondialog.h" +#include #include #include +#include using QtJson::Json; @@ -148,6 +150,13 @@ NexusInterface::NexusInterface() m_DiskCache = new QNetworkDiskCache(this); connect(m_AccessManager, SIGNAL(requestNXMDownload(QString)), this, SLOT(downloadRequestedNXM(QString))); + + + VS_FIXEDFILEINFO version = GetFileVersion(ToWString(QApplication::applicationFilePath())); + + m_MOVersion = VersionInfo(version.dwFileVersionMS >> 16, + version.dwFileVersionMS & 0xFFFF, + version.dwFileVersionLS >> 16); } @@ -396,8 +405,10 @@ void NexusInterface::nextRequest() QNetworkRequest request(url); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/xml"); -#pragma message("automatically insert the correct version number") - request.setRawHeader("User-Agent", QString("Mod Organizer v1.0.5 (compatible to Nexus Client v%1)").arg(m_NMMVersion).toUtf8()); + request.setRawHeader("User-Agent", + QString("Mod Organizer v%1 (compatible to Nexus Client v%2)") + .arg(m_MOVersion.displayString()) + .arg(m_NMMVersion).toUtf8()); info.m_Reply = m_AccessManager->get(request); diff --git a/src/nexusinterface.h b/src/nexusinterface.h index 0b53f9d0..03226d8e 100644 --- a/src/nexusinterface.h +++ b/src/nexusinterface.h @@ -307,6 +307,7 @@ private: std::list m_ActiveRequest; QQueue m_RequestQueue; + MOBase::VersionInfo m_MOVersion; QString m_NMMVersion; }; diff --git a/src/organizer_ru.qm b/src/organizer_ru.qm index 1bae65a6..5921c2dc 100644 Binary files a/src/organizer_ru.qm and b/src/organizer_ru.qm differ diff --git a/src/organizer_ru.ts b/src/organizer_ru.ts index 2204198c..9b7b8101 100644 --- a/src/organizer_ru.ts +++ b/src/organizer_ru.ts @@ -1,4 +1,3 @@ - @@ -11,26 +10,26 @@ This is a list of esps and esms that were active when the save game was created. - Это список ESP и ESM, которые были активны во время создания сейва. + Это список esp и esm, которые были активны во время создания сохранения. - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">This is a list of esps and esms that were active when the save game was created.</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;">For each esp, the right column contains the mod (or mods) that can be enabled to make the missing esps/esms available.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></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;">If you hit Ok, all the mods selected in the right columns and all missing esps that have become available will be activated.</span></p></body></html> - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +</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;">This is a list of esps and esms that were active when the save game was created.</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;">For each esp, the right column contains the mod (or mods) that can be enabled to make the missing esps/esms available.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></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;">If you hit Ok, all the mods selected in the right columns and all missing esps that have become available will be activated.</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">Это список ESP и ESM, которые были активны, когда сейв был создан..</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;">Для каждого ESP, правый столбец содержит мод (или моды), которые могут быть включены, чтобы неактивные ESP / ESM стали активными.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></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;">Если вы нажмете ОК, все моды, выбранные в правой колонке будут активированы..</span></p></body></html> +</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;">Это список ESP и ESM, которые были активны, когда сейв был создан..</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;">Для каждого ESP, правый столбец содержит мод (или моды), которые могут быть включены, чтобы неактивные ESP / ESM стали активными.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></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;">Если вы нажмете ОК, все моды, выбранные в правой колонке будут активированы..</span></p></body></html> @@ -45,7 +44,7 @@ p, li { white-space: pre-wrap; } not found - Не найдено + не найдено @@ -73,8 +72,9 @@ p, li { white-space: pre-wrap; } Components of this package. -If there is a component called "00 Core" it is usually required. Options are ordered by priority as set up by the author. - Компоненты этого пакета.Если есть компонент который называется "00 Core", значит так надо. Параметры отсортированы по приоритетности созданной автором. +If there is a component called "00 Core" it is usually required. Options are ordered by priority as set up by the author. + Компоненты этого пакета. +Если есть компонент, называемый "00 Core", то это обычно необходимо. Опции упорядочены по приоритету, установленному автором. @@ -91,7 +91,7 @@ If there is a component called "00 Core" it is usually required. Optio Opens a Dialog that allows custom modifications. - Открывает диалоговое окно, которое позволяет выбрать пользовательские модификации. + Открывает диалог, позволяющий выбрать пользовательские модификации. @@ -101,7 +101,7 @@ If there is a component called "00 Core" it is usually required. Optio Ok - ОК + Ок @@ -129,7 +129,7 @@ If there is a component called "00 Core" it is usually required. Optio Internal ID for the category. The categories a mod belongs to are stored by this ID. It is recommended you use new IDs for categories you add instead of re-using existing ones. - Внутренний ID категории. Категории мода хранятся в истории под этим ID. Это рекомендуется использовать при создании новых ID для категорий, чтобы повторно использовать уже существующие. + Внутренний ID категории. Категории мода хранятся в истории под этим ID. Рекомендуется использовать новые ID для добавляемых вами категорий, вместо повторного использования существующих. @@ -154,20 +154,20 @@ If there is a component called "00 Core" it is usually required. Optio - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">You can match one or multiple nexus categories to a internal ID. Whenever you download a mod from a Nexus Page, Mod Organizer will try to resolve the category defined on the Nexus to one available in MO.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></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;">To find out a category id used by the nexus, visit the categories list of the nexus page and hover over the links there.</span></p></body></html> - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +</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;">You can match one or multiple nexus categories to a internal ID. Whenever you download a mod from a Nexus Page, Mod Organizer will try to resolve the category defined on the Nexus to one available in MO.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></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;">To find out a category id used by the nexus, visit the categories list of the nexus page and hover over the links there.</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">Вы можете задать соответствие с одной или нескольким категориям с внутренними ID. Каждый раз, когда вы загружаете мод со страницы Nexus, МО автоматически постарается задать соответствие, как на Nexus.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></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;">Чтобы узнать идентификатор категории используемого соответствия, посетите список категорий на странице Связь и наведите курсор мыши на нужную ссылку.</span></p></body></html> +</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;">Вы можете задать одну или несколько категорий Nexus внутреннему ID. Каждый раз, когда вы загружаете мод со страницы Nexus, МО постарается автоматически задать моду категорию, присвоенную ему на Nexus.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></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;">Чтобы узнать ID категории, используемой на Nexus, перейдите в список категорий Nexus и наведите курсор мыши на нужную ссылку.</span></p></body></html> @@ -199,7 +199,7 @@ p, li { white-space: pre-wrap; } - This feature may not work unless you're logged in with Nexus + This feature may not work unless you're logged in with Nexus Эта функция может не работать, если вход выполнен с Nexus @@ -225,14 +225,10 @@ p, li { white-space: pre-wrap; } DirectoryRefresher - - failed to read %1: %2 - Не удалось прочитать %1: %2 - failed to read bsa: %1 - + не удалось прочитать bsa: %1 @@ -245,73 +241,63 @@ p, li { white-space: pre-wrap; } Filetime - Ждите + Дата модификации Done - Готово + Выполнено - Information missing, please select "Query Info" from the context menu to re-retrieve. - Информация отсутствует, пожалуйста, выберите пункт "Справочная информация" из контекстного меню. + Information missing, please select "Query Info" from the context menu to re-retrieve. + Информация отсутствует, пожалуйста, выберите пункт "Справочная информация" из контекстного меню. DownloadListWidget - + Placeholder Заполнитель - - 0 - - - - - KB - - - - + + - Done - Double Click to install Готово - двойной щелчок для установки. + - Paused - Double Click to resume - + Пауза - двойной клик для продолжения + - Installed - Double Click to re-install Установлено - двойной клик для переустановки + - Uninstalled - Double Click to re-install - + Удалено - двойной клик для переустановки DownloadListWidgetCompact - + Placeholder Заполнитель - + Done Готово @@ -319,120 +305,120 @@ p, li { white-space: pre-wrap; } DownloadListWidgetCompactDelegate - + + Paused + Приостановлено + + + + Fetching Info 1 + Извлечение информации 1 + + + + Fetching Info 2 + Извлечение информации 2 + + + Installed Установлено - + Uninstalled - + Удалено - + Done Готово - - - - + + + + Are you sure? Вы уверены? - + This will remove all finished downloads from this list and from disk. Это удалит все готовые загрузки из этого списка и с диска. - + This will remove all installed downloads from this list and from disk. Это удалит все установленные загрузки из этого списка и с диска. - + This will permanently remove all finished downloads from this list (but NOT from disk). - + Это полностью удалит все завершенные загрузки из этого списка (но НЕ с диска). - + This will permanently remove all installed downloads from this list (but NOT from disk). - + Это полностью удалит все установленные загрузки из этого списка (но НЕ с диска). - + Install Установка - + Query Info Справочная информация - + Delete - + Удалить - + Remove from View - - - - - Remove - Удаление + Скрыть от просмотра - + Cancel Отмена - - Paused - - - - - Fetching Info 1 - - - - - Fetching Info 2 - - - - + Pause Пауза - + + Remove + Удаление + + + Resume Возобновить - + Delete Installed... - + Удалить установленное... - + Delete All... - + Удалить все... - + Remove Installed... Отменить установку - + Remove All... Удалить все @@ -440,100 +426,100 @@ p, li { white-space: pre-wrap; } DownloadListWidgetDelegate - - - - + + Fetching Info 1 + Извлечение информации 1 + + + + Fetching Info 2 + Извлечение информации 2 + + + + + + Are you sure? Вы уверены? - + This will remove all finished downloads from this list and from disk. Это удалит все готовые загрузки из этого списка и с диска. - + This will remove all installed downloads from this list and from disk. Это удалит все установленные загрузки из этого листа и с диска. - + This will remove all finished downloads from this list (but NOT from disk). - + Это удалит все готовые загрузки из этого списка (но НЕ с диска). - + This will remove all installed downloads from this list (but NOT from disk). - + Это удалит все установленные загрузки из этого списка (но НЕ с диска). - + Install Установить - + Query Info Справочная информация - + Delete - + Удалить - + Remove from View - - - - - Remove - Удалить + Скрыть от просмотра - + Cancel Отмена - - Fetching Info 1 - - - - - Fetching Info 2 - + + Pause + Пауза - Pause - Пауза + Remove + Удалить - + Resume Возобновить - + Delete Installed... - + Удалить установленное... - + Delete All... - + Удалить все... - + Remove Installed... Удалить установленные - + Remove All... Удалить все @@ -541,109 +527,103 @@ p, li { white-space: pre-wrap; } DownloadManager - - failed to rename "%1" to "%2" - Не удалось переименовать "%1" в "%2" + + failed to rename "%1" to "%2" + не удалось переименовать "%1" в "%2" - + Download again? Скачать снова - + A file with the same name has already been downloaded. Do you want to download it again? The new file will receive a different name. Файл с таким именем загружен. Вы хотите загрузить его снова? У него будет другое имя. - + failed to download %1: could not open output file: %2 - Ошибка загрузки %1: не удалось открыть входящий файл: %2 - - - - - - - - - - - - - + не удалось загрузить %1: не удалось открыть выходной файл: %2 + + + + + + + + + + + + invalid index - Неверный индекс + неверный индекс - + failed to delete %1 - Не удалось удалить %1 + не удалось удалить %1 - + failed to delete meta file for %1 - Не удалось удалить мета файл %1 + не удалось удалить мета-файл %1 - - - - - - + + + + + invalid index %1 - Неверный индекс %1 + неверный индекс %1 - + Please enter the nexus mod id - Выберите ID мода с Nexus + Пожалуйста, введите ID мода на Nexus - + Mod ID: ID мода: - invalid alphabetical index %1 - Недействительный алфавитный указатель %1 - - - + Information updated Информация обновлена - - + + No matching file found on Nexus! Maybe this file is no longer available or it was renamed? Нет соответствующих модов на Nexus! Возможно фал был удален или переименован? - + No file on Nexus matches the selected file by name. Please manually choose the correct one. Нет соответствующих фалов на Nexus. Выберите файл вручную. - + No download server available. Please try again later. Сервер недоступен. Попробуйте позже. - + Failed to request file info from nexus: %1 Не удалось получить информацию о файле: %1 - + Download failed: %1 (%2) Загрузка не удалась: %1 (%2) - + failed to re-open %1 - Не удалось открыть %1 + не удалось повторно открыть %1 @@ -720,14 +700,16 @@ p, li { white-space: pre-wrap; } Allow the Steam AppID to be used for this executable to be changed. - Разрешить Steam AppID. Для использования исполняемый файл будет изменен. + Разрешить изменение Steam AppID, используемого для этого исполняемого файла. Allow the Steam AppID to be used for this executable to be changed. Every game/tool distributed through Steam has a unique ID. MO needs to know this ID to start those programs directly, otherwise the program is started by steam and then MO will not work. By default, MO will use the AppID for the game. Right now the only case I know of where this needs to be overwritten is for the Skyrim Creation Kit which has its own AppID. This overwrite is already preconfigured. - Разрешить Steam AppID, который будет использоваться для изменения исполняемого файла. Каждая игра\инструмент раcпространяется через Steam и имеет уникальный ID. MO необходимо знать этот ID, что бы активировать игру\инструмент, иначе придется запускать через Steam. По умолчанию MO будет использовать AppID для игры\инструмента.Возможны проблемы с ID создаваемыми в Skyrim Creation Kit. + Разрешить изменение Steam AppID, который будет использоваться для исполняемого файла. +Каждая игра/инструмент распространяемые через Steam имеют свой уникальный ID. MO необходимо знать этот ID для прямого запуска этих программ, иначе они будут запущены через Steam и MO работать не будет. По умолчанию MO будет использовать AppID для игры. +В данный момент единственный случай, где это должно быть перезаписано это Skyrim Creation Kit, который имеет свой собственный AppID. Эта замена уже предварительно сконфигурирована. @@ -744,7 +726,9 @@ Right now the only case I know of where this needs to be overwritten is for the Steam AppID to use for this executable that differs from the games AppID. Every game/tool distributed through Steam has a unique ID. MO needs to know this ID to start those programs directly, otherwise the program is started by steam and then MO will not work. By default, MO will use the AppID for the game (usually 72850). Right now the only case I know of where this needs to be overwritten is for the Skyrim Creation Kit which has its own AppID (usually 202480). This overwrite is already preconfigured. - Steam AppID, который будет использоваться для изменения исполняемого файла. Каждая игра\инструмент раcпространяется через Steam и имеет уникальный ID. MO необходимо знать этот ID, что бы активировать игру\инструмент, иначе придется запускать через Steam. По умолчанию MO будет использовать AppID для игры\инструмента.Возможны проблемы с ID создаваемыми в Skyrim Creation Kit. + Steam AppID, используемый для этого исполняемого файла, отличающийся от AppID других игр. +Каждая игра/инструмент распространяемые через Steam имеют свой уникальный ID. MO необходимо знать этот ID для прямого запуска этих программ, иначе они будут запущены через Steam и MO работать не будет. По умолчанию MO будет использовать AppID для игры (обычно 72850). +В данный момент единственный случай, где он должен быть перезаписан, это для Skyrim Creation Kit, который имеет свой собственный AppID (обычно 202480). Эта замена уже предварительно сконфигурирована. @@ -794,12 +778,12 @@ Right now the only case I know of where this needs to be overwritten is for the Java (32-bit) required - + Требуется Java (32-bit) MO requires 32-bit java to run this application. If you already have it installed, select javaw.exe from that installation as the binary. - + MO требует 32-bit java для запуска этого приложения. Если он у вас уже установлен, выберете javaw.exe для этой установки как исполняемый файл. @@ -813,8 +797,8 @@ Right now the only case I know of where this needs to be overwritten is for the - Really remove "%1" from executables? - Действительно удалить "%1" исполняемых? + Really remove "%1" from executables? + Действительно удалить "%1" исполняемых? @@ -843,7 +827,7 @@ Right now the only case I know of where this needs to be overwritten is for the Search term - Поиск терминала + Поиск термина @@ -893,8 +877,8 @@ Right now the only case I know of where this needs to be overwritten is for the - <a href="#">Link</a> - <a href="#">ссылка</a> + <a href="#">Link</a> + <a href="#">Ссылка</a> @@ -916,58 +900,6 @@ Right now the only case I know of where this needs to be overwritten is for the Cancel Отмена - - ModuleConfig.xml missing - ModuleConfig.xml отсутствует - - - failed to parse info.xml: %1 (%2) (line %3, column %4) - не удалось проанализировать info.xml: %1 (%2) (строка %3, столбец %4) - - - unsupported order type %1 - не поддерживаемый тип порядка %1 - - - unsupported group type %1 - не поддерживаемый тип группы %1 - - - This component is required - Этот компонент необходим - - - It is recommended you enable this component - Рекомендуется включить этот компонент - - - Optional component - Дополнительный компонент - - - This component is not usable in combination with other installed plugins - Этот компонент не может сочетаться с другими установленными плагинами. - - - You may be experiencing instability in combination with other installed plugins - Могут наблюдаться нестабильность в сочетании с другими установленными плагинами. - - - None - Ни один - - - Select one or more of these options: - Выберите один или несколько из следующих вариантов: - - - failed to parse ModuleConfig.xml: %1 - не удается проанализировать ModuleConfig.xml: %1 - - - Install - Установить - InstallDialog @@ -993,7 +925,7 @@ Right now the only case I know of where this needs to be overwritten is for the - Pick a name for the mod. This is also used as a directory name, so please don't use characters that are illegal in file names. + Pick a name for the mod. This is also used as a directory name, so please don't use characters that are illegal in file names. Выбери имя для мода. Это также используется в качестве имени каталога, поэтому, пожалуйста, не используйте символы, которые запрещены в именах файлов. @@ -1008,16 +940,16 @@ Right now the only case I know of where this needs to be overwritten is for the - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">This displays the content of the archive. &lt;data&gt; represents the base directory which will map to the game's data directory. You can change the base directory via the right-click context menu and you can move around files via drag&amp;drop</span></p></body></html> - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +</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;">This displays the content of the archive. &lt;data&gt; represents the base directory which will map to the game's data directory. You can change the base directory via the right-click context menu and you can move around files via drag&amp;drop</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">Это показывает содержимое архива. <data> представляет базовый каталог, в котором будут сопоставлены с данными каталога игры. Вы можете изменить базовый каталог с помощью правой кнопкой мыши через контекстное меню, и можете перемещаться по файлам с помощью drag&drop.</span></p></body></html> +</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;">Отображает содержимое архива. &lt;data&gt; представляет базовый каталог, данные в котором будут сопоставлены с данными каталога игры. Вы можете изменить базовый каталог нажатием правой кнопки мыши, через контекстное меню, а также можете перемещаться по файлам с помощью drag&amp;drop</span></p></body></html> @@ -1027,59 +959,20 @@ p, li { white-space: pre-wrap; } OK - + OK Cancel Отмена - - Looks good - Выглядит хорошо - - - No problem detected - Проблем не обнаружено - - - No game data on top level - Нет данных игры уровнем выше - - - There is no esp/esm file or asset directory (textures, meshes, interface, ...) on the top level. - Существующий ESP / ESM файла или каталога не имеет текстуры textures, meshes, interface, ... уровнем выше. - - - Enter a directory name - Введите имя каталога - - - A directory with that name exists - Каталог с таким именем не существует - - - Set data directory - Набор данных каталога - - - Unset data directory - Отключенный каталог данных - - - Create directory... - Создать директорию... - - - &Open - &Открыть - InstallationManager - mo_archive.dll not loaded: "%1" - mo_archive.dll не загружен: "%1" + + archive.dll not loaded: "%1" + archive.dll не загружен: "%1" @@ -1092,158 +985,91 @@ p, li { white-space: pre-wrap; } Пароль - Directory exists - Каталог существует - - - This mod seems to be installed already. Do you want to add files from this archive (overwriting existing ones) or do you want to completely replace the existing files (old files are deleted)? - Этот мод, кажется, уже установлен. Вы хотите перезаписать существующие или вы хотите полностью заменить существующие файлы (старые файлы удаляются)? - - - Add Files - Добавить файлы - - - Replace - Заменить - - - - - + + + Extracting files Извлечение файлов - Preparing installer - Подготовка к установке - - - Installation as fomod failed: %1 - Установка в fomod не удалась: %1 - - - failed to start %1 - Не удалось начать %1 - - - Running external installer. -Note: This installer will not be aware of other installed mods! - Запуск внешней установки. -Внимание: Других запущенных программ установки не должно быть! - - - Force Close - Закрыть принудительно - - - Confirm - Подтвердить - - - installation failed (errorcode %1) - Установка не удалась (errorcode %1) - - - - File format "%1" not supported - Формат файла "%1" не поддерживается - - - failed to open archive "%1": %2 - Не удалось открыть архив "%1": %2 - - - - archive.dll not loaded: "%1" - - - - + failed to create backup - + не удалось создать резервную копию - + Mod Name - + Имя мода - + Name Имя - + Invalid name - + Недопустимое имя - + The name you entered is invalid, please enter a different one. - - - - Installer missing - Установщик отсутствует - - - This package contains a scripted installer. To use this installer you need the optional "NCC"-package and the .net runtime. Do you want to continue, treating this as a manual installer? - Этот пакет содержит сценарии установки. Для использования этой установки необходимо дополнительно «NCC» пакет и .net runtime. Вы хотите использовать это в качестве установки? + Введенное вами имя недопустимо, пожалуйста введите другое. - Please install NCC - Установите NCC + + File format "%1" not supported + Формат файла "%1" не поддерживается - + None of the available installer plugins were able to handle that archive - + Не один из доступных плагинов-установщиков не смог просмотреть этот архив - + no error - Ошибки отсутствуют + ошибки отсутствуют - + 7z.dll not found 7z.dll не найден - - 7z.dll isn't valid + + 7z.dll isn't valid 7z.dll поврежден - + archive not found - Архив не найден + архив не найден - + failed to open archive - Ошибка открытия архива + не удалось открыть архив - + unsupported archive type - Не поддерживаемый тип архива + не поддерживаемый тип архива - + internal library error - Внутренняя ошибка библиотеки + внутренняя ошибка библиотеки - + archive invalid - Архив поврежден + архив поврежден - + unknown archive error - Неизвестная ошибка архива + неизвестная ошибка архива @@ -1255,8 +1081,8 @@ Note: This installer will not be aware of other installed mods! - This dialog should disappear automatically if the application/game is done. Click unlock if it didn't. - Это окно должно закрыться автоматически если игра запущена. Нажмите кнопку "Разблокировать" если этого не произошло. + This dialog should disappear automatically if the application/game is done. Click unlock if it didn't. + Этот диалог должен закрыться автоматически если игра/приложение запущены. Нажмите разблокировать, если этого не произошло. @@ -1274,7 +1100,7 @@ Note: This installer will not be aware of other installed mods! failed to write log to %1: %2 - Не удалось произвести запись в журнал %1: %2 + не удалось произвести запись в журнал %1: %2 @@ -1282,12 +1108,12 @@ Note: This installer will not be aware of other installed mods! an error occured: %1 - + произошла ошибка: %1 an error occured - + произошла ошибка @@ -1301,148 +1127,169 @@ Note: This installer will not be aware of other installed mods! Profile - + Профиль Pick a module collection - + Выберете набор модулей - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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> - +</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> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">Создать профили здесь. Каждый профиль включает свой собственный список активных модов и esp. Таким образом, вы можете быстро переключаться между установками для различных прохождений игры.</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;">Обратите внимание, что порядок загрузки esp одинаков для всех профилей.</span></p></body></html> Refresh list - + Обновить список Refresh list. This is usually not necessary unless you modified data outside the program. - + Обновить список. Обычно в этом нет необходимости, пока вы не измените данные вне программы. List of available mods. - + Список доступных модов. - This is a list of installed mods. Use the checkboxes to activate/deactivate mods and drag & drop mods to change their "installation" orders. - + This is a list of installed mods. Use the checkboxes to activate/deactivate mods and drag & drop mods to change their "installation" orders. + Это список установленных модов. Используйте флажки, для включения/отключения модов и перетаскивание модов, для изменения их порядка установки. Filter - + Фильтр No groups - + Без группировки Nexus IDs - Nexus IDs + Nexus IDs - + Namefilter - + Фильтр по имени Pick a program to run. - + Выберете программу для запуска. - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">Choose the program to run. Once you start using ModOrganizer, you should always run your game and tools from here or through shortcuts created here, otherwise mods installed through MO will not be visible.</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;">You can add new Tools to this list, but I can't promise tools I haven't tested will work.</span></p></body></html> - +</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;">Choose the program to run. Once you start using ModOrganizer, you should always run your game and tools from here or through shortcuts created here, otherwise mods installed through MO will not be visible.</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;">You can add new Tools to this list, but I can't promise tools I haven't tested will work.</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">Выберете программу для запуска. Как только вы начинаете использовать ModOrganizer, вы всегда должны запускать игры и инструменты из него или через созданные в нем ярлыки, в противном случае, установленные через MO моды отображаться не будут.</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;">Вы можете добавить новые инструменты в этот список, но работоспособность их всех не гарантированна.</span></p></body></html> Run program - + Запустить программу - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">Run the selected program with ModOrganizer enabled.</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">Run the selected program with ModOrganizer enabled.</span></p></body></html> - +</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;">Запустить выбранную программу с поддержкой ModOrganizer.</span></p></body></html> Run - + Запустить Create a shortcut in your start menu or on the desktop to the specified program - + Создать ярлык для выбранной программы, в меню Пуск или на рабочем столе. - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">This creates a start menu shortcut that directly starts the selected program with the MO active.</span></p></body></html> - +</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;">This creates a start menu shortcut that directly starts the selected program with the MO active.</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">Создает ярлык в меню Пуск, который запускает выбранную программу с активным MO.</span></p></body></html> Shortcut - - - - Save - Сохранить + Ярлык List of available esp/esm files - + Список доступных esp/esm файлов - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">This list contains the esps and esms contained in the active mods. These require their own load order. Use drag&amp;drop to modify this load order. Please note that MO will only save the load order for mods that are active/checked.<br />There is a great tool named &quot;BOSS&quot; to automatically sort these files.</span></p></body></html> - +</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;">This list contains the esps and esms contained in the active mods. These require their own load order. Use drag&amp;drop to modify this load order. Please note that MO will only save the load order for mods that are active/checked.<br />There is a great tool named &quot;BOSS&quot; to automatically sort these files.</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">Этот список содержит esp и esm файлы активных модов. Для них требуется определенный порядок загрузки. Используйте перетаскивание для изменения порядка загрузки. Обратите внимание, что MO сохранит порядок загрузки только для активными/проверенных модов.<br />Существует замечательная утилита, называющаяся &quot;BOSS&quot; , которая автоматически сортирует эти файлы.</span></p></body></html> List of available BS Archives. Archives not checked here are not managed by MO and ignore installation order. - + Список доступных BSA. Они не отмечены здесь, не управляются с помощью MO и игнорируют порядок установки. - BSA files are archives (comparable to .zip files) that contain data assets (meshes, textures, ...) to be used by the game. As such they "compete" with loose files in your data directory over which is loaded. + BSA files are archives (comparable to .zip files) that contain data assets (meshes, textures, ...) to be used by the game. As such they "compete" with loose files in your data directory over which is loaded. By default, BSAs that share their base name with an enabled ESP (i.e. plugin.esp and plugin.bsa) are automatically loaded and will have precedence over all loose files, the installation order you set up to the left is then ignored! BSAs checked here are loaded in such a way that your installation order is obeyed properly. - + BSA файлы - архивы (сопоставимы с файлами .zip) которые содержат используемые игрой данные (meshes, textures, ...). Как таковые они "конкурируют" с отдельными файлами в папке Data, поверх которых загружены. +По умолчанию, BSA, у которых имя совпадает с именем ESP (т.е. plugin.esp и plugin.bsa) будут автоматически загружены и будут иметь приоритет над всеми отдельными файлами и установленный вами слева порядок установки будет проигнорирован! + +BSA, отмеченные здесь, загружаются так, чтобы порядок установки соблюдался должным образом. @@ -1458,1030 +1305,1035 @@ BSAs checked here are loaded in such a way that your installation order is obeye - <html><head/><body><p>Marked Archives (<img src=":/MO/gui/resources/dialog-warning_16.png"/>) are still loaded on Skyrim but the <a href="http://forums.bethsoft.com/topic/1354395-update-bsas-and-you/"><span style=" text-decoration: underline; color:#0000ff;">regular file override</span></a> mechanism will apply: Loose files override BSAs, no matter the mod/plugin priority.</p></body></html> - + <html><head/><body><p>Marked Archives (<img src=":/MO/gui/resources/dialog-warning_16.png"/>) are still loaded on Skyrim but the <a href="http://forums.bethsoft.com/topic/1354395-update-bsas-and-you/"><span style=" text-decoration: underline; color:#0000ff;">regular file override</span></a> mechanism will apply: Loose files override BSAs, no matter the mod/plugin priority.</p></body></html> + <html><head/><body><p>Помеченые архивы (<img src=":/MO/gui/resources/dialog-warning_16.png"/>) все еще загружаются в Skyrim, но <a href="http://forums.bethsoft.com/topic/1354395-update-bsas-and-you/"><span style=" text-decoration: underline; color:#0000ff;">применяется обычный</span></a> механизм: Отдельные файлы перезаписывают BSAs, вне зависимости от приоритета мода/плагина.</p></body></html> Data - + Данные refresh data-directory overview - + обновить обзор каталога Data Refresh the overview. This may take a moment. - + Обновление обзора. Это может занять некоторое время. - - + + Refresh - + Обновить This is an overview of your data directory as visible to the game (and tools). - + Это обзор вашего каталога данных так, как он будет видим игре (и инструментам). Filter the above list so that only conflicts are displayed. - + Отфильтровать вышеприведенный список так, чтобы отображались только конфликты. Show only conflicts - + Показать только конфликты Saves - + Сохранения - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">This is a list of all savegames for this game. Hover over a list entry to get detailed information about the save including a list of esps/esms that were used at the time this save was created but aren't active now.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></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;">If you click &quot;Fix Mods...&quot; in the context menu, MO will try to activate all mods and esps to fix those missing esps. It will not disable anything!</span></p></body></html> - +</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;">This is a list of all savegames for this game. Hover over a list entry to get detailed information about the save including a list of esps/esms that were used at the time this save was created but aren't active now.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></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;">If you click &quot;Fix Mods...&quot; in the context menu, MO will try to activate all mods and esps to fix those missing esps. It will not disable anything!</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">Список всех сохранений игры. Наведите указатель мыши на элемент списка, чтобы получить подробную информацию о сохранении, включающем список esp/esm, которые использовались во время создания сохранения, но не активны в настоящее время.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></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;">Если вы выберете в контекстном меню пункт &quot;Исправить моды...&quot;, MO попытается подключить все моды и esp, чтобы исправить эти отсутствующие esp. Это ничего не отключит!</span></p></body></html> Downloads - + Загрузки This is a list of mods you downloaded from Nexus. Double click one to install it. - + Список модов, загруженных с Nexus. Двойной клик для установки. - + Compact - + Упаковать - + Tool Bar - + Панель инструментов - + Install Mod - + Установить мод - + Install &Mod - + Установить &мод - + Install a new mod from an archive - + Установить новый мод из архива - + Ctrl+M - + Ctrl+M - + Profiles - + Профили - + &Profiles - + &Профили - + Configure Profiles - + Настройка профилей - + Ctrl+P - + Ctrl+P - + Executables - + Программы - + &Executables - + &Программы - + Configure the executables that can be started through Mod Organizer - + Настройка программ, которые могут быть запущены через Mod Organizer - + Ctrl+E - + Ctrl+E + - Tools - + Инструменты - + &Tools - + &Инструменты - + Ctrl+I - + Ctrl+I - + Settings - + Настройки - + &Settings - + &Настройки - + Configure settings and workarounds - + Настройка параметров и способов обхода - + Ctrl+S - + Ctrl+S - + Nexus - + Nexus - + Search nexus network for more mods - + Поиск дополнительных модов на Nexus - + Ctrl+N - + Ctrl+N - - + + Update - + Обновление - + Mod Organizer is up-to-date - + Mod Organizer обновлен - - + + No Problems - + Проблем не обнаружено - + This button will be highlighted if MO discovered potential problems in your setup and provide tips on how to fix them. !Work in progress! Right now this has very limited functionality - + Эта кнопка будет подсвечена, если MO обнарул возможные проблемы в вашей установке и имеются советы по их исправлению. + +!В разработке! +Прямо сейчас этот функционал сильно ограничен - - + + Help - + Справка - + Ctrl+H - + Ctrl+H - + Endorse MO - + Одобрить MO - - + + Endorse Mod Organizer - + Одобрить Mod Organizer - + Toolbar - + Панель инструментов - + Desktop - + Рабочий стол - + Start Menu - + Меню Пуск - + Problems - + Проблемы - + There are potential problems with your setup - + Есть возможные проблемы с вашей установкой - + Everything seems to be in order - + Кажется всё в порядке - + Help on UI - + Справка по интерфейсу - + Documentation Wiki - + Wiki-документация - + Report Issue - + Сообщить о проблеме - + Tutorials - + Уроки - - failed to save load order: %1 - + + failed to save archives order, do you have write access to "%1"? + не удалось сохранить порядок архивов, у вас имеется доступ на запись к "%1"? - - failed to save archives order, do you have write access to "%1"? - + + failed to save load order: %1 + не удалось сохранить порядок загрузки: %1 - + Name Имя - + Please enter a name for the new profile - + Введите имя нового профиля - + failed to create profile: %1 - + не удалось создать профиль: %1 - + Show tutorial? - + Показать урок? - - You are starting Mod Organizer for the first time. Do you want to show a tutorial of its basic features? If you choose no you can always start the tutorial from the "Help"-menu. - + + You are starting Mod Organizer for the first time. Do you want to show a tutorial of its basic features? If you choose no you can always start the tutorial from the "Help"-menu. + Вы запустили Mod Organizer впервые. Вы хотите просмотреть уроки по основным возможностям? В случае отказа вы всегда можете открыть уроки из меню "Помощь". - + Downloads in progress - + Загрузки в процессе - + There are still downloads in progress, do you really want to quit? - + Загрузки всё ещё в процессе, вы правда хотите выйти? - + failed to read savegame: %1 - + не удалось прочесть сохранение: %1 + + + + Plugin "%1" failed: %2 + Плагин "%1" не удалось: %2 - - Plugin "%1" failed: %2 - + + Plugin "%1" failed + Плагин "%1" не удалось - - Failed to start "%1" - + + failed to init plugin %1: %2 + не удалось инициализировать плагин %1: %2 + + + + Failed to start "%1" + Не удалось запустить "%1" - + Waiting - + Ожидание - - Please press OK once you're logged into steam. - + + Please press OK once you're logged into steam. + Нажмите OK как только вы войдете в Steam. - - "%1" not found - + + "%1" not found + "%1" не найден - + Start Steam? - + Запустить Steam? - + Steam is required to be running already to correctly start the game. Should MO try to start steam now? - + Требуется запущенный Steam, для корректного запуска игры. Должен ли MO попытаться запустить Steam сейчас? - + Also in: <br> - + Также в: <br> - + No conflict - + Конфликтов нет - + <Edit...> - + <Правка...> - + This bsa is enabled in the ini file so it may be required! - + Этот bsa подключен через ini, так что он может быть необходим! - + This archive will still be loaded since there is a plugin of the same name but its files will not follow installation order! - + Этот архив все равно будет загружен, так как есть плагин с одноименным названием, но его файлы не будут следовать порядку установки! - + Activating Network Proxy - + Подключение сетевого прокси - - + + Installation successful - + Установка завершена - - + + Configure Mod - + Настройка мода - - + + This mod contains ini tweaks. Do you want to configure them now? - + Этот мод включает настройки ini. Вы хотите настроить их сейчас? - - - mod "%1" not found - + + + mod "%1" not found + мод "%1" не найден - - + + Installation cancelled - + Установка отменена - - + + The mod was not installed completely. - + Мод не был установлен полностью. - + Some plugins could not be loaded - + Некоторые плагины не могут быть загружены - + The following Plugins could not be loaded. The reason may be missing dependencies (i.e. python) or an outdated version:<ul> - + Следующие плагины не могут быть загружены. Причина может быть в отсутствующих зависимостях (таких как python) или в устаревшей версии:<ul> - + Choose Mod - + Выберете мод - + Mod Archive - + Архив мода - + Start Tutorial? - + Начать обучение? - - You're about to start a tutorial. For technical reasons it's not possible to end the tutorial early. Continue? - + + You're about to start a tutorial. For technical reasons it's not possible to end the tutorial early. Continue? + Вы собираетесь открыть обучение. По техническим причинам будет невозможно досрочно закончить обучение. Продолжить? - - + + Download started - + Загрузка начата - + failed to update mod list: %1 - + не удалось обновить список модов: %1 - + failed to spawn notepad.exe: %1 - + не удалось вызвать notepad.exe: %1 - + failed to open %1 - + не удалось открыть %1 - + failed to change origin name: %1 - - - - - Multiple esps activated, please check that they don't conflict. - + не удалось изменить оригинальное имя: %1 - - - Create Mod... - - - - - This will move all files from overwrite into a new, regular mod. -Please enter a name: - - - - - A mod with this name already exists - - - - - <All> - - - - + <Checked> - - - - - Plugin "%1" failed - + <Подключен> - - failed to init plugin %1: %2 - - - - - - Description missing - - - - + <Unchecked> - + <Отключен> - + <Update> - + <Обновлен> - + <No category> - + <Без категории> - + <Conflicted> - + <Конфликтует> - + failed to rename mod: %1 - + не удалось переименовать мод: %1 - + Overwrite? - + Перезаписать? - - This will replace the existing mod "%1". Continue? - + + This will replace the existing mod "%1". Continue? + Это заменит существующий мод "%1". Продолжить? - - failed to remove mod "%1" - + + failed to remove mod "%1" + не удалось удалить мод "%1" - - - - failed to rename "%1" to "%2" - Не удалось переименовать "%1" в "%2" + + + + failed to rename "%1" to "%2" + не удалось переименовать "%1" в "%2" - - - + + Multiple esps activated, please check that they don't conflict. + Подключено несколько esp, выберете из них не конфликтующие. + + + + + Confirm - Подтвердить + Подтверждение - + Remove the following mods?<br><ul>%1</ul> - + Удалить следующие моды?<br><ul>%1</ul> - + failed to remove mod: %1 - + не удалось удалить мод: %1 - - + + Failed - + Неудача - + Installation file no longer exists - + Установочный файл больше не существует - - Mods installed with old versions of MO can't be reinstalled in this way. - + + Mods installed with old versions of MO can't be reinstalled in this way. + Моды, установленные с использованием старых версий MO не могут быть перестановленны таким образом. - - + + You need to be logged in with Nexus to endorse - + Вы должны быть авторизированы на Nexus, чтобы одобрять. - - + + Extract BSA - + Извлечь BSA - + This mod contains at least one BSA. Do you want to unpack it? -(This removes the BSA after completion. If you don't know about BSAs, just select no) - +(This removes the BSA after completion. If you don't know about BSAs, just select no) + Этот мод включает как минимум один BSA. Вы хотите распаковать их? +(Это удалит BSA после завершения. Если вы не знаете ничего о BSAs, просто откажитесь) - - - + + + failed to read %1: %2 - Не удалось прочитать %1: %2 + не удалось прочесть %1: %2 - - + + This archive contains invalid hashes. Some files may be broken. - + Архив содержит неверные хеши. Некоторые файлы могут быть испорчены. - + Nexus ID for this Mod is unknown - + Nexus ID для этого мода неизвестен + + + + + Create Mod... + Создать мод... + + + + This will move all files from overwrite into a new, regular mod. +Please enter a name: + Это переместит все файлы от перезаписи в новый, отдельный мод. +Пожалуйста, введите имя: + + + + A mod with this name already exists + Мод с таким именем уже существует - + Really enable all visible mods? - + Действительно подключить все видимые моды? - + Really disable all visible mods? - + Действительно отключить все видимые моды? - + Choose what to export - + Выберете, что экспортировать - + Everything - + Всё - + All installed mods are included in the list - + Все установленные моды, включенные в список - + Active Mods - + Активные моды - + Only active (checked) mods from your current profile are included - + Включены все активные (подключенные) моды вашего текущего профиля - + Visible - + Видимые - + All mods visible in the mod list are included - + Включены все моды, видимые в списке модов - + export failed: %1 - + экспорт не удался: %1 - + Install Mod... - + Установить мод... - + Enable all visible - + Включить все видимые - + Disable all visible - + Отключить все видимые - + Check all for update - + Проверить все на обновления - + Export to csv... - + Экспорт в csv... - + Sync to Mods... - + Синхронизировать с модами... - + Restore Backup - + Восстановить из резервной копии - + Remove Backup... - + Удалить резервную копию... - + Set Category - + Задать категорию - + Primary Category - + Основная категория - + Rename Mod... - + Переименовать мод... - + Remove Mod... - + Удалить мод... - + Reinstall Mod - + Переустановить мод - + Un-Endorse - + Отменить одобрение - - + + Endorse - + Одобрить - - Won't endorse - + + Won't endorse + Не одобрять - + Endorsement state unknown - + Статус одобрения неизвестен - + Ignore missing data - + Игнорировать отсутствующие данные - + Visit on Nexus - + Перейти на Nexus - + Open in explorer - + Открыть в проводнике - + Information... - + Информация... - - + + Exception: - + Исключение: - - + + Unknown exception - + Неизвестное исключение - + + <All> + <Все> + + + <Multiple> - + <Несколько> - + Fix Mods... - + Исправить моды... - - + + failed to remove %1 - + не удалось удалить %1 - - + + failed to create %1 - + не удалось создать %1 - - Can't change download directory while downloads are in progress! - + + Can't change download directory while downloads are in progress! + Нельзя изменить каталог для загрузок, когда загрузки ещё не завершены! - + Download failed - + Загрузка не удалась - + failed to write to file %1 - + ошибка записи в файл %1 - + %1 written - + %1 записан - + Select binary - + Выбрать исполняемый файл - + Binary - Двоичный + Исполняемый файл - + Enter Name - + Введите имя - + Please enter a name for the executable - + Введите название для программы - + Not an executable - + Не является исполняемым - + This is not a recognized executable. - + Это неверный исполняемый файл. - - + + Replace file? - + Заменить файл? - + There already is a hidden version of this file. Replace it? - + Уже существует скрытая версия этого файла. Заменить? - - + + File operation failed - + Операция с файлом не удалась - - - Failed to remove "%1". Maybe you lack the required file permissions? - + + + Failed to remove "%1". Maybe you lack the required file permissions? + Не удалось удалить "%1". Может быть, вам не хватает необходимых прав доступа к файлу? - + There already is a visible version of this file. Replace it? - + Видимая версия этого файла уже существует. Заменить? - + Update available - + Доступно обновление - + Open/Execute - + Открыть/Выполнить - + Add as Executable - + Добавить как исполняемый - + Un-Hide - + Показать - + Hide - + Скрыть - + Write To File... - + Записать в файл... - + Do you want to endorse Mod Organizer on %1 now? - + Вы хотите одобрить Mod Organizer на %1 сейчас? - - Unlock load order - - - - - Lock load order - - - - + Request to Nexus failed: %1 - + Запрос на Nexus не удался: %1 - - + + login successful - + успешный вход - + login failed: %1. Trying to download anyway - + вход не удался: %1. Пытаюсь загрузить всё равно - + login failed: %1 - + войти не удалось: %1 - + login failed: %1. You need to log-in with Nexus to update MO. - + войти не удалось: %1. Вам нужно войти на Nexus, чтобы обновить MO. - + Error - + Ошибка - + failed to extract %1 (errorcode %2) - + не удалось извлечь %1 (код ошибки %2) - + Extract... - + Распаковка... - + Edit Categories... - + Изменить категории... - + Enable all - + Включить все - + Disable all - + Отключить все + + + + Unlock load order + Разблокировать порядок загрузки + + + + Lock load order + Заблокировать порядок загрузки @@ -2492,10 +2344,6 @@ Please enter a name: Placeholder Заполнитель - - Please install NCC - Установите NCC - ModInfo @@ -2503,11 +2351,7 @@ Please enter a name: invalid index %1 - Неверный индекс %1 - - - invalid mod id %1 - неверный ID мода %1 + неверный индекс %1 @@ -2515,7 +2359,7 @@ Please enter a name: This is the backup of a mod - + Это резервная копия мода @@ -2538,7 +2382,7 @@ Please enter a name: A list of text-files in the mod directory like readmes. - Список текстовых файлов в каталоге мода, ознакомительных. + Список текстовых файлов в каталоге мода, таких как ридми. @@ -2554,7 +2398,7 @@ Please enter a name: This is a list of .ini files in the mod. - Это список INI - фалов мода. + Это список .ini-файлов мода. @@ -2583,16 +2427,16 @@ Please enter a name: - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">This lists all the images (.jpg and .png) in the mod directory, like screenshots and such. Click one to get a larger view.</span></p></body></html> - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +</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;">This lists all the images (.jpg and .png) in the mod directory, like screenshots and such. Click one to get a larger view.</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">Это список всех изображений (. JPG и. PNG) в каталоге мода, такие как скриншоты и т.п. Нажмите на один из них, что бы увеличить.</span></p></body></html> +</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;">Это список всех изображений (.jpg и .png) в каталоге мода, таких как скриншоты и т.п. Нажмите на любое, для увеличения.</span></p></body></html> @@ -2603,26 +2447,26 @@ p, li { white-space: pre-wrap; } List of esps and esms that can not be loaded by the game. - Список ESP и ESM которые не могут быть включены в игру. + Список esp и esm, которые не могут быть загружены игрой. - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">List of esps and esms contained in this plugin that currently can not be loaded by the game. They will not even appear in the esp-list in the main MO-window.</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;">They usually contain optional functionality, see the readme.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></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;">Most mods do not have optional esps, so chances are good you are looking at an empty list.</span></p></body></html> - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +</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;">List of esps and esms contained in this plugin that currently can not be loaded by the game. They will not even appear in the esp-list in the main MO-window.</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;">They usually contain optional functionality, see the readme.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></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;">Most mods do not have optional esps, so chances are good you are looking at an empty list.</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">Список ESP и ESM содержащие в паллагине, которые не могут быть включены в игру. они так же не будут отображены в списке ESP и ESM мода.</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;">Они обычно содержат дополнительные функции. См. ReadME.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></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;">Большинство модов не имеют дополнительные ESP. Поэтому вы можете увидеть пустой список</span></p></body></html> +</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;">Список esp и esm, содержащихся в плагине, которые не могут быть загружены в игру. Они так же не будут отображены в списке esp, в главном окне MO.</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;">Они обычно содержат опциональный функционал, смотрите документацию.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></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;">Большинство модов не содержат дополнительных esp, поэтому вы можете увидеть пустой список</span></p></body></html> @@ -2631,8 +2475,8 @@ p, li { white-space: pre-wrap; } - The selected esp (in the lower list) will be pushed into a subdirectory of the mod and will thus become "invisible" to the game. It can then no longer be activated. - Выбранный ESP (в нижнем списке) будет перемещены в подкаталог мода и, таким образом, станут "невидимыми" для игры. Затем они больше не будут активированы. + The selected esp (in the lower list) will be pushed into a subdirectory of the mod and will thus become "invisible" to the game. It can then no longer be activated. + Выбранный ESP (в нижнем списке) будет перемещены в подкаталог мода и, таким образом, станут "невидимыми" для игры. Затем они больше не будут активированы. @@ -2641,8 +2485,8 @@ p, li { white-space: pre-wrap; } - This moves a esp to the esp directory so it can be enabled in the main window. Please note that the ESP merely becomes "available", it will not necessarily be loaded! That is configured in the main window of omo. - Перемещает ESP в каталог Data. Он может быть включен в главном окне. Обратите внимание, что ESP просто становится "доступным", это не обязательно будет включен! Это настраивается в главном окне OMO. + This moves a esp to the esp directory so it can be enabled in the main window. Please note that the ESP merely becomes "available", it will not necessarily be loaded! That is configured in the main window of omo. + Перемещает esp в каталог с другими esp так, что он может быть подключен в главном окне. Обратите внимание, что ESP просто становится "доступным", но не будет загружен! Это настраивается в главном окне MO. @@ -2652,7 +2496,7 @@ p, li { white-space: pre-wrap; } 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. - Это моды который находятся в каталоге игры (виртуальном). Они могут быть включены в главном окне. + Это файлы модов которые находятся в (виртуальном)каталоге данных вашей игры и могут быть выбираемыми в списке esp, в главном окне. @@ -2703,7 +2547,7 @@ p, li { white-space: pre-wrap; } Primary Category - + Основная категория @@ -2722,29 +2566,29 @@ p, li { white-space: pre-wrap; } - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">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: </span><a href=" http://www.skyrimnexus.com/downloads/file.php?id=1334"><span style=" font-size:8pt; text-decoration: underline; color:#0000ff;">http://skyrim.nexusmods.com/downloads/file.php?id=1334</span></a><a href="http://www.skyrimnexus.com/downloads/file.php?id=1334"><span style=" font-size:8pt; color:#000000;">. In this example, 1334 is the id you're looking for. Besides: The above is the link to Mod Organizer on the Nexus. Why not go there now and endorse?</span></a></p></body></html> - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +</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;">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: </span><a href=" http://www.skyrimnexus.com/downloads/file.php?id=1334"><span style=" font-size:8pt; text-decoration: underline; color:#0000ff;">http://skyrim.nexusmods.com/downloads/file.php?id=1334</span></a><a href="http://www.skyrimnexus.com/downloads/file.php?id=1334"><span style=" font-size:8pt; color:#000000;">. In this example, 1334 is the id you're looking for. Besides: The above is the link to Mod Organizer on the Nexus. Why not go there now and endorse?</span></a></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">ID этого мода на Nexus. Заполняется автоматически, если скачали и установили мод МО. Иначе вы можете ввести его вручную. Чтобы найти правильный ID, нужно найти источник. URL будет выглядеть следующим образом: </span><a href=" http://www.skyrimnexus.com/downloads/file.php?id=1334"><span style=" font-size:8pt; text-decoration: underline; color:#0000ff;">http://skyrim.nexusmods.com/downloads/file.php?id=1334</span></a><a href="http://www.skyrimnexus.com/downloads/file.php?id=1334"><span style=" font-size:8pt; color:#000000;">. В этом примере, вы ищите ID 1334. Кроме того: выше есть ссылка на Mod Organizer на Nexus. Почему бы не пойти туда b yt ghjdthbnm?</span></a></p></body></html> +</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;">ID этого мода на Nexus. Заполняется автоматически, если скачали и установили мод из МО. В противном случае вы можете ввести его вручную. Чтобы найти правильный ID, нужно найти мод на Nexus. URL будет выглядеть следующим образом: </span><a href=" http://www.skyrimnexus.com/downloads/file.php?id=1334"><span style=" font-size:8pt; text-decoration: underline; color:#0000ff;">http://skyrim.nexusmods.com/downloads/file.php?id=1334</span></a><a href="http://www.skyrimnexus.com/downloads/file.php?id=1334"><span style=" font-size:8pt; color:#000000;">. В этом примере, 1334 - ID, который вы ищете. Кроме того: Выше есть ссылка на Mod Organizer на Nexus. Почему бы не перейти по ней и не одобрить?</span></a></p></body></html> - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">Installed Version of the Mod. The tooltip will contain the current version available on nexus. The installed version is only set if you installed the mod through MO.</span></p></body></html> - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +</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;">Installed Version of the Mod. The tooltip will contain the current version available on nexus. The installed version is only set if you installed the mod through MO.</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">Установленная версия мода. В подсказке будет содержаться текущая версия ссылка. Установленная версия устанавливается только если вы установили мод через МО</span></p></body></html> +</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;">Установленная версия мода. Подсказка будет содержать текущую версию, доступную на Nexus. Установленная версия установится только если вы установили мод через МО.</span></p></body></html> @@ -2754,12 +2598,12 @@ p, li { white-space: pre-wrap; } Refresh - + Обновить информацию Refresh all information from Nexus. - + Обновить всю информацию с Nexus @@ -2768,51 +2612,28 @@ p, li { white-space: pre-wrap; } - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p></body></html> - - - - Files - Файлы - - - List of files currently uploaded on nexus. Double click to download. - Список файлов загружаемых с Nexus. Двойной клик для загрузки - - - Type - Тип - - - Name - Имя - - - Size (kB) - Размер (KB) +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p></body></html> Endorse - + Одобрить Notes - - - - Endorsements are an important motivation for authors. Please don't forget to endorse mods you like. - Не забудте поблагодарить автора. - - - Have you endorsed this yet? - Поблагодарить? + Примечания @@ -2826,23 +2647,28 @@ p, li { white-space: pre-wrap; } - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">This is a modifiable directory view of the mod directory. You can move around files using drag &amp; drop and rename them (double click).</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;">Changes happen immediately on disc, so do</span><span style=" font-size:8pt; font-weight:600;"> be careful</span><span style=" font-size:8pt;">.</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">This is a modifiable directory view of the mod directory. You can move around files using drag &amp; drop and rename them (double click).</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;">Changes happen immediately on disc, so do</span><span style=" font-size:8pt; font-weight:600;"> be careful</span><span style=" font-size:8pt;">.</span></p></body></html> - +</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;">Это обзор модифицируемого каталога папки мода. Вы можете перемещать файлы, используя перетаскивание и переименовывать их двойным кликом.</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;">Изменения происходят непосредственно на диске, так что</span><span style=" font-size:8pt; font-weight:600;"> будьте осторожныl</span><span style=" font-size:8pt;">.</span></p></body></html> Previous - + Предыдущий Next - Вперед + Вперед @@ -2852,22 +2678,22 @@ p, li { white-space: pre-wrap; } &Delete - + &Удалить &Rename - + &Переименовать &Hide - + &Скрыть &Unhide - + &Показать @@ -2877,184 +2703,184 @@ p, li { white-space: pre-wrap; } &New Folder - + &Новая папка Save changes? - + Сохранить изменения? + + + + + Save changes to "%1"? + Сохранить изменения в "%1"? File Exists - + Файл уже существует A file with that name exists, please enter a new one - + Файл с таким именем уже существует, укажите другое failed to move file - + не удалось переместить файл - failed to create directory "optional" - + failed to create directory "optional" + не удалось создать папку "optional" Info requested, please wait - - - - - (description incomplete, please visit nexus) - - - - - Current Version: %1 - - - - - No update available - + Информация запрошена, пожалуйста, подождите Main - - - - - - Save changes to "%1"? - + Главное Update - + Обновление Optional - + Опционально Old - + Старые Misc - + Разное Unknown - + Неизвестно - - <a href="%1">Visit on Nexus</a> - + + Current Version: %1 + Текущая версия: %1 - - - Confirm - Подтвердить + + No update available + Нет доступных обновлений + + + + (description incomplete, please visit nexus) + (описание не завершено, смотрите на nexus) + + + + <a href="%1">Visit on Nexus</a> + <a href="%1">Перейти на Nexus</a> Failed to delete %1 - + Не удалось удалить %1 - Are sure you want to delete "%1"? - + + Confirm + Подтверждение + + + + Are sure you want to delete "%1"? + Вы уверены, что хотите удалить "%1"? Are sure you want to delete the selected files? - + Вы уверены, что хотите удалить выбранные файлы? New Folder - + Новая папка - Failed to create "%1" - + Failed to create "%1" + Не удалось создать "%1" Replace file? - + Заменить файл? There already is a hidden version of this file. Replace it? - + Скрытая версия этого файла уже существует. Заменить? File operation failed - + Не удалась операция с файлом - Failed to remove "%1". Maybe you lack the required file permissions? - + Failed to remove "%1". Maybe you lack the required file permissions? + Не удалось удалить "%1". Может быть, вам не хватает необходимых прав доступа к файлу? failed to rename %1 to %2 - + не удалось переименовать %1 в %2 There already is a visible version of this file. Replace it? - + Видимая версия этого файла уже существует. Заменить? Un-Hide - + Показать Hide - + Скрыть ModInfoOverwrite - - - Overwrite - - This pseudo mod contains files from the virtual data tree that got modified (i.e. by the construction kit) - + Этот псевдо-мод содержит файлы из виртуального древа данных, которые были изменены (в Construction Kit и других программах) + + + + Overwrite + Замена @@ -3062,180 +2888,176 @@ p, li { white-space: pre-wrap; } failed to write %1/meta.ini: %2 - + не удалось записать %1/meta.ini: %2 %1 contains no esp/esm and no asset (textures, meshes, interface, ...) directory - + %1 не содержит ни esp/esm, ни папок ресурсов (textures, meshes, interface, ...) Categories: <br> - + Категории: <br> ModList - - - Confirm - Подтвердить - Overwrite - + Замена This entry contains files that have been created inside the virtual data tree (i.e. by the construction kit) - + Эта запись включает файлы, которые были созданы внутри виртуального древа (с помощью Construction Kit и др. программ) Backup - + Резервная копия No valid game data - + Неверные игровые данные Not endorsed yet - + Еще не одобрено Overwrites files - + Заменяет файлы Overwritten files - + Замененные файлы Overwrites & Overwritten - + Заменяет и заменяется Redundant - - - - - Category of the mod. - - - - - Id of the mod as used on Nexus. - - - - - Emblemes to highlight things that might require attention. - + Избыточные - - Categories: <br> - + + invalid + неверные installed version: %1, newest version: %2 - - - - Name - Имя - - - - Version - Версия - - - - Version of the mod (if available) - + установленная версия: %1, новейшая версия: %2 - - Priority - - - - - invalid - + + Categories: <br> + Категории: <br> Invalid name - + Недопустимое имя drag&drop failed: %1 - + перетаскивание не удалось: %1 + + + + Confirm + Подтверждение + + + + Are you sure you want to remove "%1"? + Вы действительно хотите удалить "%1"? Flags - + Флаги Mod Name - + Имя мода + + + + Version + Версия + + + + Priority + Приоритет Category - + Категория Nexus ID - + Nexus ID Installation - + Установка unknown - + неизвестный Name of your mods - + Имя ваших модов + + + + Version of the mod (if available) + Версия мода (если доступно) - Installation priority of your mod. The higher, the more "important" it is and thus overwrites files from mods with lower priority. - + Installation priority of your mod. The higher, the more "important" it is and thus overwrites files from mods with lower priority. + Приоритет установки для ваших модов. Файлы модов с большим приоритетом перезапишут файлы модов с меньшим приоритетом. - - Time this mod was installed - + + Category of the mod. + Категория мода. - - Are you sure you want to remove "%1"? - + + Id of the mod as used on Nexus. + ID мода, используемый на Nexus. + + + + Emblemes to highlight things that might require attention. + Выделяет подсветкой вещи, которые могут потребовать внимания. + + + + Time this mod was installed + Время, когда мод был установлен. @@ -3243,12 +3065,12 @@ p, li { white-space: pre-wrap; } Message of the Day - + Сообщение дня OK - + OK @@ -3256,12 +3078,12 @@ p, li { white-space: pre-wrap; } Overwrites - + Заменяет not implemented - + не реализовано @@ -3269,37 +3091,30 @@ p, li { white-space: pre-wrap; } timeout - + задержка Please check your password - - - - - NexusDialog - - Mod ID - ID мода + Проверьте ваш пароль NexusInterface - Failed to guess mod id for "%1", please pick the correct one - + Failed to guess mod id for "%1", please pick the correct one + Не удалось опознать id мода "%1", пожалуйста, выберете правильный empty response - + пустой ответ invalid response - + неверный ответ @@ -3307,22 +3122,22 @@ p, li { white-space: pre-wrap; } Overwrite - + Замена You can use drag&drop to move files and directories to regular mods. - + Вы можете использовать перетаскивание, для перемещения папок и файлов в распакованные моды. &Delete - + &Удалить &Rename - + &Переименовать @@ -3332,130 +3147,114 @@ p, li { white-space: pre-wrap; } &New Folder - + &Новая папка - Failed to delete "%1" - + Failed to delete "%1" + Не удалось удалить "%1" Confirm - Подтвердить + Подтверждение - Are sure you want to delete "%1"? - + Are sure you want to delete "%1"? + Вы уверены, что хотите удалить "%1"? Are sure you want to delete the selected files? - + Вы действительно хотите удалить выбранные файлы? New Folder - + Новая папка - Failed to create "%1" - + Failed to create "%1" + Не удалось создать "%1" PluginList - + + Name + Имя + + + + Priority + Приоритет + + + Mod Index - + Индекс мода - - + + unknown - + неизвестно - + Name of your mods - + Имена ваших модов - - Load priority of your mod. The higher, the more "important" it is and thus overwrites data from plugins with lower priority. - + + Load priority of your mod. The higher, the more "important" it is and thus overwrites data from plugins with lower priority. + Приоритет загрузки ваших модов. Моды с большим приоритетом перезапишут данные модов с меньшим приоритетом. - + The modindex determins the formids of objects originating from this mods. - + Индекс мода определяющий id форм объектов, происходящих из этих модов. - + esp not found: %1 - + esp не найден: %1 - - - Confirm - Подтвердить - - - - Really enable all plugins? - - - - - Really disable all plugins? - - - - + The file containing locked plugin indices is broken - + Файл, содержащий индексы заблокированного плагина, не работает. - + failed to open output file: %1 - + не удалось открыть выходной файл: %1 Some of your plugins have invalid names! These plugins can not be loaded by the game. Please see mo_interface.log for a list of affected plugins and rename them. - - - - - failed to restore load order for %1 - + Некоторые из ваших плагинов имеют неверные имена. Эти плагины не могут быть загружены игрой. Смотрите mo_interface.log для получения списка таких плагинов и переименуйте их. - This plugin can't be disabled (enforced by the game) - + This plugin can't be disabled (enforced by the game) + Этот плагин не может быть отключен (грузится игрой принудительно) Origin: %1 - + Источник: %1 - - Name - Имя - - - - Priority - + + failed to restore load order for %1 + не удалось восстановить порядок загрузки для %1 @@ -3463,31 +3262,35 @@ p, li { white-space: pre-wrap; } Problems - + Проблемы - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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:7.8pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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:7.8pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p></body></html> - +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:7.8pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p></body></html> fix - + исправить Fix - + Исправить No guided fix - + Не управляемое исправление @@ -3495,27 +3298,27 @@ p, li { white-space: pre-wrap; } invalid profile name %1 - + неверное имя профиля %1 failed to create %1 - + не удалось создать %1 - failed to open "%1" for writing - + failed to open "%1" for writing + не удалось открыть "%1" для записи failed to update tweaked ini file, wrong settings may be used: %1 - + не удалось обновить настроенный ini-файл, вероятно используются ошибочные настройки: %1 failed to create tweaked ini: %1 - + не удалось создать настроенный ini: %1 @@ -3524,43 +3327,43 @@ p, li { white-space: pre-wrap; } invalid index %1 - Неверный индекс %1 + неверный индекс %1 - Overwrite directory couldn't be parsed - + Overwrite directory couldn't be parsed + Замена каталога не может быть обработана invalid priority %1 - + неверный приоритет %1 failed to parse ini file (%1) - + не удалось обработать ini файл (%1) failed to parse ini file (%1): %2 - + не удалось обработать ini файл (%1): %2 - failed to modify "%1" - + failed to modify "%1" + не удалось изменить "%1" - + Delete savegames? - + Удалить сохранения? - - Do you want to delete local savegames? (If you select "No", the save games will show up again if you re-enable local savegames) - + + Do you want to delete local savegames? (If you select "No", the save games will show up again if you re-enable local savegames) + Вы хотите удалить локальные сохранения? (При отрицательном выборе сохранения отобразятся снова, если повторно включить локальные сохранения) @@ -3568,27 +3371,27 @@ p, li { white-space: pre-wrap; } Dialog - + Диалог Please enter a name for the new profile - + Введите имя нового профиля If checked, the new profile will use the default game settings. - + Если отмечено, новый профиль будет использовать настройки игры по умолчанию. - If checked, the new profile will use the default game settings instead of the "global" settings. Global settings are the settings you configure when running the game launcher directly, without MO. - + If checked, the new profile will use the default game settings instead of the "global" settings. Global settings are the settings you configure when running the game launcher directly, without MO. + Если отмечено, новый профиль будет использовать настройки игры по умолчанию, вместо общих настроек. Общие настройки, это настройки, которые вы установили, когда запустили лаунчер игры напрямую, без MO. Default Game Settings - + Настройки игры по умолчанию @@ -3596,109 +3399,122 @@ p, li { white-space: pre-wrap; } Profiles - + Профили List of Profiles - + Список профилей - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">This is the list of profiles. Each Profile contains its own list and installation order of enabled mods (from a shared pool), a configuration of enabled esps/esms, a copy of the games ini-file and an optional savegame filter.</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></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-weight:600;">Note</span> For technical reasons it's currently not possible to have seperate load-orders for esps. This means you can't load moda.esp before modb.esp in one profile and the other way around in another.</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">This is the list of profiles. Each Profile contains its own list and installation order of enabled mods (from a shared pool), a configuration of enabled esps/esms, a copy of the games ini-file and an optional savegame filter.</p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></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-weight:600;">Note</span> For technical reasons it's currently not possible to have seperate load-orders for esps. This means you can't load moda.esp before modb.esp in one profile and the other way around in another.</p></body></html> - +</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;">Это список профилей. Каждый профиль содержит свой собственный список и порядок установки подключенных модов (из общего пула), настройки подключенных esps/esms, копии игровых ini-файлов и опциональный фильтр сохранений.</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></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-weight:600;">Примечание</span> По техническим причинам невозможно иметь отдельные порядки загрузки для esp. Это означает, что вы не сможете загрузить moda.esp пере modb.esp в одном профиле и иным образом в другом профиле.</p></body></html> If checked, savegames are local to this profile and will not appear when starting with a different profile. - + Если отмечено, сохранения будут локальными для этого профиля и не будут отображены для других профилей. Local Savegames - + Локальные сохранения This ensures data files from mods are actually used. You want to enable this unless you use a different tool for Archive Invalidation. - + Это гарантирует использование файлов данных из модов. Вам нужно включить это, если вы не используете других инструментов для инвалидации. - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">The games Oblivion, Fallout 3 and Fallout NV contain a bug which prevents texture and mesh replacers (that is: all modifications to meshes and textures already in game) from working.</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;">The Mod Organizer uses a workaround called &quot;BSA redirection&quot; (google is your friend) to fix this issue reliably and without further work. Simply activate and forget.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></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;">With Skyrim this bug seems to be fixed to a degree but whether a mod becomes active still depends on file dates. Therefore, it still makes sense to activate this.</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">The games Oblivion, Fallout 3 and Fallout NV contain a bug which prevents texture and mesh replacers (that is: all modifications to meshes and textures already in game) from working.</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;">The Mod Organizer uses a workaround called &quot;BSA redirection&quot; (google is your friend) to fix this issue reliably and without further work. Simply activate and forget.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></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;">With Skyrim this bug seems to be fixed to a degree but whether a mod becomes active still depends on file dates. Therefore, it still makes sense to activate this.</span></p></body></html> - +</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;">Игры Oblivion, Fallout 3 и Fallout NV содержат баг, который делает неработоспособными текстуры и модели реплейсеров (то есть: все изменения моделей и текстур в игре).</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;">Mod Organizer использует способ обхода, называемый &quot;BSA redirection&quot; (google в помощь), чтобы решить эту проблему надежно и без дальнейшей возни. Просто подключить и забыть.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></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;">В Скайрим, кажется, этот баг исправлен в известной степени, но будет ли мод активным, зависит по прежнему от даты модификации файлов. Поэтому всё ещё есть смысл включить это.</span></p></body></html> Automatic Archive Invalidation - + Автоматическая инвалидадция Create a new profile from scratch - + Создать новый профиль «с нуля» Create - + Создать Clone the selected profile - + Клонировать выбранный профиль This creates a new profile with the same settings and active mods as the selected one. - + Это создаст новый профиль с такими же настройками и активными модами, как у выбранного. Copy - + Копировать Delete the selected Profile. This can not be un-done! - + Удалить выбранный профиль. Это нельзя будет отменить! Remove - + Удалить Rename - + Переименовать Transfer save games to the selected profile. - + Передать сохранения в выбранный профиль. Transfer Saves - + Передать сохранения @@ -3707,14 +3523,14 @@ p, li { white-space: pre-wrap; } - Archive invalidation isn't required for this game. - + Archive invalidation isn't required for this game. + Инвалидация не требуется для этой игры. failed to create profile: %1 - + не удалось создать профиль: %1 @@ -3724,42 +3540,42 @@ p, li { white-space: pre-wrap; } Please enter a name for the new profile - + Введите имя нового профиля failed to copy profile: %1 - + не удалось скопировать профиль: %1 Confirm - Подтвердить + Подтверждение Are you sure you want to remove this profile? - + Вы действительно хотите удалить этот профиль? Rename Profile - + Переименовать профиль New Name - + Новое имя failed to change archive invalidation state: %1 - + не удалось изменить режим инвалидации: %1 failed to determine if invalidation is active: %1 - + не удалось определить активность инвалидации: %1 @@ -3767,7 +3583,7 @@ p, li { white-space: pre-wrap; } Failed to save custom categories - + Не удалось сохранить пользовательские категории @@ -3775,301 +3591,311 @@ p, li { white-space: pre-wrap; } invalid index %1 - Неверный индекс %1 + неверный индекс %1 invalid category id %1 - + неверный id категории %1 + + + + invalid field name "%1" + неверное имя поля "%1" + + + + invalid type for "%1" (should be integer) + неверный тип для "%1" (должно быть целое) + + + + invalid type for "%1" (should be string) + неверный тип для "%1" (должна быть строка) + + + + invalid type for "%1" (should be float) + неверный тип для "%1" (должно быть с плавающей запятой) + + + + no fields set up yet! + установленных полей ещё нет! + + + + field not set "%1" + поле не установлено "%1" + + + + invalid character in field "%1" + неверный символ в поле "%1" + + + + empty field name + пустое имя поля + + + + invalid game type %1 + неверный тип игры %1 helper failed - + сбой помощника failed to determine account name - + не удалось определить имя аккаунта invalid 7-zip32.dll: %1 - + неверный 7-zip32.dll: %1 failed to open %1: %2 - + не удалось открыть %1: %2 %1 not found - + %1 не найден Failed to delete %1 - + Не удалось удалить %1 Failed to deactivate script extender loading - + Не удалось отключить загрузку расширителя скриптов Failed to remove %1: %2 - + Не удалось удалить %1: %2 Failed to rename %1 to %2 - + Не удалось переименовать %1 в %2 Failed to deactivate proxy-dll loading - + Не удалось отключить загрузку proxy-dll Failed to copy %1 to %2 - + Не удалось скопировать %1 в %2 Failed to set up script extender loading - + Не удалось установить загрузку расширителя скриптов Failed to delete old proxy-dll %1 - + Не удалось удалить старый proxy-dll %1 Failed to overwrite %1 - + Не удалось заменить %1 Failed to set up proxy-dll loading - - - - - "%1" is missing - + Не удалось установить загрузку proxy-dll Permissions required - + Требуются права доступа + + + + The current user account doesn't have the required access rights to run Mod Organizer. The neccessary changes can be made automatically (the MO directory will be made writable for the current user account). You will be asked to run "helper.exe" with administrative rights). + Текущий аккаунт пользователя не имеет необходимых прав для запуска Mod Organizer. Необходимые изменения могут быть сделаны автоматически (каталог MO будет установлен записываемым для текущего аккаунта пользователя). Вам будет предложено запустить "helper.exe" с правами администратора. Woops - - - - - The current user account doesn't have the required access rights to run Mod Organizer. The neccessary changes can be made automatically (the MO directory will be made writable for the current user account). You will be asked to run "helper.exe" with administrative rights). - + Упс ModOrganizer has crashed! Should a diagnostic file be created? If you send me this file (%1) to sherb@gmx.net, the bug is a lot more likely to be fixed. Please include a short description of what you were doing when the crash happened - + Mod Organizer вышел из строя! Нужно ли создать диагностический файл? Если вы вышлите файл (%1) по адресу sherb@gmx.net, ошибка с намного большей вероятностью будет исправлена. Пожалуйста, добавьте краткое описание своих действий, перед тем, как произошла ошибка ModOrganizer has crashed! Unfortunately I was not able to write a diagnostic file: %1 - + ModOrganizer вышел из строя! К сожалению не удалось записать диагностический файл: %1 - + Mod Organizer - + Mod Organizer An instance of Mod Organizer is already running - + Другой экземпляр Mod Organizer уже запущен - No game identified in "%1". The directory is required to contain the game binary and its launcher. - + No game identified in "%1". The directory is required to contain the game binary and its launcher. + Игра не обнаружена в "%1". Требуется, чтобы папка содержала исполняемые файлы игры. Please select the game to manage - + Выберете игру для управления - - Please use "Help" from the toolbar to get usage instructions to all elements - + + Please use "Help" from the toolbar to get usage instructions to all elements + Используйте пункт "Справка" на панели инструментов, чтобы получить инструкции по использованию всех элементов. - - + + <Manage...> - + <Управлять...> - + failed to parse profile %1: %2 - + не удалось обработать профиль %1: %2 - + - failed to find "%1" - + failed to find "%1" + не удалось найти "%1" + + + + encoding error, please report this as a bug and include the file mo_interface.log! + ошибка кодирования, пожалуйста сообщите об этом баге, включив файл mo_interface.log! failed to access %1 - + не удалось получить доступ к %1 failed to set file time %1 - + не удалось изменить дату модификации для %1 failed to create %1 - + не удалось создать %1 + + + + "%1" is missing + "%1" отсутствует Before you can use ModOrganizer, you need to create at least one profile. ATTENTION: Run the game at least once before creating a profile! - + Перед тем, как использовать Mod Organizer, вам нужно создать хотя бы один профиль. ВНИМАНИЕ: Перед созданием профиля запустите игру хотя бы один раз! Error - + Ошибка wrong file format - + неверный формат файла failed to open %1 - + не удалось открыть %1 - + Script Extender - + Script Extender - + Proxy DLL - + Proxy DLL - failed to spawn "%1" - + failed to spawn "%1" + не удалось вызвать "%1" Elevation required - + Требуется повышение прав This process requires elevation to run. This is a potential security risk so I highly advice you to investigate if -"%1" +"%1" can be installed to work without elevation. Start elevated anyway? (you will be asked if you want to allow ModOrganizer.exe to make changes to the system) - + Этот процесс требует повышения прав на запуск. +Это потенциальный риск для безопасности, поэтому настоятельно рекомендуется изучить +"%1" + на возможность установки без повышения прав. + +Запустить с повышенными правами в любом случае? (будет выведен запрос о разрешении ModOrganizer.exe сделать изменения в системе) - failed to spawn "%1": %2 - + failed to spawn "%1": %2 + не удалось вызвать "%1": %2 - "%1" doesn't exist - + "%1" doesn't exist + "%1" не существует - failed to inject dll into "%1": %2 - + failed to inject dll into "%1": %2 + не удалось подключить dll к "%1": %2 - failed to run "%1" - - - - - invalid field name "%1" - - - - - invalid type for "%1" (should be integer) - - - - - invalid type for "%1" (should be string) - - - - - invalid type for "%1" (should be float) - - - - - no fields set up yet! - - - - - field not set "%1" - - - - - invalid character in field "%1" - - - - - empty field name - - - - - invalid game type %1 - + failed to run "%1" + не удалось запустить "%1" @@ -4077,22 +3903,22 @@ Start elevated anyway? (you will be asked if you want to allow ModOrganizer.exe Mod Exists - + Мод существует This mod seems to be installed already. Do you want to add files from this archive (overwriting existing ones) or do you want to completely replace the existing files (old files are deleted)? Alternatively you can install this mod under a different name. - + Кажется, что этот мод уже установлен. Вы хотите добавить файлы из архива (с перезаписью уже существующих) или вам нужно полностью заменить существующие файлы (старые будут удалены)? Как вариант, вы можете установить этот мод под другим именем. Keep Backup - + Оставить резервную копию Merge - + Объединить @@ -4102,7 +3928,7 @@ Start elevated anyway? (you will be asked if you want to allow ModOrganizer.exe Rename - + Переименовать @@ -4115,7 +3941,7 @@ Start elevated anyway? (you will be asked if you want to allow ModOrganizer.exe Remember selection - + Запомнить выбор @@ -4123,27 +3949,27 @@ Start elevated anyway? (you will be asked if you want to allow ModOrganizer.exe Save # - + Сохранение № Character - + Персонаж Level - + Уровень Location - + Местоположение Date - + Дата @@ -4151,7 +3977,7 @@ Start elevated anyway? (you will be asked if you want to allow ModOrganizer.exe Missing ESPs - + Отсутствующие ESP @@ -4159,17 +3985,17 @@ Start elevated anyway? (you will be asked if you want to allow ModOrganizer.exe Dialog - + Диалог Copy To Clipboard - + Копировать в буфер обмена Save As... - + Сохранить как... @@ -4179,17 +4005,17 @@ Start elevated anyway? (you will be asked if you want to allow ModOrganizer.exe Save CSV - + Сохранить CSV Text Files - + Текстовые файлы - failed to open "%1" for writing - + failed to open "%1" for writing + не удалось открыть "%1" для записи @@ -4197,7 +4023,7 @@ Start elevated anyway? (you will be asked if you want to allow ModOrganizer.exe Select - + Выбрать @@ -4214,8 +4040,8 @@ Start elevated anyway? (you will be asked if you want to allow ModOrganizer.exe SelfUpdater - archive.dll not loaded: "%1" - + archive.dll not loaded: "%1" + archive.dll не загружен: "%1" @@ -4223,95 +4049,95 @@ Start elevated anyway? (you will be asked if you want to allow ModOrganizer.exe Update - + Обновление An update is available (newest version: %1), do you want to install it? - + Доступно обновление (последняя версия: %1). Вы хотите установить его? Download in progress - + Загрузка в процессе Download failed: %1 - + Загрузка не удалась: %1 Failed to install update: %1 - + Не удалось установить обновление: %1 - failed to open archive "%1": %2 - Не удалось открыть архив "%1": %2 + failed to open archive "%1": %2 + не удалось открыть архив "%1": %2 failed to move outdated files: %1. Please update manually. - + не удалось переместить устаревшие файлы: %1. Пожалуйста, обновите вручную. Update installed, Mod Organizer will now be restarted. - + Обновление установлено, Mod Organizer будет перезапущен. Error - + Ошибка Failed to parse response. Please report this as a bug and include the file mo_interface.log. - + Не удалось обработать запрос. Пожалуйста, сообщите об этом баге, включив в сообщение файл mo_interface.log. No incremental update available for this version, the complete package needs to be downloaded (%1 kB) - + Нет дополнительных обновлений для этой версии, необходимо загрузить полный пакет (%1 kB) no file for update found. Please update manually. - - - - - No download server available. Please try again later. - Сервер недоступен. Попробуйте позже. + не найдено файла для обновления. Пожалуйста, обновите вручную. Failed to retrieve update information: %1 - + Не удалось получить сведения об обновлении: %1 + + + + No download server available. Please try again later. + Нет доступных для загрузки серверов. Пожалуйста, попробуйте позже. Settings - - setting for invalid plugin "%1" requested - + + setting for invalid plugin "%1" requested + запрошена настройка для недействительного плагина "%1" - - invalid setting "%1" requested for plugin "%2" - + + invalid setting "%1" requested for plugin "%2" + неверная настройка "%1" запрошена для плагина "%2" - + Confirm - Подтвердить + Подтверждение - + Changing the mod directory affects all your profiles! Mods not present (or named differently) in the new location will be disabled in all profiles. There is no way to undo this unless you backed up your profiles manually. Proceed? - + Изменение каталога для модов отразится на всех ваших профилях. Нельзя будет отменить это, если только вы не сохранили резервные копии ваших профилей вручную. Продолжить? @@ -4319,169 +4145,178 @@ Start elevated anyway? (you will be asked if you want to allow ModOrganizer.exe Settings - + Настройки General - + Общие Language - + Язык The display language - + Используемый язык - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">The display language. This will only displaye languages for which you have a translation installed.</span></p></body></html> - +</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;">The display language. This will only displaye languages for which you have a translation installed.</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">Используемый язык. Будут отображены языки, локализация на которые имеется.</span></p></body></html> Style - + Стиль graphical style - + графический стиль graphical style of the MO user interface - + графический стиль пользовательского интерфейса MO Log Level - + Уровень журналирования - Decides the amount of data printed to "ModOrganizer.log" - + Decides the amount of data printed to "ModOrganizer.log" + Определяет количество данных, выводимых в "ModOrganizer.log" - 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. - + 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. + Определяет количество данных, выводимых в "ModOrganizer.log". +"Отладка" позволяет получить очень полезную для поиска проблем информацию. Влияния на производительность не замечено, однако размер лога может быть довольно большим. Если это проблема, то вы можете предпочесть для обычного использования уровень "Информация". На уровне "Ошибка" лог обычно остается пустым. Debug - + Отладка Info - + Информация Error - + Ошибка Advanced - + Продвинутый Directory where downloads are stored. - + Каталог, в котором хранятся загрузки. Mod Directory - + Каталог модов Directory where mods are stored. - + Каталог, в котором хранятся моды. - Directory where mods are stored. Please note that changing this will break all associations of profiles with mods that don't exist in the new location (with the same name). - + Directory where mods are stored. Please note that changing this will break all associations of profiles with mods that don't exist in the new location (with the same name). + Каталог, в котором хранятся моды. Имейте ввиду, эти изменения нарушат все ассоциации профилей с несуществующими в новом расположении модами (с тем же именем). Download Directory - + Каталог для загрузки Cache Directory - + Каталог кэша Reset stored information from dialogs. - + Сброс хранимой информации о диалогах. - This will make all dialogs show up again where you checked the "Remember selection"-box. - + This will make all dialogs show up again where you checked the "Remember selection"-box. + Заставит снова появиться все диалоги, в которых вы ранее отмечали флажок "Запомнить выбор". Reset Dialogs - + Сбросить диалоги Modify the categories available to arrange your mods. - + Изменение категорий, доступных для упорядочивания ваших модов. Configure Mod Categories - + Настроить категории модов Nexus - + Nexus Allows automatic log-in when the Nexus-Page for the game is clicked. - + Позволяет автоматически входить, кликнув на Nexus-страницу игры. - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">Allows automatic log-in when the Nexus-Page for the game is clicked. Please note that the obfuscation with which the password is stored in modorganizer.ini is not very strong. If you're worried someone might steal your password, don't store it here.</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">Allows automatic log-in when the Nexus-Page for the game is clicked. Please note that the obfuscation with which the password is stored in modorganizer.ini is not very strong. If you're worried someone might steal your password, don't store it here.</span></p></body></html> - +</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;">Позволяет автоматически входить, кликнув на Nexus-страницу игры. Обратите внимание, что шифрование с которым пароль хранится в файле modorganizer.ini не очень сильное. Если вы беспокоитесь, что кто-нибудь может украсть ваш пароль, не храните его здесь.</span></p></body></html> If checked and if correct credentials are entered below, log-in to Nexus (for browsing and downloading) is automatic. - + Если отмечено и данные ниже введены правильно, входит на Nexus (для просмотра и загрузки) автоматически. Automatically Log-In to Nexus - + Автоматический вход на Nexus @@ -4493,220 +4328,244 @@ p, li { white-space: pre-wrap; } Password Пароль + + + Disable automatic internet features + Отключить автоматические возможности интернет + + + + Disable automatic internet features. This does not affect features that are explicitly invoked by the user (like checking mods for updates, endorsing, opening the web browser) + Отключает автоматические возможности интернет. Это не подействует на функции, которые явно вызваны пользователем (проверка модов на обновления, одобрение, открытие в браузере) + + + + Offline Mode + Автономный режим + + + + Use a proxy for network connections. + Использовать прокси для соединения с сетью + + + + Use a proxy for network connections. This uses the system-wide settings which can be configured in Internet Explorer. Please note that MO will start up a few seconds slower on some systems when using a proxy. + Использовать прокси для соединения с сетью. Используются системные параметры, настраиваемые в Internet Explorer. Обратите внимание, что MO запустится на несколько секунд медленнее на некоторых системах, когда используется прокси. + + + + Use HTTP Proxy (Uses System Settings) + Использовать HTTP Proxy (Используются системные настройки) + + + + Known Servers (Dynamically updated every download) + Известные серверы (Динамически обновляется при каждой загрузке) + + + + Preferred Servers (Drag & Drop) + Предпочитаемые серверы (Используйте перетаскивание) + Plugins - + Плагины Author: - + Автор: Version: - + Версия: Description: - + Описание: Key - + Клавиша Value - + Значение Workarounds - + Способы обхода Steam App ID - + ID приложения Steam The Steam AppID for your game - + ID в Steam для вашей игры - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">The Steam App ID is required to directly start some games. For Skyrim, if this is not set or wrong, the &quot;Mod Organizer&quot; load mechanism may not work properly.</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;">The preset for this is the App ID of the &quot;regular&quot; version so in most cases, you should be set.</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;">If you think you have a different version (GotY or something), follow these steps to get to the id:</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;">1. Navigate to the game library in steam</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;">2. right-click on the game you need the id for and choose </span><span style=" font-size:8pt; font-weight:600;">Create desktop shortcut</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;">3. right-click on the newly created shortcut on your desktop and select </span><span style=" font-size:8pt; font-weight:600;">Properties</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;">4. in the URL-field you should see something like this: </span><span style=" font-size:8pt; font-style:italic;">steam://rungameid/22380</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;">22380 is the id you're looking for.</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<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;">The Steam App ID is required to directly start some games. For Skyrim, if this is not set or wrong, the &quot;Mod Organizer&quot; load mechanism may not work properly.</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;">The preset for this is the App ID of the &quot;regular&quot; version so in most cases, you should be set.</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;">If you think you have a different version (GotY or something), follow these steps to get to the id:</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;">1. Navigate to the game library in steam</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;">2. right-click on the game you need the id for and choose </span><span style=" font-size:8pt; font-weight:600;">Create desktop shortcut</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;">3. right-click on the newly created shortcut on your desktop and select </span><span style=" font-size:8pt; font-weight:600;">Properties</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;">4. in the URL-field you should see something like this: </span><span style=" font-size:8pt; font-style:italic;">steam://rungameid/22380</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;">22380 is the id you're looking for.</span></p></body></html> - +</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;">ID приложения в Steam необходим для прямого запуска некоторых игр. Для Skyrim, если он не установлен или неверен, механизм загрузки &quot;Mod Organizer&quot; может работать неправильно.</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;">Предустановленный ID в большинстве случаев должен быть установлен.</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;">Если вы думаете, что у вас другая версия (GotY или другое), следуйте следующей инструкции по установке id:</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;">1. Перейдите в библиотеку игр Steam.</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;">2. Сделайте правый клик по игре, id которой нужен и выберете </span><span style=" font-size:8pt; font-weight:600;">Создать ярлык на рабочем столе</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;">3. Сделайте правый клик на созданном на рабочем столе ярлыке и выберете </span><span style=" font-size:8pt; font-weight:600;">Свойства</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;">4. в поле URL вы должны увидеть что-то вроде: </span><span style=" font-size:8pt; font-style:italic;">steam://rungameid/22380</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;">22380 это и есть id, который вам нужен.</span></p></body></html> Load Mechanism - + Механизм загрузки Select loading mechanism. See help for details. - + Выберете механизм загрузки. Смотрите справку для подробностей. + + + + Mod Organizer needs a dll to be injected into the game so all mods are visible to it. +There are several means to do this: +*Mod Organizer* (default) In this mode the Mod Organizer itself injects the dll. The disadvantage is that you always have to start the game through MO or a link created by it. +*Script Extender* In this mode, MO is installed as a Script Extender (obse, fose, nvse, skse) plugin. +*Proxy DLL* In this mode, MO replaces one of the game's dlls with one that loads MO (and the original dll of course). This will ONLY work with Steam games and it has only been tested with Skyrim. Please use this only if the other mechanisms don't work. + +If you use the Steam version of Oblivion the default will NOT work. In this case, please install obse and use "Script Extender" as the load mechanism. Also you can then not start Oblivion from MO. Instead, use MO only to set up your mods, then quit and start Oblivion through Steam. + Mod Organizer необходимо подключить dll к игре, чтобы все моды были видны в ней. +Есть несколько способов сделать это: +*Mod Organizer* (по умолчанию) В этом режиме Mod Organizer сам подключает dll. Недостатком этого является то, что вам необходимо всегда начинать игру через MO или созданный им ярлык. +*Script Extender* В этом режиме, MO установлен как плагин Script Extender (obse, fose, nvse, skse). +*Proxy DLL* В этом режиме MO заменяет одну из игровых dll игры своей, которая загружает MO и оригинальную игру. Это работает только с играми Steam и тестировалось только на Skyrim. Используйте этот способ только если другие не работают. + +Если вы используете Steam-версию Oblivion , способ по умолчанию не работает. В этом случае установите obse и используйте "Script Extender" как механизм загрузки. Также после этого вы не сможете запустить Oblivion из MO, вместо этого используйте MO только для настройки модов и запускайте игру через Steam. NMM Version - + Версия NMM The Version of Nexus Mod Manager to impersonate. - + Версия Nexus Mod Manager для представления. Mod Organizer uses an API provided by the Nexus to provide features like checking for updates and downloading files. Unfortunately this API has not been made available officially to third party tools like MO so we have to impersonate the Nexus Mod Manager to be allowed in. -On top of this Nexus has used the client identification to lock out outdated versions of NMM to force users to update. This means that MO also needs to impersonate the new version of NMM even if MO doesn't need an update. Therefore you can configure the version to identify as here. -Please note that MO does identify itself as MO to the webserver, it's not lying about what it is. It is merely adding a "compatible" NMM version to the user agent. +On top of this Nexus has used the client identification to lock out outdated versions of NMM to force users to update. This means that MO also needs to impersonate the new version of NMM even if MO doesn't need an update. Therefore you can configure the version to identify as here. +Please note that MO does identify itself as MO to the webserver, it's not lying about what it is. It is merely adding a "compatible" NMM version to the user agent. -tl;dr-version: If Nexus-features don't work, insert the current version number of NMM here and try again. - - - - - These are workarounds for problems with Mod Organizer. Please make sure you read the help text before changing anything here. - +tl;dr-version: If Nexus-features don't work, insert the current version number of NMM here and try again. + Mod Organizer использует API Nexus , для предоставления таких возможностей, как проверка обновлений и загрузка файлов. К сожалению этот API не был сделан официально доступным прочим утилитам, вроде MO, так что нужно представляться как Nexus Mod Manager, чтобы получить доступ. +Помимо этого Nexus использует идентификатор версий, чтобы блокировать устаревшии версии NMM и принудительно заставить пользователей обновиться. Это значит, что MO также нужно представляться последней версией NMM, даже если MO не нуждается в обновлении. Поэтому вы можете настроить здесь также и версию для идентификации. +Обратите внимание, что MO идентифицирует себя вебсерверу как MO, он не подделывает данные о себе. Он всего лишь добавляется как "совместимая" с NMM версия, в поле user agent. + +tl;dr-версия: Если возможности Nexus не работают, вставьте здесь текущую версию NMM и повторите попытку. Enforces that inactive ESPs and ESMs are never loaded. - - - - - Disable automatic internet features - - - - - Disable automatic internet features. This does not affect features that are explicitly invoked by the user (like checking mods for updates, endorsing, opening the web browser) - - - - - Offline Mode - - - - - Use a proxy for network connections. - - - - - Use a proxy for network connections. This uses the system-wide settings which can be configured in Internet Explorer. Please note that MO will start up a few seconds slower on some systems when using a proxy. - - - - - Use HTTP Proxy (Uses System Settings) - - - - - Known Servers (Dynamically updated every download) - - - - - Preferred Servers (Drag & Drop) - - - - - Mod Organizer needs a dll to be injected into the game so all mods are visible to it. -There are several means to do this: -*Mod Organizer* (default) In this mode the Mod Organizer itself injects the dll. The disadvantage is that you always have to start the game through MO or a link created by it. -*Script Extender* In this mode, MO is installed as a Script Extender (obse, fose, nvse, skse) plugin. -*Proxy DLL* In this mode, MO replaces one of the game's dlls with one that loads MO (and the original dll of course). This will ONLY work with Steam games and it has only been tested with Skyrim. Please use this only if the other mechanisms don't work. - -If you use the Steam version of Oblivion the default will NOT work. In this case, please install obse and use "Script Extender" as the load mechanism. Also you can then not start Oblivion from MO. Instead, use MO only to set up your mods, then quit and start Oblivion through Steam. - + Обеспечивает то, что неактивные ESP и ESM не будут загружены. - It seems that the Games occasionally load ESP or ESM files even if they haven't been activated as plugins. -I don't yet know what the circumstances are, but user reports imply it is in some cases unwanted. If this is checked, ESPs and ESMs not checked in the List are invisible to the game and can not be loaded. - + It seems that the Games occasionally load ESP or ESM files even if they haven't been activated as plugins. +I don't yet know what the circumstances are, but user reports imply it is in some cases unwanted. If this is checked, ESPs and ESMs not checked in the List are invisible to the game and can not be loaded. + Кажется, что иногда игры загружают ESP и ESM файлы, даже если они не были не подключены как плагины +Обстоятельства этого пока не известны, но отчеты пользователей подразумевают, что это в ряде случаев нежелательно. Если этот флажок отмечен, не отмеченные в списке ESP и ESM не будут видимы в списке и не будут загружены. Hide inactive ESPs/ESMs - + Скрыть неактивные ESPs/ESMs If checked, files (i.e. esps, esms and bsas) belonging to the core game can not be disabled in the UI. (default: on) - + Если отмечено, файлы (т.е. esp, esm и bsa) принадлежащие основной игре не смогут быть отключены из интерфейса. (по умолчанию: вкл) If checked, files (i.e. esps, esms and bsas) belonging to the core game can not be disabled in the UI. (default: on) Uncheck this if you want to use Mod Organizer with total conversions (like Nehrim) but be aware that the game will crash if required files are not enabled. - + Если отмечено, файлы (т.е. esp, esm и bsa) принадлежащие основной игре не смогут быть отключены из интерфейса. (по умолчанию: вкл) +Снимите флажок, если вы собираетесь использовать Mod Organizer с тотальными конверсиями (как Nehrim) , но будьте осторожны, игра может вылететь, если требуемые файлы будут отключены. Force-enable game files - + Принудительно подключить файлы игры For Skyrim, this can be used instead of Archive Invalidation. It should make AI redundant for all Profiles. For the other games this is not a sufficient replacement for AI! - + Для Скайрим это может быть использовано вместо инвалидации. Это должно сделать AI избыточным для всех профилей. +Для других игр недостаточно замены для AI! Back-date BSAs - + Back-date BSAs + + + + These are workarounds for problems with Mod Organizer. Please make sure you read the help text before changing anything here. + Это способы обхода проблем с Mod Organizer. Убедитесь, что вы прочли справку, перед тем, как делать какие-либо изменения здесь. Select download directory - + Выберете каталог для загрузок Select mod directory - + Выберете каталог для модов Select cache directory - + Выберете каталог для кеша Confirm? - + Подтвердить? - This will make all dialogs show up again where you checked the "Remember selection"-box. Continue? - + This will make all dialogs show up again where you checked the "Remember selection"-box. Continue? + Это позволить снова отобразить все диалоги, для которых вы ранее выбрали флажок "Запомнить выбор". @@ -4714,7 +4573,7 @@ For the other games this is not a sufficient replacement for AI! Quick Install - + Быстрая установка @@ -4725,17 +4584,17 @@ For the other games this is not a sufficient replacement for AI! Opens a Dialog that allows custom modifications. - Открывает диалоговое окно, которое позволяет выбрать пользовательские модификации. + Открывает диалог, позволяющий выбрать пользовательские модификации. Manual - + Руководство OK - + OK @@ -4748,18 +4607,18 @@ For the other games this is not a sufficient replacement for AI! SHM error: %1 - + Ошибка SHM: %1 failed to connect to running instance: %1 - + не удалось подключиться к запущенному экземпляру: %1 failed to receive data from secondary instance: %1 - + не удалось получить данные из вторичного экземпляра: %1 @@ -4767,7 +4626,7 @@ For the other games this is not a sufficient replacement for AI! Sync Overwrite - + Синхронизация замены @@ -4777,22 +4636,22 @@ For the other games this is not a sufficient replacement for AI! Sync To - + Синхронизация с - <don't sync> - + <don't sync> + <не синхронизировать> failed to remove %1 - + не удалось удалить %1 failed to move %1 to %2 - + не удалось переместить %1 в %2 @@ -4800,17 +4659,17 @@ For the other games this is not a sufficient replacement for AI! Dialog - + Диалог Global Characters - + Общие символы This is a list of characters in the global location. - + Это список персонажей в общем месторасположении. @@ -4822,7 +4681,14 @@ On Windows Vista/Windows 7: On Windows XP: C:\Documents and Settings[UserName]\My Documents\My Games\Skyrim\Saves - + Список персонажей в общем месторасположении. + +На Windows Vista/Windows 7: +C:\Users\[UserName]\Documents\My Games\Skyrim\Saves + +На Windows XP: +C:\Documents and Settings[UserName]\My Documents\My Games\Skyrim\Saves + @@ -4835,27 +4701,35 @@ On Windows XP: C:\Documents and Settings[UserName]\My Documents\My Games\Skyrim\Saves - + Список сохранений с выбранным персонажем в общем месторасположении. + +На Windows Vista/Windows 7: +C:\Users\[UserName]\Documents\My Games\Skyrim\Saves + +На Windows XP: +C:\Documents and Settings[UserName]\My Documents\My Games\Skyrim\Saves + + Move -> - + Переместить -> Copy -> - + Скопировать -> <- Move - + <- Переместить <- Copy - + <- Скопировать @@ -4865,17 +4739,17 @@ On Windows XP: Profile Characters - + Персонажи профиля Overwrite - + Переписать - Overwrite the file "%1" - + Overwrite the file "%1" + Перезаписать файл "%1" @@ -4883,23 +4757,23 @@ On Windows XP: Confirm - Подтвердить + Подтверждение - Copy all save games of character "%1" to the profile? - + Copy all save games of character "%1" to the profile? + Скопировать все игры с персонажем "%1" в профиль? - Move all save games of character "%1" to the global location? Please be aware that this will mess up the running number of save games. - + Move all save games of character "%1" to the global location? Please be aware that this will mess up the running number of save games. + Переместить все сохранения с персонажем "%1" в общее месторасположение? Имейте ввиду, что это запутает текущую нумерацию сохранений. - Copy all save games of character "%1" to the global location? Please be aware that this will mess up the running number of save games. - + Copy all save games of character "%1" to the global location? Please be aware that this will mess up the running number of save games. + Скопировать все сохранения с персонажем "%1" в общее месторасположение? Имейте ввиду, что это запутает текущую нумерацию сохранений. diff --git a/src/overwriteinfodialog.cpp b/src/overwriteinfodialog.cpp index e215146f..2ba81633 100644 --- a/src/overwriteinfodialog.cpp +++ b/src/overwriteinfodialog.cpp @@ -72,7 +72,8 @@ private: OverwriteInfoDialog::OverwriteInfoDialog(ModInfo::Ptr modInfo, QWidget *parent) : QDialog(parent), ui(new Ui::OverwriteInfoDialog), m_FileSystemModel(NULL), - m_DeleteAction(NULL), m_RenameAction(NULL), m_OpenAction(NULL) + m_DeleteAction(NULL), m_RenameAction(NULL), m_OpenAction(NULL), + m_ModInfo(modInfo) { ui->setupUi(this); @@ -101,7 +102,6 @@ OverwriteInfoDialog::~OverwriteInfoDialog() delete ui; } - bool OverwriteInfoDialog::recursiveDelete(const QModelIndex &index) { for (int childRow = 0; childRow < m_FileSystemModel->rowCount(index); ++childRow) { diff --git a/src/overwriteinfodialog.h b/src/overwriteinfodialog.h index a60e0571..34e86219 100644 --- a/src/overwriteinfodialog.h +++ b/src/overwriteinfodialog.h @@ -17,51 +17,55 @@ You should have received a copy of the GNU General Public License along with Mod Organizer. If not, see . */ -#ifndef OVERWRITEINFODIALOG_H -#define OVERWRITEINFODIALOG_H - -#include "modinfo.h" -#include -#include - -namespace Ui { -class OverwriteInfoDialog; -} - -class OverwriteInfoDialog : public QDialog -{ - Q_OBJECT - -public: - - explicit OverwriteInfoDialog(ModInfo::Ptr modInfo, QWidget *parent = 0); - ~OverwriteInfoDialog(); - -private: - - void openFile(const QModelIndex &index); - bool recursiveDelete(const QModelIndex &index); - void deleteFile(const QModelIndex &index); - -private slots: - - void deleteTriggered(); - void renameTriggered(); - void openTriggered(); - void createDirectoryTriggered(); - - void on_filesView_customContextMenuRequested(const QPoint &pos); - -private: - - Ui::OverwriteInfoDialog *ui; - QFileSystemModel *m_FileSystemModel; - QModelIndexList m_FileSelection; - QAction *m_DeleteAction; - QAction *m_RenameAction; - QAction *m_OpenAction; - QAction *m_NewFolderAction; - -}; - -#endif // OVERWRITEINFODIALOG_H +#ifndef OVERWRITEINFODIALOG_H +#define OVERWRITEINFODIALOG_H + +#include "modinfo.h" +#include +#include + +namespace Ui { +class OverwriteInfoDialog; +} + +class OverwriteInfoDialog : public QDialog +{ + Q_OBJECT + +public: + + explicit OverwriteInfoDialog(ModInfo::Ptr modInfo, QWidget *parent = 0); + ~OverwriteInfoDialog(); + + ModInfo::Ptr modInfo() const { return m_ModInfo; } + +private: + + void openFile(const QModelIndex &index); + bool recursiveDelete(const QModelIndex &index); + void deleteFile(const QModelIndex &index); + +private slots: + + void deleteTriggered(); + void renameTriggered(); + void openTriggered(); + void createDirectoryTriggered(); + + void on_filesView_customContextMenuRequested(const QPoint &pos); + +private: + + Ui::OverwriteInfoDialog *ui; + QFileSystemModel *m_FileSystemModel; + QModelIndexList m_FileSelection; + QAction *m_DeleteAction; + QAction *m_RenameAction; + QAction *m_OpenAction; + QAction *m_NewFolderAction; + + ModInfo::Ptr m_ModInfo; + +}; + +#endif // OVERWRITEINFODIALOG_H diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index 456d29ee..b0228849 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -199,10 +199,11 @@ void PluginList::refresh(const QString &profileName, const DirectoryEntry &baseD readLockedOrderFrom(lockedOrderFile); - refreshLoadOrder(); - emit layoutChanged(); + refreshLoadOrder(); emit dataChanged(this->index(0, 0), this->index(m_ESPs.size(), 1)); + + m_Refreshed(); } @@ -534,6 +535,7 @@ void PluginList::syncLoadOrder() void PluginList::refreshLoadOrder() { + emit layoutAboutToBeChanged(); syncLoadOrder(); // set priorities according to locked load order std::map lockedLoadOrder; @@ -550,9 +552,9 @@ void PluginList::refreshLoadOrder() // find the location to insert at while ((targetPrio < static_cast(m_ESPs.size() - 1)) && (m_ESPs[m_ESPsByPriority[targetPrio]].m_LoadOrder < iter->first)) { - if (QString::compare(m_ESPs[m_ESPsByPriority[targetPrio]].m_Name, iter->second) != 0) { +// if (QString::compare(m_ESPs[m_ESPsByPriority[targetPrio]].m_Name, iter->second) != 0) { ++targetPrio; - } +// } } if (static_cast(targetPrio) >= m_ESPs.size()) { @@ -569,6 +571,7 @@ void PluginList::refreshLoadOrder() } } } + emit layoutChanged(); } IPluginList::PluginState PluginList::state(const QString &name) const @@ -621,6 +624,12 @@ QString PluginList::origin(const QString &name) const } } +bool PluginList::onRefreshed(const std::function &callback) +{ + auto conn = m_Refreshed.connect(callback); + return conn.connected(); +} + void PluginList::updateIndices() { m_ESPsByName.clear(); @@ -743,10 +752,11 @@ QVariant PluginList::data(const QModelIndex &modelIndex, int role) const } -bool PluginList::setData(const QModelIndex &index, const QVariant &value, int role) +bool PluginList::setData(const QModelIndex &modIndex, const QVariant &value, int role) { if (role == Qt::CheckStateRole) { - m_ESPs[index.row()].m_Enabled = value.toInt() == Qt::Checked; + m_ESPs[modIndex.row()].m_Enabled = value.toInt() == Qt::Checked; + emit dataChanged(modIndex, modIndex); refreshLoadOrder(); startSaveTime(); @@ -829,14 +839,17 @@ void PluginList::setPluginPriority(int row, int &newPriority) for (int i = oldPriority + 1; i <= newPriorityTemp; ++i) { --m_ESPs.at(m_ESPsByPriority.at(i)).m_Priority; } + emit dataChanged(index(oldPriority + 1, 0), index(newPriorityTemp, columnCount())); } else { for (int i = newPriorityTemp; i < oldPriority; ++i) { ++m_ESPs.at(m_ESPsByPriority.at(i)).m_Priority; } + emit dataChanged(index(newPriorityTemp, 0), index(oldPriority - 1, columnCount())); ++newPriority; } m_ESPs.at(row).m_Priority = newPriorityTemp; + emit dataChanged(index(row, 0), index(row, columnCount())); } catch (const std::out_of_range&) { reportError(tr("failed to restore load order for %1").arg(m_ESPs[row].m_Name)); } @@ -868,9 +881,9 @@ void PluginList::changePluginPriority(std::vector rows, int newPriority) for (std::vector::const_iterator iter = rows.begin(); iter != rows.end(); ++iter) { setPluginPriority(*iter, newPriority); } - refreshLoadOrder(); emit layoutChanged(); + refreshLoadOrder(); startSaveTime(); } @@ -958,7 +971,6 @@ bool PluginList::eventFilter(QObject *obj, QEvent *event) int newPriority = m_ESPs[idx.row()].m_Priority + diff; if ((newPriority >= 0) && (newPriority < rowCount())) { setPluginPriority(idx.row(), newPriority); - emit dataChanged(this->index(idx.row(), 0), this->index(idx.row(), this->columnCount() - 1)); } } refreshLoadOrder(); diff --git a/src/pluginlist.h b/src/pluginlist.h index 4da7be4b..2af5a0df 100644 --- a/src/pluginlist.h +++ b/src/pluginlist.h @@ -20,12 +20,13 @@ along with Mod Organizer. If not, see . #ifndef PLUGINLIST_H #define PLUGINLIST_H +#include +#include #include #include #include +#include #include -#include -#include /** @@ -45,6 +46,8 @@ public: COL_LASTCOLUMN = COL_MODINDEX }; + typedef boost::signals2::signal SignalRefreshed; + public: /** @@ -141,6 +144,7 @@ public: virtual int loadOrder(const QString &name) const; virtual bool isMaster(const QString &name) const; virtual QString origin(const QString &name) const; + virtual bool onRefreshed(const std::function &callback); public: // implementation of the QAbstractTableModel interface @@ -240,6 +244,8 @@ private: mutable QTimer m_SaveTimer; + SignalRefreshed m_Refreshed; + }; #endif // PLUGINLIST_H diff --git a/src/problemsdialog.cpp b/src/problemsdialog.cpp index d5700381..edb34f39 100644 --- a/src/problemsdialog.cpp +++ b/src/problemsdialog.cpp @@ -10,11 +10,26 @@ using namespace MOBase; ProblemsDialog::ProblemsDialog(std::vector diagnosePlugins, QWidget *parent) - : QDialog(parent), ui(new Ui::ProblemsDialog) + : QDialog(parent), ui(new Ui::ProblemsDialog), m_DiagnosePlugins(diagnosePlugins) { ui->setupUi(this); - foreach (IPluginDiagnose *diagnose, diagnosePlugins) { + runDiagnosis(); + + connect(ui->problemsWidget, SIGNAL(itemSelectionChanged()), this, SLOT(selectionChanged())); + connect(ui->descriptionText, SIGNAL(anchorClicked(QUrl)), this, SLOT(urlClicked(QUrl))); +} + + +ProblemsDialog::~ProblemsDialog() +{ + delete ui; +} + +void ProblemsDialog::runDiagnosis() +{ + ui->problemsWidget->clear(); + foreach (IPluginDiagnose *diagnose, m_DiagnosePlugins) { std::vector activeProblems = diagnose->activeProblems(); foreach (unsigned int key, activeProblems) { QTreeWidgetItem *newItem = new QTreeWidgetItem(); @@ -26,7 +41,7 @@ ProblemsDialog::ProblemsDialog(std::vector diagnosePl ui->problemsWidget->addTopLevelItem(newItem); if (diagnose->hasGuidedFix(key)) { - newItem->setText(1, tr("fix")); + newItem->setText(1, tr("Fix")); QPushButton *fixButton = new QPushButton(tr("Fix")); connect(fixButton, SIGNAL(clicked()), this, SLOT(startFix())); ui->problemsWidget->setItemWidget(newItem, 1, fixButton); @@ -35,17 +50,8 @@ ProblemsDialog::ProblemsDialog(std::vector diagnosePl } } } - connect(ui->problemsWidget, SIGNAL(itemSelectionChanged()), this, SLOT(selectionChanged())); - connect(ui->descriptionText, SIGNAL(anchorClicked(QUrl)), this, SLOT(urlClicked(QUrl))); -} - - -ProblemsDialog::~ProblemsDialog() -{ - delete ui; } - bool ProblemsDialog::hasProblems() const { return ui->problemsWidget->topLevelItemCount() != 0; @@ -62,6 +68,7 @@ void ProblemsDialog::startFix() { IPluginDiagnose *plugin = reinterpret_cast(ui->problemsWidget->currentItem()->data(1, Qt::UserRole).value()); plugin->startGuidedFix(ui->problemsWidget->currentItem()->data(1, Qt::UserRole + 1).toUInt()); + runDiagnosis(); } void ProblemsDialog::urlClicked(const QUrl &url) diff --git a/src/problemsdialog.h b/src/problemsdialog.h index 050785f4..24a69cdf 100644 --- a/src/problemsdialog.h +++ b/src/problemsdialog.h @@ -21,6 +21,9 @@ public: ~ProblemsDialog(); bool hasProblems() const; +private: + + void runDiagnosis(); private slots: @@ -31,6 +34,7 @@ private slots: private: Ui::ProblemsDialog *ui; + std::vector m_DiagnosePlugins; }; #endif // PROBLEMSDIALOG_H diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index e7bd0fa3..39d49a39 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -652,7 +652,7 @@ Please note that MO does identify itself as MO to the webserver, it's not lying tl;dr-version: If Nexus-features don't work, insert the current version number of NMM here and try again. - 009.009.009; + 009.009.009 Qt::AlignCenter diff --git a/src/shared/directoryentry.cpp b/src/shared/directoryentry.cpp index dde8a69e..685e14a9 100644 --- a/src/shared/directoryentry.cpp +++ b/src/shared/directoryentry.cpp @@ -494,7 +494,7 @@ static bool SupportOptimizedFind() static bool DirCompareByName(const DirectoryEntry *lhs, const DirectoryEntry *rhs) { - return wcsicmp(lhs->getName().c_str(), rhs->getName().c_str()) < 0; + return _wcsicmp(lhs->getName().c_str(), rhs->getName().c_str()) < 0; } diff --git a/src/version.rc b/src/version.rc index 55de3798..ab144909 100644 --- a/src/version.rc +++ b/src/version.rc @@ -1,7 +1,7 @@ #include "Winver.h" -#define VER_FILEVERSION 1,0,7,0 -#define VER_FILEVERSION_STR "1,0,7,0\0" +#define VER_FILEVERSION 1,0,8,0 +#define VER_FILEVERSION_STR "1,0,8,0\0" VS_VERSION_INFO VERSIONINFO FILEVERSION VER_FILEVERSION -- cgit v1.3.1 From b32457a7d2af4aeb095308c7f358a7a398ad849e Mon Sep 17 00:00:00 2001 From: Tannin Date: Sat, 7 Dec 2013 16:07:28 +0100 Subject: - minor text fixes - versions without a subminor version are now displayed without it (1.1 instead of 1.1.0) - version compares now prefer the decimal comparison over the traditional --- src/mainwindow.cpp | 6 +++--- src/mainwindow.h | 2 +- src/mainwindow.ui | 57 ++++++------------------------------------------------ src/version.rc | 4 ++-- 4 files changed, 12 insertions(+), 57 deletions(-) (limited to 'src/mainwindow.ui') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 5c487e7a..59666a20 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -3998,7 +3998,7 @@ void MainWindow::downloadRequested(QNetworkReply *reply, int modID, const QStrin } -QTranslator *MainWindow::installTranslator(const QString &name) +void MainWindow::installTranslator(const QString &name) { QTranslator *translator = new QTranslator(this); QString fileName = name + "_" + m_CurrentLanguage; @@ -4006,7 +4006,7 @@ QTranslator *MainWindow::installTranslator(const QString &name) qWarning("localization file %s not found", qPrintable(fileName)); } qApp->installTranslator(translator); - return translator; + m_Translators.push_back(translator); } @@ -4028,7 +4028,7 @@ void MainWindow::languageChange(const QString &newLanguage) QVariant fileNameVariant = pluginObj->property("filename"); if (fileNameVariant.isValid()) { QString fileName = QFileInfo(fileNameVariant.toString()).baseName(); - m_Translators.push_back(installTranslator(fileName)); + installTranslator(fileName); } } } diff --git a/src/mainwindow.h b/src/mainwindow.h index 5a8278f9..197ac73c 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -272,7 +272,7 @@ private: static void setupNetworkProxy(bool activate); void activateProxy(bool activate); - QTranslator *installTranslator(const QString &name); + void installTranslator(const QString &name); private: diff --git a/src/mainwindow.ui b/src/mainwindow.ui index bc7dc212..73ca868e 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -31,16 +31,7 @@ 4 - - 6 - - - 6 - - - 6 - - + 6 @@ -586,7 +577,7 @@ p, li { white-space: pre-wrap; } QTabWidget::Rounded - 0 + 1 @@ -730,16 +721,7 @@ p, li { white-space: pre-wrap; } Archives - - 6 - - - 6 - - - 6 - - + 6 @@ -819,16 +801,7 @@ BSAs checked here are loaded in such a way that your installation order is obeye Data - - 6 - - - 6 - - - 6 - - + 6 @@ -898,16 +871,7 @@ BSAs checked here are loaded in such a way that your installation order is obeye Saves - - 6 - - - 6 - - - 6 - - + 6 @@ -936,16 +900,7 @@ p, li { white-space: pre-wrap; } Downloads - - 2 - - - 2 - - - 2 - - + 2 diff --git a/src/version.rc b/src/version.rc index ab144909..b91dce85 100644 --- a/src/version.rc +++ b/src/version.rc @@ -1,7 +1,7 @@ #include "Winver.h" -#define VER_FILEVERSION 1,0,8,0 -#define VER_FILEVERSION_STR "1,0,8,0\0" +#define VER_FILEVERSION 1,0,10,0 +#define VER_FILEVERSION_STR "1,0,10,0\0" VS_VERSION_INFO VERSIONINFO FILEVERSION VER_FILEVERSION -- cgit v1.3.1 From e71c37df37dea1e4eb8b5e87027fc7f5f81bef56 Mon Sep 17 00:00:00 2001 From: Tannin Date: Sat, 7 Dec 2013 16:54:08 +0100 Subject: - bugfix: drag&drop on archive list didn't always work properly --- src/mainwindow.cpp | 6 ++++-- src/mainwindow.ui | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src/mainwindow.ui') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 59666a20..102c798e 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -207,6 +207,8 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget } ui->espList->installEventFilter(&m_PluginList); + ui->bsaList->setLocalMoveOnly(true); + resizeLists(initSettings.contains("mod_list_state"), initSettings.contains("plugin_list_state")); QMenu *linkMenu = new QMenu(this); @@ -1790,8 +1792,8 @@ void MainWindow::refreshBSAList() QTreeWidgetItem *newItem = new QTreeWidgetItem(strings); newItem->setData(0, Qt::UserRole, index); newItem->setData(1, Qt::UserRole, origin); -// newItem->setFlags(newItem->flags() & ~Qt::ItemIsDropEnabled | Qt::ItemIsUserCheckable); - newItem->setFlags(newItem->flags() | Qt::ItemIsUserCheckable); + newItem->setFlags(newItem->flags() & ~Qt::ItemIsDropEnabled | Qt::ItemIsUserCheckable); +// newItem->setFlags(newItem->flags() | Qt::ItemIsUserCheckable); newItem->setCheckState(0, (index != -1) ? Qt::Checked : Qt::Unchecked); if (m_Settings.forceEnableCoreFiles() && m_DefaultArchives.contains(filename)) { newItem->setCheckState(0, Qt::Checked); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 73ca868e..5c89a7e0 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -577,7 +577,7 @@ p, li { white-space: pre-wrap; } QTabWidget::Rounded - 1 + 0 -- cgit v1.3.1 From e597823337c858f2985c615ee5147f47567991ee Mon Sep 17 00:00:00 2001 From: Tannin Date: Thu, 23 Jan 2014 00:05:46 +0100 Subject: - boss integration - plugin list can now also display multiple flags for a file (like the mod list) - changed some compiler&linker settings to produce smaller binaries --- src/ModOrganizer.pro | 3 +- src/aboutdialog.cpp | 2 + src/icondelegate.cpp | 30 +-- src/icondelegate.h | 5 +- src/lockeddialog.cpp | 104 ++++++----- src/lockeddialog.h | 96 +++++----- src/logbuffer.cpp | 3 +- src/main.cpp | 5 +- src/mainwindow.cpp | 26 ++- src/mainwindow.h | 1 + src/mainwindow.ui | 82 +++++++-- src/modflagicondelegate.cpp | 50 +++++ src/modflagicondelegate.h | 18 ++ src/organizer.pro | 32 ++-- src/pdll.h | 402 +++++++++++++++++++++++++++++++++++++++++ src/pluginflagicondelegate.cpp | 24 +++ src/pluginflagicondelegate.h | 17 ++ src/pluginlist.cpp | 270 +++++++++++++++++++++++---- src/pluginlist.h | 95 +++++++++- src/pluginlistsortproxy.cpp | 5 - src/profile.cpp | 34 +--- src/resources.qrc | 2 +- src/safewritefile.cpp | 48 +++++ src/safewritefile.h | 51 ++++++ 24 files changed, 1179 insertions(+), 226 deletions(-) create mode 100644 src/modflagicondelegate.cpp create mode 100644 src/modflagicondelegate.h create mode 100644 src/pdll.h create mode 100644 src/pluginflagicondelegate.cpp create mode 100644 src/pluginflagicondelegate.h create mode 100644 src/safewritefile.cpp create mode 100644 src/safewritefile.h (limited to 'src/mainwindow.ui') diff --git a/src/ModOrganizer.pro b/src/ModOrganizer.pro index dbf6ab6e..05b05855 100644 --- a/src/ModOrganizer.pro +++ b/src/ModOrganizer.pro @@ -13,11 +13,12 @@ SUBDIRS = bsatk \ nxmhandler \ BossDummy \ pythonRunner \ + boss_modified \ esptk plugins.depends = pythonRunner hookdll.depends = shared -organizer.depends = shared uibase plugins +organizer.depends = shared uibase plugins boss_modified CONFIG(debug, debug|release) { DESTDIR = outputd diff --git a/src/aboutdialog.cpp b/src/aboutdialog.cpp index c7f95640..a8f9b4db 100644 --- a/src/aboutdialog.cpp +++ b/src/aboutdialog.cpp @@ -44,6 +44,8 @@ AboutDialog::AboutDialog(const QString &version, QWidget *parent) addLicense("7-zip", LICENSE_LGPL3); addLicense("ZLib", LICENSE_ZLIB); addLicense("NIF File Format Library", LICENSE_BSD3); + addLicense("BOSS (modified)", LICENSE_GPL3); + addLicense("Alphanum Algorithm", LICENSE_ZLIB); ui->nameLabel->setText(QString("%1 %2").arg(ui->nameLabel->text()).arg(version)); #ifdef HGID diff --git a/src/icondelegate.cpp b/src/icondelegate.cpp index 2540e1d5..048b09f9 100644 --- a/src/icondelegate.cpp +++ b/src/icondelegate.cpp @@ -29,38 +29,17 @@ IconDelegate::IconDelegate(QObject *parent) } -QIcon IconDelegate::getFlagIcon(ModInfo::EFlag flag) const -{ - switch (flag) { - case ModInfo::FLAG_BACKUP: return QIcon(":/MO/gui/emblem_backup"); - case ModInfo::FLAG_INVALID: return QIcon(":/MO/gui/emblem_problem"); - case ModInfo::FLAG_NOTENDORSED: return QIcon(":/MO/gui/emblem_notendorsed"); - case ModInfo::FLAG_NOTES: return QIcon(":/MO/gui/emblem_notes"); - case ModInfo::FLAG_CONFLICT_OVERWRITE: return QIcon(":/MO/gui/emblem_conflict_overwrite"); - case ModInfo::FLAG_CONFLICT_OVERWRITTEN: return QIcon(":/MO/gui/emblem_conflict_overwritten"); - case ModInfo::FLAG_CONFLICT_MIXED: return QIcon(":/MO/gui/emblem_conflict_mixed"); - case ModInfo::FLAG_CONFLICT_REDUNDANT: return QIcon(":MO/gui/emblem_conflict_redundant"); - default: return QIcon(); - } -} - - void IconDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QStyledItemDelegate::paint(painter, option, index); - QVariant modid = index.data(Qt::UserRole + 1); - if (!modid.isValid()) { - return; - } - ModInfo::Ptr info = ModInfo::getByIndex(modid.toInt()); - std::vector flags = info->getFlags(); + + QList icons = getIcons(index); int x = 4; painter->save(); painter->translate(option.rect.topLeft()); - for (auto iter = flags.begin(); iter != flags.end(); ++iter) { - QIcon temp = getFlagIcon(*iter); - painter->drawPixmap(x, 2, 16, 16, temp.pixmap(QSize(16, 16))); + for (auto iter = icons.begin(); iter != icons.end(); ++iter) { + painter->drawPixmap(x, 2, 16, 16, iter->pixmap(QSize(16, 16))); x += 20; } @@ -70,6 +49,7 @@ void IconDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, QSize IconDelegate::sizeHint(const QStyleOptionViewItem&, const QModelIndex &modelIndex) const { + int count = getNumIcons(modelIndex); unsigned int index = modelIndex.data(Qt::UserRole + 1).toInt(); if (index < ModInfo::getNumMods()) { ModInfo::Ptr info = ModInfo::getByIndex(index); diff --git a/src/icondelegate.h b/src/icondelegate.h index dd9f9dfc..cf292443 100644 --- a/src/icondelegate.h +++ b/src/icondelegate.h @@ -34,13 +34,16 @@ public: virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; + signals: public slots: private: - QIcon getFlagIcon(ModInfo::EFlag flag) const; + virtual QList getIcons(const QModelIndex &index) const = 0; + virtual size_t getNumIcons(const QModelIndex &index) const = 0; + private: diff --git a/src/lockeddialog.cpp b/src/lockeddialog.cpp index 4c19c615..065d9270 100644 --- a/src/lockeddialog.cpp +++ b/src/lockeddialog.cpp @@ -17,51 +17,59 @@ You should have received a copy of the GNU General Public License along with Mod Organizer. If not, see . */ -#include "lockeddialog.h" -#include "ui_lockeddialog.h" -#include - - -LockedDialog::LockedDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::LockedDialog), m_UnlockClicked(false) -{ - ui->setupUi(this); - - this->setWindowFlags(this->windowFlags() | Qt::ToolTip | Qt::FramelessWindowHint); - - if (parent != NULL) { - QPoint position = parent->mapToGlobal(QPoint(parent->width() / 2, parent->height() / 2)); - position.rx() -= this->width() / 2; - position.ry() -= this->height() / 2; - move(position); - } -} - -LockedDialog::~LockedDialog() -{ - delete ui; -} - - -void LockedDialog::setProcessName(const QString &name) -{ - ui->processLabel->setText(name); -} - - -void LockedDialog::resizeEvent(QResizeEvent *event) -{ - QWidget *par = parentWidget(); - if (par != NULL) { - QPoint position = par->mapToGlobal(QPoint(par->width() / 2, par->height() / 2)); - position.rx() -= event->size().width() / 2; - position.ry() -= event->size().height() / 2; - move(position); - } -} - -void LockedDialog::on_unlockButton_clicked() -{ - m_UnlockClicked = true; -} +#include "lockeddialog.h" +#include "ui_lockeddialog.h" +#include + + +LockedDialog::LockedDialog(QWidget *parent, const QString &text, bool unlockButton) + : QDialog(parent) + , ui(new Ui::LockedDialog) + , m_UnlockClicked(false) +{ + ui->setupUi(this); + + this->setWindowFlags(this->windowFlags() | Qt::ToolTip | Qt::FramelessWindowHint); + + if (parent != NULL) { + QPoint position = parent->mapToGlobal(QPoint(parent->width() / 2, parent->height() / 2)); + position.rx() -= this->width() / 2; + position.ry() -= this->height() / 2; + move(position); + } + + if (text.length() > 0) { + ui->label->setText(text); + } + if (!unlockButton) { + ui->unlockButton->hide(); + } +} + +LockedDialog::~LockedDialog() +{ + delete ui; +} + + +void LockedDialog::setProcessName(const QString &name) +{ + ui->processLabel->setText(name); +} + + +void LockedDialog::resizeEvent(QResizeEvent *event) +{ + QWidget *par = parentWidget(); + if (par != NULL) { + QPoint position = par->mapToGlobal(QPoint(par->width() / 2, par->height() / 2)); + position.rx() -= event->size().width() / 2; + position.ry() -= event->size().height() / 2; + move(position); + } +} + +void LockedDialog::on_unlockButton_clicked() +{ + m_UnlockClicked = true; +} diff --git a/src/lockeddialog.h b/src/lockeddialog.h index 5be398bc..0f3b29b0 100644 --- a/src/lockeddialog.h +++ b/src/lockeddialog.h @@ -17,51 +17,51 @@ You should have received a copy of the GNU General Public License along with Mod Organizer. If not, see . */ -#ifndef LOCKEDDIALOG_H -#define LOCKEDDIALOG_H - -#include - -namespace Ui { - class LockedDialog; -} - -/** - * a small borderless dialog displayed while the Mod Organizer UI is locked - * The dialog contains only a label and a button to force the UI to be unlocked - * - * The UI gets locked while running external applications since they may modify the - * data on which Mod Organizer works. After the UI is unlocked (manually or after the - * external application closed) MO will refresh all of its data sources - **/ -class LockedDialog : public QDialog -{ - Q_OBJECT - -public: - explicit LockedDialog(QWidget *parent = 0); - ~LockedDialog(); - - /** - * @brief see if the user clicked the unlock-button - * - * @return true if the user clicked the unlock button - **/ - bool unlockClicked() const { return m_UnlockClicked; } - - void setProcessName(const QString &name); - -protected: - - virtual void resizeEvent(QResizeEvent *event); - -private slots: - - void on_unlockButton_clicked(); - -private: - Ui::LockedDialog *ui; - bool m_UnlockClicked; -}; - -#endif // LOCKEDDIALOG_H +#ifndef LOCKEDDIALOG_H +#define LOCKEDDIALOG_H + +#include + +namespace Ui { + class LockedDialog; +} + +/** + * a small borderless dialog displayed while the Mod Organizer UI is locked + * The dialog contains only a label and a button to force the UI to be unlocked + * + * The UI gets locked while running external applications since they may modify the + * data on which Mod Organizer works. After the UI is unlocked (manually or after the + * external application closed) MO will refresh all of its data sources + **/ +class LockedDialog : public QDialog +{ + Q_OBJECT + +public: + explicit LockedDialog(QWidget *parent = 0, const QString &text = "", bool unlockButton = true); + ~LockedDialog(); + + /** + * @brief see if the user clicked the unlock-button + * + * @return true if the user clicked the unlock button + **/ + bool unlockClicked() const { return m_UnlockClicked; } + + void setProcessName(const QString &name); + +protected: + + virtual void resizeEvent(QResizeEvent *event); + +private slots: + + void on_unlockButton_clicked(); + +private: + Ui::LockedDialog *ui; + bool m_UnlockClicked; +}; + +#endif // LOCKEDDIALOG_H diff --git a/src/logbuffer.cpp b/src/logbuffer.cpp index 4f72e551..689d2b55 100644 --- a/src/logbuffer.cpp +++ b/src/logbuffer.cpp @@ -21,6 +21,7 @@ along with Mod Organizer. If not, see . #include "report.h" #include #include +#include #include QScopedPointer LogBuffer::s_Instance; @@ -124,8 +125,6 @@ char LogBuffer::msgTypeID(QtMsgType type) } } -#include - void LogBuffer::log(QtMsgType type, const char *message) { QMutexLocker guard(&s_Mutex); diff --git a/src/main.cpp b/src/main.cpp index 8b74ba83..05d68ec7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -119,7 +119,8 @@ bool bootstrap() QDir::fromNativeSeparators(ToQString(gameInfo.getDownloadDir())), QDir::fromNativeSeparators(ToQString(gameInfo.getOverwriteDir())), QDir::fromNativeSeparators(ToQString(gameInfo.getLogDir())), - QDir::fromNativeSeparators(ToQString(gameInfo.getTutorialDir())) + QDir::fromNativeSeparators(ToQString(gameInfo.getTutorialDir())), + QDir::fromNativeSeparators(ToQString(gameInfo.getOrganizerDirectory()) + "/boss") }; static const int NUM_DIRECTORIES = sizeof(dirNames) / sizeof(QString); @@ -284,7 +285,7 @@ int main(int argc, char *argv[]) SetUnhandledExceptionFilter(MyUnhandledExceptionFilter); - LogBuffer::init(20, QtDebugMsg, application.applicationDirPath() + "/logs/mo_interface.log"); + LogBuffer::init(200, QtDebugMsg, application.applicationDirPath() + "/logs/mo_interface.log"); qDebug("Working directory: %s", qPrintable(QDir::toNativeSeparators(QDir::currentPath()))); qDebug("MO at: %s", qPrintable(QDir::toNativeSeparators(application.applicationDirPath()))); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 582bc283..0f98989c 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -48,7 +48,8 @@ along with Mod Organizer. If not, see . #include "filedialogmemory.h" #include "questionboxmemory.h" #include "tutorialmanager.h" -#include "icondelegate.h" +#include "modflagicondelegate.h" +#include "pluginflagicondelegate.h" #include "credentialsdialog.h" #include "selectiondialog.h" #include "csvbuilder.h" @@ -104,6 +105,7 @@ along with Mod Organizer. If not, see . #include #include #include +#include #ifdef TEST_MODELS @@ -186,7 +188,7 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget ui->modList->setModel(m_ModListSortProxy); ui->modList->sortByColumn(ModList::COL_PRIORITY, Qt::AscendingOrder); - ui->modList->setItemDelegateForColumn(ModList::COL_FLAGS, new IconDelegate(ui->modList)); + ui->modList->setItemDelegateForColumn(ModList::COL_FLAGS, new ModFlagIconDelegate(ui->modList)); //ui->modList->setAcceptDrops(true); ui->modList->header()->installEventFilter(&m_ModList); if (initSettings.contains("mod_list_state")) { @@ -206,6 +208,7 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget ui->espList->setModel(m_PluginListSortProxy); ui->espList->sortByColumn(PluginList::COL_PRIORITY, Qt::AscendingOrder); + ui->espList->setItemDelegateForColumn(PluginList::COL_FLAGS, new PluginFlagIconDelegate(ui->espList)); if (initSettings.contains("plugin_list_state")) { ui->espList->header()->restoreState(initSettings.value("plugin_list_state").toByteArray()); } @@ -1314,6 +1317,8 @@ HANDLE MainWindow::spawnBinaryDirect(const QFileInfo &binary, const QString &arg QCoreApplication::processEvents(); } + m_CurrentProfile->writeModlistNow(true); + // TODO: should also pass arguments if (m_AboutToRun(binary.absoluteFilePath())) { return startBinary(binary, arguments, profileName, m_Settings.logLevel(), currentDirectory, true); @@ -1778,7 +1783,7 @@ void MainWindow::refreshESPList() m_CurrentProfile->getLoadOrderFileName(), m_CurrentProfile->getLockedOrderFileName()); } catch (const std::exception &e) { - reportError(tr("Failed to refresh list of esps: %s").arg(e.what())); + reportError(tr("Failed to refresh list of esps: %1").arg(e.what())); } } @@ -5123,3 +5128,18 @@ void MainWindow::on_showHiddenBox_toggled(bool checked) m_DownloadManager.setShowHidden(checked); } +void MainWindow::on_bossButton_clicked() +{ + try { + LockedDialog dialog(this, tr("BOSS working"), false); + dialog.show(); + qApp->processEvents(); + m_PluginList.bossSort(); + + savePluginList(); + dialog.hide(); + } catch (const std::exception &e) { + reportError(tr("failed to run boss: %1").arg(e.what())); + ui->bossButton->setEnabled(false); + } +} diff --git a/src/mainwindow.h b/src/mainwindow.h index c01ce767..b247b924 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -564,6 +564,7 @@ private slots: // ui slots void on_linkButton_pressed(); void on_showHiddenBox_toggled(bool checked); void on_bsaList_itemChanged(QTreeWidgetItem *item, int column); + void on_bossButton_clicked(); }; #endif // MAINWINDOW_H diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 5c89a7e0..f3bb425c 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -31,7 +31,16 @@ 4 - + + 6 + + + 6 + + + 6 + + 6 @@ -705,14 +714,25 @@ p, li { white-space: pre-wrap; } - - - - - - Namefilter - - + + + + + + + + Namefilter + + + + + + + Sort + + + + @@ -721,7 +741,16 @@ p, li { white-space: pre-wrap; } Archives - + + 6 + + + 6 + + + 6 + + 6 @@ -801,7 +830,16 @@ BSAs checked here are loaded in such a way that your installation order is obeye Data - + + 6 + + + 6 + + + 6 + + 6 @@ -871,7 +909,16 @@ BSAs checked here are loaded in such a way that your installation order is obeye Saves - + + 6 + + + 6 + + + 6 + + 6 @@ -900,7 +947,16 @@ p, li { white-space: pre-wrap; } Downloads - + + 2 + + + 2 + + + 2 + + 2 diff --git a/src/modflagicondelegate.cpp b/src/modflagicondelegate.cpp new file mode 100644 index 00000000..db69eb52 --- /dev/null +++ b/src/modflagicondelegate.cpp @@ -0,0 +1,50 @@ +#include "modflagicondelegate.h" +#include + + +ModFlagIconDelegate::ModFlagIconDelegate(QObject *parent) + : IconDelegate(parent) +{ +} + +QList ModFlagIconDelegate::getIcons(const QModelIndex &index) const +{ + QList result; + QVariant modid = index.data(Qt::UserRole + 1); + if (modid.isValid()) { + ModInfo::Ptr info = ModInfo::getByIndex(modid.toInt()); + std::vector flags = info->getFlags(); + + for (auto iter = flags.begin(); iter != flags.end(); ++iter) { + result.append(getFlagIcon(*iter)); + } + } + return result; +} + +QIcon ModFlagIconDelegate::getFlagIcon(ModInfo::EFlag flag) const +{ + switch (flag) { + case ModInfo::FLAG_BACKUP: return QIcon(":/MO/gui/emblem_backup"); + case ModInfo::FLAG_INVALID: return QIcon(":/MO/gui/emblem_problem"); + case ModInfo::FLAG_NOTENDORSED: return QIcon(":/MO/gui/emblem_notendorsed"); + case ModInfo::FLAG_NOTES: return QIcon(":/MO/gui/emblem_notes"); + case ModInfo::FLAG_CONFLICT_OVERWRITE: return QIcon(":/MO/gui/emblem_conflict_overwrite"); + case ModInfo::FLAG_CONFLICT_OVERWRITTEN: return QIcon(":/MO/gui/emblem_conflict_overwritten"); + case ModInfo::FLAG_CONFLICT_MIXED: return QIcon(":/MO/gui/emblem_conflict_mixed"); + case ModInfo::FLAG_CONFLICT_REDUNDANT: return QIcon(":MO/gui/emblem_conflict_redundant"); + default: return QIcon(); + } +} + +size_t ModFlagIconDelegate::getNumIcons(const QModelIndex &index) const +{ + unsigned int modIdx = index.data(Qt::UserRole + 1).toInt(); + if (modIdx < ModInfo::getNumMods()) { + ModInfo::Ptr info = ModInfo::getByIndex(modIdx); + return info->getFlags().size(); + } else { + return 0; + } +} + diff --git a/src/modflagicondelegate.h b/src/modflagicondelegate.h new file mode 100644 index 00000000..800e2741 --- /dev/null +++ b/src/modflagicondelegate.h @@ -0,0 +1,18 @@ +#ifndef MODFLAGICONDELEGATE_H +#define MODFLAGICONDELEGATE_H + +#include "icondelegate.h" + +class ModFlagIconDelegate : public IconDelegate +{ +public: + explicit ModFlagIconDelegate(QObject *parent = 0); +private: + virtual QList getIcons(const QModelIndex &index) const; + virtual size_t getNumIcons(const QModelIndex &index) const; + + QIcon getFlagIcon(ModInfo::EFlag flag) const; + +}; + +#endif // MODFLAGICONDELEGATE_H diff --git a/src/organizer.pro b/src/organizer.pro index fd72dea3..9a9d0da3 100644 --- a/src/organizer.pro +++ b/src/organizer.pro @@ -81,7 +81,10 @@ SOURCES += \ previewgenerator.cpp \ previewdialog.cpp \ aboutdialog.cpp \ - json.cpp + json.cpp \ + safewritefile.cpp \ + modflagicondelegate.cpp \ + pluginflagicondelegate.cpp HEADERS += \ @@ -152,7 +155,11 @@ HEADERS += \ previewgenerator.h \ previewdialog.h \ aboutdialog.h \ - json.h + json.h \ + safewritefile.h\ + pdll.h \ + modflagicondelegate.h \ + pluginflagicondelegate.h FORMS += \ transfersavesdialog.ui \ @@ -185,24 +192,28 @@ FORMS += \ previewdialog.ui \ aboutdialog.ui -INCLUDEPATH += ../shared ../archive ../uibase ../bsatk ../esptk "$(BOOSTPATH)" +INCLUDEPATH += ../shared ../archive ../uibase ../bsatk ../esptk ../boss_modified/boss-api "$(BOOSTPATH)" LIBS += -L"$(BOOSTPATH)/stage/lib" CONFIG(debug, debug|release) { OUTDIR = $$OUT_PWD/debug DSTDIR = $$PWD/../../outputd - LIBS += -L$$OUT_PWD/../shared/debug -L$$OUT_PWD/../bsatk/debug - LIBS += -L$$OUT_PWD/../uibase/debug - LIBS += -lDbgHelp + LIBS += -L$$OUT_PWD/../shared/debug + LIBS += -L$$OUT_PWD/../bsatk/debug + LIBS += -L$$OUT_PWD/../uibase/debug + LIBS += -L$$OUT_PWD/../boss_modified/debug + LIBS += -lDbgHelp } else { OUTDIR = $$OUT_PWD/release DSTDIR = $$PWD/../../output - LIBS += -L$$OUT_PWD/../shared/release -L$$OUT_PWD/../bsatk/release + LIBS += -L$$OUT_PWD/../shared/release + LIBS += -L$$OUT_PWD/../bsatk/release LIBS += -L$$OUT_PWD/../uibase/release - QMAKE_CXXFLAGS += /Zi + LIBS += -L$$OUT_PWD/../boss_modified/release + QMAKE_CXXFLAGS += /Zi /GL # QMAKE_CXXFLAGS -= -O2 - QMAKE_LFLAGS += /DEBUG + QMAKE_LFLAGS += /DEBUG /LTCG /OPT:REF /OPT:ICF } #QMAKE_CXXFLAGS_WARN_ON -= -W3 @@ -299,9 +310,6 @@ OTHER_FILES += \ tutorials/tutorial_window_installer.js \ tutorials/tutorials_installdialog.qml -INCLUDEPATH += "$(ZLIBPATH)" "$(ZLIBPATH)/build" "$(BOOSTPATH)" -LIBS += -L"$(ZLIBPATH)/build" -lzlibstatic - # leak detection with vld #INCLUDEPATH += "E:/Visual Leak Detector/include" diff --git a/src/pdll.h b/src/pdll.h new file mode 100644 index 00000000..6e1d06f3 --- /dev/null +++ b/src/pdll.h @@ -0,0 +1,402 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Class: PDll // +// Authors: MicHael Galkovsky // +// Date: April 14, 1998 // +// Company: Pervasive Software // +// Purpose: Base class to wrap dynamic use of dll // +////////////////////////////////////////////////////////////////////////////////////////////// + +#if !defined (_PDLL_H_) +#define _PDLL_H_ + +#include +#include + +#include +#include +#include + + +#define FUNC_LOADED 3456 + +//function declarations according to the number of parameters +//define the type +//declare a variable of that type +//declare a member function by the same name as the dll function +//check for dll handle +//if this is the first call to the function then try to load it +//if not then if the function was loaded successfully make a call to it +//otherwise return a NULL cast to the return parameter. + +#define DECLARE_FUNCTION0(CallType, retVal, FuncName) \ + typedef retVal (CallType* TYPE_##FuncName)(); \ + TYPE_##FuncName m_##FuncName; \ + short m_is##FuncName; \ + retVal FuncName() \ + { \ + if (m_dllHandle) \ + { \ + if (FUNC_LOADED != m_is##FuncName) \ + {\ + m_##FuncName = NULL; \ + m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \ + m_is##FuncName = FUNC_LOADED;\ + }\ + if (NULL != m_##FuncName) \ + return m_##FuncName(); \ + else \ + return (retVal)NULL; \ + } \ + else \ + return (retVal)NULL; \ + } + +#define DECLARE_FUNCTION1(CallType,retVal, FuncName, Param1) \ + typedef retVal (CallType* TYPE_##FuncName)(Param1); \ + TYPE_##FuncName m_##FuncName; \ + short m_is##FuncName;\ + retVal FuncName(Param1 p1) \ + { \ + if (m_dllHandle) \ + { \ + if (FUNC_LOADED != m_is##FuncName) \ + {\ + m_##FuncName = NULL; \ + m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \ + m_is##FuncName = FUNC_LOADED;\ + }\ + if (NULL != m_##FuncName) \ + return m_##FuncName(p1); \ + else \ + return (retVal)NULL; \ + } \ + else \ + return (retVal)NULL; \ + } + +#define DECLARE_FUNCTION2(CallType,retVal, FuncName, Param1, Param2) \ + typedef retVal (CallType* TYPE_##FuncName)(Param1, Param2); \ + TYPE_##FuncName m_##FuncName; \ + short m_is##FuncName;\ + retVal FuncName (Param1 p1, Param2 p2) \ + {\ + if (m_dllHandle)\ + {\ + if (FUNC_LOADED != m_is##FuncName) \ + {\ + m_##FuncName = NULL; \ + m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \ + m_is##FuncName = FUNC_LOADED;\ + }\ + if (NULL != m_##FuncName) \ + return m_##FuncName(p1, p2); \ + else \ + return (retVal)NULL; \ + } \ + else\ + return (retVal)NULL; \ + } + +#define DECLARE_FUNCTION3(CallType,retVal, FuncName, Param1, Param2, Param3) \ + typedef retVal (CallType* TYPE_##FuncName)(Param1, Param2, Param3); \ + TYPE_##FuncName m_##FuncName; \ + short m_is##FuncName;\ + retVal FuncName (Param1 p1, Param2 p2, Param3 p3) \ + {\ + if (m_dllHandle)\ + {\ + if (FUNC_LOADED != m_is##FuncName) \ + {\ + m_##FuncName = NULL; \ + m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \ + m_is##FuncName = FUNC_LOADED; \ + }\ + if (NULL != m_##FuncName) \ + return m_##FuncName(p1, p2, p3);\ + else \ + return (retVal)NULL; \ + } \ + else\ + return (retVal)NULL; \ + } + +#define DECLARE_FUNCTION4(CallType,retVal, FuncName, Param1, Param2, Param3, Param4) \ + typedef retVal (CallType* TYPE_##FuncName)(Param1, Param2, Param3, Param4); \ + TYPE_##FuncName m_##FuncName; \ + short m_is##FuncName;\ + retVal FuncName (Param1 p1, Param2 p2, Param3 p3, Param4 p4) \ + {\ + if (m_dllHandle)\ + {\ + if (FUNC_LOADED != m_is##FuncName) \ + {\ + m_##FuncName = NULL; \ + m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \ + m_is##FuncName = FUNC_LOADED;\ + }\ + if (NULL != m_##FuncName) \ + return m_##FuncName(p1, p2, p3, p4);\ + else \ + return (retVal)NULL; \ + } \ + else\ + return (retVal)NULL; \ + } + +#define DECLARE_FUNCTION5(CallType,retVal, FuncName, Param1, Param2, Param3, Param4, Param5) \ + typedef retVal (CallType* TYPE_##FuncName)(Param1, Param2, Param3, Param4, Param5); \ + TYPE_##FuncName m_##FuncName; \ + short m_is##FuncName; \ + retVal FuncName (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) \ + {\ + if (m_dllHandle)\ + {\ + if (FUNC_LOADED != m_is##FuncName) \ + {\ + m_##FuncName = NULL; \ + m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \ + m_is##FuncName = FUNC_LOADED;\ + }\ + if (NULL != m_##FuncName) \ + return m_##FuncName(p1, p2, p3, p4, p5);\ + else \ + return (retVal)NULL; \ + } \ + else\ + return (retVal)NULL; \ + } + +#define DECLARE_FUNCTION6(CallType,retVal, FuncName, Param1, Param2, Param3, Param4, Param5, Param6) \ + typedef retVal (CallType* TYPE_##FuncName)(Param1, Param2, Param3, Param4, Param5, Param6); \ + TYPE_##FuncName m_##FuncName; \ + short m_is##FuncName;\ + retVal FuncName (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) \ + {\ + if (m_dllHandle)\ + {\ + if (FUNC_LOADED != m_is##FuncName) \ + {\ + m_##FuncName = NULL; \ + m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \ + m_is##FuncName = FUNC_LOADED;\ + }\ + if (NULL != m_##FuncName) \ + return m_##FuncName(p1, p2, p3, p4, p5, p6);\ + else \ + return (retVal)NULL; \ + } \ + else\ + return (retVal)NULL; \ + } + +#define DECLARE_FUNCTION7(CallType,retVal, FuncName, Param1, Param2, Param3, Param4, Param5, Param6, Param7) \ + typedef retVal (CallType* TYPE_##FuncName)(Param1, Param2, Param3, Param4, Param5, Param6, Param7); \ + TYPE_##FuncName m_##FuncName; \ + short m_is##FuncName;\ + retVal FuncName (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) \ + {\ + if (m_dllHandle)\ + {\ + if (FUNC_LOADED != m_is##FuncName) \ + {\ + m_##FuncName = NULL; \ + m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \ + m_is##FuncName = FUNC_LOADED;\ + }\ + if (NULL != m_##FuncName) \ + return m_##FuncName(p1, p2, p3, p4, p5, p6, p7);\ + else \ + return (retVal)NULL; \ + } \ + else\ + return (retVal)NULL; \ + } + +#define DECLARE_FUNCTION8(CallType,retVal, FuncName, Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8) \ + typedef retVal (CallType* TYPE_##FuncName)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8); \ + TYPE_##FuncName m_##FuncName; \ + short m_is##FuncName;\ + retVal FuncName (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) \ + {\ + if (m_dllHandle)\ + {\ + if (FUNC_LOADED != m_is##FuncName) \ + {\ + m_##FuncName = NULL; \ + m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \ + m_is##FuncName = FUNC_LOADED;\ + }\ + if (NULL != m_##FuncName) \ + return m_##FuncName(p1, p2, p3, p4, p5, p6, p7, p8);\ + else \ + return (retVal)NULL; \ + }\ + else\ + return (retVal)NULL; \ + } + +#define DECLARE_FUNCTION9(CallType,retVal, FuncName, Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9) \ + typedef retVal (CallType* TYPE_##FuncName)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9); \ + TYPE_##FuncName m_##FuncName; \ + short m_is##FuncName; \ + retVal FuncName (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) \ + {\ + if (m_dllHandle)\ + {\ + if (FUNC_NAME != m_is##FuncName) \ + {\ + m_##FuncName = NULL; \ + m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \ + m_is##FuncName = FUNC_LOADED;\ + }\ + if (NULL != m_##FuncName) \ + return m_##FuncName(p1, p2, p3, p4, p5, p6, p7, p8, p9);\ + else \ + return (retVal)NULL; \ + }\ + else\ + return (retVal)NULL; \ + } + +#define DECLARE_FUNCTION10(CallType,retVal, FuncName, Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10) \ + typedef retVal (CallType* TYPE_##FuncName)FuncName(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10); \ + TYPE_##FuncName m_##FuncName; \ + short m_is##FuncName;\ + retVal FuncName (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) \ + {\ + if (m_dllHandle)\ + {\ + if (FUNC_LOADED != m_is##FuncName) \ + {\ + m_##FuncName = NULL; \ + m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \ + m_is##FuncName = FUNC_LOADED;\ + }\ + if (NULL != m_##FuncName) \ + return m_##FuncName(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);\ + else \ + return (retVal)NULL; \ + }\ + else \ + return (retVal)NULL;\ + } + +//declare constructors and LoadFunctions +#define DECLARE_CLASS(ClassName) \ + public: \ + ClassName (LPCTSTR name){LoadDll(name);} \ + ClassName () {PDLL();} + +class PDLL +{ +protected: + HINSTANCE m_dllHandle; +private: + LPTSTR m_dllName; + int m_refCount; + +public: + + PDLL() + { + m_dllHandle = NULL; + m_dllName = NULL; + m_refCount = 0; + } + + //A NULL here means the name has already been set + void LoadDll(LPCTSTR name, bool showMsg = true) + { + if (name) + SetDllName(name); + + //try to load + m_dllHandle = LoadLibrary(m_dllName); + + if (m_dllHandle == NULL && showMsg) + { + std::ostringstream message; + message << "failed to load dll: " << ::GetLastError(); + throw std::runtime_error(message.str().c_str()); + } + } + + bool SetDllName(LPCTSTR newName) + { + bool retVal = false; + + //we allow name resets only if the current DLL handle is invalid + //once they've hooked into a DLL, the name cannot be changed + if (!m_dllHandle) + { + if (m_dllName) + { + delete []m_dllName; + m_dllName = NULL; + } + + //They may be setting this null (e.g., uninitialize) + if (newName) + { + m_dllName = new TCHAR[_tcslen(newName) + 1]; + _tcscpy(m_dllName, newName); + } + retVal = true; + } + return retVal; + } + + virtual bool Initialize(short showMsg = 1) + { + + bool retVal = false; + + //Add one to our internal reference counter + m_refCount++; + + if (m_refCount == 1 && m_dllName) //if this is first time, load the DLL + { + //we are assuming the name is already set + LoadDll(NULL, showMsg); + retVal = (m_dllHandle != NULL); + } + return retVal; + } + + virtual void Uninitialize(void) + { + //If we're already completely unintialized, early exit + if (!m_refCount) + return; + //if this is the last time this instance has been unitialized, + //then do a full uninitialization + m_refCount--; + + if (m_refCount < 1) + { + if (m_dllHandle) + { + FreeLibrary(m_dllHandle); + m_dllHandle = NULL; + } + + SetDllName(NULL); //clear out the name & free memory + } + } + + virtual ~PDLL() + { + //force this to be a true uninitialize + m_refCount = 1; + Uninitialize(); + + //free name + if (m_dllName) + { + delete [] m_dllName; + m_dllName = NULL; + } + } + +}; +#endif diff --git a/src/pluginflagicondelegate.cpp b/src/pluginflagicondelegate.cpp new file mode 100644 index 00000000..6c0bb29e --- /dev/null +++ b/src/pluginflagicondelegate.cpp @@ -0,0 +1,24 @@ +#include "pluginflagicondelegate.h" +#include "pluginlist.h" +#include + + +PluginFlagIconDelegate::PluginFlagIconDelegate(QObject *parent) + : IconDelegate(parent) +{ +} + +QList PluginFlagIconDelegate::getIcons(const QModelIndex &index) const +{ + QList result; + foreach (const QVariant &var, index.data(Qt::UserRole + 1).toList()) { + result.append(var.value()); + } + return result; +} + +size_t PluginFlagIconDelegate::getNumIcons(const QModelIndex &index) const +{ + return index.data(Qt::UserRole + 1).toList().count(); +} + diff --git a/src/pluginflagicondelegate.h b/src/pluginflagicondelegate.h new file mode 100644 index 00000000..554e968b --- /dev/null +++ b/src/pluginflagicondelegate.h @@ -0,0 +1,17 @@ +#ifndef PLUGINFLAGICONDELEGATE_H +#define PLUGINFLAGICONDELEGATE_H + +#include "icondelegate.h" + +class PluginFlagIconDelegate : public IconDelegate +{ +public: + PluginFlagIconDelegate(QObject *parent = NULL); + + // IconDelegate interface +private: + virtual QList getIcons(const QModelIndex &index) const; + virtual size_t getNumIcons(const QModelIndex &index) const; +}; + +#endif // PLUGINFLAGICONDELEGATE_H diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index 85137390..c2e14182 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -20,8 +20,10 @@ along with Mod Organizer. If not, see . #include "pluginlist.h" #include "report.h" #include "inject.h" -#include #include "settings.h" +#include "safewritefile.h" +#include "scopeguard.h" +#include #include #include #include @@ -39,7 +41,6 @@ along with Mod Organizer. If not, see . #include #include -#include #include #include #include @@ -74,8 +75,10 @@ bool ByDate(const PluginList::ESPInfo& LHS, const PluginList::ESPInfo& RHS) { } PluginList::PluginList(QObject *parent) - : QAbstractTableModel(parent), - m_FontMetrics(QFont()), m_SaveTimer(this) + : QAbstractTableModel(parent) + , m_FontMetrics(QFont()) + , m_SaveTimer(this) + , m_BOSS(NULL) { m_SaveTimer.setSingleShot(true); connect(&m_SaveTimer, SIGNAL(timeout()), this, SIGNAL(saveTimer())); @@ -92,6 +95,12 @@ PluginList::PluginList(QObject *parent) PluginList::~PluginList() { + if (m_BOSS != NULL) { + m_BOSS->DestroyBossDb(m_BOSSDB); + m_BOSS->CleanUpAPI(); + delete m_BOSS; + m_BOSS = NULL; + } } @@ -101,6 +110,7 @@ QString PluginList::getColumnName(int column) case COL_NAME: return tr("Name"); case COL_PRIORITY: return tr("Priority"); case COL_MODINDEX: return tr("Mod Index"); + case COL_FLAGS: return tr("Flags"); default: return tr("unknown"); } } @@ -205,7 +215,7 @@ void PluginList::refresh(const QString &profileName, const DirectoryEntry &baseD emit layoutChanged(); refreshLoadOrder(); - emit dataChanged(this->index(0, 0), this->index(m_ESPs.size(), 1)); + emit dataChanged(this->index(0, 0), this->index(m_ESPs.size(), columnCount())); m_Refreshed(); } @@ -375,18 +385,16 @@ void PluginList::readLockedOrderFrom(const QString &fileName) } + void PluginList::writePlugins(const QString &fileName, bool writeUnchecked) const { - QFile file(fileName); - if (!file.open(QIODevice::WriteOnly)) { - throw MyException(tr("failed to open output file: %1").arg(fileName)); - } + SafeWriteFile file(fileName); QTextCodec *textCodec = writeUnchecked ? m_Utf8Codec : m_LocalCodec; - file.resize(0); + file->resize(0); - file.write(textCodec->fromUnicode("# This file was automatically generated by Mod Organizer.\r\n")); + file->write(textCodec->fromUnicode("# This file was automatically generated by Mod Organizer.\r\n")); bool invalidFileNames = false; int writtenCount = 0; @@ -398,36 +406,34 @@ void PluginList::writePlugins(const QString &fileName, bool writeUnchecked) cons invalidFileNames = true; qCritical("invalid plugin name %s", m_ESPs[priority].m_Name.toUtf8().constData()); } else { - file.write(textCodec->fromUnicode(m_ESPs[priority].m_Name)); + file->write(textCodec->fromUnicode(m_ESPs[priority].m_Name)); } - file.write("\r\n"); + file->write("\r\n"); ++writtenCount; } } - file.close(); if (invalidFileNames) { reportError(tr("Some of your plugins have invalid names! These plugins can not be loaded by the game. " "Please see mo_interface.log for a list of affected plugins and rename them.")); } + file.commit(); + qDebug("%s saved", QDir::toNativeSeparators(fileName).toUtf8().constData()); } void PluginList::writeLockedOrder(const QString &fileName) const { - QFile file(fileName); - if (!file.open(QIODevice::WriteOnly)) { - throw MyException(tr("failed to open output file: %1").arg(fileName)); - } + SafeWriteFile file(fileName); - file.resize(0); - file.write(QString("# This file was automatically generated by Mod Organizer.\r\n").toUtf8()); + file->resize(0); + file->write(QString("# This file was automatically generated by Mod Organizer.\r\n").toUtf8()); for (auto iter = m_LockedOrder.begin(); iter != m_LockedOrder.end(); ++iter) { - file.write(QString("%1|%2\r\n").arg(iter->first).arg(iter->second).toUtf8()); + file->write(QString("%1|%2\r\n").arg(iter->first).arg(iter->second).toUtf8()); } - file.close(); + file.commit(); } @@ -590,6 +596,175 @@ void PluginList::refreshLoadOrder() emit layoutChanged(); } + +class boss_exception : public std::runtime_error { +public: + boss_exception(const std::string &message) : std::runtime_error(message) {} +}; + +#define THROW_BOSS_ERROR(obj) \ + uint8_t *message; \ + obj->GetLastErrorDetails(&message); \ + throw boss_exception(std::string(reinterpret_cast(message))); + +#define U8(text) reinterpret_cast(text) + + +void outputBossLog(const QString &filename) +{ + QFile file(filename); + if (file.open(QIODevice::ReadOnly)) { + while (!file.atEnd()) { + QByteArray line = file.readLine().trimmed(); + if (line.length() < 1) + continue; + + int endFirstWord = line.indexOf(':'); + if (endFirstWord < 0) { + endFirstWord = 0; + } + QString firstWord = line.mid(0, endFirstWord); + if (firstWord == "DEBUG") { + qDebug("(boss) %s", line.mid(endFirstWord + 2).constData()); + } else { + qWarning("(boss) %s", line.mid(endFirstWord + 2).constData()); + } + } + } + file.resize(0); +} + + +void PluginList::initBoss() +{ + m_BOSS = new BossDLL(TEXT("dlls\\boss.dll")); + + if (!m_BOSS->IsCompatibleVersion(2,1,1)) { + throw MyException(tr("BOSS dll incompatible")); + } + uint8_t *versionString; + if (m_BOSS->GetVersionString(&versionString) != BossDLL::RESULT_OK) { + THROW_BOSS_ERROR(m_BOSS) + } + qDebug("using boss version %s", versionString); + + m_TempFile.open(); m_TempFile.close(); // yeah, stupid, but open is required to generate the name + m_BOSS->SetLoggerOutput(m_TempFile.fileName().toLocal8Bit().constData(), 4); + + if (m_BOSS->CreateBossDb(&m_BOSSDB, BossDLL::SKYRIM, NULL) != BossDLL::RESULT_OK) { + uint8_t *message; + m_BOSS->GetLastErrorDetails(&message); + std::string messageCopy(reinterpret_cast(message)); + delete m_BOSS; + m_BOSS = NULL; + throw boss_exception(messageCopy); + } + qApp->processEvents(); + + QString masterlistName = QDir::toNativeSeparators(qApp->applicationDirPath() + "/boss/masterlist.txt"); + + uint32_t res = m_BOSS->UpdateMasterlist(m_BOSSDB, U8(masterlistName.toUtf8().constData())); + qApp->processEvents(); + if (res == BossDLL::RESULT_OK) { + qDebug("boss masterlist updated"); + } else if (res == BossDLL::RESULT_NO_UPDATE_NECESSARY) { + qDebug("boss masterlist already up-to-date"); + } else { + THROW_BOSS_ERROR(m_BOSS) + } + if (m_BOSS->Load(m_BOSSDB, + U8(masterlistName.toUtf8().constData()), + U8(QDir::toNativeSeparators(qApp->applicationDirPath() + "/boss/userlist.txt").toUtf8().constData())) != BossDLL::RESULT_OK) { + THROW_BOSS_ERROR(m_BOSS) + } +} + +void PluginList::convertPluginListForBoss(boost::ptr_vector &inputPlugins, std::vector &activePlugins) +{ + foreach (int idx, m_ESPsByPriority) { + QString fileName = m_ESPs[idx].m_Name; + QByteArray name = fileName.toUtf8(); + + uint8_t *nameU8 = new uint8_t[name.length() + 1]; + memcpy(nameU8, name.constData(), name.length() + 1); + if (m_ESPs[idx].m_Enabled) { + activePlugins.push_back(nameU8); + } + inputPlugins.push_back(nameU8); + } + if (m_BOSS->SetActivePluginsDumb(m_BOSSDB, &activePlugins[0], activePlugins.size()) != BossDLL::RESULT_OK) { + THROW_BOSS_ERROR(m_BOSS) + } +} + +void PluginList::applyBOSSSorting(uint8_t **pluginList, size_t size, int &priority, bool recognized, const char *extension) +{ + for (size_t i= 0; i < size; ++i) { + QString name = QString::fromUtf8(reinterpret_cast(pluginList[i])).toLower(); + if (name.endsWith(extension)) { + auto iter = m_ESPsByName.find(name); + if (iter == m_ESPsByName.end()) { + throw MyException("boss returned invalid data"); + } + BossMessage *message; + size_t numMessages = 0; + m_BOSS->GetPluginMessages(m_BOSSDB, pluginList[i], &message, &numMessages); + m_ESPs[iter->second].m_BOSSMessages.clear(); + for (size_t im = 0; im < numMessages; ++im) { + m_ESPs[iter->second].m_BOSSMessages.append(QString::fromUtf8(reinterpret_cast(message[im].message))); + } + m_ESPs[iter->second].m_Priority = priority++; + m_ESPs[iter->second].m_BOSSUnrecognized = !recognized; + } + } +} + +void PluginList::bossSort() +{ + if (m_BOSS == NULL) { + // first run, check boss compatibility and update + initBoss(); + } + + // create a boss-compatible representation of our current mod list. + boost::ptr_vector inputPlugins; + std::vector activePlugins; + convertPluginListForBoss(inputPlugins, activePlugins); + + // sort mods in-memory + uint8_t **sortedPlugins; + uint8_t **unrecognizedPlugins; + size_t sizeSorted, sizeUnrecognized; + + if (m_BOSS->SortCustomMods(m_BOSSDB, + inputPlugins.c_array(), inputPlugins.size(), + &sortedPlugins, &sizeSorted, + &unrecognizedPlugins, &sizeUnrecognized) != BossDLL::RESULT_OK) { + THROW_BOSS_ERROR(m_BOSS) + } + + // output the log from boss to our own log to make it visible + outputBossLog(m_TempFile.fileName()); + + qDebug("%d sorted, %d unrecognized", sizeSorted, sizeUnrecognized); + + emit layoutAboutToBeChanged(); + + int priority = 0; + applyBOSSSorting(sortedPlugins, sizeSorted, priority, true, "esm"); + applyBOSSSorting(unrecognizedPlugins, sizeUnrecognized, priority, false, "esm"); + applyBOSSSorting(sortedPlugins, sizeSorted, priority, true, "esp"); + applyBOSSSorting(unrecognizedPlugins, sizeUnrecognized, priority, false, "esp"); + + // inform view of the changed data + updateIndices(); + emit layoutChanged(); + syncLoadOrder(); + + emit dataChanged(this->index(0, 0), this->index(m_ESPs.size(), columnCount())); + m_Refreshed(); +} + IPluginList::PluginState PluginList::state(const QString &name) const { auto iter = m_ESPsByName.find(name.toLower()); @@ -670,7 +845,7 @@ int PluginList::rowCount(const QModelIndex &parent) const int PluginList::columnCount(const QModelIndex &) const { - return 3; + return COL_LASTCOLUMN + 1; } @@ -724,18 +899,6 @@ QVariant PluginList::data(const QModelIndex &modelIndex, int role) const return QVariant(); } break; } - } else if ((role == Qt::DecorationRole) && (modelIndex.column() == 0)) { - if (m_ESPs[index].m_MasterUnset.size() > 0) { - return QIcon(":/MO/gui/warning"); - } else if (m_LockedOrder.find(m_ESPs[index].m_Name.toLower()) != m_LockedOrder.end()) { - return QIcon(":/MO/gui/locked"); - } else if (m_ESPs[index].m_HasIni) { - return QIcon(":/MO/gui/attachment"); - } else if (m_ESPs[index].m_IsDummy && m_ESPs[index].m_Enabled && !m_ESPs[index].m_HasIni) { - return QIcon(":/MO/gui/edit_clear"); - } else { - return QVariant(); - } } else if ((role == Qt::CheckStateRole) && (modelIndex.column() == 0)) { return m_ESPs[index].m_Enabled ? Qt::Checked : Qt::Unchecked; } else if (role == Qt::FontRole) { @@ -754,8 +917,15 @@ QVariant PluginList::data(const QModelIndex &modelIndex, int role) const return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); } } else if (role == Qt::ToolTipRole) { + QString toolTip; + if (!m_ESPs[index].m_BOSSMessages.isEmpty()) { + toolTip += m_ESPs[index].m_BOSSMessages.join("
      ") + "

      "; + } + if (m_ESPs[index].m_BOSSUnrecognized) { + toolTip += "Not recognized by BOSS
      "; + } if (m_ESPs[index].m_ForceEnabled) { - return tr("This plugin can't be disabled (enforced by the game)"); + toolTip += tr("This plugin can't be disabled (enforced by the game)"); } else { QString text = tr("Origin: %1").arg(m_ESPs[index].m_OriginName); if (m_ESPs[index].m_MasterUnset.size() > 0) { @@ -773,8 +943,30 @@ QVariant PluginList::data(const QModelIndex &modelIndex, int role) const text += "
      This file is a dummy! It exists only so the bsa with the same name gets loaded. With MO you don't need this: " "If you enable the archive with the same name in the \"Archive\" tab you can disable this plugin."; } - return text; + toolTip += text; + } + return toolTip; + } else if (role == Qt::UserRole + 1) { + QVariantList result; + if (m_ESPs[index].m_MasterUnset.size() > 0) { + result.append(QIcon(":/MO/gui/warning")); + } + if (m_LockedOrder.find(m_ESPs[index].m_Name.toLower()) != m_LockedOrder.end()) { + result.append(QIcon(":/MO/gui/locked")); } + if (!m_ESPs[index].m_BOSSMessages.isEmpty()) { + result.append(QIcon(":/MO/gui/information")); + } + if (m_ESPs[index].m_BOSSUnrecognized) { + result.append(QIcon(":/MO/gui/help")); + } + if (m_ESPs[index].m_HasIni) { + result.append(QIcon(":/MO/gui/attachment")); + } + if (m_ESPs[index].m_IsDummy && m_ESPs[index].m_Enabled && !m_ESPs[index].m_HasIni) { + result.append(QIcon(":/MO/gui/edit_clear")); + } + return result; } else { return QVariant(); } @@ -784,7 +976,6 @@ QVariant PluginList::data(const QModelIndex &modelIndex, int role) const bool PluginList::setData(const QModelIndex &modIndex, const QVariant &value, int role) { if (role == Qt::CheckStateRole) { -qDebug("uncheck plugin"); m_ESPs[modIndex.row()].m_Enabled = value.toInt() == Qt::Checked; emit dataChanged(modIndex, modIndex); @@ -1036,7 +1227,8 @@ PluginList::ESPInfo::ESPInfo(const QString &name, bool enabled, FILETIME time, const QString &originName, const QString &fullPath, bool hasIni) : m_Name(name), m_Enabled(enabled), m_ForceEnabled(enabled), m_Removed(false), - m_Priority(0), m_LoadOrder(-1), m_Time(time), m_OriginName(originName), m_HasIni(hasIni) + m_Priority(0), m_LoadOrder(-1), m_Time(time), m_OriginName(originName), m_HasIni(hasIni), + m_BOSSUnrecognized(false) { try { ESP::File file(ToWString(fullPath)); diff --git a/src/pluginlist.h b/src/pluginlist.h index 64c914df..bb7428d0 100644 --- a/src/pluginlist.h +++ b/src/pluginlist.h @@ -25,8 +25,12 @@ along with Mod Organizer. If not, see . #include #include #include +#include #include +#include #include +#include +#include /** @@ -40,6 +44,7 @@ public: enum EColumn { COL_NAME, + COL_FLAGS, COL_PRIORITY, COL_MODINDEX, @@ -143,6 +148,8 @@ public: void refreshLoadOrder(); + void bossSort(); + public: virtual PluginState state(const QString &name) const; virtual int priority(const QString &name) const; @@ -162,6 +169,7 @@ public: // implementation of the QAbstractTableModel interface virtual Qt::DropActions supportedDropActions() const { return Qt::MoveAction; } virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); + void applyBOSSSorting(uint8_t **pluginList, size_t size, int &priority, bool recognized, const char *extension); public slots: /** @@ -194,7 +202,6 @@ private: ESPInfo(const QString &name, bool enabled, FILETIME time, const QString &originName, const QString &fullPath, bool hasIni); QString m_Name; - QString m_FullPath; bool m_Enabled; bool m_ForceEnabled; bool m_Removed; @@ -207,12 +214,91 @@ private: bool m_HasIni; std::set m_Masters; mutable std::set m_MasterUnset; + QStringList m_BOSSMessages; + bool m_BOSSUnrecognized; }; friend bool ByName(const ESPInfo& LHS, const ESPInfo& RHS); friend bool ByDate(const ESPInfo& LHS, const ESPInfo& RHS); friend bool ByPriority(const ESPInfo& LHS, const ESPInfo& RHS); + + class BossDLL : public PDLL { + DECLARE_CLASS(BossDLL) + + DECLARE_FUNCTION3(__cdecl, uint32_t, CreateBossDb, boss_db*, const uint32_t, const uint8_t*) + DECLARE_FUNCTION1(__cdecl, void, DestroyBossDb, boss_db) + DECLARE_FUNCTION0(__cdecl, void, CleanUpAPI) + + DECLARE_FUNCTION7(__cdecl, uint32_t, SortCustomMods, boss_db, uint8_t**, size_t, uint8_t***, size_t*, uint8_t***, size_t*) + DECLARE_FUNCTION3(__cdecl, uint32_t, SetActivePluginsDumb, boss_db, uint8_t**, const size_t) + + DECLARE_FUNCTION3(__cdecl, uint32_t, GetActivePluginsDumb , boss_db, uint8_t***, size_t*) + + DECLARE_FUNCTION2(__cdecl, uint32_t, UpdateMasterlist, boss_db, const uint8_t*) + DECLARE_FUNCTION3(__cdecl, uint32_t, Load, boss_db, const uint8_t*, const uint8_t*) + + DECLARE_FUNCTION2(__cdecl, void, SetLoggerOutput, const char*, uint8_t) + DECLARE_FUNCTION1(__cdecl, uint32_t, GetLastErrorDetails, uint8_t**) + + DECLARE_FUNCTION1(__cdecl, uint32_t, GetVersionString, uint8_t**) + DECLARE_FUNCTION3(__cdecl, bool, IsCompatibleVersion, const uint32_t, const uint32_t, const uint32_t) + + DECLARE_FUNCTION4(__cdecl, uint32_t, GetPluginMessages, boss_db, const uint8_t*, BossMessage**, size_t*) + + enum ResultCode { + RESULT_OK = 0, + RESULT_NO_MASTER_FILE = 1, + RESULT_FILE_READ_FAIL = 2, + RESULT_FILE_WRITE_FAIL = 3, + RESULT_FILE_NOT_UTF8 = 4, + RESULT_FILE_NOT_FOUND = 5, + RESULT_FILE_PARSE_FAIL = 6, + RESULT_CONDITION_EVAL_FAIL = 7, + RESULT_REGEX_EVAL_FAIL = 8, + RESULT_NO_GAME_DETECTED = 9, + RESULT_ENCODING_CONVERSION_FAIL = 10, + RESULT_FIND_ONLINE_MASTERLIST_REVISION_FAIL = 11, + RESULT_FIND_ONLINE_MASTERLIST_DATE_FAIL = 12, + RESULT_READ_UPDATE_FILE_LIST_FAIL = 13, + RESULT_FILE_CRC_MISMATCH = 14, + RESULT_FS_FILE_MOD_TIME_READ_FAIL = 15, + RESULT_FS_FILE_MOD_TIME_WRITE_FAIL = 16, + RESULT_FS_FILE_RENAME_FAIL = 17, + RESULT_FS_FILE_DELETE_FAIL = 18, + RESULT_FS_CREATE_DIRECTORY_FAIL = 19, + RESULT_FS_ITER_DIRECTORY_FAIL = 20, + RESULT_CURL_INIT_FAIL = 21, + RESULT_CURL_SET_ERRBUFF_FAIL = 22, + RESULT_CURL_SET_OPTION_FAIL = 23, + RESULT_CURL_SET_PROXY_FAIL = 24, + RESULT_CURL_SET_PROXY_TYPE_FAIL = 25, + RESULT_CURL_SET_PROXY_AUTH_FAIL = 26, + RESULT_CURL_SET_PROXY_AUTH_TYPE_FAIL = 27, + RESULT_CURL_PERFORM_FAIL = 28, + RESULT_CURL_USER_CANCEL = 29, + RESULT_GUI_WINDOW_INIT_FAIL = 30, + RESULT_NO_UPDATE_NECESSARY = 31, + RESULT_LO_MISMATCH = 32, + RESULT_NO_MEM = 33, + RESULT_INVALID_ARGS = 34, + RESULT_NETWORK_FAIL = 35, + RESULT_NO_INTERNET_CONNECTION = 36, + RESULT_NO_TAG_MAP = 37, + RESULT_PLUGINS_FULL = 38, + RESULT_PLUGIN_BEFORE_MASTER = 39, + RESULT_INVALID_SYNTAX = 40 + }; + + enum GameIDs { + AUTODETECT = 0, + OBLIVION = 1, + SKYRIM = 3, + FALLOUT3 = 4, + FALLOUTNV = 5 + }; + }; + private: void syncLoadOrder(); @@ -230,6 +316,9 @@ private: void testMasters(); + void initBoss(); + void convertPluginListForBoss(boost::ptr_vector &inputPlugins, std::vector &activePlugins); + private: std::vector m_ESPs; @@ -253,6 +342,10 @@ private: SignalRefreshed m_Refreshed; + BossDLL *m_BOSS; + boss_db m_BOSSDB; + QTemporaryFile m_TempFile; + }; #endif // PLUGINLIST_H diff --git a/src/pluginlistsortproxy.cpp b/src/pluginlistsortproxy.cpp index 5bff24f5..8412fa27 100644 --- a/src/pluginlistsortproxy.cpp +++ b/src/pluginlistsortproxy.cpp @@ -125,11 +125,6 @@ bool PluginListSortProxy::lessThan(const QModelIndex &left, return plugins->getPriority(left.row()) < plugins->getPriority(right.row()); } break; default: { - static bool first = true; - if (first) { - qCritical("invalid sort column %d", left.column()); - first = false; - } return plugins->getPriority(left.row()) < plugins->getPriority(right.row()); } break; } diff --git a/src/profile.cpp b/src/profile.cpp index e075a4e6..c1f1025e 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -23,6 +23,7 @@ along with Mod Organizer. If not, see . #include "windows_error.h" #include "dummybsa.h" #include "modinfo.h" +#include "safewritefile.h" #include #include #include @@ -149,15 +150,10 @@ void Profile::writeModlistNow(bool onlyOnTimer) const #pragma message("right now, this is doing unnecessary saves. Need a flag that says that mod priority, enabled-state or name of a mod has changed") try { - QTemporaryFile file; - - if (!file.open()) { - reportError(tr("failed to open temporary file")); - return; - } + QString fileName = getModlistFileName(); + SafeWriteFile file(fileName); - file.resize(0); - file.write(QString("# This file was automatically generated by Mod Organizer.\r\n").toUtf8()); + file->write(QString("# This file was automatically generated by Mod Organizer.\r\n").toUtf8()); if (m_ModStatus.empty()) { return; } @@ -169,29 +165,17 @@ void Profile::writeModlistNow(bool onlyOnTimer) const ModInfo::Ptr modInfo = ModInfo::getByIndex(index); if (modInfo->getFixedPriority() == INT_MIN) { if (m_ModStatus[index].m_Enabled) { - file.write("+"); + file->write("+"); } else { - file.write("-"); + file->write("-"); } - file.write(modInfo->name().toUtf8()); - file.write("\r\n"); + file->write(modInfo->name().toUtf8()); + file->write("\r\n"); } } } - file.close(); - - - QString fileName = getModlistFileName(); - - if (QFile::exists(fileName)) { - shellDeleteQuiet(fileName); - } - - if (!file.copy(fileName)) { - reportError(tr("failed to open \"%1\" for writing").arg(fileName)); - return; - } + file.commit(); qDebug("%s saved", QDir::toNativeSeparators(fileName).toUtf8().constData()); } catch (const std::exception &e) { diff --git a/src/resources.qrc b/src/resources.qrc index 1582a3f2..73921f64 100644 --- a/src/resources.qrc +++ b/src/resources.qrc @@ -18,7 +18,7 @@ resources/contact-new.png resources/preferences-system.png resources/application-x-executable.png - resources/dialog-information.png + resources/dialog-information.png resources/emblem-readonly.png resources/go-next_16.png resources/go-previous_16.png diff --git a/src/safewritefile.cpp b/src/safewritefile.cpp new file mode 100644 index 00000000..6df8c2b8 --- /dev/null +++ b/src/safewritefile.cpp @@ -0,0 +1,48 @@ +/* +Copyright (C) 2014 Sebastian Herbord. All rights reserved. + +This file is part of Mod Organizer. + +Mod Organizer is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Mod Organizer is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Mod Organizer. If not, see . +*/ + + +#include "safewritefile.h" +#include + + +using namespace MOBase; + + +SafeWriteFile::SafeWriteFile(const QString &fileName) +: m_FileName(fileName) +{ + if (!m_TempFile.open()) { + throw MyException(QObject::tr("failed to open temporary file")); + } +} + + +QFile *SafeWriteFile::operator->() { + Q_ASSERT(m_TempFile.isOpen()); + return &m_TempFile; +} + + +void SafeWriteFile::commit() { + shellDeleteQuiet(m_FileName); + m_TempFile.rename(m_FileName); + m_TempFile.setAutoRemove(false); + m_TempFile.close(); +} diff --git a/src/safewritefile.h b/src/safewritefile.h new file mode 100644 index 00000000..56bd7744 --- /dev/null +++ b/src/safewritefile.h @@ -0,0 +1,51 @@ +/* +Copyright (C) 2014 Sebastian Herbord. All rights reserved. + +This file is part of Mod Organizer. + +Mod Organizer is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Mod Organizer is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Mod Organizer. If not, see . +*/ + + +#ifndef SAFEWRITEFILE_H +#define SAFEWRITEFILE_H + + +#include +#include +#include + +/** + * @brief a wrapper for QFile that ensures the file is only actually (over-)written if writing was successful + */ +class SafeWriteFile { +public: + SafeWriteFile(const QString &fileName); + + QFile *operator->(); + + void commit(); + +private: + QString m_FileName; + QTemporaryFile m_TempFile; +}; + + +#endif // SAFEWRITEFILE_H + + + + + -- cgit v1.3.1 From 9c8e43853dfeb6ac80faffe0960222ff0f087fd3 Mon Sep 17 00:00:00 2001 From: Tannin Date: Wed, 12 Feb 2014 21:00:49 +0100 Subject: - a few hooks will now somewhat handle file names starting with \\?\ - mod meta information is now (also) saved by a timer to reduce the likelyhood of a data loss in case of a crash - mod meta files are now written to a temporary file and then renamed to real name to reduce chance of breaking the file - updated minimum compatible nmm version to 0.47.0 - bugfix: defaults for newestVersion, version and installationFile when creating an empty mod were integers instead of strings - bugfix: "Plugins" and "Archives" weren't translatable --- src/mainwindow.cpp | 19 +- src/mainwindow.h | 3 + src/mainwindow.ui | 4 +- src/modinfo.cpp | 62 ++++-- src/modinfo.h | 2 +- src/organizer_cs.ts | 498 ++++++++++++++++++++++++------------------------ src/organizer_de.ts | 500 +++++++++++++++++++++++++------------------------ src/organizer_es.ts | 500 +++++++++++++++++++++++++------------------------ src/organizer_fr.ts | 500 +++++++++++++++++++++++++------------------------ src/organizer_ru.ts | 498 ++++++++++++++++++++++++------------------------ src/organizer_tr.ts | 500 +++++++++++++++++++++++++------------------------ src/organizer_zh_CN.ts | 498 ++++++++++++++++++++++++------------------------ src/organizer_zh_TW.ts | 498 ++++++++++++++++++++++++------------------------ src/settings.cpp | 2 +- 14 files changed, 2111 insertions(+), 1973 deletions(-) (limited to 'src/mainwindow.ui') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index d83d4d06..12db5e2b 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -295,6 +295,10 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget m_CheckBSATimer.setSingleShot(true); connect(&m_CheckBSATimer, SIGNAL(timeout()), this, SLOT(checkBSAList())); + m_SaveMetaTimer.setSingleShot(false); + connect(&m_SaveMetaTimer, SIGNAL(timeout()), this, SLOT(saveModMetas())); + m_SaveMetaTimer.start(5000); + m_DirectoryRefresher.moveToThread(&m_RefresherThread); m_RefresherThread.start(); @@ -1208,10 +1212,10 @@ IModInterface *MainWindow::createMod(GuessedValue &name) QSettings settingsFile(targetDirectory.mid(0).append("/meta.ini"), QSettings::IniFormat); settingsFile.setValue("modid", 0); - settingsFile.setValue("version", 0); - settingsFile.setValue("newestVersion", 0); + settingsFile.setValue("version", ""); + settingsFile.setValue("newestVersion", ""); settingsFile.setValue("category", 0); - settingsFile.setValue("installationFile", 0); + settingsFile.setValue("installationFile", ""); return ModInfo::createFrom(QDir(targetDirectory), &m_DirectoryStructure).data(); // } } @@ -1956,6 +1960,15 @@ void MainWindow::checkBSAList() } +void MainWindow::saveModMetas() +{ + for (unsigned int i = 0; i < ModInfo::getNumMods(); ++i) { + ModInfo::Ptr modInfo = ModInfo::getByIndex(i); + modInfo->saveMeta(); + } + } + + void MainWindow::fixCategories() { for (unsigned int i = 0; i < ModInfo::getNumMods(); ++i) { diff --git a/src/mainwindow.h b/src/mainwindow.h index 527db8b3..250f2a48 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -352,6 +352,7 @@ private: bool m_DirectoryUpdate; bool m_ArchivesInit; QTimer m_CheckBSATimer; + QTimer m_SaveMetaTimer; QTime m_StartTime; SaveGameInfoWidget *m_CurrentSaveView; @@ -495,6 +496,8 @@ private slots: void startExeAction(); void checkBSAList(); + void saveModMetas(); + void updateStyle(const QString &style); void modlistChanged(const QModelIndex &index, int role); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index f3bb425c..110c14c6 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -602,7 +602,7 @@ p, li { white-space: pre-wrap; }
      - Plugins + Plugins @@ -738,7 +738,7 @@ p, li { white-space: pre-wrap; } - Archives + Archives diff --git a/src/modinfo.cpp b/src/modinfo.cpp index 85612b32..ff44b392 100644 --- a/src/modinfo.cpp +++ b/src/modinfo.cpp @@ -373,26 +373,48 @@ void ModInfoRegular::saveMeta() { // only write meta data if the mod directory exists if (m_MetaInfoChanged && QFile::exists(absolutePath())) { - QSettings metaFile(absolutePath().append("/meta.ini"), QSettings::IniFormat); - if (metaFile.status() == QSettings::NoError) { - std::set temp = m_Categories; - temp.erase(m_PrimaryCategory); - metaFile.setValue("category", QString("%1").arg(m_PrimaryCategory) + "," + SetJoin(temp, ",")); - metaFile.setValue("newestVersion", m_NewestVersion.canonicalString()); - metaFile.setValue("ignoredVersion", m_IgnoredVersion.canonicalString()); - metaFile.setValue("version", m_Version.canonicalString()); - metaFile.setValue("modid", m_NexusID); - metaFile.setValue("notes", m_Notes); - metaFile.setValue("nexusDescription", m_NexusDescription); - metaFile.setValue("lastNexusQuery", m_LastNexusQuery.toString(Qt::ISODate)); - if (m_EndorsedState != ENDORSED_UNKNOWN) { - metaFile.setValue("endorsed", m_EndorsedState); + bool success = false; + { + QSettings metaFile(absolutePath().append("/meta.ini.new"), QSettings::IniFormat); + if (metaFile.status() == QSettings::NoError) { + std::set temp = m_Categories; + temp.erase(m_PrimaryCategory); + metaFile.setValue("category", QString("%1").arg(m_PrimaryCategory) + "," + SetJoin(temp, ",")); + metaFile.setValue("newestVersion", m_NewestVersion.canonicalString()); + metaFile.setValue("ignoredVersion", m_IgnoredVersion.canonicalString()); + metaFile.setValue("version", m_Version.canonicalString()); + if (m_NexusID != -1) { + metaFile.setValue("modid", m_NexusID); + } + metaFile.setValue("notes", m_Notes); + metaFile.setValue("nexusDescription", m_NexusDescription); + metaFile.setValue("lastNexusQuery", m_LastNexusQuery.toString(Qt::ISODate)); + if (m_EndorsedState != ENDORSED_UNKNOWN) { + metaFile.setValue("endorsed", m_EndorsedState); + } + metaFile.sync(); // sync needs to be called to ensure the file is created + + if (metaFile.status() == QSettings::NoError) { + success = true; + m_MetaInfoChanged = false; + } else { + reportError(tr("failed to write %1/meta.ini: error %2").arg(absolutePath()).arg(metaFile.status())); + } + } else { + reportError(tr("failed to write %1/meta.ini: error %2").arg(absolutePath()).arg(metaFile.status())); + } + } + if (success) { + if (!QFile::remove(absolutePath().append("/meta.ini"))) { + qCritical("failed to remove %s", qPrintable(absolutePath().append("/meta.ini"))); + return; + } + if (QFile::rename(absolutePath().append("/meta.ini.new"), absolutePath().append("/meta.ini"))) { + qDebug("%s written", qPrintable(absolutePath().append("/meta.ini"))); + } else { + qCritical("writing %s failed", qPrintable(absolutePath().append("/meta.ini"))); } - metaFile.sync(); // sync needs to be called to ensure the file is created - } else { - reportError(tr("failed to write %1/meta.ini: %2").arg(absolutePath()).arg(metaFile.status())); } - m_MetaInfoChanged = false; } } @@ -556,6 +578,10 @@ void ModInfoRegular::setVersion(const VersionInfo &version) m_MetaInfoChanged = true; } +void ModInfoRegular::setNewestVersion(const VersionInfo &version) { + m_NewestVersion = version; +} + void ModInfoRegular::setNexusDescription(const QString &description) { m_NexusDescription = description; diff --git a/src/modinfo.h b/src/modinfo.h index 83654c7e..b7d72584 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -592,7 +592,7 @@ public: * @todo this function should be made obsolete. All queries for mod information should go through * this class so no public function for this change is required **/ - void setNewestVersion(const MOBase::VersionInfo &version) { m_NewestVersion = version; } + void setNewestVersion(const MOBase::VersionInfo &version); /** * @brief changes/updates the nexus description text diff --git a/src/organizer_cs.ts b/src/organizer_cs.ts index 08f8d70e..654ca00c 100644 --- a/src/organizer_cs.ts +++ b/src/organizer_cs.ts @@ -1638,11 +1638,21 @@ BSAs checked here are loaded in such a way that your installation order is obeye Data Data + + + Plugins + + Sort + + + Archives + + refresh data-directory overview @@ -1655,8 +1665,8 @@ BSAs checked here are loaded in such a way that your installation order is obeye - - + + Refresh Znovunačíst @@ -1836,7 +1846,7 @@ p, li { white-space: pre-wrap; } - + Update @@ -1847,7 +1857,7 @@ p, li { white-space: pre-wrap; } - + No Problems Žádné problémy @@ -1880,37 +1890,37 @@ V současnosti má omezenou funkcionalitu - + Endorse Mod Organizer - + Toolbar - + Desktop - + Start Menu - + Problems Problémy - + There are potential problems with your setup Existují potenciální problémy s programem - + Everything seems to be in order Všechno se jeví v pořádku @@ -1927,22 +1937,22 @@ V současnosti má omezenou funkcionalitu <li>dotNet není nainstalován nebo je neaktuální. Tohle vyžaduje NCC. Najděte ho zde: <a href="%1">%1</a></li> - + Help on UI Pomoc s programem - + Documentation Wiki Dokumentace wiki - + Report Issue Nahlásit chybu - + Tutorials @@ -1951,93 +1961,92 @@ V současnosti má omezenou funkcionalitu pořadí načtení se nezdařilo uložit - + failed to save load order: %1 zlyhalo uložení pořadí načtení: %1 - failed to save archives order, do you have write access to "%1"? - zlyhal zápis pořadí archivů, máte administrátorsky povoleno zapisovat na "%1"? + zlyhal zápis pořadí archivů, máte administrátorsky povoleno zapisovat na "%1"? - + About - + About Qt - + Name Jméno - + Please enter a name for the new profile Prosím zadej jméno pro nový profil - + failed to create profile: %1 Zlyhalo vytvoření profilu: %1 - + Show tutorial? - + You are starting Mod Organizer for the first time. Do you want to show a tutorial of its basic features? If you choose no you can always start the tutorial from the "Help"-menu. - + Downloads in progress Probíhá stahování - + There are still downloads in progress, do you really want to quit? Pořád probíhá stahování, určitě chcete skončit (zruší stahování)? - + failed to read savegame: %1 nezdařilo se načíst pozici: %1 - + Plugin "%1" failed: %2 - + Plugin error - + It appears the plugin "%1" failed to load last startup and caused MO to crash. Do you want to disable it? (Please note: If this is the first time you see this message for this plugin you may want to give it another try. The plugin may be able to recover from the problem) - + Failed to start "%1" Zlyhal start "%1" - + Waiting Čekání - + Please press OK once you're logged into steam. Stiskni OK až budeš přihlášen do Steamu. @@ -2046,331 +2055,336 @@ V současnosti má omezenou funkcionalitu "%1" nenalezeno - + Start Steam? Spustit Steam? - + Steam is required to be running already to correctly start the game. Should MO try to start steam now? Steam by měl běžet aby se podařilo spustit hru. Má se MO pokusit spustit steam teď? - + Also in: <br> Také v: <br> - + No conflict Žádné konflikty - + <Edit...> <Edit...> - + This bsa is enabled in the ini file so it may be required! Tenhle BSA soubor je aktivován v ini souboru, tak zřejmě je vyžadován! - + This archive will still be loaded since there is a plugin of the same name but its files will not follow installation order! Tento archív se stejně načte, protože existuje plugin se stejným jménem ale jeho soubory nebudou zodpovídat pořadí nainstalování! - + Activating Network Proxy - - + + Installation successful Instalace úspěšná - - + + Configure Mod Konfigurace Modu - - + + This mod contains ini tweaks. Do you want to configure them now? Tenhle mod obsahuje ini úpravy. Chcete je nastavovat teď? - - + + mod "%1" not found mod "%1" nenalezen - - + + Installation cancelled Instalace zrušena - - + + The mod was not installed completely. Tento mod se nenainstaloval úplne. - + Some plugins could not be loaded - + Too many esps and esms enabled - - + + Description missing - + The game doesn't allow more than 255 active plugins (including the official ones) to be loaded. You have to disable some unused plugins or merge some plugins into one. You can find a guide here: <a href="http://wiki.step-project.com/Guide:Merging_Plugins">http://wiki.step-project.com/Guide:Merging_Plugins</a> - + Choose Mod Vyber Mod - + Mod Archive Archív Modu - + Start Tutorial? - + You're about to start a tutorial. For technical reasons it's not possible to end the tutorial early. Continue? - - + + Download started Stahování začalo - + failed to update mod list: %1 nezdařilo se aktualizovat seznam modů: %1 - + failed to spawn notepad.exe: %1 zlyhalo otevření notepad.exe: %1 - + failed to open %1 - + failed to change origin name: %1 Nezdařilo se změnit původní jméno: %1 - + + failed to move "%1" from mod "%2" to "%3": %4 + + + + Multiple esps activated, please check that they don't conflict. - - + + Create Mod... - + A mod with this name already exists - + Continue? - + The versioning scheme decides which version is considered newer than another. This function will guess the versioning scheme under the assumption that the installed version is outdated. - - + + Sorry - + I don't know a versioning scheme where %1 is newer than %2. - + <All> <Všechny> - + <Checked> <Aktivované> - + Plugin "%1" failed - + failed to init plugin %1: %2 - + The following plugins could not be loaded. The reason may be missing dependencies (i.e. python) or an outdated version: - + <Unchecked> <Neaktivované> - + <Update> <Aktualizace> - + <No category> <Bez kategorie> - + <Conflicted> - + <Not Endorsed> - + failed to rename mod: %1 Nezdařilo se přejmenovat mod: %1 - + Overwrite? - + This will replace the existing mod "%1". Continue? - + failed to remove mod "%1" - - - + + + failed to rename "%1" to "%2" Nezdařilo se přejmenovat "%1" na "%2" - - - - + + + + Confirm Potvrdit - + Remove the following mods?<br><ul>%1</ul> - + failed to remove mod: %1 Nezdařilo se odstranit mod: %1 - - + + Failed Zlyhání - + Installation file no longer exists Instalační soubor již neexistuje - + Mods installed with old versions of MO can't be reinstalled in this way. Mody nainstalovány staršími verzemi MO nemůžou být přeinstalovány tímto spůsobem. - - + + You need to be logged in with Nexus to endorse - - + + Extract BSA Extrakce BSA - + This mod contains at least one BSA. Do you want to unpack it? (This removes the BSA after completion. If you don't know about BSAs, just select no) Tento mod obsahuje alespoň jeden BSA soubor. Chcete rozpakovat i jeho obsah? (BSA se po úspěšném rozpakování odstrání. Pokud nevíte, co je BSA, zvolte možnost Ne) - - - + + + failed to read %1: %2 - - + + This archive contains invalid hashes. Some files may be broken. Tento archiv má neplatné identifikační součty. Nekteré soubory mohou být poškozeny. - + Nexus ID for this Mod is unknown Nexus ID pro tento Mod není známo @@ -2383,92 +2397,92 @@ This function will guess the versioning scheme under the assumption that the ins Zvol Prioritu - + Really enable all visible mods? Opravdu aktivovat všechny zobrazené mody? - + Really disable all visible mods? Opravdu deaktivovat všechny zobrazené mody? - + Choose what to export - + Everything - + All installed mods are included in the list - + Active Mods - + Only active (checked) mods from your current profile are included - + Visible - + All mods visible in the mod list are included - + export failed: %1 - + Install Mod... Instaluj Mod... - + Enable all visible Aktivuj všechny v seznamu - + Disable all visible Deaktivuj všechny v seznamu - + Check all for update Skontroluj všechny pro aktualizaci - + Export to csv... - + Sync to Mods... Synchronizuj s Mody... - + Restore Backup - + Remove Backup... @@ -2477,362 +2491,362 @@ This function will guess the versioning scheme under the assumption that the ins Označ Kategorii - + Primary Category - + Change versioning scheme - + Un-ignore update - + Ignore update - + Rename Mod... Přejmenuj Mod... - + Remove Mod... Odstranit Mod... - + Reinstall Mod Přeinstaluj Mod - + Un-Endorse - - + + Endorse - + Won't endorse - + Endorsement state unknown - + Ignore missing data - + Visit on Nexus Navštiv na Nexusu - + Open in explorer Otevři v prohlížeči - + Information... Informace... - - + + Exception: Výnimky: - - + + Unknown exception Neznámá výnimka - + <Multiple> - + Really delete "%1"? - + Fix Mods... Oprav Mody... - + Delete - - + + failed to remove %1 - - + + failed to create %1 - + Can't change download directory while downloads are in progress! Není možné změnit cíl pro stahování když probíhá stahování! - + Download failed Stahování zlyhalo - + failed to write to file %1 Nezdařil se zápis do souboru %1 - + %1 written %1 zapsáno - + Select binary Vyber binární soubor - + Binary Soubor - + Enter Name Zadej jméno - + Please enter a name for the executable Prosím zadej jméno pro spouštění - + Not an executable Není spustitelný - + This is not a recognized executable. Tenhle soubor není rozpoznán jako spustitelný. - - + + Replace file? Nahradit soubor? - + There already is a hidden version of this file. Replace it? Už existuje skrytá verze tohto souboru. Nahradit? - - + + File operation failed Operace se souborem zlyhala - - + + Failed to remove "%1". Maybe you lack the required file permissions? Nepodařilo se odstranit "%1". Možná nejsou k dispozici požadována práva? - + There already is a visible version of this file. Replace it? Už existuje viditelná verze tohto souboru. Nahradit? - + file not found: %1 soubor nenalezen: %1 - + failed to generate preview for %1 - + Sorry, can't preview anything. This function currently does not support extracting from bsas. - + Update available Aktualizace k dispozici - + Open/Execute Otevřít/Spustit - + Add as Executable Přidat Spouštení - + Preview - + Un-Hide Odekrýt - + Hide Skrýt - + Write To File... Zápis do souboru... - + Do you want to endorse Mod Organizer on %1 now? - + Remove - + Unlock load order - + Lock load order - + BOSS working - + failed to run boss: %1 - + Request to Nexus failed: %1 - + Executable "%1" not found - + Failed to refresh list of esps: %1 - + This will move all files from overwrite into a new, regular mod. Please enter a name: - + Add/Remove Categories - + Replace Categories - - + + login successful - + login failed: %1. Trying to download anyway přihlášení zlyhalo: %1. Pokouším se beztak stahovat - + login failed: %1 přihlášení zlyhalo: %1 - + login failed: %1. You need to log-in with Nexus to update MO. přihlášení zlyhalo: %1. Na aktualizaci MO je potřebné přihlášení k Nexusu. - + Error Chyba - + failed to extract %1 (errorcode %2) zlyhala extrakce %1 (errorcode %2) - + Extract... Extrakce... - + Edit Categories... Editovat Kategorie... - + Enable all - + Disable all @@ -4811,64 +4825,64 @@ V současnosti má omezenou funkcionalitu esp nenalezeno: %1 - + Mod Index - + Flags - - + + unknown - + Name of your mods - + Load priority of your mod. The higher, the more "important" it is and thus overwrites data from plugins with lower priority. - + The modindex determins the formids of objects originating from this mods. - + failed to update esp info for file %1 (source id: %2), error: %3 - + esp not found: %1 - - + + Confirm Potvrdit - + Really enable all plugins? - + Really disable all plugins? - + The file containing locked plugin indices is broken @@ -4877,7 +4891,7 @@ V současnosti má omezenou funkcionalitu zlyhalo otevření výstupního souboru: %1 - + Some of your plugins have invalid names! These plugins can not be loaded by the game. Please see mo_interface.log for a list of affected plugins and rename them. Některé vaše pluginy mají neplatné názvy! Tyhle pluginy nemůžou být načteny hrou. Prosím nahlédněte do souboru mo_interface.log pro kompletní seznam pluginů a přejmenujte je. @@ -4887,17 +4901,17 @@ V současnosti má omezenou funkcionalitu - + Missing Masters - + Enabled Masters - + failed to restore load order for %1 @@ -4910,17 +4924,17 @@ V současnosti má omezenou funkcionalitu max - + This plugin can't be disabled (enforced by the game) Tenhle plugin nemůže být deaktivován (vyžaduje to hra) - + Origin: %1 Původní mod: %1 - + Name Jméno @@ -4929,7 +4943,7 @@ V současnosti má omezenou funkcionalitu Jména vašich modů - + Priority Priorita @@ -5512,23 +5526,23 @@ p, li { white-space: pre-wrap; } - + Please use "Help" from the toolbar to get usage instructions to all elements Prosím použijte "Pomoc" z panelu nástrojú pro instrukce ke všem elementům - - + + <Manage...> <Manage...> - + failed to parse profile %1: %2 Nezdařilo se rozebrat profil %1: %2 - + failed to find "%1" Nepodařilo sa najít "%1" @@ -5538,12 +5552,12 @@ p, li { white-space: pre-wrap; } Chyba kódování, prosím nahlaste tuto chybu a poskytněte záznamový soubor mo_interface.log! - + failed to access %1 zlyhal přístup k %1 - + failed to set file time %1 nepodařilo se nastavit čas souboru %1 diff --git a/src/organizer_de.ts b/src/organizer_de.ts index 306ce0ef..16d4521f 100644 --- a/src/organizer_de.ts +++ b/src/organizer_de.ts @@ -1642,11 +1642,21 @@ BSAs checked here are loaded in such a way that your installation order is obeye Data Data + + + Plugins + + Sort + + + Archives + + refresh data-directory overview @@ -1659,8 +1669,8 @@ BSAs checked here are loaded in such a way that your installation order is obeye - - + + Refresh Neu laden @@ -1840,7 +1850,7 @@ p, li { white-space: pre-wrap; } - + Update Aktualisierung @@ -1851,7 +1861,7 @@ p, li { white-space: pre-wrap; } - + No Problems Keine Probleme @@ -1882,37 +1892,37 @@ Diese Funktion ist noch in arbeit und ist sehr eingeschränkt. - + Endorse Mod Organizer - + Toolbar - + Desktop - + Start Menu - + Problems Probleme - + There are potential problems with your setup Es bestehen möglicherweise Probleme mit Ihrer Konfiguration - + Everything seems to be in order Alles in bester Ordnung @@ -1929,22 +1939,22 @@ Diese Funktion ist noch in arbeit und ist sehr eingeschränkt. <li>dotNet ist nicht installiert oder veraltet. Dies wird benötigt um NCC nutzen zu können. Laden Sie die korrekte Version von <a href="%1">%1</a> herunter</li> - + Help on UI Hilfe zur Oberfläche - + Documentation Wiki Wiki Dokumentation - + Report Issue Fehler melden - + Tutorials @@ -1953,93 +1963,88 @@ Diese Funktion ist noch in arbeit und ist sehr eingeschränkt. Ladereihenfolge konnte nicht gespeichert werden - + failed to save load order: %1 Reihenfolge konnt nicht gespeichert werden: %1 - - failed to save archives order, do you have write access to "%1"? - - - - + About - + About Qt - + Name Name - + Please enter a name for the new profile Bitte geben Sie einen Namen für das neue Profil an - + failed to create profile: %1 Erstellen des Profils fehlgeschlagen: %1 - + Show tutorial? - + You are starting Mod Organizer for the first time. Do you want to show a tutorial of its basic features? If you choose no you can always start the tutorial from the "Help"-menu. - + Downloads in progress Download in Bearbeitung - + There are still downloads in progress, do you really want to quit? Es gibt noch unfertige Downloads, wollen Sie wirklich das Programm beenden? - + failed to read savegame: %1 Spielstand konnte nicht gelesen werden: %1 - + Plugin "%1" failed: %2 - + Plugin error - + It appears the plugin "%1" failed to load last startup and caused MO to crash. Do you want to disable it? (Please note: If this is the first time you see this message for this plugin you may want to give it another try. The plugin may be able to recover from the problem) - + Failed to start "%1" - + Waiting Warte - + Please press OK once you're logged into steam. Bitte drücken sie OK sobald sie bei Steam angemeldet sind. @@ -2048,331 +2053,336 @@ Diese Funktion ist noch in arbeit und ist sehr eingeschränkt. "%1" nicht gefunden - + Start Steam? - + Steam is required to be running already to correctly start the game. Should MO try to start steam now? Steam muss laufen um das Spiel korrekt zu starten. Soll MO versuchen Steam zu starten? - + Also in: <br> Auch in: <br> - + No conflict Keine Konflikte - + <Edit...> <Bearbeiten...> - + This bsa is enabled in the ini file so it may be required! Dieses Archiv ist in der ini Konfiguration gelistet, daher ist es möglicherweise erforderlich! - + This archive will still be loaded since there is a plugin of the same name but its files will not follow installation order! Dieses Archiv wird vom Spiel geladen werden da ein Plugin mit dem selben Namen aktiv ist aber die enthaltenen Dateien werden sich nicht an Ihre Installations-Reihenfolge halten! - + Activating Network Proxy - - + + Installation successful Installation erfolgreich - - + + Configure Mod Mod konfigurieren - - + + This mod contains ini tweaks. Do you want to configure them now? Diese Mod enthält Anpassungen für die Ini datei. Wollen Sie diese nun konfigurieren? - - + + mod "%1" not found mod "%1" nicht gefunden - - + + Installation cancelled Installation abgebrochen - - + + The mod was not installed completely. Die mod wurde nicht erfolgreich installiert. - + Some plugins could not be loaded - + Too many esps and esms enabled - - + + Description missing - + The game doesn't allow more than 255 active plugins (including the official ones) to be loaded. You have to disable some unused plugins or merge some plugins into one. You can find a guide here: <a href="http://wiki.step-project.com/Guide:Merging_Plugins">http://wiki.step-project.com/Guide:Merging_Plugins</a> - + Choose Mod Mod wählen - + Mod Archive Mod Archiv - + Start Tutorial? - + You're about to start a tutorial. For technical reasons it's not possible to end the tutorial early. Continue? - - + + Download started Download gestartet - + failed to update mod list: %1 Aktualisieren der Modliste fehlgeschlagen: %1 - + failed to spawn notepad.exe: %1 notepad.exe konnte nicht aufgerufen werden: %1 - + failed to open %1 %1 konnte nicht geöffnet werden - + failed to change origin name: %1 konnte den Namen der Dateiquelle nicht ändern: %1 - + + failed to move "%1" from mod "%2" to "%3": %4 + + + + Multiple esps activated, please check that they don't conflict. - - + + Create Mod... - + A mod with this name already exists - + Continue? - + The versioning scheme decides which version is considered newer than another. This function will guess the versioning scheme under the assumption that the installed version is outdated. - - + + Sorry - + I don't know a versioning scheme where %1 is newer than %2. - + <All> <Alle> - + <Checked> <Markierte> - + Plugin "%1" failed - + failed to init plugin %1: %2 - + The following plugins could not be loaded. The reason may be missing dependencies (i.e. python) or an outdated version: - + <Unchecked> <Nicht markierte> - + <Update> <Update> - + <No category> <Ohne Kategorie> - + <Conflicted> - + <Not Endorsed> - + failed to rename mod: %1 konnte die Mod nicht umbenennen: %1 - + Overwrite? - + This will replace the existing mod "%1". Continue? - + failed to remove mod "%1" - - - + + + failed to rename "%1" to "%2" - - - - + + + + Confirm Bestätigen - + Remove the following mods?<br><ul>%1</ul> - + failed to remove mod: %1 konnte die mod nicht entfernen: %1 - - + + Failed Fehlgeschlagen - + Installation file no longer exists Installationsdatei existiert nicht mehr - + Mods installed with old versions of MO can't be reinstalled in this way. Mods die mit alten Versionen von MO installiert wurden können nicht auf diese Weise neu-installiert werden. - - + + You need to be logged in with Nexus to endorse - - + + Extract BSA BSA extrahieren - + This mod contains at least one BSA. Do you want to unpack it? (This removes the BSA after completion. If you don't know about BSAs, just select no) Diese mod enthält mindestens eine BSA datei. Soll sie entpackt werden? (Das BSA wird danach gelöscht. Wenn Sie nicht wissen was BSAs sind wählen Sie am besten \"nein\") - - - + + + failed to read %1: %2 - - + + This archive contains invalid hashes. Some files may be broken. Dieses Archiv enthält ungültige Prüfsummen. Einige Dateien sind evtl. defekt. - + Nexus ID for this Mod is unknown Nexus ID für diese Mod unbekannt @@ -2385,92 +2395,92 @@ This function will guess the versioning scheme under the assumption that the ins Priorität wählen - + Really enable all visible mods? Alle angezeigten Mods aktivieren? - + Really disable all visible mods? Alle angezeigten Mods deaktivieren? - + Choose what to export - + Everything - + All installed mods are included in the list - + Active Mods - + Only active (checked) mods from your current profile are included - + Visible - + All mods visible in the mod list are included - + export failed: %1 - + Install Mod... Mod installieren... - + Enable all visible Alle sichtbaren aktvieren - + Disable all visible Alle sichtbaren deaktvieren - + Check all for update Alle auf Aktualisierungen überprüfen - + Export to csv... - + Sync to Mods... Mods synchronisieren... - + Restore Backup - + Remove Backup... @@ -2479,362 +2489,362 @@ This function will guess the versioning scheme under the assumption that the ins Kategorie festlegen - + Primary Category - + Change versioning scheme - + Un-ignore update - + Ignore update - + Rename Mod... Mod umbenennen... - + Remove Mod... Mod entfernen... - + Reinstall Mod Mod neu installieren - + Un-Endorse - - + + Endorse - + Won't endorse - + Endorsement state unknown - + Ignore missing data - + Visit on Nexus Auf Nexus besuchen - + Open in explorer In Explorer öffnen - + Information... Informationen... - - + + Exception: Ausnahme: - - + + Unknown exception Unbekannte Ausnahme - + <Multiple> - + Really delete "%1"? - + Fix Mods... Mods reparieren... - + Delete - - + + failed to remove %1 %1 konnte nicht entfernt werden - - + + failed to create %1 %1 konnte nicht erstellt werden - + Can't change download directory while downloads are in progress! Das download verzeichnis kann nicht geändert werden solange Downloads laufen! - + Download failed Download fehlgeschlagen - + failed to write to file %1 Speichern in Datei "%1" fehlgeschlagen - + %1 written "%1" gespeichert - + Select binary Binary wählen - + Binary Ausführbare Datei - + Enter Name Namen eingeben - + Please enter a name for the executable Bitte geben Sie einen Namen für die Anwendungsdatei ein - + Not an executable Datei ist nicht ausführbar - + This is not a recognized executable. - - + + Replace file? Datei ersetzen? - + There already is a hidden version of this file. Replace it? Es existiert bereits eine versteckte Variante von dieser Datei. Soll diese ersetzt werden? - - + + File operation failed Dateioperation fehlgeschlagen - - + + Failed to remove "%1". Maybe you lack the required file permissions? Konnte "%1" nicht löschen. Fehlen Ihnen evtl. die nötigen Berechtigungen? - + There already is a visible version of this file. Replace it? Es existiert bereits eine sichtbare Variante dieser Datei. Soll diese ersetzt werden? - + file not found: %1 Datei nicht gefunden: %1 - + failed to generate preview for %1 - + Sorry, can't preview anything. This function currently does not support extracting from bsas. - + Update available Aktualisierung verfügbar - + Open/Execute Öffnen/Ausführen - + Add as Executable Als Anwendung hinzufügen - + Preview - + Un-Hide Sichtbar machen - + Hide Verstecken - + Write To File... In Datei speichern... - + Do you want to endorse Mod Organizer on %1 now? - + Remove - + Unlock load order - + Lock load order - + BOSS working - + failed to run boss: %1 - + Request to Nexus failed: %1 - + Executable "%1" not found - + Failed to refresh list of esps: %1 - + This will move all files from overwrite into a new, regular mod. Please enter a name: - + Add/Remove Categories - + Replace Categories - - + + login successful - + login failed: %1. Trying to download anyway login fehlgeschlagen: %1. Der Download scheitert vermutlich - + login failed: %1 login fehlgeschlagen: %1 - + login failed: %1. You need to log-in with Nexus to update MO. - + Error Fehler - + failed to extract %1 (errorcode %2) konnte "%1" nicht extrahieren (fehlercode %2) - + Extract... Extrahieren... - + Edit Categories... - + Enable all - + Disable all @@ -4908,64 +4918,64 @@ Diese Funktion ist noch in arbeit und ist sehr eingeschränkt. PluginList - + Mod Index - + Flags - - + + unknown - + Name of your mods - + Load priority of your mod. The higher, the more "important" it is and thus overwrites data from plugins with lower priority. - + The modindex determins the formids of objects originating from this mods. - + failed to update esp info for file %1 (source id: %2), error: %3 - + esp not found: %1 ESP nicht gefunden: %1 - - + + Confirm Bestätigen - + Really enable all plugins? - + Really disable all plugins? - + The file containing locked plugin indices is broken @@ -4974,7 +4984,7 @@ Diese Funktion ist noch in arbeit und ist sehr eingeschränkt. konnte die Ausgabedatei nicht öffnen: %1 - + Some of your plugins have invalid names! These plugins can not be loaded by the game. Please see mo_interface.log for a list of affected plugins and rename them. Einige Ihrer Plugins haben ungültige Namen! Diese Plugins können nicht vom Spiel geladen werden. Die Datei mo_interface.log enthält eine Liste der betroffenen Plugins. Bitte benennen Sie diese um. @@ -4984,17 +4994,17 @@ Diese Funktion ist noch in arbeit und ist sehr eingeschränkt. - + Missing Masters - + Enabled Masters - + failed to restore load order for %1 @@ -5007,17 +5017,17 @@ Diese Funktion ist noch in arbeit und ist sehr eingeschränkt. max - + This plugin can't be disabled (enforced by the game) Dieses Plugin kann nicht deaktiviert werden (vom Spiel benötigt) - + Origin: %1 Ursprung: %1 - + Name Name @@ -5026,7 +5036,7 @@ Diese Funktion ist noch in arbeit und ist sehr eingeschränkt. Namen Ihrer Mods - + Priority Priorität @@ -5617,7 +5627,7 @@ p, li { white-space: pre-wrap; } "%1" nicht gefunden - + Please use "Help" from the toolbar to get usage instructions to all elements Bitte verwenden Sie die "Hilfe" Funktion um Hinweise zu Nutzung aller Elemete zu bekommen @@ -5630,19 +5640,19 @@ p, li { white-space: pre-wrap; } Ungültige Priorität %1 - + failed to find "%1" Konnte "%1" nicht finden - - + + <Manage...> <Verwalten...> - + failed to parse profile %1: %2 Konnte Profil %1 nicht verarbeiten: %2 @@ -5651,12 +5661,12 @@ p, li { white-space: pre-wrap; } Kodierungsfehler! Bitte melden Sie dies als Bug und fügen Sie die Datei mo_interface.log bei! - + failed to access %1 Auf %1 konnte nicht zugegriffen werden - + failed to set file time %1 Konnte Dateizeit nicht setzen %1 diff --git a/src/organizer_es.ts b/src/organizer_es.ts index 0a19f56f..1dcb62c3 100644 --- a/src/organizer_es.ts +++ b/src/organizer_es.ts @@ -1501,11 +1501,21 @@ BSAs checked here are loaded in such a way that your installation order is obeye Data Datos + + + Plugins + + Sort + + + Archives + + refresh data-directory overview @@ -1518,8 +1528,8 @@ BSAs checked here are loaded in such a way that your installation order is obeye - - + + Refresh Recargar @@ -1693,7 +1703,7 @@ p, li { white-space: pre-wrap; } - + Update @@ -1704,7 +1714,7 @@ p, li { white-space: pre-wrap; } - + No Problems @@ -1734,148 +1744,143 @@ Right now this has very limited functionality - + Endorse Mod Organizer - + Toolbar - + Desktop - + Start Menu - + Problems - + There are potential problems with your setup - + Everything seems to be in order - + Help on UI - + Documentation Wiki - + Report Issue - + Tutorials - + failed to save load order: %1 Fallo guardando el orden de carga: %1 - - failed to save archives order, do you have write access to "%1"? - - - - + About - + About Qt - + Name Nombre - + Please enter a name for the new profile Por favor introduzca un nombre para el nuevo perfil - + failed to create profile: %1 Fallo al crear el perfil: %1 - + Show tutorial? - + You are starting Mod Organizer for the first time. Do you want to show a tutorial of its basic features? If you choose no you can always start the tutorial from the "Help"-menu. - + Downloads in progress Descarga en progreso - + There are still downloads in progress, do you really want to quit? Aun hay descargas en progreso, estas seguro que quieres salir? - + failed to read savegame: %1 Fallo al leer la partida guardada: %1 - + Plugin "%1" failed: %2 - + Plugin error - + It appears the plugin "%1" failed to load last startup and caused MO to crash. Do you want to disable it? (Please note: If this is the first time you see this message for this plugin you may want to give it another try. The plugin may be able to recover from the problem) - + Failed to start "%1" - + Waiting - + Please press OK once you're logged into steam. @@ -1884,330 +1889,335 @@ Right now this has very limited functionality "%1" no encontrado - + Start Steam? - + Steam is required to be running already to correctly start the game. Should MO try to start steam now? - + Also in: <br> - + No conflict Sin conflictos - + <Edit...> <Editar...> - + This bsa is enabled in the ini file so it may be required! - + This archive will still be loaded since there is a plugin of the same name but its files will not follow installation order! - + Activating Network Proxy - - + + Installation successful Instalacion completada - - + + Configure Mod Configurar Mod - - + + This mod contains ini tweaks. Do you want to configure them now? Este mod contiene modificaciones del Ini. Quieres configurarlas ahora? - - + + mod "%1" not found - - + + Installation cancelled - - + + The mod was not installed completely. - + Some plugins could not be loaded - + Too many esps and esms enabled - - + + Description missing - + The game doesn't allow more than 255 active plugins (including the official ones) to be loaded. You have to disable some unused plugins or merge some plugins into one. You can find a guide here: <a href="http://wiki.step-project.com/Guide:Merging_Plugins">http://wiki.step-project.com/Guide:Merging_Plugins</a> - + Choose Mod Seleccione Mod - + Mod Archive Fichero Mod - + Start Tutorial? - + You're about to start a tutorial. For technical reasons it's not possible to end the tutorial early. Continue? - - + + Download started Descarga comenzada - + failed to update mod list: %1 Fallo al actualizar la lista de Mods: %1 - + failed to spawn notepad.exe: %1 Fallo al cargar el Bloc de notas: %1 - + failed to open %1 Fallo al abrir %1 - + failed to change origin name: %1 fallo al cambiar el nombre original del fichero %1 - + + failed to move "%1" from mod "%2" to "%3": %4 + + + + Multiple esps activated, please check that they don't conflict. - - + + Create Mod... - + A mod with this name already exists - + Continue? - + The versioning scheme decides which version is considered newer than another. This function will guess the versioning scheme under the assumption that the installed version is outdated. - - + + Sorry - + I don't know a versioning scheme where %1 is newer than %2. - + <All> <Todos> - + <Checked> <Marcado> - + Plugin "%1" failed - + failed to init plugin %1: %2 - + The following plugins could not be loaded. The reason may be missing dependencies (i.e. python) or an outdated version: - + <Unchecked> <Desmarcado> - + <Update> <Actualizacion> - + <No category> - + <Conflicted> - + <Not Endorsed> - + failed to rename mod: %1 fallo al cambiar el nombre al mod: %1 - + Overwrite? - + This will replace the existing mod "%1". Continue? - + failed to remove mod "%1" - - - + + + failed to rename "%1" to "%2" - - - - + + + + Confirm Confirma - + Remove the following mods?<br><ul>%1</ul> - + failed to remove mod: %1 - - + + Failed - + Installation file no longer exists - + Mods installed with old versions of MO can't be reinstalled in this way. - - + + You need to be logged in with Nexus to endorse - - + + Extract BSA - + This mod contains at least one BSA. Do you want to unpack it? (This removes the BSA after completion. If you don't know about BSAs, just select no) - - - + + + failed to read %1: %2 - - + + This archive contains invalid hashes. Some files may be broken. - + Nexus ID for this Mod is unknown @@ -2220,92 +2230,92 @@ This function will guess the versioning scheme under the assumption that the ins Selecciona Prioridad - + Really enable all visible mods? - + Really disable all visible mods? - + Choose what to export - + Everything - + All installed mods are included in the list - + Active Mods - + Only active (checked) mods from your current profile are included - + Visible - + All mods visible in the mod list are included - + export failed: %1 - + Install Mod... Instalar Mod... - + Enable all visible Activar todos los visibles - + Disable all visible Desactivar todos los visibles - + Check all for update Buscar Actualizaciones - + Export to csv... - + Sync to Mods... - + Restore Backup - + Remove Backup... @@ -2314,362 +2324,362 @@ This function will guess the versioning scheme under the assumption that the ins Definir Categoria - + Primary Category - + Change versioning scheme - + Un-ignore update - + Ignore update - + Rename Mod... Cambiar nombre... - + Remove Mod... Quitar Mod... - + Reinstall Mod - + Un-Endorse - - + + Endorse - + Won't endorse - + Endorsement state unknown - + Ignore missing data - + Visit on Nexus - + Open in explorer - + Information... Informacion... - - + + Exception: - - + + Unknown exception - + <Multiple> - + Really delete "%1"? - + Fix Mods... Activar Mods faltantes... - + Delete - - + + failed to remove %1 Fallo eliminando %1 - - + + failed to create %1 - + Can't change download directory while downloads are in progress! - + Download failed - + failed to write to file %1 Fallo de escritura en el fichero %1 - + %1 written %1 escrito - + Select binary - + Binary Fichero - + Enter Name - + Please enter a name for the executable - + Not an executable - + This is not a recognized executable. - - + + Replace file? - + There already is a hidden version of this file. Replace it? - - + + File operation failed - - + + Failed to remove "%1". Maybe you lack the required file permissions? - + There already is a visible version of this file. Replace it? - + file not found: %1 fichero no encontrado: %1 - + failed to generate preview for %1 - + Sorry, can't preview anything. This function currently does not support extracting from bsas. - + Update available Disponible actualización - + Open/Execute - + Add as Executable - + Preview - + Un-Hide - + Hide - + Write To File... Escribir al fichero... - + Do you want to endorse Mod Organizer on %1 now? - + Remove - + Unlock load order - + Lock load order - + BOSS working - + failed to run boss: %1 - + Request to Nexus failed: %1 - + Executable "%1" not found - + Failed to refresh list of esps: %1 - + This will move all files from overwrite into a new, regular mod. Please enter a name: - + Add/Remove Categories - + Replace Categories - - + + login successful - + login failed: %1. Trying to download anyway - + login failed: %1 - + login failed: %1. You need to log-in with Nexus to update MO. - + Error Error - + failed to extract %1 (errorcode %2) - + Extract... - + Edit Categories... - + Enable all - + Disable all @@ -4272,69 +4282,69 @@ Activar Mods faltantes en el menu contextual del raton intentara activar los mod PluginList - + Mod Index - + Flags - - + + unknown - + Name of your mods - + Load priority of your mod. The higher, the more "important" it is and thus overwrites data from plugins with lower priority. - + The modindex determins the formids of objects originating from this mods. - + failed to update esp info for file %1 (source id: %2), error: %3 - + esp not found: %1 ESP no encontrado: %1 - - + + Confirm Confirma - + Really enable all plugins? - + Really disable all plugins? - + The file containing locked plugin indices is broken - + Some of your plugins have invalid names! These plugins can not be loaded by the game. Please see mo_interface.log for a list of affected plugins and rename them. @@ -4344,17 +4354,17 @@ Activar Mods faltantes en el menu contextual del raton intentara activar los mod - + Missing Masters - + Enabled Masters - + failed to restore load order for %1 @@ -4367,17 +4377,17 @@ Activar Mods faltantes en el menu contextual del raton intentara activar los mod max - + This plugin can't be disabled (enforced by the game) - + Origin: %1 - + Name Nombre @@ -4386,7 +4396,7 @@ Activar Mods faltantes en el menu contextual del raton intentara activar los mod Nombres de tus Mods - + Priority Prioridad @@ -4979,7 +4989,7 @@ p, li { white-space: pre-wrap; } "%1" no encontrado - + Please use "Help" from the toolbar to get usage instructions to all elements Por favor utilice "Ayuda" en la barra superior para obtener informacion sobre todos los elementos @@ -4992,19 +5002,19 @@ p, li { white-space: pre-wrap; } prioridad invalida %1 - + failed to find "%1" fallo al encontrar %1 - - + + <Manage...> <Definir...> - + failed to parse profile %1: %2 no se pudo analizar el perfil % 1: %2 @@ -5017,12 +5027,12 @@ p, li { white-space: pre-wrap; } Esto tomara un momento - + failed to access %1 Fallo al acceder %1 - + failed to set file time %1 Fallo al definir la hora al fihcero %1 diff --git a/src/organizer_fr.ts b/src/organizer_fr.ts index c283cb71..462e1699 100644 --- a/src/organizer_fr.ts +++ b/src/organizer_fr.ts @@ -1541,11 +1541,21 @@ BSAs checked here are loaded in such a way that your installation order is obeye Data DATA + + + Plugins + + Sort + + + Archives + + refresh data-directory overview @@ -1558,8 +1568,8 @@ BSAs checked here are loaded in such a way that your installation order is obeye - - + + Refresh Actualiser @@ -1739,7 +1749,7 @@ p, li { white-space: pre-wrap; } - + Update @@ -1750,7 +1760,7 @@ p, li { white-space: pre-wrap; } - + No Problems @@ -1780,148 +1790,143 @@ Right now this has very limited functionality - + Endorse Mod Organizer - + Toolbar - + Desktop - + Start Menu - + Problems - + There are potential problems with your setup - + Everything seems to be in order - + Help on UI - + Documentation Wiki - + Report Issue - + Tutorials - + failed to save load order: %1 impossible d'enregistrer l'ordre de chargement: %1 - - failed to save archives order, do you have write access to "%1"? - - - - + About - + About Qt - + Name Nom - + Please enter a name for the new profile Veuillez inscrire un nom pour le nouveau profil - + failed to create profile: %1 impossible de créer le profil: %1 - + Show tutorial? - + You are starting Mod Organizer for the first time. Do you want to show a tutorial of its basic features? If you choose no you can always start the tutorial from the "Help"-menu. - + Downloads in progress Téléchargements en cours - + There are still downloads in progress, do you really want to quit? Il encore des téléchargements en cours, voulez-vous vraiment quitter? - + failed to read savegame: %1 impossible de lire la sauvegarde: %1 - + Plugin "%1" failed: %2 - + Plugin error - + It appears the plugin "%1" failed to load last startup and caused MO to crash. Do you want to disable it? (Please note: If this is the first time you see this message for this plugin you may want to give it another try. The plugin may be able to recover from the problem) - + Failed to start "%1" - + Waiting Attente - + Please press OK once you're logged into steam. Veuillez cliquer OK une fois connecté à steam. @@ -1930,330 +1935,335 @@ Right now this has very limited functionality "%1" introuvable - + Start Steam? - + Steam is required to be running already to correctly start the game. Should MO try to start steam now? - + Also in: <br> - + No conflict Aucun conflit - + <Edit...> <Modifier...> - + This bsa is enabled in the ini file so it may be required! - + This archive will still be loaded since there is a plugin of the same name but its files will not follow installation order! - + Activating Network Proxy - - + + Installation successful Installation réussie - - + + Configure Mod Configurer mod - - + + This mod contains ini tweaks. Do you want to configure them now? Ce mod contient des ajustement pour les fichiers ini. Désirez-vous les configurer maintenant? - - + + mod "%1" not found - - + + Installation cancelled - - + + The mod was not installed completely. - + Some plugins could not be loaded - + Too many esps and esms enabled - - + + Description missing - + The game doesn't allow more than 255 active plugins (including the official ones) to be loaded. You have to disable some unused plugins or merge some plugins into one. You can find a guide here: <a href="http://wiki.step-project.com/Guide:Merging_Plugins">http://wiki.step-project.com/Guide:Merging_Plugins</a> - + Choose Mod Choisir mod - + Mod Archive Archive de mod - + Start Tutorial? - + You're about to start a tutorial. For technical reasons it's not possible to end the tutorial early. Continue? - - + + Download started Téléchargement commencé - + failed to update mod list: %1 impossible de mettre à jour la liste de mods: %1 - + failed to spawn notepad.exe: %1 impossible de lancer notepad.exe: %1 - + failed to open %1 impossible d'ouvrir %1 - + failed to change origin name: %1 impossible de changer le nom d'origine: %1 - + + failed to move "%1" from mod "%2" to "%3": %4 + + + + Multiple esps activated, please check that they don't conflict. - - + + Create Mod... - + A mod with this name already exists - + Continue? - + The versioning scheme decides which version is considered newer than another. This function will guess the versioning scheme under the assumption that the installed version is outdated. - - + + Sorry - + I don't know a versioning scheme where %1 is newer than %2. - + <All> <Tous> - + <Checked> <Cochés> - + Plugin "%1" failed - + failed to init plugin %1: %2 - + The following plugins could not be loaded. The reason may be missing dependencies (i.e. python) or an outdated version: - + <Unchecked> <Décochés> - + <Update> <Rafraichir> - + <No category> - + <Conflicted> - + <Not Endorsed> - + failed to rename mod: %1 impossible de renommer le mod: %1 - + Overwrite? - + This will replace the existing mod "%1". Continue? - + failed to remove mod "%1" - - - + + + failed to rename "%1" to "%2" - - - - + + + + Confirm Confirmer - + Remove the following mods?<br><ul>%1</ul> - + failed to remove mod: %1 - - + + Failed - + Installation file no longer exists - + Mods installed with old versions of MO can't be reinstalled in this way. - - + + You need to be logged in with Nexus to endorse - - + + Extract BSA - + This mod contains at least one BSA. Do you want to unpack it? (This removes the BSA after completion. If you don't know about BSAs, just select no) - - - + + + failed to read %1: %2 Échec de lecture %1: %2 - - + + This archive contains invalid hashes. Some files may be broken. - + Nexus ID for this Mod is unknown @@ -2266,92 +2276,92 @@ This function will guess the versioning scheme under the assumption that the ins Choisir priorité - + Really enable all visible mods? - + Really disable all visible mods? - + Choose what to export - + Everything - + All installed mods are included in the list - + Active Mods - + Only active (checked) mods from your current profile are included - + Visible - + All mods visible in the mod list are included - + export failed: %1 - + Install Mod... Installer mod... - + Enable all visible Activer tous les mods visibles - + Disable all visible Désactiver tous les mods visibles - + Check all for update Vérifier toutes les mises à jour - + Export to csv... - + Sync to Mods... - + Restore Backup - + Remove Backup... @@ -2360,362 +2370,362 @@ This function will guess the versioning scheme under the assumption that the ins Assigner catégorie - + Primary Category - + Change versioning scheme - + Un-ignore update - + Ignore update - + Rename Mod... Renommer mod... - + Remove Mod... Supprimer mod... - + Reinstall Mod - + Un-Endorse - - + + Endorse - + Won't endorse - + Endorsement state unknown - + Ignore missing data - + Visit on Nexus - + Open in explorer - + Information... Information... - - + + Exception: - - + + Unknown exception - + <Multiple> - + Really delete "%1"? - + Fix Mods... Réparer mods... - + Delete - - + + failed to remove %1 Impossible de supprimer %1 - - + + failed to create %1 impossible de créer %1 - + Can't change download directory while downloads are in progress! - + Download failed - + failed to write to file %1 impossible d'écrire dans le fichier %1 - + %1 written %1 écrit - + Select binary - + Binary Programme - + Enter Name - + Please enter a name for the executable - + Not an executable - + This is not a recognized executable. - - + + Replace file? - + There already is a hidden version of this file. Replace it? - - + + File operation failed - - + + Failed to remove "%1". Maybe you lack the required file permissions? - + There already is a visible version of this file. Replace it? - + file not found: %1 fichier introuvable: %1 - + failed to generate preview for %1 - + Sorry, can't preview anything. This function currently does not support extracting from bsas. - + Update available Mise à jour disponible - + Open/Execute - + Add as Executable - + Preview - + Un-Hide - + Hide - + Write To File... Écriture du fichier... - + Do you want to endorse Mod Organizer on %1 now? - + Remove Supprimer - + Unlock load order - + Lock load order - + BOSS working - + failed to run boss: %1 - + Request to Nexus failed: %1 - + Executable "%1" not found - + Failed to refresh list of esps: %1 - + This will move all files from overwrite into a new, regular mod. Please enter a name: - + Add/Remove Categories - + Replace Categories - - + + login successful - + login failed: %1. Trying to download anyway - + login failed: %1 - + login failed: %1. You need to log-in with Nexus to update MO. - + Error Erreur - + failed to extract %1 (errorcode %2) - + Extract... - + Edit Categories... - + Enable all - + Disable all @@ -4391,69 +4401,69 @@ p, li { white-space: pre-wrap; } PluginList - + Mod Index - + Flags - - + + unknown - + Name of your mods - + Load priority of your mod. The higher, the more "important" it is and thus overwrites data from plugins with lower priority. - + The modindex determins the formids of objects originating from this mods. - + failed to update esp info for file %1 (source id: %2), error: %3 - + esp not found: %1 ESP introuvable: %1 - - + + Confirm Confirmer - + Really enable all plugins? - + Really disable all plugins? - + The file containing locked plugin indices is broken - + Some of your plugins have invalid names! These plugins can not be loaded by the game. Please see mo_interface.log for a list of affected plugins and rename them. @@ -4463,17 +4473,17 @@ p, li { white-space: pre-wrap; } - + Missing Masters - + Enabled Masters - + failed to restore load order for %1 @@ -4486,17 +4496,17 @@ p, li { white-space: pre-wrap; } max - + This plugin can't be disabled (enforced by the game) - + Origin: %1 - + Name Nom @@ -4505,7 +4515,7 @@ p, li { white-space: pre-wrap; } Les noms de vos mods - + Priority Priorité @@ -5088,34 +5098,34 @@ p, li { white-space: pre-wrap; } "%1" introuvable - + Please use "Help" from the toolbar to get usage instructions to all elements Veuillez utiliser l'aide dans la barre d'outil pour obtenir des instructions à propos de tous les éléments - - + + <Manage...> <Gérer...> - + failed to parse profile %1: %2 impossible d'analyser le profil %1: %2 - + failed to find "%1" impossible de trouver "%1" - + failed to access %1 impossible d'accéder à %1 - + failed to set file time %1 impossible de changer la date du fichier %1 diff --git a/src/organizer_ru.ts b/src/organizer_ru.ts index 2a75ce82..0fc6ecea 100644 --- a/src/organizer_ru.ts +++ b/src/organizer_ru.ts @@ -1375,6 +1375,11 @@ p, li { white-space: pre-wrap; } Shortcut Ярлык + + + Plugins + Плагины + List of available esp/esm files @@ -1398,6 +1403,11 @@ p, li { white-space: pre-wrap; } Sort + + + Archives + + List of available BS Archives. Archives not checked here are not managed by MO and ignore installation order. @@ -1451,8 +1461,8 @@ BSA, отмеченные здесь, загружаются так, чтобы - - + + Refresh Обновить @@ -1632,7 +1642,7 @@ p, li { white-space: pre-wrap; } - + Update Обновление @@ -1643,7 +1653,7 @@ p, li { white-space: pre-wrap; } - + No Problems Проблем не обнаружено @@ -1676,158 +1686,157 @@ Right now this has very limited functionality - + Endorse Mod Organizer Одобрить Mod Organizer - + Toolbar Панель инструментов - + Desktop Рабочий стол - + Start Menu Меню Пуск - + Problems Проблемы - + There are potential problems with your setup Есть возможные проблемы с вашей установкой - + Everything seems to be in order Кажется всё в порядке - + Help on UI Справка по интерфейсу - + Documentation Wiki Wiki-документация - + Report Issue Сообщить о проблеме - + Tutorials Уроки - + About - + About Qt - failed to save archives order, do you have write access to "%1"? - не удалось сохранить порядок архивов, у вас имеется доступ на запись к "%1"? + не удалось сохранить порядок архивов, у вас имеется доступ на запись к "%1"? - + failed to save load order: %1 не удалось сохранить порядок загрузки: %1 - + Name Имя - + Please enter a name for the new profile Введите имя нового профиля - + failed to create profile: %1 не удалось создать профиль: %1 - + Show tutorial? Показать урок? - + You are starting Mod Organizer for the first time. Do you want to show a tutorial of its basic features? If you choose no you can always start the tutorial from the "Help"-menu. Вы запустили Mod Organizer впервые. Вы хотите просмотреть уроки по основным возможностям? В случае отказа вы всегда можете открыть уроки из меню "Помощь". - + Downloads in progress Загрузки в процессе - + There are still downloads in progress, do you really want to quit? Загрузки всё ещё в процессе, вы правда хотите выйти? - + failed to read savegame: %1 не удалось прочесть сохранение: %1 - + Plugin "%1" failed: %2 Плагин "%1" не удалось: %2 - + Plugin "%1" failed Плагин "%1" не удалось - + failed to init plugin %1: %2 не удалось инициализировать плагин %1: %2 - + Plugin error - + It appears the plugin "%1" failed to load last startup and caused MO to crash. Do you want to disable it? (Please note: If this is the first time you see this message for this plugin you may want to give it another try. The plugin may be able to recover from the problem) - + Failed to start "%1" Не удалось запустить "%1" - + Waiting Ожидание - + Please press OK once you're logged into steam. Нажмите OK как только вы войдете в Steam. @@ -1836,83 +1845,83 @@ Right now this has very limited functionality "%1" не найден - + Start Steam? Запустить Steam? - + Steam is required to be running already to correctly start the game. Should MO try to start steam now? Требуется запущенный Steam, для корректного запуска игры. Должен ли MO попытаться запустить Steam сейчас? - + Also in: <br> Также в: <br> - + No conflict Конфликтов нет - + <Edit...> <Правка...> - + This bsa is enabled in the ini file so it may be required! Этот bsa подключен через ini, так что он может быть необходим! - + This archive will still be loaded since there is a plugin of the same name but its files will not follow installation order! Этот архив все равно будет загружен, так как есть плагин с одноименным названием, но его файлы не будут следовать порядку установки! - + Activating Network Proxy Подключение сетевого прокси - - + + Installation successful Установка завершена - - + + Configure Mod Настройка мода - - + + This mod contains ini tweaks. Do you want to configure them now? Этот мод включает настройки ini. Вы хотите настроить их сейчас? - - + + mod "%1" not found мод "%1" не найден - - + + Installation cancelled Установка отменена - - + + The mod was not installed completely. Мод не был установлен полностью. - + Some plugins could not be loaded Некоторые плагины не могут быть загружены @@ -1921,203 +1930,203 @@ Right now this has very limited functionality Следующие плагины не могут быть загружены. Причина может быть в отсутствующих зависимостях (таких как python) или в устаревшей версии:<ul> - + Too many esps and esms enabled - - + + Description missing - + The following plugins could not be loaded. The reason may be missing dependencies (i.e. python) or an outdated version: - + Choose Mod Выберете мод - + Mod Archive Архив мода - + Start Tutorial? Начать обучение? - + You're about to start a tutorial. For technical reasons it's not possible to end the tutorial early. Continue? Вы собираетесь открыть обучение. По техническим причинам будет невозможно досрочно закончить обучение. Продолжить? - - + + Download started Загрузка начата - + failed to update mod list: %1 не удалось обновить список модов: %1 - + failed to spawn notepad.exe: %1 не удалось вызвать notepad.exe: %1 - + failed to open %1 не удалось открыть %1 - + failed to change origin name: %1 не удалось изменить оригинальное имя: %1 - + <Checked> <Подключен> - + <Unchecked> <Отключен> - + <Update> <Обновлен> - + <No category> <Без категории> - + <Conflicted> <Конфликтует> - + <Not Endorsed> - + failed to rename mod: %1 не удалось переименовать мод: %1 - + Overwrite? Перезаписать? - + This will replace the existing mod "%1". Continue? Это заменит существующий мод "%1". Продолжить? - + failed to remove mod "%1" не удалось удалить мод "%1" - - - + + + failed to rename "%1" to "%2" не удалось переименовать "%1" в "%2" - + Multiple esps activated, please check that they don't conflict. Подключено несколько esp, выберете из них не конфликтующие. - - - - + + + + Confirm Подтверждение - + Remove the following mods?<br><ul>%1</ul> Удалить следующие моды?<br><ul>%1</ul> - + failed to remove mod: %1 не удалось удалить мод: %1 - - + + Failed Неудача - + Installation file no longer exists Установочный файл больше не существует - + Mods installed with old versions of MO can't be reinstalled in this way. Моды, установленные с использованием старых версий MO не могут быть перестановленны таким образом. - - + + You need to be logged in with Nexus to endorse Вы должны быть авторизированы на Nexus, чтобы одобрять. - - + + Extract BSA Извлечь BSA - + This mod contains at least one BSA. Do you want to unpack it? (This removes the BSA after completion. If you don't know about BSAs, just select no) Этот мод включает как минимум один BSA. Вы хотите распаковать их? (Это удалит BSA после завершения. Если вы не знаете ничего о BSAs, просто откажитесь) - - - + + + failed to read %1: %2 не удалось прочесть %1: %2 - - + + This archive contains invalid hashes. Some files may be broken. Архив содержит неверные хеши. Некоторые файлы могут быть испорчены. - + Nexus ID for this Mod is unknown Nexus ID для этого мода неизвестен - - + + Create Mod... Создать мод... @@ -2128,119 +2137,119 @@ Please enter a name: Пожалуйста, введите имя: - + A mod with this name already exists Мод с таким именем уже существует - + Continue? - + The versioning scheme decides which version is considered newer than another. This function will guess the versioning scheme under the assumption that the installed version is outdated. - - + + Sorry - + I don't know a versioning scheme where %1 is newer than %2. - + Really enable all visible mods? Действительно подключить все видимые моды? - + Really disable all visible mods? Действительно отключить все видимые моды? - + Choose what to export Выберете, что экспортировать - + Everything Всё - + All installed mods are included in the list Все установленные моды, включенные в список - + Active Mods Активные моды - + Only active (checked) mods from your current profile are included Включены все активные (подключенные) моды вашего текущего профиля - + Visible Видимые - + All mods visible in the mod list are included Включены все моды, видимые в списке модов - + export failed: %1 экспорт не удался: %1 - + Install Mod... Установить мод... - + Enable all visible Включить все видимые - + Disable all visible Отключить все видимые - + Check all for update Проверить все на обновления - + Export to csv... Экспорт в csv... - + Sync to Mods... Синхронизировать с модами... - + Restore Backup Восстановить из резервной копии - + Remove Backup... Удалить резервную копию... @@ -2249,372 +2258,377 @@ This function will guess the versioning scheme under the assumption that the ins Задать категорию - + Executable "%1" not found - + Failed to refresh list of esps: %1 - + The game doesn't allow more than 255 active plugins (including the official ones) to be loaded. You have to disable some unused plugins or merge some plugins into one. You can find a guide here: <a href="http://wiki.step-project.com/Guide:Merging_Plugins">http://wiki.step-project.com/Guide:Merging_Plugins</a> - + + failed to move "%1" from mod "%2" to "%3": %4 + + + + This will move all files from overwrite into a new, regular mod. Please enter a name: - + Add/Remove Categories - + Replace Categories - + Primary Category Основная категория - + Change versioning scheme - + Un-ignore update - + Ignore update - + Rename Mod... Переименовать мод... - + Remove Mod... Удалить мод... - + Reinstall Mod Переустановить мод - + Un-Endorse Отменить одобрение - - + + Endorse Одобрить - + Won't endorse Не одобрять - + Endorsement state unknown Статус одобрения неизвестен - + Ignore missing data Игнорировать отсутствующие данные - + Visit on Nexus Перейти на Nexus - + Open in explorer Открыть в проводнике - + Information... Информация... - - + + Exception: Исключение: - - + + Unknown exception Неизвестное исключение - + <All> <Все> - + <Multiple> <Несколько> - + Really delete "%1"? - + Fix Mods... Исправить моды... - + Delete Удалить - - + + failed to remove %1 не удалось удалить %1 - - + + failed to create %1 не удалось создать %1 - + Can't change download directory while downloads are in progress! Нельзя изменить каталог для загрузок, когда загрузки ещё не завершены! - + Download failed Загрузка не удалась - + failed to write to file %1 ошибка записи в файл %1 - + %1 written %1 записан - + Select binary Выбрать исполняемый файл - + Binary Исполняемый файл - + Enter Name Введите имя - + Please enter a name for the executable Введите название для программы - + Not an executable Не является исполняемым - + This is not a recognized executable. Это неверный исполняемый файл. - - + + Replace file? Заменить файл? - + There already is a hidden version of this file. Replace it? Уже существует скрытая версия этого файла. Заменить? - - + + File operation failed Операция с файлом не удалась - - + + Failed to remove "%1". Maybe you lack the required file permissions? Не удалось удалить "%1". Может быть, вам не хватает необходимых прав доступа к файлу? - + There already is a visible version of this file. Replace it? Видимая версия этого файла уже существует. Заменить? - + file not found: %1 - + failed to generate preview for %1 - + Sorry, can't preview anything. This function currently does not support extracting from bsas. - + Update available Доступно обновление - + Open/Execute Открыть/Выполнить - + Add as Executable Добавить как исполняемый - + Preview - + Un-Hide Показать - + Hide Скрыть - + Write To File... Записать в файл... - + Do you want to endorse Mod Organizer on %1 now? Вы хотите одобрить Mod Organizer на %1 сейчас? - + Request to Nexus failed: %1 Запрос на Nexus не удался: %1 - - + + login successful успешный вход - + login failed: %1. Trying to download anyway вход не удался: %1. Пытаюсь загрузить всё равно - + login failed: %1 войти не удалось: %1 - + login failed: %1. You need to log-in with Nexus to update MO. войти не удалось: %1. Вам нужно войти на Nexus, чтобы обновить MO. - + Error Ошибка - + failed to extract %1 (errorcode %2) не удалось извлечь %1 (код ошибки %2) - + Extract... Распаковка... - + Edit Categories... Изменить категории... - + Remove - + Enable all Включить все - + Disable all Отключить все - + Unlock load order Разблокировать порядок загрузки - + Lock load order Заблокировать порядок загрузки - + BOSS working - + failed to run boss: %1 @@ -3539,74 +3553,74 @@ p, li { white-space: pre-wrap; } PluginList - + Name Имя - + Priority Приоритет - + Mod Index Индекс мода - + Flags Флаги - - + + unknown неизвестно - + Name of your mods Имена ваших модов - + Load priority of your mod. The higher, the more "important" it is and thus overwrites data from plugins with lower priority. Приоритет загрузки ваших модов. Моды с большим приоритетом перезапишут данные модов с меньшим приоритетом. - + The modindex determins the formids of objects originating from this mods. Индекс мода определяющий id форм объектов, происходящих из этих модов. - + failed to update esp info for file %1 (source id: %2), error: %3 - + esp not found: %1 esp не найден: %1 - - + + Confirm - + Really enable all plugins? - + Really disable all plugins? - + The file containing locked plugin indices is broken Файл, содержащий индексы заблокированного плагина, не работает. @@ -3615,7 +3629,7 @@ p, li { white-space: pre-wrap; } не удалось открыть выходной файл: %1 - + Some of your plugins have invalid names! These plugins can not be loaded by the game. Please see mo_interface.log for a list of affected plugins and rename them. Некоторые из ваших плагинов имеют неверные имена. Эти плагины не могут быть загружены игрой. Смотрите mo_interface.log для получения списка таких плагинов и переименуйте их. @@ -3625,27 +3639,27 @@ p, li { white-space: pre-wrap; } - + This plugin can't be disabled (enforced by the game) Этот плагин не может быть отключен (грузится игрой принудительно) - + Origin: %1 Источник: %1 - + Missing Masters - + Enabled Masters - + failed to restore load order for %1 не удалось восстановить порядок загрузки для %1 @@ -4226,23 +4240,23 @@ p, li { white-space: pre-wrap; } - + Please use "Help" from the toolbar to get usage instructions to all elements Используйте пункт "Справка" на панели инструментов, чтобы получить инструкции по использованию всех элементов. - - + + <Manage...> <Управлять...> - + failed to parse profile %1: %2 не удалось обработать профиль %1: %2 - + failed to find "%1" не удалось найти "%1" @@ -4252,12 +4266,12 @@ p, li { white-space: pre-wrap; } ошибка кодирования, пожалуйста сообщите об этом баге, включив файл mo_interface.log! - + failed to access %1 не удалось получить доступ к %1 - + failed to set file time %1 не удалось изменить дату модификации для %1 diff --git a/src/organizer_tr.ts b/src/organizer_tr.ts index 58d30d00..d091ad76 100644 --- a/src/organizer_tr.ts +++ b/src/organizer_tr.ts @@ -1583,11 +1583,21 @@ BSAs checked here are loaded in such a way that your installation order is obeye Data + + + Plugins + + Sort + + + Archives + + refresh data-directory overview @@ -1600,8 +1610,8 @@ BSAs checked here are loaded in such a way that your installation order is obeye - - + + Refresh @@ -1775,7 +1785,7 @@ p, li { white-space: pre-wrap; } - + Update @@ -1786,7 +1796,7 @@ p, li { white-space: pre-wrap; } - + No Problems @@ -1816,926 +1826,926 @@ Right now this has very limited functionality - + Endorse Mod Organizer - + Toolbar - + Desktop - + Start Menu - + Problems - + There are potential problems with your setup - + Everything seems to be in order - + Help on UI - + Documentation Wiki - + Report Issue - + Tutorials - + failed to save load order: %1 - - failed to save archives order, do you have write access to "%1"? - - - - + About - + About Qt - + Name İsim - + Please enter a name for the new profile - + failed to create profile: %1 - + Show tutorial? - + You are starting Mod Organizer for the first time. Do you want to show a tutorial of its basic features? If you choose no you can always start the tutorial from the "Help"-menu. - + Downloads in progress - + There are still downloads in progress, do you really want to quit? - + failed to read savegame: %1 - + Plugin "%1" failed: %2 - + Failed to start "%1" - + Waiting - + Please press OK once you're logged into steam. - + Start Steam? - + Steam is required to be running already to correctly start the game. Should MO try to start steam now? - + Also in: <br> - + No conflict - + <Edit...> - + Failed to refresh list of esps: %1 - + This bsa is enabled in the ini file so it may be required! - + This archive will still be loaded since there is a plugin of the same name but its files will not follow installation order! - + Activating Network Proxy - - + + Installation successful - - + + Configure Mod - - + + This mod contains ini tweaks. Do you want to configure them now? - - + + mod "%1" not found - - + + Installation cancelled - - + + The mod was not installed completely. - + Some plugins could not be loaded - + The game doesn't allow more than 255 active plugins (including the official ones) to be loaded. You have to disable some unused plugins or merge some plugins into one. You can find a guide here: <a href="http://wiki.step-project.com/Guide:Merging_Plugins">http://wiki.step-project.com/Guide:Merging_Plugins</a> - + Choose Mod - + Mod Archive - + Start Tutorial? - + You're about to start a tutorial. For technical reasons it's not possible to end the tutorial early. Continue? - - + + Download started - + failed to update mod list: %1 - + failed to spawn notepad.exe: %1 - + failed to open %1 - + failed to change origin name: %1 - + Multiple esps activated, please check that they don't conflict. - - + + Create Mod... - + A mod with this name already exists - + <All> - + <Checked> - + Plugin "%1" failed - + failed to init plugin %1: %2 - + Plugin error - + It appears the plugin "%1" failed to load last startup and caused MO to crash. Do you want to disable it? (Please note: If this is the first time you see this message for this plugin you may want to give it another try. The plugin may be able to recover from the problem) - + Too many esps and esms enabled - - + + Description missing - + The following plugins could not be loaded. The reason may be missing dependencies (i.e. python) or an outdated version: - + + failed to move "%1" from mod "%2" to "%3": %4 + + + + <Unchecked> - + <Update> - + <No category> - + <Conflicted> - + <Not Endorsed> - + failed to rename mod: %1 - + Overwrite? - + This will replace the existing mod "%1". Continue? - + failed to remove mod "%1" - - - + + + failed to rename "%1" to "%2" "%1"yi "%2" olarak yeniden adlandırma başarılı olamadı. - - - - + + + + Confirm Onayla - + Remove the following mods?<br><ul>%1</ul> - + failed to remove mod: %1 - - + + Failed - + Installation file no longer exists - + Mods installed with old versions of MO can't be reinstalled in this way. - - + + You need to be logged in with Nexus to endorse - - + + Extract BSA - + This mod contains at least one BSA. Do you want to unpack it? (This removes the BSA after completion. If you don't know about BSAs, just select no) - - - + + + failed to read %1: %2 %1: %2 okunamadı - - + + This archive contains invalid hashes. Some files may be broken. - + Nexus ID for this Mod is unknown - + This will move all files from overwrite into a new, regular mod. Please enter a name: - + Continue? - + The versioning scheme decides which version is considered newer than another. This function will guess the versioning scheme under the assumption that the installed version is outdated. - - + + Sorry - + I don't know a versioning scheme where %1 is newer than %2. - + Really enable all visible mods? - + Really disable all visible mods? - + Choose what to export - + Everything - + All installed mods are included in the list - + Active Mods - + Only active (checked) mods from your current profile are included - + Visible - + All mods visible in the mod list are included - + export failed: %1 - + Install Mod... - + Enable all visible - + Disable all visible - + Check all for update - + Export to csv... - + Sync to Mods... - + Restore Backup - + Remove Backup... - + Primary Category - + Change versioning scheme - + Un-ignore update - + Ignore update - + Rename Mod... - + Remove Mod... - + Reinstall Mod - + Un-Endorse - - + + Endorse - + Won't endorse - + Endorsement state unknown - + Ignore missing data - + Visit on Nexus - + Open in explorer - + Information... - - + + Exception: - - + + Unknown exception - + <Multiple> - + Really delete "%1"? - + Fix Mods... - + Delete - - + + failed to remove %1 - - + + failed to create %1 - + Can't change download directory while downloads are in progress! - + Download failed - + failed to write to file %1 - + %1 written - + Select binary - + Binary İkili değer - + Enter Name - + Please enter a name for the executable - + Not an executable - + This is not a recognized executable. - - + + Replace file? - + There already is a hidden version of this file. Replace it? - - + + File operation failed - - + + Failed to remove "%1". Maybe you lack the required file permissions? - + There already is a visible version of this file. Replace it? - + file not found: %1 - + failed to generate preview for %1 - + Sorry, can't preview anything. This function currently does not support extracting from bsas. - + Update available - + Open/Execute - + Add as Executable - + Preview - + Un-Hide - + Hide - + Write To File... - + Do you want to endorse Mod Organizer on %1 now? - + Remove - + Unlock load order - + Lock load order - + BOSS working - + failed to run boss: %1 - + Request to Nexus failed: %1 - + Executable "%1" not found - + Add/Remove Categories - + Replace Categories - - + + login successful - + login failed: %1. Trying to download anyway - + login failed: %1 - + login failed: %1. You need to log-in with Nexus to update MO. - + Error - + failed to extract %1 (errorcode %2) - + Extract... - + Edit Categories... - + Enable all - + Disable all @@ -3625,69 +3635,69 @@ p, li { white-space: pre-wrap; } PluginList - + Mod Index - + Flags - - + + unknown - + Name of your mods - + Load priority of your mod. The higher, the more "important" it is and thus overwrites data from plugins with lower priority. - + The modindex determins the formids of objects originating from this mods. - + failed to update esp info for file %1 (source id: %2), error: %3 - + esp not found: %1 - - + + Confirm Onayla - + Really enable all plugins? - + Really disable all plugins? - + The file containing locked plugin indices is broken - + Some of your plugins have invalid names! These plugins can not be loaded by the game. Please see mo_interface.log for a list of affected plugins and rename them. @@ -3697,37 +3707,37 @@ p, li { white-space: pre-wrap; } - + Missing Masters - + Enabled Masters - + failed to restore load order for %1 - + This plugin can't be disabled (enforced by the game) - + Origin: %1 - + Name İsim - + Priority @@ -4235,34 +4245,34 @@ p, li { white-space: pre-wrap; } - + Please use "Help" from the toolbar to get usage instructions to all elements - - + + <Manage...> - + failed to parse profile %1: %2 - + failed to find "%1" - + failed to access %1 - + failed to set file time %1 diff --git a/src/organizer_zh_CN.ts b/src/organizer_zh_CN.ts index 4e24267f..a5fb1bcc 100644 --- a/src/organizer_zh_CN.ts +++ b/src/organizer_zh_CN.ts @@ -1629,11 +1629,21 @@ BSAs checked here are loaded in such a way that your installation order is obeye Data Data + + + Plugins + + Sort + + + Archives + + refresh data-directory overview @@ -1646,8 +1656,8 @@ BSAs checked here are loaded in such a way that your installation order is obeye - - + + Refresh 刷新 @@ -1827,7 +1837,7 @@ p, li { white-space: pre-wrap; } - + Update 更新 @@ -1838,7 +1848,7 @@ p, li { white-space: pre-wrap; } - + No Problems 没有问题 @@ -1871,37 +1881,37 @@ Right now this has very limited functionality - + Endorse Mod Organizer - + Toolbar - + Desktop - + Start Menu - + Problems 问题 - + There are potential problems with your setup 您的安装中存在潜在的问题 - + Everything seems to be in order 一切井然有序 @@ -1918,22 +1928,22 @@ Right now this has very limited functionality <li>.Net 未安装或版本过旧。想要运行 NCC 您必须先安装 .Net,您可以在以下地址中获取: <a href="%1">%1</a></li> - + Help on UI 界面帮助 - + Documentation Wiki 说明文档 (维基) - + Report Issue 报告问题 - + Tutorials @@ -1942,93 +1952,92 @@ Right now this has very limited functionality 无法保存加载顺序 - + failed to save load order: %1 无法保存加载顺序: %1 - failed to save archives order, do you have write access to "%1"? - 无法保存档案顺序,您确定您有权限更改 "%1"? + 无法保存档案顺序,您确定您有权限更改 "%1"? - + About - + About Qt - + Name 名称 - + Please enter a name for the new profile - + failed to create profile: %1 无法创建配置文件: %1 - + Show tutorial? - + You are starting Mod Organizer for the first time. Do you want to show a tutorial of its basic features? If you choose no you can always start the tutorial from the "Help"-menu. - + Downloads in progress 正在下载 - + There are still downloads in progress, do you really want to quit? 仍有正在进行中的下载,您确定要退出吗? - + failed to read savegame: %1 无法读取存档: %1 - + Plugin "%1" failed: %2 - + Plugin error - + It appears the plugin "%1" failed to load last startup and caused MO to crash. Do you want to disable it? (Please note: If this is the first time you see this message for this plugin you may want to give it another try. The plugin may be able to recover from the problem) - + Failed to start "%1" 无法启动 "%1" - + Waiting 稍等 - + Please press OK once you're logged into steam. 当您登录 Steam 时请点击确定。 @@ -2037,331 +2046,336 @@ Right now this has very limited functionality "%1" 未找到 - + Start Steam? 启动 Steam? - + Steam is required to be running already to correctly start the game. Should MO try to start steam now? 想要正确地启动遊戲,Steam 必须处于运行状态。MO 要立即启动 Steam 吗? - + Also in: <br> 也在: <br> - + No conflict 没有冲突 - + <Edit...> <编辑...> - + This bsa is enabled in the ini file so it may be required! 该 BSA 已在 Ini 文件中启用,因此它可能是必需的。 - + This archive will still be loaded since there is a plugin of the same name but its files will not follow installation order! 此档案还是会被加载,因为存在同名插件。不过它所包含的的文件不会遵循安装顺序! - + Activating Network Proxy - - + + Installation successful 安装成功 - - + + Configure Mod 配置 Mod - - + + This mod contains ini tweaks. Do you want to configure them now? 此 Mod 中包含 Ini 设定文件,您想现在就对它们进行配置吗? - - + + mod "%1" not found Mod "%1" 未找到 - - + + Installation cancelled 安装已取消 - - + + The mod was not installed completely. Mod 没有完全安装。 - + Some plugins could not be loaded - + Too many esps and esms enabled - - + + Description missing - + The game doesn't allow more than 255 active plugins (including the official ones) to be loaded. You have to disable some unused plugins or merge some plugins into one. You can find a guide here: <a href="http://wiki.step-project.com/Guide:Merging_Plugins">http://wiki.step-project.com/Guide:Merging_Plugins</a> - + Choose Mod 选择 Mod - + Mod Archive Mod 压缩包 - + Start Tutorial? - + You're about to start a tutorial. For technical reasons it's not possible to end the tutorial early. Continue? - - + + Download started 开始下载 - + failed to update mod list: %1 无法更新 Mod 列表: %1 - + failed to spawn notepad.exe: %1 无法生成 notepad.exe: %1 - + failed to open %1 无法打开 %1 - + failed to change origin name: %1 无法更改原始文件名: %1 - + + failed to move "%1" from mod "%2" to "%3": %4 + + + + Multiple esps activated, please check that they don't conflict. - - + + Create Mod... - + A mod with this name already exists - + Continue? - + The versioning scheme decides which version is considered newer than another. This function will guess the versioning scheme under the assumption that the installed version is outdated. - - + + Sorry - + I don't know a versioning scheme where %1 is newer than %2. - + <All> <全部> - + <Checked> <已勾选> - + Plugin "%1" failed - + failed to init plugin %1: %2 - + The following plugins could not be loaded. The reason may be missing dependencies (i.e. python) or an outdated version: - + <Unchecked> <未勾选> - + <Update> <有更新> - + <No category> <无类别> - + <Conflicted> - + <Not Endorsed> - + failed to rename mod: %1 无法重命名 Mod: %1 - + Overwrite? - + This will replace the existing mod "%1". Continue? - + failed to remove mod "%1" - - - + + + failed to rename "%1" to "%2" - - - - + + + + Confirm 确认 - + Remove the following mods?<br><ul>%1</ul> - + failed to remove mod: %1 无法移动 Mod: %1 - - + + Failed 失败 - + Installation file no longer exists 安装文件不复存在 - + Mods installed with old versions of MO can't be reinstalled in this way. 旧版 MO 安装的 Mod 无法使用此方法重新安装。 - - + + You need to be logged in with Nexus to endorse - - + + Extract BSA 解压 BSA - + This mod contains at least one BSA. Do you want to unpack it? (This removes the BSA after completion. If you don't know about BSAs, just select no) 此 Mod 中至少包含一个 BSA。您确定要解压吗? (解压完成后,BSA 文件将会被删除。如果您不了解 BSA 的话,请选择“否”) - - - + + + failed to read %1: %2 无法读取 %1: %2 - - + + This archive contains invalid hashes. Some files may be broken. 压缩包 Hash 值错误。部分文件可能已经损坏。 - + Nexus ID for this Mod is unknown 此 Mod 的N网 ID 未知 @@ -2374,92 +2388,92 @@ This function will guess the versioning scheme under the assumption that the ins 选择优先级 - + Really enable all visible mods? 确定要启用全部可见的 Mod 吗? - + Really disable all visible mods? 确定要禁用全部可见的 Mod 吗? - + Choose what to export - + Everything - + All installed mods are included in the list - + Active Mods - + Only active (checked) mods from your current profile are included - + Visible - + All mods visible in the mod list are included - + export failed: %1 - + Install Mod... 安装 Mod... - + Enable all visible 启用所有可见项目 - + Disable all visible 禁用所有可见项目 - + Check all for update 检查更新 - + Export to csv... - + Sync to Mods... 同步到 Mod... - + Restore Backup - + Remove Backup... @@ -2468,362 +2482,362 @@ This function will guess the versioning scheme under the assumption that the ins 设置类别 - + Primary Category - + Change versioning scheme - + Un-ignore update - + Ignore update - + Rename Mod... 重命名... - + Remove Mod... 移除 Mod... - + Reinstall Mod 重新安装 Mod - + Un-Endorse - - + + Endorse - + Won't endorse - + Endorsement state unknown - + Ignore missing data - + Visit on Nexus 在N网上浏览 - + Open in explorer 在资源管理器中打开 - + Information... 信息... - - + + Exception: 例外: - - + + Unknown exception 未知的例外 - + <Multiple> - + Really delete "%1"? - + Fix Mods... 修复 Mod... - + Delete - - + + failed to remove %1 无法删除 %1 - - + + failed to create %1 无法创建 %1 - + Can't change download directory while downloads are in progress! 下载文件时不能修改下载目录! - + Download failed 下载失败 - + failed to write to file %1 无法写入文件 %1 - + %1 written 已写入 %1 - + Select binary 选择可执行文件 - + Binary - + Enter Name 输入名称 - + Please enter a name for the executable 请为程序输入一个名称 - + Not an executable 不是可执行程序 - + This is not a recognized executable. 无法识别的可执行文件 - - + + Replace file? 替换文件? - + There already is a hidden version of this file. Replace it? 已存在同名文件,但该文件被隐藏了。确定要覆盖吗? - - + + File operation failed 文件操作错误 - - + + Failed to remove "%1". Maybe you lack the required file permissions? - + There already is a visible version of this file. Replace it? - + file not found: %1 文件未找到: %1 - + failed to generate preview for %1 - + Sorry, can't preview anything. This function currently does not support extracting from bsas. - + Update available 更新可用 - + Open/Execute 打开/执行 - + Add as Executable 添加为可执行文件 - + Preview - + Un-Hide 取消隐藏 - + Hide 隐藏 - + Write To File... 写入文件... - + Do you want to endorse Mod Organizer on %1 now? - + Remove 移除 - + Unlock load order - + Lock load order - + BOSS working - + failed to run boss: %1 - + Request to Nexus failed: %1 - + Executable "%1" not found - + Failed to refresh list of esps: %1 - + This will move all files from overwrite into a new, regular mod. Please enter a name: - + Add/Remove Categories - + Replace Categories - - + + login successful 登录成功 - + login failed: %1. Trying to download anyway 登录失败: %1,请尝试使用别的方法下载 - + login failed: %1 无法登录: %1 - + login failed: %1. You need to log-in with Nexus to update MO. 登录失败: %1。您需要登录到N网才能更新 MO - + Error 错误 - + failed to extract %1 (errorcode %2) 无法解压 %1 (错误代码 %2) - + Extract... 解压... - + Edit Categories... 编辑类别... - + Enable all 全部启用 - + Disable all 全部禁用 @@ -4765,64 +4779,64 @@ Right now this has very limited functionality ESP 文件没有找到: %1 - + Mod Index - + Flags - - + + unknown - + Name of your mods - + Load priority of your mod. The higher, the more "important" it is and thus overwrites data from plugins with lower priority. - + The modindex determins the formids of objects originating from this mods. - + failed to update esp info for file %1 (source id: %2), error: %3 - + esp not found: %1 - - + + Confirm 确认 - + Really enable all plugins? - + Really disable all plugins? - + The file containing locked plugin indices is broken @@ -4831,7 +4845,7 @@ Right now this has very limited functionality 无法打开输出文件: %1 - + Some of your plugins have invalid names! These plugins can not be loaded by the game. Please see mo_interface.log for a list of affected plugins and rename them. 您的一些插件名称无效!这些插件无法被游戏载入。请查看 mo_interface.log 来确认那些受影响的插件并重命名它们。 @@ -4841,17 +4855,17 @@ Right now this has very limited functionality - + Missing Masters - + Enabled Masters - + failed to restore load order for %1 @@ -4864,17 +4878,17 @@ Right now this has very limited functionality 最高值 - + This plugin can't be disabled (enforced by the game) 这个插件不能被禁用 (由游戏执行) - + Origin: %1 隶属于: %1 - + Name 名称 @@ -4883,7 +4897,7 @@ Right now this has very limited functionality Mod 名称 - + Priority 优先级 @@ -5466,23 +5480,23 @@ p, li { white-space: pre-wrap; } - + Please use "Help" from the toolbar to get usage instructions to all elements 请使用工具栏上的“帮助”来获得所有元素的使用说明 - - + + <Manage...> <管理...> - + failed to parse profile %1: %2 无法解析配置文件 %1: %2 - + failed to find "%1" 未能找到 "%1" @@ -5492,12 +5506,12 @@ p, li { white-space: pre-wrap; } 编码错误,请向作者汇报此 Bug 并且附上 mo_interface.log 文件! - + failed to access %1 无法访问 %1 - + failed to set file time %1 无法设置文件时间 %1 diff --git a/src/organizer_zh_TW.ts b/src/organizer_zh_TW.ts index 1fc6b17b..0ae46a41 100644 --- a/src/organizer_zh_TW.ts +++ b/src/organizer_zh_TW.ts @@ -1629,11 +1629,21 @@ BSAs checked here are loaded in such a way that your installation order is obeye Data Data + + + Plugins + + Sort + + + Archives + + refresh data-directory overview @@ -1646,8 +1656,8 @@ BSAs checked here are loaded in such a way that your installation order is obeye - - + + Refresh 重新整理 @@ -1827,7 +1837,7 @@ p, li { white-space: pre-wrap; } - + Update 更新 @@ -1838,7 +1848,7 @@ p, li { white-space: pre-wrap; } - + No Problems 沒有問題 @@ -1871,37 +1881,37 @@ Right now this has very limited functionality - + Endorse Mod Organizer - + Toolbar - + Desktop - + Start Menu - + Problems 問題 - + There are potential problems with your setup 您的安裝中存在潛在的問題 - + Everything seems to be in order 一切井然有序 @@ -1918,22 +1928,22 @@ Right now this has very limited functionality <li>.Net 未安裝或版本過舊。想要運行 NCC 您必須先安裝 .Net,您可以在以下地址中獲取: <a href="%1">%1</a></li> - + Help on UI 介面幫助 - + Documentation Wiki 說明文檔 (維基) - + Report Issue 報告問題 - + Tutorials @@ -1942,93 +1952,92 @@ Right now this has very limited functionality 無法儲存加載順序 - + failed to save load order: %1 無法儲存加載順序: %1 - failed to save archives order, do you have write access to "%1"? - 無法儲存檔案順序,您確定您有權限更改 "%1"? + 無法儲存檔案順序,您確定您有權限更改 "%1"? - + About - + About Qt - + Name 名稱 - + Please enter a name for the new profile - + failed to create profile: %1 無法建立配置檔案: %1 - + Show tutorial? - + You are starting Mod Organizer for the first time. Do you want to show a tutorial of its basic features? If you choose no you can always start the tutorial from the "Help"-menu. - + Downloads in progress 正在下載 - + There are still downloads in progress, do you really want to quit? 仍有正在進行中的下載,您確定要退出嗎? - + failed to read savegame: %1 無法讀取存檔: %1 - + Plugin "%1" failed: %2 - + Plugin error - + It appears the plugin "%1" failed to load last startup and caused MO to crash. Do you want to disable it? (Please note: If this is the first time you see this message for this plugin you may want to give it another try. The plugin may be able to recover from the problem) - + Failed to start "%1" 無法啟動 "%1" - + Waiting 稍等 - + Please press OK once you're logged into steam. 當您登入 Steam 時請點擊確定。 @@ -2037,331 +2046,336 @@ Right now this has very limited functionality "%1" 未找到 - + Start Steam? 啟動 Steam? - + Steam is required to be running already to correctly start the game. Should MO try to start steam now? 想要正確地啟動遊戲,Steam 必須處於運行狀態,MO 要立即啟動 Steam 嗎? - + Also in: <br> 也在: <br> - + No conflict 沒有衝突 - + <Edit...> <編輯...> - + This bsa is enabled in the ini file so it may be required! 該 BSA 已在 Ini 檔案中啟用,因此它可能是必需的。 - + This archive will still be loaded since there is a plugin of the same name but its files will not follow installation order! 此檔案還是會被加載,因為存在同名插件。不過它所包含的的檔案不會遵循安裝順序! - + Activating Network Proxy - - + + Installation successful 安裝成功 - - + + Configure Mod 配置 Mod - - + + This mod contains ini tweaks. Do you want to configure them now? 此 Mod 中包含 Ini 設定檔案,您想現在就對它們進行配置嗎? - - + + mod "%1" not found Mod "%1" 未找到 - - + + Installation cancelled 安裝已取消 - - + + The mod was not installed completely. Mod 沒有完全安裝。 - + Some plugins could not be loaded - + Too many esps and esms enabled - - + + Description missing - + The game doesn't allow more than 255 active plugins (including the official ones) to be loaded. You have to disable some unused plugins or merge some plugins into one. You can find a guide here: <a href="http://wiki.step-project.com/Guide:Merging_Plugins">http://wiki.step-project.com/Guide:Merging_Plugins</a> - + Choose Mod 選擇 Mod - + Mod Archive Mod 壓縮包 - + Start Tutorial? - + You're about to start a tutorial. For technical reasons it's not possible to end the tutorial early. Continue? - - + + Download started 開始下載 - + failed to update mod list: %1 無法更新 Mod 列表: %1 - + failed to spawn notepad.exe: %1 無法生成 notepad.exe: %1 - + failed to open %1 無法開啟 %1 - + failed to change origin name: %1 無法更改原始檔案名: %1 - + + failed to move "%1" from mod "%2" to "%3": %4 + + + + Multiple esps activated, please check that they don't conflict. - - + + Create Mod... - + A mod with this name already exists - + Continue? - + The versioning scheme decides which version is considered newer than another. This function will guess the versioning scheme under the assumption that the installed version is outdated. - - + + Sorry - + I don't know a versioning scheme where %1 is newer than %2. - + <All> <全部> - + <Checked> <已勾選> - + Plugin "%1" failed - + failed to init plugin %1: %2 - + The following plugins could not be loaded. The reason may be missing dependencies (i.e. python) or an outdated version: - + <Unchecked> <未勾選> - + <Update> <有更新> - + <No category> <無類別> - + <Conflicted> - + <Not Endorsed> - + failed to rename mod: %1 無法重新命名 Mod: %1 - + Overwrite? - + This will replace the existing mod "%1". Continue? - + failed to remove mod "%1" - - - + + + failed to rename "%1" to "%2" - - - - + + + + Confirm 確認 - + Remove the following mods?<br><ul>%1</ul> - + failed to remove mod: %1 無法移動 Mod: %1 - - + + Failed 失敗 - + Installation file no longer exists 安裝檔案不複存在 - + Mods installed with old versions of MO can't be reinstalled in this way. 舊版 MO 安裝的 Mod 無法使用此方法重新安裝。 - - + + You need to be logged in with Nexus to endorse - - + + Extract BSA 解壓 BSA - + This mod contains at least one BSA. Do you want to unpack it? (This removes the BSA after completion. If you don't know about BSAs, just select no) 此 Mod 中至少包含一個 BSA。您確定要解壓嗎? (解壓完成後,BSA 檔案將會被刪除。如果您不瞭解 BSA 的話,請選擇“否”) - - - + + + failed to read %1: %2 無法讀取 %1: %2 - - + + This archive contains invalid hashes. Some files may be broken. 壓縮包 Hash 值錯誤。部分檔案可能已經損壞。 - + Nexus ID for this Mod is unknown 此 Mod 的N網 ID 未知 @@ -2374,92 +2388,92 @@ This function will guess the versioning scheme under the assumption that the ins 選擇優先級 - + Really enable all visible mods? 確定要啟用全部可見的 Mod 嗎? - + Really disable all visible mods? 確定要禁用全部可見的 Mod 嗎? - + Choose what to export - + Everything - + All installed mods are included in the list - + Active Mods - + Only active (checked) mods from your current profile are included - + Visible - + All mods visible in the mod list are included - + export failed: %1 - + Install Mod... 安裝 Mod... - + Enable all visible 啟用所有可見項目 - + Disable all visible 禁用所有可見項目 - + Check all for update 檢查更新 - + Export to csv... - + Sync to Mods... 同步到 Mod... - + Restore Backup - + Remove Backup... @@ -2468,362 +2482,362 @@ This function will guess the versioning scheme under the assumption that the ins 設定類別 - + Primary Category - + Change versioning scheme - + Un-ignore update - + Ignore update - + Rename Mod... 重新命名... - + Remove Mod... 移除 Mod... - + Reinstall Mod 重新安裝 Mod - + Un-Endorse - - + + Endorse - + Won't endorse - + Endorsement state unknown - + Ignore missing data - + Visit on Nexus 在N網上流覽 - + Open in explorer 在檔案總管中開啟 - + Information... 訊息... - - + + Exception: 例外: - - + + Unknown exception 未知的例外 - + <Multiple> - + Really delete "%1"? - + Fix Mods... 修復 Mod... - + Delete - - + + failed to remove %1 無法刪除 %1 - - + + failed to create %1 無法建立 %1 - + Can't change download directory while downloads are in progress! 下載檔案時不能修改下載目錄! - + Download failed 下載失敗 - + failed to write to file %1 無法寫入檔案 %1 - + %1 written 已寫入 %1 - + Select binary 選擇可執行檔案 - + Binary - + Enter Name 輸入名稱 - + Please enter a name for the executable 請為程式輸入一個名稱 - + Not an executable 不是可執行程式 - + This is not a recognized executable. 無法識別的可執行檔案 - - + + Replace file? 取代檔案? - + There already is a hidden version of this file. Replace it? 已存在同名檔案,但該檔案被隱藏了。確定要覆蓋嗎? - - + + File operation failed 檔案操作錯誤 - - + + Failed to remove "%1". Maybe you lack the required file permissions? - + There already is a visible version of this file. Replace it? - + file not found: %1 檔案未找到: %1 - + failed to generate preview for %1 - + Sorry, can't preview anything. This function currently does not support extracting from bsas. - + Update available 更新可用 - + Open/Execute 開啟/執行 - + Add as Executable 添加為可執行檔案 - + Preview - + Un-Hide 取消隱藏 - + Hide 隱藏 - + Write To File... 寫入檔案... - + Do you want to endorse Mod Organizer on %1 now? - + Remove 移除 - + Unlock load order - + Lock load order - + BOSS working - + failed to run boss: %1 - + Request to Nexus failed: %1 - + Executable "%1" not found - + Failed to refresh list of esps: %1 - + This will move all files from overwrite into a new, regular mod. Please enter a name: - + Add/Remove Categories - + Replace Categories - - + + login successful 登入成功 - + login failed: %1. Trying to download anyway 登入失敗: %1,請嘗試使用別的方法下載 - + login failed: %1 無法登入: %1 - + login failed: %1. You need to log-in with Nexus to update MO. 登入失敗: %1。您需要登入到N網才能更新 MO - + Error 錯誤 - + failed to extract %1 (errorcode %2) 無法解壓 %1 (錯誤代碼 %2) - + Extract... 解壓... - + Edit Categories... 編輯類別... - + Enable all 全部啟用 - + Disable all 全部禁用 @@ -4765,64 +4779,64 @@ Right now this has very limited functionality ESP 檔案沒有找到: %1 - + Mod Index - + Flags - - + + unknown - + Name of your mods - + Load priority of your mod. The higher, the more "important" it is and thus overwrites data from plugins with lower priority. - + The modindex determins the formids of objects originating from this mods. - + failed to update esp info for file %1 (source id: %2), error: %3 - + esp not found: %1 - - + + Confirm 確認 - + Really enable all plugins? - + Really disable all plugins? - + The file containing locked plugin indices is broken @@ -4831,7 +4845,7 @@ Right now this has very limited functionality 無法開啟輸出檔案: %1 - + Some of your plugins have invalid names! These plugins can not be loaded by the game. Please see mo_interface.log for a list of affected plugins and rename them. 您的一些插件名稱無效!這些插件無法被遊戲載入。請查看 mo_interface.log 來確認那些受影響的插件並重新命名它們。 @@ -4841,17 +4855,17 @@ Right now this has very limited functionality - + Missing Masters - + Enabled Masters - + failed to restore load order for %1 @@ -4864,17 +4878,17 @@ Right now this has very limited functionality 最高值 - + This plugin can't be disabled (enforced by the game) 這個插件不能被禁用 (由遊戲執行) - + Origin: %1 隸屬於: %1 - + Name 名稱 @@ -4883,7 +4897,7 @@ Right now this has very limited functionality Mod 名稱 - + Priority 優先級 @@ -5466,23 +5480,23 @@ p, li { white-space: pre-wrap; } - + Please use "Help" from the toolbar to get usage instructions to all elements 請使用工具列上的“幫助”來獲得所有元素的使用說明 - - + + <Manage...> <管理...> - + failed to parse profile %1: %2 無法解析配置檔案 %1: %2 - + failed to find "%1" 未能找到 "%1" @@ -5492,12 +5506,12 @@ p, li { white-space: pre-wrap; } 編碼錯誤,請向作者彙報此 Bug 並且附上 mo_interface.log 檔案! - + failed to access %1 無法訪問 %1 - + failed to set file time %1 無法設定檔案時間 %1 diff --git a/src/settings.cpp b/src/settings.cpp index 895094f7..dd3891d4 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -223,7 +223,7 @@ QString Settings::getModDirectory() const QString Settings::getNMMVersion() const { - static const QString MIN_NMM_VERSION = "0.46.0"; + static const QString MIN_NMM_VERSION = "0.47.0"; QString result = m_Settings.value("Settings/nmm_version", MIN_NMM_VERSION).toString(); if (VersionInfo(result) < VersionInfo(MIN_NMM_VERSION)) { result = MIN_NMM_VERSION; -- cgit v1.3.1 From f9eba9dc15ec655cc16efbb1ddccac3a562741d5 Mon Sep 17 00:00:00 2001 From: Tannin Date: Mon, 17 Feb 2014 21:15:20 +0100 Subject: - ini file changes that would have to overwrite ini tweaks are now stored in a separate file and actually get used. - a warning message advices users to clean out that separate file - slightly improved default main window layout - bugfix: newly created ini tweaks were added to the list with incorrect properties --- src/mainwindow.cpp | 4 ++ src/mainwindow.ui | 4 +- src/modinfo.cpp | 120 +++++++++++++++++++++-------------------------- src/modinfo.h | 6 +++ src/modinfodialog.cpp | 17 +++---- src/profile.cpp | 6 +++ src/profile.h | 5 ++ src/shared/appconfig.inc | 1 + 8 files changed, 85 insertions(+), 78 deletions(-) (limited to 'src/mainwindow.ui') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 12db5e2b..556c33f3 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -217,6 +217,9 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget ui->bsaList->setLocalMoveOnly(true); + ui->splitter->setStretchFactor(0, 3); + ui->splitter->setStretchFactor(1, 2); + resizeLists(initSettings.contains("mod_list_state"), initSettings.contains("plugin_list_state")); QMenu *linkMenu = new QMenu(this); @@ -3158,6 +3161,7 @@ void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index, dialog->activateWindow(); connect(dialog, SIGNAL(finished(int)), this, SLOT(overwriteClosed(int))); } else { + modInfo->saveMeta(); ModInfoDialog dialog(modInfo, m_DirectoryStructure, this); connect(&dialog, SIGNAL(nexusLinkActivated(QString)), this, SLOT(nexusLinkActivated(QString))); connect(&dialog, SIGNAL(downloadRequest(QString)), this, SLOT(downloadRequestedNXM(QString))); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 110c14c6..26cbbf83 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -6,8 +6,8 @@ 0 0 - 868 - 701 + 926 + 710 diff --git a/src/modinfo.cpp b/src/modinfo.cpp index ff44b392..ed13deae 100644 --- a/src/modinfo.cpp +++ b/src/modinfo.cpp @@ -300,8 +300,37 @@ ModInfoRegular::ModInfoRegular(const QDir &path, DirectoryEntry **directoryStruc testValid(); m_CreationTime = QFileInfo(path.absolutePath()).created(); // read out the meta-file for information - QString metaFileName = path.absoluteFilePath("meta.ini"); - QSettings metaFile(metaFileName, QSettings::IniFormat); + readMeta(); + + connect(&m_NexusBridge, SIGNAL(descriptionAvailable(int,QVariant,QVariant)), this, SLOT(nxmDescriptionAvailable(int,QVariant,QVariant))); + connect(&m_NexusBridge, SIGNAL(endorsementToggled(int,QVariant,QVariant)), this, SLOT(nxmEndorsementToggled(int,QVariant,QVariant))); + connect(&m_NexusBridge, SIGNAL(requestFailed(int,int,QVariant,QString)), this, SLOT(nxmRequestFailed(int,int,QVariant,QString))); +} + + +ModInfoRegular::~ModInfoRegular() +{ + try { + saveMeta(); + } catch (const std::exception &e) { + qCritical("failed to save meta information for \"%s\": %s", + m_Name.toUtf8().constData(), e.what()); + } +} + +bool ModInfoRegular::isEmpty() const +{ + QDirIterator iter(m_Path, QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs); + if (!iter.hasNext()) return true; + iter.next(); + if ((iter.fileName() == "meta.ini") && !iter.hasNext()) return true; + return false; +} + + +void ModInfoRegular::readMeta() +{ + QSettings metaFile(m_Path + "/meta.ini", QSettings::IniFormat); m_Notes = metaFile.value("notes", "").toString(); m_NexusID = metaFile.value("modid", -1).toInt(); @@ -324,7 +353,6 @@ ModInfoRegular::ModInfoRegular(const QDir &path, DirectoryEntry **directoryStruc } } - QString categoriesString = metaFile.value("category", "").toString(); QStringList categories = categoriesString.split(',', QString::SkipEmptyParts); @@ -343,77 +371,39 @@ ModInfoRegular::ModInfoRegular(const QDir &path, DirectoryEntry **directoryStruc } } - connect(&m_NexusBridge, SIGNAL(descriptionAvailable(int,QVariant,QVariant)), this, SLOT(nxmDescriptionAvailable(int,QVariant,QVariant))); - connect(&m_NexusBridge, SIGNAL(endorsementToggled(int,QVariant,QVariant)), this, SLOT(nxmEndorsementToggled(int,QVariant,QVariant))); - connect(&m_NexusBridge, SIGNAL(requestFailed(int,int,QVariant,QString)), this, SLOT(nxmRequestFailed(int,int,QVariant,QString))); -} - - -ModInfoRegular::~ModInfoRegular() -{ - try { - saveMeta(); - } catch (const std::exception &e) { - qCritical("failed to save meta information for \"%s\": %s", - m_Name.toUtf8().constData(), e.what()); - } -} - -bool ModInfoRegular::isEmpty() const -{ - QDirIterator iter(m_Path, QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs); - if (!iter.hasNext()) return true; - iter.next(); - if ((iter.fileName() == "meta.ini") && !iter.hasNext()) return true; - return false; + m_MetaInfoChanged = false; } - void ModInfoRegular::saveMeta() { // only write meta data if the mod directory exists if (m_MetaInfoChanged && QFile::exists(absolutePath())) { - bool success = false; - { - QSettings metaFile(absolutePath().append("/meta.ini.new"), QSettings::IniFormat); - if (metaFile.status() == QSettings::NoError) { - std::set temp = m_Categories; - temp.erase(m_PrimaryCategory); - metaFile.setValue("category", QString("%1").arg(m_PrimaryCategory) + "," + SetJoin(temp, ",")); - metaFile.setValue("newestVersion", m_NewestVersion.canonicalString()); - metaFile.setValue("ignoredVersion", m_IgnoredVersion.canonicalString()); - metaFile.setValue("version", m_Version.canonicalString()); - if (m_NexusID != -1) { - metaFile.setValue("modid", m_NexusID); - } - metaFile.setValue("notes", m_Notes); - metaFile.setValue("nexusDescription", m_NexusDescription); - metaFile.setValue("lastNexusQuery", m_LastNexusQuery.toString(Qt::ISODate)); - if (m_EndorsedState != ENDORSED_UNKNOWN) { - metaFile.setValue("endorsed", m_EndorsedState); - } - metaFile.sync(); // sync needs to be called to ensure the file is created - - if (metaFile.status() == QSettings::NoError) { - success = true; - m_MetaInfoChanged = false; - } else { - reportError(tr("failed to write %1/meta.ini: error %2").arg(absolutePath()).arg(metaFile.status())); - } - } else { - reportError(tr("failed to write %1/meta.ini: error %2").arg(absolutePath()).arg(metaFile.status())); + QSettings metaFile(absolutePath().append("/meta.ini"), QSettings::IniFormat); + if (metaFile.status() == QSettings::NoError) { + std::set temp = m_Categories; + temp.erase(m_PrimaryCategory); + metaFile.setValue("category", QString("%1").arg(m_PrimaryCategory) + "," + SetJoin(temp, ",")); + metaFile.setValue("newestVersion", m_NewestVersion.canonicalString()); + metaFile.setValue("ignoredVersion", m_IgnoredVersion.canonicalString()); + metaFile.setValue("version", m_Version.canonicalString()); + if (m_NexusID != -1) { + metaFile.setValue("modid", m_NexusID); } - } - if (success) { - if (!QFile::remove(absolutePath().append("/meta.ini"))) { - qCritical("failed to remove %s", qPrintable(absolutePath().append("/meta.ini"))); - return; + metaFile.setValue("notes", m_Notes); + metaFile.setValue("nexusDescription", m_NexusDescription); + metaFile.setValue("lastNexusQuery", m_LastNexusQuery.toString(Qt::ISODate)); + if (m_EndorsedState != ENDORSED_UNKNOWN) { + metaFile.setValue("endorsed", m_EndorsedState); } - if (QFile::rename(absolutePath().append("/meta.ini.new"), absolutePath().append("/meta.ini"))) { - qDebug("%s written", qPrintable(absolutePath().append("/meta.ini"))); + metaFile.sync(); // sync needs to be called to ensure the file is created + + if (metaFile.status() == QSettings::NoError) { + m_MetaInfoChanged = false; } else { - qCritical("writing %s failed", qPrintable(absolutePath().append("/meta.ini"))); + reportError(tr("failed to write %1/meta.ini: error %2").arg(absolutePath()).arg(metaFile.status())); } + } else { + reportError(tr("failed to write %1/meta.ini: error %2").arg(absolutePath()).arg(metaFile.status())); } } } @@ -717,13 +707,11 @@ QString ModInfoRegular::getNexusDescription() const return m_NexusDescription; } - ModInfoRegular::EEndorsedState ModInfoRegular::endorsedState() const { return m_EndorsedState; } - ModInfoRegular::EConflictType ModInfoRegular::isConflicted() const { // this is costy so cache the result diff --git a/src/modinfo.h b/src/modinfo.h index b7d72584..8b37b915 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -431,6 +431,11 @@ public: */ void testValid(); + /** + * @brief reads meta information from disk + */ + virtual void readMeta() {} + /** * @brief stores meta information back to disk */ @@ -748,6 +753,7 @@ public: */ virtual void saveMeta(); + void readMeta(); private: enum EConflictType { diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp index 117b2726..dae4cc18 100644 --- a/src/modinfodialog.cpp +++ b/src/modinfodialog.cpp @@ -158,9 +158,8 @@ ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directo ModInfoDialog::~ModInfoDialog() { m_ModInfo->setNotes(ui->notesEdit->toPlainText()); - saveIniTweaks(); saveCategories(ui->categoriesTree->invisibleRootItem()); - + saveIniTweaks(); // ini tweaks are written to the ini file directly. This is the only information not managed by ModInfo delete ui; delete m_Settings; } @@ -216,7 +215,6 @@ QByteArray ModInfoDialog::saveTabState() const stream << ui->tabWidget->count(); for (int i = 0; i < ui->tabWidget->count(); ++i) { stream << ui->tabWidget->widget(i)->objectName(); - } return result; @@ -475,18 +473,15 @@ void ModInfoDialog::openIniFile(const QString &fileName) void ModInfoDialog::saveIniTweaks() { - QListWidget *iniTweaksList = findChild("iniTweaksList"); - m_Settings->beginWriteArray("INI Tweaks"); int countEnabled = 0; - for (int i = 0; i < iniTweaksList->count(); ++i) { - if (iniTweaksList->item(i)->checkState() == Qt::Checked) { + for (int i = 0; i < ui->iniTweaksList->count(); ++i) { + if (ui->iniTweaksList->item(i)->checkState() == Qt::Checked) { m_Settings->setArrayIndex(countEnabled++); - m_Settings->setValue("name", iniTweaksList->item(i)->text()); + m_Settings->setValue("name", ui->iniTweaksList->item(i)->text()); } } - m_Settings->endArray(); } @@ -1229,8 +1224,10 @@ void ModInfoDialog::createTweak() return; } - QListWidgetItem *newTweak = new QListWidgetItem(name); + QListWidgetItem *newTweak = new QListWidgetItem(name + ".ini"); newTweak->setData(Qt::UserRole, "INI Tweaks/" + name + ".ini"); + newTweak->setFlags(newTweak->flags() | Qt::ItemIsUserCheckable); + newTweak->setCheckState(Qt::Unchecked); ui->iniTweaksList->addItem(newTweak); } diff --git a/src/profile.cpp b/src/profile.cpp index c1f1025e..41a867c5 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -201,6 +201,7 @@ void Profile::createTweakedIniFile() } } + mergeTweak(getProfileTweaks(), tweakedIni); bool error = false; if (!::WritePrivateProfileStringW(L"Archive", L"bInvalidateOlderFiles", L"1", ToWString(tweakedIni).c_str())) { @@ -740,6 +741,11 @@ QString Profile::getIniFileName() const return m_Directory.absoluteFilePath(ToQString(primaryIniFile)); } +QString Profile::getProfileTweaks() const +{ + return QDir::cleanPath(m_Directory.absoluteFilePath(ToQString(AppConfig::profileTweakIni()))); +} + QString Profile::getPath() const { diff --git a/src/profile.h b/src/profile.h index 9c678a23..4960671a 100644 --- a/src/profile.h +++ b/src/profile.h @@ -177,6 +177,11 @@ public: **/ QString getIniFileName() const; + /** + * @return the path of the tweak ini in this profile + */ + QString getProfileTweaks() const; + /** * @return path to this profile **/ diff --git a/src/shared/appconfig.inc b/src/shared/appconfig.inc index 7710925a..080d3655 100644 --- a/src/shared/appconfig.inc +++ b/src/shared/appconfig.inc @@ -1,6 +1,7 @@ APPPARAM(std::wstring, translationPrefix, L"organizer") APPPARAM(std::wstring, pluginPath, L"plugins") APPPARAM(std::wstring, stylesheetsPath, L"stylesheets") +APPPARAM(std::wstring, profileTweakIni, L"profile_tweaks.ini") APPPARAM(std::wstring, logFile, L"ModOrganizer.log") APPPARAM(std::wstring, proxyDLLTarget, L"steam_api.dll") APPPARAM(std::wstring, proxyDLLOrig, L"steam_api_orig.dll") // needs to be identical to the value used in proxydll-project -- cgit v1.3.1 From c017f4a0d50b67a44e276bd5ae8929ed3990c62c Mon Sep 17 00:00:00 2001 From: Tannin Date: Sat, 5 Apr 2014 15:14:37 +0200 Subject: - added buttons to backup and restore the modlist and pluginlist - replaced boss integration with loot --- src/ModOrganizer.pro | 3 +- src/main.cpp | 23 +--- src/mainwindow.cpp | 204 ++++++++++++++++++++++++++++++++- src/mainwindow.h | 16 ++- src/mainwindow.ui | 112 +++++++++++++++++-- src/modlist.cpp | 2 +- src/pluginlist.cpp | 224 +------------------------------------ src/pluginlist.h | 83 +------------- src/profile.h | 6 +- src/resources.qrc | 3 + src/resources/arrange-boxes.png | Bin 0 -> 1634 bytes src/resources/document-save_32.png | Bin 0 -> 1971 bytes src/resources/edit-undo.png | Bin 0 -> 1601 bytes src/selectiondialog.cpp | 123 ++++++++++---------- src/selectiondialog.h | 96 ++++++++-------- src/shared/gameinfo.cpp | 8 ++ src/shared/gameinfo.h | 1 + src/spawn.cpp | 29 ++++- src/spawn.h | 8 +- 19 files changed, 486 insertions(+), 455 deletions(-) create mode 100644 src/resources/arrange-boxes.png create mode 100644 src/resources/document-save_32.png create mode 100644 src/resources/edit-undo.png (limited to 'src/mainwindow.ui') diff --git a/src/ModOrganizer.pro b/src/ModOrganizer.pro index 05b05855..62de3f66 100644 --- a/src/ModOrganizer.pro +++ b/src/ModOrganizer.pro @@ -14,7 +14,8 @@ SUBDIRS = bsatk \ BossDummy \ pythonRunner \ boss_modified \ - esptk + esptk \ + loot_cli plugins.depends = pythonRunner hookdll.depends = shared diff --git a/src/main.cpp b/src/main.cpp index ac903615..d1c5e263 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -80,24 +80,6 @@ using namespace MOBase; using namespace MOShared; -void removeOldLogfiles() -{ - QFileInfoList files = QDir(ToQString(GameInfo::instance().getLogDir())).entryInfoList(QStringList("ModOrganizer*.log"), - QDir::Files, QDir::Name); - - if (files.count() > 5) { - QStringList deleteFiles; - for (int i = 0; i < files.count() - 5; ++i) { - deleteFiles.append(files.at(i).absoluteFilePath()); - } - - if (!shellDelete(deleteFiles)) { - qWarning("failed to remove log files: %s", qPrintable(windowsErrorString(::GetLastError()))); - } - } -} - - // set up required folders (for a first install or after an update or to fix a broken installation) bool bootstrap() { @@ -111,7 +93,7 @@ bool bootstrap() } // cycle logfile - removeOldLogfiles(); + removeOldFiles(ToQString(GameInfo::instance().getLogDir()), "ModOrganizer*.log", 5, QDir::Name); // create organizer directories QString dirNames[] = { @@ -120,8 +102,7 @@ bool bootstrap() QDir::fromNativeSeparators(ToQString(gameInfo.getDownloadDir())), QDir::fromNativeSeparators(ToQString(gameInfo.getOverwriteDir())), QDir::fromNativeSeparators(ToQString(gameInfo.getLogDir())), - QDir::fromNativeSeparators(ToQString(gameInfo.getTutorialDir())), - QDir::fromNativeSeparators(ToQString(gameInfo.getOrganizerDirectory()) + "/boss") + QDir::fromNativeSeparators(ToQString(gameInfo.getTutorialDir())) }; static const int NUM_DIRECTORIES = sizeof(dirNames) / sizeof(QString); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index bf5ea7f0..87360f3c 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -109,8 +109,10 @@ along with Mod Organizer. If not, see . #include #endif #include +#include #include #include +#include #ifdef TEST_MODELS @@ -2649,7 +2651,6 @@ void MainWindow::directory_refreshed() delete oldStructure; refreshDataTree(); - refreshLists(); } else { // TODO: don't know why this happens, this slot seems to get called twice with only one emit return; @@ -5155,20 +5156,213 @@ void MainWindow::on_showHiddenBox_toggled(bool checked) m_DownloadManager.setShowHidden(checked); } + +void MainWindow::createStdoutPipe(HANDLE *stdOutRead, HANDLE *stdOutWrite) +{ + SECURITY_ATTRIBUTES secAttributes; + secAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); + secAttributes.bInheritHandle = TRUE; + secAttributes.lpSecurityDescriptor = NULL; + + if (!::CreatePipe(stdOutRead, stdOutWrite, &secAttributes, 0)) { + qCritical("failed to create stdout reroute"); + } + + if (!::SetHandleInformation(*stdOutRead, HANDLE_FLAG_INHERIT, 0)) { + qCritical("failed to correctly set up the stdout reroute"); + *stdOutWrite = *stdOutRead = INVALID_HANDLE_VALUE; + } +} + +std::string MainWindow::readFromPipe(HANDLE stdOutRead) +{ + static const int chunkSize = 128; + std::string result; + + char buffer[chunkSize + 1]; + buffer[chunkSize] = '\0'; + + DWORD read = 1; + while (read > 0) { + if (!::ReadFile(stdOutRead, buffer, chunkSize, &read, NULL)) { + break; + } + if (read > 0) { + result.append(buffer, read); + if (read < chunkSize) { + break; + } + } + } + return result; +} + void MainWindow::on_bossButton_clicked() { try { this->setEnabled(false); ON_BLOCK_EXIT([&] () { this->setEnabled(true); }); - LockedDialog dialog(this, tr("BOSS working"), false); + QProgressDialog dialog(this); + dialog.setLabelText(tr("LOOT working")); + dialog.setMaximum(0); dialog.show(); - qApp->processEvents(); - m_PluginList.bossSort(); - savePluginList(); + QStringList parameters; + parameters << "--game" << ToQString(GameInfo::instance().getGameName()) + << "--gamePath" << ToQString(GameInfo::instance().getGameDirectory()); + + HANDLE stdOutWrite = INVALID_HANDLE_VALUE; + HANDLE stdOutRead = INVALID_HANDLE_VALUE; + createStdoutPipe(&stdOutRead, &stdOutWrite); + + HANDLE loot = startBinary(QFileInfo(qApp->applicationDirPath() + "/lootcli.exe"), + parameters.join(" "), + m_CurrentProfile->getName(), + m_Settings.logLevel(), + qApp->applicationDirPath(), + true, + stdOutWrite); + + // we don't use the write end + ::CloseHandle(stdOutWrite); + + if (loot != INVALID_HANDLE_VALUE) { + while (::WaitForSingleObject(loot, 100) == WAIT_TIMEOUT) { + // keep processing events so the app doesn't appear dead + QCoreApplication::processEvents(); + if (dialog.wasCanceled()) { + ::TerminateProcess(loot, 1); + } + std::string lootOut = readFromPipe(stdOutRead); + std::vector lines; + boost::split(lines, lootOut, boost::is_any_of("\r\n")); + foreach (const std::string &line, lines) { + if (line.length() > 0) { + size_t progidx = line.find("[progress]"); + size_t reportidx = line.find("[report]"); + if (progidx != std::string::npos) { + dialog.setLabelText(line.substr(progidx + 11).c_str()); + } else if (reportidx != std::string::npos) { + qDebug("report at %s", line.substr(reportidx + 9).c_str()); + } else { + qDebug("%s", line.c_str()); + } + } + } + } + std::string remainder = readFromPipe(stdOutRead).c_str(); + if (remainder.length() > 0) { + qDebug("%s", remainder.c_str()); + } + + refreshESPList(); + + if (GameInfo::instance().getLoadOrderMechanism() == GameInfo::TYPE_FILETIME) { + QFile::remove(m_CurrentProfile->getLoadOrderFileName()); + } + } + dialog.hide(); } catch (const std::exception &e) { reportError(tr("failed to run boss: %1").arg(e.what())); ui->bossButton->setEnabled(false); } } + + +const char *MainWindow::PATTERN_BACKUP_GLOB = ".????_??_??_??_??_??"; +const char *MainWindow::PATTERN_BACKUP_REGEX = "\\.(\\d\\d\\d\\d_\\d\\d_\\d\\d_\\d\\d_\\d\\d_\\d\\d)"; +const char *MainWindow::PATTERN_BACKUP_DATE = "yyyy_MM_dd_hh_mm_ss"; + + +bool MainWindow::createBackup(const QString &filePath, const QDateTime &time) +{ + QString outPath = filePath + "." + time.toString(PATTERN_BACKUP_DATE); + if (shellCopy(QStringList(filePath), QStringList(outPath), this)) { + QFileInfo fileInfo(filePath); + removeOldFiles(fileInfo.absolutePath(), fileInfo.fileName() + PATTERN_BACKUP_GLOB, 3, QDir::Name); + return true; + } else { + return false; + } +} + +void MainWindow::on_saveButton_clicked() +{ + savePluginList(); + QDateTime now = QDateTime::currentDateTime(); + if (createBackup(m_CurrentProfile->getPluginsFileName(), now) + && createBackup(m_CurrentProfile->getLoadOrderFileName(), now) + && createBackup(m_CurrentProfile->getLockedOrderFileName(), now)) { + MessageDialog::showMessage(tr("Backup of load order created"), this); + } +} + +QString MainWindow::queryRestore(const QString &filePath) +{ + QFileInfo pluginFileInfo(filePath); + QString pattern = pluginFileInfo.fileName() + ".*"; + QFileInfoList files = pluginFileInfo.absoluteDir().entryInfoList(QStringList(pattern), QDir::Files, QDir::Name); + + SelectionDialog dialog(tr("Choose backup to restore"), this); + QRegExp exp(pluginFileInfo.fileName() + PATTERN_BACKUP_REGEX); + QRegExp exp2(pluginFileInfo.fileName() + "\\.(.*)"); + foreach(const QFileInfo &info, files) { + if (exp.exactMatch(info.fileName())) { + QDateTime time = QDateTime::fromString(exp.cap(1), PATTERN_BACKUP_DATE); + dialog.addChoice(time.toString(), "", exp.cap(1)); + } else if (exp2.exactMatch(info.fileName())) { + dialog.addChoice(exp2.cap(1), "", exp2.cap(1)); + } + } + + if (dialog.numChoices() == 0) { + QMessageBox::information(this, tr("No Backups"), tr("There are no backups to restore")); + return QString(); + } + + if (dialog.exec() == QDialog::Accepted) { + return dialog.getChoiceData().toString(); + } else { + return QString(); + } +} + +void MainWindow::on_restoreButton_clicked() +{ + QString pluginName = m_CurrentProfile->getPluginsFileName(); + QString choice = queryRestore(pluginName); + if (!choice.isEmpty()) { + QString loadOrderName = m_CurrentProfile->getLoadOrderFileName(); + QString lockedName = m_CurrentProfile->getLockedOrderFileName(); + if (!shellCopy(pluginName + "." + choice, pluginName, true, this) || + !shellCopy(loadOrderName + "." + choice, loadOrderName, true, this) || + !shellCopy(lockedName + "." + choice, lockedName, true, this)) { + QMessageBox::critical(this, tr("Restore failed"), + tr("Failed to restore the backup. Errorcode: %1").arg(windowsErrorString(::GetLastError()))); + } + refreshESPList(); + } +} + +void MainWindow::on_saveModsButton_clicked() +{ + m_CurrentProfile->writeModlistNow(true); + QDateTime now = QDateTime::currentDateTime(); + if (createBackup(m_CurrentProfile->getModlistFileName(), now)) { + MessageDialog::showMessage(tr("Backup of modlist created"), this); + } +} +void MainWindow::on_restoreModsButton_clicked() +{ + QString modlistName = m_CurrentProfile->getModlistFileName(); + QString choice = queryRestore(modlistName); + if (!choice.isEmpty()) { + if (!shellCopy(modlistName + "." + choice, modlistName, true, this)) { + QMessageBox::critical(this, tr("Restore failed"), + tr("Failed to restore the backup. Errorcode: %1").arg(windowsErrorString(::GetLastError()))); + } + refreshModList(false); + } +} + diff --git a/src/mainwindow.h b/src/mainwindow.h index 23923677..c5b4a8d3 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -154,6 +154,8 @@ public: void saveArchiveList(); + void createStdoutPipe(HANDLE *stdOutRead, HANDLE *stdOutWrite); + std::string readFromPipe(HANDLE stdOutRead); public slots: void displayColumnSelection(const QPoint &pos); @@ -207,8 +209,6 @@ private: bool nexusLogin(); - void saveCurrentESPList(); - bool testForSteam(); void startSteam(); @@ -290,11 +290,18 @@ private: void activateProxy(bool activate); void installTranslator(const QString &name); + bool createBackup(const QString &filePath, const QDateTime &time); + QString queryRestore(const QString &filePath); + private: static const unsigned int PROBLEM_PLUGINSNOTLOADED = 1; static const unsigned int PROBLEM_TOOMANYPLUGINS = 2; + static const char *PATTERN_BACKUP_GLOB; + static const char *PATTERN_BACKUP_REGEX; + static const char *PATTERN_BACKUP_DATE; + private: Ui::MainWindow *ui; @@ -574,6 +581,11 @@ private slots: // ui slots void on_showHiddenBox_toggled(bool checked); void on_bsaList_itemChanged(QTreeWidgetItem *item, int column); void on_bossButton_clicked(); + + void on_saveButton_clicked(); + void on_restoreButton_clicked(); + void on_restoreModsButton_clicked(); + void on_saveModsButton_clicked(); }; #endif // MAINWINDOW_H diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 26cbbf83..dc91121c 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -115,7 +115,7 @@ 2 - + @@ -170,6 +170,47 @@ p, li { white-space: pre-wrap; } + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Restore Backup... + + + + + + + :/MO/gui/restore:/MO/gui/restore + + + + + + + Create Backup + + + + + + + :/MO/gui/backup:/MO/gui/backup + + + @@ -617,6 +658,68 @@ p, li { white-space: pre-wrap; } 0 + + + + + + Sort + + + + :/MO/gui/sort:/MO/gui/sort + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Restore Backup... + + + + + + + :/MO/gui/restore:/MO/gui/restore + + + + 16 + 16 + + + + + + + + Create Backup + + + + + + + :/MO/gui/backup:/MO/gui/backup + + + + + @@ -725,13 +828,6 @@ p, li { white-space: pre-wrap; } - - - - Sort - - -
      diff --git a/src/modlist.cpp b/src/modlist.cpp index e2cb7cf0..836406e4 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -669,7 +669,7 @@ bool ModList::dropURLs(const QMimeData *mimeData, int row, const QModelIndex &pa } if (source.count() != 0) { - shellMove(source, target, NULL); + shellMove(source, target); } return true; diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index af6f42da..1f4ed9b1 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -78,7 +78,6 @@ PluginList::PluginList(QObject *parent) : QAbstractItemModel(parent) , m_FontMetrics(QFont()) , m_SaveTimer(this) - , m_BOSS(NULL) { m_SaveTimer.setSingleShot(true); connect(&m_SaveTimer, SIGNAL(timeout()), this, SIGNAL(saveTimer())); @@ -95,11 +94,6 @@ PluginList::PluginList(QObject *parent) PluginList::~PluginList() { - if (m_BOSS != NULL) { - m_BOSS->CleanUpAPI(); - delete m_BOSS; - m_BOSS = NULL; - } } @@ -595,225 +589,9 @@ void PluginList::refreshLoadOrder() } -class boss_exception : public std::runtime_error { -public: - boss_exception(const std::string &message) : std::runtime_error(message) {} -}; - -#define THROW_BOSS_ERROR(obj) \ - uint8_t *message; \ - obj->GetLastErrorDetails(&message); \ - throw boss_exception(std::string(reinterpret_cast(message))); - -#define U8(text) reinterpret_cast(text) - - -void outputBossLog(const QString &filename) -{ - QFile file(filename); - if (file.open(QIODevice::ReadOnly)) { - while (!file.atEnd()) { - QByteArray line = file.readLine().trimmed(); - if (line.length() < 1) - continue; - - int endFirstWord = line.indexOf(':'); - if (endFirstWord < 0) { - endFirstWord = 0; - } - QString firstWord = line.mid(0, endFirstWord); - if (firstWord == "DEBUG") { - qDebug("(boss) %s", line.mid(endFirstWord + 2).constData()); - } else { - qWarning("(boss) %s", line.mid(endFirstWord + 2).constData()); - } - } - } - file.resize(0); -} - - -boss_db PluginList::initBoss() -{ - boss_db result; - bool firstRun = (m_BOSS == nullptr); - if (firstRun) { - m_BOSS = new BossDLL(TEXT("dlls\\boss.dll")); - - if (!m_BOSS->IsCompatibleVersion(2,1,1)) { - throw MyException(tr("BOSS dll incompatible")); - } - uint8_t *versionString; - if (m_BOSS->GetVersionString(&versionString) != BossDLL::RESULT_OK) { - THROW_BOSS_ERROR(m_BOSS) - } - qDebug("using boss version %s", versionString); - - m_TempFile.open(); m_TempFile.close(); // yeah, stupid, but open is required to generate the name - m_BOSS->SetLoggerOutput(m_TempFile.fileName().toLocal8Bit().constData(), 4); - } - - if (m_BOSS->CreateBossDb(&result, BossDLL::SKYRIM, NULL) != BossDLL::RESULT_OK) { - uint8_t *message; - m_BOSS->GetLastErrorDetails(&message); - std::string messageCopy(reinterpret_cast(message)); - delete m_BOSS; - m_BOSS = NULL; - throw boss_exception(messageCopy); - } - qApp->processEvents(); - - QString masterlistName = QDir::toNativeSeparators(qApp->applicationDirPath() + "/boss/masterlist.txt"); - - if (firstRun) { - uint32_t res = m_BOSS->UpdateMasterlist(result, U8(masterlistName.toUtf8().constData())); - qApp->processEvents(); - if (res == BossDLL::RESULT_OK) { - qDebug("boss masterlist updated"); - } else if (res == BossDLL::RESULT_NO_UPDATE_NECESSARY) { - qDebug("boss masterlist already up-to-date"); - } else { - THROW_BOSS_ERROR(m_BOSS) - } - } - if (m_BOSS->Load(result, - U8(masterlistName.toUtf8().constData()), - U8(QDir::toNativeSeparators(qApp->applicationDirPath() + "/boss/userlist.txt").toUtf8().constData())) != BossDLL::RESULT_OK) { - THROW_BOSS_ERROR(m_BOSS) - } - return result; -} - -void PluginList::convertPluginListForBoss(boss_db db, boost::ptr_vector &inputPlugins, std::vector &activePlugins) -{ - foreach (int idx, m_ESPsByPriority) { - QString fileName = m_ESPs[idx].m_Name; - QByteArray name = fileName.toUtf8(); - - uint8_t *nameU8 = new uint8_t[name.length() + 1]; - memcpy(nameU8, name.constData(), name.length() + 1); - if (m_ESPs[idx].m_Enabled) { - activePlugins.push_back(nameU8); - } - inputPlugins.push_back(nameU8); - } - if (m_BOSS->SetActivePluginsDumb(db, &activePlugins[0], activePlugins.size()) != BossDLL::RESULT_OK) { - THROW_BOSS_ERROR(m_BOSS) - } -} - -void PluginList::applyBOSSSorting(boss_db db, std::map &lockedLoadOrder, uint8_t **pluginList, size_t size, - int &priority, int &loadOrder, bool recognized, const char *extension) -{ - for (size_t i = 0; i < size; ++i) { - QString name = QString::fromUtf8(reinterpret_cast(pluginList[i])).toLower(); - if (name.endsWith(extension)) { - auto iter = m_ESPsByName.find(name); - if (iter == m_ESPsByName.end()) { - // boss seems to report plugins from userlist as sorted that aren't even installed - continue; - } - - BossMessage *message; - size_t numMessages = 0; - m_BOSS->GetPluginMessages(db, pluginList[i], &message, &numMessages); - BossInfo newInfo; - for (size_t im = 0; im < numMessages; ++im) { - newInfo.m_BOSSMessages.append(QString::fromUtf8(reinterpret_cast(message[im].message))); - } - newInfo.m_BOSSUnrecognized = !recognized; - m_BossInfo[name] = newInfo; - - // locked order plugins are not inserted by boss sorting ... - if (m_LockedOrder.find(name) != m_LockedOrder.end()) { - continue; - } - - // ... but by their enforced priority - while (lockedLoadOrder.find(loadOrder) != lockedLoadOrder.end()) { - auto lloIter = lockedLoadOrder.find(loadOrder); - auto nameIter = m_ESPsByName.find(lloIter->second); - if (nameIter != m_ESPsByName.end()) { - m_ESPs[nameIter->second].m_Priority = priority++; - if (m_ESPs[nameIter->second].m_Enabled) { - m_ESPs[nameIter->second].m_LoadOrder = loadOrder++; - } else { - m_ESPs[nameIter->second].m_LoadOrder = -1; - } - } - lockedLoadOrder.erase(lloIter); - } - - m_ESPs[iter->second].m_Priority = priority++; - if (m_ESPs[iter->second].m_Enabled) { - m_ESPs[iter->second].m_LoadOrder = loadOrder++; - } else { - m_ESPs[iter->second].m_LoadOrder = -1; - } - } - } -} - -void PluginList::bossSort() +void PluginList::lootSort() { - boss_db db = initBoss(); - ON_BLOCK_EXIT([&] { m_BOSS->DestroyBossDb(db); }); - - // create a boss-compatible representation of our current mod list. - boost::ptr_vector inputPlugins; - std::vector activePlugins; - convertPluginListForBoss(db, inputPlugins, activePlugins); - - // sort mods in-memory - uint8_t **sortedPlugins; - uint8_t **unrecognizedPlugins; - size_t sizeSorted, sizeUnrecognized; - if (m_BOSS->SortCustomMods(db, - inputPlugins.c_array(), inputPlugins.size(), - &sortedPlugins, &sizeSorted, - &unrecognizedPlugins, &sizeUnrecognized) != BossDLL::RESULT_OK) { - THROW_BOSS_ERROR(m_BOSS) - } - - // output the log from boss to our own log to make it visible - outputBossLog(m_TempFile.fileName()); - - qDebug("%d sorted, %d unrecognized", sizeSorted, sizeUnrecognized); - ChangeBracket layoutChange(this); - - std::map lockedLoadOrder; - std::for_each(m_LockedOrder.begin(), m_LockedOrder.end(), - [&lockedLoadOrder] (const std::pair &ele) { lockedLoadOrder[ele.second] = ele.first; }); - - int priority = 0; - int loadOrder = 0; - applyBOSSSorting(db, lockedLoadOrder, sortedPlugins, sizeSorted, priority, loadOrder, true, "esm"); - applyBOSSSorting(db, lockedLoadOrder, unrecognizedPlugins, sizeUnrecognized, priority, loadOrder, false, "esm"); - applyBOSSSorting(db, lockedLoadOrder, sortedPlugins, sizeSorted, priority, loadOrder, true, "esp"); - applyBOSSSorting(db, lockedLoadOrder, unrecognizedPlugins, sizeUnrecognized, priority, loadOrder, false, "esp"); - - // applyBOSSSorting removed entries from lockedLoadOrder when they were inserted so everything that's left is plugins - // locked to the end of the list. Now this inserts the rest in the ascending priority order. If the list is too short - // to place the plugins in their intended position then this guarantees plugins are kept in the correct relative order - // but it doesn't minimize the number of misplaced plugins. - for (auto iter = lockedLoadOrder.begin(); iter != lockedLoadOrder.end(); ++iter) { - auto nameIter = m_ESPsByName.find(iter->second); - if (nameIter != m_ESPsByName.end()) { - m_ESPs[nameIter->second].m_Priority = priority++; - if (m_ESPs[nameIter->second].m_Enabled) { - m_ESPs[nameIter->second].m_LoadOrder = loadOrder++; - } else { - m_ESPs[nameIter->second].m_LoadOrder = -1; - } - } - } - - // inform view of the changed data - updateIndices(); - layoutChange.finish(); - emit dataChanged(this->index(0, 0), this->index(m_ESPs.size(), columnCount())); - m_Refreshed(); } IPluginList::PluginState PluginList::state(const QString &name) const diff --git a/src/pluginlist.h b/src/pluginlist.h index fff2a595..5e8557e2 100644 --- a/src/pluginlist.h +++ b/src/pluginlist.h @@ -181,7 +181,7 @@ public: void refreshLoadOrder(); - void bossSort(); + void lootSort(); public: virtual PluginState state(const QString &name) const; @@ -204,7 +204,6 @@ public: // implementation of the QAbstractTableModel interface virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; virtual QModelIndex parent(const QModelIndex &child) const; - void applyBOSSSorting(boss_db db, std::map &lockedLoadOrder, uint8_t **pluginList, size_t size, int &priority, int &loadOrder, bool recognized, const char *extension); public slots: /** @@ -260,82 +259,6 @@ private: friend bool ByDate(const ESPInfo& LHS, const ESPInfo& RHS); friend bool ByPriority(const ESPInfo& LHS, const ESPInfo& RHS); - class BossDLL : public PDLL { - DECLARE_CLASS(BossDLL) - - DECLARE_FUNCTION3(__cdecl, uint32_t, CreateBossDb, boss_db*, const uint32_t, const uint8_t*) - DECLARE_FUNCTION1(__cdecl, void, DestroyBossDb, boss_db) - DECLARE_FUNCTION0(__cdecl, void, CleanUpAPI) - - DECLARE_FUNCTION7(__cdecl, uint32_t, SortCustomMods, boss_db, uint8_t**, size_t, uint8_t***, size_t*, uint8_t***, size_t*) - DECLARE_FUNCTION3(__cdecl, uint32_t, SetActivePluginsDumb, boss_db, uint8_t**, const size_t) - - DECLARE_FUNCTION3(__cdecl, uint32_t, GetActivePluginsDumb , boss_db, uint8_t***, size_t*) - - DECLARE_FUNCTION2(__cdecl, uint32_t, UpdateMasterlist, boss_db, const uint8_t*) - DECLARE_FUNCTION3(__cdecl, uint32_t, Load, boss_db, const uint8_t*, const uint8_t*) - - DECLARE_FUNCTION2(__cdecl, void, SetLoggerOutput, const char*, uint8_t) - DECLARE_FUNCTION1(__cdecl, uint32_t, GetLastErrorDetails, uint8_t**) - - DECLARE_FUNCTION1(__cdecl, uint32_t, GetVersionString, uint8_t**) - DECLARE_FUNCTION3(__cdecl, bool, IsCompatibleVersion, const uint32_t, const uint32_t, const uint32_t) - - DECLARE_FUNCTION4(__cdecl, uint32_t, GetPluginMessages, boss_db, const uint8_t*, BossMessage**, size_t*) - - enum ResultCode { - RESULT_OK = 0, - RESULT_NO_MASTER_FILE = 1, - RESULT_FILE_READ_FAIL = 2, - RESULT_FILE_WRITE_FAIL = 3, - RESULT_FILE_NOT_UTF8 = 4, - RESULT_FILE_NOT_FOUND = 5, - RESULT_FILE_PARSE_FAIL = 6, - RESULT_CONDITION_EVAL_FAIL = 7, - RESULT_REGEX_EVAL_FAIL = 8, - RESULT_NO_GAME_DETECTED = 9, - RESULT_ENCODING_CONVERSION_FAIL = 10, - RESULT_FIND_ONLINE_MASTERLIST_REVISION_FAIL = 11, - RESULT_FIND_ONLINE_MASTERLIST_DATE_FAIL = 12, - RESULT_READ_UPDATE_FILE_LIST_FAIL = 13, - RESULT_FILE_CRC_MISMATCH = 14, - RESULT_FS_FILE_MOD_TIME_READ_FAIL = 15, - RESULT_FS_FILE_MOD_TIME_WRITE_FAIL = 16, - RESULT_FS_FILE_RENAME_FAIL = 17, - RESULT_FS_FILE_DELETE_FAIL = 18, - RESULT_FS_CREATE_DIRECTORY_FAIL = 19, - RESULT_FS_ITER_DIRECTORY_FAIL = 20, - RESULT_CURL_INIT_FAIL = 21, - RESULT_CURL_SET_ERRBUFF_FAIL = 22, - RESULT_CURL_SET_OPTION_FAIL = 23, - RESULT_CURL_SET_PROXY_FAIL = 24, - RESULT_CURL_SET_PROXY_TYPE_FAIL = 25, - RESULT_CURL_SET_PROXY_AUTH_FAIL = 26, - RESULT_CURL_SET_PROXY_AUTH_TYPE_FAIL = 27, - RESULT_CURL_PERFORM_FAIL = 28, - RESULT_CURL_USER_CANCEL = 29, - RESULT_GUI_WINDOW_INIT_FAIL = 30, - RESULT_NO_UPDATE_NECESSARY = 31, - RESULT_LO_MISMATCH = 32, - RESULT_NO_MEM = 33, - RESULT_INVALID_ARGS = 34, - RESULT_NETWORK_FAIL = 35, - RESULT_NO_INTERNET_CONNECTION = 36, - RESULT_NO_TAG_MAP = 37, - RESULT_PLUGINS_FULL = 38, - RESULT_PLUGIN_BEFORE_MASTER = 39, - RESULT_INVALID_SYNTAX = 40 - }; - - enum GameIDs { - AUTODETECT = 0, - OBLIVION = 1, - SKYRIM = 3, - FALLOUT3 = 4, - FALLOUTNV = 5 - }; - }; - private: void syncLoadOrder(); @@ -353,9 +276,6 @@ private: void testMasters(); - boss_db initBoss(); - void convertPluginListForBoss(boss_db db, boost::ptr_vector &inputPlugins, std::vector &activePlugins); - private: std::vector m_ESPs; @@ -381,7 +301,6 @@ private: SignalRefreshed m_Refreshed; - BossDLL *m_BOSS; QTemporaryFile m_TempFile; }; diff --git a/src/profile.h b/src/profile.h index 4960671a..5aa77357 100644 --- a/src/profile.h +++ b/src/profile.h @@ -159,6 +159,11 @@ public: */ QString getLockedOrderFileName() const; + /** + * @return the path of the modlist file in this profile + */ + QString getModlistFileName() const; + /** * @return path of the archives file in this profile */ @@ -301,7 +306,6 @@ private: void updateIndices(); - QString getModlistFileName() const; void copyFilesTo(QString &target) const; std::vector splitDZString(const wchar_t *buffer) const; diff --git a/src/resources.qrc b/src/resources.qrc index 73921f64..bf53ea95 100644 --- a/src/resources.qrc +++ b/src/resources.qrc @@ -52,5 +52,8 @@ resources/x-office-calendar.png resources/dialog-warning_16.png resources/mail-attachment.png + resources/document-save_32.png + resources/edit-undo.png + resources/arrange-boxes.png diff --git a/src/resources/arrange-boxes.png b/src/resources/arrange-boxes.png new file mode 100644 index 00000000..b1ab67cf Binary files /dev/null and b/src/resources/arrange-boxes.png differ diff --git a/src/resources/document-save_32.png b/src/resources/document-save_32.png new file mode 100644 index 00000000..db5c52b7 Binary files /dev/null and b/src/resources/document-save_32.png differ diff --git a/src/resources/edit-undo.png b/src/resources/edit-undo.png new file mode 100644 index 00000000..61b2ce9a Binary files /dev/null and b/src/resources/edit-undo.png differ diff --git a/src/selectiondialog.cpp b/src/selectiondialog.cpp index dbc10791..902b4d9c 100644 --- a/src/selectiondialog.cpp +++ b/src/selectiondialog.cpp @@ -17,62 +17,67 @@ You should have received a copy of the GNU General Public License along with Mod Organizer. If not, see . */ -#include "selectiondialog.h" -#include "ui_selectiondialog.h" - -#include - -SelectionDialog::SelectionDialog(const QString &description, QWidget *parent) - : QDialog(parent), ui(new Ui::SelectionDialog), m_Choice(NULL), m_ValidateByData(false) -{ - ui->setupUi(this); - - ui->descriptionLabel->setText(description); -} - -SelectionDialog::~SelectionDialog() -{ - delete ui; -} - - -void SelectionDialog::addChoice(const QString &buttonText, const QString &description, const QVariant &data) -{ - QCommandLinkButton *button = new QCommandLinkButton(buttonText, description, ui->buttonBox); - button->setProperty("data", data); - ui->buttonBox->addButton(button, QDialogButtonBox::AcceptRole); - if (data.isValid()) m_ValidateByData = true; -} - - -QVariant SelectionDialog::getChoiceData() -{ - return m_Choice->property("data"); -} - - -QString SelectionDialog::getChoiceString() -{ - if ((m_Choice == NULL) || - (m_ValidateByData && !m_Choice->property("data").isValid())) { - return QString(); - } else { - return m_Choice->text(); - } -} - - -void SelectionDialog::on_buttonBox_clicked(QAbstractButton *button) -{ - m_Choice = button; - if (!m_ValidateByData || m_Choice->property("data").isValid()) { - this->accept(); - } else { - this->reject(); - } -} - -void SelectionDialog::on_cancelButton_clicked() -{ - this->reject(); -} +#include "selectiondialog.h" +#include "ui_selectiondialog.h" + +#include + +SelectionDialog::SelectionDialog(const QString &description, QWidget *parent) + : QDialog(parent), ui(new Ui::SelectionDialog), m_Choice(NULL), m_ValidateByData(false) +{ + ui->setupUi(this); + + ui->descriptionLabel->setText(description); +} + +SelectionDialog::~SelectionDialog() +{ + delete ui; +} + + +void SelectionDialog::addChoice(const QString &buttonText, const QString &description, const QVariant &data) +{ + QCommandLinkButton *button = new QCommandLinkButton(buttonText, description, ui->buttonBox); + button->setProperty("data", data); + ui->buttonBox->addButton(button, QDialogButtonBox::AcceptRole); + if (data.isValid()) m_ValidateByData = true; +} + +int SelectionDialog::numChoices() const +{ + return ui->buttonBox->findChildren(QString()).count(); +} + + +QVariant SelectionDialog::getChoiceData() +{ + return m_Choice->property("data"); +} + + +QString SelectionDialog::getChoiceString() +{ + if ((m_Choice == NULL) || + (m_ValidateByData && !m_Choice->property("data").isValid())) { + return QString(); + } else { + return m_Choice->text(); + } +} + + +void SelectionDialog::on_buttonBox_clicked(QAbstractButton *button) +{ + m_Choice = button; + if (!m_ValidateByData || m_Choice->property("data").isValid()) { + this->accept(); + } else { + this->reject(); + } +} + +void SelectionDialog::on_cancelButton_clicked() +{ + this->reject(); +} diff --git a/src/selectiondialog.h b/src/selectiondialog.h index a2844e97..fc04291e 100644 --- a/src/selectiondialog.h +++ b/src/selectiondialog.h @@ -17,50 +17,52 @@ You should have received a copy of the GNU General Public License along with Mod Organizer. If not, see . */ -#ifndef SELECTIONDIALOG_H -#define SELECTIONDIALOG_H - -#include -#include - -namespace Ui { -class SelectionDialog; -} - -class SelectionDialog : public QDialog -{ - Q_OBJECT - -public: - - explicit SelectionDialog(const QString &description, QWidget *parent = 0); - - ~SelectionDialog(); - - /** - * @brief add a choice to the dialog - * @param buttonText the text to be displayed on the button - * @param description the description that shows up under in small letters inside the button - * @param data data to be stored with the button. Please note that as soon as one choice has data associated with it (non-invalid QVariant) - * all buttons that contain no data will be treated as "cancel" buttons - */ - void addChoice(const QString &buttonText, const QString &description, const QVariant &data); - - QVariant getChoiceData(); - QString getChoiceString(); - -private slots: - - void on_buttonBox_clicked(QAbstractButton *button); - - void on_cancelButton_clicked(); - -private: - - Ui::SelectionDialog *ui; - QAbstractButton *m_Choice; - bool m_ValidateByData; - -}; - -#endif // SELECTIONDIALOG_H +#ifndef SELECTIONDIALOG_H +#define SELECTIONDIALOG_H + +#include +#include + +namespace Ui { +class SelectionDialog; +} + +class SelectionDialog : public QDialog +{ + Q_OBJECT + +public: + + explicit SelectionDialog(const QString &description, QWidget *parent = 0); + + ~SelectionDialog(); + + /** + * @brief add a choice to the dialog + * @param buttonText the text to be displayed on the button + * @param description the description that shows up under in small letters inside the button + * @param data data to be stored with the button. Please note that as soon as one choice has data associated with it (non-invalid QVariant) + * all buttons that contain no data will be treated as "cancel" buttons + */ + void addChoice(const QString &buttonText, const QString &description, const QVariant &data); + + int numChoices() const; + + QVariant getChoiceData(); + QString getChoiceString(); + +private slots: + + void on_buttonBox_clicked(QAbstractButton *button); + + void on_cancelButton_clicked(); + +private: + + Ui::SelectionDialog *ui; + QAbstractButton *m_Choice; + bool m_ValidateByData; + +}; + +#endif // SELECTIONDIALOG_H diff --git a/src/shared/gameinfo.cpp b/src/shared/gameinfo.cpp index 00bb42fd..b580a226 100644 --- a/src/shared/gameinfo.cpp +++ b/src/shared/gameinfo.cpp @@ -172,6 +172,14 @@ std::wstring GameInfo::getLogDir() const } +std::wstring GameInfo::getLootDir() const +{ + std::wostringstream temp; + temp << m_OrganizerDirectory << "\\loot"; + return temp.str(); +} + + std::wstring GameInfo::getTutorialDir() const { std::wostringstream temp; diff --git a/src/shared/gameinfo.h b/src/shared/gameinfo.h index 10775e6c..89c9402d 100644 --- a/src/shared/gameinfo.h +++ b/src/shared/gameinfo.h @@ -113,6 +113,7 @@ public: virtual std::wstring getCacheDir() const; virtual std::wstring getOverwriteDir() const; virtual std::wstring getLogDir() const; + virtual std::wstring getLootDir() const; virtual std::wstring getTutorialDir() const; virtual bool requiresBSAInvalidation() const { return true; } diff --git a/src/spawn.cpp b/src/spawn.cpp index b1c5e963..6adafba0 100644 --- a/src/spawn.cpp +++ b/src/spawn.cpp @@ -36,10 +36,23 @@ using namespace MOShared; static const int BUFSIZE = 4096; -bool spawn(LPCWSTR binary, LPCWSTR arguments, LPCWSTR currentDirectory, bool suspended, HANDLE& processHandle, HANDLE& threadHandle) +bool spawn(LPCWSTR binary, LPCWSTR arguments, LPCWSTR currentDirectory, bool suspended, + HANDLE stdOut, HANDLE stdErr, + HANDLE& processHandle, HANDLE& threadHandle) { + BOOL inheritHandles = FALSE; STARTUPINFO si; ::ZeroMemory(&si, sizeof(si)); + if (stdOut != INVALID_HANDLE_VALUE) { + si.hStdOutput = stdOut; + inheritHandles = TRUE; + si.dwFlags |= STARTF_USESTDHANDLES; + } + if (stdErr != INVALID_HANDLE_VALUE) { + si.hStdError = stdErr; + inheritHandles = TRUE; + si.dwFlags |= STARTF_USESTDHANDLES; + } si.cb = sizeof(si); int length = wcslen(binary) + wcslen(arguments) + 4; wchar_t *commandLine = NULL; @@ -74,7 +87,7 @@ bool spawn(LPCWSTR binary, LPCWSTR arguments, LPCWSTR currentDirectory, bool sus BOOL success = ::CreateProcess(NULL, commandLine, NULL, NULL, // no special process or thread attributes - FALSE, // don't inherit handle + inheritHandles, // inherit handles if we plan to use stdout or stderr reroute suspended ? CREATE_SUSPENDED : 0, // create suspended so I have time to inject the DLL NULL, // same environment as parent currentDirectory, // current directory @@ -95,14 +108,22 @@ bool spawn(LPCWSTR binary, LPCWSTR arguments, LPCWSTR currentDirectory, bool sus } -HANDLE startBinary(const QFileInfo &binary, const QString &arguments, const QString& profileName, int logLevel, const QDir ¤tDirectory, bool hooked) +HANDLE startBinary(const QFileInfo &binary, + const QString &arguments, + const QString& profileName, + int logLevel, + const QDir ¤tDirectory, + bool hooked, + HANDLE stdOut, + HANDLE stdErr) { HANDLE processHandle, threadHandle; std::wstring binaryName = ToWString(QDir::toNativeSeparators(binary.absoluteFilePath())); std::wstring currentDirectoryName = ToWString(QDir::toNativeSeparators(currentDirectory.absolutePath())); try { - if (!spawn(binaryName.c_str(), ToWString(arguments).c_str(), currentDirectoryName.c_str(), hooked, processHandle, threadHandle)) { + if (!spawn(binaryName.c_str(), ToWString(arguments).c_str(), currentDirectoryName.c_str(), hooked, + stdOut, stdErr, processHandle, threadHandle)) { reportError(QObject::tr("failed to spawn \"%1\"").arg(binary.fileName())); return INVALID_HANDLE_VALUE; } diff --git a/src/spawn.h b/src/spawn.h index 48320fea..3f037119 100644 --- a/src/spawn.h +++ b/src/spawn.h @@ -52,11 +52,17 @@ private: * @param arguments arguments to pass to the binary * @param profileName name of the active profile * @param currentDirectory the directory to use as the working directory to run in + * @param logLevel log level to be used by the hook library. Ignored if hooked is false * @param hooked if set, the binary is started with mo injected + * @param stdout if not equal to INVALID_HANDLE_VALUE, this is used as stdout for the process + * @param stderr if not equal to INVALID_HANDLE_VALUE, this is used as stderr for the process * @return the process handle * @todo is the profile name even used any more? * @todo is the hooked parameter used? **/ -HANDLE startBinary(const QFileInfo &binary, const QString &arguments, const QString &profileName, int logLevel, const QDir ¤tDirectory, bool hooked); +HANDLE startBinary(const QFileInfo &binary, const QString &arguments, const QString &profileName, int logLevel, + const QDir ¤tDirectory, bool hooked, + HANDLE stdOut = INVALID_HANDLE_VALUE, HANDLE stdErr = INVALID_HANDLE_VALUE); #endif // SPAWN_H + -- cgit v1.3.1