save, work on toasts

This commit is contained in:
Martin Rotter 2023-09-20 07:20:08 +02:00
parent 33deafe194
commit e3e1929436
16 changed files with 135 additions and 37 deletions

View File

@ -99,6 +99,8 @@ set(SOURCES
gui/notifications/notificationseditor.h
gui/notifications/singlenotificationeditor.cpp
gui/notifications/singlenotificationeditor.h
gui/notifications/articlelistnotification.cpp
gui/notifications/articlelistnotification.h
gui/reusable/baselineedit.cpp
gui/reusable/baselineedit.h
gui/reusable/basetreeview.cpp
@ -440,9 +442,10 @@ set(UI_FILES
gui/dialogs/formupdate.ui
gui/notifications/notificationseditor.ui
gui/notifications/singlenotificationeditor.ui
gui/notifications/articlelistnotification.ui
gui/notifications/toastnotification.ui
gui/reusable/networkproxydetails.ui
gui/itemdetails.ui
gui/notifications/toastnotification.ui
gui/richtexteditor/mrichtextedit.ui
gui/newspaperpreviewer.ui
gui/reusable/searchtextwidget.ui

View File

@ -1090,20 +1090,7 @@ void FormMain::showAddAccountDialog() {
}
void FormMain::reportABug() {
qApp
->showGuiMessage(Notification::Event::GeneralEvent,
GuiMessage(QDateTime::currentDateTime().toString(),
"Quisque ullamcorper ut purus nec tempus. Vivamus eros dolor, sagittis ultrices augue "
"ut, posuere fringilla lorem. Donec posuere, enim sit amet fermentum dignissim, tellus "
"lectus laoreet lectus, vestibulum laoreet felis tortor eget nunc. Curabitur sagittis "
"quam in scelerisque placerat. Vivamus vel porta tortor. Vivamus nec volutpat sem",
QSystemTrayIcon::MessageIcon::Information),
GuiMessageDestination(),
GuiAction("test", []() {
qDebugNN << "aa";
}));
// qApp->web()->openUrlInExternalBrowser(QSL(APP_URL_ISSUES_NEW));
qApp->web()->openUrlInExternalBrowser(QSL(APP_URL_ISSUES_NEW));
}
void FormMain::donate() {

View File

@ -0,0 +1,10 @@
// For license of this file, see <project-root-folder>/LICENSE.md.
#include "gui/notifications/articlelistnotification.h"
ArticleListNotification::ArticleListNotification(QWidget* parent) : BaseToastNotification(parent) {
m_ui.setupUi(this);
setupCloseButton(m_ui.m_btnClose);
setupTimedClosing();
}

View File

@ -0,0 +1,20 @@
// For license of this file, see <project-root-folder>/LICENSE.md.
#ifndef ARTICLELISTNOTIFICATION_H
#define ARTICLELISTNOTIFICATION_H
#include "gui/notifications/basetoastnotification.h"
#include "ui_articlelistnotification.h"
class ArticleListNotification : public BaseToastNotification {
Q_OBJECT
public:
explicit ArticleListNotification(QWidget* parent = nullptr);
private:
Ui::ArticleListNotification m_ui;
};
#endif // ARTICLELISTNOTIFICATION_H

View File

@ -26,7 +26,7 @@ BaseToastNotification::BaseToastNotification(QWidget* parent) : QDialog(parent)
#endif
Qt::WindowType::FramelessWindowHint | Qt::WindowType::WindowStaysOnTopHint | Qt::WindowType::WindowSystemMenuHint);
setStyleSheet(QSL("BaseToastNotification { border: 1px solid black; }"));
setStyleSheet(QSL("BaseToastNotification { border: 1px solid %1; }").arg(palette().windowText().color().name()));
installEventFilter(this);
}

View File

@ -14,9 +14,6 @@ class BaseToastNotification : public QDialog {
explicit BaseToastNotification(QWidget* parent = nullptr);
virtual ~BaseToastNotification();
// If true, then notification is always moved as close to top as possible.
virtual bool alwaysOnTop() const = 0;
public slots:
virtual void reject();

View File

@ -21,7 +21,7 @@ ToastNotification::ToastNotification(Notification::Event event,
const GuiMessage& msg,
const GuiAction& action,
QWidget* parent)
: BaseToastNotification(parent) {
: BaseToastNotification() {
m_ui.setupUi(this);
setupHeading();
@ -31,10 +31,6 @@ ToastNotification::ToastNotification(Notification::Event event,
loadNotification(event, msg, action);
}
bool ToastNotification::alwaysOnTop() const {
return false;
}
void ToastNotification::loadNotification(Notification::Event event, const GuiMessage& msg, const GuiAction& action) {
m_ui.m_lblTitle->setText(msg.m_title);
m_ui.m_lblBody->setText(msg.m_message);

View File

@ -18,8 +18,6 @@ class ToastNotification : public BaseToastNotification {
const GuiAction& action,
QWidget* parent = nullptr);
virtual bool alwaysOnTop() const;
private:
void setupHeading();
void loadNotification(Notification::Event event, const GuiMessage& msg, const GuiAction& action);

View File

@ -4,14 +4,16 @@
#include "3rd-party/boolinq/boolinq.h"
#include "gui/notifications/basetoastnotification.h"
#include "gui/notifications/articlelistnotification.h"
#include "gui/notifications/toastnotification.h"
#include <QRect>
#include <QScreen>
#include <QWindow>
ToastNotificationsManager::ToastNotificationsManager(QObject* parent)
: QObject(parent), m_position(NotificationPosition::BottomRight), m_screen(-1) {}
ToastNotificationsManager::ToastNotificationsManager(NotificationPosition position, int screen, QObject* parent)
: QObject(parent), m_position(position), m_screen(screen), m_articleListNotification(nullptr) {}
ToastNotificationsManager::~ToastNotificationsManager() {
clear();
@ -39,7 +41,7 @@ void ToastNotificationsManager::setPosition(NotificationPosition position) {
void ToastNotificationsManager::clear() {
for (BaseToastNotification* notif : m_activeNotifications) {
closeNotification(notif);
closeNotification(notif, true);
}
m_activeNotifications.clear();
@ -74,12 +76,48 @@ void ToastNotificationsManager::showNotification(Notification::Event event,
m_activeNotifications.prepend(notif);
}
void ToastNotificationsManager::showNotification(const QList<Message>& new_messages) {}
void ToastNotificationsManager::showNotification(const QList<Message>& new_messages) {
if (m_articleListNotification == nullptr) {
m_articleListNotification = new ArticleListNotification();
hookNotification(m_articleListNotification);
}
void ToastNotificationsManager::closeNotification(BaseToastNotification* notif) {
if (!m_activeNotifications.isEmpty() && m_activeNotifications.first() != m_articleListNotification) {
// Article notification is somewhere in list, clear first to move it to first positon.
closeNotification(m_articleListNotification, false);
}
auto* screen = moveToProperScreen(m_articleListNotification);
// Insert new notification into free space.
m_articleListNotification->show();
auto notif_new_pos = cornerForNewNotification(screen->availableGeometry());
// Make sure notification is finally resized.
m_articleListNotification->adjustSize();
qApp->processEvents();
// Move notification, at this point we already need to know its precise size.
moveNotificationToCorner(m_articleListNotification, notif_new_pos);
// Remove out-of-bounds old notifications and shift existing
// ones to make space for new notifications.
removeOutOfBoundsNotifications(m_articleListNotification->height());
makeSpaceForNotification(m_articleListNotification->height());
m_activeNotifications.prepend(m_articleListNotification);
}
void ToastNotificationsManager::closeNotification(BaseToastNotification* notif, bool delete_from_memory) {
auto notif_idx = m_activeNotifications.indexOf(notif);
if (delete_from_memory) {
notif->deleteLater();
}
else {
notif->hide();
}
m_activeNotifications.removeAll(notif);
@ -121,7 +159,9 @@ QPoint ToastNotificationsManager::cornerForNewNotification(QRect screen_rect) {
}
void ToastNotificationsManager::hookNotification(BaseToastNotification* notif) {
connect(notif, &BaseToastNotification::closeRequested, this, &ToastNotificationsManager::closeNotification);
connect(notif, &BaseToastNotification::closeRequested, this, [this](BaseToastNotification* notif) {
closeNotification(notif, false);
});
}
void ToastNotificationsManager::moveNotificationToCorner(BaseToastNotification* notif, QPoint corner) {

View File

@ -9,6 +9,7 @@
class BaseToastNotification;
class ToastNotification;
class ArticleListNotification;
class QScreen;
class ToastNotificationsManager : public QObject {
@ -22,7 +23,9 @@ class ToastNotificationsManager : public QObject {
BottomRight = 3
};
explicit ToastNotificationsManager(QObject* parent = nullptr);
explicit ToastNotificationsManager(ToastNotificationsManager::NotificationPosition position,
int screen,
QObject* parent = nullptr);
virtual ~ToastNotificationsManager();
QList<BaseToastNotification*> activeNotifications() const;
@ -41,7 +44,7 @@ class ToastNotificationsManager : public QObject {
void showNotification(const QList<Message>& new_messages);
private slots:
void closeNotification(BaseToastNotification* notif);
void closeNotification(BaseToastNotification* notif, bool delete_from_memory);
private:
QScreen* activeScreen() const;
@ -60,6 +63,8 @@ class ToastNotificationsManager : public QObject {
// List of all displayed notifications, newest notifications are in the beginning of the list
// and oldest at the end.
QList<BaseToastNotification*> m_activeNotifications;
ArticleListNotification* m_articleListNotification;
};
#endif // TOASTNOTIFICATIONSMANAGER_H

View File

@ -18,6 +18,21 @@ SettingsNotifications::SettingsNotifications(Settings* settings, QWidget* parent
connect(m_ui.m_checkEnableNotifications, &QCheckBox::toggled, this, &SettingsNotifications::dirtifySettings);
connect(m_ui.m_editor, &NotificationsEditor::someNotificationChanged, this, &SettingsNotifications::dirtifySettings);
connect(m_ui.m_rbCustomNotifications, &QRadioButton::toggled, this, &SettingsNotifications::dirtifySettings);
connect(m_ui.m_rbCustomNotifications, &QRadioButton::toggled, this, &SettingsNotifications::requireRestart);
connect(m_ui.m_rbNativeNotifications, &QRadioButton::toggled, this, &SettingsNotifications::dirtifySettings);
connect(m_ui.m_rbNativeNotifications, &QRadioButton::toggled, this, &SettingsNotifications::requireRestart);
connect(m_ui.m_cbCustomNotificationsPosition,
&QComboBox::currentIndexChanged,
this,
&SettingsNotifications::dirtifySettings);
connect(m_ui.m_cbCustomNotificationsPosition,
&QComboBox::currentIndexChanged,
this,
&SettingsNotifications::requireRestart);
}
void SettingsNotifications::loadSettings() {

View File

@ -37,7 +37,7 @@
<item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="m_gbNotificationsType">
<property name="title">
<string>Notifications type</string>
<string>Balloon notifications type</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0" colspan="2">
@ -45,6 +45,9 @@
<property name="text">
<string>Native notifications (tray icon must be enabled)</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">

View File

@ -110,7 +110,12 @@ Application::Application(const QString& id, int& argc, char** argv, const QStrin
m_database = new DatabaseFactory(this);
m_downloadManager = nullptr;
m_notifications = new NotificationFactory(this);
m_toastNotifications = new ToastNotificationsManager(this);
m_toastNotifications =
new ToastNotificationsManager(settings()
->value(GROUP(GUI), SETTING(GUI::ToastNotificationsPosition))
.value<ToastNotificationsManager::NotificationPosition>(),
settings()->value(GROUP(GUI), SETTING(GUI::ToastNotificationsScreen)).toInt(),
this);
m_shouldRestart = false;
#if defined(Q_OS_WIN)

View File

@ -255,6 +255,19 @@ void FeedReader::removeMessageFilterToFeedAssignment(Feed* feed, MessageFilter*
}
void FeedReader::updateAllFeeds() {
qApp
->showGuiMessage(Notification::Event::GeneralEvent,
GuiMessage(QDateTime::currentDateTime().toString(),
"Quisque ullamcorper ut purus nec tempus. Vivamus eros dolor, sagittis ultrices augue "
"ut, posuere fringilla lorem. Donec posuere, enim sit amet fermentum dignissim, tellus "
"lectus laoreet lectus, vestibulum laoreet felis tortor eget nunc. Curabitur sagittis "
"quam in scelerisque placerat. Vivamus vel porta tortor. Vivamus nec volutpat sem",
QSystemTrayIcon::MessageIcon::Information),
GuiMessageDestination(),
GuiAction("test", []() {
qDebugNN << "aa";
}));
updateFeeds(m_feedsModel->rootItem()->getSubTreeFeeds());
}

View File

@ -292,6 +292,9 @@ DKEY GUI::ToastNotificationsPosition = "toast_notifications_position";
DVALUE(ToastNotificationsManager::NotificationPosition)
GUI::ToastNotificationsPositionDef = ToastNotificationsManager::NotificationPosition::BottomRight;
DKEY GUI::ToastNotificationsScreen = "toast_notifications_screen";
DVALUE(int) GUI::ToastNotificationsScreenDef = -1;
DKEY GUI::HideMainWindowWhenMinimized = "hide_when_minimized";
DVALUE(bool) GUI::HideMainWindowWhenMinimizedDef = false;

View File

@ -225,6 +225,9 @@ namespace GUI {
KEY ToastNotificationsPosition;
VALUE(ToastNotificationsManager::NotificationPosition) ToastNotificationsPositionDef;
KEY ToastNotificationsScreen;
VALUE(int) ToastNotificationsScreenDef;
KEY MessageViewState;
VALUE(QString) MessageViewStateDef;