Bug 221398 - Configurable default settings for all Podcasts
Summary: Configurable default settings for all Podcasts
Status: RESOLVED FIXED
Alias: None
Product: amarok
Classification: Applications
Component: Podcast (show other bugs)
Version: 2.2.1.90
Platform: openSUSE Unspecified
: NOR wishlist
Target Milestone: ---
Assignee: Amarok Developers
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-01-05 14:48 UTC by Achim Herwig
Modified: 2010-02-10 01:57 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
Workaround: fix paths via python script afterwards (657 bytes, text/x-python)
2010-01-05 15:58 UTC, Achim Herwig
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Achim Herwig 2010-01-05 14:48:28 UTC
Version:           2.2.1.90 (using KDE 4.3.4)
Installed from:    openSUSE RPMs

I'd like to have default settings for Podcasts in amarok, especially the default Podcast download directory (or a base download directory) that are taken over for new podcasts added or imported.

I know that I can set the download directory individually (Wishlist Bug 205710), but when I import an OPML file with 20 podcasts, I do not want to change the download directory individually.
Comment 1 Achim Herwig 2010-01-05 15:58:14 UTC
Created attachment 39585 [details]
Workaround: fix paths via python script afterwards

Use at your own risk, it only works when amarok uses mysqldb for collection storage. In case anything was already downloaded, files have to be moved manually.
Comment 2 Bart Cerneels 2010-02-10 01:57:19 UTC
commit b355ba09e8069ee527ccc9fff514fe33482aa5df
Author: Bart Cerneels <bart.cerneels@kde.org>
Date:   Mon Feb 8 17:00:23 2010 +0100

    Add configuration to the Local Podcasts.
    
    Had to add support for multiple actions it the PlaylistItemDelegate. The same can be done for the CollectionTreeItemDelegates.
    BUG:221398

diff --git a/src/browsers/playlistbrowser/PodcastCategory.cpp b/src/browsers/playlistbrowser/PodcastCategory.cpp
index b1eda12..51d50b0 100644
--- a/src/browsers/playlistbrowser/PodcastCategory.cpp
+++ b/src/browsers/playlistbrowser/PodcastCategory.cpp
@@ -566,14 +566,24 @@ PodcastView::mouseReleaseEvent( QMouseEvent * event )
             const QRect rect = PlaylistTreeItemDelegate::actionsRect( index );
             if( rect.contains( event->pos() ) )
             {
-                QList<QAction*> actions =
-                        index.data( PlaylistBrowserNS::MetaPlaylistModel::ActionRole )
-                        .toList().first().value<QList<QAction*> >();
-                foreach( QAction *action, actions )
+                QVariantList variantList =
+                        index.data( PlaylistBrowserNS::MetaPlaylistModel::ActionRole ).toList();
+                if( variantList.isEmpty() )
+                    return;
+
+                QList<QAction*> actions = variantList.first().value<QList<QAction*> >();
+                //hack: rect height == the width of one action's area.
+                int indexOfActionToTrigger
+                    = ( event->pos().x() - rect.left() ) / rect.height();
+                debug() << "triggering action " << indexOfActionToTrigger;
+                if( indexOfActionToTrigger >= actions.count() )
                 {
-                    if( action )
-                        action->trigger();
+                    debug() << "no such action";
+                    return;
                 }
+                QAction *action = actions.value( indexOfActionToTrigger );
+                if( action )
+                    action->trigger();
                 return;
             }
         }
diff --git a/src/podcasts/sql/SqlPodcastMeta.cpp b/src/podcasts/sql/SqlPodcastMeta.cpp
index f3e31ca..c8b374c 100644
--- a/src/podcasts/sql/SqlPodcastMeta.cpp
+++ b/src/podcasts/sql/SqlPodcastMeta.cpp
@@ -449,7 +449,7 @@ Meta::SqlPodcastEpisode::deleteFromDb()
         QString( "DELETE FROM podcastepisodes WHERE id = %1;" ).arg( dbId() ) );
 }
 
