128
131
bundle->setPath ( path );
129
132
bundle->setFilesize ( track->size );
134
QString rss( track->podcastrss );
135
QString url( track->podcasturl );
136
QString desc( track->description );
137
QString subtitle( track->subtitle );
139
date.setTime_t( itdb_time_mac_to_host( track->time_released) );
141
if( !rss.isEmpty() || !url.isEmpty() )
143
PodcastEpisodeBundle peb( KURL::fromPathOrURL(url), KURL::fromPathOrURL(rss),
144
track->title, track->artist, desc, date.toString(Qt::ISODate), QString::null /*type*/,
145
bundle->length(), QString::null /*guid*/, track->playcount<=0 );
146
bundle->setPodcastBundle( peb );
131
149
setBundle( bundle );
149
167
bool ratingChanged() const { return m_track ? m_track->rating != m_track->app_rating : false; }
169
void setListened( bool l )
171
MediaItem::setListened( l );
172
if( type() == PODCASTITEM )
175
m_podcastInfo->listened = listened();
176
#ifdef HAVE_ITDB_MARK_UNPLAYED
178
m_track->mark_unplayed = listened() ? 0x01 : 0x02;
151
183
QDateTime playTime() const
233
IpodMediaDevice::insertTrackIntoDB( const QString &pathname, const MetaBundle &bundle, const PodcastInfo *podcastInfo )
265
IpodMediaDevice::insertTrackIntoDB( const QString &pathname,
266
const MetaBundle &metaBundle, const MetaBundle &propertiesBundle,
267
const PodcastInfo *podcastInfo )
235
return updateTrackInDB( 0, pathname, bundle, podcastInfo );
269
return updateTrackInDB( 0, pathname, metaBundle, propertiesBundle, podcastInfo );
239
273
IpodMediaDevice::updateTrackInDB( IpodMediaItem *item, const QString &pathname,
240
const MetaBundle &bundle, const PodcastInfo *podcastInfo )
274
const MetaBundle &metaBundle, const MetaBundle &propertiesBundle,
275
const PodcastInfo *podcastInfo )
258
293
track->ipod_path = g_strdup( ipodPath(pathname).latin1() );
259
294
debug() << "on iPod: " << track->ipod_path << ", podcast=" << podcastInfo << endl;
261
track->title = g_strdup( bundle.title().utf8() );
262
track->album = g_strdup( bundle.album()->utf8() );
263
track->artist = g_strdup( bundle.artist()->utf8() );
264
track->genre = g_strdup( bundle.genre()->utf8() );
296
if( metaBundle.isValidMedia() || !metaBundle.title().isEmpty() )
297
track->title = g_strdup( metaBundle.title().utf8() );
299
track->title = g_strdup( metaBundle.url().filename().utf8() );
300
track->album = g_strdup( metaBundle.album()->utf8() );
301
track->artist = g_strdup( metaBundle.artist()->utf8() );
302
track->genre = g_strdup( metaBundle.genre()->utf8() );
265
305
track->unk208 = 0x01; // for audio
284
324
track->flag3 |= 0x01; // remember current position in track
326
track->unk208 = 0x08; // for audiobooks
287
else if(type=="m4v" || type=="mp4v" || type=="mov" || type=="mpg")
328
else if(type=="m4v" || type=="mp4v" || type=="mov" || type=="mpg" || type=="mp4")
289
330
track->filetype = g_strdup( "m4v video" );
290
331
#ifdef HAVE_ITDB_SKIP_SHUFFLE_FLAG
301
342
track->flag3 |= 0x01; // remember current position in track
344
track->unk208 = 0x08; // for audiobooks
304
TagLib::Audible::File f( QFile::encodeName( bundle.url().path() ) );
346
TagLib::Audible::File f( QFile::encodeName( propertiesBundle.url().path() ) );
305
347
TagLib::Audible::Tag *t = f.getAudibleTag();
307
349
track->drm_userid = t->userID();
314
356
track->filetype = g_strdup( type.utf8() );
317
track->composer = g_strdup( bundle.composer()->utf8() );
318
track->comment = g_strdup( bundle.comment()->utf8() );
319
track->track_nr = bundle.track();
320
track->cd_nr = bundle.discNumber();
321
track->BPM = static_cast<int>( bundle.bpm() );
322
track->year = bundle.year();
323
track->size = bundle.filesize();
359
track->composer = g_strdup( metaBundle.composer()->utf8() );
360
track->comment = g_strdup( metaBundle.comment()->utf8() );
361
track->track_nr = metaBundle.track();
362
track->cd_nr = metaBundle.discNumber();
363
track->BPM = static_cast<int>( metaBundle.bpm() );
364
track->year = metaBundle.year();
365
track->size = propertiesBundle.filesize();
324
366
if( track->size == 0 )
326
368
debug() << "filesize is zero for " << track->ipod_path << ", expect strange problems with your ipod" << endl;
328
track->bitrate = bundle.bitrate();
329
track->samplerate = bundle.sampleRate();
330
track->tracklen = bundle.length()*1000;
370
track->bitrate = propertiesBundle.bitrate();
371
track->samplerate = propertiesBundle.sampleRate();
372
track->tracklen = propertiesBundle.length()*1000;
334
376
#ifdef HAVE_ITDB_SKIP_SHUFFLE_FLAG
335
377
track->skip_when_shuffling = 0x01; // skip when shuffling
336
378
track->remember_playback_position = 0x01; // remember playback position
337
track->mark_unplayed = 0x02; // for podcasts
339
380
track->flag2 = 0x01; // skip when shuffling
340
381
track->flag3 = 0x01; // remember playback position
341
382
// FIXME: track->unk176 = 0x00020000; // for podcasts
384
#ifdef HAVE_ITDB_MARK_UNPLAYED
385
track->mark_unplayed = podcastInfo->listened ? 0x01 : 0x02;
387
track->unk208 = track->unk208==0x02 ? 0x06 : 0x04; // video or audio podcast
343
388
track->flag4 = 0x01; // also show description on iPod
344
389
QString plaindesc = podcastInfo->description;
345
390
plaindesc.replace( QRegExp("<[^>]*>"), "" );
371
416
if( m_supportsArtwork )
374
if( bundle.podcastBundle() )
419
if( metaBundle.podcastBundle() )
376
421
PodcastChannelBundle pcb;
377
if( CollectionDB::instance()->getPodcastChannelBundle( bundle.podcastBundle()->parent(), &pcb ) )
422
if( CollectionDB::instance()->getPodcastChannelBundle( metaBundle.podcastBundle()->parent(), &pcb ) )
378
423
image = CollectionDB::instance()->podcastImage( pcb.imageURL().url(), 0 );
380
425
if( image.isEmpty() )
381
image = CollectionDB::instance()->albumImage(bundle.artist(), bundle.album(), false, 0);
426
image = CollectionDB::instance()->albumImage(metaBundle.artist(), metaBundle.album(), false, 0);
382
427
if( !image.endsWith( "@nocover.png" ) )
384
debug() << "adding image " << image << " to " << bundle.artist() << ":" << bundle.album() << endl;
429
debug() << "adding image " << image << " to " << metaBundle.artist() << ":" << metaBundle.album() << endl;
385
430
itdb_track_set_thumbnails( track, g_strdup( QFile::encodeName(image) ) );
485
530
podcastInfo->author = peb->author();
486
531
podcastInfo->rss = peb->parent().url();
487
532
podcastInfo->date = peb->dateTime();
533
podcastInfo->listened = !peb->isNew();
490
MetaBundle *newBundle = 0;
491
if( bundle.url().isLocalFile() && !bundle.isValidMedia() )
492
newBundle = new MetaBundle( url );
494
MediaItem *ret = insertTrackIntoDB( url.path(), newBundle ? *newBundle : bundle, podcastInfo );
536
MetaBundle propertiesBundle( url );
537
MediaItem *ret = insertTrackIntoDB( url.path(), bundle, propertiesBundle, podcastInfo );
495
538
delete podcastInfo;
500
543
IpodMediaDevice::tagsChanged( MediaItem *item, const MetaBundle &bundle )
502
return updateTrackInDB( dynamic_cast<IpodMediaItem *>(item), item->url().path(), bundle, NULL );
545
return updateTrackInDB( dynamic_cast<IpodMediaItem *>(item), item->url().path(), bundle, bundle, NULL );
860
904
if( !writeITunesDB( false ) )
863
amaroK::StatusBar::instance()->longMessage(
907
Amarok::StatusBar::instance()->longMessage(
864
908
i18n("Media Device: Initialized iPod mounted at %1").arg(mountPoint()),
865
909
KDE::StatusBar::Information );
888
932
// try to find a mounted ipod
889
933
bool ipodFound = false;
934
bool canInitialize = false;
890
935
KMountPoint::List currentmountpoints = KMountPoint::currentMountPoints();
891
936
for( KMountPoint::List::Iterator mountiter = currentmountpoints.begin();
892
937
mountiter != currentmountpoints.end();
940
canInitialize = false;
895
941
QString devicenode = (*mountiter)->mountedFrom();
896
942
QString mountpoint = (*mountiter)->mountPoint();
944
if( mountpoint.startsWith( "/proc" ) ||
945
mountpoint.startsWith( "/sys" ) ||
946
mountpoint.startsWith( "/dev" ) ||
947
mountpoint.startsWith( "/boot" ) )
898
950
if( !mountPoint().isEmpty() )
900
if( mountPoint() != mountpoint )
952
if( mountpoint != mountPoint() )
954
canInitialize = true;
903
957
else if( !deviceNode().isEmpty() )
905
959
if( devicenode != deviceNode() )
961
canInitialize = true;
965
m_itdb = itdb_parse(QFile::encodeName(mountpoint), &err);
911
m_itdb = itdb_parse(QFile::encodeName(mountpoint), &err);
926
979
if( mountPoint().isEmpty() )
985
if( !ipodFound && !canInitialize )
936
amaroK::StatusBar::instance()->longMessage(
989
Amarok::StatusBar::instance()->longMessage(
937
990
i18n("Media Device: No mounted iPod found" ),
938
991
KDE::StatusBar::Sorry );
944
m_itdb = itdb_parse( QFile::encodeName(mountPoint()), &err );
996
if( !m_itdb && canInitialize )
957
998
QString msg = i18n( "Media Device: could not find iTunesDB on device mounted at %1. "
958
999
"Should I try to initialize your iPod?" ).arg( mountPoint() );
1023
1064
debug() << "iPod type detection failed, no video support" << endl;
1024
//amaroK::StatusBar::instance()->shortMessage( i18n("Media device: iPod type detection failed, no video support") );
1065
//Amarok::StatusBar::instance()->shortMessage( i18n("Media device: iPod type detection failed, no video support") );
1156
1197
if(dir[i] == "." || dir[i] == "..")
1159
QString hashpath = musicpath + "/" + dir[i];
1200
QString hashpath = musicpath + '/' + dir[i];
1160
1201
QDir hashdir( hashpath, QString::null, QDir::Unsorted, QDir::Files );
1161
1202
for(unsigned j=0; j<hashdir.count(); j++)
1163
QString filename = hashpath + "/" + hashdir[j];
1164
QString ipodPath = itunesDir( "Music:" ) + dir[i] + ":" + hashdir[j];
1204
QString filename = hashpath + '/' + hashdir[j];
1205
QString ipodPath = itunesDir( "Music:" ) + dir[i] + ':' + hashdir[j];
1165
1206
Itdb_Track *track = m_files[ipodPath.lower()];
1644
1684
IpodMediaItem *
1645
IpodMediaDevice::getTrack(const QString &artist, const QString &album, const QString &title, int trackNumber)
1685
IpodMediaDevice::getTrack(const QString &artist, const QString &album, const QString &title, int discNumber, int trackNumber)
1647
1687
IpodMediaItem *item = getAlbum(artist, album);
1652
1692
track = dynamic_cast<IpodMediaItem *>(item->findItem(title, track)) )
1654
if( trackNumber==-1 || track->bundle()->track() == trackNumber )
1694
if( ( discNumber==-1 || track->bundle()->discNumber()==discNumber )
1695
&& ( trackNumber==-1 || track->bundle()->track()==trackNumber ) )
1679
1721
track = dynamic_cast<IpodMediaItem *>(item->findItem(title, track)) )
1681
if( trackNumber==-1 || track->bundle()->track() == trackNumber )
1723
if( ( discNumber==-1 || track->bundle()->discNumber()==discNumber )
1724
&& ( trackNumber==-1 || track->bundle()->track()==trackNumber ) )
1757
1800
int num = std::rand() % 1000000;
1758
int music_dirs = itdb_musicdirs_number(m_itdb) > 0 ? itdb_musicdirs_number(m_itdb) : 20;
1801
int music_dirs = itdb_musicdirs_number(m_itdb) > 1 ? itdb_musicdirs_number(m_itdb) : 20;
1759
1802
int dir = num % music_dirs;
1760
1803
QString dirname;
1761
1804
dirname.sprintf( "%s:Music:f%02d", itunesDir().latin1(), dir );
1860
1903
KPopupMenu *playlistsMenu = 0;
1863
menu.insertItem( SmallIconSet( amaroK::icon( "playlist" ) ), i18n( "&Load" ), LOAD );
1864
menu.insertItem( SmallIconSet( amaroK::icon( "add_playlist" ) ), i18n( "&Append to Playlist" ), APPEND );
1865
menu.insertItem( SmallIconSet( amaroK::icon( "fastforward" ) ), i18n( "&Queue Tracks" ), QUEUE );
1906
menu.insertItem( SmallIconSet( Amarok::icon( "playlist" ) ), i18n( "&Load" ), LOAD );
1907
menu.insertItem( SmallIconSet( Amarok::icon( "add_playlist" ) ), i18n( "&Append to Playlist" ), APPEND );
1908
menu.insertItem( SmallIconSet( Amarok::icon( "fastforward" ) ), i18n( "&Queue Tracks" ), QUEUE );
1866
1909
menu.insertSeparator();
1868
menu.insertItem( SmallIconSet( amaroK::icon( "collection" ) ), i18n( "&Copy Files to Collection..." ), COPY_TO_COLLECTION );
1911
menu.insertItem( SmallIconSet( Amarok::icon( "collection" ) ), i18n( "&Copy Files to Collection..." ), COPY_TO_COLLECTION );
1869
1912
switch( item->type() )
1871
1914
case MediaItem::ARTIST:
1872
menu.insertItem( SmallIconSet( amaroK::icon( "cdrom_unmount" ) ), i18n( "Burn All Tracks by This Artist" ), BURN_ARTIST );
1915
menu.insertItem( SmallIconSet( Amarok::icon( "cdrom_unmount" ) ), i18n( "Burn All Tracks by This Artist" ), BURN_ARTIST );
1873
1916
menu.setItemEnabled( BURN_ARTIST, K3bExporter::isAvailable() );
1876
1919
case MediaItem::ALBUM:
1877
menu.insertItem( SmallIconSet( amaroK::icon( "cdrom_unmount" ) ), i18n( "Burn This Album" ), BURN_ALBUM );
1920
menu.insertItem( SmallIconSet( Amarok::icon( "cdrom_unmount" ) ), i18n( "Burn This Album" ), BURN_ALBUM );
1878
1921
menu.setItemEnabled( BURN_ALBUM, K3bExporter::isAvailable() );
1882
menu.insertItem( SmallIconSet( amaroK::icon( "cdrom_unmount" ) ), i18n( "Burn to CD as Data" ), BURN_DATACD );
1925
menu.insertItem( SmallIconSet( Amarok::icon( "cdrom_unmount" ) ), i18n( "Burn to CD as Data" ), BURN_DATACD );
1883
1926
menu.setItemEnabled( BURN_DATACD, K3bExporter::isAvailable() );
1884
menu.insertItem( SmallIconSet( amaroK::icon( "cdaudio_unmount" ) ), i18n( "Burn to CD as Audio" ), BURN_AUDIOCD );
1927
menu.insertItem( SmallIconSet( Amarok::icon( "cdaudio_unmount" ) ), i18n( "Burn to CD as Audio" ), BURN_AUDIOCD );
1885
1928
menu.setItemEnabled( BURN_AUDIOCD, K3bExporter::isAvailable() );
1892
1935
|| item->type() == MediaItem::PODCASTCHANNEL) )
1894
1937
IpodMediaItem *it = static_cast<IpodMediaItem *>(item);
1895
menu.insertItem( SmallIconSet( amaroK::icon( "podcast" ) ), i18n( "Subscribe to This Podcast" ), SUBSCRIBE );
1938
menu.insertItem( SmallIconSet( Amarok::icon( "podcast" ) ), i18n( "Subscribe to This Podcast" ), SUBSCRIBE );
1896
1939
//menu.setItemEnabled( SUBSCRIBE, item->bundle()->podcastBundle() && item->bundle()->podcastBundle()->parent().isValid() );
1897
1940
menu.setItemEnabled( SUBSCRIBE, it->m_podcastInfo && !it->m_podcastInfo->rss.isEmpty() );
1898
1941
menu.insertSeparator();
1908
1951
case MediaItem::PODCASTITEM:
1909
1952
if(m_playlistItem)
1911
menu.insertItem( SmallIconSet( amaroK::icon( "playlist" ) ), i18n( "Make Media Device Playlist" ), MAKE_PLAYLIST );
1954
menu.insertItem( SmallIconSet( Amarok::icon( "playlist" ) ), i18n( "Make Media Device Playlist" ), MAKE_PLAYLIST );
1912
1955
menu.setItemEnabled( MAKE_PLAYLIST, !locked );
1914
1957
playlistsMenu = new KPopupMenu(&menu);
1918
1961
it = dynamic_cast<MediaItem *>(it->nextSibling()))
1920
playlistsMenu->insertItem( SmallIconSet( amaroK::icon( "playlist" ) ), it->text(0), FIRST_PLAYLIST+i );
1963
playlistsMenu->insertItem( SmallIconSet( Amarok::icon( "playlist" ) ), it->text(0), FIRST_PLAYLIST+i );
1923
menu.insertItem( SmallIconSet( amaroK::icon( "playlist" ) ), i18n("Add to Playlist"), playlistsMenu, ADD_TO_PLAYLIST );
1966
menu.insertItem( SmallIconSet( Amarok::icon( "playlist" ) ), i18n("Add to Playlist"), playlistsMenu, ADD_TO_PLAYLIST );
1924
1967
menu.setItemEnabled( ADD_TO_PLAYLIST, !locked && m_playlistItem->childCount()>0 );
1925
1968
menu.insertSeparator();
1928
1971
if( item->type() == MediaItem::ARTIST ||
1929
1972
item->type() == MediaItem::ALBUM ||
1930
item->type() == MediaItem::TRACK )
1973
item->type() == MediaItem::TRACK ||
1974
item->type() == MediaItem::ORPHANED )
1932
menu.insertItem( SmallIconSet( amaroK::icon( "edit" ) ),
1976
menu.insertItem( SmallIconSet( Amarok::icon( "edit" ) ),
1933
1977
i18n( "Edit &Information...", "Edit &Information for %n Tracks...", urls.count()),
1938
1982
case MediaItem::ORPHANED:
1939
1983
case MediaItem::ORPHANEDROOT:
1940
menu.insertItem( SmallIconSet( amaroK::icon( "edit" ) ), i18n( "Add to Database" ), ADD );
1984
menu.insertItem( SmallIconSet( Amarok::icon( "edit" ) ), i18n( "Add to Database" ), ADD );
1941
1985
menu.setItemEnabled( ADD, !locked );
1944
1988
case MediaItem::PLAYLIST:
1945
menu.insertItem( SmallIconSet( amaroK::icon( "edit" ) ), i18n( "Rename" ), RENAME );
1989
menu.insertItem( SmallIconSet( Amarok::icon( "edit" ) ), i18n( "Rename" ), RENAME );
1946
1990
menu.setItemEnabled( RENAME, !locked );
1953
1997
if( item->type() == MediaItem::PLAYLIST || item->type() == MediaItem::PLAYLISTITEM )
1955
menu.insertItem( SmallIconSet( amaroK::icon( "remove_from_playlist" ) ),
1999
menu.insertItem( SmallIconSet( Amarok::icon( "remove_from_playlist" ) ),
1956
2000
item->type()==MediaItem::PLAYLIST ? i18n( "Remove Playlist" ) : i18n( "Remove from Playlist" ),
1957
2001
REMOVE_FROM_PLAYLIST );
1958
2002
menu.setItemEnabled( REMOVE_FROM_PLAYLIST, !locked );
1960
2004
if( item->type() == MediaItem::PODCASTSROOT || item->type() == MediaItem::PODCASTCHANNEL )
1962
menu.insertItem( SmallIconSet( amaroK::icon( "remove" ) ), i18n( "Delete Podcasts Already Played" ), DELETE_PLAYED );
2006
menu.insertItem( SmallIconSet( Amarok::icon( "remove" ) ), i18n( "Delete Podcasts Already Played" ), DELETE_PLAYED );
1963
2007
menu.setItemEnabled( DELETE_PLAYED, !locked );
1965
menu.insertItem( SmallIconSet( amaroK::icon( "remove" ) ),
2009
menu.insertItem( SmallIconSet( Amarok::icon( "remove" ) ),
1966
2010
i18n( "Delete Track from iPod", "Delete %n Tracks from iPod", urls.count() ),
1967
2011
DELETE_FROM_IPOD );
1968
2012
menu.setItemEnabled( DELETE_FROM_IPOD, !locked && urls.count() > 0 );
1971
2015
KPopupMenu repairMenu;
1972
repairMenu.insertItem( SmallIconSet( amaroK::icon( "playlist_refresh" ) ), i18n( "Scan for Orphaned and Missing Files" ), REPAIR_SCAN );
1973
repairMenu.insertItem( SmallIconSet( amaroK::icon( "covermanager" ) ), i18n( "Refresh Cover Images" ), REPAIR_COVERS );
2016
repairMenu.insertItem( SmallIconSet( Amarok::icon( "playlist_refresh" ) ), i18n( "Scan for Orphaned and Missing Files" ), REPAIR_SCAN );
2017
repairMenu.insertItem( SmallIconSet( Amarok::icon( "covermanager" ) ), i18n( "Refresh Cover Images" ), REPAIR_COVERS );
1974
2018
repairMenu.setItemEnabled( REPAIR_COVERS, m_supportsArtwork );
1975
2019
menu.insertItem( SmallIconSet( "folder" ), i18n("Repair iPod"), &repairMenu, REPAIR_MENU );
2104
2148
i->parent()->takeItem(i);
2105
insertTrackIntoDB(i->url().path(), *i->bundle(), 0);
2149
insertTrackIntoDB(i->url().path(), *i->bundle(), *i->bundle(), 0);
2110
2154
if( dupes > 0 )
2111
amaroK::StatusBar::instance()->shortMessage( i18n(
2155
Amarok::StatusBar::instance()->shortMessage( i18n(
2112
2156
"One duplicate track not added to database",
2113
2157
"%n duplicate tracks not added to database", dupes ) );