Warning, file /multimedia/amarok/src/dynamic/BiasFactory.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /**************************************************************************************** 0002 * Copyright (c) 2010 Ralf Engels <ralf-engels@gmx.de> * 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 #define DEBUG_PREFIX "BiasFactory" 0018 0019 #include "BiasFactory.h" 0020 0021 #include "App.h" 0022 #include "biases/AlbumPlayBias.h" 0023 #include "biases/IfElseBias.h" 0024 #include "biases/PartBias.h" 0025 #include "biases/TagMatchBias.h" 0026 #include "biases/SearchQueryBias.h" 0027 #include "biases/QuizPlayBias.h" 0028 #include "biases/EchoNestBias.h" 0029 #include "core/support/Debug.h" 0030 #include "core/collections/QueryMaker.h" 0031 #include "dynamic/Bias.h" 0032 #include "scripting/scriptengine/exporters/ScriptableBiasExporter.h" 0033 0034 #include <QFormLayout> 0035 #include <QLabel> 0036 #include <QList> 0037 #include <QXmlStreamReader> 0038 0039 Dynamic::BiasPtr 0040 Dynamic::AbstractBiasFactory::createFromXml( QXmlStreamReader *reader ) 0041 { 0042 Dynamic::BiasPtr bias( createBias() ); 0043 bias->fromXml( reader ); 0044 return bias; 0045 } 0046 0047 class RandomBiasFactory : public Dynamic::AbstractBiasFactory 0048 { 0049 QString i18nName() const override 0050 { return i18nc("Name of the random bias", "Random"); } 0051 0052 QString name() const override 0053 { return Dynamic::RandomBias::sName(); } 0054 0055 QString i18nDescription() const override 0056 { return i18nc("Description of the random bias", 0057 "The random bias adds random tracks from the\n" 0058 "whole collection without any bias."); } 0059 0060 Dynamic::BiasPtr createBias() override 0061 { return Dynamic::BiasPtr( new Dynamic::RandomBias() ); } 0062 }; 0063 0064 0065 class AndBiasFactory : public Dynamic::AbstractBiasFactory 0066 { 0067 QString i18nName() const override 0068 { return i18nc("Name of the \"And\" bias", "And"); } 0069 0070 QString name() const override 0071 { return Dynamic::AndBias::sName(); } 0072 0073 QString i18nDescription() const override 0074 { return i18nc("Description of the \"And\" bias", 0075 "The \"And\" bias adds tracks that match all\n" 0076 "of the sub biases."); } 0077 0078 Dynamic::BiasPtr createBias() override 0079 { return Dynamic::BiasPtr( new Dynamic::AndBias() ); } 0080 }; 0081 0082 0083 class OrBiasFactory : public Dynamic::AbstractBiasFactory 0084 { 0085 QString i18nName() const override 0086 { return i18nc("Name of the \"Or\" bias", "Or"); } 0087 0088 QString name() const override 0089 { return Dynamic::OrBias::sName(); } 0090 0091 QString i18nDescription() const override 0092 { return i18nc("Description of the \"Or\" bias", 0093 "The \"Or\" bias adds tracks that match at\n" 0094 "least one of the sub biases."); } 0095 0096 Dynamic::BiasPtr createBias() override 0097 { return Dynamic::BiasPtr( new Dynamic::OrBias() ); } 0098 }; 0099 0100 Dynamic::BiasFactory* Dynamic::BiasFactory::s_instance = nullptr; 0101 0102 QList<Dynamic::AbstractBiasFactory*> Dynamic::BiasFactory::s_biasFactories = QList<Dynamic::AbstractBiasFactory*>(); 0103 0104 Dynamic::BiasFactory* 0105 Dynamic::BiasFactory::instance() 0106 { 0107 if( !s_instance ) 0108 { 0109 // --- build in biases 0110 s_biasFactories.append( new Dynamic::SearchQueryBiasFactory() ); 0111 s_biasFactories.append( new RandomBiasFactory() ); 0112 s_biasFactories.append( new AndBiasFactory() ); 0113 s_biasFactories.append( new OrBiasFactory() ); 0114 s_biasFactories.append( new Dynamic::PartBiasFactory() ); 0115 s_biasFactories.append( new Dynamic::IfElseBiasFactory() ); 0116 s_biasFactories.append( new Dynamic::TagMatchBiasFactory() ); 0117 s_biasFactories.append( new Dynamic::AlbumPlayBiasFactory() ); 0118 s_biasFactories.append( new Dynamic::QuizPlayBiasFactory() ); 0119 s_biasFactories.append( new Dynamic::EchoNestBiasFactory() ); 0120 0121 s_instance = new BiasFactory( pApp ); 0122 } 0123 return s_instance; 0124 } 0125 0126 0127 0128 // --------------- ReplacementBias ------------- 0129 0130 0131 Dynamic::ReplacementBias::ReplacementBias( const QString &n ) 0132 : m_name( n ) 0133 { 0134 connect( BiasFactory::instance(), &Dynamic::BiasFactory::changed, this, &ReplacementBias::factoryChanged ); 0135 } 0136 0137 Dynamic::ReplacementBias::ReplacementBias( const QString &n, QXmlStreamReader *reader ) 0138 : m_name( n ) 0139 { 0140 // -- read the original bias data as one block 0141 quint64 start = reader->characterOffset(); 0142 reader->skipCurrentElement(); 0143 quint64 end = reader->characterOffset(); 0144 0145 QIODevice *device = reader->device(); 0146 if( device->isSequential() ) 0147 { 0148 warning() << "Cannot read xml for bias"<<n<<"from sequential device."; 0149 return; 0150 } 0151 device->seek( start ); 0152 m_html = device->read( end - start ); 0153 0154 debug() << "replacement bias for"<<n<<"is"<<m_html; 0155 0156 connect( BiasFactory::instance(), &Dynamic::BiasFactory::changed, this, &ReplacementBias::factoryChanged ); 0157 } 0158 0159 void 0160 Dynamic::ReplacementBias::toXml( QXmlStreamWriter *writer ) const 0161 { 0162 Q_UNUSED( writer ); 0163 writer->writeComment(QStringLiteral("Replacement")); // we need to force the closing of the bias start tag 0164 writer->device()->write( m_html.left( m_html.size() - m_name.length() - 3 ) ); 0165 } 0166 0167 QString 0168 Dynamic::ReplacementBias::sName() 0169 { 0170 return QStringLiteral( "replacementBias" ); 0171 } 0172 0173 QString 0174 Dynamic::ReplacementBias::name() const 0175 { 0176 return m_name; 0177 } 0178 0179 QString 0180 Dynamic::ReplacementBias::toString() const 0181 { 0182 return i18n( "Replacement for bias %1", m_name ); 0183 } 0184 0185 QWidget* 0186 Dynamic::ReplacementBias::widget( QWidget* parent ) 0187 { 0188 QLabel *label = new QLabel( i18n( "Replacement for bias %1", m_name ), parent ); 0189 0190 return label; 0191 } 0192 0193 void 0194 Dynamic::ReplacementBias::factoryChanged() 0195 { 0196 DEBUG_BLOCK; 0197 0198 // -- search if there is a new factory with my name 0199 foreach( AbstractBiasFactory* factory, BiasFactory::instance()->factories() ) 0200 { 0201 if( factory->name() == m_name ) 0202 { 0203 debug() << "Found new factory for" << m_name; 0204 0205 // -- replace myself with the new bias 0206 QXmlStreamReader reader( m_html ); 0207 0208 Dynamic::BiasPtr newBias( factory->createFromXml( &reader ) ); 0209 replace( newBias ); 0210 return; 0211 } 0212 } 0213 } 0214 0215 0216 // ------------- BiasFactory -------------- 0217 0218 Dynamic::BiasFactory::BiasFactory( QObject *parent ) 0219 : QObject( parent ) 0220 { } 0221 0222 Dynamic::BiasFactory::~BiasFactory() 0223 { 0224 qDeleteAll(s_biasFactories); 0225 } 0226 0227 Dynamic::BiasPtr 0228 Dynamic::BiasFactory::fromXml( QXmlStreamReader *reader ) 0229 { 0230 QStringRef name = reader->name(); 0231 0232 instance(); // ensure that we have an instance with the default factories 0233 foreach( Dynamic::AbstractBiasFactory* fac, s_biasFactories ) 0234 { 0235 if( name == fac->name() ) 0236 return fac->createFromXml( reader ); 0237 } 0238 return Dynamic::BiasPtr( new ReplacementBias( name.toString(), reader ) ); 0239 } 0240 0241 Dynamic::BiasPtr 0242 Dynamic::BiasFactory::fromName( const QString &name ) 0243 { 0244 instance(); // ensure that we have an instance with the default factories 0245 foreach( Dynamic::AbstractBiasFactory* fac, s_biasFactories ) 0246 { 0247 if( name == fac->name() ) 0248 return fac->createBias(); 0249 } 0250 return Dynamic::BiasPtr( new ReplacementBias( name ) ); 0251 } 0252 0253 void 0254 Dynamic::BiasFactory::registerNewBiasFactory( Dynamic::AbstractBiasFactory* factory ) 0255 { 0256 instance(); // ensure that we have an instance with the default factories 0257 debug() << "new factory of type:" << factory->name(); 0258 if( !s_biasFactories.contains( factory ) ) 0259 s_biasFactories.append( factory ); 0260 0261 /* 0262 foreach( const QString &name, s_failedMap.keys() ) 0263 { 0264 if( name == entry->pluginName() ) // lazy loading! 0265 { 0266 debug() << "found entry loaded without proper custombiasentry. fixing now, with old weight of" << s_failedMap[ name ]->weight() ; 0267 // need to manually set the weight, as we set it on the old widget which is now being thrown away 0268 Dynamic::CustomBiasEntry* cbe = factory->newCustomBiasEntry( s_failedMapXml[ name ] ); 0269 s_failedMap[ name ]->setCurrentEntry( cbe ); 0270 s_failedMap.remove( name ); 0271 s_failedMapXml.remove( name ); 0272 } 0273 } 0274 */ 0275 0276 instance()->emitChanged(); 0277 } 0278 0279 void 0280 Dynamic::BiasFactory::removeBiasFactory( Dynamic::AbstractBiasFactory* factory ) 0281 { 0282 if( s_biasFactories.contains( factory ) ) 0283 s_biasFactories.removeAll( factory ); 0284 0285 instance()->emitChanged(); 0286 } 0287 0288 QList<Dynamic::AbstractBiasFactory*> 0289 Dynamic::BiasFactory::factories() 0290 { 0291 instance(); // ensure that we have an instance with the default factories 0292 return s_biasFactories; 0293 } 0294 0295 void 0296 Dynamic::BiasFactory::emitChanged() 0297 { 0298 Q_EMIT changed(); 0299 } 0300