Warning, file /multimedia/amarok/src/browsers/CollectionTreeItem.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /**************************************************************************************** 0002 * Copyright (c) 2007 Alexandre Pereira de Oliveira <aleprj@gmail.com> * 0003 * Copyright (c) 2007-2009 Maximilian Kossick <maximilian.kossick@googlemail.com> * 0004 * Copyright (c) 2009 Seb Ruiz <ruiz@kde.org> * 0005 * * 0006 * This program is free software; you can redistribute it and/or modify it under * 0007 * the terms of the GNU General Public License as published by the Free Software * 0008 * Foundation; either version 2 of the License, or (at your option) any later * 0009 * version. * 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 "CollectionTreeItem.h" 0020 0021 #include "amarokconfig.h" 0022 #include "browsers/CollectionTreeItemModelBase.h" 0023 #include "core/capabilities/ActionsCapability.h" 0024 #include "core/meta/Meta.h" 0025 #include "core/support/Debug.h" 0026 #include "widgets/PrettyTreeRoles.h" 0027 0028 #include <QIcon> 0029 #include <KLocalizedString> 0030 0031 Q_DECLARE_METATYPE( QAction* ) 0032 Q_DECLARE_METATYPE( QList<QAction*> ) 0033 0034 CollectionTreeItem::CollectionTreeItem( CollectionTreeItemModelBase *model ) 0035 : m_data( nullptr ) 0036 , m_parent( nullptr ) 0037 , m_model( model ) 0038 , m_parentCollection( nullptr ) 0039 , m_updateRequired( false ) 0040 , m_trackCount( -1 ) 0041 , m_type( Root ) 0042 //, m_name( "Root" ) 0043 , m_isCounting( false ) 0044 { 0045 } 0046 0047 CollectionTreeItem::CollectionTreeItem( const Meta::DataPtr &data, CollectionTreeItem *parent, CollectionTreeItemModelBase *model ) 0048 : m_data( data ) 0049 , m_parent( parent ) 0050 , m_model( model ) 0051 , m_parentCollection( nullptr ) 0052 , m_updateRequired( true ) 0053 , m_trackCount( -1 ) 0054 , m_type( Data ) 0055 //, m_name( data ? data->name() : "NullData" ) 0056 , m_isCounting( false ) 0057 { 0058 if ( m_parent ) 0059 m_parent->appendChild( this ); 0060 } 0061 0062 CollectionTreeItem::CollectionTreeItem( Collections::Collection *parentCollection, CollectionTreeItem *parent, CollectionTreeItemModelBase *model ) 0063 : m_data( nullptr ) 0064 , m_parent( parent ) 0065 , m_model( model ) 0066 , m_parentCollection( parentCollection ) 0067 , m_updateRequired( true ) 0068 , m_trackCount( -1 ) 0069 , m_type( Collection ) 0070 //, m_name( parentCollection ? parentCollection->collectionId() : "NullColl" ) 0071 , m_isCounting( false ) 0072 { 0073 if ( m_parent ) 0074 m_parent->appendChild( this ); 0075 0076 connect( parentCollection, &Collections::Collection::updated, this, &CollectionTreeItem::collectionUpdated ); 0077 } 0078 0079 CollectionTreeItem::CollectionTreeItem( Type type, const Meta::DataList &data, CollectionTreeItem *parent, CollectionTreeItemModelBase *model ) 0080 : m_data( nullptr ) 0081 , m_parent( parent ) 0082 , m_model( model ) 0083 , m_parentCollection( nullptr ) 0084 , m_updateRequired( false ) //the node already has all children 0085 , m_trackCount( -1 ) 0086 , m_type( type ) 0087 , m_isCounting( false ) 0088 { 0089 if( m_parent ) 0090 m_parent->m_childItems.insert( 0, this ); 0091 0092 foreach( Meta::DataPtr datap, data ) 0093 new CollectionTreeItem( datap, this, m_model ); 0094 } 0095 0096 CollectionTreeItem::~CollectionTreeItem() 0097 { 0098 qDeleteAll( m_childItems ); 0099 } 0100 0101 void 0102 CollectionTreeItem::appendChild(CollectionTreeItem *child) 0103 { 0104 m_childItems.append(child); 0105 } 0106 0107 void 0108 CollectionTreeItem::removeChild( int index ) 0109 { 0110 CollectionTreeItem *child = m_childItems[index]; 0111 m_childItems.removeAt( index ); 0112 child->prepareForRemoval(); 0113 child->deleteLater(); 0114 } 0115 0116 void 0117 CollectionTreeItem::prepareForRemoval() 0118 { 0119 m_parent = nullptr; 0120 m_model->itemAboutToBeDeleted( this ); 0121 foreach( CollectionTreeItem *item, m_childItems ) 0122 { 0123 item->prepareForRemoval(); 0124 } 0125 } 0126 0127 CollectionTreeItem* 0128 CollectionTreeItem::child( int row ) 0129 { 0130 return m_childItems.value( row ); 0131 } 0132 0133 QVariant 0134 CollectionTreeItem::data( int role ) const 0135 { 0136 if( isNoLabelItem() ) 0137 { 0138 switch( role ) 0139 { 0140 case Qt::DisplayRole: 0141 return i18nc( "No labels are assigned to the given item are any of its subitems", "No Labels" ); 0142 case Qt::DecorationRole: 0143 return QIcon::fromTheme( QStringLiteral("label-amarok") ); 0144 } 0145 return QVariant(); 0146 } 0147 else if( m_parentCollection ) 0148 { 0149 static const QString counting = i18n( "Counting..." ); 0150 switch( role ) 0151 { 0152 case Qt::DisplayRole: 0153 case PrettyTreeRoles::FilterRole: 0154 case PrettyTreeRoles::SortRole: 0155 return m_parentCollection->prettyName(); 0156 case Qt::DecorationRole: 0157 return m_parentCollection->icon(); 0158 case PrettyTreeRoles::ByLineRole: 0159 if( m_isCounting ) 0160 return counting; 0161 if( m_trackCount < 0 ) 0162 { 0163 m_isCounting = true; 0164 0165 Collections::QueryMaker *qm = m_parentCollection->queryMaker(); 0166 connect( qm, &Collections::QueryMaker::newResultReady, 0167 this, &CollectionTreeItem::tracksCounted ); 0168 0169 qm->setAutoDelete( true ) 0170 ->setQueryType( Collections::QueryMaker::Custom ) 0171 ->addReturnFunction( Collections::QueryMaker::Count, Meta::valUrl ) 0172 ->run(); 0173 0174 return counting; 0175 } 0176 return i18np( "1 track", "%1 tracks", m_trackCount ); 0177 case PrettyTreeRoles::HasCapacityRole: 0178 return m_parentCollection->hasCapacity(); 0179 case PrettyTreeRoles::UsedCapacityRole: 0180 return m_parentCollection->usedCapacity(); 0181 case PrettyTreeRoles::TotalCapacityRole: 0182 return m_parentCollection->totalCapacity(); 0183 case PrettyTreeRoles::DecoratorRoleCount: 0184 return decoratorActions().size(); 0185 case PrettyTreeRoles::DecoratorRole: 0186 QVariant v; 0187 v.setValue( decoratorActions() ); 0188 return v; 0189 } 0190 } 0191 return QVariant(); 0192 } 0193 0194 QList<QAction*> 0195 CollectionTreeItem::decoratorActions() const 0196 { 0197 QList<QAction*> decoratorActions; 0198 QScopedPointer<Capabilities::ActionsCapability> dc( m_parentCollection->create<Capabilities::ActionsCapability>() ); 0199 if( dc ) 0200 decoratorActions = dc->actions(); 0201 return decoratorActions; 0202 } 0203 0204 void 0205 CollectionTreeItem::tracksCounted( QStringList res ) 0206 { 0207 if( !res.isEmpty() ) 0208 m_trackCount = res.first().toInt(); 0209 else 0210 m_trackCount = 0; 0211 m_isCounting = false; 0212 Q_EMIT dataUpdated(); 0213 } 0214 0215 void 0216 CollectionTreeItem::collectionUpdated() 0217 { 0218 m_trackCount = -1; 0219 } 0220 0221 int 0222 CollectionTreeItem::row() const 0223 { 0224 if( m_parent ) 0225 { 0226 const QList<CollectionTreeItem*> &children = m_parent->m_childItems; 0227 if( !children.isEmpty() && children.contains( const_cast<CollectionTreeItem*>(this) ) ) 0228 return children.indexOf( const_cast<CollectionTreeItem*>(this) ); 0229 else 0230 return -1; 0231 } 0232 return 0; 0233 } 0234 0235 int 0236 CollectionTreeItem::level() const 0237 { 0238 if( m_parent ) 0239 return m_parent->level() + 1; 0240 return -1; 0241 } 0242 0243 bool 0244 CollectionTreeItem::isDataItem() const 0245 { 0246 return m_type == Data; 0247 } 0248 0249 bool 0250 CollectionTreeItem::isVariousArtistItem() const 0251 { 0252 return m_type == CollectionTreeItem::VariousArtist; 0253 } 0254 0255 bool 0256 CollectionTreeItem::isNoLabelItem() const 0257 { 0258 return m_type == CollectionTreeItem::NoLabel; 0259 } 0260 0261 bool 0262 CollectionTreeItem::isAlbumItem() const 0263 { 0264 return m_type == Data && !Meta::AlbumPtr::dynamicCast( m_data ).isNull(); 0265 } 0266 0267 bool 0268 CollectionTreeItem::isTrackItem() const 0269 { 0270 return m_type == Data && !Meta::TrackPtr::dynamicCast( m_data ).isNull(); 0271 } 0272 0273 Collections::QueryMaker* 0274 CollectionTreeItem::queryMaker() const 0275 { 0276 Collections::Collection* coll = parentCollection(); 0277 if( coll ) 0278 return coll->queryMaker(); 0279 return nullptr; 0280 } 0281 0282 void 0283 CollectionTreeItem::addMatch( Collections::QueryMaker *qm, CategoryId::CatMenuId levelCategory ) const 0284 { 0285 if( !qm ) 0286 return; 0287 0288 if( isVariousArtistItem() ) 0289 qm->setAlbumQueryMode( Collections::QueryMaker::OnlyCompilations ); 0290 if( isNoLabelItem() ) 0291 qm->setLabelQueryMode( Collections::QueryMaker::OnlyWithoutLabels ); 0292 else if( Meta::TrackPtr track = Meta::TrackPtr::dynamicCast( m_data ) ) 0293 qm->addMatch( track ); 0294 else if( Meta::ArtistPtr artist = Meta::ArtistPtr::dynamicCast( m_data ) ) 0295 { 0296 Collections::QueryMaker::ArtistMatchBehaviour behaviour = 0297 ( levelCategory == CategoryId::AlbumArtist ) ? Collections::QueryMaker::AlbumArtists : 0298 Collections::QueryMaker::TrackArtists; 0299 qm->addMatch( artist, behaviour ); 0300 } 0301 else if( Meta::AlbumPtr album = Meta::AlbumPtr::dynamicCast( m_data ) ) 0302 qm->addMatch( album ); 0303 else if( Meta::ComposerPtr composer = Meta::ComposerPtr::dynamicCast( m_data ) ) 0304 qm->addMatch( composer ); 0305 else if( Meta::GenrePtr genre = Meta::GenrePtr::dynamicCast( m_data ) ) 0306 qm->addMatch( genre ); 0307 else if( Meta::YearPtr year = Meta::YearPtr::dynamicCast( m_data ) ) 0308 qm->addMatch( year ); 0309 else if( Meta::LabelPtr label = Meta::LabelPtr::dynamicCast( m_data ) ) 0310 qm->addMatch( label ); 0311 } 0312 0313 0314 QList<QUrl> 0315 CollectionTreeItem::urls() const 0316 { 0317 /*QueryBuilder qb = queryBuilder(); 0318 qb.addReturnValue( QueryBuilder::tabSong, QueryBuilder::valURL ); 0319 QStringList values = qb.run(); 0320 QList<QUrl> list; 0321 foreach( QString s, values ) { 0322 list += QUrl( s ); 0323 } 0324 return list;*/ 0325 QList<QUrl> list; 0326 return list; 0327 } 0328 0329 bool 0330 CollectionTreeItem::operator<( const CollectionTreeItem& other ) const 0331 { 0332 if( isVariousArtistItem() ) 0333 return true; 0334 return m_data->sortableName() < other.m_data->sortableName(); 0335 } 0336 0337 const Meta::DataPtr 0338 CollectionTreeItem::data() const 0339 { 0340 return m_data; 0341 } 0342 0343 Meta::TrackList 0344 CollectionTreeItem::descendentTracks() 0345 { 0346 QList<Meta::TrackPtr> descendentTracks; 0347 Meta::TrackPtr track; 0348 if( isDataItem() ) 0349 track = Meta::TrackPtr::dynamicCast( m_data ); 0350 0351 if( !track.isNull() ) 0352 descendentTracks << track; 0353 else 0354 { 0355 foreach( CollectionTreeItem *child, m_childItems ) 0356 descendentTracks << child->descendentTracks(); 0357 } 0358 return descendentTracks; 0359 } 0360 0361 bool 0362 CollectionTreeItem::allDescendentTracksLoaded() const 0363 { 0364 if( isTrackItem() ) 0365 return true; 0366 0367 if( requiresUpdate() ) 0368 return false; 0369 0370 foreach( CollectionTreeItem *item, m_childItems ) 0371 { 0372 if( !item->allDescendentTracksLoaded() ) 0373 return false; 0374 } 0375 return true; 0376 } 0377 0378 void 0379 CollectionTreeItem::setRequiresUpdate( bool updateRequired ) 0380 { 0381 m_updateRequired = updateRequired; 0382 } 0383 0384 bool 0385 CollectionTreeItem::requiresUpdate() const 0386 { 0387 return m_updateRequired; 0388 } 0389 0390 CollectionTreeItem::Type 0391 CollectionTreeItem::type() const 0392 { 0393 return m_type; 0394 } 0395 0396 QList<CollectionTreeItem*> 0397 CollectionTreeItem::children() const 0398 { 0399 return m_childItems; 0400 } 0401 0402