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.ui | 46 +++++++++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 13 deletions(-) (limited to 'src/mainwindow.ui') 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 + + + + + -- 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/mainwindow.ui') 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/mainwindow.ui') 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 70ddfaadbfdf3999eea0fe50f7cdac3675e5f019 Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Fri, 14 Dec 2018 17:26:37 -0600 Subject: Expand mod list search edit to work on categories, nexus IDs, and notes --- src/mainwindow.cpp | 15 ++++++++++--- src/mainwindow.h | 1 + src/mainwindow.ui | 8 +++---- src/modlistsortproxy.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++----- src/modlistsortproxy.h | 8 +++++++ 5 files changed, 77 insertions(+), 13 deletions(-) (limited to 'src/mainwindow.ui') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 3b7fa917..44381864 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -285,14 +285,17 @@ MainWindow::MainWindow(QSettings &initSettings ui->modList->setItemDelegateForColumn(ModList::COL_FLAGS, new ModFlagIconDelegate(ui->modList)); ui->modList->setItemDelegateForColumn(ModList::COL_CONTENT, contentDelegate); ui->modList->header()->installEventFilter(m_OrganizerCore.modList()); + connect(ui->modList->header(), SIGNAL(sectionResized(int, int, int)), this, SLOT(modListSectionResized(int, int, int))); bool modListAdjusted = registerWidgetState(ui->modList->objectName(), ui->modList->header(), "mod_list_state"); if (modListAdjusted) { // hack: force the resize-signal to be triggered because restoreState doesn't seem to do that - int sectionSize = ui->modList->header()->sectionSize(ModList::COL_CONTENT); - ui->modList->header()->resizeSection(ModList::COL_CONTENT, sectionSize + 1); - ui->modList->header()->resizeSection(ModList::COL_CONTENT, sectionSize); + for (int column = 0; column <= ModList::COL_LASTCOLUMN; ++column) { + int sectionSize = ui->modList->header()->sectionSize(column); + ui->modList->header()->resizeSection(column, sectionSize + 1); + ui->modList->header()->resizeSection(column, sectionSize); + } } else { // hide these columns by default ui->modList->header()->setSectionHidden(ModList::COL_CONTENT, true); @@ -2474,6 +2477,12 @@ void MainWindow::modListSortIndicatorChanged(int, Qt::SortOrder) ui->modList->verticalScrollBar()->repaint(); } +void MainWindow::modListSectionResized(int logicalIndex, int oldSize, int newSize) +{ + bool enabled = (newSize != 0); + qobject_cast(ui->modList->model())->setColumnVisible(logicalIndex, enabled); +} + void MainWindow::removeMod_clicked() { try { diff --git a/src/mainwindow.h b/src/mainwindow.h index e799a64a..f66ea5e7 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -577,6 +577,7 @@ private slots: void modlistSelectionChanged(const QModelIndex ¤t, const QModelIndex &previous); void modListSortIndicatorChanged(int column, Qt::SortOrder order); + void modListSectionResized(int logicalIndex, int oldSize, int newSize); void modlistSelectionsChanged(const QItemSelection ¤t); void esplistSelectionsChanged(const QItemSelection ¤t); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index e42bed27..7e94000d 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -448,7 +448,7 @@ p, li { white-space: pre-wrap; } false
- 20 + 35 true @@ -612,7 +612,7 @@ p, li { white-space: pre-wrap; }
- Namefilter + Filter
@@ -999,7 +999,7 @@ p, li { white-space: pre-wrap; } - Namefilter + Filter
@@ -1338,7 +1338,7 @@ p, li { white-space: pre-wrap; } - Namefilter + Filter diff --git a/src/modlistsortproxy.cpp b/src/modlistsortproxy.cpp index 9adaa511..b5f1ee5c 100644 --- a/src/modlistsortproxy.cpp +++ b/src/modlistsortproxy.cpp @@ -39,10 +39,6 @@ ModListSortProxy::ModListSortProxy(Profile* profile, QObject *parent) , m_FilterActive(false) , m_FilterMode(FILTER_AND) { - m_EnabledColumns.set(ModList::COL_FLAGS); - m_EnabledColumns.set(ModList::COL_NAME); - m_EnabledColumns.set(ModList::COL_VERSION); - m_EnabledColumns.set(ModList::COL_PRIORITY); setDynamicSortFilter(true); // this seems to work without dynamicsortfilter // but I don't know why. This should be necessary } @@ -340,8 +336,53 @@ bool ModListSortProxy::filterMatchesModOr(ModInfo::Ptr info, bool enabled) const bool ModListSortProxy::filterMatchesMod(ModInfo::Ptr info, bool enabled) const { - if (!m_CurrentFilter.isEmpty() && - !info->name().contains(m_CurrentFilter, Qt::CaseInsensitive)) { + bool display = true; + if (!m_CurrentFilter.isEmpty()) { + display = false; + + // Search by name + if (!display && + m_EnabledColumns[ModList::COL_NAME] && + info->name().contains(m_CurrentFilter, Qt::CaseInsensitive)) { + display = true; + } + + // Search by notes + if (!display && + m_EnabledColumns[ModList::COL_NOTES] && + info->comments().contains(m_CurrentFilter, Qt::CaseInsensitive)) { + display = true; + } + + // Search by Nexus ID + if (!display && + m_EnabledColumns[ModList::COL_MODID]) { + bool ok; + int filterID = m_CurrentFilter.toInt(&ok); + if (ok) { + int modID = info->getNexusID(); + while (modID > 0) { + if (modID == filterID) { + display = true; + break; + } + modID = (int)(modID / 10); + } + } + } + + // Search by categories + if (!display && + m_EnabledColumns[ModList::COL_CATEGORY]) { + for (auto category : info->categories()) { + if (category.contains(m_CurrentFilter, Qt::CaseInsensitive)) { + display = true; + break; + } + } + } + } + if (!display) { return false; } @@ -352,6 +393,11 @@ bool ModListSortProxy::filterMatchesMod(ModInfo::Ptr info, bool enabled) const } } +void ModListSortProxy::setColumnVisible(int column, bool visible) +{ + m_EnabledColumns[column] = visible; +} + void ModListSortProxy::setFilterMode(ModListSortProxy::FilterMode mode) { if (m_FilterMode != mode) { diff --git a/src/modlistsortproxy.h b/src/modlistsortproxy.h index b3c01fea..5fe8d9d6 100644 --- a/src/modlistsortproxy.h +++ b/src/modlistsortproxy.h @@ -60,6 +60,7 @@ public: virtual void setSourceModel(QAbstractItemModel *sourceModel) override; + /** * @brief enable all mods visible under the current filter **/ @@ -94,6 +95,13 @@ public: return rowCount(parent) > 0; } + /** + * @brief sets whether a column is visible + * @param column the index of the column + * @param visible the visibility of the column + */ + void setColumnVisible(int column, bool visible); + public slots: void updateFilter(const QString &filter); -- cgit v1.3.1 From d28ddcfbb52394a2a7ac793ad376ea8fd7b514fe Mon Sep 17 00:00:00 2001 From: Al Date: Mon, 24 Dec 2018 17:29:16 +0100 Subject: Added Active Plugins and Active Mods counters --- src/mainwindow.cpp | 12 ++++++++++++ src/mainwindow.h | 1 + src/mainwindow.ui | 22 +++++++++++++++++++++- src/organizercore.cpp | 4 ++++ src/pluginlist.cpp | 1 + 5 files changed, 39 insertions(+), 1 deletion(-) (limited to 'src/mainwindow.ui') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index bb136364..74374c2b 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -458,6 +458,12 @@ MainWindow::MainWindow(QSettings &initSettings // set the name of the widget to the name of the action to allow styling ui->toolBar->widgetForAction(action)->setObjectName(action->objectName()); } + ui->activePluginsCounter->display(m_OrganizerCore.pluginList()->enabledCount()); + ui->activeModsCounter->display((int)m_OrganizerCore.currentProfile()->getActiveMods().size()); + qDebug("Plugin enabledCount: %d", m_OrganizerCore.pluginList()->enabledCount()); + qDebug("Mods enabledCount: %d", (int)m_OrganizerCore.currentProfile()->getActiveMods().size()); + + } @@ -2186,6 +2192,11 @@ void MainWindow::directory_refreshed() statusBar()->hide(); } +void MainWindow::esplist_changed() +{ + ui->activePluginsCounter->display(m_OrganizerCore.pluginList()->enabledCount()); +} + void MainWindow::modorder_changed() { for (unsigned int i = 0; i < m_OrganizerCore.currentProfile()->numMods(); ++i) { @@ -2443,6 +2454,7 @@ void MainWindow::restoreBackup_clicked() void MainWindow::modlistChanged(const QModelIndex&, int) { m_OrganizerCore.currentProfile()->writeModlist(); + ui->activeModsCounter->display((int)m_OrganizerCore.currentProfile()->getActiveMods().size()); } void MainWindow::modlistSelectionChanged(const QModelIndex ¤t, const QModelIndex&) diff --git a/src/mainwindow.h b/src/mainwindow.h index f66ea5e7..61113b8c 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -162,6 +162,7 @@ public slots: void displayColumnSelection(const QPoint &pos); void modorder_changed(); + void esplist_changed(); void refresher_progress(int percent); void directory_refreshed(); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 7e94000d..067cd4d0 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -179,7 +179,7 @@ 2 - + @@ -224,6 +224,16 @@ p, li { white-space: pre-wrap; } + + + + Active: + + + + + + @@ -853,6 +863,16 @@ p, li { white-space: pre-wrap; } + + + + Active: + + + + + + diff --git a/src/organizercore.cpp b/src/organizercore.cpp index d52ef40b..1f4e3434 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -560,6 +560,10 @@ void OrganizerCore::setUserInterface(IUserInterface *userInterface, SLOT(fileMoved(QString, QString, QString))); connect(&m_ModList, SIGNAL(modorder_changed()), widget, SLOT(modorder_changed())); + connect(&m_PluginList, SIGNAL(writePluginsList()), widget, + SLOT(esplist_changed())); + connect(&m_PluginList, SIGNAL(esplist_changed()), widget, + SLOT(esplist_changed())); connect(&m_DownloadManager, SIGNAL(showMessage(QString)), widget, SLOT(showMessage(QString))); } diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index b0f59e1e..fcb05979 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -846,6 +846,7 @@ void PluginList::generatePluginIndexes() m_ESPs[i].m_Index = QString("%1").arg(l - numESLs - numSkipped, 2, 16, QChar('0')).toUpper(); } } + emit esplist_changed(); } -- cgit v1.3.1 From 23cf8e60fd7144294ee1ffc013f76d4917518a76 Mon Sep 17 00:00:00 2001 From: Al Date: Mon, 24 Dec 2018 21:22:48 +0100 Subject: Changed ui of active mod counters --- src/mainwindow.cpp | 5 ++--- src/mainwindow.ui | 60 ++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 42 insertions(+), 23 deletions(-) (limited to 'src/mainwindow.ui') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 74374c2b..657f89bd 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -460,9 +460,8 @@ MainWindow::MainWindow(QSettings &initSettings } ui->activePluginsCounter->display(m_OrganizerCore.pluginList()->enabledCount()); ui->activeModsCounter->display((int)m_OrganizerCore.currentProfile()->getActiveMods().size()); - qDebug("Plugin enabledCount: %d", m_OrganizerCore.pluginList()->enabledCount()); - qDebug("Mods enabledCount: %d", (int)m_OrganizerCore.currentProfile()->getActiveMods().size()); - + + } diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 067cd4d0..1c2a5aed 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -224,16 +224,6 @@ p, li { white-space: pre-wrap; } - - - - Active: - - - - - - @@ -305,6 +295,26 @@ p, li { white-space: pre-wrap; } + + + + Active: + + + + + + + QFrame::Sunken + + + 5 + + + QLCDNumber::Flat + + + @@ -863,16 +873,6 @@ p, li { white-space: pre-wrap; } - - - - Active: - - - - - - @@ -907,6 +907,26 @@ p, li { white-space: pre-wrap; } + + + + Active: + + + + + + + QFrame::Sunken + + + 3 + + + QLCDNumber::Outline + + + -- cgit v1.3.1 From 7fa230411e3615e923f39fe85d9ccb985e3d4e5d Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Mon, 24 Dec 2018 19:46:31 -0600 Subject: Improvements to the plugin and mod counters * Fix style * Add whatsThis * Add tooltips with additional statistics * Don't count mods like overwrite, unmanaged, DLC, etc. --- src/mainwindow.cpp | 106 +++++++++++++++++++++++++++++++++++++++++++++++++---- src/mainwindow.h | 3 ++ src/mainwindow.ui | 10 ++++- 3 files changed, 110 insertions(+), 9 deletions(-) (limited to 'src/mainwindow.ui') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 657f89bd..e3f12e39 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -458,11 +458,8 @@ MainWindow::MainWindow(QSettings &initSettings // set the name of the widget to the name of the action to allow styling ui->toolBar->widgetForAction(action)->setObjectName(action->objectName()); } - ui->activePluginsCounter->display(m_OrganizerCore.pluginList()->enabledCount()); - ui->activeModsCounter->display((int)m_OrganizerCore.currentProfile()->getActiveMods().size()); - - - + emit updatePluginCount(); + emit updateModCount(); } @@ -2193,7 +2190,7 @@ void MainWindow::directory_refreshed() void MainWindow::esplist_changed() { - ui->activePluginsCounter->display(m_OrganizerCore.pluginList()->enabledCount()); + emit updatePluginCount(); } void MainWindow::modorder_changed() @@ -2453,7 +2450,7 @@ void MainWindow::restoreBackup_clicked() void MainWindow::modlistChanged(const QModelIndex&, int) { m_OrganizerCore.currentProfile()->writeModlist(); - ui->activeModsCounter->display((int)m_OrganizerCore.currentProfile()->getActiveMods().size()); + emit updateModCount(); } void MainWindow::modlistSelectionChanged(const QModelIndex ¤t, const QModelIndex&) @@ -3004,6 +3001,101 @@ void MainWindow::searchClear_activated() } } +void MainWindow::updateModCount() +{ + int activeCount = 0; + int backupCount = 0; + int foreignCount = 0; + int separatorCount = 0; + int regularCount = 0; + + QStringList allMods = m_OrganizerCore.modList()->allMods(); + + auto hasFlag = [](std::vector flags, ModInfo::EFlag filter) { + return std::find(flags.begin(), flags.end(), filter) != flags.end(); + }; + + for (QString mod : allMods) { + int modIndex = ModInfo::getIndex(mod); + ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex); + std::vector modFlags = modInfo->getFlags(); + for (auto flag : modFlags) { + switch (flag) { + case ModInfo::FLAG_BACKUP: backupCount++; break; + case ModInfo::FLAG_FOREIGN: foreignCount++; break; + case ModInfo::FLAG_SEPARATOR: separatorCount++; break; + } + } + + if (!hasFlag(modFlags, ModInfo::FLAG_BACKUP) && + !hasFlag(modFlags, ModInfo::FLAG_FOREIGN) && + !hasFlag(modFlags, ModInfo::FLAG_SEPARATOR) && + !hasFlag(modFlags, ModInfo::FLAG_OVERWRITE)) { + if (m_OrganizerCore.currentProfile()->modEnabled(modIndex)) + activeCount++; + regularCount++; + } + } + + ui->activeModsCounter->display(activeCount); + ui->activeModsCounter->setToolTip(tr("" + "" + "" + "" + "" + "
Active mods: %1 of %2
Unmanaged mods/DLC: %3
Mod backups: %4
Separators: %5
") + .arg(activeCount) + .arg(regularCount) + .arg(foreignCount) + .arg(backupCount) + .arg(separatorCount) + ); +} + +void MainWindow::updatePluginCount() +{ + int activeMasterCount = 0; + int activeLightMasterCount = 0; + int activeRegularCount = 0; + int masterCount = 0; + int lightMasterCount = 0; + int regularCount = 0; + + PluginList *list = m_OrganizerCore.pluginList(); + + for (QString plugin : list->pluginNames()) { + bool active = list->isEnabled(plugin); + if (list->isMaster(plugin)) { + masterCount++; + activeMasterCount += active; + } else if (list->isLight(plugin) || list->isLightFlagged(plugin)) { + lightMasterCount++; + activeLightMasterCount += active; + } else { + regularCount++; + activeRegularCount += active; + } + } + + int activeCount = activeMasterCount + activeLightMasterCount + activeRegularCount; + int totalCount = masterCount + lightMasterCount + regularCount; + + ui->activePluginsCounter->display(activeCount); + ui->activePluginsCounter->setToolTip(tr("" + "" + "" + "" + "" + "" + "
Active plugins: %1 of %2
Active ESMs: %3 of %4
Active ESLs: %5 of %6
Active ESPs: %7 of %8
Active ESMs+ESPs: %9 of %10
") + .arg(activeCount).arg(totalCount) + .arg(activeMasterCount).arg(masterCount) + .arg(activeLightMasterCount).arg(lightMasterCount) + .arg(activeRegularCount).arg(regularCount) + .arg(activeMasterCount+activeRegularCount).arg(masterCount+regularCount) + ); +} + void MainWindow::information_clicked() { try { diff --git a/src/mainwindow.h b/src/mainwindow.h index 61113b8c..654a11d5 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -586,6 +586,9 @@ private slots: void search_activated(); void searchClear_activated(); + void updateModCount(); + void updatePluginCount(); + private slots: // ui slots // actions void on_actionAdd_Profile_triggered(); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 1c2a5aed..1180dee0 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -304,6 +304,9 @@ p, li { white-space: pre-wrap; }
+ + 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. + QFrame::Sunken @@ -916,14 +919,17 @@ p, li { white-space: pre-wrap; } + + 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. + QFrame::Sunken - 3 + 4 - QLCDNumber::Outline + QLCDNumber::Flat -- cgit v1.3.1 From 66d0ae4317129f852627e6cddd6fa485dcdf6779 Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Wed, 26 Dec 2018 09:19:44 -0600 Subject: Add a small gutter around the active mod/plugin counters --- src/mainwindow.ui | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/mainwindow.ui') diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 1180dee0..f2b12037 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -304,6 +304,12 @@ p, li { white-space: pre-wrap; } + + + 0 + 26 + + 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. @@ -919,6 +925,12 @@ p, li { white-space: pre-wrap; } + + + 0 + 26 + + 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. -- cgit v1.3.1 From 6a4e52f9dc9e929f3404145702e8279eb19beae0 Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Wed, 26 Dec 2018 10:59:18 -0600 Subject: Display counter tooltips when clicked --- src/CMakeLists.txt | 2 ++ src/lcdnumber.cpp | 37 +++++++++++++++++++++++++++++++++++++ src/lcdnumber.h | 35 +++++++++++++++++++++++++++++++++++ src/mainwindow.ui | 9 +++++++-- src/organizer.pro | 6 ++++-- 5 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 src/lcdnumber.cpp create mode 100644 src/lcdnumber.h (limited to 'src/mainwindow.ui') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3f004ddc..a084bae0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -92,6 +92,7 @@ SET(organizer_SRCS eventfilter.cpp moshortcut.cpp listdialog.cpp + lcdnumber.cpp shared/windows_error.cpp shared/error_report.cpp @@ -187,6 +188,7 @@ SET(organizer_HDRS descriptionpage.h moshortcut.h listdialog.h + lcdnumber.h shared/windows_error.h shared/error_report.h diff --git a/src/lcdnumber.cpp b/src/lcdnumber.cpp new file mode 100644 index 00000000..3191b434 --- /dev/null +++ b/src/lcdnumber.cpp @@ -0,0 +1,37 @@ +/* +This file is part of Mod Organizer. + +Mod Organizer is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Mod Organizer is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Mod Organizer. If not, see . +*/ + +#include "lcdnumber.h" + +#include +#include + +LCDNumber::LCDNumber(QWidget *parent) + : QLCDNumber(parent) +{ +} + +void LCDNumber::mousePressEvent(QMouseEvent *event) +{ + m_toolTipPosition = mapToGlobal(event->pos()); + QTimer::singleShot(100, this, SLOT(showToolTip())); +} + +void LCDNumber::showToolTip() +{ + QToolTip::showText(m_toolTipPosition, toolTip()); +} diff --git a/src/lcdnumber.h b/src/lcdnumber.h new file mode 100644 index 00000000..2f8e0454 --- /dev/null +++ b/src/lcdnumber.h @@ -0,0 +1,35 @@ +/* +This file is part of Mod Organizer. + +Mod Organizer is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Mod Organizer is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Mod Organizer. If not, see . +*/ + +#include +#include +#include + +class LCDNumber : public QLCDNumber +{ + Q_OBJECT + +public: + LCDNumber(QWidget *parent = nullptr); + void mousePressEvent(QMouseEvent *event); + +public slots: + void showToolTip(); + +private: + QPoint m_toolTipPosition; +}; diff --git a/src/mainwindow.ui b/src/mainwindow.ui index f2b12037..b1ed8e5a 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -303,7 +303,7 @@ p, li { white-space: pre-wrap; } - + 0 @@ -924,7 +924,7 @@ p, li { white-space: pre-wrap; } - + 0 @@ -1678,6 +1678,11 @@ Right now this has very limited functionality QTreeView
pluginlistview.h
+ + LCDNumber + QLCDNumber +
lcdnumber.h
+
diff --git a/src/organizer.pro b/src/organizer.pro index 582fde9f..df42db40 100644 --- a/src/organizer.pro +++ b/src/organizer.pro @@ -92,7 +92,8 @@ SOURCES += \ modinfobackup.cpp \ modinfooverwrite.cpp \ modinfoforeign.cpp \ - listdialog.cpp + listdialog.cpp \ + lcdnumber.cpp HEADERS += \ @@ -169,7 +170,8 @@ HEADERS += \ modinfobackup.h \ modinfooverwrite.h \ modinfoforeign.h \ - listdialog.h + listdialog.h \ + lcdnumber.h FORMS += \ transfersavesdialog.ui \ -- cgit v1.3.1 From 5920dc2cd14ef5dc6e3802939cbe6256ea13848b Mon Sep 17 00:00:00 2001 From: Krzysztof Starecki Date: Sun, 30 Dec 2018 12:07:40 +0100 Subject: Disable downloadlist widget delegates, port partial functionality to QTreeView --- src/downloadlist.cpp | 45 ++- src/downloadlist.h | 2 +- src/downloadlistsortproxy.cpp | 14 +- src/downloadlistwidget.cpp | 10 +- src/downloadlistwidget.h | 16 +- src/mainwindow.cpp | 6 + src/mainwindow.ui | 2 +- src/organizer_en.ts | 657 +++++++++++++++++++++--------------------- 8 files changed, 398 insertions(+), 354 deletions(-) (limited to 'src/mainwindow.ui') diff --git a/src/downloadlist.cpp b/src/downloadlist.cpp index f470e57b..503274e6 100644 --- a/src/downloadlist.cpp +++ b/src/downloadlist.cpp @@ -40,7 +40,7 @@ int DownloadList::rowCount(const QModelIndex&) const int DownloadList::columnCount(const QModelIndex&) const { - return 4; + return 3; } @@ -61,21 +61,34 @@ QVariant DownloadList::headerData(int section, Qt::Orientation orientation, int if ((role == Qt::DisplayRole) && (orientation == Qt::Horizontal)) { switch (section) { - case COL_NAME: return tr("Name"); - case COL_FILETIME: return tr("Filetime"); - case COL_SIZE: return tr("Size"); - default: return tr("Done"); + case COL_NAME : return tr("Name"); + case COL_SIZE : return tr("Size"); + case COL_STATUS : return tr("Status"); + default : return "-"; } } else { return QAbstractItemModel::headerData(section, orientation, role); } } - QVariant DownloadList::data(const QModelIndex &index, int role) const { if (role == Qt::DisplayRole) { - return index.row(); + if (index.column() == COL_NAME) { + return m_Manager->getFileName(index.row()); + } else if (index.column() == COL_SIZE) { + return sizeFormat(m_Manager->getFileSize(index.row())); + } else if (index.column() == COL_STATUS) { + DownloadManager::DownloadState state = m_Manager->getState(index.row()); + switch (state) { + case DownloadManager::STATE_INSTALLED : return tr("Installed"); + case DownloadManager::STATE_READY : return tr("Downloaded"); + case DownloadManager::STATE_DOWNLOADING : return m_Manager->getProgress(index.row()).second; + default : return state; + } + } else { + return index.row(); + } } else if (role == Qt::ToolTipRole) { if (index.row() < m_Manager->numTotalDownloads()) { QString text = m_Manager->getFileName(index.row()) + "\n"; @@ -112,3 +125,21 @@ void DownloadList::update(int row) } } +QString DownloadList::sizeFormat(quint64 size) const +{ + qreal calc = size; + QStringList list; + list << "MB" << "GB" << "TB"; + + QStringListIterator i(list); + QString unit("KB"); + + calc /= 1024.0; + while (calc >= 1024.0 && i.hasNext()) + { + unit = i.next(); + calc /= 1024.0; + } + + return QString().setNum(calc, 'f', 2) + " " + unit; +} diff --git a/src/downloadlist.h b/src/downloadlist.h index e8833f0f..1a5ca0b2 100644 --- a/src/downloadlist.h +++ b/src/downloadlist.h @@ -38,7 +38,6 @@ public: enum EColumn { COL_NAME = 0, - COL_FILETIME, COL_STATUS, COL_SIZE }; @@ -92,6 +91,7 @@ private: DownloadManager *m_Manager; + QString sizeFormat(quint64 size) const; }; #endif // DOWNLOADLIST_H diff --git a/src/downloadlistsortproxy.cpp b/src/downloadlistsortproxy.cpp index f791617a..ee16860a 100644 --- a/src/downloadlistsortproxy.cpp +++ b/src/downloadlistsortproxy.cpp @@ -42,13 +42,11 @@ bool DownloadListSortProxy::lessThan(const QModelIndex &left, if ((leftIndex < m_Manager->numTotalDownloads()) && (rightIndex < m_Manager->numTotalDownloads())) { if (left.column() == DownloadList::COL_NAME) { - return m_Manager->getFileName(leftIndex).compare(m_Manager->getFileName(rightIndex), Qt::CaseInsensitive) < 0; - } else if (left.column() == DownloadList::COL_FILETIME) { - return m_Manager->getFileTime(leftIndex) < m_Manager->getFileTime(rightIndex); + return m_Manager->getFileName(left.row()).compare(m_Manager->getFileName(right.row()), Qt::CaseInsensitive) < 0; } else if (left.column() == DownloadList::COL_STATUS) { - return m_Manager->getState(leftIndex) < m_Manager->getState(rightIndex); + return m_Manager->getState(left.row()) < m_Manager->getState(right.row()); } else if(left.column() == DownloadList::COL_SIZE){ - return m_Manager->getFileSize(leftIndex) < m_Manager->getFileSize(rightIndex); + return m_Manager->getFileSize(left.row()) < m_Manager->getFileSize(right.row()); } else { return leftIndex < rightIndex; } @@ -63,11 +61,9 @@ bool DownloadListSortProxy::filterAcceptsRow(int sourceRow, const QModelIndex&) if (m_CurrentFilter.length() == 0) { return true; } else if (sourceRow < m_Manager->numTotalDownloads()) { - int downloadIndex = sourceModel()->index(sourceRow, 0).data().toInt(); - QString displayedName = Settings::instance().metaDownloads() - ? m_Manager->getDisplayName(downloadIndex) - : m_Manager->getFileName(downloadIndex); + ? m_Manager->getDisplayName(sourceRow) + : m_Manager->getFileName(sourceRow); return displayedName.contains(m_CurrentFilter, Qt::CaseInsensitive); } else { return false; diff --git a/src/downloadlistwidget.cpp b/src/downloadlistwidget.cpp index c62d774c..b3d9b083 100644 --- a/src/downloadlistwidget.cpp +++ b/src/downloadlistwidget.cpp @@ -27,15 +27,19 @@ along with Mod Organizer. If not, see . DownloadListWidget::DownloadListWidget(QWidget *parent) - : QWidget(parent), ui(new Ui::DownloadListWidget) + : QTreeView(parent) { - ui->setupUi(this); + connect(this, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(onDoubleClick(QModelIndex))); } DownloadListWidget::~DownloadListWidget() { - delete ui; +} + +void DownloadListWidget::onDoubleClick(const QModelIndex &index) +{ + emit(resumeDownload(dynamic_cast(model())->mapToSource(index).row())); } diff --git a/src/downloadlistwidget.h b/src/downloadlistwidget.h index fe7f3b22..7a7a25f7 100644 --- a/src/downloadlistwidget.h +++ b/src/downloadlistwidget.h @@ -28,20 +28,22 @@ along with Mod Organizer. If not, see . #include namespace Ui { - class DownloadListWidget; + class DownloadListWidget; } -class DownloadListWidget : public QWidget +class DownloadListWidget : public QTreeView { - Q_OBJECT + Q_OBJECT public: - explicit DownloadListWidget(QWidget *parent = 0); - ~DownloadListWidget(); + explicit DownloadListWidget(QWidget *parent = 0); + ~DownloadListWidget(); +signals: + void resumeDownload(int index); -private: - Ui::DownloadListWidget *ui; +private slots: + void onDoubleClick(const QModelIndex &index); }; class DownloadManager; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 27ffc71e..5ca60ef1 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -5152,6 +5152,7 @@ void MainWindow::on_actionEndorseMO_triggered() void MainWindow::updateDownloadListDelegate() { + /* if (m_OrganizerCore.settings().compactDownloads()) { ui->downloadView->setItemDelegate( new DownloadListWidgetCompactDelegate(m_OrganizerCore.downloadManager(), @@ -5165,6 +5166,7 @@ void MainWindow::updateDownloadListDelegate() ui->downloadView, ui->downloadView)); } + */ DownloadListSortProxy *sortProxy = new DownloadListSortProxy(m_OrganizerCore.downloadManager(), ui->downloadView); sortProxy->setSourceModel(new DownloadList(m_OrganizerCore.downloadManager(), ui->downloadView)); @@ -5175,6 +5177,9 @@ void MainWindow::updateDownloadListDelegate() //ui->downloadView->sortByColumn(1, Qt::DescendingOrder); ui->downloadView->header()->resizeSections(QHeaderView::Stretch); + connect(ui->downloadView, SIGNAL(resumeDownload(int)), m_OrganizerCore.downloadManager(), SLOT(resumeDownload(int))); + + /* connect(ui->downloadView->itemDelegate(), SIGNAL(installDownload(int)), &m_OrganizerCore, SLOT(installDownload(int))); connect(ui->downloadView->itemDelegate(), SIGNAL(queryInfo(int)), m_OrganizerCore.downloadManager(), SLOT(queryInfo(int))); connect(ui->downloadView->itemDelegate(), SIGNAL(visitOnNexus(int)), m_OrganizerCore.downloadManager(), SLOT(visitOnNexus(int))); @@ -5185,6 +5190,7 @@ void MainWindow::updateDownloadListDelegate() connect(ui->downloadView->itemDelegate(), SIGNAL(cancelDownload(int)), m_OrganizerCore.downloadManager(), SLOT(cancelDownload(int))); connect(ui->downloadView->itemDelegate(), SIGNAL(pauseDownload(int)), m_OrganizerCore.downloadManager(), SLOT(pauseDownload(int))); connect(ui->downloadView->itemDelegate(), SIGNAL(resumeDownload(int)), this, SLOT(resumeDownload(int))); + */ } diff --git a/src/mainwindow.ui b/src/mainwindow.ui index b1ed8e5a..5dfd075b 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1303,7 +1303,7 @@ p, li { white-space: pre-wrap; } - + 320 diff --git a/src/organizer_en.ts b/src/organizer_en.ts index 46bb42cf..9b61eafc 100644 --- a/src/organizer_en.ts +++ b/src/organizer_en.ts @@ -298,26 +298,31 @@ p, li { white-space: pre-wrap; } - Filetime + Size - Size + Status - - Done + + Installed - + + Downloaded + + + + Information missing, please select "Query Info" from the context menu to re-retrieve. - + pending download @@ -332,26 +337,26 @@ p, li { white-space: pre-wrap; } - - + + Done - Double Click to install - - + + Paused - Double Click to resume - - + + Installed - Double Click to re-install - - + + Uninstalled - Double Click to re-install @@ -559,165 +564,165 @@ p, li { white-space: pre-wrap; } DownloadListWidgetDelegate - + < game %1 mod %2 file %3 > - + Pending - + Fetching Info 1 - + Fetching Info 2 - - - - + + + + Delete Files? - + This will permanently delete the selected download. - + This will remove all finished downloads from this list and from disk. - + This will remove all installed downloads from this list and from disk. - + This will remove all uninstalled downloads from this list and from disk. - - - + + + Are you sure? - + This will remove all finished downloads from this list (but NOT from disk). - + This will remove all installed downloads from this list (but NOT from disk). - + This will remove all uninstalled downloads from this list (but NOT from disk). - + Install - + Query Info - + Visit on Nexus - + Open File - - + + Show in Folder - - + + Delete - + Un-Hide - + Hide - + Cancel - + Pause - + Resume - + Delete Installed... - + Delete Uninstalled... - + Delete All... - + Hide Installed... - + Hide Uninstalled... - + Hide All... - + Un-Hide All... @@ -1620,7 +1625,7 @@ p, li { white-space: pre-wrap; } - + Create Backup @@ -1796,8 +1801,8 @@ p, li { white-space: pre-wrap; } - - + + Refresh @@ -2022,7 +2027,7 @@ Right now this has very limited functionality - + Endorse Mod Organizer @@ -2090,8 +2095,8 @@ Error: %1 - - + + Endorse @@ -2181,711 +2186,711 @@ Error: %1 - + 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 - + 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. @@ -2893,12 +2898,12 @@ You can also use online editors and converters instead. - + Enable Mods... - + Delete %n save(s) @@ -2906,22 +2911,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. @@ -2929,7 +2934,7 @@ Click OK to restart MO now. - + Can't change download directory while downloads are in progress! @@ -3003,7 +3008,7 @@ Click OK to restart MO now. - + Set Priority @@ -3033,231 +3038,231 @@ Click OK to restart MO now. - + 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 @@ -4455,135 +4460,135 @@ p, li { white-space: pre-wrap; } - + 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. @@ -4730,94 +4735,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 @@ -5619,13 +5624,13 @@ If the folder was still in use, restart MO and try again. - + <Manage...> - + failed to parse profile %1: %2 @@ -5661,12 +5666,12 @@ If the folder was still in use, restart MO and try again. - + failed to access %1 - + failed to set file time %1 -- cgit v1.3.1 From ec8dbcbf280bf6b542e9087d562e51757d205299 Mon Sep 17 00:00:00 2001 From: Krzysztof Starecki Date: Sun, 30 Dec 2018 14:54:28 +0100 Subject: Port context menus to new downloadlist --- src/downloadlist.cpp | 2 + src/downloadlistwidget.cpp | 359 +++++++++----------------------------- src/downloadlistwidget.h | 58 +------ src/downloadmanager.cpp | 2 +- src/mainwindow.cpp | 41 ++--- src/mainwindow.ui | 2 +- src/organizer_en.ts | 417 +++++++++++++++++++++------------------------ 7 files changed, 291 insertions(+), 590 deletions(-) (limited to 'src/mainwindow.ui') diff --git a/src/downloadlist.cpp b/src/downloadlist.cpp index 503274e6..a44850cb 100644 --- a/src/downloadlist.cpp +++ b/src/downloadlist.cpp @@ -82,8 +82,10 @@ QVariant DownloadList::data(const QModelIndex &index, int role) const DownloadManager::DownloadState state = m_Manager->getState(index.row()); switch (state) { case DownloadManager::STATE_INSTALLED : return tr("Installed"); + case DownloadManager::STATE_UNINSTALLED : return tr("Uninstalled"); case DownloadManager::STATE_READY : return tr("Downloaded"); case DownloadManager::STATE_DOWNLOADING : return m_Manager->getProgress(index.row()).second; + case DownloadManager::STATE_PAUSED : return tr("Paused"); default : return state; } } else { diff --git a/src/downloadlistwidget.cpp b/src/downloadlistwidget.cpp index b3d9b083..915ddda5 100644 --- a/src/downloadlistwidget.cpp +++ b/src/downloadlistwidget.cpp @@ -30,224 +30,101 @@ DownloadListWidget::DownloadListWidget(QWidget *parent) : QTreeView(parent) { connect(this, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(onDoubleClick(QModelIndex))); + connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onCustomContextMenu(QPoint))); } - DownloadListWidget::~DownloadListWidget() { } -void DownloadListWidget::onDoubleClick(const QModelIndex &index) -{ - emit(resumeDownload(dynamic_cast(model())->mapToSource(index).row())); -} - - -DownloadListWidgetDelegate::DownloadListWidgetDelegate(DownloadManager *manager, bool metaDisplay, QTreeView *view, QObject *parent) - : QItemDelegate(parent) - , m_Manager(manager) - , m_MetaDisplay(metaDisplay) - , m_ItemWidget(new DownloadListWidget) - , m_ContextRow(0) - , m_View(view) -{ - m_NameLabel = m_ItemWidget->findChild("nameLabel"); - m_SizeLabel = m_ItemWidget->findChild("sizeLabel"); - m_Progress = m_ItemWidget->findChild("downloadProgress"); - m_InstallLabel = m_ItemWidget->findChild("installLabel"); - - m_InstallLabel->setVisible(false); - m_Progress->setTextVisible(true); - - connect(manager, SIGNAL(stateChanged(int,DownloadManager::DownloadState)), this, SLOT(stateChanged(int,DownloadManager::DownloadState))); - connect(manager, SIGNAL(downloadRemoved(int)), this, SLOT(resetCache(int))); -} - - -DownloadListWidgetDelegate::~DownloadListWidgetDelegate() -{ - delete m_ItemWidget; -} - - -void DownloadListWidgetDelegate::stateChanged(int row,DownloadManager::DownloadState) +void DownloadListWidget::setManager(DownloadManager *manager) { - m_Cache.remove(row); + m_Manager = manager; } - -void DownloadListWidgetDelegate::resetCache(int) +void DownloadListWidget::onDoubleClick(const QModelIndex &index) { - m_Cache.clear(); + QModelIndex sourceIndex = qobject_cast(model())->mapToSource(index); + if (m_Manager->getState(sourceIndex.row()) >= DownloadManager::STATE_READY) { + emit installDownload(sourceIndex.row()); + } else if ((m_Manager->getState(sourceIndex.row()) >= DownloadManager::STATE_PAUSED) || (m_Manager->getState(sourceIndex.row()) == DownloadManager::STATE_PAUSING)) { + emit resumeDownload(sourceIndex.row()); + } } - -void DownloadListWidgetDelegate::drawCache(QPainter *painter, const QStyleOptionViewItem &option, const QPixmap &cache) const +void DownloadListWidget::onCustomContextMenu(const QPoint &point) { - QRect rect = option.rect; - rect.setLeft(0); - rect.setWidth(m_View->columnWidth(0) + m_View->columnWidth(1) + m_View->columnWidth(2) + m_View->columnWidth(3)); - painter->drawPixmap(rect, cache); -} - - -QString DownloadListWidgetDelegate::sizeFormat(quint64 size) const -{ - qreal calc = size; - QStringList list; - list << "KB" << "MB" << "GB" << "TB"; - - QStringListIterator i(list); - QString unit("byte(s)"); - - while (calc >= 1024.0 && i.hasNext()) - { - unit = i.next(); - calc /= 1024.0; - } - - return QString().setNum(calc, 'f', 2) + " " + unit; -} - + QMenu menu(this); + QModelIndex index = indexAt(point); + bool hidden = false; + if (index.row() >= 0) { + m_ContextRow = qobject_cast(model())->mapToSource(index).row(); + DownloadManager::DownloadState state = m_Manager->getState(m_ContextRow); + hidden = m_Manager->isHidden(m_ContextRow); + if (state >= DownloadManager::STATE_READY) { + menu.addAction(tr("Install"), this, SLOT(issueInstall())); + if (m_Manager->isInfoIncomplete(m_ContextRow)) { + menu.addAction(tr("Query Info"), this, SLOT(issueQueryInfo())); + } + else { + menu.addAction(tr("Visit on Nexus"), this, SLOT(issueVisitOnNexus())); + } -void DownloadListWidgetDelegate::paintPendingDownload(int downloadIndex) const -{ - std::tuple nexusids = m_Manager->getPendingDownload(downloadIndex); - m_NameLabel->setText(tr("< game %1 mod %2 file %3 >").arg(std::get<0>(nexusids)).arg(std::get<1>(nexusids)).arg(std::get<2>(nexusids))); - m_SizeLabel->setText("???"); - m_InstallLabel->setVisible(true); - m_InstallLabel->setText(tr("Pending")); - m_Progress->setVisible(false); -} + menu.addAction(tr("Open File"), this, SLOT(issueOpenFile())); + menu.addAction(tr("Show in Folder"), this, SLOT(issueOpenInDownloadsFolder())); + menu.addSeparator(); -void DownloadListWidgetDelegate::paintRegularDownload(int downloadIndex) const -{ - QString name = m_MetaDisplay ? m_Manager->getDisplayName(downloadIndex) : m_Manager->getFileName(downloadIndex); - if (name.length() > 120) { - name.truncate(120); - name.append("..."); - } - m_NameLabel->setText(name); - m_SizeLabel->setText(sizeFormat(m_Manager->getFileSize(downloadIndex) )); - DownloadManager::DownloadState state = m_Manager->getState(downloadIndex); - if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR) || (state == DownloadManager::STATE_PAUSING)) { - QPalette labelPalette; - m_InstallLabel->setVisible(true); - m_Progress->setVisible(false); -#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) - m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Paused - Double Click to resume", 0)); -#else - m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Paused - Double Click to resume", 0, QApplication::UnicodeUTF8)); -#endif - labelPalette.setColor(QPalette::WindowText, Qt::darkRed); - m_InstallLabel->setPalette(labelPalette); - } else if (state == DownloadManager::STATE_FETCHINGMODINFO) { - m_InstallLabel->setText(tr("Fetching Info 1")); - m_Progress->setVisible(false); - } else if (state == DownloadManager::STATE_FETCHINGFILEINFO) { - m_InstallLabel->setText(tr("Fetching Info 2")); - m_Progress->setVisible(false); - } else if (state >= DownloadManager::STATE_READY) { - QPalette labelPalette; - m_InstallLabel->setVisible(true); - m_Progress->setVisible(false); - if (state == DownloadManager::STATE_INSTALLED) { - // the tr-macro doesn't work here, maybe because the translation is actually associated with DownloadListWidget instead - // of DownloadListWidgetDelegate? -#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) - m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Installed - Double Click to re-install", 0)); -#else - m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Installed - Double Click to re-install", 0, QApplication::UnicodeUTF8)); -#endif - labelPalette.setColor(QPalette::WindowText, Qt::darkGray); - } else if (state == DownloadManager::STATE_UNINSTALLED) { -#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) - m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Uninstalled - Double Click to re-install", 0)); -#else - m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Uninstalled - Double Click to re-install", 0, QApplication::UnicodeUTF8)); -#endif - labelPalette.setColor(QPalette::WindowText, Qt::lightGray); - } else { -#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) - m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Done - Double Click to install", 0)); -#else - m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Done - Double Click to install", 0, QApplication::UnicodeUTF8)); -#endif - labelPalette.setColor(QPalette::WindowText, Qt::darkGreen); + menu.addAction(tr("Delete"), this, SLOT(issueDelete())); + if (hidden) { + menu.addAction(tr("Un-Hide"), this, SLOT(issueRestoreToView())); + } + else { + menu.addAction(tr("Hide"), this, SLOT(issueRemoveFromView())); + } } - m_InstallLabel->setPalette(labelPalette); - if (m_Manager->isInfoIncomplete(downloadIndex)) { - m_NameLabel->setText(" " + m_NameLabel->text()); + else if (state == DownloadManager::STATE_DOWNLOADING) { + menu.addAction(tr("Cancel"), this, SLOT(issueCancel())); + menu.addAction(tr("Pause"), this, SLOT(issuePause())); + menu.addAction(tr("Show in Folder"), this, SLOT(issueOpenInDownloadsFolder())); } - } else { - m_InstallLabel->setVisible(false); - m_Progress->setVisible(true); - m_Progress->setValue(m_Manager->getProgress(downloadIndex).first); - m_Progress->setFormat(m_Manager->getProgress(downloadIndex).second); - } -} - -void DownloadListWidgetDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - try { - auto iter = m_Cache.find(index.row()); - if (iter != m_Cache.end()) { - drawCache(painter, option, *iter); - return; + else if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR) || (state == DownloadManager::STATE_PAUSING)) { + menu.addAction(tr("Delete"), this, SLOT(issueDelete())); + menu.addAction(tr("Resume"), this, SLOT(issueResume())); + menu.addAction(tr("Show in Folder"), this, SLOT(issueOpenInDownloadsFolder())); } - m_ItemWidget->resize(QSize(m_View->columnWidth(0) + m_View->columnWidth(1) + m_View->columnWidth(2) + m_View->columnWidth(3), option.rect.height())); - - int downloadIndex = index.data().toInt(); - - if (downloadIndex >= m_Manager->numTotalDownloads()) { - paintPendingDownload(downloadIndex - m_Manager->numTotalDownloads()); - } else { - paintRegularDownload(downloadIndex); - } - -#pragma message("caching disabled because changes in the list (including resorting) doesn't work correctly") -// if (state >= DownloadManager::STATE_READY) { - if (false) { -#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) - QPixmap cache = m_ItemWidget->grab(); -#else - QPixmap cache = QPixmap::grabWidget(m_ItemWidget); -#endif - m_Cache[index.row()] = cache; - drawCache(painter, option, cache); - } else { - painter->save(); - painter->translate(QPoint(0, option.rect.topLeft().y())); - - m_ItemWidget->render(painter); - painter->restore(); - } - } catch (const std::exception &e) { - qCritical("failed to paint download list: %s", e.what()); + menu.addSeparator(); + } + menu.addAction(tr("Delete Installed..."), this, SLOT(issueDeleteCompleted())); + menu.addAction(tr("Delete Uninstalled..."), this, SLOT(issueDeleteUninstalled())); + menu.addAction(tr("Delete All..."), this, SLOT(issueDeleteAll())); + + if (!hidden) { + menu.addSeparator(); + menu.addAction(tr("Hide Installed..."), this, SLOT(issueRemoveFromViewCompleted())); + menu.addAction(tr("Hide Uninstalled..."), this, SLOT(issueRemoveFromViewUninstalled())); + menu.addAction(tr("Hide All..."), this, SLOT(issueRemoveFromViewAll())); + } + if (hidden) { + menu.addSeparator(); + menu.addAction(tr("Un-Hide All..."), this, SLOT(issueRestoreToViewAll())); } -} -QSize DownloadListWidgetDelegate::sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const -{ - const int width = m_ItemWidget->minimumWidth(); - const int height = m_ItemWidget->height(); - return QSize(width, height); + menu.exec(viewport()->mapToGlobal(point)); } - -void DownloadListWidgetDelegate::issueInstall() +void DownloadListWidget::issueInstall() { emit installDownload(m_ContextRow); } -void DownloadListWidgetDelegate::issueQueryInfo() +void DownloadListWidget::issueQueryInfo() { emit queryInfo(m_ContextRow); } -void DownloadListWidgetDelegate::issueDelete() +void DownloadListWidget::issueDelete() { if (QMessageBox::question(nullptr, tr("Delete Files?"), tr("This will permanently delete the selected download."), @@ -256,52 +133,53 @@ void DownloadListWidgetDelegate::issueDelete() } } -void DownloadListWidgetDelegate::issueRemoveFromView() +void DownloadListWidget::issueRemoveFromView() { + qDebug() << "removing from view: " << m_ContextRow; emit removeDownload(m_ContextRow, false); } -void DownloadListWidgetDelegate::issueRestoreToView() +void DownloadListWidget::issueRestoreToView() { emit restoreDownload(m_ContextRow); } -void DownloadListWidgetDelegate::issueRestoreToViewAll() +void DownloadListWidget::issueRestoreToViewAll() { emit restoreDownload(-1); } -void DownloadListWidgetDelegate::issueVisitOnNexus() +void DownloadListWidget::issueVisitOnNexus() { emit visitOnNexus(m_ContextRow); } -void DownloadListWidgetDelegate::issueOpenFile() +void DownloadListWidget::issueOpenFile() { emit openFile(m_ContextRow); } -void DownloadListWidgetDelegate::issueOpenInDownloadsFolder() +void DownloadListWidget::issueOpenInDownloadsFolder() { emit openInDownloadsFolder(m_ContextRow); } -void DownloadListWidgetDelegate::issueCancel() +void DownloadListWidget::issueCancel() { emit cancelDownload(m_ContextRow); } -void DownloadListWidgetDelegate::issuePause() +void DownloadListWidget::issuePause() { emit pauseDownload(m_ContextRow); } -void DownloadListWidgetDelegate::issueResume() +void DownloadListWidget::issueResume() { emit resumeDownload(m_ContextRow); } -void DownloadListWidgetDelegate::issueDeleteAll() +void DownloadListWidget::issueDeleteAll() { if (QMessageBox::question(nullptr, tr("Delete Files?"), tr("This will remove all finished downloads from this list and from disk."), @@ -310,7 +188,7 @@ void DownloadListWidgetDelegate::issueDeleteAll() } } -void DownloadListWidgetDelegate::issueDeleteCompleted() +void DownloadListWidget::issueDeleteCompleted() { if (QMessageBox::question(nullptr, tr("Delete Files?"), tr("This will remove all installed downloads from this list and from disk."), @@ -319,7 +197,7 @@ void DownloadListWidgetDelegate::issueDeleteCompleted() } } -void DownloadListWidgetDelegate::issueDeleteUninstalled() +void DownloadListWidget::issueDeleteUninstalled() { if (QMessageBox::question(nullptr, tr("Delete Files?"), tr("This will remove all uninstalled downloads from this list and from disk."), @@ -328,7 +206,7 @@ void DownloadListWidgetDelegate::issueDeleteUninstalled() } } -void DownloadListWidgetDelegate::issueRemoveFromViewAll() +void DownloadListWidget::issueRemoveFromViewAll() { if (QMessageBox::question(nullptr, tr("Are you sure?"), tr("This will remove all finished downloads from this list (but NOT from disk)."), @@ -337,7 +215,7 @@ void DownloadListWidgetDelegate::issueRemoveFromViewAll() } } -void DownloadListWidgetDelegate::issueRemoveFromViewCompleted() +void DownloadListWidget::issueRemoveFromViewCompleted() { if (QMessageBox::question(nullptr, tr("Are you sure?"), tr("This will remove all installed downloads from this list (but NOT from disk)."), @@ -346,7 +224,7 @@ void DownloadListWidgetDelegate::issueRemoveFromViewCompleted() } } -void DownloadListWidgetDelegate::issueRemoveFromViewUninstalled() +void DownloadListWidget::issueRemoveFromViewUninstalled() { if (QMessageBox::question(nullptr, tr("Are you sure?"), tr("This will remove all uninstalled downloads from this list (but NOT from disk)."), @@ -354,82 +232,3 @@ void DownloadListWidgetDelegate::issueRemoveFromViewUninstalled() emit removeDownload(-3, false); } } - -bool DownloadListWidgetDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, - const QStyleOptionViewItem &option, const QModelIndex &index) -{ - try { - if (event->type() == QEvent::MouseButtonDblClick) { - QModelIndex sourceIndex = qobject_cast(model)->mapToSource(index); - if (m_Manager->getState(sourceIndex.row()) >= DownloadManager::STATE_READY) { - emit installDownload(sourceIndex.row()); - } else if ((m_Manager->getState(sourceIndex.row()) >= DownloadManager::STATE_PAUSED) || (m_Manager->getState(sourceIndex.row()) == DownloadManager::STATE_PAUSING)) { - emit resumeDownload(sourceIndex.row()); - } - return true; - } else if (event->type() == QEvent::MouseButtonRelease) { - QMouseEvent *mouseEvent = static_cast(event); - if (mouseEvent->button() == Qt::RightButton) { - QMenu menu(m_View); - bool hidden = false; - m_ContextRow = qobject_cast(model)->mapToSource(index).row(); - if (m_ContextRow < m_Manager->numTotalDownloads()) { - DownloadManager::DownloadState state = m_Manager->getState(m_ContextRow); - hidden = m_Manager->isHidden(m_ContextRow); - if (state >= DownloadManager::STATE_READY) { - menu.addAction(tr("Install"), this, SLOT(issueInstall())); - if (m_Manager->isInfoIncomplete(m_ContextRow)) { - menu.addAction(tr("Query Info"), this, SLOT(issueQueryInfo())); - }else { - menu.addAction(tr("Visit on Nexus"), this,SLOT(issueVisitOnNexus())); - } - - menu.addAction(tr("Open File"), this, SLOT(issueOpenFile())); - menu.addAction(tr("Show in Folder"), this, SLOT(issueOpenInDownloadsFolder())); - - menu.addSeparator(); - - menu.addAction(tr("Delete"), this, SLOT(issueDelete())); - if (hidden) { - menu.addAction(tr("Un-Hide"), this, SLOT(issueRestoreToView())); - } else { - menu.addAction(tr("Hide"), this, SLOT(issueRemoveFromView())); - } - } else if (state == DownloadManager::STATE_DOWNLOADING){ - menu.addAction(tr("Cancel"), this, SLOT(issueCancel())); - menu.addAction(tr("Pause"), this, SLOT(issuePause())); - menu.addAction(tr("Show in Folder"), this, SLOT(issueOpenInDownloadsFolder())); - } else if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR) || (state == DownloadManager::STATE_PAUSING)) { - menu.addAction(tr("Delete"), this, SLOT(issueDelete())); - menu.addAction(tr("Resume"), this, SLOT(issueResume())); - menu.addAction(tr("Show in Folder"), this, SLOT(issueOpenInDownloadsFolder())); - } - - menu.addSeparator(); - } - menu.addAction(tr("Delete Installed..."), this, SLOT(issueDeleteCompleted())); - menu.addAction(tr("Delete Uninstalled..."), this, SLOT(issueDeleteUninstalled())); - menu.addAction(tr("Delete All..."), this, SLOT(issueDeleteAll())); - - if (!hidden) { - menu.addSeparator(); - menu.addAction(tr("Hide Installed..."), this, SLOT(issueRemoveFromViewCompleted())); - menu.addAction(tr("Hide Uninstalled..."), this, SLOT(issueRemoveFromViewUninstalled())); - menu.addAction(tr("Hide All..."), this, SLOT(issueRemoveFromViewAll())); - } - if (hidden) { - menu.addSeparator(); - menu.addAction(tr("Un-Hide All..."), this, SLOT(issueRestoreToViewAll())); - } - - menu.exec(mouseEvent->globalPos()); - - event->accept(); - return true; - } - } - } catch (const std::exception &e) { - qCritical("failed to handle editor event: %s", e.what()); - } - return QItemDelegate::editorEvent(event, model, option, index); -} diff --git a/src/downloadlistwidget.h b/src/downloadlistwidget.h index 7a7a25f7..0c17de87 100644 --- a/src/downloadlistwidget.h +++ b/src/downloadlistwidget.h @@ -31,6 +31,8 @@ namespace Ui { class DownloadListWidget; } +class DownloadManager; + class DownloadListWidget : public QTreeView { Q_OBJECT @@ -39,33 +41,9 @@ public: explicit DownloadListWidget(QWidget *parent = 0); ~DownloadListWidget(); -signals: - void resumeDownload(int index); - -private slots: - void onDoubleClick(const QModelIndex &index); -}; - -class DownloadManager; - -class DownloadListWidgetDelegate : public QItemDelegate -{ - - Q_OBJECT - -public: - - DownloadListWidgetDelegate(DownloadManager *manager, bool metaDisplay, QTreeView *view, QObject *parent = 0); - ~DownloadListWidgetDelegate(); - - virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; - virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; - - void paintPendingDownload(int downloadIndex) const; - void paintRegularDownload(int downloadIndex) const; + void setManager(DownloadManager *manager); signals: - void installDownload(int index); void queryInfo(int index); void removeDownload(int index, bool deleteFile); @@ -77,19 +55,9 @@ signals: void openFile(int index); void openInDownloadsFolder(int index); -protected: - - QString sizeFormat(quint64 size) const; - bool editorEvent(QEvent *event, QAbstractItemModel *model, - const QStyleOptionViewItem &option, const QModelIndex &index); - -private: - - - void drawCache(QPainter *painter, const QStyleOptionViewItem &option, const QPixmap &cache) const; - private slots: - + void onDoubleClick(const QModelIndex &index); + void onCustomContextMenu(const QPoint &point); void issueInstall(); void issueDelete(); void issueRemoveFromView(); @@ -109,25 +77,9 @@ private slots: void issueRemoveFromViewUninstalled(); void issueQueryInfo(); - void stateChanged(int row, DownloadManager::DownloadState); - void resetCache(int); - private: - - DownloadListWidget *m_ItemWidget; DownloadManager *m_Manager; - - bool m_MetaDisplay; - - QLabel *m_NameLabel; - QLabel *m_SizeLabel; - QProgressBar *m_Progress; - QLabel *m_InstallLabel; int m_ContextRow; - - QTreeView *m_View; - - mutable QMap m_Cache; }; #endif // DOWNLOADLISTWIDGET_H diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp index f1cbf109..9f07b030 100644 --- a/src/downloadmanager.cpp +++ b/src/downloadmanager.cpp @@ -1853,4 +1853,4 @@ void DownloadManager::writeData(DownloadInfo *info) "Canceling download \"%2\"...").arg(ret).arg(fileName)); } } -} \ No newline at end of file +} diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 5ca60ef1..80ddf093 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -5152,45 +5152,26 @@ void MainWindow::on_actionEndorseMO_triggered() void MainWindow::updateDownloadListDelegate() { - /* - if (m_OrganizerCore.settings().compactDownloads()) { - ui->downloadView->setItemDelegate( - new DownloadListWidgetCompactDelegate(m_OrganizerCore.downloadManager(), - m_OrganizerCore.settings().metaDownloads(), - ui->downloadView, - ui->downloadView)); - } else { - ui->downloadView->setItemDelegate( - new DownloadListWidgetDelegate(m_OrganizerCore.downloadManager(), - m_OrganizerCore.settings().metaDownloads(), - ui->downloadView, - ui->downloadView)); - } - */ - DownloadListSortProxy *sortProxy = new DownloadListSortProxy(m_OrganizerCore.downloadManager(), ui->downloadView); sortProxy->setSourceModel(new DownloadList(m_OrganizerCore.downloadManager(), ui->downloadView)); connect(ui->downloadFilterEdit, SIGNAL(textChanged(QString)), sortProxy, SLOT(updateFilter(QString))); connect(ui->downloadFilterEdit, SIGNAL(textChanged(QString)), this, SLOT(downloadFilterChanged(QString))); ui->downloadView->setModel(sortProxy); + ui->downloadView->setManager(m_OrganizerCore.downloadManager()); //ui->downloadView->sortByColumn(1, Qt::DescendingOrder); ui->downloadView->header()->resizeSections(QHeaderView::Stretch); - connect(ui->downloadView, SIGNAL(resumeDownload(int)), m_OrganizerCore.downloadManager(), SLOT(resumeDownload(int))); - - /* - connect(ui->downloadView->itemDelegate(), SIGNAL(installDownload(int)), &m_OrganizerCore, SLOT(installDownload(int))); - connect(ui->downloadView->itemDelegate(), SIGNAL(queryInfo(int)), m_OrganizerCore.downloadManager(), SLOT(queryInfo(int))); - connect(ui->downloadView->itemDelegate(), SIGNAL(visitOnNexus(int)), m_OrganizerCore.downloadManager(), SLOT(visitOnNexus(int))); - connect(ui->downloadView->itemDelegate(), SIGNAL(openFile(int)), m_OrganizerCore.downloadManager(), SLOT(openFile(int))); - connect(ui->downloadView->itemDelegate(), SIGNAL(openInDownloadsFolder(int)), m_OrganizerCore.downloadManager(), SLOT(openInDownloadsFolder(int))); - connect(ui->downloadView->itemDelegate(), SIGNAL(removeDownload(int, bool)), m_OrganizerCore.downloadManager(), SLOT(removeDownload(int, bool))); - connect(ui->downloadView->itemDelegate(), SIGNAL(restoreDownload(int)), m_OrganizerCore.downloadManager(), SLOT(restoreDownload(int))); - connect(ui->downloadView->itemDelegate(), SIGNAL(cancelDownload(int)), m_OrganizerCore.downloadManager(), SLOT(cancelDownload(int))); - connect(ui->downloadView->itemDelegate(), SIGNAL(pauseDownload(int)), m_OrganizerCore.downloadManager(), SLOT(pauseDownload(int))); - connect(ui->downloadView->itemDelegate(), SIGNAL(resumeDownload(int)), this, SLOT(resumeDownload(int))); - */ + connect(ui->downloadView, SIGNAL(installDownload(int)), &m_OrganizerCore, SLOT(installDownload(int))); + connect(ui->downloadView, SIGNAL(queryInfo(int)), m_OrganizerCore.downloadManager(), SLOT(queryInfo(int))); + connect(ui->downloadView, SIGNAL(visitOnNexus(int)), m_OrganizerCore.downloadManager(), SLOT(visitOnNexus(int))); + connect(ui->downloadView, SIGNAL(openFile(int)), m_OrganizerCore.downloadManager(), SLOT(openFile(int))); + connect(ui->downloadView, SIGNAL(openInDownloadsFolder(int)), m_OrganizerCore.downloadManager(), SLOT(openInDownloadsFolder(int))); + connect(ui->downloadView, SIGNAL(removeDownload(int, bool)), m_OrganizerCore.downloadManager(), SLOT(removeDownload(int, bool))); + connect(ui->downloadView, SIGNAL(restoreDownload(int)), m_OrganizerCore.downloadManager(), SLOT(restoreDownload(int))); + connect(ui->downloadView, SIGNAL(cancelDownload(int)), m_OrganizerCore.downloadManager(), SLOT(cancelDownload(int))); + connect(ui->downloadView, SIGNAL(pauseDownload(int)), m_OrganizerCore.downloadManager(), SLOT(pauseDownload(int))); + connect(ui->downloadView, SIGNAL(resumeDownload(int)), this, SLOT(resumeDownload(int))); } diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 5dfd075b..771832fd 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1311,7 +1311,7 @@ p, li { white-space: pre-wrap; } - Qt::PreventContextMenu + Qt::CustomContextMenu true diff --git a/src/organizer_en.ts b/src/organizer_en.ts index 9b61eafc..e958c116 100644 --- a/src/organizer_en.ts +++ b/src/organizer_en.ts @@ -313,16 +313,26 @@ p, li { white-space: pre-wrap; } + Uninstalled + + + + Downloaded - + + Paused + + + + Information missing, please select "Query Info" from the context menu to re-retrieve. - + pending download @@ -337,392 +347,349 @@ p, li { white-space: pre-wrap; } - - Done - Double Click to install - - - Paused - Double Click to resume - - - - - - Installed - Double Click to re-install - - - - - - Uninstalled - Double Click to re-install - - - - - DownloadListWidgetCompact - - - - Placeholder - - - - - Done - - - - - DownloadListWidgetCompactDelegate - - - < game %1 mod %2 file %3 > - - - - - Pending - - - - - Paused + + Install - - Fetching Info 1 + + Query Info - - Fetching Info 2 + + Visit on Nexus - - Installed + + Open File - - Uninstalled + + + + Show in Folder - - Done + + + Delete - - - - - - - - Are you sure? + + Un-Hide - - This will permanently delete the selected download. + + Hide - - This will remove all finished downloads from this list and from disk. + + Cancel - - This will remove all installed downloads from this list and from disk. + + Pause - - This will remove all uninstalled downloads from this list and from disk. + + Resume - - This will permanently remove all finished downloads from this list (but NOT from disk). + + Delete Installed... - - This will permanently remove all installed downloads from this list (but NOT from disk). + + Delete Uninstalled... - - This will permanently remove all uninstalled downloads from this list (but NOT from disk). + + Delete All... - - Install + + Hide Installed... - - Query Info + + Hide Uninstalled... - - Visit on Nexus + + Hide All... - - Open File + + Un-Hide All... - - - - Show in Folder + + + + + Delete Files? - - Delete + + This will permanently delete the selected download. - - Un-Hide + + This will remove all finished downloads from this list and from disk. - - Hide + + This will remove all installed downloads from this list and from disk. - - Cancel + + This will remove all uninstalled downloads from this list and from disk. - - Pause + + + + Are you sure? - - Remove + + This will remove all finished downloads from this list (but NOT from disk). - - Resume + + This will remove all installed downloads from this list (but NOT from disk). - - Delete Installed... + + This will remove all uninstalled downloads from this list (but NOT from disk). + + + DownloadListWidgetCompact - - Delete Uninstalled... + + + Placeholder - - Delete All... + + Done + + + DownloadListWidgetCompactDelegate - - Hide Installed... + + < game %1 mod %2 file %3 > - - Hide Uninstalled... + + Pending - - Hide All... + + Paused - - Un-Hide All... + + Fetching Info 1 - - - DownloadListWidgetDelegate - - < game %1 mod %2 file %3 > + + Fetching Info 2 - - Pending + + Installed - - Fetching Info 1 + + Uninstalled - - Fetching Info 2 + + Done - - - - - Delete Files? + + + + + + + + Are you sure? - + This will permanently delete the selected download. - + This will remove all finished downloads from this list and from disk. - + This will remove all installed downloads from this list and from disk. - + This will remove all uninstalled downloads from this list and from disk. - - - - Are you sure? - - - - - This will remove all finished downloads from this list (but NOT from disk). + + This will permanently remove all finished downloads from this list (but NOT from disk). - - This will remove all installed downloads from this list (but NOT from disk). + + This will permanently remove all installed downloads from this list (but NOT from disk). - - This will remove all uninstalled downloads from this list (but NOT from disk). + + This will permanently remove all uninstalled downloads from this list (but NOT from disk). - + Install - + Query Info - + Visit on Nexus - + Open File - - - + + + Show in Folder - - + Delete - + Un-Hide - + Hide - + Cancel - + Pause - + + Remove + + + + Resume - + Delete Installed... - + Delete Uninstalled... - + Delete All... - + Hide Installed... - + Hide Uninstalled... - + Hide All... - + Un-Hide All... @@ -2470,7 +2437,7 @@ Please enter a name: - + Are you sure? @@ -2797,13 +2764,13 @@ You can also use online editors and converters instead. - + Enable selected - + Disable selected @@ -2864,13 +2831,13 @@ You can also use online editors and converters instead. - + Exception: - + Unknown exception @@ -3008,7 +2975,7 @@ Click OK to restart MO now. - + Set Priority @@ -3073,196 +3040,196 @@ Click OK to restart MO 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 -- cgit v1.3.1 From 895556f257c2625ac53371089835aab0d01979be Mon Sep 17 00:00:00 2001 From: Krzysztof Starecki Date: Mon, 31 Dec 2018 20:53:35 +0100 Subject: Add filetime column to download tab --- src/downloadlist.cpp | 12 +++++++----- src/downloadlist.h | 3 ++- src/downloadlistsortproxy.cpp | 4 +++- src/mainwindow.cpp | 2 +- src/mainwindow.ui | 2 +- 5 files changed, 14 insertions(+), 9 deletions(-) (limited to 'src/mainwindow.ui') diff --git a/src/downloadlist.cpp b/src/downloadlist.cpp index a0286aef..b21a5306 100644 --- a/src/downloadlist.cpp +++ b/src/downloadlist.cpp @@ -47,7 +47,7 @@ int DownloadList::rowCount(const QModelIndex&) const int DownloadList::columnCount(const QModelIndex&) const { - return 3; + return 4; } @@ -68,10 +68,11 @@ QVariant DownloadList::headerData(int section, Qt::Orientation orientation, int if ((role == Qt::DisplayRole) && (orientation == Qt::Horizontal)) { switch (section) { - case COL_NAME : return tr("Name"); - case COL_SIZE : return tr("Size"); - case COL_STATUS : return tr("Status"); - default : return QVariant(); + case COL_NAME: return tr("Name"); + case COL_SIZE: return tr("Size"); + case COL_STATUS: return tr("Status"); + case COL_FILETIME: return tr("Filetime"); + default: return QVariant(); } } else { return QAbstractItemModel::headerData(section, orientation, role); @@ -93,6 +94,7 @@ QVariant DownloadList::data(const QModelIndex &index, int role) const switch (index.column()) { case COL_NAME: return m_MetaDisplay ? m_Manager->getDisplayName(index.row()) : m_Manager->getFileName(index.row()); case COL_SIZE: return sizeFormat(m_Manager->getFileSize(index.row())); + case COL_FILETIME: return m_Manager->getFileTime(index.row()); case COL_STATUS: switch (m_Manager->getState(index.row())) { // STATE_DOWNLOADING handled by DownloadProgressDelegate diff --git a/src/downloadlist.h b/src/downloadlist.h index a504f209..2c32a397 100644 --- a/src/downloadlist.h +++ b/src/downloadlist.h @@ -39,7 +39,8 @@ public: enum EColumn { COL_NAME = 0, COL_STATUS, - COL_SIZE + COL_SIZE, + COL_FILETIME }; public: diff --git a/src/downloadlistsortproxy.cpp b/src/downloadlistsortproxy.cpp index 1df3a9f1..dc97dc3e 100644 --- a/src/downloadlistsortproxy.cpp +++ b/src/downloadlistsortproxy.cpp @@ -50,8 +50,10 @@ bool DownloadListSortProxy::lessThan(const QModelIndex &left, return m_Manager->getFileTime(left.row()) < m_Manager->getFileTime(right.row()); else return leftState > rightState; - } else if(left.column() == DownloadList::COL_SIZE){ + } else if (left.column() == DownloadList::COL_SIZE) { return m_Manager->getFileSize(left.row()) < m_Manager->getFileSize(right.row()); + } else if (left.column() == DownloadList::COL_FILETIME) { + return m_Manager->getFileTime(left.row()) < m_Manager->getFileTime(right.row()); } else { return leftIndex < rightIndex; } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 63606833..f913ad0a 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -5160,7 +5160,7 @@ void MainWindow::initDownloadView() ui->downloadView->setModel(sortProxy); ui->downloadView->setManager(m_OrganizerCore.downloadManager()); ui->downloadView->setItemDelegate(new DownloadProgressDelegate(m_OrganizerCore.downloadManager(), sortProxy, ui->downloadView)); - ui->downloadView->setUniformRowHeights(true); + ui->downloadView->setUniformRowHeights(false); ui->downloadView->header()->setStretchLastSection(false); ui->downloadView->header()->setSectionResizeMode(QHeaderView::Interactive); ui->downloadView->header()->setSectionResizeMode(0, QHeaderView::Stretch); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 771832fd..ba4b8d63 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1365,7 +1365,7 @@ p, li { white-space: pre-wrap; } 15 - true + false -- cgit v1.3.1 From 6fa416fc52f21ddb3eebcd1568baf8394e89ef6b Mon Sep 17 00:00:00 2001 From: Krzysztof Starecki Date: Tue, 1 Jan 2019 21:47:59 +0100 Subject: Add default download row sizes for generic styles, sanitize mainwindow.ui --- src/mainwindow.cpp | 12 +++- src/mainwindow.ui | 47 ++++---------- src/organizer_en.ts | 172 ++++++++++++++++++++++++++-------------------------- 3 files changed, 107 insertions(+), 124 deletions(-) (limited to 'src/mainwindow.ui') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 80db447c..224ce0a9 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -5185,10 +5185,18 @@ void MainWindow::initDownloadView() void MainWindow::updateDownloadView() { - if (m_OrganizerCore.settings().compactDownloads()) + // set the view attribute and default row sizes + if (m_OrganizerCore.settings().compactDownloads()) { ui->downloadView->setProperty("downloadView", "compact"); - else + setStyleSheet("DownloadListWidget::item { padding: 4px; }"); + } else { ui->downloadView->setProperty("downloadView", "standard"); + setStyleSheet("DownloadListWidget::item { padding: 16px; }"); + } + + // reapply global stylesheet on the widget level (!) to override the defaults + ui->downloadView->setStyleSheet(styleSheet()); + ui->downloadView->setMetaDisplay(m_OrganizerCore.settings().metaDownloads()); ui->downloadView->style()->unpolish(ui->downloadView); ui->downloadView->style()->polish(ui->downloadView); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index ba4b8d63..547faaa9 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1303,7 +1303,7 @@ p, li { white-space: pre-wrap; } - + 320 @@ -1322,51 +1322,21 @@ p, li { white-space: pre-wrap; } This is a list of mods you downloaded from Nexus. Double click one to install it. You can also drag an archive into here. - - Qt::ScrollBarAlwaysOn - - - Qt::ScrollBarAsNeeded - - + true - - QAbstractItemView::DragDrop - - - Qt::MoveAction - - + true - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectRows - - - QAbstractItemView::ScrollPerPixel - - + 0 - + false - + true - - 50 - - - 15 - - - false - @@ -1683,6 +1653,11 @@ Right now this has very limited functionality QLCDNumber
lcdnumber.h
+ + DownloadListWidget + QWidget +
downloadlistwidget.h
+
diff --git a/src/organizer_en.ts b/src/organizer_en.ts index de09d513..4c6eb51b 100644 --- a/src/organizer_en.ts +++ b/src/organizer_en.ts @@ -1465,7 +1465,7 @@ p, li { white-space: pre-wrap; } - + Filter @@ -1675,145 +1675,145 @@ p, li { white-space: pre-wrap; } - + 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! @@ -1821,39 +1821,39 @@ 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 @@ -2281,7 +2281,7 @@ Please enter a name: - + Are you sure? @@ -2608,13 +2608,13 @@ You can also use online editors and converters instead. - + Enable selected - + Disable selected @@ -2675,13 +2675,13 @@ You can also use online editors and converters instead. - + Exception: - + Unknown exception @@ -2819,7 +2819,7 @@ Click OK to restart MO now. - + Set Priority @@ -2884,196 +2884,196 @@ Click OK to restart MO 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 -- cgit v1.3.1 From d32695843d4c3fa888b3d26bf20a9126029020b0 Mon Sep 17 00:00:00 2001 From: Al Date: Mon, 7 Jan 2019 13:28:46 +0100 Subject: Fix drop to downloads tab. Fix DownloadView to be QtreeView in QCreator. --- src/mainwindow.ui | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'src/mainwindow.ui') diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 547faaa9..4f5400dd 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1303,7 +1303,7 @@ p, li { white-space: pre-wrap; } - + 320 @@ -1322,19 +1322,25 @@ p, li { white-space: pre-wrap; } This is a list of mods you downloaded from Nexus. Double click one to install it. You can also drag an archive into here. - - true + + QAbstractItemView::NoEditTriggers + + + QAbstractItemView::DropOnly - + + Qt::MoveAction + + true - + 0 - + false - + true @@ -1655,7 +1661,7 @@ Right now this has very limited functionality DownloadListWidget - QWidget + QTreeView
downloadlistwidget.h
-- cgit v1.3.1 From ea3df2e9bdb02f44f17acc2f389fb6280d0dc98b Mon Sep 17 00:00:00 2001 From: Al Date: Sat, 12 Jan 2019 14:35:09 +0100 Subject: Some more drag and drop related changes, still no fix though. --- src/mainwindow.ui | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src/mainwindow.ui') diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 4f5400dd..83b99486 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1322,11 +1322,14 @@ p, li { white-space: pre-wrap; } This is a list of mods you downloaded from Nexus. Double click one to install it. You can also drag an archive into here. - - QAbstractItemView::NoEditTriggers + + Qt::ScrollBarAlwaysOn + + + true - QAbstractItemView::DropOnly + QAbstractItemView::DragDrop Qt::MoveAction @@ -1334,6 +1337,9 @@ p, li { white-space: pre-wrap; } true + + QAbstractItemView::ScrollPerPixel + 0 -- cgit v1.3.1 From cfc0b3c05551a5fb612258a3afe81fbcfca5c645 Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Wed, 30 Jan 2019 19:31:25 -0600 Subject: Rename problems to notifications --- src/mainwindow.cpp | 18 +++++++++--------- src/mainwindow.h | 2 +- src/mainwindow.ui | 18 ++++++++++-------- src/problemsdialog.ui | 2 +- 4 files changed, 21 insertions(+), 19 deletions(-) (limited to 'src/mainwindow.ui') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index c22bd485..7913391e 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -658,9 +658,9 @@ void MainWindow::updateProblemsButton() { size_t numProblems = checkForProblems(); if (numProblems > 0) { - ui->actionProblems->setEnabled(true); - ui->actionProblems->setIconText(tr("Problems")); - ui->actionProblems->setToolTip(tr("There are potential problems with your setup")); + ui->actionNotifications->setEnabled(true); + ui->actionNotifications->setIconText(tr("Notifications")); + ui->actionNotifications->setToolTip(tr("There are notifications to read")); QPixmap mergedIcon = QPixmap(":/MO/gui/warning").scaled(64, 64); { @@ -668,12 +668,12 @@ void MainWindow::updateProblemsButton() std::string badgeName = std::string(":/MO/gui/badge_") + (numProblems < 10 ? std::to_string(static_cast(numProblems)) : "more"); painter.drawPixmap(32, 32, 32, 32, QPixmap(badgeName.c_str())); } - ui->actionProblems->setIcon(QIcon(mergedIcon)); + ui->actionNotifications->setIcon(QIcon(mergedIcon)); } else { - ui->actionProblems->setEnabled(false); - ui->actionProblems->setIconText(tr("No Problems")); - ui->actionProblems->setToolTip(tr("Everything seems to be in order")); - ui->actionProblems->setIcon(QIcon(":/MO/gui/warning")); + ui->actionNotifications->setEnabled(false); + ui->actionNotifications->setIconText(tr("No Notifications")); + ui->actionNotifications->setToolTip(tr("There are no notifications")); + ui->actionNotifications->setIcon(QIcon(":/MO/gui/warning")); } } @@ -5667,7 +5667,7 @@ void MainWindow::on_bsaList_itemChanged(QTreeWidgetItem*, int) m_CheckBSATimer.start(500); } -void MainWindow::on_actionProblems_triggered() +void MainWindow::on_actionNotifications_triggered() { ProblemsDialog problems(m_PluginContainer.plugins(), this); if (problems.hasProblems()) { diff --git a/src/mainwindow.h b/src/mainwindow.h index a8601bee..e919ed2c 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -611,7 +611,7 @@ private slots: // ui slots void on_actionInstallMod_triggered(); void on_actionModify_Executables_triggered(); void on_actionNexus_triggered(); - void on_actionProblems_triggered(); + void on_actionNotifications_triggered(); void on_actionSettings_triggered(); void on_actionUpdate_triggered(); void on_actionEndorseMO_triggered(); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index e30466ac..72cfa21b 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1106,7 +1106,7 @@ p, li { white-space: pre-wrap; }
- + Qt::CustomContextMenu @@ -1478,7 +1478,7 @@ p, li { white-space: pre-wrap; } - + @@ -1603,7 +1603,7 @@ p, li { white-space: pre-wrap; } Mod Organizer is up-to-date
- + false @@ -1612,13 +1612,10 @@ p, li { white-space: pre-wrap; } :/MO/gui/warning:/MO/gui/warning - No Problems + No Notifications - This button will be highlighted if MO discovered potential problems in your setup and provide tips on how to fix them. - -!Work in progress! -Right now this has very limited functionality + This button will be highlighted if MO discovered potential problems in your setup and provide tips on how to fix them. @@ -1693,6 +1690,11 @@ Right now this has very limited functionality QTreeView
downloadlistwidget.h
+ + MOBase::SortableTreeWidget + QWidget +
sortabletreewidget.h
+
diff --git a/src/problemsdialog.ui b/src/problemsdialog.ui index 313a3c74..a1712d4a 100644 --- a/src/problemsdialog.ui +++ b/src/problemsdialog.ui @@ -11,7 +11,7 @@ - Problems + Notifications -- cgit v1.3.1 From 4932c52136ce1c8a704c5322e26ca75e55726a15 Mon Sep 17 00:00:00 2001 From: Silarn Date: Mon, 28 Jan 2019 18:36:19 -0600 Subject: Add counter for API requests --- src/mainwindow.cpp | 26 + src/mainwindow.h | 2 + src/mainwindow.ui | 3437 ++++++++++++++++++++++++------------------------ src/nexusinterface.cpp | 7 +- src/nexusinterface.h | 1 + 5 files changed, 1769 insertions(+), 1704 deletions(-) (limited to 'src/mainwindow.ui') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index f875c95c..2f39bf7a 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -363,6 +363,12 @@ MainWindow::MainWindow(QSettings &initSettings ui->bossButton->setToolTip(tr("There is no supported sort mechanism for this game. You will probably have to use a third-party tool.")); } + ui->apiRequests->setAutoFillBackground(true); + QPalette palette = ui->apiRequests->palette(); + palette.setColor(ui->apiRequests->backgroundRole(), Qt::darkGreen); + palette.setColor(ui->apiRequests->foregroundRole(), Qt::white); + ui->apiRequests->setPalette(palette); + connect(ui->savegameList, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(saveSelectionChanged(QListWidgetItem*))); connect(ui->modList, SIGNAL(dropModeUpdate(bool)), m_OrganizerCore.modList(), SLOT(dropModeUpdate(bool))); @@ -398,6 +404,7 @@ MainWindow::MainWindow(QSettings &initSettings this, SLOT(updateWindowTitle(const QString&, bool))); connect(NexusInterface::instance(&pluginContainer)->getAccessManager(), SIGNAL(credentialsReceived(const QString&, bool)), NexusInterface::instance(&m_PluginContainer), SLOT(setRateMax(const QString&, bool))); + connect(NexusInterface::instance(&pluginContainer), SIGNAL(requestsChanged(int, int)), this, SLOT(updateAPICounter(int, int))); connect(&TutorialManager::instance(), SIGNAL(windowTutorialFinished(QString)), this, SLOT(windowTutorialFinished(QString))); connect(ui->tabWidget, SIGNAL(currentChanged(int)), &TutorialManager::instance(), SIGNAL(tabChanged(int))); @@ -5619,6 +5626,25 @@ void MainWindow::nxmRequestFailed(QString gameName, int modID, int, QVariant, in } +void MainWindow::updateAPICounter(int queueCount, int requestsRemaining) +{ + ui->apiRequests->setText(QString("API: Q: %1 | T: %2").arg(queueCount).arg(requestsRemaining)); + if (requestsRemaining > 150) { + QPalette palette = ui->apiRequests->palette(); + palette.setColor(ui->apiRequests->backgroundRole(), Qt::darkGreen); + ui->apiRequests->setPalette(palette); + } else if (requestsRemaining < 50) { + QPalette palette = ui->apiRequests->palette(); + palette.setColor(ui->apiRequests->backgroundRole(), Qt::darkRed); + ui->apiRequests->setPalette(palette); + } else { + QPalette palette = ui->apiRequests->palette(); + palette.setColor(ui->apiRequests->backgroundRole(), Qt::darkYellow); + ui->apiRequests->setPalette(palette); + } +} + + BSA::EErrorCode MainWindow::extractBSA(BSA::Archive &archive, BSA::Folder::Ptr folder, const QString &destination, QProgressDialog &progress) { diff --git a/src/mainwindow.h b/src/mainwindow.h index bf475120..900f7cba 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -515,6 +515,8 @@ private slots: void nxmDownloadURLs(QString, int modID, int fileID, QVariant userData, QVariant resultData, int requestID); void nxmRequestFailed(QString gameName, int modID, int fileID, QVariant userData, int requestID, QNetworkReply::NetworkError error, const QString &errorString); + void updateAPICounter(int queueCount, int requestsRemaining); + void editCategories(); void deselectFilters(); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 72cfa21b..1aa7ce4c 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1,1703 +1,1734 @@ - - - MainWindow - - - - 0 - 0 - 926 - 710 - - - - true - - - Mod Organizer - - - - mo_icon.icomo_icon.ico - - - false - - - - - 0 - 0 - - - - - - - Qt::Vertical - - - - - - - - - Categories - - - - 0 - - - 3 - - - 7 - - - 3 - - - 1 - - - - - - 120 - 0 - - - - - 214 - 16777215 - - - - Qt::CustomContextMenu - - - QAbstractItemView::ExtendedSelection - - - 0 - - - true - - - false - - - - 1 - - - - - - - - false - - - - 0 - 0 - - - - - 0 - 25 - - - - Clear - - - true - - - - - - - - 0 - 0 - - - - - - - If checked, only mods that match all selected categories are displayed. - - - And - - - true - - - - - - - If checked, all mods that match at least one of the selected categories are displayed. - - - Or - - - - - - - - - - - - - - - - 0 - 0 - - - - Qt::Horizontal - - - - - 2 - - - - - - - - 0 - 0 - - - - Profile - - - profileBox - - - - - - - Pick a module collection - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Create profiles here. Each profile contains its own list of active mods and esps. This way you can quickly switch between setups for different play throughs.</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Please note that right now your esp load order is not kept seperate for different profiles.</span></p></body></html> - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 16777215 - 16777215 - - - - Open list options... - - - Refresh list. This is usually not necessary unless you modified data outside the program. - - - - - - - :/MO/gui/settings:/MO/gui/settings - - - - 16 - 16 - - - - - - - - Show Open Folders menu... - - - - - - - :/MO/gui/open_folder:/MO/gui/open_folder - - - - - - - Restore Backup... - - - - - - - :/MO/gui/restore:/MO/gui/restore - - - - - - - Create Backup - - - - - - - :/MO/gui/backup:/MO/gui/backup - - - - - - - Active: - - - - - - - - 0 - 26 - - - - 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. - - - QFrame::Sunken - - - 5 - - - QLCDNumber::Flat - - - - - - - - - - 330 - 400 - - - - - - - - - 64 - 64 - 64 - - - - - - - 255 - 0 - 0 - - - - - - - 0 - 170 - 0 - - - - - - - - - 64 - 64 - 64 - - - - - - - 255 - 0 - 0 - - - - - - - 0 - 170 - 0 - - - - - - - - - 120 - 120 - 120 - - - - - - - 255 - 0 - 0 - - - - - - - 0 - 170 - 0 - - - - - - - - Qt::CustomContextMenu - - - 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. - - - - - - QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked - - - true - - - true - - - QAbstractItemView::DragDrop - - - Qt::MoveAction - - - true - - - QAbstractItemView::ExtendedSelection - - - QAbstractItemView::SelectRows - - - 20 - - - true - - - true - - - true - - - false - - - 35 - - - true - - - false - - - - - - - - - - 20 - 16777215 - - - - x - - - - 20 - 20 - - - - true - - - - - - - - 0 - 0 - - - - Filter - - - - - - - - 8 - true - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 0 - 22 - - - - - 95 - 0 - - - - false - - - Qt::RightToLeft - - - border:1px solid #ff0000; - - - Clear all Filters - - - - :/MO/gui/edit_clear:/MO/gui/edit_clear - - - - 12 - 12 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 220 - 0 - - - - Qt::ClickFocus - - - - No groups - - - - - Categories - - - - - Nexus IDs - - - - - - - - - 220 - 0 - - - - Filter - - - - - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 40 - - - - - 9 - 75 - true - - - - 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; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Choose the program to run. Once you start using ModOrganizer, you should always run your game and tools from here or through shortcuts created here, otherwise mods installed through MO will not be visible.</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">You can add new Tools to this list, but I can't promise tools I haven't tested will work.</span></p></body></html> - - - - 32 - 32 - - - - false - - - - - - - - - - 0 - 0 - - - - - 120 - 0 - - - - - 16777215 - 16777215 - - - - - 10 - 75 - true - - - - 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; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Run the selected program with ModOrganizer enabled.</span></p></body></html> - - - - - - Run - - - - :/MO/gui/run:/MO/gui/run - - - - 36 - 36 - - - - - - - - - 0 - 0 - - - - - 140 - 0 - - - - - 16777215 - 16777215 - - - - - 0 - 0 - - - - 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; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">This creates a start menu shortcut that directly starts the selected program with the MO active.</span></p></body></html> - - - Shortcut - - - - :/MO/gui/link:/MO/gui/link - - - - - - - - - - - - - 340 - 250 - - - - - 16777215 - 16777215 - - - - Qt::NoContextMenu - - - QTabWidget::Rounded - - - 0 - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - Plugins - - - - 6 - - - 6 - - - 6 - - - 0 - - - - - - - true - - - Sort - - - - :/MO/gui/sort:/MO/gui/sort - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Restore Backup... - - - - - - - :/MO/gui/restore:/MO/gui/restore - - - - 16 - 16 - - - - - - - - Create Backup - - - - - - - :/MO/gui/backup:/MO/gui/backup - - - - - - - Active: - - - - - - - - 0 - 26 - - - - 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. - - - QFrame::Sunken - - - 4 - - - QLCDNumber::Flat - - - - - - - - - - 250 - 250 - - - - - - - - - 64 - 64 - 64 - - - - - - - - - 64 - 64 - 64 - - - - - - - - - 120 - 120 - 120 - - - - - - - - Qt::CustomContextMenu - - - 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; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">This list contains the esps, esms, and esls contained in the active mods. These require their own load order. Use drag&amp;drop to modify this load order. Please note that MO will only save the load order for mods that are active/checked.<br />There is a great tool named &quot;BOSS&quot; to automatically sort these files.</span></p></body></html> - - - QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked - - - true - - - false - - - QAbstractItemView::InternalMove - - - Qt::MoveAction - - - true - - - QAbstractItemView::ExtendedSelection - - - QAbstractItemView::SelectRows - - - 0 - - - true - - - false - - - true - - - false - - - false - - - - - - - - - - - - Filter - - - - - - - - - - false - - - Archives - - - - 6 - - - 6 - - - 6 - - - 6 - - - - - - - <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> - - - true - - - - - - - - - Qt::CustomContextMenu - - - 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! - - BSAs checked here are loaded in such a way that your installation order is obeyed properly. - - - false - - - false - - - false - - - 20 - - - true - - - 1 - - - - Archives - - - - - - - - - Data - - - - 6 - - - 6 - - - 6 - - - 6 - - - - - refresh data-directory overview - - - Refresh the overview. This may take a moment. - - - Refresh - - - - :/MO/gui/resources/view-refresh.png:/MO/gui/resources/view-refresh.png - - - - - - - - - Qt::CustomContextMenu - - - This is an overview of your data directory as visible to the game (and tools). - - - true - - - true - - - 400 - - - - File - - - - - Mod - - - - - - - - - - - - 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 - - - - - - - - - - Saves - - - - 6 - - - 6 - - - 6 - - - 6 - - - - - Qt::CustomContextMenu - - - - - - <!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 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> - - - QAbstractItemView::ExtendedSelection - - - QAbstractItemView::SelectRows - - - - - - - - Downloads - - - - 2 - - - 2 - - - 2 - - - 2 - - - - - Refresh downloads view - - - Refresh - - - - :/MO/gui/resources/view-refresh.png:/MO/gui/resources/view-refresh.png - - - - - - - - - - 320 - 0 - - - - Qt::CustomContextMenu - - - true - - - - - - This is a list of mods you downloaded from Nexus. Double click one to install it. You can also drag an archive into here. - - - Qt::ScrollBarAlwaysOn - - - true - - - QAbstractItemView::DragDrop - - - Qt::MoveAction - - - true - - - QAbstractItemView::ScrollPerPixel - - - 0 - - - false - - - true - - - - - - - - - - - Show Hidden - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Filter - - - - - - - - - - - - - - - - - - Qt::ActionsContextMenu - - - QAbstractItemView::NoSelection - - - true - - - false - - - true - - - - - - - - - true - - - Qt::CustomContextMenu - - - Tool Bar - - - false - - - - 42 - 36 - - - - Qt::ToolButtonIconOnly - - - false - - - TopToolBarArea - - - false - - - - - - - - - - - - - - - - - - - :/MO/gui/resources/system-installer.png:/MO/gui/resources/system-installer.png - - - Install Mod - - - Install &Mod - - - Install a new mod from an archive - - - Ctrl+M - - - - - - :/MO/gui/profiles:/MO/gui/profiles - - - Profiles - - - &Profiles - - - Configure Profiles - - - Ctrl+P - - - - - - :/MO/gui/icon_executable:/MO/gui/icon_executable - - - Executables - - - &Executables - - - Configure the executables that can be started through Mod Organizer - - - Ctrl+E - - - - - - :/MO/gui/plugins:/MO/gui/plugins - - - Tools - - - &Tools - - - Tools - - - Ctrl+I - - - - - - :/MO/gui/settings:/MO/gui/settings - - - Settings - - - &Settings - - - Configure settings and workarounds - - - Ctrl+S - - - - - - :/MO/gui/resources/internet-web-browser.png:/MO/gui/resources/internet-web-browser.png - - - Nexus - - - Search nexus network for more mods - - - Ctrl+N - - - - - false - - - - :/MO/gui/update:/MO/gui/update - - - Update - - - Mod Organizer is up-to-date - - - - - false - - - - :/MO/gui/warning:/MO/gui/warning - - - No Notifications - - - This button will be highlighted if MO discovered potential problems in your setup and provide tips on how to fix them. - - - - - - :/MO/gui/help:/MO/gui/help - - - Help - - - Help - - - Ctrl+H - - - - - - :/MO/gui/icon_favorite:/MO/gui/icon_favorite - - - Endorse MO - - - Endorse Mod Organizer - - - - - Copy Log to Clipboard - - - - - - :/MO/gui/instance_switch:/MO/gui/instance_switch - - - Change Game - - - Open the Instance selection dialog to manage a different Game - - - - - - - MOBase::LineEditClear - QLineEdit -
lineeditclear.h
-
- - ModListView - QTreeView -
modlistview.h
-
- - PluginListView - QTreeView -
pluginlistview.h
-
- - LCDNumber - QLCDNumber -
lcdnumber.h
-
- - DownloadListWidget - QTreeView -
downloadlistwidget.h
-
- - MOBase::SortableTreeWidget - QWidget -
sortabletreewidget.h
-
-
- - - - -
+ + + MainWindow + + + + 0 + 0 + 926 + 710 + + + + true + + + Mod Organizer + + + + mo_icon.icomo_icon.ico + + + false + + + + + 0 + 0 + + + + + + + Qt::Vertical + + + + + + + + + Categories + + + + 0 + + + 3 + + + 7 + + + 3 + + + 1 + + + + + + 120 + 0 + + + + + 214 + 16777215 + + + + Qt::CustomContextMenu + + + QAbstractItemView::ExtendedSelection + + + 0 + + + true + + + false + + + + 1 + + + + + + + + false + + + + 0 + 0 + + + + + 0 + 25 + + + + Clear + + + true + + + + + + + + 0 + 0 + + + + + + + If checked, only mods that match all selected categories are displayed. + + + And + + + true + + + + + + + If checked, all mods that match at least one of the selected categories are displayed. + + + Or + + + + + + + + + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + + + 2 + + + + + + + + 0 + 0 + + + + Profile + + + profileBox + + + + + + + Pick a module collection + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Create profiles here. Each profile contains its own list of active mods and esps. This way you can quickly switch between setups for different play throughs.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Please note that right now your esp load order is not kept seperate for different profiles.</span></p></body></html> + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 16777215 + 16777215 + + + + Open list options... + + + Refresh list. This is usually not necessary unless you modified data outside the program. + + + + + + + :/MO/gui/settings:/MO/gui/settings + + + + 16 + 16 + + + + + + + + Show Open Folders menu... + + + + + + + :/MO/gui/open_folder:/MO/gui/open_folder + + + + + + + Restore Backup... + + + + + + + :/MO/gui/restore:/MO/gui/restore + + + + + + + Create Backup + + + + + + + :/MO/gui/backup:/MO/gui/backup + + + + + + + Active: + + + + + + + + 0 + 26 + + + + 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. + + + QFrame::Sunken + + + 5 + + + QLCDNumber::Flat + + + + + + + + + + 330 + 400 + + + + + + + + + 64 + 64 + 64 + + + + + + + 255 + 0 + 0 + + + + + + + 0 + 170 + 0 + + + + + + + + + 64 + 64 + 64 + + + + + + + 255 + 0 + 0 + + + + + + + 0 + 170 + 0 + + + + + + + + + 120 + 120 + 120 + + + + + + + 255 + 0 + 0 + + + + + + + 0 + 170 + 0 + + + + + + + + Qt::CustomContextMenu + + + 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. + + + + + + QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked + + + true + + + true + + + QAbstractItemView::DragDrop + + + Qt::MoveAction + + + true + + + QAbstractItemView::ExtendedSelection + + + QAbstractItemView::SelectRows + + + 20 + + + true + + + true + + + true + + + false + + + 35 + + + true + + + false + + + + + + + + + + 20 + 16777215 + + + + x + + + + 20 + 20 + + + + true + + + + + + + + 0 + 0 + + + + Filter + + + + + + + + 8 + true + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + API Queued Requests and Throttle Count + + + This tracks the number of queues Nexus API requests on the left and the current requests remaining before being throttled. You have 300 requests as a regular user and 600 as a premium user. These requests renew at the rate of one per second. + + + QFrame::StyledPanel + + + QFrame::Sunken + + + 2 + + + 1 + + + API: Q: 0 | Ts: 300 + + + Qt::AlignCenter + + + 2 + + + + + + + + 0 + 0 + + + + + 0 + 22 + + + + + 95 + 0 + + + + false + + + Qt::RightToLeft + + + border:1px solid #ff0000; + + + Clear all Filters + + + + :/MO/gui/edit_clear:/MO/gui/edit_clear + + + + 12 + 12 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 220 + 0 + + + + Qt::ClickFocus + + + + No groups + + + + + Categories + + + + + Nexus IDs + + + + + + + + + 220 + 0 + + + + Filter + + + + + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 40 + + + + + 9 + 75 + true + + + + 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; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Choose the program to run. Once you start using ModOrganizer, you should always run your game and tools from here or through shortcuts created here, otherwise mods installed through MO will not be visible.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">You can add new Tools to this list, but I can't promise tools I haven't tested will work.</span></p></body></html> + + + + 32 + 32 + + + + false + + + + + + + + + + 0 + 0 + + + + + 120 + 0 + + + + + 16777215 + 16777215 + + + + + 10 + 75 + true + + + + 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; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Run the selected program with ModOrganizer enabled.</span></p></body></html> + + + + + + Run + + + + :/MO/gui/run:/MO/gui/run + + + + 36 + 36 + + + + + + + + + 0 + 0 + + + + + 140 + 0 + + + + + 16777215 + 16777215 + + + + + 0 + 0 + + + + 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; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">This creates a start menu shortcut that directly starts the selected program with the MO active.</span></p></body></html> + + + Shortcut + + + + :/MO/gui/link:/MO/gui/link + + + + + + + + + + + + + 340 + 250 + + + + + 16777215 + 16777215 + + + + Qt::NoContextMenu + + + QTabWidget::Rounded + + + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Plugins + + + + 6 + + + 6 + + + 6 + + + 0 + + + + + + + true + + + Sort + + + + :/MO/gui/sort:/MO/gui/sort + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Restore Backup... + + + + + + + :/MO/gui/restore:/MO/gui/restore + + + + 16 + 16 + + + + + + + + Create Backup + + + + + + + :/MO/gui/backup:/MO/gui/backup + + + + + + + Active: + + + + + + + + 0 + 26 + + + + 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. + + + QFrame::Sunken + + + 4 + + + QLCDNumber::Flat + + + + + + + + + + 250 + 250 + + + + + + + + + 64 + 64 + 64 + + + + + + + + + 64 + 64 + 64 + + + + + + + + + 120 + 120 + 120 + + + + + + + + Qt::CustomContextMenu + + + 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; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">This list contains the esps, esms, and esls contained in the active mods. These require their own load order. Use drag&amp;drop to modify this load order. Please note that MO will only save the load order for mods that are active/checked.<br />There is a great tool named &quot;BOSS&quot; to automatically sort these files.</span></p></body></html> + + + QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked + + + true + + + false + + + QAbstractItemView::InternalMove + + + Qt::MoveAction + + + true + + + QAbstractItemView::ExtendedSelection + + + QAbstractItemView::SelectRows + + + 0 + + + true + + + false + + + true + + + false + + + false + + + + + + + + + + + + Filter + + + + + + + + + + false + + + Archives + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + + <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> + + + true + + + + + + + + + Qt::CustomContextMenu + + + 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! + + BSAs checked here are loaded in such a way that your installation order is obeyed properly. + + + false + + + false + + + false + + + 20 + + + true + + + 1 + + + + Archives + + + + + + + + + Data + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + refresh data-directory overview + + + Refresh the overview. This may take a moment. + + + Refresh + + + + :/MO/gui/resources/view-refresh.png:/MO/gui/resources/view-refresh.png + + + + + + + + + Qt::CustomContextMenu + + + This is an overview of your data directory as visible to the game (and tools). + + + true + + + true + + + 400 + + + + File + + + + + Mod + + + + + + + + + + + + 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 + + + + + + + + + + Saves + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + Qt::CustomContextMenu + + + + + + <!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 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> + + + QAbstractItemView::ExtendedSelection + + + QAbstractItemView::SelectRows + + + + + + + + Downloads + + + + 2 + + + 2 + + + 2 + + + 2 + + + + + Refresh downloads view + + + Refresh + + + + :/MO/gui/resources/view-refresh.png:/MO/gui/resources/view-refresh.png + + + + + + + + + + 320 + 0 + + + + Qt::CustomContextMenu + + + true + + + + + + This is a list of mods you downloaded from Nexus. Double click one to install it. You can also drag an archive into here. + + + Qt::ScrollBarAlwaysOn + + + true + + + QAbstractItemView::DragDrop + + + Qt::MoveAction + + + true + + + QAbstractItemView::ScrollPerPixel + + + 0 + + + false + + + true + + + + + + + + + + + Show Hidden + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Filter + + + + + + + + + + + + + + + + + + Qt::ActionsContextMenu + + + QAbstractItemView::NoSelection + + + true + + + false + + + true + + + + + + + + + true + + + Qt::CustomContextMenu + + + Tool Bar + + + false + + + + 42 + 36 + + + + Qt::ToolButtonIconOnly + + + false + + + TopToolBarArea + + + false + + + + + + + + + + + + + + + + + + + :/MO/gui/resources/system-installer.png:/MO/gui/resources/system-installer.png + + + Install Mod + + + Install &Mod + + + Install a new mod from an archive + + + Ctrl+M + + + + + + :/MO/gui/profiles:/MO/gui/profiles + + + Profiles + + + &Profiles + + + Configure Profiles + + + Ctrl+P + + + + + + :/MO/gui/icon_executable:/MO/gui/icon_executable + + + Executables + + + &Executables + + + Configure the executables that can be started through Mod Organizer + + + Ctrl+E + + + + + + :/MO/gui/plugins:/MO/gui/plugins + + + Tools + + + &Tools + + + Tools + + + Ctrl+I + + + + + + :/MO/gui/settings:/MO/gui/settings + + + Settings + + + &Settings + + + Configure settings and workarounds + + + Ctrl+S + + + + + + :/MO/gui/resources/internet-web-browser.png:/MO/gui/resources/internet-web-browser.png + + + Nexus + + + Search nexus network for more mods + + + Ctrl+N + + + + + false + + + + :/MO/gui/update:/MO/gui/update + + + Update + + + Mod Organizer is up-to-date + + + + + false + + + + :/MO/gui/warning:/MO/gui/warning + + + No Notifications + + + This button will be highlighted if MO discovered potential problems in your setup and provide tips on how to fix them. + + + + + + :/MO/gui/help:/MO/gui/help + + + Help + + + Help + + + Ctrl+H + + + + + + :/MO/gui/icon_favorite:/MO/gui/icon_favorite + + + Endorse MO + + + Endorse Mod Organizer + + + + + Copy Log to Clipboard + + + + + + :/MO/gui/instance_switch:/MO/gui/instance_switch + + + Change Game + + + Open the Instance selection dialog to manage a different Game + + + + + + + MOBase::LineEditClear + QLineEdit +
lineeditclear.h
+
+ + ModListView + QTreeView +
modlistview.h
+
+ + PluginListView + QTreeView +
pluginlistview.h
+
+ + LCDNumber + QLCDNumber +
lcdnumber.h
+
+ + DownloadListWidget + QTreeView +
downloadlistwidget.h
+
+ + MOBase::SortableTreeWidget + QWidget +
sortabletreewidget.h
+
+
+ + + + +
diff --git a/src/nexusinterface.cpp b/src/nexusinterface.cpp index 25843c51..c149f987 100644 --- a/src/nexusinterface.cpp +++ b/src/nexusinterface.cpp @@ -203,6 +203,7 @@ void NexusInterface::setRateMax(const QString &userName, bool isPremium) m_MaxRequests = 300; m_RemainingRequests = 300; } + emit requestsChanged(m_RequestQueue.size(), m_RemainingRequests); } void NexusInterface::interpretNexusFileName(const QString &fileName, QString &modName, int &modID, bool query) @@ -543,6 +544,7 @@ void NexusInterface::nextRequest() connect(info.m_Timeout, SIGNAL(timeout()), this, SLOT(requestTimeout())); info.m_Timeout->start(); m_ActiveRequest.push_back(info); + emit requestsChanged(m_RequestQueue.size(), m_RemainingRequests); } @@ -559,6 +561,7 @@ void NexusInterface::requestFinished(std::list::iterator iter) int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if (statusCode == 429) { m_RemainingRequests = 0; + emit requestsChanged(m_RequestQueue.size(), m_RemainingRequests); qWarning("Requests have hit the rate limit threshold and are now being throttled. This request will be retried."); qWarning("Error: %s", reply->errorString().toUtf8().constData()); m_RequestQueue.enqueue(*iter); @@ -666,8 +669,10 @@ void NexusInterface::requestTimeout() void NexusInterface::calculateRequests() { - if (m_RemainingRequests < m_MaxRequests) + if (m_RemainingRequests < m_MaxRequests) { m_RemainingRequests++; + emit requestsChanged(m_RequestQueue.size(), m_RemainingRequests); + } } namespace { diff --git a/src/nexusinterface.h b/src/nexusinterface.h index e797d34e..a68948e6 100644 --- a/src/nexusinterface.h +++ b/src/nexusinterface.h @@ -348,6 +348,7 @@ signals: void nxmDownloadURLsAvailable(QString gameName, int modID, int fileID, QVariant userData, QVariant resultData, int requestID); void nxmEndorsementToggled(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID); void nxmRequestFailed(QString gameName, int modID, int fileID, QVariant userData, int requestID, QNetworkReply::NetworkError error, const QString &errorString); + void requestsChanged(int queueCount, int requestsRemaining); public slots: -- cgit v1.3.1 From 370e010a1adebf68efe5062c5d3a2ed8e048b654 Mon Sep 17 00:00:00 2001 From: Silarn Date: Mon, 28 Jan 2019 19:48:28 -0600 Subject: Fix a typo --- src/mainwindow.ui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mainwindow.ui') diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 1aa7ce4c..758b1123 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -550,10 +550,10 @@ p, li { white-space: pre-wrap; } - API Queued Requests and Throttle Count + API Queued Requests and Throttle Count - This tracks the number of queues Nexus API requests on the left and the current requests remaining before being throttled. You have 300 requests as a regular user and 600 as a premium user. These requests renew at the rate of one per second. + This tracks the number of queued Nexus API requests on the left and the current requests remaining before being throttled. You have 300 requests as a regular user and 600 as a premium user. These requests renew at the rate of one per second. QFrame::StyledPanel -- cgit v1.3.1 From c7c4a8b08e16ac7f40b5ce75c35a1ee5787a97b0 Mon Sep 17 00:00:00 2001 From: Silarn Date: Tue, 29 Jan 2019 21:17:54 -0600 Subject: Update outdated UI descriptions for API monitor --- src/mainwindow.ui | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/mainwindow.ui') diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 758b1123..ad6b3e38 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -550,10 +550,10 @@ p, li { white-space: pre-wrap; } - API Queued Requests and Throttle Count + API Queued and Remaining Requests - This tracks the number of queued Nexus API requests on the left and the current requests remaining before being throttled. You have 300 requests as a regular user and 600 as a premium user. These requests renew at the rate of one per second. + <html><head/><body><p>This tracks the number of queued Nexus API requests on the left (<span style=" font-weight:600;">Q</span>) and the remaining daily (<span style=" font-weight:600;">D</span>) and hourly (<span style=" font-weight:600;">H</span>) requests on the right. The Nexus API limits you to a pool of <span style=" font-weight:600;">2500</span> requests per day and <span style=" font-weight:600;">100</span> requests per hour. It is dynamically updated every time a request is completed. If you exceed this limit, you will be unable to queue downloads, check updates, parse mod info, or even log in.</p></body></html> QFrame::StyledPanel @@ -568,7 +568,7 @@ p, li { white-space: pre-wrap; } 1 - API: Q: 0 | Ts: 300 + API: Q: 0 | D: 0 | H: 0 Qt::AlignCenter -- cgit v1.3.1 From f7d1ce1fae80e42141198547d6c54689e085327f Mon Sep 17 00:00:00 2001 From: Silarn Date: Mon, 11 Feb 2019 20:30:45 -0600 Subject: Small updates, cleanup, update code, cache settings, tooltips --- src/CMakeLists.txt | 2 - src/json.cpp | 522 ----------------------------------------------- src/json.h | 94 --------- src/mainwindow.cpp | 22 +- src/mainwindow.h | 5 +- src/mainwindow.ui | 4 +- src/modinforegular.cpp | 25 --- src/modlist.cpp | 12 +- src/nexusinterface.cpp | 14 +- src/nxmaccessmanager.cpp | 53 ++--- src/settings.cpp | 14 -- src/settings.h | 16 -- src/settingsdialog.ui | 10 - 13 files changed, 65 insertions(+), 728 deletions(-) delete mode 100644 src/json.cpp delete mode 100644 src/json.h (limited to 'src/mainwindow.ui') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cc7d7a78..b241d99a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -79,7 +79,6 @@ SET(organizer_SRCS previewgenerator.cpp previewdialog.cpp aboutdialog.cpp - json.cpp modflagicondelegate.cpp genericicondelegate.cpp organizerproxy.cpp @@ -173,7 +172,6 @@ SET(organizer_HDRS previewgenerator.h previewdialog.h aboutdialog.h - json.h modflagicondelegate.h genericicondelegate.h organizerproxy.h diff --git a/src/json.cpp b/src/json.cpp deleted file mode 100644 index 05a2665a..00000000 --- a/src/json.cpp +++ /dev/null @@ -1,522 +0,0 @@ -/** - * QtJson - A simple class for parsing JSON data into a QVariant hierarchies and vice-versa. - * Copyright (C) 2011 Eeli Reilin - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file json.cpp - */ - -#include "json.h" - -namespace QtJson { - static QString sanitizeString(QString str); - static QByteArray join(const QList &list, const QByteArray &sep); - static QVariant parseValue(const QString &json, int &index, bool &success); - static QVariant parseObject(const QString &json, int &index, bool &success); - static QVariant parseArray(const QString &json, int &index, bool &success); - static QVariant parseString(const QString &json, int &index, bool &success); - static QVariant parseNumber(const QString &json, int &index); - static int lastIndexOfNumber(const QString &json, int index); - static void eatWhitespace(const QString &json, int &index); - static int lookAhead(const QString &json, int index); - static int nextToken(const QString &json, int &index); - - template - QByteArray serializeMap(const T &map, bool &success) { - QByteArray str = "{ "; - QList pairs; - for (typename T::const_iterator it = map.begin(), itend = map.end(); it != itend; ++it) { - QByteArray serializedValue = serialize(it.value()); - if (serializedValue.isNull()) { - success = false; - break; - } - pairs << sanitizeString(it.key()).toUtf8() + " : " + serializedValue; - } - - str += join(pairs, ", "); - str += " }"; - return str; - } - - - /** - * parse - */ - QVariant parse(const QString &json) { - bool success = true; - return parse(json, success); - } - - /** - * parse - */ - QVariant parse(const QString &json, bool &success) { - success = true; - - // Return an empty QVariant if the JSON data is either null or empty - if (!json.isNull() || !json.isEmpty()) { - QString data = json; - // We'll start from index 0 - int index = 0; - - // Parse the first value - QVariant value = parseValue(data, index, success); - - // Return the parsed value - return value; - } else { - // Return the empty QVariant - return QVariant(); - } - } - - QByteArray serialize(const QVariant &data) { - bool success = true; - return serialize(data, success); - } - - QByteArray serialize(const QVariant &data, bool &success) { - QByteArray str; - success = true; - - if (!data.isValid()) { // invalid or null? - str = "null"; - } else if ((data.type() == QVariant::List) || - (data.type() == QVariant::StringList)) { // variant is a list? - QList values; - const QVariantList list = data.toList(); - Q_FOREACH(const QVariant& v, list) { - QByteArray serializedValue = serialize(v); - if (serializedValue.isNull()) { - success = false; - break; - } - values << serializedValue; - } - - str = "[ " + join( values, ", " ) + " ]"; - } else if (data.type() == QVariant::Hash) { // variant is a hash? - str = serializeMap<>(data.toHash(), success); - } else if (data.type() == QVariant::Map) { // variant is a map? - str = serializeMap<>(data.toMap(), success); - } else if ((data.type() == QVariant::String) || - (data.type() == QVariant::ByteArray)) {// a string or a byte array? - str = sanitizeString(data.toString()).toUtf8(); - } else if (data.type() == QVariant::Double) { // double? - double value = data.toDouble(); - if ((value - value) == 0.0) { - str = QByteArray::number(value, 'g'); - if (!str.contains(".") && ! str.contains("e")) { - str += ".0"; - } - } else { - success = false; - } - } else if (data.type() == QVariant::Bool) { // boolean value? - str = data.toBool() ? "true" : "false"; - } else if (data.type() == QVariant::ULongLong) { // large unsigned number? - str = QByteArray::number(data.value()); - } else if (data.canConvert()) { // any signed number? - str = QByteArray::number(data.value()); - } else if (data.canConvert()) { //TODO: this code is never executed - str = QString::number(data.value()).toUtf8(); - } else if (data.canConvert()) { // can value be converted to string? - // this will catch QDate, QDateTime, QUrl, ... - str = sanitizeString(data.toString()).toUtf8(); - } else { - success = false; - } - - if (success) { - return str; - } else { - return QByteArray(); - } - } - - QString serializeStr(const QVariant &data) { - return QString::fromUtf8(serialize(data)); - } - - QString serializeStr(const QVariant &data, bool &success) { - return QString::fromUtf8(serialize(data, success)); - } - - - /** - * \enum JsonToken - */ - enum JsonToken { - JsonTokenNone = 0, - JsonTokenCurlyOpen = 1, - JsonTokenCurlyClose = 2, - JsonTokenSquaredOpen = 3, - JsonTokenSquaredClose = 4, - JsonTokenColon = 5, - JsonTokenComma = 6, - JsonTokenString = 7, - JsonTokenNumber = 8, - JsonTokenTrue = 9, - JsonTokenFalse = 10, - JsonTokenNull = 11 - }; - - static QString sanitizeString(QString str) { - str.replace(QLatin1String("\\"), QLatin1String("\\\\")); - str.replace(QLatin1String("\""), QLatin1String("\\\"")); - str.replace(QLatin1String("\b"), QLatin1String("\\b")); - str.replace(QLatin1String("\f"), QLatin1String("\\f")); - str.replace(QLatin1String("\n"), QLatin1String("\\n")); - str.replace(QLatin1String("\r"), QLatin1String("\\r")); - str.replace(QLatin1String("\t"), QLatin1String("\\t")); - return QString(QLatin1String("\"%1\"")).arg(str); - } - - static QByteArray join(const QList &list, const QByteArray &sep) { - QByteArray res; - Q_FOREACH(const QByteArray &i, list) { - if (!res.isEmpty()) { - res += sep; - } - res += i; - } - return res; - } - - /** - * parseValue - */ - static QVariant parseValue(const QString &json, int &index, bool &success) { - // Determine what kind of data we should parse by - // checking out the upcoming token - switch(lookAhead(json, index)) { - case JsonTokenString: - return parseString(json, index, success); - case JsonTokenNumber: - return parseNumber(json, index); - case JsonTokenCurlyOpen: - return parseObject(json, index, success); - case JsonTokenSquaredOpen: - return parseArray(json, index, success); - case JsonTokenTrue: - nextToken(json, index); - return QVariant(true); - case JsonTokenFalse: - nextToken(json, index); - return QVariant(false); - case JsonTokenNull: - nextToken(json, index); - return QVariant(); - case JsonTokenNone: - break; - } - - // If there were no tokens, flag the failure and return an empty QVariant - success = false; - return QVariant(); - } - - /** - * parseObject - */ - static QVariant parseObject(const QString &json, int &index, bool &success) { - QVariantMap map; - int token; - - // Get rid of the whitespace and increment index - nextToken(json, index); - - // Loop through all of the key/value pairs of the object - bool done = false; - while (!done) { - // Get the upcoming token - token = lookAhead(json, index); - - if (token == JsonTokenNone) { - success = false; - return QVariantMap(); - } else if (token == JsonTokenComma) { - nextToken(json, index); - } else if (token == JsonTokenCurlyClose) { - nextToken(json, index); - return map; - } else { - // Parse the key/value pair's name - QString name = parseString(json, index, success).toString(); - - if (!success) { - return QVariantMap(); - } - - // Get the next token - token = nextToken(json, index); - - // If the next token is not a colon, flag the failure - // return an empty QVariant - if (token != JsonTokenColon) { - success = false; - return QVariant(QVariantMap()); - } - - // Parse the key/value pair's value - QVariant value = parseValue(json, index, success); - - if (!success) { - return QVariantMap(); - } - - // Assign the value to the key in the map - map[name] = value; - } - } - - // Return the map successfully - return QVariant(map); - } - - /** - * parseArray - */ - static QVariant parseArray(const QString &json, int &index, bool &success) { - QVariantList list; - - nextToken(json, index); - - bool done = false; - while(!done) { - int token = lookAhead(json, index); - - if (token == JsonTokenNone) { - success = false; - return QVariantList(); - } else if (token == JsonTokenComma) { - nextToken(json, index); - } else if (token == JsonTokenSquaredClose) { - nextToken(json, index); - break; - } else { - QVariant value = parseValue(json, index, success); - if (!success) { - return QVariantList(); - } - list.push_back(value); - } - } - - return QVariant(list); - } - - /** - * parseString - */ - static QVariant parseString(const QString &json, int &index, bool &success) { - QString s; - QChar c; - - eatWhitespace(json, index); - - c = json[index++]; - - bool complete = false; - while(!complete) { - if (index == json.size()) { - break; - } - - c = json[index++]; - - if (c == '\"') { - complete = true; - break; - } else if (c == '\\') { - if (index == json.size()) { - break; - } - - c = json[index++]; - - if (c == '\"') { - s.append('\"'); - } else if (c == '\\') { - s.append('\\'); - } else if (c == '/') { - s.append('/'); - } else if (c == 'b') { - s.append('\b'); - } else if (c == 'f') { - s.append('\f'); - } else if (c == 'n') { - s.append('\n'); - } else if (c == 'r') { - s.append('\r'); - } else if (c == 't') { - s.append('\t'); - } else if (c == 'u') { - int remainingLength = json.size() - index; - if (remainingLength >= 4) { - QString unicodeStr = json.mid(index, 4); - - int symbol = unicodeStr.toInt(0, 16); - - s.append(QChar(symbol)); - - index += 4; - } else { - break; - } - } - } else { - s.append(c); - } - } - - if (!complete) { - success = false; - return QVariant(); - } - - return QVariant(s); - } - - /** - * parseNumber - */ - static QVariant parseNumber(const QString &json, int &index) { - eatWhitespace(json, index); - - int lastIndex = lastIndexOfNumber(json, index); - int charLength = (lastIndex - index) + 1; - QString numberStr; - - numberStr = json.mid(index, charLength); - - index = lastIndex + 1; - bool ok; - - if (numberStr.contains('.')) { - return QVariant(numberStr.toDouble(nullptr)); - } else if (numberStr.startsWith('-')) { - int i = numberStr.toInt(&ok); - if (!ok) { - qlonglong ll = numberStr.toLongLong(&ok); - return ok ? ll : QVariant(numberStr); - } - return i; - } else { - uint u = numberStr.toUInt(&ok); - if (!ok) { - qulonglong ull = numberStr.toULongLong(&ok); - return ok ? ull : QVariant(numberStr); - } - return u; - } - } - - /** - * lastIndexOfNumber - */ - static int lastIndexOfNumber(const QString &json, int index) { - int lastIndex; - - for(lastIndex = index; lastIndex < json.size(); lastIndex++) { - if (QString("0123456789+-.eE").indexOf(json[lastIndex]) == -1) { - break; - } - } - - return lastIndex -1; - } - - /** - * eatWhitespace - */ - static void eatWhitespace(const QString &json, int &index) { - for(; index < json.size(); index++) { - if (QString(" \t\n\r").indexOf(json[index]) == -1) { - break; - } - } - } - - /** - * lookAhead - */ - static int lookAhead(const QString &json, int index) { - int saveIndex = index; - return nextToken(json, saveIndex); - } - - /** - * nextToken - */ - static int nextToken(const QString &json, int &index) { - eatWhitespace(json, index); - - if (index == json.size()) { - return JsonTokenNone; - } - - QChar c = json[index]; - index++; - switch(c.toLatin1()) { - case '{': return JsonTokenCurlyOpen; - case '}': return JsonTokenCurlyClose; - case '[': return JsonTokenSquaredOpen; - case ']': return JsonTokenSquaredClose; - case ',': return JsonTokenComma; - case '"': return JsonTokenString; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case '-': return JsonTokenNumber; - case ':': return JsonTokenColon; - } - index--; // ^ WTF? - - int remainingLength = json.size() - index; - - // True - if (remainingLength >= 4) { - if (json[index] == 't' && json[index + 1] == 'r' && - json[index + 2] == 'u' && json[index + 3] == 'e') { - index += 4; - return JsonTokenTrue; - } - } - - // False - if (remainingLength >= 5) { - if (json[index] == 'f' && json[index + 1] == 'a' && - json[index + 2] == 'l' && json[index + 3] == 's' && - json[index + 4] == 'e') { - index += 5; - return JsonTokenFalse; - } - } - - // Null - if (remainingLength >= 4) { - if (json[index] == 'n' && json[index + 1] == 'u' && - json[index + 2] == 'l' && json[index + 3] == 'l') { - index += 4; - return JsonTokenNull; - } - } - - return JsonTokenNone; - } -} //end namespace diff --git a/src/json.h b/src/json.h deleted file mode 100644 index 57842e37..00000000 --- a/src/json.h +++ /dev/null @@ -1,94 +0,0 @@ -/** - * QtJson - A simple class for parsing JSON data into a QVariant hierarchies and vice-versa. - * Copyright (C) 2011 Eeli Reilin - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file json.h - */ - -#ifndef JSON_H -#define JSON_H - -#include -#include - - -/** - * \namespace QtJson - * \brief A JSON data parser - * - * Json parses a JSON data into a QVariant hierarchy. - */ -namespace QtJson { - typedef QVariantMap JsonObject; - typedef QVariantList JsonArray; - - /** - * Parse a JSON string - * - * \param json The JSON data - */ - QVariant parse(const QString &json); - - /** - * Parse a JSON string - * - * \param json The JSON data - * \param success The success of the parsing - */ - QVariant parse(const QString &json, bool &success); - - /** - * This method generates a textual JSON representation - * - * \param data The JSON data generated by the parser. - * - * \return QByteArray Textual JSON representation in UTF-8 - */ - QByteArray serialize(const QVariant &data); - - /** - * This method generates a textual JSON representation - * - * \param data The JSON data generated by the parser. - * \param success The success of the serialization - * - * \return QByteArray Textual JSON representation in UTF-8 - */ - QByteArray serialize(const QVariant &data, bool &success); - - /** - * This method generates a textual JSON representation - * - * \param data The JSON data generated by the parser. - * - * \return QString Textual JSON representation - */ - QString serializeStr(const QVariant &data); - - /** - * This method generates a textual JSON representation - * - * \param data The JSON data generated by the parser. - * \param success The success of the serialization - * - * \return QString Textual JSON representation - */ - QString serializeStr(const QVariant &data, bool &success); -} - -#endif //JSON_H diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 7592bd1e..1ecb6417 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -749,11 +749,11 @@ void MainWindow::createEndorseWidget() buttonMenu->clear(); QAction *endorseAction = new QAction(tr("Endorse"), buttonMenu); - connect(endorseAction, SIGNAL(triggered()), this, SLOT(on_actionEndorseMO_triggered())); + connect(endorseAction, SIGNAL(triggered()), this, SLOT(actionEndorseMO())); buttonMenu->addAction(endorseAction); QAction *wontEndorseAction = new QAction(tr("Won't Endorse"), buttonMenu); - connect(wontEndorseAction, SIGNAL(triggered()), this, SLOT(on_actionWontEndorseMO_triggered())); + connect(wontEndorseAction, SIGNAL(triggered()), this, SLOT(actionWontEndorseMO())); buttonMenu->addAction(wontEndorseAction); } @@ -1866,9 +1866,21 @@ void MainWindow::processUpdates() { lastHidden = hidden; } } - if (lastVersion < QVersionNumber(2,1,6)) { + if (lastVersion < QVersionNumber(2, 1, 6)) { ui->modList->header()->setSectionHidden(ModList::COL_NOTES, true); } + if (lastVersion < QVersionNumber(2, 2, 0)) { + QSettings &instance = Settings::instance().directInterface(); + instance.beginGroup("Settings"); + instance.remove("steam_password"); + instance.remove("nexus_username"); + instance.remove("nexus_password"); + instance.remove("nexus_api_key"); + instance.endGroup(); + instance.beginGroup("Servers"); + instance.remove(""); + instance.endGroup(); + } } if (currentVersion > lastVersion) { @@ -5366,7 +5378,7 @@ void MainWindow::on_actionUpdate_triggered() } -void MainWindow::on_actionEndorseMO_triggered() +void MainWindow::actionEndorseMO() { // Normally this would be the managed game but MO2 is only uploaded to the Skyrim SE site right now IPluginGame * game = m_OrganizerCore.getGame("skyrimse"); @@ -5381,7 +5393,7 @@ void MainWindow::on_actionEndorseMO_triggered() } } -void MainWindow::on_actionWontEndorseMO_triggered() +void MainWindow::actionWontEndorseMO() { // Normally this would be the managed game but MO2 is only uploaded to the Skyrim SE site right now IPluginGame * game = m_OrganizerCore.getGame("skyrimse"); diff --git a/src/mainwindow.h b/src/mainwindow.h index a0c043a1..ff23b8fb 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -494,6 +494,9 @@ private slots: void updateAvailable(); + void actionEndorseMO(); + void actionWontEndorseMO(); + void motdReceived(const QString &motd); void originModified(int originID); @@ -621,8 +624,6 @@ private slots: // ui slots void on_actionNotifications_triggered(); void on_actionSettings_triggered(); void on_actionUpdate_triggered(); - void on_actionEndorseMO_triggered(); - void on_actionWontEndorseMO_triggered(); void on_bsaList_customContextMenuRequested(const QPoint &pos); void on_clearFiltersButton_clicked(); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index ad6b3e38..5ac8f092 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -550,10 +550,10 @@ p, li { white-space: pre-wrap; } - API Queued and Remaining Requests + Nexus API Queued and Remaining Requests - <html><head/><body><p>This tracks the number of queued Nexus API requests on the left (<span style=" font-weight:600;">Q</span>) and the remaining daily (<span style=" font-weight:600;">D</span>) and hourly (<span style=" font-weight:600;">H</span>) requests on the right. The Nexus API limits you to a pool of <span style=" font-weight:600;">2500</span> requests per day and <span style=" font-weight:600;">100</span> requests per hour. It is dynamically updated every time a request is completed. If you exceed this limit, you will be unable to queue downloads, check updates, parse mod info, or even log in.</p></body></html> + <html><head/><body><p>This tracks the number of queued Nexus API requests on the left (<span style=" font-weight:600;">Q</span>) and the remaining daily (<span style=" font-weight:600;">D</span>) and hourly (<span style=" font-weight:600;">H</span>) requests on the right. The Nexus API limits you to a pool of requests per day and requests per hour. It is dynamically updated every time a request is completed. If you run out of requests, you will be unable to queue downloads, check updates, parse mod info, or even log in. Both pools must be consumed before this happens.</p></body></html> QFrame::StyledPanel diff --git a/src/modinforegular.cpp b/src/modinforegular.cpp index ac1c46d6..8bef1c28 100644 --- a/src/modinforegular.cpp +++ b/src/modinforegular.cpp @@ -508,31 +508,6 @@ bool ModInfoRegular::canBeUpdated() const QDateTime ModInfoRegular::getExpires() const { return m_LastNexusUpdate.addSecs(300); - /* - switch (Settings::instance().nexusUpdateStrategy()) { - case Settings::NexusUpdateStrategy::Flexible: { - qint64 diff = m_NexusLastModified.msecsTo(QDateTime::currentDateTimeUtc()); - qint64 year = 31536000000; - qint64 sixMonths = 15768000000; - qint64 threeMonths = 7884000000; - qint64 oneMonth = 1314000000; - - if (diff < oneMonth) - return m_LastNexusUpdate.addSecs(7200); - else if (diff < threeMonths) - return m_LastNexusUpdate.addSecs(14400); - else if (diff < sixMonths) - return m_LastNexusUpdate.addSecs(21600); - else if (diff < year) - return m_LastNexusUpdate.addSecs(43200); - else - return m_LastNexusUpdate.addSecs(86400); - } break; - case Settings::NexusUpdateStrategy::Rigid: { - return m_LastNexusUpdate.addSecs(86400); - } break; - } - */ } std::vector ModInfoRegular::getFlags() const diff --git a/src/modlist.cpp b/src/modlist.cpp index 55241492..bb490113 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -466,15 +466,11 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const if (modInfo->getNexusID() > 0) { if (!modInfo->canBeUpdated()) { qint64 remains = QDateTime::currentDateTimeUtc().secsTo(modInfo->getExpires()); - qint64 hours = remains / 3600; - qint64 minutes = (remains % 3600) / 60; - QString remainsStr(tr("%1 hours and %2 minutes").arg(hours).arg(minutes)); - text += "
" + tr("This mod was last checked on %1. It will be available to check in %2.") - .arg(modInfo->getLastNexusUpdate().toLocalTime().toString(Qt::DefaultLocaleShortDate)) + qint64 minutes = remains / 60; + qint64 seconds = (remains % 60) / 60; + QString remainsStr(tr("%1 minute(s) and %2 second(s)").arg(minutes).arg(seconds)); + text += "
" + tr("This mod will be available to check in %2.") .arg(remainsStr); - } else { - text += "
" + tr("This mod is eligible for an update check."); - text += "
" + tr("It was last checked on %1").arg(modInfo->getLastNexusUpdate().toLocalTime().toString(Qt::DefaultLocaleShortDate)); } } return text; diff --git a/src/nexusinterface.cpp b/src/nexusinterface.cpp index e657dfc1..265d898c 100644 --- a/src/nexusinterface.cpp +++ b/src/nexusinterface.cpp @@ -21,7 +21,6 @@ along with Mod Organizer. If not, see . #include "iplugingame.h" #include "nxmaccessmanager.h" -#include "json.h" #include "selectiondialog.h" #include "bbcode.h" #include @@ -613,6 +612,8 @@ void NexusInterface::nextRequest() url = info.m_URL; } QNetworkRequest request(url); + request.setAttribute(QNetworkRequest::CacheSaveControlAttribute, false); + request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork); request.setRawHeader("APIKEY", m_AccessManager->apiKey().toUtf8()); request.setHeader(QNetworkRequest::KnownHeaders::UserAgentHeader, m_AccessManager->userAgent(info.m_SubModule)); request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json"); @@ -645,7 +646,10 @@ void NexusInterface::requestFinished(std::list::iterator iter) if (reply->error() != QNetworkReply::NoError) { int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if (statusCode == 429) { - qWarning("All API requests have been consumed and are now being denied."); + if (reply->rawHeader("x-rl-daily-remaining").toInt() || reply->rawHeader("x-rl-hourly-remaining").toInt()) + qWarning("You appear to be making requests to the Nexus API too quickly and are being throttled. Please inform the MO2 team."); + else + qWarning("All API requests have been consumed and are now being denied."); qWarning("Error: %s", reply->errorString().toUtf8().constData()); } else { qWarning("request failed: %s", reply->errorString().toUtf8().constData()); @@ -670,9 +674,9 @@ void NexusInterface::requestFinished(std::list::iterator iter) qDebug("nexus error: %s", qUtf8Printable(nexusError)); emit nxmRequestFailed(iter->m_GameName, iter->m_ModID, iter->m_FileID, iter->m_UserData, iter->m_ID, reply->error(), nexusError); } else { - bool ok; - QVariant result = QtJson::parse(data, ok); - if (result.isValid() && ok) { + QJsonDocument responseDoc = QJsonDocument::fromJson(data); + if (!responseDoc.isNull()) { + QVariant result = responseDoc.toVariant(); switch (iter->m_Type) { case NXMRequestInfo::TYPE_DESCRIPTION: { emit nxmDescriptionAvailable(iter->m_GameName, iter->m_ModID, iter->m_UserData, result, iter->m_ID); diff --git a/src/nxmaccessmanager.cpp b/src/nxmaccessmanager.cpp index 1e0ac49b..aca1d785 100644 --- a/src/nxmaccessmanager.cpp +++ b/src/nxmaccessmanager.cpp @@ -259,33 +259,40 @@ void NXMAccessManager::validateFinished() if (m_ValidateReply != nullptr) { QJsonDocument jdoc = QJsonDocument::fromJson(m_ValidateReply->readAll()); - QJsonObject credentialsData = jdoc.object(); - if (credentialsData.contains("user_id")) { - QString name = credentialsData.value("name").toString(); - bool premium = credentialsData.value("is_premium").toBool(); - - std::tuple limits(std::make_tuple( - m_ValidateReply->rawHeader("x-rl-daily-remaining").toInt(), - m_ValidateReply->rawHeader("x-rl-daily-limit").toInt(), - m_ValidateReply->rawHeader("x-rl-hourly-remaining").toInt(), - m_ValidateReply->rawHeader("x-rl-hourly-limit").toInt() - )); - - emit credentialsReceived(name, premium, limits); - - m_ValidateReply->deleteLater(); - m_ValidateReply = nullptr; - - m_ValidateState = VALIDATE_VALID; - emit validateSuccessful(true); + if (!jdoc.isNull()) { + QJsonObject credentialsData = jdoc.object(); + if (credentialsData.contains("user_id")) { + QString name = credentialsData.value("name").toString(); + bool premium = credentialsData.value("is_premium").toBool(); + + std::tuple limits(std::make_tuple( + m_ValidateReply->rawHeader("x-rl-daily-remaining").toInt(), + m_ValidateReply->rawHeader("x-rl-daily-limit").toInt(), + m_ValidateReply->rawHeader("x-rl-hourly-remaining").toInt(), + m_ValidateReply->rawHeader("x-rl-hourly-limit").toInt() + )); + + emit credentialsReceived(name, premium, limits); + + m_ValidateReply->deleteLater(); + m_ValidateReply = nullptr; + + m_ValidateState = VALIDATE_VALID; + emit validateSuccessful(true); + } else { + m_ApiKey.clear(); + m_ValidateState = VALIDATE_NOT_VALID; + emit validateFailed(tr("Validation failed, please reauthenticate in the Settings -> Nexus tab: %1").arg(credentialsData.value("message").toString())); + } } else { m_ApiKey.clear(); - m_ValidateState = VALIDATE_NOT_VALID; - emit validateFailed(tr("Validation failed, please reauthenticate in the Settings -> Nexus tab: %1").arg(credentialsData.value("message").toString())); + m_ValidateState = VALIDATE_NOT_CHECKED; + emit validateFailed(tr("Could not parse response. Invalid JSON.")); } - } else { + } + else { m_ApiKey.clear(); m_ValidateState = VALIDATE_NOT_CHECKED; - emit validateFailed(tr("unknown error")); + emit validateFailed(tr("Unknown error.")); } } diff --git a/src/settings.cpp b/src/settings.cpp index 64a39e12..7b4b3a67 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -92,8 +92,6 @@ Settings::Settings(const QSettings &settingsSource) } else { s_Instance = this; } - - qRegisterMetaType("NexusUpdateStrategy"); } @@ -416,11 +414,6 @@ int Settings::crashDumpsMax() const return m_Settings.value("Settings/crash_dumps_max", 5).toInt(); } -Settings::NexusUpdateStrategy Settings::nexusUpdateStrategy() const -{ - return static_cast(m_Settings.value("Settings/nexus_update_strategy", std::rand() / ((RAND_MAX + 1u) / 2)).toInt()); -} - QColor Settings::modlistOverwrittenLooseColor() const { return m_Settings.value("Settings/overwrittenLooseFilesColor", QColor(0, 255, 0, 64)).value(); @@ -1042,10 +1035,7 @@ Settings::NexusTab::NexusTab(Settings *parent, SettingsDialog &dialog) , m_preferredServersList( dialog.findChild("preferredServersList")) , m_endorsementBox(dialog.findChild("endorsementBox")) - , m_updateStrategyBox(dialog.findChild("updateStrategy")) { - qRegisterMetaType("NexusUpdateStrategy"); - if (!deObfuscate("APIKEY").isEmpty()) { m_nexusConnect->setText("Nexus API Key Stored"); m_nexusConnect->setDisabled(true); @@ -1054,8 +1044,6 @@ Settings::NexusTab::NexusTab(Settings *parent, SettingsDialog &dialog) m_offlineBox->setChecked(parent->offlineMode()); m_proxyBox->setChecked(parent->useProxy()); m_endorsementBox->setChecked(parent->endorsementIntegration()); - if (parent->nexusUpdateStrategy() == Settings::NexusUpdateStrategy::Flexible) - m_updateStrategyBox->setChecked(true); // display server preferences @@ -1101,8 +1089,6 @@ void Settings::NexusTab::update() m_Settings.setValue("Settings/offline_mode", m_offlineBox->isChecked()); m_Settings.setValue("Settings/use_proxy", m_proxyBox->isChecked()); m_Settings.setValue("Settings/endorsement_integration", m_endorsementBox->isChecked()); - m_Settings.setValue("Settings/nexus_update_strategy", m_updateStrategyBox->isChecked() - ? Settings::NexusUpdateStrategy::Flexible : Settings::NexusUpdateStrategy::Rigid); // store server preference m_Settings.beginGroup("Servers"); diff --git a/src/settings.h b/src/settings.h index ddb7cac0..2cd3f0b6 100644 --- a/src/settings.h +++ b/src/settings.h @@ -65,14 +65,6 @@ class Settings : public QObject { Q_OBJECT - Q_ENUMS(NexusUpdateStrategy) - -public: - - enum NexusUpdateStrategy { - Rigid, - Flexible - }; public: @@ -239,11 +231,6 @@ public: */ int crashDumpsMax() const; - /** - * @return the configured Nexus update strategy - */ - NexusUpdateStrategy nexusUpdateStrategy() const; - QColor modlistOverwrittenLooseColor() const; QColor modlistOverwritingLooseColor() const; @@ -499,7 +486,6 @@ private: QListWidget *m_knownServersList; QListWidget *m_preferredServersList; QCheckBox *m_endorsementBox; - QCheckBox *m_updateStrategyBox; }; /** Display/store the configuration in the 'steam' tab of the settings dialogue */ @@ -578,6 +564,4 @@ private: }; -Q_DECLARE_METATYPE(Settings::NexusUpdateStrategy) - #endif // SETTINGS_H diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index cfbcf429..127c94c7 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -578,16 +578,6 @@ p, li { white-space: pre-wrap; }
- - - - <html><head/><body><p>Rather than a global <span style=" font-weight:600;">1 day</span> cache, update caches will expire at different rates depending on how recently a mod has been updated on Nexus.</p><p><br/></p><p>Less than a month: <span style=" font-style:italic;">2 hours</span></p><p>Less than three months: <span style=" font-style:italic;">4 hours</span></p><p>Less than six months: <span style=" font-style:italic;">6 hours</span></p><p>Less than one year: <span style=" font-style:italic;">12 hours</span></p><p>More than one year: <span style=" font-style:italic;">1 day</span></p></body></html> - - - Use dynamic update timeouts - - -
-- cgit v1.3.1 From fa44740193e510df569441016d40e74b8dc6fca1 Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Tue, 5 Mar 2019 01:58:25 -0600 Subject: Clear palette of mod list and plugin list to better support themes --- src/mainwindow.ui | 133 ------------------------------------------------------ 1 file changed, 133 deletions(-) (limited to 'src/mainwindow.ui') diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 5ac8f092..d876b54a 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -334,97 +334,6 @@ p, li { white-space: pre-wrap; } 400 - - - - - - - 64 - 64 - 64 - - - - - - - 255 - 0 - 0 - - - - - - - 0 - 170 - 0 - - - - - - - - - 64 - 64 - 64 - - - - - - - 255 - 0 - 0 - - - - - - - 0 - 170 - 0 - - - - - - - - - 120 - 120 - 120 - - - - - - - 255 - 0 - 0 - - - - - - - 0 - 170 - 0 - - - - - - Qt::CustomContextMenu @@ -989,43 +898,6 @@ p, li { white-space: pre-wrap; } 250 - - - - - - - 64 - 64 - 64 - - - - - - - - - 64 - 64 - 64 - - - - - - - - - 120 - 120 - 120 - - - - - - Qt::CustomContextMenu @@ -1168,11 +1040,6 @@ p, li { white-space: pre-wrap; } 1 - - - Archives - - -- cgit v1.3.1