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

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::PlaylistFileSize"
0018 
0019 #include "PlaylistFileSize.h"
0020 
0021 #include "core/meta/Meta.h"
0022 #include "playlistgenerator/Constraint.h"
0023 #include "playlistgenerator/ConstraintFactory.h"
0024 
0025 #include <cmath>
0026 #include <cstdlib>
0027 
0028 #include <KFormat>
0029 
0030 
0031 Constraint*
0032 ConstraintTypes::PlaylistFileSize::createFromXml( QDomElement& xmlelem, ConstraintNode* p )
0033 {
0034     if ( p ) {
0035         return new PlaylistFileSize( xmlelem, p );
0036     } else {
0037         return nullptr;
0038     }
0039 }
0040 
0041 Constraint*
0042 ConstraintTypes::PlaylistFileSize::createNew( ConstraintNode* p )
0043 {
0044     if ( p ) {
0045         return new PlaylistFileSize( p );
0046     } else {
0047         return nullptr;
0048     }
0049 }
0050 
0051 ConstraintFactoryEntry*
0052 ConstraintTypes::PlaylistFileSize::registerMe()
0053 {
0054     return new ConstraintFactoryEntry( QStringLiteral("PlaylistFileSize"),
0055                                        i18n("Total File Size of Playlist"),
0056                                        i18n("Sets the preferred total file size of the playlist"),
0057                                        &PlaylistFileSize::createFromXml, &PlaylistFileSize::createNew );
0058 }
0059 
0060 ConstraintTypes::PlaylistFileSize::PlaylistFileSize( QDomElement& xmlelem, ConstraintNode* p )
0061         : Constraint( p )
0062         , m_size( 700 )
0063         , m_unit( 1 )
0064         , m_comparison( CompareNumEquals )
0065         , m_strictness( 1.0 )
0066 {
0067     QDomAttr a;
0068 
0069     a = xmlelem.attributeNode( QStringLiteral("size") );
0070     if ( !a.isNull() )
0071         m_size = a.value().toInt();
0072 
0073     a = xmlelem.attributeNode( QStringLiteral("unit") );
0074     if ( !a.isNull() )
0075         m_unit = a.value().toInt();
0076 
0077     a = xmlelem.attributeNode( QStringLiteral("comparison") );
0078     if ( !a.isNull() )
0079         m_comparison = a.value().toInt();
0080 
0081     a = xmlelem.attributeNode( QStringLiteral("strictness") );
0082     if ( !a.isNull() )
0083         m_strictness = a.value().toDouble();
0084 }
0085 
0086 ConstraintTypes::PlaylistFileSize::PlaylistFileSize( ConstraintNode* p )
0087         : Constraint( p )
0088         , m_size( 700 )
0089         , m_unit( 1 )
0090         , m_comparison( CompareNumEquals )
0091         , m_strictness( 1.0 )
0092 {
0093 }
0094 
0095 QWidget*
0096 ConstraintTypes::PlaylistFileSize::editWidget() const
0097 {
0098     PlaylistFileSizeEditWidget* e = new PlaylistFileSizeEditWidget( m_size, m_unit, m_comparison, static_cast<int>( 10*m_strictness ) );
0099     connect( e, &PlaylistFileSizeEditWidget::comparisonChanged, this, &PlaylistFileSize::setComparison );
0100     connect( e, &PlaylistFileSizeEditWidget::sizeChanged, this, &PlaylistFileSize::setSize );
0101     connect( e, &PlaylistFileSizeEditWidget::unitChanged, this, &PlaylistFileSize::setUnit );
0102     connect( e, &PlaylistFileSizeEditWidget::strictnessChanged, this, &PlaylistFileSize::setStrictness );
0103     return e;
0104 }
0105 
0106 void
0107 ConstraintTypes::PlaylistFileSize::toXml( QDomDocument& doc, QDomElement& elem ) const
0108 {
0109     QDomElement c = doc.createElement( QStringLiteral("constraint") );
0110     c.setAttribute( QStringLiteral("type"), QStringLiteral("PlaylistFileSize") );
0111     c.setAttribute( QStringLiteral("size"), QString::number( m_size ) );
0112     c.setAttribute( QStringLiteral("unit"), QString::number( m_unit ) );
0113     c.setAttribute( QStringLiteral("comparison"), QString::number( m_comparison ) );
0114     c.setAttribute( QStringLiteral("strictness"), QString::number( m_strictness ) );
0115     elem.appendChild( c );
0116 }
0117 
0118 QString
0119 ConstraintTypes::PlaylistFileSize::getName() const
0120 {
0121     KLocalizedString v;
0122     if ( m_comparison == CompareNumEquals ) {
0123         v = ki18nc( "%1 is a file size (e.g. 50 MB)", "Total file size of playlist: equals %1");
0124     } else if ( m_comparison == CompareNumGreaterThan ) {
0125         v = ki18nc( "%1 is a file size (e.g. 50 MB)", "Total file size of playlist: more than %1");
0126     } else if ( m_comparison == CompareNumLessThan ) {
0127         v = ki18nc( "%1 is a file size (e.g. 50 MB)", "Total file size of playlist: less than %1");
0128     } else {
0129         v = ki18n( "Total file size of playlist: unknown");
0130     }
0131     v = v.subs( KFormat().formatByteSize( getWantedSize(), 1, KFormat::MetricBinaryDialect ) );
0132     return v.toString();
0133 }
0134 
0135 double
0136 ConstraintTypes::PlaylistFileSize::satisfaction( const Meta::TrackList& tl ) const
0137 {
0138     quint64 tlSize = 0;
0139     foreach ( const Meta::TrackPtr t, tl ) {
0140         // Boy it sure would be nice if Qt had a "reduce" function built in
0141         tlSize += static_cast<quint64>( t->filesize() );
0142     }
0143 
0144     quint64 wantedSize = getWantedSize();
0145 
0146     if ( m_comparison == CompareNumEquals ) {
0147         if ( tlSize > wantedSize )
0148             return ( tlSize == wantedSize ) ? 1.0 : transformFileSize( tlSize - wantedSize );
0149         else
0150             return ( tlSize == wantedSize ) ? 1.0 : transformFileSize( wantedSize - tlSize );
0151     } else if ( m_comparison == CompareNumGreaterThan ) {
0152         return ( tlSize > wantedSize ) ? 1.0 : transformFileSize( wantedSize - tlSize );
0153     } else if ( m_comparison == CompareNumLessThan ) {
0154         return ( tlSize < wantedSize ) ? 1.0 : transformFileSize( tlSize - wantedSize );
0155     } else {
0156         return 0.0;
0157     }
0158 }
0159 
0160 quint32
0161 ConstraintTypes::PlaylistFileSize::suggestPlaylistSize() const
0162 {
0163     // estimate that each file is about 8MB large
0164     quint64 s = getWantedSize() / static_cast<quint64>( 8000000 );
0165     return static_cast<quint32>( s );
0166 }
0167 
0168 quint64
0169 ConstraintTypes::PlaylistFileSize::getWantedSize() const
0170 {
0171     switch ( m_unit ) {
0172         case 0:
0173             return static_cast<quint64>( m_size ) * Q_INT64_C( 1000 );
0174         case 1:
0175             return static_cast<quint64>( m_size ) * Q_INT64_C( 1000000 );
0176         case 2:
0177             return static_cast<quint64>( m_size ) * Q_INT64_C( 1000000000 );
0178         case 3:
0179             return static_cast<quint64>( m_size ) * Q_INT64_C( 1000000000000 );
0180         default:
0181             return static_cast<quint64>( m_size ) * Q_INT64_C( 1 );
0182     }
0183 }
0184 
0185 double
0186 ConstraintTypes::PlaylistFileSize::transformFileSize( const quint64 delta ) const
0187 {
0188     // Note: delta must be positive
0189     const double factor = m_strictness * 3e-9;
0190     return 1.0 / (1.0 + exp( factor*(double)(delta)));
0191 }
0192 
0193 void
0194 ConstraintTypes::PlaylistFileSize::setComparison( const int c )
0195 {
0196     m_comparison = c;
0197     Q_EMIT dataChanged();
0198 }
0199 
0200 void
0201 ConstraintTypes::PlaylistFileSize::setSize( const int l )
0202 {
0203     m_size = l;
0204     Q_EMIT dataChanged();
0205 }
0206 
0207 void
0208 ConstraintTypes::PlaylistFileSize::setStrictness( const int sv )
0209 {
0210     m_strictness = static_cast<double>(sv)/10.0;
0211 }
0212 
0213 void
0214 ConstraintTypes::PlaylistFileSize::setUnit( const int u )
0215 {
0216     m_unit = u;
0217     Q_EMIT dataChanged();
0218 }
0219 
0220 /******************************
0221  * Edit Widget                *
0222  ******************************/
0223 
0224 ConstraintTypes::PlaylistFileSizeEditWidget::PlaylistFileSizeEditWidget( const int size,
0225                                                                      const int unit,
0226                                                                      const int comparison,
0227                                                                      const int strictness ) : QWidget( nullptr )
0228 {
0229     ui.setupUi( this );
0230 
0231     ui.spinBox_Size->setValue( size );
0232     ui.comboBox_Unit->setCurrentIndex( unit );
0233     ui.comboBox_Comparison->setCurrentIndex( comparison );
0234     ui.slider_Strictness->setValue( strictness );
0235 }
0236 
0237 void
0238 ConstraintTypes::PlaylistFileSizeEditWidget::on_spinBox_Size_valueChanged( const int l )
0239 {
0240     Q_EMIT sizeChanged( l );
0241     Q_EMIT updated();
0242 }
0243 
0244 void
0245 ConstraintTypes::PlaylistFileSizeEditWidget::on_comboBox_Unit_currentIndexChanged( const int l )
0246 {
0247     Q_EMIT unitChanged( l );
0248     Q_EMIT updated();
0249 }
0250 
0251 void
0252 ConstraintTypes::PlaylistFileSizeEditWidget::on_comboBox_Comparison_currentIndexChanged( const int v )
0253 {
0254     Q_EMIT comparisonChanged( v );
0255     Q_EMIT updated();
0256 }
0257 
0258 void
0259 ConstraintTypes::PlaylistFileSizeEditWidget::on_slider_Strictness_valueChanged( const int v )
0260 {
0261     Q_EMIT strictnessChanged( v );
0262     Q_EMIT updated();
0263 }