Ejemplo n.º 1
0
void Ripper::switchTitlesAndArtists()
{
    if (!m_compilationCheck->GetBooleanCheckState())
        return;

    Metadata *data;

    // Switch title and artist for each track
    QString tmp;
    if (m_tracks->size() > 0)
    {
        for (int track = 0; track < m_tracks->size(); ++track)
        {
            data = m_tracks->at(track)->metadata;

            if (data)
            {
                tmp = data->Artist();
                data->setArtist(data->Title());
                data->setTitle(tmp);
            }
        }

        updateTrackList();
    }
}
Ejemplo n.º 2
0
void ImportMusicDialog::metadataChanged(void)
{
    Metadata *editMeta = m_tracks->at(m_currentTrack)->metadata;
    m_tracks->at(m_currentTrack)->metadataHasChanged = true;
    m_tracks->at(m_currentTrack)->isNewTune =
        Ripper::isNewTune(editMeta->Artist(), editMeta->Album(), editMeta->Title());
    fillWidgets();
}
Ejemplo n.º 3
0
void Ripper::updateTrackList(void)
{
    if (m_tracks->isEmpty())
        return;

    QString tmptitle;
    if (m_trackList)
    {
        m_trackList->Reset();

        int i;
        for (i = 0; i < (int)m_tracks->size(); i++)
        {
            if (i >= m_tracks->size())
                break;

            RipTrack *track = m_tracks->at(i);
            Metadata *metadata = track->metadata;

            MythUIButtonListItem *item = new MythUIButtonListItem(m_trackList,"");

            item->setCheckable(true);

            item->SetData(qVariantFromValue(track));

            if (track->isNew)
                item->DisplayState("new", "yes");
            else
                item->DisplayState("new", "no");

            if (track->active)
                item->setChecked(MythUIButtonListItem::FullChecked);
            else
                item->setChecked(MythUIButtonListItem::NotChecked);

            item->SetText(QString::number(metadata->Track()), "track");
            item->SetText(metadata->Title(), "title");
            item->SetText(metadata->Artist(), "artist");

            int length = track->length / 1000;
            if (length > 0)
            {
                int min, sec;
                min = length / 60;
                sec = length % 60;
                QString s;
                s.sprintf("%02d:%02d", min, sec);
                item->SetText(s, "length");
            }
            else
                item->SetText("", "length");

//             if (i == m_currentTrack)
//                 m_trackList->SetItemCurrent(i);
        }
    }
}
Ejemplo n.º 4
0
/*!
 * \copydoc MetaIO::read()
 */
Metadata* MetaIOFLACVorbis::read(QString filename)
{
    TagLib::FLAC::File *flacfile = OpenFile(filename);
    
    if (!flacfile)
        return NULL;
    
    TagLib::Ogg::XiphComment *tag = flacfile->xiphComment();
    
    if (!tag)
    {
        delete flacfile;
        return NULL;
    }
    
    Metadata *metadata = new Metadata(filename);
    
    ReadGenericMetadata(tag, metadata);
    
    bool compilation = false;

    if (tag->contains("COMPILATION_ARTIST"))
    {
        QString compilation_artist = TStringToQString(
            tag->fieldListMap()["COMPILATION_ARTIST"].toString()).trimmed();
        if (compilation_artist != metadata->Artist())
        {
            metadata->setCompilationArtist(compilation_artist);
            compilation = true;
        }
    }
    
    if (!compilation && tag->contains("MUSICBRAINZ_ALBUMARTISTID"))
    {
        QString musicbrainzcode = TStringToQString(
        tag->fieldListMap()["MUSICBRAINZ_ALBUMARTISTID"].toString()).trimmed();
        if (musicbrainzcode == MYTH_MUSICBRAINZ_ALBUMARTIST_UUID)
            compilation = true;
    }

    metadata->setCompilation(compilation);

    if (metadata->Length() <= 0)
    {
        TagLib::FileRef *fileref = new TagLib::FileRef(flacfile);
        metadata->setLength(getTrackLength(fileref));
        // FileRef takes ownership of flacfile, and is responsible for it's
        // deletion. Messy.
        delete fileref;
    }
    else
        delete flacfile;
    
    return metadata;
}
Ejemplo n.º 5
0
void ImportMusicDialog::saveDefaults(void)
{
    Metadata *data = m_tracks->at(m_currentTrack)->metadata;
    m_defaultCompilation = data->Compilation();
    m_defaultCompArtist = data->CompilationArtist();
    m_defaultArtist = data->Artist();
    m_defaultAlbum = data->Album();
    m_defaultGenre = data->Genre();
    m_defaultYear = data->Year();
    m_defaultRating = data->Rating();

    m_haveDefaults = true;
}
Ejemplo n.º 6
0
void ImportMusicDialog::setAlbum(void)
{
    if (!m_haveDefaults)
        return;

    Metadata *data = m_tracks->at(m_currentTrack)->metadata;
    data->setAlbum(m_defaultAlbum);

    m_tracks->at(m_currentTrack)->isNewTune = Ripper::isNewTune(
            data->Artist(), data->Album(), data->Title());

    fillWidgets();
}
Ejemplo n.º 7
0
/*!
* \copydoc MetaIO::read()
*/
Metadata* MetaIOOggVorbis::read(const QString &filename)
{
    TagLib::Ogg::Vorbis::File *oggfile = OpenFile(filename);

    if (!oggfile)
        return NULL;

    TagLib::Ogg::XiphComment *tag = oggfile->tag();

    if (!tag)
    {
        delete oggfile;
        return NULL;
    }

    Metadata *metadata = new Metadata(filename);

    ReadGenericMetadata(tag, metadata);

    bool compilation = false;

    if (tag->contains("COMPILATION_ARTIST"))
    {
        QString compilation_artist = TStringToQString(
            tag->fieldListMap()["COMPILATION_ARTIST"].toString()).trimmed();
        if (compilation_artist != metadata->Artist())
        {
            metadata->setCompilationArtist(compilation_artist);
            compilation = true;
        }
    }

    if (!compilation && tag->contains("MUSICBRAINZ_ALBUMARTISTID"))
    {
        QString musicbrainzcode = TStringToQString(
        tag->fieldListMap()["MUSICBRAINZ_ALBUMARTISTID"].toString()).trimmed();
        if (musicbrainzcode == MYTH_MUSICBRAINZ_ALBUMARTIST_UUID)
            compilation = true;
    }

    metadata->setCompilation(compilation);

    if (metadata->Length() <= 0)
        metadata->setLength(getTrackLength(oggfile));
    else
        delete oggfile;

    return metadata;
}
Ejemplo n.º 8
0
void ImportMusicDialog::fillWidgets()
{
    if (m_tracks->size() > 0)
    {
        // update current
        m_currentText->SetText(QString("%1 of %2")
                .arg(m_currentTrack + 1).arg(m_tracks->size()));

        Metadata *meta = m_tracks->at(m_currentTrack)->metadata;
        m_filenameText->SetText(meta->Filename());
        m_compilationCheck->SetCheckState(meta->Compilation());
        m_compartistText->SetText(meta->CompilationArtist());
        m_artistText->SetText(meta->Artist());
        m_albumText->SetText(meta->Album());
        m_titleText->SetText(meta->Title());
        m_genreText->SetText(meta->Genre());
        m_yearText->SetText(QString::number(meta->Year()));
        m_trackText->SetText(QString::number(meta->Track()));
        if (m_tracks->at(m_currentTrack)->isNewTune)
        {
            m_coverartButton->SetVisible(false);
            m_statusText->SetText(tr("New File"));
        }
        else
        {
            m_coverartButton->SetVisible(true);
            m_statusText->SetText(tr("Already in Database"));
        }
    }
    else
    {
        // update current
        m_currentText->SetText(tr("Not found"));
        m_filenameText->Reset();
        m_compilationCheck->SetCheckState(false);
        m_compartistText->Reset();
        m_artistText->Reset();
        m_albumText->Reset();
        m_titleText->Reset();
        m_genreText->Reset();
        m_yearText->Reset();
        m_trackText->Reset();
        m_statusText->Reset();
        m_coverartButton->SetVisible(false);
    }
}
Ejemplo n.º 9
0
void ImportMusicDialog::scanDirectory(QString &directory, vector<TrackInfo*> *tracks)
{
    QDir d(directory);

    if (!d.exists())
        return;

    const QFileInfoList list = d.entryInfoList();
    if (list.isEmpty())
        return;

    QFileInfoList::const_iterator it = list.begin();
    const QFileInfo *fi;

    while (it != list.end())
    {
        fi = &(*it);
        ++it;
        if (fi->fileName() == "." || fi->fileName() == "..")
            continue;
        QString filename = fi->absoluteFilePath();
        if (fi->isDir())
            scanDirectory(filename, tracks);
        else
        {
            Decoder *decoder = Decoder::create(filename, NULL, NULL, true);
            if (decoder)
            {
                Metadata *metadata = decoder->getMetadata();
                if (metadata)
                {
                    TrackInfo * track = new TrackInfo;
                    track->metadata = metadata;
                    track->isNewTune = Ripper::isNewTune(metadata->Artist(),
                            metadata->Album(), metadata->Title());
                    track->metadataHasChanged = false;
                    tracks->push_back(track);
                    m_sourceFiles.append(filename);
                }

                delete decoder;
            }
        }
    }
}
Ejemplo n.º 10
0
/*!
 * \brief Insert file details into database.
 *        If it is an audio file, read the metadata and insert
 *        that information at the same time.
 *
 *        If it is an image file, just insert the filename and
 *        type.
 *
 * \param filename Full path to file.
 *
 * \returns Nothing.
 */
