Skip to content

Commit 99c77f3

Browse files
committed
Merge branch '2.5' into '2.6'
2 parents d9519f5 + ae37416 commit 99c77f3

5 files changed

Lines changed: 98 additions & 15 deletions

File tree

src/effects/backends/builtin/echoeffect.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,13 +167,13 @@ void EchoEffect::processChannel(
167167
int read_position = pGroupState->write_position;
168168
decrementRing(&read_position, delay_samples, pGroupState->delay_buf.size());
169169

170-
RampingValue<CSAMPLE_GAIN> send(send_current,
171-
pGroupState->prev_send,
170+
RampingValue<CSAMPLE_GAIN> send(pGroupState->prev_send,
171+
send_current,
172172
engineParameters.framesPerBuffer());
173173
// Feedback the delay buffer and then add the new input.
174174

175-
RampingValue<CSAMPLE_GAIN> feedback(feedback_current,
176-
pGroupState->prev_feedback,
175+
RampingValue<CSAMPLE_GAIN> feedback(pGroupState->prev_feedback,
176+
feedback_current,
177177
engineParameters.framesPerBuffer());
178178

179179
int rampIndex = 0;

src/library/dao/playlistdao.cpp

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
#include "util/math.h"
1414

1515
PlaylistDAO::PlaylistDAO()
16-
: m_pAutoDJProcessor(nullptr) {
16+
: m_currentHistoryPlaylist(kInvalidPlaylistId),
17+
m_pAutoDJProcessor(nullptr) {
1718
}
1819

1920
void PlaylistDAO::initialize(const QSqlDatabase& database) {
@@ -330,19 +331,35 @@ bool PlaylistDAO::deleteUnlockedPlaylists(QStringList&& idStringList) {
330331
}
331332

332333
bool PlaylistDAO::deleteAllUnlockedPlaylistsWithFewerTracks(
333-
PlaylistDAO::HiddenType type, int minNumberOfTracks) {
334+
PlaylistDAO::HiddenType type,
335+
int minNumberOfTracks,
336+
bool skipCurrHistory) {
337+
// Note: this slot is also called after purging tracks in order to delete
338+
// now empty history playlists.
339+
// Though, if the current History is now also empty, we must not delete that!
340+
// Else the following session log is lost -- or rather not recorded in the
341+
// first place since the id passed to appendTrackToPlaylist() does not exist
342+
// anymore.
343+
// skipCurrHistory prevents that.
334344
VERIFY_OR_DEBUG_ASSERT(minNumberOfTracks > 0) {
335345
return false; // nothing to do, probably unintended invocation
336346
}
337347

338348
QSqlQuery query(m_database);
339-
query.prepare(QStringLiteral(
349+
QString queryString = QStringLiteral(
340350
"SELECT id FROM Playlists "
341351
"WHERE (SELECT count(playlist_id) FROM PlaylistTracks WHERE "
342352
"Playlists.ID = PlaylistTracks.playlist_id) < :length AND "
343-
"Playlists.hidden = :hidden AND Playlists.locked = 0"));
353+
"Playlists.hidden = :hidden AND Playlists.locked = 0");
354+
if (skipCurrHistory) {
355+
queryString.append(QStringLiteral(" AND Playlists.ID != :currHistoryId"));
356+
}
357+
query.prepare(queryString);
344358
query.bindValue(":hidden", static_cast<int>(type));
345359
query.bindValue(":length", minNumberOfTracks);
360+
if (skipCurrHistory) {
361+
query.bindValue(":currHistoryId", m_currentHistoryPlaylist);
362+
}
346363
if (!query.exec()) {
347364
LOG_FAILED_QUERY(query);
348365
return false;
@@ -352,6 +369,11 @@ bool PlaylistDAO::deleteAllUnlockedPlaylistsWithFewerTracks(
352369
while (query.next()) {
353370
idStringList.append(query.value(0).toString());
354371
}
372+
373+
if (idStringList.isEmpty()) {
374+
return false;
375+
}
376+
355377
qInfo() << "Prepared deletion of" << idStringList.size() << "playlists of type" << type
356378
<< "that contain fewer than" << minNumberOfTracks << "tracks";
357379

@@ -481,9 +503,29 @@ bool PlaylistDAO::removeTracksFromPlaylist(int playlistId, int startIndex) {
481503
return true;
482504
}
483505

506+
bool PlaylistDAO::playlistExists(const int playlistId) const {
507+
ScopedTransaction transaction(m_database);
508+
QSqlQuery query(m_database);
509+
query.prepare(QStringLiteral("SELECT id FROM Playlists WHERE id = :id"));
510+
query.bindValue(":id", playlistId);
511+
512+
if (!query.exec()) {
513+
LOG_FAILED_QUERY(query);
514+
return false;
515+
}
516+
517+
if (query.next()) {
518+
// id is guaranteed to be unique, so we can return here
519+
return true;
520+
}
521+
// not found
522+
return false;
523+
}
524+
484525
bool PlaylistDAO::appendTracksToPlaylist(const QList<TrackId>& trackIds, const int playlistId) {
485526
// qDebug() << "PlaylistDAO::appendTracksToPlaylist"
486527
// << QThread::currentThread() << m_database.connectionName();
528+
DEBUG_ASSERT(playlistExists(playlistId));
487529

488530
// Start the transaction
489531
ScopedTransaction transaction(m_database);
@@ -1094,7 +1136,8 @@ void PlaylistDAO::removeTracksFromPlaylists(const QList<TrackId>& trackIds, bool
10941136
transaction.commit();
10951137

10961138
// We may now have empty history playlists. Remove them.
1097-
deleteAllUnlockedPlaylistsWithFewerTracks(PlaylistDAO::PLHT_SET_LOG, 1);
1139+
// Note: does not delete current History playlist.
1140+
deleteAllUnlockedPlaylistsWithFewerTracks(PlaylistDAO::PLHT_SET_LOG, 1, true);
10981141

10991142
// update the sidebar
11001143
emit playlistContentChanged(playlistIds);

src/library/dao/playlistdao.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ class PlaylistDAO : public QObject, public virtual DAO {
4848
/// Needs to be called inside a transaction.
4949
/// @return true on success, false on error
5050
bool deleteAllUnlockedPlaylistsWithFewerTracks(const PlaylistDAO::HiddenType type,
51-
int minNumberOfTracks);
51+
int minNumberOfTracks,
52+
bool skipCurrHistory = false);
5253
// Rename a playlist
5354
void renamePlaylist(const int playlistId, const QString& newName);
5455
// Lock or unlock a playlist
@@ -57,6 +58,8 @@ class PlaylistDAO : public QObject, public virtual DAO {
5758
int setPlaylistsLocked(const QSet<int>& playlistIds, const bool lock);
5859
// Find out the state of a playlist lock
5960
bool isPlaylistLocked(const int playlistId) const;
61+
// Check if a playlist exists
62+
bool playlistExists(const int playlistId) const;
6063
// Append a list of tracks to a playlist
6164
bool appendTracksToPlaylist(const QList<TrackId>& trackIds, const int playlistId);
6265
// Append a track to a playlist
@@ -120,6 +123,10 @@ class PlaylistDAO : public QObject, public virtual DAO {
120123

121124
void getPlaylistsTrackIsIn(TrackId trackId, QSet<int>* playlistSet) const;
122125

126+
void setCurrentHistoryPlaylistId(int id) {
127+
m_currentHistoryPlaylist = id;
128+
}
129+
123130
void setAutoDJProcessor(AutoDJProcessor* pAutoDJProcessor);
124131

125132
signals:
@@ -151,6 +158,7 @@ class PlaylistDAO : public QObject, public virtual DAO {
151158
void populatePlaylistMembershipCache();
152159

153160
QMultiHash<TrackId, int> m_playlistsTrackIsIn;
161+
int m_currentHistoryPlaylist;
154162
AutoDJProcessor* m_pAutoDJProcessor;
155163
DISALLOW_COPY_AND_ASSIGN(PlaylistDAO);
156164
};

src/library/trackset/setlogfeature.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,7 @@ void SetlogFeature::slotGetNewPlaylist() {
383383
<< set_log_name;
384384
} else {
385385
m_recentTracks.clear();
386+
m_playlistDao.setCurrentHistoryPlaylistId(m_currentPlaylistId);
386387
}
387388

388389
// reload child model again because the 'added' signal fired by PlaylistDAO
@@ -447,6 +448,7 @@ void SetlogFeature::slotJoinWithPrevious() {
447448

448449
// Change current setlog
449450
m_currentPlaylistId = previousPlaylistId;
451+
m_playlistDao.setCurrentHistoryPlaylistId(m_currentPlaylistId);
450452
}
451453
qDebug() << "slotJoinWithPrevious() current:"
452454
<< clickedPlaylistId

src/widget/wlibrarytableview.cpp

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,15 +111,45 @@ bool WLibraryTableView::restoreTrackModelState(
111111
verticalScrollBar()->setValue(state->verticalScrollPosition);
112112
horizontalScrollBar()->setValue(state->horizontalScrollPosition);
113113

114-
auto* pSelection = selectionModel();
115-
pSelection->clearSelection();
114+
// Build a selection range rather than selecting each track individually,
115+
// which can lag the GUI by spamming selectionChanged() handlers.
116+
QItemSelectionModel* pSelectionModel = selectionModel();
117+
pSelectionModel->clearSelection();
118+
QItemSelection newSelection;
116119
QModelIndexList selectedRows = state->selectedRows;
120+
QModelIndex topLeft;
121+
QModelIndex bottomRight;
117122
if (!selectedRows.isEmpty()) {
118-
for (auto index : std::as_const(selectedRows)) {
119-
pSelection->select(index,
120-
QItemSelectionModel::Select | QItemSelectionModel::Rows);
123+
// In saveTrackModelState() we fill state->selectedRows with the sorted
124+
// rows, hence no need to sort here.
125+
for (const QModelIndex& index : std::as_const(selectedRows)) {
126+
if (!topLeft.isValid()) {
127+
// start new range. only done once for first row
128+
topLeft = index;
129+
bottomRight = index;
130+
continue;
131+
}
132+
133+
if (index.row() == bottomRight.row() + 1) {
134+
// continuous range
135+
bottomRight = index;
136+
continue;
137+
} else {
138+
// prev index was end of range, add current range to selection
139+
// and start a new one
140+
newSelection.select(topLeft, bottomRight);
141+
topLeft = index;
142+
bottomRight = index;
143+
}
144+
}
145+
146+
// If we reached end, submit the last selection
147+
if (bottomRight == selectedRows.last()) {
148+
newSelection.select(topLeft, bottomRight);
121149
}
122150
}
151+
pSelectionModel->select(newSelection,
152+
QItemSelectionModel::Select | QItemSelectionModel::Rows);
123153

124154
QModelIndex currIndex = state->currentIndex;
125155
restoreCurrentIndex(currIndex);

0 commit comments

Comments
 (0)