2010-06-22 13:39:49 +00:00
/*
* Bittorrent Client using Qt4 and libtorrent .
* Copyright ( C ) 2010 Christophe Dumez
*
* 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 .
*
* In addition , as a special exception , the copyright holders give permission to
* link this program with the OpenSSL project ' s " OpenSSL " library ( or with
* modified versions of it that use the same license as the " OpenSSL " library ) ,
* and distribute the linked executables . You must obey the GNU General Public
* License in all respects for all of the code used other than " OpenSSL " . If you
* modify file ( s ) , you may extend this exception to your version of the file ( s ) ,
* but you are not obligated to do so . If you do not wish to do so , delete this
* exception statement from your version .
*
* Contact : chris @ qbittorrent . org
*/
2010-11-13 10:49:22 +00:00
# include <QInputDialog>
# include <QMessageBox>
# include <QFileDialog>
# include <QDebug>
2010-11-13 15:51:36 +00:00
# include <QMenu>
# include <QCursor>
2010-11-13 10:49:22 +00:00
2010-10-31 12:35:07 +00:00
# include "automatedrssdownloader.h"
# include "ui_automatedrssdownloader.h"
2010-06-22 13:39:49 +00:00
# include "rsssettings.h"
2010-11-13 10:49:22 +00:00
# include "rssdownloadrulelist.h"
# include "preferences.h"
# include "qinisettings.h"
2010-06-22 13:39:49 +00:00
2010-10-31 12:35:07 +00:00
AutomatedRssDownloader : : AutomatedRssDownloader ( QWidget * parent ) :
2010-11-13 10:49:22 +00:00
QDialog ( parent ) ,
ui ( new Ui : : AutomatedRssDownloader )
2010-06-22 13:39:49 +00:00
{
2010-11-13 10:49:22 +00:00
ui - > setupUi ( this ) ;
ui - > listRules - > setSortingEnabled ( true ) ;
2010-11-13 16:08:08 +00:00
ui - > listRules - > setSelectionMode ( QAbstractItemView : : ExtendedSelection ) ;
2010-11-13 15:51:36 +00:00
connect ( ui - > listRules , SIGNAL ( customContextMenuRequested ( const QPoint & ) ) , this , SLOT ( displayRulesListMenu ( const QPoint & ) ) ) ;
2010-11-13 10:49:22 +00:00
m_ruleList = RssDownloadRuleList : : instance ( ) ;
initLabelCombobox ( ) ;
loadFeedList ( ) ;
loadSettings ( ) ;
connect ( ui - > listRules , SIGNAL ( currentItemChanged ( QListWidgetItem * , QListWidgetItem * ) ) , SLOT ( updateRuleDefinitionBox ( QListWidgetItem * , QListWidgetItem * ) ) ) ;
connect ( ui - > listRules , SIGNAL ( currentItemChanged ( QListWidgetItem * , QListWidgetItem * ) ) , SLOT ( updateFeedList ( QListWidgetItem * , QListWidgetItem * ) ) ) ;
2010-11-13 15:18:56 +00:00
updateRuleDefinitionBox ( ) ;
2010-06-22 13:39:49 +00:00
}
2010-10-31 12:35:07 +00:00
AutomatedRssDownloader : : ~ AutomatedRssDownloader ( )
2010-06-22 13:39:49 +00:00
{
2010-11-13 10:49:22 +00:00
qDebug ( ) < < Q_FUNC_INFO ;
// Save current item on exit
saveCurrentRule ( ui - > listRules - > currentItem ( ) ) ;
2010-10-31 12:35:07 +00:00
saveSettings ( ) ;
delete ui ;
2010-06-22 13:39:49 +00:00
}
2010-10-31 12:35:07 +00:00
void AutomatedRssDownloader : : loadSettings ( )
{
2010-11-13 11:04:40 +00:00
// load dialog geometry
QIniSettings settings ( " qBittorrent " , " qBittorrent " ) ;
restoreGeometry ( settings . value ( " RssFeedDownloader/geometry " ) . toByteArray ( ) ) ;
2010-10-31 12:35:07 +00:00
ui - > checkEnableDownloader - > setChecked ( RssSettings : : isRssDownloadingEnabled ( ) ) ;
2010-11-13 10:49:22 +00:00
// Display download rules
loadRulesList ( ) ;
2010-10-31 12:35:07 +00:00
}
void AutomatedRssDownloader : : saveSettings ( )
{
RssSettings : : setRssDownloadingEnabled ( ui - > checkEnableDownloader - > isChecked ( ) ) ;
2010-11-13 11:04:40 +00:00
// Save dialog geometry
QIniSettings settings ( " qBittorrent " , " qBittorrent " ) ;
settings . setValue ( " RssFeedDownloader/geometry " , saveGeometry ( ) ) ;
2010-11-13 10:49:22 +00:00
}
void AutomatedRssDownloader : : loadRulesList ( )
{
2010-11-13 15:14:50 +00:00
// Make sure we save the current item before clearing
if ( ui - > listRules - > currentItem ( ) ) {
saveCurrentRule ( ui - > listRules - > currentItem ( ) ) ;
}
ui - > listRules - > clear ( ) ;
2010-11-13 10:49:22 +00:00
foreach ( const QString & rule_name , m_ruleList - > ruleNames ( ) ) {
QListWidgetItem * item = new QListWidgetItem ( rule_name , ui - > listRules ) ;
item - > setFlags ( item - > flags ( ) | Qt : : ItemIsUserCheckable ) ;
if ( m_ruleList - > getRule ( rule_name ) . isEnabled ( ) )
item - > setCheckState ( Qt : : Checked ) ;
else
item - > setCheckState ( Qt : : Unchecked ) ;
}
}
void AutomatedRssDownloader : : loadFeedList ( )
{
const QStringList feed_aliases = RssSettings : : getRssFeedsAliases ( ) ;
const QStringList feed_urls = RssSettings : : getRssFeedsUrls ( ) ;
for ( int i = 0 ; i < feed_aliases . size ( ) ; + + i ) {
QListWidgetItem * item = new QListWidgetItem ( feed_aliases . at ( i ) , ui - > listFeeds ) ;
item - > setData ( Qt : : UserRole , feed_urls . at ( i ) ) ;
item - > setFlags ( item - > flags ( ) | Qt : : ItemIsUserCheckable ) ;
}
2010-11-13 15:18:56 +00:00
if ( ui - > listRules - > count ( ) > 0 & & ! ui - > listRules - > currentItem ( ) )
ui - > listRules - > setCurrentRow ( 0 ) ;
2010-11-13 10:49:22 +00:00
}
QStringList AutomatedRssDownloader : : getSelectedFeeds ( ) const
{
QStringList feeds ;
for ( int i = 0 ; i < ui - > listFeeds - > count ( ) ; + + i ) {
QListWidgetItem * item = ui - > listFeeds - > item ( i ) ;
if ( item - > checkState ( ) ! = Qt : : Unchecked )
feeds < < item - > data ( Qt : : UserRole ) . toString ( ) ;
}
return feeds ;
}
void AutomatedRssDownloader : : updateFeedList ( QListWidgetItem * current , QListWidgetItem * previous )
{
Q_UNUSED ( previous ) ;
RssDownloadRule rule = getCurrentRule ( ) ;
const QStringList affected_feeds = rule . rssFeeds ( ) ;
for ( int i = 0 ; i < ui - > listFeeds - > count ( ) ; + + i ) {
QListWidgetItem * item = ui - > listFeeds - > item ( i ) ;
const QString feed_url = item - > data ( Qt : : UserRole ) . toString ( ) ;
if ( affected_feeds . contains ( feed_url ) )
item - > setCheckState ( Qt : : Checked ) ;
else
item - > setCheckState ( Qt : : Unchecked ) ;
}
ui - > listFeeds - > setEnabled ( current ! = 0 ) ;
}
bool AutomatedRssDownloader : : isRssDownloaderEnabled ( ) const
{
return ui - > checkEnableDownloader - > isChecked ( ) ;
}
void AutomatedRssDownloader : : updateRuleDefinitionBox ( QListWidgetItem * current , QListWidgetItem * previous )
{
qDebug ( ) < < Q_FUNC_INFO < < current < < previous ;
// Save previous item
saveCurrentRule ( previous ) ;
// Update rule definition box
2010-11-13 16:08:08 +00:00
const QList < QListWidgetItem * > selection = ui - > listRules - > selectedItems ( ) ;
2010-11-13 10:49:22 +00:00
RssDownloadRule rule = getCurrentRule ( ) ;
2010-11-13 16:08:08 +00:00
if ( selection . count ( ) = = 1 & & rule . isValid ( ) ) {
2010-11-13 10:49:22 +00:00
ui - > lineContains - > setText ( rule . mustContain ( ) ) ;
ui - > lineNotContains - > setText ( rule . mustNotContain ( ) ) ;
ui - > saveDiffDir_check - > setChecked ( ! rule . savePath ( ) . isEmpty ( ) ) ;
ui - > lineSavePath - > setText ( rule . savePath ( ) ) ;
if ( rule . label ( ) . isEmpty ( ) ) {
ui - > comboLabel - > setCurrentIndex ( - 1 ) ;
ui - > comboLabel - > clearEditText ( ) ;
} else {
ui - > comboLabel - > setCurrentIndex ( ui - > comboLabel - > findText ( rule . label ( ) ) ) ;
}
// Enable
ui - > ruleDefBox - > setEnabled ( true ) ;
} else {
// Clear
ui - > lineNotContains - > clear ( ) ;
ui - > saveDiffDir_check - > setChecked ( false ) ;
ui - > lineSavePath - > clear ( ) ;
ui - > comboLabel - > clearEditText ( ) ;
2010-11-13 16:08:08 +00:00
if ( current & & selection . count ( ) = = 1 ) {
2010-11-13 10:49:22 +00:00
// Use the rule name as a default for the "contains" field
ui - > lineContains - > setText ( current - > text ( ) ) ;
ui - > ruleDefBox - > setEnabled ( true ) ;
} else {
ui - > lineContains - > clear ( ) ;
ui - > ruleDefBox - > setEnabled ( false ) ;
}
}
}
RssDownloadRule AutomatedRssDownloader : : getCurrentRule ( ) const
{
QListWidgetItem * current_item = ui - > listRules - > currentItem ( ) ;
if ( current_item )
return m_ruleList - > getRule ( current_item - > text ( ) ) ;
return RssDownloadRule ( ) ;
}
void AutomatedRssDownloader : : initLabelCombobox ( )
{
// Load custom labels
const QStringList customLabels = Preferences : : getTorrentLabels ( ) ;
foreach ( const QString & label , customLabels ) {
ui - > comboLabel - > addItem ( label ) ;
}
}
void AutomatedRssDownloader : : saveCurrentRule ( QListWidgetItem * item )
{
qDebug ( ) < < Q_FUNC_INFO < < item ;
if ( ! item ) return ;
2010-11-13 12:33:52 +00:00
if ( ! ui - > listRules - > findItems ( item - > text ( ) , Qt : : MatchExactly ) . isEmpty ( ) ) return ;
2010-11-13 10:49:22 +00:00
RssDownloadRule rule = m_ruleList - > getRule ( item - > text ( ) ) ;
if ( ! rule . isValid ( ) ) {
rule . setName ( item - > text ( ) ) ;
}
if ( item - > checkState ( ) = = Qt : : Unchecked )
rule . setEnabled ( false ) ;
else
rule . setEnabled ( true ) ;
rule . setMustContain ( ui - > lineContains - > text ( ) ) ;
rule . setMustNotContain ( ui - > lineNotContains - > text ( ) ) ;
if ( ui - > saveDiffDir_check - > isChecked ( ) )
rule . setSavePath ( ui - > lineSavePath - > text ( ) ) ;
else
rule . setSavePath ( " " ) ;
rule . setLabel ( ui - > comboLabel - > currentText ( ) ) ;
// Save new label
if ( ! rule . label ( ) . isEmpty ( ) )
2010-11-13 12:08:29 +00:00
Preferences : : addTorrentLabel ( rule . label ( ) ) ;
2010-11-13 10:49:22 +00:00
rule . setRssFeeds ( getSelectedFeeds ( ) ) ;
// Save it
m_ruleList - > saveRule ( rule ) ;
}
void AutomatedRssDownloader : : on_addRuleBtn_clicked ( )
{
// Ask for a rule name
const QString rule = QInputDialog : : getText ( this , tr ( " New rule name " ) , tr ( " Please type the name of the new download rule. " ) ) ;
if ( rule . isEmpty ( ) ) return ;
// Check if this rule name already exists
if ( m_ruleList - > getRule ( rule ) . isValid ( ) ) {
QMessageBox : : warning ( this , tr ( " Rule name conflict " ) , tr ( " A rule with this name already exists, please choose another name. " ) ) ;
return ;
}
// Add the new rule to the list
QListWidgetItem * item = new QListWidgetItem ( rule , ui - > listRules ) ;
item - > setFlags ( item - > flags ( ) | Qt : : ItemIsUserCheckable ) ;
item - > setCheckState ( Qt : : Checked ) ; // Enable as a default
ui - > listRules - > setCurrentItem ( item ) ;
}
void AutomatedRssDownloader : : on_removeRuleBtn_clicked ( )
{
2010-11-13 16:00:14 +00:00
const QList < QListWidgetItem * > selection = ui - > listRules - > selectedItems ( ) ;
if ( selection . isEmpty ( ) ) return ;
2010-11-13 10:49:22 +00:00
// Ask for confirmation
2010-11-13 16:00:14 +00:00
QString confirm_text ;
if ( selection . count ( ) = = 1 )
confirm_text = tr ( " Are you sure you want to remove the download rule named %1? " ) . arg ( selection . first ( ) - > text ( ) ) ;
else
confirm_text = tr ( " Are you sure you want to remove the selected download rules? " ) ;
if ( QMessageBox : : question ( this , tr ( " Rule deletion confirmation " ) , confirm_text , QMessageBox : : Yes , QMessageBox : : No ) ! = QMessageBox : : Yes )
2010-11-13 10:49:22 +00:00
return ;
2010-11-13 16:00:14 +00:00
foreach ( QListWidgetItem * item , selection ) {
// Actually remove the item
ui - > listRules - > removeItemWidget ( item ) ;
// Remove it from the m_ruleList
m_ruleList - > removeRule ( item - > text ( ) ) ;
// Clean up memory
delete item ;
}
2010-11-13 10:49:22 +00:00
}
void AutomatedRssDownloader : : on_browseSP_clicked ( )
{
QString save_path = QFileDialog : : getExistingDirectory ( this , tr ( " Destination directory " ) , QDir : : homePath ( ) ) ;
if ( ! save_path . isEmpty ( ) )
ui - > lineSavePath - > setText ( save_path ) ;
2010-06-22 13:39:49 +00:00
}
2010-11-13 12:08:29 +00:00
void AutomatedRssDownloader : : on_exportBtn_clicked ( )
{
if ( m_ruleList - > isEmpty ( ) ) {
QMessageBox : : warning ( this , tr ( " Invalid action " ) , tr ( " The list is empty, there is nothing to export. " ) ) ;
return ;
}
// Ask for a save path
2010-11-13 12:33:52 +00:00
QString save_path = QFileDialog : : getSaveFileName ( this , tr ( " Where would you like to save the list? " ) , QDir : : homePath ( ) , tr ( " Rules list (*.rssrules) " ) ) ;
2010-11-13 12:08:29 +00:00
if ( save_path . isEmpty ( ) ) return ;
if ( ! save_path . endsWith ( " .rssrules " , Qt : : CaseInsensitive ) )
save_path + = " .rssrules " ;
if ( ! m_ruleList - > serialize ( save_path ) ) {
QMessageBox : : warning ( this , tr ( " I/O Error " ) , tr ( " Failed to create the destination file " ) ) ;
return ;
}
}
void AutomatedRssDownloader : : on_importBtn_clicked ( )
{
2010-11-13 12:33:52 +00:00
// Ask for filter path
QString load_path = QFileDialog : : getOpenFileName ( this , tr ( " Please point to the RSS download rules file " ) , QDir : : homePath ( ) , tr ( " Rules list (*.rssrules *.filters) " ) ) ;
if ( load_path . isEmpty ( ) | | ! QFile : : exists ( load_path ) ) return ;
// Load it
2010-11-13 15:14:50 +00:00
if ( ! m_ruleList - > unserialize ( load_path ) ) {
2010-11-13 12:33:52 +00:00
QMessageBox : : warning ( this , tr ( " Import Error " ) , tr ( " Failed to import the selected rules file " ) ) ;
return ;
}
2010-11-13 15:14:50 +00:00
// Reload the rule list
loadRulesList ( ) ;
2010-11-13 12:08:29 +00:00
}
2010-11-13 15:51:36 +00:00
void AutomatedRssDownloader : : displayRulesListMenu ( const QPoint & pos )
{
Q_UNUSED ( pos ) ;
QMenu menu ;
QAction * addAct = menu . addAction ( QIcon ( " :/Icons/oxygen/list-add.png " ) , tr ( " Add new rule... " ) ) ;
QAction * delAct = 0 ;
QAction * renameAct = 0 ;
2010-11-13 16:08:08 +00:00
const QList < QListWidgetItem * > selection = ui - > listRules - > selectedItems ( ) ;
if ( ! selection . isEmpty ( ) ) {
if ( selection . count ( ) = = 1 ) {
2010-11-13 16:00:14 +00:00
delAct = menu . addAction ( QIcon ( " :/Icons/oxygen/list-remove.png " ) , tr ( " Delete rule " ) ) ;
menu . addSeparator ( ) ;
renameAct = menu . addAction ( QIcon ( " :/Icons/oxygen/edit_clear.png " ) , tr ( " Rename rule... " ) ) ;
} else {
delAct = menu . addAction ( QIcon ( " :/Icons/oxygen/list-remove.png " ) , tr ( " Delete selected rules " ) ) ;
}
2010-11-13 15:51:36 +00:00
}
QAction * act = menu . exec ( QCursor : : pos ( ) ) ;
if ( ! act ) return ;
if ( act = = addAct ) {
on_addRuleBtn_clicked ( ) ;
return ;
}
if ( act = = delAct ) {
on_removeRuleBtn_clicked ( ) ;
return ;
}
if ( act = = renameAct ) {
renameSelectedRule ( ) ;
return ;
}
}
void AutomatedRssDownloader : : renameSelectedRule ( )
{
QListWidgetItem * item = ui - > listRules - > currentItem ( ) ;
if ( ! item ) return ;
forever {
QString new_name = QInputDialog : : getText ( this , tr ( " Rule renaming " ) , tr ( " Please type the new rule name " ) , QLineEdit : : Normal , item - > text ( ) ) ;
new_name = new_name . trimmed ( ) ;
if ( new_name . isEmpty ( ) ) return ;
if ( m_ruleList - > ruleNames ( ) . contains ( new_name , Qt : : CaseInsensitive ) ) {
QMessageBox : : warning ( this , tr ( " Rule name conflict " ) , tr ( " A rule with this name already exists, please choose another name. " ) ) ;
} else {
// Rename the rule
m_ruleList - > renameRule ( item - > text ( ) , new_name ) ;
item - > setText ( new_name ) ;
return ;
}
}
}