mirror of
https://github.com/ModOrganizer2/modorganizer.git
synced 2026-07-27 13:58:24 -07:00
Compare commits
223
Commits
v2.1.6
...
v2.2.0beta3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd9cc6254c | ||
|
|
57fd35fc47 | ||
|
|
ee266e5220 | ||
|
|
d0a6321a39 | ||
|
|
b1f91d28fb | ||
|
|
c19ba15337 | ||
|
|
4b98a3f5b6 | ||
|
|
55249ba3a6 | ||
|
|
600b0786eb | ||
|
|
02c5b083dc | ||
|
|
4d8920cec1 | ||
|
|
2106f29224 | ||
|
|
ad7d740a0b | ||
|
|
1c02ae101b | ||
|
|
280a32597f | ||
|
|
749ceff04f | ||
|
|
448a37e6bc | ||
|
|
d4a066dbd9 | ||
|
|
a803baa900 | ||
|
|
777ebdd922 | ||
|
|
a7350a1940 | ||
|
|
67cb214d47 | ||
|
|
dc1b1dd829 | ||
|
|
b38a26c2bc | ||
|
|
5eb686ac48 | ||
|
|
c98f00f77e | ||
|
|
de2274e175 | ||
|
|
75d16660fd | ||
|
|
1d55e1f6f9 | ||
|
|
5767e27925 | ||
|
|
98683eca6f | ||
|
|
10336caf9e | ||
|
|
3444b9a46e | ||
|
|
2201a5b0dd | ||
|
|
02433c486b | ||
|
|
bd0efe4d60 | ||
|
|
0cac03cdf6 | ||
|
|
46e2eac1ca | ||
|
|
1369c8d571 | ||
|
|
4b522f40e8 | ||
|
|
6d45350546 | ||
|
|
cfc0b3c055 | ||
|
|
d3f1006a51 | ||
|
|
583bc5b6c6 | ||
|
|
34640c4d08 | ||
|
|
6e3d40a230 | ||
|
|
4b87be4d3d | ||
|
|
3f2a41979e | ||
|
|
26d5313cba | ||
|
|
0740b2b22f | ||
|
|
2053efac29 | ||
|
|
a853b07953 | ||
|
|
08c298c964 | ||
|
|
3372230ca9 | ||
|
|
a68a027feb | ||
|
|
63511cd390 | ||
|
|
75d29f7e03 | ||
|
|
ae794dba32 | ||
|
|
c0c754728c | ||
|
|
0ab87850c4 | ||
|
|
5800f2b7b3 | ||
|
|
7fd81029ce | ||
|
|
a349ec24df | ||
|
|
a40613f885 | ||
|
|
917c08cd5f | ||
|
|
11b2e0fe34 | ||
|
|
fe04cb47e1 | ||
|
|
8719248fcf | ||
|
|
23e81f7109 | ||
|
|
6d36f1d959 | ||
|
|
952a9c2ded | ||
|
|
e6e8ce1d68 | ||
|
|
a63d12bd0f | ||
|
|
5b8b2ddac7 | ||
|
|
2ee3aec6b5 | ||
|
|
077a050e59 | ||
|
|
0d04ba1873 | ||
|
|
9c364c0dff | ||
|
|
643d2a7725 | ||
|
|
5efba39f86 | ||
|
|
821ca74166 | ||
|
|
864cab8c8a | ||
|
|
ea3df2e9bd | ||
|
|
37e1009d94 | ||
|
|
029da32412 | ||
|
|
d24519501f | ||
|
|
64a242d922 | ||
|
|
b41c99b742 | ||
|
|
e9c35cad2e | ||
|
|
9c721c08eb | ||
|
|
aa934e5fb3 | ||
|
|
f1572a2fc4 | ||
|
|
04a4346dc8 | ||
|
|
cc7c3adcad | ||
|
|
2d78ac26c8 | ||
|
|
96b6677ed9 | ||
|
|
347ac2b8b5 | ||
|
|
183069a85d | ||
|
|
ff49e2a43c | ||
|
|
d0445685bf | ||
|
|
14b117d74a | ||
|
|
301c1156f8 | ||
|
|
fa8e40adcb | ||
|
|
d32695843d | ||
|
|
f2ea231f92 | ||
|
|
2a010e5cdb | ||
|
|
eb6ee86da4 | ||
|
|
e35cdd6c89 | ||
|
|
f2c145b2fc | ||
|
|
cc7d1ed721 | ||
|
|
08477d6524 | ||
|
|
23426d920e | ||
|
|
e97f073570 | ||
|
|
299a769a83 | ||
|
|
14782a374c | ||
|
|
070a9a4d47 | ||
|
|
3d24650095 | ||
|
|
a6e526210f | ||
|
|
3839de53f0 | ||
|
|
474fdca394 | ||
|
|
c54bc7edfa | ||
|
|
c57d7567c4 | ||
|
|
683d17784b | ||
|
|
0d0e9ee175 | ||
|
|
15e4711417 | ||
|
|
5ad411cd47 | ||
|
|
9a2b9224ca | ||
|
|
35995a4989 | ||
|
|
76fb954b3d | ||
|
|
523cb203ce | ||
|
|
6fa416fc52 | ||
|
|
619a0887d8 | ||
|
|
9c1cbed8db | ||
|
|
ad752182bc | ||
|
|
63b2189416 | ||
|
|
79ccbccb1b | ||
|
|
d8396bfa2c | ||
|
|
858930cb46 | ||
|
|
44d42cb26d | ||
|
|
263a3f7d24 | ||
|
|
79a2f8477b | ||
|
|
954785f83e | ||
|
|
895556f257 | ||
|
|
e7c59b26e1 | ||
|
|
fd6345cd4e | ||
|
|
f3ee7a0566 | ||
|
|
527b310ef3 | ||
|
|
b8babae78a | ||
|
|
776bc8efdf | ||
|
|
412a062082 | ||
|
|
ba57657b4f | ||
|
|
398cc0112e | ||
|
|
4809c30132 | ||
|
|
7cdaecc5bd | ||
|
|
03823a433a | ||
|
|
580f45429f | ||
|
|
22643edb21 | ||
|
|
e9fe45eb89 | ||
|
|
b2ca83366a | ||
|
|
c11ff7e2db | ||
|
|
cfb941082e | ||
|
|
463abedee7 | ||
|
|
4d40e8d18c | ||
|
|
c3ad0349d4 | ||
|
|
7a71a9eb9e | ||
|
|
ec8dbcbf28 | ||
|
|
5920dc2cd1 | ||
|
|
71091f679d | ||
|
|
302f9b99d8 | ||
|
|
b842eb1ca3 | ||
|
|
b525ee392f | ||
|
|
7f0844bdd4 | ||
|
|
87c6b019bc | ||
|
|
5fc107cdb2 | ||
|
|
d6f9e6d900 | ||
|
|
eb50d0b447 | ||
|
|
f6884fe3d6 | ||
|
|
93a60177ee | ||
|
|
b82677fab1 | ||
|
|
66bf2ab537 | ||
|
|
2d9cf25657 | ||
|
|
dea754ad91 | ||
|
|
b84e938726 | ||
|
|
b397e0bc5d | ||
|
|
4cc371ab84 | ||
|
|
bbed72c6a3 | ||
|
|
a3110731ca | ||
|
|
6a4e52f9dc | ||
|
|
66d0ae4317 | ||
|
|
fecb66f66b | ||
|
|
85eb57eebb | ||
|
|
22f40072cf | ||
|
|
40a3e93c46 | ||
|
|
d021011cfa | ||
|
|
5f06da756e | ||
|
|
7fa230411e | ||
|
|
23cf8e60fd | ||
|
|
d28ddcfbb5 | ||
|
|
6211a23c5f | ||
|
|
ce02da497a | ||
|
|
fcff329c1e | ||
|
|
2d79e37e59 | ||
|
|
77e4cb5c6e | ||
|
|
69ff53f443 | ||
|
|
127fbda849 | ||
|
|
d8e988d372 | ||
|
|
da3a95ed66 | ||
|
|
101d656709 | ||
|
|
549db7d331 | ||
|
|
9bc15eb6f7 | ||
|
|
70ddfaadbf | ||
|
|
afdd21440a | ||
|
|
a899823fff | ||
|
|
3161bdb9a5 | ||
|
|
4436d376a8 | ||
|
|
40c82fc190 | ||
|
|
57178f8988 | ||
|
|
49159de5d7 | ||
|
|
75a663941d | ||
|
|
b05f56c808 | ||
|
|
f9f70b224e | ||
|
|
01e1232cf8 | ||
|
|
8d6c715672 |
@@ -1,25 +0,0 @@
|
||||
# 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!
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
name: Dev Ticket
|
||||
about: Reserved for development tasks and management.
|
||||
title: ''
|
||||
labels: Dev Ticket
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Task:
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
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.
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
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!
|
||||
+8
-4
@@ -54,7 +54,6 @@ SET(organizer_SRCS
|
||||
executableslist.cpp
|
||||
editexecutablesdialog.cpp
|
||||
downloadmanager.cpp
|
||||
downloadlistwidgetcompact.cpp
|
||||
downloadlistwidget.cpp
|
||||
downloadlistsortproxy.cpp
|
||||
downloadlist.cpp
|
||||
@@ -92,6 +91,9 @@ SET(organizer_SRCS
|
||||
eventfilter.cpp
|
||||
moshortcut.cpp
|
||||
listdialog.cpp
|
||||
lcdnumber.cpp
|
||||
forcedloaddialog.cpp
|
||||
forcedloaddialogwidget.cpp
|
||||
|
||||
shared/windows_error.cpp
|
||||
shared/error_report.cpp
|
||||
@@ -146,7 +148,6 @@ SET(organizer_HDRS
|
||||
executableslist.h
|
||||
editexecutablesdialog.h
|
||||
downloadmanager.h
|
||||
downloadlistwidgetcompact.h
|
||||
downloadlistwidget.h
|
||||
downloadlistsortproxy.h
|
||||
downloadlist.h
|
||||
@@ -187,6 +188,9 @@ SET(organizer_HDRS
|
||||
descriptionpage.h
|
||||
moshortcut.h
|
||||
listdialog.h
|
||||
lcdnumber.h
|
||||
forcedloaddialog.h
|
||||
forcedloaddialogwidget.h
|
||||
|
||||
shared/windows_error.h
|
||||
shared/error_report.h
|
||||
@@ -216,8 +220,6 @@ SET(organizer_UIS
|
||||
installdialog.ui
|
||||
finddialog.ui
|
||||
editexecutablesdialog.ui
|
||||
downloadlistwidgetcompact.ui
|
||||
downloadlistwidget.ui
|
||||
credentialsdialog.ui
|
||||
categoriesdialog.ui
|
||||
activatemodsdialog.ui
|
||||
@@ -228,6 +230,8 @@ SET(organizer_UIS
|
||||
browserdialog.ui
|
||||
aboutdialog.ui
|
||||
listdialog.ui
|
||||
forcedloaddialog.ui
|
||||
forcedloaddialogwidget.ui
|
||||
)
|
||||
|
||||
SET(organizer_QRCS
|
||||
|
||||
+32
-12
@@ -157,7 +157,7 @@
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Current Maintainers</string>
|
||||
<string>Lead Developers/ Maintainers</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
@@ -175,11 +175,6 @@
|
||||
<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>
|
||||
@@ -190,7 +185,7 @@
|
||||
<string notr="true">Silarn</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">LostDragonist</string>
|
||||
</property>
|
||||
@@ -203,11 +198,11 @@
|
||||
<item row="1" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Major Contributors</string>
|
||||
<string>Mo2 devs and Contributors</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7" stretch="0">
|
||||
<item>
|
||||
<widget class="QListWidget" name="listWidget_2">
|
||||
<widget class="QListWidget" name="listWidget_3">
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::NoSelection</enum>
|
||||
</property>
|
||||
@@ -216,6 +211,16 @@
|
||||
<string notr="true">AnyOldName3</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Project579</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>przester</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@@ -226,9 +231,9 @@
|
||||
<property name="title">
|
||||
<string>Translators</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_61">
|
||||
<item>
|
||||
<widget class="QListWidget" name="listWidget_2">
|
||||
<widget class="QListWidget" name="listWidget_4">
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::NoSelection</enum>
|
||||
</property>
|
||||
@@ -310,6 +315,11 @@
|
||||
<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>
|
||||
@@ -330,6 +340,11 @@
|
||||
<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>
|
||||
@@ -348,12 +363,17 @@
|
||||
<property name="title">
|
||||
<string>Other Supporters && Contributors</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_71">
|
||||
<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
@@ -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", qPrintable(tagName));
|
||||
qWarning("don't know how to deal with tag %s", qUtf8Printable(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",
|
||||
temp.toUtf8().constData(), tagName.toUtf8().constData());
|
||||
qUtf8Printable(temp), qUtf8Printable(tagName));
|
||||
length = 0;
|
||||
return QString();
|
||||
}
|
||||
|
||||
+6
-6
@@ -72,7 +72,7 @@ void CategoryFactory::loadCategories()
|
||||
bool ok = false;
|
||||
int temp = iter->toInt(&ok);
|
||||
if (!ok) {
|
||||
qCritical("invalid id %s", iter->constData());
|
||||
qCritical("invalid category 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 index %1").arg(index));
|
||||
throw MyException(QObject::tr("invalid category 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 index %1").arg(index));
|
||||
throw MyException(QObject::tr("invalid category 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 index %1").arg(index));
|
||||
throw MyException(QObject::tr("invalid category 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 index %1").arg(index));
|
||||
throw MyException(QObject::tr("invalid category 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;
|
||||
}
|
||||
|
||||
@@ -23,10 +23,13 @@ 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;
|
||||
@@ -83,13 +86,29 @@ 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 {
|
||||
//directoryStructure->addFromBSA(ToWString(modName), directoryW,
|
||||
// ToWString(QDir::toNativeSeparators(fileInfo.absoluteFilePath())), priority);
|
||||
IPluginGame *game = qApp->property("managed_game").value<IPluginGame*>();
|
||||
directoryStructure->addFromBSA(ToWString(modName), directoryW, ToWString(QDir::toNativeSeparators(fileInfo.absoluteFilePath())), priority, order);
|
||||
} catch (const std::exception &e) {
|
||||
throw MyException(tr("failed to parse bsa %1: %2").arg(archive, e.what()));
|
||||
}
|
||||
@@ -107,6 +126,10 @@ 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) {
|
||||
@@ -115,9 +138,12 @@ void DirectoryRefresher::addModFilesToStructure(DirectoryEntry *directoryStructu
|
||||
file->removeOrigin(0);
|
||||
}
|
||||
origin.addFile(file->getIndex());
|
||||
file->addOrigin(origin.getID(), file->getFileTime(), L"");
|
||||
file->addOrigin(origin.getID(), file->getFileTime(), L"", -1);
|
||||
} else {
|
||||
qWarning("%s not found", qPrintable(fileInfo.fileName()));
|
||||
QString warnStr = fileInfo.absolutePath();
|
||||
if (warnStr.isEmpty())
|
||||
warnStr = filename;
|
||||
qWarning("file not found: %s", qUtf8Printable(warnStr));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -133,7 +159,10 @@ void DirectoryRefresher::addModToStructure(DirectoryEntry *directoryStructure
|
||||
, const QStringList &archives)
|
||||
{
|
||||
addModFilesToStructure(directoryStructure, modName, priority, directory, stealFiles);
|
||||
addModBSAToStructure(directoryStructure, modName, priority, directory, archives);
|
||||
|
||||
if (Settings::instance().archiveParsing()) {
|
||||
addModBSAToStructure(directoryStructure, modName, priority, directory, archives);
|
||||
}
|
||||
}
|
||||
|
||||
void DirectoryRefresher::refresh()
|
||||
@@ -162,6 +191,8 @@ void DirectoryRefresher::refresh()
|
||||
emit progress((i * 100) / static_cast<int>(m_Mods.size()) + 1);
|
||||
}
|
||||
|
||||
m_DirectoryStructure->getFileRegister()->sortOrigins();
|
||||
|
||||
emit progress(100);
|
||||
|
||||
cleanStructure(m_DirectoryStructure);
|
||||
|
||||
@@ -27,6 +27,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <tuple>
|
||||
#include "profile.h"
|
||||
|
||||
|
||||
/**
|
||||
|
||||
+86
-15
@@ -20,6 +20,8 @@ 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>
|
||||
|
||||
@@ -31,6 +33,11 @@ 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
|
||||
{
|
||||
@@ -62,22 +69,65 @@ QVariant DownloadList::headerData(int section, Qt::Orientation orientation, int
|
||||
(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_STATUS: return tr("Status");
|
||||
case COL_FILETIME: return tr("Filetime");
|
||||
default: return QVariant();
|
||||
}
|
||||
} 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) {
|
||||
return index.row();
|
||||
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 1");
|
||||
case DownloadManager::STATE_FETCHINGFILEINFO: return tr("Fetching Info 2");
|
||||
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);
|
||||
}
|
||||
} else if (role == Qt::ToolTipRole) {
|
||||
if (index.row() < m_Manager->numTotalDownloads()) {
|
||||
if (pendingDownload) {
|
||||
return tr("Pending download");
|
||||
} else {
|
||||
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.");
|
||||
@@ -86,12 +136,18 @@ QVariant DownloadList::data(const QModelIndex &index, int role) const
|
||||
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 {
|
||||
return QVariant();
|
||||
} 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);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
|
||||
@@ -103,13 +159,28 @@ void DownloadList::aboutToUpdate()
|
||||
|
||||
void DownloadList::update(int row)
|
||||
{
|
||||
if (row < 0) {
|
||||
if (row < 0)
|
||||
emit endResetModel();
|
||||
} else if (row < this->rowCount()) {
|
||||
#pragma message("updating only the one column is a hack")
|
||||
emit dataChanged(this->index(row, 2, QModelIndex()), this->index(row, 2, QModelIndex()));
|
||||
} else {
|
||||
else if (row < this->rowCount())
|
||||
emit dataChanged(this->index(row, 0, QModelIndex()), this->index(row, this->columnCount(QModelIndex())-1, QModelIndex()));
|
||||
else
|
||||
qCritical("invalid row %d in download list, update failed", row);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
+6
-3
@@ -22,7 +22,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
|
||||
|
||||
class DownloadManager;
|
||||
|
||||
|
||||
@@ -38,9 +37,9 @@ public:
|
||||
|
||||
enum EColumn {
|
||||
COL_NAME = 0,
|
||||
COL_FILETIME,
|
||||
COL_STATUS,
|
||||
COL_SIZE
|
||||
COL_SIZE,
|
||||
COL_FILETIME
|
||||
};
|
||||
|
||||
public:
|
||||
@@ -53,6 +52,8 @@ public:
|
||||
**/
|
||||
explicit DownloadList(DownloadManager *manager, QObject *parent = 0);
|
||||
|
||||
void setMetaDisplay(bool metaDisplay);
|
||||
|
||||
/**
|
||||
* @brief retrieve the number of rows to display. Invoked by Qt
|
||||
*
|
||||
@@ -91,7 +92,9 @@ public slots:
|
||||
private:
|
||||
|
||||
DownloadManager *m_Manager;
|
||||
bool m_MetaDisplay;
|
||||
|
||||
QString sizeFormat(quint64 size) const;
|
||||
};
|
||||
|
||||
#endif // DOWNLOADLIST_H
|
||||
|
||||
@@ -37,18 +37,23 @@ void DownloadListSortProxy::updateFilter(const QString &filter)
|
||||
bool DownloadListSortProxy::lessThan(const QModelIndex &left,
|
||||
const QModelIndex &right) const
|
||||
{
|
||||
int leftIndex = left.data().toInt();
|
||||
int rightIndex = right.data().toInt();
|
||||
int leftIndex = left.row();
|
||||
int rightIndex = right.row();
|
||||
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);
|
||||
} else if(left.column() == DownloadList::COL_SIZE){
|
||||
return m_Manager->getFileSize(leftIndex) < m_Manager->getFileSize(rightIndex);
|
||||
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());
|
||||
} else if (left.column() == DownloadList::COL_FILETIME) {
|
||||
return m_Manager->getFileTime(left.row()) < m_Manager->getFileTime(right.row());
|
||||
} else {
|
||||
return leftIndex < rightIndex;
|
||||
}
|
||||
@@ -63,11 +68,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;
|
||||
|
||||
+218
-287
File diff suppressed because it is too large
Load Diff
+42
-52
@@ -21,49 +21,61 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define DOWNLOADLISTWIDGET_H
|
||||
|
||||
#include "downloadmanager.h"
|
||||
#include "downloadlist.h"
|
||||
#include "downloadlistsortproxy.h"
|
||||
#include <QWidget>
|
||||
#include <QItemDelegate>
|
||||
#include <QLabel>
|
||||
#include <QProgressBar>
|
||||
#include <QTreeView>
|
||||
#include <QHeaderView>
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class DownloadListWidget;
|
||||
class DownloadListWidget;
|
||||
}
|
||||
|
||||
class DownloadListWidget : public QWidget
|
||||
class DownloadProgressDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DownloadListWidget(QWidget *parent = 0);
|
||||
~DownloadListWidget();
|
||||
|
||||
|
||||
private:
|
||||
Ui::DownloadListWidget *ui;
|
||||
};
|
||||
|
||||
class DownloadManager;
|
||||
|
||||
class DownloadListWidgetDelegate : public QItemDelegate
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DownloadProgressDelegate(DownloadManager *manager, DownloadListSortProxy *sortProxy, QWidget *parent = 0) : QStyledItemDelegate(parent), m_Manager(manager), m_SortProxy(sortProxy) {}
|
||||
|
||||
DownloadListWidgetDelegate(DownloadManager *manager, bool metaDisplay, QTreeView *view, QObject *parent = 0);
|
||||
~DownloadListWidgetDelegate();
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const override;
|
||||
|
||||
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
private:
|
||||
DownloadManager *m_Manager;
|
||||
DownloadListSortProxy *m_SortProxy;
|
||||
};
|
||||
|
||||
void paintPendingDownload(int downloadIndex) const;
|
||||
void paintRegularDownload(int downloadIndex) const;
|
||||
class DownloadListHeader : public QHeaderView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DownloadListHeader(Qt::Orientation orientation, QWidget *parent = nullptr) : QHeaderView(orientation, parent) {}
|
||||
void customResizeSections();
|
||||
|
||||
private:
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
};
|
||||
|
||||
class DownloadListWidget : public QTreeView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DownloadListWidget(QWidget *parent = 0);
|
||||
~DownloadListWidget();
|
||||
|
||||
void setManager(DownloadManager *manager);
|
||||
void setSourceModel(DownloadList *sourceModel);
|
||||
void setMetaDisplay(bool metaDisplay);
|
||||
|
||||
signals:
|
||||
|
||||
void installDownload(int index);
|
||||
void queryInfo(int index);
|
||||
void removeDownload(int index, bool deleteFile);
|
||||
@@ -75,19 +87,10 @@ 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 onHeaderCustomContextMenu(const QPoint &point);
|
||||
void issueInstall();
|
||||
void issueDelete();
|
||||
void issueRemoveFromView();
|
||||
@@ -107,25 +110,12 @@ 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;
|
||||
DownloadList *m_SourceModel = 0;
|
||||
int m_ContextRow;
|
||||
|
||||
QTreeView *m_View;
|
||||
|
||||
mutable QMap<int, QPixmap> m_Cache;
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
};
|
||||
|
||||
#endif // DOWNLOADLISTWIDGET_H
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DownloadListWidget</class>
|
||||
<widget class="QWidget" name="DownloadListWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>315</width>
|
||||
<height>81</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Placeholder</string>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="nameLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>323</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Placeholder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="sizeLabel">
|
||||
<property name="text">
|
||||
<string notr="true">0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string notr="true">KB</string>
|
||||
</property>
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="installLabel">
|
||||
<property name="text">
|
||||
<string>Done - Double Click to install</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="downloadProgress">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,413 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
|
||||
|
||||
This file is part of Mod Organizer.
|
||||
|
||||
Mod Organizer is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Mod Organizer is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "downloadlistwidgetcompact.h"
|
||||
#include "ui_downloadlistwidgetcompact.h"
|
||||
#include <QPainter>
|
||||
#include <QMouseEvent>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
|
||||
DownloadListWidgetCompact::DownloadListWidgetCompact(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::DownloadListWidgetCompact)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
DownloadListWidgetCompact::~DownloadListWidgetCompact()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
||||
DownloadListWidgetCompactDelegate::DownloadListWidgetCompactDelegate(DownloadManager *manager, bool metaDisplay, QTreeView *view, QObject *parent)
|
||||
: QItemDelegate(parent)
|
||||
, m_Manager(manager)
|
||||
, m_MetaDisplay(metaDisplay)
|
||||
, m_ItemWidget(new DownloadListWidgetCompact)
|
||||
, m_View(view)
|
||||
{
|
||||
m_NameLabel = m_ItemWidget->findChild<QLabel*>("nameLabel");
|
||||
m_SizeLabel = m_ItemWidget->findChild<QLabel*>("sizeLabel");
|
||||
m_Progress = m_ItemWidget->findChild<QProgressBar*>("downloadProgress");
|
||||
m_DoneLabel = m_ItemWidget->findChild<QLabel*>("doneLabel");
|
||||
|
||||
m_DoneLabel->setVisible(false);
|
||||
|
||||
connect(manager, SIGNAL(stateChanged(int,DownloadManager::DownloadState)),
|
||||
this, SLOT(stateChanged(int,DownloadManager::DownloadState)));
|
||||
connect(manager, SIGNAL(downloadRemoved(int)), this, SLOT(resetCache(int)));
|
||||
}
|
||||
|
||||
|
||||
DownloadListWidgetCompactDelegate::~DownloadListWidgetCompactDelegate()
|
||||
{
|
||||
delete m_ItemWidget;
|
||||
}
|
||||
|
||||
|
||||
void DownloadListWidgetCompactDelegate::stateChanged(int row,DownloadManager::DownloadState)
|
||||
{
|
||||
m_Cache.remove(row);
|
||||
}
|
||||
|
||||
|
||||
void DownloadListWidgetCompactDelegate::resetCache(int)
|
||||
{
|
||||
m_Cache.clear();
|
||||
}
|
||||
|
||||
|
||||
void DownloadListWidgetCompactDelegate::drawCache(QPainter *painter, const QStyleOptionViewItem &option, const QPixmap &cache) const
|
||||
{
|
||||
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 DownloadListWidgetCompactDelegate::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;
|
||||
}
|
||||
|
||||
void DownloadListWidgetCompactDelegate::paintPendingDownload(int downloadIndex) const
|
||||
{
|
||||
std::tuple<QString, int, int> 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)));
|
||||
//if (m_SizeLabel != nullptr) {
|
||||
// m_SizeLabel->setText("???");
|
||||
//}
|
||||
m_DoneLabel->setVisible(true);
|
||||
m_DoneLabel->setText(tr("Pending"));
|
||||
m_Progress->setVisible(false);
|
||||
}
|
||||
|
||||
|
||||
void DownloadListWidgetCompactDelegate::paintRegularDownload(int downloadIndex) const
|
||||
{
|
||||
QString name = m_MetaDisplay ? m_Manager->getDisplayName(downloadIndex) : m_Manager->getFileName(downloadIndex);
|
||||
if (name.length() > 53) {
|
||||
name.truncate(50);
|
||||
name.append("...");
|
||||
}
|
||||
m_NameLabel->setText(name);
|
||||
|
||||
DownloadManager::DownloadState state = m_Manager->getState(downloadIndex);
|
||||
|
||||
if (m_SizeLabel != nullptr) {
|
||||
m_SizeLabel->setText(sizeFormat(m_Manager->getFileSize(downloadIndex)) + " ");
|
||||
m_SizeLabel->setVisible(true);
|
||||
}
|
||||
//else {
|
||||
// m_SizeLabel->setVisible(false);
|
||||
//}
|
||||
|
||||
if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR) || (state == DownloadManager::STATE_PAUSING)) {
|
||||
m_DoneLabel->setVisible(true);
|
||||
m_Progress->setVisible(false);
|
||||
m_DoneLabel->setText(QString("%1<img src=\":/MO/gui/inactive\">").arg(tr("Paused")));
|
||||
} else if (state == DownloadManager::STATE_FETCHINGMODINFO) {
|
||||
m_DoneLabel->setText(QString("%1").arg(tr("Fetching Info 1")));
|
||||
} else if (state == DownloadManager::STATE_FETCHINGFILEINFO) {
|
||||
m_DoneLabel->setText(QString("%1").arg(tr("Fetching Info 2")));
|
||||
} else if (state >= DownloadManager::STATE_READY) {
|
||||
m_DoneLabel->setVisible(true);
|
||||
m_Progress->setVisible(false);
|
||||
if (state == DownloadManager::STATE_INSTALLED) {
|
||||
m_DoneLabel->setText(QString("%1<img src=\":/MO/gui/check\">").arg(tr("Installed")));
|
||||
} else if (state == DownloadManager::STATE_UNINSTALLED) {
|
||||
m_DoneLabel->setText(QString("%1<img src=\":/MO/gui/awaiting\">").arg(tr("Uninstalled")));
|
||||
} else {
|
||||
m_DoneLabel->setText(QString("%1<img src=\":/MO/gui/active\">").arg(tr("Done")));
|
||||
}
|
||||
if (m_Manager->isInfoIncomplete(downloadIndex)) {
|
||||
m_NameLabel->setText("<img src=\":/MO/gui/warning_16\"/> " + m_NameLabel->text());
|
||||
}
|
||||
} else {
|
||||
m_DoneLabel->setVisible(false);
|
||||
m_Progress->setVisible(true);
|
||||
m_Progress->setValue(m_Manager->getProgress(downloadIndex).first);
|
||||
m_Progress->setFormat(m_Manager->getProgress(downloadIndex).second);
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadListWidgetCompactDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
#pragma message("This is quite costy - room for optimization?")
|
||||
try {
|
||||
auto iter = m_Cache.find(index.row());
|
||||
if (iter != m_Cache.end()) {
|
||||
drawCache(painter, option, *iter);
|
||||
return;
|
||||
}
|
||||
|
||||
m_ItemWidget->resize(QSize(m_View->columnWidth(0) + m_View->columnWidth(1) + m_View->columnWidth(2) + m_View->columnWidth(3), option.rect.height()));
|
||||
if (index.row() % 2 == 1) {
|
||||
m_ItemWidget->setBackgroundRole(QPalette::AlternateBase);
|
||||
} else {
|
||||
m_ItemWidget->setBackgroundRole(QPalette::Base);
|
||||
}
|
||||
|
||||
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 (false) {
|
||||
// if (state >= DownloadManager::STATE_READY) {
|
||||
#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 item %d: %s", index.row(), e.what());
|
||||
}
|
||||
}
|
||||
|
||||
QSize DownloadListWidgetCompactDelegate::sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const
|
||||
{
|
||||
const int width = m_ItemWidget->minimumWidth();
|
||||
const int height = m_ItemWidget->height();
|
||||
return QSize(width, height);
|
||||
}
|
||||
|
||||
|
||||
void DownloadListWidgetCompactDelegate::issueInstall()
|
||||
{
|
||||
emit installDownload(m_ContextIndex.row());
|
||||
}
|
||||
|
||||
void DownloadListWidgetCompactDelegate::issueQueryInfo()
|
||||
{
|
||||
emit queryInfo(m_ContextIndex.row());
|
||||
}
|
||||
|
||||
void DownloadListWidgetCompactDelegate::issueDelete()
|
||||
{
|
||||
if (QMessageBox::question(nullptr, tr("Are you sure?"),
|
||||
tr("This will permanently delete the selected download."),
|
||||
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||
emit removeDownload(m_ContextIndex.row(), true);
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadListWidgetCompactDelegate::issueRemoveFromView()
|
||||
{
|
||||
emit removeDownload(m_ContextIndex.row(), false);
|
||||
}
|
||||
|
||||
void DownloadListWidgetCompactDelegate::issueVisitOnNexus()
|
||||
{
|
||||
emit visitOnNexus(m_ContextIndex.row());
|
||||
}
|
||||
|
||||
void DownloadListWidgetCompactDelegate::issueOpenFile()
|
||||
{
|
||||
emit openFile(m_ContextIndex.row());
|
||||
}
|
||||
|
||||
void DownloadListWidgetCompactDelegate::issueOpenInDownloadsFolder()
|
||||
{
|
||||
emit openInDownloadsFolder(m_ContextIndex.row());
|
||||
}
|
||||
|
||||
void DownloadListWidgetCompactDelegate::issueRestoreToView()
|
||||
{
|
||||
emit restoreDownload(m_ContextIndex.row());
|
||||
}
|
||||
|
||||
void DownloadListWidgetCompactDelegate::issueRestoreToViewAll()
|
||||
{
|
||||
emit restoreDownload(-1);
|
||||
}
|
||||
|
||||
|
||||
void DownloadListWidgetCompactDelegate::issueCancel()
|
||||
{
|
||||
emit cancelDownload(m_ContextIndex.row());
|
||||
}
|
||||
|
||||
void DownloadListWidgetCompactDelegate::issuePause()
|
||||
{
|
||||
emit pauseDownload(m_ContextIndex.row());
|
||||
}
|
||||
|
||||
void DownloadListWidgetCompactDelegate::issueResume()
|
||||
{
|
||||
emit resumeDownload(m_ContextIndex.row());
|
||||
}
|
||||
|
||||
void DownloadListWidgetCompactDelegate::issueDeleteAll()
|
||||
{
|
||||
if (QMessageBox::question(nullptr, tr("Are you sure?"),
|
||||
tr("This will remove all finished downloads from this list and from disk."),
|
||||
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||
emit removeDownload(-1, true);
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadListWidgetCompactDelegate::issueDeleteCompleted()
|
||||
{
|
||||
if (QMessageBox::question(nullptr, tr("Are you sure?"),
|
||||
tr("This will remove all installed downloads from this list and from disk."),
|
||||
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||
emit removeDownload(-2, true);
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadListWidgetCompactDelegate::issueDeleteUninstalled()
|
||||
{
|
||||
if (QMessageBox::question(nullptr, tr("Are you sure?"),
|
||||
tr("This will remove all uninstalled downloads from this list and from disk."),
|
||||
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||
emit removeDownload(-3, true);
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadListWidgetCompactDelegate::issueRemoveFromViewAll()
|
||||
{
|
||||
if (QMessageBox::question(nullptr, tr("Are you sure?"),
|
||||
tr("This will permanently remove all finished downloads from this list (but NOT from disk)."),
|
||||
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||
emit removeDownload(-1, false);
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadListWidgetCompactDelegate::issueRemoveFromViewCompleted()
|
||||
{
|
||||
if (QMessageBox::question(nullptr, tr("Are you sure?"),
|
||||
tr("This will permanently remove all installed downloads from this list (but NOT from disk)."),
|
||||
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||
emit removeDownload(-2, false);
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadListWidgetCompactDelegate::issueRemoveFromViewUninstalled()
|
||||
{
|
||||
if (QMessageBox::question(nullptr, tr("Are you sure?"),
|
||||
tr("This will permanently remove all uninstalled downloads from this list (but NOT from disk)."),
|
||||
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||
emit removeDownload(-3, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool DownloadListWidgetCompactDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
|
||||
const QStyleOptionViewItem &option, const QModelIndex &index)
|
||||
{
|
||||
try {
|
||||
if (event->type() == QEvent::MouseButtonDblClick) {
|
||||
QModelIndex sourceIndex = qobject_cast<QSortFilterProxyModel*>(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<QMouseEvent*>(event);
|
||||
if (mouseEvent->button() == Qt::RightButton) {
|
||||
QMenu menu;
|
||||
bool hidden = false;
|
||||
m_ContextIndex = qobject_cast<QSortFilterProxyModel*>(model)->mapToSource(index);
|
||||
if (m_ContextIndex.row() < m_Manager->numTotalDownloads()) {
|
||||
DownloadManager::DownloadState state = m_Manager->getState(m_ContextIndex.row());
|
||||
hidden = m_Manager->isHidden(m_ContextIndex.row());
|
||||
if (state >= DownloadManager::STATE_READY) {
|
||||
menu.addAction(tr("Install"), this, SLOT(issueInstall()));
|
||||
if (m_Manager->isInfoIncomplete(m_ContextIndex.row())) {
|
||||
menu.addAction(tr("Query Info"), this, SLOT(issueQueryInfo()));
|
||||
}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("Remove"), 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 false;
|
||||
}
|
||||
}
|
||||
} catch (const std::exception &e) {
|
||||
qCritical("failed to handle editor event: %s", e.what());
|
||||
}
|
||||
|
||||
return QItemDelegate::editorEvent(event, model, option, index);
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
|
||||
|
||||
This file is part of Mod Organizer.
|
||||
|
||||
Mod Organizer is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Mod Organizer is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DOWNLOADLISTWIDGETCOMPACT_H
|
||||
#define DOWNLOADLISTWIDGETCOMPACT_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QItemDelegate>
|
||||
#include <QLabel>
|
||||
#include <QProgressBar>
|
||||
#include <QTreeView>
|
||||
#include "downloadmanager.h"
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class DownloadListWidgetCompact;
|
||||
}
|
||||
|
||||
class DownloadListWidgetCompact : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DownloadListWidgetCompact(QWidget *parent = 0);
|
||||
~DownloadListWidgetCompact();
|
||||
|
||||
private:
|
||||
Ui::DownloadListWidgetCompact *ui;
|
||||
int m_ContextRow;
|
||||
};
|
||||
|
||||
class DownloadManager;
|
||||
|
||||
class DownloadListWidgetCompactDelegate : public QItemDelegate
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
DownloadListWidgetCompactDelegate(DownloadManager *manager, bool metaDisplay, QTreeView *view, QObject *parent = 0);
|
||||
~DownloadListWidgetCompactDelegate();
|
||||
|
||||
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
|
||||
signals:
|
||||
|
||||
void installDownload(int index);
|
||||
void queryInfo(int index);
|
||||
void removeDownload(int index, bool deleteFile);
|
||||
void restoreDownload(int index);
|
||||
void cancelDownload(int index);
|
||||
void pauseDownload(int index);
|
||||
void resumeDownload(int index);
|
||||
void visitOnNexus(int index);
|
||||
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;
|
||||
void paintPendingDownload(int downloadIndex) const;
|
||||
void paintRegularDownload(int downloadIndex) const;
|
||||
|
||||
private slots:
|
||||
|
||||
void issueInstall();
|
||||
void issueDelete();
|
||||
void issueRemoveFromView();
|
||||
void issueRestoreToView();
|
||||
void issueRestoreToViewAll();
|
||||
void issueVisitOnNexus();
|
||||
void issueOpenFile();
|
||||
void issueOpenInDownloadsFolder();
|
||||
void issueCancel();
|
||||
void issuePause();
|
||||
void issueResume();
|
||||
void issueDeleteAll();
|
||||
void issueDeleteCompleted();
|
||||
void issueDeleteUninstalled();
|
||||
void issueRemoveFromViewAll();
|
||||
void issueRemoveFromViewCompleted();
|
||||
void issueRemoveFromViewUninstalled();
|
||||
void issueQueryInfo();
|
||||
|
||||
void stateChanged(int row, DownloadManager::DownloadState);
|
||||
void resetCache(int);
|
||||
private:
|
||||
|
||||
DownloadListWidgetCompact *m_ItemWidget;
|
||||
DownloadManager *m_Manager;
|
||||
|
||||
bool m_MetaDisplay;
|
||||
|
||||
QLabel *m_NameLabel;
|
||||
QLabel *m_SizeLabel;
|
||||
QProgressBar *m_Progress;
|
||||
QLabel *m_DoneLabel;
|
||||
|
||||
QModelIndex m_ContextIndex;
|
||||
|
||||
QTreeView *m_View;
|
||||
|
||||
mutable QMap<int, QPixmap> m_Cache;
|
||||
|
||||
};
|
||||
|
||||
#endif // DOWNLOADLISTWIDGETCOMPACT_H
|
||||
@@ -1,168 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DownloadListWidgetCompact</class>
|
||||
<widget class="QWidget" name="DownloadListWidgetCompact">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>315</width>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Placeholder</string>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0,0,0">
|
||||
<property name="spacing">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="nameLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::NoContextMenu</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Placeholder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="sizeLabel">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="doneLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="palette">
|
||||
<palette>
|
||||
<active>
|
||||
<colorrole role="WindowText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>0</red>
|
||||
<green>118</green>
|
||||
<blue>0</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</active>
|
||||
<inactive>
|
||||
<colorrole role="WindowText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>0</red>
|
||||
<green>118</green>
|
||||
<blue>0</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</inactive>
|
||||
<disabled>
|
||||
<colorrole role="WindowText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>120</red>
|
||||
<green>120</green>
|
||||
<blue>120</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</disabled>
|
||||
</palette>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::NoContextMenu</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Done</string>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="downloadProgress">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::NoContextMenu</enum>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+26
-29
@@ -64,7 +64,7 @@ DownloadManager::DownloadInfo *DownloadManager::DownloadInfo::createNew(const Mo
|
||||
info->m_DownloadID = s_NextDownloadID++;
|
||||
info->m_StartTime.start();
|
||||
info->m_PreResumeSize = 0LL;
|
||||
info->m_Progress = std::make_pair<int, QString>(0, " 0.0 Bytes/s ");
|
||||
info->m_Progress = std::make_pair<int, QString>(0, "0.0 B/s ");
|
||||
info->m_ResumePos = 0;
|
||||
info->m_FileInfo = new ModRepositoryFileInfo(*fileInfo);
|
||||
info->m_Urls = URLs;
|
||||
@@ -378,7 +378,7 @@ void DownloadManager::refreshList()
|
||||
}
|
||||
|
||||
//if (m_ActiveDownloads.size() != downloadsBefore) {
|
||||
qDebug("downloads after refresh: %d", m_ActiveDownloads.size());
|
||||
qDebug("Downloads after refresh: %d", m_ActiveDownloads.size());
|
||||
//}
|
||||
emit update(-1);
|
||||
|
||||
@@ -400,7 +400,7 @@ bool DownloadManager::addDownload(const QStringList &URLs, QString gameName,
|
||||
}
|
||||
|
||||
QUrl preferredUrl = QUrl::fromEncoded(URLs.first().toLocal8Bit());
|
||||
qDebug("selected download url: %s", qPrintable(preferredUrl.toString()));
|
||||
qDebug("selected download url: %s", qUtf8Printable(preferredUrl.toString()));
|
||||
QNetworkRequest request(preferredUrl);
|
||||
request.setHeader(QNetworkRequest::UserAgentHeader, m_NexusInterface->getAccessManager()->userAgent());
|
||||
return addDownload(m_NexusInterface->getAccessManager()->get(request), URLs, fileName, gameName, modID, fileID, fileInfo);
|
||||
@@ -499,8 +499,8 @@ void DownloadManager::startDownload(QNetworkReply *reply, DownloadInfo *newDownl
|
||||
if (QFile::exists(m_OutputDirectory + "/" + newDownload->m_FileName)) {
|
||||
setState(newDownload, STATE_PAUSING);
|
||||
QCoreApplication::processEvents();
|
||||
if (QMessageBox::question(nullptr, tr("Download again?"), tr("A file with the same name has already been downloaded. "
|
||||
"Do you want to download it again? The new file will receive a different name."),
|
||||
if (QMessageBox::question(nullptr, tr("Download again?"), tr("A file with the same name \"%1\" has already been downloaded. "
|
||||
"Do you want to download it again? The new file will receive a different name.").arg(newDownload->m_FileName),
|
||||
QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
|
||||
if (reply->isFinished())
|
||||
setState(newDownload, STATE_CANCELED);
|
||||
@@ -540,9 +540,9 @@ void DownloadManager::addNXMDownload(const QString &url)
|
||||
QStringList validGames;
|
||||
validGames.append(m_ManagedGame->gameShortName());
|
||||
validGames.append(m_ManagedGame->validShortNames());
|
||||
qDebug("add nxm download: %s", qPrintable(url));
|
||||
qDebug("add nxm download: %s", qUtf8Printable(url));
|
||||
if (!validGames.contains(nxmInfo.game(), Qt::CaseInsensitive)) {
|
||||
qDebug("download requested for wrong game (game: %s, url: %s)", qPrintable(m_ManagedGame->gameShortName()), qPrintable(nxmInfo.game()));
|
||||
qDebug("download requested for wrong game (game: %s, url: %s)", qUtf8Printable(m_ManagedGame->gameShortName()), qUtf8Printable(nxmInfo.game()));
|
||||
QMessageBox::information(nullptr, tr("Wrong Game"), tr("The download link is for a mod for \"%1\" but this instance of MO "
|
||||
"has been set up for \"%2\".").arg(nxmInfo.game()).arg(m_ManagedGame->gameShortName()), QMessageBox::Ok);
|
||||
return;
|
||||
@@ -550,7 +550,7 @@ void DownloadManager::addNXMDownload(const QString &url)
|
||||
|
||||
for (auto tuple : m_PendingDownloads) {
|
||||
if (std::get<0>(tuple).compare(nxmInfo.game(), Qt::CaseInsensitive) == 0, std::get<1>(tuple) == nxmInfo.modId() && std::get<2>(tuple) == nxmInfo.fileId()) {
|
||||
qDebug("download requested is already started (mod id: %s, file id: %s)", qPrintable(QString(nxmInfo.modId())), qPrintable(QString(nxmInfo.fileId())));
|
||||
qDebug("download requested is already started (mod id: %s, file id: %s)", qUtf8Printable(QString(nxmInfo.modId())), qUtf8Printable(QString(nxmInfo.fileId())));
|
||||
QMessageBox::information(nullptr, tr("Already Started"), tr("A download for this mod file has already been queued."), QMessageBox::Ok);
|
||||
return;
|
||||
}
|
||||
@@ -559,8 +559,8 @@ void DownloadManager::addNXMDownload(const QString &url)
|
||||
for (DownloadInfo *download : m_ActiveDownloads) {
|
||||
if (download->m_FileInfo->modID == nxmInfo.modId() && download->m_FileInfo->fileID == nxmInfo.fileId()) {
|
||||
if (download->m_State == STATE_DOWNLOADING || download->m_State == STATE_PAUSED || download->m_State == STATE_STARTED) {
|
||||
qDebug("download requested is already started (mod: %s, file: %s)", qPrintable(QString(download->m_FileInfo->modID)),
|
||||
qPrintable(download->m_FileInfo->fileName));
|
||||
qDebug("download requested is already started (mod: %s, file: %s)", qUtf8Printable(QString(download->m_FileInfo->modID)),
|
||||
qUtf8Printable(download->m_FileInfo->fileName));
|
||||
|
||||
QMessageBox::information(nullptr, tr("Already Started"), tr("There is already a download started for this file (mod: %1, file: %2).")
|
||||
.arg(download->m_FileInfo->modName).arg(download->m_FileInfo->fileName), QMessageBox::Ok);
|
||||
@@ -700,22 +700,18 @@ void DownloadManager::removeDownload(int index, bool deleteFile)
|
||||
emit aboutToUpdate();
|
||||
|
||||
if (index < 0) {
|
||||
DownloadState minState;
|
||||
if (index == -3) {
|
||||
minState = STATE_UNINSTALLED;
|
||||
}
|
||||
else
|
||||
minState = index == -1 ? STATE_READY : STATE_INSTALLED;
|
||||
bool removeAll = (index == -1);
|
||||
DownloadState removeState = (index == -2 ? STATE_INSTALLED : STATE_UNINSTALLED);
|
||||
|
||||
index = 0;
|
||||
for (QVector<DownloadInfo*>::iterator iter = m_ActiveDownloads.begin(); iter != m_ActiveDownloads.end();) {
|
||||
if ((*iter)->m_State >= minState) {
|
||||
for (QVector<DownloadInfo*>::iterator iter = m_ActiveDownloads.begin(); iter != m_ActiveDownloads.end();) {
|
||||
DownloadState downloadState = (*iter)->m_State;
|
||||
if ((removeAll && (downloadState >= STATE_READY)) ||
|
||||
(removeState == downloadState)) {
|
||||
removeFile(index, deleteFile);
|
||||
delete *iter;
|
||||
iter = m_ActiveDownloads.erase(iter);
|
||||
//QCoreApplication::processEvents();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
++iter;
|
||||
++index;
|
||||
}
|
||||
@@ -818,7 +814,7 @@ void DownloadManager::resumeDownloadInt(int index)
|
||||
if (info->m_State == STATE_ERROR) {
|
||||
info->m_CurrentUrl = (info->m_CurrentUrl + 1) % info->m_Urls.count();
|
||||
}
|
||||
qDebug("request resume from url %s", qPrintable(info->currentURL()));
|
||||
qDebug("request resume from url %s", qUtf8Printable(info->currentURL()));
|
||||
QNetworkRequest request(QUrl::fromEncoded(info->currentURL().toLocal8Bit()));
|
||||
request.setHeader(QNetworkRequest::UserAgentHeader, m_NexusInterface->getAccessManager()->userAgent());
|
||||
if (info->m_State != STATE_ERROR) {
|
||||
@@ -879,7 +875,8 @@ void DownloadManager::queryInfo(int index)
|
||||
std::numeric_limits<int>::max(), 1, &ok);
|
||||
// careful now: while the dialog was displayed, events were processed.
|
||||
// the download list might have changed and our info-ptr invalidated.
|
||||
m_ActiveDownloads[index]->m_FileInfo->modID = modId;
|
||||
if (ok)
|
||||
m_ActiveDownloads[index]->m_FileInfo->modID = modId;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1338,7 +1335,7 @@ void DownloadManager::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
|
||||
|
||||
QString unit;
|
||||
if (speed < 1000) {
|
||||
unit = "Bytes/s";
|
||||
unit = "B/s";
|
||||
}
|
||||
else if (speed < 1000*1024) {
|
||||
speed /= 1024;
|
||||
@@ -1349,7 +1346,7 @@ void DownloadManager::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
|
||||
unit = "MB/s";
|
||||
}
|
||||
|
||||
info->m_Progress.second = QString::fromLatin1("%1% - %2 %3").arg(info->m_Progress.first).arg(speed, 8, 'f', 1,' ').arg(unit, -8, ' ');
|
||||
info->m_Progress.second = QString::fromLatin1("%1% - %2 %3").arg(info->m_Progress.first).arg(QString::number(speed, 'f', 1)).arg(unit);
|
||||
|
||||
TaskProgressManager::instance().updateProgress(info->m_TaskProgressId, bytesReceived, bytesTotal);
|
||||
emit update(index);
|
||||
@@ -1438,7 +1435,7 @@ QDateTime DownloadManager::matchDate(const QString &timeString)
|
||||
if (m_DateExpression.exactMatch(timeString)) {
|
||||
return QDateTime::fromMSecsSinceEpoch(m_DateExpression.cap(1).toLongLong());
|
||||
} else {
|
||||
qWarning("date not matched: %s", qPrintable(timeString));
|
||||
qWarning("date not matched: %s", qUtf8Printable(timeString));
|
||||
return QDateTime::currentDateTime();
|
||||
}
|
||||
}
|
||||
@@ -1514,7 +1511,7 @@ void DownloadManager::nxmFilesAvailable(QString, int, QVariant userData, QVarian
|
||||
} else {
|
||||
if (info->m_FileInfo->fileID == 0) {
|
||||
qWarning("could not determine file id for %s (state %d)",
|
||||
info->m_FileName.toUtf8().constData(), info->m_State);
|
||||
qUtf8Printable(info->m_FileName), info->m_State);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1787,7 +1784,7 @@ void DownloadManager::downloadError(QNetworkReply::NetworkError error)
|
||||
{
|
||||
if (error != QNetworkReply::OperationCanceledError) {
|
||||
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
|
||||
qWarning("%s (%d)", reply != nullptr ? qPrintable(reply->errorString())
|
||||
qWarning("%s (%d)", reply != nullptr ? qUtf8Printable(reply->errorString())
|
||||
: "Download error occured",
|
||||
error);
|
||||
}
|
||||
@@ -1853,4 +1850,4 @@ void DownloadManager::writeData(DownloadInfo *info)
|
||||
"Canceling download \"%2\"...").arg(ret).arg(fileName));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user