-Meta::SqlPodcastChannel::SqlPodcastChannel( PlaylistProvider *provider,
+Meta::SqlPodcastChannel::SqlPodcastChannel( SqlPodcastProvider *provider,
                                             const QStringList &result )
     : Meta::PodcastChannel()
     , m_provider( provider )
@@ -474,7 +474,7 @@ Meta::SqlPodcastChannel::SqlPodcastChannel( PlaylistProvider *provider,
     loadEpisodes();
 }
 
-Meta::SqlPodcastChannel::SqlPodcastChannel( PlaylistProvider *provider,
+Meta::SqlPodcastChannel::SqlPodcastChannel( SqlPodcastProvider *provider,
                                             PodcastChannelPtr channel )
     : Meta::PodcastChannel()
     , m_dbId( 0 )
@@ -500,7 +500,8 @@ Meta::SqlPodcastChannel::SqlPodcastChannel( PlaylistProvider *provider,
         m_image = channel->image();
 
     //Default Settings
-    m_directory = KUrl( Amarok::saveLocation("podcasts") );
+
+    m_directory = KUrl( m_provider->baseDownloadDir() );
     m_directory.addPath( Amarok::vfatPath( m_title ) );
     m_autoScan = true;
     m_fetchType = StreamOrDownloadOnDemand;
@@ -519,6 +520,12 @@ Meta::SqlPodcastChannel::SqlPodcastChannel( PlaylistProvider *provider,
     }
 }
 
+PlaylistProvider *
+Meta::SqlPodcastChannel::provider() const
+{
+    return dynamic_cast<PlaylistProvider *>( m_provider );
+}
+
 Meta::SqlPodcastChannel::~SqlPodcastChannel()
 {
     m_episodes.clear();
diff --git a/src/podcasts/sql/SqlPodcastMeta.h b/src/podcasts/sql/SqlPodcastMeta.h
index 2b52a29..3cd2dcf 100644
--- a/src/podcasts/sql/SqlPodcastMeta.h
+++ b/src/podcasts/sql/SqlPodcastMeta.h
@@ -20,6 +20,8 @@
 #include "PodcastMeta.h"
 #include "meta/file/File.h"
 
+class SqlPodcastProvider;
+
 namespace Meta
 {
 
@@ -87,16 +89,16 @@ class SqlPodcastChannel : public PodcastChannel
         static TrackList sqlEpisodesToTracks( SqlPodcastEpisodeList episodes );
         static PodcastEpisodeList sqlEpisodesToPodcastEpisodes( SqlPodcastEpisodeList episodes );
 
-        SqlPodcastChannel( PlaylistProvider *provider, const QStringList &queryResult );
+        SqlPodcastChannel( SqlPodcastProvider *provider, const QStringList &queryResult );
 
         /** Copy a PodcastChannel
         */
-        SqlPodcastChannel( PlaylistProvider *provider, PodcastChannelPtr channel );
+        SqlPodcastChannel( SqlPodcastProvider *provider, PodcastChannelPtr channel );
 
         ~SqlPodcastChannel();
         // Meta::Playlist methods
         virtual TrackList tracks() { return sqlEpisodesToTracks( m_episodes ); }
-        virtual PlaylistProvider *provider() const { return m_provider; }
+        virtual PlaylistProvider *provider() const;
 
         //Meta::PodcastChannel methods
         virtual void setTitle( const QString &title );
@@ -127,7 +129,7 @@ class SqlPodcastChannel : public PodcastChannel
         int m_dbId; //database ID
 
         SqlPodcastEpisodeList m_episodes;
-        PlaylistProvider *m_provider;
+        SqlPodcastProvider *m_provider;
 };
 
 }
diff --git a/src/podcasts/sql/SqlPodcastProvider.cpp b/src/podcasts/sql/SqlPodcastProvider.cpp
index 440a158..dca3936 100644
--- a/src/podcasts/sql/SqlPodcastProvider.cpp
+++ b/src/podcasts/sql/SqlPodcastProvider.cpp
@@ -59,6 +59,7 @@ SqlPodcastProvider::SqlPodcastProvider()
         : m_updateTimer( new QTimer( this ) )
         , m_updatingChannels( 0 )
         , m_completedDownloads( 0 )
+        , m_providerSettingsDialog( 0 )
         , m_configureChannelAction( 0 )
         , m_deleteAction( 0 )
         , m_downloadAction( 0 )
@@ -84,6 +85,8 @@ SqlPodcastProvider::SqlPodcastProvider()
                                .readEntry( "Maximum Simultaneous Downloads", 4 );
     m_maxConcurrentUpdates = Amarok::config( "Podcasts" )
                              .readEntry( "Maximum Simultaneous Updates", 4 );
+    m_baseDownloadDir = Amarok::config( "Podcasts" ).readEntry( "Base Downlaod Directory",
+                                                           Amarok::saveLocation( "podcasts" ) );
 
     QStringList values;
 
@@ -383,16 +386,53 @@ void
 SqlPodcastProvider::configureProvider()
 {
     DEBUG_BLOCK
-    KDialog *dialog = new KDialog( The::mainWindow() );
-    QWidget *settingsWidget = new QWidget( dialog );
-    Ui::SqlPodcastProviderSettingsWidget sqlPodcastProviderSettingsWidget;
-    sqlPodcastProviderSettingsWidget.setupUi( settingsWidget );
+    m_providerSettingsDialog = new KDialog( The::mainWindow() );
+    QWidget *settingsWidget = new QWidget( m_providerSettingsDialog );
+    Ui::SqlPodcastProviderSettingsWidget settings;
+    settings.setupUi( settingsWidget );
 
-    dialog->setMainWidget( settingsWidget );
+    settings.m_baseDirUrl->setMode( KFile::Directory );
+    settings.m_baseDirUrl->setUrl( m_baseDownloadDir );
 
-    if( dialog->exec() == QDialog::Accepted )
+    settings.m_autoUpdateInterval->setValue( m_autoUpdateInterval );
+
+    m_providerSettingsDialog->setButtons( KDialog::Ok | KDialog::Cancel | KDialog::Apply );
+    m_providerSettingsDialog->setMainWidget( settingsWidget );
+
+    connect( settings.m_baseDirUrl, SIGNAL( textChanged(QString) ), SLOT( slotConfigChanged() ) );
+    connect( settings.m_autoUpdateInterval, SIGNAL( valueChanged(int) ),
+             SLOT( slotConfigChanged() ) );
+
+    m_providerSettingsDialog->setWindowTitle( i18n( "Configure Local Podcasts" ) );
+    m_providerSettingsDialog->enableButtonApply( false );
+
+    if( m_providerSettingsDialog->exec() == QDialog::Accepted )
+    {
         debug() << "accepted";
 
+        //TODO: apply
+    }
+
+    delete m_providerSettingsDialog;
+    m_providerSettingsDialog = 0;
+
+}
+
+void
+SqlPodcastProvider::slotConfigChanged()
+{
+    Ui::SqlPodcastProviderSettingsWidget *settings =
+            dynamic_cast<Ui::SqlPodcastProviderSettingsWidget *>(
+                    m_providerSettingsDialog->mainWidget() );
+
+    if( !settings )
+        return;
+
+    if( settings->m_autoUpdateInterval->value() != m_autoUpdateInterval
+        || settings->m_baseDirUrl->url() != m_baseDownloadDir )
+    {
+        m_providerSettingsDialog->enableButtonApply( true );
+    }
 }
 
 void
@@ -1374,7 +1414,7 @@ SqlPodcastProvider::podcastImageFetcherDone( PodcastImageFetcher *fetcher )
 void
 SqlPodcastProvider::slotConfigureProvider()
 {
-    DEBUG_BLOCK
+    configureProvider();
 }
 
 #include "SqlPodcastProvider.moc"
diff --git a/src/podcasts/sql/SqlPodcastProvider.h b/src/podcasts/sql/SqlPodcastProvider.h
index 138df15..1b25c32 100644
--- a/src/podcasts/sql/SqlPodcastProvider.h
+++ b/src/podcasts/sql/SqlPodcastProvider.h
@@ -25,6 +25,7 @@
 
 class PodcastImageFetcher;
 
+class KDialog;
 class KUrl;
 class PodcastReader;
 class SqlStorage;
@@ -71,6 +72,8 @@ class SqlPodcastProvider : public PodcastProvider
         //SqlPodcastProvider specific methods
         Meta::SqlPodcastChannelPtr podcastChannelForId( int podcastChannelDbId );
 
+        KUrl baseDownloadDir() const { return m_baseDownloadDir; }
+
     public slots:
         void updateAll();
         void update( Meta::PodcastChannelPtr channel );
@@ -95,6 +98,7 @@ class SqlPodcastProvider : public PodcastProvider
         void slotUpdateChannels();
         void slotDownloadProgress( KJob *job, unsigned long percent );
         void slotWriteTagsToFiles();
+        void slotConfigChanged();
 
     signals:
         void updated();
@@ -134,7 +138,7 @@ class SqlPodcastProvider : public PodcastProvider
         Meta::SqlPodcastChannelList m_channels;
 
         QTimer *m_updateTimer;
-        unsigned int m_autoUpdateInterval; //interval between autoupdate attempts in minutes
+        int m_autoUpdateInterval; //interval between autoupdate attempts in minutes
         unsigned int m_updatingChannels;
         unsigned int m_maxConcurrentUpdates;
         Meta::PodcastChannelList m_updateQueue;
@@ -148,6 +152,10 @@ class SqlPodcastProvider : public PodcastProvider
         int m_maxConcurrentDownloads;
         int m_completedDownloads;
 
+        KUrl m_baseDownloadDir;
+
+        KDialog *m_providerSettingsDialog;
+
         QList<QAction *> m_providerActions;
 
         QAction *m_configureChannelAction; //Configure a Channel
diff --git a/src/podcasts/sql/SqlPodcastProviderSettingsWidget.ui b/src/podcasts/sql/SqlPodcastProviderSettingsWidget.ui
index 67e0192..0c18dcd 100644
--- a/src/podcasts/sql/SqlPodcastProviderSettingsWidget.ui
+++ b/src/podcasts/sql/SqlPodcastProviderSettingsWidget.ui
@@ -6,76 +6,139 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>275</width>
-    <height>91</height>
+    <width>330</width>
+    <height>65</height>
    </rect>
   </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>330</width>
+    <height>65</height>
+   </size>
+  </property>
   <property name="windowTitle">
    <string>Form</string>
   </property>
-  <layout class="QFormLayout" name="formLayout">
-   <item row="0" column="0">
-    <widget class="QLabel" name="m_intervalLabel">
-     <property name="text">
-      <string>Auto-update interval:</string>
-     </property>
-     <property name="alignment">
-      <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-     </property>
-    </widget>
-   </item>
-   <item row="0" column="1">
-    <widget class="KIntSpinBox" name="m_autoUpdateInterval">
-     <property name="suffix">
-      <string comment="auto-update interval"> minutes</string>
-     </property>
-     <property name="prefix">
-      <string/>
-     </property>
-     <property name="minimum">
-      <number>30</number>
-     </property>
-     <property name="maximum">
-      <number>300</number>
-     </property>
-     <property name="singleStep">
-      <number>30</number>
-     </property>
-    </widget>
-   </item>
-   <item row="1" column="0">
-    <widget class="QLabel" name="m_baseDirLabel">
-     <property name="toolTip">
-      <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+  <widget class="QLabel" name="m_intervalLabel">
+   <property name="geometry">
+    <rect>
+     <x>22</x>
+     <y>4</y>
+     <width>68</width>
+     <height>16</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Auto-update</string>
+   </property>
+   <property name="alignment">
+    <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+   </property>
+  </widget>
+  <widget class="KIntSpinBox" name="m_autoUpdateInterval">
+   <property name="geometry">
+    <rect>
+     <x>94</x>
+     <y>4</y>
+     <width>201</width>
+     <height>24</height>
+    </rect>
+   </property>
+   <property name="sizePolicy">
+    <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+     <horstretch>0</horstretch>
+     <verstretch>0</verstretch>
+    </sizepolicy>
+   </property>
+   <property name="minimumSize">
+    <size>
+     <width>200</width>
+     <height>0</height>
+    </size>
+   </property>
+   <property name="buttonSymbols">
+    <enum>QAbstractSpinBox::PlusMinus</enum>
+   </property>
+   <property name="specialValueText">
+    <string extracomment="automatic updates turned off">disabled</string>
+   </property>
+   <property name="suffix">
+    <string comment="auto-update interval"> minutes</string>
+   </property>
+   <property name="prefix">
+    <string extracomment="prefix to update interval in minutes">every </string>
+   </property>
+   <property name="minimum">
+    <number>0</number>
+   </property>
+   <property name="maximum">
+    <number>300</number>
+   </property>
+   <property name="singleStep">
+    <number>30</number>
+   </property>
+  </widget>
+  <widget class="QLabel" name="m_baseDirLabel">
+   <property name="geometry">
+    <rect>
+     <x>4</x>
+     <y>33</y>
+     <width>86</width>
+     <height>16</height>
+    </rect>
+   </property>
+   <property name="toolTip">
+    <string/>
+   </property>
+   <property name="text">
+    <string>Base directory:</string>
+   </property>
+   <property name="alignment">
+    <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+   </property>
+  </widget>
+  <widget class="KUrlRequester" name="m_baseDirUrl">
+   <property name="geometry">
+    <rect>
+     <x>94</x>
+     <y>33</y>
+     <width>231</width>
+     <height>25</height>
+    </rect>
+   </property>
+   <property name="sizePolicy">
+    <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+     <horstretch>0</horstretch>
+     <verstretch>0</verstretch>
+    </sizepolicy>
+   </property>
+   <property name="minimumSize">
+    <size>
+     <width>230</width>
+     <height>0</height>
+    </size>
+   </property>
+   <property name="toolTip">
+    <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
 &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
 p, li { white-space: pre-wrap; }
 &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
 &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Base directory for all new podcast channels.&lt;/p&gt;
 &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;When a podcast channel is added &lt;span style=&quot; font-style:italic;&quot;&gt;&amp;lt;base directory&amp;gt;&lt;/span&gt;/&lt;span style=&quot; font-style:italic;&quot;&gt;&amp;lt;channel name&amp;gt;&lt;/span&gt; is used as the download directory.&lt;/p&gt;
 &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;This can be changed for each channel individually.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
-     </property>
-     <property name="text">
-      <string>Base directory:</string>
-     </property>
-     <property name="alignment">
-      <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-     </property>
-    </widget>
-   </item>
-   <item row="1" column="1">
-    <widget class="KUrlRequester" name="m_baseDirUrl"/>
-   </item>
-   <item row="2" column="0">
-    <widget class="QLabel" name="m_episodeLimitLabel">
-     <property name="text">
-      <string>Default episode limit:</string>
-     </property>
-    </widget>
-   </item>
-   <item row="2" column="1">
-    <widget class="KIntSpinBox" name="m_episodeLimit"/>
-   </item>
-  </layout>
+   </property>
+   <property name="whatsThis">
+    <string>Base directory for all new podcast channels.
+When a podcast channel is added &lt;base directory&gt;/&lt;channel name&gt; is used as the download directory.
+This can be changed for each channel individually.</string>
+   </property>
+  </widget>
  </widget>
  <customwidgets>
   <customwidget>