diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp index ce6ba665d..33be6a6ec 100644 --- a/src/downloadmanager.cpp +++ b/src/downloadmanager.cpp @@ -42,6 +42,7 @@ along with Mod Organizer. If not, see . #include #include #include +#include #include #include @@ -1365,7 +1366,11 @@ QString DownloadManager::getDisplayName(int index) const } DownloadInfo* info = m_ActiveDownloads.at(index); + return displayNameByInfo(info); +} +QString DownloadManager::displayNameByInfo(const DownloadInfo* info) const +{ QTextDocument doc; if (!info->m_FileInfo->name.isEmpty()) { doc.setHtml(info->m_FileInfo->name); @@ -1789,6 +1794,11 @@ void DownloadManager::nxmDescriptionAvailable(QString, int, QVariant userData, info->m_FileInfo->modName = doc.toPlainText(); if (info->m_FileInfo->fileID != 0) { setState(info, STATE_READY); + if (m_OrganizerCore->settings().interface().showDownloadNotifications()) { + m_OrganizerCore->showNotification( + tr("Download complete"), + tr("%1 is ready to be installed.").arg(displayNameByInfo(info))); + } } else { setState(info, STATE_FETCHINGFILEINFO); } @@ -2278,6 +2288,12 @@ void DownloadManager::downloadFinished(int index) emit showMessage(tr("Download failed: %1 (%2)") .arg(reply->errorString()) .arg(reply->error())); + if (m_OrganizerCore->settings().interface().showDownloadNotifications()) { + m_OrganizerCore->showNotification( + tr("Download failed"), + tr("%1 failed to download.").arg(displayNameByInfo(info)), + QSystemTrayIcon::MessageIcon::Critical); + } } error = true; setState(info, STATE_ERROR); diff --git a/src/downloadmanager.h b/src/downloadmanager.h index abf909c86..0cdeae7f0 100644 --- a/src/downloadmanager.h +++ b/src/downloadmanager.h @@ -588,6 +588,8 @@ private slots: DownloadInfo* downloadInfoByID(unsigned int id); + QString displayNameByInfo(const DownloadInfo* info) const; + void removePending(QString gameName, int modID, int fileID); static QString getFileTypeString(int fileType); diff --git a/src/iuserinterface.h b/src/iuserinterface.h index 7ddc545d0..ae5ed880a 100644 --- a/src/iuserinterface.h +++ b/src/iuserinterface.h @@ -4,6 +4,7 @@ #include "modinfodialogfwd.h" #include #include +#include #include #include #include @@ -27,6 +28,10 @@ class IUserInterface virtual MOBase::DelayedFileWriterBase& archivesWriter() = 0; virtual QMainWindow* mainWindow() = 0; + + virtual void showNotification(const QString& title, const QString& message, + QSystemTrayIcon::MessageIcon icon = + QSystemTrayIcon::MessageIcon::Information) = 0; }; #endif // IUSERINTERFACE_H diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 5d5a88cec..f3f1bba0f 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -139,6 +139,7 @@ along with Mod Organizer. If not, see . #include #include #include +#include #include #include #include @@ -2259,6 +2260,12 @@ QMainWindow* MainWindow::mainWindow() return this; } +void MainWindow::showNotification(const QString& title, const QString& message, + QSystemTrayIcon::MessageIcon icon) +{ + m_SystemTrayManager->showNotification(title, message, icon); +} + void MainWindow::on_tabWidget_currentChanged(int index) { QWidget* currentWidget = ui->tabWidget->widget(index); diff --git a/src/mainwindow.h b/src/mainwindow.h index d3e1d480e..cc7e3366e 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -78,6 +78,7 @@ class DirectoryEntry; #include #include #include +#include #include #include #include @@ -156,6 +157,10 @@ class MainWindow : public QMainWindow, public IUserInterface return m_ArchiveListWriter; } + void showNotification(const QString& title, const QString& message, + QSystemTrayIcon::MessageIcon icon = + QSystemTrayIcon::MessageIcon::Information) override; + public slots: void refresherProgress(const DirectoryRefreshProgress* p); diff --git a/src/organizercore.cpp b/src/organizercore.cpp index a8fc67c27..53375ac13 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -539,6 +540,14 @@ std::wstring OrganizerCore::getGlobalCoreDumpPath() return {}; } +void OrganizerCore::showNotification(const QString& message, const QString& title, + QSystemTrayIcon::MessageIcon icon) +{ + if (m_UserInterface) { + m_UserInterface->showNotification(message, title, icon); + } +} + void OrganizerCore::setCurrentProfile(const QString& profileName) { if ((m_CurrentProfile != nullptr) && (profileName == m_CurrentProfile->name())) { diff --git a/src/organizercore.h b/src/organizercore.h index 80f340b68..d7810e1b6 100644 --- a/src/organizercore.h +++ b/src/organizercore.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -360,6 +361,10 @@ class OrganizerCore : public QObject, public MOBase::IPluginDiagnose static void setGlobalCoreDumpType(env::CoreDumpTypes type); static std::wstring getGlobalCoreDumpPath(); + void showNotification( + const QString& title, const QString& message, + QSystemTrayIcon::MessageIcon icon = QSystemTrayIcon::MessageIcon::Information); + public: MOBase::IModRepositoryBridge* createNexusBridge() const; QString profileName() const; diff --git a/src/settings.cpp b/src/settings.cpp index ef1785b16..0356cf944 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -2263,6 +2263,16 @@ void InterfaceSettings::setHideDownloadsAfterInstallation(bool b) set(m_Settings, "Settings", "autohide_downloads", b); } +bool InterfaceSettings::showDownloadNotifications() const +{ + return get(m_Settings, "Settings", "download_notifications", false); +} + +void InterfaceSettings::setShowDownloadNotifications(bool b) +{ + set(m_Settings, "Settings", "download_notifications", b); +} + bool InterfaceSettings::hideAPICounter() const { return get(m_Settings, "Settings", "hide_api_counter", false); diff --git a/src/settings.h b/src/settings.h index edc1d6445..1f5d2bc26 100644 --- a/src/settings.h +++ b/src/settings.h @@ -653,6 +653,11 @@ class InterfaceSettings bool hideDownloadsAfterInstallation() const; void setHideDownloadsAfterInstallation(bool b); + // whether to show notifications when downloads complete or fail + // + bool showDownloadNotifications() const; + void setShowDownloadNotifications(bool b); + // whether the API counter should be hidden // bool hideAPICounter() const; diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index 6011b1588..f1ff4f7d1 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -166,6 +166,19 @@ + + + + Show notifications when downloads complete or fail. + + + Show notifications when downloads complete or fail. + + + Show notifications for completed or failed downloads + + + @@ -178,10 +191,10 @@ - Check for Mod Organizer updates on Github on startup. + Check for Mod Organizer updates on GitHub on startup. - Check for Mod Organizer updates on Github on startup. + Check for Mod Organizer updates on GitHub on startup. Check for updates diff --git a/src/settingsdialoggeneral.cpp b/src/settingsdialoggeneral.cpp index 265c9db90..8daef5827 100644 --- a/src/settingsdialoggeneral.cpp +++ b/src/settingsdialoggeneral.cpp @@ -20,6 +20,8 @@ GeneralSettingsTab::GeneralSettingsTab(Settings& s, SettingsDialog& d) ui->showMetaBox->setChecked(settings().interface().metaDownloads()); ui->hideDownloadInstallBox->setChecked( settings().interface().hideDownloadsAfterInstallation()); + ui->showDownloadNotificationsBox->setChecked( + settings().interface().showDownloadNotifications()); // updates ui->checkForUpdates->setChecked(settings().checkForUpdates()); @@ -64,6 +66,8 @@ void GeneralSettingsTab::update() settings().interface().setMetaDownloads(ui->showMetaBox->isChecked()); settings().interface().setHideDownloadsAfterInstallation( ui->hideDownloadInstallBox->isChecked()); + settings().interface().setShowDownloadNotifications( + ui->showDownloadNotificationsBox->isChecked()); // updates settings().setCheckForUpdates(ui->checkForUpdates->isChecked()); diff --git a/src/systemtraymanager.cpp b/src/systemtraymanager.cpp index d885f1ebd..afbd598de 100644 --- a/src/systemtraymanager.cpp +++ b/src/systemtraymanager.cpp @@ -24,6 +24,7 @@ along with Mod Organizer. If not, see . #include #include #include +#include #include SystemTrayManager::SystemTrayManager(QMainWindow* parent, QDockWidget* logDock) @@ -42,11 +43,11 @@ SystemTrayManager::SystemTrayManager(QMainWindow* parent, QDockWidget* logDock) trayMenu->addAction(exitAction); m_SystemTrayIcon->setContextMenu(trayMenu); + m_SystemTrayIcon->show(); } void SystemTrayManager::minimizeToSystemTray() { - m_SystemTrayIcon->show(); m_Parent->hide(); if (m_LogDock->isFloating() && m_LogDock->isVisible()) { @@ -56,8 +57,6 @@ void SystemTrayManager::minimizeToSystemTray() void SystemTrayManager::restoreFromSystemTray() { - m_SystemTrayIcon->hide(); - m_Parent->showNormal(); m_Parent->raise(); m_Parent->activateWindow(); @@ -67,6 +66,12 @@ void SystemTrayManager::restoreFromSystemTray() } } +void SystemTrayManager::showNotification(const QString& title, const QString& message, + QSystemTrayIcon::MessageIcon icon) +{ + m_SystemTrayIcon->showMessage(title, message, icon); +} + void SystemTrayManager::on_systemTrayIcon_activated( QSystemTrayIcon::ActivationReason reason) { diff --git a/src/systemtraymanager.h b/src/systemtraymanager.h index 43a3b0e48..e7e03c093 100644 --- a/src/systemtraymanager.h +++ b/src/systemtraymanager.h @@ -21,8 +21,10 @@ along with Mod Organizer. If not, see . #define SYSTEMTRAYMANAGER_H #include +#include #include #include +#include #include class SystemTrayManager : public QObject @@ -35,6 +37,10 @@ class SystemTrayManager : public QObject void minimizeToSystemTray(); void restoreFromSystemTray(); + void showNotification( + const QString& title, const QString& message, + QSystemTrayIcon::MessageIcon icon = QSystemTrayIcon::MessageIcon::Information); + private: QMainWindow* m_Parent; QDockWidget* m_LogDock;