Mixxx

/home/maxime/Projets/Mixxx/1.10/mixxx/src/dlgtrackinfo.cpp

Go to the documentation of this file.
00001 // dlgtrackinfo.cpp
00002 // Created 11/10/2009 by RJ Ryan (rryan@mit.edu)
00003 
00004 #include <QtDebug>
00005 
00006 #include "dlgtrackinfo.h"
00007 #include "library/dao/cue.h"
00008 #include "trackinfoobject.h"
00009 
00010 DlgTrackInfo::DlgTrackInfo(QWidget* parent) :
00011         QDialog(parent),
00012         m_pLoadedTrack() {
00013 
00014     setupUi(this);
00015 
00016     cueTable->hideColumn(0);
00017 
00018     connect(btnNext, SIGNAL(clicked()),
00019             this, SLOT(slotNext()));
00020     connect(btnPrev, SIGNAL(clicked()),
00021             this, SLOT(slotPrev()));
00022     connect(btnApply, SIGNAL(clicked()),
00023             this, SLOT(apply()));
00024     connect(btnCancel, SIGNAL(clicked()),
00025             this, SLOT(cancel()));
00026 
00027     connect(bpmDouble, SIGNAL(clicked()),
00028             this, SLOT(slotBpmDouble()));
00029     connect(bpmHalve, SIGNAL(clicked()),
00030             this, SLOT(slotBpmHalve()));
00031     connect(bpmTap, SIGNAL(pressed()),
00032             this, SLOT(slotBpmTap()));
00033 
00034     connect(btnCueActivate, SIGNAL(clicked()),
00035             this, SLOT(cueActivate()));
00036     connect(btnCueDelete, SIGNAL(clicked()),
00037             this, SLOT(cueDelete()));
00038 
00039     connect(btnReloadFromFile, SIGNAL(clicked()),
00040             this, SLOT(reloadTrackMetadata()));
00041 
00042     m_bpmTapTimer.start();
00043     for (int i = 0; i < filterLength; ++i) {
00044         m_bpmTapFilter[i] = 0.0f;
00045     }
00046 }
00047 
00048 DlgTrackInfo::~DlgTrackInfo() {
00049     unloadTrack(false);
00050     qDebug() << "~DlgTrackInfo()";
00051 }
00052 
00053 void DlgTrackInfo::apply() {
00054     unloadTrack(true);
00055     accept();
00056 }
00057 
00058 void DlgTrackInfo::cancel() {
00059     unloadTrack(false);
00060     reject();
00061 }
00062 
00063 void DlgTrackInfo::trackUpdated() {
00064 
00065 }
00066 
00067 void DlgTrackInfo::slotNext() {
00068     emit(next());
00069 }
00070 
00071 void DlgTrackInfo::slotPrev() {
00072     emit(previous());
00073 }
00074 
00075 void DlgTrackInfo::cueActivate() {
00076 
00077 }
00078 
00079 void DlgTrackInfo::cueDelete() {
00080     QList<QTableWidgetItem*> selected = cueTable->selectedItems();
00081     QListIterator<QTableWidgetItem*> item_it(selected);
00082 
00083     QSet<int> rowsToDelete;
00084     while(item_it.hasNext()) {
00085         QTableWidgetItem* item = item_it.next();
00086         rowsToDelete.insert(item->row());
00087     }
00088 
00089     QList<int> rowsList = QList<int>::fromSet(rowsToDelete);
00090     qSort(rowsList);
00091 
00092     QListIterator<int> it(rowsList);
00093     it.toBack();
00094     while (it.hasPrevious()) {
00095         cueTable->removeRow(it.previous());
00096     }
00097 }
00098 
00099 void DlgTrackInfo::populateFields(TrackPointer pTrack) {
00100     // Editable fields
00101     lblSong->setText(pTrack->getTitle());
00102     txtTrackName->setText(pTrack->getTitle());
00103     txtArtist->setText(pTrack->getArtist());
00104     txtAlbum->setText(pTrack->getAlbum());
00105     txtGenre->setText(pTrack->getGenre());
00106     txtYear->setText(pTrack->getYear());
00107     txtTrackNumber->setText(pTrack->getTrackNumber());
00108     txtComment->setText(pTrack->getComment());
00109     spinBpm->setValue(pTrack->getBpm());
00110 
00111     // Non-editable fields
00112     txtDuration->setText(pTrack->getDurationStr());
00113     txtFilepath->setText(pTrack->getFilename());
00114     txtFilepath->setCursorPosition(0);
00115     txtType->setText(pTrack->getType());
00116 }
00117 
00118 void DlgTrackInfo::loadTrack(TrackPointer pTrack) {
00119     m_pLoadedTrack = pTrack;
00120     clear();
00121 
00122     if (m_pLoadedTrack == NULL)
00123         return;
00124 
00125     populateFields(m_pLoadedTrack);
00126     populateCues(m_pLoadedTrack);
00127 }
00128 
00129 void DlgTrackInfo::populateCues(TrackPointer pTrack) {
00130     int sampleRate = pTrack->getSampleRate();
00131 
00132     QList<Cue*> listPoints;
00133     const QList<Cue*>& cuePoints = pTrack->getCuePoints();
00134     QListIterator<Cue*> it(cuePoints);
00135     while (it.hasNext()) {
00136         Cue* pCue = it.next();
00137         if (pCue->getType() == Cue::CUE || pCue->getType() == Cue::LOAD) {
00138             listPoints.push_back(pCue);
00139         }
00140     }
00141     it = QListIterator<Cue*>(listPoints);
00142     cueTable->setSortingEnabled(false);
00143     int row = 0;
00144 
00145     while (it.hasNext()) {
00146         Cue* pCue = it.next();
00147 
00148         QString rowStr = QString("%1").arg(row);
00149 
00150         // All hotcues are stored in Cue's as 0-indexed, but the GUI presents
00151         // them to the user as 1-indexex. Add 1 here. rryan 9/2010
00152         int iHotcue = pCue->getHotCue() + 1;
00153         QString hotcue = "";
00154         if (iHotcue != -1) {
00155             hotcue = QString("%1").arg(iHotcue);
00156         }
00157 
00158         int position = pCue->getPosition();
00159         double totalSeconds;
00160         if (position == -1)
00161             continue;
00162         else {
00163             totalSeconds = float(position) / float(sampleRate) / 2.0;
00164         }
00165 
00166         int fraction = 100*(totalSeconds - floor(totalSeconds));
00167         int seconds = int(totalSeconds) % 60;
00168         int mins = int(totalSeconds) / 60;
00169         //int hours = mins / 60; //Not going to worry about this for now. :)
00170 
00171         //Construct a nicely formatted duration string now.
00172         QString duration = QString("%1:%2.%3").arg(mins).arg(seconds, 2, 10, QChar('0')).arg(fraction, 2,10, QChar('0'));
00173 
00174         QTableWidgetItem* durationItem = new QTableWidgetItem(duration);
00175         // Make the duration read only
00176         durationItem->setFlags(Qt::NoItemFlags);
00177 
00178         m_cueMap[row] = pCue;
00179         cueTable->insertRow(row);
00180         cueTable->setItem(row, 0, new QTableWidgetItem(rowStr));
00181         cueTable->setItem(row, 1, durationItem);
00182         cueTable->setItem(row, 2, new QTableWidgetItem(hotcue));
00183         cueTable->setItem(row, 3, new QTableWidgetItem(pCue->getLabel()));
00184         row += 1;
00185     }
00186     cueTable->setSortingEnabled(true);
00187 }
00188 
00189 void DlgTrackInfo::unloadTrack(bool save) {
00190     if (!m_pLoadedTrack)
00191         return;
00192 
00193     if (save) {
00194         m_pLoadedTrack->setTitle(txtTrackName->text());
00195         m_pLoadedTrack->setArtist(txtArtist->text());
00196         m_pLoadedTrack->setAlbum(txtAlbum->text());
00197         m_pLoadedTrack->setGenre(txtGenre->text());
00198         m_pLoadedTrack->setYear(txtYear->text());
00199         m_pLoadedTrack->setTrackNumber(txtTrackNumber->text());
00200         m_pLoadedTrack->setBpm(spinBpm->value());
00201         m_pLoadedTrack->setComment(txtComment->toPlainText());
00202 
00203         QHash<int, Cue*> cueMap;
00204         for (int row = 0; row < cueTable->rowCount(); ++row) {
00205 
00206             QTableWidgetItem* rowItem = cueTable->item(row, 0);
00207             QTableWidgetItem* hotcueItem = cueTable->item(row, 2);
00208             QTableWidgetItem* labelItem = cueTable->item(row, 3);
00209 
00210             if (!rowItem || !hotcueItem || !labelItem)
00211                 continue;
00212 
00213             int oldRow = rowItem->data(Qt::DisplayRole).toInt();
00214             Cue* pCue = m_cueMap.take(oldRow);
00215 
00216             QVariant vHotcue = hotcueItem->data(Qt::DisplayRole);
00217             if (vHotcue.canConvert<int>()) {
00218                 int iTableHotcue = vHotcue.toInt();
00219                 // The GUI shows hotcues as 1-indexed, but they are actually
00220                 // 0-indexed, so subtract 1
00221                 pCue->setHotCue(iTableHotcue-1);
00222             } else {
00223                 pCue->setHotCue(-1);
00224             }
00225 
00226             QString label = labelItem->data(Qt::DisplayRole).toString();
00227             pCue->setLabel(label);
00228         }
00229 
00230         QMutableHashIterator<int,Cue*> it(m_cueMap);
00231         // Everything remaining in m_cueMap must have been deleted.
00232         while (it.hasNext()) {
00233             it.next();
00234             Cue* pCue = it.value();
00235             it.remove();
00236             qDebug() << "Deleting cue" << pCue->getId() << pCue->getHotCue();
00237             m_pLoadedTrack->removeCue(pCue);
00238         }
00239     }
00240 
00241     m_pLoadedTrack.clear();
00242     clear();
00243 }
00244 
00245 void DlgTrackInfo::clear() {
00246     txtTrackName->setText("");
00247     lblSong->setText("Track:");
00248 
00249     txtTrackName->setText("");
00250     txtArtist->setText("");
00251     txtAlbum->setText("");
00252     txtGenre->setText("");
00253     txtYear->setText("");
00254     txtTrackNumber->setText("");
00255     txtComment->setText("");
00256     spinBpm->setValue(0.0);
00257 
00258     txtDuration->setText("");
00259     txtFilepath->setText("");
00260     txtType->setText("");
00261 
00262     m_cueMap.clear();
00263     cueTable->clearContents();
00264     cueTable->setRowCount(0);
00265 }
00266 
00267 void DlgTrackInfo::slotBpmDouble() {
00268     spinBpm->setValue(spinBpm->value() * 2.0);
00269 }
00270 
00271 void DlgTrackInfo::slotBpmHalve() {
00272     spinBpm->setValue(spinBpm->value() / 2.0);
00273 }
00274 
00275 void DlgTrackInfo::slotBpmTap() {
00276     int elapsed = m_bpmTapTimer.elapsed();
00277     m_bpmTapTimer.restart();
00278 
00279     if (elapsed <= maxInterval) {
00280         // Move back in filter one sample
00281         for (int i = 1; i < filterLength; ++i) {
00282             m_bpmTapFilter[i-1] = m_bpmTapFilter[i];
00283         }
00284 
00285         m_bpmTapFilter[filterLength-1] = 60000.0f/elapsed;
00286         if (m_bpmTapFilter[filterLength-1] > maxBPM)
00287             m_bpmTapFilter[filterLength-1] = maxBPM;
00288 
00289         double temp = 0.;
00290         for (int i = 0; i < filterLength; ++i) {
00291             temp += m_bpmTapFilter[i];
00292         }
00293         temp /= filterLength;
00294         spinBpm->setValue(temp);
00295     }
00296 }
00297 
00298 void DlgTrackInfo::reloadTrackMetadata() {
00299     if (m_pLoadedTrack) {
00300         TrackPointer pTrack(new TrackInfoObject(m_pLoadedTrack->getLocation()));
00301         populateFields(pTrack);
00302     }
00303 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines