File indexing completed on 2024-05-05 04:49:20
0001 /**************************************************************************************** 0002 * Copyright (c) 2012 Matěj Laitl <matej@laitl.cz> * 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 #include "Config.h" 0018 0019 #include "MetaValues.h" 0020 #include "core/meta/support/MetaConstants.h" 0021 #include "core/support/Amarok.h" 0022 0023 #include <KConfigGroup> 0024 #include <QIcon> 0025 #include <KLocalizedString> 0026 0027 #include <QBrush> 0028 #include <QPalette> 0029 0030 namespace StatSyncing 0031 { 0032 struct ProviderData { 0033 ProviderData( const QString &id_, const QString &name_, const QIcon &icon_, bool online_, bool enabled_ ) 0034 : id( id_ ), name( name_ ), icon( icon_ ), online( online_ ), enabled( enabled_ ) 0035 {} 0036 0037 QString id; 0038 QString name; 0039 QIcon icon; 0040 bool online; 0041 bool enabled; 0042 }; 0043 } 0044 0045 using namespace StatSyncing; 0046 0047 Config::Config( QObject *parent ) 0048 : QAbstractListModel( parent ) 0049 , m_checkedFields( 0 ) 0050 , m_hasChanged( false ) 0051 { 0052 read(); 0053 } 0054 0055 Config::~Config() 0056 { 0057 } 0058 0059 int 0060 Config::rowCount( const QModelIndex &parent ) const 0061 { 0062 return parent.isValid() ? 0 : m_providerData.count(); 0063 } 0064 0065 QVariant 0066 Config::data( const QModelIndex &index, int role ) const 0067 { 0068 if( !index.isValid() ) 0069 return QVariant(); 0070 if( index.row() < 0 || index.row() >= m_providerData.count() ) 0071 return QVariant(); 0072 if( index.column() != 0 ) 0073 return QVariant(); 0074 0075 const ProviderData &provider = m_providerData.at( index.row() ); 0076 switch( role ) 0077 { 0078 case Qt::DisplayRole: 0079 return provider.name; 0080 case Qt::DecorationRole: 0081 { 0082 if( !provider.icon.isNull() ) 0083 return provider.icon; 0084 return QIcon::fromTheme( provider.online ? "image-missing" : "network-disconnect" ); 0085 } 0086 case Qt::CheckStateRole: 0087 return provider.enabled ? Qt::Checked : Qt::Unchecked; 0088 case ProviderIdRole: 0089 return provider.id; 0090 case Qt::ForegroundRole: 0091 { 0092 // we need to do this trick, because not having ItemIsEnabled in flags() has 0093 // unwanded side-effects 0094 QBrush brush; 0095 QPalette::ColorGroup group = provider.online ? QPalette::Active : QPalette::Disabled; 0096 brush.setColor( QPalette().color( group, QPalette::Text ) ); 0097 return brush; 0098 } 0099 case Qt::ToolTipRole: 0100 return provider.online ? QString() : i18n( "This collection is currently offline" ); 0101 } 0102 return QVariant(); 0103 } 0104 0105 bool 0106 Config::setData( const QModelIndex &index, const QVariant &value, int role ) 0107 { 0108 if( !index.isValid() ) 0109 return false; 0110 if( index.row() < 0 || index.row() >= m_providerData.count() ) 0111 return false; 0112 if( index.column() != 0 ) 0113 return false; 0114 if( role != Qt::CheckStateRole ) 0115 return false; 0116 0117 Qt::CheckState state = Qt::CheckState( value.toInt() ); 0118 m_providerData[ index.row() ].enabled = ( state == Qt::Checked ) ? true : false; 0119 m_hasChanged = true; 0120 Q_EMIT dataChanged( index, index ); 0121 return true; 0122 } 0123 0124 Qt::ItemFlags 0125 Config::flags( const QModelIndex &index ) const 0126 { 0127 if( !index.isValid() ) 0128 return Qt::ItemFlags(); 0129 if( index.row() < 0 || index.row() >= m_providerData.count() ) 0130 return Qt::ItemFlags(); 0131 if( index.column() != 0 ) 0132 return Qt::ItemFlags(); 0133 0134 Qt::ItemFlags flags = Qt::ItemIsUserCheckable | Qt::ItemIsEnabled; 0135 if( !m_providerData.at( index.row() ).online ) 0136 flags |= Qt::ItemIsSelectable; 0137 return flags; 0138 } 0139 0140 void 0141 Config::updateProvider( const QString &id, const QString &name, const QIcon &icon, 0142 bool online, bool enabled ) 0143 { 0144 ProviderData providerData( id, name, icon, online, enabled ); 0145 for( int i = 0; i < m_providerData.count(); i++ ) 0146 { 0147 if( m_providerData.at( i ).id == id ) 0148 { 0149 m_providerData[ i ] = providerData; 0150 m_hasChanged = true; 0151 Q_EMIT dataChanged( index( i ), index( i ) ); 0152 return; 0153 } 0154 } 0155 beginInsertRows( QModelIndex(), m_providerData.count(), m_providerData.count() ); 0156 m_providerData << providerData; 0157 m_hasChanged = true; 0158 endInsertRows(); 0159 } 0160 0161 void 0162 Config::updateProvider( const QString &id, const QString &name, const QIcon &icon, 0163 bool online ) 0164 { 0165 updateProvider( id, name, icon, online, providerEnabled( id, false ) ); 0166 } 0167 0168 bool 0169 Config::forgetProvider( const QString &id ) 0170 { 0171 QMutableListIterator<ProviderData> it( m_providerData ); 0172 int i = 0; 0173 while( it.hasNext() ) 0174 { 0175 if( it.next().id == id ) 0176 { 0177 if( it.value().online ) 0178 continue; // refuse to forget online provider 0179 beginRemoveRows( QModelIndex(), i, i ); 0180 it.remove(); 0181 m_hasChanged = true; 0182 endRemoveRows(); 0183 Q_EMIT providerForgotten( id ); 0184 return true; 0185 } 0186 i++; 0187 } 0188 return false; 0189 } 0190 0191 bool 0192 Config::providerKnown( const QString &id ) const 0193 { 0194 foreach( const ProviderData &data, m_providerData ) 0195 { 0196 if( data.id == id ) 0197 return true; 0198 } 0199 return false; 0200 } 0201 0202 bool 0203 Config::providerEnabled( const QString &id, bool aDefault ) const 0204 { 0205 foreach( const ProviderData &data, m_providerData ) 0206 { 0207 if( data.id == id ) 0208 return data.enabled; 0209 } 0210 return aDefault; 0211 } 0212 0213 bool 0214 Config::providerOnline( const QString &id, bool aDefault ) const 0215 { 0216 foreach( const ProviderData &data, m_providerData ) 0217 { 0218 if( data.id == id ) 0219 return data.online; 0220 } 0221 return aDefault; 0222 } 0223 0224 QIcon 0225 Config::providerIcon( const QString &id ) const 0226 { 0227 foreach( const ProviderData &data, m_providerData ) 0228 { 0229 if( data.id == id ) 0230 return data.icon; 0231 } 0232 return QIcon(); 0233 } 0234 0235 qint64 0236 Config::checkedFields() const 0237 { 0238 return m_checkedFields; 0239 } 0240 0241 void 0242 Config::setCheckedFields( qint64 fields ) 0243 { 0244 m_checkedFields = fields; 0245 m_hasChanged = true; 0246 } 0247 0248 QSet<QString> 0249 Config::excludedLabels() const 0250 { 0251 return m_excludedLabels; 0252 } 0253 0254 void 0255 Config::setExcludedLabels( const QSet<QString> &labels ) 0256 { 0257 m_excludedLabels = labels; 0258 m_hasChanged = true; 0259 } 0260 0261 bool 0262 Config::hasChanged() const 0263 { 0264 return m_hasChanged; 0265 } 0266 0267 void 0268 Config::read() 0269 { 0270 KConfigGroup group = Amarok::config( QStringLiteral("StatSyncing") ); 0271 0272 QStringList providerIds = group.readEntry( "providerIds", QStringList() ); 0273 QStringList providerNames = group.readEntry( "providerNames", QStringList() ); 0274 QList<bool> providerEnabledStatuses = group.readEntry( "providerEnabledStatuses", QList<bool>() ); 0275 int count = qMin( providerIds.count(), providerNames.count() ); 0276 count = qMin( count, providerEnabledStatuses.count() ); 0277 0278 beginResetModel(); 0279 QList<ProviderData> newData; 0280 for( int i = 0; i < count; i++ ) 0281 { 0282 QString id = providerIds.at( i ); 0283 newData << ProviderData( id, providerNames.at( i ), providerIcon( id ), 0284 providerOnline( id ), providerEnabledStatuses.at( i ) ); 0285 } 0286 m_providerData = newData; 0287 endResetModel(); 0288 0289 m_checkedFields = 0; 0290 QStringList fieldNames = group.readEntry( "checkedFields", QStringList( QStringLiteral("FIRST") ) ); 0291 if( fieldNames == QStringList( QStringLiteral("FIRST") ) ) 0292 m_checkedFields = Meta::valRating | Meta::valFirstPlayed | Meta::valLastPlayed | 0293 Meta::valPlaycount | Meta::valLabel; 0294 else 0295 { 0296 foreach( const QString &fieldName, fieldNames ) 0297 m_checkedFields |= Meta::fieldForName( fieldName ); 0298 } 0299 0300 QStringList list = group.readEntry( "excludedLabels", QStringList() ); 0301 QSet<QString> addEntrySet(list.begin(), list.end()); 0302 m_excludedLabels += addEntrySet; 0303 0304 m_hasChanged = false; 0305 } 0306 0307 void 0308 Config::save() 0309 { 0310 QStringList providerIds; 0311 QStringList providerNames; 0312 QList<bool> providerEnabledStatuses; 0313 foreach( const ProviderData &data, m_providerData ) 0314 { 0315 providerIds << data.id; 0316 providerNames << data.name; 0317 providerEnabledStatuses << data.enabled; 0318 } 0319 0320 KConfigGroup group = Amarok::config( QStringLiteral("StatSyncing") ); 0321 group.writeEntry( "providerIds", providerIds ); 0322 group.writeEntry( "providerNames", providerNames ); 0323 group.writeEntry( "providerEnabledStatuses", providerEnabledStatuses ); 0324 0325 // prefer string representation for fwd compatibility and user-readability 0326 QStringList fieldNames; 0327 for( qint64 i = 0; i < 64; i++ ) 0328 { 0329 qint64 field = 1LL << i; 0330 if( field & m_checkedFields ) 0331 fieldNames << Meta::nameForField( field ); 0332 } 0333 group.writeEntry( "checkedFields", fieldNames ); 0334 0335 group.writeEntry( "excludedLabels", m_excludedLabels.values() ); 0336 0337 group.sync(); 0338 m_hasChanged = false; 0339 }