diff options
Diffstat (limited to 'plugins/rssfeed/rssfeedmanager.cpp')
-rw-r--r-- | plugins/rssfeed/rssfeedmanager.cpp | 1318 |
1 files changed, 1318 insertions, 0 deletions
diff --git a/plugins/rssfeed/rssfeedmanager.cpp b/plugins/rssfeed/rssfeedmanager.cpp new file mode 100644 index 0000000..106ca0f --- /dev/null +++ b/plugins/rssfeed/rssfeedmanager.cpp @@ -0,0 +1,1318 @@ +/*************************************************************************** + * Copyright (C) 2006 by Alan Jones * + * skyphyr@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#include "rssfeedmanager.h" + +#include <kdirlister.h> +#include <kfileitem.h> +#include <klocale.h> +#include <kio/netaccess.h> +#include <kstandarddirs.h> +#include <keditlistbox.h> +// #include <kmimetype.h> +#include <kmessagebox.h> + +#include <qstring.h> +#include <qobject.h> +#include <qfile.h> +#include <qdatetime.h> + +#include <qlineedit.h> +#include <kurlrequester.h> +#include <qspinbox.h> +#include <qcheckbox.h> +#include <qdatetimeedit.h> +#include <qtable.h> +#include <qregexp.h> +#include <qlayout.h> + +#include <torrent/globals.h> +#include <util/log.h> +#include <util/constants.h> + +#include <interfaces/coreinterface.h> + +#include <qapplication.h> + +#include "../../libktorrent/torrent/bdecoder.h" +#include "../../libktorrent/torrent/bnode.h" + +#include "rsslinkdownloader.h" + +using namespace bt; + +namespace kt +{ + + RssFeedManager::RssFeedManager(CoreInterface* core, QWidget * parent) : RssFeedWidget(parent) + { + //Construct the manager + m_core = core; + currentFeed = -1; + currentAcceptFilter = -1; + currentRejectFilter = -1; + + feedListSaving = false; + filterListSaving = false; + + //get the articles list setup + feedArticles->setLeftMargin(0); + feedArticles->verticalHeader()->hide(); + feedArticles->setNumCols(3); + feedArticles->setColumnLabels(QStringList() << i18n("Title") << i18n("Description") << i18n("Link")); + feedArticles->horizontalHeader()->setStretchEnabled(true, 0); + feedArticles->hideColumn(1); + feedArticles->hideColumn(2); + + //get the matches list setup + filterMatches->setLeftMargin(0); + filterMatches->verticalHeader()->hide(); + filterMatches->setNumCols(4); + filterMatches->setColumnLabels(QStringList() << i18n("Season") << i18n("Episode") << i18n("Time") << i18n("Link")); + filterMatches->setColumnWidth(0, 60); + filterMatches->setColumnWidth(1, 60); + filterMatches->setColumnWidth(2, 180); + filterMatches->horizontalHeader()->setStretchEnabled(true, 3); + + loadFeedList(); + loadFilterList(); + + //connect the buttons + connect(newFeed, SIGNAL(clicked()), this, SLOT(addNewFeed() ) ); + connect(deleteFeed, SIGNAL(clicked()), this, SLOT(deleteSelectedFeed() ) ); + + connect(newAcceptFilter, SIGNAL(clicked()), this, SLOT(addNewAcceptFilter() ) ); + connect(deleteAcceptFilter, SIGNAL(clicked()), this, SLOT(deleteSelectedAcceptFilter() ) ); + + connect(newRejectFilter, SIGNAL(clicked()), this, SLOT(addNewRejectFilter() ) ); + connect(deleteRejectFilter, SIGNAL(clicked()), this, SLOT(deleteSelectedRejectFilter() ) ); + + //connect the changing of the active feed + connect(feedlist, SIGNAL(selectionChanged()), this, SLOT(changedActiveFeed()) ); + + //connect the changing of the url to enable the refresh button + connect(feedUrl, SIGNAL(textChanged(const QString &)), this, SLOT(changedFeedUrl()) ); + + //connect the changing of the filters + connect(acceptFilterList, SIGNAL(selectionChanged()), this, SLOT(changedActiveAcceptFilter()) ); + connect(rejectFilterList, SIGNAL(selectionChanged()), this, SLOT(changedActiveRejectFilter()) ); + + //connect the selection and downloading of articles + connect(feedArticles, SIGNAL(selectionChanged()), this, SLOT(changedArticleSelection()) ); + connect(downloadArticle, SIGNAL(clicked()), this, SLOT(downloadSelectedArticles()) ); + + //connect the selection, downloading and deletion of matches + connect(filterMatches, SIGNAL(selectionChanged()), this, SLOT(changedMatchSelection()) ); + connect(downloadFilterMatch, SIGNAL(clicked()), this, SLOT(downloadSelectedMatches()) ); + connect(deleteFilterMatch, SIGNAL(clicked()), this, SLOT(deleteSelectedMatches()) ); + + //connect the test text update to the slot + connect(testText, SIGNAL(textChanged(const QString &)), this, SLOT(testTextChanged()) ); + connect(testTestText, SIGNAL(clicked()), this, SLOT(testFilter()) ); + + changedActiveFeed(); + changedActiveAcceptFilter(); + + } + + RssFeedManager::~RssFeedManager() + { + //Destruct the manager + } + + void RssFeedManager::clearArticles() + { + int pos = feeds.find((RssFeed *)sender()); + + if (pos >= 0) + { + feeds.at(pos)->clearArticles(); + if (feedlist->isSelected(pos)) + { + //this feed is active so we should update the display + feedArticles->setNumRows(0); + } + } + } + + void RssFeedManager::changedFeedUrl() + { + refreshFeed->setEnabled(!feedUrl->url().isEmpty()); + } + + void RssFeedManager::connectFeed(int index) + { + + connect(feedTitle, SIGNAL(textChanged(const QString &)), feeds.at(index), SLOT(setTitle(const QString &) ) ); + connect(feeds.at(index), SIGNAL(titleChanged(const QString &)), this, SLOT(setFeedTitle(const QString &) ) ); + + //url + connect(feedUrl, SIGNAL(textChanged(const QString &)), feeds.at(index), SLOT(setFeedUrl(const QString&) ) ); + connect(feeds.at(index), SIGNAL(feedUrlChanged(const KURL&)), feedUrl, SLOT(setKURL(const KURL&) ) ); + + //articleAge + connect(feedArticleAge, SIGNAL(valueChanged(int)), feeds.at(index), SLOT(setArticleAge(int) ) ); + connect(feeds.at(index), SIGNAL(articleAgeChanged(int)), feedArticleAge, SLOT(setValue(int) ) ); + + //active + connect(feedActive, SIGNAL(toggled(bool)), feeds.at(index), SLOT(setActive(bool) ) ); + connect(feeds.at(index), SIGNAL(activeChanged(bool)), feedActive, SLOT(setChecked(bool) ) ); + + //autoRefresh + connect(feedAutoRefresh, SIGNAL(valueChanged(const QTime&)), feeds.at(index), SLOT(setAutoRefresh(const QTime&) ) ); + connect(feeds.at(index), SIGNAL(autoRefreshChanged(const QTime&)), feedAutoRefresh, SLOT(setTime(const QTime&) ) ); + + //ignoreTTL + connect(feedIgnoreTTL, SIGNAL(toggled(bool)), feeds.at(index), SLOT(setIgnoreTTL(bool) ) ); + connect(feeds.at(index), SIGNAL(ignoreTTLChanged(bool)), feedIgnoreTTL, SLOT(setChecked(bool) ) ); + + //articles + connect(feeds.at(index), SIGNAL(articlesChanged(const RssArticle::List&)), this, SLOT(updateArticles(const RssArticle::List&) ) ); + + //connect the refresh button + connect(refreshFeed, SIGNAL(clicked()), feeds.at(index), SLOT(refreshFeed()) ); + } + + void RssFeedManager::disconnectFeed(int index) + { + disconnect(feedTitle, SIGNAL(textChanged(const QString &)), feeds.at(index), SLOT(setTitle(const QString &) ) ); + disconnect(feeds.at(index), SIGNAL(titleChanged(const QString &)), this, SLOT(setFeedTitle(const QString &) ) ); + + //url + disconnect(feedUrl, SIGNAL(textChanged(const QString &)), feeds.at(index), SLOT(setFeedUrl(const QString&) ) ); + disconnect(feeds.at(index), SIGNAL(feedUrlChanged(const KURL&)), feedUrl, SLOT(setKURL(const KURL&) ) ); + + //articleAge + disconnect(feedArticleAge, SIGNAL(valueChanged(int)), feeds.at(index), SLOT(setArticleAge(int) ) ); + disconnect(feeds.at(index), SIGNAL(articleAgeChanged(int)), feedArticleAge, SLOT(setValue(int) ) ); + + //active + disconnect(feedActive, SIGNAL(toggled(bool)), feeds.at(index), SLOT(setActive(bool) ) ); + disconnect(feeds.at(index), SIGNAL(activeChanged(bool)), feedActive, SLOT(setChecked(bool) ) ); + + //autoRefresh + disconnect(feedAutoRefresh, SIGNAL(valueChanged(const QTime&)), feeds.at(index), SLOT(setAutoRefresh(const QTime&) ) ); + disconnect(feeds.at(index), SIGNAL(autoRefreshChanged(const QTime&)), feedAutoRefresh, SLOT(setTime(const QTime&) ) ); + + //ignoreTTL + disconnect(feedIgnoreTTL, SIGNAL(toggled(bool)), feeds.at(index), SLOT(setIgnoreTTL(bool) ) ); + disconnect(feeds.at(index), SIGNAL(ignoreTTLChanged(bool)), feedIgnoreTTL, SLOT(setChecked(bool) ) ); + + //articles + disconnect(feeds.at(index), SIGNAL(articlesChanged(const RssArticle::List&)), this, SLOT(updateArticles(const RssArticle::List&) ) ); + + disconnect(refreshFeed, SIGNAL(clicked()), feeds.at(index), SLOT(refreshFeed()) ); + } + + void RssFeedManager::connectFilter(int index, bool acceptFilter) + { + if (acceptFilter) + { + //title + connect(filterTitle, SIGNAL(textChanged(const QString &)), acceptFilters.at(index), SLOT(setTitle(const QString &) ) ); + connect(acceptFilters.at(index), SIGNAL(titleChanged(const QString &)), this, SLOT(setFilterTitle(const QString &) ) ); + //active + connect(filterActive, SIGNAL(toggled(bool)), acceptFilters.at(index), SLOT(setActive(bool) ) ); + connect(acceptFilters.at(index), SIGNAL(activeChanged(bool)), filterActive, SLOT(setChecked(bool) ) ); + //regExps + connect(filterRegExps, SIGNAL(changed()), this, SLOT(updateRegExps()) ); + //series + connect(filterSeries, SIGNAL(toggled(bool)), acceptFilters.at(index), SLOT(setSeries(bool) ) ); + connect(acceptFilters.at(index), SIGNAL(seriesChanged(bool)), filterSeries, SLOT(setChecked(bool) ) ); + //sansEpisode + connect(filterSansEpisode, SIGNAL(toggled(bool)), acceptFilters.at(index), SLOT(setSansEpisode(bool) ) ); + connect(acceptFilters.at(index), SIGNAL(sansEpisodeChanged(bool)), filterSansEpisode, SLOT(setChecked(bool) ) ); + //minSeason + connect(filterMinSeason, SIGNAL(valueChanged(int)), acceptFilters.at(index), SLOT(setMinSeason(int) ) ); + connect(acceptFilters.at(index), SIGNAL(minSeasonChanged(int)), filterMinSeason, SLOT(setValue(int) ) ); + //minEpisode + connect(filterMinEpisode, SIGNAL(valueChanged(int)), acceptFilters.at(index), SLOT(setMinEpisode(int) ) ); + connect(acceptFilters.at(index), SIGNAL(minEpisodeChanged(int)), filterMinEpisode, SLOT(setValue(int) ) ); + //maxSeason + connect(filterMaxSeason, SIGNAL(valueChanged(int)), acceptFilters.at(index), SLOT(setMaxSeason(int) ) ); + connect(acceptFilters.at(index), SIGNAL(maxSeasonChanged(int)), filterMaxSeason, SLOT(setValue(int) ) ); + //maxEpisode + connect(filterMaxEpisode, SIGNAL(valueChanged(int)), acceptFilters.at(index), SLOT(setMaxEpisode(int) ) ); + connect(acceptFilters.at(index), SIGNAL(maxEpisodeChanged(int)), filterMaxEpisode, SLOT(setValue(int) ) ); + //matches + connect(acceptFilters.at(index), SIGNAL(matchesChanged(const QValueList<FilterMatch>&)), this, SLOT(updateMatches(const QValueList<FilterMatch>&) ) ); + + connect(processFilter, SIGNAL(clicked()), acceptFilters.at(index), SIGNAL(rescanFilter()) ); + + } + else + { + //title + connect(filterTitle, SIGNAL(textChanged(const QString &)), rejectFilters.at(index), SLOT(setTitle(const QString &) ) ); + connect(rejectFilters.at(index), SIGNAL(titleChanged(const QString &)), this, SLOT(setFilterTitle(const QString &) ) ); + //active + connect(filterActive, SIGNAL(toggled(bool)), rejectFilters.at(index), SLOT(setActive(bool) ) ); + connect(rejectFilters.at(index), SIGNAL(activeChanged(bool)), filterActive, SLOT(setChecked(bool) ) ); + //regExps + connect(filterRegExps, SIGNAL(changed()), this, SLOT(updateRegExps()) ); + //series + connect(filterSeries, SIGNAL(toggled(bool)), rejectFilters.at(index), SLOT(setSeries(bool) ) ); + connect(rejectFilters.at(index), SIGNAL(seriesChanged(bool)), filterSeries, SLOT(setChecked(bool) ) ); + //sansEpisode + connect(filterSansEpisode, SIGNAL(toggled(bool)), rejectFilters.at(index), SLOT(setSansEpisode(bool) ) ); + connect(rejectFilters.at(index), SIGNAL(sansEpisodeChanged(bool)), filterSansEpisode, SLOT(setChecked(bool) ) ); + //minSeason + connect(filterMinSeason, SIGNAL(valueChanged(int)), rejectFilters.at(index), SLOT(setMinSeason(int) ) ); + connect(rejectFilters.at(index), SIGNAL(minSeasonChanged(int)), filterMinSeason, SLOT(setValue(int) ) ); + //minEpisode + connect(filterMinEpisode, SIGNAL(valueChanged(int)), rejectFilters.at(index), SLOT(setMinEpisode(int) ) ); + connect(rejectFilters.at(index), SIGNAL(minEpisodeChanged(int)), filterMinEpisode, SLOT(setValue(int) ) ); + //maxSeason + connect(filterMaxSeason, SIGNAL(valueChanged(int)), rejectFilters.at(index), SLOT(setMaxSeason(int) ) ); + connect(rejectFilters.at(index), SIGNAL(maxSeasonChanged(int)), filterMaxSeason, SLOT(setValue(int) ) ); + //maxEpisode + connect(filterMaxEpisode, SIGNAL(valueChanged(int)), rejectFilters.at(index), SLOT(setMaxEpisode(int) ) ); + connect(rejectFilters.at(index), SIGNAL(maxEpisodeChanged(int)), filterMaxEpisode, SLOT(setValue(int) ) ); + //matches + connect(rejectFilters.at(index), SIGNAL(matchesChanged(const QValueList<FilterMatch>&)), this, SLOT(updateMatches(const QValueList<FilterMatch>&) ) ); + + connect(processFilter, SIGNAL(clicked()), rejectFilters.at(index), SIGNAL(rescanFilter()) ); + + } + } + + void RssFeedManager::disconnectFilter(int index, bool acceptFilter) + { + if (acceptFilter) + { + //title + disconnect(filterTitle, SIGNAL(textChanged(const QString &)), acceptFilters.at(index), SLOT(setTitle(const QString &) ) ); + disconnect(acceptFilters.at(index), SIGNAL(titleChanged(const QString &)), this, SLOT(setFilterTitle(const QString &) ) ); + //active + disconnect(filterActive, SIGNAL(toggled(bool)), acceptFilters.at(index), SLOT(setActive(bool) ) ); + disconnect(acceptFilters.at(index), SIGNAL(activeChanged(bool)), filterActive, SLOT(setChecked(bool) ) ); + //regExps + disconnect(filterRegExps, SIGNAL(changed()), this, SLOT(updateRegExps()) ); + //series + disconnect(filterSeries, SIGNAL(toggled(bool)), acceptFilters.at(index), SLOT(setSeries(bool) ) ); + disconnect(acceptFilters.at(index), SIGNAL(seriesChanged(bool)), filterSeries, SLOT(setChecked(bool) ) ); + //sansEpisode + disconnect(filterSansEpisode, SIGNAL(toggled(bool)), acceptFilters.at(index), SLOT(setSansEpisode(bool) ) ); + disconnect(acceptFilters.at(index), SIGNAL(sansEpisodeChanged(bool)), filterSansEpisode, SLOT(setChecked(bool) ) ); + //minSeason + disconnect(filterMinSeason, SIGNAL(valueChanged(int)), acceptFilters.at(index), SLOT(setMinSeason(int) ) ); + disconnect(acceptFilters.at(index), SIGNAL(minSeasonChanged(int)), filterMinSeason, SLOT(setValue(int) ) ); + //minEpisode + disconnect(filterMinEpisode, SIGNAL(valueChanged(int)), acceptFilters.at(index), SLOT(setMinEpisode(int) ) ); + disconnect(acceptFilters.at(index), SIGNAL(minEpisodeChanged(int)), filterMinEpisode, SLOT(setValue(int) ) ); + //maxSeason + disconnect(filterMaxSeason, SIGNAL(valueChanged(int)), acceptFilters.at(index), SLOT(setMaxSeason(int) ) ); + disconnect(acceptFilters.at(index), SIGNAL(maxSeasonChanged(int)), filterMaxSeason, SLOT(setValue(int) ) ); + //maxEpisode + disconnect(filterMaxEpisode, SIGNAL(valueChanged(int)), acceptFilters.at(index), SLOT(setMaxEpisode(int) ) ); + disconnect(acceptFilters.at(index), SIGNAL(maxEpisodeChanged(int)), filterMaxEpisode, SLOT(setValue(int) ) ); + //matches + disconnect(acceptFilters.at(index), SIGNAL(matchesChanged(const QValueList<FilterMatch>&)), this, SLOT(updateMatches(const QValueList<FilterMatch>&) ) ); + + disconnect(processFilter, SIGNAL(clicked()), acceptFilters.at(index), SIGNAL(rescanFilter()) ); + } + else + { + //title + disconnect(filterTitle, SIGNAL(textChanged(const QString &)), rejectFilters.at(index), SLOT(setTitle(const QString &) ) ); + disconnect(rejectFilters.at(index), SIGNAL(titleChanged(const QString &)), this, SLOT(setFilterTitle(const QString &) ) ); + //active + disconnect(filterActive, SIGNAL(toggled(bool)), rejectFilters.at(index), SLOT(setActive(bool) ) ); + disconnect(rejectFilters.at(index), SIGNAL(activeChanged(bool)), filterActive, SLOT(setChecked(bool) ) ); + //regExps + disconnect(filterRegExps, SIGNAL(changed()), this, SLOT(updateRegExps()) ); + //series + disconnect(filterSeries, SIGNAL(toggled(bool)), rejectFilters.at(index), SLOT(setSeries(bool) ) ); + disconnect(rejectFilters.at(index), SIGNAL(seriesChanged(bool)), filterSeries, SLOT(setChecked(bool) ) ); + //sansEpisode + disconnect(filterSansEpisode, SIGNAL(toggled(bool)), rejectFilters.at(index), SLOT(setSansEpisode(bool) ) ); + disconnect(rejectFilters.at(index), SIGNAL(sansEpisodeChanged(bool)), filterSansEpisode, SLOT(setChecked(bool) ) ); + //minSeason + disconnect(filterMinSeason, SIGNAL(valueChanged(int)), rejectFilters.at(index), SLOT(setMinSeason(int) ) ); + disconnect(rejectFilters.at(index), SIGNAL(minSeasonChanged(int)), filterMinSeason, SLOT(setValue(int) ) ); + //minEpisode + disconnect(filterMinEpisode, SIGNAL(valueChanged(int)), rejectFilters.at(index), SLOT(setMinEpisode(int) ) ); + disconnect(rejectFilters.at(index), SIGNAL(minEpisodeChanged(int)), filterMinEpisode, SLOT(setValue(int) ) ); + //maxSeason + disconnect(filterMaxSeason, SIGNAL(valueChanged(int)), rejectFilters.at(index), SLOT(setMaxSeason(int) ) ); + disconnect(rejectFilters.at(index), SIGNAL(maxSeasonChanged(int)), filterMaxSeason, SLOT(setValue(int) ) ); + //maxEpisode + disconnect(filterMaxEpisode, SIGNAL(valueChanged(int)), rejectFilters.at(index), SLOT(setMaxEpisode(int) ) ); + disconnect(rejectFilters.at(index), SIGNAL(maxEpisodeChanged(int)), filterMaxEpisode, SLOT(setValue(int) ) ); + //matches + disconnect(rejectFilters.at(index), SIGNAL(matchesChanged(const QValueList<FilterMatch>&)), this, SLOT(updateMatches(const QValueList<FilterMatch>&) ) ); + + disconnect(processFilter, SIGNAL(clicked()), rejectFilters.at(index), SIGNAL(rescanFilter()) ); + + } + } + + void RssFeedManager::addNewFeed(RssFeed feed) + { + if (feeds.isEmpty()) + deleteFeed->setEnabled(true); + + feeds.append(new RssFeed(feed)); + + int index = feeds.count()-1; + feedlist->insertItem(feeds.at(index)->title()); + feedlist->setCurrentItem(index); + + //update the feed list + connect(feeds.at(index), SIGNAL(titleChanged(const QString&)), this, SLOT(updateFeedList()) ); + + //clear the articles list when the url is changed + connect(feeds.at(index), SIGNAL(feedUrlChanged(const KURL&)), this, SLOT(clearArticles() ) ); + + //connect the scanArticle signal to the scanArticle slot + connect(feeds.at(index), SIGNAL(scanRssArticle(RssArticle)), this, SLOT(scanArticle(RssArticle) ) ); + + //connect all the fields to the save slot + //title + connect(feeds.at(index), SIGNAL(titleChanged(const QString &)), this, SLOT(saveFeedList() ) ); + //url + connect(feeds.at(index), SIGNAL(feedUrlChanged(const KURL&)), this, SLOT(saveFeedList() ) ); + //articleAge + connect(feeds.at(index), SIGNAL(articleAgeChanged(int)), this, SLOT(saveFeedList() ) ); + //active + connect(feeds.at(index), SIGNAL(activeChanged(bool)), this, SLOT(saveFeedList() ) ); + //autoRefresh + connect(feeds.at(index), SIGNAL(autoRefreshChanged(const QTime&)), this, SLOT(saveFeedList() ) ); + //ignoreTTL + connect(feeds.at(index), SIGNAL(ignoreTTLChanged(bool)), this, SLOT(saveFeedList() ) ); + + } + + void RssFeedManager::addNewAcceptFilter(RssFilter filter) + { + if (acceptFilters.isEmpty()) + deleteAcceptFilter->setEnabled(true); + + acceptFilters.append(new RssFilter(filter)); + + int index = acceptFilters.count()-1; + acceptFilterList->insertItem(acceptFilters.at(index)->title()); + acceptFilterList->setCurrentItem(index); + + connect(acceptFilters.at(index), SIGNAL(titleChanged(const QString&)), this, SLOT(updateAcceptFilterList()) ); + + //connect all the fields to the save slot + //title + connect(acceptFilters.at(index), SIGNAL(titleChanged(const QString &)), this, SLOT(saveFilterList() ) ); + //active + connect(acceptFilters.at(index), SIGNAL(activeChanged( bool )), this, SLOT(saveFilterList() ) ); + //regexps + connect(acceptFilters.at(index), SIGNAL(regExpsChanged( const QStringList& )), this, SLOT(saveFilterList() ) ); + //series + connect(acceptFilters.at(index), SIGNAL(seriesChanged( bool )), this, SLOT(saveFilterList() ) ); + //sansEpisode + connect(acceptFilters.at(index), SIGNAL(sansEpisodeChanged( bool )), this, SLOT(saveFilterList() ) ); + //minSeason + connect(acceptFilters.at(index), SIGNAL(minSeasonChanged (int )), this, SLOT(saveFilterList() ) ); + //minEpisode + connect(acceptFilters.at(index), SIGNAL(minEpisodeChanged (int )), this, SLOT(saveFilterList() ) ); + //maxSeason + connect(acceptFilters.at(index), SIGNAL(maxSeasonChanged (int )), this, SLOT(saveFilterList() ) ); + //maxEpiosde + connect(acceptFilters.at(index), SIGNAL(maxEpisodeChanged (int )), this, SLOT(saveFilterList() ) ); + //matches + connect(acceptFilters.at(index), SIGNAL(matchesChanged( const QValueList<FilterMatch>& )), this, SLOT(saveFilterList() ) ); + + //connect the rescan signal to the rescan slot + connect(acceptFilters.at(index), SIGNAL(rescanFilter()), this, SLOT(rescanFilter()) ); + +// //connect all except the matchesChanged to the rescanFilter slot +// //title +// connect(acceptFilters.at(index), SIGNAL(titleChanged(const QString &)), this, SLOT(rescanFilter() ) ); +// //active +// connect(acceptFilters.at(index), SIGNAL(activeChanged( bool )), this, SLOT(rescanFilter() ) ); +// //regexps +// connect(acceptFilters.at(index), SIGNAL(regExpsChanged( const QStringList& )), this, SLOT(rescanFilter() ) ); +// //series +// connect(acceptFilters.at(index), SIGNAL(seriesChanged( bool )), this, SLOT(rescanFilter() ) ); +// //sansEpisode +// connect(acceptFilters.at(index), SIGNAL(sansEpisodeChanged( bool )), this, SLOT(rescanFilter() ) ); +// //minSeason +// connect(acceptFilters.at(index), SIGNAL(minSeasonChanged (int )), this, SLOT(rescanFilter() ) ); +// //minEpisode +// connect(acceptFilters.at(index), SIGNAL(minEpisodeChanged (int )), this, SLOT(rescanFilter() ) ); +// //maxSeason +// connect(acceptFilters.at(index), SIGNAL(maxSeasonChanged (int )), this, SLOT(rescanFilter() ) ); +// //maxEpiosde +// connect(acceptFilters.at(index), SIGNAL(maxEpisodeChanged (int )), this, SLOT(rescanFilter() ) ); + + } + + void RssFeedManager::addNewRejectFilter(RssFilter filter) + { + if (rejectFilters.isEmpty()) + deleteRejectFilter->setEnabled(true); + + rejectFilters.append(new RssFilter(filter)); + + int index = rejectFilters.count()-1; + rejectFilterList->insertItem(rejectFilters.at(index)->title()); + rejectFilterList->setCurrentItem(index); + + connect(rejectFilters.at(index), SIGNAL(titleChanged(const QString&)), this, SLOT(updateRejectFilterList()) ); + + //connect all the fields to the save slot + //title + connect(rejectFilters.at(index), SIGNAL(titleChanged(const QString &)), this, SLOT(saveFilterList() ) ); + //active + connect(rejectFilters.at(index), SIGNAL(activeChanged( bool )), this, SLOT(saveFilterList() ) ); + //regexps + connect(rejectFilters.at(index), SIGNAL(regExpsChanged( const QStringList& )), this, SLOT(saveFilterList() ) ); + //series + connect(rejectFilters.at(index), SIGNAL(seriesChanged( bool )), this, SLOT(saveFilterList() ) ); + //sansEpisode + connect(rejectFilters.at(index), SIGNAL(sansEpisodeChanged( bool )), this, SLOT(saveFilterList() ) ); + //minSeason + connect(rejectFilters.at(index), SIGNAL(minSeasonChanged (int )), this, SLOT(saveFilterList() ) ); + //minEpisode + connect(rejectFilters.at(index), SIGNAL(minEpisodeChanged (int )), this, SLOT(saveFilterList() ) ); + //maxSeason + connect(rejectFilters.at(index), SIGNAL(maxSeasonChanged (int )), this, SLOT(saveFilterList() ) ); + //maxEpiosde + connect(rejectFilters.at(index), SIGNAL(maxEpisodeChanged (int )), this, SLOT(saveFilterList() ) ); + //matches + connect(rejectFilters.at(index), SIGNAL(matchesChanged( const QValueList<FilterMatch>& )), this, SLOT(saveFilterList() ) ); + + } + + void RssFeedManager::deleteSelectedFeed() + { + int currentItem = feedlist->currentItem(); + + if (currentItem < 0) + return; + + int newItem=currentItem-1; + + if (currentItem == -1 && feeds.count()) + newItem = 0; + + disconnectFeed(currentItem); + currentFeed = -1; + + delete feeds.at(currentItem); + feeds.remove(currentItem); + feedlist->removeItem(currentItem); + + if (feeds.isEmpty()) + deleteFeed->setEnabled(false); + + if (newItem >= 0) + { + feedlist->setSelected(newItem, true); + } + + saveFeedList(); + } + + void RssFeedManager::deleteSelectedAcceptFilter() + { + int currentItem = acceptFilterList->currentItem(); + + if (currentItem < 0) + return; + + int newItem=currentItem-1; + + if (currentItem == -1 && acceptFilters.count()) + newItem = 0; + + disconnectFilter(currentItem, true); + currentAcceptFilter = -1; + + delete acceptFilters.at(currentItem); + acceptFilters.remove(currentItem); + acceptFilterList->removeItem(currentItem); + + if (acceptFilters.isEmpty()) + deleteAcceptFilter->setEnabled(false); + + if (newItem >= 0) + { + acceptFilterList->setSelected(newItem, true); + } + + saveFilterList(); + } + + void RssFeedManager::deleteSelectedRejectFilter() + { + int currentItem = rejectFilterList->currentItem(); + + if (currentItem < 0) + return; + + int newItem=currentItem-1; + + if (currentItem == -1 && rejectFilters.count()) + newItem = 0; + + disconnectFilter(currentItem, false); + currentRejectFilter = -1; + + delete rejectFilters.at(currentItem); + rejectFilters.remove(currentItem); + rejectFilterList->removeItem(currentItem); + + if (rejectFilters.isEmpty()) + deleteRejectFilter->setEnabled(false); + + if (newItem >= 0) + { + rejectFilterList->setSelected(newItem, true); + } + + saveFilterList(); + } + + void RssFeedManager::updateRegExps() + { + if (currentRejectFilter < 0) + { + //accept filter is active + acceptFilters.at(currentAcceptFilter)->setRegExps(filterRegExps->items()); + } + else + { + //reject filter is active + rejectFilters.at(currentRejectFilter)->setRegExps(filterRegExps->items()); + } + } + + void RssFeedManager::updateFeedList(int item) + { + int cursorPos = feedTitle->cursorPosition(); + if (item < 0) + { + //let's check which one sent the signal - if we can't figure it all then update them all + int pos = feeds.find((RssFeed *)sender()); + + if (pos < 0) + { + for (int i=0; i<feedlist->count(); i++) + { + feedlist->changeItem(feeds.at(i)->title(), i); + } + } + else + { + //just change the feed sending the signal + feedlist->changeItem(feeds.at(pos)->title(), pos); + if (feedlist->isSelected(pos)) + { + feedTitle->setFocus(); + } + } + } + else + { + //just update item + feedlist->changeItem(feeds.at(item)->title(), item); + } + feedTitle->setCursorPosition(cursorPos); + } + + void RssFeedManager::updateAcceptFilterList(int item) + { + int cursorPos = filterTitle->cursorPosition(); + if (item < 0) + { + //let's check which one sent the signal - if we can't figure it all then update them all + int pos = acceptFilters.find((RssFilter *)sender()); + + if (pos < 0) + { + for (int i=0; i<feedlist->count(); i++) + { + acceptFilterList->changeItem(acceptFilters.at(i)->title(), i); + } + } + else + { + //just change the feed sending the signal + acceptFilterList->changeItem(acceptFilters.at(pos)->title(), pos); + if (acceptFilterList->isSelected(pos)) + { + filterTitle->setFocus(); + } + } + } + else + { + //just update item + acceptFilterList->changeItem(acceptFilters.at(item)->title(), item); + } + filterTitle->setCursorPosition(cursorPos); + } + + void RssFeedManager::updateRejectFilterList(int item) + { + int cursorPos = filterTitle->cursorPosition(); + if (item < 0) + { + //let's check which one sent the signal - if we can't figure it all then update them all + int pos = rejectFilters.find((RssFilter *)sender()); + + if (pos < 0) + { + for (int i=0; i<feedlist->count(); i++) + { + rejectFilterList->changeItem(rejectFilters.at(i)->title(), i); + } + } + else + { + //just change the feed sending the signal + rejectFilterList->changeItem(rejectFilters.at(pos)->title(), pos); + if (rejectFilterList->isSelected(pos)) + { + filterTitle->setFocus(); + } + } + } + else + { + //just update item + rejectFilterList->changeItem(rejectFilters.at(item)->title(), item); + } + filterTitle->setCursorPosition(cursorPos); + } + + void RssFeedManager::updateArticles(const RssArticle::List& articles) + { + feedArticles->setNumRows(articles.count()); + for (int i=0; i<articles.count(); i++) + { + QString info; + if (articles[i].downloaded()==1) + { + info = ": Manually downloaded"; + } + else if (articles[i].downloaded()==3) + { + info = ": Automatically downloaded"; + } + feedArticles->setText(i, 0, articles[i].title() + info); + feedArticles->setText(i, 1, articles[i].description()); + feedArticles->setText(i, 2, articles[i].link().prettyURL()); + } + } + + void RssFeedManager::updateMatches(const QValueList<FilterMatch>& matches) + { + filterMatches->setNumRows(matches.count()); + for (int i=0; i<matches.count(); i++) + { + filterMatches->setText(i, 0, QString::number(matches[i].season())); + filterMatches->setText(i, 1, QString::number(matches[i].episode())); + filterMatches->setText(i, 2, matches[i].time()); + filterMatches->setText(i, 3, matches[i].link()); + } + + changedMatchSelection(); + } + + void RssFeedManager::changedArticleSelection() + { + bool downloadEnabled = false; + for (int i=0; i<feedArticles->numSelections(); i++) + { + if (feedArticles->selection(i).numRows()) + { + downloadEnabled = true; + break; + } + } + downloadArticle->setEnabled(downloadEnabled); + } + + void RssFeedManager::changedMatchSelection() + { + bool downloadEnabled = false; + for (int i=0; i<filterMatches->numSelections(); i++) + { + if (filterMatches->selection(i).numRows()) + { + downloadEnabled = true; + break; + } + } + downloadFilterMatch->setEnabled(downloadEnabled); + deleteFilterMatch->setEnabled(downloadEnabled); + } + + void RssFeedManager::downloadSelectedArticles() + { + for (int i=0; i<feedArticles->numSelections(); i++) + { + int endRow = feedArticles->selection(i).topRow() + feedArticles->selection(i).numRows(); + RssLinkDownloader * curDownload; + for (int j=feedArticles->selection(i).topRow(); j<endRow; j++) + { + curDownload = new RssLinkDownloader(m_core, feedArticles->text(j, 2)); + for (int i=0; i<feeds.count(); i++) + { + connect(curDownload, SIGNAL(linkDownloaded( QString, int )), feeds.at(i), SLOT(setDownloaded(QString, int)) ); + } + } + } + } + + void RssFeedManager::downloadSelectedMatches() + { + for (int i=0; i<filterMatches->numSelections(); i++) + { + int endRow = filterMatches->selection(i).topRow() + filterMatches->selection(i).numRows(); + for (int j=filterMatches->selection(i).topRow(); j<endRow; j++) + { + new RssLinkDownloader(m_core, filterMatches->text(j, 3)); + } + } + } + + void RssFeedManager::deleteSelectedMatches() + { + QStringList selectedLinks; + for (int i=0; i<filterMatches->numSelections(); i++) + { + int endRow = filterMatches->selection(i).topRow() + filterMatches->selection(i).numRows(); + for (int j=filterMatches->selection(i).topRow(); j<endRow; j++) + { + //add a match to the list of selected matches + selectedLinks.append(filterMatches->text(j, 3)); + } + } + + RssFilter * curFilter; + if (currentRejectFilter<0) + { + //we're currently testing an acceptFilter + curFilter = acceptFilters.at(currentAcceptFilter); + } + else + { + //it's a reject filter + curFilter = rejectFilters.at(currentRejectFilter); + } + + for (int i=0; i<selectedLinks.count(); i++) + { + curFilter->deleteMatch( selectedLinks[i] ); + } + + updateMatches(curFilter->matches()); + } + + void RssFeedManager::changedActiveFeed() + { + if (currentFeed != feedlist->currentItem() || currentFeed < 0) + { + //the selection has indeed changed + if (currentFeed >= 0) + { + //disconnect the gui signals from the old feed + disconnectFeed(currentFeed); + } + + //update the currentFeed + currentFeed = feedlist->currentItem(); + if (currentFeed >= 0) + { + //set the values + //title + feedTitle->setText(feeds.at(currentFeed)->title()); + //url + feedUrl->setKURL(feeds.at(currentFeed)->feedUrl()); + refreshFeed->setEnabled(!feeds.at(currentFeed)->feedUrl().url().isEmpty()); + //articleAge + feedArticleAge->setValue(feeds.at(currentFeed)->articleAge()); + //active + feedActive->setChecked(feeds.at(currentFeed)->active()); + //autoRefresh + feedAutoRefresh->setTime(feeds.at(currentFeed)->autoRefresh()); + //ignoreTTL + feedIgnoreTTL->setChecked(feeds.at(currentFeed)->ignoreTTL()); + feedAutoRefresh->setEnabled(feeds.at(currentFeed)->ignoreTTL()); + //articles + updateArticles(feeds.at(currentFeed)->articles()); + + //title + feedTitle->setEnabled(true); + //url + feedUrl->setEnabled(true); + //articleAge + feedArticleAge->setEnabled(true); + //active + feedActive->setEnabled(true); + //ignoreTTL + feedIgnoreTTL->setEnabled(true); + + //connect all the signals + connectFeed(currentFeed); + } + else + { + //clear the items + //title + feedTitle->clear(); + //url + feedUrl->clear(); + //articleAge + feedArticleAge->setValue(0); + //active + feedActive->setChecked(false); + //autoRefresh + feedAutoRefresh->setTime(QTime()); + //ignoreTTL + feedIgnoreTTL->setChecked(false); + //articles + feedArticles->setNumRows(0); + + //title + feedTitle->setEnabled(false); + //url + feedUrl->setEnabled(false); + //articleAge + feedArticleAge->setEnabled(false); + //active + feedActive->setEnabled(false); + //autoRefresh + feedAutoRefresh->setEnabled(false); + //ignoreTTL + feedIgnoreTTL->setEnabled(false); + } + } + } + + void RssFeedManager::changedActiveAcceptFilter() + { + if (currentRejectFilter >= 0) + { + rejectFilterList->setSelected(currentRejectFilter, false); + disconnectFilter(currentRejectFilter, false); + currentRejectFilter = -1; + } + + if (currentAcceptFilter != acceptFilterList->currentItem() || currentAcceptFilter < 0) + { + //the selection has indeed changed + + if (currentAcceptFilter >= 0) + { + //disconnect the gui signals from the old feed + disconnectFilter(currentAcceptFilter, true); + + } + + //update the currentFeed + currentAcceptFilter = acceptFilterList->currentItem(); + + if (currentAcceptFilter >= 0) + { + //set the values + filterTitle->setText(acceptFilters.at(currentAcceptFilter)->title()); + filterActive->setChecked(acceptFilters.at(currentAcceptFilter)->active()); + filterRegExps->setItems(acceptFilters.at(currentAcceptFilter)->regExps()); + filterSeries->setChecked(acceptFilters.at(currentAcceptFilter)->series()); + filterSansEpisode->setChecked(acceptFilters.at(currentAcceptFilter)->sansEpisode()); + filterMinSeason->setValue(acceptFilters.at(currentAcceptFilter)->minSeason()); + filterMinEpisode->setValue(acceptFilters.at(currentAcceptFilter)->minEpisode()); + filterMaxSeason->setValue(acceptFilters.at(currentAcceptFilter)->maxSeason()); + filterMaxEpisode->setValue(acceptFilters.at(currentAcceptFilter)->maxEpisode()); + + updateMatches(acceptFilters.at(currentAcceptFilter)->matches()); + + filterTitle->setEnabled(true); + filterActive->setEnabled(true); + filterRegExps->setEnabled(true); + filterSeries->setEnabled(true); + filterSansEpisode->setEnabled(true); + filterMinSeason->setEnabled(true); + filterMinEpisode->setEnabled(true); + filterMaxSeason->setEnabled(true); + filterMaxEpisode->setEnabled(true); + + processFilter->setEnabled(true); + testText->setEnabled(true); + + //connect all the signals + connectFilter(currentAcceptFilter, true); + } + else + { + if (currentRejectFilter < 0) + { + //clear the items + filterTitle->clear(); + filterActive->setChecked(false); + filterRegExps->clear(); + filterSeries->setChecked(false); + filterSansEpisode->setChecked(false); + filterMinSeason->setValue(0); + filterMinEpisode->setValue(0); + filterMaxSeason->setValue(0); + filterMaxEpisode->setValue(0); + filterMatches->setNumRows(0); + + filterTitle->setEnabled(false); + filterActive->setEnabled(false); + filterRegExps->setEnabled(false); + filterSeries->setEnabled(false); + filterSansEpisode->setEnabled(false); + filterMinSeason->setEnabled(false); + filterMinEpisode->setEnabled(false); + filterMaxSeason->setEnabled(false); + filterMaxEpisode->setEnabled(false); + + processFilter->setEnabled(false); + testText->setEnabled(false); + + } + } + } + } + + void RssFeedManager::changedActiveRejectFilter() + { + if (currentAcceptFilter >= 0) + { + acceptFilterList->setSelected(currentAcceptFilter, false); + disconnectFilter(currentAcceptFilter, true); + currentAcceptFilter = -1; + } + + if (currentRejectFilter != rejectFilterList->currentItem() || currentRejectFilter < 0) + { + //the selection has indeed changed + + if (currentRejectFilter >= 0) + { + //disconnect the gui signals from the old feed + disconnectFilter(currentRejectFilter, false); + } + + //update the currentFeed + currentRejectFilter = rejectFilterList->currentItem(); + + if (currentRejectFilter >= 0) + { + //set the values + //title + filterTitle->setText(rejectFilters.at(currentRejectFilter)->title()); + filterActive->setChecked(rejectFilters.at(currentRejectFilter)->active()); + filterRegExps->setItems(rejectFilters.at(currentRejectFilter)->regExps()); + filterSeries->setChecked(rejectFilters.at(currentRejectFilter)->series()); + filterSansEpisode->setChecked(rejectFilters.at(currentRejectFilter)->sansEpisode()); + filterMinSeason->setValue(rejectFilters.at(currentRejectFilter)->minSeason()); + filterMinEpisode->setValue(rejectFilters.at(currentRejectFilter)->minEpisode()); + filterMaxSeason->setValue(rejectFilters.at(currentRejectFilter)->maxSeason()); + filterMaxEpisode->setValue(rejectFilters.at(currentRejectFilter)->maxEpisode()); + + updateMatches(rejectFilters.at(currentRejectFilter)->matches()); + + filterTitle->setEnabled(true); + filterActive->setEnabled(true); + filterRegExps->setEnabled(true); + filterSeries->setEnabled(true); + filterSansEpisode->setEnabled(true); + filterMinSeason->setEnabled(true); + filterMinEpisode->setEnabled(true); + filterMaxSeason->setEnabled(true); + filterMaxEpisode->setEnabled(true); + + processFilter->setEnabled(true); + testText->setEnabled(true); + + //connect all the signals + connectFilter(currentRejectFilter, false); + } + else + { + if (currentRejectFilter < 0) + { + //clear the items + filterTitle->clear(); + filterActive->setChecked(false); + filterRegExps->clear(); + filterSeries->setChecked(false); + filterSansEpisode->setChecked(false); + filterMinSeason->setValue(0); + filterMinEpisode->setValue(0); + filterMaxSeason->setValue(0); + filterMaxEpisode->setValue(0); + filterMatches->setNumRows(0); + + filterTitle->setEnabled(false); + filterActive->setEnabled(false); + filterRegExps->setEnabled(false); + filterSeries->setEnabled(false); + filterSansEpisode->setEnabled(false); + filterMinSeason->setEnabled(false); + filterMinEpisode->setEnabled(false); + filterMaxSeason->setEnabled(false); + filterMaxEpisode->setEnabled(false); + + processFilter->setEnabled(false); + testText->setEnabled(false); + } + } + } + } + + QString RssFeedManager::getFeedListFilename() + { + return KGlobal::dirs()->saveLocation("data","ktorrent") + "rssfeeds.ktr"; + } + + QString RssFeedManager::getFilterListFilename() + { + return KGlobal::dirs()->saveLocation("data","ktorrent") + "rssfilters.ktr"; + } + + void RssFeedManager::saveFeedList() + { + if (feedListSaving) + return; + + feedListSaving = true; + + QString filename = getFeedListFilename(); + + //save feeds to disk + QFile file(filename); + + file.open( IO_WriteOnly ); + QDataStream out(&file); + + out << feeds.count(); + + for (int i=0; i<feeds.count(); i++) + { + out << *(feeds.at(i)); + } + + feedListSaving = false; + } + + void RssFeedManager::loadFeedList() + { + QString filename = getFeedListFilename(); + + //load feeds from disk + QFile file(filename); + + if (file.exists()) + { + file.open( IO_ReadOnly ); + QDataStream in(&file); + + int numFeeds; + + in >> numFeeds; + + RssFeed curFeed; + + for (int i=0; i<numFeeds; i++) + { + in >> curFeed; + addNewFeed(curFeed); + } + + changedActiveFeed(); + } + } + + void RssFeedManager::saveFilterList() + { + if (filterListSaving) + return; + + filterListSaving = true; + + QString filename = getFilterListFilename(); + + //save feeds to disk + QFile file(filename); + + file.open( IO_WriteOnly ); + QDataStream out(&file); + + out << acceptFilters.count(); + + for (int i=0; i<acceptFilters.count(); i++) + { + out << *(acceptFilters.at(i)); + } + + out << rejectFilters.count(); + + for (int i=0; i<rejectFilters.count(); i++) + { + out << *(rejectFilters.at(i)); + } + + filterListSaving = false; + } + + void RssFeedManager::loadFilterList() + { + QString filename = getFilterListFilename(); + + //load feeds from disk + QFile file(filename); + + if (file.exists()) + { + file.open( IO_ReadOnly ); + QDataStream in(&file); + + int numFilters; + + in >> numFilters; + + RssFilter curFilter; + + for (int i=0; i<numFilters; i++) + { + in >> curFilter; + addNewAcceptFilter(curFilter); + } + + in >> numFilters; + + for (int i=0; i<numFilters; i++) + { + in >> curFilter; + addNewRejectFilter(curFilter); + } + + //go through and grab the reject filters + changedActiveRejectFilter(); + changedActiveAcceptFilter(); + } + } + + void RssFeedManager::scanArticle(RssArticle article, RssFilter * filter) + { + //first run it through the reject filters - if any match go no further + for (int i=0; i<rejectFilters.count(); i++) + { + if (rejectFilters.at(i)->scanArticle(article, false)) + { + return; + } + } + + if (filter) + { + //we were passed a filter - so just scan it with that one + if (filter->scanArticle(article)) + { + RssLinkDownloader * curDownload = new RssLinkDownloader(m_core, article.link().prettyURL(), filter); + for (int i=0; i<feeds.count(); i++) + { + connect(curDownload, SIGNAL(linkDownloaded( QString, int )), feeds.at(i), SLOT(setDownloaded(QString, int)) ); + } + } + } + else + { + for (int i=0; i<acceptFilters.count(); i++) + { + if (acceptFilters.at(i)->scanArticle(article)) + { + RssLinkDownloader * curDownload = new RssLinkDownloader(m_core, article.link().prettyURL(), acceptFilters.at(i)); + for (int i=0; i<feeds.count(); i++) + { + connect(curDownload, SIGNAL(linkDownloaded( QString, int )), feeds.at(i), SLOT(setDownloaded(QString, int)) ); + } + } + } + } + } + + void RssFeedManager::rescanFilter() + { + int pos = acceptFilters.find((RssFilter *)sender()); + + if (pos >= 0) + { + for (int i=0; i<feeds.count(); i++) + { + for (int j=0; j<feeds.at(i)->articles().count(); j++) + { + scanArticle(feeds.at(i)->articles()[j], (RssFilter *)sender()); + } + } + } + } + + void RssFeedManager::testTextChanged() + { + testText->setPaletteBackgroundColor(QColor(255, 255, 255)); + testTestText->setEnabled(!testText->text().isEmpty()); + } + + void RssFeedManager::testFilter() + { + RssFilter * curFilter; + if (currentRejectFilter<0) + { + //we're currently testing an acceptFilter + curFilter = acceptFilters.at(currentAcceptFilter); + } + else + { + //it's a reject filter + curFilter = rejectFilters.at(currentRejectFilter); + } + + RssArticle testArticle; + testArticle.setTitle(testText->text()); + + if (curFilter->scanArticle(testArticle, false, false)) + { + testText->setPaletteBackgroundColor(QColor(0, 255, 0)); + } + else + { + testText->setPaletteBackgroundColor(QColor(255, 0, 0)); + } + } + + void RssFeedManager::setFilterTitle(const QString& title) + { + int cursorPos = filterTitle->cursorPosition(); + filterTitle->setText(title); + filterTitle->setCursorPosition(cursorPos); + } + + void RssFeedManager::setFeedTitle(const QString& title) + { + int cursorPos = feedTitle->cursorPosition(); + feedTitle->setText(title); + feedTitle->setCursorPosition(cursorPos); + } + +} |