diff --git a/src/librssguard/gui/messagepreviewer.cpp b/src/librssguard/gui/messagepreviewer.cpp index 7d7ef6a36..41ca7325a 100644 --- a/src/librssguard/gui/messagepreviewer.cpp +++ b/src/librssguard/gui/messagepreviewer.cpp @@ -282,7 +282,7 @@ void MessagePreviewer::updateLabels(bool only_clear) { for (auto* label : lbls) { LabelToolbarAction* act_label = new LabelToolbarAction(this); - act_label->setIcon(Label::generateIcon(label->color())); + act_label->setIcon(IconFactory::generateIcon(label->color())); act_label->setText(QSL(" ") + label->title()); act_label->setCheckable(true); act_label->setChecked(m_message.m_assignedLabelsIds.contains(label->customId())); diff --git a/src/librssguard/gui/settings/settingslocalization.cpp b/src/librssguard/gui/settings/settingslocalization.cpp index 21925ff22..41c8c9794 100644 --- a/src/librssguard/gui/settings/settingslocalization.cpp +++ b/src/librssguard/gui/settings/settingslocalization.cpp @@ -33,6 +33,7 @@ SettingsLocalization::SettingsLocalization(Settings* settings, QWidget* parent) m_ui->m_treeLanguages->header()->setSectionResizeMode(1, QHeaderView::ResizeMode::ResizeToContents); m_ui->m_treeLanguages->header()->setSectionResizeMode(2, QHeaderView::ResizeMode::ResizeToContents); m_ui->m_treeLanguages->header()->setSectionResizeMode(3, QHeaderView::ResizeMode::ResizeToContents); + connect(m_ui->m_treeLanguages, &QTreeWidget::currentItemChanged, this, &SettingsLocalization::requireRestart); connect(m_ui->m_treeLanguages, &QTreeWidget::currentItemChanged, this, &SettingsLocalization::dirtifySettings); } @@ -89,17 +90,9 @@ void SettingsLocalization::loadSettings() { item->setText(3, language.m_author); item->setIcon(0, qApp->icons()->miscIcon(QSL(FLAG_ICON_SUBFOLDER) + QDir::separator() + language.m_code)); - if (perc_translated < 40) { - item->setBackground(2, - qApp->skins()->colorForModel(SkinEnums::PaletteColors::FgError).value().darker(110)); - } - else if (perc_translated < 75) { - item->setBackground(2, - qApp->skins()->colorForModel(SkinEnums::PaletteColors::FgError).value().darker(90)); - } - else { - item->setBackground(2, qApp->skins()->colorForModel(SkinEnums::PaletteColors::Allright).value()); - } + QColor col_translated = QColor::fromHsv(perc_translated, 200, 230); + + item->setIcon(2, IconFactory::generateIcon(col_translated)); } m_ui->m_treeLanguages->sortByColumn(0, Qt::SortOrder::AscendingOrder); diff --git a/src/librssguard/miscellaneous/iconfactory.cpp b/src/librssguard/miscellaneous/iconfactory.cpp index 05142fd7d..b732afafe 100644 --- a/src/librssguard/miscellaneous/iconfactory.cpp +++ b/src/librssguard/miscellaneous/iconfactory.cpp @@ -6,6 +6,7 @@ #include "miscellaneous/settings.h" #include +#include IconFactory::IconFactory(QObject* parent) : QObject(parent) {} @@ -13,6 +14,20 @@ IconFactory::~IconFactory() { qDebugNN << LOGSEC_GUI << "Destroying IconFactory instance."; } +QIcon IconFactory::generateIcon(const QColor& color) { + QPixmap pxm(64, 64); + + pxm.fill(Qt::GlobalColor::transparent); + + QPainter paint(&pxm); + + paint.setBrush(color); + paint.setPen(Qt::GlobalColor::transparent); + paint.drawEllipse(pxm.rect().marginsRemoved(QMargins(2, 2, 2, 2))); + + return pxm; +} + QIcon IconFactory::fromByteArray(QByteArray array) { if (array.isEmpty()) { return {}; @@ -61,14 +76,11 @@ QIcon IconFactory::miscIcon(const QString& name) { void IconFactory::setupSearchPaths() { auto paths = QIcon::themeSearchPaths(); - paths << APP_THEME_PATH - << qApp->userDataFolder() + QDir::separator() + APP_LOCAL_ICON_THEME_FOLDER + paths << APP_THEME_PATH << qApp->userDataFolder() + QDir::separator() + APP_LOCAL_ICON_THEME_FOLDER << qApp->applicationDirPath() + QDir::separator() + APP_LOCAL_ICON_THEME_FOLDER; QIcon::setThemeSearchPaths(paths); - qDebugNN << LOGSEC_GUI - << "Available icon theme paths: " - << paths; + qDebugNN << LOGSEC_GUI << "Available icon theme paths: " << paths; } void IconFactory::setCurrentIconTheme(const QString& theme_name) { @@ -87,8 +99,9 @@ void IconFactory::loadCurrentIconTheme() { // Display list of installed themes. qDebugNN << LOGSEC_GUI << "Installed icon themes are: " << QStringList(installed_themes) - .replaceInStrings(QRegularExpression(QSL("^|$")), QSL("\'")) - .replaceInStrings(QRegularExpression(QSL("^\\'$")), QSL("\'\'")).join(QSL(", ")); + .replaceInStrings(QRegularExpression(QSL("^|$")), QSL("\'")) + .replaceInStrings(QRegularExpression(QSL("^\\'$")), QSL("\'\'")) + .join(QSL(", ")); if (installed_themes.contains(theme_name_from_settings)) { // Desired icon theme is installed and can be loaded. @@ -109,12 +122,10 @@ void IconFactory::loadCurrentIconTheme() { // Desired icon theme is not currently available. // Activate "default" or "no" icon theme instead. #if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) - qWarningNN << "Icon theme" - << QUOTE_W_SPACE(theme_name_from_settings) + qWarningNN << "Icon theme" << QUOTE_W_SPACE(theme_name_from_settings) << "cannot be loaded because it is not installed. Activating \"no\" icon theme."; #else - qWarningNN << "Icon theme" - << QUOTE_W_SPACE(theme_name_from_settings) + qWarningNN << "Icon theme" << QUOTE_W_SPACE(theme_name_from_settings) << "cannot be loaded because it is not installed. Activating \"no\" icon theme."; QIcon::setThemeName(QSL(APP_NO_THEME)); #endif @@ -122,7 +133,7 @@ void IconFactory::loadCurrentIconTheme() { } QStringList IconFactory::installedIconThemes() const { - QStringList icon_theme_names = { QSL(APP_NO_THEME) }; + QStringList icon_theme_names = {QSL(APP_NO_THEME)}; // Iterate all directories with icon themes. QStringList icon_themes_paths = QIcon::themeSearchPaths(); @@ -133,10 +144,10 @@ QStringList IconFactory::installedIconThemes() const { for (const QString& icon_path : icon_themes_paths) { const QDir icon_dir(icon_path); - auto icon_paths = icon_dir.entryInfoList(QDir::Filter::Dirs | QDir::Filter::NoDotAndDotDot | - QDir::Filter::Readable | QDir::Filter::CaseSensitive | - QDir::Filter::NoSymLinks, - QDir::SortFlag::Time); + auto icon_paths = + icon_dir.entryInfoList(QDir::Filter::Dirs | QDir::Filter::NoDotAndDotDot | QDir::Filter::Readable | + QDir::Filter::CaseSensitive | QDir::Filter::NoSymLinks, + QDir::SortFlag::Time); // Iterate all icon themes in this directory. for (const QFileInfo& icon_theme_path : qAsConst(icon_paths)) { diff --git a/src/librssguard/miscellaneous/iconfactory.h b/src/librssguard/miscellaneous/iconfactory.h index 13924c0ac..324c4860c 100644 --- a/src/librssguard/miscellaneous/iconfactory.h +++ b/src/librssguard/miscellaneous/iconfactory.h @@ -14,12 +14,15 @@ #include class RSSGUARD_DLLSPEC IconFactory : public QObject { - Q_OBJECT + Q_OBJECT public: explicit IconFactory(QObject* parent = nullptr); virtual ~IconFactory(); + // Generates round icon of given color. + static QIcon generateIcon(const QColor& color); + // Used to store/retrieve QIcons from/to Base64-encoded // byte array. static QIcon fromByteArray(QByteArray array); diff --git a/src/librssguard/services/abstract/label.cpp b/src/librssguard/services/abstract/label.cpp index 82000816a..daab0dbb9 100644 --- a/src/librssguard/services/abstract/label.cpp +++ b/src/librssguard/services/abstract/label.cpp @@ -26,7 +26,7 @@ QColor Label::color() const { } void Label::setColor(const QColor& color) { - setIcon(generateIcon(color)); + setIcon(IconFactory::generateIcon(color)); m_color = color; } @@ -93,20 +93,6 @@ QList Label::undeletedMessages() const { return DatabaseQueries::getUndeletedMessagesWithLabel(database, this); } -QIcon Label::generateIcon(const QColor& color) { - QPixmap pxm(64, 64); - - pxm.fill(Qt::GlobalColor::transparent); - - QPainter paint(&pxm); - - paint.setBrush(color); - paint.setPen(Qt::GlobalColor::transparent); - paint.drawEllipse(pxm.rect().marginsRemoved(QMargins(2, 2, 2, 2))); - - return pxm; -} - void Label::assignToMessage(const Message& msg, bool reload_model) { QSqlDatabase database = qApp->database()->driver()->threadSafeConnection(metaObject()->className()); diff --git a/src/librssguard/services/abstract/label.h b/src/librssguard/services/abstract/label.h index 88e504ad6..d6358087b 100644 --- a/src/librssguard/services/abstract/label.h +++ b/src/librssguard/services/abstract/label.h @@ -34,9 +34,6 @@ class RSSGUARD_DLLSPEC Label : public RootItem { virtual void updateCounts(bool including_total_count); virtual QList undeletedMessages() const; - public: - static QIcon generateIcon(const QColor& color); - public slots: void assignToMessage(const Message& msg, bool reload_model = true); void deassignFromMessage(const Message& msg, bool reload_model = true); diff --git a/src/librssguard/services/abstract/rootitem.cpp b/src/librssguard/services/abstract/rootitem.cpp index 0b5dd5086..c3409e123 100644 --- a/src/librssguard/services/abstract/rootitem.cpp +++ b/src/librssguard/services/abstract/rootitem.cpp @@ -220,7 +220,7 @@ int RootItem::countOfUnreadMessages() const { it->kind() == RootItem::Kind::Unread || it->kind() == RootItem::Kind::Labels || it->kind() == RootItem::Kind::Probes) ? 0 - : it->countOfUnreadMessages(); + : std::max(it->countOfUnreadMessages(), 0); }); } @@ -230,7 +230,7 @@ int RootItem::countOfAllMessages() const { it->kind() == RootItem::Kind::Unread || it->kind() == RootItem::Kind::Labels || it->kind() == RootItem::Kind::Probes) ? 0 - : it->countOfAllMessages(); + : std::max(it->countOfAllMessages(), 0); }); } diff --git a/src/librssguard/services/abstract/search.cpp b/src/librssguard/services/abstract/search.cpp index 90876b6aa..a97afa56c 100644 --- a/src/librssguard/services/abstract/search.cpp +++ b/src/librssguard/services/abstract/search.cpp @@ -28,7 +28,7 @@ QColor Search::color() const { } void Search::setColor(const QColor& color) { - setIcon(generateIcon(color)); + setIcon(IconFactory::generateIcon(color)); m_color = color; } @@ -113,20 +113,6 @@ QList Search::undeletedMessages() const { return DatabaseQueries::getUndeletedMessagesForProbe(database, this); } -QIcon Search::generateIcon(const QColor& color) { - QPixmap pxm(64, 64); - - pxm.fill(Qt::GlobalColor::transparent); - - QPainter paint(&pxm); - - paint.setBrush(color); - paint.setPen(Qt::GlobalColor::transparent); - paint.drawEllipse(pxm.rect().marginsRemoved(QMargins(2, 2, 2, 2))); - - return pxm; -} - QString Search::filter() const { return m_filter; } diff --git a/src/librssguard/services/abstract/search.h b/src/librssguard/services/abstract/search.h index db9120734..eb8f7657a 100644 --- a/src/librssguard/services/abstract/search.h +++ b/src/librssguard/services/abstract/search.h @@ -38,9 +38,6 @@ class RSSGUARD_DLLSPEC Search : public RootItem { virtual void updateCounts(bool including_total_count); virtual QList undeletedMessages() const; - public: - static QIcon generateIcon(const QColor& color); - private: QString m_filter; QColor m_color; diff --git a/src/librssguard/services/abstract/searchsnode.cpp b/src/librssguard/services/abstract/searchsnode.cpp index 2224305b3..4bd7fdbd9 100644 --- a/src/librssguard/services/abstract/searchsnode.cpp +++ b/src/librssguard/services/abstract/searchsnode.cpp @@ -30,7 +30,6 @@ QList SearchsNode::undeletedMessages() const { QSqlDatabase database = qApp->database()->driver()->connection(metaObject()->className()); return {}; - // return DatabaseQueries::getUndeletedLabelledMessages(database, getParentServiceRoot()->accountId()); } Search* SearchsNode::probeById(const QString& custom_id) { @@ -73,6 +72,12 @@ void SearchsNode::updateCounts(bool including_total_count) { RootItem::updateCounts(including_total_count); } else { + for (RootItem* child : qAsConst(childItems())) { + auto* sear = qobject_cast(child); + + sear->setCountOfAllMessages(-1); + sear->setCountOfUnreadMessages(-1); + } } } diff --git a/src/librssguard/services/abstract/serviceroot.cpp b/src/librssguard/services/abstract/serviceroot.cpp index 8d21858d0..28905164a 100644 --- a/src/librssguard/services/abstract/serviceroot.cpp +++ b/src/librssguard/services/abstract/serviceroot.cpp @@ -746,6 +746,9 @@ bool ServiceRoot::loadMessagesForItem(RootItem* item, MessagesModel* model) { .arg(QString::number(accountId()))); } else if (item->kind() == RootItem::Kind::Probe) { + item->updateCounts(true); + itemChanged({item}); + model->setFilter(QSL("Messages.is_deleted = 0 AND Messages.is_pdeleted = 0 AND Messages.account_id = %1 AND " "(Messages.title REGEXP '%2' OR Messages.contents REGEXP '%2')") .arg(QString::number(accountId()), item->toProbe()->filter())); @@ -766,7 +769,12 @@ bool ServiceRoot::loadMessagesForItem(RootItem* item, MessagesModel* model) { model->setFilter(QSL("Messages.is_deleted = 0 AND Messages.is_pdeleted = 0 AND Messages.account_id = %1") .arg(QString::number(accountId()))); - qDebugNN << "Displaying messages from account:" << QUOTE_W_SPACE_DOT(accountId()); + qDebugNN << LOGSEC_CORE << "Displaying messages from account:" << QUOTE_W_SPACE_DOT(accountId()); + } + else if (item->kind() == RootItem::Kind::Probes) { + model->setFilter(QSL(DEFAULT_SQL_MESSAGES_FILTER)); + + qWarningNN << LOGSEC_CORE << "Showing of all regex queries combined is not supported."; } else { QList children = item->getSubTreeFeeds(); @@ -782,7 +790,7 @@ bool ServiceRoot::loadMessagesForItem(RootItem* item, MessagesModel* model) { QString urls = textualFeedUrls(children).join(QSL(", ")); - qDebugNN << "Displaying messages from feeds IDs:" << QUOTE_W_SPACE(filter_clause) + qDebugNN << LOGSEC_CORE << "Displaying messages from feeds IDs:" << QUOTE_W_SPACE(filter_clause) << "and URLs:" << QUOTE_W_SPACE_DOT(urls); }