File indexing completed on 2024-05-19 04:49:41

0001 /****************************************************************************************
0002  * Copyright (c) 2011 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) version 3 or        *
0007  * any later version accepted by the membership of KDE e.V. (or its successor approved  *
0008  * by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of  *
0009  * version 3 of the license.                                                            *
0010  *                                                                                      *
0011  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0012  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0013  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0014  *                                                                                      *
0015  * You should have received a copy of the GNU General Public License along with         *
0016  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0017  ****************************************************************************************/
0018 
0019 #define DEBUG_PREFIX "IfElseBias"
0020 
0021 #include "IfElseBias.h"
0022 
0023 #include "amarokconfig.h"
0024 #include "core/meta/Meta.h"
0025 
0026 #include <QtGlobal> // for qRound
0027 #include <QPainter>
0028 #include <QXmlStreamReader>
0029 #include <QXmlStreamWriter>
0030 
0031 #include <KLocalizedString>
0032 
0033 QString
0034 Dynamic::IfElseBiasFactory::i18nName() const
0035 { return i18nc("Name of the \"IfElse\" bias", "If Else"); }
0036 
0037 QString
0038 Dynamic::IfElseBiasFactory::name() const
0039 { return Dynamic::IfElseBias::sName(); }
0040 
0041 QString
0042 Dynamic::IfElseBiasFactory::i18nDescription() const
0043 { return i18nc("Description of the \"IfElse\" bias",
0044                    "The \"IfElse\" bias adds tracks that match at least one of the sub biases.\nIt will only check the second sub-bias if the first doesn't return any results."); }
0045 
0046 Dynamic::BiasPtr
0047 Dynamic::IfElseBiasFactory::createBias()
0048 { return Dynamic::BiasPtr( new Dynamic::IfElseBias() ); }
0049 
0050 
0051 
0052 
0053 Dynamic::IfElseBias::IfElseBias()
0054     : OrBias()
0055 { }
0056 
0057 QString
0058 Dynamic::IfElseBias::sName()
0059 {
0060     return QStringLiteral( "ifElseBias" );
0061 }
0062 
0063 QString
0064 Dynamic::IfElseBias::name() const
0065 {
0066     return Dynamic::IfElseBias::sName();
0067 }
0068 
0069 QString
0070 Dynamic::IfElseBias::toString() const
0071 {
0072     return i18nc("IfElse bias representation", "Match all sequentially");
0073 }
0074 
0075 void
0076 Dynamic::IfElseBias::paintOperator( QPainter* painter, const QRect& rect, Dynamic::AbstractBias* bias )
0077 {
0078     if( m_biases.indexOf( Dynamic::BiasPtr(bias) ) > 0 )
0079         painter->drawText( rect.adjusted(2, 0, -2, 0),
0080                            Qt::AlignRight,
0081                            i18nc("Prefix for IfElseBias. Shown in front of a bias in the dynamic playlist view", "else" ) );
0082 }
0083 
0084 Dynamic::TrackSet
0085 Dynamic::IfElseBias::matchingTracks( const Meta::TrackList& playlist,
0086                                      int contextCount, int finalCount,
0087                                      const Dynamic::TrackCollectionPtr &universe ) const
0088 {
0089     // store the parameters in case we need to request additional matching tracks later
0090     m_playlist = playlist;
0091     m_contextCount = contextCount;
0092     m_finalCount = finalCount;
0093     m_universe = universe;
0094 
0095     m_tracks = Dynamic::TrackSet( universe, false );
0096     m_outstandingMatches = 0;
0097 
0098     foreach( Dynamic::BiasPtr bias, m_biases )
0099     {
0100         m_tracks = bias->matchingTracks( playlist, contextCount, finalCount, universe );
0101         if( m_tracks.isOutstanding() )
0102         {
0103             m_outstandingMatches++;
0104             return m_tracks;
0105         }
0106         else
0107         {
0108             removeDuplicate();
0109             if( !m_tracks.isEmpty() ) {
0110                 return m_tracks;
0111             }
0112         }
0113     }
0114 
0115     return m_tracks;
0116 }
0117 
0118 void
0119 Dynamic::IfElseBias::resultReceived( const Dynamic::TrackSet &tracks )
0120 {
0121     m_tracks = tracks;
0122     --m_outstandingMatches;
0123 
0124     // we got some tracks result
0125     removeDuplicate();
0126     if( !m_tracks.isEmpty() )
0127     {
0128         Q_EMIT resultReady( m_tracks );
0129         return;
0130     }
0131 
0132     // ok. check the next biases
0133     bool alreadyChecked = true;
0134     foreach( Dynamic::BiasPtr bias, m_biases )
0135     {
0136         // jump over already checked biases
0137         if( bias.data() == sender() )
0138         {
0139             alreadyChecked = false;
0140             continue;
0141         }
0142         else if( alreadyChecked )
0143         {
0144             continue;
0145         }
0146 
0147         // check the next bias
0148         m_tracks = bias->matchingTracks( m_playlist, m_contextCount, m_finalCount, m_universe );
0149         if( m_tracks.isOutstanding() )
0150         {
0151             m_outstandingMatches++;
0152             return; // wait for the next results
0153         }
0154         else
0155         {
0156             removeDuplicate();
0157             if( !m_tracks.isEmpty() ) {
0158                 Q_EMIT resultReady( m_tracks );
0159                 return;
0160             }
0161         }
0162     }
0163     Q_EMIT resultReady( m_tracks );
0164 }
0165 
0166 // we need to eliminate duplicates now to have a proper check for an empty result
0167 void
0168 Dynamic::IfElseBias::removeDuplicate() const
0169 {
0170     if( AmarokConfig::dynamicDuplicates() )
0171         return;
0172 
0173     for( int i = 0; i < m_playlist.count(); i++ )
0174         if( m_playlist[i] )
0175             m_tracks.subtract( m_playlist[i] );
0176 }
0177 
0178