1 /*
2     This file is part of Akregator.
3 
4     SPDX-FileCopyrightText: 2004 Stanislav Karchebny <Stanislav.Karchebny@kdemail.net>
5 
6     SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0
7 */
8 
9 #include "feedpropertiesdialog.h"
10 #include "akregatorconfig.h"
11 
12 #include <KLocalizedString>
13 #include <QComboBox>
14 
15 #include <QCheckBox>
16 #include <QDialogButtonBox>
17 #include <QPushButton>
18 #include <QVBoxLayout>
19 
20 using namespace Akregator;
FeedPropertiesWidget(QWidget * parent,const QString & name)21 FeedPropertiesWidget::FeedPropertiesWidget(QWidget *parent, const QString &name)
22     : QWidget(parent)
23 {
24     setObjectName(name);
25     setupUi(this);
26     connect(cb_updateInterval, &QCheckBox::toggled, updateSpinBox, &QSpinBox::setEnabled);
27     connect(cb_updateInterval, &QCheckBox::toggled, updateComboBox, &QComboBox::setEnabled);
28     connect(cb_updateInterval, &QCheckBox::toggled, updateLabel, &QLabel::setEnabled);
29     connect(cb_updateInterval, &QCheckBox::toggled, this, &FeedPropertiesWidget::slotUpdateCheckBoxToggled);
30     connect(updateComboBox, qOverload<int>(&QComboBox::activated), this, &FeedPropertiesWidget::slotUpdateComboBoxActivated);
31     connect(updateSpinBox, &QSpinBox::valueChanged, this, &FeedPropertiesWidget::slotUpdateComboBoxLabels);
32     connect(rb_limitArticleAge, &QRadioButton::toggled, sb_maxArticleAge, &KPluralHandlingSpinBox::setEnabled);
33     connect(rb_limitArticleNumber, &QRadioButton::toggled, sb_maxArticleNumber, &KPluralHandlingSpinBox::setEnabled);
34 }
35 
~FeedPropertiesWidget()36 FeedPropertiesWidget::~FeedPropertiesWidget()
37 {
38 }
39 
slotUpdateComboBoxActivated(int index)40 void FeedPropertiesWidget::slotUpdateComboBoxActivated(int index)
41 {
42     updateSpinBox->setEnabled(index != Never);
43 }
44 
slotUpdateComboBoxLabels(int value)45 void FeedPropertiesWidget::slotUpdateComboBoxLabels(int value)
46 {
47     updateComboBox->setItemText(FeedPropertiesWidget::Minutes, i18np("Minute", "Minutes", value));
48     updateComboBox->setItemText(FeedPropertiesWidget::Hours, i18np("Hour", "Hours", value));
49     updateComboBox->setItemText(FeedPropertiesWidget::Days, i18np("Day", "Days", value));
50 }
51 
slotUpdateCheckBoxToggled(bool enabled)52 void FeedPropertiesWidget::slotUpdateCheckBoxToggled(bool enabled)
53 {
54     updateSpinBox->setEnabled(enabled && updateComboBox->currentIndex() != Never);
55 }
56 
FeedPropertiesDialog(QWidget * parent,const QString & name)57 FeedPropertiesDialog::FeedPropertiesDialog(QWidget *parent, const QString &name)
58     : QDialog(parent)
59     , m_feed(nullptr)
60 {
61     setObjectName(name);
62     setWindowTitle(i18nc("@title:window", "Feed Properties"));
63     auto mainLayout = new QVBoxLayout(this);
64 
65     widget = new FeedPropertiesWidget(this);
66     auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
67     mOkButton = buttonBox->button(QDialogButtonBox::Ok);
68     mOkButton->setDefault(true);
69     mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return);
70     connect(buttonBox, &QDialogButtonBox::accepted, this, &FeedPropertiesDialog::accept);
71     connect(buttonBox, &QDialogButtonBox::rejected, this, &FeedPropertiesDialog::reject);
72     buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
73     setModal(true);
74 
75     mainLayout->addWidget(widget);
76     mainLayout->addWidget(buttonBox);
77     widget->feedNameEdit->setFocus();
78 
79     widget->updateComboBox->insertItem(FeedPropertiesWidget::Minutes, i18np("Minute", "Minutes", 0));
80     widget->updateComboBox->insertItem(FeedPropertiesWidget::Hours, i18np("Hour", "Hours", 0));
81     widget->updateComboBox->insertItem(FeedPropertiesWidget::Days, i18np("Day", "Days", 0));
82     widget->updateComboBox->insertItem(FeedPropertiesWidget::Never, i18nc("never fetch new articles", "Never"));
83     widget->sb_maxArticleAge->setSuffix(ki18np(" day", " days"));
84     widget->sb_maxArticleNumber->setSuffix(ki18np(" article", " articles"));
85 
86     connect(widget->feedNameEdit, &QLineEdit::textChanged, this, &FeedPropertiesDialog::slotSetWindowTitle);
87 }
88 
~FeedPropertiesDialog()89 FeedPropertiesDialog::~FeedPropertiesDialog()
90 {
91 }
92 
accept()93 void FeedPropertiesDialog::accept()
94 {
95     m_feed->setNotificationMode(false);
96     m_feed->setTitle(feedName());
97     m_feed->setXmlUrl(url());
98     m_feed->setCustomFetchIntervalEnabled(autoFetch());
99     if (autoFetch()) {
100         m_feed->setFetchInterval(fetchInterval());
101     }
102     m_feed->setArchiveMode(archiveMode());
103     m_feed->setMaxArticleAge(maxArticleAge());
104     m_feed->setMaxArticleNumber(maxArticleNumber());
105     m_feed->setMarkImmediatelyAsRead(markImmediatelyAsRead());
106     m_feed->setUseNotification(useNotification());
107     m_feed->setLoadLinkedWebsite(loadLinkedWebsite());
108     m_feed->setNotificationMode(true);
109     m_feed->setComment(comment());
110 
111     QDialog::accept();
112 }
113 
slotSetWindowTitle(const QString & title)114 void FeedPropertiesDialog::slotSetWindowTitle(const QString &title)
115 {
116     setWindowTitle(title.isEmpty() ? i18nc("@title:window", "Feed Properties") : i18nc("@title:window", "Properties of %1", title));
117     mOkButton->setEnabled(!title.trimmed().isEmpty());
118 }
119 
setFeed(Feed * feed)120 void FeedPropertiesDialog::setFeed(Feed *feed)
121 {
122     m_feed = feed;
123     if (!feed) {
124         return;
125     }
126 
127     setFeedName(feed->title());
128     setUrl(feed->xmlUrl());
129     setAutoFetch(feed->useCustomFetchInterval());
130     if (feed->useCustomFetchInterval()) {
131         setFetchInterval(feed->fetchInterval());
132     } else {
133         setFetchInterval(Settings::autoFetchInterval());
134     }
135     setArchiveMode(feed->archiveMode());
136     setMaxArticleAge(feed->maxArticleAge());
137     setMaxArticleNumber(feed->maxArticleNumber());
138     setMarkImmediatelyAsRead(feed->markImmediatelyAsRead());
139     setUseNotification(feed->useNotification());
140     setLoadLinkedWebsite(feed->loadLinkedWebsite());
141     setComment(feed->comment());
142     slotSetWindowTitle(feedName());
143 }
144 
comment() const145 QString FeedPropertiesDialog::comment() const
146 {
147     return widget->commentEdit->text();
148 }
149 
setComment(const QString & comment)150 void FeedPropertiesDialog::setComment(const QString &comment)
151 {
152     widget->commentEdit->setText(comment);
153 }
154 
feedName() const155 QString FeedPropertiesDialog::feedName() const
156 {
157     return widget->feedNameEdit->text();
158 }
159 
url() const160 QString FeedPropertiesDialog::url() const
161 {
162     return widget->urlEdit->text();
163 }
164 
autoFetch() const165 bool FeedPropertiesDialog::autoFetch() const
166 {
167     return widget->cb_updateInterval->isChecked();
168 }
169 
fetchInterval() const170 int FeedPropertiesDialog::fetchInterval() const
171 {
172     switch (widget->updateComboBox->currentIndex()) {
173     case FeedPropertiesWidget::Minutes:
174         return widget->updateSpinBox->value();
175     case FeedPropertiesWidget::Hours:
176         return widget->updateSpinBox->value() * 60;
177     case FeedPropertiesWidget::Days:
178         return widget->updateSpinBox->value() * 60 * 24;
179     case FeedPropertiesWidget::Never:
180     default:
181         return -1; // never
182     }
183 }
184 
archiveMode() const185 Feed::ArchiveMode FeedPropertiesDialog::archiveMode() const
186 {
187     // i could check the button group's int, but order could change...
188     if (widget->rb_globalDefault->isChecked()) {
189         return Feed::globalDefault;
190     }
191 
192     if (widget->rb_keepAllArticles->isChecked()) {
193         return Feed::keepAllArticles;
194     }
195 
196     if (widget->rb_limitArticleAge->isChecked()) {
197         return Feed::limitArticleAge;
198     }
199 
200     if (widget->rb_limitArticleNumber->isChecked()) {
201         return Feed::limitArticleNumber;
202     }
203 
204     if (widget->rb_disableArchiving->isChecked()) {
205         return Feed::disableArchiving;
206     }
207 
208     // in a perfect world, this is never reached
209 
210     return Feed::globalDefault;
211 }
212 
maxArticleAge() const213 int FeedPropertiesDialog::maxArticleAge() const
214 {
215     return widget->sb_maxArticleAge->value();
216 }
217 
maxArticleNumber() const218 int FeedPropertiesDialog::maxArticleNumber() const
219 {
220     return widget->sb_maxArticleNumber->value();
221 }
222 
setArchiveMode(Feed::ArchiveMode mode)223 void FeedPropertiesDialog::setArchiveMode(Feed::ArchiveMode mode)
224 {
225     switch (mode) {
226     case Feed::globalDefault:
227         widget->rb_globalDefault->setChecked(true);
228         break;
229     case Feed::keepAllArticles:
230         widget->rb_keepAllArticles->setChecked(true);
231         break;
232     case Feed::disableArchiving:
233         widget->rb_disableArchiving->setChecked(true);
234         break;
235     case Feed::limitArticleAge:
236         widget->rb_limitArticleAge->setChecked(true);
237         break;
238     case Feed::limitArticleNumber:
239         widget->rb_limitArticleNumber->setChecked(true);
240     }
241 }
242 
setFeedName(const QString & title)243 void FeedPropertiesDialog::setFeedName(const QString &title)
244 {
245     widget->feedNameEdit->setText(title);
246 }
247 
setUrl(const QString & url)248 void FeedPropertiesDialog::setUrl(const QString &url)
249 {
250     widget->urlEdit->setText(url);
251 }
252 
setAutoFetch(bool customFetchEnabled)253 void FeedPropertiesDialog::setAutoFetch(bool customFetchEnabled)
254 {
255     widget->cb_updateInterval->setChecked(customFetchEnabled);
256     widget->updateComboBox->setEnabled(customFetchEnabled);
257 
258     if (widget->updateSpinBox->value() > -1) {
259         widget->updateSpinBox->setEnabled(customFetchEnabled);
260     } else {
261         widget->updateSpinBox->setEnabled(false);
262     }
263 }
264 
setFetchInterval(int interval)265 void FeedPropertiesDialog::setFetchInterval(int interval)
266 {
267     if (interval == -1) { // never update
268         widget->updateSpinBox->setValue(0);
269         widget->updateSpinBox->setDisabled(true);
270         widget->updateComboBox->setCurrentIndex(FeedPropertiesWidget::Never);
271         return;
272     }
273 
274     if (interval == 0) {
275         widget->updateSpinBox->setValue(0);
276         widget->updateSpinBox->setEnabled(widget->cb_updateInterval->isChecked());
277         widget->updateComboBox->setCurrentIndex(FeedPropertiesWidget::Minutes);
278         return;
279     }
280 
281     if (interval % (60 * 24) == 0) {
282         widget->updateSpinBox->setValue(interval / (60 * 24));
283         widget->updateSpinBox->setEnabled(widget->cb_updateInterval->isChecked());
284         widget->updateComboBox->setCurrentIndex(FeedPropertiesWidget::Days);
285         return;
286     }
287 
288     if (interval % 60 == 0) {
289         widget->updateSpinBox->setValue(interval / 60);
290         widget->updateSpinBox->setEnabled(widget->cb_updateInterval->isChecked());
291         widget->updateComboBox->setCurrentIndex(FeedPropertiesWidget::Hours);
292         return;
293     }
294 
295     widget->updateSpinBox->setValue(interval);
296     widget->updateSpinBox->setEnabled(widget->cb_updateInterval->isChecked());
297     widget->updateComboBox->setCurrentIndex(FeedPropertiesWidget::Minutes);
298 }
299 
setMaxArticleAge(int age)300 void FeedPropertiesDialog::setMaxArticleAge(int age)
301 {
302     widget->sb_maxArticleAge->setValue(age);
303 }
304 
setMaxArticleNumber(int number)305 void FeedPropertiesDialog::setMaxArticleNumber(int number)
306 {
307     widget->sb_maxArticleNumber->setValue(number);
308 }
309 
setMarkImmediatelyAsRead(bool enabled)310 void FeedPropertiesDialog::setMarkImmediatelyAsRead(bool enabled)
311 {
312     widget->checkBox_markRead->setChecked(enabled);
313 }
314 
markImmediatelyAsRead() const315 bool FeedPropertiesDialog::markImmediatelyAsRead() const
316 {
317     return widget->checkBox_markRead->isChecked();
318 }
319 
setUseNotification(bool enabled)320 void FeedPropertiesDialog::setUseNotification(bool enabled)
321 {
322     widget->checkBox_useNotification->setChecked(enabled);
323 }
324 
useNotification() const325 bool FeedPropertiesDialog::useNotification() const
326 {
327     return widget->checkBox_useNotification->isChecked();
328 }
329 
loadLinkedWebsite() const330 bool FeedPropertiesDialog::loadLinkedWebsite() const
331 {
332     return widget->checkBox_loadWebsite->isChecked();
333 }
334 
setLoadLinkedWebsite(bool enabled)335 void FeedPropertiesDialog::setLoadLinkedWebsite(bool enabled)
336 {
337     widget->checkBox_loadWebsite->setChecked(enabled);
338 }
339 
selectFeedName()340 void FeedPropertiesDialog::selectFeedName()
341 {
342     widget->feedNameEdit->selectAll();
343 }
344