void WTrackProperty::slotTrackLoaded(TrackPointer track) { if (track) { m_pCurrentTrack = track; connect(track.data(), SIGNAL(changed(Track*)), this, SLOT(updateLabel(Track*))); updateLabel(track.data()); } }
SoundSourceProxy::SoundSourceProxy(const TrackPointer& pTrack) : m_pTrack(pTrack), m_url(getCanonicalUrlForTrack(pTrack.data())), m_soundSourceProviderRegistrations(findSoundSourceProviderRegistrations(m_url)), m_soundSourceProviderRegistrationIndex(0) { initSoundSource(); }
//static CoverArt CoverArtUtils::guessCoverArt(TrackPointer pTrack) { CoverArt art; art.info.source = CoverInfo::GUESSED; if (pTrack.isNull()) { return art; } const QFileInfo fileInfo(pTrack->getFileInfo()); art.image = extractEmbeddedCover(fileInfo, pTrack->getSecurityToken()); if (!art.image.isNull()) { // TODO() here we my introduce a duplicate hash code art.info.hash = calculateHash(art.image); art.info.coverLocation = QString(); art.info.type = CoverInfo::METADATA; qDebug() << "CoverArtUtils::guessCoverArt found metadata art" << art; return art; } QLinkedList<QFileInfo> possibleCovers = findPossibleCoversInFolder( fileInfo.absolutePath()); art = selectCoverArtForTrack(pTrack.data(), possibleCovers); if (art.info.type == CoverInfo::FILE) { qDebug() << "CoverArtUtils::guessCoverArt found file art" << art; } else { qDebug() << "CoverArtUtils::guessCoverArt didn't find art" << art; } return art; }
void CueControl::trackUnloaded(TrackPointer pTrack) { QMutexLocker lock(&m_mutex); disconnect(pTrack.data(), 0, this, 0); for (int i = 0; i < m_iNumHotCues; ++i) { detachCue(i); } // Store the cue point in a load cue. double cuePoint = m_pCuePoint->get(); if (cuePoint != -1 && cuePoint != 0.0) { Cue* loadCue = NULL; const QList<Cue*>& cuePoints = pTrack->getCuePoints(); QListIterator<Cue*> it(cuePoints); while (it.hasNext()) { Cue* pCue = it.next(); if (pCue->getType() == Cue::LOAD) { loadCue = pCue; break; } } if (!loadCue) { loadCue = pTrack->addCue(); loadCue->setType(Cue::LOAD); loadCue->setLength(0); } loadCue->setPosition(cuePoint); } m_pCueIndicator->setBlinkValue(ControlIndicator::OFF); m_pCuePoint->set(-1.0); m_pLoadedTrack.clear(); }
BeatsPointer BeatFactory::makePreferredBeats( TrackPointer pTrack, QVector<double> beats, const QHash<QString, QString> extraVersionInfo, const bool bEnableFixedTempoCorrection, const bool bEnableOffsetCorrection, const int iSampleRate, const int iTotalSamples, const int iMinBpm, const int iMaxBpm) { const QString version = getPreferredVersion(bEnableFixedTempoCorrection); const QString subVersion = getPreferredSubVersion(bEnableFixedTempoCorrection, bEnableOffsetCorrection, iMinBpm, iMaxBpm, extraVersionInfo); BeatUtils::printBeatStatistics(beats, iSampleRate); if (version == BEAT_GRID_2_VERSION) { double globalBpm = BeatUtils::calculateBpm(beats, iSampleRate, iMinBpm, iMaxBpm); double firstBeat = BeatUtils::calculateFixedTempoFirstBeat( bEnableOffsetCorrection, beats, iSampleRate, iTotalSamples, globalBpm); BeatGrid* pGrid = new BeatGrid(pTrack.data(), iSampleRate); // firstBeat is in frames here and setGrid() takes samples. pGrid->setGrid(globalBpm, firstBeat * 2); pGrid->setSubVersion(subVersion); return BeatsPointer(pGrid, &BeatFactory::deleteBeats); } else if (version == BEAT_MAP_VERSION) { BeatMap* pBeatMap = new BeatMap(pTrack, iSampleRate, beats); pBeatMap->setSubVersion(subVersion); return BeatsPointer(pBeatMap, &BeatFactory::deleteBeats); } else { qDebug() << "ERROR: Could not determine what type of beatgrid to create."; return BeatsPointer(); } }
void PlaylistItemDelegate::paintTrack(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { // get the data object const TrackPointer trackPointer = index.data(Playlist::DataObjectRole).value<TrackPointer>(); Track *track = trackPointer.data(); // const PlaylistModel* playlistModel = dynamic_cast<const PlaylistModel*>(index.model()); const bool isActive = index.data(Playlist::ActiveItemRole).toBool(); // const bool isHovered = index.data(Playlist::HoveredItemRole).toBool(); const bool isSelected = option.state & QStyle::State_Selected; if (isSelected) QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter); painter->save(); painter->translate(option.rect.topLeft()); QRect line(0, 0, option.rect.width(), option.rect.height()); // text color if (isSelected) painter->setPen(QPen(option.palette.brush(QPalette::HighlightedText), 0)); else painter->setPen(QPen(option.palette.brush(QPalette::Text), 0)); if (line.height() > ITEM_HEIGHT) { // qDebug() << "header at index" << index.row(); line.setHeight(ITEM_HEIGHT); paintAlbumHeader(painter, option, line, track); // now modify our rect and painter // to make them similar to "headerless" items line.moveBottom(ITEM_HEIGHT); painter->translate(0, ITEM_HEIGHT); } if (isActive) { if (!isSelected) paintActiveOverlay(painter, option, line); QFont boldFont = painter->font(); boldFont.setBold(true); painter->setFont(boldFont); // play icon painter->drawPixmap(PADDING*2, (ITEM_HEIGHT - 16) / 2, 16, 16, getPlayIcon()); } else { paintTrackNumber(painter, option, line, track); } paintTrackTitle(painter, option, line, track); paintTrackLength(painter, option, line, track); // separator painter->setPen(option.palette.color(QPalette::Midlight)); painter->drawLine(0, line.height()-1, line.width(), line.height()-1); painter->restore(); }
void CueControl::trackLoaded(TrackPointer pTrack) { QMutexLocker lock(&m_mutex); if (m_pLoadedTrack) trackUnloaded(m_pLoadedTrack); if (!pTrack) { return; } m_pLoadedTrack = pTrack; connect(pTrack.data(), SIGNAL(cuesUpdated()), this, SLOT(trackCuesUpdated()), Qt::DirectConnection); Cue* loadCue = NULL; const QList<Cue*>& cuePoints = pTrack->getCuePoints(); QListIterator<Cue*> it(cuePoints); while (it.hasNext()) { Cue* pCue = it.next(); if (pCue->getType() == Cue::LOAD) { loadCue = pCue; } else if (pCue->getType() != Cue::CUE) { continue; } int hotcue = pCue->getHotCue(); if (hotcue != -1) attachCue(pCue, hotcue); } double loadCuePoint = 0.0; // If cue recall is ON in the prefs, then we're supposed to seek to the cue // point on song load. Note that [Controls],cueRecall == 0 corresponds to "ON", not OFF. bool cueRecall = (getConfig()->getValueString( ConfigKey("[Controls]","CueRecall"), "0").toInt() == 0); if (loadCue != NULL) { m_pCuePoint->set(loadCue->getPosition()); if (cueRecall) { loadCuePoint = loadCue->getPosition(); } } else { // If no cue point is stored, set one at track start m_pCuePoint->set(0.0); } // Need to unlock before emitting any signals to prevent deadlock. lock.unlock(); // If cueRecall is on, seek to it even if we didn't find a cue value (we'll // seek to 0. if (cueRecall) { seekExact(loadCuePoint); } else if (!(m_pVinylControlEnabled->get() && m_pVinylControlMode->get() == MIXXX_VCMODE_ABSOLUTE)) { // If cuerecall is off, seek to zero unless // vinylcontrol is on and set to absolute. This allows users to // load tracks and have the needle-drop be maintained. seekExact(0.0); } }
/** Do a non-recursive import of all the songs in a directory. Does NOT decend into subdirectories. @param trackDao The track data access object which provides a connection to the database. We use this parameter in order to make this function callable from separate threads. You need to use a different DB connection for each thread. @return true if the scan completed without being cancelled. False if the scan was cancelled part-way through. */ bool TrackCollection::importDirectory(const QString& directory, TrackDAO& trackDao, const QStringList& nameFilters, volatile bool* cancel) { //qDebug() << "TrackCollection::importDirectory(" << directory<< ")"; emit(startedLoading()); // QFileInfoList files; //get a list of the contents of the directory and go through it. QDirIterator it(directory, nameFilters, QDir::Files | QDir::NoDotAndDotDot); while (it.hasNext()) { //If a flag was raised telling us to cancel the library scan then stop. if (*cancel) { return false; } QString absoluteFilePath = it.next(); // If the track is in the database, mark it as existing. This code gets exectuted // when other files in the same directory have changed (the directory hash has changed). trackDao.markTrackLocationAsVerified(absoluteFilePath); // If the file already exists in the database, continue and go on to // the next file. // If the file doesn't already exist in the database, then add // it. If it does exist in the database, then it is either in the // user's library OR the user has "removed" the track via // "Right-Click -> Remove". These tracks stay in the library, but // their mixxx_deleted column is 1. if (!trackDao.trackExistsInDatabase(absoluteFilePath)) { //qDebug() << "Loading" << it.fileName(); emit(progressLoading(it.fileName())); TrackPointer pTrack = TrackPointer(new TrackInfoObject( absoluteFilePath), &QObject::deleteLater); if (trackDao.addTracksAdd(pTrack.data(), false)) { // Successful added // signal the main instance of TrackDao, that there is a // new Track in the database m_trackDao->databaseTrackAdded(pTrack); } else { qDebug() << "Track ("+absoluteFilePath+") could not be added"; } } } emit(finishedLoading()); return true; }
void SearchModel::itemActivated(const QModelIndex &index) { int itemType = index.data(Finder::ItemTypeRole).toInt(); if (itemType == Finder::ItemTypeArtist) { const ArtistPointer pointer = index.data(Finder::DataObjectRole).value<ArtistPointer>(); finder->artistActivated(pointer.data()); } else if (itemType == Finder::ItemTypeAlbum) { const AlbumPointer pointer = index.data(Finder::DataObjectRole).value<AlbumPointer>(); finder->albumActivated(pointer.data()); } else if (itemType == Finder::ItemTypeFolder) { } else if (itemType == Finder::ItemTypeTrack) { const TrackPointer pointer = index.data(Finder::DataObjectRole).value<TrackPointer>(); finder->trackActivated(pointer.data()); } }
QSize PlaylistItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { // determine item height based on font metrics if (ITEM_HEIGHT == 0) { ITEM_HEIGHT = option.fontMetrics.height() * 2; } QModelIndex previousIndex = index.sibling(index.row()-1, index.column()); if (previousIndex.isValid()) { const TrackPointer previousTrackPointer = previousIndex.data(Playlist::DataObjectRole).value<TrackPointer>(); Track *previousTrack = previousTrackPointer.data(); if (previousTrack) { const TrackPointer trackPointer = index.data(Playlist::DataObjectRole).value<TrackPointer>(); Track *track = trackPointer.data(); if (previousTrack->getAlbum() != track->getAlbum()) { return QSize(ITEM_HEIGHT*2, ITEM_HEIGHT*2); } } } else { return QSize(ITEM_HEIGHT*2, ITEM_HEIGHT*2); } return QSize(ITEM_HEIGHT, ITEM_HEIGHT); }
void DlgTagFetcher::loadTrack(const TrackPointer track) { if (track == NULL) { return; } results->clear(); m_track = track; m_data = Data(); m_TagFetcher.startFetch(m_track); disconnect(this, SLOT(updateTrackMetadata(TrackPointer))); connect(track.data(), SIGNAL(changed(TrackInfoObject*)), this, SLOT(updateTrackMetadata(TrackInfoObject*))); updateStack(); }
void CueControl::trackLoaded(TrackPointer pTrack) { QMutexLocker lock(&m_mutex); if (m_pLoadedTrack) trackUnloaded(m_pLoadedTrack); if (!pTrack) { return; } m_pLoadedTrack = pTrack; connect(pTrack.data(), SIGNAL(cuesUpdated()), this, SLOT(trackCuesUpdated()), Qt::DirectConnection); Cue* loadCue = NULL; const QList<Cue*>& cuePoints = pTrack->getCuePoints(); QListIterator<Cue*> it(cuePoints); while (it.hasNext()) { Cue* pCue = it.next(); if (pCue->getType() == Cue::LOAD) { loadCue = pCue; } else if (pCue->getType() != Cue::CUE) { continue; } int hotcue = pCue->getHotCue(); if (hotcue != -1) attachCue(pCue, hotcue); } double loadCuePoint = 0.0; if (loadCue != NULL) { m_pCuePoint->set(loadCue->getPosition()); // If cue recall is ON in the prefs, then we're supposed to seek to the cue // point on song load. Note that [Controls],cueRecall == 0 corresponds to "ON", not OFF. if (!getConfig()->getValueString( ConfigKey("[Controls]","CueRecall")).toInt()) { loadCuePoint = loadCue->getPosition(); } } else { // If no cue point is stored, set one at track start m_pCuePoint->set(0.0); } // Need to unlock before emitting any signals to prevent deadlock. lock.unlock(); seekExact(loadCuePoint); }
Item *SearchModel::itemAt(const QModelIndex &index) const { Item *item = nullptr; int itemType = index.data(Finder::ItemTypeRole).toInt(); if (itemType == Finder::ItemTypeArtist) { const ArtistPointer pointer = index.data(Finder::DataObjectRole).value<ArtistPointer>(); item = qobject_cast<Item *>(pointer.data()); } else if (itemType == Finder::ItemTypeAlbum) { const AlbumPointer pointer = index.data(Finder::DataObjectRole).value<AlbumPointer>(); item = qobject_cast<Item *>(pointer.data()); } else if (itemType == Finder::ItemTypeFolder) { } else if (itemType == Finder::ItemTypeTrack) { const TrackPointer pointer = index.data(Finder::DataObjectRole).value<TrackPointer>(); item = qobject_cast<Item *>(pointer.data()); } return item; }
BeatsPointer BeatFactory::loadBeatsFromByteArray(TrackPointer pTrack, QString beatsVersion, QString beatsSubVersion, QByteArray* beatsSerialized) { if (beatsVersion == BEAT_GRID_1_VERSION || beatsVersion == BEAT_GRID_2_VERSION) { BeatGrid* pGrid = new BeatGrid(pTrack.data(), 0, beatsSerialized); pGrid->setSubVersion(beatsSubVersion); qDebug() << "Successfully deserialized BeatGrid"; return BeatsPointer(pGrid, &BeatFactory::deleteBeats); } else if (beatsVersion == BEAT_MAP_VERSION) { BeatMap* pMap = new BeatMap(pTrack, 0, beatsSerialized); pMap->setSubVersion(beatsSubVersion); qDebug() << "Successfully deserialized BeatMap"; return BeatsPointer(pMap, &BeatFactory::deleteBeats); } qDebug() << "BeatFactory::loadBeatsFromByteArray could not parse serialized beats."; return BeatsPointer(); }
void CueControl::trackLoaded(TrackPointer pNewTrack, TrackPointer pOldTrack) { Q_UNUSED(pOldTrack); QMutexLocker lock(&m_mutex); if (m_pLoadedTrack) { disconnect(m_pLoadedTrack.data(), 0, this, 0); for (int i = 0; i < m_iNumHotCues; ++i) { detachCue(i); } // Store the cue point in a load cue. double cuePoint = m_pCuePoint->get(); if (cuePoint != -1 && cuePoint != 0.0) { CuePointer loadCue; const QList<CuePointer> cuePoints(m_pLoadedTrack->getCuePoints()); QListIterator<CuePointer> it(cuePoints); while (it.hasNext()) { CuePointer pCue(it.next()); if (pCue->getType() == Cue::LOAD) { loadCue = pCue; break; } } if (!loadCue) { loadCue = m_pLoadedTrack->addCue(); loadCue->setType(Cue::LOAD); loadCue->setLength(0); } loadCue->setPosition(cuePoint); } m_pCueIndicator->setBlinkValue(ControlIndicator::OFF); m_pCuePoint->set(-1.0); m_pLoadedTrack.clear(); } if (pNewTrack.isNull()) { return; } m_pLoadedTrack = pNewTrack; connect(pNewTrack.data(), SIGNAL(cuesUpdated()), this, SLOT(trackCuesUpdated()), Qt::DirectConnection); CuePointer loadCue; const QList<CuePointer> cuePoints(pNewTrack->getCuePoints()); QListIterator<CuePointer> it(cuePoints); while (it.hasNext()) { CuePointer pCue(it.next()); if (pCue->getType() == Cue::LOAD) { loadCue = pCue; } else if (pCue->getType() != Cue::CUE) { continue; } int hotcue = pCue->getHotCue(); if (hotcue != -1) attachCue(pCue, hotcue); } double loadCuePoint = 0.0; // If cue recall is ON in the prefs, then we're supposed to seek to the cue // point on song load. Note that [Controls],cueRecall == 0 corresponds to "ON", not OFF. bool cueRecall = (getConfig()->getValueString( ConfigKey("[Controls]","CueRecall"), "0").toInt() == 0); if (loadCue != NULL) { m_pCuePoint->set(loadCue->getPosition()); if (cueRecall) { loadCuePoint = loadCue->getPosition(); } } else { // If no cue point is stored, set one at track start m_pCuePoint->set(0.0); } // Need to unlock before emitting any signals to prevent deadlock. lock.unlock(); // If cueRecall is on, seek to it even if we didn't find a cue value (we'll // seek to 0. if (cueRecall) { seekExact(loadCuePoint); } else if (!(m_pVinylControlEnabled->get() && m_pVinylControlMode->get() == MIXXX_VCMODE_ABSOLUTE)) { // If cuerecall is off, seek to zero unless // vinylcontrol is on and set to absolute. This allows users to // load tracks and have the needle-drop be maintained. seekExact(0.0); } }