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

0001 /****************************************************************************************
0002  * Copyright (c) 2008-2012 Soren Harward <stharward@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 #define DEBUG_PREFIX "Constraint::PreventDuplicates"
0018 
0019 #include "PreventDuplicates.h"
0020 #include "playlistgenerator/Constraint.h"
0021 #include "playlistgenerator/ConstraintFactory.h"
0022 
0023 #include "core/meta/Meta.h"
0024 
0025 #include <QSet>
0026 
0027 #include <cmath>
0028 
0029 Constraint*
0030 ConstraintTypes::PreventDuplicates::createFromXml( QDomElement& xmlelem, ConstraintNode* p )
0031 {
0032     if ( p )
0033         return new PreventDuplicates( xmlelem, p );
0034     else
0035         return nullptr;
0036 }
0037 
0038 Constraint*
0039 ConstraintTypes::PreventDuplicates::createNew( ConstraintNode* p )
0040 {
0041     if ( p )
0042         return new PreventDuplicates( p );
0043     else
0044         return nullptr;
0045 }
0046 
0047 ConstraintFactoryEntry*
0048 ConstraintTypes::PreventDuplicates::registerMe()
0049 {
0050     return new ConstraintFactoryEntry( QStringLiteral("PreventDuplicates"),
0051                                        i18n("Prevent Duplicates"),
0052                                        i18n("Prevents duplicate tracks, albums, or artists from appearing in the playlist"),
0053                                        &PreventDuplicates::createFromXml, &PreventDuplicates::createNew );
0054 }
0055 
0056 ConstraintTypes::PreventDuplicates::PreventDuplicates( QDomElement& xmlelem, ConstraintNode* p )
0057         : Constraint( p )
0058 {
0059     QDomAttr a;
0060 
0061     a = xmlelem.attributeNode( QStringLiteral("field") );
0062     if ( !a.isNull() ) {
0063         m_field = static_cast<DupeField>( a.value().toInt() );
0064     }
0065 }
0066 
0067 ConstraintTypes::PreventDuplicates::PreventDuplicates( ConstraintNode* p )
0068         : Constraint( p )
0069         , m_field( DupeTrack )
0070 {
0071 }
0072 
0073 QWidget*
0074 ConstraintTypes::PreventDuplicates::editWidget() const
0075 {
0076     PreventDuplicatesEditWidget* e = new PreventDuplicatesEditWidget( m_field );
0077     connect( e, &PreventDuplicatesEditWidget::fieldChanged, this, &PreventDuplicates::setField );
0078     return e;
0079 }
0080 
0081 void
0082 ConstraintTypes::PreventDuplicates::toXml( QDomDocument& doc, QDomElement& elem ) const
0083 {
0084     QDomElement c = doc.createElement( QStringLiteral("constraint") );
0085     c.setAttribute( QStringLiteral("type"), QStringLiteral("PreventDuplicates") );
0086     c.setAttribute( QStringLiteral("field"), QString::number( m_field ) );
0087     elem.appendChild( c );
0088 }
0089 
0090 QString
0091 ConstraintTypes::PreventDuplicates::getName() const
0092 {
0093     switch ( m_field ) {
0094         case DupeTrack:
0095             return i18n("Prevent duplicate tracks");
0096         case DupeArtist:
0097             return i18n("Prevent duplicate artists");
0098         case DupeAlbum:
0099             return i18n("Prevent duplicate albums");
0100     }
0101     return QString();
0102 }
0103 
0104 double
0105 ConstraintTypes::PreventDuplicates::satisfaction( const Meta::TrackList& tl ) const
0106 {
0107     int d = 0;
0108     QSet<Meta::TrackPtr> tracks;
0109     QSet<Meta::AlbumPtr> albums;
0110     QSet<Meta::ArtistPtr> artists;
0111     switch ( m_field ) {
0112         case DupeTrack:
0113             foreach( Meta::TrackPtr t, tl ) {
0114                 if ( tracks.contains(t) ) {
0115                     d++;
0116                 } else {
0117                     tracks.insert(t);
0118                 }
0119             }
0120             break;
0121         case DupeAlbum:
0122             foreach( Meta::TrackPtr t, tl ) {
0123                 if ( albums.contains(t->album()) ) {
0124                     d++;
0125                 } else {
0126                     albums.insert(t->album());
0127                 }
0128             }
0129             break;
0130         case DupeArtist:
0131             foreach( Meta::TrackPtr t, tl ) {
0132                 if ( artists.contains(t->artist()) ) {
0133                     d++;
0134                 } else {
0135                     artists.insert(t->artist());
0136                 }
0137             }
0138             break;
0139     }
0140             
0141     return exp( (double)d / -3.0 );
0142 }
0143 
0144 void
0145 ConstraintTypes::PreventDuplicates::setField( const int c )
0146 {
0147     m_field = static_cast<DupeField>( c );
0148     Q_EMIT dataChanged();
0149 }
0150 
0151 
0152 /******************************
0153  * Edit Widget                *
0154  ******************************/
0155 
0156 ConstraintTypes::PreventDuplicatesEditWidget::PreventDuplicatesEditWidget( const int field )
0157     : QWidget( nullptr )
0158 {
0159     ui.setupUi( this );
0160     ui.comboBox_Field->setCurrentIndex( field );
0161 }
0162 
0163 void
0164 ConstraintTypes::PreventDuplicatesEditWidget::on_comboBox_Field_currentIndexChanged( const int v )
0165 {
0166     Q_EMIT fieldChanged( v );
0167     Q_EMIT updated();
0168 }