From 8d6c715672023577dca5a6528ff49081dede1052 Mon Sep 17 00:00:00 2001 From: Silarn Date: Wed, 11 Apr 2018 17:46:59 -0500 Subject: Initial archive conflict parsing Squashed commit: Basic archive conflict parsing - pass 1 Merge fixes for archive parsing Basic archive conflict parsing - pass 1 Merge fixes for archive parsing Should fix conflict detection for archive files --- src/directoryrefresher.cpp | 27 ++++++++-- src/directoryrefresher.h | 1 + src/mainwindow.cpp | 25 ++++++--- src/modflagicondelegate.cpp | 3 ++ src/modinfo.h | 24 ++++++++- src/modinfodialog.cpp | 8 +-- src/modinfodialog.h | 2 +- src/modinfowithconflictinfo.cpp | 75 +++++++++++++++++++++++--- src/modinfowithconflictinfo.h | 12 +++++ src/modlist.cpp | 40 +++++++++++--- src/modlist.h | 6 +++ src/modlistsortproxy.cpp | 5 +- src/organizercore.cpp | 2 +- src/pluginlist.cpp | 4 +- src/shared/directoryentry.cpp | 114 +++++++++++++++++++++++++++------------- src/shared/directoryentry.h | 26 +++++---- src/syncoverwritedialog.cpp | 4 +- 17 files changed, 295 insertions(+), 83 deletions(-) (limited to 'src') diff --git a/src/directoryrefresher.cpp b/src/directoryrefresher.cpp index 272b0596..5c789049 100644 --- a/src/directoryrefresher.cpp +++ b/src/directoryrefresher.cpp @@ -27,6 +27,8 @@ along with Mod Organizer. If not, see . #include #include #include +#include +#include using namespace MOBase; @@ -83,13 +85,30 @@ void DirectoryRefresher::addModBSAToStructure(DirectoryEntry *directoryStructure int priority, const QString &directory, const QStringList &archives) { std::wstring directoryW = ToWString(QDir::toNativeSeparators(directory)); + QStringList loadOrder = QStringList(); for (const QString &archive : archives) { QFileInfo fileInfo(archive); if (m_EnabledArchives.find(fileInfo.fileName()) != m_EnabledArchives.end()) { + IPluginGame *game = qApp->property("managed_game").value(); + + GamePlugins *gamePlugins = game->feature(); + QStringList loadOrder = QStringList(); + gamePlugins->getLoadOrder(loadOrder); + + int order = -1; + + for (auto plugin : loadOrder) + { + QString name = plugin.left(plugin.size() - 4); + if (fileInfo.fileName().startsWith(name + " - ", Qt::CaseInsensitive) || fileInfo.fileName().startsWith(name + ".", Qt::CaseInsensitive)) { + order = loadOrder.indexOf(plugin); + } + } + try { - //directoryStructure->addFromBSA(ToWString(modName), directoryW, - // ToWString(QDir::toNativeSeparators(fileInfo.absoluteFilePath())), priority); + IPluginGame *game = qApp->property("managed_game").value(); + directoryStructure->addFromBSA(ToWString(modName), directoryW, ToWString(QDir::toNativeSeparators(fileInfo.absoluteFilePath())), priority, order); } catch (const std::exception &e) { throw MyException(tr("failed to parse bsa %1: %2").arg(archive, e.what())); } @@ -115,7 +134,7 @@ void DirectoryRefresher::addModFilesToStructure(DirectoryEntry *directoryStructu file->removeOrigin(0); } origin.addFile(file->getIndex()); - file->addOrigin(origin.getID(), file->getFileTime(), L""); + file->addOrigin(origin.getID(), file->getFileTime(), L"", -1); } else { qWarning("%s not found", qPrintable(fileInfo.fileName())); } @@ -162,6 +181,8 @@ void DirectoryRefresher::refresh() emit progress((i * 100) / static_cast(m_Mods.size()) + 1); } + m_DirectoryStructure->getFileRegister()->sortOrigins(); + emit progress(100); cleanStructure(m_DirectoryStructure); diff --git a/src/directoryrefresher.h b/src/directoryrefresher.h index 53709e1e..a4fc5dbc 100644 --- a/src/directoryrefresher.h +++ b/src/directoryrefresher.h @@ -27,6 +27,7 @@ along with Mod Organizer. If not, see . #include #include #include +#include "profile.h" /** diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 931fa2af..832f42d0 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1263,9 +1263,9 @@ void MainWindow::updateTo(QTreeWidgetItem *subTree, const std::wstring &director source = modInfo->name(); } - std::wstring archive = current->getArchive(); - if (archive.length() != 0) { - source.append(" (").append(ToQString(archive)).append(")"); + std::pair archive = current->getArchive(); + if (archive.first.length() != 0) { + source.append(" (").append(ToQString(archive.first)).append(")"); } columns.append(source); QTreeWidgetItem *fileChild = new QTreeWidgetItem(columns); @@ -1287,12 +1287,12 @@ void MainWindow::updateTo(QTreeWidgetItem *subTree, const std::wstring &director fileChild->setData(1, Qt::UserRole, source); fileChild->setData(1, Qt::UserRole + 1, originID); - std::vector> alternatives = current->getAlternatives(); + std::vector>> alternatives = current->getAlternatives(); if (!alternatives.empty()) { std::wostringstream altString; altString << ToWString(tr("Also in:
")); - for (std::vector>::iterator altIter = alternatives.begin(); + for (std::vector>>::iterator altIter = alternatives.begin(); altIter != alternatives.end(); ++altIter) { if (altIter != alternatives.begin()) { altString << " , "; @@ -2196,9 +2196,16 @@ void MainWindow::modorder_changed() for (int i : modInfo->getModOverwritten()) { ModInfo::getByIndex(i)->clearCaches(); } + for (int i : modInfo->getModArchiveOverwrite()) { + ModInfo::getByIndex(i)->clearCaches(); + } + for (int i : modInfo->getModArchiveOverwritten()) { + ModInfo::getByIndex(i)->clearCaches(); + } // update conflict check on the moved mod modInfo->doConflictCheck(); m_OrganizerCore.modList()->setOverwriteMarkers(modInfo->getModOverwrite(), modInfo->getModOverwritten()); + m_OrganizerCore.modList()->setArchiveOverwriteMarkers(modInfo->getModArchiveOverwrite(), modInfo->getModArchiveOverwritten()); if (m_ModListSortProxy != nullptr) { m_ModListSortProxy->invalidate(); } @@ -2274,7 +2281,7 @@ void MainWindow::fileMoved(const QString &filePath, const QString &oldOriginName WIN32_FIND_DATAW findData; HANDLE hFind; hFind = ::FindFirstFileW(ToWString(fullNewPath).c_str(), &findData); - filePtr->addOrigin(newOrigin.getID(), findData.ftCreationTime, L""); + filePtr->addOrigin(newOrigin.getID(), findData.ftCreationTime, L"", -1); FindClose(hFind); } if (m_OrganizerCore.directoryStructure()->originExists(ToWString(oldOriginName))) { @@ -2434,8 +2441,10 @@ void MainWindow::modlistSelectionChanged(const QModelIndex ¤t, const QMode if (current.isValid()) { ModInfo::Ptr selectedMod = ModInfo::getByIndex(current.data(Qt::UserRole + 1).toInt()); m_OrganizerCore.modList()->setOverwriteMarkers(selectedMod->getModOverwrite(), selectedMod->getModOverwritten()); + m_OrganizerCore.modList()->setArchiveOverwriteMarkers(selectedMod->getModArchiveOverwrite(), selectedMod->getModArchiveOverwritten()); } else { m_OrganizerCore.modList()->setOverwriteMarkers(std::set(), std::set()); + m_OrganizerCore.modList()->setArchiveOverwriteMarkers(std::set(), std::set()); } /* if ((m_ModListSortProxy != nullptr) && !m_ModListSortProxy->beingInvalidated()) { @@ -2656,7 +2665,7 @@ void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index, } } else { modInfo->saveMeta(); - ModInfoDialog dialog(modInfo, m_OrganizerCore.directoryStructure(), modInfo->hasFlag(ModInfo::FLAG_FOREIGN), &m_OrganizerCore, &m_PluginContainer,this); + ModInfoDialog dialog(modInfo, m_OrganizerCore.directoryStructure(), modInfo->hasFlag(ModInfo::FLAG_FOREIGN), &m_OrganizerCore, &m_PluginContainer, this); connect(&dialog, SIGNAL(linkActivated(QString)), this, SLOT(linkClicked(QString))); connect(&dialog, SIGNAL(downloadRequest(QString)), &m_OrganizerCore, SLOT(downloadRequestedNXM(QString))); connect(&dialog, SIGNAL(modOpen(QString, int)), this, SLOT(displayModInformation(QString, int)), Qt::QueuedConnection); @@ -2691,7 +2700,6 @@ void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index, m_OrganizerCore.settings().directInterface().setValue("mod_info_tabs", dialog.saveTabState()); settings.setValue(key, dialog.saveGeometry()); - modInfo->saveMeta(); emit modInfoDisplayed(); m_OrganizerCore.modList()->modInfoChanged(modInfo); @@ -2713,6 +2721,7 @@ void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index, , modInfo->stealFiles() , modInfo->archives()); DirectoryRefresher::cleanStructure(m_OrganizerCore.directoryStructure()); + m_OrganizerCore.directoryStructure()->getFileRegister()->sortOrigins(); m_OrganizerCore.refreshLists(); } } diff --git a/src/modflagicondelegate.cpp b/src/modflagicondelegate.cpp index 1995964b..4404ce60 100644 --- a/src/modflagicondelegate.cpp +++ b/src/modflagicondelegate.cpp @@ -49,6 +49,9 @@ QString ModFlagIconDelegate::getFlagIcon(ModInfo::EFlag flag) const case ModInfo::FLAG_CONFLICT_MIXED: return ":/MO/gui/emblem_conflict_mixed"; case ModInfo::FLAG_CONFLICT_REDUNDANT: return ":MO/gui/emblem_conflict_redundant"; case ModInfo::FLAG_ALTERNATE_GAME: return ":MO/gui/alternate_game"; + case ModInfo::FLAG_ARCHIVE_CONFLICT_MIXED: return ":/MO/gui/archive_conflict_mixed"; + case ModInfo::FLAG_ARCHIVE_CONFLICT_OVERWRITE: return ":/MO/gui/archive_conflict_winner"; + case ModInfo::FLAG_ARCHIVE_CONFLICT_OVERWRITTEN: return ":/MO/gui/archive_conflict_loser"; default: return QString(); } } diff --git a/src/modinfo.h b/src/modinfo.h index 5a69185d..15876a23 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -72,6 +72,9 @@ public: FLAG_CONFLICT_OVERWRITTEN, FLAG_CONFLICT_MIXED, FLAG_CONFLICT_REDUNDANT, + FLAG_ARCHIVE_CONFLICT_OVERWRITE, + FLAG_ARCHIVE_CONFLICT_OVERWRITTEN, + FLAG_ARCHIVE_CONFLICT_MIXED, FLAG_PLUGIN_SELECTED, FLAG_ALTERNATE_GAME }; @@ -90,7 +93,6 @@ public: CONTENT_MCM, CONTENT_INI, CONTENT_MODGROUP - }; static const int NUM_CONTENT_TYPES = CONTENT_MODGROUP + 1; @@ -625,6 +627,26 @@ public: */ virtual std::set getModOverwritten() { return std::set(); } + /** + * @return retrieve list of mods (as mod index) with archives that are overwritten by this one. Updates may be delayed + */ + virtual std::set getModArchiveOverwrite() { return std::set(); } + + /** + * @return list of mods (as mod index) with archives that overwrite this one. Updates may be delayed + */ + virtual std::set getModArchiveOverwritten() { return std::set(); } + + /** + * @return retrieve list of mods (as mod index) with archives that are overwritten by this one. Updates may be delayed + */ + virtual std::set getModArchiveOverwrite() { return std::set(); } + + /** + * @return list of mods (as mod index) with archives that overwrite this one. Updates may be delayed + */ + virtual std::set getModArchiveOverwritten() { return std::set(); } + /** * @brief update conflict information */ diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp index 416eca58..204b539b 100644 --- a/src/modinfodialog.cpp +++ b/src/modinfodialog.cpp @@ -312,10 +312,10 @@ void ModInfoDialog::refreshLists() QString fileName = relativeName.mid(0).prepend(m_RootPath); bool archive; if ((*iter)->getOrigin(archive) == m_Origin->getID()) { - std::vector> alternatives = (*iter)->getAlternatives(); + std::vector>> alternatives = (*iter)->getAlternatives(); if (!alternatives.empty()) { std::wostringstream altString; - for (std::vector>::iterator altIter = alternatives.begin(); + for (std::vector>>::iterator altIter = alternatives.begin(); altIter != alternatives.end(); ++altIter) { if (altIter != alternatives.begin()) { altString << ", "; @@ -326,8 +326,8 @@ void ModInfoDialog::refreshLists() fields.append(ToQString(altString.str())); QTreeWidgetItem *item = new QTreeWidgetItem(fields); item->setData(0, Qt::UserRole, fileName); - item->setData(1, Qt::UserRole, ToQString(m_Directory->getOriginByID(alternatives.begin()->first).getName())); - item->setData(1, Qt::UserRole + 1, alternatives.begin()->first); + item->setData(1, Qt::UserRole, ToQString(m_Directory->getOriginByID(alternatives.back().first).getName())); + item->setData(1, Qt::UserRole + 1, alternatives.back().first); item->setData(1, Qt::UserRole + 2, archive); ui->overwriteTree->addTopLevelItem(item); ++numOverwrite; diff --git a/src/modinfodialog.h b/src/modinfodialog.h index f3bc48b4..6a315a93 100644 --- a/src/modinfodialog.h +++ b/src/modinfodialog.h @@ -78,7 +78,7 @@ public: * @param modInfo info structure about the mod to display * @param parent parend widget **/ - explicit ModInfoDialog(ModInfo::Ptr modInfo, const MOShared::DirectoryEntry *directory, bool unmanaged, OrganizerCore *organizerCore, PluginContainer *pluginContainer,QWidget *parent = 0); + explicit ModInfoDialog(ModInfo::Ptr modInfo, const MOShared::DirectoryEntry *directory, bool unmanaged, OrganizerCore *organizerCore, PluginContainer *pluginContainer, QWidget *parent = 0); ~ModInfoDialog(); /** diff --git a/src/modinfowithconflictinfo.cpp b/src/modinfowithconflictinfo.cpp index e88ba29d..67006261 100644 --- a/src/modinfowithconflictinfo.cpp +++ b/src/modinfowithconflictinfo.cpp @@ -32,6 +32,18 @@ std::vector ModInfoWithConflictInfo::getFlags() const } break; default: { /* NOP */ } } + switch (isArchiveConflicted()) { + case CONFLICT_MIXED: { + result.push_back(ModInfo::FLAG_ARCHIVE_CONFLICT_MIXED); + } break; + case CONFLICT_OVERWRITE: { + result.push_back(ModInfo::FLAG_ARCHIVE_CONFLICT_OVERWRITE); + } break; + case CONFLICT_OVERWRITTEN: { + result.push_back(ModInfo::FLAG_ARCHIVE_CONFLICT_OVERWRITTEN); + } break; + default: { /* NOP */ } + } return result; } @@ -40,6 +52,8 @@ void ModInfoWithConflictInfo::doConflictCheck() const { m_OverwriteList.clear(); m_OverwrittenList.clear(); + m_ArchiveOverwriteList.clear(); + m_ArchiveOverwrittenList.clear(); bool providesAnything = false; @@ -51,34 +65,66 @@ void ModInfoWithConflictInfo::doConflictCheck() const std::wstring name = ToWString(this->name()); m_CurrentConflictState = CONFLICT_NONE; + m_ArchiveConflictState = CONFLICT_NONE; if ((*m_DirectoryStructure)->originExists(name)) { FilesOrigin &origin = (*m_DirectoryStructure)->getOriginByName(name); std::vector files = origin.getFiles(); // for all files in this origin for (FileEntry::Ptr file : files) { - const std::vector> &alternatives = file->getAlternatives(); - if ((alternatives.size() == 0) || (alternatives.begin()->first == dataID)) { + auto alternatives = file->getAlternatives(); + if ((alternatives.size() == 0) || (alternatives.back().first == dataID)) { // no alternatives -> no conflict providesAnything = true; } else { if (file->getOrigin() != origin.getID()) { FilesOrigin &altOrigin = (*m_DirectoryStructure)->getOriginByID(file->getOrigin()); unsigned int altIndex = ModInfo::getIndex(ToQString(altOrigin.getName())); - m_OverwrittenList.insert(altIndex); + if (file->getArchive().first.size() == 0) + m_OverwrittenList.insert(altIndex); + else + m_ArchiveOverwrittenList.insert(altIndex); } else { providesAnything = true; } // for all non-providing alternative origins + bool found = file->getOrigin() == origin.getID(); + std::pair archiveData; + if (found) + archiveData = file->getArchive(); + else { + for (auto alts : alternatives) { + if (alts.first == origin.getID()) { + archiveData = alts.second; + break; + } + } + } for (auto altInfo : alternatives) { if ((altInfo.first != dataID) && (altInfo.first != origin.getID())) { FilesOrigin &altOrigin = (*m_DirectoryStructure)->getOriginByID(altInfo.first); unsigned int altIndex = ModInfo::getIndex(ToQString(altOrigin.getName())); - if (origin.getPriority() > altOrigin.getPriority()) { - m_OverwriteList.insert(altIndex); + if (altInfo.second.first.size() == 0) { + if (archiveData.first.size() == 0) { + if (origin.getPriority() > altOrigin.getPriority()) { + m_OverwriteList.insert(altIndex); + } else { + m_OverwrittenList.insert(altIndex); + } + } else { + m_ArchiveOverwrittenList.insert(altIndex); + } } else { - m_OverwrittenList.insert(altIndex); + if (archiveData.first.size() == 0) { + m_ArchiveOverwrittenList.insert(altIndex); + } else { + if (archiveData.second > altInfo.second.second) { + m_ArchiveOverwriteList.insert(altIndex); + } else if (archiveData.second < altInfo.second.second) { + m_ArchiveOverwrittenList.insert(altIndex); + } + } } } } @@ -96,6 +142,13 @@ void ModInfoWithConflictInfo::doConflictCheck() const else if (!m_OverwrittenList.empty()) m_CurrentConflictState = CONFLICT_OVERWRITTEN; } + + if (!m_ArchiveOverwriteList.empty() && !m_ArchiveOverwrittenList.empty()) + m_ArchiveConflictState = CONFLICT_MIXED; + else if (!m_ArchiveOverwriteList.empty()) + m_ArchiveConflictState = CONFLICT_OVERWRITE; + else if (!m_ArchiveOverwrittenList.empty()) + m_ArchiveConflictState = CONFLICT_OVERWRITTEN; } } @@ -110,6 +163,16 @@ ModInfoWithConflictInfo::EConflictType ModInfoWithConflictInfo::isConflicted() c return m_CurrentConflictState; } +ModInfoWithConflictInfo::EConflictType ModInfoWithConflictInfo::isArchiveConflicted() const +{ + QTime now = QTime::currentTime(); + if (m_LastConflictCheck.isNull() || (m_LastConflictCheck.secsTo(now) > 10)) { + doConflictCheck(); + } + + return m_ArchiveConflictState; +} + bool ModInfoWithConflictInfo::isRedundant() const { diff --git a/src/modinfowithconflictinfo.h b/src/modinfowithconflictinfo.h index 6c1591c5..5cf2d24e 100644 --- a/src/modinfowithconflictinfo.h +++ b/src/modinfowithconflictinfo.h @@ -23,6 +23,10 @@ public: virtual std::set getModOverwritten() { return m_OverwrittenList; } + virtual std::set getModArchiveOverwrite() { return m_ArchiveOverwriteList; } + + virtual std::set getModArchiveOverwritten() { return m_ArchiveOverwrittenList; } + virtual void doConflictCheck() const; private: @@ -42,6 +46,11 @@ private: */ EConflictType isConflicted() const; + /** + * @return true if there are archive conflicts for files in this mod + */ + EConflictType isArchiveConflicted() const; + /** * @return true if this mod is completely replaced by others */ @@ -52,10 +61,13 @@ private: MOShared::DirectoryEntry **m_DirectoryStructure; mutable EConflictType m_CurrentConflictState; + mutable EConflictType m_ArchiveConflictState; mutable QTime m_LastConflictCheck; mutable std::set m_OverwriteList; // indices of mods overritten by this mod mutable std::set m_OverwrittenList; // indices of mods overwriting this mod + mutable std::set m_ArchiveOverwriteList; // indices of mods with archive files overritten by this mod + mutable std::set m_ArchiveOverwrittenList; // indices of mods with archive files overwriting this mod }; diff --git a/src/modlist.cpp b/src/modlist.cpp index 16d2cd07..e9a12862 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -163,6 +163,9 @@ QString ModList::getFlagText(ModInfo::EFlag flag, ModInfo::Ptr modInfo) const case ModInfo::FLAG_CONFLICT_MIXED: return tr("Overwrites & Overwritten"); case ModInfo::FLAG_CONFLICT_REDUNDANT: return tr("Redundant"); case ModInfo::FLAG_ALTERNATE_GAME: return tr("Alternate game source"); + case ModInfo::FLAG_ARCHIVE_CONFLICT_OVERWRITE: return tr("Overwrites another archive file"); + case ModInfo::FLAG_ARCHIVE_CONFLICT_OVERWRITTEN: return tr("Overwritten by another archive file"); + case ModInfo::FLAG_ARCHIVE_CONFLICT_MIXED: return tr("Archive files overwrites & overwritten"); default: return ""; } } @@ -401,10 +404,18 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const || (role == ViewMarkingScrollBar::DEFAULT_ROLE)) { if (modInfo->getHighlight() & ModInfo::HIGHLIGHT_PLUGIN) { return Settings::instance().modlistContainsPluginColor(); - } else if (m_Overwrite.find(modIndex) != m_Overwrite.end()) { + } else if (m_Overwrite.find(modIndex) != m_Overwrite.end() && m_ArchiveOverwritten.find(modIndex) != m_ArchiveOverwritten.end()) { + return QColor(255, 0, 255, 32); //TODO: Make configurable + } else if (m_Overwrite.find(modIndex) != m_Overwrite.end() && m_ArchiveOverwritten.find(modIndex) != m_ArchiveOverwritten.end()) { + return QColor(255, 0, 255, 32); //TODO: Make configurable + } else if (m_Overwritten.find(modIndex) != m_Overwritten.end() && m_ArchiveOverwrite.find(modIndex) != m_ArchiveOverwrite.end()) { + return QColor(255, 0, 255, 32); //TODO: Make configurable + } else if (m_Overwritten.find(modIndex) != m_Overwritten.end() && m_ArchiveOverwrite.find(modIndex) != m_ArchiveOverwrite.end()) { + return QColor(255, 0, 255, 32); //TODO: Make configurable + } else if (m_Overwrite.find(modIndex) != m_Overwrite.end() || m_ArchiveOverwrite.find(modIndex) != m_ArchiveOverwrite.end()) { return Settings::instance().modlistOverwrittenLooseColor(); } - else if (m_Overwritten.find(modIndex) != m_Overwritten.end()) { + } else if (m_Overwritten.find(modIndex) != m_Overwritten.end() || m_ArchiveOverwritten.find(modIndex) != m_ArchiveOverwritten.end()) { return Settings::instance().modlistOverwritingLooseColor(); } else if (modInfo->hasFlag(ModInfo::FLAG_SEPARATOR) && modInfo->getColor().isValid() @@ -516,7 +527,6 @@ bool ModList::setData(const QModelIndex &index, const QVariant &value, int role) ModInfo::Ptr info = ModInfo::getByIndex(modID); IModList::ModStates oldState = state(modID); - bool result = false; emit aboutToChangeData(); @@ -754,9 +764,23 @@ void ModList::setOverwriteMarkers(const std::set &overwrite, const notifyChange(0, rowCount() - 1); } +void ModList::setArchiveOverwriteMarkers(const std::set &overwrite, const std::set &overwritten) +{ + m_ArchiveOverwrite = overwrite; + m_ArchiveOverwritten = overwritten; + notifyChange(0, rowCount() - 1); +} + void ModList::setPluginContainer(PluginContainer *pluginContianer) { - m_PluginContainer = pluginContianer; + m_PluginContainer = pluginContianer; +} + +void ModList::setArchiveOverwriteMarkers(const std::set &overwrite, const std::set &overwritten) +{ + m_ArchiveOverwrite = overwrite; + m_ArchiveOverwritten = overwritten; + notifyChange(0, rowCount() - 1); } bool ModList::modInfoAboutToChange(ModInfo::Ptr info) @@ -810,10 +834,10 @@ void ModList::highlightMods(const QItemSelectionModel *selection, const MOShared const MOShared::FileEntry::Ptr fileEntry = directoryEntry.findFile(modName.toStdWString()); if (fileEntry.get() != nullptr) { bool archive = false; - std::vector> origins; + std::vector>> origins; { - std::vector> alternatives = fileEntry->getAlternatives(); - origins.insert(origins.end(), std::pair(fileEntry->getOrigin(archive), fileEntry->getArchive())); + std::vector>> alternatives = fileEntry->getAlternatives(); + origins.insert(origins.end(), std::pair>(fileEntry->getOrigin(archive), fileEntry->getArchive())); } for (auto originInfo : origins) { MOShared::FilesOrigin &origin = directoryEntry.getOriginByID(originInfo.first); @@ -1117,6 +1141,8 @@ void ModList::notifyChange(int rowStart, int rowEnd) if (rowStart < 0) { m_Overwrite.clear(); m_Overwritten.clear(); + m_ArchiveOverwrite.clear(); + m_ArchiveOverwritten.clear(); beginResetModel(); endResetModel(); } else { diff --git a/src/modlist.h b/src/modlist.h index 42269386..5841b9f2 100644 --- a/src/modlist.h +++ b/src/modlist.h @@ -112,6 +112,10 @@ public: void setOverwriteMarkers(const std::set &overwrite, const std::set &overwritten); void setPluginContainer(PluginContainer *pluginContainer); + void setArchiveOverwriteMarkers(const std::set &overwrite, const std::set &overwritten); + + void setArchiveOverwriteMarkers(const std::set &overwrite, const std::set &overwritten); + bool modInfoAboutToChange(ModInfo::Ptr info); void modInfoChanged(ModInfo::Ptr info); @@ -331,6 +335,8 @@ private: std::set m_Overwrite; std::set m_Overwritten; + std::set m_ArchiveOverwrite; + std::set m_ArchiveOverwritten; TModInfoChange m_ChangeInfo; diff --git a/src/modlistsortproxy.cpp b/src/modlistsortproxy.cpp index 9adaa511..6f6983ba 100644 --- a/src/modlistsortproxy.cpp +++ b/src/modlistsortproxy.cpp @@ -240,7 +240,10 @@ bool ModListSortProxy::hasConflictFlag(const std::vector &flags) if ((flag == ModInfo::FLAG_CONFLICT_MIXED) || (flag == ModInfo::FLAG_CONFLICT_OVERWRITE) || (flag == ModInfo::FLAG_CONFLICT_OVERWRITTEN) || - (flag == ModInfo::FLAG_CONFLICT_REDUNDANT)) { + (flag == ModInfo::FLAG_CONFLICT_REDUNDANT) || + (flag == ModInfo::FLAG_ARCHIVE_CONFLICT_OVERWRITE) || + (flag == ModInfo::FLAG_ARCHIVE_CONFLICT_OVERWRITTEN) || + (flag == ModInfo::FLAG_ARCHIVE_CONFLICT_MIXED)) { return true; } } diff --git a/src/organizercore.cpp b/src/organizercore.cpp index d52ef40b..f19f56c3 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -1151,7 +1151,7 @@ QList OrganizerCore::findFileInfos( info.origins.append(ToQString( m_DirectoryStructure->getOriginByID(file->getOrigin(fromArchive)) .getName())); - info.archive = fromArchive ? ToQString(file->getArchive()) : ""; + info.archive = fromArchive ? ToQString(file->getArchive().first) : ""; foreach (auto idx, file->getAlternatives()) { info.origins.append( ToQString(m_DirectoryStructure->getOriginByID(idx.first).getName())); diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index b0f59e1e..04e39abf 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -140,8 +140,8 @@ void PluginList::highlightPlugins(const QItemSelectionModel *selection, const MO for (auto plugin : plugins) { MOShared::FileEntry::Ptr file = directoryEntry.findFile(plugin.toStdWString()); if (file->getOrigin() != origin.getID()) { - const std::vector> alternatives = file->getAlternatives(); - if (std::find_if(alternatives.begin(), alternatives.end(), [&](const std::pair& element) { return element.first == origin.getID(); }) == alternatives.end()) + const std::vector>> alternatives = file->getAlternatives(); + if (std::find_if(alternatives.begin(), alternatives.end(), [&](const std::pair>& element) { return element.first == origin.getID(); }) == alternatives.end()) continue; } std::map::iterator iter = m_ESPsByName.find(plugin.toLower()); diff --git a/src/shared/directoryentry.cpp b/src/shared/directoryentry.cpp index cebf270e..477f4dad 100644 --- a/src/shared/directoryentry.cpp +++ b/src/shared/directoryentry.cpp @@ -220,12 +220,19 @@ std::vector FilesOrigin::getFiles() const return result; } +bool FilesOrigin::containsArchive(std::wstring archiveName) +{ + for (FileEntry::Index fileIdx : m_Files) + if (FileEntry::Ptr p = m_FileRegister.lock()->getFile(fileIdx)) + if (p->isFromArchive(archiveName)) return true; + return false; +} // // FileEntry // -void FileEntry::addOrigin(int origin, FILETIME fileTime, const std::wstring &archive) +void FileEntry::addOrigin(int origin, FILETIME fileTime, const std::wstring &archive, int order) { m_LastAccessed = time(nullptr); if (m_Parent != nullptr) { @@ -234,36 +241,36 @@ void FileEntry::addOrigin(int origin, FILETIME fileTime, const std::wstring &arc if (m_Origin == -1) { m_Origin = origin; m_FileTime = fileTime; - m_Archive = archive; + m_Archive = std::pair(archive, order); } else if ((m_Parent != nullptr) && (m_Parent->getOriginByID(origin).getPriority() > m_Parent->getOriginByID(m_Origin).getPriority()) - && (archive.size() == 0 || m_Archive.size() > 0 )) { - if (std::find_if(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair &i) -> bool { return i.first == m_Origin; }) == m_Alternatives.end()) { - m_Alternatives.push_back(std::pair(m_Origin, m_Archive)); + && (archive.size() == 0 || m_Archive.first.size() > 0 )) { + if (std::find_if(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair> &i) -> bool { return i.first == m_Origin; }) == m_Alternatives.end()) { + m_Alternatives.push_back(std::pair>(m_Origin, m_Archive)); } m_Origin = origin; m_FileTime = fileTime; - m_Archive = archive; + m_Archive = std::pair(archive, order); } else { bool found = false; if (m_Origin == origin) { // already an origin return; } - for (std::vector>::iterator iter = m_Alternatives.begin(); iter != m_Alternatives.end(); ++iter) { + for (std::vector>>::iterator iter = m_Alternatives.begin(); iter != m_Alternatives.end(); ++iter) { if (iter->first == origin) { // already an origin return; } if ((m_Parent != nullptr) && (m_Parent->getOriginByID(iter->first).getPriority() < m_Parent->getOriginByID(origin).getPriority())) { - m_Alternatives.insert(iter, std::pair(origin, archive)); + m_Alternatives.insert(iter, std::pair>(origin, std::pair(archive, order))); found = true; break; } } if (!found) { - m_Alternatives.push_back(std::pair(origin, archive)); + m_Alternatives.push_back(std::pair>(origin, std::pair(archive, order))); } } } @@ -273,8 +280,8 @@ bool FileEntry::removeOrigin(int origin) if (m_Origin == origin) { if (!m_Alternatives.empty()) { // find alternative with the highest priority - std::vector>::iterator currentIter = m_Alternatives.begin(); - for (std::vector>::iterator iter = m_Alternatives.begin(); iter != m_Alternatives.end(); ++iter) { + std::vector>>::iterator currentIter = m_Alternatives.begin(); + for (std::vector>>::iterator iter = m_Alternatives.begin(); iter != m_Alternatives.end(); ++iter) { if ((m_Parent->getOriginByID(iter->first).getPriority() > m_Parent->getOriginByID(currentIter->first).getPriority()) && (iter->first != origin)) { currentIter = iter; @@ -292,9 +299,9 @@ bool FileEntry::removeOrigin(int origin) if (!::GetFileTime(file, nullptr, nullptr, &m_FileTime)) { // maybe this file is in a bsa, but there is no easy way to find out which. User should refresh // the view to find out - m_Archive = L"bsa?"; + m_Archive = std::pair(L"bsa?", -1); } else { - m_Archive = L""; + m_Archive = std::pair(L"", -1); } ::CloseHandle(file); @@ -304,7 +311,7 @@ bool FileEntry::removeOrigin(int origin) return true; } } else { - std::vector>::iterator newEnd = std::find_if(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair &i) -> bool { return i.first == origin; }); + std::vector>>::iterator newEnd = std::find_if(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair> &i) -> bool { return i.first == origin; }); if (newEnd != m_Alternatives.end()) m_Alternatives.erase(newEnd, m_Alternatives.end()); } @@ -318,7 +325,7 @@ FileEntry::FileEntry() } FileEntry::FileEntry(Index index, const std::wstring &name, DirectoryEntry *parent) - : m_Index(index), m_Name(name), m_Origin(-1), m_Archive(L""), m_Parent(parent), m_LastAccessed(time(nullptr)) + : m_Index(index), m_Name(name), m_Origin(-1), m_Archive(L"", -1), m_Parent(parent), m_LastAccessed(time(nullptr)) { LEAK_TRACE; } @@ -330,16 +337,23 @@ FileEntry::~FileEntry() void FileEntry::sortOrigins() { - m_Alternatives.push_back(std::pair(m_Origin, m_Archive)); - std::sort(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair &LHS, const std::pair &RHS) -> bool { - if ((!LHS.second.size() && !RHS.second.size()) || (LHS.second.size() && RHS.second.size())) { + m_Alternatives.push_back(std::pair>(m_Origin, m_Archive)); + std::sort(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair> &LHS, const std::pair> &RHS) -> bool { + if (!LHS.second.first.size() && !RHS.second.first.size()) { int l = m_Parent->getOriginByID(LHS.first).getPriority(); if (l < 0) l = INT_MAX; int r = m_Parent->getOriginByID(RHS.first).getPriority(); if (r < 0) r = INT_MAX; return l < r; } - if (RHS.second.size()) return false; + if (LHS.second.first.size() && RHS.second.first.size()) { + int l = LHS.second.second; if (l < 0) l = INT_MAX; + int r = RHS.second.second; if (r < 0) r = INT_MAX; + + return l < r; + } + + if (RHS.second.first.size()) return false; return true; }); if (!m_Alternatives.empty()) { @@ -379,6 +393,16 @@ std::wstring FileEntry::getRelativePath() const return result + L"\\" + m_Name; } +bool FileEntry::isFromArchive(std::wstring archiveName) +{ + if (archiveName.length() == 0) return m_Archive.first.length() != 0; + if (m_Archive.first.compare(archiveName) == 0) return true; + for (auto alternative : m_Alternatives) { + if (alternative.second.first.compare(archiveName) == 0) return true; + } + return false; +} + // // DirectoryEntry @@ -451,7 +475,7 @@ void DirectoryEntry::addFromOrigin(const std::wstring &originName, const std::ws } -void DirectoryEntry::addFromBSA(const std::wstring &originName, std::wstring &directory, const std::wstring &fileName, int priority) +void DirectoryEntry::addFromBSA(const std::wstring &originName, std::wstring &directory, const std::wstring &fileName, int priority, int order) { FilesOrigin &origin = createOrigin(originName, directory, priority); @@ -459,23 +483,33 @@ void DirectoryEntry::addFromBSA(const std::wstring &originName, std::wstring &di if (::GetFileAttributesExW(fileName.c_str(), GetFileExInfoStandard, &fileData) == 0) { throw windows_error("failed to determine file time"); } + FILETIME now; + ::GetSystemTimeAsFileTime(&now); + + const double clfSecondsPer100ns = 100. * 1.E-9; + + ((ULARGE_INTEGER *)&now)->QuadPart -= ((double)5) / clfSecondsPer100ns; - BSA::Archive archive; - BSA::EErrorCode res = archive.read(ToString(fileName, false).c_str(), false); - if ((res != BSA::ERROR_NONE) && (res != BSA::ERROR_INVALIDHASHES)) { - std::ostringstream stream; - stream << "invalid bsa file: " << ToString(fileName, false) << " errorcode " << res << " - " << ::GetLastError(); - throw std::runtime_error(stream.str()); - } size_t namePos = fileName.find_last_of(L"\\/"); if (namePos == std::wstring::npos) { namePos = 0; - } else { + } + else { ++namePos; } - addFiles(origin, archive.getRoot(), fileData.ftLastWriteTime, fileName.substr(namePos)); - m_Populated = true; + if (!containsArchive(fileName.substr(namePos)) || ::CompareFileTime(&fileData.ftLastWriteTime, &now) > 0) { + BSA::Archive archive; + BSA::EErrorCode res = archive.read(ToString(fileName, false).c_str(), false); + if ((res != BSA::ERROR_NONE) && (res != BSA::ERROR_INVALIDHASHES)) { + std::ostringstream stream; + stream << "invalid bsa file: " << ToString(fileName, false) << " errorcode " << res << " - " << ::GetLastError(); + throw std::runtime_error(stream.str()); + } + + addFiles(origin, archive.getRoot(), fileData.ftLastWriteTime, fileName.substr(namePos), order); + m_Populated = true; + } } void DirectoryEntry::propagateOrigin(int origin) @@ -536,7 +570,7 @@ void DirectoryEntry::addFiles(FilesOrigin &origin, wchar_t *buffer, int bufferOf getSubDirectory(findData.cFileName, true, origin.getID())->addFiles(origin, buffer, bufferOffset + offset); } } else { - insert(findData.cFileName, origin, findData.ftLastWriteTime, L""); + insert(findData.cFileName, origin, findData.ftLastWriteTime, L"", -1); } result = ::FindNextFileW(searchHandle, &findData); } @@ -546,12 +580,12 @@ void DirectoryEntry::addFiles(FilesOrigin &origin, wchar_t *buffer, int bufferOf } -void DirectoryEntry::addFiles(FilesOrigin &origin, BSA::Folder::Ptr archiveFolder, FILETIME &fileTime, const std::wstring &archiveName) +void DirectoryEntry::addFiles(FilesOrigin &origin, BSA::Folder::Ptr archiveFolder, FILETIME &fileTime, const std::wstring &archiveName, int order) { // add files for (unsigned int fileIdx = 0; fileIdx < archiveFolder->getNumFiles(); ++fileIdx) { BSA::File::Ptr file = archiveFolder->getFile(fileIdx); - insert(ToWString(file->getName(), true), origin, fileTime, archiveName); + insert(ToWString(file->getName(), true), origin, fileTime, archiveName, order); } // recurse into subdirectories @@ -559,7 +593,7 @@ void DirectoryEntry::addFiles(FilesOrigin &origin, BSA::Folder::Ptr archiveFolde BSA::Folder::Ptr folder = archiveFolder->getSubFolder(folderIdx); DirectoryEntry *folderEntry = getSubDirectoryRecursive(ToWString(folder->getName(), true), true, origin.getID()); - folderEntry->addFiles(origin, folder, fileTime, archiveName); + folderEntry->addFiles(origin, folder, fileTime, archiveName, order); } } @@ -626,7 +660,7 @@ void DirectoryEntry::insertFile(const std::wstring &filePath, FilesOrigin &origi { size_t pos = filePath.find_first_of(L"\\/"); if (pos == std::string::npos) { - this->insert(filePath, origin, fileTime, std::wstring()); + this->insert(filePath, origin, fileTime, std::wstring(), -1); } else { std::wstring dirName = filePath.substr(0, pos); std::wstring rest = filePath.substr(pos + 1); @@ -667,6 +701,14 @@ void DirectoryEntry::removeFiles(const std::set &indices) } } +bool DirectoryEntry::containsArchive(std::wstring archiveName) +{ + for (auto iter = m_Files.begin(); iter != m_Files.end(); ++iter) { + FileEntry::Ptr entry = m_FileRegister->getFile(iter->second); + if (entry->isFromArchive(archiveName)) return true; + } + return false; +} int DirectoryEntry::anyOrigin() const { @@ -890,7 +932,7 @@ void FileRegister::unregisterFile(FileEntry::Ptr file) // unregister from origin int originID = file->getOrigin(ignore); m_OriginConnection->getByID(originID).removeFile(file->getIndex()); - const std::vector> &alternatives = file->getAlternatives(); + const std::vector>> &alternatives = file->getAlternatives(); for (auto iter = alternatives.begin(); iter != alternatives.end(); ++iter) { m_OriginConnection->getByID(iter->first).removeFile(file->getIndex()); } diff --git a/src/shared/directoryentry.h b/src/shared/directoryentry.h index 8dbedaf4..12cef11d 100644 --- a/src/shared/directoryentry.h +++ b/src/shared/directoryentry.h @@ -64,7 +64,7 @@ public: time_t lastAccessed() const { return m_LastAccessed; } - void addOrigin(int origin, FILETIME fileTime, const std::wstring &archive); + void addOrigin(int origin, FILETIME fileTime, const std::wstring &archive, int order); // remove the specified origin from the list of origins that contain this file. if no origin is left, // the file is effectively deleted and true is returned. otherwise, false is returned bool removeOrigin(int origin); @@ -72,13 +72,13 @@ public: // gets the list of alternative origins (origins with lower priority than the primary one). // if sortOrigins has been called, it is sorted by priority (ascending) - const std::vector> &getAlternatives() const { return m_Alternatives; } + const std::vector>> &getAlternatives() const { return m_Alternatives; } const std::wstring &getName() const { return m_Name; } int getOrigin() const { return m_Origin; } - int getOrigin(bool &archive) const { archive = (m_Archive.length() != 0); return m_Origin; } - const std::wstring &getArchive() const { return m_Archive; } - bool isFromArchive() const { return m_Archive.length() != 0; } + int getOrigin(bool &archive) const { archive = (m_Archive.first.length() != 0); return m_Origin; } + const std::pair &getArchive() const { return m_Archive; } + bool isFromArchive(std::wstring archiveName = L""); std::wstring getFullPath() const; std::wstring getRelativePath() const; DirectoryEntry *getParent() { return m_Parent; } @@ -97,8 +97,8 @@ private: Index m_Index; std::wstring m_Name; int m_Origin = -1; - std::wstring m_Archive; - std::vector> m_Alternatives; + std::pair m_Archive; + std::vector>> m_Alternatives; DirectoryEntry *m_Parent; mutable FILETIME m_FileTime; @@ -142,6 +142,8 @@ public: void addFile(FileEntry::Index index) { m_Files.insert(index); } void removeFile(FileEntry::Index index); + bool containsArchive(std::wstring archiveName); + private: FilesOrigin(int ID, const std::wstring &name, const std::wstring &path, int priority, @@ -221,7 +223,7 @@ public: // add files to this directory (and subdirectories) from the specified origin. That origin may exist or not void addFromOrigin(const std::wstring &originName, const std::wstring &directory, int priority); - void addFromBSA(const std::wstring &originName, std::wstring &directory, const std::wstring &fileName, int priority); + void addFromBSA(const std::wstring &originName, std::wstring &directory, const std::wstring &fileName, int priority, int order); void propagateOrigin(int origin); @@ -253,6 +255,8 @@ public: */ const FileEntry::Ptr findFile(const std::wstring &name) const; + bool containsArchive(std::wstring archiveName); + /** search through this directory and all subdirectories for a file by the specified name (relative path). if directory is not nullptr, the referenced variable will be set to the path containing the file */ const FileEntry::Ptr searchFile(const std::wstring &path, const DirectoryEntry **directory) const; @@ -297,7 +301,7 @@ private: DirectoryEntry(const DirectoryEntry &reference); DirectoryEntry &operator=(const DirectoryEntry &reference); - void insert(const std::wstring &fileName, FilesOrigin &origin, FILETIME fileTime, const std::wstring &archive) { + void insert(const std::wstring &fileName, FilesOrigin &origin, FILETIME fileTime, const std::wstring &archive, int order) { std::wstring fileNameLower = ToLower(fileName); auto iter = m_Files.find(fileNameLower); FileEntry::Ptr file; @@ -308,12 +312,12 @@ private: // TODO this has been observed to cause a crash, no clue why m_Files[fileNameLower] = file->getIndex(); } - file->addOrigin(origin.getID(), fileTime, archive); + file->addOrigin(origin.getID(), fileTime, archive, order); origin.addFile(file->getIndex()); } void addFiles(FilesOrigin &origin, wchar_t *buffer, int bufferOffset); - void addFiles(FilesOrigin &origin, BSA::Folder::Ptr archiveFolder, FILETIME &fileTime, const std::wstring &archiveName); + void addFiles(FilesOrigin &origin, BSA::Folder::Ptr archiveFolder, FILETIME &fileTime, const std::wstring &archiveName, int order); DirectoryEntry *getSubDirectory(const std::wstring &name, bool create, int originID = -1); diff --git a/src/syncoverwritedialog.cpp b/src/syncoverwritedialog.cpp index f03e29c5..7c341567 100644 --- a/src/syncoverwritedialog.cpp +++ b/src/syncoverwritedialog.cpp @@ -98,8 +98,8 @@ void SyncOverwriteDialog::readTree(const QString &path, DirectoryEntry *director bool ignore; int origin = entry->getOrigin(ignore); addToComboBox(combo, ToQString(m_DirectoryStructure->getOriginByID(origin).getName()), origin); - const std::vector> &alternatives = entry->getAlternatives(); - for (std::vector>::const_iterator iter = alternatives.begin(); iter != alternatives.end(); ++iter) { + const std::vector>> &alternatives = entry->getAlternatives(); + for (std::vector>>::const_iterator iter = alternatives.begin(); iter != alternatives.end(); ++iter) { addToComboBox(combo, ToQString(m_DirectoryStructure->getOriginByID(iter->first).getName()), iter->first); } combo->setCurrentIndex(combo->count() - 1); -- cgit v1.3.1 From 01e1232cf85f09efde780537bbbca40fd6f0c097 Mon Sep 17 00:00:00 2001 From: Al12rs Date: Thu, 2 Aug 2018 15:33:27 +0200 Subject: Added new "loose files overwrite archive" icon and all the flags. The logic to show it is still missing until the other issues are fixed. --- src/modflagicondelegate.cpp | 1 + src/modinfo.h | 1 + src/modlist.cpp | 7 ++++--- src/modlistsortproxy.cpp | 3 ++- src/resources.qrc | 3 ++- src/resources/conflict-overwrite-blue.png | Bin 0 -> 964 bytes 6 files changed, 10 insertions(+), 5 deletions(-) create mode 100644 src/resources/conflict-overwrite-blue.png (limited to 'src') diff --git a/src/modflagicondelegate.cpp b/src/modflagicondelegate.cpp index 4404ce60..f7f85a18 100644 --- a/src/modflagicondelegate.cpp +++ b/src/modflagicondelegate.cpp @@ -45,6 +45,7 @@ QString ModFlagIconDelegate::getFlagIcon(ModInfo::EFlag flag) const case ModInfo::FLAG_NOTENDORSED: return ":/MO/gui/emblem_notendorsed"; case ModInfo::FLAG_NOTES: return ":/MO/gui/emblem_notes"; case ModInfo::FLAG_CONFLICT_OVERWRITE: return ":/MO/gui/emblem_conflict_overwrite"; + case ModInfo::FLAG_CONFLICT_LOOSE_OVERWRITE_ARCHIVE: return ":/MO/gui/emblem_conflict_loose_overwrite_archive"; case ModInfo::FLAG_CONFLICT_OVERWRITTEN: return ":/MO/gui/emblem_conflict_overwritten"; case ModInfo::FLAG_CONFLICT_MIXED: return ":/MO/gui/emblem_conflict_mixed"; case ModInfo::FLAG_CONFLICT_REDUNDANT: return ":MO/gui/emblem_conflict_redundant"; diff --git a/src/modinfo.h b/src/modinfo.h index 15876a23..c763e69b 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -69,6 +69,7 @@ public: FLAG_NOTENDORSED, FLAG_NOTES, FLAG_CONFLICT_OVERWRITE, + FLAG_CONFLICT_LOOSE_OVERWRITE_ARCHIVE, FLAG_CONFLICT_OVERWRITTEN, FLAG_CONFLICT_MIXED, FLAG_CONFLICT_REDUNDANT, diff --git a/src/modlist.cpp b/src/modlist.cpp index e9a12862..876e8958 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -158,9 +158,10 @@ QString ModList::getFlagText(ModInfo::EFlag flag, ModInfo::Ptr modInfo) const output << QString("%1").arg(modInfo->notes()).replace("\n", "
"); return output.join("
"); } - case ModInfo::FLAG_CONFLICT_OVERWRITE: return tr("Overwrites files"); - case ModInfo::FLAG_CONFLICT_OVERWRITTEN: return tr("Overwritten files"); - case ModInfo::FLAG_CONFLICT_MIXED: return tr("Overwrites & Overwritten"); + case ModInfo::FLAG_CONFLICT_OVERWRITE: return tr("Overwrites loose files"); + case ModInfo::FLAG_CONFLICT_LOOSE_OVERWRITE_ARCHIVE: return tr("Loose files overwrite another archive"); + case ModInfo::FLAG_CONFLICT_OVERWRITTEN: return tr("Overwritten loose files"); + case ModInfo::FLAG_CONFLICT_MIXED: return tr("Loose files Overwrites & Overwritten"); case ModInfo::FLAG_CONFLICT_REDUNDANT: return tr("Redundant"); case ModInfo::FLAG_ALTERNATE_GAME: return tr("Alternate game source"); case ModInfo::FLAG_ARCHIVE_CONFLICT_OVERWRITE: return tr("Overwrites another archive file"); diff --git a/src/modlistsortproxy.cpp b/src/modlistsortproxy.cpp index 6f6983ba..c34985b6 100644 --- a/src/modlistsortproxy.cpp +++ b/src/modlistsortproxy.cpp @@ -243,7 +243,8 @@ bool ModListSortProxy::hasConflictFlag(const std::vector &flags) (flag == ModInfo::FLAG_CONFLICT_REDUNDANT) || (flag == ModInfo::FLAG_ARCHIVE_CONFLICT_OVERWRITE) || (flag == ModInfo::FLAG_ARCHIVE_CONFLICT_OVERWRITTEN) || - (flag == ModInfo::FLAG_ARCHIVE_CONFLICT_MIXED)) { + (flag == ModInfo::FLAG_ARCHIVE_CONFLICT_MIXED) || + (flag == ModInfo::FLAG_CONFLICT_LOOSE_OVERWRITE_ARCHIVE)) { return true; } } diff --git a/src/resources.qrc b/src/resources.qrc index 1dccce0b..dff1ad72 100644 --- a/src/resources.qrc +++ b/src/resources.qrc @@ -47,7 +47,8 @@ resources/conflict-mixed.png resources/conflict-overwrite.png resources/conflict-overwritten.png - resources/conflict-redundant.png + resources/conflict-redundant.png + resources/conflict-overwrite-blue.png resources/accessories-text-editor.png resources/x-office-calendar.png resources/dialog-warning_16.png diff --git a/src/resources/conflict-overwrite-blue.png b/src/resources/conflict-overwrite-blue.png new file mode 100644 index 00000000..3247e7b7 Binary files /dev/null and b/src/resources/conflict-overwrite-blue.png differ -- cgit v1.3.1 From f9f70b224e25c2d5bff017fd08d32521d39d5b08 Mon Sep 17 00:00:00 2001 From: Silarn Date: Thu, 2 Aug 2018 11:54:48 -0500 Subject: Add loose file/archive conflict icons --- src/mainwindow.cpp | 9 +++ src/modflagicondelegate.cpp | 6 +- src/modinfo.h | 14 ++++- src/modinfowithconflictinfo.cpp | 86 ++++++++++++++++++++-------- src/modinfowithconflictinfo.h | 16 +++++- src/modlist.cpp | 42 +++++++++----- src/modlist.h | 3 + src/modlistsortproxy.cpp | 16 +++--- src/resources.qrc | 10 ++-- src/resources/conflict-mixed-blue.png | Bin 0 -> 692 bytes src/resources/conflict-overwritten-blue.png | Bin 0 -> 577 bytes 11 files changed, 151 insertions(+), 51 deletions(-) create mode 100644 src/resources/conflict-mixed-blue.png create mode 100644 src/resources/conflict-overwritten-blue.png (limited to 'src') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 832f42d0..d7ae18fb 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2202,10 +2202,17 @@ void MainWindow::modorder_changed() for (int i : modInfo->getModArchiveOverwritten()) { ModInfo::getByIndex(i)->clearCaches(); } + for (int i : modInfo->getModArchiveLooseOverwrite()) { + ModInfo::getByIndex(i)->clearCaches(); + } + for (int i : modInfo->getModArchiveLooseOverwritten()) { + ModInfo::getByIndex(i)->clearCaches(); + } // update conflict check on the moved mod modInfo->doConflictCheck(); m_OrganizerCore.modList()->setOverwriteMarkers(modInfo->getModOverwrite(), modInfo->getModOverwritten()); m_OrganizerCore.modList()->setArchiveOverwriteMarkers(modInfo->getModArchiveOverwrite(), modInfo->getModArchiveOverwritten()); + m_OrganizerCore.modList()->setArchiveLooseOverwriteMarkers(modInfo->getModArchiveLooseOverwrite(), modInfo->getModArchiveLooseOverwritten()); if (m_ModListSortProxy != nullptr) { m_ModListSortProxy->invalidate(); } @@ -2442,9 +2449,11 @@ void MainWindow::modlistSelectionChanged(const QModelIndex ¤t, const QMode ModInfo::Ptr selectedMod = ModInfo::getByIndex(current.data(Qt::UserRole + 1).toInt()); m_OrganizerCore.modList()->setOverwriteMarkers(selectedMod->getModOverwrite(), selectedMod->getModOverwritten()); m_OrganizerCore.modList()->setArchiveOverwriteMarkers(selectedMod->getModArchiveOverwrite(), selectedMod->getModArchiveOverwritten()); + m_OrganizerCore.modList()->setArchiveLooseOverwriteMarkers(selectedMod->getModArchiveLooseOverwrite(), selectedMod->getModArchiveLooseOverwritten()); } else { m_OrganizerCore.modList()->setOverwriteMarkers(std::set(), std::set()); m_OrganizerCore.modList()->setArchiveOverwriteMarkers(std::set(), std::set()); + m_OrganizerCore.modList()->setArchiveLooseOverwriteMarkers(std::set(), std::set()); } /* if ((m_ModListSortProxy != nullptr) && !m_ModListSortProxy->beingInvalidated()) { diff --git a/src/modflagicondelegate.cpp b/src/modflagicondelegate.cpp index f7f85a18..5584dea1 100644 --- a/src/modflagicondelegate.cpp +++ b/src/modflagicondelegate.cpp @@ -1,4 +1,4 @@ - #include "modflagicondelegate.h" +#include "modflagicondelegate.h" #include @@ -44,15 +44,19 @@ QString ModFlagIconDelegate::getFlagIcon(ModInfo::EFlag flag) const case ModInfo::FLAG_INVALID: return ":/MO/gui/problem"; case ModInfo::FLAG_NOTENDORSED: return ":/MO/gui/emblem_notendorsed"; case ModInfo::FLAG_NOTES: return ":/MO/gui/emblem_notes"; + case ModInfo::FLAG_CONFLICT_MIXED: return ":/MO/gui/emblem_conflict_mixed"; case ModInfo::FLAG_CONFLICT_OVERWRITE: return ":/MO/gui/emblem_conflict_overwrite"; case ModInfo::FLAG_CONFLICT_LOOSE_OVERWRITE_ARCHIVE: return ":/MO/gui/emblem_conflict_loose_overwrite_archive"; case ModInfo::FLAG_CONFLICT_OVERWRITTEN: return ":/MO/gui/emblem_conflict_overwritten"; case ModInfo::FLAG_CONFLICT_MIXED: return ":/MO/gui/emblem_conflict_mixed"; case ModInfo::FLAG_CONFLICT_REDUNDANT: return ":MO/gui/emblem_conflict_redundant"; case ModInfo::FLAG_ALTERNATE_GAME: return ":MO/gui/alternate_game"; + case ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITE: return ":/MO/gui/archive_loose_conflict_overwrite"; + case ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITTEN: return ":/MO/gui/archive_loose_conflict_overwritten"; case ModInfo::FLAG_ARCHIVE_CONFLICT_MIXED: return ":/MO/gui/archive_conflict_mixed"; case ModInfo::FLAG_ARCHIVE_CONFLICT_OVERWRITE: return ":/MO/gui/archive_conflict_winner"; case ModInfo::FLAG_ARCHIVE_CONFLICT_OVERWRITTEN: return ":/MO/gui/archive_conflict_loser"; + case ModInfo::FLAG_ALTERNATE_GAME: return ":MO/gui/alternate_game"; default: return QString(); } } diff --git a/src/modinfo.h b/src/modinfo.h index c763e69b..99ce35b5 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -69,10 +69,12 @@ public: FLAG_NOTENDORSED, FLAG_NOTES, FLAG_CONFLICT_OVERWRITE, - FLAG_CONFLICT_LOOSE_OVERWRITE_ARCHIVE, FLAG_CONFLICT_OVERWRITTEN, FLAG_CONFLICT_MIXED, FLAG_CONFLICT_REDUNDANT, + FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITE, + FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITTEN, + FLAG_ARCHIVE_LOOSE_CONFLICT_MIXED, FLAG_ARCHIVE_CONFLICT_OVERWRITE, FLAG_ARCHIVE_CONFLICT_OVERWRITTEN, FLAG_ARCHIVE_CONFLICT_MIXED, @@ -648,6 +650,16 @@ public: */ virtual std::set getModArchiveOverwritten() { return std::set(); } + /** + * @return retrieve list of mods (as mod index) with archives that are overwritten by thos mod's loose files. Updates may be delayed + */ + virtual std::set getModArchiveLooseOverwrite() { return std::set(); } + + /** + * @return list of mods (as mod index) with loose files that overwrite this one's archive files. Updates may be delayed + */ + virtual std::set getModArchiveLooseOverwritten() { return std::set(); } + /** * @brief update conflict information */ diff --git a/src/modinfowithconflictinfo.cpp b/src/modinfowithconflictinfo.cpp index 67006261..68b5b265 100644 --- a/src/modinfowithconflictinfo.cpp +++ b/src/modinfowithconflictinfo.cpp @@ -7,7 +7,7 @@ using namespace MOBase; using namespace MOShared; ModInfoWithConflictInfo::ModInfoWithConflictInfo(PluginContainer *pluginContainer, DirectoryEntry **directoryStructure) - : ModInfo(pluginContainer), m_DirectoryStructure(directoryStructure) {} + : ModInfo(pluginContainer), m_DirectoryStructure(directoryStructure), m_HasLooseOverwrite(false) {} void ModInfoWithConflictInfo::clearCaches() { @@ -32,6 +32,18 @@ std::vector ModInfoWithConflictInfo::getFlags() const } break; default: { /* NOP */ } } + switch (isLooseArchiveConflicted()) { + case CONFLICT_MIXED: { + result.push_back(ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_MIXED); + } break; + case CONFLICT_OVERWRITE: { + result.push_back(ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITE); + } break; + case CONFLICT_OVERWRITTEN: { + result.push_back(ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITTEN); + } break; + default: { /* NOP */ } + } switch (isArchiveConflicted()) { case CONFLICT_MIXED: { result.push_back(ModInfo::FLAG_ARCHIVE_CONFLICT_MIXED); @@ -54,6 +66,8 @@ void ModInfoWithConflictInfo::doConflictCheck() const m_OverwrittenList.clear(); m_ArchiveOverwriteList.clear(); m_ArchiveOverwrittenList.clear(); + m_ArchiveLooseOverwriteList.clear(); + m_ArchiveLooseOverwrittenList.clear(); bool providesAnything = false; @@ -66,6 +80,7 @@ void ModInfoWithConflictInfo::doConflictCheck() const m_CurrentConflictState = CONFLICT_NONE; m_ArchiveConflictState = CONFLICT_NONE; + m_ArchiveConflictLooseState = CONFLICT_NONE; if ((*m_DirectoryStructure)->originExists(name)) { FilesOrigin &origin = (*m_DirectoryStructure)->getOriginByName(name); @@ -77,18 +92,7 @@ void ModInfoWithConflictInfo::doConflictCheck() const // no alternatives -> no conflict providesAnything = true; } else { - if (file->getOrigin() != origin.getID()) { - FilesOrigin &altOrigin = (*m_DirectoryStructure)->getOriginByID(file->getOrigin()); - unsigned int altIndex = ModInfo::getIndex(ToQString(altOrigin.getName())); - if (file->getArchive().first.size() == 0) - m_OverwrittenList.insert(altIndex); - else - m_ArchiveOverwrittenList.insert(altIndex); - } else { - providesAnything = true; - } - - // for all non-providing alternative origins + // Get the archive data for the current mod bool found = file->getOrigin() == origin.getID(); std::pair archiveData; if (found) @@ -101,6 +105,23 @@ void ModInfoWithConflictInfo::doConflictCheck() const } } } + + // If this is not the origin then determine the correct overwrite + if (file->getOrigin() != origin.getID()) { + FilesOrigin &altOrigin = (*m_DirectoryStructure)->getOriginByID(file->getOrigin()); + unsigned int altIndex = ModInfo::getIndex(ToQString(altOrigin.getName())); + if (file->getArchive().first.size() == 0) + if (archiveData.first.size() == 0) + m_OverwrittenList.insert(altIndex); + else + m_ArchiveLooseOverwrittenList.insert(altIndex); + else + m_ArchiveOverwrittenList.insert(altIndex); + } else { + providesAnything = true; + } + + // Sort out the alternatives for (auto altInfo : alternatives) { if ((altInfo.first != dataID) && (altInfo.first != origin.getID())) { FilesOrigin &altOrigin = (*m_DirectoryStructure)->getOriginByID(altInfo.first); @@ -113,11 +134,11 @@ void ModInfoWithConflictInfo::doConflictCheck() const m_OverwrittenList.insert(altIndex); } } else { - m_ArchiveOverwrittenList.insert(altIndex); + m_ArchiveLooseOverwrittenList.insert(altIndex); } } else { if (archiveData.first.size() == 0) { - m_ArchiveOverwrittenList.insert(altIndex); + m_ArchiveLooseOverwriteList.insert(altIndex); } else { if (archiveData.second > altInfo.second.second) { m_ArchiveOverwriteList.insert(altIndex); @@ -141,14 +162,21 @@ void ModInfoWithConflictInfo::doConflictCheck() const m_CurrentConflictState = CONFLICT_OVERWRITE; else if (!m_OverwrittenList.empty()) m_CurrentConflictState = CONFLICT_OVERWRITTEN; - } - if (!m_ArchiveOverwriteList.empty() && !m_ArchiveOverwrittenList.empty()) + if (!m_ArchiveOverwriteList.empty() && !m_ArchiveOverwrittenList.empty()) m_ArchiveConflictState = CONFLICT_MIXED; - else if (!m_ArchiveOverwriteList.empty()) + else if (!m_ArchiveOverwriteList.empty()) m_ArchiveConflictState = CONFLICT_OVERWRITE; - else if (!m_ArchiveOverwrittenList.empty()) + else if (!m_ArchiveOverwrittenList.empty()) m_ArchiveConflictState = CONFLICT_OVERWRITTEN; + + if (!m_ArchiveLooseOverwrittenList.empty() && !m_ArchiveLooseOverwriteList.empty()) + m_ArchiveConflictLooseState = CONFLICT_MIXED; + else if (!m_ArchiveLooseOverwrittenList.empty()) + m_ArchiveConflictLooseState = CONFLICT_OVERWRITTEN; + else if (!m_ArchiveLooseOverwriteList.empty()) + m_ArchiveConflictLooseState = CONFLICT_OVERWRITE; + } } } @@ -165,12 +193,22 @@ ModInfoWithConflictInfo::EConflictType ModInfoWithConflictInfo::isConflicted() c ModInfoWithConflictInfo::EConflictType ModInfoWithConflictInfo::isArchiveConflicted() const { - QTime now = QTime::currentTime(); - if (m_LastConflictCheck.isNull() || (m_LastConflictCheck.secsTo(now) > 10)) { - doConflictCheck(); - } + QTime now = QTime::currentTime(); + if (m_LastConflictCheck.isNull() || (m_LastConflictCheck.secsTo(now) > 10)) { + doConflictCheck(); + } + + return m_ArchiveConflictState; +} + +ModInfoWithConflictInfo::EConflictType ModInfoWithConflictInfo::isLooseArchiveConflicted() const +{ + QTime now = QTime::currentTime(); + if (m_LastConflictCheck.isNull() || (m_LastConflictCheck.secsTo(now) > 10)) { + doConflictCheck(); + } - return m_ArchiveConflictState; + return m_ArchiveConflictLooseState; } diff --git a/src/modinfowithconflictinfo.h b/src/modinfowithconflictinfo.h index 5cf2d24e..13d87d25 100644 --- a/src/modinfowithconflictinfo.h +++ b/src/modinfowithconflictinfo.h @@ -27,6 +27,10 @@ public: virtual std::set getModArchiveOverwritten() { return m_ArchiveOverwrittenList; } + virtual std::set getModArchiveLooseOverwrite() { return m_ArchiveLooseOverwriteList; } + + virtual std::set getModArchiveLooseOverwritten() { return m_ArchiveLooseOverwrittenList; } + virtual void doConflictCheck() const; private: @@ -36,7 +40,8 @@ private: CONFLICT_OVERWRITE, CONFLICT_OVERWRITTEN, CONFLICT_MIXED, - CONFLICT_REDUNDANT + CONFLICT_REDUNDANT, + CONFLICT_CROSS }; private: @@ -51,6 +56,11 @@ private: */ EConflictType isArchiveConflicted() const; + /** + * @return true if there are archive conflicts with loose files in this mod + */ + EConflictType isLooseArchiveConflicted() const; + /** * @return true if this mod is completely replaced by others */ @@ -62,12 +72,16 @@ private: mutable EConflictType m_CurrentConflictState; mutable EConflictType m_ArchiveConflictState; + mutable EConflictType m_ArchiveConflictLooseState; + mutable bool m_HasLooseOverwrite; mutable QTime m_LastConflictCheck; mutable std::set m_OverwriteList; // indices of mods overritten by this mod mutable std::set m_OverwrittenList; // indices of mods overwriting this mod mutable std::set m_ArchiveOverwriteList; // indices of mods with archive files overritten by this mod mutable std::set m_ArchiveOverwrittenList; // indices of mods with archive files overwriting this mod + mutable std::set m_ArchiveLooseOverwriteList; // indices of mods with archives being overwritten by this mod's loose files + mutable std::set m_ArchiveLooseOverwrittenList; // indices of mods with loose files overwriting this mod's archive files }; diff --git a/src/modlist.cpp b/src/modlist.cpp index 876e8958..fd6da43b 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -163,10 +163,13 @@ QString ModList::getFlagText(ModInfo::EFlag flag, ModInfo::Ptr modInfo) const case ModInfo::FLAG_CONFLICT_OVERWRITTEN: return tr("Overwritten loose files"); case ModInfo::FLAG_CONFLICT_MIXED: return tr("Loose files Overwrites & Overwritten"); case ModInfo::FLAG_CONFLICT_REDUNDANT: return tr("Redundant"); - case ModInfo::FLAG_ALTERNATE_GAME: return tr("Alternate game source"); + case ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_MIXED: return tr("Contains archive files overwritten by loose files and loose files overwriting an archive"); + case ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITE: return tr("Overwrites an archive with loose files"); + case ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITTEN: return tr("Archive is overwritten by loose files"); case ModInfo::FLAG_ARCHIVE_CONFLICT_OVERWRITE: return tr("Overwrites another archive file"); case ModInfo::FLAG_ARCHIVE_CONFLICT_OVERWRITTEN: return tr("Overwritten by another archive file"); case ModInfo::FLAG_ARCHIVE_CONFLICT_MIXED: return tr("Archive files overwrites & overwritten"); + case ModInfo::FLAG_ALTERNATE_GAME: return tr("Alternate game source"); default: return ""; } } @@ -403,20 +406,26 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const return QVariant(); } else if ((role == Qt::BackgroundRole) || (role == ViewMarkingScrollBar::DEFAULT_ROLE)) { + bool overwrite = m_Overwrite.find(modIndex) != m_Overwrite.end(); + bool archiveOverwrite = m_ArchiveOverwrite.find(modIndex) != m_ArchiveOverwrite.end(); + bool archiveLooseOverwrite = m_ArchiveLooseOverwrite.find(modIndex) != m_ArchiveLooseOverwrite.end(); + bool overwritten = m_Overwritten.find(modIndex) != m_Overwritten.end(); + bool archiveOverwritten = m_ArchiveOverwritten.find(modIndex) != m_ArchiveOverwritten.end(); + bool archiveLooseOverwritten = m_ArchiveLooseOverwritten.find(modIndex) != m_ArchiveLooseOverwritten.end(); if (modInfo->getHighlight() & ModInfo::HIGHLIGHT_PLUGIN) { return Settings::instance().modlistContainsPluginColor(); - } else if (m_Overwrite.find(modIndex) != m_Overwrite.end() && m_ArchiveOverwritten.find(modIndex) != m_ArchiveOverwritten.end()) { - return QColor(255, 0, 255, 32); //TODO: Make configurable - } else if (m_Overwrite.find(modIndex) != m_Overwrite.end() && m_ArchiveOverwritten.find(modIndex) != m_ArchiveOverwritten.end()) { - return QColor(255, 0, 255, 32); //TODO: Make configurable - } else if (m_Overwritten.find(modIndex) != m_Overwritten.end() && m_ArchiveOverwrite.find(modIndex) != m_ArchiveOverwrite.end()) { + } else if ((overwrite && (archiveOverwritten || archiveLooseOverwritten)) || + (overwritten && (archiveOverwrite || archiveLooseOverwrite)) || + (archiveOverwrite && (overwritten || archiveLooseOverwritten)) || + (archiveOverwritten && (overwrite || archiveLooseOverwrite)) || + (archiveLooseOverwrite && (overwritten || archiveOverwritten)) || + (archiveLooseOverwritten && (overwrite || archiveLooseOverwrite)) + ) { return QColor(255, 0, 255, 32); //TODO: Make configurable - } else if (m_Overwritten.find(modIndex) != m_Overwritten.end() && m_ArchiveOverwrite.find(modIndex) != m_ArchiveOverwrite.end()) { - return QColor(255, 0, 255, 32); //TODO: Make configurable - } else if (m_Overwrite.find(modIndex) != m_Overwrite.end() || m_ArchiveOverwrite.find(modIndex) != m_ArchiveOverwrite.end()) { + } else if (overwrite || archiveOverwrite || archiveLooseOverwrite) { return Settings::instance().modlistOverwrittenLooseColor(); } - } else if (m_Overwritten.find(modIndex) != m_Overwritten.end() || m_ArchiveOverwritten.find(modIndex) != m_ArchiveOverwritten.end()) { + } else if (overwritten || archiveOverwritten || archiveLooseOverwritten) { return Settings::instance().modlistOverwritingLooseColor(); } else if (modInfo->hasFlag(ModInfo::FLAG_SEPARATOR) && modInfo->getColor().isValid() @@ -767,9 +776,16 @@ void ModList::setOverwriteMarkers(const std::set &overwrite, const void ModList::setArchiveOverwriteMarkers(const std::set &overwrite, const std::set &overwritten) { - m_ArchiveOverwrite = overwrite; - m_ArchiveOverwritten = overwritten; - notifyChange(0, rowCount() - 1); + m_ArchiveOverwrite = overwrite; + m_ArchiveOverwritten = overwritten; + notifyChange(0, rowCount() - 1); +} + +void ModList::setArchiveLooseOverwriteMarkers(const std::set &overwrite, const std::set &overwritten) +{ + m_ArchiveLooseOverwrite = overwrite; + m_ArchiveLooseOverwritten = overwritten; + notifyChange(0, rowCount() - 1); } void ModList::setPluginContainer(PluginContainer *pluginContianer) diff --git a/src/modlist.h b/src/modlist.h index 5841b9f2..a8263a76 100644 --- a/src/modlist.h +++ b/src/modlist.h @@ -113,6 +113,7 @@ public: void setPluginContainer(PluginContainer *pluginContainer); void setArchiveOverwriteMarkers(const std::set &overwrite, const std::set &overwritten); + void setArchiveLooseOverwriteMarkers(const std::set &overwrite, const std::set &overwritten); void setArchiveOverwriteMarkers(const std::set &overwrite, const std::set &overwritten); @@ -337,6 +338,8 @@ private: std::set m_Overwritten; std::set m_ArchiveOverwrite; std::set m_ArchiveOverwritten; + std::set m_ArchiveLooseOverwrite; + std::set m_ArchiveLooseOverwritten; TModInfoChange m_ChangeInfo; diff --git a/src/modlistsortproxy.cpp b/src/modlistsortproxy.cpp index c34985b6..88a073e0 100644 --- a/src/modlistsortproxy.cpp +++ b/src/modlistsortproxy.cpp @@ -238,13 +238,15 @@ bool ModListSortProxy::hasConflictFlag(const std::vector &flags) { for (ModInfo::EFlag flag : flags) { if ((flag == ModInfo::FLAG_CONFLICT_MIXED) || - (flag == ModInfo::FLAG_CONFLICT_OVERWRITE) || - (flag == ModInfo::FLAG_CONFLICT_OVERWRITTEN) || - (flag == ModInfo::FLAG_CONFLICT_REDUNDANT) || - (flag == ModInfo::FLAG_ARCHIVE_CONFLICT_OVERWRITE) || - (flag == ModInfo::FLAG_ARCHIVE_CONFLICT_OVERWRITTEN) || - (flag == ModInfo::FLAG_ARCHIVE_CONFLICT_MIXED) || - (flag == ModInfo::FLAG_CONFLICT_LOOSE_OVERWRITE_ARCHIVE)) { + (flag == ModInfo::FLAG_CONFLICT_OVERWRITE) || + (flag == ModInfo::FLAG_CONFLICT_OVERWRITTEN) || + (flag == ModInfo::FLAG_CONFLICT_REDUNDANT) || + (flag == ModInfo::FLAG_ARCHIVE_CONFLICT_OVERWRITE) || + (flag == ModInfo::FLAG_ARCHIVE_CONFLICT_OVERWRITTEN) || + (flag == ModInfo::FLAG_ARCHIVE_CONFLICT_MIXED) || + (flag == ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_MIXED) || + (flag == ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITE) || + (flag == ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITTEN)) { return true; } } diff --git a/src/resources.qrc b/src/resources.qrc index dff1ad72..9e4c9192 100644 --- a/src/resources.qrc +++ b/src/resources.qrc @@ -47,8 +47,10 @@ resources/conflict-mixed.png resources/conflict-overwrite.png resources/conflict-overwritten.png - resources/conflict-redundant.png - resources/conflict-overwrite-blue.png + resources/conflict-redundant.png + resources/conflict-mixed-blue.png + resources/conflict-overwrite-blue.png + resources/conflict-overwritten-blue.png resources/accessories-text-editor.png resources/x-office-calendar.png resources/dialog-warning_16.png @@ -94,8 +96,8 @@ resources/contents/conversation.png resources/contents/locked-chest.png resources/contents/config.png - resources/contents/feather-and-scroll.png - resources/contents/xedit.png + resources/contents/feather-and-scroll.png + resources/contents/xedit.png qt.conf diff --git a/src/resources/conflict-mixed-blue.png b/src/resources/conflict-mixed-blue.png new file mode 100644 index 00000000..2afbb304 Binary files /dev/null and b/src/resources/conflict-mixed-blue.png differ diff --git a/src/resources/conflict-overwritten-blue.png b/src/resources/conflict-overwritten-blue.png new file mode 100644 index 00000000..3a032a55 Binary files /dev/null and b/src/resources/conflict-overwritten-blue.png differ -- cgit v1.3.1 From b05f56c8084fc95590f8a79b9d8a7faf4e0b1844 Mon Sep 17 00:00:00 2001 From: Al12rs Date: Thu, 2 Aug 2018 13:12:31 -0500 Subject: Added red archive conflict icon and made the conflicts tab change font for files that come from an archive. --- src/modinfodialog.cpp | 15 ++++++++++++++- src/modinfowithconflictinfo.cpp | 3 ++- src/resources.qrc | 2 +- src/resources/red-archive-conflict-loser.png | Bin 0 -> 746 bytes 4 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 src/resources/red-archive-conflict-loser.png (limited to 'src') diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp index 204b539b..d1d8d82a 100644 --- a/src/modinfodialog.cpp +++ b/src/modinfodialog.cpp @@ -324,11 +324,18 @@ void ModInfoDialog::refreshLists() } QStringList fields(relativeName.prepend("...")); fields.append(ToQString(altString.str())); - QTreeWidgetItem *item = new QTreeWidgetItem(fields); + + QTreeWidgetItem *item = new QTreeWidgetItem(fields); item->setData(0, Qt::UserRole, fileName); item->setData(1, Qt::UserRole, ToQString(m_Directory->getOriginByID(alternatives.back().first).getName())); item->setData(1, Qt::UserRole + 1, alternatives.back().first); item->setData(1, Qt::UserRole + 2, archive); + if (archive) { + QFont font = item->font(0); + font.setItalic(true); + item->setFont(0, font); + item->setFont(1, font); + } ui->overwriteTree->addTopLevelItem(item); ++numOverwrite; } else {// otherwise don't display the file @@ -342,6 +349,12 @@ void ModInfoDialog::refreshLists() item->setData(0, Qt::UserRole, fileName); item->setData(1, Qt::UserRole, ToQString(realOrigin.getName())); item->setData(1, Qt::UserRole + 2, archive); + if (archive) { + QFont font = item->font(0); + font.setItalic(true); + item->setFont(0, font); + item->setFont(1, font); + } ui->overwrittenTree->addTopLevelItem(item); ++numOverwritten; } diff --git a/src/modinfowithconflictinfo.cpp b/src/modinfowithconflictinfo.cpp index 68b5b265..79896cc3 100644 --- a/src/modinfowithconflictinfo.cpp +++ b/src/modinfowithconflictinfo.cpp @@ -34,7 +34,8 @@ std::vector ModInfoWithConflictInfo::getFlags() const } switch (isLooseArchiveConflicted()) { case CONFLICT_MIXED: { - result.push_back(ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_MIXED); + result.push_back(ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITE); + result.push_back(ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITTEN); } break; case CONFLICT_OVERWRITE: { result.push_back(ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITE); diff --git a/src/resources.qrc b/src/resources.qrc index 9e4c9192..5ed1780e 100644 --- a/src/resources.qrc +++ b/src/resources.qrc @@ -50,7 +50,7 @@ resources/conflict-redundant.png resources/conflict-mixed-blue.png resources/conflict-overwrite-blue.png - resources/conflict-overwritten-blue.png + resources/red-archive-conflict-loser.png resources/accessories-text-editor.png resources/x-office-calendar.png resources/dialog-warning_16.png diff --git a/src/resources/red-archive-conflict-loser.png b/src/resources/red-archive-conflict-loser.png new file mode 100644 index 00000000..18284ee2 Binary files /dev/null and b/src/resources/red-archive-conflict-loser.png differ -- cgit v1.3.1 From 75a663941d5a58b9676e2eb99a2a288abc19a359 Mon Sep 17 00:00:00 2001 From: Silarn Date: Thu, 9 Aug 2018 02:30:06 -0500 Subject: Add flag padding for all conflict icons --- src/modflagicondelegate.cpp | 39 ++++++++++++++++++++++++++++++++++++++- src/modflagicondelegate.h | 2 ++ 2 files changed, 40 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/modflagicondelegate.cpp b/src/modflagicondelegate.cpp index 5584dea1..a0a0a86d 100644 --- a/src/modflagicondelegate.cpp +++ b/src/modflagicondelegate.cpp @@ -7,6 +7,14 @@ ModInfo::EFlag ModFlagIconDelegate::m_ConflictFlags[4] = { ModInfo::FLAG_CONFLIC , ModInfo::FLAG_CONFLICT_OVERWRITTEN , ModInfo::FLAG_CONFLICT_REDUNDANT }; +ModInfo::EFlag ModFlagIconDelegate::m_ArchiveLooseConflictFlags[3] = { ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_MIXED + , ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITE + , ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITTEN }; + +ModInfo::EFlag ModFlagIconDelegate::m_ArchiveConflictFlags[3] = { ModInfo::FLAG_ARCHIVE_CONFLICT_MIXED + , ModInfo::FLAG_ARCHIVE_CONFLICT_OVERWRITE + , ModInfo::FLAG_ARCHIVE_CONFLICT_OVERWRITTEN }; + ModFlagIconDelegate::ModFlagIconDelegate(QObject *parent) : IconDelegate(parent) { @@ -19,7 +27,8 @@ QList ModFlagIconDelegate::getIcons(const QModelIndex &index) const { ModInfo::Ptr info = ModInfo::getByIndex(modid.toInt()); std::vector flags = info->getFlags(); - { // insert conflict icon first to provide nicer alignment + // insert conflict icons to provide nicer alignment + { // insert loose file conflicts first auto iter = std::find_first_of(flags.begin(), flags.end(), m_ConflictFlags, m_ConflictFlags + 4); if (iter != flags.end()) { @@ -30,6 +39,34 @@ QList ModFlagIconDelegate::getIcons(const QModelIndex &index) const { } } + { // insert archive vs loose conflicts second + int pad = 2; + auto iter = std::find_first_of(flags.begin(), flags.end(), + m_ArchiveLooseConflictFlags, m_ArchiveLooseConflictFlags + 4); + while (iter != flags.end()) { + result.append(getFlagIcon(*iter)); + flags.erase(iter); + pad--; + iter = std::find_first_of(flags.begin(), flags.end(), + m_ArchiveLooseConflictFlags, m_ArchiveLooseConflictFlags + 4); + } + while (pad > 0) { + result.append(QString()); + pad--; + } + } + + { // insert archive conflicts last + auto iter = std::find_first_of(flags.begin(), flags.end(), + m_ArchiveConflictFlags, m_ArchiveConflictFlags + 4); + if (iter != flags.end()) { + result.append(getFlagIcon(*iter)); + flags.erase(iter); + } else { + result.append(QString()); + } + } + for (auto iter = flags.begin(); iter != flags.end(); ++iter) { result.append(getFlagIcon(*iter)); } diff --git a/src/modflagicondelegate.h b/src/modflagicondelegate.h index b31a250b..7324d516 100644 --- a/src/modflagicondelegate.h +++ b/src/modflagicondelegate.h @@ -15,6 +15,8 @@ private: QString getFlagIcon(ModInfo::EFlag flag) const; private: static ModInfo::EFlag m_ConflictFlags[4]; + static ModInfo::EFlag m_ArchiveLooseConflictFlags[3]; + static ModInfo::EFlag m_ArchiveConflictFlags[3]; }; #endif // MODFLAGICONDELEGATE_H -- cgit v1.3.1 From 49159de5d7084bf1ac159e3e37e2b406cdd87dbf Mon Sep 17 00:00:00 2001 From: Al12rs Date: Tue, 14 Aug 2018 11:35:20 -0500 Subject: Improved refresh performance by replacing std::transform() with CharLowerBuffer(). Fixed padding to four spaces and removed references to FLAG_ARCHIVE_LOOSE_CONFLICTS_MIXED that isn't used. --- src/modflagicondelegate.cpp | 32 +++++++++++++++++++------------- src/modflagicondelegate.h | 2 +- src/modinfo.h | 1 - src/modlist.cpp | 1 - src/modlistsortproxy.cpp | 1 - src/shared/util.cpp | 12 ++++++++---- 6 files changed, 28 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/modflagicondelegate.cpp b/src/modflagicondelegate.cpp index a0a0a86d..48d71313 100644 --- a/src/modflagicondelegate.cpp +++ b/src/modflagicondelegate.cpp @@ -7,8 +7,7 @@ ModInfo::EFlag ModFlagIconDelegate::m_ConflictFlags[4] = { ModInfo::FLAG_CONFLIC , ModInfo::FLAG_CONFLICT_OVERWRITTEN , ModInfo::FLAG_CONFLICT_REDUNDANT }; -ModInfo::EFlag ModFlagIconDelegate::m_ArchiveLooseConflictFlags[3] = { ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_MIXED - , ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITE +ModInfo::EFlag ModFlagIconDelegate::m_ArchiveLooseConflictFlags[2] = { ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITE , ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITTEN }; ModInfo::EFlag ModFlagIconDelegate::m_ArchiveConflictFlags[3] = { ModInfo::FLAG_ARCHIVE_CONFLICT_MIXED @@ -39,26 +38,33 @@ QList ModFlagIconDelegate::getIcons(const QModelIndex &index) const { } } - { // insert archive vs loose conflicts second - int pad = 2; + { // insert loose vs archive overwrite second + auto iter = std::find(flags.begin(), flags.end(), + ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITE); + if (iter != flags.end()) { + result.append(getFlagIcon(*iter)); + flags.erase(iter); + } + else { + result.append(QString()); + } + } + + { // insert loose vs archive overwritten third auto iter = std::find_first_of(flags.begin(), flags.end(), - m_ArchiveLooseConflictFlags, m_ArchiveLooseConflictFlags + 4); - while (iter != flags.end()) { + m_ArchiveLooseConflictFlags + 1, m_ArchiveLooseConflictFlags + 2); + if (iter != flags.end()) { result.append(getFlagIcon(*iter)); flags.erase(iter); - pad--; - iter = std::find_first_of(flags.begin(), flags.end(), - m_ArchiveLooseConflictFlags, m_ArchiveLooseConflictFlags + 4); } - while (pad > 0) { + else { result.append(QString()); - pad--; } } { // insert archive conflicts last auto iter = std::find_first_of(flags.begin(), flags.end(), - m_ArchiveConflictFlags, m_ArchiveConflictFlags + 4); + m_ArchiveConflictFlags, m_ArchiveConflictFlags + 3); if (iter != flags.end()) { result.append(getFlagIcon(*iter)); flags.erase(iter); @@ -87,7 +93,7 @@ QString ModFlagIconDelegate::getFlagIcon(ModInfo::EFlag flag) const case ModInfo::FLAG_CONFLICT_OVERWRITTEN: return ":/MO/gui/emblem_conflict_overwritten"; case ModInfo::FLAG_CONFLICT_MIXED: return ":/MO/gui/emblem_conflict_mixed"; case ModInfo::FLAG_CONFLICT_REDUNDANT: return ":MO/gui/emblem_conflict_redundant"; - case ModInfo::FLAG_ALTERNATE_GAME: return ":MO/gui/alternate_game"; + case ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_MIXED: return ":/MO/gui/archive_loose_conflict_mixed"; case ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITE: return ":/MO/gui/archive_loose_conflict_overwrite"; case ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITTEN: return ":/MO/gui/archive_loose_conflict_overwritten"; case ModInfo::FLAG_ARCHIVE_CONFLICT_MIXED: return ":/MO/gui/archive_conflict_mixed"; diff --git a/src/modflagicondelegate.h b/src/modflagicondelegate.h index 7324d516..0f257c7d 100644 --- a/src/modflagicondelegate.h +++ b/src/modflagicondelegate.h @@ -15,7 +15,7 @@ private: QString getFlagIcon(ModInfo::EFlag flag) const; private: static ModInfo::EFlag m_ConflictFlags[4]; - static ModInfo::EFlag m_ArchiveLooseConflictFlags[3]; + static ModInfo::EFlag m_ArchiveLooseConflictFlags[2]; static ModInfo::EFlag m_ArchiveConflictFlags[3]; }; diff --git a/src/modinfo.h b/src/modinfo.h index 99ce35b5..00859209 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -74,7 +74,6 @@ public: FLAG_CONFLICT_REDUNDANT, FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITE, FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITTEN, - FLAG_ARCHIVE_LOOSE_CONFLICT_MIXED, FLAG_ARCHIVE_CONFLICT_OVERWRITE, FLAG_ARCHIVE_CONFLICT_OVERWRITTEN, FLAG_ARCHIVE_CONFLICT_MIXED, diff --git a/src/modlist.cpp b/src/modlist.cpp index fd6da43b..8c070667 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -163,7 +163,6 @@ QString ModList::getFlagText(ModInfo::EFlag flag, ModInfo::Ptr modInfo) const case ModInfo::FLAG_CONFLICT_OVERWRITTEN: return tr("Overwritten loose files"); case ModInfo::FLAG_CONFLICT_MIXED: return tr("Loose files Overwrites & Overwritten"); case ModInfo::FLAG_CONFLICT_REDUNDANT: return tr("Redundant"); - case ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_MIXED: return tr("Contains archive files overwritten by loose files and loose files overwriting an archive"); case ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITE: return tr("Overwrites an archive with loose files"); case ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITTEN: return tr("Archive is overwritten by loose files"); case ModInfo::FLAG_ARCHIVE_CONFLICT_OVERWRITE: return tr("Overwrites another archive file"); diff --git a/src/modlistsortproxy.cpp b/src/modlistsortproxy.cpp index 88a073e0..8cf4bb9c 100644 --- a/src/modlistsortproxy.cpp +++ b/src/modlistsortproxy.cpp @@ -244,7 +244,6 @@ bool ModListSortProxy::hasConflictFlag(const std::vector &flags) (flag == ModInfo::FLAG_ARCHIVE_CONFLICT_OVERWRITE) || (flag == ModInfo::FLAG_ARCHIVE_CONFLICT_OVERWRITTEN) || (flag == ModInfo::FLAG_ARCHIVE_CONFLICT_MIXED) || - (flag == ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_MIXED) || (flag == ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITE) || (flag == ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITTEN)) { return true; diff --git a/src/shared/util.cpp b/src/shared/util.cpp index 102565f5..b65ed071 100644 --- a/src/shared/util.cpp +++ b/src/shared/util.cpp @@ -108,27 +108,31 @@ static auto locToLower = [] (char in) -> char { std::string &ToLower(std::string &text) { - std::transform(text.begin(), text.end(), text.begin(), locToLower); + //std::transform(text.begin(), text.end(), text.begin(), locToLower); + CharLowerBuffA(const_cast(text.c_str()), static_cast(text.size())); return text; } std::string ToLower(const std::string &text) { std::string result(text); - std::transform(result.begin(), result.end(), result.begin(), locToLower); + //std::transform(result.begin(), result.end(), result.begin(), locToLower); + CharLowerBuffA(const_cast(result.c_str()), static_cast(result.size())); return result; } std::wstring &ToLower(std::wstring &text) { - std::transform(text.begin(), text.end(), text.begin(), locToLowerW); + //std::transform(text.begin(), text.end(), text.begin(), locToLowerW); + CharLowerBuffW(const_cast(text.c_str()), static_cast(text.size())); return text; } std::wstring ToLower(const std::wstring &text) { std::wstring result(text); - std::transform(result.begin(), result.end(), result.begin(), locToLowerW); + //std::transform(result.begin(), result.end(), result.begin(), locToLowerW); + CharLowerBuffW(const_cast(result.c_str()), static_cast(result.size())); return result; } -- cgit v1.3.1 From 57178f898838afed6e7a50413899d6082aad9989 Mon Sep 17 00:00:00 2001 From: Project579 Date: Mon, 20 Aug 2018 12:55:02 -0500 Subject: Added button to disable Archives in Data Tree and entirely. --- src/mainwindow.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++++++++-- src/mainwindow.h | 3 +++ src/mainwindow.ui | 46 ++++++++++++++++++++++++++++++------------ src/organizercore.cpp | 24 ++++++++++++++++------ src/organizercore.h | 3 +++ src/settings.cpp | 10 ++++++++- src/settings.h | 6 ++++++ src/settingsdialog.ui | 21 +++++++++++++++++++ 8 files changed, 147 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index d7ae18fb..0d3abce5 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -448,6 +448,19 @@ MainWindow::MainWindow(QSettings &initSettings ui->profileBox->setCurrentText(m_OrganizerCore.currentProfile()->name()); + if (m_OrganizerCore.getArchiveParsing()) + { + ui->showArchiveDataCheckBox->setCheckState(Qt::Checked); + ui->showArchiveDataCheckBox->setEnabled(true); + m_showArchiveData = true; + } + else + { + ui->showArchiveDataCheckBox->setCheckState(Qt::Unchecked); + ui->showArchiveDataCheckBox->setEnabled(false); + m_showArchiveData = false; + } + refreshExecutablesList(); updateToolBar(); @@ -1250,11 +1263,15 @@ void MainWindow::updateTo(QTreeWidgetItem *subTree, const std::wstring &director if (conflictsOnly && (current->getAlternatives().size() == 0)) { continue; } + + bool isArchive = false; + int originID = current->getOrigin(isArchive); + if (!m_showArchiveData && isArchive) { + continue; + } QString fileName = ToQString(current->getName()); QStringList columns(fileName); - bool isArchive = false; - int originID = current->getOrigin(isArchive); FilesOrigin origin = m_OrganizerCore.directoryStructure()->getOriginByID(originID); QString source("data"); unsigned int modIndex = ModInfo::getIndex(ToQString(origin.getName())); @@ -4351,6 +4368,27 @@ void MainWindow::on_actionSettings_triggered() m_OrganizerCore.profileRefresh(); } + const auto state = settings.archiveParsing(); + if (state != m_OrganizerCore.getArchiveParsing()) + { + m_OrganizerCore.setArchiveParsing(state); + if (!state) + { + ui->showArchiveDataCheckBox->setCheckState(Qt::Unchecked); + ui->showArchiveDataCheckBox->setEnabled(false); + m_showArchiveData = false; + } + else + { + ui->showArchiveDataCheckBox->setCheckState(Qt::Checked); + ui->showArchiveDataCheckBox->setEnabled(true); + m_showArchiveData = true; + } + m_OrganizerCore.refreshModList(); + m_OrganizerCore.refreshDirectoryStructure(); + m_OrganizerCore.refreshLists(); + } + if (settings.getCacheDirectory() != oldCacheDirectory) { NexusInterface::instance(&m_PluginContainer)->setCacheDirectory(settings.getCacheDirectory()); } @@ -5985,3 +6023,17 @@ void MainWindow::sendSelectedModsToSeparator_clicked() } settings.setValue(key, dialog.saveGeometry()); } + +void MainWindow::on_showArchiveDataCheckBox_toggled(const bool checked) +{ + if (m_OrganizerCore.getArchiveParsing() && checked) + { + m_showArchiveData = checked; + } + else + { + m_showArchiveData = false; + } + refreshDataTree(); +} + diff --git a/src/mainwindow.h b/src/mainwindow.h index 69d08337..ad88c42c 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -373,6 +373,8 @@ private: bool m_closing{ false }; + bool m_showArchiveData{ true }; + std::vector> m_PersistedGeometry; MOBase::DelayedFileWriter m_ArchiveListWriter; @@ -600,6 +602,7 @@ private slots: // ui slots void on_btnRefreshDownloads_clicked(); void on_categoriesList_customContextMenuRequested(const QPoint &pos); void on_conflictsCheckBox_toggled(bool checked); + void on_showArchiveDataCheckBox_toggled(bool checked); void on_dataTree_customContextMenuRequested(const QPoint &pos); void on_executablesListBox_currentIndexChanged(int index); void on_modList_customContextMenuRequested(const QPoint &pos); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 41365768..fba246f5 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1152,19 +1152,39 @@ p, li { white-space: pre-wrap; } - - - - Filter the above list so that only conflicts are displayed. - - - Filter the above list so that only conflicts are displayed. - - - Show only conflicts - - - + + + + + + Filters the above list so that only conflicts are displayed. + + + Filters the above list so that only conflicts are displayed. + + + Show only conflicts + + + + + + + Filters the above list so that files from archives are not shown + + + + + + Filters the above list so that files from archives are not shown + + + Show files from Archives + + + + + diff --git a/src/organizercore.cpp b/src/organizercore.cpp index f19f56c3..d21fa844 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -786,6 +786,16 @@ std::wstring OrganizerCore::crashDumpsPath() { ).toStdWString(); } +bool OrganizerCore::getArchiveParsing() const +{ + return m_ArchiveParsing; +} + +void OrganizerCore::setArchiveParsing(const bool archiveParsing) +{ + m_ArchiveParsing = archiveParsing; +} + void OrganizerCore::setCurrentProfile(const QString &profileName) { if ((m_CurrentProfile != nullptr) @@ -1925,12 +1935,14 @@ IPluginGame const *OrganizerCore::managedGame() const std::vector OrganizerCore::enabledArchives() { std::vector result; - QFile archiveFile(m_CurrentProfile->getArchivesFileName()); - if (archiveFile.open(QIODevice::ReadOnly)) { - while (!archiveFile.atEnd()) { - result.push_back(QString::fromUtf8(archiveFile.readLine()).trimmed()); - } - archiveFile.close(); + if (m_ArchiveParsing) { + QFile archiveFile(m_CurrentProfile->getArchivesFileName()); + if (archiveFile.open(QIODevice::ReadOnly)) { + while (!archiveFile.atEnd()) { + result.push_back(QString::fromUtf8(archiveFile.readLine()).trimmed()); + } + archiveFile.close(); + } } return result; } diff --git a/src/organizercore.h b/src/organizercore.h index 086fa11d..d0964ed5 100644 --- a/src/organizercore.h +++ b/src/organizercore.h @@ -211,6 +211,8 @@ public: bool onFinishedRun(const std::function &func); void refreshModList(bool saveChanges = true); QStringList modsSortedByProfilePriority() const; + bool getArchiveParsing() const; + void setArchiveParsing(bool archiveParsing); public: // IPluginDiagnose interface @@ -335,6 +337,7 @@ private: bool m_AskForNexusPW; bool m_DirectoryUpdate; bool m_ArchivesInit; + bool m_ArchiveParsing{ m_Settings.archiveParsing() }; MOBase::DelayedFileWriter m_PluginListsWriter; UsvfsConnector m_USVFS; diff --git a/src/settings.cpp b/src/settings.cpp index 18e893cb..eb5b372f 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -474,6 +474,11 @@ uint Settings::getMotDHash() const return m_Settings.value("motd_hash", 0).toUInt(); } +bool Settings::archiveParsing() const +{ + return m_Settings.value("Settings/archive_parsing", true).toBool(); +} + QVariant Settings::pluginSetting(const QString &pluginName, const QString &key) const { auto iterPlugin = m_PluginSettings.find(pluginName); @@ -1085,6 +1090,7 @@ Settings::WorkaroundsTab::WorkaroundsTab(Settings *m_parent, , m_forceEnableBox(m_dialog.findChild("forceEnableBox")) , m_displayForeignBox(m_dialog.findChild("displayForeignBox")) , m_lockGUIBox(m_dialog.findChild("lockGUIBox")) + , m_enableArchiveParsingBox(m_dialog.findChild("enableArchiveParsingBox")) { m_appIDEdit->setText(m_parent->getSteamAppID()); @@ -1119,7 +1125,8 @@ Settings::WorkaroundsTab::WorkaroundsTab(Settings *m_parent, m_forceEnableBox->setChecked(m_parent->forceEnableCoreFiles()); m_displayForeignBox->setChecked(m_parent->displayForeign()); m_lockGUIBox->setChecked(m_parent->lockGUI()); - + m_enableArchiveParsingBox->setChecked(m_parent->archiveParsing()); + m_dialog.setExecutableBlacklist(m_parent->executablesBlacklist()); } @@ -1137,6 +1144,7 @@ void Settings::WorkaroundsTab::update() m_Settings.setValue("Settings/force_enable_core_files", m_forceEnableBox->isChecked()); m_Settings.setValue("Settings/display_foreign", m_displayForeignBox->isChecked()); m_Settings.setValue("Settings/lock_gui", m_lockGUIBox->isChecked()); + m_Settings.setValue("Settings/archive_parsing", m_enableArchiveParsingBox->isChecked()); m_Settings.setValue("Settings/executable_blacklist", m_dialog.getExecutableBlacklist()); diff --git a/src/settings.h b/src/settings.h index 912864e2..3694bfad 100644 --- a/src/settings.h +++ b/src/settings.h @@ -280,6 +280,11 @@ public: **/ void setMotDHash(uint hash); + /** + * @return true if the user wants to have archives being parsed to show conflicts and contents + */ + bool archiveParsing() const; + /** * @return hash of the last displayed message of the day **/ @@ -514,6 +519,7 @@ private: QCheckBox *m_forceEnableBox; QCheckBox *m_displayForeignBox; QCheckBox *m_lockGUIBox; + QCheckBox *m_enableArchiveParsingBox; }; private slots: diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index 0412fc10..51f35683 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -1100,6 +1100,27 @@ programs you are intentionally running. + + + + Enable parsing of Archives Archives, has effects on perfromance. + + + + By default Mod Organizer will parse Archive files to calculate conflicts between themselves and loose files, this process has a noticeable cost in performance. + This feature should not be confused from the one offered by ModOrganizer 1, ModOrganizer 2 will only show conflicts with archives NOT load them into the game or program. + + If you disable this feature, MO will only display conflicts with Loose files. + + + + Enable parsing of Archives + + + true + + + -- cgit v1.3.1 From 40c82fc1908a8ca53abeeabdc618e81e941c987c Mon Sep 17 00:00:00 2001 From: Al12rs Date: Mon, 10 Sep 2018 05:58:24 -0500 Subject: Fixed mainwindow.cpp so that Qt Creator does not break it anymore. We should be able to normally use Creator now without having to worry about breaking the build. Partial fix for conflict information getting messd up after opening infodialog or disabling a mod. Icons still get messed up but conflict tab remains consistent at first inspection. Reverted main tab to plugins Changed version of Archive conflicts branch to 2.2.0 pre-alpha. --- src/directoryrefresher.cpp | 12 ++++---- src/mainwindow.cpp | 1 + src/mainwindow.ui | 66 +++++++++++++++++++++---------------------- src/shared/directoryentry.cpp | 31 ++++++++++++++++---- src/version.rc | 4 +-- 5 files changed, 68 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/directoryrefresher.cpp b/src/directoryrefresher.cpp index 5c789049..82eb093b 100644 --- a/src/directoryrefresher.cpp +++ b/src/directoryrefresher.cpp @@ -85,17 +85,17 @@ void DirectoryRefresher::addModBSAToStructure(DirectoryEntry *directoryStructure int priority, const QString &directory, const QStringList &archives) { std::wstring directoryW = ToWString(QDir::toNativeSeparators(directory)); + //QStringList loadOrder = QStringList(); + IPluginGame *game = qApp->property("managed_game").value(); + + GamePlugins *gamePlugins = game->feature(); QStringList loadOrder = QStringList(); + gamePlugins->getLoadOrder(loadOrder); for (const QString &archive : archives) { QFileInfo fileInfo(archive); if (m_EnabledArchives.find(fileInfo.fileName()) != m_EnabledArchives.end()) { - IPluginGame *game = qApp->property("managed_game").value(); - - GamePlugins *gamePlugins = game->feature(); - QStringList loadOrder = QStringList(); - gamePlugins->getLoadOrder(loadOrder); - + int order = -1; for (auto plugin : loadOrder) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 0d3abce5..cdd53dc9 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -313,6 +313,7 @@ MainWindow::MainWindow(QSettings &initSettings ui->espList->setItemDelegateForColumn(PluginList::COL_FLAGS, new GenericIconDelegate(ui->espList)); ui->espList->installEventFilter(m_OrganizerCore.pluginList()); + //bsaList converted to normal QTreeWidget since we can't sort BSAs anymore. //ui->bsaList->setLocalMoveOnly(true); bool pluginListAdjusted = registerWidgetState(ui->espList->objectName(), ui->espList->header(), "plugin_list_state"); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index fba246f5..eb88a855 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1152,39 +1152,39 @@ p, li { white-space: pre-wrap; } - - - - - - Filters the above list so that only conflicts are displayed. - - - Filters the above list so that only conflicts are displayed. - - - Show only conflicts - - - - - - - Filters the above list so that files from archives are not shown - - - - - - Filters the above list so that files from archives are not shown - - - Show files from Archives - - - - - + + + + + + Filters the above list so that only conflicts are displayed. + + + Filters the above list so that only conflicts are displayed. + + + Show only conflicts + + + + + + + Filters the above list so that files from archives are not shown + + + + + + Filters the above list so that files from archives are not shown + + + Show files from Archives + + + + + diff --git a/src/shared/directoryentry.cpp b/src/shared/directoryentry.cpp index 477f4dad..602d58c7 100644 --- a/src/shared/directoryentry.cpp +++ b/src/shared/directoryentry.cpp @@ -282,12 +282,32 @@ bool FileEntry::removeOrigin(int origin) // find alternative with the highest priority std::vector>>::iterator currentIter = m_Alternatives.begin(); for (std::vector>>::iterator iter = m_Alternatives.begin(); iter != m_Alternatives.end(); ++iter) { - if ((m_Parent->getOriginByID(iter->first).getPriority() > m_Parent->getOriginByID(currentIter->first).getPriority()) && - (iter->first != origin)) { - currentIter = iter; + if (iter->first != origin) { + + //Both files are not from archives. + if (!iter->second.first.size() && !currentIter->second.first.size()) { + if ((m_Parent->getOriginByID(iter->first).getPriority() > m_Parent->getOriginByID(currentIter->first).getPriority())) { + currentIter = iter; + } + } + else { + //Both files are from archives + if (iter->second.first.size() && currentIter->second.first.size()) { + if (iter->second.second > currentIter->second.second) { + currentIter = iter; + } + } + else { + //Only one of the two is an archive, so we change currentIter only if he is the archive one. + if (currentIter->second.first.size()) { + currentIter = iter; + } + } + } } } int currentID = currentIter->first; + m_Archive = currentIter->second; m_Alternatives.erase(currentIter); m_Origin = currentID; @@ -299,15 +319,16 @@ bool FileEntry::removeOrigin(int origin) if (!::GetFileTime(file, nullptr, nullptr, &m_FileTime)) { // maybe this file is in a bsa, but there is no easy way to find out which. User should refresh // the view to find out - m_Archive = std::pair(L"bsa?", -1); + //m_Archive = std::pair(L"bsa?", -1); } else { - m_Archive = std::pair(L"", -1); + //m_Archive = std::pair(L"", -1); } ::CloseHandle(file); } else { m_Origin = -1; + m_Archive = std::pair(L"", -1); return true; } } else { diff --git a/src/version.rc b/src/version.rc index 3f2deab0..e1f80785 100644 --- a/src/version.rc +++ b/src/version.rc @@ -3,8 +3,8 @@ // If VS_FF_PRERELEASE is not set, MO labels the build as a release and uses VER_FILEVERSION to determine version number. // Otherwise, if letters are used in VER_FILEVERSION_STR, uses the full MOBase::VersionInfo parser // Otherwise, uses the numbers from VER_FILEVERSION and sets the release type as pre-alpha -#define VER_FILEVERSION 2,1,6 -#define VER_FILEVERSION_STR "2.1.6\0" +#define VER_FILEVERSION 2,2,0 +#define VER_FILEVERSION_STR "2.2.0\0" VS_VERSION_INFO VERSIONINFO FILEVERSION VER_FILEVERSION -- cgit v1.3.1 From 4436d376a8d426867f217b03838570a424b09c5f Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Wed, 12 Dec 2018 20:26:35 -0600 Subject: Clean up and fix merge issues --- src/directoryrefresher.cpp | 3 +- src/mainwindow.cpp | 77 ++- src/mainwindow.ui | 15 +- src/modflagicondelegate.cpp | 3 - src/modinfo.h | 10 - src/modinfodialog.h | 3 +- src/modinfowithconflictinfo.cpp | 2 +- src/modlist.cpp | 18 +- src/modlist.h | 2 - src/organizer_en.ts | 1124 ++++++++++++++++++++------------------- src/organizercore.cpp | 18 +- src/settings.cpp | 4 +- 12 files changed, 652 insertions(+), 627 deletions(-) (limited to 'src') diff --git a/src/directoryrefresher.cpp b/src/directoryrefresher.cpp index 82eb093b..e6e6a8e0 100644 --- a/src/directoryrefresher.cpp +++ b/src/directoryrefresher.cpp @@ -85,7 +85,6 @@ void DirectoryRefresher::addModBSAToStructure(DirectoryEntry *directoryStructure int priority, const QString &directory, const QStringList &archives) { std::wstring directoryW = ToWString(QDir::toNativeSeparators(directory)); - //QStringList loadOrder = QStringList(); IPluginGame *game = qApp->property("managed_game").value(); GamePlugins *gamePlugins = game->feature(); @@ -95,7 +94,7 @@ void DirectoryRefresher::addModBSAToStructure(DirectoryEntry *directoryStructure for (const QString &archive : archives) { QFileInfo fileInfo(archive); if (m_EnabledArchives.find(fileInfo.fileName()) != m_EnabledArchives.end()) { - + int order = -1; for (auto plugin : loadOrder) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index cdd53dc9..73a40f46 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -313,8 +313,7 @@ MainWindow::MainWindow(QSettings &initSettings ui->espList->setItemDelegateForColumn(PluginList::COL_FLAGS, new GenericIconDelegate(ui->espList)); ui->espList->installEventFilter(m_OrganizerCore.pluginList()); - //bsaList converted to normal QTreeWidget since we can't sort BSAs anymore. - //ui->bsaList->setLocalMoveOnly(true); + ui->bsaList->setLocalMoveOnly(true); bool pluginListAdjusted = registerWidgetState(ui->espList->objectName(), ui->espList->header(), "plugin_list_state"); registerWidgetState(ui->dataTree->objectName(), ui->dataTree->header()); @@ -451,15 +450,15 @@ MainWindow::MainWindow(QSettings &initSettings if (m_OrganizerCore.getArchiveParsing()) { - ui->showArchiveDataCheckBox->setCheckState(Qt::Checked); - ui->showArchiveDataCheckBox->setEnabled(true); - m_showArchiveData = true; + ui->showArchiveDataCheckBox->setCheckState(Qt::Checked); + ui->showArchiveDataCheckBox->setEnabled(true); + m_showArchiveData = true; } else { - ui->showArchiveDataCheckBox->setCheckState(Qt::Unchecked); - ui->showArchiveDataCheckBox->setEnabled(false); - m_showArchiveData = false; + ui->showArchiveDataCheckBox->setCheckState(Qt::Unchecked); + ui->showArchiveDataCheckBox->setEnabled(false); + m_showArchiveData = false; } refreshExecutablesList(); @@ -1230,7 +1229,7 @@ void MainWindow::updateTo(QTreeWidgetItem *subTree, const std::wstring &director directoryChild->setData(0, Qt::DecorationRole, (new QFileIconProvider())->icon(QFileIconProvider::Folder)); directoryChild->setData(0, Qt::UserRole + 3, isDirectory); - if (conflictsOnly) { + if (conflictsOnly || !m_showArchiveData) { updateTo(directoryChild, temp.str(), **current, conflictsOnly); if (directoryChild->childCount() != 0) { subTree->addChild(directoryChild); @@ -1264,9 +1263,9 @@ void MainWindow::updateTo(QTreeWidgetItem *subTree, const std::wstring &director if (conflictsOnly && (current->getAlternatives().size() == 0)) { continue; } - + bool isArchive = false; - int originID = current->getOrigin(isArchive); + int originID = current->getOrigin(isArchive); if (!m_showArchiveData && isArchive) { continue; } @@ -2304,10 +2303,10 @@ void MainWindow::fileMoved(const QString &filePath, const QString &oldOriginName QString fullNewPath = ToQString(newOrigin.getPath()) + "\\" + filePath; WIN32_FIND_DATAW findData; - HANDLE hFind; - hFind = ::FindFirstFileW(ToWString(fullNewPath).c_str(), &findData); + HANDLE hFind; + hFind = ::FindFirstFileW(ToWString(fullNewPath).c_str(), &findData); filePtr->addOrigin(newOrigin.getID(), findData.ftCreationTime, L"", -1); - FindClose(hFind); + FindClose(hFind); } if (m_OrganizerCore.directoryStructure()->originExists(ToWString(oldOriginName))) { FilesOrigin &oldOrigin = m_OrganizerCore.directoryStructure()->getOriginByName(ToWString(oldOriginName)); @@ -4372,22 +4371,22 @@ void MainWindow::on_actionSettings_triggered() const auto state = settings.archiveParsing(); if (state != m_OrganizerCore.getArchiveParsing()) { - m_OrganizerCore.setArchiveParsing(state); - if (!state) - { - ui->showArchiveDataCheckBox->setCheckState(Qt::Unchecked); - ui->showArchiveDataCheckBox->setEnabled(false); - m_showArchiveData = false; - } - else - { - ui->showArchiveDataCheckBox->setCheckState(Qt::Checked); - ui->showArchiveDataCheckBox->setEnabled(true); - m_showArchiveData = true; - } - m_OrganizerCore.refreshModList(); - m_OrganizerCore.refreshDirectoryStructure(); - m_OrganizerCore.refreshLists(); + m_OrganizerCore.setArchiveParsing(state); + if (!state) + { + ui->showArchiveDataCheckBox->setCheckState(Qt::Unchecked); + ui->showArchiveDataCheckBox->setEnabled(false); + m_showArchiveData = false; + } + else + { + ui->showArchiveDataCheckBox->setCheckState(Qt::Checked); + ui->showArchiveDataCheckBox->setEnabled(true); + m_showArchiveData = true; + } + m_OrganizerCore.refreshModList(); + m_OrganizerCore.refreshDirectoryStructure(); + m_OrganizerCore.refreshLists(); } if (settings.getCacheDirectory() != oldCacheDirectory) { @@ -6027,14 +6026,14 @@ void MainWindow::sendSelectedModsToSeparator_clicked() void MainWindow::on_showArchiveDataCheckBox_toggled(const bool checked) { - if (m_OrganizerCore.getArchiveParsing() && checked) - { - m_showArchiveData = checked; - } - else - { - m_showArchiveData = false; - } - refreshDataTree(); + if (m_OrganizerCore.getArchiveParsing() && checked) + { + m_showArchiveData = checked; + } + else + { + m_showArchiveData = false; + } + refreshDataTree(); } diff --git a/src/mainwindow.ui b/src/mainwindow.ui index eb88a855..c6b43be0 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -831,6 +831,9 @@ p, li { white-space: pre-wrap; } + + true + Sort @@ -1045,7 +1048,7 @@ p, li { white-space: pre-wrap; } - + Qt::CustomContextMenu @@ -1061,19 +1064,19 @@ p, li { white-space: pre-wrap; } false - + false - + false - + 20 - + true - + 1 diff --git a/src/modflagicondelegate.cpp b/src/modflagicondelegate.cpp index 48d71313..eb6945c4 100644 --- a/src/modflagicondelegate.cpp +++ b/src/modflagicondelegate.cpp @@ -89,11 +89,8 @@ QString ModFlagIconDelegate::getFlagIcon(ModInfo::EFlag flag) const case ModInfo::FLAG_NOTES: return ":/MO/gui/emblem_notes"; case ModInfo::FLAG_CONFLICT_MIXED: return ":/MO/gui/emblem_conflict_mixed"; case ModInfo::FLAG_CONFLICT_OVERWRITE: return ":/MO/gui/emblem_conflict_overwrite"; - case ModInfo::FLAG_CONFLICT_LOOSE_OVERWRITE_ARCHIVE: return ":/MO/gui/emblem_conflict_loose_overwrite_archive"; case ModInfo::FLAG_CONFLICT_OVERWRITTEN: return ":/MO/gui/emblem_conflict_overwritten"; - case ModInfo::FLAG_CONFLICT_MIXED: return ":/MO/gui/emblem_conflict_mixed"; case ModInfo::FLAG_CONFLICT_REDUNDANT: return ":MO/gui/emblem_conflict_redundant"; - case ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_MIXED: return ":/MO/gui/archive_loose_conflict_mixed"; case ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITE: return ":/MO/gui/archive_loose_conflict_overwrite"; case ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITTEN: return ":/MO/gui/archive_loose_conflict_overwritten"; case ModInfo::FLAG_ARCHIVE_CONFLICT_MIXED: return ":/MO/gui/archive_conflict_mixed"; diff --git a/src/modinfo.h b/src/modinfo.h index 00859209..350b3a0d 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -639,16 +639,6 @@ public: */ virtual std::set getModArchiveOverwritten() { return std::set(); } - /** - * @return retrieve list of mods (as mod index) with archives that are overwritten by this one. Updates may be delayed - */ - virtual std::set getModArchiveOverwrite() { return std::set(); } - - /** - * @return list of mods (as mod index) with archives that overwrite this one. Updates may be delayed - */ - virtual std::set getModArchiveOverwritten() { return std::set(); } - /** * @return retrieve list of mods (as mod index) with archives that are overwritten by thos mod's loose files. Updates may be delayed */ diff --git a/src/modinfodialog.h b/src/modinfodialog.h index 6a315a93..52768649 100644 --- a/src/modinfodialog.h +++ b/src/modinfodialog.h @@ -78,7 +78,8 @@ public: * @param modInfo info structure about the mod to display * @param parent parend widget **/ - explicit ModInfoDialog(ModInfo::Ptr modInfo, const MOShared::DirectoryEntry *directory, bool unmanaged, OrganizerCore *organizerCore, PluginContainer *pluginContainer, QWidget *parent = 0); + explicit ModInfoDialog(ModInfo::Ptr modInfo, const MOShared::DirectoryEntry *directory, bool unmanaged, OrganizerCore *organizerCore, PluginContainer *pluginContainer, QWidget *parent = 0); + ~ModInfoDialog(); /** diff --git a/src/modinfowithconflictinfo.cpp b/src/modinfowithconflictinfo.cpp index 79896cc3..12cbf416 100644 --- a/src/modinfowithconflictinfo.cpp +++ b/src/modinfowithconflictinfo.cpp @@ -35,7 +35,7 @@ std::vector ModInfoWithConflictInfo::getFlags() const switch (isLooseArchiveConflicted()) { case CONFLICT_MIXED: { result.push_back(ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITE); - result.push_back(ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITTEN); + result.push_back(ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITTEN); } break; case CONFLICT_OVERWRITE: { result.push_back(ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITE); diff --git a/src/modlist.cpp b/src/modlist.cpp index 8c070667..757fedb2 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -159,7 +159,6 @@ QString ModList::getFlagText(ModInfo::EFlag flag, ModInfo::Ptr modInfo) const return output.join("
"); } case ModInfo::FLAG_CONFLICT_OVERWRITE: return tr("Overwrites loose files"); - case ModInfo::FLAG_CONFLICT_LOOSE_OVERWRITE_ARCHIVE: return tr("Loose files overwrite another archive"); case ModInfo::FLAG_CONFLICT_OVERWRITTEN: return tr("Overwritten loose files"); case ModInfo::FLAG_CONFLICT_MIXED: return tr("Loose files Overwrites & Overwritten"); case ModInfo::FLAG_CONFLICT_REDUNDANT: return tr("Redundant"); @@ -420,13 +419,13 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const (archiveLooseOverwrite && (overwritten || archiveOverwritten)) || (archiveLooseOverwritten && (overwrite || archiveLooseOverwrite)) ) { - return QColor(255, 0, 255, 32); //TODO: Make configurable - } else if (overwrite || archiveOverwrite || archiveLooseOverwrite) { return Settings::instance().modlistOverwrittenLooseColor(); } - } else if (overwritten || archiveOverwritten || archiveLooseOverwritten) { + else if (overwrite || archiveOverwrite || archiveLooseOverwrite) { return Settings::instance().modlistOverwritingLooseColor(); - } else if (modInfo->hasFlag(ModInfo::FLAG_SEPARATOR) + } else if (overwritten || archiveOverwritten || archiveLooseOverwritten) { + return QColor(255, 0, 0, 64); //TODO: Make configurable + } else if (modInfo->hasFlag(ModInfo::FLAG_SEPARATOR) && modInfo->getColor().isValid() && ((role != ViewMarkingScrollBar::DEFAULT_ROLE) || Settings::instance().colorSeparatorScrollbar())) { @@ -789,14 +788,7 @@ void ModList::setArchiveLooseOverwriteMarkers(const std::set &over void ModList::setPluginContainer(PluginContainer *pluginContianer) { - m_PluginContainer = pluginContianer; -} - -void ModList::setArchiveOverwriteMarkers(const std::set &overwrite, const std::set &overwritten) -{ - m_ArchiveOverwrite = overwrite; - m_ArchiveOverwritten = overwritten; - notifyChange(0, rowCount() - 1); + m_PluginContainer = pluginContianer; } bool ModList::modInfoAboutToChange(ModInfo::Ptr info) diff --git a/src/modlist.h b/src/modlist.h index a8263a76..49627d68 100644 --- a/src/modlist.h +++ b/src/modlist.h @@ -115,8 +115,6 @@ public: void setArchiveOverwriteMarkers(const std::set &overwrite, const std::set &overwritten); void setArchiveLooseOverwriteMarkers(const std::set &overwrite, const std::set &overwritten); - void setArchiveOverwriteMarkers(const std::set &overwrite, const std::set &overwritten); - bool modInfoAboutToChange(ModInfo::Ptr info); void modInfoChanged(ModInfo::Ptr info); diff --git a/src/organizer_en.ts b/src/organizer_en.ts index 44a386d6..550f7d5c 100644 --- a/src/organizer_en.ts +++ b/src/organizer_en.ts @@ -279,12 +279,12 @@ p, li { white-space: pre-wrap; } DirectoryRefresher - + failed to parse bsa %1: %2 - + failed to read mod (%1): %2 @@ -1620,7 +1620,7 @@ p, li { white-space: pre-wrap; } - + Create Backup @@ -1657,7 +1657,7 @@ p, li { white-space: pre-wrap; } - + Namefilter @@ -1783,9 +1783,9 @@ p, li { white-space: pre-wrap; } - - - + + + Refresh @@ -1805,23 +1805,34 @@ p, li { white-space: pre-wrap; } - - - Filter the above list so that only conflicts are displayed. + + + Filters the above list so that only conflicts are displayed. - + Show only conflicts - + + + Filters the above list so that files from archives are not shown + + + + + Show files from Archives + + + + 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"> p, li { white-space: pre-wrap; } @@ -1832,160 +1843,160 @@ p, li { white-space: pre-wrap; } - + Downloads - + Refresh downloads view - + This is a list of mods you downloaded from Nexus. Double click one to install it. You can also drag an archive into here. - + Show Hidden - + Tool Bar - + Install Mod - + Install &Mod - + Install a new mod from an archive - + Ctrl+M - + Profiles - + &Profiles - + Configure Profiles - + Ctrl+P - + Executables - + &Executables - + Configure the executables that can be started through Mod Organizer - + Ctrl+E - - + + Tools - + &Tools - + Ctrl+I - + Settings - + &Settings - + Configure settings and workarounds - + Ctrl+S - + Nexus - + Search nexus network for more mods - + Ctrl+N - - + + Update - + Mod Organizer is up-to-date - - + + 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! @@ -1993,830 +2004,830 @@ Right now this has very limited functionality - - + + Help - + Ctrl+H - + Endorse MO - - + + Endorse Mod Organizer - + Copy Log to Clipboard - + Change Game - + Open the Instance selection dialog to manage a different Game - + Toolbar - + Desktop - + Start Menu - + There is no supported sort mechanism for this game. You will probably have to use a third-party tool. - + Problems - + There are potential problems with your setup - + Everything seems to be in order - + Help on UI - + Documentation Wiki - + Report Issue - + Tutorials - + About - + About Qt - + Name - + 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? - + Plugin "%1" failed: %2 - + Plugin "%1" failed - + Browse Mod Page - + Also in: <br> - + No conflict - + <Edit...> - + This bsa is enabled in the ini file so it may be required! - + Activating Network Proxy - + Notice: Your current MO version (%1) is lower than the previous version (%2).<br>The GUI may not downgrade gracefully, so you may experience oddities.<br>However, there should be no serious issues. - + 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? - + failed to spawn notepad.exe: %1 - + failed to change origin name: %1 - + failed to move "%1" from mod "%2" to "%3": %4 - + <Contains %1> - + <Checked> - + <Unchecked> - + <Update> - + <Mod Backup> - + <Managed by MO> - + <Managed outside MO> - + <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" - - - - + + + + Confirm - + 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. - + Failed to create backup. - + You need to be logged in with Nexus to resume a download - - + + You need to be logged in with Nexus to endorse - + Failed to display overwrite dialog: %1 - + Nexus ID for this Mod is unknown - + Web page for this mod is unknown - - - + + + Create Mod... - + This will create an empty mod. Please enter a name: - - + + A mod with this name already exists - + Create Separator... - + This will create a new separator. Please enter a name: - + A separator with this name already exists - + This will move all files from overwrite into a new, regular mod. Please enter a name: - - + + Are you sure? - + About to recursively delete: - + Not logged in, endorsement information will be wrong - + 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? - + Export to csv - + CSV (Comma Separated Values) is a format that can be imported in programs like Excel to create a spreadsheet. You can also use online editors and converters instead. - + Select what mods you want export: - + All installed mods - + Only active (checked) mods from your current profile - + All currently visible mods in the mod list - + Choose what Columns to export: - + Mod_Priority - + Mod_Name - + Mod_Status - + Primary_Category - + Nexus_ID - + Mod_Nexus_URL - + Mod_Version - + Install_Date - + Download_File_Name - + export failed: %1 - + Open Game folder - + Open MyGames folder - + Open Instance folder - + Open Mods folder - + Open Profile folder - + Open Downloads folder - + Open MO2 Install folder - + Open MO2 Plugins folder - + Open MO2 Logs folder - + Install Mod... - + Create empty mod - + Create Separator - + Enable all visible - + Disable all visible - + Check all for update - + Export to csv... - - + + Send to - - + + Top - - + + Bottom - - + + Priority... - + Separator... - + All Mods - + Sync to Mods... - + Clear Overwrite... - - + + Open in Explorer - + Restore Backup - + Remove Backup... - - + + Change Categories - - + + Primary Category - + Rename Separator... - + Remove Separator... - + Select Color... - + Reset Color - + Change versioning scheme - + Un-ignore update - + Ignore update - - + + Enable selected - - + + Disable selected - + Rename Mod... - + Reinstall Mod - + Remove Mod... - + Un-Endorse - - + + Endorse - + Won't endorse - + Endorsement state unknown - + Ignore missing data - + Mark as converted/working - + Visit on Nexus - + Visit web page - + Information... - - + + Exception: - - + + Unknown exception - + <All> - + <Multiple> - + %1 more - + Are you sure you want to remove the following %n save(s)?<br><ul>%1</ul><br>Removed saves will be sent to the Recycle Bin. @@ -2824,12 +2835,12 @@ You can also use online editors and converters instead. - + Enable Mods... - + Delete %n save(s) @@ -2837,22 +2848,22 @@ You can also use online editors and converters instead. - + failed to remove %1 - + failed to create %1 - + Restarting MO - + Changing the managed game directory requires restarting MO. Any pending downloads will be paused. @@ -2860,335 +2871,335 @@ Click OK to restart MO now. - + Can't change download directory while downloads are in progress! - + failed to write to file %1 - + %1 written - + 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? - - + + Set Priority - + Set the priority of the selected plugins - + 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? - + Thank you! - + Thank you for your endorsement! - + Request to Nexus failed: %1 - - + + failed to read %1: %2 - - + + Error - + failed to extract %1 (errorcode %2) - + Extract BSA - + This archive contains invalid hashes. Some files may be broken. - + Extract... - + This will restart MO, continue? - + Edit Categories... - + Deselect filter - + Remove - + Enable all - + Disable all - + Unlock load order - + Lock load order - + Open Origin in Explorer - + Open Origin Info... - + depends on missing "%1" - + incompatible with "%1" - + Please wait while LOOT is running - + loot failed. Exit code was: %1 - + failed to start loot - + failed to run loot: %1 - + Errors occured - + Backup of load order created - + Choose backup to restore - + No Backups - + There are no backups to restore - - + + Restore failed - - + + Failed to restore the backup. Errorcode: %1 - + Backup of modlist created - + A file with the same name has already been downloaded. What would you like to do? - + Overwrite - + Rename new file - + Ignore file - + Set the priority of the selected mods @@ -3649,243 +3660,243 @@ p, li { white-space: pre-wrap; } - - + + Save changes? - - + + Save changes to "%1"? - + File Exists - + A file with that name exists, please enter a new one - + failed to move file - + failed to create directory "optional" - - + + Info requested, please wait - + Main - + Update - + Optional - + Old - + Misc - + Unknown - + Current Version: %1 - + No update available - + (description incomplete, please visit nexus) - + <a href="%1">Visit on Nexus</a> - + Failed to delete %1 - - - - + + + + Confirm - - + + Are sure you want to delete "%1"? - - + + Are sure you want to delete the selected files? - - + + New Folder - + Failed to create "%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 rename %1 to %2 - + There already is a visible version of this file. Replace it? - + Select binary - + Binary - + file not found: %1 - + failed to generate preview for %1 - + Sorry - + Sorry, can't preview anything. This function currently does not support extracting from bsas. - + Un-Hide - + Hide - - + + Open/Execute - - + + Preview - + Name - + Please enter a name - - + + Error - + Invalid name. Must be a valid file name - + A tweak by that name exists - + Create Tweak @@ -4037,182 +4048,197 @@ p, li { white-space: pre-wrap; } - Overwrites files + Overwrites loose files - Overwritten files + Loose files overwrite another archive - Overwrites & Overwritten + Overwritten loose files - Redundant + Loose files Overwrites & Overwritten - Alternate game source + Redundant - - Non-MO + + Overwrites an archive with loose files - - invalid + + Archive is overwritten by loose files - - installed version: "%1", newest version: "%2" + + Overwrites another archive file - - The newest version on Nexus seems to be older than the one you have installed. This could either mean the version you have has been withdrawn (i.e. due to a bug) or the author uses a non-standard versioning scheme and that newest version is actually newer. Either way you may want to "upgrade". + + Overwritten by another archive file - - Categories: <br> + + Archive files overwrites & overwritten + + + + + Alternate game source + + + + + Non-MO - + + invalid + + + + Invalid name - + Name is already in use by another mod - + drag&drop failed: %1 - + Confirm - + Are you sure you want to remove "%1"? - + Flags - + Content - + Mod Name - + Version - + Priority - + Category - + Source Game - + Nexus ID - + Installation - + Notes - - + + 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. - + Category of the mod. - + The source game which was the origin of this mod. - + Id of the mod as used on Nexus. - + Emblemes to highlight things that might require attention. - + Depicts the content of the mod:<br><table cellspacing=7><tr><td><img src=":/MO/gui/content/plugin" width=32/></td><td>Game plugins (esp/esm/esl)</td></tr><tr><td><img src=":/MO/gui/content/interface" width=32/></td><td>Interface</td></tr><tr><td><img src=":/MO/gui/content/mesh" width=32/></td><td>Meshes</td></tr><tr><td><img src=":/MO/gui/content/bsa" width=32/></td><td>BSA</td></tr><tr><td><img src=":/MO/gui/content/texture" width=32/></td><td>Textures</td></tr><tr><td><img src=":/MO/gui/content/sound" width=32/></td><td>Sounds</td></tr><tr><td><img src=":/MO/gui/content/music" width=32/></td><td>Music</td></tr><tr><td><img src=":/MO/gui/content/string" width=32/></td><td>Strings</td></tr><tr><td><img src=":/MO/gui/content/script" width=32/></td><td>Scripts (Papyrus)</td></tr><tr><td><img src=":/MO/gui/content/skse" width=32/></td><td>Script Extender plugins</td></tr><tr><td><img src=":/MO/gui/content/skyproc" width=32/></td><td>SkyProc Patcher</td></tr><tr><td><img src=":/MO/gui/content/menu" width=32/></td><td>Mod Configuration Menu</td></tr><tr><td><img src=":/MO/gui/content/inifile" width=32/></td><td>INI files</td></tr><tr><td><img src=":/MO/gui/content/modgroup" width=32/></td><td>ModGroup files</td></tr></table> - + Time this mod was installed - + User notes about the mod @@ -4220,7 +4246,7 @@ p, li { white-space: pre-wrap; } ModListSortProxy - + Drag&Drop is only supported when sorting by priority @@ -4350,171 +4376,171 @@ p, li { white-space: pre-wrap; } - - + + 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. - + Executable "%1" not found - + Start Steam? - + Steam is required to be running already to correctly start the game. Should MO try to start steam now? - + Error - + Windows Event Log Error - + The Windows Event Log service is disabled and/or not running. This prevents USVFS from running properly. Your mods may not be working in the executable that you are launching. Note that you may have to restart MO and/or your PC after the service is fixed. Continue launching %1? - + Blacklisted Executable - + The executable you are attempted to launch is blacklisted in the virtual file system. This will likely prevent the executable, and any executables that are launched by this one, from seeing any mods. This could extend to INI files, save games and any other virtualized files. Continue launching %1? - + No profile set - + Failed to refresh list of esps: %1 - + Multiple esps/esls activated, please check that they don't conflict. - + Download? - + A download has been started but no installed page plugin recognizes it. If you download anyway no information (i.e. version) will be associated with the download. Continue? - + failed to update mod list: %1 - - + + login successful - + Login failed - + Login failed, try again? - + login failed: %1. Download will not be associated with an account - + login failed: %1 - + login failed: %1. You need to log-in with Nexus to update MO. - + MO1 "Script Extender" load mechanism has left hook.dll in your game folder - - + + Description missing - + <a href="%1">hook.dll</a> has been found in your game folder (right click to copy the full path). This is most likely a leftover of setting the ModOrganizer 1 load mechanism to "Script Extender", in which case you must remove this file either by changing the load mechanism in ModOrganizer 1 or manually removing the file, otherwise the game is likely to crash and burn. - + failed to save load order: %1 - + The designated write target "%1" is not enabled. @@ -4661,94 +4687,94 @@ Continue? - + 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 - - + + <b>Origin</b>: %1 - + <br><b><i>This plugin can't be disabled (enforced by the game).</i></b> - + Author - + Description - + Missing Masters - + Enabled Masters - + Loads Archives - + There are Archives connected to this plugin. Their assets will be added to your game, overwriting in case of conflicts following the plugin order. Loose files will always overwrite assets from Archives. (This flag only checks for Archives from the same mod as the plugin) - + Loads INI settings - + There is an ini file connected to this plugin. Its settings will be added to your game settings, overwriting in case of conflicts. - + This ESP is flagged as an ESL. It will adhere to the ESP load order but the records will be loaded in ESL space. - + failed to restore load order for %1 @@ -5490,7 +5516,7 @@ If the folder was still in use, restart MO and try again. - + Mod Organizer @@ -5505,18 +5531,18 @@ If the folder was still in use, restart MO and try again. - + Please use "Help" from the toolbar to get usage instructions to all elements - - + + <Manage...> - + failed to parse profile %1: %2 @@ -5552,12 +5578,12 @@ If the folder was still in use, restart MO and try again. - + failed to access %1 - + failed to set file time %1 @@ -5567,12 +5593,12 @@ If the folder was still in use, restart MO and try again. - + Script Extender - + Proxy DLL @@ -5763,12 +5789,12 @@ Select Show Details option to see the full change-log. - + Failed to start %1: %2 - + Error @@ -5786,28 +5812,28 @@ Select Show Details option to see the full change-log. - - + + attempt to store setting for unknown plugin "%1" - + Error - + Failed to create "%1", you may not have the necessary permission. path remains unchanged. - + Restart Mod Organizer? - + In order to reset the window geometries, MO must be restarted. Restart it now? @@ -6351,75 +6377,90 @@ programs you are intentionally running. + Enable parsing of Archives Archives, has effects on perfromance. + + + - Resets the window geometries for all windows. This can be useful if a window becomes too small or too large, if a column becomes too thin or too wide, and in similar situations. + + By default Mod Organizer will parse Archive files to calculate conflicts between themselves and loose files, this process has a noticeable cost in performance. + This feature should not be confused from the one offered by ModOrganizer 1, ModOrganizer 2 will only show conflicts with archives NOT load them into the game or program. + + If you disable this feature, MO will only display conflicts with Loose files. + - - Reset Window Geometries + + Enable parsing of Archives - - These are workarounds for problems with Mod Organizer. Please make sure you read the help text before changing anything here. + + + Resets the window geometries for all windows. This can be useful if a window becomes too small or too large, if a column becomes too thin or too wide, and in similar situations. - - Diagnostics + + Reset Window Geometries - - Log Level + + These are workarounds for problems with Mod Organizer. Please make sure you read the help text before changing anything here. - - Decides the amount of data printed to "ModOrganizer.log" + + Diagnostics - - - 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. - + + Max Dumps To Keep - - Debug + + Maximum number of crash dumps to keep on disk. Use 0 for unlimited. - - Info (recommended) + + + Maximum number of crash dumps to keep on disk. Use 0 for unlimited. + Set "Crash Dumps" above to None to disable crash dump collection. + - - Warning + + Hint: right click link and copy link location - - Error + + + Logs and crash dumps are stored under your current instance in the <a href="LOGS_FULL_PATH">LOGS_DIR</a> + and <a href="DUMPS_FULL_PATH">DUMPS_DIR</a> folders. + Sending logs and/or crash dumps to the developers can help investigate issues. + It is recommended to compress large log and dmp files before sending. + - + Crash Dumps - + Decides which type of crash dumps are collected when injected processes crash. - + Decides which type of crash dumps are collected when injected processes crash. "None" Disables the generation of crash dumps by MO. @@ -6430,56 +6471,61 @@ programs you are intentionally running. - + None - + Mini (recommended) - + Data - + Full - - Max Dumps To Keep + + Log Level - - Maximum number of crash dumps to keep on disk. Use 0 for unlimited. + + Decides the amount of data printed to "ModOrganizer.log" - + - Maximum number of crash dumps to keep on disk. Use 0 for unlimited. - Set "Crash Dumps" above to None to disable crash dump collection. + 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. - - Hint: right click link and copy link location + + Debug - - - Logs and crash dumps are stored under your current instance in the <a href="LOGS_FULL_PATH">LOGS_DIR</a> - and <a href="DUMPS_FULL_PATH">DUMPS_DIR</a> folders. - Sending logs and/or crash dumps to the developers can help investigate issues. - It is recommended to compress large log and dmp files before sending. - + + Info (recommended) + + + + + Warning + + + + + Error diff --git a/src/organizercore.cpp b/src/organizercore.cpp index d21fa844..acce25dc 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -788,12 +788,12 @@ std::wstring OrganizerCore::crashDumpsPath() { bool OrganizerCore::getArchiveParsing() const { - return m_ArchiveParsing; + return m_ArchiveParsing; } void OrganizerCore::setArchiveParsing(const bool archiveParsing) { - m_ArchiveParsing = archiveParsing; + m_ArchiveParsing = archiveParsing; } void OrganizerCore::setCurrentProfile(const QString &profileName) @@ -1936,13 +1936,13 @@ std::vector OrganizerCore::enabledArchives() { std::vector result; if (m_ArchiveParsing) { - QFile archiveFile(m_CurrentProfile->getArchivesFileName()); - if (archiveFile.open(QIODevice::ReadOnly)) { - while (!archiveFile.atEnd()) { - result.push_back(QString::fromUtf8(archiveFile.readLine()).trimmed()); - } - archiveFile.close(); - } + QFile archiveFile(m_CurrentProfile->getArchivesFileName()); + if (archiveFile.open(QIODevice::ReadOnly)) { + while (!archiveFile.atEnd()) { + result.push_back(QString::fromUtf8(archiveFile.readLine()).trimmed()); + } + archiveFile.close(); + } } return result; } diff --git a/src/settings.cpp b/src/settings.cpp index eb5b372f..74c95ebf 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -476,7 +476,7 @@ uint Settings::getMotDHash() const bool Settings::archiveParsing() const { - return m_Settings.value("Settings/archive_parsing", true).toBool(); + return m_Settings.value("Settings/archive_parsing", true).toBool(); } QVariant Settings::pluginSetting(const QString &pluginName, const QString &key) const @@ -1126,7 +1126,7 @@ Settings::WorkaroundsTab::WorkaroundsTab(Settings *m_parent, m_displayForeignBox->setChecked(m_parent->displayForeign()); m_lockGUIBox->setChecked(m_parent->lockGUI()); m_enableArchiveParsingBox->setChecked(m_parent->archiveParsing()); - + m_dialog.setExecutableBlacklist(m_parent->executablesBlacklist()); } -- cgit v1.3.1 From b525ee392f9f79f8e4bde899778f19a0a1a240eb Mon Sep 17 00:00:00 2001 From: Project579 Date: Sun, 30 Dec 2018 11:07:56 +0100 Subject: Updated translation file --- src/organizer_en.ts | 1434 ++++++++++++++++++++++++++++----------------------- 1 file changed, 786 insertions(+), 648 deletions(-) (limited to 'src') diff --git a/src/organizer_en.ts b/src/organizer_en.ts index 550f7d5c..dad42fee 100644 --- a/src/organizer_en.ts +++ b/src/organizer_en.ts @@ -1386,58 +1386,58 @@ p, li { white-space: pre-wrap; } - + File format "%1" not supported - + None of the available installer plugins were able to handle that archive. This is likely due to a corrupted or incompatible download or unrecognized archive format. - + no error - + 7z.dll not found - + 7z.dll isn't valid - + archive not found - + failed to open archive - + unsupported archive type - + internal library error - + archive invalid - + unknown archive error @@ -1512,17 +1512,17 @@ This is likely due to a corrupted or incompatible download or unrecognized archi - + failed to write to %1 - + file not found: %1 - + Save @@ -1547,7 +1547,7 @@ This is likely due to a corrupted or incompatible download or unrecognized archi MainWindow - + Categories @@ -1613,61 +1613,68 @@ p, li { white-space: pre-wrap; } - + Restore Backup... - - + + Create Backup - + + + Active: + + + + + This provides statistics about the mod list. The total number of active mod is normally displayed. Other statistics may be accessed with the tooltip of this counter. + + + + 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. - + + + + Filter - + Clear all Filters - + No groups - + 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"> p, li { white-space: pre-wrap; } @@ -1677,12 +1684,12 @@ p, li { white-space: pre-wrap; } - + 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"> p, li { white-space: pre-wrap; } @@ -1691,17 +1698,17 @@ p, li { white-space: pre-wrap; } - + 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"> p, li { white-space: pre-wrap; } @@ -1710,27 +1717,32 @@ p, li { white-space: pre-wrap; } - + Shortcut - + Plugins - + Sort - + + This provides statistics about the plugin list. The total number of active plugins is normally displayed. Other statistics may be accessed with the tooltip of this counter. + + + + List of available esp/esm files - + <!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; } @@ -1739,27 +1751,27 @@ p, li { white-space: pre-wrap; } - + Archives - + <html><head/><body><p>BSAs / BA2s are bundles of game assets (textures, scripts, etc.). By default, the engine loads these bundles in a separate step from loose files. <p>Their load order is specified by the priority of the corresponding plugin (right pane, plugins tab).</p><p>If there is a matching plugin, the game will load them no matter what.</p></body></html> - + <html><head/><body><p>Currently detected archives. (<a href="#"><span style=" text-decoration: underline; color:#0000ff;">What is an archive?</span></a>)</p></body></html> - + List of available BS Archives. Archives not checked here are not managed by MO and ignore installation order. - + 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! @@ -1767,236 +1779,236 @@ p, li { white-space: pre-wrap; } - + Data - + refresh data-directory overview - + Refresh the overview. This may take a moment. - - - - + + + + Refresh - + This is an overview of your data directory as visible to the game (and tools). - + File - + Mod - - + + Filters the above list so that only conflicts are displayed. - + Show only conflicts - - + + Filters the above list so that files from archives are not shown - + Show files from Archives - + 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"> 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=" 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 save games 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> - + Downloads - + Refresh downloads view - + This is a list of mods you downloaded from Nexus. Double click one to install it. You can also drag an archive into here. - + Show Hidden - + Tool Bar - + Install Mod - + Install &Mod - + Install a new mod from an archive - + Ctrl+M - + Profiles - + &Profiles - + Configure Profiles - + Ctrl+P - + Executables - + &Executables - + Configure the executables that can be started through Mod Organizer - + Ctrl+E - - + + Tools - + &Tools - + Ctrl+I - + Settings - + &Settings - + Configure settings and workarounds - + Ctrl+S - + Nexus - + Search nexus network for more mods - + Ctrl+N - - + + Update - + Mod Organizer is up-to-date - - + + 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! @@ -2004,830 +2016,887 @@ Right now this has very limited functionality - - + + Help - + Ctrl+H - + Endorse MO - - + + Endorse Mod Organizer - + Copy Log to Clipboard - + Change Game - + Open the Instance selection dialog to manage a different Game - + Toolbar - + Desktop - + Start Menu - + There is no supported sort mechanism for this game. You will probably have to use a third-party tool. - + + Crash on exit + + + + + MO crashed while exiting. Some settings may not be saved. + +Error: %1 + + + + Problems - + There are potential problems with your setup - + Everything seems to be in order - + + Won't Endorse + + + + Help on UI - + Documentation Wiki - + Report Issue - + Tutorials - + About - + About Qt - + Name - + 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? - + Plugin "%1" failed: %2 - + Plugin "%1" failed - + Browse Mod Page - + Also in: <br> - + No conflict - + <Edit...> - + This bsa is enabled in the ini file so it may be required! - + Activating Network Proxy - + Notice: Your current MO version (%1) is lower than the previous version (%2).<br>The GUI may not downgrade gracefully, so you may experience oddities.<br>However, there should be no serious issues. - + 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? - + failed to spawn notepad.exe: %1 - + failed to change origin name: %1 - + failed to move "%1" from mod "%2" to "%3": %4 - + <Contains %1> - + <Checked> - + <Unchecked> - + <Update> - + <Mod Backup> - + <Managed by MO> - + <Managed outside MO> - + <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" - - - - + + + + Confirm - + 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. - + Failed to create backup. - + You need to be logged in with Nexus to resume a download - - + + + + You need to be logged in with Nexus to endorse - + + + Endorsing multiple mods will take a while. Please wait... + + + + + + Unendorsing multiple mods will take a while. Please wait... + + + + Failed to display overwrite dialog: %1 - + + Opening Nexus Links + + + + + You are trying to open %1 links to Nexus Mods. Are you sure you want to do this? + + + + Nexus ID for this Mod is unknown - + Web page for this mod is unknown - - - + + <table cellspacing="5"><tr><th>Type</th><th>All</th><th>Visible</th><tr><td>Enabled mods:&emsp;</td><td align=right>%1 / %2</td><td align=right>%3 / %4</td></tr><tr><td>Unmanaged/DLCs:&emsp;</td><td align=right>%5</td><td align=right>%6</td></tr><tr><td>Mod backups:&emsp;</td><td align=right>%7</td><td align=right>%8</td></tr><tr><td>Separators:&emsp;</td><td align=right>%9</td><td align=right>%10</td></tr></table> + + + + + <table cellspacing="4"><tr><th>Type</th><th>Active</th><th>Total</th></tr><tr><td>Active plugins:</td><td align=right>%1</td><td align=right>%2</td></tr><tr><td>Active ESMs:</td><td align=right>%3</td><td align=right>%4</td></tr><tr><td>Active ESPs:</td><td align=right>%7</td><td align=right>%8</td></tr><tr><td>Active ESMs+ESPs:</td><td align=right>%9</td><td align=right>%10</td></tr><tr><td>Active ESLs:</td><td align=right>%5</td><td align=right>%6</td></tr></table> + + + + + + Create Mod... - + This will create an empty mod. Please enter a name: - - + + A mod with this name already exists - + Create Separator... - + This will create a new separator. Please enter a name: - + A separator with this name already exists - + This will move all files from overwrite into a new, regular mod. Please enter a name: - - + + Are you sure? - + About to recursively delete: - + Not logged in, endorsement information will be wrong - + 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? - + Export to csv - + CSV (Comma Separated Values) is a format that can be imported in programs like Excel to create a spreadsheet. You can also use online editors and converters instead. - + Select what mods you want export: - + All installed mods - + Only active (checked) mods from your current profile - + All currently visible mods in the mod list - + Choose what Columns to export: - + Mod_Priority - + Mod_Name - + Mod_Status - + Primary_Category - + Nexus_ID - + Mod_Nexus_URL - + Mod_Version - + Install_Date - + Download_File_Name - + export failed: %1 - + Open Game folder - + Open MyGames folder - + + Open INIs folder + + + + Open Instance folder - + Open Mods folder - + Open Profile folder - + Open Downloads folder - + Open MO2 Install folder - + Open MO2 Plugins folder - + Open MO2 Logs folder - + Install Mod... - + Create empty mod - + Create Separator - + Enable all visible - + Disable all visible - + Check all for update - + Export to csv... - - + + Send to - - + + Top - - + + Bottom - - + + Priority... - + Separator... - + All Mods - + Sync to Mods... - + Clear Overwrite... - - + + Open in Explorer - + Restore Backup - + Remove Backup... - - + + Change Categories - - + + Primary Category - + Rename Separator... - + Remove Separator... - + Select Color... - + Reset Color - + Change versioning scheme - + Un-ignore update - + Ignore update - - + + Enable selected - - + + Disable selected - + Rename Mod... - + Reinstall Mod - + Remove Mod... - + Un-Endorse - - + + + Endorse - + Won't endorse - + Endorsement state unknown - + Ignore missing data - + Mark as converted/working - + Visit on Nexus - + Visit web page - + Information... - - + + Exception: - - + + Unknown exception - + <All> - + <Multiple> - + %1 more - + Are you sure you want to remove the following %n save(s)?<br><ul>%1</ul><br>Removed saves will be sent to the Recycle Bin. @@ -2835,12 +2904,12 @@ You can also use online editors and converters instead. - + Enable Mods... - + Delete %n save(s) @@ -2848,22 +2917,22 @@ You can also use online editors and converters instead. - + failed to remove %1 - + failed to create %1 - + Restarting MO - + Changing the managed game directory requires restarting MO. Any pending downloads will be paused. @@ -2871,335 +2940,335 @@ Click OK to restart MO now. - + Can't change download directory while downloads are in progress! - + failed to write to file %1 - + %1 written - + 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? - - + + Set Priority - + Set the priority of the selected plugins - + 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? - + Thank you! - + Thank you for your endorsement! - + Request to Nexus failed: %1 - - + + failed to read %1: %2 - - + + Error - + failed to extract %1 (errorcode %2) - + Extract BSA - + This archive contains invalid hashes. Some files may be broken. - + Extract... - + This will restart MO, continue? - + Edit Categories... - + Deselect filter - + Remove - + Enable all - + Disable all - + Unlock load order - + Lock load order - + Open Origin in Explorer - + Open Origin Info... - + depends on missing "%1" - + incompatible with "%1" - + Please wait while LOOT is running - + loot failed. Exit code was: %1 - + failed to start loot - + failed to run loot: %1 - + Errors occured - + Backup of load order created - + Choose backup to restore - + No Backups - + There are no backups to restore - - + + Restore failed - - + + Failed to restore the backup. Errorcode: %1 - + Backup of modlist created - + A file with the same name has already been downloaded. What would you like to do? - + Overwrite - + Rename new file - + Ignore file - + Set the priority of the selected mods @@ -3630,273 +3699,273 @@ p, li { white-space: pre-wrap; } - + &Delete - + &Rename - + &Hide - + &Unhide - + &Open - + &New Folder - - + + Save changes? - - + + Save changes to "%1"? - + File Exists - + A file with that name exists, please enter a new one - + failed to move file - + failed to create directory "optional" - - + + Info requested, please wait - + Main - + Update - + Optional - + Old - + Misc - + Unknown - + Current Version: %1 - + No update available - + (description incomplete, please visit nexus) - + <a href="%1">Visit on Nexus</a> - + Failed to delete %1 - - - - + + + + Confirm - - + + Are sure you want to delete "%1"? - - + + Are sure you want to delete the selected files? - - + + New Folder - + Failed to create "%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 rename %1 to %2 - + There already is a visible version of this file. Replace it? - + Select binary - + Binary - + file not found: %1 - + failed to generate preview for %1 - + Sorry - + Sorry, can't preview anything. This function currently does not support extracting from bsas. - + Un-Hide - + Hide - - + + Open/Execute - - + + Preview - + Name - + Please enter a name - - + + Error - + Invalid name. Must be a valid file name - + A tweak by that name exists - + Create Tweak @@ -3935,18 +4004,18 @@ p, li { white-space: pre-wrap; } ModInfoRegular - - + + failed to write %1/meta.ini: error %2 - + %1 contains no esp/esm/esl and no asset (textures, meshes, interface, ...) directory - + Categories: <br> @@ -4053,192 +4122,208 @@ p, li { white-space: pre-wrap; } - Loose files overwrite another archive + Overwritten loose files + Loose files overwrite another archive - + Overwritten loose files - + Loose files Overwrites & Overwritten - + Redundant - + Overwrites an archive with loose files - + Archive is overwritten by loose files - + Overwrites another archive file - + Overwritten by another archive file - + Archive files overwrites & overwritten - - Alternate game source + + This mod targets a different game - + Non-MO - + invalid - + + installed version: "%1", newest version: "%2" + + + + + The newest version on Nexus seems to be older than the one you have installed. This could either mean the version you have has been withdrawn (i.e. due to a bug) or the author uses a non-standard versioning scheme and that newest version is actually newer. Either way you may want to "upgrade". + + + + + Categories: <br> + + + + Invalid name - + Name is already in use by another mod - + drag&drop failed: %1 - + Confirm - + Are you sure you want to remove "%1"? - + Flags - + Content - + Mod Name - + Version - + Priority - + Category - + Source Game - + Nexus ID - + Installation - + Notes - - + + 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. - + Category of the mod. - + The source game which was the origin of this mod. - + Id of the mod as used on Nexus. - + Emblemes to highlight things that might require attention. - + Depicts the content of the mod:<br><table cellspacing=7><tr><td><img src=":/MO/gui/content/plugin" width=32/></td><td>Game plugins (esp/esm/esl)</td></tr><tr><td><img src=":/MO/gui/content/interface" width=32/></td><td>Interface</td></tr><tr><td><img src=":/MO/gui/content/mesh" width=32/></td><td>Meshes</td></tr><tr><td><img src=":/MO/gui/content/bsa" width=32/></td><td>BSA</td></tr><tr><td><img src=":/MO/gui/content/texture" width=32/></td><td>Textures</td></tr><tr><td><img src=":/MO/gui/content/sound" width=32/></td><td>Sounds</td></tr><tr><td><img src=":/MO/gui/content/music" width=32/></td><td>Music</td></tr><tr><td><img src=":/MO/gui/content/string" width=32/></td><td>Strings</td></tr><tr><td><img src=":/MO/gui/content/script" width=32/></td><td>Scripts (Papyrus)</td></tr><tr><td><img src=":/MO/gui/content/skse" width=32/></td><td>Script Extender plugins</td></tr><tr><td><img src=":/MO/gui/content/skyproc" width=32/></td><td>SkyProc Patcher</td></tr><tr><td><img src=":/MO/gui/content/menu" width=32/></td><td>Mod Configuration Menu</td></tr><tr><td><img src=":/MO/gui/content/inifile" width=32/></td><td>INI files</td></tr><tr><td><img src=":/MO/gui/content/modgroup" width=32/></td><td>ModGroup files</td></tr></table> - + Time this mod was installed - + User notes about the mod @@ -4246,7 +4331,7 @@ p, li { white-space: pre-wrap; } ModListSortProxy - + Drag&Drop is only supported when sorting by priority @@ -4365,182 +4450,182 @@ p, li { white-space: pre-wrap; } - - + + Download started - + Download failed - - + + 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. - + Executable "%1" not found - + Start Steam? - + Steam is required to be running already to correctly start the game. Should MO try to start steam now? - + Error - + Windows Event Log Error - + The Windows Event Log service is disabled and/or not running. This prevents USVFS from running properly. Your mods may not be working in the executable that you are launching. Note that you may have to restart MO and/or your PC after the service is fixed. Continue launching %1? - + Blacklisted Executable - + The executable you are attempted to launch is blacklisted in the virtual file system. This will likely prevent the executable, and any executables that are launched by this one, from seeing any mods. This could extend to INI files, save games and any other virtualized files. Continue launching %1? - + No profile set - + Failed to refresh list of esps: %1 - + Multiple esps/esls activated, please check that they don't conflict. - + Download? - + A download has been started but no installed page plugin recognizes it. If you download anyway no information (i.e. version) will be associated with the download. Continue? - + failed to update mod list: %1 - - + + login successful - + Login failed - + Login failed, try again? - + login failed: %1. Download will not be associated with an account - + login failed: %1 - + login failed: %1. You need to log-in with Nexus to update MO. - + MO1 "Script Extender" load mechanism has left hook.dll in your game folder - - + + Description missing - + <a href="%1">hook.dll</a> has been found in your game folder (right click to copy the full path). This is most likely a leftover of setting the ModOrganizer 1 load mechanism to "Script Extender", in which case you must remove this file either by changing the load mechanism in ModOrganizer 1 or manually removing the file, otherwise the game is likely to crash and burn. - + failed to save load order: %1 - + The designated write target "%1" is not enabled. @@ -4687,94 +4772,94 @@ Continue? - + 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 - + <b>Origin</b>: %1 - + <br><b><i>This plugin can't be disabled (enforced by the game).</i></b> - + Author - + Description - + Missing Masters - + Enabled Masters - + Loads Archives - + There are Archives connected to this plugin. Their assets will be added to your game, overwriting in case of conflicts following the plugin order. Loose files will always overwrite assets from Archives. (This flag only checks for Archives from the same mod as the plugin) - + Loads INI settings - + There is an ini file connected to this plugin. Its settings will be added to your game settings, overwriting in case of conflicts. - + This ESP is flagged as an ESL. It will adhere to the ESP load order but the records will be loaded in ESL space. - + failed to restore load order for %1 @@ -4782,7 +4867,7 @@ Continue? PluginListSortProxy - + Drag&Drop is only supported when sorting by priority or mod index @@ -4836,12 +4921,12 @@ p, li { white-space: pre-wrap; } Profile - + invalid profile name %1 - + failed to create %1 @@ -4891,12 +4976,34 @@ p, li { white-space: pre-wrap; } - Delete savegames? + Delete profile-specific save games? + 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 the profile-specific save games? (If you select "No", the save games will show up again if you re-enable profile-specific save games) + Do you want to delete local savegames? (If you select "No", the save games will show up again if you re-enable local savegames) + + + + + Missing profile-specific game INI files! + + + + + Some of your profile-specific game INI files were missing. They will now be copied from the vanilla game folder. You might want double-check your settings. + + + + + Delete profile-specific game INI files? + + + + + Do you want to delete the profile-specific game INI files? (If you select "No", the INI files will be used again if you re-enable profile-specific game INI files.) @@ -4953,17 +5060,20 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p>If checked, savegames are stored locally to this profile and will not appear when starting with a different profile.</p></body></html> + <html><head/><body><p>If checked, save games are stored locally to this profile and will not appear when starting with a different profile.</p></body></html> + <html><head/><body><p>If checked, savegames are stored locally to this profile and will not appear when starting with a different profile.</p></body></html> - If checked, savegames are local to this profile and will not appear when starting with a different profile. + If checked, save games are local to this profile and will not appear when starting with a different profile. + If checked, savegames are local to this profile and will not appear when starting with a different profile. - Use profile-specific Savegames + Use profile-specific Save Games + Use profile-specific Savegames @@ -5114,7 +5224,7 @@ p, li { white-space: pre-wrap; } - Are you sure you want to remove this profile (including local savegames if any)? + Are you sure you want to remove this profile (including profile-specific save games, if any)? @@ -5148,13 +5258,32 @@ p, li { white-space: pre-wrap; } + + QApplication + + + INI file is read-only + + + + + + Mod Organizer is attempting to write to "%1" which is currently set to read-only. Clear the read-only flag to allow the write? + + + + + File is read-only + + + QObject - + Error @@ -5254,12 +5383,13 @@ p, li { white-space: pre-wrap; } - + + helper failed - + failed to determine account name @@ -5394,7 +5524,7 @@ If the folder was still in use, restart MO and try again. - + failed to create %1 @@ -5474,7 +5604,7 @@ If the folder was still in use, restart MO and try again. - + Failed to create "%1". Your user account probably lacks permission. @@ -5516,7 +5646,7 @@ If the folder was still in use, restart MO and try again. - + Mod Organizer @@ -5531,18 +5661,18 @@ If the folder was still in use, restart MO and try again. - + Please use "Help" from the toolbar to get usage instructions to all elements - - + + <Manage...> - + failed to parse profile %1: %2 @@ -5578,12 +5708,12 @@ If the folder was still in use, restart MO and try again. - + failed to access %1 - + failed to set file time %1 @@ -5593,37 +5723,39 @@ If the folder was still in use, restart MO and try again. - + Script Extender - + Proxy DLL - + failed to spawn "%1" - + Elevation required - + This process requires elevation to run. This is a potential security risk so I highly advice you to investigate if "%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) +Restart Mod Organizer as an elevated process? +You will be asked if you want to allow helper.exe to make changes to the system. You will need to relaunch the process above manually. - + + failed to spawn "%1": %2 @@ -5812,28 +5944,28 @@ Select Show Details option to see the full change-log. - - + + attempt to store setting for unknown plugin "%1" - + Error - + Failed to create "%1", you may not have the necessary permission. path remains unchanged. - + Restart Mod Organizer? - + In order to reset the window geometries, MO must be restarted. Restart it now? @@ -6102,13 +6234,13 @@ p, li { white-space: pre-wrap; } - + Username - + Password @@ -6123,112 +6255,117 @@ p, li { white-space: pre-wrap; } - + 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) + Endorsement Integration + + + + Associate with "Download with manager" links - + Known Servers (updated on download) - + Preferred Servers (Drag & Drop) - + Steam - + If you save your steam user ID and password here, they will be used when logging into steam. Note, however, your password will be stored unencrypted, so make sure your computer is secure. - + Plugins - + Author: - + Version: - + Description: - + Key - + Value - + Blacklisted Plugins (use <del> to remove): - + Workarounds - + Steam App ID - + The Steam AppID for your 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; } @@ -6244,17 +6381,17 @@ p, li { white-space: pre-wrap; } - + 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. @@ -6265,17 +6402,17 @@ If you use the Steam version of Oblivion the default will NOT work. In this case - + NMM Version - + The Version of Nexus Mod Manager to impersonate. - + 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. @@ -6284,28 +6421,28 @@ tl;dr-version: If Nexus-features don't work, insert the current version num - + If checked, files (i.e. esps, esms and bsas) belonging to the core game can not be disabled in the UI. (default: on) - + 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. - + Force-enable game files - + Disable this to no longer display mods installed outside MO in the mod list (left pane). Assets from those mods will then be treated as having lowest mod priority together with the original game content. - + By default Mod Organizer will display esp+bsa bundles installed with foreign tools as mods (left pane). This allows you to control their priority in relation to other mods. This is particularly useful if you also use Steam Workshop to install mods. However, if you installed loose file mods outside MO which conflict with BSAs also installed outside MO those conflicts can't be resolved correctly. @@ -6313,51 +6450,51 @@ If you disable this feature, MO will only display official DLCs this way. Please - + Display mods installed outside MO - + Enforces that inactive ESPs and ESMs are never 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. - + Hide inactive ESPs/ESMs - - + + Disable this to prevent the GUI from being locked when running an executable. This may result in abnormal behavior. - + Lock GUI when running executable - - + + 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! - + Back-date BSAs - + Add executables to the blacklist to prevent them from accessing the virtual file system. This is useful to prevent unintended programs from being hooked. Hooking unintended @@ -6366,22 +6503,22 @@ programs you are intentionally running. - + Add executables to the blacklist to prevent them from accessing the virtual file system. This is useful to prevent unintended programs from being hooked. Hooking unintended programs may affect the execution of these programs or the programs you are intentionally running. - + Configure Executables Blacklist - + Enable parsing of Archives Archives, has effects on perfromance. - + By default Mod Organizer will parse Archive files to calculate conflicts between themselves and loose files, this process has a noticeable cost in performance. This feature should not be confused from the one offered by ModOrganizer 1, ModOrganizer 2 will only show conflicts with archives NOT load them into the game or program. @@ -6391,43 +6528,43 @@ programs you are intentionally running. - + Enable parsing of Archives - - + + Resets the window geometries for all windows. This can be useful if a window becomes too small or too large, if a column becomes too thin or too wide, and in similar situations. - + Reset Window Geometries - + These are workarounds for problems with Mod Organizer. Please make sure you read the help text before changing anything here. - + Diagnostics - + Max Dumps To Keep - + Maximum number of crash dumps to keep on disk. Use 0 for unlimited. - + Maximum number of crash dumps to keep on disk. Use 0 for unlimited. Set "Crash Dumps" above to None to disable crash dump collection. @@ -6435,12 +6572,12 @@ programs you are intentionally running. - + Hint: right click link and copy link location - + Logs and crash dumps are stored under your current instance in the <a href="LOGS_FULL_PATH">LOGS_DIR</a> and <a href="DUMPS_FULL_PATH">DUMPS_DIR</a> folders. @@ -6450,17 +6587,17 @@ programs you are intentionally running. - + Crash Dumps - + Decides which type of crash dumps are collected when injected processes crash. - + Decides which type of crash dumps are collected when injected processes crash. "None" Disables the generation of crash dumps by MO. @@ -6471,37 +6608,37 @@ programs you are intentionally running. - + None - + Mini (recommended) - + Data - + Full - + Log Level - + Decides the amount of data printed to "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. @@ -6509,22 +6646,22 @@ programs you are intentionally running. - + Debug - + Info (recommended) - + Warning - + Error @@ -6707,7 +6844,8 @@ Example: TransferSavesDialog - Transfer Savegames + Transfer Save Games + Transfer Savegames -- cgit v1.3.1 From b842eb1ca377501e6ca2cb387168536f87e1c6d9 Mon Sep 17 00:00:00 2001 From: Project579 Date: Sat, 29 Dec 2018 22:17:00 +0100 Subject: Fix for download list refreshing, courtesy of bshd --- src/downloadlist.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/downloadlist.cpp b/src/downloadlist.cpp index 1e31973d..77c5973b 100644 --- a/src/downloadlist.cpp +++ b/src/downloadlist.cpp @@ -106,8 +106,7 @@ void DownloadList::update(int row) if (row < 0) { emit endResetModel(); } else if (row < this->rowCount()) { -#pragma message("updating only the one column is a hack") - emit dataChanged(this->index(row, 2, QModelIndex()), this->index(row, 2, QModelIndex())); + emit dataChanged(this->index(row, 0, QModelIndex()), this->index(row, this->columnCount(QModelIndex())-1, QModelIndex())); } else { qCritical("invalid row %d in download list, update failed", row); } -- cgit v1.3.1 From 302f9b99d85b0325b3106ca8518fdeb799bfc6a8 Mon Sep 17 00:00:00 2001 From: Project579 Date: Sat, 29 Dec 2018 22:24:05 +0100 Subject: Updated version to reflect changes --- src/version.rc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/version.rc b/src/version.rc index 1061d112..e1f80785 100644 --- a/src/version.rc +++ b/src/version.rc @@ -3,8 +3,8 @@ // If VS_FF_PRERELEASE is not set, MO labels the build as a release and uses VER_FILEVERSION to determine version number. // Otherwise, if letters are used in VER_FILEVERSION_STR, uses the full MOBase::VersionInfo parser // Otherwise, uses the numbers from VER_FILEVERSION and sets the release type as pre-alpha -#define VER_FILEVERSION 2,2,1 -#define VER_FILEVERSION_STR "2.2.1\0" +#define VER_FILEVERSION 2,2,0 +#define VER_FILEVERSION_STR "2.2.0\0" VS_VERSION_INFO VERSIONINFO FILEVERSION VER_FILEVERSION -- cgit v1.3.1 From 71091f679dd1625b96e6d88d781a93fe6f14d210 Mon Sep 17 00:00:00 2001 From: Project579 Date: Sun, 30 Dec 2018 11:21:32 +0100 Subject: Updated translation --- src/organizer_en.ts | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src') diff --git a/src/organizer_en.ts b/src/organizer_en.ts index dad42fee..c91a966b 100644 --- a/src/organizer_en.ts +++ b/src/organizer_en.ts @@ -4126,11 +4126,6 @@ p, li { white-space: pre-wrap; } Loose files overwrite another archive - - - Overwritten loose files - - Loose files Overwrites & Overwritten -- cgit v1.3.1 From 580f45429fca07a4d3cd8daae83b6963ce5de54a Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Sun, 30 Dec 2018 18:52:15 -0600 Subject: Fix conflict colors and make archive conflict colors configurable --- src/modlist.cpp | 29 +++++++++------- src/settings.cpp | 22 ++++++++++++ src/settings.h | 6 ++++ src/settingsdialog.cpp | 56 +++++++++++++++++------------- src/settingsdialog.h | 10 ++++++ src/settingsdialog.ui | 92 +++++++++++++++++++++++++++++--------------------- 6 files changed, 141 insertions(+), 74 deletions(-) (limited to 'src') diff --git a/src/modlist.cpp b/src/modlist.cpp index 0b66a663..44ca6eaf 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -411,21 +411,26 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const bool archiveOverwritten = m_ArchiveOverwritten.find(modIndex) != m_ArchiveOverwritten.end(); bool archiveLooseOverwritten = m_ArchiveLooseOverwritten.find(modIndex) != m_ArchiveLooseOverwritten.end(); if (modInfo->getHighlight() & ModInfo::HIGHLIGHT_PLUGIN) { + return Settings::instance().modlistContainsPluginColor(); - } else if ((overwrite && (archiveOverwritten || archiveLooseOverwritten)) || - (overwritten && (archiveOverwrite || archiveLooseOverwrite)) || - (archiveOverwrite && (overwritten || archiveLooseOverwritten)) || - (archiveOverwritten && (overwrite || archiveLooseOverwrite)) || - (archiveLooseOverwrite && (overwritten || archiveOverwritten)) || - (archiveLooseOverwritten && (overwrite || archiveLooseOverwrite)) - ) { + + } else if (overwritten || archiveLooseOverwritten) { + return Settings::instance().modlistOverwrittenLooseColor(); - } - else if (overwrite || archiveOverwrite || archiveLooseOverwrite) { + + } else if (overwrite || archiveLooseOverwrite) { + return Settings::instance().modlistOverwritingLooseColor(); - } else if (overwritten || archiveOverwritten || archiveLooseOverwritten) { - return QColor(255, 0, 0, 64); //TODO: Make configurable - } else if (modInfo->hasFlag(ModInfo::FLAG_SEPARATOR) + + } else if (archiveOverwritten) { + + return Settings::instance().modlistOverwrittenArchiveColor(); + + } else if (archiveOverwrite) { + + return Settings::instance().modlistOverwritingArchiveColor(); + + } else if (modInfo->hasFlag(ModInfo::FLAG_SEPARATOR) && modInfo->getColor().isValid() && ((role != ViewMarkingScrollBar::DEFAULT_ROLE) || Settings::instance().colorSeparatorScrollbar())) { diff --git a/src/settings.cpp b/src/settings.cpp index 2bad749f..3202dffe 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -391,6 +391,16 @@ QColor Settings::modlistOverwritingLooseColor() const return m_Settings.value("Settings/overwritingLooseFilesColor", QColor(255, 0, 0, 64)).value(); } +QColor Settings::modlistOverwrittenArchiveColor() const +{ + return m_Settings.value("Settings/overwrittenArchiveFilesColor", QColor(0, 255, 255, 64)).value(); +} + +QColor Settings::modlistOverwritingArchiveColor() const +{ + return m_Settings.value("Settings/overwritingArchiveFilesColor", QColor(255, 0, 255, 64)).value(); +} + QColor Settings::modlistContainsPluginColor() const { return m_Settings.value("Settings/containsPluginColor", QColor(0, 0, 255, 64)).value(); @@ -729,6 +739,8 @@ Settings::GeneralTab::GeneralTab(Settings *m_parent, SettingsDialog &m_dialog) , m_usePrereleaseBox(m_dialog.findChild("usePrereleaseBox")) , m_overwritingBtn(m_dialog.findChild("overwritingBtn")) , m_overwrittenBtn(m_dialog.findChild("overwrittenBtn")) + , m_overwritingArchiveBtn(m_dialog.findChild("overwritingArchiveBtn")) + , m_overwrittenArchiveBtn(m_dialog.findChild("overwrittenArchiveBtn")) , m_containsBtn(m_dialog.findChild("containsBtn")) , m_containedBtn(m_dialog.findChild("containedBtn")) , m_colorSeparatorsBox(m_dialog.findChild("colorSeparatorsBox")) @@ -789,6 +801,12 @@ Settings::GeneralTab::GeneralTab(Settings *m_parent, SettingsDialog &m_dialog) m_overwrittenBtn->setStyleSheet(m_dialog.getColoredButtonStyleSheet().arg( m_parent->modlistOverwrittenLooseColor().name()).arg(getIdealTextColor( m_parent->modlistOverwrittenLooseColor()).name())); + m_overwritingArchiveBtn->setStyleSheet(m_dialog.getColoredButtonStyleSheet().arg( + m_parent->modlistOverwritingArchiveColor().name()).arg(getIdealTextColor( + m_parent->modlistOverwritingArchiveColor()).name())); + m_overwrittenArchiveBtn->setStyleSheet(m_dialog.getColoredButtonStyleSheet().arg( + m_parent->modlistOverwrittenArchiveColor().name()).arg(getIdealTextColor( + m_parent->modlistOverwrittenArchiveColor()).name())); m_containsBtn->setStyleSheet(m_dialog.getColoredButtonStyleSheet().arg( m_parent->modlistContainsPluginColor().name()).arg(getIdealTextColor( m_parent->modlistContainsPluginColor()).name())); @@ -798,6 +816,8 @@ Settings::GeneralTab::GeneralTab(Settings *m_parent, SettingsDialog &m_dialog) m_dialog.setOverwritingColor(m_parent->modlistOverwritingLooseColor()); m_dialog.setOverwrittenColor(m_parent->modlistOverwrittenLooseColor()); + m_dialog.setOverwritingArchiveColor(m_parent->modlistOverwritingArchiveColor()); + m_dialog.setOverwrittenArchiveColor(m_parent->modlistOverwrittenArchiveColor()); m_dialog.setContainsColor(m_parent->modlistContainsPluginColor()); m_dialog.setContainedColor(m_parent->pluginListContainedColor()); @@ -825,6 +845,8 @@ void Settings::GeneralTab::update() m_Settings.setValue("Settings/overwritingLooseFilesColor", m_dialog.getOverwritingColor()); m_Settings.setValue("Settings/overwrittenLooseFilesColor", m_dialog.getOverwrittenColor()); + m_Settings.setValue("Settings/overwritingArchiveFilesColor", m_dialog.getOverwritingArchiveColor()); + m_Settings.setValue("Settings/overwrittenArchiveFilesColor", m_dialog.getOverwrittenArchiveColor()); m_Settings.setValue("Settings/containsPluginColor", m_dialog.getContainsColor()); m_Settings.setValue("Settings/containedColor", m_dialog.getContainedColor()); m_Settings.setValue("Settings/compact_downloads", m_compactBox->isChecked()); diff --git a/src/settings.h b/src/settings.h index 4a932da7..f88f9652 100644 --- a/src/settings.h +++ b/src/settings.h @@ -233,6 +233,10 @@ public: QColor modlistOverwritingLooseColor() const; + QColor modlistOverwrittenArchiveColor() const; + + QColor modlistOverwritingArchiveColor() const; + QColor modlistContainsPluginColor() const; QColor pluginListContainedColor() const; @@ -428,6 +432,8 @@ private: QCheckBox *m_usePrereleaseBox; QPushButton *m_overwritingBtn; QPushButton *m_overwrittenBtn; + QPushButton *m_overwritingArchiveBtn; + QPushButton *m_overwrittenArchiveBtn; QPushButton *m_containsBtn; QPushButton *m_containedBtn; QCheckBox *m_colorSeparatorsBox; diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 0d96e63a..75e08afd 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -239,12 +239,6 @@ void SettingsDialog::on_containsBtn_clicked() ui->containsBtn->setStyleSheet(getColoredButtonStyleSheet().arg( result.name()).arg(Settings::getIdealTextColor( result).name())); - - /*ui->containsBtn->setAutoFillBackground(true); - ui->containsBtn->setPalette(QPalette(result)); - QPalette palette = ui->containsBtn->palette(); - palette.setColor(QPalette::Background, result); - ui->containsBtn->setPalette(palette);*/ } } @@ -257,12 +251,6 @@ void SettingsDialog::on_containedBtn_clicked() ui->containedBtn->setStyleSheet(getColoredButtonStyleSheet().arg( result.name()).arg(Settings::getIdealTextColor( result).name())); - - /*ui->containedBtn->setAutoFillBackground(true); - ui->containedBtn->setPalette(QPalette(result)); - QPalette palette = ui->containedBtn->palette(); - palette.setColor(QPalette::Background, result); - ui->containedBtn->setPalette(palette);*/ } } @@ -275,12 +263,6 @@ void SettingsDialog::on_overwrittenBtn_clicked() ui->overwrittenBtn->setStyleSheet(getColoredButtonStyleSheet().arg( result.name()).arg(Settings::getIdealTextColor( result).name())); - - /*ui->overwrittenBtn->setAutoFillBackground(true); - ui->overwrittenBtn->setPalette(QPalette(result)); - QPalette palette = ui->overwrittenBtn->palette(); - palette.setColor(QPalette::Background, result); - ui->overwrittenBtn->setPalette(palette);*/ } } @@ -293,12 +275,30 @@ void SettingsDialog::on_overwritingBtn_clicked() ui->overwritingBtn->setStyleSheet(getColoredButtonStyleSheet().arg( result.name()).arg(Settings::getIdealTextColor( result).name())); + } +} + +void SettingsDialog::on_overwrittenArchiveBtn_clicked() +{ + QColor result = QColorDialog::getColor(m_OverwrittenArchiveColor, this); + if (result.isValid()) { + m_OverwrittenArchiveColor = result; + + ui->overwrittenArchiveBtn->setStyleSheet(getColoredButtonStyleSheet().arg( + result.name()).arg(Settings::getIdealTextColor( + result).name())); + } +} + +void SettingsDialog::on_overwritingArchiveBtn_clicked() +{ + QColor result = QColorDialog::getColor(m_OverwritingArchiveColor, this); + if (result.isValid()) { + m_OverwritingArchiveColor = result; - /*ui->overwritingBtn->setAutoFillBackground(true); - ui->overwritingBtn->setPalette(QPalette(result)); - QPalette palette = ui->overwritingBtn->palette(); - palette.setColor(QPalette::Background, result); - ui->overwritingBtn->setPalette(palette);*/ + ui->overwritingArchiveBtn->setStyleSheet(getColoredButtonStyleSheet().arg( + result.name()).arg(Settings::getIdealTextColor( + result).name())); } } @@ -306,6 +306,8 @@ void SettingsDialog::on_resetColorsBtn_clicked() { m_OverwritingColor = QColor(255, 0, 0, 64); m_OverwrittenColor = QColor(0, 255, 0, 64); + m_OverwritingArchiveColor = QColor(255, 0, 255, 64); + m_OverwrittenArchiveColor = QColor(0, 255, 255, 64); m_ContainsColor = QColor(0, 0, 255, 64); m_ContainedColor = QColor(0, 0, 255, 64); @@ -317,6 +319,14 @@ void SettingsDialog::on_resetColorsBtn_clicked() QColor(0, 255, 0, 64).name()).arg(Settings::getIdealTextColor( QColor(0, 255, 0, 64)).name())); + ui->overwritingArchiveBtn->setStyleSheet(getColoredButtonStyleSheet().arg( + QColor(255, 0, 255, 64).name()).arg(Settings::getIdealTextColor( + QColor(255, 0, 255, 64)).name())); + + ui->overwrittenArchiveBtn->setStyleSheet(getColoredButtonStyleSheet().arg( + QColor(0, 255, 255, 64).name()).arg(Settings::getIdealTextColor( + QColor(0, 255, 255, 64)).name())); + ui->containsBtn->setStyleSheet(getColoredButtonStyleSheet().arg( QColor(0, 0, 255, 64).name()).arg(Settings::getIdealTextColor( QColor(0, 0, 255, 64)).name())); diff --git a/src/settingsdialog.h b/src/settingsdialog.h index f0567d87..e3c7d413 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -67,6 +67,8 @@ public: QColor getOverwritingColor() { return m_OverwritingColor; } QColor getOverwrittenColor() { return m_OverwrittenColor; } + QColor getOverwritingArchiveColor() { return m_OverwritingArchiveColor; } + QColor getOverwrittenArchiveColor() { return m_OverwrittenArchiveColor; } QColor getContainsColor() { return m_ContainsColor; } QColor getContainedColor() { return m_ContainedColor; } QString getExecutableBlacklist() { return m_ExecutableBlacklist; } @@ -74,6 +76,8 @@ public: void setOverwritingColor(QColor col) { m_OverwritingColor = col; } void setOverwrittenColor(QColor col) { m_OverwrittenColor = col; } + void setOverwritingArchiveColor(QColor col) { m_OverwritingArchiveColor = col; } + void setOverwrittenArchiveColor(QColor col) { m_OverwrittenArchiveColor = col; } void setContainsColor(QColor col) { m_ContainsColor = col; } void setContainedColor(QColor col) { m_ContainedColor = col; } void setExecutableBlacklist(QString blacklist) { m_ExecutableBlacklist = blacklist; } @@ -116,6 +120,10 @@ private slots: void on_overwrittenBtn_clicked(); + void on_overwritingArchiveBtn_clicked(); + + void on_overwrittenArchiveBtn_clicked(); + void on_containsBtn_clicked(); void on_containedBtn_clicked(); @@ -140,6 +148,8 @@ private: QColor m_OverwritingColor; QColor m_OverwrittenColor; + QColor m_OverwritingArchiveColor; + QColor m_OverwrittenArchiveColor; QColor m_ContainsColor; QColor m_ContainedColor; diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index 832fa71a..58b2b48f 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -7,7 +7,7 @@ 0 0 586 - 462 + 486
@@ -99,10 +99,26 @@ If you use pre-releases, never contact me directly by e-mail or via private mess Colors + + + + When this is enabled, the color defined for a separator will be shown on the mod list scrollbar at the location of the separator. This can be useful for quick navigation between separator sections or to a specific separator section. + + + When this is enabled, the color defined for a separator will be shown on the mod list scrollbar at the location of the separator. This can be useful for quick navigation between separator sections or to a specific separator section. + + + Show mod list separator colors on the scrollbar + + + true + + + - + - Reset Colors + Plugin is Contained in selected Mod @@ -113,40 +129,38 @@ If you use pre-releases, never contact me directly by e-mail or via private mess
- - + + - Mod Contains selected Plugin + Is overwriting (loose files) - - + + - Plugin is Contained in selected Mod + Reset Colors - - + + - Is overwriting (loose files) + Mod Contains selected Plugin - - - - When this is enabled, the color defined for a separator will be shown on the mod list scrollbar at the location of the separator. This can be useful for quick navigation between separator sections or to a specific separator section. - - - When this is enabled, the color defined for a separator will be shown on the mod list scrollbar at the location of the separator. This can be useful for quick navigation between separator sections or to a specific separator section. - + + - Show mod list separator colors on the scrollbar + Is overwritten (archive files) - - true + + + + + + Is overwriting (archive files) @@ -1114,27 +1128,27 @@ programs you are intentionally running. - - - - Enable parsing of Archives Archives, has effects on perfromance. - - - + + + + Enable parsing of Archives Archives, has effects on perfromance. + + + By default Mod Organizer will parse Archive files to calculate conflicts between themselves and loose files, this process has a noticeable cost in performance. This feature should not be confused from the one offered by ModOrganizer 1, ModOrganizer 2 will only show conflicts with archives NOT load them into the game or program. If you disable this feature, MO will only display conflicts with Loose files. - - - Enable parsing of Archives - - - true - - - + + + Enable parsing of Archives + + + true + + + -- cgit v1.3.1 From ba57657b4f2322b7b980cca5f0e839c4b74e7384 Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Mon, 31 Dec 2018 07:40:44 -0600 Subject: Correct logic of mod conflict color selection --- src/modlist.cpp | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/modlist.cpp b/src/modlist.cpp index 44ca6eaf..fd39654e 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -411,25 +411,15 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const bool archiveOverwritten = m_ArchiveOverwritten.find(modIndex) != m_ArchiveOverwritten.end(); bool archiveLooseOverwritten = m_ArchiveLooseOverwritten.find(modIndex) != m_ArchiveLooseOverwritten.end(); if (modInfo->getHighlight() & ModInfo::HIGHLIGHT_PLUGIN) { - return Settings::instance().modlistContainsPluginColor(); - } else if (overwritten || archiveLooseOverwritten) { - - return Settings::instance().modlistOverwrittenLooseColor(); - - } else if (overwrite || archiveLooseOverwrite) { - return Settings::instance().modlistOverwritingLooseColor(); - + } else if (overwrite || archiveLooseOverwrite) { + return Settings::instance().modlistOverwrittenLooseColor(); } else if (archiveOverwritten) { - - return Settings::instance().modlistOverwrittenArchiveColor(); - - } else if (archiveOverwrite) { - return Settings::instance().modlistOverwritingArchiveColor(); - + } else if (archiveOverwrite) { + return Settings::instance().modlistOverwrittenArchiveColor(); } else if (modInfo->hasFlag(ModInfo::FLAG_SEPARATOR) && modInfo->getColor().isValid() && ((role != ViewMarkingScrollBar::DEFAULT_ROLE) -- cgit v1.3.1 From 858930cb461988adec846bdf96fad6f600b81cd6 Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Tue, 1 Jan 2019 00:57:12 -0600 Subject: Change find_if to remove_if --- src/shared/directoryentry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/shared/directoryentry.cpp b/src/shared/directoryentry.cpp index 602d58c7..9f54e526 100644 --- a/src/shared/directoryentry.cpp +++ b/src/shared/directoryentry.cpp @@ -332,7 +332,7 @@ bool FileEntry::removeOrigin(int origin) return true; } } else { - std::vector>>::iterator newEnd = std::find_if(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair> &i) -> bool { return i.first == origin; }); + auto newEnd = std::remove_if(m_Alternatives.begin(), m_Alternatives.end(), [&](auto &i) -> bool { return i.first == origin; }); if (newEnd != m_Alternatives.end()) m_Alternatives.erase(newEnd, m_Alternatives.end()); } -- cgit v1.3.1 From d8396bfa2cde422c7522b0e6a78b0d5ab2e218ac Mon Sep 17 00:00:00 2001 From: Al Date: Tue, 1 Jan 2019 12:39:35 +0100 Subject: Fixed refresh not clearing overwrite highlighting. --- src/modlist.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/modlist.cpp b/src/modlist.cpp index fd39654e..a0822e49 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -1150,6 +1150,8 @@ void ModList::notifyChange(int rowStart, int rowEnd) m_Overwritten.clear(); m_ArchiveOverwrite.clear(); m_ArchiveOverwritten.clear(); + m_ArchiveLooseOverwrite.clear(); + m_ArchiveLooseOverwritten.clear(); beginResetModel(); endResetModel(); } else { -- cgit v1.3.1 From 2ee3aec6b5f9d429336aa4481e083e6ed86a5401 Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Fri, 18 Jan 2019 15:34:08 -0600 Subject: Fix location of archive parsing setting --- src/settingsdialog.ui | 78 +++++++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index 58b2b48f..82afd8a1 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -1018,20 +1018,20 @@ tl;dr-version: If Nexus-features don't work, insert the current version number o - - + + + + false + - If checked, files (i.e. esps, esms and bsas) belonging to the core game can not be disabled in the UI. (default: on) + Enforces that inactive ESPs and ESMs are never loaded. - 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. + 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. - Force-enable game files - - - true + Hide inactive ESPs/ESMs @@ -1054,20 +1054,20 @@ If you disable this feature, MO will only display official DLCs this way. Please - - - - false - + + - Enforces that inactive ESPs and ESMs are never loaded. + If checked, files (i.e. esps, esms and bsas) belonging to the core game can not be disabled in the UI. (default: on) - 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. + 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. - Hide inactive ESPs/ESMs + Force-enable game files + + + true @@ -1087,6 +1087,27 @@ I don't yet know what the circumstances are, but user reports imply it is in som + + + + Enable parsing of Archives Archives, has effects on perfromance. + + + + By default Mod Organizer will parse Archive files to calculate conflicts between themselves and loose files, this process has a noticeable cost in performance. + This feature should not be confused from the one offered by ModOrganizer 1, ModOrganizer 2 will only show conflicts with archives NOT load them into the game or program. + + If you disable this feature, MO will only display conflicts with Loose files. + + + + Enable parsing of Archives + + + true + + + @@ -1128,27 +1149,6 @@ programs you are intentionally running. - - - - Enable parsing of Archives Archives, has effects on perfromance. - - - - By default Mod Organizer will parse Archive files to calculate conflicts between themselves and loose files, this process has a noticeable cost in performance. - This feature should not be confused from the one offered by ModOrganizer 1, ModOrganizer 2 will only show conflicts with archives NOT load them into the game or program. - - If you disable this feature, MO will only display conflicts with Loose files. - - - - Enable parsing of Archives - - - true - - - -- cgit v1.3.1 From 5b8b2ddac79e9a32655c1dad3475f9943987e62e Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Fri, 18 Jan 2019 15:45:31 -0600 Subject: Edit tooltip and what's this of archive parsing option --- src/settingsdialog.ui | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index 82afd8a1..686a3028 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -1090,15 +1090,10 @@ Uncheck this if you want to use Mod Organizer with total conversions (like Nehri - Enable parsing of Archives Archives, has effects on perfromance. + Enable parsing of Archives. Has negative effects on performance. - - By default Mod Organizer will parse Archive files to calculate conflicts between themselves and loose files, this process has a noticeable cost in performance. - This feature should not be confused from the one offered by ModOrganizer 1, ModOrganizer 2 will only show conflicts with archives NOT load them into the game or program. - - If you disable this feature, MO will only display conflicts with Loose files. - + <html><head/><body><p>By default, MO will parse archive files (BSA, BA2) to calculate conflicts between the contents of the archive files and other loose files. This process has a noticeable cost in performance.</p><p>This feature should not be confused with the archive management feature offered by MO1. MO2 will only show conflicts with archives and will NOT load them into the game or program.</p><p>If you disable this feature, MO will only display conflicts between loose files.</p></body></html> Enable parsing of Archives -- cgit v1.3.1 From a63d12bd0f586576855da9f36018c5844d620064 Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Fri, 18 Jan 2019 17:46:56 -0600 Subject: Cancel the installation progress bar when done to prevent it showing up again --- src/installationmanager.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/installationmanager.cpp b/src/installationmanager.cpp index 50e170d2..6719c84a 100644 --- a/src/installationmanager.cpp +++ b/src/installationmanager.cpp @@ -579,6 +579,7 @@ bool InstallationManager::doInstall(GuessedValue &modName, QString game m_InstallationProgress = new QProgressDialog(m_ParentWidget); ON_BLOCK_EXIT([this] () { + m_InstallationProgress->cancel(); m_InstallationProgress->hide(); m_InstallationProgress->deleteLater(); m_InstallationProgress = nullptr; -- cgit v1.3.1 From 952a9c2dedf63e4b9b182b7dce379c4fe7898355 Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Sat, 19 Jan 2019 15:15:31 -0600 Subject: Fix forced libraries when using shortcuts --- src/organizercore.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/organizercore.cpp b/src/organizercore.cpp index 885afeff..6710f89a 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -1437,7 +1437,7 @@ HANDLE OrganizerCore::runShortcut(const MOShortcut& shortcut) Executable& exe = m_ExecutablesList.find(shortcut.executable()); auto forcedLibaries = m_CurrentProfile->determineForcedLibraries(shortcut.executable()); - if (!m_CurrentProfile->forcedLibrariesEnabled(exe.m_BinaryInfo.fileName())) { + if (!m_CurrentProfile->forcedLibrariesEnabled(shortcut.executable())) { forcedLibaries.clear(); } -- cgit v1.3.1