Compare commits

..
5 Commits
Author SHA1 Message Date
Jeremy Rimpo 886fb10288 Merge pull request #343 from Modorganizer2/Develop
Better error message when archives can't be extracted
2018-05-08 19:33:47 -05:00
Jeremy Rimpo 26b946a905 Merge pull request #342 from Modorganizer2/Develop
Fix an issue with resuming a completed download
2018-05-08 19:24:02 -05:00
Jeremy Rimpo 5e6bb0a16e Merge pull request #341 from Modorganizer2/Develop
Reset the progress bar data after completing the extraction
2018-05-08 11:35:45 -05:00
Brian Munro 0da6af17b2 Merge pull request #336 from Modorganizer2/Develop
Release 2.1.3
2018-05-08 12:47:54 +02:00
Brian Munro bc75009169 Merge pull request #294 from Modorganizer2/Develop
Release 2.1.2
2018-04-13 11:56:36 +02:00
387 changed files with 24678 additions and 49506 deletions
-16
View File
@@ -1,16 +0,0 @@
root = true
[*.cpp]
indent_style = space
indent_size = 2
insert_final_newline = true
[*.h]
indent_style = space
indent_size = 2
insert_final_newline = true
[*.ui]
indent_style = space
indent_size = 2
insert_final_newline = true
+25
View File
@@ -0,0 +1,25 @@
# The problem
Briefly describe the issue you are experiencing (or the feature you want to see added to Mod Organizer). Tell us what you were trying to do and what happened instead. Remember, this is _not_ a place to ask questions. For that, go to our discord channel
# Environment
* Mod Organizer Version that exhibits the issue:
* Last Mod Organizer Verison that did not exhibit the issue (if applicable):
* Desktop OS/version used to run Mod Organizer:
# Details
If necessary, describe the problem you have been experiencing in more detail.
# Link to Mod Organizer logs
## USVFS
Create a [GIST](https://gist.github.com) which is a paste of your USVFS logs, and link them here.
Do _NOT_ paste your full USVFS logs here, as it will make this issue very long and hard to read!
If you are reporting a bug, _always_ include the USVFS logs!
## MO Interface
Create a [GIST](https://gist.github.com) which is a paste of your mo_interface logs, and link them here.
Do _NOT_ paste your full mo_interface logs here, as it will make this issue very long and hard to read!
If you are reporting a bug, _always_ include the mo_interface logs!
-10
View File
@@ -1,10 +0,0 @@
---
name: Dev Ticket
about: Reserved for development tasks and management.
title: ''
labels: Dev Ticket
assignees: ''
---
Task:
-20
View File
@@ -1,20 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: Feature Request
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
-41
View File
@@ -1,41 +0,0 @@
---
name: Issue Report
about: Create an issue report.
title: ''
labels: issue report
assignees: ''
---
## The problem:
Briefly describe the issue you are experiencing. Tell us what you were trying to do and what happened instead. Remember, this is _not_ a place to ask questions. For that, go to our [discord channel](https://discord.gg/5tCqt6V)
## To Reproduce:
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
## Environment:
* Mod Organizer Version that exhibits the issue:
* Last Mod Organizer Verison that did not exhibit the issue (if applicable):
* Desktop OS/version used to run Mod Organizer:
## Details:
If necessary, describe the problem you have been experiencing with more details and pictures.
## Link to Mod Organizer logs:
To access the log files you can press the Open folder icon over the modlist and select "Open MO2 Logs folder". You should close MO2 before sending or examining the logs as they are finished writing only after the program is closed.
### USVFS:
Create a [GIST](https://gist.github.com) which is a paste of your USVFS logs, and link them here.
Do _NOT_ paste your full USVFS logs here, as it will make this issue very long and hard to read!
If you are reporting a bug, _always_ include the USVFS logs!
### MO Interface:
Create a [GIST](https://gist.github.com) which is a paste of your mo_interface logs, and link them here.
Do _NOT_ paste your full mo_interface logs here, as it will make this issue very long and hard to read!
If you are reporting a bug, _always_ include the mo_interface logs!
-28
View File
@@ -1,28 +0,0 @@
version: 1.0.{build}
skip_branch_with_pr: true
image: Visual Studio 2017
environment:
WEBHOOK_URL:
secure: gOKbXaZM9ImtMD5XrYITvdyZUW/az082G9OIN1EC1VYoNNsKROB4s6VsQiL6qbLNLc4XQhc8Y9DhdU9Hfh49vhypcjUEQmMsENxnp+1hYMJctTqIYDunVSd767eez5wz6rKHqk+XOHmg5gyVNCV9u4DVcCZJSVe4UTKn1lc47H0=
build_script:
- cmd: >-
git clone --depth=1 --branch=%APPVEYOR_REPO_BRANCH% https://github.com/ModOrganizer2/modorganizer-umbrella.git c:\projects\modorganizer-umbrella 2> $null
mkdir c:\projects\modorganizer-build -type directory
cd c:\projects\modorganizer-umbrella
C:\Python37-x64\python.exe unimake.py -d c:\projects\modorganizer-build -s Appveyor_Build=True %APPVEYOR_PROJECT_NAME%
artifacts:
- path: vsbuild\src\RelWithDebInfo\ModOrganizer.exe
name: modorganizer_exe
- path: vsbuild\src\RelWithDebInfo\ModOrganizer.pdb
name: modorganizer_pdb
on_success:
- ps: Set-Location -Path $env:APPVEYOR_BUILD_FOLDER
- ps: Invoke-RestMethod https://raw.githubusercontent.com/DiscordHooks/appveyor-discord-webhook/master/send.ps1 -o send.ps1
- ps: ./send.ps1 success $env:WEBHOOK_URL
on_failure:
- ps: Set-Location -Path $env:APPVEYOR_BUILD_FOLDER
- ps: Invoke-RestMethod https://raw.githubusercontent.com/DiscordHooks/appveyor-discord-webhook/master/send.ps1 -o send.ps1
- ps: ./send.ps1 failure $env:WEBHOOK_URL
+2 -5
View File
@@ -1,5 +1,3 @@
[![Build status](https://ci.appveyor.com/api/projects/status/23qmd9rufv9vpmg7?svg=true)](https://ci.appveyor.com/project/Modorganizer2/modorganizer)
# Mod Organizer
Mod Organizer (MO) is a tool for managing mod collections of arbitrary size. It is specifically designed for people who like to experiment with mods and thus need an easy and reliable way to install and uninstall them.
@@ -22,7 +20,7 @@ Through the work of a few people of the community MO2 has come quite far, now it
## Reporting Issues:
Issues should be reported to the GitHub page or on the open discord server: [ModOrganizerDevs](https://discord.gg/vD2ZbfX). Here is also where dev builds are tested, bugs are reported and investigated, suggestions are discussed and a lot more.
Credits to Tannin, LePresidente, Silarn, erasmux, AL12, LostDragonist, AnyOldName3 and many others for the development.
Credits to Tannin, LePresidente, Silarn, erasmux, AL12 and many others for the development.
## Download Location
@@ -51,7 +49,6 @@ Here is a complete list:
* https://github.com/Modorganizer2/modorganizer-check_fnis
* https://github.com/Modorganizer2/modorganizer-diagnose_basic
* https://github.com/Modorganizer2/modorganizer-esptk
* https://github.com/ModOrganizer2/modorganizer-fnistool
* https://github.com/Modorganizer2/modorganizer-helper
* https://github.com/Modorganizer2/modorganizer-game_fallout3
* https://github.com/Modorganizer2/modorganizer-game_fallout4
@@ -63,7 +60,6 @@ Here is a complete list:
* https://github.com/Modorganizer2/modorganizer-game_oblivion
* https://github.com/Modorganizer2/modorganizer-game_skyrim
* https://github.com/Modorganizer2/modorganizer-game_skyrimSE
* https://github.com/ModOrganizer2/modorganizer-game_skyrimVR
* https://github.com/Modorganizer2/modorganizer-game_ttw
* https://github.com/Modorganizer2/modorganizer-installer_bain
* https://github.com/Modorganizer2/modorganizer-installer_bundle
@@ -84,3 +80,4 @@ Here is a complete list:
### Unused Repositories
* https://github.com/Modorganizer2/modorganizer-hookdll
* https://github.com/TanninOne/modorganizer-tool_nmmimport
+13 -23
View File
@@ -37,7 +37,6 @@ SET(organizer_SRCS
modinfoforeign.cpp
modinfooverwrite.cpp
modinforegular.cpp
modinfoseparator.cpp
modinfowithconflictinfo.cpp
messagedialog.cpp
mainwindow.cpp
@@ -54,6 +53,7 @@ SET(organizer_SRCS
executableslist.cpp
editexecutablesdialog.cpp
downloadmanager.cpp
downloadlistwidgetcompact.cpp
downloadlistwidget.cpp
downloadlistsortproxy.cpp
downloadlist.cpp
@@ -79,6 +79,7 @@ SET(organizer_SRCS
previewgenerator.cpp
previewdialog.cpp
aboutdialog.cpp
json.cpp
modflagicondelegate.cpp
genericicondelegate.cpp
organizerproxy.cpp
@@ -89,10 +90,6 @@ SET(organizer_SRCS
usvfsconnector.cpp
eventfilter.cpp
moshortcut.cpp
listdialog.cpp
lcdnumber.cpp
forcedloaddialog.cpp
forcedloaddialogwidget.cpp
shared/windows_error.cpp
shared/error_report.cpp
@@ -131,7 +128,6 @@ SET(organizer_HDRS
modinfoforeign.h
modinfooverwrite.h
modinforegular.h
modinfoseparator.h
modinfowithconflictinfo.h
messagedialog.h
mainwindow.h
@@ -147,6 +143,7 @@ SET(organizer_HDRS
executableslist.h
editexecutablesdialog.h
downloadmanager.h
downloadlistwidgetcompact.h
downloadlistwidget.h
downloadlistsortproxy.h
downloadlist.h
@@ -172,6 +169,7 @@ SET(organizer_HDRS
previewgenerator.h
previewdialog.h
aboutdialog.h
json.h
modflagicondelegate.h
genericicondelegate.h
organizerproxy.h
@@ -185,10 +183,6 @@ SET(organizer_HDRS
eventfilter.h
descriptionpage.h
moshortcut.h
listdialog.h
lcdnumber.h
forcedloaddialog.h
forcedloaddialogwidget.h
shared/windows_error.h
shared/error_report.h
@@ -218,6 +212,8 @@ SET(organizer_UIS
installdialog.ui
finddialog.ui
editexecutablesdialog.ui
downloadlistwidgetcompact.ui
downloadlistwidget.ui
credentialsdialog.ui
categoriesdialog.ui
activatemodsdialog.ui
@@ -227,9 +223,6 @@ SET(organizer_UIS
previewdialog.ui
browserdialog.ui
aboutdialog.ui
listdialog.ui
forcedloaddialog.ui
forcedloaddialogwidget.ui
)
SET(organizer_QRCS
@@ -248,8 +241,7 @@ SOURCE_GROUP(Headers FILES ${organizer_HDRS})
SOURCE_GROUP(UI FILES ${organizer_UIS})
# MO projects
SET(dependency_project_path "${DEPENDENCIES_DIR}")
SET(default_project_path "${DEPENDENCIES_DIR}/modorganizer_super")
SET(default_project_path "${CMAKE_SOURCE_DIR}/..")
GET_FILENAME_COMPONENT(${default_project_path} ${default_project_path} REALPATH)
SET(project_path "${default_project_path}" CACHE PATH "path to the other mo projects")
@@ -266,7 +258,6 @@ FIND_PACKAGE(Qt5Quick REQUIRED)
FIND_PACKAGE(Qt5Network REQUIRED)
FIND_PACKAGE(Qt5WinExtras REQUIRED)
FIND_PACKAGE(Qt5WebEngineWidgets REQUIRED)
FIND_PACKAGE(Qt5WebSockets REQUIRED)
FIND_PACKAGE(Qt5Qml REQUIRED)
FIND_PACKAGE(Qt5LinguistTools)
QT5_WRAP_UI(organizer_UIHDRS ${organizer_UIS})
@@ -296,9 +287,8 @@ INCLUDE_DIRECTORIES(${project_path}/uibase/src
${project_path}/bsatk/src
${project_path}/esptk/src
${project_path}/archive/src
${dependency_project_path}/usvfs/include
${project_path}/game_gamebryo/src/gamebryo
${project_path}/game_gamebryo/src/creation
${project_path}/../usvfs/include
${project_path}/game_gamebryo/src
${project_path}/game_features/src
${project_path}/githubpp/src
${LZ4_ROOT}/include)
@@ -325,12 +315,12 @@ ENDIF()
ADD_EXECUTABLE(ModOrganizer WIN32 ${organizer_HDRS} ${organizer_SRCS} ${organizer_UIHDRS} ${organizer_RCS} ${organizer_RCCPPS} ${organizer_translations_qm})
TARGET_LINK_LIBRARIES(ModOrganizer
Qt5::Widgets Qt5::WinExtras Qt5::WebEngineWidgets Qt5::Quick
Qt5::Qml Qt5::QuickWidgets Qt5::Network Qt5::WebSockets
Qt5::Qml Qt5::QuickWidgets Qt5::Network
${Boost_LIBRARIES}
zlibstatic
uibase esptk bsatk githubpp
${usvfs_name}
Dbghelp advapi32 Version Shlwapi liblz4 Crypt32)
Dbghelp advapi32 Version Shlwapi liblz4)
IF (MSVC)
SET_TARGET_PROPERTIES(ModOrganizer PROPERTIES COMPILE_FLAGS "/std:c++latest")
@@ -368,12 +358,12 @@ SET(windeploy_parameters "--no-translations --plugindir qtplugins --libdir dlls
INSTALL(
CODE
"EXECUTE_PROCESS(COMMAND
${qt5bin}/windeployqt.exe ModOrganizer.exe --webenginewidgets --websockets ${windeploy_parameters}
${qt5bin}/windeployqt.exe ModOrganizer.exe --webenginewidgets ${windeploy_parameters}
WORKING_DIRECTORY ${CMAKE_INSTALL_PREFIX}/bin
)
# run it a second time because on the first run it misses some files
EXECUTE_PROCESS(COMMAND
${qt5bin}/windeployqt.exe ModOrganizer.exe --webenginewidgets --websockets ${windeploy_parameters}
${qt5bin}/windeployqt.exe ModOrganizer.exe --webenginewidgets ${windeploy_parameters}
WORKING_DIRECTORY ${CMAKE_INSTALL_PREFIX}/bin
)
EXECUTE_PROCESS(COMMAND
+12 -37
View File
@@ -157,7 +157,7 @@
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Lead Developers/ Maintainers</string>
<string>Current Maintainers</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
@@ -175,6 +175,11 @@
<string notr="true">AL12</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Diana</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">erasmux</string>
@@ -185,11 +190,6 @@
<string notr="true">Silarn</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">LostDragonist</string>
</property>
</item>
</widget>
</item>
</layout>
@@ -198,27 +198,17 @@
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Mo2 devs and Contributors</string>
<string>Major Contributors</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_7" stretch="0">
<item>
<widget class="QListWidget" name="listWidget_3">
<widget class="QListWidget" name="listWidget_2">
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<item>
<property name="text">
<string notr="true">AnyOldName3</string>
</property>
</item>
<item>
<property name="text">
<string>Project579</string>
</property>
</item>
<item>
<property name="text">
<string>przester</string>
<string notr="true">AnyOldName3 (Python Plugins)</string>
</property>
</item>
</widget>
@@ -231,9 +221,9 @@
<property name="title">
<string>Translators</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_61">
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QListWidget" name="listWidget_4">
<widget class="QListWidget" name="listWidget_2">
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
@@ -315,11 +305,6 @@
<string>Brgodfx (Portuguese)</string>
</property>
</item>
<item>
<property name="text">
<string>zDas (Portuguese)</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">tokcdk (Russian)</string>
@@ -340,11 +325,6 @@
<string>Jax (Swedish)</string>
</property>
</item>
<item>
<property name="text">
<string>yohru (Japanese)</string>
</property>
</item>
<item>
<property name="text">
<string>...and all other Transifex contributors!</string>
@@ -363,17 +343,12 @@
<property name="title">
<string>Other Supporters &amp;&amp; Contributors</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_71">
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QListWidget" name="listWidget">
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<item>
<property name="text">
<string>Tannin (Original Creator)</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">blacksol</string>
+2 -2
View File
@@ -88,7 +88,7 @@ public:
return temp.replace(tagIter->second.first, QString("<font style=\"color: #%1;\">%2</font>").arg(color, content));
}
} else {
qWarning("don't know how to deal with tag %s", qUtf8Printable(tagName));
qWarning("don't know how to deal with tag %s", qPrintable(tagName));
}
} else {
if (tagName == "*") {
@@ -100,7 +100,7 @@ public:
// expression doesn't match. either the input string is invalid
// or the expression is
qWarning("%s doesn't match the expression for %s",
qUtf8Printable(temp), qUtf8Printable(tagName));
temp.toUtf8().constData(), tagName.toUtf8().constData());
length = 0;
return QString();
}
+6 -6
View File
@@ -72,7 +72,7 @@ void CategoryFactory::loadCategories()
bool ok = false;
int temp = iter->toInt(&ok);
if (!ok) {
qCritical("invalid category id %s", iter->constData());
qCritical("invalid id %s", iter->constData());
}
nexusIDs.push_back(temp);
}
@@ -268,7 +268,7 @@ void CategoryFactory::loadDefaultCategories()
int CategoryFactory::getParentID(unsigned int index) const
{
if (index >= m_Categories.size()) {
throw MyException(QObject::tr("invalid category index: %1").arg(index));
throw MyException(QObject::tr("invalid index %1").arg(index));
}
return m_Categories[index].m_ParentID;
@@ -303,7 +303,7 @@ bool CategoryFactory::isDecendantOf(int id, int parentID) const
bool CategoryFactory::hasChildren(unsigned int index) const
{
if (index >= m_Categories.size()) {
throw MyException(QObject::tr("invalid category index: %1").arg(index));
throw MyException(QObject::tr("invalid index %1").arg(index));
}
return m_Categories[index].m_HasChildren;
@@ -313,7 +313,7 @@ bool CategoryFactory::hasChildren(unsigned int index) const
QString CategoryFactory::getCategoryName(unsigned int index) const
{
if (index >= m_Categories.size()) {
throw MyException(QObject::tr("invalid category index: %1").arg(index));
throw MyException(QObject::tr("invalid index %1").arg(index));
}
return m_Categories[index].m_Name;
@@ -323,7 +323,7 @@ QString CategoryFactory::getCategoryName(unsigned int index) const
int CategoryFactory::getCategoryID(unsigned int index) const
{
if (index >= m_Categories.size()) {
throw MyException(QObject::tr("invalid category index: %1").arg(index));
throw MyException(QObject::tr("invalid index %1").arg(index));
}
return m_Categories[index].m_ID;
@@ -334,7 +334,7 @@ int CategoryFactory::getCategoryIndex(int ID) const
{
std::map<int, unsigned int>::const_iterator iter = m_IDMap.find(ID);
if (iter == m_IDMap.end()) {
throw MyException(QObject::tr("invalid category id: %1").arg(ID));
throw MyException(QObject::tr("invalid category id %1").arg(ID));
}
return iter->second;
}
+2 -4
View File
@@ -47,10 +47,8 @@ public:
static const int CATEGORY_SPECIAL_NOCATEGORY = 10003;
static const int CATEGORY_SPECIAL_CONFLICT = 10004;
static const int CATEGORY_SPECIAL_NOTENDORSED = 10005;
static const int CATEGORY_SPECIAL_BACKUP = 10006;
static const int CATEGORY_SPECIAL_MANAGED = 10007;
static const int CATEGORY_SPECIAL_UNMANAGED = 10008;
static const int CATEGORY_SPECIAL_MANAGED = 10006;
static const int CATEGORY_SPECIAL_UNMANAGED = 10007;
public:
+10
View File
@@ -32,6 +32,16 @@ CredentialsDialog::~CredentialsDialog()
delete ui;
}
QString CredentialsDialog::username() const
{
return ui->usernameEdit->text();
}
QString CredentialsDialog::password() const
{
return ui->passwordEdit->text();
}
bool CredentialsDialog::store() const
{
return ui->rememberCheck->isChecked();
+3
View File
@@ -34,6 +34,9 @@ public:
explicit CredentialsDialog(QWidget *parent = 0);
~CredentialsDialog();
QString username() const;
QString password() const;
bool store() const;
bool neverAsk() const;
+7 -37
View File
@@ -23,13 +23,10 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "utility.h"
#include "report.h"
#include "modinfo.h"
#include "settings.h"
#include <QApplication>
#include <QDir>
#include <QString>
#include <QTextCodec>
#include <gameplugins.h>
using namespace MOBase;
@@ -86,29 +83,13 @@ void DirectoryRefresher::addModBSAToStructure(DirectoryEntry *directoryStructure
int priority, const QString &directory, const QStringList &archives)
{
std::wstring directoryW = ToWString(QDir::toNativeSeparators(directory));
IPluginGame *game = qApp->property("managed_game").value<IPluginGame*>();
GamePlugins *gamePlugins = game->feature<GamePlugins>();
QStringList loadOrder = QStringList();
gamePlugins->getLoadOrder(loadOrder);
for (const QString &archive : archives) {
QFileInfo fileInfo(archive);
if (m_EnabledArchives.find(fileInfo.fileName()) != m_EnabledArchives.end()) {
int order = -1;
for (auto plugin : loadOrder)
{
QString name = plugin.left(plugin.size() - 4);
if (fileInfo.fileName().startsWith(name + " - ", Qt::CaseInsensitive) || fileInfo.fileName().startsWith(name + ".", Qt::CaseInsensitive)) {
order = loadOrder.indexOf(plugin);
}
}
try {
IPluginGame *game = qApp->property("managed_game").value<IPluginGame*>();
directoryStructure->addFromBSA(ToWString(modName), directoryW, ToWString(QDir::toNativeSeparators(fileInfo.absoluteFilePath())), priority, order);
//directoryStructure->addFromBSA(ToWString(modName), directoryW,
// ToWString(QDir::toNativeSeparators(fileInfo.absoluteFilePath())), priority);
} catch (const std::exception &e) {
throw MyException(tr("failed to parse bsa %1: %2").arg(archive, e.what()));
}
@@ -126,10 +107,6 @@ void DirectoryRefresher::addModFilesToStructure(DirectoryEntry *directoryStructu
// files to this mod
FilesOrigin &origin = directoryStructure->createOrigin(ToWString(modName), directoryW, priority);
for (const QString &filename : stealFiles) {
if (filename.isEmpty()) {
qWarning("Trying to find file with no name");
continue;
}
QFileInfo fileInfo(filename);
FileEntry::Ptr file = directoryStructure->findFile(ToWString(fileInfo.fileName()));
if (file.get() != nullptr) {
@@ -138,12 +115,9 @@ void DirectoryRefresher::addModFilesToStructure(DirectoryEntry *directoryStructu
file->removeOrigin(0);
}
origin.addFile(file->getIndex());
file->addOrigin(origin.getID(), file->getFileTime(), L"", -1);
file->addOrigin(origin.getID(), file->getFileTime(), L"");
} else {
QString warnStr = fileInfo.absolutePath();
if (warnStr.isEmpty())
warnStr = filename;
qWarning("file not found: %s", qUtf8Printable(warnStr));
qWarning("%s not found", qPrintable(fileInfo.fileName()));
}
}
} else {
@@ -159,10 +133,7 @@ void DirectoryRefresher::addModToStructure(DirectoryEntry *directoryStructure
, const QStringList &archives)
{
addModFilesToStructure(directoryStructure, modName, priority, directory, stealFiles);
if (Settings::instance().archiveParsing()) {
addModBSAToStructure(directoryStructure, modName, priority, directory, archives);
}
addModBSAToStructure(directoryStructure, modName, priority, directory, archives);
}
void DirectoryRefresher::refresh()
@@ -178,9 +149,10 @@ void DirectoryRefresher::refresh()
std::wstring dataDirectory = QDir::toNativeSeparators(game->dataDirectory().absolutePath()).toStdWString();
m_DirectoryStructure->addFromOrigin(L"data", dataDirectory, 0);
std::sort(m_Mods.begin(), m_Mods.end(), [](auto lhs, auto rhs){return lhs.priority < rhs.priority;});
// TODO what was the point of having the priority in this tuple? the list is already sorted by priority
auto iter = m_Mods.begin();
//TODO i is the priority here, where higher = more important. the input vector is also sorted by priority but inverted!
for (int i = 1; iter != m_Mods.end(); ++iter, ++i) {
try {
addModToStructure(m_DirectoryStructure, iter->modName, i, iter->absolutePath, iter->stealFiles, iter->archives);
@@ -190,8 +162,6 @@ void DirectoryRefresher::refresh()
emit progress((i * 100) / static_cast<int>(m_Mods.size()) + 1);
}
m_DirectoryStructure->getFileRegister()->sortOrigins();
emit progress(100);
cleanStructure(m_DirectoryStructure);
-1
View File
@@ -27,7 +27,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <vector>
#include <set>
#include <tuple>
#include "profile.h"
/**
+1 -2
View File
@@ -21,7 +21,6 @@
<file name="Qt5Svg.dll"/>
<file name="Qt5WebEngineCore.dll"/>
<file name="Qt5WebEngineWidgets.dll"/>
<file name="Qt5WebSockets.dll"/>
<file name="Qt5Widgets.dll"/>
<file name="Qt5WinExtras.dll"/>
</assembly>
</assembly>
+16 -89
View File
@@ -20,8 +20,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "downloadlist.h"
#include "downloadmanager.h"
#include <QEvent>
#include <QColor>
#include <QIcon>
#include <QSortFilterProxyModel>
@@ -33,11 +31,6 @@ DownloadList::DownloadList(DownloadManager *manager, QObject *parent)
connect(m_Manager, SIGNAL(aboutToUpdate()), this, SLOT(aboutToUpdate()));
}
void DownloadList::setMetaDisplay(bool metaDisplay)
{
m_MetaDisplay = metaDisplay;
}
int DownloadList::rowCount(const QModelIndex&) const
{
@@ -47,7 +40,7 @@ int DownloadList::rowCount(const QModelIndex&) const
int DownloadList::columnCount(const QModelIndex&) const
{
return 4;
return 3;
}
@@ -69,86 +62,35 @@ QVariant DownloadList::headerData(int section, Qt::Orientation orientation, int
(orientation == Qt::Horizontal)) {
switch (section) {
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();
default: return tr("Done");
}
} else {
return QAbstractItemModel::headerData(section, orientation, role);
}
}
QVariant DownloadList::data(const QModelIndex &index, int role) const
{
bool pendingDownload = index.row() >= m_Manager->numTotalDownloads();
if (role == Qt::DisplayRole) {
if (pendingDownload) {
std::tuple<QString, int, int> nexusids = m_Manager->getPendingDownload(index.row() - m_Manager->numTotalDownloads());
switch (index.column()) {
case COL_NAME: return tr("< game %1 mod %2 file %3 >").arg(std::get<0>(nexusids)).arg(std::get<1>(nexusids)).arg(std::get<2>(nexusids));
case COL_SIZE: return tr("Unknown");
case COL_STATUS: return tr("Pending");
}
} else {
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
case DownloadManager::STATE_STARTED: return tr("Started");
case DownloadManager::STATE_CANCELING: return tr("Canceling");
case DownloadManager::STATE_PAUSING: return tr("Pausing");
case DownloadManager::STATE_CANCELED: return tr("Canceled");
case DownloadManager::STATE_PAUSED: return tr("Paused");
case DownloadManager::STATE_ERROR: return tr("Error");
case DownloadManager::STATE_FETCHINGMODINFO: return tr("Fetching Info");
case DownloadManager::STATE_FETCHINGFILEINFO: return tr("Fetching Info");
case DownloadManager::STATE_FETCHINGMODINFO_MD5: return tr("Fetching Info");
case DownloadManager::STATE_READY: return tr("Downloaded");
case DownloadManager::STATE_INSTALLED: return tr("Installed");
case DownloadManager::STATE_UNINSTALLED: return tr("Uninstalled");
}
}
}
} else if (role == Qt::ForegroundRole && index.column() == COL_STATUS) {
if (pendingDownload) {
return QColor(Qt::darkBlue);
} else {
DownloadManager::DownloadState state = m_Manager->getState(index.row());
if (state == DownloadManager::STATE_READY)
return QColor(Qt::darkGreen);
else if (state == DownloadManager::STATE_UNINSTALLED)
return QColor(Qt::darkYellow);
else if (state == DownloadManager::STATE_PAUSED)
return QColor(Qt::darkRed);
}
return index.row();
} else if (role == Qt::ToolTipRole) {
if (pendingDownload) {
return tr("Pending download");
} else {
if (index.row() < m_Manager->numTotalDownloads()) {
QString text = m_Manager->getFileName(index.row()) + "\n";
if (m_Manager->isInfoIncomplete(index.row())) {
text += tr("Information missing, please select \"Query Info\" from the context menu to re-retrieve.");
} else {
const MOBase::ModRepositoryFileInfo *info = m_Manager->getFileInfo(index.row());
return QString("%1 (ID %2) %3<br><span>%4</span>").arg(info->modName).arg(m_Manager->getModID(index.row())).arg(info->version.canonicalString()).arg(info->description.chopped(4096));
return QString("%1 (ID %2) %3<br><span>%4</span>").arg(info->modName).arg(m_Manager->getModID(index.row())).arg(info->version.canonicalString()).arg(info->description);
}
return text;
} else {
return tr("pending download");
}
} else if (role == Qt::DecorationRole && index.column() == COL_NAME) {
if (!pendingDownload && m_Manager->getState(index.row()) >= DownloadManager::STATE_READY
&& m_Manager->isInfoIncomplete(index.row()))
return QIcon(":/MO/gui/warning_16");
} else if (role == Qt::TextAlignmentRole) {
if (index.column() == COL_NAME)
return QVariant(Qt::AlignVCenter | Qt::AlignLeft);
else
return QVariant(Qt::AlignVCenter | Qt::AlignRight);
} else {
return QVariant();
}
return QVariant();
}
@@ -160,28 +102,13 @@ void DownloadList::aboutToUpdate()
void DownloadList::update(int row)
{
if (row < 0)
if (row < 0) {
emit endResetModel();
else if (row < this->rowCount())
emit dataChanged(this->index(row, 0, QModelIndex()), this->index(row, this->columnCount(QModelIndex())-1, QModelIndex()));
else
} else if (row < this->rowCount()) {
#pragma message("updating only the one column is a hack")
emit dataChanged(this->index(row, 2, QModelIndex()), this->index(row, 2, QModelIndex()));
} else {
qCritical("invalid row %d in download list, update failed", 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;
}
+3 -7
View File
@@ -22,6 +22,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QAbstractTableModel>
class DownloadManager;
@@ -37,9 +38,8 @@ public:
enum EColumn {
COL_NAME = 0,
COL_STATUS,
COL_SIZE,
COL_FILETIME
COL_FILETIME,
COL_STATUS
};
public:
@@ -52,8 +52,6 @@ public:
**/
explicit DownloadList(DownloadManager *manager, QObject *parent = 0);
void setMetaDisplay(bool metaDisplay);
/**
* @brief retrieve the number of rows to display. Invoked by Qt
*
@@ -92,9 +90,7 @@ public slots:
private:
DownloadManager *m_Manager;
bool m_MetaDisplay;
QString sizeFormat(quint64 size) const;
};
#endif // DOWNLOADLIST_H
+10 -15
View File
@@ -37,23 +37,16 @@ void DownloadListSortProxy::updateFilter(const QString &filter)
bool DownloadListSortProxy::lessThan(const QModelIndex &left,
const QModelIndex &right) const
{
int leftIndex = left.row();
int rightIndex = right.row();
int leftIndex = left.data().toInt();
int rightIndex = right.data().toInt();
if ((leftIndex < m_Manager->numTotalDownloads())
&& (rightIndex < m_Manager->numTotalDownloads())) {
if (left.column() == DownloadList::COL_NAME) {
return m_Manager->getFileName(left.row()).compare(m_Manager->getFileName(right.row()), Qt::CaseInsensitive) < 0;
} else if (left.column() == DownloadList::COL_STATUS) {
DownloadManager::DownloadState leftState = m_Manager->getState(left.row());
DownloadManager::DownloadState rightState = m_Manager->getState(right.row());
if (leftState == rightState)
return m_Manager->getFileTime(left.row()) < m_Manager->getFileTime(right.row());
else
return leftState > rightState;
} else if (left.column() == DownloadList::COL_SIZE) {
return m_Manager->getFileSize(left.row()) < m_Manager->getFileSize(right.row());
return m_Manager->getFileName(leftIndex).compare(m_Manager->getFileName(rightIndex), Qt::CaseInsensitive) < 0;
} else if (left.column() == DownloadList::COL_FILETIME) {
return m_Manager->getFileTime(left.row()) < m_Manager->getFileTime(right.row());
return m_Manager->getFileTime(leftIndex) < m_Manager->getFileTime(rightIndex);
} else if (left.column() == DownloadList::COL_STATUS) {
return m_Manager->getState(leftIndex) < m_Manager->getState(rightIndex);
} else {
return leftIndex < rightIndex;
}
@@ -68,9 +61,11 @@ 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(sourceRow)
: m_Manager->getFileName(sourceRow);
? m_Manager->getDisplayName(downloadIndex)
: m_Manager->getFileName(downloadIndex);
return displayedName.contains(m_CurrentFilter, Qt::CaseInsensitive);
} else {
return false;

Some files were not shown because too many files have changed in this diff Show More