=== modified file 'mixxx/src/library/cratetablemodel.cpp' --- mixxx/src/library/cratetablemodel.cpp 2013-04-22 19:29:54 +0000 +++ mixxx/src/library/cratetablemodel.cpp 2013-05-09 17:54:29 +0000 @@ -1,3 +1,4 @@ + // cratetablemodel.cpp // Created 10/25/2009 by RJ Ryan (rryan@mit.edu) @@ -202,7 +203,7 @@ | TRACKMODELCAPS_LOADTOSAMPLER | TRACKMODELCAPS_LOADTOPREVIEWDECK | TRACKMODELCAPS_REMOVE - | TRACKMODELCAPS_BPMLOCK + | TRACKMODELCAPS_MANIPULATEBEATS | TRACKMODELCAPS_CLEAR_BEATS | TRACKMODELCAPS_RESETPLAYED; === modified file 'mixxx/src/library/librarytablemodel.cpp' --- mixxx/src/library/librarytablemodel.cpp 2012-11-25 11:17:13 +0000 +++ mixxx/src/library/librarytablemodel.cpp 2013-05-09 17:53:57 +0000 @@ -139,7 +139,7 @@ | TRACKMODELCAPS_LOADTOSAMPLER | TRACKMODELCAPS_LOADTOPREVIEWDECK | TRACKMODELCAPS_HIDE - | TRACKMODELCAPS_BPMLOCK + | TRACKMODELCAPS_MANIPULATEBEATS | TRACKMODELCAPS_CLEAR_BEATS | TRACKMODELCAPS_RESETPLAYED; } === modified file 'mixxx/src/library/playlisttablemodel.cpp' --- mixxx/src/library/playlisttablemodel.cpp 2013-05-12 22:17:32 +0000 +++ mixxx/src/library/playlisttablemodel.cpp 2013-05-15 08:10:11 +0000 @@ -380,7 +380,7 @@ | TRACKMODELCAPS_LOADTOSAMPLER | TRACKMODELCAPS_LOADTOPREVIEWDECK | TRACKMODELCAPS_REMOVE - | TRACKMODELCAPS_BPMLOCK + | TRACKMODELCAPS_MANIPULATEBEATS | TRACKMODELCAPS_CLEAR_BEATS | TRACKMODELCAPS_RESETPLAYED; === modified file 'mixxx/src/library/trackmodel.h' --- mixxx/src/library/trackmodel.h 2012-11-25 09:33:00 +0000 +++ mixxx/src/library/trackmodel.h 2013-05-09 17:45:28 +0000 @@ -38,7 +38,7 @@ TRACKMODELCAPS_LOADTOPREVIEWDECK = 0x00200, TRACKMODELCAPS_REMOVE = 0x00400, TRACKMODELCAPS_RELOCATE = 0x00800, - TRACKMODELCAPS_BPMLOCK = 0x01000, + TRACKMODELCAPS_MANIPULATEBEATS = 0x01000, TRACKMODELCAPS_CLEAR_BEATS = 0x02000, TRACKMODELCAPS_RESETPLAYED = 0x04000, TRACKMODELCAPS_HIDE = 0x08000, === modified file 'mixxx/src/widget/wtracktableview.cpp' --- mixxx/src/widget/wtracktableview.cpp 2013-05-21 03:02:42 +0000 +++ mixxx/src/widget/wtracktableview.cpp 2013-05-21 18:32:38 +0000 @@ -57,6 +57,8 @@ m_pPlaylistMenu->setTitle(tr("Add to Playlist")); m_pCrateMenu = new QMenu(this); m_pCrateMenu->setTitle(tr("Add to Crate")); + m_pBPMMenu = new QMenu(this); + m_pBPMMenu->setTitle(tr("BPM Settings")); // Disable editing //setEditTriggers(QAbstractItemView::NoEditTriggers); @@ -101,6 +103,10 @@ delete m_pNumPreviewDecks; delete m_pBpmLockAction; delete m_pBpmUnlockAction; + delete m_pBpmDoubleAction; + delete m_pBpmHalveAction; + delete m_pBpmTwoThirdsAction; + delete m_pBPMMenu; delete m_pPurgeAct; delete m_pFileBrowserAct; delete m_pResetPlayedAct; @@ -308,6 +314,18 @@ connect(m_pBpmUnlockAction, SIGNAL(triggered()), this, SLOT(slotUnlockBpm())); + //new BPM actions + m_pBpmDoubleAction = new QAction(tr("Double BPM"), this); + m_pBpmHalveAction = new QAction(tr("Halve BPM"), this); + m_pBpmTwoThirdsAction = new QAction(tr("2/3 BPM"), this); + + connect(m_pBpmDoubleAction, SIGNAL(triggered()), + this, SLOT(slotDoubleBpm())); + connect(m_pBpmHalveAction, SIGNAL(triggered()), + this, SLOT(slotHalveBpm())); + connect(m_pBpmTwoThirdsAction, SIGNAL(triggered()), + this, SLOT(slotTwoThirdsBpm())); + m_pClearBeatsAction = new QAction(tr("Clear BPM and Beatgrid"), this); connect(m_pClearBeatsAction, SIGNAL(triggered()), this, SLOT(slotClearBeats())); @@ -459,11 +477,14 @@ void WTrackTableView::contextMenuEvent(QContextMenuEvent* event) { QModelIndexList indices = selectionModel()->selectedRows(); + // Gray out some stuff if multiple songs were selected. bool oneSongSelected = indices.size() == 1; m_pMenu->clear(); + + if (modelHasCapabilities(TrackModel::TRACKMODELCAPS_ADDTOAUTODJ)) { m_pMenu->addAction(m_pAutoDJAct); m_pMenu->addAction(m_pAutoDJTopAct); @@ -571,9 +592,15 @@ m_pMenu->addSeparator(); - if (modelHasCapabilities(TrackModel::TRACKMODELCAPS_BPMLOCK)) { - m_pMenu->addAction(m_pBpmLockAction); - m_pMenu->addAction(m_pBpmUnlockAction); + //start of BPM section of menu + + + if (modelHasCapabilities(TrackModel::TRACKMODELCAPS_MANIPULATEBEATS)) { + m_pBPMMenu->addAction(m_pBpmLockAction); + m_pBPMMenu->addAction(m_pBpmUnlockAction); + m_pBPMMenu->addAction(m_pBpmDoubleAction); + m_pBPMMenu->addAction(m_pBpmHalveAction); + m_pBPMMenu->addAction(m_pBpmTwoThirdsAction); if (oneSongSelected) { TrackModel* trackModel = getTrackModel(); if (trackModel == NULL) { @@ -581,15 +608,51 @@ } int column = trackModel->fieldIndex("bpm_lock"); QModelIndex index = indices.at(0).sibling(indices.at(0).row(),column); - if (index.data().toBool()){ - m_pBpmLockAction->setEnabled(false); - m_pBpmUnlockAction->setEnabled(true); - } else { - m_pBpmUnlockAction->setEnabled(false); - m_pBpmLockAction->setEnabled(true); + if (index.data().toBool()){ //BPM is locked + m_pBpmLockAction->setEnabled(false); + m_pBpmUnlockAction->setEnabled(true); + m_pBpmDoubleAction->setEnabled(false); + m_pBpmHalveAction->setEnabled(false); + m_pBpmTwoThirdsAction->setEnabled(false); + } else { //BPM is not locked + m_pBpmUnlockAction->setEnabled(false); + m_pBpmLockAction->setEnabled(true); + m_pBpmDoubleAction->setEnabled(true); + m_pBpmHalveAction->setEnabled(true); + m_pBpmTwoThirdsAction->setEnabled(true); + } + } + else{ + bool anyLocked = false; //true if any of the selected items are locked + TrackModel* trackModel = getTrackModel(); + int column = trackModel->fieldIndex("bpm_lock"); + for (int i = 0; i < indices.size() && !anyLocked; ++i) { + int row = indices.at(i).row(); + QModelIndex index = indices.at(i).sibling(row,column); + if (index.data().toBool()) { + anyLocked = true; + } + } + + if(anyLocked){ + m_pBpmLockAction->setEnabled(false); + m_pBpmUnlockAction->setEnabled(true); + m_pBpmDoubleAction->setEnabled(false); + m_pBpmHalveAction->setEnabled(false); + m_pBpmTwoThirdsAction->setEnabled(false); + } + else{ + m_pBpmLockAction->setEnabled(true); + m_pBpmUnlockAction->setEnabled(false); + m_pBpmDoubleAction->setEnabled(true); + m_pBpmHalveAction->setEnabled(true); + m_pBpmTwoThirdsAction->setEnabled(true); } } } + //add BPM menu to pMenu + m_pMenu->addMenu(m_pBPMMenu); + //end of BPM section of menu if (modelHasCapabilities(TrackModel::TRACKMODELCAPS_CLEAR_BEATS)) { TrackModel* trackModel = getTrackModel(); @@ -606,7 +669,7 @@ } } m_pClearBeatsAction->setEnabled(allowClear); - m_pMenu->addAction(m_pClearBeatsAction); + m_pBPMMenu->addAction(m_pClearBeatsAction); } bool locked = modelHasCapabilities(TrackModel::TRACKMODELCAPS_LOCKED); @@ -1204,6 +1267,78 @@ lockBpm(false); } +//new BPM slots +void WTrackTableView::slotDoubleBpm(){ + TrackModel* trackModel = getTrackModel(); + if (trackModel == NULL) { + return; + } + + QModelIndexList selectedTrackIndices = selectionModel()->selectedRows(); + // TODO: This should be done in a thread for large selections + for (int i = 0; i < selectedTrackIndices.size(); ++i) { + QModelIndex index = selectedTrackIndices.at(i); + TrackPointer track = trackModel->getTrack(index); + if (!track->hasBpmLock()) { //bpm is not locked + BeatsPointer beats = track->getBeats(); + if(beats != NULL){ + beats->scale(2); + } + else{ + continue; + } + } + } +} + +void WTrackTableView::slotHalveBpm(){ + TrackModel* trackModel = getTrackModel(); + if (trackModel == NULL) { + return; + } + + QModelIndexList selectedTrackIndices = selectionModel()->selectedRows(); + // TODO: This should be done in a thread for large selections + for (int i = 0; i < selectedTrackIndices.size(); ++i) { + QModelIndex index = selectedTrackIndices.at(i); + TrackPointer track = trackModel->getTrack(index); + if (!track->hasBpmLock()) { //bpm is not locked + BeatsPointer beats = track->getBeats(); + if(beats != NULL){ + beats->scale(0.5); + } + else{ + continue; + } + } + } +} + +void WTrackTableView::slotTwoThirdsBpm(){ + TrackModel* trackModel = getTrackModel(); + if (trackModel == NULL) { + return; + } + + QModelIndexList selectedTrackIndices = selectionModel()->selectedRows(); + // TODO: This should be done in a thread for large selections + for (int i = 0; i < selectedTrackIndices.size(); ++i) { + QModelIndex index = selectedTrackIndices.at(i); + TrackPointer track = trackModel->getTrack(index); + if (!track->hasBpmLock()) { //bpm is not locked + BeatsPointer beats = track->getBeats(); + if(beats != NULL){ + double twoThirds = 2.0 / 3.0; //keep as much accuracy as possbile + beats->scale(twoThirds); + } + else{ + continue; + } + } + } +} +//end of new BPM slots + void WTrackTableView::lockBpm(bool lock) { TrackModel* trackModel = getTrackModel(); if (trackModel == NULL) { === modified file 'mixxx/src/widget/wtracktableview.h' --- mixxx/src/widget/wtracktableview.h 2013-05-21 03:02:42 +0000 +++ mixxx/src/widget/wtracktableview.h 2013-05-21 18:32:38 +0000 @@ -56,6 +56,9 @@ void doSortByColumn(int headerSection); void slotLockBpm(); void slotUnlockBpm(); + void slotDoubleBpm(); + void slotHalveBpm(); + void slotTwoThirdsBpm(); void slotClearBeats(); private: @@ -89,7 +92,7 @@ ControlObjectThreadMain* m_pNumPreviewDecks; // Context menu machinery - QMenu *m_pMenu, *m_pPlaylistMenu, *m_pCrateMenu, *m_pSamplerMenu; + QMenu *m_pMenu, *m_pPlaylistMenu, *m_pCrateMenu, *m_pSamplerMenu, *m_pBPMMenu; QSignalMapper m_playlistMapper, m_crateMapper, m_deckMapper, m_samplerMapper; // Reload Track Metadata Action: @@ -119,6 +122,11 @@ QAction *m_pBpmLockAction; QAction *m_pBpmUnlockAction; + //BPM changes + QAction *m_pBpmDoubleAction; + QAction *m_pBpmHalveAction; + QAction *m_pBpmTwoThirdsAction; + // Clear track beats QAction* m_pClearBeatsAction;