work on better notifications
This commit is contained in:
parent
a357c97226
commit
5e4ae7657b
23 changed files with 407 additions and 29 deletions
|
@ -6,6 +6,11 @@
|
||||||
<file>text/COPYING_GNU_GPL</file>
|
<file>text/COPYING_GNU_GPL</file>
|
||||||
<file>text/COPYING_GNU_GPL_HTML</file>
|
<file>text/COPYING_GNU_GPL_HTML</file>
|
||||||
|
|
||||||
|
<file>sounds/boing.wav</file>
|
||||||
|
<file>sounds/doorbell.wav</file>
|
||||||
|
<file>sounds/rooster.wav</file>
|
||||||
|
<file>sounds/sheep.wav</file>
|
||||||
|
|
||||||
<file>scripts/adblock/adblock-server.js</file>
|
<file>scripts/adblock/adblock-server.js</file>
|
||||||
<file>scripts/public_suffix_list.dat</file>
|
<file>scripts/public_suffix_list.dat</file>
|
||||||
|
|
||||||
|
|
BIN
resources/sounds/boing.wav
Executable file
BIN
resources/sounds/boing.wav
Executable file
Binary file not shown.
BIN
resources/sounds/doorbell.wav
Executable file
BIN
resources/sounds/doorbell.wav
Executable file
Binary file not shown.
BIN
resources/sounds/rooster.wav
Executable file
BIN
resources/sounds/rooster.wav
Executable file
Binary file not shown.
BIN
resources/sounds/sheep.wav
Executable file
BIN
resources/sounds/sheep.wav
Executable file
Binary file not shown.
|
@ -45,6 +45,7 @@
|
||||||
#define MSG_SCORE_MAX 100.0
|
#define MSG_SCORE_MAX 100.0
|
||||||
#define MSG_SCORE_MIN 0.0
|
#define MSG_SCORE_MIN 0.0
|
||||||
|
|
||||||
|
#define SOUNDS_BUILTIN_DIRECTORY ":/sounds"
|
||||||
#define ARGUMENTS_LIST_SEPARATOR "\n"
|
#define ARGUMENTS_LIST_SEPARATOR "\n"
|
||||||
#define IS_IN_ARRAY(offset, array) ((offset >= 0) && (offset < array.count()))
|
#define IS_IN_ARRAY(offset, array) ((offset >= 0) && (offset < array.count()))
|
||||||
#define DEFAULT_SQL_MESSAGES_FILTER "0 > 1"
|
#define DEFAULT_SQL_MESSAGES_FILTER "0 > 1"
|
||||||
|
|
|
@ -42,13 +42,13 @@ void NewspaperPreviewer::showMoreMessages() {
|
||||||
prev->loadMessage(msg, m_root.data());
|
prev->loadMessage(msg, m_root.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ui->m_btnShowMoreMessages->setText(tr("Show more messages (%n remaining)", "", m_messages.size()));
|
m_ui->m_btnShowMoreMessages->setText(tr("Show more articles (%n remaining)", "", m_messages.size()));
|
||||||
m_ui->m_btnShowMoreMessages->setEnabled(!m_messages.isEmpty());
|
m_ui->m_btnShowMoreMessages->setEnabled(!m_messages.isEmpty());
|
||||||
m_ui->scrollArea->verticalScrollBar()->setValue(current_scroll);
|
m_ui->scrollArea->verticalScrollBar()->setValue(current_scroll);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
qApp->showGuiMessage(tr("Cannot show more messages"),
|
qApp->showGuiMessage(tr("Cannot show more articles"),
|
||||||
tr("Cannot show more messages because parent feed was removed."),
|
tr("Cannot show more articles because parent feed was removed."),
|
||||||
QSystemTrayIcon::MessageIcon::Warning,
|
QSystemTrayIcon::MessageIcon::Warning,
|
||||||
qApp->mainForm(),
|
qApp->mainForm(),
|
||||||
true);
|
true);
|
||||||
|
|
41
src/librssguard/gui/notifications/notificationseditor.cpp
Executable file
41
src/librssguard/gui/notifications/notificationseditor.cpp
Executable file
|
@ -0,0 +1,41 @@
|
||||||
|
// For license of this file, see <project-root-folder>/LICENSE.md.
|
||||||
|
|
||||||
|
#include "gui/notifications/notificationseditor.h"
|
||||||
|
|
||||||
|
#include "3rd-party/boolinq/boolinq.h"
|
||||||
|
#include "gui/notifications/singlenotificationeditor.h"
|
||||||
|
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
NotificationsEditor::NotificationsEditor(QWidget* parent) : QScrollArea(parent), m_layout(new QVBoxLayout(this)) {
|
||||||
|
m_ui.setupUi(this);
|
||||||
|
setLayout(m_layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationsEditor::loadNotifications(const QList<Notification>& notifications) {
|
||||||
|
auto all_events = Notification::allEvents();
|
||||||
|
auto notif = boolinq::from(notifications);
|
||||||
|
|
||||||
|
for (auto ev : all_events) {
|
||||||
|
if (notif.any([ev](auto n) {
|
||||||
|
return n.event() == ev;
|
||||||
|
})) {
|
||||||
|
auto* notif_editor = new SingleNotificationEditor(notif.first([ev](auto n) {
|
||||||
|
return n.event() == ev;
|
||||||
|
}), this);
|
||||||
|
|
||||||
|
notif_editor->setNotificationEnabled(true);
|
||||||
|
|
||||||
|
m_layout->addWidget(notif_editor);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
auto* notif_editor = new SingleNotificationEditor(Notification(ev, {}), this);
|
||||||
|
|
||||||
|
notif_editor->setNotificationEnabled(false);
|
||||||
|
m_layout->addWidget(notif_editor);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_layout->addSpacerItem(new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding));
|
||||||
|
}
|
27
src/librssguard/gui/notifications/notificationseditor.h
Executable file
27
src/librssguard/gui/notifications/notificationseditor.h
Executable file
|
@ -0,0 +1,27 @@
|
||||||
|
// For license of this file, see <project-root-folder>/LICENSE.md.
|
||||||
|
|
||||||
|
#ifndef NOTIFICATIONSEDITOR_H
|
||||||
|
#define NOTIFICATIONSEDITOR_H
|
||||||
|
|
||||||
|
#include <QScrollArea>
|
||||||
|
|
||||||
|
#include "ui_notificationseditor.h"
|
||||||
|
|
||||||
|
#include "miscellaneous/notification.h"
|
||||||
|
|
||||||
|
class QVBoxLayout;
|
||||||
|
|
||||||
|
class NotificationsEditor : public QScrollArea {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit NotificationsEditor(QWidget* parent = nullptr);
|
||||||
|
|
||||||
|
void loadNotifications(const QList<Notification>& notifications);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::NotificationsEditor m_ui;
|
||||||
|
QVBoxLayout* m_layout;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NOTIFICATIONSEDITOR_H
|
19
src/librssguard/gui/notifications/notificationseditor.ui
Executable file
19
src/librssguard/gui/notifications/notificationseditor.ui
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>NotificationsEditor</class>
|
||||||
|
<widget class="QScrollArea" name="NotificationsEditor">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
41
src/librssguard/gui/notifications/singlenotificationeditor.cpp
Executable file
41
src/librssguard/gui/notifications/singlenotificationeditor.cpp
Executable file
|
@ -0,0 +1,41 @@
|
||||||
|
// For license of this file, see <project-root-folder>/LICENSE.md.
|
||||||
|
|
||||||
|
#include "gui/notifications/singlenotificationeditor.h"
|
||||||
|
|
||||||
|
#include "miscellaneous/application.h"
|
||||||
|
#include "miscellaneous/iconfactory.h"
|
||||||
|
|
||||||
|
SingleNotificationEditor::SingleNotificationEditor(const Notification& notification, QWidget* parent)
|
||||||
|
: QWidget(parent), m_notificationEvent(Notification::Event::UnknownEvent) {
|
||||||
|
m_ui.setupUi(this);
|
||||||
|
|
||||||
|
m_ui.m_btnBrowseSound->setIcon(qApp->icons()->fromTheme(QSL("document-open")));
|
||||||
|
m_ui.m_btnPlaySound->setIcon(qApp->icons()->fromTheme(QSL("media-playback-start")));
|
||||||
|
|
||||||
|
connect(m_ui.m_btnPlaySound, &QPushButton::clicked, this, &SingleNotificationEditor::playSound);
|
||||||
|
|
||||||
|
loadNotification(notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
Notification SingleNotificationEditor::notification() const {
|
||||||
|
return Notification(m_notificationEvent, m_ui.m_txtSound->text());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SingleNotificationEditor::notificationEnabled() const {
|
||||||
|
return m_ui.m_gbNotification->isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SingleNotificationEditor::setNotificationEnabled(bool enabled) {
|
||||||
|
m_ui.m_gbNotification->setChecked(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SingleNotificationEditor::playSound() {
|
||||||
|
Notification({}, m_ui.m_txtSound->text()).playSound(qApp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SingleNotificationEditor::loadNotification(const Notification& notification) {
|
||||||
|
m_ui.m_txtSound->setText(notification.soundPath());
|
||||||
|
m_ui.m_gbNotification->setTitle(Notification::nameForEvent(notification.event()));
|
||||||
|
|
||||||
|
m_notificationEvent = notification.event();
|
||||||
|
}
|
34
src/librssguard/gui/notifications/singlenotificationeditor.h
Executable file
34
src/librssguard/gui/notifications/singlenotificationeditor.h
Executable file
|
@ -0,0 +1,34 @@
|
||||||
|
// For license of this file, see <project-root-folder>/LICENSE.md.
|
||||||
|
|
||||||
|
#ifndef SINGLENOTIFICATIONEDITOR_H
|
||||||
|
#define SINGLENOTIFICATIONEDITOR_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include "ui_singlenotificationeditor.h"
|
||||||
|
|
||||||
|
#include "miscellaneous/notification.h"
|
||||||
|
|
||||||
|
class SingleNotificationEditor : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SingleNotificationEditor(const Notification& notification, QWidget* parent = nullptr);
|
||||||
|
|
||||||
|
Notification notification() const;
|
||||||
|
|
||||||
|
bool notificationEnabled() const;
|
||||||
|
void setNotificationEnabled(bool enabled);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void playSound();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void loadNotification(const Notification& notification);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::SingleNotificationEditor m_ui;
|
||||||
|
Notification::Event m_notificationEvent;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SINGLENOTIFICATIONEDITOR_H
|
86
src/librssguard/gui/notifications/singlenotificationeditor.ui
Executable file
86
src/librssguard/gui/notifications/singlenotificationeditor.ui
Executable file
|
@ -0,0 +1,86 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>SingleNotificationEditor</class>
|
||||||
|
<widget class="QWidget" name="SingleNotificationEditor">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>125</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="m_gbNotification">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QFormLayout" name="formLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Sound</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="m_txtSound">
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>Full path to your WAV sound file</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="m_btnBrowseSound">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Browse</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="m_btnPlaySound">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Play</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
|
@ -2,19 +2,38 @@
|
||||||
|
|
||||||
#include "gui/settings/settingsnotifications.h"
|
#include "gui/settings/settingsnotifications.h"
|
||||||
|
|
||||||
|
#include "3rd-party/boolinq/boolinq.h"
|
||||||
|
#include "gui/guiutilities.h"
|
||||||
|
#include "gui/notifications/notificationseditor.h"
|
||||||
|
#include "miscellaneous/application.h"
|
||||||
|
#include "miscellaneous/notificationfactory.h"
|
||||||
#include "miscellaneous/settings.h"
|
#include "miscellaneous/settings.h"
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
SettingsNotifications::SettingsNotifications(Settings* settings, QWidget* parent) : SettingsPanel(settings, parent) {
|
SettingsNotifications::SettingsNotifications(Settings* settings, QWidget* parent) : SettingsPanel(settings, parent) {
|
||||||
m_ui.setupUi(this);
|
m_ui.setupUi(this);
|
||||||
|
|
||||||
|
GuiUtilities::setLabelAsNotice(*m_ui.m_lblAvailableSounds, false);
|
||||||
|
|
||||||
connect(m_ui.m_checkEnableNotifications, &QCheckBox::toggled, this, &SettingsNotifications::dirtifySettings);
|
connect(m_ui.m_checkEnableNotifications, &QCheckBox::toggled, this, &SettingsNotifications::dirtifySettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsNotifications::loadSettings() {
|
void SettingsNotifications::loadSettings() {
|
||||||
onBeginLoadSettings();
|
onBeginLoadSettings();
|
||||||
|
|
||||||
|
auto builtin_sounds = QDir(SOUNDS_BUILTIN_DIRECTORY).entryInfoList(QDir::Filter::Files,
|
||||||
|
QDir::SortFlag::Name);
|
||||||
|
auto iter = boolinq::from(builtin_sounds).select([](const QFileInfo& i) {
|
||||||
|
return QSL(" %1").arg(i.absoluteFilePath());
|
||||||
|
}).toStdList();
|
||||||
|
auto descs = FROM_STD_LIST(QStringList, iter).join(QSL("\n"));
|
||||||
|
|
||||||
|
m_ui.m_lblAvailableSounds->setText(QSL("Built-in sounds:\n%1").arg(descs));
|
||||||
|
|
||||||
// Load fancy notification settings.
|
// Load fancy notification settings.
|
||||||
m_ui.m_checkEnableNotifications->setChecked(settings()->value(GROUP(Notifications), SETTING(Notifications::EnableNotifications)).toBool());
|
m_ui.m_checkEnableNotifications->setChecked(settings()->value(GROUP(Notifications), SETTING(Notifications::EnableNotifications)).toBool());
|
||||||
|
m_ui.m_editor->loadNotifications(qApp->notifications()->allNotifications());
|
||||||
|
|
||||||
onEndLoadSettings();
|
onEndLoadSettings();
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,28 +26,59 @@
|
||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item row="1" column="0" colspan="2">
|
|
||||||
<spacer name="verticalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>40</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0" colspan="2">
|
<item row="0" column="0" colspan="2">
|
||||||
<widget class="QCheckBox" name="m_checkEnableNotifications">
|
<widget class="QCheckBox" name="m_checkEnableNotifications">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Enable popup balloon tooltips</string>
|
<string>Enable notifications</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="2" column="0" colspan="2">
|
||||||
|
<widget class="NotificationsEditor" name="m_editor" native="true">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>1</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" colspan="2">
|
||||||
|
<widget class="QLabel" name="m_lblAvailableSounds"/>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>NotificationsEditor</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>notificationseditor.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<tabstops>
|
||||||
|
<tabstop>m_checkEnableNotifications</tabstop>
|
||||||
|
</tabstops>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>m_checkEnableNotifications</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>m_editor</receiver>
|
||||||
|
<slot>setEnabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>199</x>
|
||||||
|
<y>8</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>0</x>
|
||||||
|
<y>31</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
</ui>
|
</ui>
|
||||||
|
|
|
@ -60,6 +60,8 @@ HEADERS += core/feeddownloader.h \
|
||||||
exceptions/ioexception.h \
|
exceptions/ioexception.h \
|
||||||
exceptions/networkexception.h \
|
exceptions/networkexception.h \
|
||||||
exceptions/scriptexception.h \
|
exceptions/scriptexception.h \
|
||||||
|
gui/notifications/notificationseditor.h \
|
||||||
|
gui/notifications/singlenotificationeditor.h \
|
||||||
gui/reusable/baselineedit.h \
|
gui/reusable/baselineedit.h \
|
||||||
gui/settings/settingsnotifications.h \
|
gui/settings/settingsnotifications.h \
|
||||||
gui/toolbars/basetoolbar.h \
|
gui/toolbars/basetoolbar.h \
|
||||||
|
@ -242,6 +244,8 @@ SOURCES += core/feeddownloader.cpp \
|
||||||
exceptions/ioexception.cpp \
|
exceptions/ioexception.cpp \
|
||||||
exceptions/networkexception.cpp \
|
exceptions/networkexception.cpp \
|
||||||
exceptions/scriptexception.cpp \
|
exceptions/scriptexception.cpp \
|
||||||
|
gui/notifications/notificationseditor.cpp \
|
||||||
|
gui/notifications/singlenotificationeditor.cpp \
|
||||||
gui/reusable/baselineedit.cpp \
|
gui/reusable/baselineedit.cpp \
|
||||||
gui/settings/settingsnotifications.cpp \
|
gui/settings/settingsnotifications.cpp \
|
||||||
gui/toolbars/basetoolbar.cpp \
|
gui/toolbars/basetoolbar.cpp \
|
||||||
|
@ -402,6 +406,8 @@ FORMS += gui/dialogs/formabout.ui \
|
||||||
gui/dialogs/formrestoredatabasesettings.ui \
|
gui/dialogs/formrestoredatabasesettings.ui \
|
||||||
gui/dialogs/formsettings.ui \
|
gui/dialogs/formsettings.ui \
|
||||||
gui/dialogs/formupdate.ui \
|
gui/dialogs/formupdate.ui \
|
||||||
|
gui/notifications/notificationseditor.ui \
|
||||||
|
gui/notifications/singlenotificationeditor.ui \
|
||||||
gui/reusable/networkproxydetails.ui \
|
gui/reusable/networkproxydetails.ui \
|
||||||
gui/newspaperpreviewer.ui \
|
gui/newspaperpreviewer.ui \
|
||||||
gui/reusable/searchtextwidget.ui \
|
gui/reusable/searchtextwidget.ui \
|
||||||
|
@ -494,6 +500,7 @@ INCLUDEPATH += $$PWD/. \
|
||||||
$$PWD/gui/dialogs \
|
$$PWD/gui/dialogs \
|
||||||
$$PWD/gui/reusable \
|
$$PWD/gui/reusable \
|
||||||
$$PWD/gui/toolbars \
|
$$PWD/gui/toolbars \
|
||||||
|
$$PWD/gui/notifications \
|
||||||
$$PWD/dynamic-shortcuts
|
$$PWD/dynamic-shortcuts
|
||||||
|
|
||||||
TRANSLATIONS += $$files($$PWD/../../localization/rssguard_*.ts, false) \
|
TRANSLATIONS += $$files($$PWD/../../localization/rssguard_*.ts, false) \
|
||||||
|
|
|
@ -87,7 +87,15 @@ Application::Application(const QString& id, int& argc, char** argv)
|
||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (isFirstRun()) {
|
||||||
|
m_notifications->save({
|
||||||
|
Notification(Notification::Event::NewArticlesFetched,
|
||||||
|
QSL("%1/rooster.wav").arg(SOUNDS_BUILTIN_DIRECTORY))
|
||||||
|
}, settings());
|
||||||
|
}
|
||||||
|
else {
|
||||||
m_notifications->load(settings());
|
m_notifications->load(settings());
|
||||||
|
}
|
||||||
|
|
||||||
qDebugNN << LOGSEC_CORE
|
qDebugNN << LOGSEC_CORE
|
||||||
<< "OpenSSL version:"
|
<< "OpenSSL version:"
|
||||||
|
@ -231,6 +239,11 @@ void Application::eliminateFirstRuns() {
|
||||||
settings()->setValue(GROUP(General), QString(General::FirstRun) + QL1C('_') + APP_VERSION, false);
|
settings()->setValue(GROUP(General), QString(General::FirstRun) + QL1C('_') + APP_VERSION, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NotificationFactory* Application::notifications() const
|
||||||
|
{
|
||||||
|
return m_notifications;
|
||||||
|
}
|
||||||
|
|
||||||
void Application::setFeedReader(FeedReader* feed_reader) {
|
void Application::setFeedReader(FeedReader* feed_reader) {
|
||||||
m_feedReader = feed_reader;
|
m_feedReader = feed_reader;
|
||||||
connect(m_feedReader, &FeedReader::feedUpdatesFinished, this, &Application::onFeedUpdatesFinished);
|
connect(m_feedReader, &FeedReader::feedUpdatesFinished, this, &Application::onFeedUpdatesFinished);
|
||||||
|
|
|
@ -76,6 +76,7 @@ class RSSGUARD_DLLSPEC Application : public SingleApplication {
|
||||||
FormMain* mainForm();
|
FormMain* mainForm();
|
||||||
QWidget* mainFormWidget();
|
QWidget* mainFormWidget();
|
||||||
SystemTrayIcon* trayIcon();
|
SystemTrayIcon* trayIcon();
|
||||||
|
NotificationFactory* notifications() const;
|
||||||
|
|
||||||
QIcon desktopAwareIcon() const;
|
QIcon desktopAwareIcon() const;
|
||||||
|
|
||||||
|
|
|
@ -30,3 +30,27 @@ void Notification::setSoundPath(const QString& sound_path) {
|
||||||
void Notification::playSound(Application* app) const {
|
void Notification::playSound(Application* app) const {
|
||||||
QSound::play(QDir::toNativeSeparators(app->replaceDataUserDataFolderPlaceholder(m_soundPath)));
|
QSound::play(QDir::toNativeSeparators(app->replaceDataUserDataFolderPlaceholder(m_soundPath)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<Notification::Event> Notification::allEvents() {
|
||||||
|
return {
|
||||||
|
Event::NewArticlesFetched,
|
||||||
|
Event::ArticlesFetchingStarted,
|
||||||
|
Event::LoginDataRefreshed
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Notification::nameForEvent(Notification::Event event) {
|
||||||
|
switch (event) {
|
||||||
|
case Notification::Event::NewArticlesFetched:
|
||||||
|
return QObject::tr("New articles fetched");
|
||||||
|
|
||||||
|
case Notification::Event::ArticlesFetchingStarted:
|
||||||
|
return QObject::tr("Fetching articles right now");
|
||||||
|
|
||||||
|
case Notification::Event::LoginDataRefreshed:
|
||||||
|
return QObject::tr("Login data refreshed");
|
||||||
|
|
||||||
|
default:
|
||||||
|
return QObject::tr("Unknown event");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -10,16 +10,20 @@ class Application;
|
||||||
class Notification {
|
class Notification {
|
||||||
public:
|
public:
|
||||||
enum class Event {
|
enum class Event {
|
||||||
|
UnknownEvent = 0,
|
||||||
|
|
||||||
// New (unread) messages were downloaded for some feed.
|
// New (unread) messages were downloaded for some feed.
|
||||||
NewMessagesDownloaded = 1,
|
NewArticlesFetched = 1,
|
||||||
|
|
||||||
// RSS Guard started downloading messages for some feed.
|
// RSS Guard started downloading messages for some feed.
|
||||||
MesssagesDownloadStarted = 2,
|
ArticlesFetchingStarted = 2,
|
||||||
|
|
||||||
// Login tokens were successfuly refreshed.
|
// Login tokens were successfuly refreshed.
|
||||||
// NOTE: This is primarily used in accounts which use
|
// NOTE: This is primarily used in accounts which use
|
||||||
// OAuth or similar mechanism.
|
// OAuth or similar mechanism.
|
||||||
LoginDataRefreshed = 4
|
LoginDataRefreshed = 4,
|
||||||
|
|
||||||
|
// TODO: app update is available
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit Notification();
|
explicit Notification();
|
||||||
|
@ -36,6 +40,9 @@ class Notification {
|
||||||
|
|
||||||
void playSound(Application* app) const;
|
void playSound(Application* app) const;
|
||||||
|
|
||||||
|
static QList<Event> allEvents();
|
||||||
|
static QString nameForEvent(Event event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Event m_event;
|
Event m_event;
|
||||||
QString m_soundPath;
|
QString m_soundPath;
|
||||||
|
|
|
@ -7,8 +7,14 @@
|
||||||
#include "exceptions/applicationexception.h"
|
#include "exceptions/applicationexception.h"
|
||||||
#include "miscellaneous/settings.h"
|
#include "miscellaneous/settings.h"
|
||||||
|
|
||||||
|
#include <QRegularExpression>
|
||||||
|
|
||||||
NotificationFactory::NotificationFactory(QObject* parent) : QObject(parent) {}
|
NotificationFactory::NotificationFactory(QObject* parent) : QObject(parent) {}
|
||||||
|
|
||||||
|
QList<Notification> NotificationFactory::allNotifications() const {
|
||||||
|
return m_notifications;
|
||||||
|
}
|
||||||
|
|
||||||
Notification NotificationFactory::notificationForEvent(Notification::Event event) const {
|
Notification NotificationFactory::notificationForEvent(Notification::Event event) const {
|
||||||
auto good_n = boolinq::from(m_notifications).where([event](const Notification& n) {
|
auto good_n = boolinq::from(m_notifications).where([event](const Notification& n) {
|
||||||
return n.event() == event;
|
return n.event() == event;
|
||||||
|
@ -23,15 +29,23 @@ Notification NotificationFactory::notificationForEvent(Notification::Event event
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotificationFactory::load(Settings* settings) {
|
void NotificationFactory::load(Settings* settings) {
|
||||||
//settings->allKeys(Notifications::ID)
|
auto notif_keys = settings->allKeys(GROUP(Notifications)).filter(QRegularExpression(QSL("^\\d+$")));
|
||||||
|
|
||||||
m_notifications = {
|
m_notifications.clear();
|
||||||
Notification()
|
|
||||||
};
|
for (const auto& key : notif_keys) {
|
||||||
|
auto event = Notification::Event(key.toInt());
|
||||||
|
auto sound = settings->value(GROUP(Notifications), key).toString();
|
||||||
|
|
||||||
|
m_notifications.append(Notification(event, sound));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotificationFactory::save(const QList<Notification>& new_notifications, Settings* settings) {
|
void NotificationFactory::save(const QList<Notification>& new_notifications, Settings* settings) {
|
||||||
|
settings->remove(GROUP(Notifications));
|
||||||
m_notifications = new_notifications;
|
m_notifications = new_notifications;
|
||||||
|
|
||||||
//
|
for (const auto& n : qAsConst(m_notifications)) {
|
||||||
|
settings->setValue(GROUP(Notifications), QString::number(int(n.event())), n.soundPath());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ class NotificationFactory : public QObject {
|
||||||
public:
|
public:
|
||||||
explicit NotificationFactory(QObject* parent = nullptr);
|
explicit NotificationFactory(QObject* parent = nullptr);
|
||||||
|
|
||||||
|
QList<Notification> allNotifications() const;
|
||||||
Notification notificationForEvent(Notification::Event event) const;
|
Notification notificationForEvent(Notification::Event event) const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
|
@ -432,7 +432,7 @@ class Settings : public QSettings {
|
||||||
void setValue(const QString& key, const QVariant& value);
|
void setValue(const QString& key, const QVariant& value);
|
||||||
|
|
||||||
bool contains(const QString& section, const QString& key) const;
|
bool contains(const QString& section, const QString& key) const;
|
||||||
void remove(const QString& section, const QString& key);
|
void remove(const QString& section, const QString& key = {});
|
||||||
|
|
||||||
// Returns the path which contains the settings.
|
// Returns the path which contains the settings.
|
||||||
QString pathName() const;
|
QString pathName() const;
|
||||||
|
@ -487,7 +487,14 @@ inline bool Settings::contains(const QString& section, const QString& key) const
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Settings::remove(const QString& section, const QString& key) {
|
inline void Settings::remove(const QString& section, const QString& key) {
|
||||||
|
if (key.isEmpty()) {
|
||||||
|
beginGroup(section);
|
||||||
|
QSettings::remove({});
|
||||||
|
endGroup();
|
||||||
|
}
|
||||||
|
else {
|
||||||
QSettings::remove(QString(QSL("%1/%2")).arg(section, key));
|
QSettings::remove(QString(QSL("%1/%2")).arg(section, key));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif // SETTINGS_H
|
#endif // SETTINGS_H
|
||||||
|
|
Loading…
Add table
Reference in a new issue