Mixxx

/home/maxime/Projets/Mixxx/1.10/mixxx/src/library/browse/browsethread.cpp

Go to the documentation of this file.
00001 /*
00002  * browsethread.cpp         (C) 2011 Tobias Rafreider
00003  */
00004 
00005 #include <QStringList>
00006 #include <QDirIterator>
00007 #include <QtCore>
00008 
00009 #include "library/browse/browsethread.h"
00010 #include "library/browse/browsetablemodel.h"
00011 #include "soundsourceproxy.h"
00012 #include "mixxxutils.cpp"
00013 
00014 
00015 BrowseThread* BrowseThread::m_instance = NULL;
00016 static QMutex s_Mutex;
00017 
00018 /*
00019  * This class is a singleton and represents a thread
00020  * that is used to read ID3 metadata
00021  * from a particular folder.
00022  *
00023  * The BroseTableModel uses this class.
00024  * Note: Don't call getInstance() from places
00025  * other than the GUI thread. BrowseThreads emit
00026  * signals to BrowseModel objects. It does not
00027  * make sense to use this class in non-GUI threads
00028  */
00029 BrowseThread::BrowseThread(QObject *parent): QThread(parent)
00030 {
00031     m_bStopThread = false;
00032     m_model_observer = NULL;
00033     //start Thread
00034     start(QThread::LowestPriority);
00035 
00036 }
00037 
00038 BrowseThread::~BrowseThread() {
00039     qDebug() << "Wait to finish browser background thread";
00040     m_bStopThread = true;
00041     //wake up thread since it might wait for user input
00042     m_locationUpdated.wakeAll();
00043     //Wait until thread terminated
00044     //terminate();
00045     wait();
00046     qDebug() << "Browser background thread terminated!";
00047 }
00048 BrowseThread* BrowseThread::getInstance(){
00049     if (!m_instance)
00050     {
00051         s_Mutex.lock();
00052 
00053          if (!m_instance)
00054                m_instance = new BrowseThread();
00055 
00056          s_Mutex.unlock();
00057     }
00058     return m_instance;
00059 }
00060 void BrowseThread::destroyInstance()
00061 {
00062     s_Mutex.lock();
00063     if(m_instance){
00064         delete m_instance;
00065         m_instance = 0;
00066     }
00067     s_Mutex.unlock();
00068 }
00069 
00070 void BrowseThread::executePopulation(QString& path, BrowseTableModel* client) {
00071     m_path_mutex.lock();
00072     m_path = path;
00073     m_model_observer = client;
00074     m_path_mutex.unlock();
00075     m_locationUpdated.wakeAll();
00076 }
00077 
00078 void BrowseThread::run() {
00079     m_mutex.lock();
00080     while(!m_bStopThread) {
00081         //Wait until the user has selected a folder
00082         m_locationUpdated.wait(&m_mutex);
00083 
00084         //Terminate thread if Mixxx closes
00085         if(m_bStopThread) {
00086             break;
00087         }
00088         // Populate the model
00089         populateModel();
00090     }
00091     m_mutex.unlock();
00092 }
00093 
00094 void BrowseThread::populateModel() {
00095     m_path_mutex.lock();
00096     QString thisPath = m_path;
00097     BrowseTableModel* thisModelObserver = m_model_observer;
00098     m_path_mutex.unlock();
00099 
00100     // Refresh the name filters in case we loaded new SoundSource plugins.
00101     QStringList nameFilters(SoundSourceProxy::supportedFileExtensionsString().split(" "));
00102 
00103     QDirIterator fileIt(thisPath, nameFilters, QDir::Files | QDir::NoDotAndDotDot);
00104 
00105     // remove all rows
00106     // This is a blocking operation
00107     // see signal/slot connection in BrowseTableModel
00108     emit(clearModel(thisModelObserver));
00109 
00110     QList< QList<QStandardItem*> > rows;
00111 
00112     int row = 0;
00113     // Iterate over the files
00114     while (fileIt.hasNext()) {
00115         // If a user quickly jumps through the folders
00116         // the current task becomes "dirty"
00117         QMutexLocker locker(&m_path_mutex);
00118         if(thisPath != m_path){
00119             qDebug() << "Abort populateModel()";
00120             return populateModel();
00121         }
00122         locker.unlock();
00123 
00124         QString filepath = fileIt.next();
00125         TrackInfoObject tio(filepath);
00126         QList<QStandardItem*> row_data;
00127 
00128         QStandardItem* item = new QStandardItem(tio.getFilename());
00129         row_data.insert(COLUMN_FILENAME, item);
00130 
00131         item = new QStandardItem(tio.getArtist());
00132         row_data.insert(COLUMN_ARTIST, item);
00133 
00134         item = new QStandardItem(tio.getTitle());
00135         row_data.insert(COLUMN_TITLE, item);
00136 
00137         item = new QStandardItem(tio.getAlbum());
00138         row_data.insert(COLUMN_ALBUM, item);
00139 
00140         item = new QStandardItem(tio.getTrackNumber());
00141         row_data.insert(COLUMN_TRACK_NUMBER, item);
00142 
00143         item = new QStandardItem(tio.getYear());
00144         row_data.insert(COLUMN_YEAR, item);
00145 
00146         item = new QStandardItem(tio.getGenre());
00147         row_data.insert(COLUMN_GENRE, item);
00148 
00149         item = new QStandardItem(tio.getComment());
00150         row_data.insert(COLUMN_COMMENT, item);
00151 
00152         QString duration = MixxxUtils::secondsToMinutes(qVariantValue<int>(tio.getDuration()));
00153         item = new QStandardItem(duration);
00154         row_data.insert(COLUMN_DURATION, item);
00155 
00156         item = new QStandardItem(tio.getBpmStr());
00157         row_data.insert(COLUMN_BPM, item);
00158 
00159         item = new QStandardItem(tio.getKey());
00160         row_data.insert(COLUMN_KEY, item);
00161 
00162         item = new QStandardItem(tio.getType());
00163         row_data.insert(COLUMN_TYPE, item);
00164 
00165         item = new QStandardItem(tio.getBitrateStr());
00166         row_data.insert(COLUMN_BITRATE, item);
00167 
00168         item = new QStandardItem(filepath);
00169         row_data.insert(COLUMN_LOCATION, item);
00170 
00171         rows.append(row_data);
00172         ++row;
00173         // If 10 tracks have been analyzed, send it to GUI
00174         // Will limit GUI freezing
00175         if(row % 10 == 0){
00176             // this is a blocking operation
00177             emit(rowsAppended(rows, thisModelObserver));
00178             //qDebug() << "Append " << rows.count() << " from " << filepath;
00179             rows.clear();
00180         }
00181         // Sleep additionally for 10ms which prevents us from GUI freezes
00182         msleep(20);
00183     }
00184     emit(rowsAppended(rows, thisModelObserver));
00185     //qDebug() << "Append last " << rows.count() << " from " << thisPath;
00186 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines