From 853c95b921f4fc3beb8daf71d79b44aa1ab06c92 Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Mon, 10 Jun 2019 16:43:39 -0400
Subject: added new statusbar class, moved refresh progress bar to it
---
src/CMakeLists.txt | 3 +++
src/mainwindow.cpp | 20 ++++----------------
src/mainwindow.h | 5 +++--
src/statusbar.cpp | 27 +++++++++++++++++++++++++++
src/statusbar.h | 20 ++++++++++++++++++++
5 files changed, 57 insertions(+), 18 deletions(-)
create mode 100644 src/statusbar.cpp
create mode 100644 src/statusbar.h
(limited to 'src')
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 93597d62..71f87a8a 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -116,6 +116,7 @@ SET(organizer_SRCS
forcedloaddialog.cpp
forcedloaddialogwidget.cpp
filterwidget.cpp
+ statusbar.cpp
shared/windows_error.cpp
shared/error_report.cpp
@@ -213,6 +214,7 @@ SET(organizer_HDRS
forcedloaddialog.h
forcedloaddialogwidget.h
filterwidget.h
+ statusbar.h
shared/windows_error.h
shared/error_report.h
@@ -277,6 +279,7 @@ set(application
moshortcut
selfupdater
singleinstance
+ statusbar
)
set(browser
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 911d0ff1..67d0f2ff 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -77,6 +77,7 @@ along with Mod Organizer. If not, see .
#include "nxmaccessmanager.h"
#include "appconfig.h"
#include "eventfilter.h"
+#include "statusbar.h"
#include
#include
#include
@@ -242,13 +243,7 @@ MainWindow::MainWindow(QSettings &initSettings
connect(ui->logList->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
ui->logList, SLOT(scrollToBottom()));
- m_RefreshProgress = new QProgressBar(statusBar());
- m_RefreshProgress->setTextVisible(true);
- m_RefreshProgress->setRange(0, 100);
- m_RefreshProgress->setValue(0);
- m_RefreshProgress->setVisible(false);
- statusBar()->addWidget(m_RefreshProgress, 1000);
- statusBar()->clearMessage();
+ m_statusBar.reset(new StatusBar(statusBar()));
updateProblemsButton();
@@ -2534,15 +2529,8 @@ void MainWindow::setESPListSorting(int index)
void MainWindow::refresher_progress(int percent)
{
- if (percent == 100) {
- m_RefreshProgress->setVisible(false);
- this->setEnabled(true);
- } else if (!m_RefreshProgress->isVisible()) {
- this->setEnabled(false);
- m_RefreshProgress->setVisible(true);
- m_RefreshProgress->setRange(0, 100);
- m_RefreshProgress->setValue(percent);
- }
+ setEnabled(percent == 100);
+ m_statusBar->setProgress(percent);
}
void MainWindow::directory_refreshed()
diff --git a/src/mainwindow.h b/src/mainwindow.h
index b8d9f49f..734ece88 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -37,6 +37,7 @@ struct Executable;
class CategoryFactory;
class LockedDialogBase;
class OrganizerCore;
+class StatusBar;
#include "plugincontainer.h" //class PluginContainer;
class PluginListSortProxy;
namespace BSA { class Archive; }
@@ -75,7 +76,6 @@ class QListWidgetItem;
class QMenu;
class QModelIndex;
class QPoint;
-class QProgressBar;
class QProgressDialog;
class QTranslator;
class QTreeWidgetItem;
@@ -329,6 +329,8 @@ private:
// the window is closed and the menubar is hidden
bool m_menuBarVisible;
+ std::unique_ptr m_statusBar;
+
// last separator on the toolbar, used to add spacer for right-alignment and
// as an insert point for executables
QAction* m_linksSeparator;
@@ -338,7 +340,6 @@ private:
int m_OldProfileIndex;
std::vector m_ModNameList; // the mod-list to go with the directory structure
- QProgressBar *m_RefreshProgress;
bool m_Refreshing;
QStringList m_DefaultArchives;
diff --git a/src/statusbar.cpp b/src/statusbar.cpp
new file mode 100644
index 00000000..7370662a
--- /dev/null
+++ b/src/statusbar.cpp
@@ -0,0 +1,27 @@
+#include "statusbar.h"
+
+StatusBar::StatusBar(QStatusBar* bar)
+ : m_bar(bar), m_nexusAPI(new QLabel), m_progress(new QProgressBar)
+{
+ m_progress->setTextVisible(true);
+ m_progress->setRange(0, 100);
+ m_progress->setValue(0);
+ m_progress->setVisible(false);
+
+ m_bar->addPermanentWidget(m_nexusAPI);
+ m_bar->addPermanentWidget(m_progress);
+
+ m_bar->clearMessage();
+}
+
+void StatusBar::setProgress(int percent)
+{
+ qDebug().nospace() << "progress: " << percent;
+
+ if (percent < 0 || percent >= 100) {
+ m_progress->setVisible(false);
+ } else if (!m_progress->isVisible()) {
+ m_progress->setVisible(true);
+ m_progress->setValue(percent);
+ }
+}
diff --git a/src/statusbar.h b/src/statusbar.h
new file mode 100644
index 00000000..f3ad3081
--- /dev/null
+++ b/src/statusbar.h
@@ -0,0 +1,20 @@
+#ifndef MO_STATUSBAR_H
+#define MO_STATUSBAR_H
+
+#include
+#include
+
+class StatusBar
+{
+public:
+ StatusBar(QStatusBar* bar);
+
+ void setProgress(int percent);
+
+private:
+ QStatusBar* m_bar;
+ QLabel* m_api;
+ QProgressBar* m_progress;
+};
+
+#endif // MO_STATUSBAR_H
--
cgit v1.3.1
From ebbc900755b09862be95d29d2a02b8abd1792a3a Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Wed, 12 Jun 2019 15:10:41 -0400
Subject: added a few helper classes for user accounts and stats moved the api
label to the status bar refactored a bunch of copy/pasted code in
NexusInterface to use shouldThrottle() and throttledWarning()
---
src/mainwindow.cpp | 68 +++++-----
src/mainwindow.h | 5 +-
src/mainwindow.ui | 46 +------
src/nexusinterface.cpp | 314 ++++++++++++++++++++++++++++++-----------------
src/nexusinterface.h | 150 +++++++++++++++++++---
src/nxmaccessmanager.cpp | 15 +--
src/nxmaccessmanager.h | 5 +-
src/statusbar.cpp | 53 +++++++-
src/statusbar.h | 6 +
9 files changed, 428 insertions(+), 234 deletions(-)
(limited to 'src')
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 67d0f2ff..6b3ee11f 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -225,7 +225,7 @@ MainWindow::MainWindow(QSettings &initSettings
QWebEngineProfile::defaultProfile()->setCachePath(m_OrganizerCore.settings().getCacheDirectory());
QWebEngineProfile::defaultProfile()->setPersistentStoragePath(m_OrganizerCore.settings().getCacheDirectory());
ui->setupUi(this);
- updateWindowTitle(QString(), 0, false);
+ updateWindowTitle({});
languageChange(m_OrganizerCore.settings().language());
@@ -340,13 +340,6 @@ MainWindow::MainWindow(QSettings &initSettings
ui->bossButton->setToolTip(tr("There is no supported sort mechanism for this game. You will probably have to use a third-party tool."));
}
- ui->apiRequests->setAutoFillBackground(true);
- QPalette palette = ui->apiRequests->palette();
- palette.setColor(ui->apiRequests->backgroundRole(), Qt::darkGreen);
- palette.setColor(ui->apiRequests->foregroundRole(), Qt::white);
- ui->apiRequests->setPalette(palette);
- ui->apiRequests->setVisible(!m_OrganizerCore.settings().hideAPICounter());
-
connect(&m_PluginContainer, SIGNAL(diagnosisUpdate()), this, SLOT(updateProblemsButton()));
connect(ui->savegameList, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(saveSelectionChanged(QListWidgetItem*)));
@@ -379,11 +372,24 @@ MainWindow::MainWindow(QSettings &initSettings
connect(NexusInterface::instance(&pluginContainer), SIGNAL(nxmDownloadURLsAvailable(QString,int,int,QVariant,QVariant,int)), this, SLOT(nxmDownloadURLs(QString,int,int,QVariant,QVariant,int)));
connect(NexusInterface::instance(&pluginContainer), SIGNAL(needLogin()), &m_OrganizerCore, SLOT(nexusApi()));
connect(NexusInterface::instance(&pluginContainer)->getAccessManager(), SIGNAL(validateFailed(QString)), this, SLOT(validationFailed(QString)));
- connect(NexusInterface::instance(&pluginContainer)->getAccessManager(), SIGNAL(credentialsReceived(const QString&, int, bool, std::tuple)),
- this, SLOT(updateWindowTitle(const QString&, int, bool)));
- connect(NexusInterface::instance(&pluginContainer)->getAccessManager(), SIGNAL(credentialsReceived(const QString&, int, bool, std::tuple)),
- NexusInterface::instance(&m_PluginContainer), SLOT(setRateMax(const QString&, int, bool, std::tuple)));
- connect(NexusInterface::instance(&pluginContainer), SIGNAL(requestsChanged(int, std::tuple)), this, SLOT(updateAPICounter(int, std::tuple)));
+
+ connect(
+ NexusInterface::instance(&pluginContainer)->getAccessManager(),
+ SIGNAL(credentialsReceived(const APIUserAccount&)),
+ this,
+ SLOT(updateWindowTitle(const APIUserAccount&)));
+
+ connect(
+ NexusInterface::instance(&pluginContainer)->getAccessManager(),
+ SIGNAL(credentialsReceived(const APIUserAccount&)),
+ NexusInterface::instance(&m_PluginContainer),
+ SLOT(setUserAccount(const APIUserAccount&)));
+
+ connect(
+ NexusInterface::instance(&pluginContainer),
+ SIGNAL(requestsChanged(const APIStats&, const APIUserAccount&)),
+ this,
+ SLOT(onRequestsChanged(const APIStats&, const APIUserAccount&)));
connect(&TutorialManager::instance(), SIGNAL(windowTutorialFinished(QString)), this, SLOT(windowTutorialFinished(QString)));
connect(ui->tabWidget, SIGNAL(currentChanged(int)), &TutorialManager::instance(), SIGNAL(tabChanged(int)));
@@ -548,20 +554,27 @@ MainWindow::~MainWindow()
}
-void MainWindow::updateWindowTitle(const QString &accountName, int, bool premium)
+void MainWindow::updateWindowTitle(const APIUserAccount& user)
{
QString title = QString("%1 Mod Organizer v%2").arg(
m_OrganizerCore.managedGame()->gameName(),
m_OrganizerCore.getVersion().displayString(3));
- if (!accountName.isEmpty()) {
- title.append(QString(" (%1%2)").arg(accountName, premium ? "*" : ""));
+ if (!user.name().isEmpty()) {
+ const QString premium = (user.type() == APIUserAccountTypes::Premium ? "*" : "");
+ title.append(QString(" (%1%2)").arg(user.name(), premium));
}
this->setWindowTitle(title);
}
+void MainWindow::onRequestsChanged(const APIStats& stats, const APIUserAccount& user)
+{
+ m_statusBar->updateAPI(stats, user);
+}
+
+
void MainWindow::disconnectPlugins()
{
if (ui->actionTool->menu() != nullptr) {
@@ -5267,8 +5280,7 @@ void MainWindow::on_actionSettings_triggered()
activateProxy(settings.useProxy());
}
- ui->apiRequests->setVisible(!settings.hideAPICounter());
-
+ m_statusBar->checkSettings(m_OrganizerCore.settings());
updateDownloadView();
m_OrganizerCore.updateVFSParams(settings.logLevel(), settings.crashDumpsType(), settings.executablesBlacklist());
@@ -6067,26 +6079,6 @@ void MainWindow::nxmRequestFailed(QString gameName, int modID, int, QVariant, in
}
-void MainWindow::updateAPICounter(int queueCount, std::tuple limits)
-{
- ui->apiRequests->setText(QString("API: Q: %1 | D: %2 | H: %3").arg(queueCount).arg(std::get<0>(limits)).arg(std::get<2>(limits)));
- int requestsRemaining = std::get<0>(limits) + std::get<2>(limits);
- if (requestsRemaining > 300) {
- QPalette palette = ui->apiRequests->palette();
- palette.setColor(ui->apiRequests->backgroundRole(), Qt::darkGreen);
- ui->apiRequests->setPalette(palette);
- } else if (requestsRemaining < 150) {
- QPalette palette = ui->apiRequests->palette();
- palette.setColor(ui->apiRequests->backgroundRole(), Qt::darkRed);
- ui->apiRequests->setPalette(palette);
- } else {
- QPalette palette = ui->apiRequests->palette();
- palette.setColor(ui->apiRequests->backgroundRole(), Qt::darkYellow);
- ui->apiRequests->setPalette(palette);
- }
-}
-
-
BSA::EErrorCode MainWindow::extractBSA(BSA::Archive &archive, BSA::Folder::Ptr folder, const QString &destination,
QProgressDialog &progress)
{
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 734ece88..e2c6ce8b 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -416,8 +416,7 @@ private:
private slots:
- void updateWindowTitle(const QString &accountName, int, bool premium);
-
+ void updateWindowTitle(const APIUserAccount& user);
void showMessage(const QString &message);
void showError(const QString &message);
@@ -544,7 +543,7 @@ private slots:
void nxmDownloadURLs(QString, int modID, int fileID, QVariant userData, QVariant resultData, int requestID);
void nxmRequestFailed(QString gameName, int modID, int fileID, QVariant userData, int requestID, QNetworkReply::NetworkError error, const QString &errorString);
- void updateAPICounter(int queueCount, std::tuple limits);
+ void onRequestsChanged(const APIStats& stats, const APIUserAccount& user);
void editCategories();
void deselectFilters();
diff --git a/src/mainwindow.ui b/src/mainwindow.ui
index d3f9ef39..bbcb734c 100644
--- a/src/mainwindow.ui
+++ b/src/mainwindow.ui
@@ -412,7 +412,7 @@ p, li { white-space: pre-wrap; }
-
-
+
-
@@ -471,37 +471,6 @@ p, li { white-space: pre-wrap; }
- -
-
-
- Nexus API Queued and Remaining Requests
-
-
- <html><head/><body><p>This tracks the number of queued Nexus API requests on the left (<span style=" font-weight:600;">Q</span>) and the remaining daily (<span style=" font-weight:600;">D</span>) and hourly (<span style=" font-weight:600;">H</span>) requests on the right. The Nexus API limits you to a pool of requests per day and requests per hour. It is dynamically updated every time a request is completed. If you run out of requests, you will be unable to queue downloads, check updates, parse mod info, or even log in. Both pools must be consumed before this happens.</p></body></html>
-
-
- QFrame::StyledPanel
-
-
- QFrame::Sunken
-
-
- 2
-
-
- 1
-
-
- API: Q: 0 | D: 0 | H: 0
-
-
- Qt::AlignCenter
-
-
- 2
-
-
-
-
@@ -546,19 +515,6 @@ p, li { white-space: pre-wrap; }
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
diff --git a/src/nexusinterface.cpp b/src/nexusinterface.cpp
index c677add0..8362143a 100644
--- a/src/nexusinterface.cpp
+++ b/src/nexusinterface.cpp
@@ -38,6 +38,82 @@ using namespace MOBase;
using namespace MOShared;
+void throttledWarning(const APIUserAccount& user)
+{
+ qCritical() <<
+ QString(
+ "You have fewer than %1 requests remaining (%2). Only downloads and "
+ "login validation are being allowed.")
+ .arg(APIUserAccount::ThrottleThreshold)
+ .arg(user.remainingRequests());
+}
+
+
+APIUserAccount::APIUserAccount()
+ : m_type(APIUserAccountTypes::None)
+{
+}
+
+const QString& APIUserAccount::id() const
+{
+ return m_id;
+}
+
+const QString& APIUserAccount::name() const
+{
+ return m_name;
+}
+
+APIUserAccountTypes APIUserAccount::type() const
+{
+ return m_type;
+}
+
+const APILimits& APIUserAccount::limits() const
+{
+ return m_limits;
+}
+
+APIUserAccount& APIUserAccount::id(const QString& id)
+{
+ m_id = id;
+ return *this;
+}
+
+APIUserAccount& APIUserAccount::name(const QString& name)
+{
+ m_name = name;
+ return *this;
+}
+
+APIUserAccount& APIUserAccount::type(APIUserAccountTypes type)
+{
+ m_type = type;
+ return *this;
+}
+
+APIUserAccount& APIUserAccount::limits(const APILimits& limits)
+{
+ m_limits = limits;
+ return *this;
+}
+
+int APIUserAccount::remainingRequests() const
+{
+ return m_limits.remainingDailyRequests + m_limits.remainingHourlyRequests;
+}
+
+bool APIUserAccount::shouldThrottle() const
+{
+ return (remainingRequests() < ThrottleThreshold);
+}
+
+bool APIUserAccount::exhausted() const
+{
+ return (remainingRequests() <= 0);
+}
+
+
NexusBridge::NexusBridge(PluginContainer *pluginContainer, const QString &subModule)
: m_Interface(NexusInterface::instance(pluginContainer))
, m_SubModule(subModule)
@@ -179,15 +255,39 @@ void NexusBridge::nxmRequestFailed(QString gameName, int modID, int fileID, QVar
QAtomicInt NexusInterface::NXMRequestInfo::s_NextID(0);
+APILimits NexusInterface::defaultAPILimits()
+{
+ // https://app.swaggerhub.com/apis-docs/NexusMods/nexus-mods_public_api_params_in_form_data/1.0#/
+ const int MaxDaily = 2500;
+ const int MaxHourly = 100;
+
+ APILimits limits;
+
+ limits.maxDailyRequests = MaxDaily;
+ limits.remainingDailyRequests = MaxDaily;
+ limits.maxHourlyRequests = MaxHourly;
+ limits.remainingHourlyRequests = MaxHourly;
+
+ return limits;
+}
+
+APILimits NexusInterface::parseLimits(const QNetworkReply* reply)
+{
+ APILimits limits;
+
+ limits.maxDailyRequests = reply->rawHeader("x-rl-daily-limit").toInt();
+ limits.remainingDailyRequests = reply->rawHeader("x-rl-daily-remaining").toInt();
+ limits.maxHourlyRequests = reply->rawHeader("x-rl-hourly-limit").toInt();
+ limits.remainingHourlyRequests = reply->rawHeader("x-rl-hourly-remaining").toInt();
+
+ return limits;
+}
+
+
NexusInterface::NexusInterface(PluginContainer *pluginContainer)
: m_PluginContainer(pluginContainer)
- , m_RemainingDailyRequests(2500)
- , m_RemainingHourlyRequests(100)
- , m_MaxDailyRequests(2500)
- , m_MaxHourlyRequests(100)
- , m_IsPremium(false)
- , m_UserID(0)
{
+ m_User.limits(defaultAPILimits());
m_MOVersion = createVersionInfo();
m_AccessManager = new NXMAccessManager(this, m_MOVersion.displayString(3));
@@ -222,15 +322,10 @@ void NexusInterface::loginCompleted()
nextRequest();
}
-void NexusInterface::setRateMax(const QString&, int userId, bool isPremium, std::tuple limits)
+void NexusInterface::setUserAccount(const APIUserAccount& user)
{
- m_RemainingDailyRequests = std::get<0>(limits);
- m_MaxDailyRequests = std::get<1>(limits);
- m_RemainingHourlyRequests = std::get<2>(limits);
- m_MaxHourlyRequests = std::get<3>(limits);
- m_IsPremium = isPremium;
- m_UserID = userId;
- emit requestsChanged(m_RequestQueue.size(), limits);
+ m_User = user;
+ emit requestsChanged(stats(), m_User);
}
void NexusInterface::interpretNexusFileName(const QString &fileName, QString &modName, int &modID, bool query)
@@ -369,70 +464,70 @@ int NexusInterface::requestDescription(QString gameName, int modID, QObject *rec
int NexusInterface::requestModInfo(QString gameName, int modID, QObject *receiver, QVariant userData,
const QString &subModule, MOBase::IPluginGame const *game)
{
- if (std::max(m_RemainingDailyRequests, m_RemainingHourlyRequests) >= 200) {
- NXMRequestInfo requestInfo(modID, NXMRequestInfo::TYPE_MODINFO, userData, subModule, game);
- m_RequestQueue.enqueue(requestInfo);
+ if (m_User.shouldThrottle()) {
+ throttledWarning(m_User);
+ return -1;
+ }
- connect(this, SIGNAL(nxmModInfoAvailable(QString, int, QVariant, QVariant, int)),
- receiver, SLOT(nxmModInfoAvailable(QString, int, QVariant, QVariant, int)), Qt::UniqueConnection);
+ NXMRequestInfo requestInfo(modID, NXMRequestInfo::TYPE_MODINFO, userData, subModule, game);
+ m_RequestQueue.enqueue(requestInfo);
- connect(this, SIGNAL(nxmRequestFailed(QString, int, int, QVariant, int, QNetworkReply::NetworkError, QString)),
- receiver, SLOT(nxmRequestFailed(QString, int, int, QVariant, int, QNetworkReply::NetworkError, QString)), Qt::UniqueConnection);
+ connect(this, SIGNAL(nxmModInfoAvailable(QString, int, QVariant, QVariant, int)),
+ receiver, SLOT(nxmModInfoAvailable(QString, int, QVariant, QVariant, int)), Qt::UniqueConnection);
- nextRequest();
- return requestInfo.m_ID;
- }
- qCritical() << QString("You have fewer than 200 requests remaining (%1). Only downloads and login validation are being allowed.")
- .arg(std::max(m_RemainingDailyRequests, m_RemainingHourlyRequests));
- return -1;
+ connect(this, SIGNAL(nxmRequestFailed(QString, int, int, QVariant, int, QNetworkReply::NetworkError, QString)),
+ receiver, SLOT(nxmRequestFailed(QString, int, int, QVariant, int, QNetworkReply::NetworkError, QString)), Qt::UniqueConnection);
+
+ nextRequest();
+ return requestInfo.m_ID;
}
int NexusInterface::requestUpdateInfo(QString gameName, NexusInterface::UpdatePeriod period, QObject *receiver, QVariant userData,
const QString &subModule, const MOBase::IPluginGame *game)
{
- if (std::max(m_RemainingDailyRequests, m_RemainingHourlyRequests) >= 200) {
- NXMRequestInfo requestInfo(period, NXMRequestInfo::TYPE_CHECKUPDATES, userData, subModule, game);
- m_RequestQueue.enqueue(requestInfo);
+ if (m_User.shouldThrottle()) {
+ throttledWarning(m_User);
+ return -1;
+ }
- connect(this, SIGNAL(nxmUpdateInfoAvailable(QString, QVariant, QVariant, int)),
- receiver, SLOT(nxmUpdateInfoAvailable(QString, QVariant, QVariant, int)), Qt::UniqueConnection);
+ NXMRequestInfo requestInfo(period, NXMRequestInfo::TYPE_CHECKUPDATES, userData, subModule, game);
+ m_RequestQueue.enqueue(requestInfo);
- connect(this, SIGNAL(nxmRequestFailed(QString, int, int, QVariant, int, QNetworkReply::NetworkError, QString)),
- receiver, SLOT(nxmRequestFailed(QString, int, int, QVariant, int, QNetworkReply::NetworkError, QString)), Qt::UniqueConnection);
+ connect(this, SIGNAL(nxmUpdateInfoAvailable(QString, QVariant, QVariant, int)),
+ receiver, SLOT(nxmUpdateInfoAvailable(QString, QVariant, QVariant, int)), Qt::UniqueConnection);
- nextRequest();
- return requestInfo.m_ID;
- }
- qCritical() << QString("You have fewer than 200 requests remaining (%1). Only downloads and login validation are being allowed.")
- .arg(std::max(m_RemainingDailyRequests, m_RemainingHourlyRequests));
- return -1;
+ connect(this, SIGNAL(nxmRequestFailed(QString, int, int, QVariant, int, QNetworkReply::NetworkError, QString)),
+ receiver, SLOT(nxmRequestFailed(QString, int, int, QVariant, int, QNetworkReply::NetworkError, QString)), Qt::UniqueConnection);
+
+ nextRequest();
+ return requestInfo.m_ID;
}
int NexusInterface::requestUpdates(const int &modID, QObject *receiver, QVariant userData,
QString gameName, const QString &subModule)
{
- if (std::max(m_RemainingDailyRequests, m_RemainingHourlyRequests) >= 200) {
- IPluginGame *game = getGame(gameName);
- if (game == nullptr) {
- qCritical("requestUpdates can't find plugin for %s", qUtf8Printable(gameName));
- return -1;
- }
+ if (m_User.shouldThrottle()) {
+ throttledWarning(m_User);
+ return -1;
+ }
+
+ IPluginGame *game = getGame(gameName);
+ if (game == nullptr) {
+ qCritical("requestUpdates can't find plugin for %s", qUtf8Printable(gameName));
+ return -1;
+ }
- NXMRequestInfo requestInfo(modID, NXMRequestInfo::TYPE_GETUPDATES, userData, subModule, game);
- m_RequestQueue.enqueue(requestInfo);
+ NXMRequestInfo requestInfo(modID, NXMRequestInfo::TYPE_GETUPDATES, userData, subModule, game);
+ m_RequestQueue.enqueue(requestInfo);
- connect(this, SIGNAL(nxmUpdatesAvailable(QString, int, QVariant, QVariant, int)),
- receiver, SLOT(nxmUpdatesAvailable(QString, int, QVariant, QVariant, int)), Qt::UniqueConnection);
+ connect(this, SIGNAL(nxmUpdatesAvailable(QString, int, QVariant, QVariant, int)),
+ receiver, SLOT(nxmUpdatesAvailable(QString, int, QVariant, QVariant, int)), Qt::UniqueConnection);
- connect(this, SIGNAL(nxmRequestFailed(QString, int, int, QVariant, int, QNetworkReply::NetworkError, QString)),
- receiver, SLOT(nxmRequestFailed(QString, int, int, QVariant, int, QNetworkReply::NetworkError, QString)), Qt::UniqueConnection);
+ connect(this, SIGNAL(nxmRequestFailed(QString, int, int, QVariant, int, QNetworkReply::NetworkError, QString)),
+ receiver, SLOT(nxmRequestFailed(QString, int, int, QVariant, int, QNetworkReply::NetworkError, QString)), Qt::UniqueConnection);
- nextRequest();
- return requestInfo.m_ID;
- }
- qCritical() << QString("You have fewer than 200 requests remaining (%1). Only downloads and login validation are being allowed.")
- .arg(std::max(m_RemainingDailyRequests, m_RemainingHourlyRequests));
- return -1;
+ nextRequest();
+ return requestInfo.m_ID;
}
@@ -527,23 +622,23 @@ int NexusInterface::requestEndorsementInfo(QObject *receiver, QVariant userData,
int NexusInterface::requestToggleEndorsement(QString gameName, int modID, QString modVersion, bool endorse, QObject *receiver, QVariant userData,
const QString &subModule, MOBase::IPluginGame const *game)
{
- if (std::max(m_RemainingDailyRequests, m_RemainingHourlyRequests) >= 200) {
- NXMRequestInfo requestInfo(modID, modVersion, NXMRequestInfo::TYPE_TOGGLEENDORSEMENT, userData, subModule, game);
- requestInfo.m_Endorse = endorse;
- m_RequestQueue.enqueue(requestInfo);
+ if (m_User.shouldThrottle()) {
+ throttledWarning(m_User);
+ return -1;
+ }
- connect(this, SIGNAL(nxmEndorsementToggled(QString, int, QVariant, QVariant, int)),
- receiver, SLOT(nxmEndorsementToggled(QString, int, QVariant, QVariant, int)), Qt::UniqueConnection);
+ NXMRequestInfo requestInfo(modID, modVersion, NXMRequestInfo::TYPE_TOGGLEENDORSEMENT, userData, subModule, game);
+ requestInfo.m_Endorse = endorse;
+ m_RequestQueue.enqueue(requestInfo);
- connect(this, SIGNAL(nxmRequestFailed(QString, int, int, QVariant, int, QNetworkReply::NetworkError, QString)),
- receiver, SLOT(nxmRequestFailed(QString, int, int, QVariant, int, QNetworkReply::NetworkError, QString)), Qt::UniqueConnection);
+ connect(this, SIGNAL(nxmEndorsementToggled(QString, int, QVariant, QVariant, int)),
+ receiver, SLOT(nxmEndorsementToggled(QString, int, QVariant, QVariant, int)), Qt::UniqueConnection);
- nextRequest();
- return requestInfo.m_ID;
- }
- qCritical() << QString("You have fewer than 200 requests remaining (%1). Only downloads and login validation are being allowed.")
- .arg(std::max(m_RemainingDailyRequests, m_RemainingHourlyRequests));
- return -1;
+ connect(this, SIGNAL(nxmRequestFailed(QString, int, int, QVariant, int, QNetworkReply::NetworkError, QString)),
+ receiver, SLOT(nxmRequestFailed(QString, int, int, QVariant, int, QNetworkReply::NetworkError, QString)), Qt::UniqueConnection);
+
+ nextRequest();
+ return requestInfo.m_ID;
}
int NexusInterface::requestTrackingInfo(QObject *receiver, QVariant userData, const QString &subModule)
@@ -564,23 +659,23 @@ int NexusInterface::requestTrackingInfo(QObject *receiver, QVariant userData, co
int NexusInterface::requestToggleTracking(QString gameName, int modID, bool track, QObject *receiver, QVariant userData,
const QString &subModule, MOBase::IPluginGame const *game)
{
- if (std::max(m_RemainingDailyRequests, m_RemainingHourlyRequests) >= 200) {
- NXMRequestInfo requestInfo(modID, NXMRequestInfo::TYPE_TOGGLETRACKING, userData, subModule, game);
- requestInfo.m_Track = track;
- m_RequestQueue.enqueue(requestInfo);
+ if (m_User.shouldThrottle()) {
+ throttledWarning(m_User);
+ return -1;
+ }
- connect(this, SIGNAL(nxmTrackingToggled(QString, int, QVariant, bool, int)),
- receiver, SLOT(nxmTrackingToggled(QString, int, QVariant, bool, int)), Qt::UniqueConnection);
+ NXMRequestInfo requestInfo(modID, NXMRequestInfo::TYPE_TOGGLETRACKING, userData, subModule, game);
+ requestInfo.m_Track = track;
+ m_RequestQueue.enqueue(requestInfo);
- connect(this, SIGNAL(nxmRequestFailed(QString, int, int, QVariant, int, QNetworkReply::NetworkError, QString)),
- receiver, SLOT(nxmRequestFailed(QString, int, int, QVariant, int, QNetworkReply::NetworkError, QString)), Qt::UniqueConnection);
+ connect(this, SIGNAL(nxmTrackingToggled(QString, int, QVariant, bool, int)),
+ receiver, SLOT(nxmTrackingToggled(QString, int, QVariant, bool, int)), Qt::UniqueConnection);
- nextRequest();
- return requestInfo.m_ID;
- }
- qCritical() << QString("You have fewer than 200 requests remaining (%1). Only downloads and login validation are being allowed.")
- .arg(std::max(m_RemainingDailyRequests, m_RemainingHourlyRequests));
- return -1;
+ connect(this, SIGNAL(nxmRequestFailed(QString, int, int, QVariant, int, QNetworkReply::NetworkError, QString)),
+ receiver, SLOT(nxmRequestFailed(QString, int, int, QVariant, int, QNetworkReply::NetworkError, QString)), Qt::UniqueConnection);
+
+ nextRequest();
+ return requestInfo.m_ID;
}
int NexusInterface::requestInfoFromMd5(QString gameName, QByteArray &hash, QObject *receiver, QVariant userData,
@@ -645,7 +740,7 @@ void NexusInterface::nextRequest()
}
}
- if (std::max(m_RemainingDailyRequests, m_RemainingHourlyRequests) <= 0) {
+ if (m_User.exhausted()) {
m_RequestQueue.clear();
QTime time = QTime::currentTime();
QTime targetTime;
@@ -696,9 +791,9 @@ void NexusInterface::nextRequest()
} break;
case NXMRequestInfo::TYPE_DOWNLOADURL: {
ModRepositoryFileInfo *fileInfo = qobject_cast(qvariant_cast(info.m_UserData));
- if (m_IsPremium) {
+ if (m_User.type() == APIUserAccountTypes::Premium) {
url = QString("%1/games/%2/mods/%3/files/%4/download_link").arg(info.m_URL).arg(info.m_GameName).arg(info.m_ModID).arg(info.m_FileID);
- } else if (!fileInfo->nexusKey.isEmpty() && fileInfo->nexusExpires && fileInfo->nexusDownloadUser == m_UserID) {
+ } else if (!fileInfo->nexusKey.isEmpty() && fileInfo->nexusExpires && fileInfo->nexusDownloadUser == m_User.id().toInt()) {
url = QString("%1/games/%2/mods/%3/files/%4/download_link?key=%5&expires=%6")
.arg(info.m_URL).arg(info.m_GameName).arg(info.m_ModID).arg(info.m_FileID).arg(fileInfo->nexusKey).arg(fileInfo->nexusExpires);
} else {
@@ -780,23 +875,16 @@ void NexusInterface::requestFinished(std::list::iterator iter)
if (iter->m_AllowedErrors.contains(error) && iter->m_AllowedErrors[error].contains(statusCode)) {
// These errors are allows to silently happen. They should be handled in nxmRequestFailed below.
} else if (statusCode == 429) {
- m_RemainingDailyRequests = reply->rawHeader("x-rl-daily-remaining").toInt();
- m_MaxDailyRequests = reply->rawHeader("x-rl-daily-limit").toInt();
- m_RemainingHourlyRequests = reply->rawHeader("x-rl-hourly-remaining").toInt();
- m_MaxHourlyRequests = reply->rawHeader("x-rl-hourly-limit").toInt();
+ m_User.limits(parseLimits(reply));
- if (m_RemainingDailyRequests || m_RemainingHourlyRequests)
+ if (!m_User.exhausted()) {
qWarning("You appear to be making requests to the Nexus API too quickly and are being throttled. Please inform the MO2 team.");
- else
+ }
+ else {
qWarning("All API requests have been consumed and are now being denied.");
+ }
- emit requestsChanged(m_RequestQueue.size(), std::tuple(std::make_tuple(
- m_RemainingDailyRequests,
- m_MaxDailyRequests,
- m_RemainingHourlyRequests,
- m_MaxHourlyRequests
- )));
-
+ emit requestsChanged(stats(), m_User);
qWarning("Error: %s", reply->errorString().toUtf8().constData());
} else {
qWarning("request failed: %s", reply->errorString().toUtf8().constData());
@@ -871,17 +959,8 @@ void NexusInterface::requestFinished(std::list::iterator iter)
} break;
}
- m_RemainingDailyRequests = reply->rawHeader("x-rl-daily-remaining").toInt();
- m_MaxDailyRequests = reply->rawHeader("x-rl-daily-limit").toInt();
- m_RemainingHourlyRequests = reply->rawHeader("x-rl-hourly-remaining").toInt();
- m_MaxHourlyRequests = reply->rawHeader("x-rl-hourly-limit").toInt();
-
- emit requestsChanged(m_RequestQueue.size(), std::tuple(std::make_tuple(
- m_RemainingDailyRequests,
- m_MaxDailyRequests,
- m_RemainingHourlyRequests,
- m_MaxHourlyRequests
- )));
+ m_User.limits(parseLimits(reply));
+ emit requestsChanged(stats(), m_User);
} else {
emit nxmRequestFailed(iter->m_GameName, iter->m_ModID, iter->m_FileID, iter->m_UserData, iter->m_ID, reply->error(), tr("invalid response"));
}
@@ -938,6 +1017,15 @@ void NexusInterface::requestTimeout()
}
}
+APIStats NexusInterface::stats() const
+{
+ APIStats stats;
+ stats.requestsQueued = m_RequestQueue.size();
+
+ return stats;
+}
+
+
namespace {
QString get_management_url()
{
diff --git a/src/nexusinterface.h b/src/nexusinterface.h
index 70c1c9c9..6c4e8d11 100644
--- a/src/nexusinterface.h
+++ b/src/nexusinterface.h
@@ -39,6 +39,131 @@ namespace MOBase { class IPluginGame; }
class NexusInterface;
class NXMAccessManager;
+
+/**
+ * represents user account types on a mod provider website such as nexus
+ */
+enum class APIUserAccountTypes
+{
+ // not logged in
+ None = 0,
+
+ // regular account
+ Regular,
+
+ // premium account
+ Premium
+};
+
+
+/**
+ * current limits imposed on the user account
+ **/
+struct APILimits
+{
+ // maximum number of requests per day
+ int maxDailyRequests = 0;
+
+ // remaining number of requests today
+ int remainingDailyRequests = 0;
+
+ // maximum number of requests per hour
+ int maxHourlyRequests = 0;
+
+ // remaining number of requests this hour
+ int remainingHourlyRequests = 0;
+};
+
+
+/**
+ * API statistics
+ */
+struct APIStats
+{
+ // number of API requests currently queued
+ int requestsQueued = 0;
+};
+
+
+/**
+ * represents a user account on the mod provier website
+ */
+class APIUserAccount
+{
+public:
+ // when the number of remanining requests is under this number, further
+ // requests will be throttled by avoiding non-critical ones
+ static const int ThrottleThreshold = 300;
+
+ APIUserAccount();
+
+ /**
+ * user id
+ */
+ const QString& id() const;
+
+ /**
+ * user name
+ */
+ const QString& name() const;
+
+ /**
+ * account type
+ */
+ APIUserAccountTypes type() const;
+
+ /**
+ * current API limits
+ */
+ const APILimits& limits() const;
+
+
+ /**
+ * sets the user id
+ */
+ APIUserAccount& id(const QString& id);
+
+ /**
+ * sets the user name
+ **/
+ APIUserAccount& name(const QString& name);
+
+ /**
+ * sets the acount type
+ */
+ APIUserAccount& type(APIUserAccountTypes type);
+
+ /**
+ * sets the current limits
+ */
+ APIUserAccount& limits(const APILimits& limits);
+
+
+ /**
+ * returns the number of remaining requests
+ */
+ int remainingRequests() const;
+
+ /**
+ * whether the number of remaining requests is low enough that further
+ * requests should be throttled
+ */
+ bool shouldThrottle() const;
+
+ /**
+ * true if all the remaining requests have been used and the API will refuse
+ * further requests
+ */
+ bool exhausted() const;
+
+private:
+ QString m_id, m_name;
+ APIUserAccountTypes m_type;
+ APILimits m_limits;
+ APIStats m_stats;
+};
+
+
/**
* @brief convenience class to make nxm requests easier
* usually, all objects that started a nxm request will be signaled if one finished.
@@ -53,7 +178,6 @@ class NexusBridge : public MOBase::IModRepositoryBridge
Q_OBJECT
public:
-
NexusBridge(PluginContainer *pluginContainer, const QString &subModule = "");
/**
@@ -147,6 +271,8 @@ public:
};
public:
+ static APILimits defaultAPILimits();
+ static APILimits parseLimits(const QNetworkReply* reply);
~NexusInterface();
@@ -380,7 +506,7 @@ public:
/**
*
*/
- int requestInfoFromMd5(QString gameName, QByteArray &hash, QObject *receiver, QVariant userData, const QString &subModule,
+ int requestInfoFromMd5(QString gameName, QByteArray &hash, QObject *receiver, QVariant userData, const QString &subModule,
MOBase::IPluginGame const *game);
/**
@@ -459,11 +585,11 @@ signals:
void nxmTrackedModsAvailable(QVariant userData, QVariant resultData, int requestID);
void nxmTrackingToggled(QString gameName, int modID, QVariant userData, bool tracked, int requestID);
void nxmRequestFailed(QString gameName, int modID, int fileID, QVariant userData, int requestID, QNetworkReply::NetworkError error, const QString &errorString);
- void requestsChanged(int queueCount, std::tuple requestsRemaining);
+ void requestsChanged(const APIStats& stats, const APIUserAccount& user);
public slots:
- void setRateMax(const QString&, int userId, bool isPremium, std::tuple limits);
+ void setUserAccount(const APIUserAccount& user);
private slots:
@@ -534,27 +660,15 @@ private:
QString getOldModsURL(QString gameName) const;
private:
-
QNetworkDiskCache *m_DiskCache;
-
NXMAccessManager *m_AccessManager;
-
std::list m_ActiveRequest;
QQueue m_RequestQueue;
-
MOBase::VersionInfo m_MOVersion;
-
PluginContainer *m_PluginContainer;
+ APIUserAccount m_User;
- int m_RemainingDailyRequests;
- int m_RemainingHourlyRequests;
- int m_MaxDailyRequests;
- int m_MaxHourlyRequests;
-
- int m_UserID;
-
- bool m_IsPremium;
-
+ APIStats stats() const;
};
#endif // NEXUSINTERFACE_H
diff --git a/src/nxmaccessmanager.cpp b/src/nxmaccessmanager.cpp
index 684a53fa..5886d3ee 100644
--- a/src/nxmaccessmanager.cpp
+++ b/src/nxmaccessmanager.cpp
@@ -18,8 +18,8 @@ along with Mod Organizer. If not, see .
*/
#include "nxmaccessmanager.h"
-
#include "iplugingame.h"
+#include "nexusinterface.h"
#include "nxmurl.h"
#include "report.h"
#include "utility.h"
@@ -280,14 +280,11 @@ void NXMAccessManager::validateFinished()
QString name = credentialsData.value("name").toString();
bool premium = credentialsData.value("is_premium").toBool();
- std::tuple limits(std::make_tuple(
- m_ValidateReply->rawHeader("x-rl-daily-remaining").toInt(),
- m_ValidateReply->rawHeader("x-rl-daily-limit").toInt(),
- m_ValidateReply->rawHeader("x-rl-hourly-remaining").toInt(),
- m_ValidateReply->rawHeader("x-rl-hourly-limit").toInt()
- ));
-
- emit credentialsReceived(name, id, premium, limits);
+ emit credentialsReceived(APIUserAccount()
+ .id(QString("%1").arg(id))
+ .name(name)
+ .type(premium ? APIUserAccountTypes::Premium : APIUserAccountTypes::Regular)
+ .limits(NexusInterface::parseLimits(m_ValidateReply)));
m_ValidateReply->deleteLater();
m_ValidateReply = nullptr;
diff --git a/src/nxmaccessmanager.h b/src/nxmaccessmanager.h
index e3608f8d..1d23faf9 100644
--- a/src/nxmaccessmanager.h
+++ b/src/nxmaccessmanager.h
@@ -20,7 +20,6 @@ along with Mod Organizer. If not, see .
#ifndef NXMACCESSMANAGER_H
#define NXMACCESSMANAGER_H
-
#include
#include
#include
@@ -29,6 +28,8 @@ along with Mod Organizer. If not, see .
namespace MOBase { class IPluginGame; }
+class APIUserAccount;
+
/**
* @brief access manager extended to handle nxm links
**/
@@ -78,7 +79,7 @@ signals:
void validateFailed(const QString &message);
- void credentialsReceived(const QString &userName, int userId, bool premium, std::tuple limits);
+ void credentialsReceived(const APIUserAccount& user);
private slots:
diff --git a/src/statusbar.cpp b/src/statusbar.cpp
index 7370662a..6af10c56 100644
--- a/src/statusbar.cpp
+++ b/src/statusbar.cpp
@@ -1,23 +1,26 @@
#include "statusbar.h"
+#include "nexusinterface.h"
+#include "settings.h"
StatusBar::StatusBar(QStatusBar* bar)
- : m_bar(bar), m_nexusAPI(new QLabel), m_progress(new QProgressBar)
+ : m_bar(bar), m_api(new QLabel), m_progress(new QProgressBar)
{
m_progress->setTextVisible(true);
m_progress->setRange(0, 100);
- m_progress->setValue(0);
- m_progress->setVisible(false);
- m_bar->addPermanentWidget(m_nexusAPI);
+ m_bar->addPermanentWidget(m_api);
m_bar->addPermanentWidget(m_progress);
+ m_api->setObjectName("apistats");
+ m_api->setStyleSheet("QLabel{ padding-left: 0.1em; padding-right: 0.1em; }");
+
m_bar->clearMessage();
+ setProgress(-1);
+ updateAPI({}, {});
}
void StatusBar::setProgress(int percent)
{
- qDebug().nospace() << "progress: " << percent;
-
if (percent < 0 || percent >= 100) {
m_progress->setVisible(false);
} else if (!m_progress->isVisible()) {
@@ -25,3 +28,41 @@ void StatusBar::setProgress(int percent)
m_progress->setValue(percent);
}
}
+
+void StatusBar::updateAPI(const APIStats& stats, const APIUserAccount& user)
+{
+ m_api->setText(
+ QString("API: Q: %1 | D: %2 | H: %3")
+ .arg(stats.requestsQueued)
+ .arg(user.limits().remainingDailyRequests)
+ .arg(user.limits().remainingHourlyRequests));
+
+ QColor textColor;
+ QColor backgroundColor;
+
+ if (user.type() == APIUserAccountTypes::None) {
+ backgroundColor = Qt::transparent;
+ } else if (user.remainingRequests() > 300) {
+ textColor = "white";
+ backgroundColor = Qt::darkGreen;
+ } else if (user.remainingRequests() < 150) {
+ textColor = "white";
+ backgroundColor = Qt::darkRed;
+ } else {
+ textColor = "black";
+ backgroundColor = Qt::darkYellow;
+ }
+
+ QPalette palette = m_api->palette();
+
+ palette.setColor(QPalette::WindowText, textColor);
+ palette.setColor(QPalette::Background, backgroundColor);
+
+ m_api->setPalette(palette);
+ m_api->setAutoFillBackground(true);
+}
+
+void StatusBar::checkSettings(const Settings& settings)
+{
+ m_api->setVisible(!settings.hideAPICounter());
+}
diff --git a/src/statusbar.h b/src/statusbar.h
index f3ad3081..47a0e56d 100644
--- a/src/statusbar.h
+++ b/src/statusbar.h
@@ -4,12 +4,18 @@
#include
#include
+struct APIStats;
+class APIUserAccount;
+class Settings;
+
class StatusBar
{
public:
StatusBar(QStatusBar* bar);
void setProgress(int percent);
+ void updateAPI(const APIStats& stats, const APIUserAccount& user);
+ void checkSettings(const Settings& settings);
private:
QStatusBar* m_bar;
--
cgit v1.3.1
From dc8256bae1f62cf3fad3b7dd60f4befc60edca03 Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Wed, 12 Jun 2019 15:41:15 -0400
Subject: added notifications label, unused
---
src/statusbar.cpp | 12 +++++++-----
src/statusbar.h | 3 ++-
2 files changed, 9 insertions(+), 6 deletions(-)
(limited to 'src')
diff --git a/src/statusbar.cpp b/src/statusbar.cpp
index 6af10c56..f2af0272 100644
--- a/src/statusbar.cpp
+++ b/src/statusbar.cpp
@@ -2,15 +2,17 @@
#include "nexusinterface.h"
#include "settings.h"
-StatusBar::StatusBar(QStatusBar* bar)
- : m_bar(bar), m_api(new QLabel), m_progress(new QProgressBar)
+StatusBar::StatusBar(QStatusBar* bar) :
+ m_bar(bar), m_notifications(new QLabel), m_progress(new QProgressBar),
+ m_api(new QLabel)
{
+ m_bar->addPermanentWidget(m_notifications);
+ m_bar->addPermanentWidget(m_progress);
+ m_bar->addPermanentWidget(m_api);
+
m_progress->setTextVisible(true);
m_progress->setRange(0, 100);
- m_bar->addPermanentWidget(m_api);
- m_bar->addPermanentWidget(m_progress);
-
m_api->setObjectName("apistats");
m_api->setStyleSheet("QLabel{ padding-left: 0.1em; padding-right: 0.1em; }");
diff --git a/src/statusbar.h b/src/statusbar.h
index 47a0e56d..99de8f16 100644
--- a/src/statusbar.h
+++ b/src/statusbar.h
@@ -19,8 +19,9 @@ public:
private:
QStatusBar* m_bar;
- QLabel* m_api;
+ QLabel* m_notifications;
QProgressBar* m_progress;
+ QLabel* m_api;
};
#endif // MO_STATUSBAR_H
--
cgit v1.3.1
From a418d028b209ab8e6b75b77b405e9babe48a19dd Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Wed, 12 Jun 2019 16:16:17 -0400
Subject: max width for progress bar notification icon in status bar
---
src/mainwindow.cpp | 7 ++++++-
src/statusbar.cpp | 15 ++++++++++++---
src/statusbar.h | 5 +++--
3 files changed, 21 insertions(+), 6 deletions(-)
(limited to 'src')
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 6b3ee11f..c39ac749 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -243,7 +243,7 @@ MainWindow::MainWindow(QSettings &initSettings
connect(ui->logList->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
ui->logList, SLOT(scrollToBottom()));
- m_statusBar.reset(new StatusBar(statusBar()));
+ m_statusBar.reset(new StatusBar(statusBar(), ui->actionNotifications));
updateProblemsButton();
@@ -899,6 +899,11 @@ void MainWindow::updateProblemsButton()
button->setIcon(final);
}
}
+
+ // updating the status bar, may be null very early when MO is starting
+ if (m_statusBar) {
+ m_statusBar->setHasNotifications(numProblems > 0);
+ }
}
diff --git a/src/statusbar.cpp b/src/statusbar.cpp
index f2af0272..a34500b0 100644
--- a/src/statusbar.cpp
+++ b/src/statusbar.cpp
@@ -2,16 +2,20 @@
#include "nexusinterface.h"
#include "settings.h"
-StatusBar::StatusBar(QStatusBar* bar) :
- m_bar(bar), m_notifications(new QLabel), m_progress(new QProgressBar),
+StatusBar::StatusBar(QStatusBar* bar, QAction* notifications) :
+ m_bar(bar), m_progress(new QProgressBar), m_notifications(new QToolButton),
m_api(new QLabel)
{
- m_bar->addPermanentWidget(m_notifications);
m_bar->addPermanentWidget(m_progress);
+ m_bar->addPermanentWidget(m_notifications);
m_bar->addPermanentWidget(m_api);
m_progress->setTextVisible(true);
m_progress->setRange(0, 100);
+ m_progress->setMaximumWidth(100);
+
+ m_notifications->setDefaultAction(notifications);
+ m_notifications->setAutoRaise(true);
m_api->setObjectName("apistats");
m_api->setStyleSheet("QLabel{ padding-left: 0.1em; padding-right: 0.1em; }");
@@ -31,6 +35,11 @@ void StatusBar::setProgress(int percent)
}
}
+void StatusBar::setHasNotifications(bool b)
+{
+ m_notifications->setVisible(b);
+}
+
void StatusBar::updateAPI(const APIStats& stats, const APIUserAccount& user)
{
m_api->setText(
diff --git a/src/statusbar.h b/src/statusbar.h
index 99de8f16..bf14ba57 100644
--- a/src/statusbar.h
+++ b/src/statusbar.h
@@ -11,16 +11,17 @@ class Settings;
class StatusBar
{
public:
- StatusBar(QStatusBar* bar);
+ StatusBar(QStatusBar* bar, QAction* notifications);
void setProgress(int percent);
+ void setHasNotifications(bool b);
void updateAPI(const APIStats& stats, const APIUserAccount& user);
void checkSettings(const Settings& settings);
private:
QStatusBar* m_bar;
- QLabel* m_notifications;
QProgressBar* m_progress;
+ QToolButton* m_notifications;
QLabel* m_api;
};
--
cgit v1.3.1
From dc08c12fe8cde84c7cf507954d090d572ac865d5 Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Wed, 12 Jun 2019 17:08:09 -0400
Subject: fixed progress bar not updating
---
src/statusbar.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
(limited to 'src')
diff --git a/src/statusbar.cpp b/src/statusbar.cpp
index a34500b0..1c62b38e 100644
--- a/src/statusbar.cpp
+++ b/src/statusbar.cpp
@@ -29,7 +29,8 @@ void StatusBar::setProgress(int percent)
{
if (percent < 0 || percent >= 100) {
m_progress->setVisible(false);
- } else if (!m_progress->isVisible()) {
+ } else {
+ m_bar->showMessage(QObject::tr("Loading..."));
m_progress->setVisible(true);
m_progress->setValue(percent);
}
--
cgit v1.3.1
From 16d6a4c528fd226ac5bf9a2ff54911c567d5bca0 Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Wed, 12 Jun 2019 18:04:42 -0400
Subject: added a StatusBarNotifications class to handle icon, text and double
click
---
src/mainwindow.cpp | 2 +-
src/statusbar.cpp | 46 ++++++++++++++++++++++++++++++++++++----------
src/statusbar.h | 24 +++++++++++++++++++++---
3 files changed, 58 insertions(+), 14 deletions(-)
(limited to 'src')
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index c39ac749..6d65d64c 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -902,7 +902,7 @@ void MainWindow::updateProblemsButton()
// updating the status bar, may be null very early when MO is starting
if (m_statusBar) {
- m_statusBar->setHasNotifications(numProblems > 0);
+ m_statusBar->updateNotifications(numProblems > 0);
}
}
diff --git a/src/statusbar.cpp b/src/statusbar.cpp
index 1c62b38e..9ff1c476 100644
--- a/src/statusbar.cpp
+++ b/src/statusbar.cpp
@@ -2,9 +2,9 @@
#include "nexusinterface.h"
#include "settings.h"
-StatusBar::StatusBar(QStatusBar* bar, QAction* notifications) :
- m_bar(bar), m_progress(new QProgressBar), m_notifications(new QToolButton),
- m_api(new QLabel)
+StatusBar::StatusBar(QStatusBar* bar, QAction* actionNotifications) :
+ m_bar(bar), m_notifications(new StatusBarNotifications(actionNotifications)),
+ m_progress(new QProgressBar), m_api(new QLabel)
{
m_bar->addPermanentWidget(m_progress);
m_bar->addPermanentWidget(m_notifications);
@@ -12,13 +12,11 @@ StatusBar::StatusBar(QStatusBar* bar, QAction* notifications) :
m_progress->setTextVisible(true);
m_progress->setRange(0, 100);
- m_progress->setMaximumWidth(100);
-
- m_notifications->setDefaultAction(notifications);
- m_notifications->setAutoRaise(true);
+ m_progress->setMaximumWidth(150);
+ m_progress->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
m_api->setObjectName("apistats");
- m_api->setStyleSheet("QLabel{ padding-left: 0.1em; padding-right: 0.1em; }");
+ m_api->setStyleSheet("QLabel{ padding: 0.1em 0 0.1em 0; }");
m_bar->clearMessage();
setProgress(-1);
@@ -28,6 +26,7 @@ StatusBar::StatusBar(QStatusBar* bar, QAction* notifications) :
void StatusBar::setProgress(int percent)
{
if (percent < 0 || percent >= 100) {
+ m_bar->clearMessage();
m_progress->setVisible(false);
} else {
m_bar->showMessage(QObject::tr("Loading..."));
@@ -36,9 +35,9 @@ void StatusBar::setProgress(int percent)
}
}
-void StatusBar::setHasNotifications(bool b)
+void StatusBar::updateNotifications(bool hasNotifications)
{
- m_notifications->setVisible(b);
+ m_notifications->update(hasNotifications);
}
void StatusBar::updateAPI(const APIStats& stats, const APIUserAccount& user)
@@ -78,3 +77,30 @@ void StatusBar::checkSettings(const Settings& settings)
{
m_api->setVisible(!settings.hideAPICounter());
}
+
+
+StatusBarNotifications::StatusBarNotifications(QAction* action)
+ : m_action(action), m_icon(new QLabel), m_text(new QLabel)
+{
+ setLayout(new QHBoxLayout);
+ layout()->setContentsMargins(0, 0, 0, 0);
+ layout()->addWidget(m_icon);
+ layout()->addWidget(m_text);
+}
+
+void StatusBarNotifications::update(bool hasNotifications)
+{
+ if (hasNotifications) {
+ m_icon->setPixmap(m_action->icon().pixmap(16, 16));
+ m_text->setText(QObject::tr("Notifications"));
+ }
+
+ setVisible(hasNotifications);
+}
+
+void StatusBarNotifications::mouseDoubleClickEvent(QMouseEvent* e)
+{
+ if (m_action->isEnabled()) {
+ m_action->trigger();
+ }
+}
diff --git a/src/statusbar.h b/src/statusbar.h
index bf14ba57..8edfd037 100644
--- a/src/statusbar.h
+++ b/src/statusbar.h
@@ -8,20 +8,38 @@ struct APIStats;
class APIUserAccount;
class Settings;
+
+class StatusBarNotifications : public QWidget
+{
+public:
+ StatusBarNotifications(QAction* action);
+
+ void update(bool hasNotifications);
+
+protected:
+ void mouseDoubleClickEvent(QMouseEvent* e) override;
+
+private:
+ QAction* m_action;
+ QLabel* m_icon;
+ QLabel* m_text;
+};
+
+
class StatusBar
{
public:
- StatusBar(QStatusBar* bar, QAction* notifications);
+ StatusBar(QStatusBar* bar, QAction* actionNotifications);
void setProgress(int percent);
- void setHasNotifications(bool b);
+ void updateNotifications(bool hasNotifications);
void updateAPI(const APIStats& stats, const APIUserAccount& user);
void checkSettings(const Settings& settings);
private:
QStatusBar* m_bar;
+ StatusBarNotifications* m_notifications;
QProgressBar* m_progress;
- QToolButton* m_notifications;
QLabel* m_api;
};
--
cgit v1.3.1
From 4a7a77480bfd44c7780e9e37bceadac7e367c062 Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Wed, 12 Jun 2019 19:12:34 -0400
Subject: changed StatusBarNotifications to a generic StatusBarAction added
update notification to statusbar
---
src/mainwindow.cpp | 16 ++++++----------
src/statusbar.cpp | 52 +++++++++++++++++++++++++++++++++++++++-------------
src/statusbar.h | 19 ++++++++++++-------
3 files changed, 57 insertions(+), 30 deletions(-)
(limited to 'src')
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 6d65d64c..2497b05d 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -243,7 +243,7 @@ MainWindow::MainWindow(QSettings &initSettings
connect(ui->logList->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
ui->logList, SLOT(scrollToBottom()));
- m_statusBar.reset(new StatusBar(statusBar(), ui->actionNotifications));
+ m_statusBar.reset(new StatusBar(statusBar(), ui));
updateProblemsButton();
@@ -571,7 +571,7 @@ void MainWindow::updateWindowTitle(const APIUserAccount& user)
void MainWindow::onRequestsChanged(const APIStats& stats, const APIUserAccount& user)
{
- m_statusBar->updateAPI(stats, user);
+ m_statusBar->setAPI(stats, user);
}
@@ -902,7 +902,7 @@ void MainWindow::updateProblemsButton()
// updating the status bar, may be null very early when MO is starting
if (m_statusBar) {
- m_statusBar->updateNotifications(numProblems > 0);
+ m_statusBar->setNotifications(numProblems > 0);
}
}
@@ -5593,13 +5593,9 @@ void MainWindow::openDataOriginExplorer_clicked()
void MainWindow::updateAvailable()
{
- for (QAction *action : ui->toolBar->actions()) {
- if (action->text() == tr("Update")) {
- action->setEnabled(true);
- action->setToolTip(tr("Update available"));
- break;
- }
- }
+ ui->actionUpdate->setEnabled(true);
+ ui->actionUpdate->setToolTip(tr("Update available"));
+ m_statusBar->setUpdateAvailable(true);
}
diff --git a/src/statusbar.cpp b/src/statusbar.cpp
index 9ff1c476..68c0642a 100644
--- a/src/statusbar.cpp
+++ b/src/statusbar.cpp
@@ -1,13 +1,17 @@
#include "statusbar.h"
#include "nexusinterface.h"
#include "settings.h"
+#include "ui_mainwindow.h"
-StatusBar::StatusBar(QStatusBar* bar, QAction* actionNotifications) :
- m_bar(bar), m_notifications(new StatusBarNotifications(actionNotifications)),
- m_progress(new QProgressBar), m_api(new QLabel)
+StatusBar::StatusBar(QStatusBar* bar, Ui::MainWindow* ui) :
+ m_bar(bar), m_progress(new QProgressBar),
+ m_notifications(new StatusBarAction(ui->actionNotifications)),
+ m_update(new StatusBarAction(ui->actionUpdate)),
+ m_api(new QLabel)
{
m_bar->addPermanentWidget(m_progress);
m_bar->addPermanentWidget(m_notifications);
+ m_bar->addPermanentWidget(m_update);
m_bar->addPermanentWidget(m_api);
m_progress->setTextVisible(true);
@@ -15,12 +19,15 @@ StatusBar::StatusBar(QStatusBar* bar, QAction* actionNotifications) :
m_progress->setMaximumWidth(150);
m_progress->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
+ m_update->set(false);
+ m_notifications->set(false);
+
m_api->setObjectName("apistats");
m_api->setStyleSheet("QLabel{ padding: 0.1em 0 0.1em 0; }");
m_bar->clearMessage();
setProgress(-1);
- updateAPI({}, {});
+ setAPI({}, {});
}
void StatusBar::setProgress(int percent)
@@ -35,12 +42,12 @@ void StatusBar::setProgress(int percent)
}
}
-void StatusBar::updateNotifications(bool hasNotifications)
+void StatusBar::setNotifications(bool hasNotifications)
{
- m_notifications->update(hasNotifications);
+ m_notifications->set(hasNotifications);
}
-void StatusBar::updateAPI(const APIStats& stats, const APIUserAccount& user)
+void StatusBar::setAPI(const APIStats& stats, const APIUserAccount& user)
{
m_api->setText(
QString("API: Q: %1 | D: %2 | H: %3")
@@ -73,13 +80,18 @@ void StatusBar::updateAPI(const APIStats& stats, const APIUserAccount& user)
m_api->setAutoFillBackground(true);
}
+void StatusBar::setUpdateAvailable(bool b)
+{
+ m_update->set(b);
+}
+
void StatusBar::checkSettings(const Settings& settings)
{
m_api->setVisible(!settings.hideAPICounter());
}
-StatusBarNotifications::StatusBarNotifications(QAction* action)
+StatusBarAction::StatusBarAction(QAction* action)
: m_action(action), m_icon(new QLabel), m_text(new QLabel)
{
setLayout(new QHBoxLayout);
@@ -88,19 +100,33 @@ StatusBarNotifications::StatusBarNotifications(QAction* action)
layout()->addWidget(m_text);
}
-void StatusBarNotifications::update(bool hasNotifications)
+void StatusBarAction::set(bool visible)
{
- if (hasNotifications) {
+ if (visible) {
m_icon->setPixmap(m_action->icon().pixmap(16, 16));
- m_text->setText(QObject::tr("Notifications"));
+ m_text->setText(cleanupActionText(m_action->text()));
}
- setVisible(hasNotifications);
+ setVisible(visible);
}
-void StatusBarNotifications::mouseDoubleClickEvent(QMouseEvent* e)
+void StatusBarAction::mouseDoubleClickEvent(QMouseEvent* e)
{
if (m_action->isEnabled()) {
m_action->trigger();
}
}
+
+QString StatusBarAction::cleanupActionText(const QString& original) const
+{
+ QString s = original;
+
+ s.replace(QRegExp("\\&([^&])"), "\\1"); // &Item -> Item
+ s.replace("&&", "&"); // &&Item -> &Item
+
+ if (s.endsWith("...")) {
+ s = s.left(s.size() - 3);
+ }
+
+ return s;
+}
diff --git a/src/statusbar.h b/src/statusbar.h
index 8edfd037..2baf12ee 100644
--- a/src/statusbar.h
+++ b/src/statusbar.h
@@ -7,14 +7,15 @@
struct APIStats;
class APIUserAccount;
class Settings;
+namespace Ui { class MainWindow; }
-class StatusBarNotifications : public QWidget
+class StatusBarAction : public QWidget
{
public:
- StatusBarNotifications(QAction* action);
+ StatusBarAction(QAction* action);
- void update(bool hasNotifications);
+ void set(bool visible);
protected:
void mouseDoubleClickEvent(QMouseEvent* e) override;
@@ -23,23 +24,27 @@ private:
QAction* m_action;
QLabel* m_icon;
QLabel* m_text;
+
+ QString cleanupActionText(const QString& s) const;
};
class StatusBar
{
public:
- StatusBar(QStatusBar* bar, QAction* actionNotifications);
+ StatusBar(QStatusBar* bar, Ui::MainWindow* ui);
void setProgress(int percent);
- void updateNotifications(bool hasNotifications);
- void updateAPI(const APIStats& stats, const APIUserAccount& user);
+ void setNotifications(bool hasNotifications);
+ void setAPI(const APIStats& stats, const APIUserAccount& user);
+ void setUpdateAvailable(bool b);
void checkSettings(const Settings& settings);
private:
QStatusBar* m_bar;
- StatusBarNotifications* m_notifications;
QProgressBar* m_progress;
+ StatusBarAction* m_notifications;
+ StatusBarAction* m_update;
QLabel* m_api;
};
--
cgit v1.3.1
From ba0b2c2a29d32d290a16d88ff71475dbd61a8ffd Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Thu, 13 Jun 2019 23:26:46 -0400
Subject: switched to stylesheet for api colors, palette doesn't seem to
survive hiding/unhiding very well
---
src/statusbar.cpp | 31 +++++++++++++++++++------------
1 file changed, 19 insertions(+), 12 deletions(-)
(limited to 'src')
diff --git a/src/statusbar.cpp b/src/statusbar.cpp
index 68c0642a..4effa6a3 100644
--- a/src/statusbar.cpp
+++ b/src/statusbar.cpp
@@ -23,7 +23,6 @@ StatusBar::StatusBar(QStatusBar* bar, Ui::MainWindow* ui) :
m_notifications->set(false);
m_api->setObjectName("apistats");
- m_api->setStyleSheet("QLabel{ padding: 0.1em 0 0.1em 0; }");
m_bar->clearMessage();
setProgress(-1);
@@ -55,28 +54,36 @@ void StatusBar::setAPI(const APIStats& stats, const APIUserAccount& user)
.arg(user.limits().remainingDailyRequests)
.arg(user.limits().remainingHourlyRequests));
- QColor textColor;
- QColor backgroundColor;
+ QString textColor;
+ QString backgroundColor;
if (user.type() == APIUserAccountTypes::None) {
- backgroundColor = Qt::transparent;
+ backgroundColor = "transparent";
} else if (user.remainingRequests() > 300) {
textColor = "white";
- backgroundColor = Qt::darkGreen;
+ backgroundColor = "darkgreen";
} else if (user.remainingRequests() < 150) {
textColor = "white";
- backgroundColor = Qt::darkRed;
+ backgroundColor = "darkred";
} else {
textColor = "black";
- backgroundColor = Qt::darkYellow;
+ backgroundColor = "rgb(226, 192, 0)"; // yellow
}
- QPalette palette = m_api->palette();
+ m_api->setStyleSheet(QString(R"(
+ QLabel
+ {
+ padding-left: 0.1em;
+ padding-right: 0.1em;
+ padding-top: 0;
+ padding-bottom: 0;
+ color: %1;
+ background-color: %2;
+ }
+ )")
+ .arg(textColor)
+ .arg(backgroundColor));
- palette.setColor(QPalette::WindowText, textColor);
- palette.setColor(QPalette::Background, backgroundColor);
-
- m_api->setPalette(palette);
m_api->setAutoFillBackground(true);
}
--
cgit v1.3.1
From a7757e8ba6f5d10feea9e58611bde4dcb911079b Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Thu, 13 Jun 2019 23:43:51 -0400
Subject: added option to hide the status bar centralized menu visibility into
a showMenuBar() function
---
src/mainwindow.cpp | 51 +++++++++++++++++++++++++++++++++++++++++++++------
src/mainwindow.h | 8 ++++++--
src/mainwindow.ui | 9 +++++++++
3 files changed, 60 insertions(+), 8 deletions(-)
(limited to 'src')
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 2497b05d..c255759b 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -203,6 +203,7 @@ MainWindow::MainWindow(QSettings &initSettings
, ui(new Ui::MainWindow)
, m_WasVisible(false)
, m_menuBarVisible(true)
+ , m_statusBarVisible(true)
, m_linksSeparator(nullptr)
, m_Tutorial(this, "MainWindow")
, m_OldProfileIndex(-1)
@@ -752,6 +753,7 @@ void MainWindow::toolbarMenu_aboutToShow()
ui->actionMainMenuToggle->setChecked(ui->menuBar->isVisible());
ui->actionToolBarMainToggle->setChecked(ui->toolBar->isVisible());
+ ui->actionStatusBarToggle->setChecked(ui->statusBar->isVisible());
ui->actionToolBarSmallIcons->setChecked(ui->toolBar->iconSize() == SmallToolbarSize);
ui->actionToolBarMediumIcons->setChecked(ui->toolBar->iconSize() == MediumToolbarSize);
@@ -769,8 +771,7 @@ QMenu* MainWindow::createPopupMenu()
void MainWindow::on_actionMainMenuToggle_triggered()
{
- ui->menuBar->setVisible(!ui->menuBar->isVisible());
- m_menuBarVisible = ui->menuBar->isVisible();
+ showMenuBar(!ui->menuBar->isVisible());
}
void MainWindow::on_actionToolBarMainToggle_triggered()
@@ -778,6 +779,11 @@ void MainWindow::on_actionToolBarMainToggle_triggered()
ui->toolBar->setVisible(!ui->toolBar->isVisible());
}
+void MainWindow::on_actionStatusBarToggle_triggered()
+{
+ showStatusBar(!ui->statusBar->isVisible());
+}
+
void MainWindow::on_actionToolBarSmallIcons_triggered()
{
setToolbarSize(SmallToolbarSize);
@@ -822,6 +828,36 @@ void MainWindow::setToolbarButtonStyle(Qt::ToolButtonStyle s)
}
}
+void MainWindow::showMenuBar(bool b)
+{
+ ui->menuBar->setVisible(b);
+ m_menuBarVisible = b;
+}
+
+void MainWindow::showStatusBar(bool b)
+{
+ ui->statusBar->setVisible(b);
+ m_statusBarVisible = b;
+
+ // the central widget typically has no bottom padding because the status bar
+ // is more than enough, but when it's hidden, the bottom widget (currently
+ // the log) touches the bottom border of the window, which looks ugly
+ //
+ // when hiding the statusbar, the central widget is given the same border
+ // margin as it has on the top (which is typically 6, as it's the default from
+ // the qt designer)
+
+ auto m = ui->centralWidget->layout()->contentsMargins();
+
+ if (b) {
+ m.setBottom(0);
+ } else {
+ m.setBottom(m.top());
+ }
+
+ ui->centralWidget->layout()->setContentsMargins(m);
+}
+
void MainWindow::on_centralWidget_customContextMenuRequested(const QPoint &pos)
{
// this allows for getting the context menu even if both the menubar and all
@@ -2096,8 +2132,11 @@ void MainWindow::readSettings()
}
if (settings.contains("menubar_visible")) {
- m_menuBarVisible = settings.value("menubar_visible").toBool();
- ui->menuBar->setVisible(m_menuBarVisible);
+ showMenuBar(settings.value("menubar_visible").toBool());
+ }
+
+ if (settings.contains("statusbar_visible")) {
+ showStatusBar(settings.value("statusbar_visible").toBool());
}
if (settings.contains("window_split")) {
@@ -2193,6 +2232,7 @@ void MainWindow::storeSettings(QSettings &settings) {
settings.setValue("toolbar_size", ui->toolBar->iconSize());
settings.setValue("toolbar_button_style", static_cast(ui->toolBar->toolButtonStyle()));
settings.setValue("menubar_visible", m_menuBarVisible);
+ settings.setValue("statusbar_visible", m_statusBarVisible);
settings.setValue("window_split", ui->splitter->saveState());
settings.setValue("window_monitor", QApplication::desktop()->screenNumber(this));
settings.setValue("log_split", ui->topLevelSplitter->saveState());
@@ -6989,8 +7029,7 @@ void MainWindow::keyReleaseEvent(QKeyEvent *event)
// if the menubar is hidden, pressing Alt will make it visible
if (event->key() == Qt::Key_Alt) {
if (!ui->menuBar->isVisible()) {
- ui->menuBar->setVisible(true);
- m_menuBarVisible = true;
+ showMenuBar(true);
}
}
diff --git a/src/mainwindow.h b/src/mainwindow.h
index e2c6ce8b..88389738 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -326,8 +326,8 @@ private:
bool m_WasVisible;
// this has to be remembered because by the time storeSettings() is called,
- // the window is closed and the menubar is hidden
- bool m_menuBarVisible;
+ // the window is closed and the all bars are hidden
+ bool m_menuBarVisible, m_statusBarVisible;
std::unique_ptr m_statusBar;
@@ -651,6 +651,7 @@ private slots: // ui slots
void on_actionExit_triggered();
void on_actionMainMenuToggle_triggered();
void on_actionToolBarMainToggle_triggered();
+ void on_actionStatusBarToggle_triggered();
void on_actionToolBarSmallIcons_triggered();
void on_actionToolBarMediumIcons_triggered();
void on_actionToolBarLargeIcons_triggered();
@@ -694,6 +695,9 @@ private slots: // ui slots
void on_categoriesAndBtn_toggled(bool checked);
void on_categoriesOrBtn_toggled(bool checked);
void on_managedArchiveLabel_linkHovered(const QString &link);
+
+ void showMenuBar(bool b);
+ void showStatusBar(bool b);
};
diff --git a/src/mainwindow.ui b/src/mainwindow.ui
index bbcb734c..98743b7e 100644
--- a/src/mainwindow.ui
+++ b/src/mainwindow.ui
@@ -1397,6 +1397,7 @@ p, li { white-space: pre-wrap; }
+
@@ -1732,6 +1733,14 @@ p, li { white-space: pre-wrap; }
&Menu
+
+
+ true
+
+
+ St&atus bar
+
+
--
cgit v1.3.1
From 616925ebbb8e916119f8dbee0c1f0cb97b14a68b Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Fri, 14 Jun 2019 01:38:07 -0400
Subject: moved api user account classes to their own files api label in status
bar: - now shows when not logged in - changed some of the colour thresholds
to correspond to real throttling numbers make sure the api key is also
cleared from the access manager when clearing from the settings removed
unused bool m_ValidateAttempted in NXMAccessManager update the window title
and status bar api label with correct values on startup, which fixes
incorrect values when "restarting" MO after changing nexus settings
---
src/CMakeLists.txt | 3 ++
src/apiuseraccount.cpp | 67 ++++++++++++++++++++++++
src/apiuseraccount.h | 129 ++++++++++++++++++++++++++++++++++++++++++++++
src/mainwindow.cpp | 13 +++--
src/nexusinterface.cpp | 78 ++++------------------------
src/nexusinterface.h | 131 ++---------------------------------------------
src/nxmaccessmanager.cpp | 17 ++++--
src/nxmaccessmanager.h | 7 +--
src/settingsdialog.cpp | 6 ++-
src/statusbar.cpp | 34 +++++++-----
10 files changed, 263 insertions(+), 222 deletions(-)
create mode 100644 src/apiuseraccount.cpp
create mode 100644 src/apiuseraccount.h
(limited to 'src')
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 71f87a8a..5623a851 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -117,6 +117,7 @@ SET(organizer_SRCS
forcedloaddialogwidget.cpp
filterwidget.cpp
statusbar.cpp
+ apiuseraccount.cpp
shared/windows_error.cpp
shared/error_report.cpp
@@ -215,6 +216,7 @@ SET(organizer_HDRS
forcedloaddialogwidget.h
filterwidget.h
statusbar.h
+ apiuseraccount.h
shared/windows_error.h
shared/error_report.h
@@ -299,6 +301,7 @@ set(core
nxmaccessmanager
organizercore
organizerproxy
+ apiuseraccount
)
set(dialogs
diff --git a/src/apiuseraccount.cpp b/src/apiuseraccount.cpp
new file mode 100644
index 00000000..b901e41a
--- /dev/null
+++ b/src/apiuseraccount.cpp
@@ -0,0 +1,67 @@
+#include "apiuseraccount.h"
+
+APIUserAccount::APIUserAccount()
+ : m_type(APIUserAccountTypes::None)
+{
+}
+
+const QString& APIUserAccount::id() const
+{
+ return m_id;
+}
+
+const QString& APIUserAccount::name() const
+{
+ return m_name;
+}
+
+APIUserAccountTypes APIUserAccount::type() const
+{
+ return m_type;
+}
+
+const APILimits& APIUserAccount::limits() const
+{
+ return m_limits;
+}
+
+APIUserAccount& APIUserAccount::id(const QString& id)
+{
+ m_id = id;
+ return *this;
+}
+
+APIUserAccount& APIUserAccount::name(const QString& name)
+{
+ m_name = name;
+ return *this;
+}
+
+APIUserAccount& APIUserAccount::type(APIUserAccountTypes type)
+{
+ m_type = type;
+ return *this;
+}
+
+APIUserAccount& APIUserAccount::limits(const APILimits& limits)
+{
+ m_limits = limits;
+ return *this;
+}
+
+int APIUserAccount::remainingRequests() const
+{
+ return std::max(
+ m_limits.remainingDailyRequests,
+ m_limits.remainingHourlyRequests);
+}
+
+bool APIUserAccount::shouldThrottle() const
+{
+ return (remainingRequests() < ThrottleThreshold);
+}
+
+bool APIUserAccount::exhausted() const
+{
+ return (remainingRequests() <= 0);
+}
diff --git a/src/apiuseraccount.h b/src/apiuseraccount.h
new file mode 100644
index 00000000..8a238d71
--- /dev/null
+++ b/src/apiuseraccount.h
@@ -0,0 +1,129 @@
+#ifndef APIUSERACCOUNT_H
+#define APIUSERACCOUNT_H
+
+#include
+
+/**
+* represents user account types on a mod provider website such as nexus
+*/
+enum class APIUserAccountTypes
+{
+ // not logged in
+ None = 0,
+
+ // regular account
+ Regular,
+
+ // premium account
+ Premium
+};
+
+
+/**
+* current limits imposed on the user account
+**/
+struct APILimits
+{
+ // maximum number of requests per day
+ int maxDailyRequests = 0;
+
+ // remaining number of requests today
+ int remainingDailyRequests = 0;
+
+ // maximum number of requests per hour
+ int maxHourlyRequests = 0;
+
+ // remaining number of requests this hour
+ int remainingHourlyRequests = 0;
+};
+
+
+/**
+* API statistics
+*/
+struct APIStats
+{
+ // number of API requests currently queued
+ int requestsQueued = 0;
+};
+
+
+/**
+* represents a user account on the mod provier website
+*/
+class APIUserAccount
+{
+public:
+ // when the number of remanining requests is under this number, further
+ // requests will be throttled by avoiding non-critical ones
+ static const int ThrottleThreshold = 200;
+
+ APIUserAccount();
+
+ /**
+ * user id
+ */
+ const QString& id() const;
+
+ /**
+ * user name
+ */
+ const QString& name() const;
+
+ /**
+ * account type
+ */
+ APIUserAccountTypes type() const;
+
+ /**
+ * current API limits
+ */
+ const APILimits& limits() const;
+
+
+ /**
+ * sets the user id
+ */
+ APIUserAccount& id(const QString& id);
+
+ /**
+ * sets the user name
+ **/
+ APIUserAccount& name(const QString& name);
+
+ /**
+ * sets the acount type
+ */
+ APIUserAccount& type(APIUserAccountTypes type);
+
+ /**
+ * sets the current limits
+ */
+ APIUserAccount& limits(const APILimits& limits);
+
+
+ /**
+ * returns the number of remaining requests
+ */
+ int remainingRequests() const;
+
+ /**
+ * whether the number of remaining requests is low enough that further
+ * requests should be throttled
+ */
+ bool shouldThrottle() const;
+
+ /**
+ * true if all the remaining requests have been used and the API will refuse
+ * further requests
+ */
+ bool exhausted() const;
+
+private:
+ QString m_id, m_name;
+ APIUserAccountTypes m_type;
+ APILimits m_limits;
+ APIStats m_stats;
+};
+
+#endif // APIUSERACCOUNT_H
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index c255759b..5018479d 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -225,8 +225,17 @@ MainWindow::MainWindow(QSettings &initSettings
QWebEngineProfile::defaultProfile()->setHttpCacheMaximumSize(52428800);
QWebEngineProfile::defaultProfile()->setCachePath(m_OrganizerCore.settings().getCacheDirectory());
QWebEngineProfile::defaultProfile()->setPersistentStoragePath(m_OrganizerCore.settings().getCacheDirectory());
+
ui->setupUi(this);
- updateWindowTitle({});
+
+ {
+ auto* ni = NexusInterface::instance(&m_PluginContainer);
+
+ updateWindowTitle(ni->getAPIUserAccount());
+
+ m_statusBar.reset(new StatusBar(statusBar(), ui));
+ m_statusBar->setAPI(ni->getAPIStats(), ni->getAPIUserAccount());
+ }
languageChange(m_OrganizerCore.settings().language());
@@ -244,8 +253,6 @@ MainWindow::MainWindow(QSettings &initSettings
connect(ui->logList->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
ui->logList, SLOT(scrollToBottom()));
- m_statusBar.reset(new StatusBar(statusBar(), ui));
-
updateProblemsButton();
setupToolbar();
diff --git a/src/nexusinterface.cpp b/src/nexusinterface.cpp
index 8362143a..ee9acf2c 100644
--- a/src/nexusinterface.cpp
+++ b/src/nexusinterface.cpp
@@ -49,71 +49,6 @@ void throttledWarning(const APIUserAccount& user)
}
-APIUserAccount::APIUserAccount()
- : m_type(APIUserAccountTypes::None)
-{
-}
-
-const QString& APIUserAccount::id() const
-{
- return m_id;
-}
-
-const QString& APIUserAccount::name() const
-{
- return m_name;
-}
-
-APIUserAccountTypes APIUserAccount::type() const
-{
- return m_type;
-}
-
-const APILimits& APIUserAccount::limits() const
-{
- return m_limits;
-}
-
-APIUserAccount& APIUserAccount::id(const QString& id)
-{
- m_id = id;
- return *this;
-}
-
-APIUserAccount& APIUserAccount::name(const QString& name)
-{
- m_name = name;
- return *this;
-}
-
-APIUserAccount& APIUserAccount::type(APIUserAccountTypes type)
-{
- m_type = type;
- return *this;
-}
-
-APIUserAccount& APIUserAccount::limits(const APILimits& limits)
-{
- m_limits = limits;
- return *this;
-}
-
-int APIUserAccount::remainingRequests() const
-{
- return m_limits.remainingDailyRequests + m_limits.remainingHourlyRequests;
-}
-
-bool APIUserAccount::shouldThrottle() const
-{
- return (remainingRequests() < ThrottleThreshold);
-}
-
-bool APIUserAccount::exhausted() const
-{
- return (remainingRequests() <= 0);
-}
-
-
NexusBridge::NexusBridge(PluginContainer *pluginContainer, const QString &subModule)
: m_Interface(NexusInterface::instance(pluginContainer))
, m_SubModule(subModule)
@@ -325,7 +260,7 @@ void NexusInterface::loginCompleted()
void NexusInterface::setUserAccount(const APIUserAccount& user)
{
m_User = user;
- emit requestsChanged(stats(), m_User);
+ emit requestsChanged(getAPIStats(), m_User);
}
void NexusInterface::interpretNexusFileName(const QString &fileName, QString &modName, int &modID, bool query)
@@ -884,7 +819,7 @@ void NexusInterface::requestFinished(std::list::iterator iter)
qWarning("All API requests have been consumed and are now being denied.");
}
- emit requestsChanged(stats(), m_User);
+ emit requestsChanged(getAPIStats(), m_User);
qWarning("Error: %s", reply->errorString().toUtf8().constData());
} else {
qWarning("request failed: %s", reply->errorString().toUtf8().constData());
@@ -960,7 +895,7 @@ void NexusInterface::requestFinished(std::list::iterator iter)
}
m_User.limits(parseLimits(reply));
- emit requestsChanged(stats(), m_User);
+ emit requestsChanged(getAPIStats(), m_User);
} else {
emit nxmRequestFailed(iter->m_GameName, iter->m_ModID, iter->m_FileID, iter->m_UserData, iter->m_ID, reply->error(), tr("invalid response"));
}
@@ -1017,7 +952,12 @@ void NexusInterface::requestTimeout()
}
}
-APIStats NexusInterface::stats() const
+APIUserAccount NexusInterface::getAPIUserAccount() const
+{
+ return m_User;
+}
+
+APIStats NexusInterface::getAPIStats() const
{
APIStats stats;
stats.requestsQueued = m_RequestQueue.size();
diff --git a/src/nexusinterface.h b/src/nexusinterface.h
index 6c4e8d11..6e768149 100644
--- a/src/nexusinterface.h
+++ b/src/nexusinterface.h
@@ -20,6 +20,8 @@ along with Mod Organizer. If not, see .
#ifndef NEXUSINTERFACE_H
#define NEXUSINTERFACE_H
+#include "apiuseraccount.h"
+
#include
#include
#include
@@ -40,130 +42,6 @@ class NexusInterface;
class NXMAccessManager;
-/**
- * represents user account types on a mod provider website such as nexus
- */
-enum class APIUserAccountTypes
-{
- // not logged in
- None = 0,
-
- // regular account
- Regular,
-
- // premium account
- Premium
-};
-
-
-/**
- * current limits imposed on the user account
- **/
-struct APILimits
-{
- // maximum number of requests per day
- int maxDailyRequests = 0;
-
- // remaining number of requests today
- int remainingDailyRequests = 0;
-
- // maximum number of requests per hour
- int maxHourlyRequests = 0;
-
- // remaining number of requests this hour
- int remainingHourlyRequests = 0;
-};
-
-
-/**
- * API statistics
- */
-struct APIStats
-{
- // number of API requests currently queued
- int requestsQueued = 0;
-};
-
-
-/**
- * represents a user account on the mod provier website
- */
-class APIUserAccount
-{
-public:
- // when the number of remanining requests is under this number, further
- // requests will be throttled by avoiding non-critical ones
- static const int ThrottleThreshold = 300;
-
- APIUserAccount();
-
- /**
- * user id
- */
- const QString& id() const;
-
- /**
- * user name
- */
- const QString& name() const;
-
- /**
- * account type
- */
- APIUserAccountTypes type() const;
-
- /**
- * current API limits
- */
- const APILimits& limits() const;
-
-
- /**
- * sets the user id
- */
- APIUserAccount& id(const QString& id);
-
- /**
- * sets the user name
- **/
- APIUserAccount& name(const QString& name);
-
- /**
- * sets the acount type
- */
- APIUserAccount& type(APIUserAccountTypes type);
-
- /**
- * sets the current limits
- */
- APIUserAccount& limits(const APILimits& limits);
-
-
- /**
- * returns the number of remaining requests
- */
- int remainingRequests() const;
-
- /**
- * whether the number of remaining requests is low enough that further
- * requests should be throttled
- */
- bool shouldThrottle() const;
-
- /**
- * true if all the remaining requests have been used and the API will refuse
- * further requests
- */
- bool exhausted() const;
-
-private:
- QString m_id, m_name;
- APIUserAccountTypes m_type;
- APILimits m_limits;
- APIStats m_stats;
-};
-
-
/**
* @brief convenience class to make nxm requests easier
* usually, all objects that started a nxm request will be signaled if one finished.
@@ -521,6 +399,9 @@ public:
std::vector> getGameChoices(const MOBase::IPluginGame *game);
+ APIUserAccount getAPIUserAccount() const;
+ APIStats getAPIStats() const;
+
public:
/**
@@ -667,8 +548,6 @@ private:
MOBase::VersionInfo m_MOVersion;
PluginContainer *m_PluginContainer;
APIUserAccount m_User;
-
- APIStats stats() const;
};
#endif // NEXUSINTERFACE_H
diff --git a/src/nxmaccessmanager.cpp b/src/nxmaccessmanager.cpp
index 5886d3ee..ee6c03f1 100644
--- a/src/nxmaccessmanager.cpp
+++ b/src/nxmaccessmanager.cpp
@@ -190,6 +190,7 @@ void NXMAccessManager::apiCheck(const QString &apiKey, bool force)
emit validateSuccessful(false);
return;
}
+
m_ApiKey = apiKey;
startValidationCheck();
}
@@ -218,6 +219,13 @@ QString NXMAccessManager::apiKey() const
return m_ApiKey;
}
+void NXMAccessManager::clearApiKey()
+{
+ m_ApiKey = "";
+ m_ValidateState = VALIDATE_NOT_VALID;
+
+ emit credentialsReceived(APIUserAccount());
+}
void NXMAccessManager::validateTimeout()
{
@@ -233,7 +241,6 @@ void NXMAccessManager::validateTimeout()
if (m_ValidateReply != nullptr) {
m_ValidateReply->deleteLater();
m_ValidateReply = nullptr;
- m_ValidateAttempted = false; // this usually means we might have success later
}
emit validateFailed(tr("There was a timeout during the request"));
@@ -280,17 +287,21 @@ void NXMAccessManager::validateFinished()
QString name = credentialsData.value("name").toString();
bool premium = credentialsData.value("is_premium").toBool();
- emit credentialsReceived(APIUserAccount()
+ const auto user = APIUserAccount()
.id(QString("%1").arg(id))
.name(name)
.type(premium ? APIUserAccountTypes::Premium : APIUserAccountTypes::Regular)
- .limits(NexusInterface::parseLimits(m_ValidateReply)));
+ .limits(NexusInterface::parseLimits(m_ValidateReply));
+
+
+ emit credentialsReceived(user);
m_ValidateReply->deleteLater();
m_ValidateReply = nullptr;
m_ValidateState = VALIDATE_VALID;
emit validateSuccessful(true);
+
} else {
m_ApiKey.clear();
m_ValidateState = VALIDATE_NOT_VALID;
diff --git a/src/nxmaccessmanager.h b/src/nxmaccessmanager.h
index 1d23faf9..1bdeae40 100644
--- a/src/nxmaccessmanager.h
+++ b/src/nxmaccessmanager.h
@@ -20,6 +20,7 @@ along with Mod Organizer. If not, see .
#ifndef NXMACCESSMANAGER_H
#define NXMACCESSMANAGER_H
+#include "apiuseraccount.h"
#include
#include
#include
@@ -28,8 +29,6 @@ along with Mod Organizer. If not, see .
namespace MOBase { class IPluginGame; }
-class APIUserAccount;
-
/**
* @brief access manager extended to handle nxm links
**/
@@ -56,6 +55,7 @@ public:
QString userAgent(const QString &subModule = QString()) const;
QString apiKey() const;
+ void clearApiKey();
void startValidationCheck();
@@ -94,7 +94,6 @@ protected:
QIODevice *device);
private:
-
QTimer m_ValidateTimeout;
QNetworkReply *m_ValidateReply;
QProgressDialog *m_ProgressDialog { nullptr };
@@ -103,7 +102,6 @@ private:
QString m_ApiKey;
- bool m_ValidateAttempted;
enum {
VALIDATE_NOT_CHECKED,
VALIDATE_CHECKING,
@@ -112,7 +110,6 @@ private:
VALIDATE_REFUSED,
VALIDATE_VALID
} m_ValidateState = VALIDATE_NOT_CHECKED;
-
};
#endif // NXMACCESSMANAGER_H
diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp
index b3e8c8a7..95e4ceb0 100644
--- a/src/settingsdialog.cpp
+++ b/src/settingsdialog.cpp
@@ -511,6 +511,9 @@ bool SettingsDialog::clearKey()
m_KeyCleared = true;
const auto ret = m_settings->clearNexusApiKey();
updateNexusButtons();
+
+ NexusInterface::instance(m_PluginContainer)->getAccessManager()->clearApiKey();
+
return ret;
}
@@ -522,8 +525,7 @@ void SettingsDialog::testApiKey()
return;
}
- auto* am = NexusInterface::instance(m_PluginContainer)->getAccessManager();
- am->apiCheck(key, true);
+ NexusInterface::instance(m_PluginContainer)->getAccessManager()->apiCheck(key, true);
}
void SettingsDialog::updateNexusButtons()
diff --git a/src/statusbar.cpp b/src/statusbar.cpp
index 4effa6a3..712eb005 100644
--- a/src/statusbar.cpp
+++ b/src/statusbar.cpp
@@ -48,28 +48,34 @@ void StatusBar::setNotifications(bool hasNotifications)
void StatusBar::setAPI(const APIStats& stats, const APIUserAccount& user)
{
- m_api->setText(
- QString("API: Q: %1 | D: %2 | H: %3")
- .arg(stats.requestsQueued)
- .arg(user.limits().remainingDailyRequests)
- .arg(user.limits().remainingHourlyRequests));
-
+ QString text;
QString textColor;
QString backgroundColor;
if (user.type() == APIUserAccountTypes::None) {
- backgroundColor = "transparent";
- } else if (user.remainingRequests() > 300) {
- textColor = "white";
- backgroundColor = "darkgreen";
- } else if (user.remainingRequests() < 150) {
+ text = "API: not logged in";
textColor = "white";
- backgroundColor = "darkred";
+ backgroundColor = "transparent";
} else {
- textColor = "black";
- backgroundColor = "rgb(226, 192, 0)"; // yellow
+ text = QString("API: Queued: %1 | Daily: %2 | Hourly: %3")
+ .arg(stats.requestsQueued)
+ .arg(user.limits().remainingDailyRequests)
+ .arg(user.limits().remainingHourlyRequests);
+
+ if (user.remainingRequests() > 500) {
+ textColor = "white";
+ backgroundColor = "darkgreen";
+ } else if (user.remainingRequests() > 200) {
+ textColor = "black";
+ backgroundColor = "rgb(226, 192, 0)"; // yellow
+ } else {
+ textColor = "white";
+ backgroundColor = "darkred";
+ }
}
+ m_api->setText(text);
+
m_api->setStyleSheet(QString(R"(
QLabel
{
--
cgit v1.3.1
From a7c48a05f857e9ff8c0bd25abc1bb595e580149d Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Fri, 14 Jun 2019 01:41:17 -0400
Subject: fixed text color of api label when not logged in
---
src/statusbar.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'src')
diff --git a/src/statusbar.cpp b/src/statusbar.cpp
index 712eb005..8502802a 100644
--- a/src/statusbar.cpp
+++ b/src/statusbar.cpp
@@ -54,7 +54,7 @@ void StatusBar::setAPI(const APIStats& stats, const APIUserAccount& user)
if (user.type() == APIUserAccountTypes::None) {
text = "API: not logged in";
- textColor = "white";
+ textColor = "initial";
backgroundColor = "transparent";
} else {
text = QString("API: Queued: %1 | Daily: %2 | Hourly: %3")
--
cgit v1.3.1
From a75f54e5221b359d5a1e5c0d669c6ab2e3d297b2 Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Fri, 14 Jun 2019 01:44:53 -0400
Subject: show executable path in status bar
---
src/mainwindow.cpp | 1 +
1 file changed, 1 insertion(+)
(limited to 'src')
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 5018479d..1d51b42e 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -727,6 +727,7 @@ void MainWindow::updatePinnedExecutables()
iconForExecutable(iter->m_BinaryInfo.filePath()), iter->m_Title);
exeAction->setObjectName(QString("custom__") + iter->m_Title);
+ exeAction->setStatusTip(iter->m_BinaryInfo.filePath());
if (!connect(exeAction, SIGNAL(triggered()), this, SLOT(startExeAction()))) {
qDebug("failed to connect trigger?");
--
cgit v1.3.1
From d527d62b2b671b52e74a34f24a701c18d7632477 Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Fri, 14 Jun 2019 01:53:31 -0400
Subject: changed the notifications action back to being disabled when there
aren't any, having a coloured and clickable icon was confusing
---
src/mainwindow.cpp | 2 ++
1 file changed, 2 insertions(+)
(limited to 'src')
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 1d51b42e..250bc1d7 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -934,6 +934,8 @@ void MainWindow::updateProblemsButton()
final = original;
}
+ ui->actionNotifications->setEnabled(numProblems > 0);
+
// setting the icon on the action (shown on the menu)
ui->actionNotifications->setIcon(final);
--
cgit v1.3.1
From eed0f1503d2b2bf03d1ad823c72f7d279a1b41f6 Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Fri, 14 Jun 2019 02:05:06 -0400
Subject: re-added the api label tooltip comments
---
src/mainwindow.cpp | 21 +++++++++++++++++++--
src/statusbar.cpp | 7 +++++++
2 files changed, 26 insertions(+), 2 deletions(-)
(limited to 'src')
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 250bc1d7..205ab7cc 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -227,13 +227,30 @@ MainWindow::MainWindow(QSettings &initSettings
QWebEngineProfile::defaultProfile()->setPersistentStoragePath(m_OrganizerCore.settings().getCacheDirectory());
ui->setupUi(this);
+ m_statusBar.reset(new StatusBar(statusBar(), ui));
{
auto* ni = NexusInterface::instance(&m_PluginContainer);
+ // there are two ways to get here:
+ // 1) the user just started MO, and
+ // 2) the user has changed some setting that required a restart
+ //
+ // "restarting" MO doesn't actually re-execute the binary, it just basically
+ // executes most of main() again, so a bunch of things are actually not
+ // reset
+ //
+ // one of these things is the api status, which will have fired its events
+ // long before the execution gets here because stuff is still cached and no
+ // real request to nexus is actually done
+ //
+ // therefore, when the user starts MO normally, the user account and stats
+ // will be empty (which is fine) and populated later on when the api key
+ // check has finished
+ //
+ // in the rare case where the user restarts MO through the settings, this
+ // will correctly pick up the previous values
updateWindowTitle(ni->getAPIUserAccount());
-
- m_statusBar.reset(new StatusBar(statusBar(), ui));
m_statusBar->setAPI(ni->getAPIStats(), ni->getAPIUserAccount());
}
diff --git a/src/statusbar.cpp b/src/statusbar.cpp
index 8502802a..01449202 100644
--- a/src/statusbar.cpp
+++ b/src/statusbar.cpp
@@ -23,6 +23,13 @@ StatusBar::StatusBar(QStatusBar* bar, Ui::MainWindow* ui) :
m_notifications->set(false);
m_api->setObjectName("apistats");
+ m_api->setToolTip(QObject::tr(
+ "This tracks the number of queued Nexus API requests, as well as the "
+ "remaining daily and hourly requests. The Nexus API limits you to a pool "
+ "of requests per day and requests per hour. It is dynamically updated "
+ "every time a request is completed. If you run out of requests, you will "
+ "be unable to queue downloads, check updates, parse mod info, or even log "
+ "in. Both pools must be consumed before this happens."));
m_bar->clearMessage();
setProgress(-1);
--
cgit v1.3.1