File indexing completed on 2024-05-19 04:50:24
0001 /**************************************************************************************** 0002 * Copyright (c) 2008 Nikolaj Hald Nielsen <nhn@kde.org> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify it under * 0005 * the terms of the GNU General Public License as published by the Free Software * 0006 * Foundation; either version 2 of the License, or (at your option) any later * 0007 * version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0010 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0011 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0012 * * 0013 * You should have received a copy of the GNU General Public License along with * 0014 * this program. If not, see <http://www.gnu.org/licenses/>. * 0015 ****************************************************************************************/ 0016 0017 #include "OpmlDirectoryService.h" 0018 0019 #include "amarokurls/AmarokUrlHandler.h" 0020 #include "core/support/Debug.h" 0021 #include "core/support/Components.h" 0022 #include "core/logger/Logger.h" 0023 #include "browsers/CollectionTreeItem.h" 0024 #include "browsers/SingleCollectionTreeItemModel.h" 0025 #include "OpmlDirectoryInfoParser.h" 0026 #include "OpmlDirectoryModel.h" 0027 #include "OpmlDirectoryView.h" 0028 #include "playlistmanager/PlaylistManager.h" 0029 #include "core/podcasts/PodcastProvider.h" 0030 #include "ServiceSqlRegistry.h" 0031 #include "widgets/SearchWidget.h" 0032 0033 #include <QStandardPaths> 0034 0035 #include <KIconThemes/KIconLoader> 0036 0037 0038 using namespace Meta; 0039 0040 0041 OpmlDirectoryServiceFactory::OpmlDirectoryServiceFactory() 0042 : ServiceFactory() 0043 {} 0044 0045 OpmlDirectoryServiceFactory::~OpmlDirectoryServiceFactory() 0046 {} 0047 0048 void OpmlDirectoryServiceFactory::init() 0049 { 0050 ServiceBase* service = new OpmlDirectoryService( this, "OpmlDirectory", i18n( "Podcast Directory" ) ); 0051 m_initialized = true; 0052 Q_EMIT newService( service ); 0053 } 0054 0055 0056 QString OpmlDirectoryServiceFactory::name() 0057 { 0058 return "OpmlDirectory"; 0059 } 0060 0061 KConfigGroup OpmlDirectoryServiceFactory::config() 0062 { 0063 return Amarok::config( "Service_OpmlDirectory" ); 0064 } 0065 0066 0067 OpmlDirectoryService::OpmlDirectoryService( OpmlDirectoryServiceFactory* parent, const QString &name, const QString &prettyName ) 0068 : ServiceBase( name, parent, false, prettyName ) 0069 { 0070 setShortDescription( i18n( "A large listing of podcasts" ) ); 0071 setIcon( QIcon::fromTheme( "view-services-opml-amarok" ) ); 0072 0073 setLongDescription( i18n( "A comprehensive list of searchable podcasts that you can subscribe to directly from within Amarok." ) ); 0074 0075 KIconLoader loader; 0076 setImagePath( loader.iconPath( "view-services-opml-amarok", -128, true ) ); 0077 0078 The::amarokUrlHandler()->registerRunner( this, command() ); 0079 0080 setServiceReady( true ); 0081 } 0082 0083 0084 OpmlDirectoryService::~OpmlDirectoryService() 0085 { 0086 } 0087 0088 void OpmlDirectoryService::polish() 0089 { 0090 generateWidgetInfo(); 0091 if ( m_polished ) 0092 return; 0093 0094 //do not allow this content to get added to the playlist. At least not for now 0095 setPlayableTracks( false ); 0096 0097 //TODO: implement searching 0098 m_searchWidget->setVisible( false ); 0099 0100 OpmlDirectoryView* opmlView = new OpmlDirectoryView( this ); 0101 opmlView->setHeaderHidden( true ); 0102 opmlView->setFrameShape( QFrame::NoFrame ); 0103 opmlView->setDragEnabled ( true ); 0104 opmlView->setSortingEnabled( false ); 0105 opmlView->setSelectionMode( QAbstractItemView::ExtendedSelection ); 0106 opmlView->setDragDropMode ( QAbstractItemView::DragOnly ); 0107 opmlView->setEditTriggers( QAbstractItemView::SelectedClicked | QAbstractItemView::EditKeyPressed ); 0108 setView( opmlView ); 0109 QString opmlLocation = Amarok::saveLocation() + "podcast_directory.opml"; 0110 0111 if( !QFile::exists( opmlLocation ) ) 0112 { 0113 //copy from the standard data dir 0114 QString schippedOpmlLocation = QStandardPaths::locate( QStandardPaths::GenericDataLocation, "amarok/data/podcast_directory.opml" ); 0115 if( !QFile::copy( schippedOpmlLocation, opmlLocation ) ) 0116 { 0117 debug() << QString( "Failed to copy from %1 to %2" ) 0118 .arg( schippedOpmlLocation, opmlLocation ); 0119 //TODO: error box drawn in the view's area. 0120 return; 0121 } 0122 } 0123 0124 setModel( new OpmlDirectoryModel( QUrl::fromLocalFile( opmlLocation ), this ) ); 0125 0126 m_subscribeButton = new QPushButton( m_bottomPanel ); 0127 m_subscribeButton->setText( i18n( "Subscribe" ) ); 0128 m_subscribeButton->setObjectName( "subscribeButton" ); 0129 m_subscribeButton->setIcon( QIcon::fromTheme( QStringLiteral("get-hot-new-stuff-amarok") ) ); 0130 0131 m_subscribeButton->setEnabled( false ); 0132 0133 connect( m_subscribeButton, &QPushButton::clicked, this, &OpmlDirectoryService::subscribe ); 0134 0135 m_addOpmlButton = new QPushButton( m_bottomPanel ); 0136 m_addOpmlButton->setText( i18n( "Add OPML" ) ); 0137 m_addOpmlButton->setObjectName( QStringLiteral("addOpmlButton") ); 0138 m_addOpmlButton->setIcon( QIcon::fromTheme( QStringLiteral("list-add-amarok") ) ); 0139 0140 connect( m_addOpmlButton, &QPushButton::clicked, 0141 dynamic_cast<OpmlDirectoryModel*>( model() ), &OpmlDirectoryModel::slotAddOpmlAction ); 0142 0143 connect( view()->selectionModel(), &QItemSelectionModel::selectionChanged, 0144 this, &OpmlDirectoryService::slotSelectionChanged ); 0145 0146 setInfoParser( new OpmlDirectoryInfoParser() ); 0147 0148 m_polished = true; 0149 } 0150 0151 QString 0152 OpmlDirectoryService::command() const 0153 { 0154 return "service-podcastdirectory"; 0155 } 0156 0157 QString 0158 OpmlDirectoryService::prettyCommand() const 0159 { 0160 return i18n( "Add an OPML file to the list." ); 0161 } 0162 0163 bool 0164 OpmlDirectoryService::run(const AmarokUrl &url ) 0165 { 0166 //make sure this category is shown. 0167 AmarokUrl( "amarok://navigate/internet/OpmlDirectory" ).run(); 0168 if( url.path() == QLatin1String( "addOpml" ) ) 0169 { 0170 OpmlDirectoryModel *opmlModel = qobject_cast<OpmlDirectoryModel *>( model() ); 0171 Q_ASSERT_X(opmlModel, "OpmlDirectoryService::run()", "fix if a proxy is used"); 0172 0173 opmlModel->slotAddOpmlAction(); 0174 return true; 0175 } 0176 0177 return false; 0178 } 0179 0180 void 0181 OpmlDirectoryService::subscribe() 0182 { 0183 OpmlDirectoryModel * opmlModel = dynamic_cast<OpmlDirectoryModel *>( model() ); 0184 Q_ASSERT( opmlModel ); 0185 opmlModel->subscribe( view()->selectionModel()->selectedIndexes() ); 0186 } 0187 0188 void 0189 OpmlDirectoryService::slotSelectionChanged( const QItemSelection &selected, 0190 const QItemSelection &deselected ) 0191 { 0192 Q_UNUSED(selected) 0193 Q_UNUSED(deselected) 0194 m_subscribeButton->setEnabled( !view()->selectionModel()->selectedIndexes().isEmpty() ); 0195 }