Make plasma libs build.
[amarok.git] / src / MediaItem.cpp
blobc46cb47895f08a523daac31e5744ecc283d8f586
1 /* Copyright (C) 2005-2007 Jeff Mitchell <kde-dev@emailgoeshere.com>
2 (c) 2004 Christian Muehlhaeuser <chris@chris.de>
3 (c) 2005-2006 Martin Aumueller <aumuell@reserv.at>
4 (c) 2005 Seb Ruiz <ruiz@kde.org>
5 (c) 2006 T.R.Shashwath <trshash84@gmail.com>
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA.
23 #include "amarok.h"
24 #include "collectiondb.h"
25 #include "mediabrowser.h"
26 #include "MediaItem.h"
27 #include "MetaUtility.h" //Meta::secToPrettyTime
29 #include <kiconloader.h>
31 #include <QPainter>
33 QPixmap *MediaItem::s_pixUnknown = 0;
34 QPixmap *MediaItem::s_pixArtist = 0;
35 QPixmap *MediaItem::s_pixAlbum = 0;
36 QPixmap *MediaItem::s_pixFile = 0;
37 QPixmap *MediaItem::s_pixTrack = 0;
38 QPixmap *MediaItem::s_pixPodcast = 0;
39 QPixmap *MediaItem::s_pixPlaylist = 0;
40 QPixmap *MediaItem::s_pixInvisible = 0;
41 QPixmap *MediaItem::s_pixStale = 0;
42 QPixmap *MediaItem::s_pixOrphaned = 0;
43 QPixmap *MediaItem::s_pixDirectory = 0;
44 QPixmap *MediaItem::s_pixRootItem = 0;
45 QPixmap *MediaItem::s_pixTransferFailed = 0;
46 QPixmap *MediaItem::s_pixTransferBegin = 0;
47 QPixmap *MediaItem::s_pixTransferEnd = 0;
49 MediaItem::MediaItem( Q3ListView* parent )
50 : K3ListViewItem( parent )
52 init();
55 MediaItem::MediaItem( Q3ListViewItem* parent )
56 : K3ListViewItem( parent )
58 init();
61 MediaItem::MediaItem( Q3ListView* parent, Q3ListViewItem* after )
62 : K3ListViewItem( parent, after )
64 init();
67 MediaItem::MediaItem( Q3ListViewItem* parent, Q3ListViewItem* after )
68 : K3ListViewItem( parent, after )
70 init();
73 MediaItem::~MediaItem()
75 // remove this MediaItem from the MediaBrowser's ItemMap
76 setMeta( Meta::DataPtr() );
79 void
80 MediaItem::init()
82 // preload pixmaps used in browser
83 KIconLoader iconLoader;
84 MediaItem::s_pixUnknown = new QPixmap(iconLoader.loadIcon( Amarok::icon( "unknown" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ));
85 MediaItem::s_pixTrack = new QPixmap(iconLoader.loadIcon( Amarok::icon( "playlist" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ));
86 MediaItem::s_pixFile = new QPixmap(iconLoader.loadIcon( Amarok::icon( "sound" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ) );
87 MediaItem::s_pixPodcast = new QPixmap(iconLoader.loadIcon( Amarok::icon( "podcast" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ) );
88 MediaItem::s_pixPlaylist = new QPixmap(iconLoader.loadIcon( Amarok::icon( "playlist" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ) );
89 MediaItem::s_pixRootItem = new QPixmap(iconLoader.loadIcon( Amarok::icon( "files2" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ) );
90 // history
91 // favorites
92 // collection
93 // folder
94 // folder_red
95 // player_playlist_2
96 // cancel
97 // sound
98 MediaItem::s_pixArtist = new QPixmap(iconLoader.loadIcon( Amarok::icon( "personal" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ) );
99 MediaItem::s_pixAlbum = new QPixmap(iconLoader.loadIcon( Amarok::icon( "cdrom_unmount" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ) );
100 MediaItem::s_pixInvisible = new QPixmap(iconLoader.loadIcon( Amarok::icon( "cancel" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ) );
101 MediaItem::s_pixStale = new QPixmap(iconLoader.loadIcon( Amarok::icon( "cancel" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ) );
102 MediaItem::s_pixOrphaned = new QPixmap(iconLoader.loadIcon( Amarok::icon( "cancel" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ) );
103 MediaItem::s_pixDirectory = new QPixmap(iconLoader.loadIcon( Amarok::icon( "folder" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ) );
104 MediaItem::s_pixTransferBegin = new QPixmap(iconLoader.loadIcon( Amarok::icon( "play" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ) );
105 MediaItem::s_pixTransferEnd = new QPixmap(iconLoader.loadIcon( Amarok::icon( "process-stop" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ) );
106 MediaItem::s_pixTransferFailed = new QPixmap(iconLoader.loadIcon( Amarok::icon( "cancel" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ) );
108 m_meta = Meta::DataPtr();
109 m_order=0;
110 m_type=UNKNOWN;
111 m_playlistName.clear();
112 m_device=0;
113 m_flags=0;
114 setExpandable( false );
115 setDragEnabled( true );
116 setDropEnabled( true );
120 void
121 MediaItem::setMeta( Meta::DataPtr meta )
123 //remove from MediaBrowser::ItemMap
124 MediaBrowser::instance()->m_itemMapMutex.lock();
125 if( m_meta )
127 QString itemUrl = url().url();
128 MediaBrowser::ItemMap::iterator it = MediaBrowser::instance()->m_itemMap.find( itemUrl );
129 if( it != MediaBrowser::instance()->m_itemMap.end() && *it == this )
130 MediaBrowser::instance()->m_itemMap.remove( itemUrl );
133 m_meta = meta;
135 //add to MediaBrowser::ItemMap
136 if( m_meta )
138 QString itemUrl = url().url();
139 MediaBrowser::ItemMap::iterator it = MediaBrowser::instance()->m_itemMap.find( itemUrl );
140 if( it == MediaBrowser::instance()->m_itemMap.end() )
141 MediaBrowser::instance()->m_itemMap[itemUrl] = this;
143 MediaBrowser::instance()->m_itemMapMutex.unlock();
145 createToolTip();
148 void MediaItem::paintCell( QPainter *p, const QColorGroup &cg, int column, int width, int align )
150 switch( type() )
152 case INVISIBLE:
153 case PODCASTSROOT:
154 case PLAYLISTSROOT:
155 case ORPHANEDROOT:
156 case STALEROOT:
158 QFont font( p->font() );
159 font.setBold( true );
160 p->setFont( font );
162 default:
163 break;
166 K3ListViewItem::paintCell( p, cg, column, width, align );
170 const Meta::DataPtr
171 MediaItem::meta() const
173 return m_meta;
176 KUrl
177 MediaItem::url() const
179 Meta::TrackPtr track = Meta::TrackPtr::dynamicCast( meta() );
181 if ( track )
182 return track->url();
184 return KUrl();
187 bool
188 MediaItem::isFileBacked() const
190 switch( type() )
192 case ARTIST:
193 case ALBUM:
194 case PODCASTSROOT:
195 case PODCASTCHANNEL:
196 case PLAYLISTSROOT:
197 case PLAYLIST:
198 case PLAYLISTITEM:
199 case INVISIBLEROOT:
200 case STALEROOT:
201 case STALE:
202 case ORPHANEDROOT:
203 return false;
205 case UNKNOWN:
206 case TRACK:
207 case ORPHANED:
208 case INVISIBLE:
209 case PODCASTITEM:
210 case DIRECTORY:
211 return true;
214 return false;
217 void
218 MediaItem::syncStatsFromPath( const QString &url )
220 if( url.isEmpty() )
221 return;
223 // copy Amarok rating, play count and last played time to device
224 int rating = CollectionDB::instance()->getSongRating( url )*10;
225 if( rating )
226 setRating( rating );
227 int playcount = CollectionDB::instance()->getPlayCount( url );
228 if( playcount > played() )
229 setPlayCount( playcount );
230 QDateTime lastplay = CollectionDB::instance()->getLastPlay( url );
231 if( lastplay > playTime() )
232 setLastPlayed( lastplay.toTime_t() );
235 long
236 MediaItem::size() const
238 Meta::TrackPtr track = Meta::TrackPtr::dynamicCast( meta() );
240 if ( track )
241 return track->filesize();
243 return 0;
246 void
247 MediaItem::setType( Type type )
249 m_type=type;
251 setDragEnabled(true);
252 setDropEnabled(false);
254 switch(m_type)
256 case UNKNOWN:
257 setPixmap(0, *s_pixUnknown);
258 break;
259 case INVISIBLE:
260 case TRACK:
261 setPixmap(0, *s_pixFile);
262 break;
263 case PLAYLISTITEM:
264 setPixmap(0, *s_pixTrack);
265 setDropEnabled(true);
266 break;
267 case ARTIST:
268 setPixmap(0, *s_pixArtist);
269 break;
270 case ALBUM:
271 setPixmap(0, *s_pixAlbum);
272 break;
273 case PODCASTSROOT:
274 setPixmap(0, *s_pixRootItem);
275 break;
276 case PODCASTITEM:
277 case PODCASTCHANNEL:
278 setPixmap(0, *s_pixPodcast);
279 break;
280 case PLAYLIST:
281 setPixmap(0, *s_pixPlaylist);
282 setDropEnabled(true);
283 break;
284 case PLAYLISTSROOT:
285 setPixmap(0, *s_pixRootItem);
286 setDropEnabled( true );
287 break;
288 case INVISIBLEROOT:
289 setPixmap(0, *s_pixInvisible);
290 break;
291 case STALEROOT:
292 case STALE:
293 setPixmap(0, *s_pixStale);
294 break;
295 case ORPHANEDROOT:
296 case ORPHANED:
297 setPixmap(0, *s_pixOrphaned);
298 break;
299 case DIRECTORY:
300 setExpandable( true );
301 setDropEnabled( true );
302 setPixmap(0, *s_pixDirectory);
303 break;
305 createToolTip();
308 void
309 MediaItem::setFailed( bool failed )
311 if( failed )
313 m_flags &= ~MediaItem::Transferring;
314 m_flags |= MediaItem::Failed;
315 setPixmap(0, *MediaItem::s_pixTransferFailed);
317 else
319 m_flags &= ~MediaItem::Failed;
320 if( m_type == PODCASTITEM )
321 setPixmap(0, *s_pixPodcast);
322 else if( m_type == PLAYLIST )
323 setPixmap(0, *s_pixPlaylist);
324 else
325 setPixmap(0, QPixmap() );
329 MediaItem *
330 MediaItem::lastChild() const
332 Q3ListViewItem *last = 0;
333 for( Q3ListViewItem *it = firstChild();
335 it = it->nextSibling() )
337 last = it;
340 return dynamic_cast<MediaItem *>(last);
343 bool
344 MediaItem::isLeafItem() const
346 switch(type())
348 case UNKNOWN:
349 return false;
351 case INVISIBLE:
352 case TRACK:
353 case PODCASTITEM:
354 case PLAYLISTITEM:
355 case STALE:
356 case ORPHANED:
357 return true;
359 case ARTIST:
360 case ALBUM:
361 case PODCASTSROOT:
362 case PODCASTCHANNEL:
363 case PLAYLISTSROOT:
364 case PLAYLIST:
365 case INVISIBLEROOT:
366 case STALEROOT:
367 case ORPHANEDROOT:
368 case DIRECTORY:
369 return false;
372 return false;
375 MediaItem *
376 MediaItem::findItem( const QString &key, const MediaItem *after ) const
378 MediaItem *it = 0;
379 if( after )
380 it = dynamic_cast<MediaItem *>( after->nextSibling() );
381 else
382 it = dynamic_cast<MediaItem *>( firstChild() );
384 for( ; it; it = dynamic_cast<MediaItem *>(it->nextSibling()))
386 if(key == it->text(0))
387 return it;
388 if(key.isEmpty() && it->text(0).isEmpty())
389 return it;
391 return 0;
395 MediaItem::compare( Q3ListViewItem *i, int col, bool ascending ) const
397 MediaItem *item = dynamic_cast<MediaItem *>(i);
398 if(item && col==0 && item->m_order != m_order)
399 return m_order-item->m_order;
400 else if( item && item->type() == MediaItem::ARTIST )
402 QString key1 = key( col, ascending );
403 if( key1.startsWith( "the ", Qt::CaseInsensitive ) )
404 key1 = key1.mid( 4 );
405 QString key2 = i->key( col, ascending );
406 if( key2.startsWith( "the ", Qt::CaseInsensitive ) )
407 key2 = key2.mid( 4 );
409 return key1.localeAwareCompare( key2 );
412 return K3ListViewItem::compare(i, col, ascending);
415 void
416 MediaItem::createToolTip()
418 QString text;
419 switch( type() )
421 case MediaItem::TRACK:
423 Meta::TrackPtr track = Meta::TrackPtr::dynamicCast(meta());
424 if (track)
426 if ( track->trackNumber() )
427 text = QString( "%1 - %2 (%3)" )
428 .arg( QString::number(track->trackNumber()), track->name(), Meta::secToPrettyTime(track->length()) );
429 if( track->genre() )
431 if( !text.isEmpty() )
432 text += "<br>";
433 text += QString( "<i>Genre: %1</i>" )
434 .arg( track->genre()->name() );
438 break;
439 case MediaItem::PLAYLISTSROOT:
440 text = i18n( "Drag items here to create new playlist" );
441 break;
442 case MediaItem::PLAYLIST:
443 text = i18n( "Drag items here to append to this playlist" );
444 break;
445 case MediaItem::PLAYLISTITEM:
446 text = i18n( "Drag items here to insert before this item" );
447 break;
448 case MediaItem::INVISIBLEROOT:
449 case MediaItem::INVISIBLE:
450 text = i18n( "Not visible on media device" );
451 break;
452 case MediaItem::STALEROOT:
453 case MediaItem::STALE:
454 text = i18n( "In device database, but file is missing" );
455 break;
456 case MediaItem::ORPHANEDROOT:
457 case MediaItem::ORPHANED:
458 text = i18n( "File on device, but not in device database" );
459 break;
460 default:
461 break;
464 //if( !text.isEmpty() ) setToolTip( text );