예제 #1
0
void TrackInfoObject::parse() {
    // Log parsing of header information in developer mode. This is useful for
    // tracking down corrupt files.
    const QString& canonicalLocation = m_fileInfo.canonicalFilePath();
    if (CmdlineArgs::Instance().getDeveloper()) {
        qDebug() << "TrackInfoObject::parse()" << canonicalLocation;
    }

    // Parse the information stored in the sound file.
    SoundSourceProxy proxy(canonicalLocation, m_pSecurityToken);
    Mixxx::SoundSource* pProxiedSoundSource = proxy.getProxiedSoundSource();
    if (pProxiedSoundSource != NULL && proxy.parseHeader() == OK) {

        // Dump the metadata extracted from the file into the track.

        // TODO(XXX): This involves locking the mutex for every setXXX
        // method. We should figure out an optimization where there are private
        // setters that don't lock the mutex.

        // If Artist, Title and Type fields are not blank, modify them.
        // Otherwise, keep their current values.
        // TODO(rryan): Should we re-visit this decision?
        if (!(pProxiedSoundSource->getArtist().isEmpty())) {
            setArtist(pProxiedSoundSource->getArtist());
        }

        if (!(pProxiedSoundSource->getTitle().isEmpty())) {
            setTitle(pProxiedSoundSource->getTitle());
        }

        if (!(pProxiedSoundSource->getType().isEmpty())) {
            setType(pProxiedSoundSource->getType());
        }

        setAlbum(pProxiedSoundSource->getAlbum());
        setAlbumArtist(pProxiedSoundSource->getAlbumArtist());
        setYear(pProxiedSoundSource->getYear());
        setGenre(pProxiedSoundSource->getGenre());
        setComposer(pProxiedSoundSource->getComposer());
        setGrouping(pProxiedSoundSource->getGrouping());
        setComment(pProxiedSoundSource->getComment());
        setTrackNumber(pProxiedSoundSource->getTrackNumber());
        setReplayGain(pProxiedSoundSource->getReplayGain());
        setBpm(pProxiedSoundSource->getBPM());
        setDuration(pProxiedSoundSource->getDuration());
        setBitrate(pProxiedSoundSource->getBitrate());
        setSampleRate(pProxiedSoundSource->getSampleRate());
        setChannels(pProxiedSoundSource->getChannels());
        setKeyText(pProxiedSoundSource->getKey(),
                   mixxx::track::io::key::FILE_METADATA);
        setHeaderParsed(true);
    } else {
        qDebug() << "TrackInfoObject::parse() error at file"
                 << canonicalLocation;
        setHeaderParsed(false);

        // Add basic information derived from the filename:
        parseFilename();
    }
}
예제 #2
0
void EditMetadataDialog::searchGenre()
{
    QString msg = tr("Select a Genre");
    QStringList searchList = Metadata::fillFieldList("genre");
    // load genre list
    /*
    searchList.clear();
    for (int x = 0; x < genre_table_size; x++)
        searchList.push_back(QString(genre_table[x]));
    searchList.sort();
    */

    QString s = m_metadata->Genre();

    MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
    MythUISearchDialog *searchDlg = new MythUISearchDialog(popupStack, msg, searchList, false, s);

    if (!searchDlg->Create())
    {
        delete searchDlg;
        return;
    }

    connect(searchDlg, SIGNAL(haveResult(QString)), SLOT(setGenre(QString)));

    popupStack->AddScreen(searchDlg);
}
예제 #3
0
void PluginTrack::loadTrack(const QString &service, const QVariantMap &track) {
    setService(service);
    setArtist(track.value("artist").toString());
    setArtistId(track.value("artistId").toString());
    setDate(track.value("date").toString());
    setDescription(track.value("description").toString());
    setDownloadable(track.value("downloadable", true).toBool());
    setFormat(track.value("format").toString());
    setGenre(track.value("genre").toString());
    setId(track.value("id").toString());
    setLargeThumbnailUrl(track.value("largeThumbnailUrl").toString());
    setPlayCount(track.value("playCount").toLongLong());
    setStreamUrl(track.value("streamUrl").toString());
    setThumbnailUrl(track.value("thumbnailUrl").toString());
    setTitle(track.value("title").toString());
    setUrl(track.value("url").toString());
        
    if (track.value("duration").type() == QVariant::String) {
        setDurationString(track.value("duration").toString());
    }
    else {
        setDuration(track.value("duration").toLongLong());
    }
    
    if (track.value("size").type() == QVariant::String) {
        setSizeString(track.value("size").toString());
    }
    else {
        setSize(track.value("size").toLongLong());
    }
}
예제 #4
0
bool Media::setValueForRole(int role, const QVariant& value)
{
    switch (role) {
        case MediaCenter::MediaTypeRole:
            return setType(value.toString());
        case Qt::DisplayRole:
            return setTitle(value.toString());
        case MediaCenter::MediaUrlRole:
            if (d->url != value.toString()) {
                qDebug() << d->url << value.toString();
                qFatal("Media URLs CANNOT be changed");
            }
            return false;
        case Qt::DecorationRole:
            return thumbnail().isEmpty() ? setThumbnail(value.toString()) : false;
        case MediaCenter::CreatedAtRole:
            return setCreatedAt(value.toDateTime());
        case MediaCenter::GenreRole:
            return setGenre(value.toString());
        case MediaCenter::DurationRole :
            return setDuration(value.toInt());
        case MediaCenter::RatingRole :
            return setRating(value.toInt());
        default:
            //qWarning() << "Unknown role " << role << " for value " << value;
            return false;
    }
}
예제 #5
0
// when API-information is loaded, values are extracted
void TvShow::onShowInfoFilled()
{
    setTitle(info->showInfo->value("Show Name"));
    setStarted(info->showInfo->value("Started"));
    setStatus(info->showInfo->value("Status"));
    setAirtime(info->showInfo->value("Airtime"));
    setNetwork(info->showInfo->value("Network"));
    setGenre(info->showInfo->value("Genres"));
    setLatestEpisode(info->showInfo->value("Latest Episode"));
    setNextEpisode(info->showInfo->value("Next Episode"));
    setImageUrl(info->showInfo->value("Image Url"));

    // All data is loaded, now show can be added to QList
    emit allDataLoaded(this);
}
예제 #6
0
	void GraffitiTab::save ()
	{
		const auto& modified = FilesModel_->GetModified ();
		if (modified.isEmpty ())
			return;

		if (QMessageBox::question (this,
				"LMP Graffiti",
				tr ("Do you really want to accept changes to %n file(s)?", 0, modified.size ()),
				QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)
			return;

		ITagResolver *resolver = LMPProxy_->GetTagResolver ();

		auto toTLStr = [] (const QString& str)
		{
			return TagLib::String (str.toUtf8 ().constData (), TagLib::String::UTF8);
		};

		for (const auto& pair : modified)
		{
			const auto& newInfo = pair.first;

			QMutexLocker locker (&resolver->GetMutex ());
			auto file = resolver->GetFileRef (newInfo.LocalPath_);
			auto tag = file.tag ();

			tag->setArtist (toTLStr (newInfo.Artist_));
			tag->setAlbum (toTLStr (newInfo.Album_));
			tag->setTitle (toTLStr (newInfo.Title_));
			tag->setYear (newInfo.Year_);
			tag->setGenre (toTLStr (newInfo.Genres_.join (" / ")));
			tag->setTrack (newInfo.TrackNumber_);

			if (!file.save ())
				qWarning () << Q_FUNC_INFO
						<< "unable to save file"
						<< newInfo.LocalPath_;
		}

		handleRereadFiles ();
	}
예제 #7
0
void ImportMusicDialog::showMenu()
{
    if (m_popupMenu)
        return;

    if (m_tracks->size() == 0)
        return;

    MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");

    MythDialogBox *menu = new MythDialogBox("", popupStack, "importmusicmenu");

    if (menu->Create())
        popupStack->AddScreen(menu);
    else
    {
        delete menu;
        return;
    }

    menu->SetReturnEvent(this, "menu");
    menu->AddButton(tr("Save Defaults"), SLOT(saveDefaults()));

    if (m_haveDefaults)
    {
        menu->AddButton(tr("Change Compilation Flag"), SLOT(setCompilation()));
        menu->AddButton(tr("Change Compilation Artist"),
                                SLOT(setCompilationArtist()));
        menu->AddButton(tr("Change Artist"), SLOT(setArtist()));
        menu->AddButton(tr("Change Album"), SLOT(setAlbum()));
        menu->AddButton(tr("Change Genre"), SLOT(setGenre()));
        menu->AddButton(tr("Change Year"), SLOT(setYear()));
        menu->AddButton(tr("Change Rating"), SLOT(setRating()));
    }

    menu->AddButton(tr("Cancel"));
}
예제 #8
0
void PL_OggFile::setValue(dataColumn x,QVariant& value,bool replace)
{
  if(!linked)
    link();
  oggtagger->setValue(x,value,replace);
 bool a;
  switch(x)
  {
  case TITLE:
    setTitle(value.toString());
    break;
  case ARTIST:
    setArtist(value.toString());
    break;
  case ALBUM:
    setAlbumtitle(value.toString());
    break;
  case GENRE:
    setGenre(value.toInt(&a));
    break;
 case COMMENT:
    setComment(value.toString());
    break;
  case YEAR:
    setYear(value.toInt(&a));
    break;
  case TRACK:
    setTrack(value.toInt(&a));
    break;
  case TIME:
  case BITRATE:
  case PICTURE:
    break;
  }
  
 
}
예제 #9
0
bool SoundSource::processTaglibFile(TagLib::File& f) {
    if (s_bDebugMetadata)
        qDebug() << "Parsing" << getFilename();

    if (f.isValid()) {
        TagLib::Tag *tag = f.tag();
        if (tag) {
            QString title = TStringToQString(tag->title());
            setTitle(title);

            QString artist = TStringToQString(tag->artist());
            setArtist(artist);

            QString album = TStringToQString(tag->album());
            setAlbum(album);

            QString comment = TStringToQString(tag->comment());
            setComment(comment);

            QString genre = TStringToQString(tag->genre());
            setGenre(genre);

            int iYear = tag->year();
            QString year = "";
            if (iYear > 0) {
                year = QString("%1").arg(iYear);
                setYear(year);
            }

            int iTrack = tag->track();
            QString trackNumber = "";
            if (iTrack > 0) {
                trackNumber = QString("%1").arg(iTrack);
                setTrackNumber(trackNumber);
            }

            if (s_bDebugMetadata)
                qDebug() << "TagLib" << "title" << title << "artist" << artist << "album" << album << "comment" << comment << "genre" << genre << "year" << year << "trackNumber" << trackNumber;
        }

        TagLib::AudioProperties *properties = f.audioProperties();
        if (properties) {
            int lengthSeconds = properties->length();
            int bitrate = properties->bitrate();
            int sampleRate = properties->sampleRate();
            int channels = properties->channels();

            if (s_bDebugMetadata)
                qDebug() << "TagLib" << "length" << lengthSeconds << "bitrate" << bitrate << "sampleRate" << sampleRate << "channels" << channels;

            setDuration(lengthSeconds);
            setBitrate(bitrate);
            setSampleRate(sampleRate);
            setChannels(channels);
        }

        // If we didn't get any audio properties, this was a failure.
        return (properties!=NULL);
    }
    return false;
}
예제 #10
0
void Film::chargement(QDomElement & element)
{
    QDomNodeList pluton = element.elementsByTagName("nom");
    if(pluton.size() > 0)
    {
        setNom(pluton.at(0).toElement().text());
    }
    else
    {
        throw QString("Il manque le nom");
    }

    pluton = element.elementsByTagName("genre");

    if(pluton.size() > 0)
    {
        setGenre(pluton.at(0).toElement().text());
    }
    else
    {
        throw QString("Il manque le genre");
    }

    pluton = element.elementsByTagName("date");

    if(pluton.size() > 0)
    {
        setDate(QDate::fromString(pluton.at(0).toElement().text(), "d/M/yyyy"));
    }
    else
    {
        throw QString("Il manque la date");
    }

    pluton = element.elementsByTagName("vue");
    if(pluton.size() > 0)
    {
        setFini(pluton.at(0).toElement().text().toInt());
    }
    else
    {
        throw QString("Il manque fini");
    }

    pluton = element.elementsByTagName("url");
    if(pluton.size() > 0)
    {
        setUrl(QUrl(pluton.at(0).toElement().text()));
    }
    else
    {
        throw QString("Il manque l'url");
    }

    pluton = element.elementsByTagName("realisateur");

    if(pluton.size() > 0)
    {
        setRealisateur(pluton.at(0).toElement().text());
    }
    else
    {
        throw QString("Il manque le réalisateur");
    }

    pluton = element.elementsByTagName("scenariste");

    if(pluton.size() > 0)
    {
        setScenariste(pluton.at(0).toElement().text());
    }
    else
    {
        throw QString("Il manque le scenariste");
    }

    pluton = element.elementsByTagName("support");
    if(pluton.size() > 0)
    {
        setSupport((Film::Support)pluton.at(0).toElement().text().toInt());
    }
    else
    {
        throw QString("Il manque le support");
    }

    pluton = element.elementsByTagName("duree");

    if(pluton.size() > 0)
    {
        setDuree(QTime::fromString(pluton.at(0).toElement().text()));
    }
    else
    {
        throw QString("Il manque la durée");
    }

    pluton = element.elementsByTagName("acteur");

    for(int terra = 0; terra < pluton.size(); terra ++)
    {
        addActeur(pluton.at(terra).toElement().text());
    }

    pluton = element.elementsByTagName("type");

    if(pluton.size() > 0)
    {
        setType(pluton.at(0).toElement().text());
    }
    qDebug()<<"Chargement "<<nom()<<"ok";

}
예제 #11
0
bool ImportMusicDialog::keyPressEvent(QKeyEvent *event)
{
    if (GetFocusWidget() && GetFocusWidget()->keyPressEvent(event))
        return true;

    bool handled = false;
    QStringList actions;
    handled = GetMythMainWindow()->TranslateKeyPress("Global", event, actions);

    for (int i = 0; i < actions.size() && !handled; i++)
    {
        QString action = actions[i];
        handled = true;

        if (action == "LEFT")
        {
            m_prevButton->Push();
        }
        else if (action == "RIGHT")
        {
            m_nextButton->Push();
        }
        else if (action == "EDIT")
        {
            showEditMetadataDialog();
        }
        else if (action == "MENU")
        {
            showMenu();
        }
        else if (action == "1")
        {
            setCompilation();
        }
        else if (action == "2")
        {
            setCompilationArtist();
        }
        else if (action == "3")
        {
            setArtist();
        }
        else if (action == "4")
        {
            setAlbum();
        }
        else if (action == "5")
        {
            setGenre();
        }
        else if (action == "6")
        {
            setYear();
        }
        else if (action == "7")
        {
            setRating();
        }
        else if (action == "8")
        {
            setTitleWordCaps();
        }
        else if (action == "9")
        {
            setTitleInitialCap();
        }
        else if (action == "0")
        {
            setTrack();
        }
        else
            handled = false;
    }

    if (!handled && MythScreenType::keyPressEvent(event))
        handled = true;

    return handled;
}
예제 #12
0
파일: rominfo.cpp 프로젝트: MythTV/mythtv
void RomInfo::fillData()
{
    if (m_gamename == "")
    {
        return;
    }

    MSqlQuery query(MSqlQuery::InitCon());

    QString systemtype;
    if (m_system != "") {
        systemtype  += " AND system = :SYSTEM ";
    }

    QString thequery = "SELECT system,gamename,genre,year,romname,favorite,"
                       "rompath,country,crc_value,diskcount,gametype,plot,publisher,"
                       "version,screenshot,fanart,boxart,inetref,intid FROM gamemetadata "
                       "WHERE gamename = :GAMENAME "
                       + systemtype + " ORDER BY diskcount DESC";

    query.prepare(thequery);
    query.bindValue(":SYSTEM", m_system);
    query.bindValue(":GAMENAME", m_gamename);

    if (query.exec() && query.next())
    {
        setSystem(query.value(0).toString());
        setGamename(query.value(1).toString());
        setGenre(query.value(2).toString());
        setYear(query.value(3).toString());
        setRomname(query.value(4).toString());
        setField("favorite",query.value(5).toString());
        setRompath(query.value(6).toString());
        setCountry(query.value(7).toString());
        setCRC_VALUE(query.value(8).toString());
        setDiskCount(query.value(9).toInt());
        setGameType(query.value(10).toString());
        setPlot(query.value(11).toString());
        setPublisher(query.value(12).toString());
        setVersion(query.value(13).toString());
        setScreenshot(query.value(14).toString());
        setFanart(query.value(15).toString());
        setBoxart(query.value(16).toString());
        setInetref(query.value(17).toString());
        setId(query.value(18).toInt());
    }

    setRomCount(romInDB(m_romname,m_gametype));

    // If we have more than one instance of this rom in the DB fill in all
    // systems available to play it.
    if (RomCount() > 1)
    {
        query.prepare("SELECT DISTINCT system FROM gamemetadata "
                      "WHERE romname = :ROMNAME");
        query.bindValue(":ROMNAME", Romname());
        if (!query.exec())
            MythDB::DBError("RomInfo::fillData - selecting systems", query);

        while (query.next())
        {
            if (m_allsystems.isEmpty())
                m_allsystems = query.value(0).toString();
            else
                m_allsystems += "," + query.value(0).toString();
        }
    }
    else
    {
        m_allsystems = m_system;
    }
}
void PhononItem::metaStateChanged(Phonon::State newState, Phonon::State oldState) {
    Q_UNUSED(oldState);
  //  static QObjectWriter writer(this, false);

    if (newState == Phonon::ErrorState) {
        qDebug() << "PhononItem: Error Opening File: " << fileName();

        emit fetched(false);
        return;
    }

    if (m_metaMedia->currentSource().type() == Phonon::MediaSource::Invalid) {

        emit fetched(false);
        qDebug() << "Invalid metadata: " << fileName();
        return;
    }

    QMap<QString, QString> metaData = m_metaMedia->metaData();

    setArtist(metaData.value("ARTIST"));
    setTrackTitle(metaData.value("TITLE"));
    setAlbumTitle(metaData.value("ALBUM"));
    setGenre(metaData.value("GENRE"));
    QString tn = metaData.value("TRACK-NUMBER");
    if (tn == QString()) tn = metaData.value("TRACKNUMBER");
    setTrackNumber(tn);
    extendedComment = QString();
    QString comment =  metaData.value("COMMENT");
    setComment(comment);
    
    // http://www.freedesktop.org/wiki/Specifications/free-media-player-specs
    QString fmpsRating = metaData.value("FMPS_Rating");
    // ??? Why does this not work?
    if (fmpsRating.toDouble() > 0 ) {
        int stars = fmpsRating.toDouble() * 10;
        Preference fmpsPref(stars);
        qDebug() << "FMPS Rating: " << stars;
        setPreference(fmpsPref);
    }

    // Preference can be obtained from various ways.
    else setPreference(comment);

    // Check for MusicMatch preference
    if ((preference().intValue() == 0) && metaData.contains("EXTENDED-COMMENT")) {
        extendedComment = metaData.value("EXTENDED-COMMENT");
        int eqidx = extendedComment.indexOf("=");
        if (eqidx > 0)
            extendedComment=extendedComment.mid(eqidx+1);
        Preference p(extendedComment);
        if (p.intValue() > 0) {
            setPreference(p);
            setComment(p.toString());
        }
    }

//start id="notify"
    m_loaded = true;
    if (m_timeSet) {
        emit fetched();
    }
//end

}
예제 #14
0
void BandeDessine::chargement(QDomElement & element)
{
    QDomNodeList artemis = element.elementsByTagName("nom");

    if(artemis.size() != 0)
    {
        setNom(artemis.at(0).toElement().text());
    }
    else
    {
        throw QString("Il manque le nom");
    }

    artemis = element.elementsByTagName("date");

    if(artemis.size() != 0)
    {
        setDate(QDate::fromString(artemis.at(0).toElement().text()));
    }
    else
    {
        throw QString("Il manque la date");
    }
    artemis = element.elementsByTagName("genre");

    if(artemis.size() != 0)
    {
        setGenre(artemis.at(0).toElement().text());
    }
    else
    {
        throw QString("Il manque le nom");
    }
    artemis = element.elementsByTagName("url");

    if(artemis.size() != 0)
    {
        setUrl(QUrl(artemis.at(0).toElement().text()));
    }
    else
    {
        throw QString("Il manque l'url");
    }

    artemis = element.elementsByTagName("fini");

    if(artemis.size() != 0)
    {
        setFini(artemis.at(0).toElement().text().toInt());
    }
    else
    {
        throw QString("Il manque la balise fini");
    }

    artemis = element.elementsByTagName("lu");

    if(artemis.size() != 0)
    {
        setLu(artemis.at(0).toElement().text().toInt());
    }
    else
    {
        throw QString("Il manque la balise lu");
    }

    artemis = element.elementsByTagName("encoursachat");

    if(artemis.size() != 0)
    {
        setEnCoursAchat(artemis.at(0).toElement().text().toInt());
    }
    else
    {
        throw QString("Il manque la balise encoursachat");
    }

    artemis = element.elementsByTagName("tome");

    for(int zeus = 0; zeus < artemis.size(); zeus ++)
    {
        addTome(artemis.at(zeus).toElement().attribute("numero", "0").toInt(),
                artemis.at(zeus).toElement().text());
    }

    artemis = element.elementsByTagName("auteur");

    for(int zeus = 0; zeus < artemis.size(); zeus ++)
    {
        addAuteur(artemis.at(zeus).toElement().text());
    }

    artemis = element.elementsByTagName("dessinateur");

    for(int zeus = 0; zeus < artemis.size(); zeus ++)
    {
        addDessinateur(artemis.at(zeus).toElement().text());
    }

}
예제 #15
0
void Livre::chargement(QDomElement & e)
{
    QDomNodeList zeus = e.elementsByTagName ("nom");
    if(zeus.size () != 1)
    {
        throw QString("Il y a un souci sur la balise nom");
    }

    setNom(zeus.at (0).toElement ().text ());

    zeus = e.elementsByTagName ("url");
    if(zeus.size () == 1)
    {
        setUrl (zeus.at (0).toElement ().text ());
    }

    zeus = e.elementsByTagName ("genre");
    if(zeus.size () != 1)
    {
        throw QString("Il y a un souci sur la balise genre");
    }
    setGenre (zeus.at (0).toElement ().text ());

    zeus = e.elementsByTagName ("editeur");
    if(zeus.size () != 1)
    {
        throw QString("Il y a un souci sur la balise editeur");
    }
    setEditeur (zeus.at (0).toElement ().text ());

    zeus = e.elementsByTagName ("cycle");
    if(zeus.size () == 1)
    {
        QDomElement chronos = zeus.at (0).toElement ();
        setCycle(chronos.text ());
        setNumeroTome (chronos.attribute ("tome").toInt ());
    }

    zeus = e.elementsByTagName ("sortie");
    if(zeus.size () != 1)
    {
        throw QString("Il y a un souci sur la balise sortie");
    }

    setDate(QDate::fromString (zeus.at (0).toElement ().text ()));

    zeus = e.elementsByTagName ("auteur");
    if(zeus.size () == 0)
    {
        throw QString("Il manque au moins un auteur");
    }

    for(int venus = 0; venus < zeus.size (); venus ++)
    {
        addAuteur (zeus.at (venus).toElement ().text ());
    }

    zeus = e.elementsByTagName ("lu");

    if(zeus.size () != 1)
    {
        throw QString("Il y a un probleme avec la balise lu");
    }

    setFini (zeus.at (0).toElement ().text ().toInt ());
}
예제 #16
0
    }
    void endUpdate()
    {
        foreach( TrackEditorPtr ec, m_editors ) ec->endUpdate();
        m_batchMode = false;
        QTimer::singleShot( 0, m_collection, SLOT(slotUpdated()) );
    }
    void setComment( const QString &newComment ) { FORWARD( setComment( newComment ) ) }
    void setTrackNumber( int newTrackNumber ) { FORWARD( setTrackNumber( newTrackNumber ) ) }
    void setDiscNumber( int newDiscNumber ) { FORWARD( setDiscNumber( newDiscNumber ) ) }
    void setBpm( const qreal newBpm ) { FORWARD( setBpm( newBpm ) ) }
    void setTitle( const QString &newTitle ) { FORWARD( setTitle( newTitle ) ) }
    void setArtist( const QString &newArtist ) { FORWARD( setArtist( newArtist ) ) }
    void setAlbum( const QString &newAlbum ) { FORWARD( setAlbum( newAlbum ) ) }
    void setAlbumArtist( const QString &newAlbumArtist ) { FORWARD( setAlbumArtist ( newAlbumArtist ) ) }
    void setGenre( const QString &newGenre ) { FORWARD( setGenre( newGenre ) ) }
    void setComposer( const QString &newComposer ) { FORWARD( setComposer( newComposer ) ) }
    void setYear( int newYear ) { FORWARD( setYear( newYear ) ) }
private:
    bool m_batchMode;
    Collections::AggregateCollection *m_collection;
    QList<TrackEditorPtr> m_editors;
};

#undef FORWARD

AggregateTrack::AggregateTrack( Collections::AggregateCollection *coll, const TrackPtr &track )
        : Track()
        , Observer()
        , m_collection( coll )
        , m_name( track->name() )