add mp3 and ogg torrent url info to JamendoAlbum
[amarok.git] / src / MediaItem.cpp
blob8517137a02f712e6b989db1796c26ec995c03f45
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"
28 #include <kiconloader.h>
30 #include <QPainter>
32 QPixmap *MediaItem::s_pixUnknown = 0;
33 QPixmap *MediaItem::s_pixArtist = 0;
34 QPixmap *MediaItem::s_pixAlbum = 0;
35 QPixmap *MediaItem::s_pixFile = 0;
36 QPixmap *MediaItem::s_pixTrack = 0;
37 QPixmap *MediaItem::s_pixPodcast = 0;
38 QPixmap *MediaItem::s_pixPlaylist = 0;
39 QPixmap *MediaItem::s_pixInvisible = 0;
40 QPixmap *MediaItem::s_pixStale = 0;
41 QPixmap *MediaItem::s_pixOrphaned = 0;
42 QPixmap *MediaItem::s_pixDirectory = 0;
43 QPixmap *MediaItem::s_pixRootItem = 0;
44 QPixmap *MediaItem::s_pixTransferFailed = 0;
45 QPixmap *MediaItem::s_pixTransferBegin = 0;
46 QPixmap *MediaItem::s_pixTransferEnd = 0;
48 MediaItem::MediaItem( Q3ListView* parent )
49 : K3ListViewItem( parent )
51 init();
54 MediaItem::MediaItem( Q3ListViewItem* parent )
55 : K3ListViewItem( parent )
57 init();
60 MediaItem::MediaItem( Q3ListView* parent, Q3ListViewItem* after )
61 : K3ListViewItem( parent, after )
63 init();
66 MediaItem::MediaItem( Q3ListViewItem* parent, Q3ListViewItem* after )
67 : K3ListViewItem( parent, after )
69 init();
72 MediaItem::~MediaItem()
74 setBundle( 0 );
77 void
78 MediaItem::init()
80 // preload pixmaps used in browser
81 KIconLoader iconLoader;
82 MediaItem::s_pixUnknown = new QPixmap(iconLoader.loadIcon( Amarok::icon( "unknown" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ));
83 MediaItem::s_pixTrack = new QPixmap(iconLoader.loadIcon( Amarok::icon( "playlist" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ));
84 MediaItem::s_pixFile = new QPixmap(iconLoader.loadIcon( Amarok::icon( "sound" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ) );
85 MediaItem::s_pixPodcast = new QPixmap(iconLoader.loadIcon( Amarok::icon( "podcast" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ) );
86 MediaItem::s_pixPlaylist = new QPixmap(iconLoader.loadIcon( Amarok::icon( "playlist" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ) );
87 MediaItem::s_pixRootItem = new QPixmap(iconLoader.loadIcon( Amarok::icon( "files2" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ) );
88 // history
89 // favorites
90 // collection
91 // folder
92 // folder_red
93 // player_playlist_2
94 // cancel
95 // sound
96 MediaItem::s_pixArtist = new QPixmap(iconLoader.loadIcon( Amarok::icon( "personal" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ) );
97 MediaItem::s_pixAlbum = new QPixmap(iconLoader.loadIcon( Amarok::icon( "cdrom_unmount" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ) );
98 MediaItem::s_pixInvisible = new QPixmap(iconLoader.loadIcon( Amarok::icon( "cancel" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ) );
99 MediaItem::s_pixStale = new QPixmap(iconLoader.loadIcon( Amarok::icon( "cancel" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ) );
100 MediaItem::s_pixOrphaned = new QPixmap(iconLoader.loadIcon( Amarok::icon( "cancel" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ) );
101 MediaItem::s_pixDirectory = new QPixmap(iconLoader.loadIcon( Amarok::icon( "folder" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ) );
102 MediaItem::s_pixTransferBegin = new QPixmap(iconLoader.loadIcon( Amarok::icon( "play" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ) );
103 MediaItem::s_pixTransferEnd = new QPixmap(iconLoader.loadIcon( Amarok::icon( "process-stop" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ) );
104 MediaItem::s_pixTransferFailed = new QPixmap(iconLoader.loadIcon( Amarok::icon( "cancel" ), KIconLoader::Toolbar, KIconLoader::SizeSmall ) );
106 m_bundle=0;
107 m_order=0;
108 m_type=UNKNOWN;
109 m_playlistName.clear();
110 m_device=0;
111 m_flags=0;
112 setExpandable( false );
113 setDragEnabled( true );
114 setDropEnabled( true );
117 void
118 MediaItem::setBundle( MetaBundle *bundle )
120 MediaBrowser::instance()->m_itemMapMutex.lock();
121 if( m_bundle )
123 QString itemUrl = url().url();
124 MediaBrowser::ItemMap::iterator it = MediaBrowser::instance()->m_itemMap.find( itemUrl );
125 if( it != MediaBrowser::instance()->m_itemMap.end() && *it == this )
126 MediaBrowser::instance()->m_itemMap.remove( itemUrl );
128 delete m_bundle;
129 m_bundle = bundle;
131 if( m_bundle )
133 QString itemUrl = url().url();
134 MediaBrowser::ItemMap::iterator it = MediaBrowser::instance()->m_itemMap.find( itemUrl );
135 if( it == MediaBrowser::instance()->m_itemMap.end() )
136 MediaBrowser::instance()->m_itemMap[itemUrl] = this;
138 MediaBrowser::instance()->m_itemMapMutex.unlock();
139 createToolTip();
142 void MediaItem::paintCell( QPainter *p, const QColorGroup &cg, int column, int width, int align )
144 switch( type() )
146 case INVISIBLE:
147 case PODCASTSROOT:
148 case PLAYLISTSROOT:
149 case ORPHANEDROOT:
150 case STALEROOT:
152 QFont font( p->font() );
153 font.setBold( true );
154 p->setFont( font );
156 default:
157 break;
160 K3ListViewItem::paintCell( p, cg, column, width, align );
163 const MetaBundle *
164 MediaItem::bundle() const
166 return m_bundle;
169 KUrl
170 MediaItem::url() const
172 if( bundle() )
173 return bundle()->url();
174 else
175 return KUrl();
178 bool
179 MediaItem::isFileBacked() const
181 switch( type() )
183 case ARTIST:
184 case ALBUM:
185 case PODCASTSROOT:
186 case PODCASTCHANNEL:
187 case PLAYLISTSROOT:
188 case PLAYLIST:
189 case PLAYLISTITEM:
190 case INVISIBLEROOT:
191 case STALEROOT:
192 case STALE:
193 case ORPHANEDROOT:
194 return false;
196 case UNKNOWN:
197 case TRACK:
198 case ORPHANED:
199 case INVISIBLE:
200 case PODCASTITEM:
201 case DIRECTORY:
202 return true;
205 return false;
208 void
209 MediaItem::syncStatsFromPath( const QString &url )
211 if( url.isEmpty() )
212 return;
214 // copy Amarok rating, play count and last played time to device
215 int rating = CollectionDB::instance()->getSongRating( url )*10;
216 if( rating )
217 setRating( rating );
218 int playcount = CollectionDB::instance()->getPlayCount( url );
219 if( playcount > played() )
220 setPlayCount( playcount );
221 QDateTime lastplay = CollectionDB::instance()->getLastPlay( url );
222 if( lastplay > playTime() )
223 setLastPlayed( lastplay.toTime_t() );
226 long
227 MediaItem::size() const
229 if( !isFileBacked() )
230 return 0;
232 if( bundle() )
233 return bundle()->filesize();
235 return 0;
238 void
239 MediaItem::setType( Type type )
241 m_type=type;
243 setDragEnabled(true);
244 setDropEnabled(false);
246 switch(m_type)
248 case UNKNOWN:
249 setPixmap(0, *s_pixUnknown);
250 break;
251 case INVISIBLE:
252 case TRACK:
253 setPixmap(0, *s_pixFile);
254 break;
255 case PLAYLISTITEM:
256 setPixmap(0, *s_pixTrack);
257 setDropEnabled(true);
258 break;
259 case ARTIST:
260 setPixmap(0, *s_pixArtist);
261 break;
262 case ALBUM:
263 setPixmap(0, *s_pixAlbum);
264 break;
265 case PODCASTSROOT:
266 setPixmap(0, *s_pixRootItem);
267 break;
268 case PODCASTITEM:
269 case PODCASTCHANNEL:
270 setPixmap(0, *s_pixPodcast);
271 break;
272 case PLAYLIST:
273 setPixmap(0, *s_pixPlaylist);
274 setDropEnabled(true);
275 break;
276 case PLAYLISTSROOT:
277 setPixmap(0, *s_pixRootItem);
278 setDropEnabled( true );
279 break;
280 case INVISIBLEROOT:
281 setPixmap(0, *s_pixInvisible);
282 break;
283 case STALEROOT:
284 case STALE:
285 setPixmap(0, *s_pixStale);
286 break;
287 case ORPHANEDROOT:
288 case ORPHANED:
289 setPixmap(0, *s_pixOrphaned);
290 break;
291 case DIRECTORY:
292 setExpandable( true );
293 setDropEnabled( true );
294 setPixmap(0, *s_pixDirectory);
295 break;
297 createToolTip();
300 void
301 MediaItem::setFailed( bool failed )
303 if( failed )
305 m_flags &= ~MediaItem::Transferring;
306 m_flags |= MediaItem::Failed;
307 setPixmap(0, *MediaItem::s_pixTransferFailed);
309 else
311 m_flags &= ~MediaItem::Failed;
312 if( m_type == PODCASTITEM )
313 setPixmap(0, *s_pixPodcast);
314 else if( m_type == PLAYLIST )
315 setPixmap(0, *s_pixPlaylist);
316 else
317 setPixmap(0, QPixmap() );
321 MediaItem *
322 MediaItem::lastChild() const
324 Q3ListViewItem *last = 0;
325 for( Q3ListViewItem *it = firstChild();
327 it = it->nextSibling() )
329 last = it;
332 return dynamic_cast<MediaItem *>(last);
335 bool
336 MediaItem::isLeafItem() const
338 switch(type())
340 case UNKNOWN:
341 return false;
343 case INVISIBLE:
344 case TRACK:
345 case PODCASTITEM:
346 case PLAYLISTITEM:
347 case STALE:
348 case ORPHANED:
349 return true;
351 case ARTIST:
352 case ALBUM:
353 case PODCASTSROOT:
354 case PODCASTCHANNEL:
355 case PLAYLISTSROOT:
356 case PLAYLIST:
357 case INVISIBLEROOT:
358 case STALEROOT:
359 case ORPHANEDROOT:
360 case DIRECTORY:
361 return false;
364 return false;
367 MediaItem *
368 MediaItem::findItem( const QString &key, const MediaItem *after ) const
370 MediaItem *it = 0;
371 if( after )
372 it = dynamic_cast<MediaItem *>( after->nextSibling() );
373 else
374 it = dynamic_cast<MediaItem *>( firstChild() );
376 for( ; it; it = dynamic_cast<MediaItem *>(it->nextSibling()))
378 if(key == it->text(0))
379 return it;
380 if(key.isEmpty() && it->text(0).isEmpty())
381 return it;
383 return 0;
387 MediaItem::compare( Q3ListViewItem *i, int col, bool ascending ) const
389 MediaItem *item = dynamic_cast<MediaItem *>(i);
390 if(item && col==0 && item->m_order != m_order)
391 return m_order-item->m_order;
392 else if( item && item->type() == MediaItem::ARTIST )
394 QString key1 = key( col, ascending );
395 if( key1.startsWith( "the ", Qt::CaseInsensitive ) )
396 key1 = key1.mid( 4 );
397 QString key2 = i->key( col, ascending );
398 if( key2.startsWith( "the ", Qt::CaseInsensitive ) )
399 key2 = key2.mid( 4 );
401 return key1.localeAwareCompare( key2 );
404 return K3ListViewItem::compare(i, col, ascending);
407 void
408 MediaItem::createToolTip()
410 QString text;
411 switch( type() )
413 case MediaItem::TRACK:
415 const MetaBundle *b = bundle();
416 if( b )
418 if( b->track() )
419 text = QString( "%1 - %2 (%3)" )
420 .arg( QString::number(b->track()), b->title(), b->prettyLength() );
421 if( !b->genre().isEmpty() )
423 if( !text.isEmpty() )
424 text += "<br>";
425 text += QString( "<i>Genre: %1</i>" )
426 .arg( b->genre() );
430 break;
431 case MediaItem::PLAYLISTSROOT:
432 text = i18n( "Drag items here to create new playlist" );
433 break;
434 case MediaItem::PLAYLIST:
435 text = i18n( "Drag items here to append to this playlist" );
436 break;
437 case MediaItem::PLAYLISTITEM:
438 text = i18n( "Drag items here to insert before this item" );
439 break;
440 case MediaItem::INVISIBLEROOT:
441 case MediaItem::INVISIBLE:
442 text = i18n( "Not visible on media device" );
443 break;
444 case MediaItem::STALEROOT:
445 case MediaItem::STALE:
446 text = i18n( "In device database, but file is missing" );
447 break;
448 case MediaItem::ORPHANEDROOT:
449 case MediaItem::ORPHANED:
450 text = i18n( "File on device, but not in device database" );
451 break;
452 default:
453 break;
456 //if( !text.isEmpty() ) setToolTip( text );