mirror of
https://github.com/ModOrganizer2/modorganizer.git
synced 2026-07-27 13:58:24 -07:00
Compare commits
11
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7a382eab75 | ||
|
|
8e6868bf88 | ||
|
|
a891146446 | ||
|
|
72f14df8a7 | ||
|
|
0fa7155eb8 | ||
|
|
c6c61ce792 | ||
|
|
ef801879ab | ||
|
|
1e6c5f7c25 | ||
|
|
49e1dd23b6 | ||
|
|
9c31cfa915 | ||
|
|
91dd38cb29 |
@@ -12,7 +12,8 @@ SUBDIRS = bsatk \
|
||||
plugins \
|
||||
proxydll \
|
||||
nxmhandler \
|
||||
BossDummy
|
||||
BossDummy \
|
||||
pythonRunner
|
||||
|
||||
hookdll.depends = shared
|
||||
organizer.depends = shared, uibase, plugins
|
||||
|
||||
@@ -46,6 +46,7 @@ public:
|
||||
static const int CATEGORY_SPECIAL_UPDATEAVAILABLE = 10002;
|
||||
static const int CATEGORY_SPECIAL_NOCATEGORY = 10003;
|
||||
static const int CATEGORY_SPECIAL_CONFLICT = 10004;
|
||||
static const int CATEGORY_SPECIAL_NOTENDORSED = 10005;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@@ -60,8 +60,8 @@ QVariant DownloadList::headerData(int section, Qt::Orientation orientation, int
|
||||
if ((role == Qt::DisplayRole) &&
|
||||
(orientation == Qt::Horizontal)) {
|
||||
switch (section) {
|
||||
case 0: return tr("Name");
|
||||
case 1: return tr("Filetime");
|
||||
case COL_NAME: return tr("Name");
|
||||
case COL_FILETIME: return tr("Filetime");
|
||||
default: return tr("Done");
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -34,6 +34,14 @@ class DownloadList : public QAbstractTableModel
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
enum EColumn {
|
||||
COL_NAME = 0,
|
||||
COL_FILETIME,
|
||||
COL_STATUS
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,6 +18,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "downloadlistsortproxy.h"
|
||||
#include "downloadlist.h"
|
||||
|
||||
DownloadListSortProxy::DownloadListSortProxy(const DownloadManager *manager, QObject *parent)
|
||||
: QSortFilterProxyModel(parent), m_Manager(manager), m_CurrentFilter()
|
||||
@@ -30,18 +31,21 @@ void DownloadListSortProxy::updateFilter(const QString &filter)
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
|
||||
bool DownloadListSortProxy::lessThan(const QModelIndex &left,
|
||||
const QModelIndex &right) const
|
||||
{
|
||||
int leftIndex = sourceModel()->data(left).toInt();
|
||||
int rightIndex = sourceModel()->data(right).toInt();
|
||||
|
||||
if (left.column() == 0) {
|
||||
if (left.column() == DownloadList::COL_NAME) {
|
||||
return m_Manager->getFileName(leftIndex).compare(m_Manager->getFileName(rightIndex), Qt::CaseInsensitive) < 0;
|
||||
} else if (left.column() == 1) {
|
||||
return leftIndex < rightIndex;
|
||||
} else {
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ DownloadManager::DownloadInfo *DownloadManager::DownloadInfo::createNew(const Ne
|
||||
DownloadInfo *info = new DownloadInfo;
|
||||
info->m_DownloadID = s_NextDownloadID++;
|
||||
info->m_StartTime.start();
|
||||
info->m_PreResumeSize = 0LL;
|
||||
info->m_Progress = 0;
|
||||
info->m_ResumePos = 0;
|
||||
info->m_ModID = modID;
|
||||
@@ -98,6 +99,7 @@ DownloadManager::DownloadInfo *DownloadManager::DownloadInfo::createFromMeta(con
|
||||
info->m_DownloadID = s_NextDownloadID++;
|
||||
info->m_Output.setFileName(filePath);
|
||||
info->m_TotalSize = QFileInfo(filePath).size();
|
||||
info->m_PreResumeSize = info->m_TotalSize;
|
||||
info->m_ModID = metaFile.value("modID", 0).toInt();
|
||||
info->m_FileID = metaFile.value("fileID", 0).toInt();
|
||||
info->m_CurrentUrl = 0;
|
||||
@@ -283,6 +285,7 @@ bool DownloadManager::addDownload(const QStringList &URLs,
|
||||
return addDownload(m_NexusInterface->getAccessManager()->get(request), URLs, fileName, modID, fileID, nexusInfo);
|
||||
}
|
||||
|
||||
|
||||
bool DownloadManager::addDownload(QNetworkReply *reply, const QStringList &URLs, const QString &fileName,
|
||||
int modID, int fileID, const NexusInfo &nexusInfo)
|
||||
{
|
||||
@@ -331,6 +334,8 @@ void DownloadManager::startDownload(QNetworkReply *reply, DownloadInfo *newDownl
|
||||
mode |= QIODevice::Append;
|
||||
}
|
||||
|
||||
newDownload->m_StartTime.start();
|
||||
|
||||
if (!newDownload->m_Output.open(mode)) {
|
||||
reportError(tr("failed to download %1: could not open output file: %2")
|
||||
.arg(reply->url().toString()).arg(newDownload->m_Output.fileName()));
|
||||
@@ -343,6 +348,8 @@ void DownloadManager::startDownload(QNetworkReply *reply, DownloadInfo *newDownl
|
||||
connect(newDownload->m_Reply, SIGNAL(metaDataChanged()), this, SLOT(metaDataChanged()));
|
||||
|
||||
if (!resume) {
|
||||
newDownload->m_PreResumeSize = newDownload->m_Output.size();
|
||||
|
||||
emit aboutToUpdate();
|
||||
|
||||
m_ActiveDownloads.append(newDownload);
|
||||
@@ -597,6 +604,20 @@ QString DownloadManager::getFileName(int index) const
|
||||
return m_ActiveDownloads.at(index)->m_FileName;
|
||||
}
|
||||
|
||||
QDateTime DownloadManager::getFileTime(int index) const
|
||||
{
|
||||
if ((index < 0) || (index >= m_ActiveDownloads.size())) {
|
||||
throw MyException(tr("invalid index"));
|
||||
}
|
||||
|
||||
DownloadInfo *info = m_ActiveDownloads.at(index);
|
||||
if (!info->m_Created.isValid()) {
|
||||
info->m_Created = QFileInfo(info->m_Output).created();
|
||||
}
|
||||
|
||||
return info->m_Created;
|
||||
}
|
||||
|
||||
qint64 DownloadManager::getFileSize(int index) const
|
||||
{
|
||||
if ((index < 0) || (index >= m_ActiveDownloads.size())) {
|
||||
@@ -1034,6 +1055,8 @@ void DownloadManager::nxmDownloadURLsAvailable(int modID, int fileID, QVariant u
|
||||
|
||||
std::sort(resultList.begin(), resultList.end(), boost::bind(&DownloadManager::ServerByPreference, m_PreferredServers, _1, _2));
|
||||
|
||||
info.m_DownloadMap = resultList;
|
||||
|
||||
QStringList URLs;
|
||||
|
||||
foreach (const QVariant &server, resultList) {
|
||||
@@ -1121,6 +1144,19 @@ void DownloadManager::downloadFinished()
|
||||
createMetaFile(info);
|
||||
emit update(index);
|
||||
} else {
|
||||
|
||||
QString url = info->m_Urls[info->m_CurrentUrl];
|
||||
foreach (const QVariant &server, info->m_NexusInfo.m_DownloadMap) {
|
||||
QVariantMap serverMap = server.toMap();
|
||||
if (serverMap["URI"].toString() == url) {
|
||||
int deltaTime = info->m_StartTime.secsTo(QTime::currentTime());
|
||||
if (deltaTime > 5) {
|
||||
emit downloadSpeed(serverMap["Name"].toString(), (info->m_TotalSize - info->m_PreResumeSize) / deltaTime);
|
||||
} // no division by zero please! Also, if the download is shorter than a few seconds, the result is way to inprecise
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
setState(info, STATE_FETCHINGMODINFO); // need to set this state before changing the file name, otherwise .unfinished is appended
|
||||
|
||||
QString newName = getFileNameFromNetworkReply(reply);
|
||||
|
||||
@@ -45,6 +45,7 @@ struct NexusInfo {
|
||||
QString m_Version;
|
||||
QString m_NewestVersion;
|
||||
QString m_FileName;
|
||||
QVariantList m_DownloadMap;
|
||||
bool m_Set;
|
||||
};
|
||||
Q_DECLARE_METATYPE(NexusInfo)
|
||||
@@ -82,6 +83,7 @@ private:
|
||||
QFile m_Output;
|
||||
QNetworkReply *m_Reply;
|
||||
QTime m_StartTime;
|
||||
qint64 m_PreResumeSize;
|
||||
int m_Progress;
|
||||
int m_ModID;
|
||||
int m_FileID;
|
||||
@@ -90,6 +92,9 @@ private:
|
||||
QStringList m_Urls;
|
||||
qint64 m_ResumePos;
|
||||
qint64 m_TotalSize;
|
||||
|
||||
QDateTime m_Created; // used as a cache in DownloadManager::getFileTime, may not be valid elsewhere
|
||||
|
||||
int m_Tries;
|
||||
bool m_ReQueried;
|
||||
|
||||
@@ -214,6 +219,13 @@ public:
|
||||
*/
|
||||
qint64 getFileSize(int index) const;
|
||||
|
||||
/**
|
||||
* @brief retrieve the creation time of the download specified by index
|
||||
* @param index index of the file to look up
|
||||
* @return size of the file (total size during download)
|
||||
*/
|
||||
QDateTime getFileTime(int index) const;
|
||||
|
||||
/**
|
||||
* @brief retrieve the current progress of the download specified by index
|
||||
*
|
||||
@@ -297,6 +309,7 @@ public:
|
||||
int indexByName(const QString &fileName) const;
|
||||
|
||||
void pauseAll();
|
||||
|
||||
signals:
|
||||
|
||||
void aboutToUpdate();
|
||||
@@ -322,6 +335,11 @@ signals:
|
||||
*/
|
||||
void stateChanged(int row, DownloadManager::DownloadState state);
|
||||
|
||||
/**
|
||||
* @brief emitted whenever a download completes successfully, reporting the download speed for the server used
|
||||
*/
|
||||
void downloadSpeed(const QString &serverName, int bytesPerSecond);
|
||||
|
||||
public slots:
|
||||
|
||||
/**
|
||||
|
||||
+29
-12
@@ -114,7 +114,8 @@ void InstallationManager::mapToArchive(const DirectoryTree::Node *node, std::wst
|
||||
for (DirectoryTree::const_node_iterator iter = node->nodesBegin(); iter != node->nodesEnd(); ++iter) {
|
||||
if ((*iter)->getData().index != -1) {
|
||||
data[(*iter)->getData().index]->setSkip(false);
|
||||
data[(*iter)->getData().index]->setOutputFileName(path.substr().append(ToWString((*iter)->getData().name)).c_str());
|
||||
std::wstring temp = path.substr().append(ToWString((*iter)->getData().name));
|
||||
data[(*iter)->getData().index]->setOutputFileName(temp.c_str());
|
||||
}
|
||||
mapToArchive(*iter, path.substr().append(ToWString((*iter)->getData().name)), data);
|
||||
}
|
||||
@@ -206,7 +207,7 @@ QString canonicalize(const QString &name)
|
||||
}
|
||||
|
||||
|
||||
QStringList InstallationManager::extractFiles(const QStringList &filesOrig)
|
||||
QStringList InstallationManager::extractFiles(const QStringList &filesOrig, bool flatten)
|
||||
{
|
||||
QStringList files;
|
||||
|
||||
@@ -222,20 +223,26 @@ QStringList InstallationManager::extractFiles(const QStringList &filesOrig)
|
||||
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
if (files.contains(ToQString(data[i]->getFileName()), Qt::CaseInsensitive)) {
|
||||
const wchar_t *baseName = wcsrchr(data[i]->getFileName(), '\\');
|
||||
if (baseName == NULL) {
|
||||
baseName = wcsrchr(data[i]->getFileName(), '/');
|
||||
const wchar_t *targetFile = data[i]->getFileName();
|
||||
if (flatten) {
|
||||
targetFile = wcsrchr(data[i]->getFileName(), '\\');
|
||||
if (targetFile == NULL) {
|
||||
targetFile = wcsrchr(data[i]->getFileName(), '/');
|
||||
}
|
||||
if (targetFile == NULL) {
|
||||
qCritical("failed to find backslash in %ls", data[i]->getFileName());
|
||||
continue;
|
||||
} else {
|
||||
// skip the slash
|
||||
++targetFile;
|
||||
}
|
||||
}
|
||||
if (baseName == NULL) {
|
||||
qCritical("failed to find backslash in %ls", data[i]->getFileName());
|
||||
continue;
|
||||
}
|
||||
data[i]->setOutputFileName(baseName);
|
||||
data[i]->setOutputFileName(targetFile);
|
||||
|
||||
result.append(QDir::tempPath().append("/").append(ToQString(baseName)));
|
||||
result.append(QDir::tempPath().append("/").append(ToQString(targetFile)));
|
||||
|
||||
data[i]->setSkip(false);
|
||||
m_TempFilesToDelete.insert(ToQString(baseName));
|
||||
m_TempFilesToDelete.insert(ToQString(targetFile));
|
||||
} else {
|
||||
data[i]->setSkip(true);
|
||||
}
|
||||
@@ -252,6 +259,7 @@ QStringList InstallationManager::extractFiles(const QStringList &filesOrig)
|
||||
new MethodCallback<InstallationManager, void, float>(this, &InstallationManager::updateProgress),
|
||||
new MethodCallback<InstallationManager, void, LPCWSTR>(this, &InstallationManager::dummyProgressFile),
|
||||
new MethodCallback<InstallationManager, void, LPCWSTR>(this, &InstallationManager::report7ZipError))) {
|
||||
m_InstallationProgress.hide();
|
||||
throw std::runtime_error("extracting failed");
|
||||
}
|
||||
|
||||
@@ -401,6 +409,7 @@ void InstallationManager::report7ZipError(LPCWSTR errorMessage)
|
||||
#else
|
||||
reportError(QString::fromUtf16(errorMessage));
|
||||
#endif
|
||||
m_CurrentArchive->cancel();
|
||||
}
|
||||
|
||||
|
||||
@@ -527,6 +536,7 @@ bool InstallationManager::doInstall(GuessedValue<QString> &modName, int modID,
|
||||
new MethodCallback<InstallationManager, void, float>(this, &InstallationManager::updateProgress),
|
||||
new MethodCallback<InstallationManager, void, LPCWSTR>(this, &InstallationManager::updateProgressFile),
|
||||
new MethodCallback<InstallationManager, void, LPCWSTR>(this, &InstallationManager::report7ZipError))) {
|
||||
m_InstallationProgress.hide();
|
||||
if (m_CurrentArchive->getLastError() == Archive::ERROR_EXTRACT_CANCELLED) {
|
||||
return false;
|
||||
} else {
|
||||
@@ -716,6 +726,13 @@ bool InstallationManager::install(const QString &fileName, GuessedValue<QString>
|
||||
qPrintable(installer->name()), e.what());
|
||||
}
|
||||
|
||||
// clean up temp files
|
||||
// TODO: this doesn't yet remove directories. Also, the files may be left there if this point isn't reached
|
||||
foreach (const QString &tempFile, m_TempFilesToDelete) {
|
||||
QFile::remove(QDir::tempPath() + "/" + tempFile);
|
||||
}
|
||||
|
||||
|
||||
// act upon the installation result. at this point the files have already been
|
||||
// extracted to the correct location
|
||||
switch (installResult) {
|
||||
|
||||
@@ -114,7 +114,7 @@ public:
|
||||
* @note the temporary file is automatically cleaned up after the installation
|
||||
* @note This call can be very slow if the archive is large and "solid"
|
||||
*/
|
||||
virtual QStringList extractFiles(const QStringList &files);
|
||||
virtual QStringList extractFiles(const QStringList &files, bool flatten);
|
||||
|
||||
/**
|
||||
* @brief installs an archive
|
||||
|
||||
+6
-15
@@ -182,16 +182,7 @@ void cleanupDir()
|
||||
"QtXml4.dll",
|
||||
"QtWebKit4.dll",
|
||||
"qjpeg4.dll",
|
||||
/* "dlls/phonon4.dll",
|
||||
"dlls/QtCore4.dll",
|
||||
"dlls/QtGui4.dll",
|
||||
"dlls/QtNetwork4.dll",
|
||||
"dlls/QtXml4.dll",
|
||||
"dlls/QtXmlPatterns4.dll",
|
||||
"dlls/QtWebKit4.dll",
|
||||
"dlls/QtDeclarative4.dll",
|
||||
"dlls/QtScript4.dll",
|
||||
"dlls/QtSql4.dll"*/
|
||||
"NCC/GamebryoBase.dll"
|
||||
};
|
||||
|
||||
static const int NUM_FILES = sizeof(fileNames) / sizeof(QString);
|
||||
@@ -283,15 +274,15 @@ void registerMetaTypes()
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
MOApplication application(argc, argv);
|
||||
qApp->addLibraryPath(application.applicationDirPath() + "/dlls");
|
||||
|
||||
application.addLibraryPath(application.applicationDirPath() + "/dlls");
|
||||
|
||||
SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
|
||||
|
||||
LogBuffer::init(20, QtDebugMsg, application.applicationDirPath() + "/logs/mo_interface.log");
|
||||
|
||||
qDebug("Working directory: %s", qPrintable(QDir::currentPath()));
|
||||
qDebug("MO at: %s", qPrintable(application.applicationDirPath()));
|
||||
qDebug("user name: %s", getenv("USERNAME"));
|
||||
qDebug("Working directory: %s", qPrintable(QDir::toNativeSeparators(QDir::currentPath())));
|
||||
qDebug("MO at: %s", qPrintable(QDir::toNativeSeparators(application.applicationDirPath())));
|
||||
QPixmap pixmap(":/MO/gui/splash");
|
||||
QSplashScreen splash(pixmap);
|
||||
splash.show();
|
||||
@@ -404,7 +395,7 @@ int main(int argc, char *argv[])
|
||||
settings.setValue("gamePath", gamePath.toUtf8().constData());
|
||||
}
|
||||
|
||||
qDebug("managing game at %s", qPrintable(gamePath));
|
||||
qDebug("managing game at %s", qPrintable(QDir::toNativeSeparators(gamePath)));
|
||||
|
||||
ExecutablesList executablesList;
|
||||
|
||||
|
||||
+33
-7
@@ -104,6 +104,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "modeltest.h"
|
||||
#endif // TEST_MODELS
|
||||
|
||||
#pragma warning( disable : 4428 )
|
||||
|
||||
using namespace MOBase;
|
||||
using namespace MOShared;
|
||||
@@ -218,6 +219,7 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget
|
||||
ui->savegameList->setMouseTracking(true);
|
||||
|
||||
connect(&m_DownloadManager, SIGNAL(showMessage(QString)), this, SLOT(showMessage(QString)));
|
||||
connect(&m_DownloadManager, SIGNAL(downloadSpeed(QString,int)), this, SLOT(downloadSpeed(QString,int)));
|
||||
|
||||
connect(ui->savegameList, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(saveSelectionChanged(QListWidgetItem*)));
|
||||
|
||||
@@ -1035,7 +1037,7 @@ void MainWindow::loadPlugins()
|
||||
}
|
||||
|
||||
QString pluginPath = QDir::fromNativeSeparators(ToQString(GameInfo::instance().getOrganizerDirectory())) + "/" + ToQString(AppConfig::pluginPath());
|
||||
qDebug("looking for plugins in %s", pluginPath.toUtf8().constData());
|
||||
qDebug("looking for plugins in %s", QDir::toNativeSeparators(pluginPath).toUtf8().constData());
|
||||
QDirIterator iter(pluginPath, QDir::Files | QDir::NoDotAndDotDot);
|
||||
while (iter.hasNext()) {
|
||||
iter.next();
|
||||
@@ -2590,6 +2592,7 @@ void MainWindow::refreshFilters()
|
||||
addFilterItem(NULL, tr("<Update>"), CategoryFactory::CATEGORY_SPECIAL_UPDATEAVAILABLE);
|
||||
addFilterItem(NULL, tr("<No category>"), CategoryFactory::CATEGORY_SPECIAL_NOCATEGORY);
|
||||
addFilterItem(NULL, tr("<Conflicted>"), CategoryFactory::CATEGORY_SPECIAL_CONFLICT);
|
||||
addFilterItem(NULL, tr("<Not Endorsed>"), CategoryFactory::CATEGORY_SPECIAL_NOTENDORSED);
|
||||
|
||||
std::set<int> categoriesUsed;
|
||||
for (unsigned int modIdx = 0; modIdx < ModInfo::getNumMods(); ++modIdx) {
|
||||
@@ -3016,6 +3019,9 @@ void MainWindow::createModFromOverwrite()
|
||||
}
|
||||
|
||||
IModInterface *newMod = createMod(name);
|
||||
if (newMod == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ModInfo::Ptr overwriteInfo = ModInfo::getByIndex(m_ContextRow);
|
||||
|
||||
@@ -3306,6 +3312,17 @@ void MainWindow::exportModListCSV()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void addMenuAsPushButton(QMenu *menu, QMenu *subMenu)
|
||||
{
|
||||
QPushButton *pushBtn = new QPushButton(subMenu->title());
|
||||
pushBtn->setMenu(subMenu);
|
||||
QWidgetAction *action = new QWidgetAction(menu);
|
||||
action->setDefaultWidget(pushBtn);
|
||||
menu->addAction(action);
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos)
|
||||
{
|
||||
try {
|
||||
@@ -3314,6 +3331,7 @@ void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos)
|
||||
m_ContextRow = mapToModel(&m_ModList, modList->indexAt(pos)).row();
|
||||
|
||||
QMenu menu;
|
||||
|
||||
menu.addAction(tr("Install Mod..."), this, SLOT(installMod_clicked()));
|
||||
|
||||
menu.addAction(tr("Enable all visible"), this, SLOT(enableVisibleMods()));
|
||||
@@ -3338,13 +3356,16 @@ void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos)
|
||||
menu.addAction(tr("Restore Backup"), this, SLOT(restoreBackup_clicked()));
|
||||
menu.addAction(tr("Remove Backup..."), this, SLOT(removeMod_clicked()));
|
||||
} else {
|
||||
QMenu *addCategoryMenu = menu.addMenu(tr("Set Category"));
|
||||
// Set categories is a separate menu connected to a push button. This way it doesn't simply close every time you hover the mouse outside
|
||||
QMenu *addCategoryMenu = new QMenu(tr("Set Category"));
|
||||
addCategories(addCategoryMenu, 0);
|
||||
connect(addCategoryMenu, SIGNAL(aboutToHide()), this, SLOT(saveCategories()));
|
||||
addMenuAsPushButton(&menu, addCategoryMenu);
|
||||
|
||||
QMenu *primaryCategoryMenu = menu.addMenu(tr("Primary Category"));
|
||||
QMenu *primaryCategoryMenu = new QMenu(tr("Primary Category"));
|
||||
connect(primaryCategoryMenu, SIGNAL(aboutToShow()), this, SLOT(addPrimaryCategoryCandidates()));
|
||||
connect(primaryCategoryMenu, SIGNAL(aboutToHide()), this, SLOT(savePrimaryCategory()));
|
||||
addMenuAsPushButton(&menu, primaryCategoryMenu);
|
||||
|
||||
menu.addAction(tr("Rename Mod..."), this, SLOT(renameMod_clicked()));
|
||||
menu.addAction(tr("Remove Mod..."), this, SLOT(removeMod_clicked()));
|
||||
@@ -3592,6 +3613,12 @@ void MainWindow::linkMenu()
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::downloadSpeed(const QString &serverName, int bytesPerSecond)
|
||||
{
|
||||
m_Settings.setDownloadSpeed(serverName, bytesPerSecond);
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_actionSettings_triggered()
|
||||
{
|
||||
QString oldModDirectory(m_Settings.getModDirectory());
|
||||
@@ -4098,7 +4125,6 @@ void MainWindow::updateDownloadListDelegate()
|
||||
ui->downloadView->setModel(sortProxy);
|
||||
ui->downloadView->sortByColumn(1, Qt::AscendingOrder);
|
||||
ui->downloadView->header()->resizeSections(QHeaderView::Fixed);
|
||||
// ui->downloadView->setFirstColumnSpanned(0, QModelIndex(), true);
|
||||
|
||||
connect(ui->downloadView->itemDelegate(), SIGNAL(installDownload(int)), this, SLOT(installDownload(int)));
|
||||
connect(ui->downloadView->itemDelegate(), SIGNAL(queryInfo(int)), &m_DownloadManager, SLOT(queryInfo(int)));
|
||||
@@ -4136,7 +4162,6 @@ void MainWindow::modDetailsUpdated(bool)
|
||||
void MainWindow::nxmUpdatesAvailable(const std::vector<int> &modIDs, QVariant userData, QVariant resultData, int)
|
||||
{
|
||||
m_ModsToUpdate -= modIDs.size();
|
||||
|
||||
QVariantList resultList = resultData.toList();
|
||||
for (auto iter = resultList.begin(); iter != resultList.end(); ++iter) {
|
||||
QVariantMap result = iter->toMap();
|
||||
@@ -4149,8 +4174,9 @@ void MainWindow::nxmUpdatesAvailable(const std::vector<int> &modIDs, QVariant us
|
||||
for (auto iter = info.begin(); iter != info.end(); ++iter) {
|
||||
(*iter)->setNewestVersion(VersionInfo(result["version"].toString()));
|
||||
(*iter)->setNexusDescription(result["description"].toString());
|
||||
if (NexusInterface::instance()->getAccessManager()->loggedIn()) {
|
||||
// don't use endorsement info if we're not logged in
|
||||
if (NexusInterface::instance()->getAccessManager()->loggedIn() &&
|
||||
result.contains("voted_by_user")) {
|
||||
// don't use endorsement info if we're not logged in or if the response doesn't contain it
|
||||
(*iter)->setIsEndorsed(result["voted_by_user"].toBool());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -452,6 +452,8 @@ private slots:
|
||||
*/
|
||||
void allowListResize();
|
||||
|
||||
void downloadSpeed(const QString &serverName, int bytesPerSecond);
|
||||
|
||||
private slots: // ui slots
|
||||
// actions
|
||||
void on_actionAdd_Profile_triggered();
|
||||
|
||||
+58
-7
@@ -31,7 +31,16 @@
|
||||
<property name="spacing">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
@@ -721,7 +730,16 @@ p, li { white-space: pre-wrap; }
|
||||
<string notr="true">Archives</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_9">
|
||||
<property name="margin">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
@@ -800,7 +818,16 @@ BSAs checked here are loaded in such a way that your installation order is obeye
|
||||
<string>Data</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<property name="margin">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
@@ -870,7 +897,16 @@ BSAs checked here are loaded in such a way that your installation order is obeye
|
||||
<string>Saves</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="margin">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
@@ -899,7 +935,16 @@ p, li { white-space: pre-wrap; }
|
||||
<string>Downloads</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<property name="margin">
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
@@ -927,8 +972,14 @@ p, li { white-space: pre-wrap; }
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
<property name="dragEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::DragDrop</enum>
|
||||
</property>
|
||||
<property name="defaultDropAction">
|
||||
<enum>Qt::MoveAction</enum>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
|
||||
+1
-1
@@ -410,7 +410,7 @@ void ModInfoRegular::nxmDescriptionAvailable(int, QVariant, QVariant resultData)
|
||||
QVariantMap result = resultData.toMap();
|
||||
m_NewestVersion.parse(result["version"].toString());
|
||||
m_NexusDescription = result["description"].toString();
|
||||
if (m_EndorsedState != ENDORSED_NEVER) {
|
||||
if ((m_EndorsedState != ENDORSED_NEVER) && (result.contains("voted_by_user"))) {
|
||||
m_EndorsedState = result["voted_by_user"].toBool() ? ENDORSED_TRUE : ENDORSED_FALSE;
|
||||
}
|
||||
m_LastNexusQuery = QDateTime::currentDateTime();
|
||||
|
||||
+1
-1
@@ -809,7 +809,7 @@ public:
|
||||
virtual void setNeverEndorse() {}
|
||||
virtual bool remove() { return false; }
|
||||
virtual void endorse(bool) {}
|
||||
virtual QString name() const { return tr("Overwrite"); }
|
||||
virtual QString name() const { return "Overwrite"; }
|
||||
virtual QString notes() const { return ""; }
|
||||
virtual QDateTime creationTime() const { return QDateTime::currentDateTime(); }
|
||||
virtual QString absolutePath() const;
|
||||
|
||||
+2
-2
@@ -91,7 +91,7 @@ QVariant ModList::getOverwriteData(int column, int role) const
|
||||
switch (role) {
|
||||
case Qt::DisplayRole: {
|
||||
if (column == 0) {
|
||||
return tr("Overwrite");
|
||||
return "Overwrite";
|
||||
} else {
|
||||
return QVariant();
|
||||
}
|
||||
@@ -747,7 +747,7 @@ bool ModList::eventFilter(QObject *obj, QEvent *event)
|
||||
if (event->type() == QEvent::ContextMenu) {
|
||||
QContextMenuEvent *contextEvent = static_cast<QContextMenuEvent*>(event);
|
||||
QWidget *object = qobject_cast<QWidget*>(obj);
|
||||
if (object != NULL) {
|
||||
if ((object != NULL) && (contextEvent->reason() == QContextMenuEvent::Mouse)) {
|
||||
emit requestColumnSelect(object->mapToGlobal(contextEvent->pos()));
|
||||
|
||||
return true;
|
||||
|
||||
@@ -164,6 +164,9 @@ bool ModListSortProxy::lessThan(const QModelIndex &left,
|
||||
|
||||
return leftPrio.toInt() < rightPrio.toInt();
|
||||
} break;
|
||||
case ModList::COL_INSTALLTIME: {
|
||||
return left.data().toDateTime() < right.data().toDateTime();
|
||||
} break;
|
||||
}
|
||||
return lt;
|
||||
}
|
||||
@@ -216,6 +219,10 @@ bool ModListSortProxy::filterMatches(ModInfo::Ptr info, bool enabled) const
|
||||
case CategoryFactory::CATEGORY_SPECIAL_CONFLICT: {
|
||||
if (!hasConflictFlag(info->getFlags())) return false;
|
||||
} break;
|
||||
case CategoryFactory::CATEGORY_SPECIAL_NOTENDORSED: {
|
||||
ModInfo::EEndorsedState state = info->endorsedState();
|
||||
return (state == ModInfo::ENDORSED_FALSE) || (state == ModInfo::ENDORSED_NEVER);
|
||||
} break;
|
||||
default: {
|
||||
if (!info->categorySet(*iter)) return false;
|
||||
} break;
|
||||
|
||||
@@ -23,10 +23,12 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "utility.h"
|
||||
#include "selfupdater.h"
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QNetworkProxy>
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkCookie>
|
||||
#include <QNetworkCookieJar>
|
||||
#include <QCoreApplication>
|
||||
#include <gameinfo.h>
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
@@ -38,7 +40,7 @@ using namespace MOShared;
|
||||
|
||||
|
||||
NXMAccessManager::NXMAccessManager(QObject *parent)
|
||||
: QNetworkAccessManager(parent), m_LoginReply(NULL)
|
||||
: QNetworkAccessManager(parent), m_LoginReply(NULL), m_ProgressDialog()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -117,8 +119,13 @@ void NXMAccessManager::pageLogin()
|
||||
postDataQuery = postData.encodedQuery();
|
||||
#endif
|
||||
|
||||
m_LoginReply = post(request, postDataQuery);
|
||||
m_ProgressDialog.setLabelText(tr("Logging into Nexus"));
|
||||
QList<QPushButton*> buttons = m_ProgressDialog.findChildren<QPushButton*>();
|
||||
buttons.at(0)->setEnabled(false);
|
||||
m_ProgressDialog.show();
|
||||
QCoreApplication::processEvents(); // for some reason the whole app hangs during the login. This way the user has at least a little feedback
|
||||
|
||||
m_LoginReply = post(request, postDataQuery);
|
||||
m_LoginTimeout.start();
|
||||
connect(m_LoginReply, SIGNAL(finished()), this, SLOT(loginFinished()));
|
||||
connect(m_LoginReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(loginError(QNetworkReply::NetworkError)));
|
||||
@@ -138,6 +145,7 @@ void NXMAccessManager::loginTimeout()
|
||||
|
||||
void NXMAccessManager::loginError(QNetworkReply::NetworkError)
|
||||
{
|
||||
m_ProgressDialog.hide();
|
||||
emit loginFailed(m_LoginReply->errorString());
|
||||
m_LoginTimeout.stop();
|
||||
m_LoginReply->deleteLater();
|
||||
@@ -162,6 +170,7 @@ bool NXMAccessManager::hasLoginCookies() const
|
||||
|
||||
void NXMAccessManager::loginFinished()
|
||||
{
|
||||
m_ProgressDialog.hide();
|
||||
if (hasLoginCookies()) {
|
||||
emit loginSuccessful(true);
|
||||
} else {
|
||||
|
||||
@@ -24,6 +24,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QTimer>
|
||||
#include <QNetworkReply>
|
||||
#include <QProgressDialog>
|
||||
|
||||
|
||||
/**
|
||||
@@ -85,6 +86,7 @@ private:
|
||||
|
||||
QTimer m_LoginTimeout;
|
||||
QNetworkReply *m_LoginReply;
|
||||
QProgressDialog m_ProgressDialog;
|
||||
|
||||
QString m_Username;
|
||||
QString m_Password;
|
||||
|
||||
+382
-353
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user