File indexing completed on 2024-05-05 04:49:16

0001 /****************************************************************************************
0002  * Copyright (c) 2007 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 #ifndef AMAROKSERVICEBASE_H
0018 #define AMAROKSERVICEBASE_H
0019 
0020 #include "browsers/BrowserCategory.h"
0021 #include "core/support/Amarok.h"
0022 #include "core/support/PluginFactory.h"
0023 #include "InfoParserBase.h"
0024 #include "ServiceCollectionTreeView.h"
0025 #include "ServiceMetaBase.h"
0026 #include "amarok_export.h"
0027 #include "core-impl/meta/proxy/MetaProxy.h"
0028 #include "widgets/PrettyTreeView.h"
0029 
0030 #include <KLocalizedString>
0031 
0032 #include <QAbstractItemModel>
0033 #include <QPushButton>
0034 #include <QQueue>
0035 #include <QSortFilterProxyModel>
0036 #include <QSplitter>
0037 
0038 class BoxWidget;
0039 class ServiceBase;
0040 class SearchWidget;
0041 class QMenuBar;
0042 /**
0043 A virtual base class for factories for creating and handling the different types of service plugins
0044 
0045 @author Nikolaj Hald Nielsen <nhn@kde.org>
0046  */
0047 class AMAROK_EXPORT ServiceFactory : public Plugins::PluginFactory, public Collections::TrackProvider
0048 {
0049     Q_OBJECT
0050     public:
0051         /**
0052          * Constructor.
0053          */
0054         ServiceFactory();
0055 
0056         /**
0057          * Destructor.
0058          */
0059         ~ServiceFactory() override;
0060 
0061         /**
0062          * Get the name of this service type. Reimplemented by subclasses.
0063          * @return The name.
0064          */
0065         virtual QString name() = 0;
0066 
0067         /**
0068          * Get a KConfigGroup object containing the config for this type of service. Reimplemented by subclasses.
0069          * @return
0070          */
0071         virtual KConfigGroup config() = 0;
0072 
0073         /**
0074          * Get a best guess if a service of the type generated by this factory will be likely to be able to provide tracks
0075          * for a given url. This is needed in order to allow on.demand loading of service plugins to handle a url. Reimplemented by subclasses.
0076          * @param url The url to test.
0077          * @return A bool representing whether the ServiceFactory believes that a service of this kind can process the given url.
0078          */
0079         bool possiblyContainsTrack( const QUrl &url ) const override { Q_UNUSED( url ); return false; }
0080 
0081         /**
0082          * 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
0083          * 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
0084          * demand.
0085          * @param url The url to test.
0086          * @return A Meta::TrackPtr based one the url, or empty if nothing was known about the url.
0087          */
0088         Meta::TrackPtr trackForUrl( const QUrl &url ) override;
0089 
0090         /**
0091          * Clear the list of active services created by this factory. Used when unloading services.
0092          */
0093         void clearActiveServices();
0094 
0095         QList<ServiceBase *> activeServices() { return m_activeServices.values(); }
0096 
0097     public Q_SLOTS:
0098         /**
0099          * The service is ready!
0100          */
0101         void slotServiceReady();
0102 
0103     Q_SIGNALS:
0104         /**
0105          * This signal is emitted whenever a new service has been loaded.
0106          * @param newService The service that has been loaded.
0107          */
0108         void newService( ServiceBase *newService );
0109 
0110         /**
0111          * This signal is emitted whenever a service is removed. ServiceFactory deletes
0112          * the service in next event loop iteration.
0113          *
0114          * @param removedService The service that has been removed
0115          */
0116         void removeService( ServiceBase *removedService );
0117 
0118     private Q_SLOTS:
0119         void slotNewService( ServiceBase *newService );
0120         void slotRemoveService( ServiceBase *service );
0121 
0122     private:
0123         QSet<ServiceBase *> m_activeServices;
0124         QQueue<MetaProxy::TrackPtr> m_tracksToLocate;
0125 };
0126 
0127 
0128 /**
0129 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.
0130 
0131 @author Nikolaj Hald Nielsen <nhn@kde.org>
0132 */
0133 class AMAROK_EXPORT ServiceBase : public BrowserCategory
0134 {
0135     Q_OBJECT
0136 
0137 public:
0138 
0139      /**
0140       * Constructor.
0141       */
0142      ServiceBase( const QString &name, ServiceFactory* parent, bool useCollectionTreeView = true, const QString &m_prettyName = QString() );
0143 
0144     /**
0145      * Destructor.
0146      */
0147     ~ServiceBase() override;
0148 
0149     /**
0150      * Set the SingleCollectionTreeItemModel that will be used to populate the tree view.
0151      * @param model The model.
0152      */
0153     void setModel( QAbstractItemModel * model );
0154 
0155     /**
0156      * Get the model that is used for displaying items in the tree view.
0157      * @return The model.
0158      */
0159     QAbstractItemModel * model();
0160 
0161     /**
0162     * Set the SingleCollectionTreeItemModel that will be used to populate the tree view.
0163     * @param model The model.
0164     */
0165     void setView( QTreeView * model );
0166 
0167     /**
0168     * Get the model that is used for displaying items in the tree view.
0169     * @return The model.
0170     */
0171     QTreeView * view();
0172 
0173     /**
0174      * 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!
0175      * @param playable Are tracks playable.
0176      */
0177     void setPlayableTracks( bool playable );
0178 
0179     /**
0180      * Set the info parser that will be used to show information about selected items in the service info context applet.
0181      * @param infoParser The info parser to use.
0182      */
0183     void setInfoParser( InfoParserBase * infoParser );
0184 
0185     /**
0186      * Get the info parser used to show information about selected items in the service info context applet.
0187      * @return The info parser.
0188      */
0189     InfoParserBase * infoParser();
0190 
0191     /**
0192      * Return the Collection used by this service.
0193      * @return The collection.
0194      */
0195     virtual Collections::Collection * collection() = 0;
0196 
0197     /**
0198      * Do expensive initialization. This method is called when the service is first shown.
0199      */
0200     void polish() override = 0;
0201 
0202     /**
0203      * ??????
0204      * @return 
0205      */
0206     virtual bool updateContextView() { return false; }
0207 
0208     /**
0209      * Apply a filter to the tree view.
0210      * @param filter The filter to apply.
0211      */
0212     void setFilter( const QString &filter ) override;
0213 
0214     /**
0215      * Returns a list of the messages that the current service accepts. Default implementation does not
0216      * accept any.
0217      * @return A string containing a description of accepted messages.
0218      */
0219     virtual QString messages();
0220 
0221     /**
0222      * Send a message to this service. Default implementation returns an error as no messages are
0223      * accepted
0224      * @param message The message to send to the service
0225      * @return The reply to the message
0226      */
0227     virtual QString sendMessage( const QString &message );
0228 
0229     /**
0230      * Returns whether the service is ready or not.
0231      * @return true if the status is ready, false if it is not ready
0232      */
0233     bool serviceReady() const;
0234     //virtual void reset() = 0;
0235 
0236     /**
0237      * Returns the service's parent factory.
0238      * @return the service's Factory
0239      */
0240     ServiceFactory* parent() const;
0241 
0242     QString filter() const override;
0243     QList<CategoryId::CatMenuId> levels() const override;
0244 
0245 public Q_SLOTS:
0246     //void treeViewSelectionChanged( const QItemSelection & selected );
0247     /**
0248      * New info should be shown in the service info applet ( if present ).
0249      * @param infoHtml The html formatted info to show.
0250      */
0251     void infoChanged ( const QString &infoHtml );
0252 
0253     /**
0254      * Set sorting in the tree view to be "Artist-Album".
0255      */
0256     void sortByArtistAlbum();
0257 
0258     /**
0259      * Set sorting in the tree view to be "Artist".
0260      */
0261     void sortByArtist();
0262 
0263     /**
0264      * Set sorting in the tree view to be "Album".
0265      */
0266     void sortByAlbum();
0267 
0268     /**
0269      * Set sorting in the tree view to be "Genre-Artist".
0270      */
0271     void sortByGenreArtist();
0272 
0273     /**
0274      * Set sorting in the tree view to be "Genre-Artist-Album".
0275      */
0276     void sortByGenreArtistAlbum();
0277 
0278     void setLevels( const QList<CategoryId::CatMenuId> &levels ) override;
0279 
0280 Q_SIGNALS:
0281     /**
0282      * Signal emitted when the service wants to be hidden and the service browser list shown instead, for instance when the "Home" button is clicked.
0283      */
0284     void home();
0285 
0286     /**
0287      * Signal emitted when the selection in the tree view has changed ( and is only a single item ).
0288      * @param item The selected item
0289      */
0290     void selectionChanged( CollectionTreeItem *item );
0291 
0292     /**
0293      * Signal emitted when the service is ready to be used. You don't need to Q_EMIT this
0294      * manually, just call setServiceReady() as appropriate.
0295      */
0296     void ready();
0297 
0298 protected Q_SLOTS:
0299     /**
0300      * Slot called when an item in the tree view has been activated
0301      * @param index The index of the activated item
0302      */
0303     void itemActivated ( const QModelIndex & index );
0304 
0305      /**
0306      * Slot called when the selection in the tree view has changed ( and is only a single item ).
0307      * @param item The selected item
0308      */
0309     void itemSelected( CollectionTreeItem * item  );
0310 
0311 protected:
0312     /**
0313      * Generate info to show in the service info applet. useful for showing initial info before any items are selected and hence
0314      * trigger the info parser.
0315      * @param html
0316      */
0317     virtual void generateWidgetInfo( const QString &html = QString() ) const;
0318 
0319     /**
0320      * sets serviceReady() and emits a signal ready() as appropriate.
0321      */
0322     void setServiceReady( bool ready );
0323 
0324     static ServiceBase *s_instance;
0325     QTreeView *m_contentView;
0326     ServiceFactory *m_parentFactory;
0327 
0328     BoxWidget    *m_topPanel;
0329     BoxWidget    *m_bottomPanel;
0330     bool         m_polished;
0331 
0332     bool m_useCollectionTreeView;
0333 
0334     QList<QUrl>   m_urlsToInsert;
0335 
0336     InfoParserBase * m_infoParser;
0337 
0338     QMenuBar *m_menubar;
0339     QMenu *m_filterMenu;
0340     SearchWidget * m_searchWidget;
0341 
0342     //void addToPlaylist( CollectionTreeItem * item );
0343 
0344 private: // need to move stuff here
0345     bool m_serviceready;
0346 
0347     QAbstractItemModel *m_model;
0348     QSortFilterProxyModel *m_filterModel;
0349 };
0350 
0351 
0352 #endif