Skip to content
Open
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
1 change: 1 addition & 0 deletions data/data.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<file>schema/schema-20.sql</file>
<file>schema/schema-21.sql</file>
<file>schema/schema-22.sql</file>
<file>schema/schema-23.sql</file>
<file>schema/device-schema.sql</file>
<file>style/strawberry.css</file>
<file>style/smartplaylistsearchterm.css</file>
Expand Down
5 changes: 5 additions & 0 deletions data/schema/schema-23.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ALTER TABLE playlists ADD COLUMN half_playing_time_s INTEGER;

ALTER TABLE playlists ADD COLUMN position_playing_time INTEGER;

UPDATE schema_version SET version=23;
5 changes: 4 additions & 1 deletion data/schema/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ CREATE TABLE IF NOT EXISTS schema_version (

DELETE FROM schema_version;

INSERT INTO schema_version (version) VALUES (22);
INSERT INTO schema_version (version) VALUES (23);

CREATE TABLE IF NOT EXISTS directories (
path TEXT NOT NULL,
Expand Down Expand Up @@ -1027,6 +1027,9 @@ CREATE TABLE IF NOT EXISTS playlists (
ui_path TEXT,
is_favorite INTEGER NOT NULL DEFAULT 0,

half_playing_time_s INTEGER,
position_playing_time INTEGER,

dynamic_playlist_type INTEGER,
dynamic_playlist_backend TEXT,
dynamic_playlist_data BLOB
Expand Down
2 changes: 1 addition & 1 deletion src/core/database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@

using namespace Qt::Literals::StringLiterals;

const int Database::kSchemaVersion = 22;
const int Database::kSchemaVersion = 23;

namespace {
constexpr char kDatabaseFilename[] = "strawberry.db";
Expand Down
3 changes: 3 additions & 0 deletions src/core/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1833,6 +1833,9 @@ void MainWindow::UpdateTrackPosition() {
}
}

// At the end of the time of the track, move to the next track
app_->player()->EndPositionNext(position);

}

void MainWindow::UpdateTrackSliderPosition() {
Expand Down
10 changes: 6 additions & 4 deletions src/core/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ Player::Player(const SharedPtr<TaskManager> task_manager, const SharedPtr<UrlHan
menu_previousmode_(BehaviourSettings::PreviousBehaviour::DontRestart),
seek_step_sec_(10),
volume_increment_(5),
play_offset_nanosec_(0) {
play_offset_nanosec_(0),
play_end_sec_(0) {

setObjectName(QLatin1String(QObject::metaObject()->className()));

Expand Down Expand Up @@ -757,7 +758,8 @@ void Player::PlayAt(const int index, const bool pause, const quint64 offset_nano
return;
}

current_item_ = playlist_manager_->active()->current_item();
current_item_ = playlist_manager_->active()->current_item(play_offset_nanosec_, play_end_sec_);

const QUrl url = current_item_->EffectiveUrl();

if (url_handlers_->CanHandle(url)) {
Expand All @@ -773,8 +775,8 @@ void Player::PlayAt(const int index, const bool pause, const quint64 offset_nano
HandleLoadResult(url_handler->StartLoading(url));
}
else {
qLog(Debug) << "Playing song" << current_item_->EffectiveMetadata().title() << url << "position" << offset_nanosec;
engine_->Play(current_item_->OriginalUrl(), url, pause, change, current_item_->EffectiveMetadata().has_cue(), static_cast<quint64>(current_item_->effective_beginning_nanosec()), current_item_->effective_end_nanosec(), offset_nanosec, current_item_->EffectiveMetadata().ebur128_integrated_loudness_lufs());
qLog(Debug) << "Playing song" << current_item_->EffectiveMetadata().title() << url << "position" << play_offset_nanosec_;
engine_->Play(current_item_->OriginalUrl(), url, pause, change, current_item_->EffectiveMetadata().has_cue(), static_cast<quint64>(current_item_->effective_beginning_nanosec()), current_item_->effective_end_nanosec(), play_offset_nanosec_, current_item_->EffectiveMetadata().ebur128_integrated_loudness_lufs());
}

}
Expand Down
6 changes: 6 additions & 0 deletions src/core/player.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ class Player : public PlayerInterface {
void SetAnalyzer(AnalyzerContainer *analyzer) { analyzer_ = analyzer; }
void SetEqualizer(SharedPtr<Equalizer> equalizer) { equalizer_ = equalizer; }

void EndPositionNext(const int position) {
if (play_end_sec_ > 0 && play_end_sec_ <= position)
Next();
}

public Q_SLOTS:
void ReloadSettings() override;

Expand Down Expand Up @@ -167,6 +172,7 @@ class Player : public PlayerInterface {

QDateTime pause_time_;
quint64 play_offset_nanosec_;
int play_end_sec_;
};

#endif // PLAYER_H
34 changes: 32 additions & 2 deletions src/playlist/playlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ Playlist::Playlist(const SharedPtr<TaskManager> task_manager,
const int id,
const QString &special_type,
const bool favorite,
const int half_playing_time_s,
const int percent_interest_song,
QObject *parent)
: QAbstractListModel(parent),
is_loading_(false),
Expand All @@ -156,7 +158,9 @@ Playlist::Playlist(const SharedPtr<TaskManager> task_manager,
scrobble_point_(-1),
auto_sort_(false),
sort_column_(Column::Title),
sort_order_(Qt::AscendingOrder) {
sort_order_(Qt::AscendingOrder),
half_playing_time_s_(half_playing_time_s),
percent_interest_song_(percent_interest_song) {

undo_stack_->setUndoLimit(kUndoStackSize);

Expand Down Expand Up @@ -1651,7 +1655,7 @@ void Playlist::Save() {

if (!playlist_backend_ || is_loading_) return;

playlist_backend_->SavePlaylistAsync(id_, items_, last_played_row(), dynamic_playlist_);
playlist_backend_->SavePlaylistAsync(id_, items_, last_played_row(), half_playing_time_s_, percent_interest_song_, dynamic_playlist_);

}

Expand Down Expand Up @@ -1923,6 +1927,32 @@ PlaylistItemPtr Playlist::current_item() const {

}

PlaylistItemPtr Playlist::current_item(quint64& start_offset_ns, int& end_offset_s) const {

PlaylistItemPtr ret_value = current_item();

end_offset_s = 0;

if (ret_value && half_playing_time_s_ > 0) {
auto &&current_song = ret_value->EffectiveMetadata();
auto &&middle_time_ns = (current_song.length_nanosec() * percent_interest_song_) / 100;
qint64 start_time_ns = middle_time_ns - (static_cast<qint64>(half_playing_time_s_) * 1'000'000'000L);
qint64 end_time_s = (middle_time_ns + (static_cast<qint64>(half_playing_time_s_) * 1'000'000'000L)) / 1'000'000'000L;

if (start_time_ns > static_cast<qint64>(start_offset_ns)) {
start_offset_ns = start_time_ns;
}
if (end_time_s >= (current_song.length_nanosec() / 1'000'000'000L)) {
// in the case of I am waiting for the end of the track to move to the next
// I am not doing anything to signal that we must wait the end
return ret_value;
}
end_offset_s = static_cast<int>(end_time_s);
}
return ret_value;

}

PlaylistItem::Options Playlist::current_item_options() const {
if (!current_item()) return PlaylistItem::Option::Default;
return current_item()->options();
Expand Down
13 changes: 13 additions & 0 deletions src/playlist/playlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ class Playlist : public QAbstractListModel {
const int id,
const QString &special_type = QString(),
const bool favorite = false,
const int half_playing_time_s = 0,
const int percent_interest_song = 50,
QObject *parent = nullptr);

~Playlist() override;
Expand Down Expand Up @@ -209,6 +211,7 @@ class Playlist : public QAbstractListModel {
bool has_item_at(const int index) const { return index >= 0 && index < rowCount(); }

PlaylistItemPtr current_item() const;
PlaylistItemPtr current_item(quint64& start_offset_ns, int& end_offset_s) const;

PlaylistItem::Options current_item_options() const;
Song current_item_metadata() const;
Expand All @@ -227,6 +230,12 @@ class Playlist : public QAbstractListModel {

QUndoStack *undo_stack() const { return undo_stack_; }

int half_playing_time_s() const { return half_playing_time_s_; }
void UpdatePlayingTime(const int time_s) { half_playing_time_s_ = time_s; Save(); }

int percent_interest_song() const { return percent_interest_song_; }
void UpdatePlayingPosition(const int percent_time) { percent_interest_song_ = percent_time; Save(); }

bool scrobbled() const { return scrobbled_; }
void set_scrobbled(const bool state) { scrobbled_ = state; }
qint64 scrobble_point_nanosec() const { return scrobble_point_; }
Expand Down Expand Up @@ -436,6 +445,10 @@ class Playlist : public QAbstractListModel {
bool auto_sort_;
Column sort_column_;
Qt::SortOrder sort_order_;

// Variables to maintain the time to play the song
int half_playing_time_s_;
int percent_interest_song_;
};

#endif // PLAYLIST_H
18 changes: 12 additions & 6 deletions src/playlist/playlistbackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ PlaylistBackend::PlaylistList PlaylistBackend::GetPlaylists(const GetPlaylistsFl
}

SqlQuery q(db);
q.prepare(u"SELECT ROWID, name, last_played, special_type, ui_path, is_favorite, dynamic_playlist_type, dynamic_playlist_data, dynamic_playlist_backend FROM playlists "_s + condition + u" ORDER BY ui_order"_s);
q.prepare(u"SELECT ROWID, name, last_played, special_type, ui_path, is_favorite, dynamic_playlist_type, dynamic_playlist_data, dynamic_playlist_backend, half_playing_time_s, position_playing_time FROM playlists "_s + condition + u" ORDER BY ui_order"_s);
if (!q.Exec()) {
database_->ReportErrors(q);
return ret;
Expand All @@ -147,6 +147,8 @@ PlaylistBackend::PlaylistList PlaylistBackend::GetPlaylists(const GetPlaylistsFl
p.dynamic_type = static_cast<PlaylistGenerator::Type>(q.value(6).toInt());
p.dynamic_data = q.value(7).toByteArray();
p.dynamic_backend = q.value(8).toString();
p.half_playing_time_s_ = q.value(9).toInt();
p.percent_interest_song_ = q.value(10).toInt();
ret << p;
}

Expand All @@ -160,7 +162,7 @@ PlaylistBackend::Playlist PlaylistBackend::GetPlaylist(const int id) {
QSqlDatabase db(database_->Connect());

SqlQuery q(db);
q.prepare(u"SELECT ROWID, name, last_played, special_type, ui_path, is_favorite, dynamic_playlist_type, dynamic_playlist_data, dynamic_playlist_backend FROM playlists WHERE ROWID=:id"_s);
q.prepare(u"SELECT ROWID, name, last_played, special_type, ui_path, is_favorite, dynamic_playlist_type, dynamic_playlist_data, dynamic_playlist_backend, half_playing_time_s, position_playing_time FROM playlists WHERE ROWID=:id"_s);

q.BindValue(u":id"_s, id);
if (!q.Exec()) {
Expand All @@ -180,6 +182,8 @@ PlaylistBackend::Playlist PlaylistBackend::GetPlaylist(const int id) {
p.dynamic_type = static_cast<PlaylistGenerator::Type>(q.value(6).toInt());
p.dynamic_data = q.value(7).toByteArray();
p.dynamic_backend = q.value(8).toString();
p.half_playing_time_s_ = q.value(9).toInt();
p.percent_interest_song_ = q.value(10).toInt();

return p;

Expand Down Expand Up @@ -338,13 +342,13 @@ PlaylistItemPtr PlaylistBackend::RestoreCueData(PlaylistItemPtr item, SharedPtr<

}

void PlaylistBackend::SavePlaylistAsync(int playlist, const PlaylistItemPtrList &items, int last_played, PlaylistGeneratorPtr dynamic) {
void PlaylistBackend::SavePlaylistAsync(const int playlist, const PlaylistItemPtrList &items, const int last_played, const int half_playing_s, const int position_playing, PlaylistGeneratorPtr dynamic) {

QMetaObject::invokeMethod(this, "SavePlaylist", Qt::QueuedConnection, Q_ARG(int, playlist), Q_ARG(PlaylistItemPtrList, items), Q_ARG(int, last_played), Q_ARG(PlaylistGeneratorPtr, dynamic));
QMetaObject::invokeMethod(this, "SavePlaylist", Qt::QueuedConnection, Q_ARG(int, playlist), Q_ARG(PlaylistItemPtrList, items), Q_ARG(int, last_played), Q_ARG(int, half_playing_s), Q_ARG(int, position_playing), Q_ARG(PlaylistGeneratorPtr, dynamic));

}

void PlaylistBackend::SavePlaylist(int playlist, const PlaylistItemPtrList &items, int last_played, PlaylistGeneratorPtr dynamic) {
void PlaylistBackend::SavePlaylist(const int playlist, const PlaylistItemPtrList &items, const int last_played, const int half_playing_s, const int position_playing, PlaylistGeneratorPtr dynamic) {

QMutexLocker l(database_->Mutex());
QSqlDatabase db(database_->Connect());
Expand Down Expand Up @@ -381,7 +385,7 @@ void PlaylistBackend::SavePlaylist(int playlist, const PlaylistItemPtrList &item
// Update the last played track number
{
SqlQuery q(db);
q.prepare(u"UPDATE playlists SET last_played=:last_played, dynamic_playlist_type=:dynamic_type, dynamic_playlist_data=:dynamic_data, dynamic_playlist_backend=:dynamic_backend WHERE ROWID=:playlist"_s);
q.prepare(u"UPDATE playlists SET last_played=:last_played, dynamic_playlist_type=:dynamic_type, dynamic_playlist_data=:dynamic_data, dynamic_playlist_backend=:dynamic_backend, half_playing_time_s=:half_playing_s, position_playing_time=:position_playing WHERE ROWID=:playlist"_s);
q.BindValue(u":last_played"_s, last_played);
if (dynamic) {
q.BindValue(u":dynamic_type"_s, static_cast<int>(dynamic->type()));
Expand All @@ -393,6 +397,8 @@ void PlaylistBackend::SavePlaylist(int playlist, const PlaylistItemPtrList &item
q.BindValue(u":dynamic_data"_s, QByteArray());
q.BindValue(u":dynamic_backend"_s, QString());
}
q.BindValue(u":half_playing_s"_s, half_playing_s);
q.BindValue(u":position_playing"_s, position_playing);
q.BindValue(u":playlist"_s, playlist);
if (!q.Exec()) {
database_->ReportErrors(q);
Expand Down
7 changes: 5 additions & 2 deletions src/playlist/playlistbackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ class PlaylistBackend : public QObject {
PlaylistGenerator::Type dynamic_type;
QString dynamic_backend;
QByteArray dynamic_data;

int half_playing_time_s_;
int percent_interest_song_;
};
using PlaylistList = QList<Playlist>;

Expand All @@ -80,14 +83,14 @@ class PlaylistBackend : public QObject {
void SetPlaylistUiPath(const int id, const QString &path);

int CreatePlaylist(const QString &name, const QString &special_type);
void SavePlaylistAsync(const int playlist, const PlaylistItemPtrList &items, const int last_played, PlaylistGeneratorPtr dynamic);
void SavePlaylistAsync(const int playlist, const PlaylistItemPtrList &items, const int last_played, const int half_playing_s, const int position_playing, PlaylistGeneratorPtr dynamic);
void RenamePlaylist(const int id, const QString &new_name);
void FavoritePlaylist(const int id, bool is_favorite);
void RemovePlaylist(const int id);

public Q_SLOTS:
void Exit();
void SavePlaylist(const int playlist, const PlaylistItemPtrList &items, const int last_played, PlaylistGeneratorPtr dynamic);
void SavePlaylist(const int playlist, const PlaylistItemPtrList &items, const int last_played, const int half_playing_s, const int position_playing, PlaylistGeneratorPtr dynamic);

Q_SIGNALS:
void ExitFinished();
Expand Down
39 changes: 39 additions & 0 deletions src/playlist/playlistcontainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ PlaylistContainer::PlaylistContainer(QWidget *parent)
ui_->search_field->installEventFilter(this);

ui_->search_field->setToolTip(FilterParser::ToolTip());
ui_->playing_time_before_or_after->setToolTip(PlaylistContainer::ToolTipPlayingTime());
ui_->playing_center_time->setToolTip(PlaylistContainer::ToolTipPositionTime());

ui_->show_collection_option->setIcon(IconLoader::Load(u"configure"_s));
QObject::connect(ui_->show_collection_option, &QAction::triggered, this, &PlaylistContainer::DisplayPlayingOption);

ReloadSettings();

Expand All @@ -143,6 +148,7 @@ void PlaylistContainer::SetActions(QAction *new_playlist, QAction *load_playlist
ui_->load->setDefaultAction(load_playlist);
ui_->save->setDefaultAction(save_playlist);
ui_->clear->setDefaultAction(clear_playlist);
ui_->display_option->setDefaultAction(ui_->show_collection_option);

ui_->tab_bar->SetActions(new_playlist, load_playlist);

Expand All @@ -154,6 +160,9 @@ void PlaylistContainer::SetActions(QAction *new_playlist, QAction *load_playlist
QObject::connect(previous_playlist, &QAction::triggered, this, &PlaylistContainer::GoToPreviousPlaylistTab);
QObject::connect(save_all_playlists, &QAction::triggered, &*manager_, &PlaylistManager::SaveAllPlaylists);

QObject::connect(ui_->playing_time_before_or_after, &QSpinBox::valueChanged, &*manager_, &PlaylistManager::UpdatePlayingTime);
QObject::connect(ui_->playing_center_time, &QSpinBox::valueChanged, &*manager_, &PlaylistManager::UpdatePlayingPosition);

}

void PlaylistContainer::SetManager(SharedPtr<PlaylistManager> manager) {
Expand Down Expand Up @@ -194,6 +203,12 @@ void PlaylistContainer::SetViewModel(Playlist *playlist, const int scroll_positi

playlist_ = playlist;

ui_->playing_time_before_or_after->blockSignals(true);
ui_->playing_time_before_or_after->setValue(manager_->half_playing_time_s());
ui_->playing_time_before_or_after->blockSignals(false);
ui_->playing_center_time->blockSignals(true);
ui_->playing_center_time->setValue(manager_->percent_interest_song());
ui_->playing_center_time->blockSignals(false);
// Set the view
playlist->IgnoreSorting(true);
view()->setModel(playlist->filter());
Expand Down Expand Up @@ -252,6 +267,7 @@ void PlaylistContainer::ReloadSettings() {
ui_->clear->setIconSize(QSize(iconsize, iconsize));
ui_->undo->setIconSize(QSize(iconsize, iconsize));
ui_->redo->setIconSize(QSize(iconsize, iconsize));
ui_->display_option->setIconSize(QSize(iconsize, iconsize));
ui_->search_field->setIconSize(iconsize);

s.beginGroup(kSettingsGroup);
Expand Down Expand Up @@ -466,6 +482,13 @@ void PlaylistContainer::UpdateNoMatchesLabel() {

}

void PlaylistContainer::DisplayPlayingOption() {

ui_->playing_time_before_or_after->setVisible(!ui_->playing_time_before_or_after->isVisible());
ui_->playing_center_time->setVisible(!ui_->playing_center_time->isVisible());

}

void PlaylistContainer::resizeEvent(QResizeEvent *e) {
QWidget::resizeEvent(e);
RepositionNoMatchesLabel();
Expand Down Expand Up @@ -535,3 +558,19 @@ bool PlaylistContainer::eventFilter(QObject *objectWatched, QEvent *event) {
return QWidget::eventFilter(objectWatched, event);

}

QString PlaylistContainer::ToolTipPlayingTime() {

return "<html><head/><body><p>"_L1 +
QObject::tr("The time played before and after the position time selected in seconds (0 for playing the complete track)") +
"</p></body></html>"_L1;

}

QString PlaylistContainer::ToolTipPositionTime() {

return "<html><head/><body><p>"_L1 +
QObject::tr("The position time reference selected in percent of the track length") +
"</p></body></html>"_L1;

}
Loading
Loading