1 /**************************************************************************************** 2 * Copyright (c) 2007 Nikolaj Hald Nielsen <nhn@kde.org> * 3 * * 4 * This program is free software; you can redistribute it and/or modify it under * 5 * the terms of the GNU General Public License as published by the Free Software * 6 * Foundation; either version 2 of the License, or (at your option) any later * 7 * version. * 8 * * 9 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 10 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 11 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 12 * * 13 * You should have received a copy of the GNU General Public License along with * 14 * this program. If not, see <http://www.gnu.org/licenses/>. * 15 ****************************************************************************************/ 16 17 #ifndef AMAROKSERVICEBASE_H 18 #define AMAROKSERVICEBASE_H 19 20 #include "browsers/BrowserCategory.h" 21 #include "core/support/Amarok.h" 22 #include "core/support/PluginFactory.h" 23 #include "InfoParserBase.h" 24 #include "ServiceCollectionTreeView.h" 25 #include "ServiceMetaBase.h" 26 #include "amarok_export.h" 27 #include "core-impl/meta/proxy/MetaProxy.h" 28 #include "widgets/PrettyTreeView.h" 29 30 #include <KLocalizedString> 31 32 #include <QAbstractItemModel> 33 #include <QPushButton> 34 #include <QQueue> 35 #include <QSortFilterProxyModel> 36 #include <QSplitter> 37 38 class BoxWidget; 39 class ServiceBase; 40 class SearchWidget; 41 class QMenuBar; 42 /** 43 A virtual base class for factories for creating and handling the different types of service plugins 44 45 @author Nikolaj Hald Nielsen <nhn@kde.org> 46 */ 47 class AMAROK_EXPORT ServiceFactory : public Plugins::PluginFactory, public Collections::TrackProvider 48 { 49 Q_OBJECT 50 public: 51 /** 52 * Constructor. 53 */ 54 ServiceFactory(); 55 56 /** 57 * Destructor. 58 */ 59 ~ServiceFactory() override; 60 61 /** 62 * Get the name of this service type. Reimplemented by subclasses. 63 * @return The name. 64 */ 65 virtual QString name() = 0; 66 67 /** 68 * Get a KConfigGroup object containing the config for this type of service. Reimplemented by subclasses. 69 * @return 70 */ 71 virtual KConfigGroup config() = 0; 72 73 /** 74 * Get a best guess if a service of the type generated by this factory will be likely to be able to provide tracks 75 * for a given url. This is needed in order to allow on.demand loading of service plugins to handle a url. Reimplemented by subclasses. 76 * @param url The url to test. 77 * @return A bool representing whether the ServiceFactory believes that a service of this kind can process the given url. 78 */ possiblyContainsTrack(const QUrl & url)79 bool possiblyContainsTrack( const QUrl &url ) const override { Q_UNUSED( url ); return false; } 80 81 /** 82 * Attempt to create a Meta::Track object from a given url. This method is meant as a proxy that will forward this call to one or more 83 * services managed by this factory. If init has not been called ( no services of this kind has been loaded ) they can now be loaded on 84 * demand. 85 * @param url The url to test. 86 * @return A Meta::TrackPtr based one the url, or empty if nothing was known about the url. 87 */ 88 Meta::TrackPtr trackForUrl( const QUrl &url ) override; 89 90 /** 91 * Clear the list of active services created by this factory. Used when unloading services. 92 */ 93 void clearActiveServices(); 94 activeServices()95 QList<ServiceBase *> activeServices() { return m_activeServices.toList(); } 96 97 public Q_SLOTS: 98 /** 99 * The service is ready! 100 */ 101 void slotServiceReady(); 102 103 Q_SIGNALS: 104 /** 105 * This signal is emitted whenever a new service has been loaded. 106 * @param newService The service that has been loaded. 107 */ 108 void newService( ServiceBase *newService ); 109 110 /** 111 * This signal is emitted whenever a service is removed. ServiceFactory deletes 112 * the service in next event loop iteration. 113 * 114 * @param removedService The service that has been removed 115 */ 116 void removeService( ServiceBase *removedService ); 117 118 private Q_SLOTS: 119 void slotNewService( ServiceBase *newService ); 120 void slotRemoveService( ServiceBase *service ); 121 122 private: 123 QSet<ServiceBase *> m_activeServices; 124 QQueue<MetaProxy::TrackPtr> m_tracksToLocate; 125 }; 126 127 128 /** 129 A composite widget used as a base for building service browsers. It contains a home button ( to return to the list of services ), a name label, a tree view, grouping and filtering widgets and other conveniences that handle much of the layout of a new service. Some of these items can be shown or hidden as needed. 130 131 @author Nikolaj Hald Nielsen <nhn@kde.org> 132 */ 133 class AMAROK_EXPORT ServiceBase : public BrowserCategory 134 { 135 Q_OBJECT 136 137 public: 138 139 /** 140 * Constructor. 141 */ 142 ServiceBase( const QString &name, ServiceFactory* parent, bool useCollectionTreeView = true, const QString &m_prettyName = QString() ); 143 144 /** 145 * Destructor. 146 */ 147 ~ServiceBase() override; 148 149 /** 150 * Set the SingleCollectionTreeItemModel that will be used to populate the tree view. 151 * @param model The model. 152 */ 153 void setModel( QAbstractItemModel * model ); 154 155 /** 156 * Get the model that is used for displaying items in the tree view. 157 * @return The model. 158 */ 159 QAbstractItemModel * model(); 160 161 /** 162 * Set the SingleCollectionTreeItemModel that will be used to populate the tree view. 163 * @param model The model. 164 */ 165 void setView( QTreeView * model ); 166 167 /** 168 * Get the model that is used for displaying items in the tree view. 169 * @return The model. 170 */ 171 QTreeView * view(); 172 173 /** 174 * Set if it should be possible to add the tracks shown in the tree view to the playlist. This method is a bit of a hack and might be removed! 175 * @param playable Are tracks playable. 176 */ 177 void setPlayableTracks( bool playable ); 178 179 /** 180 * Set the info parser that will be used to show information about selected items in the service info context applet. 181 * @param infoParser The info parser to use. 182 */ 183 void setInfoParser( InfoParserBase * infoParser ); 184 185 /** 186 * Get the info parser used to show information about selected items in the service info context applet. 187 * @return The info parser. 188 */ 189 InfoParserBase * infoParser(); 190 191 /** 192 * Return the Collection used by this service. 193 * @return The collection. 194 */ 195 virtual Collections::Collection * collection() = 0; 196 197 /** 198 * Do expensive initialization. This method is called when the service is first shown. 199 */ 200 void polish() override = 0; 201 202 /** 203 * ?????? 204 * @return 205 */ updateContextView()206 virtual bool updateContextView() { return false; } 207 208 /** 209 * Apply a filter to the tree view. 210 * @param filter The filter to apply. 211 */ 212 void setFilter( const QString &filter ) override; 213 214 /** 215 * Returns a list of the messages that the current service accepts. Default implementation does not 216 * accept any. 217 * @return A string containing a description of accepted messages. 218 */ 219 virtual QString messages(); 220 221 /** 222 * Send a message to this service. Default implementation returns an error as no messages are 223 * accepted 224 * @param message The message to send to the service 225 * @return The reply to the message 226 */ 227 virtual QString sendMessage( const QString &message ); 228 229 /** 230 * Returns whether the service is ready or not. 231 * @return true if the status is ready, false if it is not ready 232 */ 233 bool serviceReady() const; 234 //virtual void reset() = 0; 235 236 /** 237 * Returns the service's parent factory. 238 * @return the service's Factory 239 */ 240 ServiceFactory* parent() const; 241 242 QString filter() const override; 243 QList<CategoryId::CatMenuId> levels() const override; 244 245 public Q_SLOTS: 246 //void treeViewSelectionChanged( const QItemSelection & selected ); 247 /** 248 * New info should be shown in the service info applet ( if present ). 249 * @param infoHtml The html formatted info to show. 250 */ 251 void infoChanged ( const QString &infoHtml ); 252 253 /** 254 * Set sorting in the tree view to be "Artist-Album". 255 */ 256 void sortByArtistAlbum(); 257 258 /** 259 * Set sorting in the tree view to be "Artist". 260 */ 261 void sortByArtist(); 262 263 /** 264 * Set sorting in the tree view to be "Album". 265 */ 266 void sortByAlbum(); 267 268 /** 269 * Set sorting in the tree view to be "Genre-Artist". 270 */ 271 void sortByGenreArtist(); 272 273 /** 274 * Set sorting in the tree view to be "Genre-Artist-Album". 275 */ 276 void sortByGenreArtistAlbum(); 277 278 void setLevels( const QList<CategoryId::CatMenuId> &levels ) override; 279 280 Q_SIGNALS: 281 /** 282 * Signal emitted when the service wants to be hidden and the service browser list shown instead, for instance when the "Home" button is clicked. 283 */ 284 void home(); 285 286 /** 287 * Signal emitted when the selection in the tree view has changed ( and is only a single item ). 288 * @param item The selected item 289 */ 290 void selectionChanged( CollectionTreeItem *item ); 291 292 /** 293 * Signal emitted when the service is ready to be used. You don't need to Q_EMIT this 294 * manually, just call setServiceReady() as appropriate. 295 */ 296 void ready(); 297 298 protected Q_SLOTS: 299 /** 300 * Slot called when an item in the tree view has been activated 301 * @param index The index of the activated item 302 */ 303 void itemActivated ( const QModelIndex & index ); 304 305 /** 306 * Slot called when the selection in the tree view has changed ( and is only a single item ). 307 * @param item The selected item 308 */ 309 void itemSelected( CollectionTreeItem * item ); 310 311 protected: 312 /** 313 * Generate info to show in the service info applet. useful for showing initial info before any items are selected and hence 314 * trigger the info parser. 315 * @param html 316 */ 317 virtual void generateWidgetInfo( const QString &html = QString() ) const; 318 319 /** 320 * sets serviceReady() and emits a signal ready() as appropriate. 321 */ 322 void setServiceReady( bool ready ); 323 324 static ServiceBase *s_instance; 325 QTreeView *m_contentView; 326 ServiceFactory *m_parentFactory; 327 328 BoxWidget *m_topPanel; 329 BoxWidget *m_bottomPanel; 330 bool m_polished; 331 332 bool m_useCollectionTreeView; 333 334 QList<QUrl> m_urlsToInsert; 335 336 InfoParserBase * m_infoParser; 337 338 QMenuBar *m_menubar; 339 QMenu *m_filterMenu; 340 SearchWidget * m_searchWidget; 341 342 //void addToPlaylist( CollectionTreeItem * item ); 343 344 private: // need to move stuff here 345 bool m_serviceready; 346 347 QAbstractItemModel *m_model; 348 QSortFilterProxyModel *m_filterModel; 349 }; 350 351 352 #endif 353