File indexing completed on 2025-02-23 04:28:33

0001 /****************************************************************************************
0002  * Copyright (c) 2013 Anmol Ahuja <darthcodus@gmail.com>                                *
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 BIAS_EXPORTER_H
0018 #define BIAS_EXPORTER_H
0019 
0020 #include "dynamic/Bias.h"
0021 #include "dynamic/BiasFactory.h"
0022 
0023 #include <QObject>
0024 #include <QPointer>
0025 #include <QJSValue>
0026 #include <QString>
0027 #include <QXmlStreamReader>
0028 
0029 class QJSEngine;
0030 
0031 namespace AmarokScript
0032 {
0033     /**
0034      * Wraps ScriptableBiasFactory Ctors
0035      */
0036     class ScriptableBiasFactoryWrapper : public QObject
0037     {
0038         Q_OBJECT
0039     public:
0040         ScriptableBiasFactoryWrapper(QJSEngine *engine);
0041         Q_INVOKABLE QJSValue groupBiasCtor();
0042         Q_INVOKABLE QJSValue biasCtor();
0043 
0044     private:
0045         QJSEngine *m_engine;
0046     };
0047 
0048     // SCRIPTDOX BiasFactory
0049     class ScriptableBiasFactory : public QObject, public Dynamic::AbstractBiasFactory
0050     {
0051         Q_OBJECT
0052 
0053         /**
0054          * Set whether this bias is enabled and visible in the dynamic playlist bias menu.
0055          */
0056         Q_PROPERTY( bool enabled READ enabled WRITE setEnabled )
0057 
0058         /**
0059          * A user visible name for this bias
0060          */
0061         Q_PROPERTY( QString name READ i18nName WRITE setI18nName ) // corresponds to i18name
0062 
0063         /**
0064          * A unique identifier for this bias.
0065          */
0066         Q_PROPERTY( QString identifier READ name WRITE setName )
0067 
0068         /**
0069          * A user visible description for this bias.
0070          */
0071         Q_PROPERTY( QString description READ i18nDescription WRITE setI18nDescription )
0072 
0073         /**
0074          * Set a function returning widget appropriate for editing the bias, if needed.
0075          * var obj = new ScriptableBias(); obj.widget = function( a ) { return new QLabel(\"dfdsf\"); }"
0076          */
0077         Q_PROPERTY( QJSValue widget READ widgetFunction WRITE setWidgetFunction )
0078 
0079         Q_PROPERTY( QJSValue fromXml READ fromXmlFunction WRITE setFromXmlFunction )
0080 
0081         Q_PROPERTY( QJSValue toXml READ toXmlFunction WRITE setToXmlFunction )
0082 
0083         /**
0084          * Set this to a function of signature:
0085          * TrackSet ( const Meta::TrackList &playlist, int contextCount, int finalCount, QStringList universeUids )
0086          */
0087         Q_PROPERTY( QJSValue matchingTracks READ matchingTracksFunction WRITE setMatchingTracksFunction )
0088 
0089         /**
0090          * bool trackMatches( int position, TrackList playlist, int contextCount )
0091          */
0092         Q_PROPERTY( QJSValue trackMatches READ trackMatchesFunction WRITE setTrackMatchesFunction )
0093 
0094         Q_PROPERTY( QJSValue toStringFunction READ toStringFunction WRITE setToStringFunction )
0095 
0096         Q_PROPERTY( QJSValue init READ initFunction WRITE setInitFunction )
0097 
0098         public:
0099             static void init( QJSEngine *engine );
0100 
0101             QString i18nName() const override;
0102             QString name() const override;
0103             QString i18nDescription() const override;
0104             QJSValue initFunction() const;
0105             QJSValue fromXmlFunction() const;
0106             QJSValue matchingTracksFunction() const;
0107             QJSValue toXmlFunction() const;
0108             QJSValue toStringFunction() const;
0109             QJSValue trackMatchesFunction() const;
0110             QJSValue widgetFunction() const;
0111             QJSEngine *engine() const;
0112 
0113         public Q_SLOTS:
0114             Dynamic::BiasPtr createBias() override;
0115 
0116         private:
0117             friend QJSValue ScriptableBiasFactoryWrapper::groupBiasCtor();
0118             friend QJSValue ScriptableBiasFactoryWrapper::biasCtor();
0119             ScriptableBiasFactory( QJSEngine *engine = nullptr, bool groupBias = false );
0120             ~ScriptableBiasFactory() override;
0121 
0122             bool enabled() const;
0123             void setEnabled( bool enabled );
0124             void setName( const QString &name );
0125             void setI18nName( const QString &i18nName );
0126             void setI18nDescription( const QString &description );
0127             void setInitFunction( const QJSValue &value );
0128             void setWidgetFunction( const QJSValue &value );
0129             void setFromXmlFunction( const QJSValue &value );
0130             void setToXmlFunction( const QJSValue &value );
0131             void setTrackMatchesFunction( const QJSValue &value );
0132             void setMatchingTracksFunction( const QJSValue &value );
0133             void setToStringFunction( const QJSValue &value );
0134 
0135             QJSValue m_initFunction;
0136             QString m_name;
0137             QString m_i18nName;
0138             QString m_description;
0139             QJSValue m_widgetFunction;
0140             QJSValue m_fromXmlFunction;
0141             QJSValue m_toXmlFunction;
0142             QJSValue m_matchingTracksFunction;
0143             QJSValue m_trackMatchesFunction;
0144             QJSValue m_toStringFunction;
0145             bool m_groupBias;
0146             QJSEngine *m_engine;
0147             bool m_enabled;
0148             static ScriptableBiasFactoryWrapper* s_wrapper;
0149     };
0150 
0151     class ScriptableBias : public Dynamic::AbstractBias
0152     {
0153         Q_OBJECT
0154 
0155         public:
0156             explicit ScriptableBias( ScriptableBiasFactory *biasProto );
0157             ~ScriptableBias() override;
0158             QJSValue scriptObject() { return m_biasObject; }
0159 
0160         public:
0161             void fromXml( QXmlStreamReader *reader ) override;
0162             void toXml(QXmlStreamWriter *writer) const override;
0163             Dynamic::TrackSet matchingTracks( const Meta::TrackList &playlist, int contextCount,
0164                                               int finalCount, const Dynamic::TrackCollectionPtr &universe ) const override;
0165             bool trackMatches( int position, const Meta::TrackList &playlist, int contextCount ) const override;
0166             QString toString() const override;
0167             QString name() const override;
0168             void paintOperator( QPainter *painter, const QRect &rect, AbstractBias *bias ) override;
0169             QWidget* widget( QWidget *parent = nullptr ) override;
0170 
0171         private Q_SLOTS:
0172             Dynamic::TrackSet slotMatchingTracks( const Meta::TrackList &playlist, int contextCount,
0173                                               int finalCount, const Dynamic::TrackCollectionPtr &universe ) const;
0174             void removeBias();
0175 
0176         public Q_SLOTS:
0177 
0178             /** This slot is called when the bias should discard cached results.
0179             * This will be done in case a new playlist is requested for an updated
0180             * collection.
0181             */
0182             void invalidate() override;
0183 
0184             /** Call this function when this bias should be replaced by a new one.
0185             *                @param newBias The bias that replaces this bias. If you give
0186             *                an empty BiasPrt as argument the bias will be removed.
0187             */
0188             void replace( const Dynamic::BiasPtr &newBias ) override;
0189 
0190             /**
0191              * Call after an outstanding result is completed
0192              */
0193             void ready( const Dynamic::TrackSet &trackSet );
0194 
0195         private:
0196             QPointer<ScriptableBiasFactory> m_scriptBias;
0197             QJSEngine *m_engine;
0198             QJSValue m_biasObject;
0199     };
0200 
0201     /**
0202      * Wraps TrackSetExporter Ctors
0203      */
0204     class TrackSetExporterWrapper : public QObject
0205     {
0206         Q_OBJECT
0207         public:
0208             TrackSetExporterWrapper(QJSEngine *engine);
0209             Q_INVOKABLE QJSValue trackSetConstructor( QJSValue arg0, QJSValue arg1 = QJSValue(QJSValue::UndefinedValue) );
0210 
0211         private:
0212             QJSEngine *m_engine;
0213     };
0214 
0215     /**
0216     * A representation of a set of tracks, relative to a given universe set.
0217     * Intersecting TrackSets from different universes is not a good idea.
0218     */
0219     class TrackSetExporter : public QObject, public Dynamic::TrackSet
0220     {
0221         Q_OBJECT
0222 
0223         /**
0224          * The number of songs contained in this trackSet.
0225          */
0226         Q_PROPERTY( int count READ trackCount )
0227 
0228         /**
0229          * True if all of the tracks are included in the set.
0230          */
0231         Q_PROPERTY( bool isFull READ isFull )
0232 
0233         /**
0234          * Returns true if the results of this track set are not yet available
0235          */
0236         Q_PROPERTY( bool isOutstanding READ isOutstanding )
0237 
0238         /**
0239          * True if none of the tracks are included in the set.
0240          */
0241         Q_PROPERTY( bool isEmpty READ isEmpty )
0242 
0243         public:
0244             static QJSValue toScriptValue( QJSEngine *engine, Dynamic::TrackSet const &trackSet );
0245             static void fromScriptValue( const QJSValue &obj, Dynamic::TrackSet &trackSet );
0246 
0247             /**
0248              * Includes or excludes all tracks in the set.
0249              * @param value If true set is set to "full". Else to "empty".
0250              */
0251             Q_INVOKABLE void reset( bool value );
0252 
0253             /**
0254              * Returns true if the @param uid is included in the set
0255              */
0256             Q_INVOKABLE bool containsUid( const QString& uid ) const;
0257 
0258             Q_INVOKABLE bool containsTrack( const Meta::TrackPtr &track ) const;
0259 
0260             /**
0261              * Returns the uids of a random track contains in this set
0262              */
0263             Q_INVOKABLE Meta::TrackPtr getRandomTrack() const;
0264 
0265             /**
0266              * Add the track @param track to the trackset.
0267              */
0268             Q_INVOKABLE void uniteTrack( const Meta::TrackPtr &track );
0269 
0270             /**
0271              * Add the track set @p trackSet to the trackset.
0272              *
0273              * @param trackSet the track set to be added.
0274              */
0275             Q_INVOKABLE void uniteTrackSet( const Dynamic::TrackSet &trackSet );
0276 
0277             /**
0278              * Add the uids @p uids to the trackset.
0279              *
0280              * @param uids string list of the uids.
0281              */
0282             Q_INVOKABLE void uniteUids( const QStringList &uids );
0283 
0284             /**
0285              * Perform an intersection of the trackset with the set @param trackSet
0286              */
0287             Q_INVOKABLE void intersectTrackSet( const Dynamic::TrackSet &trackSet );
0288 
0289             /**
0290              * Perform an intersection on this trackset with the trackset represented by @param uids
0291              */
0292             Q_INVOKABLE void intersectUids( const QStringList &uids );
0293 
0294             /**
0295              * Subtract the track @param track from this trackset.
0296              */
0297             Q_INVOKABLE void subtractTrack( const Meta::TrackPtr &track );
0298 
0299             /**
0300              * Subtract the trackset @param trackSet from this trackset
0301              */
0302             Q_INVOKABLE void subtractTrackSet( const Dynamic::TrackSet &trackSet );
0303 
0304             /**
0305              * Subtract the set represented by @param uids from this trackset
0306              */
0307             Q_INVOKABLE void subtractUids( const QStringList &uids );
0308 
0309         private:
0310             static void init( QJSEngine *engine );
0311             explicit TrackSetExporter( const Dynamic::TrackSet &trackSet );
0312             friend QJSValue TrackSetExporterWrapper::trackSetConstructor( QJSValue arg0, QJSValue arg1 );
0313 
0314             static TrackSetExporterWrapper *s_wrapper;
0315 
0316             friend class ScriptableBiasFactory;
0317     };
0318 }
0319 
0320 Q_DECLARE_METATYPE( QXmlStreamReader* )
0321 Q_DECLARE_METATYPE( QXmlStreamWriter* )
0322 Q_DECLARE_METATYPE( AmarokScript::ScriptableBias* )
0323 
0324 #endif