Krita Source Code Documentation
Loading...
Searching...
No Matches
KisNewsWidget.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2018 boud <boud@valdyas.org>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6#include "KisNewsWidget.h"
7
8#include <QDesktopServices>
9#include <QUrl>
10#include <QPainter>
11#include <QStyleOptionViewItem>
12#include <QModelIndex>
13#include <QTextDocument>
14#include <QAbstractTextDocumentLayout>
15#include <QRegularExpression>
16#include <QScrollBar>
17
18#include "kis_config.h"
20#include <KisKineticScroller.h>
21
23 : QStyledItemDelegate(parent)
24{
25}
26
27void KisNewsDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
28{
29 painter->save();
30
31 QStyleOptionViewItem optionCopy = option;
32 initStyleOption(&optionCopy, index);
33
34 QStyle *style = optionCopy.widget? optionCopy.widget->style() : QApplication::style();
35
36 QTextDocument doc;
37 doc.setDocumentMargin(6);
38 doc.setHtml(optionCopy.text);
39 doc.setTextWidth(optionCopy.rect.width());
40
42 optionCopy.text = QString();
43 style->drawControl(QStyle::CE_ItemViewItem, &optionCopy, painter);
44
45 QAbstractTextDocumentLayout::PaintContext ctx;
46
47 // Highlighting text if item is selected
48 QColor textColor;
49 if (optionCopy.state & QStyle::State_Selected) {
50 textColor = optionCopy.palette.color(QPalette::Active, QPalette::HighlightedText);
51 } else {
52 textColor = optionCopy.palette.color(QPalette::Text);
53 }
54 ctx.palette.setColor(QPalette::Text, textColor);
55
56 painter->translate(optionCopy.rect.left(), optionCopy.rect.top());
57 QRect clip(0, 0, optionCopy.rect.width(), optionCopy.rect.height());
58 ctx.clip = clip;
59 doc.setPageSize(clip.size());
60 doc.documentLayout()->draw(painter, ctx);
61
62 painter->restore();
63}
64
65QSize KisNewsDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
66{
67 QStyleOptionViewItem optionCopy = option;
68 initStyleOption(&optionCopy, index);
69
70 QTextDocument doc;
71 doc.setDocumentMargin(6);
72 doc.setHtml(optionCopy.text);
73 doc.setTextWidth(optionCopy.rect.width());
74 return QSize(doc.idealWidth(), doc.size().height());
75}
76
78 : QWidget(parent)
79 , m_getNews(false)
80 , m_rssModel(0)
81{
82 setupUi(this);
83 listNews->viewport()->setAutoFillBackground(false);
84 listNews->installEventFilter(this);
85 listNews->setVerticalScrollMode(QListView::ScrollPerPixel);
86 listNews->verticalScrollBar()->setSingleStep(50);
87 {
88 QScroller* scroller = KisKineticScroller::createPreconfiguredScroller(listNews);
89 if (scroller) {
90 connect(scroller, SIGNAL(stateChanged(QScroller::State)), this, SLOT(slotScrollerStateChanged(QScroller::State)));
91 }
92 }
93
94 m_rssModel = new MultiFeedRssModel(this);
95 connect(m_rssModel, SIGNAL(feedDataChanged()), this, SLOT(rssDataChanged()), Qt::UniqueConnection);
96
97 listNews->setModel(m_rssModel);
98 listNews->setItemDelegate(new KisNewsDelegate(listNews));
99 connect(listNews, SIGNAL(clicked(QModelIndex)), this, SLOT(itemSelected(QModelIndex)));
100}
101
106
107bool KisNewsWidget::eventFilter(QObject *watched, QEvent *event)
108{
109 if (watched == listNews && event->type() == QEvent::Leave) {
110 listNews->clearSelection();
111 listNews->setCurrentIndex(QModelIndex());
112 }
113 return QWidget::eventFilter(watched, event);
114}
115
116void KisNewsWidget::toggleNewsLanguage(QString langCode, bool enabled)
117{
118 // Sanity check: Since the code is adding the language code directly into
119 // the URL, this prevents any nasty surprises with malformed URLs.
120 Q_FOREACH(const char &ch, langCode.toLatin1()) {
121 bool isValidChar = ((ch >= 'a' && ch <= 'z') || ch == '-' || ch == '@');
122 if (!isValidChar) {
123 warnUI << "Ignoring attempt to toggle malformed news lang:" << langCode;
124 return;
125 }
126 }
127
128 QString feed = QStringLiteral("https://krita.org/%1/index.xml").arg(langCode);
129 if (enabled) {
130 m_enabledFeeds.insert(feed);
131 if (m_getNews) {
132 m_rssModel->addFeed(feed);
133 }
134 } else {
135 m_enabledFeeds.remove(feed);
136 if (m_getNews) {
137 m_rssModel->removeFeed(feed);
138 }
139 }
140}
141
143{
144 m_getNews = toggle;
145
146 KisConfig cfg(false);
147 cfg.writeEntry<bool>("FetchNews", toggle);
148
149 Q_FOREACH(const QString &feed, m_enabledFeeds) {
150 if (toggle) {
151 m_rssModel->addFeed(feed);
152 } else {
153 m_rssModel->removeFeed(feed);
154 }
155 }
156}
157
158void KisNewsWidget::itemSelected(const QModelIndex &idx)
159{
160 if (idx.isValid()) {
161 QString link = idx.data(KisRssReader::RssRoles::LinkRole).toString();
162
163 // append query string for analytics tracking if we set it
165
166 // use title in analytics query string
167 QString linkTitle = idx.data(KisRssReader::RssRoles::TitleRole).toString();
168 linkTitle = linkTitle.simplified(); // trims and makes 1 white space
169 linkTitle = linkTitle.replace(" ", "");
170
172 QDesktopServices::openUrl(QUrl(link.append(m_analyticsTrackingParameters)));
173
174 } else {
175 QDesktopServices::openUrl(QUrl(link));
176 }
177
178
179 }
180}
181
183{
184 Q_EMIT newsDataChanged();
185}
186
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
void writeEntry(const QString &name, const T &value)
Definition kis_config.h:779
KisNewsDelegate(QObject *parent=0)
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
KisNewsWidget(QWidget *parent=nullptr)
bool eventFilter(QObject *watched, QEvent *event) override
void itemSelected(const QModelIndex &idx)
void slotScrollerStateChanged(QScroller::State state)
void setAnalyticsTracking(QString text)
MultiFeedRssModel * m_rssModel
void newsDataChanged()
QString m_analyticsTrackingParameters
QSet< QString > m_enabledFeeds
void toggleNews(bool toggle)
void toggleNewsLanguage(QString langCode, bool enabled)
virtual void addFeed(const QString &feed)
void removeFeed(const QString &feed)
#define warnUI
Definition kis_debug.h:94
KRITAWIDGETUTILS_EXPORT QScroller * createPreconfiguredScroller(QAbstractScrollArea *target)