[Amarok] Add support for readding orphaned files to iPod da
Seb Ruiz
ruiz at kde.org
Mon Aug 3 01:18:14 CEST 2009
Hi Alex,
Not a fan of this at all - you've practically duplicated the meta data
reading from Meta::File in here (and it's not complete).
You should be creating a new MetaFile::Track object and reading the
tags directly from this object. This way you also don't need to link
against taglib and all that foo. Remember, reusing code is always a
good thing!
Seb
2009/8/3 Alejandro Wainzinger <aikawarazuni at gmail.com>:
> commit cf40cecbe12f69b35683504b5c4068f14eff1194
> Author: Alejandro Wainzinger <aikawarazuni at gmail.com>
> AuthorDate: Sun Aug 2 19:59:07 2009 +0200
> Commit: Alejandro Wainzinger <aikawarazuni at gmail.com>
> CommitDate: Sun Aug 2 19:59:48 2009 +0200
>
> Add support for readding orphaned files to iPod database. Needs to be threaded, but it works.
>
> diff --git a/src/collection/ipodcollection/CMakeLists.txt b/src/collection/ipodcollection/CMakeLists.txt
> index 64e4485..dd96452 100644
> --- a/src/collection/ipodcollection/CMakeLists.txt
> +++ b/src/collection/ipodcollection/CMakeLists.txt
> @@ -27,7 +27,15 @@ if (IPOD_FOUND AND IPOD_0_7 AND WITH_Ipod)
> ${CMAKE_CURRENT_BINARY_DIR}/../..
> ${AMAROK_COLLECTION_SUPPORT_DIR}
> ${KDE4_INCLUDE_DIR}
> - ${QT_INCLUDES} )
> + ${QT_INCLUDES}
> + ${TAGLIB_INCLUDES}
> +)
> +
> +if ( TAGLIB-EXTRAS_FOUND )
> + include_directories( ${include_directories} ${TAGLIB-EXTRAS_INCLUDE_DIR} )
> +endif ( TAGLIB-EXTRAS_FOUND )
> +
> +add_definitions(${TAGLIB_CFLAGS})
>
> ########### set GDK var ################
> # Generate config-gdk.h.cmake
> @@ -56,6 +64,8 @@ if (IPOD_FOUND AND IPOD_0_7 AND WITH_Ipod)
> ${KDE4_SOLID_LIBRARY}
> ${KDE4_THREADWEAVER_LIBRARIES}
> ${QT_QTGUI_LIBRARY}
> + ${TAGLIB_LIBRARIES}
> + ${TAGLIB-EXTRAS_LIBRARIES}
> ${GLIB2_LIBRARIES}
> ${GDK_LIBRARIES}
> ${IPOD_LIBRARIES}
> diff --git a/src/collection/ipodcollection/handler/IpodHandler.cpp b/src/collection/ipodcollection/handler/IpodHandler.cpp
> index dfd0eaf..c5b98ee 100644
> --- a/src/collection/ipodcollection/handler/IpodHandler.cpp
> +++ b/src/collection/ipodcollection/handler/IpodHandler.cpp
> @@ -64,6 +64,32 @@ extern "C" {
> #include <QStringList>
> #include <QTime>
>
> +//Taglib:
> +#include <apetag.h>
> +#include <fileref.h>
> +#include <flacfile.h>
> +#include <id3v1tag.h>
> +#include <id3v2tag.h>
> +#include <mpcfile.h>
> +#include <mpegfile.h>
> +#include <oggfile.h>
> +#include <oggflacfile.h>
> +#include <speexfile.h>
> +#include <tlist.h>
> +#include <tstring.h>
> +#include <vorbisfile.h>
> +
> +#ifdef TAGLIB_EXTRAS_FOUND
> +#include <mp4file.h>
> +#include <mp4tag.h>
> +#include <mp4item.h>
> +#include <audiblefiletyperesolver.h>
> +#include <asffiletyperesolver.h>
> +#include <wavfiletyperesolver.h>
> +#include <realmediafiletyperesolver.h>
> +#include <mp4filetyperesolver.h>
> +#endif
> +
> using namespace Meta;
>
> /// IpodHandler
> @@ -153,7 +179,6 @@ IpodHandler::init()
>
> QString msg = i18n( "Media Device: could not find iTunesDB on device mounted at %1. "
> "Should I try to initialize your iPod?" ).arg( mountPoint() );
> -
> if( KMessageBox::warningContinueCancel( 0, msg, i18n( "Initialize iPod?" ),
> KGuiItem( i18n( "&Initialize" ), "new" ) ) == KMessageBox::Continue )
> {
> @@ -364,7 +389,7 @@ IpodHandler::collectionActions()
>
> #endif
>
> - QAction *staleOrphanedAction = new QAction( KIcon( "media-track-edit-amarok" ), i18n( "&Stale" ), this );
> + QAction *staleOrphanedAction = new QAction( KIcon( "media-track-edit-amarok" ), i18n( "&Stale and Orphaned" ), this );
> staleOrphanedAction->setProperty( "popupdropper_svg_id", "edit" );
>
> connect( staleOrphanedAction, SIGNAL( triggered() ), this, SLOT( slotStaleOrphaned() ) );
> @@ -413,40 +438,164 @@ IpodHandler::slotStaleOrphaned()
> {
> Meta::TrackList staletracks = staleTracks();
> QStringList staleList;
> + m_staletracksremoved = 0;
> +
> + if( staletracks.count() > 0 )
> + {
> +
> + foreach( Meta::TrackPtr track, staletracks )
> + {
> + QString ent;
> + QTextStream entry( &ent );
> + entry << track->artist()->name()
> + << " - "
> + << track->album()->name()
> + << " - "
> + << track->name();
> +
> + staleList << ent;
> + }
> +
> + bool ok = false;
> +
> + QStringList itemList = KInputDialog::getItemList( i18n( "Select Stale Tracks To Delete" ), i18n( "Stale Tracks" ), staleList, staleList, true /*multiple*/, &ok, 0 );
>
> - foreach( Meta::TrackPtr track, staletracks )
> + if( ok )
> + {
> + Meta::TrackList staleToDelete;
> + foreach( QString item, itemList )
> + {
> + staleToDelete << staletracks[ itemList.indexOf( item ) ];
> + }
> +
> + m_staletracksremoved = staleToDelete.count();
> + // HACK: do through signals/slots, which is how CollectionLocation
> + // does deletion of tracks. Should create protected method to
> + // allow Handlers to delete without hackery.
> + connect( this, SIGNAL( removeTracksDone() ), SLOT( slotOrphaned() ) );
> + removeTrackListFromDevice( staleToDelete );
> + }
> +
> + } // endif staletracks
> + else
> {
> - QString ent;
> - QTextStream entry( &ent );
> - entry << track->artist()->name()
> - << " - "
> - << track->album()->name()
> - << " - "
> - << track->name();
> -
> - staleList << ent;
> + slotOrphaned();
> }
> + }
>
> - bool ok = false;
>
> - QStringList itemList = KInputDialog::getItemList( i18n( "Select Stale Tracks To Delete" ), i18n( "Stale Tracks" ), staleList, staleList, true /*multiple*/, &ok, 0 );
> +}
>
> - if( ok )
> +void
> +IpodHandler::slotOrphaned()
> +{
> + writeDatabase();
> +
> + const QString msg( i18ncp( "@info", "One stale track removed from the database. Scan for orphaned tracks?",
> + "%1 tracks removed from the database. Scan for orphaned tracks?", m_staletracksremoved ) );
> +
> + const bool init = KMessageBox::warningContinueCancel(0,
> + msg,
> + i18n("Find Orphaned Tracks") ) == KMessageBox::Continue;
> +
> + if( init )
> + {
> + QStringList orphanedPaths = orphanedTracks();
> + int orphanedadded = 0;
> +
> + if( !orphanedPaths.empty() )
> {
> - Meta::TrackList staleToDelete;
> - foreach( QString item, itemList )
> + m_statusbar = The::statusBar()->newProgressOperation( this, i18n( "Adding Orphaned Tracks to iPod Database" ) );
> +
> + m_statusbar->setMaximum( orphanedPaths.count() );
> +
> + connect( this, SIGNAL( incrementProgress() ),
> + The::statusBar(), SLOT( incrementProgress() ), Qt::QueuedConnection );
> +
> + connect( this, SIGNAL( databaseWritten(bool)),
> + this, SLOT( slotDatabaseWritten(bool)), Qt::QueuedConnection );
> +
> + foreach( const QString path, orphanedPaths )
> {
> - staleToDelete << staletracks[ itemList.indexOf( item ) ];
> + QString realPath;
> + pathExists( path, &realPath );
> + const AttributeHash attributes = readTags( realPath );
> +
> + if( attributes.empty() )
> + continue;
> +
> + debug() << "Found: " << attributes["artist"] << " - " << attributes["title"];
> +
> + // Create new track
> +
> + Meta::MediaDeviceTrackPtr destTrack ( new Meta::MediaDeviceTrack( m_memColl ) );
> +
> + // Create a track struct, associate it to track
> +
> + libCreateTrack( destTrack );
> +
> + // Fill the track struct of the destTrack with info from the track parameter as source
> +
> + libSetTitle( destTrack, attributes["title"] );
> + libSetArtist( destTrack, attributes["artist"] );
> + libSetAlbum( destTrack, attributes["album"] );
> + libSetComment( destTrack, attributes["comment"] );
> + libSetGenre( destTrack, attributes["genre"] );
> + libSetYear( destTrack, attributes["year"] );
> + libSetTrackNumber( destTrack, attributes["track"].toInt() );
> +
> + if( attributes.contains("composer" ) )
> + libSetComposer( destTrack, attributes["composer"] );
> + if( attributes.contains("discnumber" ) )
> + libSetDiscNumber( destTrack, attributes["discnumber"].toInt() );
> +
> + //libSetBpm( destTrack, attributes["bpm"] );
> + if( attributes.contains("filesize" ) )
> + libSetFileSize( destTrack, attributes["filesize"].toInt() );
> +
> + libSetType( destTrack, attributes["filetype"] );
> + //libSetPlayableUrl( destTrack, srcTrack );
> +
> + if( attributes["audioproperties"] == "true" )
> + {
> + libSetBitrate( destTrack, attributes["bitrate"].toInt() );
> + libSetLength( destTrack, attributes["length"].toInt() );
> + libSetSamplerate( destTrack, attributes["samplerate"].toInt() );
> + }
> +
> + // set up the play url
> +
> + m_itdbtrackhash[ destTrack ]->ipod_path = g_strdup( path.toLatin1() );
> +
> + // Add the track struct into the database
> +
> + addTrackInDB( destTrack );
> +
> + // Inform subclass that a track has been added to the db
> +
> + databaseChanged();
> +
> + // Add the new Meta::MediaDeviceTrackPtr into the device collection
> +
> + // add track to collection
> + addMediaDeviceTrackToCollection( destTrack );
> +
> + orphanedadded++;
> +
> }
> - // HACK: do through signals/slots, which is how CollectionLocation
> - // does deletion of tracks. Should create protected method to
> - // allow Handlers to delete without hackery.
> - connect( this, SIGNAL( removeTracksDone() ), SLOT( writeDatabase() ) );
> - removeTrackListFromDevice( staleToDelete );
> - }
>
> - //QStringList orphanedPaths = orphanedTracks();
> - }
> + writeDatabase();
> +
> + } // foreach
> +
> + const QString orphmsg( i18ncp( "@info", "One orphaned track added to the database.",
> + "%1 tracks added to the database.", orphanedadded ) );
> +
> + KMessageBox::information(0,
> + orphmsg,
> + i18n("Orphaned Tracks Added") );
> + } // init
> +
>
>
> }
> @@ -806,8 +955,8 @@ IpodHandler::writeFirewireGuid()
> bool
> IpodHandler::pathExists( const QString &ipodPath, QString *realPath )
> {
> - DEBUG_BLOCK
> - debug() << "ipodPath: " << ipodPath;
> + //DEBUG_BLOCK
> + //debug() << "ipodPath: " << ipodPath;
> QDir curDir( mountPoint() );
> QString curPath = mountPoint();
> QStringList components;
> @@ -823,7 +972,7 @@ IpodHandler::pathExists( const QString &ipodPath, QString *realPath )
> QStringList::iterator it = components.begin();
> for( ; it != components.end(); ++it )
> {
> - debug() << "(*it): " << (*it);
> + //debug() << "(*it): " << (*it);
> found = false;
> for( uint i = 0;i < curDir.count(); i++ )
> {
> @@ -922,8 +1071,7 @@ IpodHandler::writeITunesDB( bool threaded )
> QString
> IpodHandler::itunesDir(const QString &p) const
> {
> - // NOTE: a colon was removed from the front since 1.4
> - QString base( "iPod_Control" );
> + QString base( ":iPod_Control" );
> if( m_isMobile )
> base = ":iTunes:iTunes_Control";
>
> @@ -1094,7 +1242,7 @@ QStringList
> IpodHandler::orphanedTracks()
> {
> DEBUG_BLOCK
> - int orph = 0;
> +
> QStringList orphanedTracks;
> QString musicpath;
> if (!pathExists( itunesDir( "Music" ), &musicpath ))
> @@ -1122,16 +1270,231 @@ IpodHandler::orphanedTracks()
> {
> debug() << "file: " << filename << " is orphaned" << endl;
> orphanedTracks << ipodPath;
> - orph++;
> + }
> + }
> + }
> +
> + return orphanedTracks;
> +}
> +
> +AttributeHash
> +IpodHandler::readTags( const QString &path, TagLib::AudioProperties::ReadStyle readStyle )
> +{
> + // Tests reveal the following:
> + //
> + // TagLib::AudioProperties Relative Time Taken
> + //
> + // No AudioProp Reading 1
> + // Fast 1.18
> + // Average Untested
> + // Accurate Untested
> +
> +
> +#ifdef COMPLEX_TAGLIB_FILENAME
> + const wchar_t * encodedName = reinterpret_cast<const wchar_t *>(path.utf16());
> +#else
> + QByteArray fileName = QFile::encodeName( path );
> + const char * encodedName = fileName.constData(); // valid as long as fileName exists
> +#endif
> +
> + TagLib::FileRef fileref;
> + TagLib::Tag *tag = 0;
> + fileref = TagLib::FileRef( encodedName, true, readStyle );
> +
> + AttributeHash attributes;
> + bool isValid = false;
> + FileType fileType = ogg;
> + if( !fileref.isNull() )
> + {
> + tag = fileref.tag();
> + if ( tag )
> + {
> + #define strip( x ) TStringToQString( x ).trimmed()
> +
> + attributes["title"] = strip( tag->title() );
> + attributes["artist"] = strip( tag->artist() );
> + attributes["album"] = strip( tag->album() );
> + attributes["comment"] = strip( tag->comment() );
> + attributes["genre"] = strip( tag->genre() );
> + attributes["year"] = QString::number( tag->year() );
> + attributes["track"] = QString::number( tag->track() );
> + isValid = true;
> + }
> +/*
> + Meta::ReplayGainTagMap replayGainTags = Meta::readReplayGainTags( fileref );
> + if ( replayGainTags.contains( Meta::ReplayGain_Track_Gain ) )
> + {
> + attributes["trackgain"] = QString::number( replayGainTags[Meta::ReplayGain_Track_Gain] );
> + if ( replayGainTags.contains( Meta::ReplayGain_Track_Peak ) )
> + attributes["trackpeakgain"] = QString::number( replayGainTags[Meta::ReplayGain_Track_Peak] );
> + }
> + if ( replayGainTags.contains( Meta::ReplayGain_Album_Gain ) )
> + {
> + attributes["albumgain"] = QString::number( replayGainTags[Meta::ReplayGain_Album_Gain] );
> + if ( replayGainTags.contains( Meta::ReplayGain_Album_Peak ) )
> + attributes["albumpeakgain"] = QString::number( replayGainTags[Meta::ReplayGain_Album_Peak] );
> + }
> +*/
> + QString disc;
> + QString compilation;
> +
> + /* As mpeg implementation on TagLib uses a Tag class that's not defined on the headers,
> + we have to cast the files, not the tags! */
> + if ( TagLib::MPEG::File *file = dynamic_cast<TagLib::MPEG::File *>( fileref.file() ) )
> + {
> + fileType = mp3;
> + if ( file->ID3v2Tag() )
> + {
> + if ( !file->ID3v2Tag()->frameListMap()["TPOS"].isEmpty() )
> + disc = TStringToQString( file->ID3v2Tag()->frameListMap()["TPOS"].front()->toString() ).trimmed();
> +
> + if ( !file->ID3v2Tag()->frameListMap()["TBPM"].isEmpty() )
> + attributes["bpm"] = TStringToQString( file->ID3v2Tag()->frameListMap()["TBPM"].front()->toString() ).trimmed().toFloat();
> +
> + if ( !file->ID3v2Tag()->frameListMap()["TCOM"].isEmpty() )
> + attributes["composer"] = TStringToQString( file->ID3v2Tag()->frameListMap()["TCOM"].front()->toString() ).trimmed();
> +
> + if ( !file->ID3v2Tag()->frameListMap()["TPE2"].isEmpty() ) // non-standard: Apple, Microsoft
> + attributes["albumArtist"] = TStringToQString( file->ID3v2Tag()->frameListMap()["TPE2"].front()->toString() ).trimmed();
>
> + if ( !file->ID3v2Tag()->frameListMap()["TCMP"].isEmpty() )
> + compilation = TStringToQString( file->ID3v2Tag()->frameListMap()["TCMP"].front()->toString() ).trimmed();
> +
> + //FIXME: Port 2.0
> +// if( images )
> +// loadImagesFromTag( *file->ID3v2Tag(), *images );
> }
>
> - if( orph > 10 )
> - return QStringList();
> + #undef strip
> + }
> +
> + if ( TagLib::Ogg::Vorbis::File *file = dynamic_cast<TagLib::Ogg::Vorbis::File *>( fileref.file() ) )
> + {
> + fileType = ogg;
> + if ( file->tag() )
> + {
> + if ( !file->tag()->fieldListMap()[ "COMPOSER" ].isEmpty() )
> + attributes["composer"] = TStringToQString( file->tag()->fieldListMap()["COMPOSER"].front() ).trimmed();
> +
> + if ( !file->tag()->fieldListMap()[ "BPM" ].isEmpty() )
> + attributes["bpm"] = TStringToQString( file->tag()->fieldListMap()["BPM"].front() ).trimmed().toFloat();
> +
> + if ( !file->tag()->fieldListMap()[ "DISCNUMBER" ].isEmpty() )
> + disc = TStringToQString( file->tag()->fieldListMap()["DISCNUMBER"].front() ).trimmed();
> +
> + if ( !file->tag()->fieldListMap()[ "COMPILATION" ].isEmpty() )
> + compilation = TStringToQString( file->tag()->fieldListMap()["COMPILATION"].front() ).trimmed();
> + }
> + }
> + else if ( TagLib::FLAC::File *file = dynamic_cast<TagLib::FLAC::File *>( fileref.file() ) )
> + {
> + fileType = flac;
> + if ( file->xiphComment() )
> + {
> + if ( !file->xiphComment()->fieldListMap()[ "COMPOSER" ].isEmpty() )
> + attributes["composer"] = TStringToQString( file->xiphComment()->fieldListMap()["COMPOSER"].front() ).trimmed();
> +
> + if ( !file->xiphComment()->fieldListMap()[ "BPM" ].isEmpty() )
> + attributes["bpm"] = TStringToQString( file->xiphComment()->fieldListMap()["BPM"].front() ).trimmed().toFloat();
> +
> + if ( !file->xiphComment()->fieldListMap()[ "DISCNUMBER" ].isEmpty() )
> + disc = TStringToQString( file->xiphComment()->fieldListMap()["DISCNUMBER"].front() ).trimmed();
> +
> + if ( !file->xiphComment()->fieldListMap()[ "COMPILATION" ].isEmpty() )
> + compilation = TStringToQString( file->xiphComment()->fieldListMap()["COMPILATION"].front() ).trimmed();
> + }
> +// if ( images && file->ID3v2Tag() )
> +// loadImagesFromTag( *file->ID3v2Tag(), *images );
> + }
> +#ifdef TAGLIB_EXTRAS_FOUND
> + else if ( TagLib::MP4::File *file = dynamic_cast<TagLib::MP4::File *>( fileref.file() ) )
> + {
> + fileType = mp4;
> + TagLib::MP4::Tag *mp4tag = dynamic_cast<TagLib::MP4::Tag *>( file->tag() );
> + if( mp4tag )
> + {
> + if ( mp4tag->itemListMap().contains( "\xA9wrt" ) )
> + attributes["composer"] = TStringToQString( mp4tag->itemListMap()["\xa9wrt"].toStringList().front() );
> +
> + if ( mp4tag->itemListMap().contains( "tmpo" ) )
> + attributes["bpm"] = QString::number( mp4tag->itemListMap()["tmpo"].toInt() );
> +
> + if ( mp4tag->itemListMap().contains( "disk" ) )
> + disc = QString::number( mp4tag->itemListMap()["disk"].toIntPair().first );
> +
> + if ( mp4tag->itemListMap().contains( "cpil" ) )
> + compilation = QString::number( mp4tag->itemListMap()["cpil"].toBool() ? '1' : '0' );
> +
> +// if ( images && mp4tag->cover().size() )
> +// images->push_back( EmbeddedImage( mp4tag->cover(), "" ) );
> + }
> + }
> +#endif
> +
> + if ( !disc.isEmpty() )
> + {
> + int i = disc.indexOf('/');
> + // guard against b0rked tags
> + int discnumber;
> + if ( i != -1 )
> + // disc.right( i ).toInt() is total number of discs, we don't use this at the moment
> + discnumber = disc.left( i ).toInt();
> + else
> + discnumber = disc.toInt();
> + attributes["discnumber"] = QString::number( discnumber );
> + }
> +
> + // Sometimes the file is explicitly tagged with compilation details. When it is not,
> + // then we need to delegate checking whether this files is in a compilation to Amarok.
> + if ( compilation.isEmpty() )
> + {
> + // well, it wasn't set, but if the artist is VA assume it's a compilation
> + //TODO: If we get pure-Qt translation support, put this back in; else functionality moved to the processor
> + //if ( attributes["artist"] == QObject::tr( "Various Artists" ) )
> + // attributes["compilation"] = QString::number( 1 );
> + attributes["compilation"] = "checkforvarious";
> + }
> + else
> + {
> + int i = compilation.toInt();
> + attributes["compilation"] = QString::number( i );
> }
> }
>
> - return orphanedTracks;
> + if ( !isValid )
> + {
> + std::cout << "<dud/>";
> + return attributes;
> + }
> +
> + attributes["filetype"] = QString::number( fileType );
> +
> + static const int Undetermined = -2;
> +
> + int bitrate = Undetermined;
> + int length = Undetermined;
> + int samplerate = Undetermined;
> + if( fileref.audioProperties() )
> + {
> + bitrate = fileref.audioProperties()->bitrate();
> + length = fileref.audioProperties()->length();
> + samplerate = fileref.audioProperties()->sampleRate();
> + }
> + if ( bitrate == Undetermined || length == Undetermined || samplerate == Undetermined )
> + attributes["audioproperties"] = "false";
> + else
> + {
> + attributes["audioproperties"] = "true";
> + attributes["bitrate"] = QString::number( bitrate );
> + attributes["length"] = QString::number( length );
> + attributes["samplerate"] = QString::number( samplerate );
> + }
> +
> + const int size = QFile( path ).size();
> + if( size >= 0 )
> + attributes["filesize"] = QString::number( size );
> +
> + return attributes;
> }
>
> bool
> diff --git a/src/collection/ipodcollection/handler/IpodHandler.h b/src/collection/ipodcollection/handler/IpodHandler.h
> index ca4c53a..8ea2ca9 100644
> --- a/src/collection/ipodcollection/handler/IpodHandler.h
> +++ b/src/collection/ipodcollection/handler/IpodHandler.h
> @@ -22,6 +22,10 @@
> #ifndef IPODHANDLER_H
> #define IPODHANDLER_H
>
> +// Taglib includes
> +#include <audioproperties.h>
> +#include <fileref.h>
> +
> /* CMake check for GDK */
> #include <config-gdk.h>
>
> @@ -60,7 +64,7 @@ class QMutex;
>
> class IpodCollection;
>
> -
> +typedef QHash<QString, QString> AttributeHash;
> typedef QMultiMap<QString, Meta::TrackPtr> TitleMap;
>
> // NOTE: podcasts NYI
> @@ -226,6 +230,14 @@ private slots:
>
> private:
>
> + enum FileType
> + {
> + mp3,
> + ogg,
> + flac,
> + mp4
> + };
> +
> /// Functions for ReadCapability
>
> virtual void prepareToParseTracks();
> @@ -274,6 +286,18 @@ private:
> */
> QStringList orphanedTracks();
>
> + // NOTE: readTags taken from CollectionScanner.cpp, not used directly since
> + // CollectionScanner is now a separate utility from Amarok, and we should
> + // not depend on it.
> +
> + /**
> + * Read metadata tags of a given file.
> + * @track Track for the file.
> + * @return QMap containing tags, or empty QMap on failure.
> + */
> +
> + AttributeHash readTags( const QString &path, TagLib::AudioProperties::ReadStyle readStyle = TagLib::AudioProperties::Fast );
> +
> bool removeDBTrack( Itdb_Track *track );
>
> /* libgpod Information Extraction Methods */
> @@ -315,6 +339,7 @@ private:
> GList *m_currtracklist;
> Itdb_Track *m_currtrack;
> QHash<QString,Itdb_Track*> m_files;
> + int m_staletracksremoved;
>
> // For space checks
>
> @@ -400,6 +425,8 @@ private slots:
> void slotDBWriteSucceeded( ThreadWeaver::Job* job );
>
> void slotCopyingDone( KIO::Job* job, KUrl from, KUrl to, time_t mtime, bool directory, bool renamed );
> +
> + void slotOrphaned();
> };
>
> class DBWorkerThread : public ThreadWeaver::Job
> diff --git a/src/collection/mediadevicecollection/handler/MediaDeviceHandler.h b/src/collection/mediadevicecollection/handler/MediaDeviceHandler.h
> index f7621a6..2dcf116 100644
> --- a/src/collection/mediadevicecollection/handler/MediaDeviceHandler.h
> +++ b/src/collection/mediadevicecollection/handler/MediaDeviceHandler.h
> @@ -237,7 +237,16 @@ protected:
>
> MediaDeviceHandler( QObject *parent );
>
> + /** Creates a MediaDeviceTrack based on the latest track struct created as a
> + * result of a copy to the device, and adds it into the collection to reflect
> + * that it has been copied.
> + * @param track The track to add to the collection
> + */
> +
> + void addMediaDeviceTrackToCollection( Meta::MediaDeviceTrackPtr &track );
> +
> MediaDeviceCollection *m_memColl; /// Associated collection
> + ProgressBar *m_statusbar; /// A progressbar to show progress of an operation
>
> bool m_success;
> bool m_copyingthreadsafe; // whether or not the handler's method of copying is threadsafe
> @@ -261,14 +270,6 @@ protected slots:
>
> private:
>
> - /** Creates a MediaDeviceTrack based on the latest track struct created as a
> - * result of a copy to the device, and adds it into the collection to reflect
> - * that it has been copied.
> - * @param track The track to add to the collection
> - */
> -
> - void addMediaDeviceTrackToCollection( Meta::MediaDeviceTrackPtr &track );
> -
> /** Removes the @param track from all the collection's maps to reflect that
> * it has been removed from the collection
> * @param track The track to remove from the collection
> @@ -349,7 +350,6 @@ private:
> QMap<Meta::TrackPtr, QString> m_tracksFailed; /// tracks that failed to copy
> QHash<Meta::TrackPtr, Meta::MediaDeviceTrackPtr> m_trackSrcDst; /// points source to destTracks, for completion of addition to collection
>
> - ProgressBar *m_statusbar; /// A progressbar to show progress of an operation
> QMutex m_mutex; /// A make certain operations atomic when threads are at play
>
> /// Capability-related variables
>
>
>
--
Seb Ruiz
http://www.sebruiz.net/
http://amarok.kde.org/
More information about the Amarok-devel
mailing list