- caching of downloadwidgets to fix performance problem, currently broken and disabled

- added new state for downloads "uninstalled" for mods that were at one point installed and then removed
- user-configured server preference is now used
- updated tutorial to account for removal of integrated browser
- reverted to qt 4
- using performance optimised findfirstfile on win vista and up
- bugfix: it was possible to disable all columns of the mod list
- bugfix: hook.dll doesn't load on win xp
This commit is contained in:
Tannin
2013-06-29 18:04:10 +02:00
parent f8c683f700
commit fe37b48dff
23 changed files with 539 additions and 250 deletions
+5
View File
@@ -8,3 +8,8 @@ source/NCC/*/obj
source/NCC/bin
*.orig
source/plugins/proxyPython/build
staging/*
source - Copy/*
ModOrganizer-build-*
pdbs/*
source/NCC/BossDummy.x/*
+15
View File
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="dlls" version="1.0.0.0" processorArchitecture="x86"/>
<file name="icuin49.dll"/>
<file name="icuuc49.dll"/>
<file name="icudt49.dll"/>
<file name="Qt5Cored.dll"/>
<file name="Qt5Declaratived.dll"/>
<file name="Qt5Guid.dll"/>
<file name="Qt5Networkd.dll"/>
<file name="Qt5Scriptd.dll"/>
<file name="Qt5Sqld.dll"/>
<file name="Qt5Widgetsd.dll"/>
<file name="Qt5XmlPatternsd.dll"/>
</assembly>
+17
View File
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="dlls" version="1.0.0.0" processorArchitecture="x86"/>
<file name="icuin49.dll"/>
<file name="icuuc49.dll"/>
<file name="icudt49.dll"/>
<file name="Qt5Core.dll"/>
<file name="Qt5Declarative.dll"/>
<file name="Qt5Gui.dll"/>
<file name="Qt5Network.dll"/>
<file name="Qt5Script.dll"/>
<file name="Qt5Sql.dll"/>
<file name="Qt5Svg.dll"/>
<file name="Qt5Widgets.dll"/>
<file name="Qt5Xml.dll"/>
<file name="Qt5XmlPatterns.dll"/>
</assembly>
+54 -8
View File
@@ -30,7 +30,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
DownloadListWidget::DownloadListWidget(QWidget *parent)
: QWidget(parent), ui(new Ui::DownloadListWidget)
{
ui->setupUi(this);
ui->setupUi(this);
}
@@ -48,6 +48,9 @@ DownloadListWidgetDelegate::DownloadListWidgetDelegate(DownloadManager *manager,
m_InstallLabel = m_ItemWidget->findChild<QLabel*>("installLabel");
m_InstallLabel->setVisible(false);
connect(manager, SIGNAL(stateChanged(int,DownloadManager::DownloadState)), this, SLOT(stateChanged(int,DownloadManager::DownloadState)));
connect(manager, SIGNAL(downloadRemoved(int)), this, SLOT(resetCache(int)));
}
@@ -57,10 +60,35 @@ DownloadListWidgetDelegate::~DownloadListWidgetDelegate()
}
void DownloadListWidgetDelegate::stateChanged(int row,DownloadManager::DownloadState)
{
m_Cache.remove(row);
}
void DownloadListWidgetDelegate::resetCache(int)
{
m_Cache.clear();
}
void DownloadListWidgetDelegate::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));
painter->drawPixmap(rect, cache);
}
void DownloadListWidgetDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
try {
if (index.column() != 2) return;
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), option.rect.height()));
@@ -103,9 +131,14 @@ void DownloadListWidgetDelegate::paint(QPainter *painter, const QStyleOptionView
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 {
// 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", "Done - Double Click to install", 0));
#else
@@ -123,10 +156,23 @@ void DownloadListWidgetDelegate::paint(QPainter *painter, const QStyleOptionView
m_Progress->setValue(m_Manager->getProgress(downloadIndex));
}
painter->save();
painter->translate(QPoint(0, option.rect.topLeft().y()));
m_ItemWidget->render(painter);
painter->restore();
#pragma message("caching disabled because changes in the list (including resorting) doesn't work correctly")
// if (state >= DownloadManager::STATE_READY) {
if (false) {
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
QPixmap cache = m_ItemWidget->grab();
#else
QPixmap cache = QPixmap::grabWidget(m_ItemWidget);
#endif
m_Cache[index.row()] = cache;
drawCache(painter, option, cache);
} else {
painter->save();
painter->translate(QPoint(0, option.rect.topLeft().y()));
m_ItemWidget->render(painter);
painter->restore();
}
} catch (const std::exception &e) {
qCritical("failed to paint download list: %s", e.what());
}
+94 -83
View File
@@ -17,86 +17,97 @@ 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 DOWNLOADLISTWIDGET_H
#define DOWNLOADLISTWIDGET_H
#include <QWidget>
#include <QItemDelegate>
#include <QLabel>
#include <QProgressBar>
#include <QTreeView>
namespace Ui {
class DownloadListWidget;
}
class DownloadListWidget : public QWidget
{
Q_OBJECT
public:
explicit DownloadListWidget(QWidget *parent = 0);
~DownloadListWidget();
private:
Ui::DownloadListWidget *ui;
};
class DownloadManager;
class DownloadListWidgetDelegate : public QItemDelegate
{
Q_OBJECT
public:
DownloadListWidgetDelegate(DownloadManager *manager, QTreeView *view, QObject *parent = 0);
~DownloadListWidgetDelegate();
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
signals:
void installDownload(int index);
void queryInfo(int index);
void removeDownload(int index, bool deleteFile);
void cancelDownload(int index);
void pauseDownload(int index);
void resumeDownload(int index);
protected:
bool editorEvent(QEvent *event, QAbstractItemModel *model,
const QStyleOptionViewItem &option, const QModelIndex &index);
private slots:
void issueInstall();
void issueDelete();
void issueRemoveFromView();
void issueCancel();
void issuePause();
void issueResume();
void issueDeleteAll();
void issueDeleteCompleted();
void issueRemoveFromViewAll();
void issueRemoveFromViewCompleted();
void issueQueryInfo();
private:
DownloadListWidget *m_ItemWidget;
DownloadManager *m_Manager;
QLabel *m_NameLabel;
QProgressBar *m_Progress;
QLabel *m_InstallLabel;
int m_ContextRow;
QTreeView *m_View;
};
#endif // DOWNLOADLISTWIDGET_H
#ifndef DOWNLOADLISTWIDGET_H
#define DOWNLOADLISTWIDGET_H
#include <QWidget>
#include <QItemDelegate>
#include <QLabel>
#include <QProgressBar>
#include <QTreeView>
#include "downloadmanager.h"
namespace Ui {
class DownloadListWidget;
}
class DownloadListWidget : public QWidget
{
Q_OBJECT
public:
explicit DownloadListWidget(QWidget *parent = 0);
~DownloadListWidget();
private:
Ui::DownloadListWidget *ui;
};
class DownloadManager;
class DownloadListWidgetDelegate : public QItemDelegate
{
Q_OBJECT
public:
DownloadListWidgetDelegate(DownloadManager *manager, QTreeView *view, QObject *parent = 0);
~DownloadListWidgetDelegate();
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
signals:
void installDownload(int index);
void queryInfo(int index);
void removeDownload(int index, bool deleteFile);
void cancelDownload(int index);
void pauseDownload(int index);
void resumeDownload(int index);
protected:
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 issueInstall();
void issueDelete();
void issueRemoveFromView();
void issueCancel();
void issuePause();
void issueResume();
void issueDeleteAll();
void issueDeleteCompleted();
void issueRemoveFromViewAll();
void issueRemoveFromViewCompleted();
void issueQueryInfo();
void stateChanged(int row, DownloadManager::DownloadState);
void resetCache(int);
private:
DownloadListWidget *m_ItemWidget;
DownloadManager *m_Manager;
QLabel *m_NameLabel;
QProgressBar *m_Progress;
QLabel *m_InstallLabel;
int m_ContextRow;
QTreeView *m_View;
mutable QMap<int, QPixmap> m_Cache;
};
#endif // DOWNLOADLISTWIDGET_H
+50 -5
View File
@@ -48,6 +48,9 @@ DownloadListWidgetCompactDelegate::DownloadListWidgetCompactDelegate(DownloadMan
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)));
}
@@ -57,11 +60,37 @@ DownloadListWidgetCompactDelegate::~DownloadListWidgetCompactDelegate()
}
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));
painter->drawPixmap(rect, cache);
}
void DownloadListWidgetCompactDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
#pragma message("This is quite costy - room for optimization?")
if (index.column() != 2) return;
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), option.rect.height()));
if (index.row() % 2 == 1) {
m_ItemWidget->setBackgroundRole(QPalette::AlternateBase);
@@ -93,6 +122,9 @@ void DownloadListWidgetCompactDelegate::paint(QPainter *painter, const QStyleOpt
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);
@@ -106,10 +138,23 @@ void DownloadListWidgetCompactDelegate::paint(QPainter *painter, const QStyleOpt
m_Progress->setValue(m_Manager->getProgress(downloadIndex));
}
painter->save();
painter->translate(QPoint(0, option.rect.topLeft().y()));
m_ItemWidget->render(painter);
painter->restore();
#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());
}
+96 -87
View File
@@ -17,90 +17,99 @@ 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>
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, 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 cancelDownload(int index);
void pauseDownload(int index);
void resumeDownload(int index);
protected:
bool editorEvent(QEvent *event, QAbstractItemModel *model,
const QStyleOptionViewItem &option, const QModelIndex &index);
private slots:
void issueInstall();
void issueDelete();
void issueRemoveFromView();
void issueCancel();
void issuePause();
void issueResume();
void issueDeleteAll();
void issueDeleteCompleted();
void issueRemoveFromViewAll();
void issueRemoveFromViewCompleted();
void issueQueryInfo();
private:
DownloadListWidgetCompact *m_ItemWidget;
DownloadManager *m_Manager;
QLabel *m_NameLabel;
QProgressBar *m_Progress;
QLabel *m_DoneLabel;
QModelIndex m_ContextIndex;
QTreeView *m_View;
};
#endif // DOWNLOADLISTWIDGETCOMPACT_H
#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, 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 cancelDownload(int index);
void pauseDownload(int index);
void resumeDownload(int index);
protected:
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 issueInstall();
void issueDelete();
void issueRemoveFromView();
void issueCancel();
void issuePause();
void issueResume();
void issueDeleteAll();
void issueDeleteCompleted();
void issueRemoveFromViewAll();
void issueRemoveFromViewCompleted();
void issueQueryInfo();
void stateChanged(int row, DownloadManager::DownloadState);
void resetCache(int);
private:
DownloadListWidgetCompact *m_ItemWidget;
DownloadManager *m_Manager;
QLabel *m_NameLabel;
QProgressBar *m_Progress;
QLabel *m_DoneLabel;
QModelIndex m_ContextIndex;
QTreeView *m_View;
mutable QMap<int, QPixmap> m_Cache;
};
#endif // DOWNLOADLISTWIDGETCOMPACT_H
+76 -23
View File
@@ -30,6 +30,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QRegExp>
#include <QDirIterator>
#include <QInputDialog>
#include <boost/bind.hpp>
#include <regex>
#include <QMessageBox>
@@ -84,6 +85,8 @@ DownloadManager::DownloadInfo *DownloadManager::DownloadInfo::createFromMeta(con
if (metaFile.value("paused", false).toBool()) {
info->m_State = STATE_PAUSED;
} else if (metaFile.value("uninstalled", false).toBool()) {
info->m_State = STATE_UNINSTALLED;
} else if (metaFile.value("installed", false).toBool()) {
info->m_State = STATE_INSTALLED;
} else {
@@ -177,6 +180,13 @@ void DownloadManager::setOutputDirectory(const QString &outputDirectory)
refreshList();
}
void DownloadManager::setPreferredServers(const std::map<QString, int> &preferredServers)
{
m_PreferredServers = preferredServers;
}
void DownloadManager::setSupportedExtensions(const QStringList &extensions)
{
m_SupportedExtensions = extensions;
@@ -606,11 +616,26 @@ void DownloadManager::markInstalled(int index)
DownloadInfo *info = m_ActiveDownloads.at(index);
QSettings metaFile(info->m_Output.fileName() + ".meta", QSettings::IniFormat);
metaFile.setValue("installed", true);
metaFile.setValue("uninstalled", false);
setState(m_ActiveDownloads.at(index), STATE_INSTALLED);
}
void DownloadManager::markUninstalled(int index)
{
if ((index < 0) || (index >= m_ActiveDownloads.size())) {
throw MyException(tr("invalid index"));
}
DownloadInfo *info = m_ActiveDownloads.at(index);
QSettings metaFile(info->m_Output.fileName() + ".meta", QSettings::IniFormat);
metaFile.setValue("uninstalled", true);
setState(m_ActiveDownloads.at(index), STATE_UNINSTALLED);
}
QString DownloadManager::getDownloadFileName(const QString &baseName) const
{
QString fullPath = m_OutputDirectory + "/" + baseName;
@@ -643,6 +668,13 @@ QString DownloadManager::getFileNameFromNetworkReply(QNetworkReply *reply)
void DownloadManager::setState(DownloadManager::DownloadInfo *info, DownloadManager::DownloadState state)
{
int row = 0;
for (int i = 0; i < m_ActiveDownloads.size(); ++i) {
if (m_ActiveDownloads[i] == info) {
row = i;
break;
}
}
info->m_State = state;
switch (state) {
case STATE_PAUSED:
@@ -660,15 +692,11 @@ void DownloadManager::setState(DownloadManager::DownloadInfo *info, DownloadMana
} break;
case STATE_READY: {
createMetaFile(info);
for (int i = 0; i < m_ActiveDownloads.size(); ++i) {
if (m_ActiveDownloads[i] == info) {
emit downloadComplete(i);
return;
}
}
emit downloadComplete(row);
} break;
default: /* NOP */ break;
}
emit stateChanged(row, state);
}
@@ -736,6 +764,7 @@ void DownloadManager::createMetaFile(DownloadInfo *info)
metaFile.setValue("newestVersion", info->m_NexusInfo.m_NewestVersion);
metaFile.setValue("category", info->m_NexusInfo.m_Category);
metaFile.setValue("installed", info->m_State == DownloadManager::STATE_INSTALLED);
metaFile.setValue("uninstalled", info->m_State == DownloadManager::STATE_UNINSTALLED);
metaFile.setValue("paused", (info->m_State == DownloadManager::STATE_PAUSED) ||
(info->m_State == DownloadManager::STATE_ERROR));
@@ -759,7 +788,6 @@ void DownloadManager::nxmDescriptionAvailable(int, QVariant userData, QVariant r
QVariantMap result = resultData.toMap();
// DownloadInfo *info = static_cast<DownloadInfo*>(userData.value<void*>());
DownloadInfo *info = downloadInfoByID(userData.toInt());
if (info == NULL) return;
@@ -869,30 +897,45 @@ void DownloadManager::nxmFileInfoAvailable(int modID, int fileID, QVariant, QVar
// sort function to sort by best download server
bool DownloadManager::ServerByPreference(const QVariant &LHS, const QVariant &RHS)
bool DownloadManager::ServerByPreference(const std::map<QString, int> &preferredServers, const QVariant &LHS, const QVariant &RHS)
{
int LHSVal = 0;
int RHSVal = 0;
QVariantMap LHSMap = LHS.toMap();
QVariantMap RHSMap = RHS.toMap();
int LHSUsers = LHSMap["ConnectedUsers"].toInt();
int RHSUsers = RHSMap["ConnectedUsers"].toInt();
bool LHSPremium = LHSMap["IsPremium"].toBool();
bool RHSPremium = RHSMap["IsPremium"].toBool();
// 0 users is probably a sign that the server is offline. Since there is currently no
// mechanism to try a different server, we avoid those without users
if ((LHSUsers == 0) && (RHSUsers != 0)) return false;
if ((LHSUsers != 0) && (RHSUsers == 0)) return true;
if (LHSPremium && !RHSPremium) {
return true;
} else if (!LHSPremium && RHSPremium) {
return false;
if (LHSUsers == 0) {
LHSVal -= 500;
} else {
LHSVal -= LHSUsers;
}
if (RHSUsers == 0) {
RHSVal -= 500;
} else {
RHSVal -= RHSUsers;
}
// TODO implement country preference
// user preference. This is a bit silly because the more servers on the preferred list the higher the boost
auto LHSPreference = preferredServers.find(LHSMap["Name"].toString());
auto RHSPreference = preferredServers.find(RHSMap["Name"].toString());
return LHSUsers < RHSUsers;
if (LHSPreference != preferredServers.end()) {
LHSVal += 100 + LHSPreference->second * 20;
}
if (RHSPreference != preferredServers.end()) {
RHSVal += 100 + RHSPreference->second * 20;
}
// premium isn't valued high because premium servers already get a massive boost for having few users online
if (LHSMap["IsPremium"].toBool()) LHSVal += 5;
if (RHSMap["IsPremium"].toBool()) RHSVal += 5;
return RHSVal < LHSVal;
}
int DownloadManager::startDownloadURLs(const QStringList &urls)
@@ -913,6 +956,16 @@ QString DownloadManager::downloadPath(int id)
return getFilePath(id);
}
int DownloadManager::indexByName(const QString &fileName) const
{
for (int i = 0; i < m_ActiveDownloads.size(); ++i) {
if (m_ActiveDownloads[i]->m_FileName == fileName) {
return i;
}
}
return -1;
}
void DownloadManager::nxmDownloadURLsAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID)
{
std::set<int>::iterator idIter = m_RequestIDs.find(requestID);
@@ -928,14 +981,14 @@ void DownloadManager::nxmDownloadURLsAvailable(int modID, int fileID, QVariant u
emit showMessage(tr("No download server available. Please try again later."));
return;
}
qSort(resultList.begin(), resultList.end(), ServerByPreference);
std::sort(resultList.begin(), resultList.end(), boost::bind(&DownloadManager::ServerByPreference, m_PreferredServers, _1, _2));
QStringList URLs;
foreach (const QVariant &server, resultList) {
URLs.append(server.toMap()["URI"].toString());
}
qDebug("urls: %s", qPrintable(URLs.join(";")));
addDownload(URLs, modID, fileID, info);
}
+30 -2
View File
@@ -70,7 +70,8 @@ public:
STATE_FETCHINGMODINFO,
STATE_FETCHINGFILEINFO,
STATE_READY,
STATE_INSTALLED
STATE_INSTALLED,
STATE_UNINSTALLED
};
private:
@@ -149,6 +150,11 @@ public:
**/
QString getOutputDirectory() const { return m_OutputDirectory; }
/**
* @brief setPreferredServers set the list of preferred servers
*/
void setPreferredServers(const std::map<QString, int> &preferredServers);
/**
* @brief set the list of supported extensions
* @param extensions list of supported extensions
@@ -250,6 +256,13 @@ public:
*/
void markInstalled(int index);
/**
* @brief mark a download as uninstalled
*
* @param index index of the file to mark uninstalled
*/
void markUninstalled(int index);
/**
* @brief refreshes the list of downloads
*/
@@ -261,13 +274,20 @@ public:
* @param RHS
* @return
*/
static bool ServerByPreference(const QVariant &LHS, const QVariant &RHS);
static bool ServerByPreference(const std::map<QString, int> &preferredServers, const QVariant &LHS, const QVariant &RHS);
virtual int startDownloadURLs(const QStringList &urls);
virtual int startDownloadNexusFile(int modID, int fileID);
virtual QString downloadPath(int id);
/**
* @brief retrieve a download index from the filename
* @param fileName file to look up
* @return index of that download or -1 if it wasn't found
*/
int indexByName(const QString &fileName) const;
signals:
void aboutToUpdate();
@@ -286,6 +306,13 @@ signals:
**/
void showMessage(const QString &message);
/**
* @brief emitted whenever the state of a download changes
* @param row the row that changed
* @param state the new state
*/
void stateChanged(int row, DownloadManager::DownloadState state);
public slots:
/**
@@ -371,6 +398,7 @@ private:
QVector<DownloadInfo*> m_ActiveDownloads;
QString m_OutputDirectory;
std::map<QString, int> m_PreferredServers;
QStringList m_SupportedExtensions;
std::set<int> m_RequestIDs;
QVector<int> m_AlphabeticalTranslation;
-24
View File
@@ -484,30 +484,6 @@ bool InstallationManager::testOverwrite(GuessedValue<QString> &modName) const
return true;
}
/*
bool InstallationManager::fixModName(QString &name)
{
QString temp = name.simplified();
while (temp.endsWith('.')) temp.chop(1);
temp.replace(QRegExp("[<>:\"/\\|?*]"), "");
static QString invalidNames[] = { "CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9",
"LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9" };
for (int i = 0; i < sizeof(invalidNames) / sizeof(QString); ++i) {
if (temp == invalidNames[i]) {
temp = "";
break;
}
}
if (temp.length() > 1) {
name = temp;
return true;
} else {
return false;
}
}
*/
bool InstallationManager::ensureValidModName(GuessedValue<QString> &name) const
{
+4 -1
View File
@@ -281,9 +281,12 @@ void registerMetaTypes()
int main(int argc, char *argv[])
{
MOApplication application(argc, argv);
qApp->addLibraryPath(application.applicationDirPath() + "/dlls");
SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
LogBuffer::init(20, QtDebugMsg, application.applicationDirPath().append("/logs/mo_interface.log"));
LogBuffer::init(20, QtDebugMsg, application.applicationDirPath() + "/logs/mo_interface.log");
qDebug("Working directory: %s", qPrintable(QDir::currentPath()));
qDebug("MO at: %s", qPrintable(application.applicationDirPath()));
+18 -3
View File
@@ -179,6 +179,7 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget
//ui->modList->setAcceptDrops(true);
ui->modList->header()->installEventFilter(&m_ModList);
ui->modList->header()->restoreState(initSettings.value("mod_list_state").toByteArray());
ui->modList->header()->setSectionHidden(0, false); // prevent the name-column from being hidden
ui->modList->installEventFilter(&m_ModList);
// restoreState also seems to restores the resize mode from previous session,
@@ -222,6 +223,7 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget
ui->linkButton->setMenu(linkMenu);
m_DownloadManager.setOutputDirectory(m_Settings.getDownloadDirectory());
m_DownloadManager.setPreferredServers(m_Settings.getPreferredServers());
NexusInterface::instance()->setCacheDirectory(m_Settings.getCacheDirectory());
NexusInterface::instance()->setNMMVersion(m_Settings.getNMMVersion());
@@ -239,6 +241,7 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget
connect(&m_ModList, SIGNAL(removeOrigin(QString)), this, SLOT(removeOrigin(QString)));
connect(&m_ModList, SIGNAL(showMessage(QString)), this, SLOT(showMessage(QString)));
connect(&m_ModList, SIGNAL(modRenamed(QString,QString)), this, SLOT(modRenamed(QString,QString)));
connect(&m_ModList, SIGNAL(modUninstalled(QString)), this, SLOT(modRemoved(QString)));
connect(&m_ModList, SIGNAL(modlist_changed(QModelIndex, int)), this, SLOT(modlistChanged(QModelIndex, int)));
connect(&m_ModList, SIGNAL(removeSelectedMods()), this, SLOT(removeMod_clicked()));
connect(&m_ModList, SIGNAL(requestColumnSelect(QPoint)), this, SLOT(displayColumnSelection(QPoint)));
@@ -2553,6 +2556,17 @@ void MainWindow::removeMod_clicked()
}
void MainWindow::modRemoved(const QString &fileName)
{
if (!fileName.isEmpty() && !QFileInfo(fileName).isAbsolute()) {
int index = m_DownloadManager.indexByName(fileName);
if (index >= 0) {
m_DownloadManager.markUninstalled(index);
}
}
}
void MainWindow::reinstallMod_clicked()
{
ModInfo::Ptr modInfo = ModInfo::getByIndex(m_ContextRow);
@@ -3417,6 +3431,7 @@ void MainWindow::on_actionSettings_triggered()
m_DownloadManager.setOutputDirectory(m_Settings.getDownloadDirectory());
}
}
m_DownloadManager.setPreferredServers(m_Settings.getPreferredServers());
if (m_Settings.getModDirectory() != oldModDirectory) {
refreshModList();
@@ -3551,9 +3566,9 @@ void MainWindow::installDownload(int index)
m_InstallationManager.setModsDirectory(m_Settings.getModDirectory());
if (m_InstallationManager.install(fileName, modName, hasIniTweaks)) {
MessageDialog::showMessage(tr("Installation successful"), this);
refreshModList();
QModelIndexList posList = m_ModList.match(m_ModList.index(0, 0), Qt::DisplayRole, static_cast<const QString&>(modName));
if (posList.count() == 1) {
ui->modList->scrollTo(posList.at(0));
@@ -4165,7 +4180,7 @@ void MainWindow::displayColumnSelection(const QPoint &pos)
// display a list of all headers as checkboxes
QAbstractItemModel *model = ui->modList->header()->model();
for (int i = 0; i < model->columnCount(); ++i) {
for (int i = 1; i < model->columnCount(); ++i) {
QString columnName = model->headerData(i, Qt::Horizontal).toString();
QCheckBox *checkBox = new QCheckBox(&menu);
checkBox->setText(columnName);
@@ -4177,7 +4192,7 @@ void MainWindow::displayColumnSelection(const QPoint &pos)
menu.exec(pos);
// view/hide columns depending on check-state
int i = 0;
int i = 1;
foreach (const QAction *action, menu.actions()) {
const QWidgetAction *widgetAction = qobject_cast<const QWidgetAction*>(action);
if (widgetAction != NULL) {
+1
View File
@@ -393,6 +393,7 @@ private slots:
void modOpenPrev();
void modRenamed(const QString &oldName, const QString &newName);
void modRemoved(const QString &fileName);
void hideSaveGameInfo();
+2
View File
@@ -642,6 +642,8 @@ void ModList::removeRowForce(int row)
if (wasEnabled) {
emit removeOrigin(modInfo->name());
}
emit modUninstalled(modInfo->getInstallationFile());
}
+6
View File
@@ -159,6 +159,12 @@ signals:
*/
void modRenamed(const QString &oldName, const QString &newName);
/**
* @brief emitted after a mod has been uninstalled
* @param fileName filename of the mod being uninstalled
*/
void modUninstalled(const QString &fileName);
/**
* @brief emitted whenever a row in the list has changed
*
-2
View File
@@ -268,14 +268,12 @@ OTHER_FILES += \
tutorials/firststeps.qml \
tutorials/tutorials.js \
tutorials/tutorial_firststeps_main.js \
tutorials/tutorial_firststeps_settings.js \
tutorials/tutorials_settingsdialog.qml \
tutorials/tutorials_mainwindow.qml \
tutorials/Highlight.qml \
tutorials/TutorialDescription.qml \
tutorials/TutorialOverlay.qml \
tutorials/tutorials_nexusdialog.qml \
tutorials/tutorial_firststeps_browser.js \
tutorials/tutorials_modinfodialog.qml \
tutorials/tutorial_firststeps_modinfo.js \
tutorials/tutorial_conflictresolution_main.js \
+4 -1
View File
@@ -35,6 +35,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QProcess>
#include <QApplication>
#include <util.h>
#include <boost/bind.hpp>
using namespace MOBase;
@@ -449,7 +450,9 @@ void SelfUpdater::nxmDownloadURLsAvailable(int, int, QVariant userData, QVariant
m_UpdateRequestID = -1;
QVariantList serverList = resultData.toList();
if (serverList.count() != 0) {
qSort(serverList.begin(), serverList.end(), DownloadManager::ServerByPreference);
std::map<QString, int> dummy;
qSort(serverList.begin(), serverList.end(), boost::bind(&DownloadManager::ServerByPreference, dummy, _1, _2));
QVariantMap dlServer = serverList.first().toMap();
+1
View File
@@ -0,0 +1 @@
#include "serverinfo.h"
+18
View File
@@ -0,0 +1,18 @@
#ifndef SERVERINFO_H
#define SERVERINFO_H
#include <QString>
#include <QDate>
#include <QMetaType>
struct ServerInfo
{
QString name;
bool premium;
QDate lastSeen;
bool preferred;
};
Q_DECLARE_METATYPE(ServerInfo)
#endif // SERVERINFO_H
+17
View File
@@ -153,6 +153,23 @@ QString Settings::getDownloadDirectory() const
return QDir::toNativeSeparators(m_Settings.value("Settings/download_directory", ToQString(GameInfo::instance().getDownloadDir())).toString());
}
std::map<QString, int> Settings::getPreferredServers()
{
std::map<QString, int> result;
m_Settings.beginGroup("Servers");
foreach (const QString &serverKey, m_Settings.childKeys()) {
QVariantMap data = m_Settings.value(serverKey).toMap();
int preference = data["preferred"].toInt();
if (preference > 0) {
result[serverKey] = preference;
}
}
m_Settings.endGroup();
return result;
}
QString Settings::getCacheDirectory() const
{
return QDir::toNativeSeparators(m_Settings.value("Settings/cache_directory", ToQString(GameInfo::instance().getCacheDir())).toString());

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