void FileScanner::AddFileToDB(const QString &filename)
{
    QString extension = filename.section( '.', -1 ) ;
    QString directory = filename;
    directory.remove(0, m_startdir.length());
    directory = directory.section( '/', 0, -2);

    QString nameFilter = gCoreContext->GetSetting("AlbumArtFilter",
                                              "*.png;*.jpg;*.jpeg;*.gif;*.bmp");

    // If this file is an image, insert the details into the music_albumart table
    if (nameFilter.indexOf(extension.toLower()) > -1)
    {
        QString name = filename.section( '/', -1);

        MSqlQuery query(MSqlQuery::InitCon());
        query.prepare("INSERT INTO music_albumart SET filename = :FILE, "
                      "directory_id = :DIRID, imagetype = :TYPE;");
        query.bindValue(":FILE", name);
        query.bindValue(":DIRID", m_directoryid[directory]);
        query.bindValue(":TYPE", AlbumArtImages::guessImageType(name));

        if (!query.exec() || query.numRowsAffected() <= 0)
        {
            MythDB::DBError("music insert artwork", query);
        }
        return;
    }

    Decoder *decoder = Decoder::create(filename, NULL, NULL, true);

    if (decoder)
    {
        LOG(VB_FILE, LOG_INFO,
            QString("Reading metadata from %1").arg(filename));
        Metadata *data = decoder->readMetadata();
        if (data) 
        {

            QString album_cache_string;

            // Set values from cache
            int did = m_directoryid[directory];
            if (did > 0)
                data->setDirectoryId(did);

            int aid = m_artistid[data->Artist().toLower()];
            if (aid > 0)
            {
                data->setArtistId(aid);

                // The album cache depends on the artist id
                album_cache_string = data->getArtistId() + "#"
                    + data->Album().toLower();

                if (m_albumid[album_cache_string] > 0)
                    data->setAlbumId(m_albumid[album_cache_string]);
            }

            int gid = m_genreid[data->Genre().toLower()];
            if (gid > 0)
                data->setGenreId(gid);

            // Commit track info to database
            data->dumpToDatabase();

            // Update the cache
            m_artistid[data->Artist().toLower()] =
                data->getArtistId();

            m_genreid[data->Genre().toLower()] =
                data->getGenreId();

            album_cache_string = data->getArtistId() + "#"
                + data->Album().toLower();
            m_albumid[album_cache_string] = data->getAlbumId();

            // read any embedded images from the tag
            MetaIO *tagger = data->getTagger();
            if (tagger && tagger->supportsEmbeddedImages())
            {
                AlbumArtList artList = tagger->getAlbumArtList(data->Filename());
                data->setEmbeddedAlbumArt(artList);
                data->getAlbumArtImages()->dumpToDatabase();
            }

            delete data;
        }

        delete decoder;
    }
}
Ejemplo n.º 11
0
void Ripper::ScanFinished()
{
    delete m_scanThread;
    m_scanThread = NULL;

    m_tracks->clear();

    bool isCompilation = false;
    bool newTune = true;
    if (m_decoder)
    {
        QString label;
        Metadata *metadata;

        m_artistName.clear();
        m_albumName.clear();
        m_genreName.clear();
        m_year.clear();
        bool yesToAll = false;
        bool noToAll = false;

        for (int trackno = 0; trackno < m_decoder->getNumTracks(); trackno++)
        {
            RipTrack *ripTrack = new RipTrack;

            metadata = m_decoder->getMetadata(trackno + 1);
            if (metadata)
            {
                ripTrack->metadata = metadata;
                ripTrack->length = metadata->Length();
                ripTrack->active = true;

                if (metadata->Compilation())
                {
                    isCompilation = true;
                    m_artistName = metadata->CompilationArtist();
                }
                else if (m_artistName.isEmpty())
                {
                    m_artistName = metadata->Artist();
                }

                if (m_albumName.isEmpty())
                    m_albumName = metadata->Album();

                if (m_genreName.isEmpty() && !metadata->Genre().isEmpty())
                    m_genreName = metadata->Genre();

                if (m_year.isEmpty() && metadata->Year() > 0)
                    m_year = QString::number(metadata->Year());

                QString title = metadata->Title();
                newTune = Ripper::isNewTune(m_artistName, m_albumName, title);

                if (newTune)
                {
                    m_tracks->push_back(ripTrack);
                }
                else
                {
                    if (yesToAll)
                    {
                        deleteTrack(m_artistName, m_albumName, title);
                        m_tracks->push_back(ripTrack);
                    }
                    else if (noToAll)
                    {
                        delete ripTrack;
                        delete metadata;
                        continue;
                    }
                    else
                    {
                        DialogBox *dlg = new DialogBox(
                            GetMythMainWindow(),
                            tr("Artist: %1\n"
                               "Album: %2\n"
                               "Track: %3\n\n"
                               "This track is already in the database. \n"
                               "Do you want to remove the existing track?")
                            .arg(m_artistName).arg(m_albumName).arg(title));

                        dlg->AddButton("No");
                        dlg->AddButton("No To All");
                        dlg->AddButton("Yes");
                        dlg->AddButton("Yes To All");
                        DialogCode res = dlg->exec();
                        dlg->deleteLater();
                        dlg = NULL;

                        if (kDialogCodeButton0 == res)
                        {
                            delete ripTrack;
                            delete metadata;
                        }
                        else if (kDialogCodeButton1 == res)
                        {
                            noToAll = true;
                            delete ripTrack;
                            delete metadata;
                        }
                        else if (kDialogCodeButton2 == res)
                        {
                            deleteTrack(m_artistName, m_albumName, title);
                            m_tracks->push_back(ripTrack);
                        }
                        else if (kDialogCodeButton3 == res)
                        {
                            yesToAll = true;
                            deleteTrack(m_artistName, m_albumName, title);
                            m_tracks->push_back(ripTrack);
                        }
                        else // treat cancel as no
                        {
                            delete ripTrack;
                            delete metadata;
                        }
                    }
                }
            }
            else
                delete ripTrack;
        }

        m_artistEdit->SetText(m_artistName);
        m_albumEdit->SetText(m_albumName);
        m_genreEdit->SetText(m_genreName);
        m_yearEdit->SetText(m_year);
        m_compilationCheck->SetCheckState(isCompilation);

        if (!isCompilation)
            m_switchTitleArtist->SetVisible(false);
        else
            m_switchTitleArtist->SetVisible(true);
    }

    BuildFocusList();
    updateTrackList();

    CloseBusyPopup();
}
Ejemplo n.º 12
0
void CDRipperThread::run(void)
{
    if (!m_tracks->size() > 0)
        return;

    Metadata *track = m_tracks->at(0)->metadata;
    QString tots;

    if (track->Compilation())
    {
        tots = track->CompilationArtist() + " ~ " + track->Album();
    }
    else
    {
        tots = track->Artist() + " ~ " + track->Album();
    }

    QApplication::postEvent(
        m_parent,
        new RipStatusEvent(RipStatusEvent::kOverallTextEvent, tots));
    QApplication::postEvent(
        m_parent,
        new RipStatusEvent(RipStatusEvent::kOverallProgressEvent, 0));
    QApplication::postEvent(
        m_parent,
        new RipStatusEvent(RipStatusEvent::kTrackProgressEvent, 0));

    QString textstatus;
    QString encodertype = gCoreContext->GetSetting("EncoderType");
    bool mp3usevbr = gCoreContext->GetNumSetting("Mp3UseVBR", 0);

    m_totalSectors = 0;
    m_totalSectorsDone = 0;
    for (int trackno = 0; trackno < m_tracks->size(); trackno++)
    {
        m_totalSectors += getSectorCount(m_CDdevice, trackno + 1);
    }

    QApplication::postEvent(m_parent,
        new RipStatusEvent(RipStatusEvent::kOverallStartEvent, m_totalSectors));

    if (LCD *lcd = LCD::Get())
    {
        QString lcd_tots = QObject::tr("Importing ") + tots;
        QList<LCDTextItem> textItems;
        textItems.append(LCDTextItem(1, ALIGN_CENTERED,
                                         lcd_tots, "Generic", false));
        lcd->switchToGeneric(textItems);
    }

    Metadata *titleTrack = NULL;
    QString outfile;

    std::auto_ptr<Encoder> encoder;

    for (int trackno = 0; trackno < m_tracks->size(); trackno++)
    {
        if (isCancelled())
            break;

        QApplication::postEvent(
            m_parent,
            new RipStatusEvent(RipStatusEvent::kStatusTextEvent,
                               QString("Track %1 of %2")
                               .arg(trackno + 1).arg(m_tracks->size())));

        QApplication::postEvent(
            m_parent,
            new RipStatusEvent(RipStatusEvent::kTrackProgressEvent, 0));

        track = m_tracks->at(trackno)->metadata;

        if (track)
        {
            textstatus = track->Title();
            QApplication::postEvent(
                m_parent,
                new RipStatusEvent(
                    RipStatusEvent::kTrackTextEvent, textstatus));
            QApplication::postEvent(
                m_parent,
                new RipStatusEvent(RipStatusEvent::kTrackProgressEvent, 0));
            QApplication::postEvent(
                m_parent,
                new RipStatusEvent(RipStatusEvent::kTrackPercentEvent, 0));

            // do we need to start a new file?
            if (m_tracks->at(trackno)->active)
            {
                titleTrack = track;
                titleTrack->setLength(m_tracks->at(trackno)->length);

                outfile = Ripper::filenameFromMetadata(track);

                if (m_quality < 3)
                {
                    if (encodertype == "mp3")
                    {
                        outfile += ".mp3";
                        encoder.reset(new LameEncoder(outfile, m_quality,
                                                      titleTrack, mp3usevbr));
                    }
                    else // ogg
                    {
                        outfile += ".ogg";
                        encoder.reset(new VorbisEncoder(outfile, m_quality,
                                                        titleTrack));
                    }
                }
                else
                {
                    outfile += ".flac";
                    encoder.reset(new FlacEncoder(outfile, m_quality,
                                                  titleTrack));
                }

                if (!encoder->isValid())
                {
                    QApplication::postEvent(
                        m_parent,
                        new RipStatusEvent(
                            RipStatusEvent::kEncoderErrorEvent,
                            "Encoder failed to open file for writing"));
                    VERBOSE(VB_IMPORTANT, "MythMusic: Encoder failed"
                                          " to open file for writing");

                    return;
                }
            }

            if (!encoder.get())
            {
                // This should never happen.
                QApplication::postEvent(
                    m_parent,
                    new RipStatusEvent(RipStatusEvent::kEncoderErrorEvent,
                                       "Failed to create encoder"));
                VERBOSE(VB_IMPORTANT,
                        QString("MythMusic: Error: No encoder, failing"));
                return;
            }
            ripTrack(m_CDdevice, encoder.get(), trackno + 1);

            if (isCancelled())
                return;

            // save the metadata to the DB
            if (m_tracks->at(trackno)->active)
            {
                titleTrack->setFilename(outfile);
                titleTrack->dumpToDatabase();
            }
        }
    }

    QString PostRipCDScript = gCoreContext->GetSetting("PostCDRipScript");

    if (!PostRipCDScript.isEmpty())
	myth_system(PostRipCDScript);

    QApplication::postEvent(
        m_parent, new RipStatusEvent(RipStatusEvent::kFinishedEvent, ""));
}
Ejemplo n.º 13
0
int Playlist::writeTree(GenericTree *tree_to_write_to, int a_counter)
{
    // compute max/min playcount,lastplay for this playlist
    int playcountMin = 0;
    int playcountMax = 0;
    double lastplayMin = 0.0;
    double lastplayMax = 0.0;

    typedef map<QString, uint32_t> AlbumMap;
    AlbumMap                       album_map;
    AlbumMap::iterator             Ialbum;
    QString                        album;

    typedef map<QString, uint32_t> ArtistMap;
    ArtistMap                      artist_map;
    ArtistMap::iterator            Iartist;
    QString                        artist;

    uint idx = 0;
    SongList::const_iterator it = songs.begin();
    for (; it != songs.end(); ++it, ++idx)
    {
        if (!(*it)->getCDFlag())
        {
            if ((*it)->getValue() == 0)
            {
                VERBOSE(VB_IMPORTANT, LOC_ERR + kID0err);
            }
            if ((*it)->getValue() > 0)
            {
                // Normal track
                Metadata *tmpdata =
                    all_available_music->getMetadata((*it)->getValue());
                if (tmpdata)
                {
                    if (tmpdata->isVisible())
                    {
                        if (0 == idx)
                        { // first song
                            playcountMin = playcountMax = tmpdata->PlayCount();
                            lastplayMin = lastplayMax = tmpdata->LastPlay().toTime_t();
                        }
                        else
                        {
                            if (tmpdata->PlayCount() < playcountMin)
                                playcountMin = tmpdata->PlayCount();
                            else if (tmpdata->PlayCount() > playcountMax)
                                playcountMax = tmpdata->PlayCount();

                            if (tmpdata->LastPlay().toTime_t() < lastplayMin)
                                lastplayMin = tmpdata->LastPlay().toTime_t();
                            else if (tmpdata->LastPlay().toTime_t() > lastplayMax)
                                lastplayMax = tmpdata->LastPlay().toTime_t();
                        }
                    }
                    // pre-fill the album-map with the album name.
                    // This allows us to do album mode in album order
                    album = tmpdata->Album();
                    // pre-fill the artist map with the artist name and song title
                    artist = tmpdata->Artist() + "~" + tmpdata->Title();
                }
                if ((Ialbum = album_map.find(album)) == album_map.end())
                    album_map.insert(AlbumMap::value_type(album,0));

                if ((Iartist = artist_map.find(artist)) == artist_map.end())
                    artist_map.insert(ArtistMap::value_type(artist,0));
            }
        }
    }
    // populate the sort id into the album map
    uint32_t album_count = 1;
    for (Ialbum = album_map.begin(); Ialbum != album_map.end(); Ialbum++)
    {
        Ialbum->second = album_count;
        album_count++;
    }

    // populate the sort id into the artist map
    uint32_t count = 1;
    for (Iartist = artist_map.begin(); Iartist != artist_map.end(); Iartist++)
    {
        Iartist->second = count;
        count++;
    }

    int RatingWeight = 2;
    int PlayCountWeight = 2;
    int LastPlayWeight = 2;
    int RandomWeight = 2;

    parent->FillIntelliWeights(RatingWeight, PlayCountWeight, LastPlayWeight,
                               RandomWeight);

    for (it = songs.begin(); it != songs.end(); ++it)
    {
        if (!(*it)->getCDFlag())
        {
            if ((*it)->getValue() == 0)
            {
                VERBOSE(VB_IMPORTANT, LOC_ERR + kID0err);
            }
            if ((*it)->getValue() > 0)
            {
                // Normal track
                Metadata *tmpdata =
                    all_available_music->getMetadata((*it)->getValue());
                if (tmpdata && tmpdata->isVisible())
                {
                    QString a_string = QString("%1 ~ %2")
                                       .arg(tmpdata->FormatArtist())
                                       .arg(tmpdata->FormatTitle());
                    GenericTree *added_node = tree_to_write_to->addNode(
                        a_string, (*it)->getValue(), true);
                    ++a_counter;
                    added_node->setAttribute(0, 1);
                    added_node->setAttribute(1, a_counter); //  regular order
                    added_node->setAttribute(2, rand()); //  random order

                    //
                    //  Compute "intelligent" weighting
                    //

                    int rating = tmpdata->Rating();
                    int playcount = tmpdata->PlayCount();
                    double lastplaydbl = tmpdata->LastPlay().toTime_t();
                    double ratingValue = (double)(rating) / 10;
                    double playcountValue, lastplayValue;

                    if (playcountMax == playcountMin)
                        playcountValue = 0;
                    else
                        playcountValue = ((playcountMin - (double)playcount)
                                         / (playcountMax - playcountMin) + 1);

                    if (lastplayMax == lastplayMin)
                        lastplayValue = 0;
                    else
                        lastplayValue = ((lastplayMin - lastplaydbl)
                                        / (lastplayMax - lastplayMin) + 1);

                    double rating_value =  (RatingWeight * ratingValue +
                                            PlayCountWeight * playcountValue +
                                            LastPlayWeight * lastplayValue +
                                            RandomWeight * (double)rand() /
                                            (RAND_MAX + 1.0));
                    uint32_t integer_rating = (int) (4000001 -
                                                     rating_value * 10000);
                    //  "intelligent" order
                    added_node->setAttribute(3, integer_rating);

                    // "intellegent/album" order
                    uint32_t album_order;
                    album = tmpdata->Album();
                    if ((Ialbum = album_map.find(album)) == album_map.end())
                    {
                        // we didn't find this album in the map,
                        // yet we pre-loaded them all. we are broken,
                        // but we just set the track order to 1, since there
                        // is no real point in reporting an error
                        album_order = 1;
                    }
                    else
                    {
                        album_order = Ialbum->second * 100;
                    }
                    album_order += tmpdata->Track();
                    added_node->setAttribute(4, album_order);

                    // "artist" order, sorts by artist name then track title
                    // uses the pre-prepared artist map to do this
                    uint32_t integer_order;
                    artist = tmpdata->Artist() + "~" + tmpdata->Title();
                    if ((Iartist = artist_map.find(artist)) == artist_map.end())
                    {
                        // we didn't find this track in the map,
                        // yet we pre-loaded them all. we are broken,
                        // but we just set the track order to 1, since there
                        // is no real point in reporting an error
                        integer_order = 1;
                    }
                    else
                    {
                        integer_order = Iartist->second;
                    }
                    added_node->setAttribute(5, integer_order);
                }
            }
            if ((*it)->getValue() < 0)
            {
                // it's a playlist, recurse (mildly)
                Playlist *level_down
                    = parent->getPlaylist(((*it)->getValue()) * -1);
                if (level_down)
                {
                    a_counter = level_down->writeTree(tree_to_write_to,
                                                      a_counter);
                }
            }
        }
        else
        {
            Metadata *tmpdata =
                all_available_music->getMetadata((*it)->getValue());
            if (tmpdata)
            {
                QString a_string = QString("(CD) %1 ~ %2")
                  .arg(tmpdata->FormatArtist()).arg(tmpdata->FormatTitle());

                if (tmpdata->FormatArtist().length() < 1 ||
                   tmpdata->FormatTitle().length() < 1)
                {
                    a_string = QString("(CD) Track %1").arg(tmpdata->Track());
                }
                GenericTree *added_node =
                    tree_to_write_to->addNode(a_string, (*it)->getValue(), true);
                ++a_counter;
                added_node->setAttribute(0, 1);
                added_node->setAttribute(1, a_counter); //  regular order
                added_node->setAttribute(2, rand()); //  random order
                added_node->setAttribute(3, rand()); //  "intelligent" order
            }
        }
    }
    return a_counter;
}
Ejemplo n.º 14
0
bool Ripper::deleteExistingTrack(RipTrack *track)
{
    if (!track)
        return false;

    Metadata *metadata = track->metadata;

    if (!metadata)
        return false;

    QString artist = metadata->Artist();
    QString album = metadata->Album();
    QString title = metadata->Title();

    MSqlQuery query(MSqlQuery::InitCon());
    QString queryString("SELECT song_id, "
            "CONCAT_WS('/', music_directories.path, music_songs.filename) AS filename "
            "FROM music_songs "
            "LEFT JOIN music_artists"
            " ON music_songs.artist_id=music_artists.artist_id "
            "LEFT JOIN music_albums"
            " ON music_songs.album_id=music_albums.album_id "
            "LEFT JOIN music_directories "
            " ON music_songs.directory_id=music_directories.directory_id "
            "WHERE artist_name REGEXP \'");
    QString token = artist;
    token.replace(QRegExp("(/|\\\\|:|\'|\\,|\\!|\\(|\\)|\"|\\?|\\|)"),
                  QString("."));

    queryString += token + "\' AND " + "album_name REGEXP \'";
    token = album;
    token.replace(QRegExp("(/|\\\\|:|\'|\\,|\\!|\\(|\\)|\"|\\?|\\|)"),
                  QString("."));
    queryString += token + "\' AND " + "name    REGEXP \'";
    token = title;
    token.replace(QRegExp("(/|\\\\|:|\'|\\,|\\!|\\(|\\)|\"|\\?|\\|)"),
                  QString("."));
    queryString += token + "\' ORDER BY artist_name, album_name,"
                           " name, song_id, filename LIMIT 1";
    query.prepare(queryString);

    if (!query.exec() || !query.isActive())
    {
        MythDB::DBError("Search music database", query);
        return false;
    }

    if (query.next())
    {
        int trackID = query.value(0).toInt();
        QString filename = gMusicData->musicDir + query.value(1).toString();

        // delete file
        if (!QFile::remove(filename))
        {
            LOG(VB_GENERAL, LOG_NOTICE, QString("Ripper::deleteExistingTrack() "
                                                "Could not delete %1")
                                                .arg(filename));
            return false;
        }

        // remove database entry
        MSqlQuery deleteQuery(MSqlQuery::InitCon());
        deleteQuery.prepare("DELETE FROM music_songs"
                            " WHERE song_id = :SONG_ID");
        deleteQuery.bindValue(":SONG_ID", trackID);
        if (!deleteQuery.exec())
        {
            MythDB::DBError("Delete Track", deleteQuery);
            return false;
        }
        return true;
    }

    return false;
}
Ejemplo n.º 15
0
void Ripper::ScanFinished()
{
    delete m_scanThread;
    m_scanThread = NULL;

    m_tracks->clear();

    bool isCompilation = false;
    if (m_decoder)
    {
        QString label;
        Metadata *metadata;

        m_artistName.clear();
        m_albumName.clear();
        m_genreName.clear();
        m_year.clear();

        for (int trackno = 0; trackno < m_decoder->getNumTracks(); trackno++)
        {
            RipTrack *ripTrack = new RipTrack;

            metadata = m_decoder->getMetadata(trackno + 1);
            if (metadata)
            {
                ripTrack->metadata = metadata;
                ripTrack->length = metadata->Length();

                if (metadata->Compilation())
                {
                    isCompilation = true;
                    m_artistName = metadata->CompilationArtist();
                }
                else if (m_artistName.isEmpty())
                {
                    m_artistName = metadata->Artist();
                }

                if (m_albumName.isEmpty())
                    m_albumName = metadata->Album();

                if (m_genreName.isEmpty() && !metadata->Genre().isEmpty())
                    m_genreName = metadata->Genre();

                if (m_year.isEmpty() && metadata->Year() > 0)
                    m_year = QString::number(metadata->Year());

                QString title = metadata->Title();
                ripTrack->isNew = isNewTune(m_artistName, m_albumName, title);

                ripTrack->active = ripTrack->isNew;

                m_tracks->push_back(ripTrack);

            }
            else
                delete ripTrack;
        }

        m_artistEdit->SetText(m_artistName);
        m_albumEdit->SetText(m_albumName);
        m_genreEdit->SetText(m_genreName);
        m_yearEdit->SetText(m_year);
        m_compilationCheck->SetCheckState(isCompilation);

        if (!isCompilation)
            m_switchTitleArtist->SetVisible(false);
        else
            m_switchTitleArtist->SetVisible(true);
    }

    BuildFocusList();
    updateTrackList();

    CloseBusyPopup();
}
Ejemplo n.º 16
0
int Playlist::CreateCDMP3(void)
{
    // Check & get global settings
    if (!gCoreContext->GetNumSetting("CDWriterEnabled"))
    {
        VERBOSE(VB_GENERAL, "CD Writer is not enabled.");
        return 1;
    }

    QString scsidev = MediaMonitor::defaultCDWriter();
    if (scsidev.isEmpty())
    {
        VERBOSE(VB_GENERAL, "No CD Writer device defined.");
        return 1;
    }

    int disksize = gCoreContext->GetNumSetting("CDDiskSize", 2);
    QString writespeed = gCoreContext->GetSetting("CDWriteSpeed", "2");
    bool MP3_dir_flag = gCoreContext->GetNumSetting("CDCreateDir", 1);

    double size_in_MB = 0.0;

    QStringList reclist;

    SongList::const_iterator it = songs.begin();
    for (; it != songs.end(); ++it)
    {
        if ((*it)->getCDFlag())
            continue;

        if ((*it)->getValue() == 0)
        {
            VERBOSE(VB_IMPORTANT, kID0err);
        }
        else if ((*it)->getValue() > 0)
        {
            // Normal track
            Metadata *tmpdata =
                all_available_music->getMetadata((*it)->getValue());
            if (tmpdata)
            {
                // check filename..
                QFileInfo testit(tmpdata->Filename());
                if (!testit.exists())
                    continue;
                size_in_MB += testit.size() / 1000000.0;
                QString outline;
                if (MP3_dir_flag)
                {
                    if (tmpdata->Artist().length() > 0)
                        outline += tmpdata->Artist() + "/";
                    if (tmpdata->Album().length() > 0)
                        outline += tmpdata->Album() + "/";
                }

                outline += "=";
                outline += tmpdata->Filename();

                reclist += outline;
            }
        }
        else if ((*it)->getValue() < 0)
        {
            // FIXME: handle playlists
        }
    }

    int max_size;
    if (disksize == 0)
        max_size = 650;
    else
        max_size = 700;

    if (size_in_MB >= max_size)
    {
        VERBOSE(VB_GENERAL, "MP3 CD creation aborted -- cd size too big.");
        return 1;
    }

    // probably should tie stdout of mkisofs to stdin of cdrecord sometime
    QString tmptemplate("/tmp/mythmusicXXXXXX");

    QString tmprecordlist = createTempFile(tmptemplate);
    if (tmprecordlist == tmptemplate)
    {
        VERBOSE(VB_IMPORTANT, "Unable to open temporary file");
        return 1;
    }

    QString tmprecordisofs = createTempFile(tmptemplate);
    if (tmprecordisofs == tmptemplate)
    {
        VERBOSE(VB_IMPORTANT, "Unable to open temporary file");
        return 1;
    }

    QFile reclistfile(tmprecordlist);

    if (!reclistfile.open(QIODevice::WriteOnly))
    {
        VERBOSE(VB_IMPORTANT, "Unable to open temporary file");
        return 1;
    }

    QTextStream recstream(&reclistfile);

    QStringList::Iterator iter;

    for (iter = reclist.begin(); iter != reclist.end(); ++iter)
    {
        recstream << *iter << "\n";
    }

    reclistfile.close();

    MythProgressDialog *progress;
    progress = new MythProgressDialog(QObject::tr("Creating CD File System"),
                                      100);
    progress->setProgress(1);

    QStringList args("mkisofs");
    args += "-graft-points";
    args += "-path-list";
    args += tmprecordlist;
    args += "-o";
    args += tmprecordisofs;
    args += "-J";
    args += "-R";

    VERBOSE(VB_GENERAL, "Running: " + args.join(" "));

    bool retval = 0;

    Q3Process isofs(args);

    if (isofs.start())
    {
        while (1)
        {
            while (isofs.canReadLineStderr())
            {
                QString buf = isofs.readLineStderr();
                if (buf[6] == '%')
                {
                    buf = buf.mid(0, 3);
                    progress->setProgress(buf.trimmed().toInt());
                }
            }
            if (isofs.isRunning())
            {
                qApp->processEvents();
                usleep(100000);
            }
            else
            {
                if (!isofs.normalExit())
                {
                    VERBOSE(VB_IMPORTANT, "Unable to run 'mkisofs'");
                    retval = 1;
                }
                break;
            }
        }
    }
    else
    {
        VERBOSE(VB_IMPORTANT, "Unable to run 'mkisofs'");
        retval = 1;
    }

    progress->Close();
    progress->deleteLater();

    progress = new MythProgressDialog(QObject::tr("Burning CD"), 100);
    progress->setProgress(2);

    args = QStringList("cdrecord");
    args += "-v";
    //args += "-dummy";
    args += "dev=";
    args += scsidev;

    if (writespeed.toInt() > 0)
    {
        args += "-speed=";
        args += writespeed;
    }

    args += "-data";
    args += tmprecordisofs;

    VERBOSE(VB_GENERAL, "Running: " + args.join(" "));

    Q3Process burn(args);

    if (burn.start())
    {
        while (1)
        {
            while (burn.canReadLineStderr())
            {
                QString err = burn.readLineStderr();
                if (err == "cdrecord: Drive needs to reload the media" ||
                    err == "cdrecord: Input/output error." ||
                    err == "cdrecord: No disk / Wrong disk!")
                {
                    VERBOSE(VB_IMPORTANT, err);
                    burn.kill();
                    retval = 1;
                }
            }
            while (burn.canReadLineStdout())
            {
                QString line = burn.readLineStdout();
                if (line.mid(15, 2) == "of")
                {
                    int mbdone = line.mid(10, 5).trimmed().toInt();
                    int mbtotal = line.mid(17, 5).trimmed().toInt();

                    if (mbtotal > 0)
                    {
                        progress->setProgress((mbdone * 100) / mbtotal);
                    }
                }
            }

            if (burn.isRunning())
            {
                qApp->processEvents();
                usleep(10000);
            }
            else
            {
                if (!burn.normalExit())
                {
                    VERBOSE(VB_IMPORTANT, "Unable to run 'cdrecord'");
                    retval = 1;
                }
                break;
            }
        }
    }
    else
    {
        VERBOSE(VB_IMPORTANT, "Unable to run 'cdrecord'");
        retval = 1;
    }

    progress->Close();
    progress->deleteLater();

    QFile::remove(tmprecordlist);
    QFile::remove(tmprecordisofs);

    return retval;
}
Ejemplo n.º 17
0
void ImportMusicDialog::addPressed()
{
    if (m_tracks->size() == 0)
        return;

    Metadata *meta = m_tracks->at(m_currentTrack)->metadata;

    // is the current track a new file?
    if (m_tracks->at(m_currentTrack)->isNewTune)
    {
        // get the save filename - this also creates the correct directory stucture
        QString saveFilename = Ripper::filenameFromMetadata(meta);

        // we need to manually copy the file extension
        QFileInfo fi(meta->Filename());
        saveFilename += "." + fi.suffix();

        // copy the file to the new location
        if (!copyFile(meta->Filename(), saveFilename))
        {
            ShowOkPopup(tr("Copy Failed\nCould not copy file to: %1")
                                                        .arg(saveFilename));
            return;
        }

        meta->setFilename(saveFilename);

        // do we need to update the tags?
        if (m_tracks->at(m_currentTrack)->metadataHasChanged)
        {
            Decoder *decoder = Decoder::create(saveFilename, NULL, NULL, true);
            if (decoder)
            {
                decoder->commitMetadata(meta);
                delete decoder;
            }
        }

        // update the database
        meta->dumpToDatabase();

        // read any embedded images from the tag
        MetaIO *tagger = meta->getTagger();
        if (tagger && tagger->supportsEmbeddedImages())
        {
            AlbumArtList artList = tagger->getAlbumArtList(meta->Filename());
            meta->setEmbeddedAlbumArt(artList);
            meta->getAlbumArtImages()->dumpToDatabase();
        }

        m_somethingWasImported = true;

        m_tracks->at(m_currentTrack)->isNewTune = Ripper::isNewTune(
                meta->Artist(), meta->Album(), meta->Title());

        // update the UI
        fillWidgets();
    }
    else
        ShowOkPopup(tr("This track is already in the database"));
}
Ejemplo n.º 18
0
void DatabaseBox::entered(UIListTreeType *treetype, UIListGenericTree *item)
{
    if (!item || !treetype)
        return;

    // Determin if this is a CD entry
    bool cd = false;
    if (dynamic_cast<CDCheckItem*>(item))
      cd = true;

    TreeCheckItem *item_ptr = dynamic_cast<TreeCheckItem*>(item);

    if (item_ptr
        && item->childCount() == 0
        && item_ptr->getLevel() == "title")
    {
        int id = item_ptr->getID();

        Metadata *mdata;
        if (!cd)
        {
            mdata = gMusicData->all_music->getMetadata(id);
            if (!mdata)
                return;
        }
        else
        {
            // Need to allocate storage for CD Metadata
            mdata = new Metadata;
            if (!gMusicData->all_music->getCDMetadata(id, mdata))
            {
                delete mdata;
                return;
            }
        }

        unsigned int line = 0;
        QString tmpstr;

        if (mdata->Compilation())
        {
            tmpstr = tr("Compilation Artist:\t") + mdata->CompilationArtist();
            if (m_lines.at(line))
                m_lines.at(line++)->SetText(tmpstr);
        }

        tmpstr = tr("Artist:\t") + mdata->Artist();
        if (m_lines.at(line))
            m_lines.at(line++)->SetText(tmpstr);

        tmpstr = tr("Album:\t") + mdata->Album();
        if (m_lines.at(line))
            m_lines.at(line++)->SetText(tmpstr);

        tmpstr = tr("Title:\t") + mdata->Title();
        if (m_lines.at(line))
            m_lines.at(line++)->SetText(tmpstr);

        if (m_lines.at(line))
        {
            int maxTime = mdata->Length() / 1000;

            int maxh = maxTime / 3600;
            int maxm = (maxTime / 60) % 60;
            int maxs = maxTime % 60;

            QString timeStr;
            if (maxh > 0)
                timeStr.sprintf("%02d:%02d:%02d", maxh, maxm, maxs);
            else
                timeStr.sprintf("%02d:%02d", maxm, maxs);

            tmpstr = tr("Length:\t") + timeStr;

            m_lines.at(line++)->SetText(tmpstr);
        }

        tmpstr = tr("Genre: ") + mdata->Genre();

        if (m_lines.at(line))
        {
            m_lines.at(line)->SetText(tmpstr);
        }
        else
        {
            QString prevvalue = m_lines.at(line-1)->GetText();
            tmpstr = prevvalue + "            " + tmpstr;
            m_lines.at(line-1)->SetText(tmpstr);
        }

        // Pre increment as not incremented from previous use.
        while (++line < (unsigned) m_lines.size())
          m_lines.at(line)->SetText("");

        // Don't forget to delete the mdata storage if we allocated it.
        if (cd)
          delete mdata;

        return;
    }

    QStringList pathto = treetype->getRouteToCurrent();

    int linelen = 0;
    int dispat = 0;
    QString data;

    for (QStringList::Iterator it = pathto.begin();
         it != pathto.end(); ++it)
    {
        if (it == pathto.begin())
            continue;

        if (!data.isEmpty())
            data += "  /  ";

        data += *it;
        linelen++;
        if (linelen == 2)
        {
            if (m_lines.at(dispat))
            {
                m_lines.at(dispat)->SetText(data);
            }

            data.clear();
            linelen = 0;
            dispat++;
        }
    }

    if (linelen != 0)
    {
        if (m_lines.at(dispat))
        {
            m_lines.at(dispat)->SetText(data);
        }
        dispat++;
    }

    for (unsigned int i = dispat; i < (unsigned) m_lines.size(); i++)
        m_lines.at(i)->SetText("");
}
Ejemplo n.º 19
0
int Playlist::CreateCDMP3(void)
{
    // Check & get global settings
    if (!gCoreContext->GetNumSetting("CDWriterEnabled"))
    {
        LOG(VB_GENERAL, LOG_ERR, "CD Writer is not enabled.");
        return 1;
    }

    QString scsidev = MediaMonitor::defaultCDWriter();
    if (scsidev.isEmpty())
    {
        LOG(VB_GENERAL, LOG_ERR, "No CD Writer device defined.");
        return 1;
    }

    int disksize = gCoreContext->GetNumSetting("CDDiskSize", 2);
    QString writespeed = gCoreContext->GetSetting("CDWriteSpeed", "2");
    bool MP3_dir_flag = gCoreContext->GetNumSetting("CDCreateDir", 1);

    double size_in_MB = 0.0;

    QStringList reclist;

    SongList::const_iterator it = songs.begin();
    for (; it != songs.end(); ++it)
    {
        if ((*it)->getCDFlag())
            continue;

        if ((*it)->getValue() == 0)
        {
            LOG(VB_GENERAL, LOG_ERR, kID0err);
        }
        else if ((*it)->getValue() > 0)
        {
            // Normal track
            Metadata *tmpdata =
                all_available_music->getMetadata((*it)->getValue());
            if (tmpdata)
            {
                // check filename..
                QFileInfo testit(tmpdata->Filename());
                if (!testit.exists())
                    continue;
                size_in_MB += testit.size() / 1000000.0;
                QString outline;
                if (MP3_dir_flag)
                {
                    if (tmpdata->Artist().length() > 0)
                        outline += tmpdata->Artist() + "/";
                    if (tmpdata->Album().length() > 0)
                        outline += tmpdata->Album() + "/";
                }

                outline += "=";
                outline += tmpdata->Filename();

                reclist += outline;
            }
        }
        else if ((*it)->getValue() < 0)
        {
            // FIXME: handle playlists
        }
    }

    int max_size;
    if (disksize == 0)
        max_size = 650;
    else
        max_size = 700;

    if (size_in_MB >= max_size)
    {
        LOG(VB_GENERAL, LOG_ERR, "MP3 CD creation aborted -- cd size too big.");
        return 1;
    }

    // probably should tie stdout of mkisofs to stdin of cdrecord sometime
    QString tmptemplate("/tmp/mythmusicXXXXXX");

    QString tmprecordlist = createTempFile(tmptemplate);
    if (tmprecordlist == tmptemplate)
    {
        LOG(VB_GENERAL, LOG_ERR, "Unable to open temporary file");
        return 1;
    }

    QString tmprecordisofs = createTempFile(tmptemplate);
    if (tmprecordisofs == tmptemplate)
    {
        LOG(VB_GENERAL, LOG_ERR, "Unable to open temporary file");
        return 1;
    }

    QFile reclistfile(tmprecordlist);

    if (!reclistfile.open(QIODevice::WriteOnly))
    {
        LOG(VB_GENERAL, LOG_ERR, "Unable to open temporary file");
        return 1;
    }

    QTextStream recstream(&reclistfile);

    QStringList::Iterator iter;

    for (iter = reclist.begin(); iter != reclist.end(); ++iter)
    {
        recstream << *iter << "\n";
    }

    reclistfile.close();

    progress = new MythProgressDialog(QObject::tr("Creating CD File System"),
                                      100);
    progress->setProgress(1);

    QStringList args;
    QString command;

    command = "mkisofs";
    args << "-graft-points";
    args << "-path-list";
    args << tmprecordlist;
    args << "-o";
    args << tmprecordisofs;
    args << "-J";
    args << "-R";

    uint flags = kMSRunShell | kMSStdErr | kMSBuffered |
                 kMSDontDisableDrawing | kMSDontBlockInputDevs | 
                 kMSRunBackground;

    proc = new MythSystem(command, args, flags);

    connect(proc, SIGNAL(readDataReady(int)), this, SLOT(mkisofsData(int)), 
            Qt::DirectConnection);
    connect(proc, SIGNAL(finished()),         this, SLOT(processExit()), 
            Qt::DirectConnection);
    connect(proc, SIGNAL(error(uint)),        this, SLOT(processExit(uint)), 
            Qt::DirectConnection);

    procExitVal = GENERIC_EXIT_RUNNING;
    proc->Run();

    while( procExitVal == GENERIC_EXIT_RUNNING )
        usleep( 100000 );

    uint retval = procExitVal;

    progress->Close();
    progress->deleteLater();
    proc->disconnect();
    delete proc;

    if (retval)
    {
        LOG(VB_GENERAL, LOG_ERR, QString("Unable to run mkisofs: returns %1")
                .arg(retval));
    }
    else
    {
        progress = new MythProgressDialog(QObject::tr("Burning CD"), 100);
        progress->setProgress(2);

        command = "cdrecord";
        args = QStringList();
        args << "-v";
        //args << "-dummy";
        args << QString("dev=%1").arg(scsidev);

        if (writespeed.toInt() > 0)
        {
            args << "-speed=";
            args << writespeed;
        }

        args << "-data";
        args << tmprecordisofs;

        flags = kMSRunShell | kMSStdErr | kMSStdOut | kMSBuffered |
                kMSDontDisableDrawing | kMSDontBlockInputDevs |
                kMSRunBackground;

        proc = new MythSystem(command, args, flags);
        connect(proc, SIGNAL(readDataReady(int)), 
                this, SLOT(cdrecordData(int)), Qt::DirectConnection);
        connect(proc, SIGNAL(finished()),
                this, SLOT(processExit()), Qt::DirectConnection);
        connect(proc, SIGNAL(error(uint)),
                this, SLOT(processExit(uint)), Qt::DirectConnection);
        procExitVal = GENERIC_EXIT_RUNNING;
        proc->Run();

        while( procExitVal == GENERIC_EXIT_RUNNING )
            usleep( 100000 );

        retval = procExitVal;

        progress->Close();
        progress->deleteLater();
        proc->disconnect();
        delete proc;

        if (retval)
        {
            LOG(VB_GENERAL, LOG_ERR,
                QString("Unable to run cdrecord: returns %1") .arg(retval));
        }
    }

    QFile::remove(tmprecordlist);
    QFile::remove(tmprecordisofs);

    return retval;
}