mirror of
https://github.com/ModOrganizer2/modorganizer.git
synced 2026-07-27 13:58:24 -07:00
Compare commits
16
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de984a4ef8 | ||
|
|
e597823337 | ||
|
|
e69210b3a7 | ||
|
|
40d20ab294 | ||
|
|
6ed82866b0 | ||
|
|
a083a2d3b6 | ||
|
|
db09b806b9 | ||
|
|
859c0aed98 | ||
|
|
0ea7d99b9f | ||
|
|
6cffbd4f27 | ||
|
|
4dc3538a7d | ||
|
|
e45b747c82 | ||
|
|
2d6bacbb6a | ||
|
|
d029e97724 | ||
|
|
a9435f637e | ||
|
|
e1e35da6fe |
@@ -13,3 +13,10 @@ source - Copy/*
|
||||
ModOrganizer-build-*
|
||||
pdbs/*
|
||||
source/NCC/BossDummy.x/*
|
||||
*.ts
|
||||
staging_prepare/*
|
||||
staging_trans/*
|
||||
tools/python_zip/*
|
||||
Makefile
|
||||
syntax: regexp
|
||||
Makefile\.(Debug|Release)
|
||||
|
||||
@@ -13,11 +13,12 @@ SUBDIRS = bsatk \
|
||||
nxmhandler \
|
||||
BossDummy \
|
||||
pythonRunner \
|
||||
boss_modified \
|
||||
esptk
|
||||
|
||||
plugins.depends = pythonRunner
|
||||
hookdll.depends = shared
|
||||
organizer.depends = shared uibase plugins
|
||||
organizer.depends = shared uibase plugins boss_modified
|
||||
|
||||
CONFIG(debug, debug|release) {
|
||||
DESTDIR = outputd
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
Copyright (C) 2014 Sebastian Herbord. All rights reserved.
|
||||
|
||||
This file is part of Mod Organizer.
|
||||
|
||||
Mod Organizer is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Mod Organizer is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "aboutdialog.h"
|
||||
#include "ui_aboutdialog.h"
|
||||
#include <utility.h>
|
||||
|
||||
|
||||
AboutDialog::AboutDialog(const QString &version, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui::AboutDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
m_LicenseFiles[LICENSE_LGPL3] = "lgpl-3.0.txt";
|
||||
m_LicenseFiles[LICENSE_GPL3] = "gpl-3.0.txt";
|
||||
m_LicenseFiles[LICENSE_BSD3] = "bsd3.txt";
|
||||
m_LicenseFiles[LICENSE_BOOST] = "boost.txt";
|
||||
m_LicenseFiles[LICENSE_CCBY3] = "by-sa3.txt";
|
||||
m_LicenseFiles[LICENSE_ZLIB] = "zlib.txt";
|
||||
|
||||
addLicense("Qt 4.8.5", LICENSE_LGPL3);
|
||||
addLicense("Qt Json", LICENSE_GPL3);
|
||||
addLicense("Boost Library", LICENSE_BOOST);
|
||||
addLicense("Tango Icon Theme", LICENSE_NONE);
|
||||
addLicense("RRZE Icon Set", LICENSE_CCBY3);
|
||||
addLicense("7-zip", LICENSE_LGPL3);
|
||||
addLicense("ZLib", LICENSE_ZLIB);
|
||||
addLicense("NIF File Format Library", LICENSE_BSD3);
|
||||
addLicense("BOSS (modified)", LICENSE_GPL3);
|
||||
addLicense("Alphanum Algorithm", LICENSE_ZLIB);
|
||||
|
||||
ui->nameLabel->setText(QString("<span style=\"font-size:12pt; font-weight:600;\">%1 %2</span>").arg(ui->nameLabel->text()).arg(version));
|
||||
#ifdef HGID
|
||||
ui->revisionLabel->setText(ui->revisionLabel->text() + " " + HGID);
|
||||
#else
|
||||
ui->revisionLabel->setText(ui->revisionLabel->text() + " unknown");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
AboutDialog::~AboutDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
||||
void AboutDialog::addLicense(const QString &name, Licenses license)
|
||||
{
|
||||
QListWidgetItem *item = new QListWidgetItem(name);
|
||||
item->setData(Qt::UserRole, license);
|
||||
ui->creditsList->addItem(item);
|
||||
}
|
||||
|
||||
|
||||
void AboutDialog::on_creditsList_currentItemChanged(QListWidgetItem *current, QListWidgetItem*)
|
||||
{
|
||||
auto iter = m_LicenseFiles.find(current->data(Qt::UserRole).toInt());
|
||||
if (iter != m_LicenseFiles.end()) {
|
||||
QString filePath = qApp->applicationDirPath() + "/license/" + iter->second;
|
||||
QString text = MOBase::readFileText(filePath);
|
||||
ui->licenseText->setText(text);
|
||||
} else {
|
||||
ui->licenseText->setText(tr("No license"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
#ifndef ABOUTDIALOG_H
|
||||
/*
|
||||
Copyright (C) 2014 Sebastian Herbord. All rights reserved.
|
||||
|
||||
This file is part of Mod Organizer.
|
||||
|
||||
Mod Organizer is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Mod Organizer is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#define ABOUTDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QListWidgetItem>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
namespace Ui {
|
||||
class AboutDialog;
|
||||
}
|
||||
|
||||
class AboutDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AboutDialog(const QString &version, QWidget *parent = 0);
|
||||
~AboutDialog();
|
||||
|
||||
private:
|
||||
|
||||
enum Licenses {
|
||||
LICENSE_NONE,
|
||||
LICENSE_LGPL3,
|
||||
LICENSE_GPL3,
|
||||
LICENSE_BSD3,
|
||||
LICENSE_BOOST,
|
||||
LICENSE_CCBY3,
|
||||
LICENSE_ZLIB
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
void addLicense(const QString &name, Licenses license);
|
||||
|
||||
private slots:
|
||||
void on_creditsList_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous);
|
||||
|
||||
private:
|
||||
|
||||
Ui::AboutDialog *ui;
|
||||
|
||||
std::map<int, QString> m_LicenseFiles;
|
||||
|
||||
};
|
||||
|
||||
#endif // ABOUTDIALOG_H
|
||||
@@ -0,0 +1,295 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AboutDialog</class>
|
||||
<widget class="QDialog" name="AboutDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>508</width>
|
||||
<height>335</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>About</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="iconLabel">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="resources.qrc">:/MO/gui/mo_icon.ico</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="about">
|
||||
<attribute name="title">
|
||||
<string>About</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="nameLabel">
|
||||
<property name="text">
|
||||
<string notr="true">Mod Organizer</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="revisionLabel">
|
||||
<property name="text">
|
||||
<string>Revision:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string notr="true">Copyright 2011-2014 Sebastian Herbord</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string notr="true"><html><head/><body><p>This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</p><p>See the GNU General Public License for more details.</p></body></html></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="software">
|
||||
<attribute name="title">
|
||||
<string>Used Software</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QListWidget" name="creditsList"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="licenseText"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="credits">
|
||||
<attribute name="title">
|
||||
<string>Credits</string>
|
||||
</attribute>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Translators</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<widget class="QListWidget" name="listWidget_2">
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::NoSelection</enum>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">pndrev (German)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">DaWul (Spanish)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">Fiama (Spanish)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">Alyndiar (French)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">Jlkawaii (French)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">Rigoletto (French)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">Scythe1912 (Chinese)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">yc0620shen (Chinese)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">miraclefreak (Czech)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">tokcdk (Russian)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Others</string>
|
||||
</property>
|
||||
<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 notr="true">blacksol</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">DoubleYou</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">deathneko11</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">Bridger</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">GSDFan</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">Uhuru</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">Wolverine2710</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">z929669</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<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="QPushButton" name="closeButton">
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="resources.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>closeButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>AboutDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>460</x>
|
||||
<y>313</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>253</x>
|
||||
<y>167</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
+12
-7
@@ -34,9 +34,10 @@ DownloadList::DownloadList(DownloadManager *manager, QObject *parent)
|
||||
|
||||
int DownloadList::rowCount(const QModelIndex&) const
|
||||
{
|
||||
return m_Manager->numTotalDownloads();
|
||||
return m_Manager->numTotalDownloads() + m_Manager->numPendingDownloads();
|
||||
}
|
||||
|
||||
|
||||
int DownloadList::columnCount(const QModelIndex&) const
|
||||
{
|
||||
return 3;
|
||||
@@ -75,14 +76,18 @@ QVariant DownloadList::data(const QModelIndex &index, int role) const
|
||||
if (role == Qt::DisplayRole) {
|
||||
return index.row();
|
||||
} else if (role == Qt::ToolTipRole) {
|
||||
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.");
|
||||
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 {
|
||||
NexusInfo info = m_Manager->getNexusInfo(index.row());
|
||||
text += QString("%1 (ID %2) %3").arg(info.m_ModName).arg(m_Manager->getModID(index.row())).arg(info.m_Version);
|
||||
}
|
||||
return text;
|
||||
} else {
|
||||
NexusInfo info = m_Manager->getNexusInfo(index.row());
|
||||
text += QString("%1 (ID %2) %3").arg(info.m_ModName).arg(m_Manager->getModID(index.row())).arg(info.m_Version);
|
||||
return tr("pending download");
|
||||
}
|
||||
return text;
|
||||
} else {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
@@ -37,13 +37,16 @@ bool DownloadListSortProxy::lessThan(const QModelIndex &left,
|
||||
{
|
||||
int leftIndex = sourceModel()->data(left).toInt();
|
||||
int rightIndex = sourceModel()->data(right).toInt();
|
||||
|
||||
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);
|
||||
} else if (left.column() == DownloadList::COL_STATUS) {
|
||||
return m_Manager->getState(leftIndex) < m_Manager->getState(rightIndex);
|
||||
if (leftIndex < 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);
|
||||
} else if (left.column() == DownloadList::COL_STATUS) {
|
||||
return m_Manager->getState(leftIndex) < m_Manager->getState(rightIndex);
|
||||
} else {
|
||||
return leftIndex < rightIndex;
|
||||
}
|
||||
} else {
|
||||
return leftIndex < rightIndex;
|
||||
}
|
||||
@@ -54,6 +57,9 @@ bool DownloadListSortProxy::filterAcceptsRow(int source_row, const QModelIndex&)
|
||||
{
|
||||
if (m_CurrentFilter.length() == 0) {
|
||||
return true;
|
||||
} else if (source_row < m_Manager->numTotalDownloads()) {
|
||||
return m_Manager->getFileName(source_row).contains(m_CurrentFilter, Qt::CaseInsensitive);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return m_Manager->getFileName(source_row).contains(m_CurrentFilter, Qt::CaseInsensitive);
|
||||
}
|
||||
|
||||
+103
-80
@@ -82,6 +82,83 @@ void DownloadListWidgetDelegate::drawCache(QPainter *painter, const QStyleOption
|
||||
}
|
||||
|
||||
|
||||
void DownloadListWidgetDelegate::paintPendingDownload(int downloadIndex) const
|
||||
{
|
||||
std::pair<int, int> nexusids = m_Manager->getPendingDownload(downloadIndex);
|
||||
m_NameLabel->setText(tr("< mod %1 file %2 >").arg(nexusids.first).arg(nexusids.second));
|
||||
m_SizeLabel->setText("???");
|
||||
m_InstallLabel->setVisible(true);
|
||||
m_InstallLabel->setText(tr("Pending"));
|
||||
m_Progress->setVisible(false);
|
||||
}
|
||||
|
||||
|
||||
void DownloadListWidgetDelegate::paintRegularDownload(int downloadIndex) const
|
||||
{
|
||||
QString name = m_Manager->getFileName(downloadIndex);
|
||||
if (name.length() > 53) {
|
||||
name.truncate(50);
|
||||
name.append("...");
|
||||
}
|
||||
m_NameLabel->setText(name);
|
||||
m_SizeLabel->setText(QString::number(m_Manager->getFileSize(downloadIndex) / 1024));
|
||||
DownloadManager::DownloadState state = m_Manager->getState(downloadIndex);
|
||||
if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
|
||||
QPalette labelPalette;
|
||||
m_InstallLabel->setVisible(true);
|
||||
m_Progress->setVisible(false);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Paused - Double Click to resume", 0));
|
||||
#else
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Paused - Double Click to resume", 0, QApplication::UnicodeUTF8));
|
||||
#endif
|
||||
labelPalette.setColor(QPalette::WindowText, Qt::darkRed);
|
||||
m_InstallLabel->setPalette(labelPalette);
|
||||
} else if (state == DownloadManager::STATE_FETCHINGMODINFO) {
|
||||
m_InstallLabel->setText(tr("Fetching Info 1"));
|
||||
m_Progress->setVisible(false);
|
||||
} else if (state == DownloadManager::STATE_FETCHINGFILEINFO) {
|
||||
m_InstallLabel->setText(tr("Fetching Info 2"));
|
||||
m_Progress->setVisible(false);
|
||||
} else if (state >= DownloadManager::STATE_READY) {
|
||||
QPalette labelPalette;
|
||||
m_InstallLabel->setVisible(true);
|
||||
m_Progress->setVisible(false);
|
||||
if (state == DownloadManager::STATE_INSTALLED) {
|
||||
// the tr-macro doesn't work here, maybe because the translation is actually associated with DownloadListWidget instead
|
||||
// of DownloadListWidgetDelegate?
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Installed - Double Click to re-install", 0));
|
||||
#else
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Installed - Double Click to re-install", 0, QApplication::UnicodeUTF8));
|
||||
#endif
|
||||
labelPalette.setColor(QPalette::WindowText, Qt::darkGray);
|
||||
} else if (state == DownloadManager::STATE_UNINSTALLED) {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Uninstalled - Double Click to re-install", 0));
|
||||
#else
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Uninstalled - Double Click to re-install", 0, QApplication::UnicodeUTF8));
|
||||
#endif
|
||||
labelPalette.setColor(QPalette::WindowText, Qt::lightGray);
|
||||
} else {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Done - Double Click to install", 0));
|
||||
#else
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Done - Double Click to install", 0, QApplication::UnicodeUTF8));
|
||||
#endif
|
||||
labelPalette.setColor(QPalette::WindowText, Qt::darkGreen);
|
||||
}
|
||||
m_InstallLabel->setPalette(labelPalette);
|
||||
if (m_Manager->isInfoIncomplete(downloadIndex)) {
|
||||
m_NameLabel->setText("<img src=\":/MO/gui/warning_16\" /> " + m_NameLabel->text());
|
||||
}
|
||||
} else {
|
||||
m_InstallLabel->setVisible(false);
|
||||
m_Progress->setVisible(true);
|
||||
m_Progress->setValue(m_Manager->getProgress(downloadIndex));
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadListWidgetDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
try {
|
||||
@@ -95,67 +172,10 @@ void DownloadListWidgetDelegate::paint(QPainter *painter, const QStyleOptionView
|
||||
|
||||
int downloadIndex = index.data().toInt();
|
||||
|
||||
QString name = m_Manager->getFileName(downloadIndex);
|
||||
if (name.length() > 53) {
|
||||
name.truncate(50);
|
||||
name.append("...");
|
||||
}
|
||||
m_NameLabel->setText(name);
|
||||
m_SizeLabel->setText(QString::number(m_Manager->getFileSize(downloadIndex) / 1024));
|
||||
DownloadManager::DownloadState state = m_Manager->getState(downloadIndex);
|
||||
if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
|
||||
QPalette labelPalette;
|
||||
m_InstallLabel->setVisible(true);
|
||||
m_Progress->setVisible(false);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Paused - Double Click to resume", 0));
|
||||
#else
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Paused - Double Click to resume", 0, QApplication::UnicodeUTF8));
|
||||
#endif
|
||||
labelPalette.setColor(QPalette::WindowText, Qt::darkRed);
|
||||
m_InstallLabel->setPalette(labelPalette);
|
||||
} else if (state == DownloadManager::STATE_FETCHINGMODINFO) {
|
||||
m_InstallLabel->setText(tr("Fetching Info 1"));
|
||||
m_Progress->setVisible(false);
|
||||
} else if (state == DownloadManager::STATE_FETCHINGFILEINFO) {
|
||||
m_InstallLabel->setText(tr("Fetching Info 2"));
|
||||
m_Progress->setVisible(false);
|
||||
} else if (state >= DownloadManager::STATE_READY) {
|
||||
QPalette labelPalette;
|
||||
m_InstallLabel->setVisible(true);
|
||||
m_Progress->setVisible(false);
|
||||
if (state == DownloadManager::STATE_INSTALLED) {
|
||||
// the tr-macro doesn't work here, maybe because the translation is actually associated with DownloadListWidget instead
|
||||
// of DownloadListWidgetDelegate?
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Installed - Double Click to re-install", 0));
|
||||
#else
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Installed - Double Click to re-install", 0, QApplication::UnicodeUTF8));
|
||||
#endif
|
||||
labelPalette.setColor(QPalette::WindowText, Qt::darkGray);
|
||||
} else if (state == DownloadManager::STATE_UNINSTALLED) {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Uninstalled - Double Click to re-install", 0));
|
||||
#else
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Uninstalled - Double Click to re-install", 0, QApplication::UnicodeUTF8));
|
||||
#endif
|
||||
labelPalette.setColor(QPalette::WindowText, Qt::lightGray);
|
||||
} else {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Done - Double Click to install", 0));
|
||||
#else
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Done - Double Click to install", 0, QApplication::UnicodeUTF8));
|
||||
#endif
|
||||
labelPalette.setColor(QPalette::WindowText, Qt::darkGreen);
|
||||
}
|
||||
m_InstallLabel->setPalette(labelPalette);
|
||||
if (m_Manager->isInfoIncomplete(downloadIndex)) {
|
||||
m_NameLabel->setText("<img src=\":/MO/gui/warning_16\" /> " + m_NameLabel->text());
|
||||
}
|
||||
if (downloadIndex >= m_Manager->numTotalDownloads()) {
|
||||
paintPendingDownload(downloadIndex - m_Manager->numTotalDownloads());
|
||||
} else {
|
||||
m_InstallLabel->setVisible(false);
|
||||
m_Progress->setVisible(true);
|
||||
m_Progress->setValue(m_Manager->getProgress(downloadIndex));
|
||||
paintRegularDownload(downloadIndex);
|
||||
}
|
||||
|
||||
#pragma message("caching disabled because changes in the list (including resorting) doesn't work correctly")
|
||||
@@ -280,29 +300,32 @@ bool DownloadListWidgetDelegate::editorEvent(QEvent *event, QAbstractItemModel *
|
||||
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
|
||||
if (mouseEvent->button() == Qt::RightButton) {
|
||||
QMenu menu(m_View);
|
||||
bool hidden = false;
|
||||
m_ContextRow = qobject_cast<QSortFilterProxyModel*>(model)->mapToSource(index).row();
|
||||
DownloadManager::DownloadState state = m_Manager->getState(m_ContextRow);
|
||||
bool hidden = m_Manager->isHidden(m_ContextRow);
|
||||
if (state >= DownloadManager::STATE_READY) {
|
||||
menu.addAction(tr("Install"), this, SLOT(issueInstall()));
|
||||
if (m_Manager->isInfoIncomplete(m_ContextRow)) {
|
||||
menu.addAction(tr("Query Info"), this, SLOT(issueQueryInfo()));
|
||||
if (m_ContextRow < m_Manager->numTotalDownloads()) {
|
||||
DownloadManager::DownloadState state = m_Manager->getState(m_ContextRow);
|
||||
hidden = m_Manager->isHidden(m_ContextRow);
|
||||
if (state >= DownloadManager::STATE_READY) {
|
||||
menu.addAction(tr("Install"), this, SLOT(issueInstall()));
|
||||
if (m_Manager->isInfoIncomplete(m_ContextRow)) {
|
||||
menu.addAction(tr("Query Info"), this, SLOT(issueQueryInfo()));
|
||||
}
|
||||
menu.addAction(tr("Delete"), this, SLOT(issueDelete()));
|
||||
if (hidden) {
|
||||
menu.addAction(tr("Un-Hide"), this, SLOT(issueRestoreToView()));
|
||||
} else {
|
||||
menu.addAction(tr("Remove from View"), this, SLOT(issueRemoveFromView()));
|
||||
}
|
||||
} else if (state == DownloadManager::STATE_DOWNLOADING){
|
||||
menu.addAction(tr("Cancel"), this, SLOT(issueCancel()));
|
||||
menu.addAction(tr("Pause"), this, SLOT(issuePause()));
|
||||
} else if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
|
||||
menu.addAction(tr("Remove"), this, SLOT(issueDelete()));
|
||||
menu.addAction(tr("Resume"), this, SLOT(issueResume()));
|
||||
}
|
||||
menu.addAction(tr("Delete"), this, SLOT(issueDelete()));
|
||||
if (hidden) {
|
||||
menu.addAction(tr("Un-Hide"), this, SLOT(issueRestoreToView()));
|
||||
} else {
|
||||
menu.addAction(tr("Remove from View"), this, SLOT(issueRemoveFromView()));
|
||||
}
|
||||
} else if (state == DownloadManager::STATE_DOWNLOADING){
|
||||
menu.addAction(tr("Cancel"), this, SLOT(issueCancel()));
|
||||
menu.addAction(tr("Pause"), this, SLOT(issuePause()));
|
||||
} else if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
|
||||
menu.addAction(tr("Remove"), this, SLOT(issueDelete()));
|
||||
menu.addAction(tr("Resume"), this, SLOT(issueResume()));
|
||||
}
|
||||
|
||||
menu.addSeparator();
|
||||
menu.addSeparator();
|
||||
}
|
||||
menu.addAction(tr("Delete Installed..."), this, SLOT(issueDeleteCompleted()));
|
||||
menu.addAction(tr("Delete All..."), this, SLOT(issueDeleteAll()));
|
||||
if (!hidden) {
|
||||
|
||||
@@ -60,6 +60,9 @@ public:
|
||||
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
|
||||
void paintPendingDownload(int downloadIndex) const;
|
||||
void paintRegularDownload(int downloadIndex) const;
|
||||
|
||||
signals:
|
||||
|
||||
void installDownload(int index);
|
||||
|
||||
@@ -82,6 +82,66 @@ void DownloadListWidgetCompactDelegate::drawCache(QPainter *painter, const QStyl
|
||||
}
|
||||
|
||||
|
||||
void DownloadListWidgetCompactDelegate::paintPendingDownload(int downloadIndex) const
|
||||
{
|
||||
std::pair<int, int> nexusids = m_Manager->getPendingDownload(downloadIndex);
|
||||
m_NameLabel->setText(tr("< mod %1 file %2 >").arg(nexusids.first).arg(nexusids.second));
|
||||
if (m_SizeLabel != NULL) {
|
||||
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_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 != NULL) && (state >= DownloadManager::STATE_READY)) {
|
||||
m_SizeLabel->setText(QString::number(m_Manager->getFileSize(downloadIndex) / 1048576));
|
||||
}
|
||||
|
||||
if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
|
||||
m_DoneLabel->setVisible(true);
|
||||
m_Progress->setVisible(false);
|
||||
m_DoneLabel->setText(tr("Paused"));
|
||||
m_DoneLabel->setForegroundRole(QPalette::Link);
|
||||
} else if (state == DownloadManager::STATE_FETCHINGMODINFO) {
|
||||
m_DoneLabel->setText(tr("Fetching Info 1"));
|
||||
} else if (state == DownloadManager::STATE_FETCHINGFILEINFO) {
|
||||
m_DoneLabel->setText(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(tr("Installed"));
|
||||
m_DoneLabel->setForegroundRole(QPalette::Mid);
|
||||
} else if (state == DownloadManager::STATE_UNINSTALLED) {
|
||||
m_DoneLabel->setText(tr("Uninstalled"));
|
||||
m_DoneLabel->setForegroundRole(QPalette::Dark);
|
||||
} else {
|
||||
m_DoneLabel->setText(tr("Done"));
|
||||
m_DoneLabel->setForegroundRole(QPalette::WindowText);
|
||||
}
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadListWidgetCompactDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
#pragma message("This is quite costy - room for optimization?")
|
||||
@@ -100,49 +160,10 @@ void DownloadListWidgetCompactDelegate::paint(QPainter *painter, const QStyleOpt
|
||||
}
|
||||
|
||||
int downloadIndex = index.data().toInt();
|
||||
|
||||
QString name = 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 != NULL) && (state >= DownloadManager::STATE_READY)) {
|
||||
m_SizeLabel->setText(QString::number(m_Manager->getFileSize(downloadIndex) / 1048576));
|
||||
}
|
||||
|
||||
if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
|
||||
m_DoneLabel->setVisible(true);
|
||||
m_Progress->setVisible(false);
|
||||
m_DoneLabel->setText(tr("Paused"));
|
||||
m_DoneLabel->setForegroundRole(QPalette::Link);
|
||||
} else if (state == DownloadManager::STATE_FETCHINGMODINFO) {
|
||||
m_DoneLabel->setText(tr("Fetching Info 1"));
|
||||
} else if (state == DownloadManager::STATE_FETCHINGFILEINFO) {
|
||||
m_DoneLabel->setText(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(tr("Installed"));
|
||||
m_DoneLabel->setForegroundRole(QPalette::Mid);
|
||||
} else if (state == DownloadManager::STATE_UNINSTALLED) {
|
||||
m_DoneLabel->setText(tr("Uninstalled"));
|
||||
m_DoneLabel->setForegroundRole(QPalette::Dark);
|
||||
} else {
|
||||
m_DoneLabel->setText(tr("Done"));
|
||||
m_DoneLabel->setForegroundRole(QPalette::WindowText);
|
||||
}
|
||||
if (m_Manager->isInfoIncomplete(downloadIndex)) {
|
||||
m_NameLabel->setText("<img src=\":/MO/gui/warning_16\"/> " + m_NameLabel->text());
|
||||
}
|
||||
if (downloadIndex >= m_Manager->numTotalDownloads()) {
|
||||
paintPendingDownload(downloadIndex - m_Manager->numTotalDownloads());
|
||||
} else {
|
||||
m_DoneLabel->setVisible(false);
|
||||
m_Progress->setVisible(true);
|
||||
m_Progress->setValue(m_Manager->getProgress(downloadIndex));
|
||||
paintRegularDownload(downloadIndex);
|
||||
}
|
||||
|
||||
#pragma message("caching disabled because changes in the list (including resorting) doesn't work correctly")
|
||||
@@ -268,29 +289,32 @@ bool DownloadListWidgetCompactDelegate::editorEvent(QEvent *event, QAbstractItem
|
||||
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
|
||||
if (mouseEvent->button() == Qt::RightButton) {
|
||||
QMenu menu;
|
||||
bool hidden = false;
|
||||
m_ContextIndex = qobject_cast<QSortFilterProxyModel*>(model)->mapToSource(index);
|
||||
DownloadManager::DownloadState state = m_Manager->getState(m_ContextIndex.row());
|
||||
bool hidden = m_Manager->isHidden(m_ContextIndex.row());
|
||||
if (state >= DownloadManager::STATE_READY) {
|
||||
menu.addAction(tr("Install"), this, SLOT(issueInstall()));
|
||||
if (m_Manager->isInfoIncomplete(m_ContextIndex.row())) {
|
||||
menu.addAction(tr("Query Info"), this, SLOT(issueQueryInfo()));
|
||||
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()));
|
||||
}
|
||||
menu.addAction(tr("Delete"), this, SLOT(issueDelete()));
|
||||
if (hidden) {
|
||||
menu.addAction(tr("Un-Hide"), this, SLOT(issueRestoreToView()));
|
||||
} else {
|
||||
menu.addAction(tr("Remove from View"), this, SLOT(issueRemoveFromView()));
|
||||
}
|
||||
} else if (state == DownloadManager::STATE_DOWNLOADING){
|
||||
menu.addAction(tr("Cancel"), this, SLOT(issueCancel()));
|
||||
menu.addAction(tr("Pause"), this, SLOT(issuePause()));
|
||||
} else if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
|
||||
menu.addAction(tr("Remove"), this, SLOT(issueDelete()));
|
||||
menu.addAction(tr("Resume"), this, SLOT(issueResume()));
|
||||
}
|
||||
menu.addAction(tr("Delete"), this, SLOT(issueDelete()));
|
||||
if (hidden) {
|
||||
menu.addAction(tr("Un-Hide"), this, SLOT(issueRestoreToView()));
|
||||
} else {
|
||||
menu.addAction(tr("Remove from View"), this, SLOT(issueRemoveFromView()));
|
||||
}
|
||||
} else if (state == DownloadManager::STATE_DOWNLOADING){
|
||||
menu.addAction(tr("Cancel"), this, SLOT(issueCancel()));
|
||||
menu.addAction(tr("Pause"), this, SLOT(issuePause()));
|
||||
} else if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
|
||||
menu.addAction(tr("Remove"), this, SLOT(issueDelete()));
|
||||
menu.addAction(tr("Resume"), this, SLOT(issueResume()));
|
||||
}
|
||||
|
||||
menu.addSeparator();
|
||||
menu.addSeparator();
|
||||
}
|
||||
menu.addAction(tr("Delete Installed..."), this, SLOT(issueDeleteCompleted()));
|
||||
menu.addAction(tr("Delete All..."), this, SLOT(issueDeleteAll()));
|
||||
if (!hidden) {
|
||||
|
||||
@@ -78,6 +78,8 @@ protected:
|
||||
private:
|
||||
|
||||
void drawCache(QPainter *painter, const QStyleOptionViewItem &option, const QPixmap &cache) const;
|
||||
void paintPendingDownload(int downloadIndex) const;
|
||||
void paintRegularDownload(int downloadIndex) const;
|
||||
|
||||
private slots:
|
||||
|
||||
|
||||
+81
-21
@@ -26,18 +26,18 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "utility.h"
|
||||
#include "json.h"
|
||||
#include "selectiondialog.h"
|
||||
#include <utility.h>
|
||||
#include <QTimer>
|
||||
#include <QFileInfo>
|
||||
#include <QRegExp>
|
||||
#include <QDirIterator>
|
||||
#include <QInputDialog>
|
||||
#include <boost/bind.hpp>
|
||||
#include <regex>
|
||||
#include <QMessageBox>
|
||||
#include <QCoreApplication>
|
||||
#include <boost/bind.hpp>
|
||||
#include <regex>
|
||||
|
||||
|
||||
using QtJson::Json;
|
||||
using namespace MOBase;
|
||||
|
||||
|
||||
@@ -218,8 +218,8 @@ void DownloadManager::setOutputDirectory(const QString &outputDirectory)
|
||||
m_DirWatcher.removePaths(directories);
|
||||
}
|
||||
m_OutputDirectory = QDir::fromNativeSeparators(outputDirectory);
|
||||
m_DirWatcher.addPath(m_OutputDirectory);
|
||||
refreshList();
|
||||
m_DirWatcher.addPath(m_OutputDirectory);
|
||||
}
|
||||
|
||||
|
||||
@@ -243,9 +243,11 @@ void DownloadManager::setShowHidden(bool showHidden)
|
||||
|
||||
void DownloadManager::refreshList()
|
||||
{
|
||||
int downloadsBefore = m_ActiveDownloads.size();
|
||||
|
||||
// remove finished downloads
|
||||
for (QVector<DownloadInfo*>::iterator Iter = m_ActiveDownloads.begin(); Iter != m_ActiveDownloads.end();) {
|
||||
if (((*Iter)->m_State == STATE_READY) || ((*Iter)->m_State == STATE_INSTALLED)) {
|
||||
if (((*Iter)->m_State == STATE_READY) || ((*Iter)->m_State == STATE_INSTALLED) || ((*Iter)->m_State == STATE_UNINSTALLED)) {
|
||||
delete *Iter;
|
||||
Iter = m_ActiveDownloads.erase(Iter);
|
||||
} else {
|
||||
@@ -259,9 +261,22 @@ void DownloadManager::refreshList()
|
||||
}
|
||||
|
||||
nameFilters.append(QString("*").append(UNFINISHED));
|
||||
|
||||
QDir dir(QDir::fromNativeSeparators(m_OutputDirectory));
|
||||
|
||||
// find orphaned meta files and delete them (sounds cruel but it's better for everyone)
|
||||
QStringList orphans;
|
||||
QStringList metaFiles = dir.entryList(QStringList() << "*.meta");
|
||||
foreach (const QString &metaFile, metaFiles) {
|
||||
QString baseFile = metaFile.left(metaFile.length() - 5);
|
||||
if (!QFile::exists(dir.absoluteFilePath(baseFile))) {
|
||||
orphans.append(dir.absoluteFilePath(metaFile));
|
||||
}
|
||||
}
|
||||
if (orphans.size() > 0) {
|
||||
qDebug("%d orphaned meta files will be deleted", orphans.size());
|
||||
shellDelete(orphans, true);
|
||||
}
|
||||
|
||||
// add existing downloads to list
|
||||
foreach (QString file, dir.entryList(nameFilters, QDir::Files, QDir::Time)) {
|
||||
bool Exists = false;
|
||||
@@ -273,6 +288,7 @@ void DownloadManager::refreshList()
|
||||
}
|
||||
}
|
||||
if (Exists) {
|
||||
qDebug("%s exists", qPrintable(file));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -283,7 +299,10 @@ void DownloadManager::refreshList()
|
||||
m_ActiveDownloads.push_front(info);
|
||||
}
|
||||
}
|
||||
qDebug("downloads after refresh: %d", m_ActiveDownloads.size());
|
||||
|
||||
if (m_ActiveDownloads.size() != downloadsBefore) {
|
||||
qDebug("downloads after refresh: %d", m_ActiveDownloads.size());
|
||||
}
|
||||
emit update(-1);
|
||||
}
|
||||
|
||||
@@ -323,6 +342,7 @@ bool DownloadManager::addDownload(QNetworkReply *reply, const QStringList &URLs,
|
||||
(QMessageBox::question(NULL, 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."),
|
||||
QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)) {
|
||||
removePending(modID, fileID);
|
||||
delete newDownload;
|
||||
return false;
|
||||
}
|
||||
@@ -331,11 +351,24 @@ bool DownloadManager::addDownload(QNetworkReply *reply, const QStringList &URLs,
|
||||
|
||||
startDownload(reply, newDownload, false);
|
||||
|
||||
emit update(-1);
|
||||
// emit update(-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void DownloadManager::removePending(int modID, int fileID)
|
||||
{
|
||||
emit aboutToUpdate();
|
||||
for (auto iter = m_PendingDownloads.begin(); iter != m_PendingDownloads.end(); ++iter) {
|
||||
if ((iter->first == modID) && (iter->second == fileID)) {
|
||||
m_PendingDownloads.erase(iter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
emit update(-1);
|
||||
}
|
||||
|
||||
|
||||
void DownloadManager::startDownload(QNetworkReply *reply, DownloadInfo *newDownload, bool resume)
|
||||
{
|
||||
newDownload->m_Reply = reply;
|
||||
@@ -365,11 +398,14 @@ void DownloadManager::startDownload(QNetworkReply *reply, DownloadInfo *newDownl
|
||||
if (!resume) {
|
||||
newDownload->m_PreResumeSize = newDownload->m_Output.size();
|
||||
|
||||
removePending(newDownload->m_ModID, newDownload->m_FileID);
|
||||
|
||||
emit aboutToUpdate();
|
||||
|
||||
m_ActiveDownloads.append(newDownload);
|
||||
|
||||
emit update(-1);
|
||||
emit downloadAdded();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -379,14 +415,21 @@ void DownloadManager::addNXMDownload(const QString &url)
|
||||
NXMUrl nxmInfo(url);
|
||||
|
||||
QString managedGame = ToQString(MOShared::GameInfo::instance().getGameShortName());
|
||||
|
||||
qDebug("add nxm download: %s", qPrintable(url));
|
||||
if (nxmInfo.game().compare(managedGame, Qt::CaseInsensitive) != 0) {
|
||||
qDebug("download requested for wrong game (game: %s, url: %s)", qPrintable(managedGame), qPrintable(nxmInfo.game()));
|
||||
QMessageBox::information(NULL, 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(managedGame), QMessageBox::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
m_RequestIDs.insert(m_NexusInterface->requestFileInfo(nxmInfo.getModId(), nxmInfo.getFileId(), this, QVariant()));
|
||||
emit aboutToUpdate();
|
||||
|
||||
m_PendingDownloads.append(std::make_pair(nxmInfo.modId(), nxmInfo.fileId()));
|
||||
|
||||
emit update(-1);
|
||||
emit downloadAdded();
|
||||
m_RequestIDs.insert(m_NexusInterface->requestFileInfo(nxmInfo.modId(), nxmInfo.fileId(), this, nxmInfo.fileId()));
|
||||
}
|
||||
|
||||
|
||||
@@ -628,6 +671,19 @@ int DownloadManager::numTotalDownloads() const
|
||||
return m_ActiveDownloads.size();
|
||||
}
|
||||
|
||||
int DownloadManager::numPendingDownloads() const
|
||||
{
|
||||
return m_PendingDownloads.size();
|
||||
}
|
||||
|
||||
std::pair<int, int> DownloadManager::getPendingDownload(int index)
|
||||
{
|
||||
if ((index < 0) || (index >= m_PendingDownloads.size())) {
|
||||
throw MyException(tr("invalid index"));
|
||||
}
|
||||
|
||||
return m_PendingDownloads.at(index);
|
||||
}
|
||||
|
||||
QString DownloadManager::getFilePath(int index) const
|
||||
{
|
||||
@@ -1025,8 +1081,8 @@ void DownloadManager::nxmFileInfoAvailable(int modID, int fileID, QVariant userD
|
||||
NexusInfo info;
|
||||
|
||||
QVariantMap result = resultData.toMap();
|
||||
|
||||
info.m_Name = result["name"].toString();
|
||||
qDebug("file info received for %s", qPrintable(info.m_Name));
|
||||
info.m_Version = result["version"].toString();
|
||||
if (info.m_Version.isEmpty()) {
|
||||
info.m_Version = info.m_NewestVersion;
|
||||
@@ -1034,11 +1090,7 @@ void DownloadManager::nxmFileInfoAvailable(int modID, int fileID, QVariant userD
|
||||
info.m_FileName = result["uri"].toString();
|
||||
info.m_FileTime = matchDate(result["date"].toString());
|
||||
|
||||
if (userData.isValid()) {
|
||||
m_RequestIDs.insert(m_NexusInterface->requestDownloadURL(modID, fileID, this, qVariantFromValue(info), userData.toString()));
|
||||
} else {
|
||||
m_RequestIDs.insert(m_NexusInterface->requestDownloadURL(modID, fileID, this, qVariantFromValue(info)));
|
||||
}
|
||||
m_RequestIDs.insert(m_NexusInterface->requestDownloadURL(modID, fileID, this, QVariant::fromValue(info)));
|
||||
}
|
||||
|
||||
|
||||
@@ -1124,6 +1176,7 @@ void DownloadManager::nxmDownloadURLsAvailable(int modID, int fileID, QVariant u
|
||||
NexusInfo info = userData.value<NexusInfo>();
|
||||
QVariantList resultList = resultData.toList();
|
||||
if (resultList.length() == 0) {
|
||||
removePending(modID, fileID);
|
||||
emit showMessage(tr("No download server available. Please try again later."));
|
||||
return;
|
||||
}
|
||||
@@ -1142,7 +1195,7 @@ void DownloadManager::nxmDownloadURLsAvailable(int modID, int fileID, QVariant u
|
||||
}
|
||||
|
||||
|
||||
void DownloadManager::nxmRequestFailed(int modID, QVariant, int requestID, const QString &errorString)
|
||||
void DownloadManager::nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString &errorString)
|
||||
{
|
||||
std::set<int>::iterator idIter = m_RequestIDs.find(requestID);
|
||||
if (idIter == m_RequestIDs.end()) {
|
||||
@@ -1166,6 +1219,8 @@ void DownloadManager::nxmRequestFailed(int modID, QVariant, int requestID, const
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
removePending(modID, fileID);
|
||||
emit showMessage(tr("Failed to request file info from nexus: %1").arg(errorString));
|
||||
}
|
||||
|
||||
@@ -1183,14 +1238,18 @@ void DownloadManager::downloadFinished()
|
||||
TaskProgressManager::instance().forgetMe(info->m_TaskProgressId);
|
||||
|
||||
bool error = false;
|
||||
|
||||
if ((info->m_State != STATE_CANCELING) &&
|
||||
(info->m_State != STATE_PAUSING)) {
|
||||
bool textData = reply->header(QNetworkRequest::ContentTypeHeader).toString().startsWith("text", Qt::CaseInsensitive);
|
||||
if ((info->m_Output.size() == 0) ||
|
||||
((reply->error() != QNetworkReply::NoError) && (reply->error() != QNetworkReply::OperationCanceledError)) ||
|
||||
reply->header(QNetworkRequest::ContentTypeHeader).toString().startsWith("text", Qt::CaseInsensitive)) {
|
||||
textData) {
|
||||
if (info->m_Tries == 0) {
|
||||
emit showMessage(tr("Download failed: %1 (%2)").arg(reply->errorString()).arg(reply->error()));
|
||||
if (textData && (reply->error() == QNetworkReply::NoError)) {
|
||||
emit showMessage(tr("Download failed. Server reported: %1").arg(readFileText(info->m_Output.fileName())));
|
||||
} else {
|
||||
emit showMessage(tr("Download failed: %1 (%2)").arg(reply->errorString()).arg(reply->error()));
|
||||
}
|
||||
}
|
||||
error = true;
|
||||
setState(info, STATE_PAUSING);
|
||||
@@ -1250,7 +1309,7 @@ void DownloadManager::downloadFinished()
|
||||
|
||||
if ((info->m_Tries > 0) && error) {
|
||||
--info->m_Tries;
|
||||
resumeDownload(index);
|
||||
resumeDownloadInt(index);
|
||||
}
|
||||
} else {
|
||||
qWarning("no download index %d", index);
|
||||
@@ -1282,3 +1341,4 @@ void DownloadManager::directoryChanged(const QString&)
|
||||
{
|
||||
refreshList();
|
||||
}
|
||||
|
||||
|
||||
+26
-1
@@ -205,6 +205,19 @@ public:
|
||||
**/
|
||||
int numTotalDownloads() const;
|
||||
|
||||
/**
|
||||
* @brief retrieve number of pending downloads (nexus downloads for which we don't know the name and url yet)
|
||||
* @return number of pending downloads
|
||||
*/
|
||||
int numPendingDownloads() const;
|
||||
|
||||
/**
|
||||
* @brief retrieve the info of a pending download
|
||||
* @param index index of the pending download (index in the range [0, numPendingDownloads()[)
|
||||
* @return pair of modid, fileid
|
||||
*/
|
||||
std::pair<int, int> getPendingDownload(int index);
|
||||
|
||||
/**
|
||||
* @brief retrieve the full path to the download specified by index
|
||||
*
|
||||
@@ -357,6 +370,11 @@ signals:
|
||||
*/
|
||||
void downloadSpeed(const QString &serverName, int bytesPerSecond);
|
||||
|
||||
/**
|
||||
* @brief emitted whenever a new download is added to the list
|
||||
*/
|
||||
void downloadAdded();
|
||||
|
||||
public slots:
|
||||
|
||||
/**
|
||||
@@ -394,7 +412,7 @@ public slots:
|
||||
|
||||
void nxmDownloadURLsAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID);
|
||||
|
||||
void nxmRequestFailed(int modID, QVariant userData, int requestID, const QString &errorString);
|
||||
void nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString &errorString);
|
||||
|
||||
private slots:
|
||||
|
||||
@@ -440,6 +458,8 @@ private:
|
||||
|
||||
QDateTime matchDate(const QString &timeString);
|
||||
|
||||
void removePending(int modID, int fileID);
|
||||
|
||||
private:
|
||||
|
||||
static const int AUTOMATIC_RETRIES = 3;
|
||||
@@ -447,6 +467,9 @@ private:
|
||||
private:
|
||||
|
||||
NexusInterface *m_NexusInterface;
|
||||
|
||||
QVector<std::pair<int, int> > m_PendingDownloads;
|
||||
|
||||
QVector<DownloadInfo*> m_ActiveDownloads;
|
||||
|
||||
QString m_OutputDirectory;
|
||||
@@ -465,4 +488,6 @@ private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // DOWNLOADMANAGER_H
|
||||
|
||||
@@ -30,7 +30,7 @@ using namespace MOShared;
|
||||
|
||||
EditExecutablesDialog::EditExecutablesDialog(const ExecutablesList &executablesList, QWidget *parent)
|
||||
: TutorableDialog("EditExecutables", parent),
|
||||
ui(new Ui::EditExecutablesDialog), m_ExecutablesList(executablesList)
|
||||
ui(new Ui::EditExecutablesDialog), m_CurrentItem(NULL), m_ExecutablesList(executablesList)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
@@ -68,21 +68,15 @@ void EditExecutablesDialog::refreshExecutablesWidget()
|
||||
executablesWidget->addItem(newItem);
|
||||
}
|
||||
|
||||
QPushButton *addButton = findChild<QPushButton*>("addButton");
|
||||
QPushButton *removeButton = findChild<QPushButton*>("removeButton");
|
||||
|
||||
addButton->setEnabled(false);
|
||||
removeButton->setEnabled(false);
|
||||
ui->addButton->setEnabled(false);
|
||||
ui->removeButton->setEnabled(false);
|
||||
}
|
||||
|
||||
|
||||
void EditExecutablesDialog::on_binaryEdit_textChanged(const QString &arg1)
|
||||
{
|
||||
QPushButton *addButton = findChild<QPushButton*>("addButton");
|
||||
// QPushButton *removeButton = findChild<QPushButton*>("removeButton");
|
||||
|
||||
QFileInfo fileInfo(arg1);
|
||||
addButton->setEnabled(fileInfo.exists() && fileInfo.isFile());
|
||||
ui->addButton->setEnabled(fileInfo.exists() && fileInfo.isFile());
|
||||
}
|
||||
|
||||
void EditExecutablesDialog::resetInput()
|
||||
@@ -91,23 +85,35 @@ void EditExecutablesDialog::resetInput()
|
||||
ui->titleEdit->setText("");
|
||||
ui->workingDirEdit->clear();
|
||||
ui->argumentsEdit->setText("");
|
||||
ui->appIDOverwriteEdit->clear();
|
||||
ui->overwriteAppIDBox->setChecked(false);
|
||||
ui->closeCheckBox->setChecked(false);
|
||||
m_CurrentItem = NULL;
|
||||
}
|
||||
|
||||
|
||||
void EditExecutablesDialog::saveExecutable()
|
||||
{
|
||||
m_ExecutablesList.addExecutable(ui->titleEdit->text(), QDir::fromNativeSeparators(ui->binaryEdit->text()),
|
||||
ui->argumentsEdit->text(), QDir::fromNativeSeparators(ui->workingDirEdit->text()),
|
||||
(ui->closeCheckBox->checkState() == Qt::Checked) ? DEFAULT_CLOSE : DEFAULT_STAY,
|
||||
ui->overwriteAppIDBox->isChecked() ? ui->appIDOverwriteEdit->text() : "",
|
||||
true, false);
|
||||
}
|
||||
|
||||
|
||||
void EditExecutablesDialog::delayedRefresh()
|
||||
{
|
||||
int index = ui->executablesListBox->currentIndex().row();
|
||||
resetInput();
|
||||
refreshExecutablesWidget();
|
||||
ui->executablesListBox->setCurrentRow(index);
|
||||
}
|
||||
|
||||
|
||||
void EditExecutablesDialog::on_addButton_clicked()
|
||||
{
|
||||
QLineEdit *titleEdit = findChild<QLineEdit*>("titleEdit");
|
||||
QLineEdit *binaryEdit = findChild<QLineEdit*>("binaryEdit");
|
||||
QLineEdit *argumentsEdit = findChild<QLineEdit*>("argumentsEdit");
|
||||
QLineEdit *workingDirEdit = findChild<QLineEdit*>("workingDirEdit");
|
||||
QCheckBox *closeCheckBox = findChild<QCheckBox*>("closeCheckBox");
|
||||
|
||||
m_ExecutablesList.addExecutable(titleEdit->text(), QDir::fromNativeSeparators(binaryEdit->text()),
|
||||
argumentsEdit->text(), QDir::fromNativeSeparators(workingDirEdit->text()),
|
||||
(closeCheckBox->checkState() == Qt::Checked) ? DEFAULT_CLOSE : DEFAULT_STAY,
|
||||
ui->overwriteAppIDBox->isChecked() ? ui->appIDOverwriteEdit->text() : "",
|
||||
true, false);
|
||||
saveExecutable();
|
||||
|
||||
resetInput();
|
||||
refreshExecutablesWidget();
|
||||
@@ -196,37 +202,88 @@ void EditExecutablesDialog::on_titleEdit_textChanged(const QString &arg1)
|
||||
}
|
||||
}
|
||||
|
||||
void EditExecutablesDialog::on_executablesListBox_itemClicked(QListWidgetItem *item)
|
||||
|
||||
bool EditExecutablesDialog::executableChanged()
|
||||
{
|
||||
QLineEdit *titleEdit = findChild<QLineEdit*>("titleEdit");
|
||||
QLineEdit *binaryEdit = findChild<QLineEdit*>("binaryEdit");
|
||||
QLineEdit *argumentsEdit = findChild<QLineEdit*>("argumentsEdit");
|
||||
QLineEdit *workingDirEdit = findChild<QLineEdit*>("workingDirEdit");
|
||||
QPushButton *removeButton = findChild<QPushButton*>("removeButton");
|
||||
QCheckBox *closeCheckBox = findChild<QCheckBox*>("closeCheckBox");
|
||||
if (m_CurrentItem != NULL) {
|
||||
const Executable &selectedExecutable = m_CurrentItem->data(Qt::UserRole).value<Executable>();
|
||||
|
||||
const Executable &selectedExecutable = item->data(Qt::UserRole).value<Executable>();
|
||||
|
||||
titleEdit->setText(selectedExecutable.m_Title);
|
||||
binaryEdit->setText(QDir::toNativeSeparators(selectedExecutable.m_BinaryInfo.absoluteFilePath()));
|
||||
argumentsEdit->setText(selectedExecutable.m_Arguments);
|
||||
workingDirEdit->setText(QDir::toNativeSeparators(selectedExecutable.m_WorkingDirectory));
|
||||
closeCheckBox->setChecked(selectedExecutable.m_CloseMO == DEFAULT_CLOSE);
|
||||
if (selectedExecutable.m_CloseMO == NEVER_CLOSE) {
|
||||
closeCheckBox->setEnabled(false);
|
||||
closeCheckBox->setToolTip(tr("MO must be kept running or this application will not work correctly."));
|
||||
return selectedExecutable.m_Arguments != ui->argumentsEdit->text()
|
||||
|| selectedExecutable.m_SteamAppID != ui->appIDOverwriteEdit->text()
|
||||
|| selectedExecutable.m_WorkingDirectory != QDir::fromNativeSeparators(ui->workingDirEdit->text())
|
||||
|| selectedExecutable.m_BinaryInfo.absoluteFilePath() != QDir::fromNativeSeparators(ui->binaryEdit->text())
|
||||
|| (selectedExecutable.m_CloseMO == DEFAULT_CLOSE) != ui->closeCheckBox->isChecked();
|
||||
} else {
|
||||
closeCheckBox->setEnabled(true);
|
||||
closeCheckBox->setToolTip(tr("If checked, MO will be closed once the specified executable is run."));
|
||||
return false;
|
||||
}
|
||||
removeButton->setEnabled(selectedExecutable.m_Custom);
|
||||
}
|
||||
|
||||
|
||||
void EditExecutablesDialog::on_executablesListBox_currentItemChanged(QListWidgetItem *current, QListWidgetItem*)
|
||||
{
|
||||
if (current == NULL) {
|
||||
resetInput();
|
||||
return;
|
||||
}
|
||||
|
||||
if (executableChanged()) {
|
||||
QMessageBox::StandardButton res = QMessageBox::question(this, tr("Save Changes?"),
|
||||
tr("You made changes to the current executable, do you want to save them?"),
|
||||
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
|
||||
if (res == QMessageBox::Cancel) {
|
||||
return;
|
||||
} else if (res == QMessageBox::Yes) {
|
||||
// this invalidates the item passed as a a parameter
|
||||
saveExecutable();
|
||||
|
||||
QTimer::singleShot(50, this, SLOT(delayedRefresh()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_CurrentItem = current;
|
||||
|
||||
const Executable &selectedExecutable = current->data(Qt::UserRole).value<Executable>();
|
||||
|
||||
ui->titleEdit->setText(selectedExecutable.m_Title);
|
||||
ui->binaryEdit->setText(QDir::toNativeSeparators(selectedExecutable.m_BinaryInfo.absoluteFilePath()));
|
||||
ui->argumentsEdit->setText(selectedExecutable.m_Arguments);
|
||||
ui->workingDirEdit->setText(QDir::toNativeSeparators(selectedExecutable.m_WorkingDirectory));
|
||||
ui->closeCheckBox->setChecked(selectedExecutable.m_CloseMO == DEFAULT_CLOSE);
|
||||
if (selectedExecutable.m_CloseMO == NEVER_CLOSE) {
|
||||
ui->closeCheckBox->setEnabled(false);
|
||||
ui->closeCheckBox->setToolTip(tr("MO must be kept running or this application will not work correctly."));
|
||||
} else {
|
||||
ui->closeCheckBox->setEnabled(true);
|
||||
ui->closeCheckBox->setToolTip(tr("If checked, MO will be closed once the specified executable is run."));
|
||||
}
|
||||
ui->removeButton->setEnabled(selectedExecutable.m_Custom);
|
||||
ui->overwriteAppIDBox->setChecked(selectedExecutable.m_SteamAppID != 0);
|
||||
if (selectedExecutable.m_SteamAppID != 0) {
|
||||
ui->appIDOverwriteEdit->setText(selectedExecutable.m_SteamAppID);
|
||||
} else {
|
||||
ui->appIDOverwriteEdit->clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EditExecutablesDialog::on_overwriteAppIDBox_toggled(bool checked)
|
||||
{
|
||||
ui->appIDOverwriteEdit->setEnabled(checked);
|
||||
}
|
||||
|
||||
void EditExecutablesDialog::on_closeButton_clicked()
|
||||
{
|
||||
if (executableChanged()) {
|
||||
QMessageBox::StandardButton res = QMessageBox::question(this, tr("Save Changes?"),
|
||||
tr("You made changes to the current executable, do you want to save them?"),
|
||||
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
|
||||
if (res == QMessageBox::Cancel) {
|
||||
return;
|
||||
} else if (res == QMessageBox::Yes) {
|
||||
saveExecutable();
|
||||
}
|
||||
}
|
||||
this->accept();
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "tutorabledialog.h"
|
||||
#include <QListWidgetItem>
|
||||
#include <QTimer>
|
||||
#include "executableslist.h"
|
||||
|
||||
namespace Ui {
|
||||
@@ -54,6 +55,7 @@ public:
|
||||
**/
|
||||
ExecutablesList getExecutablesList() const;
|
||||
|
||||
void saveExecutable();
|
||||
private slots:
|
||||
|
||||
void on_binaryEdit_textChanged(const QString &arg1);
|
||||
@@ -66,21 +68,31 @@ private slots:
|
||||
|
||||
void on_titleEdit_textChanged(const QString &arg1);
|
||||
|
||||
void on_executablesListBox_itemClicked(QListWidgetItem *item);
|
||||
|
||||
void on_overwriteAppIDBox_toggled(bool checked);
|
||||
|
||||
void on_browseDirButton_clicked();
|
||||
|
||||
void on_closeButton_clicked();
|
||||
|
||||
void on_executablesListBox_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous);
|
||||
|
||||
void delayedRefresh();
|
||||
|
||||
private:
|
||||
|
||||
void resetInput();
|
||||
|
||||
void refreshExecutablesWidget();
|
||||
|
||||
bool executableChanged();
|
||||
|
||||
private:
|
||||
Ui::EditExecutablesDialog *ui;
|
||||
|
||||
QListWidgetItem *m_CurrentItem;
|
||||
|
||||
ExecutablesList m_ExecutablesList;
|
||||
|
||||
};
|
||||
|
||||
#endif // EDITEXECUTABLESDIALOG_H
|
||||
|
||||
@@ -213,50 +213,31 @@ Right now the only case I know of where this needs to be overwritten is for the
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<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="QPushButton" name="closeButton">
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>EditExecutablesDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>EditExecutablesDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
||||
+5
-25
@@ -29,38 +29,17 @@ IconDelegate::IconDelegate(QObject *parent)
|
||||
}
|
||||
|
||||
|
||||
QIcon IconDelegate::getFlagIcon(ModInfo::EFlag flag) const
|
||||
{
|
||||
switch (flag) {
|
||||
case ModInfo::FLAG_BACKUP: return QIcon(":/MO/gui/emblem_backup");
|
||||
case ModInfo::FLAG_INVALID: return QIcon(":/MO/gui/emblem_problem");
|
||||
case ModInfo::FLAG_NOTENDORSED: return QIcon(":/MO/gui/emblem_notendorsed");
|
||||
case ModInfo::FLAG_NOTES: return QIcon(":/MO/gui/emblem_notes");
|
||||
case ModInfo::FLAG_CONFLICT_OVERWRITE: return QIcon(":/MO/gui/emblem_conflict_overwrite");
|
||||
case ModInfo::FLAG_CONFLICT_OVERWRITTEN: return QIcon(":/MO/gui/emblem_conflict_overwritten");
|
||||
case ModInfo::FLAG_CONFLICT_MIXED: return QIcon(":/MO/gui/emblem_conflict_mixed");
|
||||
case ModInfo::FLAG_CONFLICT_REDUNDANT: return QIcon(":MO/gui/emblem_conflict_redundant");
|
||||
default: return QIcon();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IconDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
QStyledItemDelegate::paint(painter, option, index);
|
||||
QVariant modid = index.data(Qt::UserRole + 1);
|
||||
if (!modid.isValid()) {
|
||||
return;
|
||||
}
|
||||
ModInfo::Ptr info = ModInfo::getByIndex(modid.toInt());
|
||||
std::vector<ModInfo::EFlag> flags = info->getFlags();
|
||||
|
||||
QList<QIcon> icons = getIcons(index);
|
||||
|
||||
int x = 4;
|
||||
painter->save();
|
||||
painter->translate(option.rect.topLeft());
|
||||
for (auto iter = flags.begin(); iter != flags.end(); ++iter) {
|
||||
QIcon temp = getFlagIcon(*iter);
|
||||
painter->drawPixmap(x, 2, 16, 16, temp.pixmap(QSize(16, 16)));
|
||||
for (auto iter = icons.begin(); iter != icons.end(); ++iter) {
|
||||
painter->drawPixmap(x, 2, 16, 16, iter->pixmap(QSize(16, 16)));
|
||||
x += 20;
|
||||
}
|
||||
|
||||
@@ -70,6 +49,7 @@ void IconDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
|
||||
QSize IconDelegate::sizeHint(const QStyleOptionViewItem&, const QModelIndex &modelIndex) const
|
||||
{
|
||||
int count = getNumIcons(modelIndex);
|
||||
unsigned int index = modelIndex.data(Qt::UserRole + 1).toInt();
|
||||
if (index < ModInfo::getNumMods()) {
|
||||
ModInfo::Ptr info = ModInfo::getByIndex(index);
|
||||
|
||||
+4
-1
@@ -34,13 +34,16 @@ public:
|
||||
|
||||
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
private:
|
||||
|
||||
QIcon getFlagIcon(ModInfo::EFlag flag) const;
|
||||
virtual QList<QIcon> getIcons(const QModelIndex &index) const = 0;
|
||||
virtual size_t getNumIcons(const QModelIndex &index) const = 0;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
+522
-588
File diff suppressed because it is too large
Load Diff
+94
-204
@@ -1,204 +1,94 @@
|
||||
/* Copyright 2011 Eeli Reilin. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL EELI REILIN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation
|
||||
* are those of the authors and should not be interpreted as representing
|
||||
* official policies, either expressed or implied, of Eeli Reilin.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file json.h
|
||||
*/
|
||||
|
||||
#ifndef JSON_H
|
||||
#define JSON_H
|
||||
|
||||
#include <QVariant>
|
||||
#include <QString>
|
||||
|
||||
namespace QtJson
|
||||
{
|
||||
|
||||
/**
|
||||
* \enum JsonToken
|
||||
*/
|
||||
enum JsonToken
|
||||
{
|
||||
JsonTokenNone = 0,
|
||||
JsonTokenCurlyOpen = 1,
|
||||
JsonTokenCurlyClose = 2,
|
||||
JsonTokenSquaredOpen = 3,
|
||||
JsonTokenSquaredClose = 4,
|
||||
JsonTokenColon = 5,
|
||||
JsonTokenComma = 6,
|
||||
JsonTokenString = 7,
|
||||
JsonTokenNumber = 8,
|
||||
JsonTokenTrue = 9,
|
||||
JsonTokenFalse = 10,
|
||||
JsonTokenNull = 11
|
||||
};
|
||||
|
||||
/**
|
||||
* \class Json
|
||||
* \brief A JSON data parser
|
||||
*
|
||||
* Json parses a JSON data into a QVariant hierarchy.
|
||||
*/
|
||||
class Json
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Parse a JSON string
|
||||
*
|
||||
* \param json The JSON data
|
||||
*/
|
||||
static QVariant parse(const QString &json);
|
||||
|
||||
/**
|
||||
* Parse a JSON string
|
||||
*
|
||||
* \param json The JSON data
|
||||
* \param success The success of the parsing
|
||||
*/
|
||||
static QVariant parse(const QString &json, bool &success);
|
||||
|
||||
/**
|
||||
* This method generates a textual JSON representation
|
||||
*
|
||||
* \param data The JSON data generated by the parser.
|
||||
* \param success The success of the serialization
|
||||
*/
|
||||
static QByteArray serialize(const QVariant &data);
|
||||
|
||||
/**
|
||||
* This method generates a textual JSON representation
|
||||
*
|
||||
* \param data The JSON data generated by the parser.
|
||||
* \param success The success of the serialization
|
||||
*
|
||||
* \return QByteArray Textual JSON representation
|
||||
*/
|
||||
static QByteArray serialize(const QVariant &data, bool &success);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Parses a value starting from index
|
||||
*
|
||||
* \param json The JSON data
|
||||
* \param index The start index
|
||||
* \param success The success of the parse process
|
||||
*
|
||||
* \return QVariant The parsed value
|
||||
*/
|
||||
static QVariant parseValue(const QString &json, int &index,
|
||||
bool &success);
|
||||
|
||||
/**
|
||||
* Parses an object starting from index
|
||||
*
|
||||
* \param json The JSON data
|
||||
* \param index The start index
|
||||
* \param success The success of the object parse
|
||||
*
|
||||
* \return QVariant The parsed object map
|
||||
*/
|
||||
static QVariant parseObject(const QString &json, int &index,
|
||||
bool &success);
|
||||
|
||||
/**
|
||||
* Parses an array starting from index
|
||||
*
|
||||
* \param json The JSON data
|
||||
* \param index The starting index
|
||||
* \param success The success of the array parse
|
||||
*
|
||||
* \return QVariant The parsed variant array
|
||||
*/
|
||||
static QVariant parseArray(const QString &json, int &index,
|
||||
bool &success);
|
||||
|
||||
/**
|
||||
* Parses a string starting from index
|
||||
*
|
||||
* \param json The JSON data
|
||||
* \param index The starting index
|
||||
* \param success The success of the string parse
|
||||
*
|
||||
* \return QVariant The parsed string
|
||||
*/
|
||||
static QVariant parseString(const QString &json, int &index,
|
||||
bool &success);
|
||||
|
||||
/**
|
||||
* Parses a number starting from index
|
||||
*
|
||||
* \param json The JSON data
|
||||
* \param index The starting index
|
||||
*
|
||||
* \return QVariant The parsed number
|
||||
*/
|
||||
static QVariant parseNumber(const QString &json, int &index);
|
||||
|
||||
/**
|
||||
* Get the last index of a number starting from index
|
||||
*
|
||||
* \param json The JSON data
|
||||
* \param index The starting index
|
||||
*
|
||||
* \return The last index of the number
|
||||
*/
|
||||
static int lastIndexOfNumber(const QString &json, int index);
|
||||
|
||||
/**
|
||||
* Skip unwanted whitespace symbols starting from index
|
||||
*
|
||||
* \param json The JSON data
|
||||
* \param index The start index
|
||||
*/
|
||||
static void eatWhitespace(const QString &json, int &index);
|
||||
|
||||
/**
|
||||
* Check what token lies ahead
|
||||
*
|
||||
* \param json The JSON data
|
||||
* \param index The starting index
|
||||
*
|
||||
* \return int The upcoming token
|
||||
*/
|
||||
static int lookAhead(const QString &json, int index);
|
||||
|
||||
/**
|
||||
* Get the next JSON token
|
||||
*
|
||||
* \param json The JSON data
|
||||
* \param index The starting index
|
||||
*
|
||||
* \return int The next JSON token
|
||||
*/
|
||||
static int nextToken(const QString &json, int &index);
|
||||
};
|
||||
|
||||
|
||||
} //end namespace
|
||||
|
||||
#endif //JSON_H
|
||||
/**
|
||||
* QtJson - A simple class for parsing JSON data into a QVariant hierarchies and vice-versa.
|
||||
* Copyright (C) 2011 Eeli Reilin
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file json.h
|
||||
*/
|
||||
|
||||
#ifndef JSON_H
|
||||
#define JSON_H
|
||||
|
||||
#include <QVariant>
|
||||
#include <QString>
|
||||
|
||||
|
||||
/**
|
||||
* \namespace QtJson
|
||||
* \brief A JSON data parser
|
||||
*
|
||||
* Json parses a JSON data into a QVariant hierarchy.
|
||||
*/
|
||||
namespace QtJson {
|
||||
typedef QVariantMap JsonObject;
|
||||
typedef QVariantList JsonArray;
|
||||
|
||||
/**
|
||||
* Parse a JSON string
|
||||
*
|
||||
* \param json The JSON data
|
||||
*/
|
||||
QVariant parse(const QString &json);
|
||||
|
||||
/**
|
||||
* Parse a JSON string
|
||||
*
|
||||
* \param json The JSON data
|
||||
* \param success The success of the parsing
|
||||
*/
|
||||
QVariant parse(const QString &json, bool &success);
|
||||
|
||||
/**
|
||||
* This method generates a textual JSON representation
|
||||
*
|
||||
* \param data The JSON data generated by the parser.
|
||||
*
|
||||
* \return QByteArray Textual JSON representation in UTF-8
|
||||
*/
|
||||
QByteArray serialize(const QVariant &data);
|
||||
|
||||
/**
|
||||
* This method generates a textual JSON representation
|
||||
*
|
||||
* \param data The JSON data generated by the parser.
|
||||
* \param success The success of the serialization
|
||||
*
|
||||
* \return QByteArray Textual JSON representation in UTF-8
|
||||
*/
|
||||
QByteArray serialize(const QVariant &data, bool &success);
|
||||
|
||||
/**
|
||||
* This method generates a textual JSON representation
|
||||
*
|
||||
* \param data The JSON data generated by the parser.
|
||||
*
|
||||
* \return QString Textual JSON representation
|
||||
*/
|
||||
QString serializeStr(const QVariant &data);
|
||||
|
||||
/**
|
||||
* This method generates a textual JSON representation
|
||||
*
|
||||
* \param data The JSON data generated by the parser.
|
||||
* \param success The success of the serialization
|
||||
*
|
||||
* \return QString Textual JSON representation
|
||||
*/
|
||||
QString serializeStr(const QVariant &data, bool &success);
|
||||
}
|
||||
|
||||
#endif //JSON_H
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user