[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