File indexing completed on 2024-05-05 04:48:30
0001 /**************************************************************************************** 0002 * Copyright (c) 2008 Daniel Caleb Jones <danielcjones@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) 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 #include "TrackSet.h" 0020 0021 #include "core/collections/Collection.h" 0022 #include "core/meta/Meta.h" 0023 #include "core/support/Debug.h" 0024 0025 #include <QRandomGenerator> 0026 0027 Dynamic::TrackCollection::TrackCollection( const QStringList& uids ) 0028 { 0029 m_uids = uids; 0030 for( int i = 0; i < m_uids.count(); i++ ) 0031 m_ids.insert( m_uids[i], i ); 0032 } 0033 0034 int 0035 Dynamic::TrackCollection::count() const 0036 { 0037 return m_uids.count(); 0038 } 0039 0040 QStringList 0041 Dynamic::TrackCollection::uids() const 0042 { 0043 return m_uids; 0044 } 0045 0046 Dynamic::TrackSet::TrackSet() 0047 : m_bits() 0048 , m_collection( nullptr ) 0049 { } 0050 0051 Dynamic::TrackSet::TrackSet( const TrackSet& other ) 0052 : m_bits( other.m_bits ) 0053 , m_collection( other.m_collection ) 0054 { } 0055 0056 Dynamic::TrackSet::TrackSet( const Dynamic::TrackCollectionPtr &collection, bool value ) 0057 : m_bits( collection->count(), value ) 0058 , m_collection( collection ) 0059 {} 0060 0061 void 0062 Dynamic::TrackSet::reset( bool value ) 0063 { 0064 m_bits.fill( value ); 0065 } 0066 0067 bool 0068 Dynamic::TrackSet::isOutstanding() const 0069 { 0070 return !m_collection; 0071 } 0072 0073 int 0074 Dynamic::TrackSet::trackCount() const 0075 { 0076 return m_bits.count(true); 0077 } 0078 0079 bool 0080 Dynamic::TrackSet::isEmpty() const 0081 { 0082 return m_bits.count(false) == m_bits.count(); 0083 } 0084 0085 bool 0086 Dynamic::TrackSet::isFull() const 0087 { 0088 return m_bits.count(true) == m_bits.count(); 0089 } 0090 0091 bool 0092 Dynamic::TrackSet::contains( const QString &uid ) const 0093 { 0094 if( !m_collection ) 0095 return false; 0096 0097 if( !m_collection->m_ids.contains( uid ) ) 0098 return false; 0099 0100 int index = m_collection->m_ids.value( uid ); 0101 return m_bits.at( index ); 0102 } 0103 0104 bool 0105 Dynamic::TrackSet::contains( const Meta::TrackPtr& B ) const 0106 { 0107 if( !m_collection ) 0108 return false; 0109 if( !B ) 0110 return false; 0111 0112 QString str = B->uidUrl(); 0113 if( !m_collection->m_ids.contains( str ) ) 0114 return false; 0115 0116 int index = m_collection->m_ids.value( str ); 0117 return m_bits.at( index ); 0118 } 0119 0120 QString 0121 Dynamic::TrackSet::getRandomTrack() const 0122 { 0123 if( !m_collection ) 0124 return QString(); 0125 0126 int count = trackCount(); 0127 if( count == 0 ) 0128 return QString(); 0129 0130 // stupid that I have to go through the set like this... 0131 int trackNr = QRandomGenerator::global()->generate() % count; 0132 for( int i = m_bits.size()-1; i>=0; i-- ) 0133 { 0134 if( m_bits.at(i) ) 0135 { 0136 if( trackNr ) 0137 trackNr--; 0138 else 0139 { 0140 return m_collection->m_uids.at(i); 0141 } 0142 } 0143 } 0144 0145 return QString(); 0146 } 0147 0148 void 0149 Dynamic::TrackSet::unite( const Meta::TrackPtr& B ) 0150 { 0151 if( !m_collection ) 0152 return; 0153 if( !B ) 0154 return; 0155 0156 QString str = B->uidUrl(); 0157 if( !m_collection->m_ids.contains( str ) ) { 0158 warning() << "TrackSet::subtract called for a track not even known to the collection. Track uid is"<<str<<"example from collection"<<m_collection->m_ids.keys().first(); 0159 return; 0160 } 0161 0162 int index = m_collection->m_ids.value( str ); 0163 m_bits.setBit( index ); 0164 } 0165 0166 void 0167 Dynamic::TrackSet::unite( const Dynamic::TrackSet& B ) 0168 { 0169 m_bits |= B.m_bits; 0170 } 0171 0172 void 0173 Dynamic::TrackSet::unite( const QStringList& B ) 0174 { 0175 if( !m_collection ) 0176 return; 0177 0178 foreach( const QString &str, B ) 0179 { 0180 if( !m_collection->m_ids.contains( str ) ) 0181 continue; 0182 0183 int index = m_collection->m_ids.value( str ); 0184 m_bits.setBit( index ); 0185 } 0186 } 0187 0188 void 0189 Dynamic::TrackSet::intersect( const Dynamic::TrackSet& B ) 0190 { 0191 m_bits &= B.m_bits; 0192 } 0193 0194 void 0195 Dynamic::TrackSet::intersect( const QStringList& B ) 0196 { 0197 if( !m_collection ) 0198 return; 0199 0200 QBitArray bBits( m_bits.count() ); 0201 foreach( const QString &str, B ) 0202 { 0203 if( !m_collection->m_ids.contains( str ) ) 0204 continue; 0205 0206 int index = m_collection->m_ids.value( str ); 0207 bBits.setBit( index ); 0208 } 0209 0210 m_bits &= bBits; 0211 } 0212 0213 void 0214 Dynamic::TrackSet::subtract( const Meta::TrackPtr& B ) 0215 { 0216 if( !m_collection ) 0217 return; 0218 if( !B ) 0219 return; 0220 0221 QString str = B->uidUrl(); 0222 if( !m_collection->m_ids.contains( str ) ) 0223 { 0224 // that seems to happen. e.g. for tracks from the file collection 0225 warning() << "TrackSet::subtract called for a track not even known to the collection. "<< 0226 "Track uid is"<<str<< 0227 "example from collection"<<(m_collection->m_ids.isEmpty()?QStringLiteral("no example"):QString(m_collection->m_ids.keys().first()))<< 0228 "track is from collection"<<(B->collection()?B->collection()->collectionId():QStringLiteral("no collection")); 0229 return; 0230 } 0231 0232 int index = m_collection->m_ids.value( str ); 0233 m_bits.clearBit( index ); 0234 } 0235 0236 void 0237 Dynamic::TrackSet::subtract( const Dynamic::TrackSet& B ) 0238 { 0239 m_bits |= B.m_bits; 0240 m_bits ^= B.m_bits; 0241 } 0242 0243 void 0244 Dynamic::TrackSet::subtract( const QStringList& B ) 0245 { 0246 if( !m_collection ) 0247 return; 0248 0249 foreach( const QString &str, B ) 0250 { 0251 if( !m_collection->m_ids.contains( str ) ) 0252 continue; 0253 0254 int index = m_collection->m_ids.value( str ); 0255 m_bits.clearBit( index ); 0256 } 0257 } 0258 0259 0260 0261 0262 Dynamic::TrackSet& 0263 Dynamic::TrackSet::operator=( const Dynamic::TrackSet& B ) 0264 { 0265 m_bits = B.m_bits; 0266 m_collection = B.m_collection; 0267 return *this; 0268 } 0269 0270 0271