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 }