void BrowseThread::populateModel() { m_path_mutex.lock(); QString thisPath = m_path; BrowseTableModel* thisModelObserver = m_model_observer; m_path_mutex.unlock(); // Refresh the name filters in case we loaded new SoundSource plugins. QStringList nameFilters(SoundSourceProxy::supportedFileExtensionsString().split(" ")); QDirIterator fileIt(thisPath, nameFilters, QDir::Files | QDir::NoDotAndDotDot); // remove all rows // This is a blocking operation // see signal/slot connection in BrowseTableModel emit(clearModel(thisModelObserver)); QList< QList<QStandardItem*> > rows; int row = 0; // Iterate over the files while (fileIt.hasNext()) { // If a user quickly jumps through the folders // the current task becomes "dirty" m_path_mutex.lock(); QString newPath = m_path; m_path_mutex.unlock(); if(thisPath != newPath) { qDebug() << "Abort populateModel()"; return populateModel(); } QString filepath = fileIt.next(); TrackInfoObject tio(filepath); QList<QStandardItem*> row_data; QStandardItem* item = new QStandardItem(tio.getFilename()); item->setToolTip(item->text()); row_data.insert(COLUMN_FILENAME, item); item = new QStandardItem(tio.getArtist()); item->setToolTip(item->text()); row_data.insert(COLUMN_ARTIST, item); item = new QStandardItem(tio.getTitle()); item->setToolTip(item->text()); row_data.insert(COLUMN_TITLE, item); item = new QStandardItem(tio.getAlbum()); item->setToolTip(item->text()); row_data.insert(COLUMN_ALBUM, item); item = new QStandardItem(tio.getAlbumArtist()); item->setToolTip(item->text()); row_data.insert(COLUMN_ALBUMARTIST, item); item = new QStandardItem(tio.getTrackNumber()); item->setToolTip(item->text()); row_data.insert(COLUMN_TRACK_NUMBER, item); item = new QStandardItem(tio.getYear()); item->setToolTip(item->text()); row_data.insert(COLUMN_YEAR, item); item = new QStandardItem(tio.getGenre()); item->setToolTip(item->text()); row_data.insert(COLUMN_GENRE, item); item = new QStandardItem(tio.getComposer()); item->setToolTip(item->text()); row_data.insert(COLUMN_COMPOSER, item); item = new QStandardItem(tio.getGrouping()); item->setToolTip(item->text()); row_data.insert(COLUMN_GROUPING, item); item = new QStandardItem(tio.getComment()); item->setToolTip(item->text()); row_data.insert(COLUMN_COMMENT, item); QString duration = Time::formatSeconds(qVariantValue<int>( tio.getDuration()), false); item = new QStandardItem(duration); item->setToolTip(item->text()); row_data.insert(COLUMN_DURATION, item); item = new QStandardItem(tio.getBpmStr()); item->setToolTip(item->text()); row_data.insert(COLUMN_BPM, item); item = new QStandardItem(tio.getKeyText()); item->setToolTip(item->text()); row_data.insert(COLUMN_KEY, item); item = new QStandardItem(tio.getType()); item->setToolTip(item->text()); row_data.insert(COLUMN_TYPE, item); item = new QStandardItem(tio.getBitrateStr()); item->setToolTip(item->text()); row_data.insert(COLUMN_BITRATE, item); item = new QStandardItem(filepath); item->setToolTip(item->text()); row_data.insert(COLUMN_LOCATION, item); rows.append(row_data); ++row; // If 10 tracks have been analyzed, send it to GUI // Will limit GUI freezing if(row % 10 == 0){ // this is a blocking operation emit(rowsAppended(rows, thisModelObserver)); //qDebug() << "Append " << rows.count() << " from " << filepath; rows.clear(); } // Sleep additionally for 10ms which prevents us from GUI freezes msleep(20); } emit(rowsAppended(rows, thisModelObserver)); //qDebug() << "Append last " << rows.count() << " from " << thisPath; }
void BrowseThread::populateModel() { m_path_mutex.lock(); MDir thisPath = m_path; BrowseTableModel* thisModelObserver = m_model_observer; m_path_mutex.unlock(); // Refresh the name filters in case we loaded new SoundSource plugins. QStringList nameFilters(SoundSourceProxy::getSupportedFileNamePatterns()); QDirIterator fileIt(thisPath.dir().absolutePath(), nameFilters, QDir::Files | QDir::NoDotAndDotDot); // remove all rows // This is a blocking operation // see signal/slot connection in BrowseTableModel emit(clearModel(thisModelObserver)); QList< QList<QStandardItem*> > rows; int row = 0; // Iterate over the files while (fileIt.hasNext()) { // If a user quickly jumps through the folders // the current task becomes "dirty" m_path_mutex.lock(); MDir newPath = m_path; m_path_mutex.unlock(); if (thisPath.dir() != newPath.dir()) { qDebug() << "Abort populateModel()"; return populateModel(); } QList<QStandardItem*> row_data; QStandardItem* item = new QStandardItem("0"); item->setData("0", Qt::UserRole); row_data.insert(COLUMN_PREVIEW, item); const QString filepath = fileIt.next(); { const TrackPointer pTrack = SoundSourceProxy::importTemporaryTrack( filepath, thisPath.token()); item = new QStandardItem(pTrack->getFileName()); item->setToolTip(item->text()); item->setData(item->text(), Qt::UserRole); row_data.insert(COLUMN_FILENAME, item); item = new QStandardItem(pTrack->getArtist()); item->setToolTip(item->text()); item->setData(item->text(), Qt::UserRole); row_data.insert(COLUMN_ARTIST, item); item = new QStandardItem(pTrack->getTitle()); item->setToolTip(item->text()); item->setData(item->text(), Qt::UserRole); row_data.insert(COLUMN_TITLE, item); item = new QStandardItem(pTrack->getAlbum()); item->setToolTip(item->text()); item->setData(item->text(), Qt::UserRole); row_data.insert(COLUMN_ALBUM, item); item = new QStandardItem(pTrack->getAlbumArtist()); item->setToolTip(item->text()); item->setData(item->text(), Qt::UserRole); row_data.insert(COLUMN_ALBUMARTIST, item); item = new QStandardItem(pTrack->getTrackNumber()); item->setToolTip(item->text()); item->setData(item->text().toInt(), Qt::UserRole); row_data.insert(COLUMN_TRACK_NUMBER, item); const QString year(pTrack->getYear()); item = new YearItem(year); item->setToolTip(year); // The year column is sorted according to the numeric calendar year item->setData(mixxx::TrackMetadata::parseCalendarYear(year), Qt::UserRole); row_data.insert(COLUMN_YEAR, item); item = new QStandardItem(pTrack->getGenre()); item->setToolTip(item->text()); item->setData(item->text(), Qt::UserRole); row_data.insert(COLUMN_GENRE, item); item = new QStandardItem(pTrack->getComposer()); item->setToolTip(item->text()); item->setData(item->text(), Qt::UserRole); row_data.insert(COLUMN_COMPOSER, item); item = new QStandardItem(pTrack->getGrouping()); item->setToolTip(item->text()); item->setData(item->text(), Qt::UserRole); row_data.insert(COLUMN_GROUPING, item); item = new QStandardItem(pTrack->getComment()); item->setToolTip(item->text()); item->setData(item->text(), Qt::UserRole); row_data.insert(COLUMN_COMMENT, item); QString duration = pTrack->getDurationText(mixxx::Duration::Precision::SECONDS); item = new QStandardItem(duration); item->setToolTip(item->text()); item->setData(item->text(), Qt::UserRole); row_data.insert(COLUMN_DURATION, item); item = new QStandardItem(pTrack->getBpmText()); item->setToolTip(item->text()); item->setData(pTrack->getBpm(), Qt::UserRole); row_data.insert(COLUMN_BPM, item); item = new QStandardItem(pTrack->getKeyText()); item->setToolTip(item->text()); item->setData(item->text(), Qt::UserRole); row_data.insert(COLUMN_KEY, item); item = new QStandardItem(pTrack->getType()); item->setToolTip(item->text()); item->setData(item->text(), Qt::UserRole); row_data.insert(COLUMN_TYPE, item); item = new QStandardItem(pTrack->getBitrateText()); item->setToolTip(item->text()); item->setData(pTrack->getBitrate(), Qt::UserRole); row_data.insert(COLUMN_BITRATE, item); QString location = pTrack->getLocation(); QString nativeLocation = QDir::toNativeSeparators(location); item = new QStandardItem(nativeLocation); item->setToolTip(nativeLocation); item->setData(location, Qt::UserRole); row_data.insert(COLUMN_NATIVELOCATION, item); QDateTime modifiedTime = pTrack->getFileModifiedTime().toLocalTime(); item = new QStandardItem(modifiedTime.toString(Qt::DefaultLocaleShortDate)); item->setToolTip(item->text()); item->setData(modifiedTime, Qt::UserRole); row_data.insert(COLUMN_FILE_MODIFIED_TIME, item); QDateTime creationTime = pTrack->getFileCreationTime().toLocalTime(); item = new QStandardItem(creationTime.toString(Qt::DefaultLocaleShortDate)); item->setToolTip(item->text()); item->setData(creationTime, Qt::UserRole); row_data.insert(COLUMN_FILE_CREATION_TIME, item); const mixxx::ReplayGain replayGain(pTrack->getReplayGain()); item = new QStandardItem( mixxx::ReplayGain::ratioToString(replayGain.getRatio())); item->setToolTip(item->text()); item->setData(item->text(), Qt::UserRole); row_data.insert(COLUMN_REPLAYGAIN, item); } // implicitly release track pointer and unlock cache rows.append(row_data); ++row; // If 10 tracks have been analyzed, send it to GUI // Will limit GUI freezing if (row % 10 == 0) { // this is a blocking operation emit(rowsAppended(rows, thisModelObserver)); qDebug() << "Append " << rows.count() << " from " << filepath; rows.clear(); } // Sleep additionally for 10ms which prevents us from GUI freezes msleep(20); } emit(rowsAppended(rows, thisModelObserver)); qDebug() << "Append last " << rows.count(); }