Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 46 additions & 1 deletion src/library/autodj/autodjfeature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,31 @@ int findOrCreateAutoDjPlaylistId(PlaylistDAO& playlistDAO) {
}
return playlistId;
}

/// Create a title for the Auto DJ node
QString createAutoDjTitle(const QString& name,
int count,
mixxx::Duration duration,
bool showCountRemaining,
bool showTimeRemaining) {
QString result(name);

// Show duration and track count only if Auto DJ queue has tracks
if (count > 0 && showCountRemaining) {
result.append(QStringLiteral(" ("));
result.append(QString::number(count));
result.append(QStringLiteral(")"));
}

if (count > 0 && showTimeRemaining) {
result.append(QStringLiteral(" "));
result.append(mixxx::Duration::formatTime(
duration.toDoubleSeconds(),
mixxx::Duration::Precision::SECONDS));
}

return result;
}
} // anonymous namespace

AutoDJFeature::AutoDJFeature(Library* pLibrary,
Expand Down Expand Up @@ -66,6 +91,13 @@ AutoDJFeature::AutoDJFeature(Library* pLibrary,
&LibraryFeature::loadTrackToPlayer,
Qt::QueuedConnection);

// Update the title of the "Auto DJ" node when the
// list of queued tracks or their properties have changed.
connect(m_pAutoDJProcessor,
&AutoDJProcessor::queueDurationChanged,
this,
&AutoDJFeature::slotRemainingQueueDurationChanged);

m_playlistDao.setAutoDJProcessor(m_pAutoDJProcessor);

// Create the "Crates" tree-item under the root item.
Expand Down Expand Up @@ -135,7 +167,20 @@ AutoDJFeature::~AutoDJFeature() {
}

QVariant AutoDJFeature::title() {
return tr("Auto DJ");
return createAutoDjTitle(tr("Auto DJ"),
m_pAutoDJProcessor->getQueueTrackCount(),
m_pAutoDJProcessor->getQueueDuration(),
true,
true);
}

void AutoDJFeature::slotRemainingQueueDurationChanged(int numTracks, mixxx::Duration duration) {
Q_UNUSED(numTracks);
Q_UNUSED(duration);

// As documented by the code docs for featureIsLoading,
// it is intended to indicate when the title() has changed.
emit featureIsLoading(this, false);
}

void AutoDJFeature::bindLibraryWidget(
Expand Down
6 changes: 6 additions & 0 deletions src/library/autodj/autodjfeature.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "library/libraryfeature.h"
#include "library/trackset/crate/crate.h"
#include "preferences/usersettings.h"
#include "util/duration.h"
#include "util/parented_ptr.h"

class DlgAutoDJ;
Expand Down Expand Up @@ -107,4 +108,9 @@ class AutoDJFeature : public LibraryFeature {
// Adds a random track from the queue upon hitting minimum number
// of tracks in the playlist
void slotRandomQueue(int numTracksToAdd);

// Updates the title of the "Auto DJ" node with the number of tracks
// and remaining duration when tracks are added to or removed from
// the Auto DJ queue.
void slotRemainingQueueDurationChanged(int numTracks, mixxx::Duration duration);
};
24 changes: 23 additions & 1 deletion src/library/autodj/autodjprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,9 @@ AutoDJProcessor::AutoDJProcessor(
m_skipNext(ConfigKey(kControlGroup, QStringLiteral("skip_next"))),
m_addRandomTrack(ConfigKey(kControlGroup, QStringLiteral("add_random_track"))),
m_fadeNow(ConfigKey(kControlGroup, QStringLiteral("fade_now"))),
m_enabledAutoDJ(ConfigKey(kControlGroup, QStringLiteral("enabled"))) {
m_enabledAutoDJ(ConfigKey(kControlGroup, QStringLiteral("enabled"))),
m_queueRemainingTracks(ConfigKey(kControlGroup, QStringLiteral("queue_tracks"))),
m_queueRemainingDuration(ConfigKey(kControlGroup, QStringLiteral("queue_duration"))) {
m_pAutoDJTableModel = make_parented<PlaylistTableModel>(
this, pTrackCollectionManager, "mixxx.db.model.autodj");
m_pAutoDJTableModel->selectPlaylist(iAutoDJPlaylistId);
Expand All @@ -151,6 +153,11 @@ AutoDJProcessor::AutoDJProcessor(
m_enabledAutoDJ.connectValueChangeRequest(this,
&AutoDJProcessor::controlEnableChangeRequest);

connect(m_pAutoDJTableModel,
&PlaylistTableModel::playlistTracksChanged,
this,
&AutoDJProcessor::playlistTracksChanged);

connect(pPlayerManager,
&PlayerManagerInterface::numberOfDecksChanged,
this,
Expand All @@ -166,6 +173,9 @@ AutoDJProcessor::AutoDJProcessor(
m_transitionMode = m_pConfig->getValue(
ConfigKey(kPreferenceGroup, kTransitionModePreferenceName),
TransitionMode::FullIntroOutro);

// Calculate the initial values for track count and time remaining
playlistTracksChanged();
}

void AutoDJProcessor::slotNumberOfDecksChanged(int decks) {
Expand Down Expand Up @@ -196,6 +206,18 @@ void AutoDJProcessor::setCrossfader(double value) {
m_coCrossfader.set(value);
}

void AutoDJProcessor::playlistTracksChanged() {
const int numTracksInQueue = m_pAutoDJTableModel->rowCount();
m_queueRemainingTracks.set(numTracksInQueue);
m_queueDuration = m_pAutoDJTableModel->getTotalDuration();
m_queueRemainingDuration.set(m_queueDuration.toDoubleSeconds());
emit queueDurationChanged(numTracksInQueue, m_queueDuration);
}

int AutoDJProcessor::getQueueTrackCount() const {
return m_pAutoDJTableModel->rowCount();
}

AutoDJProcessor::AutoDJError AutoDJProcessor::shufflePlaylist(
const QModelIndexList& selectedIndices) {
QModelIndex exclude;
Expand Down
16 changes: 16 additions & 0 deletions src/library/autodj/autodjprocessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,15 @@ class AutoDJProcessor : public QObject {
return m_pAutoDJTableModel;
}

/// Gets the total remaining duration of tracks in the AutoDJ playlist,
/// excluding the track that is currently playing already.
mixxx::Duration getQueueDuration() const {
return m_queueDuration;
}

/// Gets the number of tracks remaining in the Auto DJ queue.
int getQueueTrackCount() const;

bool nextTrackLoaded();

void setTransitionTime(int seconds);
Expand All @@ -218,6 +227,7 @@ class AutoDJProcessor : public QObject {
#endif
void autoDJStateChanged(AutoDJProcessor::AutoDJState state);
void autoDJError(AutoDJProcessor::AutoDJError error);
void queueDurationChanged(int numTracks, mixxx::Duration duration);
void transitionTimeChanged(int time);
void randomTrackRequested(int tracksToAdd);

Expand All @@ -236,6 +246,8 @@ class AutoDJProcessor : public QObject {
void playerOrientationChanged(DeckAttributes* pDeck);
void playlistFirstTrackChanged();

void playlistTracksChanged();

void controlEnableChangeRequest(double value);
void controlFadeNow(double value);
void controlShuffle(double value);
Expand Down Expand Up @@ -320,5 +332,9 @@ class AutoDJProcessor : public QObject {
ControlPushButton m_fadeNow;
ControlPushButton m_enabledAutoDJ;

ControlObject m_queueRemainingTracks;
ControlObject m_queueRemainingDuration;
mixxx::Duration m_queueDuration;

DISALLOW_COPY_AND_ASSIGN(AutoDJProcessor);
};
47 changes: 34 additions & 13 deletions src/library/autodj/dlgautodj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,11 @@ DlgAutoDJ::DlgAutoDJ(WLibrary* parent,
this,
&DlgAutoDJ::transitionTimeChanged);

connect(m_pAutoDJProcessor,
&AutoDJProcessor::queueDurationChanged,
this,
&DlgAutoDJ::queueDurationChanged);

connect(m_pAutoDJProcessor,
&AutoDJProcessor::autoDJError,
this,
Expand Down Expand Up @@ -310,6 +315,12 @@ void DlgAutoDJ::transitionSliderChanged(int value) {
m_pAutoDJProcessor->setTransitionTime(value);
}

void DlgAutoDJ::queueDurationChanged(int numTracks, mixxx::Duration duration) {
Q_UNUSED(numTracks);
Q_UNUSED(duration);
updateSelectionInfo();
}

void DlgAutoDJ::autoDJStateChanged(AutoDJProcessor::AutoDJState state) {
if (state == AutoDJProcessor::ADJ_DISABLED) {
pushButtonAutoDJ->setChecked(false);
Expand Down Expand Up @@ -355,24 +366,34 @@ void DlgAutoDJ::slotRepeatPlaylistChanged(bool checked) {
}

void DlgAutoDJ::updateSelectionInfo() {
// Obtain the total duration of the whole remaining Auto DJ queue
// from the Auto DJ processor. The calculated time is exact and
// takes transition times, intros, outros etc. into account.
mixxx::Duration totalDuration = m_pAutoDJProcessor->getQueueDuration();
int totalTracks = m_pAutoDJTableModel->rowCount();

// Derive total duration of the selected tracks from the table model.
// This is much faster than getting the duration from individual track
// objects (but does not take transition times into account...)
QModelIndexList indices = m_pTrackTableView->selectionModel()->selectedRows();
mixxx::Duration selectedDuration = m_pAutoDJTableModel->getTotalDuration(indices);
int selectedTracks = indices.size();

// Derive total duration from the table model. This is much faster than
// getting the duration from individual track objects.
mixxx::Duration duration = m_pAutoDJTableModel->getTotalDuration(indices);

// Selected tracks
QString label;

if (!indices.isEmpty()) {
label.append(mixxx::DurationBase::formatTime(duration.toDoubleSeconds()));
label.append(QString(" (%1)").arg(indices.size()));
labelSelectionInfo->setToolTip(tr("Displays the duration and number of selected tracks."));
labelSelectionInfo->setText(label);
labelSelectionInfo->setEnabled(true);
} else {
labelSelectionInfo->setText("");
labelSelectionInfo->setEnabled(false);
label.append(mixxx::DurationBase::formatTime(selectedDuration.toDoubleSeconds()));
label.append(QString(" (%1)").arg(selectedTracks));
label.append(tr(" / "));
}

// Total tracks
label.append(mixxx::DurationBase::formatTime(totalDuration.toDoubleSeconds()));
label.append(QString(" (%1)").arg(totalTracks));

labelSelectionInfo->setToolTip(tr("Displays the duration and number of selected tracks."));
labelSelectionInfo->setText(label);
labelSelectionInfo->setEnabled(true);
}

bool DlgAutoDJ::hasFocus() const {
Expand Down
1 change: 1 addition & 0 deletions src/library/autodj/dlgautodj.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class DlgAutoDJ : public QWidget, public Ui::DlgAutoDJ, public LibraryView {
void autoDJError(AutoDJProcessor::AutoDJError error);
void transitionTimeChanged(int time);
void transitionSliderChanged(int value);
void queueDurationChanged(int numTracks, mixxx::Duration duration);
void autoDJStateChanged(AutoDJProcessor::AutoDJState state);
void updateSelectionInfo();
void slotTransitionModeChanged(int comboboxIndex);
Expand Down
14 changes: 14 additions & 0 deletions src/library/playlisttablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,19 @@ const QList<int> PlaylistTableModel::getSelectedPositions(const QModelIndexList&
return positions;
}

mixxx::Duration PlaylistTableModel::getTotalDuration() {
double durationTotal = 0.0;
const int durationColumnIndex = fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_DURATION);
int numOfTracks = rowCount();
for (int i = 0; i < numOfTracks; i++) {
durationTotal += index(i, durationColumnIndex)
.data(Qt::EditRole)
.toDouble();
}

return mixxx::Duration::fromSeconds(durationTotal);
}

mixxx::Duration PlaylistTableModel::getTotalDuration(const QModelIndexList& indices) {
if (indices.isEmpty()) {
return mixxx::Duration::empty();
Expand Down Expand Up @@ -455,5 +468,6 @@ QString PlaylistTableModel::modelKey(bool noSearch) const {
void PlaylistTableModel::playlistsChanged(const QSet<int>& playlistIds) {
if (playlistIds.contains(m_iPlaylistId)) {
select(); // Repopulate the data model.
emit playlistTracksChanged();
}
}
6 changes: 6 additions & 0 deletions src/library/playlisttablemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ class PlaylistTableModel final : public TrackSetTableModel {
int* pOutInsertionPos) final;
bool isLocked() final;

/// Get the total duration of all tracks in the selected playlist
mixxx::Duration getTotalDuration();

/// Get the total duration of all tracks referenced by the given model indices
mixxx::Duration getTotalDuration(const QModelIndexList& indices);
const QList<int> getSelectedPositions(const QModelIndexList& indices) const override;
Expand All @@ -43,6 +46,9 @@ class PlaylistTableModel final : public TrackSetTableModel {

QString modelKey(bool noSearch) const override;

signals:
void playlistTracksChanged();

private slots:
void playlistsChanged(const QSet<int>& playlistIds);

Expand Down
Loading