Compare commits

...

48 Commits

Author SHA1 Message Date
Poldi c78e5622ed
Merge 992a16769a into eff6b75c43 2024-04-24 20:27:45 -05:00
Jonas Kvinge eff6b75c43 nsi: Remove /SOLID from SetCompressor for debug 2024-04-24 02:25:05 +02:00
Robert Gingras e8be0adf37 TagReaderTagLib: Remove redundant ID3v2 validity check
TagLib will have created a valid ID3v2 tag on this file by this point in the code, due to the way it handles the tag() method for WAV::File. Thus the null pointer check is redundant and the hasID3v2() call is at best redundant and at worst will cause tags to not save when they otherwise should have
2024-04-24 01:23:51 +02:00
Robert Gingras 9f4a82bb62 TagReaderTagLib: Remove file_mpeg argument from the SetEmbeddedArt ID3v2 overload 2024-04-24 01:23:51 +02:00
Robert Gingras 8d7e14f21d Song: Added WAV to list of supported filetypes 2024-04-24 01:23:51 +02:00
Robert Gingras d03d3622aa TagReaderTagLib: Have RIFF WAV files save ID3v2 tags, when applicable 2024-04-24 01:23:51 +02:00
Robert Gingras 821c32992d TagReaderTagLib: Refactor ID3v2 saving to a dedicated function 2024-04-24 01:23:51 +02:00
Robert Gingras b52cf9f3cd TagReaderTagLib: Reposition ParseID3v2Tag 2024-04-24 01:23:51 +02:00
Robert Gingras ab8e687f96 TagReaderTagLib: Add id3v2 parsing for RIFF WAV files 2024-04-24 01:23:51 +02:00
Robert Gingras 90703703aa TagReaderTagLib: Make id3v2 parsing reusable 2024-04-24 01:23:51 +02:00
Jonas Kvinge 176984afe0 RadioPlaylistItem: Set correct col position for InitFromQuery
Fixes #1430
2024-04-23 22:34:00 +02:00
Jonas Kvinge 542efa17ff Fix position for song and internet playlist items
Fixes #1430
2024-04-23 20:18:28 +02:00
Jonas Kvinge 6a2c2dbba1 Song: Fix loading length 2024-04-23 20:16:41 +02:00
Jonas Kvinge 426de61525 Add const and std::as_const 2024-04-23 17:15:42 +02:00
Jonas Kvinge 24c8d06d41 SongPlaylistItem: Use static_cast 2024-04-23 17:00:10 +02:00
Jonas Kvinge 227f5e5176 Replace QStringLiteral with QLatin1String 2024-04-23 16:57:49 +02:00
Jonas Kvinge 92e39a3e21 GlobalShortcut: Use optional 2024-04-23 16:54:54 +02:00
Jonas Kvinge fb2300e2fa EBUR128State: Add missing const reference 2024-04-23 16:54:22 +02:00
Jonas Kvinge 78becae5e9 AlbumCoverLoader: Use fully qualified namespace in slot 2024-04-23 16:53:40 +02:00
Jonas Kvinge d10eb4370e Player: Use chrono_literals 2024-04-23 16:53:12 +02:00
Jonas Kvinge 9c92ef941f CollectionModel: Remove redundant const_cast 2024-04-23 16:52:17 +02:00
Jonas Kvinge 7aefe3d71b Change QList<QString> to QStringList 2024-04-23 16:51:42 +02:00
Jonas Kvinge 398db964b8 Use QDateTime::currentSecsSinceEpoch 2024-04-23 16:48:51 +02:00
Jonas Kvinge 579349b104 ResizableTextEdit: Add Q_OBJECT macro 2024-04-23 16:44:44 +02:00
Poldi 992a16769a Merge branch 'master' of github.com:poldi171254/strawberry 2024-03-14 11:17:07 +11:00
Poldi 6c8be50fbb Pull Request V1 2024-03-14 11:13:01 +11:00
Poldi 84ac6f7915
Merge branch 'strawberrymusicplayer:master' into master 2024-03-13 09:16:31 +11:00
Poldi 4785e5fe2e All works V1 2024-03-12 16:25:59 +11:00
Poldi c00a3433eb Works but only once 2024-03-11 15:40:25 +11:00
Poldi 809027f26d Sound Info sent 2024-03-08 14:18:29 +11:00
Poldi 711316c5db First Server message ok 2024-03-04 17:15:59 +11:00
Poldi 7cebff9a03 First Outgoing Msg 2024-03-01 13:55:48 +11:00
Poldi 59e6714edc Compiles with proto 2024-02-27 10:21:20 +11:00
Poldi 2315da7858 Server V1 ok 2024-02-26 15:39:58 +11:00
Poldi fe7e4635a6 Client Add/delet now works 2024-02-18 12:30:13 +11:00
Poldi d4fb61d644 Add proxy 2024-02-17 16:30:02 +11:00
Poldi 09847eeffd client V1 2024-02-12 09:20:30 +11:00
Poldi 5376ed6a34 New Settings Class V2 2024-02-05 10:26:03 +11:00
Poldi 33a34010db New Settings Class 2024-02-04 16:43:57 +11:00
Poldi 1e313f529a Settings updates work 2024-02-03 12:24:59 +11:00
Poldi fcb11f0405 Gui comms works. Sort of 2024-02-01 12:00:21 +11:00
Poldi b38d20a3a7 Messages Stage1 2024-01-19 09:01:17 +11:00
Poldi 8a087afdc6 Tcp Server is up 2024-01-15 17:37:23 +11:00
Poldi d4f6ff208e TCP Server start 2024-01-10 15:54:53 +11:00
Poldi 2ea822d33c UI Phase1 completed 2024-01-10 12:02:28 +11:00
Poldi d8c2f1afe4 UI Section Buttons work 2024-01-09 09:16:13 +11:00
Poldi 4cb917dc2a UI Section Stage2 works 2024-01-08 16:44:50 +11:00
Poldi 181623406e UI Section Stage1 works 2024-01-06 12:31:09 +11:00
112 changed files with 1760 additions and 377 deletions

View File

@ -525,6 +525,7 @@ add_subdirectory(dist)
add_subdirectory(ext/libstrawberry-common)
add_subdirectory(ext/libstrawberry-tagreader)
add_subdirectory(ext/strawberry-tagreader)
add_subdirectory(src/networkremote)
if(HAVE_MOODBAR)
add_subdirectory(ext/gstmoodbar)
endif()

View File

@ -501,5 +501,6 @@
<file>icons/22x22/somafm.png</file>
<file>icons/22x22/radioparadise.png</file>
<file>icons/22x22/musicbrainz.png</file>
<file>icons/32x32/network-remote.png</file>
</qresource>
</RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

64
debian/control vendored Normal file
View File

@ -0,0 +1,64 @@
Source: strawberry
Section: sound
Priority: optional
Maintainer: Jonas Kvinge <jonas@jkvinge.net>
Build-Depends: debhelper (>= 11),
git,
make,
cmake,
gcc,
g++,
protobuf-compiler,
libglib2.0-dev,
libdbus-1-dev,
libprotobuf-dev,
libboost-dev,
libsqlite3-dev,
libasound2-dev,
libpulse-dev,
libtag1-dev,
libicu-dev,
qt6-base-dev,qt6-base-dev-tools,qt6-tools-dev,qt6-tools-dev-tools,qt6-l10n-tools,
libgstreamer1.0-dev,
libgstreamer-plugins-base1.0-dev,
libcdio-dev,
libgpod-dev,
libmtp-dev,
libchromaprint-dev,
libfftw3-dev,
libebur128-dev
Standards-Version: 4.6.1
Package: strawberry
Architecture: any
Depends: ${shlibs:Depends},
${misc:Depends},
libqt6sql6-sqlite,qt6-qpa-plugins,
gstreamer1.0-plugins-base,
gstreamer1.0-plugins-good,
gstreamer1.0-alsa,
gstreamer1.0-pulseaudio
Homepage: http://www.strawberrymusicplayer.org/
Description: music player and music collection organizer
Strawberry is a music player aimed at music collectors and audiophiles.
.
Features:
- Play and organize music
- Supports WAV, FLAC, WavPack, Ogg Vorbis, Speex, MPC, TrueAudio, AIFF, MP4, MP3 and ASF
- Audio CD playback
- Native desktop notifications
- Playlist management and playlists in multiple formats
- Smart and dynamic playlists
- Advanced audio output and device configuration for bit-perfect playback on Linux
- Edit tags on audio files
- Automatically retrieve tags from MusicBrainz
- Album cover art from Last.fm, Musicbrainz, Discogs, Musixmatch, Deezer, Tidal, Qobuz and Spotify
- Song lyrics from Genius, Musixmatch, ChartLyrics, lyrics.ovh, lololyrics.com, songlyrics.com, azlyrics.com, elyrics.net and lyricsmode.com
- Audio analyzer
- Audio equalizer
- Transfer music to mass-storage USB players, MTP compatible devices and iPod Nano/Classic
- Scrobbler with support for Last.fm, Libre.fm and ListenBrainz
- Streaming support for Subsonic-compatible servers
- Unofficial streaming support for Tidal and Qobuz
.
It is a fork of Clementine. The name is inspired by the band Strawbs.

View File

@ -109,7 +109,11 @@
Unicode True
!ifdef debug
SetCompressor lzma
!else
SetCompressor /SOLID lzma
!endif
!include "MUI2.nsh"
!include "FileAssociation.nsh"

View File

@ -23,6 +23,7 @@
#include <cstdio>
#include <cstddef>
#include <utility>
#include <QtGlobal>
#include <QObject>
@ -250,7 +251,7 @@ void WorkerPool<HandlerType>::DoStart() {
search_path << QDir::cleanPath(QCoreApplication::applicationDirPath() + QStringLiteral("/../PlugIns"));
#endif
for (const QString &path_prefix : search_path) {
for (const QString &path_prefix : std::as_const(search_path)) {
const QString executable_path = path_prefix + QLatin1Char('/') + executable_name_;
if (QFile::exists(executable_path)) {
executable_path_ = executable_path;

View File

@ -248,7 +248,7 @@ bool TagReaderTagLib::ReadFile(const QString &filename, spb::tagreader::SongMeta
song->set_ctime(song->mtime());
}
song->set_lastseen(QDateTime::currentDateTime().toSecsSinceEpoch());
song->set_lastseen(QDateTime::currentSecsSinceEpoch());
std::unique_ptr<TagLib::FileRef> fileref(factory_->GetFileRef(filename));
if (fileref->isNull()) {
@ -328,137 +328,8 @@ bool TagReaderTagLib::ReadFile(const QString &filename, spb::tagreader::SongMeta
}
else if (TagLib::MPEG::File *file_mpeg = dynamic_cast<TagLib::MPEG::File*>(fileref->file())) {
if (file_mpeg->ID3v2Tag()) {
const TagLib::ID3v2::FrameListMap &map = file_mpeg->ID3v2Tag()->frameListMap();
if (map.contains("TPOS")) disc = TStringToQString(map["TPOS"].front()->toString()).trimmed();
if (map.contains("TCOM")) TStringToStdString(map["TCOM"].front()->toString(), song->mutable_composer());
// content group
if (map.contains("TIT1")) TStringToStdString(map["TIT1"].front()->toString(), song->mutable_grouping());
// original artist/performer
if (map.contains("TOPE")) TStringToStdString(map["TOPE"].front()->toString(), song->mutable_performer());
// Skip TPE1 (which is the artist) here because we already fetched it
// non-standard: Apple, Microsoft
if (map.contains("TPE2")) TStringToStdString(map["TPE2"].front()->toString(), song->mutable_albumartist());
if (map.contains("TCMP")) compilation = TStringToQString(map["TCMP"].front()->toString()).trimmed();
if (map.contains("TDOR")) {
song->set_originalyear(map["TDOR"].front()->toString().substr(0, 4).toInt());
}
else if (map.contains("TORY")) {
song->set_originalyear(map["TORY"].front()->toString().substr(0, 4).toInt());
}
if (map.contains("USLT")) {
TStringToStdString(map["USLT"].front()->toString(), song->mutable_lyrics());
}
else if (map.contains("SYLT")) {
TStringToStdString(map["SYLT"].front()->toString(), song->mutable_lyrics());
}
if (map.contains("APIC")) song->set_art_embedded(true);
// Find a suitable comment tag. For now we ignore iTunNORM comments.
for (uint i = 0; i < map["COMM"].size(); ++i) {
const TagLib::ID3v2::CommentsFrame *frame = dynamic_cast<const TagLib::ID3v2::CommentsFrame*>(map["COMM"][i]);
if (frame && TStringToQString(frame->description()) != QStringLiteral("iTunNORM")) {
TStringToStdString(frame->text(), song->mutable_comment());
break;
}
}
if (TagLib::ID3v2::UserTextIdentificationFrame *frame_fmps_playcount = TagLib::ID3v2::UserTextIdentificationFrame::find(file_mpeg->ID3v2Tag(), "FMPS_Playcount")) {
TagLib::StringList frame_field_list = frame_fmps_playcount->fieldList();
if (frame_field_list.size() > 1) {
int playcount = TStringToQString(frame_field_list[1]).toInt();
if (song->playcount() <= 0 && playcount > 0) {
song->set_playcount(playcount);
}
}
}
if (TagLib::ID3v2::UserTextIdentificationFrame *frame_fmps_rating = TagLib::ID3v2::UserTextIdentificationFrame::find(file_mpeg->ID3v2Tag(), "FMPS_Rating")) {
TagLib::StringList frame_field_list = frame_fmps_rating->fieldList();
if (frame_field_list.size() > 1) {
float rating = TStringToQString(frame_field_list[1]).toFloat();
if (song->rating() <= 0 && rating > 0 && rating <= 1.0) {
song->set_rating(rating);
}
}
}
if (map.contains("POPM")) {
const TagLib::ID3v2::PopularimeterFrame *frame = dynamic_cast<const TagLib::ID3v2::PopularimeterFrame*>(map["POPM"].front());
if (frame) {
if (song->playcount() <= 0 && frame->counter() > 0) {
song->set_playcount(frame->counter());
}
if (song->rating() <= 0 && frame->rating() > 0) {
song->set_rating(ConvertPOPMRating(frame->rating()));
}
}
}
if (map.contains("UFID")) {
for (uint i = 0; i < map["UFID"].size(); ++i) {
if (TagLib::ID3v2::UniqueFileIdentifierFrame *frame = dynamic_cast<TagLib::ID3v2::UniqueFileIdentifierFrame*>(map["UFID"][i])) {
const TagLib::PropertyMap property_map = frame->asProperties();
if (property_map.contains(kID3v2_MusicBrainz_RecordingID)) {
TStringToStdString(property_map[kID3v2_MusicBrainz_RecordingID].toString(), song->mutable_musicbrainz_recording_id());
}
}
}
}
if (map.contains("TXXX")) {
for (uint i = 0; i < map["TXXX"].size(); ++i) {
if (TagLib::ID3v2::UserTextIdentificationFrame *frame = dynamic_cast<TagLib::ID3v2::UserTextIdentificationFrame*>(map["TXXX"][i])) {
const TagLib::StringList frame_field_list = frame->fieldList();
if (frame_field_list.size() != 2) continue;
if (frame->description() == kID3v2_AcoustID_ID) {
TStringToStdString(frame_field_list.back(), song->mutable_acoustid_id());
}
if (frame->description() == kID3v2_AcoustID_Fingerprint) {
TStringToStdString(frame_field_list.back(), song->mutable_acoustid_fingerprint());
}
if (frame->description() == kID3v2_MusicBrainz_AlbumArtistID) {
TStringToStdString(frame_field_list.back(), song->mutable_musicbrainz_album_artist_id());
}
if (frame->description() == kID3v2_MusicBrainz_ArtistID) {
TStringToStdString(frame_field_list.back(), song->mutable_musicbrainz_artist_id());
}
if (frame->description() == kID3v2_MusicBrainz_OriginalArtistID) {
TStringToStdString(frame_field_list.back(), song->mutable_musicbrainz_original_artist_id());
}
if (frame->description() == kID3v2_MusicBrainz_AlbumID) {
TStringToStdString(frame_field_list.back(), song->mutable_musicbrainz_album_id());
}
if (frame->description() == kID3v2_MusicBrainz_OriginalAlbumID) {
TStringToStdString(frame_field_list.back(), song->mutable_musicbrainz_original_album_id());
}
if (frame->description() == kID3v2_MusicBrainz_TrackID) {
TStringToStdString(frame_field_list.back(), song->mutable_musicbrainz_track_id());
}
if (frame->description() == kID3v2_MusicBrainz_DiscID) {
TStringToStdString(frame_field_list.back(), song->mutable_musicbrainz_disc_id());
}
if (frame->description() == kID3v2_MusicBrainz_ReleaseGroupID) {
TStringToStdString(frame_field_list.back(), song->mutable_musicbrainz_release_group_id());
}
if (frame->description() == kID3v2_MusicBrainz_WorkID) {
TStringToStdString(frame_field_list.back(), song->mutable_musicbrainz_work_id());
}
}
}
}
if (file_mpeg->hasID3v2Tag()) {
ParseID3v2Tag(file_mpeg->ID3v2Tag(), &disc, &compilation, song);
}
}
@ -658,6 +529,12 @@ bool TagReaderTagLib::ReadFile(const QString &filename, spb::tagreader::SongMeta
if (tag) TStringToStdString(tag->comment(), song->mutable_comment());
}
else if (TagLib::RIFF::WAV::File *file_wav = dynamic_cast<TagLib::RIFF::WAV::File*>(fileref->file())) {
if (file_wav->hasID3v2Tag()) {
ParseID3v2Tag(file_wav->ID3v2Tag(), &disc, &compilation, song);
}
}
else if (tag) {
TStringToStdString(tag->comment(), song->mutable_comment());
}
@ -710,6 +587,139 @@ void TagReaderTagLib::TStringToStdString(const TagLib::String &tag, std::string
}
void TagReaderTagLib::ParseID3v2Tag(TagLib::ID3v2::Tag *tag, QString *disc, QString *compilation, spb::tagreader::SongMetadata *song) const {
TagLib::ID3v2::FrameListMap map = tag->frameListMap();
if (map.contains("TPOS")) *disc = TStringToQString(map["TPOS"].front()->toString()).trimmed();
if (map.contains("TCOM")) TStringToStdString(map["TCOM"].front()->toString(), song->mutable_composer());
// content group
if (map.contains("TIT1")) TStringToStdString(map["TIT1"].front()->toString(), song->mutable_grouping());
// original artist/performer
if (map.contains("TOPE")) TStringToStdString(map["TOPE"].front()->toString(), song->mutable_performer());
// Skip TPE1 (which is the artist) here because we already fetched it
// non-standard: Apple, Microsoft
if (map.contains("TPE2")) TStringToStdString(map["TPE2"].front()->toString(), song->mutable_albumartist());
if (map.contains("TCMP")) *compilation = TStringToQString(map["TCMP"].front()->toString()).trimmed();
if (map.contains("TDOR")) {
song->set_originalyear(map["TDOR"].front()->toString().substr(0, 4).toInt());
}
else if (map.contains("TORY")) {
song->set_originalyear(map["TORY"].front()->toString().substr(0, 4).toInt());
}
if (map.contains("USLT")) {
TStringToStdString(map["USLT"].front()->toString(), song->mutable_lyrics());
}
else if (map.contains("SYLT")) {
TStringToStdString(map["SYLT"].front()->toString(), song->mutable_lyrics());
}
if (map.contains("APIC")) song->set_art_embedded(true);
// Find a suitable comment tag. For now we ignore iTunNORM comments.
for (uint i = 0; i < map["COMM"].size(); ++i) {
const TagLib::ID3v2::CommentsFrame *frame = dynamic_cast<const TagLib::ID3v2::CommentsFrame*>(map["COMM"][i]);
if (frame && TStringToQString(frame->description()) != QStringLiteral("iTunNORM")) {
TStringToStdString(frame->text(), song->mutable_comment());
break;
}
}
if (TagLib::ID3v2::UserTextIdentificationFrame *frame_fmps_playcount = TagLib::ID3v2::UserTextIdentificationFrame::find(tag, "FMPS_Playcount")) {
TagLib::StringList frame_field_list = frame_fmps_playcount->fieldList();
if (frame_field_list.size() > 1) {
int playcount = TStringToQString(frame_field_list[1]).toInt();
if (song->playcount() <= 0 && playcount > 0) {
song->set_playcount(playcount);
}
}
}
if (TagLib::ID3v2::UserTextIdentificationFrame *frame_fmps_rating = TagLib::ID3v2::UserTextIdentificationFrame::find(tag, "FMPS_Rating")) {
TagLib::StringList frame_field_list = frame_fmps_rating->fieldList();
if (frame_field_list.size() > 1) {
float rating = TStringToQString(frame_field_list[1]).toFloat();
if (song->rating() <= 0 && rating > 0 && rating <= 1.0) {
song->set_rating(rating);
}
}
}
if (map.contains("POPM")) {
const TagLib::ID3v2::PopularimeterFrame *frame = dynamic_cast<const TagLib::ID3v2::PopularimeterFrame*>(map["POPM"].front());
if (frame) {
if (song->playcount() <= 0 && frame->counter() > 0) {
song->set_playcount(frame->counter());
}
if (song->rating() <= 0 && frame->rating() > 0) {
song->set_rating(ConvertPOPMRating(frame->rating()));
}
}
}
if (map.contains("UFID")) {
for (uint i = 0; i < map["UFID"].size(); ++i) {
if (TagLib::ID3v2::UniqueFileIdentifierFrame *frame = dynamic_cast<TagLib::ID3v2::UniqueFileIdentifierFrame*>(map["UFID"][i])) {
const TagLib::PropertyMap property_map = frame->asProperties();
if (property_map.contains(kID3v2_MusicBrainz_RecordingID)) {
TStringToStdString(property_map[kID3v2_MusicBrainz_RecordingID].toString(), song->mutable_musicbrainz_recording_id());
}
}
}
}
if (map.contains("TXXX")) {
for (uint i = 0; i < map["TXXX"].size(); ++i) {
if (TagLib::ID3v2::UserTextIdentificationFrame *frame = dynamic_cast<TagLib::ID3v2::UserTextIdentificationFrame*>(map["TXXX"][i])) {
const TagLib::StringList frame_field_list = frame->fieldList();
if (frame_field_list.size() != 2) continue;
if (frame->description() == kID3v2_AcoustID_ID) {
TStringToStdString(frame_field_list.back(), song->mutable_acoustid_id());
}
if (frame->description() == kID3v2_AcoustID_Fingerprint) {
TStringToStdString(frame_field_list.back(), song->mutable_acoustid_fingerprint());
}
if (frame->description() == kID3v2_MusicBrainz_AlbumArtistID) {
TStringToStdString(frame_field_list.back(), song->mutable_musicbrainz_album_artist_id());
}
if (frame->description() == kID3v2_MusicBrainz_ArtistID) {
TStringToStdString(frame_field_list.back(), song->mutable_musicbrainz_artist_id());
}
if (frame->description() == kID3v2_MusicBrainz_OriginalArtistID) {
TStringToStdString(frame_field_list.back(), song->mutable_musicbrainz_original_artist_id());
}
if (frame->description() == kID3v2_MusicBrainz_AlbumID) {
TStringToStdString(frame_field_list.back(), song->mutable_musicbrainz_album_id());
}
if (frame->description() == kID3v2_MusicBrainz_OriginalAlbumID) {
TStringToStdString(frame_field_list.back(), song->mutable_musicbrainz_original_album_id());
}
if (frame->description() == kID3v2_MusicBrainz_TrackID) {
TStringToStdString(frame_field_list.back(), song->mutable_musicbrainz_track_id());
}
if (frame->description() == kID3v2_MusicBrainz_DiscID) {
TStringToStdString(frame_field_list.back(), song->mutable_musicbrainz_disc_id());
}
if (frame->description() == kID3v2_MusicBrainz_ReleaseGroupID) {
TStringToStdString(frame_field_list.back(), song->mutable_musicbrainz_release_group_id());
}
if (frame->description() == kID3v2_MusicBrainz_WorkID) {
TStringToStdString(frame_field_list.back(), song->mutable_musicbrainz_work_id());
}
}
}
}
}
void TagReaderTagLib::ParseOggTag(const TagLib::Ogg::FieldListMap &map, QString *disc, QString *compilation, spb::tagreader::SongMetadata *song) const {
if (map.contains("COMPOSER")) TStringToStdString(map["COMPOSER"].front(), song->mutable_composer());
@ -943,14 +953,7 @@ bool TagReaderTagLib::SaveFile(const spb::tagreader::SaveFileRequest &request) c
TagLib::ID3v2::Tag *tag = file_mpeg->ID3v2Tag(true);
if (!tag) return false;
if (save_tags) {
SetTextFrame("TPOS", song.disc() <= 0 ? QString() : QString::number(song.disc()), tag);
SetTextFrame("TCOM", song.composer().empty() ? std::string() : song.composer(), tag);
SetTextFrame("TIT1", song.grouping().empty() ? std::string() : song.grouping(), tag);
SetTextFrame("TOPE", song.performer().empty() ? std::string() : song.performer(), tag);
// Skip TPE1 (which is the artist) here because we already set it
SetTextFrame("TPE2", song.albumartist().empty() ? std::string() : song.albumartist(), tag);
SetTextFrame("TCMP", song.compilation() ? QString::number(1) : QString(), tag);
SetUnsyncLyricsFrame(song.lyrics().empty() ? std::string() : song.lyrics(), tag);
SaveID3v2Tag(tag, song);
}
if (save_playcount) {
SetPlaycount(tag, song);
@ -959,7 +962,7 @@ bool TagReaderTagLib::SaveFile(const spb::tagreader::SaveFileRequest &request) c
SetRating(tag, song);
}
if (save_cover) {
SetEmbeddedArt(file_mpeg, tag, cover.data, cover.mime_type);
SetEmbeddedArt(tag, cover.data, cover.mime_type);
}
}
@ -985,6 +988,22 @@ bool TagReaderTagLib::SaveFile(const spb::tagreader::SaveFileRequest &request) c
}
}
else if (TagLib::RIFF::WAV::File *file_wav = dynamic_cast<TagLib::RIFF::WAV::File*>(fileref->file())) {
TagLib::ID3v2::Tag *tag = file_wav->ID3v2Tag();
if (save_tags) {
SaveID3v2Tag(tag, song);
}
if (save_playcount) {
SetPlaycount(tag, song);
}
if (save_rating) {
SetRating(tag, song);
}
if (save_cover) {
SetEmbeddedArt(tag, cover.data, cover.mime_type);
}
}
// Handle all the files which have VorbisComments (Ogg, OPUS, ...) in the same way;
// apart, so we keep specific behavior for some formats by adding another "else if" block above.
if (!is_flac) {
@ -1016,6 +1035,19 @@ bool TagReaderTagLib::SaveFile(const spb::tagreader::SaveFileRequest &request) c
}
void TagReaderTagLib::SaveID3v2Tag(TagLib::ID3v2::Tag *tag, const spb::tagreader::SongMetadata &song) const {
SetTextFrame("TPOS", song.disc() <= 0 ? QString() : QString::number(song.disc()), tag);
SetTextFrame("TCOM", song.composer().empty() ? std::string() : song.composer(), tag);
SetTextFrame("TIT1", song.grouping().empty() ? std::string() : song.grouping(), tag);
SetTextFrame("TOPE", song.performer().empty() ? std::string() : song.performer(), tag);
// Skip TPE1 (which is the artist) here because we already set it
SetTextFrame("TPE2", song.albumartist().empty() ? std::string() : song.albumartist(), tag);
SetTextFrame("TCMP", song.compilation() ? QString::number(1) : QString(), tag);
SetUnsyncLyricsFrame(song.lyrics().empty() ? std::string() : song.lyrics(), tag);
}
void TagReaderTagLib::SaveAPETag(TagLib::APE::Tag *tag, const spb::tagreader::SongMetadata &song) const {
tag->setItem("album artist", TagLib::APE::Item("album artist", TagLib::StringList(song.albumartist().c_str())));
@ -1278,9 +1310,7 @@ void TagReaderTagLib::SetEmbeddedArt(TagLib::Ogg::XiphComment *xiph_comment, con
}
void TagReaderTagLib::SetEmbeddedArt(TagLib::MPEG::File *file_mp3, TagLib::ID3v2::Tag *tag, const QByteArray &data, const QString &mime_type) const {
(void)file_mp3;
void TagReaderTagLib::SetEmbeddedArt(TagLib::ID3v2::Tag *tag, const QByteArray &data, const QString &mime_type) const {
// Remove existing covers
TagLib::ID3v2::FrameList apiclist = tag->frameListMap()["APIC"];
@ -1360,7 +1390,7 @@ bool TagReaderTagLib::SaveEmbeddedArt(const spb::tagreader::SaveEmbeddedArtReque
else if (TagLib::MPEG::File *file_mp3 = dynamic_cast<TagLib::MPEG::File*>(fileref.file())) {
TagLib::ID3v2::Tag *tag = file_mp3->ID3v2Tag();
if (!tag) return false;
SetEmbeddedArt(file_mp3, tag, cover.data, cover.mime_type);
SetEmbeddedArt(tag, cover.data, cover.mime_type);
}
// MP4/AAC

View File

@ -68,10 +68,12 @@ class TagReaderTagLib : public TagReaderBase {
private:
spb::tagreader::SongMetadata_FileType GuessFileType(TagLib::FileRef *fileref) const;
void ParseID3v2Tag(TagLib::ID3v2::Tag *tag, QString *disc, QString *compilation, spb::tagreader::SongMetadata *song) const;
void ParseOggTag(const TagLib::Ogg::FieldListMap &map, QString *disc, QString *compilation, spb::tagreader::SongMetadata *song) const;
void ParseAPETag(const TagLib::APE::ItemListMap &map, QString *disc, QString *compilation, spb::tagreader::SongMetadata *song) const;
void SetVorbisComments(TagLib::Ogg::XiphComment *vorbis_comment, const spb::tagreader::SongMetadata &song) const;
void SaveID3v2Tag(TagLib::ID3v2::Tag *tag, const spb::tagreader::SongMetadata &song) const;
void SaveAPETag(TagLib::APE::Tag *tag, const spb::tagreader::SongMetadata &song) const;
void SetTextFrame(const char *id, const QString &value, TagLib::ID3v2::Tag *tag) const;
@ -98,7 +100,7 @@ class TagReaderTagLib : public TagReaderBase {
void SetEmbeddedArt(TagLib::FLAC::File *flac_file, TagLib::Ogg::XiphComment *xiph_comment, const QByteArray &data, const QString &mime_type) const;
void SetEmbeddedArt(TagLib::Ogg::XiphComment *xiph_comment, const QByteArray &data, const QString &mime_type) const;
void SetEmbeddedArt(TagLib::MPEG::File *file_mp3, TagLib::ID3v2::Tag *tag, const QByteArray &data, const QString &mime_type) const;
void SetEmbeddedArt(TagLib::ID3v2::Tag *tag, const QByteArray &data, const QString &mime_type) const;
void SetEmbeddedArt(TagLib::MP4::File *aac_file, TagLib::MP4::Tag *tag, const QByteArray &data, const QString &mime_type) const;
private:

View File

@ -207,6 +207,7 @@ set(SOURCES
settings/appearancesettingspage.cpp
settings/contextsettingspage.cpp
settings/notificationssettingspage.cpp
settings/networkremotesettingspage.cpp
dialogs/about.cpp
dialogs/console.cpp
@ -293,6 +294,13 @@ set(SOURCES
organize/organizedialog.cpp
organize/organizeerrordialog.cpp
networkremote/networkremote.cpp
networkremote/tcpserver.cpp
networkremote/remotesettings.cpp
networkremote/client.cpp
networkremote/clientmanager.cpp
networkremote/incomingmsg.cpp
networkremote/outgoingmsg.cpp
)
set(HEADERS
@ -450,6 +458,7 @@ set(HEADERS
settings/appearancesettingspage.h
settings/contextsettingspage.h
settings/notificationssettingspage.h
settings/networkremotesettingspage.h
dialogs/about.h
dialogs/errordialog.h
@ -490,6 +499,7 @@ set(HEADERS
widgets/qsearchfield.h
widgets/ratingwidget.h
widgets/forcescrollperpixel.h
widgets/resizabletextedit.h
osd/osdbase.h
osd/osdpretty.h
@ -531,6 +541,13 @@ set(HEADERS
organize/organizedialog.h
organize/organizeerrordialog.h
networkremote/networkremote.h
networkremote/tcpserver.h
networkremote/remotesettings.h
networkremote/client.h
networkremote/clientmanager.h
networkremote/incomingmsg.h
networkremote/outgoingmsg.h
)
set(UI
@ -575,6 +592,7 @@ set(UI
settings/networkproxysettingspage.ui
settings/appearancesettingspage.ui
settings/notificationssettingspage.ui
settings/networkremotesettingspage.ui
equalizer/equalizer.ui
equalizer/equalizerslider.ui
@ -1115,6 +1133,7 @@ target_link_libraries(strawberry_lib PUBLIC
${SINGLEAPPLICATION_LIBRARIES}
libstrawberry-common
libstrawberry-tagreader
lib-networkremote
)
if(HAVE_DBUS)

View File

@ -22,6 +22,7 @@
#include "config.h"
#include <optional>
#include <utility>
#include <QtGlobal>
#include <QObject>
@ -155,7 +156,7 @@ void CollectionBackend::ResetPlayStatisticsAsync(const QList<int> &id_list, cons
void CollectionBackend::LoadDirectories() {
CollectionDirectoryList dirs = GetAllDirectories();
const CollectionDirectoryList dirs = GetAllDirectories();
QMutexLocker l(db_->Mutex());
QSqlDatabase db(db_->Connect());
@ -740,7 +741,7 @@ void CollectionBackend::UpdateSongsBySongID(const SongMap &new_songs) {
}
// Add or update songs.
QList new_songs_list = new_songs.values();
const QList new_songs_list = new_songs.values();
for (const Song &new_song : new_songs_list) {
if (old_songs.contains(new_song.song_id())) {
@ -811,7 +812,7 @@ void CollectionBackend::UpdateSongsBySongID(const SongMap &new_songs) {
}
// Delete songs
QList old_songs_list = old_songs.values();
const QList old_songs_list = old_songs.values();
for (const Song &old_song : old_songs_list) {
if (!new_songs.contains(old_song.song_id())) {
{
@ -1845,7 +1846,7 @@ void CollectionBackend::ClearAlbumArt(const QString &effective_albumartist, cons
}
void CollectionBackend::ForceCompilation(const QString &album, const QList<QString> &artists, const bool on) {
void CollectionBackend::ForceCompilation(const QString &album, const QStringList &artists, const bool on) {
QMutexLocker l(db_->Mutex());
QSqlDatabase db(db_->Connect());
@ -1914,7 +1915,7 @@ void CollectionBackend::IncrementPlayCount(const int id) {
SqlQuery q(db);
q.prepare(QStringLiteral("UPDATE %1 SET playcount = playcount + 1, lastplayed = :now WHERE ROWID = :id").arg(songs_table_));
q.BindValue(QStringLiteral(":now"), QDateTime::currentDateTime().toSecsSinceEpoch());
q.BindValue(QStringLiteral(":now"), QDateTime::currentSecsSinceEpoch());
q.BindValue(QStringLiteral(":id"), id);
if (!q.Exec()) {
db_->ReportErrors(q);
@ -2097,7 +2098,7 @@ SongList CollectionBackend::GetSongsBy(const QString &artist, const QString &alb
void CollectionBackend::UpdateLastPlayed(const QString &artist, const QString &album, const QString &title, const qint64 lastplayed) {
SongList songs = GetSongsBy(artist, album, title);
const SongList songs = GetSongsBy(artist, album, title);
if (songs.isEmpty()) {
qLog(Debug) << "Could not find a matching song in the database for" << artist << album << title;
return;
@ -2126,7 +2127,7 @@ void CollectionBackend::UpdateLastPlayed(const QString &artist, const QString &a
void CollectionBackend::UpdatePlayCount(const QString &artist, const QString &title, const int playcount, const bool save_tags) {
SongList songs = GetSongsBy(artist, QString(), title);
const SongList songs = GetSongsBy(artist, QString(), title);
if (songs.isEmpty()) {
qLog(Debug) << "Could not find a matching song in the database for" << artist << title;
return;
@ -2201,7 +2202,7 @@ void CollectionBackend::UpdateLastSeen(const int directory_id, const int expire_
SqlQuery q(db);
q.prepare(QStringLiteral("UPDATE %1 SET lastseen = :lastseen WHERE directory_id = :directory_id AND unavailable = 0").arg(songs_table_));
q.BindValue(QStringLiteral(":lastseen"), QDateTime::currentDateTime().toSecsSinceEpoch());
q.BindValue(QStringLiteral(":lastseen"), QDateTime::currentSecsSinceEpoch());
q.BindValue(QStringLiteral(":directory_id"), directory_id);
if (!q.Exec()) {
db_->ReportErrors(q);
@ -2222,7 +2223,7 @@ void CollectionBackend::ExpireSongs(const int directory_id, const int expire_una
SqlQuery q(db);
q.prepare(QStringLiteral("SELECT %1 FROM %2 LEFT JOIN playlist_items ON %2.ROWID = playlist_items.collection_id WHERE %2.directory_id = :directory_id AND %2.unavailable = 1 AND %2.lastseen > 0 AND %2.lastseen < :time AND playlist_items.collection_id IS NULL").arg(Song::JoinSpec(songs_table_), songs_table_));
q.BindValue(QStringLiteral(":directory_id"), directory_id);
q.BindValue(QStringLiteral(":time"), QDateTime::currentDateTime().toSecsSinceEpoch() - (expire_unavailable_songs_days * 86400));
q.BindValue(QStringLiteral(":time"), QDateTime::currentSecsSinceEpoch() - (expire_unavailable_songs_days * 86400));
if (!q.Exec()) {
db_->ReportErrors(q);
return;

View File

@ -250,7 +250,7 @@ class CollectionBackend : public CollectionBackendInterface {
void UpdateManualAlbumArt(const QString &effective_albumartist, const QString &album, const QUrl &art_manual);
void UnsetAlbumArt(const QString &effective_albumartist, const QString &album);
void ClearAlbumArt(const QString &effective_albumartist, const QString &album, const bool art_unset);
void ForceCompilation(const QString &album, const QList<QString> &artists, const bool on);
void ForceCompilation(const QString &album, const QStringList &artists, const bool on);
void IncrementPlayCount(const int id);
void IncrementSkipCount(const int id, const float progress);
void ResetPlayStatistics(const int id, const bool save_tags = false);

View File

@ -29,7 +29,7 @@ CollectionFilterOptions::CollectionFilterOptions() : filter_mode_(FilterMode::Al
bool CollectionFilterOptions::Matches(const Song &song) const {
if (max_age_ != -1) {
const qint64 cutoff = QDateTime::currentDateTime().toSecsSinceEpoch() - max_age_;
const qint64 cutoff = QDateTime::currentSecsSinceEpoch() - max_age_;
if (song.ctime() <= cutoff) return false;
}

View File

@ -21,6 +21,7 @@
#include "config.h"
#include <utility>
#include <memory>
#include <QApplication>
@ -161,7 +162,7 @@ void CollectionFilterWidget::Init(CollectionModel *model) {
QObject::disconnect(model_, nullptr, this, nullptr);
QObject::disconnect(model_, nullptr, group_by_dialog_, nullptr);
QObject::disconnect(group_by_dialog_, nullptr, model_, nullptr);
QList<QAction*> filter_ages = filter_ages_.keys();
const QList<QAction*> filter_ages = filter_ages_.keys();
for (QAction *action : filter_ages) {
QObject::disconnect(action, &QAction::triggered, model_, nullptr);
}
@ -174,7 +175,7 @@ void CollectionFilterWidget::Init(CollectionModel *model) {
QObject::connect(model_, &CollectionModel::GroupingChanged, this, &CollectionFilterWidget::GroupingChanged);
QObject::connect(group_by_dialog_, &GroupByDialog::Accepted, model_, &CollectionModel::SetGroupBy);
QList<QAction*> filter_ages = filter_ages_.keys();
const QList<QAction*> filter_ages = filter_ages_.keys();
for (QAction *action : filter_ages) {
int age = filter_ages_[action];
QObject::connect(action, &QAction::triggered, this, [this, age]() { model_->SetFilterAge(age); } );
@ -447,7 +448,8 @@ void CollectionFilterWidget::CheckCurrentGrouping(const CollectionModel::Groupin
UpdateGroupByActions();
}
for (QAction *action : group_by_group_->actions()) {
const QList<QAction*> actions = group_by_group_->actions();
for (QAction *action : actions) {
if (action->property("group_by").isNull()) continue;
if (g == action->property("group_by").value<CollectionModel::Grouping>()) {
@ -457,7 +459,6 @@ void CollectionFilterWidget::CheckCurrentGrouping(const CollectionModel::Groupin
}
// Check the advanced action
QList<QAction*> actions = group_by_group_->actions();
QAction *action = actions.last();
action->setChecked(true);

View File

@ -2013,7 +2013,7 @@ void CollectionModel::ExpandAll(CollectionItem *item) const {
if (!root_) return;
if (!item) item = root_;
const_cast<CollectionModel*>(this)->LazyPopulate(const_cast<CollectionItem*>(item), false);
const_cast<CollectionModel*>(this)->LazyPopulate(item, false);
for (CollectionItem *child : item->children) {
ExpandAll(child);
}

View File

@ -21,6 +21,7 @@
#include "config.h"
#include <utility>
#include <memory>
#include <QtGlobal>
@ -414,7 +415,7 @@ void CollectionView::contextMenuEvent(QContextMenuEvent *e) {
context_menu_index_ = qobject_cast<QSortFilterProxyModel*>(model())->mapToSource(context_menu_index_);
QModelIndexList selected_indexes = qobject_cast<QSortFilterProxyModel*>(model())->mapSelectionToSource(selectionModel()->selection()).indexes();
const QModelIndexList selected_indexes = qobject_cast<QSortFilterProxyModel*>(model())->mapSelectionToSource(selectionModel()->selection()).indexes();
int regular_elements = 0;
int regular_editable = 0;
@ -485,7 +486,8 @@ void CollectionView::SetShowInVarious(const bool on) {
// We put through "Various Artists" changes one album at a time,
// to make sure the old album node gets removed (due to all children removed), before the new one gets added
QMultiMap<QString, QString> albums;
for (const Song &song : GetSelectedSongs()) {
const SongList songs = GetSelectedSongs();
for (const Song &song : songs) {
if (albums.find(song.album(), song.artist()) == albums.end())
albums.insert(song.album(), song.artist());
}
@ -495,7 +497,7 @@ void CollectionView::SetShowInVarious(const bool on) {
if (on && albums.keys().count() == 1) {
const QStringList albums_list = albums.keys();
const QString album = albums_list.first();
SongList all_of_album = app_->collection_backend()->GetSongsByAlbum(album);
const SongList all_of_album = app_->collection_backend()->GetSongsByAlbum(album);
QSet<QString> other_artists;
for (const Song &s : all_of_album) {
if (!albums.contains(album, s.artist()) && !other_artists.contains(s.artist())) {
@ -512,9 +514,9 @@ void CollectionView::SetShowInVarious(const bool on) {
}
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
QSet<QString> albums_set = QSet<QString>(albums.keyBegin(), albums.keyEnd());
const QSet<QString> albums_set = QSet<QString>(albums.keyBegin(), albums.keyEnd());
#else
QSet<QString> albums_set = QSet<QString>::fromList(albums.keys());
const QSet<QString> albums_set = QSet<QString>::fromList(albums.keys());
#endif
for (const QString &album : albums_set) {
app_->collection_backend()->ForceCompilation(album, albums.values(album), on);
@ -763,7 +765,7 @@ void CollectionView::FilterReturnPressed() {
void CollectionView::ShowInBrowser() const {
SongList songs = GetSelectedSongs();
const SongList songs = GetSelectedSongs();
QList<QUrl> urls;
urls.reserve(songs.count());
for (const Song &song : songs) {
@ -788,7 +790,7 @@ void CollectionView::Delete() {
if (!delete_files_) return;
SongList selected_songs = GetSelectedSongs();
const SongList selected_songs = GetSelectedSongs();
SongList songs;
QStringList files;

View File

@ -106,7 +106,7 @@ CollectionWatcher::CollectionWatcher(Song::Source source, QObject *parent)
periodic_scan_timer_->setInterval(86400 * kMsecPerSec);
periodic_scan_timer_->setSingleShot(false);
QStringList image_formats = ImageUtils::SupportedImageFormats();
const QStringList image_formats = ImageUtils::SupportedImageFormats();
for (const QString &format : image_formats) {
if (!sValidImages.contains(format)) {
sValidImages.append(format);
@ -155,7 +155,7 @@ void CollectionWatcher::ReloadSettings() {
s.beginGroup(CollectionSettingsPage::kSettingsGroup);
scan_on_startup_ = s.value("startup_scan", true).toBool();
monitor_ = s.value("monitor", true).toBool();
QStringList filters = s.value("cover_art_patterns", QStringList() << QStringLiteral("front") << QStringLiteral("cover")).toStringList();
const QStringList filters = s.value("cover_art_patterns", QStringList() << QStringLiteral("front") << QStringLiteral("cover")).toStringList();
if (source_ == Song::Source::Collection) {
song_tracking_ = s.value("song_tracking", false).toBool();
song_ebur128_loudness_analysis_ = s.value("song_ebur128_loudness_analysis", false).toBool();
@ -183,7 +183,7 @@ void CollectionWatcher::ReloadSettings() {
else if (monitor_ && !was_monitoring_before) {
// Add all directories to all QFileSystemWatchers again
for (const CollectionDirectory &dir : std::as_const(watched_dirs_)) {
CollectionSubdirectoryList subdirs = backend_->SubdirsInDirectory(dir.id);
const CollectionSubdirectoryList subdirs = backend_->SubdirsInDirectory(dir.id);
for (const CollectionSubdirectory &subdir : subdirs) {
AddWatch(dir, subdir.path);
}
@ -288,7 +288,7 @@ void CollectionWatcher::ScanTransaction::CommitNewOrUpdatedSongs() {
touched_subdirs.clear();
}
for (const CollectionSubdirectory &subdir : deleted_subdirs) {
for (const CollectionSubdirectory &subdir : std::as_const(deleted_subdirs)) {
if (watcher_->watched_dirs_.contains(dir_)) {
watcher_->RemoveWatch(watcher_->watched_dirs_[dir_], subdir);
}
@ -297,7 +297,7 @@ void CollectionWatcher::ScanTransaction::CommitNewOrUpdatedSongs() {
if (watcher_->monitor_) {
// Watch the new subdirectories
for (const CollectionSubdirectory &subdir : new_subdirs) {
for (const CollectionSubdirectory &subdir : std::as_const(new_subdirs)) {
if (watcher_->watched_dirs_.contains(dir_)) {
watcher_->AddWatch(watcher_->watched_dirs_[dir_], subdir.path);
}
@ -384,7 +384,7 @@ CollectionSubdirectoryList CollectionWatcher::ScanTransaction::GetImmediateSubdi
}
CollectionSubdirectoryList ret;
for (const CollectionSubdirectory &subdir : known_subdirs_) {
for (const CollectionSubdirectory &subdir : std::as_const(known_subdirs_)) {
if (subdir.path.left(subdir.path.lastIndexOf(QDir::separator())) == path && subdir.mtime != 0) {
ret << subdir;
}
@ -417,7 +417,7 @@ void CollectionWatcher::AddDirectory(const CollectionDirectory &dir, const Colle
transaction.SetKnownSubdirs(subdirs);
transaction.AddToProgressMax(files_count);
ScanSubdirectory(dir.path, CollectionSubdirectory(), files_count, &transaction);
last_scan_time_ = QDateTime::currentDateTime().toSecsSinceEpoch();
last_scan_time_ = QDateTime::currentSecsSinceEpoch();
}
else {
// We can do an incremental scan - looking at the mtimes of each subdirectory and only rescan if the directory has changed.
@ -434,7 +434,7 @@ void CollectionWatcher::AddDirectory(const CollectionDirectory &dir, const Colle
if (monitor_) AddWatch(dir, subdir.path);
}
last_scan_time_ = QDateTime::currentDateTime().toSecsSinceEpoch();
last_scan_time_ = QDateTime::currentSecsSinceEpoch();
}
@ -481,7 +481,7 @@ void CollectionWatcher::ScanSubdirectory(const QString &path, const CollectionSu
// If a directory is moved then only its parent gets a changed notification, so we need to look and see if any of our children don't exist anymore.
// If one has been removed, "rescan" it to get the deleted songs
CollectionSubdirectoryList previous_subdirs = t->GetImmediateSubdirs(path);
const CollectionSubdirectoryList previous_subdirs = t->GetImmediateSubdirs(path);
for (const CollectionSubdirectory &prev_subdir : previous_subdirs) {
if (!QFile::exists(prev_subdir.path) && prev_subdir.path != path) {
ScanSubdirectory(prev_subdir.path, prev_subdir, 0, t, true);
@ -658,7 +658,7 @@ void CollectionWatcher::ScanSubdirectory(const QString &path, const CollectionSu
// Make sure the songs aren't deleted, as they still exist elsewhere with a different file path.
bool matching_songs_has_cue = false;
for (const Song &matching_song : matching_songs) {
for (const Song &matching_song : std::as_const(matching_songs)) {
QString matching_filename = matching_song.url().toLocalFile();
if (!t->files_changed_path_.contains(matching_filename)) {
t->files_changed_path_ << matching_filename;
@ -691,7 +691,7 @@ void CollectionWatcher::ScanSubdirectory(const QString &path, const CollectionSu
}
else { // The song is on disk but not in the DB
SongList songs = ScanNewFile(file, path, fingerprint, new_cue, &cues_processed);
const SongList songs = ScanNewFile(file, path, fingerprint, new_cue, &cues_processed);
if (songs.isEmpty()) {
t->AddToProgress(1);
continue;
@ -713,7 +713,7 @@ void CollectionWatcher::ScanSubdirectory(const QString &path, const CollectionSu
}
// Look for deleted songs
for (const Song &song : songs_in_db) {
for (const Song &song : std::as_const(songs_in_db)) {
QString file = song.url().toLocalFile();
if (!song.unavailable() && !files_on_disk.contains(file) && !t->files_changed_path_.contains(file)) {
qLog(Debug) << "Song deleted from disk:" << file;
@ -739,7 +739,7 @@ void CollectionWatcher::ScanSubdirectory(const QString &path, const CollectionSu
}
// Recurse into the new subdirs that we found
for (const CollectionSubdirectory &my_new_subdir : my_new_subdirs) {
for (const CollectionSubdirectory &my_new_subdir : std::as_const(my_new_subdirs)) {
if (stop_requested_ || abort_requested_) return;
ScanSubdirectory(my_new_subdir.path, my_new_subdir, 0, t, true);
}
@ -991,7 +991,7 @@ void CollectionWatcher::AddWatch(const CollectionDirectory &dir, const QString &
void CollectionWatcher::RemoveWatch(const CollectionDirectory &dir, const CollectionSubdirectory &subdir) {
QStringList subdir_paths = subdir_mapping_.keys(dir);
const QStringList subdir_paths = subdir_mapping_.keys(dir);
for (const QString &subdir_path : subdir_paths) {
if (subdir_path != subdir.path) continue;
fs_watcher_->RemovePath(subdir_path);
@ -1008,7 +1008,7 @@ void CollectionWatcher::RemoveDirectory(const CollectionDirectory &dir) {
// Stop watching the directory's subdirectories
QStringList subdir_paths = subdir_mapping_.keys(dir);
for (const QString &subdir_path : subdir_paths) {
for (const QString &subdir_path : std::as_const(subdir_paths)) {
fs_watcher_->RemovePath(subdir_path);
subdir_mapping_.remove(subdir_path);
}
@ -1030,7 +1030,7 @@ bool CollectionWatcher::FindSongsByPath(const SongList &songs, const QString &pa
bool CollectionWatcher::FindSongsByFingerprint(const QString &file, const QString &fingerprint, SongList *out) {
SongList songs = backend_->GetSongsByFingerprint(fingerprint);
for (const Song &song : songs) {
for (const Song &song : std::as_const(songs)) {
QString filename = song.url().toLocalFile();
QFileInfo info(filename);
// Allow mulitiple songs in different directories with the same fingerprint.
@ -1078,19 +1078,21 @@ void CollectionWatcher::DirectoryChanged(const QString &subdir) {
void CollectionWatcher::RescanPathsNow() {
QList<int> dirs = rescan_queue_.keys();
const QList<int> dirs = rescan_queue_.keys();
for (const int dir : dirs) {
if (stop_requested_ || abort_requested_) break;
ScanTransaction transaction(this, dir, false, false, mark_songs_unavailable_);
const QStringList paths = rescan_queue_[dir];
QMap<QString, quint64> subdir_files_count;
for (const QString &path : rescan_queue_[dir]) {
for (const QString &path : paths) {
quint64 files_count = FilesCountForPath(&transaction, path);
subdir_files_count[path] = files_count;
transaction.AddToProgressMax(files_count);
}
for (const QString &path : rescan_queue_[dir]) {
for (const QString &path : paths) {
if (stop_requested_ || abort_requested_) break;
CollectionSubdirectory subdir;
subdir.directory_id = dir;
@ -1113,7 +1115,7 @@ QString CollectionWatcher::PickBestArt(const QStringList &art_automatic_list) {
QStringList filtered;
for (const QString &filter_text : best_art_filters_) {
for (const QString &filter_text : std::as_const(best_art_filters_)) {
// The images in the images list are represented by a full path, so we need to isolate just the filename
for (const QString &art_automatic : art_automatic_list) {
QFileInfo fileinfo(art_automatic);
@ -1135,7 +1137,7 @@ QString CollectionWatcher::PickBestArt(const QStringList &art_automatic_list) {
int biggest_size = 0;
QString biggest_path;
for (const QString &path : filtered) {
for (const QString &path : std::as_const(filtered)) {
if (stop_requested_ || abort_requested_) break;
QImage image(path);
@ -1198,7 +1200,7 @@ void CollectionWatcher::FullScanAsync() {
void CollectionWatcher::IncrementalScanCheck() {
qint64 duration = QDateTime::currentDateTime().toSecsSinceEpoch() - last_scan_time_;
qint64 duration = QDateTime::currentSecsSinceEpoch() - last_scan_time_;
if (duration >= 86400) {
qLog(Debug) << "Performing periodic incremental scan.";
IncrementalScanNow();
@ -1233,14 +1235,14 @@ void CollectionWatcher::PerformScan(const bool incremental, const bool ignore_mt
quint64 files_count = FilesCountForSubdirs(&transaction, subdirs, subdir_files_count);
transaction.AddToProgressMax(files_count);
for (const CollectionSubdirectory &subdir : subdirs) {
for (const CollectionSubdirectory &subdir : std::as_const(subdirs)) {
if (stop_requested_ || abort_requested_) break;
ScanSubdirectory(subdir.path, subdir, subdir_files_count[subdir.path], &transaction);
}
}
last_scan_time_ = QDateTime::currentDateTime().toSecsSinceEpoch();
last_scan_time_ = QDateTime::currentSecsSinceEpoch();
emit CompilationsNeedUpdating();
@ -1312,7 +1314,7 @@ void CollectionWatcher::RescanSongs(const SongList &songs) {
const QString song_path = song.url().toLocalFile().section(QLatin1Char('/'), 0, -2);
if (scanned_paths.contains(song_path)) continue;
ScanTransaction transaction(this, song.directory_id(), false, true, mark_songs_unavailable_);
CollectionSubdirectoryList subdirs(transaction.GetAllSubdirs());
const CollectionSubdirectoryList subdirs = transaction.GetAllSubdirs();
for (const CollectionSubdirectory &subdir : subdirs) {
if (stop_requested_ || abort_requested_) break;
if (subdir.path != song_path) continue;

View File

@ -21,6 +21,8 @@
#include "config.h"
#include <utility>
#include <QDialog>
#include <QStandardItemModel>
#include <QItemSelectionModel>
@ -195,7 +197,8 @@ void SavedGroupingManager::Remove() {
if (ui_->list->selectionModel()->hasSelection()) {
Settings s;
s.beginGroup(saved_groupings_settings_group_);
for (const QModelIndex &idx : ui_->list->selectionModel()->selectedRows()) {
const QModelIndexList indexes = ui_->list->selectionModel()->selectedRows();
for (const QModelIndex &idx : indexes) {
if (idx.isValid()) {
qLog(Debug) << "Remove saved grouping: " << model_->item(idx.row(), 0)->text();
s.remove(model_->item(idx.row(), 0)->text());

View File

@ -103,6 +103,8 @@
#include "radios/radioservices.h"
#include "radios/radiobackend.h"
#include "networkremote/networkremote.h"
using std::make_shared;
using namespace std::chrono_literals;
@ -203,8 +205,13 @@ class ApplicationImpl {
moodbar_loader_([app]() { return new MoodbarLoader(app); }),
moodbar_controller_([app]() { return new MoodbarController(app); }),
#endif
lastfm_import_([app]() { return new LastFMImport(app->network()); })
{}
lastfm_import_([app]() { return new LastFMImport(app->network()); }),
network_remote_([app]() {
NetworkRemote *remote = new NetworkRemote(app);
app->MoveToNewThread(remote);
return remote;
})
{}
Lazy<TagReaderClient> tag_reader_client_;
Lazy<Database> database_;
@ -230,6 +237,7 @@ class ApplicationImpl {
Lazy<MoodbarController> moodbar_controller_;
#endif
Lazy<LastFMImport> lastfm_import_;
Lazy<NetworkRemote> network_remote_;
};
@ -239,6 +247,7 @@ Application::Application(QObject *parent)
device_finders()->Init();
collection()->Init();
tag_reader_client();
network_remote()->Init();
QObject::connect(&*database(), &Database::Error, this, &Application::ErrorAdded);
@ -288,7 +297,8 @@ void Application::Exit() {
<< &*device_manager()
#endif
<< &*internet_services()
<< &*radio_services()->radio_backend();
<< &*radio_services()->radio_backend()
<< &*network_remote();
QObject::connect(&*tag_reader_client(), &TagReaderClient::ExitFinished, this, &Application::ExitReceived);
tag_reader_client()->ExitAsync();
@ -357,7 +367,9 @@ SharedPtr<InternetServices> Application::internet_services() const { return p_->
SharedPtr<RadioServices> Application::radio_services() const { return p_->radio_services_.ptr(); }
SharedPtr<AudioScrobbler> Application::scrobbler() const { return p_->scrobbler_.ptr(); }
SharedPtr<LastFMImport> Application::lastfm_import() const { return p_->lastfm_import_.ptr(); }
SharedPtr<NetworkRemote> Application::network_remote() const { return p_->network_remote_.ptr();}
#ifdef HAVE_MOODBAR
SharedPtr<MoodbarController> Application::moodbar_controller() const { return p_->moodbar_controller_.ptr(); }
SharedPtr<MoodbarLoader> Application::moodbar_loader() const { return p_->moodbar_loader_.ptr(); }
#endif

View File

@ -65,6 +65,8 @@ class MoodbarController;
class MoodbarLoader;
#endif
class NetworkRemote;
class Application : public QObject {
Q_OBJECT
@ -107,6 +109,8 @@ class Application : public QObject {
SharedPtr<LastFMImport> lastfm_import() const;
SharedPtr<NetworkRemote> network_remote() const;
void Exit();
QThread *MoveToNewThread(QObject *object);

View File

@ -21,6 +21,8 @@
#include "config.h"
#include <utility>
#include <sqlite3.h>
#include <QObject>
@ -87,7 +89,8 @@ Database::~Database() {
QMutexLocker l(&connect_mutex_);
for (const QString &connection_id : QSqlDatabase::connectionNames()) {
const QStringList connection_names = QSqlDatabase::connectionNames();
for (const QString &connection_id : connection_names) {
qLog(Error) << "Connection" << connection_id << "is still open!";
}
@ -157,7 +160,7 @@ QSqlDatabase Database::Connect() {
// Attach external databases
QStringList keys = attached_databases_.keys();
for (const QString &key : keys) {
for (const QString &key : std::as_const(keys)) {
QString filename = attached_databases_[key].filename_;
if (!injected_database_name_.isNull()) filename = injected_database_name_;
@ -178,7 +181,7 @@ QSqlDatabase Database::Connect() {
// We might have to initialize the schema in some attached databases now, if they were deleted and don't match up with the main schema version.
keys = attached_databases_.keys();
for (const QString &key : keys) {
for (const QString &key : std::as_const(keys)) {
if (attached_databases_[key].is_temporary_ && attached_databases_[key].schema_.isEmpty()) {
continue;
}
@ -276,7 +279,8 @@ void Database::RecreateAttachedDb(const QString &database_name) {
// We can't just re-attach the database now because it needs to be done for each thread.
// Close all the database connections, so each thread will re-attach it when they next connect.
for (const QString &name : QSqlDatabase::connectionNames()) {
const QStringList connection_names = QSqlDatabase::connectionNames();
for (const QString &name : connection_names) {
QSqlDatabase::removeDatabase(name);
}
@ -384,8 +388,7 @@ void Database::ExecSchemaCommandsFromFile(QSqlDatabase &db, const QString &filen
void Database::ExecSchemaCommands(QSqlDatabase &db, const QString &schema, int schema_version, bool in_transaction) {
// Run each command
QStringList commands;
commands = schema.split(QRegularExpression(QStringLiteral("; *\n\n")));
QStringList commands = schema.split(QRegularExpression(QStringLiteral("; *\n\n")));
// We don't want this list to reflect possible DB schema changes, so we initialize it before executing any statements.
// If no outer transaction is provided the song tables need to be queried before beginning an inner transaction!
@ -445,12 +448,13 @@ QStringList Database::SongsTables(QSqlDatabase &db, const int schema_version) {
QStringList ret;
// look for the tables in the main db
for (const QString &table : db.tables()) {
const QStringList &tables = db.tables();
for (const QString &table : tables) {
if (table == QStringLiteral("songs") || table.endsWith(QLatin1String("_songs"))) ret << table;
}
// look for the tables in attached dbs
QStringList keys = attached_databases_.keys();
const QStringList keys = attached_databases_.keys();
for (const QString &key : keys) {
SqlQuery q(db);
q.prepare(QStringLiteral("SELECT NAME FROM %1.sqlite_master WHERE type='table' AND name='songs' OR name LIKE '%songs'").arg(key));

View File

@ -19,6 +19,8 @@
#include "config.h"
#include <utility>
#include <QDir>
#include <QFile>
#include <QList>
@ -80,7 +82,8 @@ QIcon IconLoader::Load(const QString &name, const bool system_icon, const int fi
if (icon_prop.allow_system_icon) {
ret = QIcon::fromTheme(name);
if (ret.isNull()) {
for (const QString &alt_name : icon_prop.names) {
const QStringList alt_names = icon_prop.names;
for (const QString &alt_name : alt_names) {
ret = QIcon::fromTheme(alt_name);
if (!ret.isNull()) break;
}
@ -96,7 +99,8 @@ QIcon IconLoader::Load(const QString &name, const bool system_icon, const int fi
else {
int size_smallest = 0;
int size_largest = 0;
for (const QSize &s : ret.availableSizes()) {
const QList<QSize> available_sizes = ret.availableSizes();
for (const QSize &s : available_sizes) {
if (s.width() != s.height()) {
qLog(Warning) << "Can't use system icon for" << name << "icon is not proportional.";
ret = QIcon();
@ -120,7 +124,7 @@ QIcon IconLoader::Load(const QString &name, const bool system_icon, const int fi
if (custom_icons_) {
QString custom_icon_path = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + QStringLiteral("/icons/%1x%2/%3.png");
for (int s : sizes) {
for (int s : std::as_const(sizes)) {
QString filename(custom_icon_path.arg(s).arg(s).arg(name));
if (QFile::exists(filename)) ret.addFile(filename, QSize(s, s));
}
@ -129,7 +133,7 @@ QIcon IconLoader::Load(const QString &name, const bool system_icon, const int fi
}
const QString path(QStringLiteral(":/icons/%1x%2/%3.png"));
for (int s : sizes) {
for (int s : std::as_const(sizes)) {
QString filename(path.arg(s).arg(s).arg(name));
if (QFile::exists(filename)) ret.addFile(filename, QSize(s, s));
}

View File

@ -424,7 +424,7 @@ QStringList MergedProxyModel::mimeTypes() const {
QStringList ret;
ret << sourceModel()->mimeTypes();
QList<QAbstractItemModel*> models = merge_points_.keys();
const QList<QAbstractItemModel*> models = merge_points_.keys();
for (const QAbstractItemModel *model : models) {
ret << model->mimeTypes();
}
@ -506,7 +506,7 @@ QAbstractItemModel *MergedProxyModel::GetModel(const QModelIndex &source_index)
// This is essentially const_cast<QAbstractItemModel*>(source_index.model()), but without the const_cast
const QAbstractItemModel *const_model = source_index.model();
if (const_model == sourceModel()) return sourceModel();
QList<QAbstractItemModel*> submodels = merge_points_.keys();
const QList<QAbstractItemModel*> submodels = merge_points_.keys();
for (QAbstractItemModel *submodel : submodels) {
if (submodel == const_model) return submodel;
}
@ -522,7 +522,7 @@ void MergedProxyModel::DataChanged(const QModelIndex &top_left, const QModelInde
void MergedProxyModel::LayoutAboutToBeChanged() {
old_merge_points_.clear();
QList<QAbstractItemModel*> models = merge_points_.keys();
const QList<QAbstractItemModel*> models = merge_points_.keys();
for (QAbstractItemModel *model : models) {
old_merge_points_[model] = merge_points_.value(model);
}
@ -531,7 +531,7 @@ void MergedProxyModel::LayoutAboutToBeChanged() {
void MergedProxyModel::LayoutChanged() {
QList<QAbstractItemModel*> models = merge_points_.keys();
const QList<QAbstractItemModel*> models = merge_points_.keys();
for (QAbstractItemModel *model : models) {
if (!old_merge_points_.contains(model)) continue;

View File

@ -44,11 +44,10 @@ NetworkProxyFactory::NetworkProxyFactory()
#ifdef Q_OS_LINUX
// Linux uses environment variables to pass proxy configuration information, which systemProxyForQuery doesn't support for some reason.
QStringList urls;
urls << QString::fromLocal8Bit(qgetenv("HTTP_PROXY"));
urls << QString::fromLocal8Bit(qgetenv("http_proxy"));
urls << QString::fromLocal8Bit(qgetenv("ALL_PROXY"));
urls << QString::fromLocal8Bit(qgetenv("all_proxy"));
const QStringList urls = QStringList() << QString::fromLocal8Bit(qgetenv("HTTP_PROXY"))
<< QString::fromLocal8Bit(qgetenv("http_proxy"))
<< QString::fromLocal8Bit(qgetenv("ALL_PROXY"))
<< QString::fromLocal8Bit(qgetenv("all_proxy"));
qLog(Debug) << "Detected system proxy URLs:" << urls;

View File

@ -25,6 +25,7 @@
#include <algorithm>
#include <memory>
#include <chrono>
#include <QtGlobal>
#include <QObject>
@ -68,6 +69,8 @@
#include "settings/behavioursettingspage.h"
#include "settings/playlistsettingspage.h"
using namespace std::chrono_literals;
using std::make_shared;
const char *Player::kSettingsGroup = "Player";
@ -103,7 +106,7 @@ Player::Player(Application *app, QObject *parent)
CreateEngine(enginetype);
timer_save_volume_->setSingleShot(true);
timer_save_volume_->setInterval(5000);
timer_save_volume_->setInterval(5s);
QObject::connect(timer_save_volume_, &QTimer::timeout, this, &Player::SaveVolume);
}
@ -434,7 +437,8 @@ void Player::PlayPlaylistInternal(const EngineBase::TrackChangeFlags change, con
play_offset_nanosec_ = 0;
Playlist *playlist = nullptr;
for (Playlist *p : app_->playlist_manager()->GetAllPlaylists()) {
const QList<Playlist*> playlists = app_->playlist_manager()->GetAllPlaylists();
for (Playlist *p : playlists) {
if (playlist_name == app_->playlist_manager()->GetPlaylistName(p->id())) {
playlist = p;
break;
@ -532,7 +536,7 @@ void Player::UnPause() {
if (current_item_ && pause_time_.isValid()) {
const Song &song = current_item_->Metadata();
if (url_handlers_.contains(song.url().scheme()) && song.stream_url_can_expire()) {
const quint64 time = QDateTime::currentDateTime().toSecsSinceEpoch() - pause_time_.toSecsSinceEpoch();
const quint64 time = QDateTime::currentSecsSinceEpoch() - pause_time_.toSecsSinceEpoch();
if (time >= 30) { // Stream URL might be expired.
qLog(Debug) << "Re-requesting stream URL for" << song.url();
play_offset_nanosec_ = engine_->position_nanosec();

View File

@ -570,7 +570,8 @@ bool Song::write_tags_supported() const {
d->filetype_ == FileType::TrueAudio ||
d->filetype_ == FileType::APE ||
d->filetype_ == FileType::DSF ||
d->filetype_ == FileType::DSDIFF;
d->filetype_ == FileType::DSDIFF ||
d->filetype_ == FileType::WAV;
}
@ -585,7 +586,8 @@ bool Song::additional_tags_supported() const {
d->filetype_ == FileType::MPEG ||
d->filetype_ == FileType::MP4 ||
d->filetype_ == FileType::MPC ||
d->filetype_ == FileType::APE;
d->filetype_ == FileType::APE ||
d->filetype_ == FileType::WAV;
}
@ -607,7 +609,8 @@ bool Song::performer_supported() const {
d->filetype_ == FileType::OggSpeex ||
d->filetype_ == FileType::MPEG ||
d->filetype_ == FileType::MPC ||
d->filetype_ == FileType::APE;
d->filetype_ == FileType::APE ||
d->filetype_ == FileType::WAV;
}
@ -1400,7 +1403,7 @@ void Song::InitFromQuery(const QSqlRecord &r, const bool reliable_metadata, cons
d->album_id_ = SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("album_id")) + col);
d->song_id_ = SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("song_id")) + col);
d->beginning_ = r.value(ColumnIndex(QStringLiteral("beginning")) + col).isNull() ? 0 : r.value(ColumnIndex(QStringLiteral("beginning")) + col).toLongLong();
set_length_nanosec(SqlHelper::ValueToLongLong(r, ColumnIndex(QStringLiteral("length"))) + col);
set_length_nanosec(SqlHelper::ValueToLongLong(r, ColumnIndex(QStringLiteral("length")) + col));
d->bitrate_ = SqlHelper::ValueToInt(r, ColumnIndex(QStringLiteral("bitrate")) + col);
d->samplerate_ = SqlHelper::ValueToInt(r, ColumnIndex(QStringLiteral("samplerate")) + col);
d->bitdepth_ = SqlHelper::ValueToInt(r, ColumnIndex(QStringLiteral("bitdepth")) + col);

View File

@ -176,7 +176,8 @@ void StyleHelper::setBaseColor(const QColor &newcolor) {
if (color.isValid() && color != m_baseColor) {
m_baseColor = color;
for (QWidget *w : QApplication::topLevelWidgets()) {
const QList<QWidget*> widgets = QApplication::topLevelWidgets();
for (QWidget *w : widgets) {
w->update();
}
}

View File

@ -19,6 +19,8 @@
#include "config.h"
#include <utility>
#include <QCoreApplication>
#include <QTranslator>
#include <QString>
@ -29,7 +31,7 @@
Translations::Translations(QObject *parent) : QObject(parent) {}
Translations::~Translations() {
for (QTranslator *t : translations_) {
for (QTranslator *t : std::as_const(translations_)) {
QCoreApplication::removeTranslator(t);
delete t;
}

View File

@ -52,7 +52,7 @@ AlbumCoverFetcher::AlbumCoverFetcher(SharedPtr<CoverProviders> cover_providers,
AlbumCoverFetcher::~AlbumCoverFetcher() {
QList<AlbumCoverFetcherSearch*> searches = active_requests_.values();
const QList<AlbumCoverFetcherSearch*> searches = active_requests_.values();
for (AlbumCoverFetcherSearch *search : searches) {
search->disconnect();
search->deleteLater();
@ -105,7 +105,7 @@ void AlbumCoverFetcher::Clear() {
queued_requests_.clear();
QList<AlbumCoverFetcherSearch*> searches = active_requests_.values();
const QList<AlbumCoverFetcherSearch*> searches = active_requests_.values();
for (AlbumCoverFetcherSearch *search : searches) {
search->Cancel();
search->deleteLater();

View File

@ -120,7 +120,7 @@ class AlbumCoverLoader : public QObject {
private slots:
void Exit();
void ProcessTasks();
void LoadRemoteImageFinished(QNetworkReply *reply, TaskPtr task, const AlbumCoverLoaderResult::Type result_type, const QUrl &cover_url);
void LoadRemoteImageFinished(QNetworkReply *reply, AlbumCoverLoader::TaskPtr task, const AlbumCoverLoaderResult::Type result_type, const QUrl &cover_url);
private:
static const int kMaxRedirects = 3;

View File

@ -21,6 +21,8 @@
#include "config.h"
#include <utility>
#include <QWidget>
#include <QStringList>
#include <QUrl>
@ -57,7 +59,7 @@ QMimeData *AlbumCoverManagerList::mimeData(const QList<QListWidgetItem*> items)
// Get URLs from the songs
QList<QUrl> urls;
urls.reserve(songs.count());
for (const Song &song : songs) {
for (const Song &song : std::as_const(songs)) {
urls << song.url();
}

View File

@ -21,6 +21,8 @@
#include "config.h"
#include <utility>
#include <QFile>
#include <QSize>
#include <QString>
@ -64,7 +66,7 @@ void CoverExportRunnable::ProcessAndExportCover() {
QImage image;
QString extension;
for (const AlbumCoverLoaderOptions::Type cover_type : cover_types_) {
for (const AlbumCoverLoaderOptions::Type cover_type : std::as_const(cover_types_)) {
switch (cover_type) {
case AlbumCoverLoaderOptions::Type::Unset:
if (song_.art_unset()) {
@ -156,7 +158,7 @@ void CoverExportRunnable::ExportCover() {
QString cover_path;
bool embedded_cover = false;
for (const AlbumCoverLoaderOptions::Type cover_type : cover_types_) {
for (const AlbumCoverLoaderOptions::Type cover_type : std::as_const(cover_types_)) {
switch (cover_type) {
case AlbumCoverLoaderOptions::Type::Unset:
if (song_.art_unset()) {

View File

@ -21,6 +21,8 @@
#include "config.h"
#include <utility>
#include <QObject>
#include <QMutex>
#include <QList>
@ -52,14 +54,14 @@ void CoverProviders::ReloadSettings() {
QMap<int, QString> all_providers;
QList<CoverProvider*> old_providers = cover_providers_.keys();
for (CoverProvider *provider : old_providers) {
for (CoverProvider *provider : std::as_const(old_providers)) {
if (!provider->is_enabled()) continue;
all_providers.insert(provider->order(), provider->name());
}
Settings s;
s.beginGroup(CoversSettingsPage::kSettingsGroup);
QStringList providers_enabled = s.value(CoversSettingsPage::kProviders, QStringList() << all_providers.values()).toStringList();
const QStringList providers_enabled = s.value(CoversSettingsPage::kProviders, QStringList() << all_providers.values()).toStringList();
s.endGroup();
int i = 0;
@ -74,7 +76,7 @@ void CoverProviders::ReloadSettings() {
}
old_providers = cover_providers_.keys();
for (CoverProvider *provider : old_providers) {
for (CoverProvider *provider : std::as_const(old_providers)) {
if (!new_providers.contains(provider)) {
provider->set_enabled(false);
provider->set_order(++i);
@ -85,7 +87,7 @@ void CoverProviders::ReloadSettings() {
CoverProvider *CoverProviders::ProviderByName(const QString &name) const {
QList<CoverProvider*> cover_providers = cover_providers_.keys();
const QList<CoverProvider*> cover_providers = cover_providers_.keys();
for (CoverProvider *provider : cover_providers) {
if (provider->name() == name) return provider;
}

View File

@ -20,6 +20,8 @@
#include "config.h"
#include <utility>
#include <QtGlobal>
#include <QString>
@ -39,11 +41,11 @@ CoverSearchStatistics &CoverSearchStatistics::operator+=(const CoverSearchStatis
bytes_transferred_ += other.bytes_transferred_;
QStringList keys = other.chosen_images_by_provider_.keys();
for (const QString &key : keys) {
for (const QString &key : std::as_const(keys)) {
chosen_images_by_provider_[key] += other.chosen_images_by_provider_[key];
}
keys = other.total_images_by_provider_.keys();
for (const QString &key : keys) {
for (const QString &key : std::as_const(keys)) {
total_images_by_provider_[key] += other.total_images_by_provider_[key];
}

View File

@ -21,6 +21,7 @@
#include "config.h"
#include <algorithm>
#include <utility>
#include <QtGlobal>
#include <QWidget>
@ -69,7 +70,7 @@ void CoverSearchStatisticsDialog::Show(const CoverSearchStatistics &statistics)
.arg(statistics.chosen_images_ + statistics.missing_images_)
.arg(statistics.missing_images_));
for (const QString &provider : providers) {
for (const QString &provider : std::as_const(providers)) {
AddLine(tr("Covers from %1").arg(provider), QString::number(statistics.chosen_images_by_provider_[provider]));
}

View File

@ -21,6 +21,8 @@
#include "config.h"
#include <utility>
#include <QObject>
#include <QThread>
#include <QMutex>
@ -105,7 +107,7 @@ DeviceDatabaseBackend::DeviceList DeviceDatabaseBackend::GetAllDevices() {
}
}
for (const Device &dev : old_devices) {
for (const Device &dev : std::as_const(old_devices)) {
RemoveDevice(dev.id_);
}

View File

@ -64,7 +64,7 @@ void DeviceInfo::InitFromDb(const DeviceDatabaseBackend::Device &dev) {
transcode_format_ = dev.transcode_format_;
icon_name_ = dev.icon_name_;
QStringList unique_ids = dev.unique_id_.split(QLatin1Char(','));
const QStringList unique_ids = dev.unique_id_.split(QLatin1Char(','));
for (const QString &id : unique_ids) {
backends_ << Backend(nullptr, id);
}

View File

@ -22,6 +22,7 @@
#include "config.h"
#include <functional>
#include <utility>
#include <QtGlobal>
#include <QWidget>
@ -88,14 +89,13 @@ void DeviceProperties::ShowDevice(const QModelIndex &idx) {
if (ui_->icon->count() == 0) {
// Only load the icons the first time the dialog is shown
QStringList icon_names = QStringList()
<< QStringLiteral("device")
<< QStringLiteral("device-usb-drive")
<< QStringLiteral("device-usb-flash")
<< QStringLiteral("media-optical")
<< QStringLiteral("device-ipod")
<< QStringLiteral("device-ipod-nano")
<< QStringLiteral("device-phone");
const QStringList icon_names = QStringList() << QStringLiteral("device")
<< QStringLiteral("device-usb-drive")
<< QStringLiteral("device-usb-flash")
<< QStringLiteral("media-optical")
<< QStringLiteral("device-ipod")
<< QStringLiteral("device-ipod-nano")
<< QStringLiteral("device-phone");
for (const QString &icon_name : icon_names) {
@ -105,7 +105,8 @@ void DeviceProperties::ShowDevice(const QModelIndex &idx) {
#ifdef HAVE_GSTREAMER
// Load the transcode formats the first time the dialog is shown
for (const TranscoderPreset &preset : Transcoder::GetAllPresets()) {
const QList<TranscoderPreset> presets = Transcoder::GetAllPresets();
for (const TranscoderPreset &preset : presets) {
ui_->transcode_format->addItem(preset.name_, QVariant::fromValue(preset.filetype_));
}
ui_->transcode_format->model()->sort(0);
@ -161,7 +162,7 @@ void DeviceProperties::UpdateHardwareInfo() {
// Remove empty items
QStringList keys = info.keys();
for (const QString &key : keys) {
for (const QString &key : std::as_const(keys)) {
if (info[key].isNull() || info[key].toString().isEmpty())
info.remove(key);
}
@ -174,7 +175,7 @@ void DeviceProperties::UpdateHardwareInfo() {
AddHardwareInfo(row++, tr("Model"), lister->DeviceModel(id));
AddHardwareInfo(row++, tr("Manufacturer"), lister->DeviceManufacturer(id));
keys = info.keys();
for (const QString &key : keys) {
for (const QString &key : std::as_const(keys)) {
AddHardwareInfo(row++, key, info[key].toString());
}
@ -307,7 +308,7 @@ void DeviceProperties::UpdateFormatsFinished() {
// Populate supported types list
ui_->supported_formats->clear();
for (Song::FileType type : supported_formats_) {
for (Song::FileType type : std::as_const(supported_formats_)) {
QListWidgetItem *item = new QListWidgetItem(Song::TextForFiletype(type));
ui_->supported_formats->addItem(item);
}

View File

@ -377,7 +377,7 @@ void DeviceView::mouseDoubleClickEvent(QMouseEvent *e) {
SongList DeviceView::GetSelectedSongs() const {
QModelIndexList selected_merged_indexes = selectionModel()->selectedRows();
const QModelIndexList selected_merged_indexes = selectionModel()->selectedRows();
SongList songs;
for (const QModelIndex &merged_index : selected_merged_indexes) {
QModelIndex collection_index = MapToCollection(merged_index);

View File

@ -22,6 +22,7 @@
#include "config.h"
#include <functional>
#include <utility>
#include <glib.h>
#include <glib-object.h>
@ -128,7 +129,7 @@ bool GioLister::Init() {
}
GioLister::~GioLister() {
for (gulong signal : signals_) {
for (gulong signal : std::as_const(signals_)) {
g_signal_handler_disconnect(monitor_, signal);
}
}
@ -222,7 +223,7 @@ QList<QUrl> GioLister::MakeDeviceUrls(const QString &id) {
QList<QUrl> ret;
for (QString uri : uris) {
for (QString uri : std::as_const(uris)) {
// gphoto2 gives invalid hostnames with []:, characters in
uri.replace(QRegularExpression(QStringLiteral("//\\[usb:(\\d+),(\\d+)\\]")), QStringLiteral("//usb-\\1-\\2"));
@ -355,7 +356,7 @@ void GioLister::MountAdded(GMount *mount) {
QMutexLocker l(&mutex_);
// The volume might already exist - either mounted or unmounted.
QStringList ids = devices_.keys();
const QStringList ids = devices_.keys();
for (const QString &id : ids) {
if (devices_[id].volume_ptr == info.volume_ptr) {
old_id = id;

View File

@ -20,6 +20,8 @@
#include "config.h"
#include <utility>
#include <QWidget>
#include <QString>
#include <QIcon>
@ -79,7 +81,7 @@ void ErrorDialog::closeEvent(QCloseEvent *e) {
void ErrorDialog::UpdateContent() {
QString html;
for (const QString &message : current_messages_) {
for (const QString &message : std::as_const(current_messages_)) {
if (!html.isEmpty()) {
html += QLatin1String("<hr/>");
}

View File

@ -21,6 +21,8 @@
#include "config.h"
#include <utility>
#include <QtConcurrentRun>
#include <QWidget>
#include <QDialog>
@ -299,7 +301,7 @@ void TrackSelectionDialog::accept() {
QDialog::accept();
for (const Data &tag_data : data_) {
for (const Data &tag_data : std::as_const(data_)) {
if (tag_data.pending_ || tag_data.results_.isEmpty() || tag_data.selected_result_ == -1) {
continue;
}

View File

@ -179,7 +179,7 @@ class EBUR128State {
EBUR128State &operator=(const EBUR128State&) = delete;
EBUR128State &operator=(EBUR128State&&) = delete;
explicit EBUR128State(FrameFormat _dsc);
explicit EBUR128State(const FrameFormat &_dsc);
const FrameFormat dsc;
void AddFrames(const char *data, size_t size);
@ -246,7 +246,7 @@ bool operator!=(const FrameFormat &lhs, const FrameFormat &rhs) {
}
EBUR128State::EBUR128State(FrameFormat _dsc) : dsc(_dsc) {
EBUR128State::EBUR128State(const FrameFormat &_dsc) : dsc(_dsc) {
st.reset(ebur128_init(dsc.channels, dsc.samplerate, EBUR128_MODE_I | EBUR128_MODE_LRA));
Q_ASSERT(st);

View File

@ -25,6 +25,7 @@
#include <cmath>
#include <algorithm>
#include <optional>
#include <utility>
#include <memory>
#include <glib.h>
@ -815,7 +816,7 @@ SharedPtr<GstEnginePipeline> GstEngine::CreatePipeline() {
ret->set_fading_enabled(fadeout_enabled_ || autocrossfade_enabled_ || fadeout_pause_enabled_);
ret->AddBufferConsumer(this);
for (GstBufferConsumer *consumer : buffer_consumers_) {
for (GstBufferConsumer *consumer : std::as_const(buffer_consumers_)) {
ret->AddBufferConsumer(consumer);
}

View File

@ -40,7 +40,6 @@ QHash<QPair<quint32, quint32>, GlobalShortcut*> GlobalShortcut::internal_shortcu
GlobalShortcut::GlobalShortcut(QObject *parent)
: QObject(parent),
backend_(nullptr),
qt_key_(static_cast<Qt::Key>(0)),
qt_mods_(Qt::NoModifier),
native_key_(0),
native_key2_(0),
@ -57,7 +56,6 @@ GlobalShortcut::GlobalShortcut(const QKeySequence &shortcut, GlobalShortcutsBack
: QObject(parent),
backend_(backend),
shortcut_(shortcut),
qt_key_(static_cast<Qt::Key>(0)),
qt_mods_(Qt::NoModifier),
native_key_(0),
native_key2_(0),
@ -97,7 +95,7 @@ bool GlobalShortcut::setShortcut(const QKeySequence &shortcut) {
qt_mods_ = Qt::KeyboardModifiers(shortcut[0] & all_mods);
#endif
native_key_ = nativeKeycode(qt_key_);
native_key_ = nativeKeycode(qt_key_.value());
if (native_key_ == 0) return false;
native_mods_ = nativeModifiers(qt_mods_);
@ -105,7 +103,7 @@ bool GlobalShortcut::setShortcut(const QKeySequence &shortcut) {
if (success) {
internal_shortcuts_.insert(qMakePair(native_key_, native_mods_), this);
qLog(Info) << "Registered shortcut" << shortcut_.toString();
native_key2_ = nativeKeycode2(qt_key_);
native_key2_ = nativeKeycode2(qt_key_.value());
if (native_key2_ > 0 && registerShortcut(native_key2_, native_mods_)) {
internal_shortcuts_.insert(qMakePair(native_key2_, native_mods_), this);
}
@ -149,7 +147,7 @@ bool GlobalShortcut::unsetShortcut() {
qLog(Error) << "Failed to unregister shortcut" << shortcut_.toString();
}
qt_key_ = static_cast<Qt::Key>(0);
qt_key_.reset();
qt_mods_ = Qt::KeyboardModifiers();
native_key_ = 0;
native_mods_ = 0;

View File

@ -22,6 +22,8 @@
#include "config.h"
#include <optional>
#include <QtGlobal>
#include <QObject>
#include <QAbstractNativeEventFilter>
@ -74,7 +76,7 @@ class GlobalShortcut : public QObject, QAbstractNativeEventFilter {
GlobalShortcutsBackend *backend_;
QKeySequence shortcut_;
Qt::Key qt_key_;
std::optional<Qt::Key> qt_key_;
Qt::KeyboardModifiers qt_mods_;
int native_key_;
int native_key2_;

View File

@ -55,7 +55,7 @@ bool GlobalShortcutsBackendX11::DoRegister() {
if (!gshortcut_init_) gshortcut_init_ = new GlobalShortcut(this);
QList<GlobalShortcutsManager::Shortcut> shortcuts = manager_->shortcuts().values();
const QList<GlobalShortcutsManager::Shortcut> shortcuts = manager_->shortcuts().values();
for (const GlobalShortcutsManager::Shortcut &shortcut : shortcuts) {
AddShortcut(shortcut.action);
}

View File

@ -22,6 +22,7 @@
#include "config.h"
#include <functional>
#include <utility>
#include <QApplication>
#include <QWidget>
@ -197,7 +198,7 @@ bool GlobalShortcutsManager::IsX11Available() {
bool GlobalShortcutsManager::Register() {
for (GlobalShortcutsBackend *backend : backends_) {
for (GlobalShortcutsBackend *backend : std::as_const(backends_)) {
if (backend->IsAvailable() && backends_enabled_.contains(backend->type())) {
return backend->Register();
}
@ -211,7 +212,7 @@ bool GlobalShortcutsManager::Register() {
void GlobalShortcutsManager::Unregister() {
for (GlobalShortcutsBackend *backend : backends_) {
for (GlobalShortcutsBackend *backend : std::as_const(backends_)) {
if (backend->is_active()) {
backend->Unregister();
}

View File

@ -21,6 +21,8 @@
#include "config.h"
#include <utility>
#include <QWidget>
#include <QTreeView>
#include <QSortFilterProxyModel>
@ -180,7 +182,7 @@ bool InternetCollectionView::RestoreLevelFocus(const QModelIndex &parent) {
case CollectionItem::Type_Song:
if (!last_selected_song_.url().isEmpty()) {
QModelIndex idx = qobject_cast<QSortFilterProxyModel*>(model())->mapToSource(current);
SongList songs = collection_model_->GetChildSongs(idx);
const SongList songs = collection_model_->GetChildSongs(idx);
for (const Song &song : songs) {
if (song == last_selected_song_) {
setCurrentIndex(current);

View File

@ -48,7 +48,7 @@ InternetPlaylistItem::InternetPlaylistItem(InternetServicePtr service, const Son
bool InternetPlaylistItem::InitFromQuery(const SqlRow &query) {
metadata_.InitFromQuery(query, false, static_cast<int>(Song::kRowIdColumns.count()) * 3);
metadata_.InitFromQuery(query, false, static_cast<int>(Song::kRowIdColumns.count()));
InitMetadata();
return true;

View File

@ -349,7 +349,7 @@ bool InternetSearchView::ResultsContextMenuEvent(QContextMenuEvent *e) {
const bool enable_context_actions = ui_->results->selectionModel() && ui_->results->selectionModel()->hasSelection();
for (QAction *action : context_actions_) {
for (QAction *action : std::as_const(context_actions_)) {
action->setEnabled(enable_context_actions);
}
@ -607,7 +607,7 @@ MimeData *InternetSearchView::SelectedMimeData() {
// Get items for these indexes
QList<QStandardItem*> items;
for (const QModelIndex &idx : indexes) {
for (const QModelIndex &idx : std::as_const(indexes)) {
items << (front_model_->itemFromIndex(front_proxy_->mapToSource(idx))); // clazy:exclude=reserve-candidates
}
@ -715,7 +715,8 @@ void InternetSearchView::SetGroupBy(const CollectionModel::Grouping g) {
s.endGroup();
// Make sure the correct action is checked.
for (QAction *action : group_by_actions_->actions()) {
const QList<QAction*> actions = group_by_actions_->actions();
for (QAction *action : actions) {
if (action->property("group_by").isNull()) continue;
if (g == action->property("group_by").value<CollectionModel::Grouping>()) {
@ -725,7 +726,6 @@ void InternetSearchView::SetGroupBy(const CollectionModel::Grouping g) {
}
// Check the advanced action
QList<QAction*> actions = group_by_actions_->actions();
actions.last()->setChecked(true);
}

View File

@ -69,7 +69,7 @@ InternetServicePtr InternetServices::ServiceBySource(const Song::Source source)
void InternetServices::ReloadSettings() {
QList<InternetServicePtr> services = services_.values();
const QList<InternetServicePtr> services = services_.values();
for (InternetServicePtr service : services) {
service->ReloadSettings();
}
@ -78,7 +78,7 @@ void InternetServices::ReloadSettings() {
void InternetServices::Exit() {
QList<InternetServicePtr> services = services_.values();
const QList<InternetServicePtr> services = services_.values();
for (InternetServicePtr service : services) {
wait_for_exit_ << &*service;
QObject::connect(&*service, &InternetService::ExitFinished, this, &InternetServices::ExitReceived);

View File

@ -79,7 +79,7 @@ void LyricsFetcher::Clear() {
queued_requests_.clear();
QList<LyricsFetcherSearch*> searches = active_requests_.values();
const QList<LyricsFetcherSearch*> searches = active_requests_.values();
for (LyricsFetcherSearch *search : searches) {
search->Cancel();
search->deleteLater();

View File

@ -20,6 +20,7 @@
#include "config.h"
#include <algorithm>
#include <utility>
#include <QObject>
#include <QTimer>
@ -49,7 +50,7 @@ LyricsFetcherSearch::LyricsFetcherSearch(const quint64 id, const LyricsSearchReq
void LyricsFetcherSearch::TerminateSearch() {
QList<int> keys = pending_requests_.keys();
const QList<int> keys = pending_requests_.keys();
for (const int id : keys) {
pending_requests_.take(id)->CancelSearch(id);
}
@ -68,7 +69,7 @@ void LyricsFetcherSearch::Start(SharedPtr<LyricsProviders> lyrics_providers) {
QList<LyricsProvider*> lyrics_providers_sorted = lyrics_providers->List();
std::stable_sort(lyrics_providers_sorted.begin(), lyrics_providers_sorted.end(), ProviderCompareOrder);
for (LyricsProvider *provider : lyrics_providers_sorted) {
for (LyricsProvider *provider : std::as_const(lyrics_providers_sorted)) {
if (!provider->is_enabled() || !provider->IsAuthenticated()) continue;
QObject::connect(provider, &LyricsProvider::SearchFinished, this, &LyricsFetcherSearch::ProviderSearchFinished);
const int id = lyrics_providers->NextId();

View File

@ -19,6 +19,8 @@
#include "config.h"
#include <utility>
#include <QObject>
#include <QMutex>
#include <QList>
@ -51,14 +53,14 @@ void LyricsProviders::ReloadSettings() {
QMap<int, QString> all_providers;
QList<LyricsProvider*> old_providers = lyrics_providers_.keys();
for (LyricsProvider *provider : old_providers) {
for (LyricsProvider *provider : std::as_const(old_providers)) {
if (!provider->is_enabled()) continue;
all_providers.insert(provider->order(), provider->name());
}
Settings s;
s.beginGroup(LyricsSettingsPage::kSettingsGroup);
QStringList providers_enabled = s.value("providers", QStringList() << all_providers.values()).toStringList();
const QStringList providers_enabled = s.value("providers", QStringList() << all_providers.values()).toStringList();
s.endGroup();
int i = 0;
@ -73,7 +75,7 @@ void LyricsProviders::ReloadSettings() {
}
old_providers = lyrics_providers_.keys();
for (LyricsProvider *provider : old_providers) {
for (LyricsProvider *provider : std::as_const(old_providers)) {
if (!new_providers.contains(provider)) {
provider->set_enabled(false);
provider->set_order(++i);
@ -84,7 +86,7 @@ void LyricsProviders::ReloadSettings() {
LyricsProvider *LyricsProviders::ProviderByName(const QString &name) const {
QList<LyricsProvider*> providers = lyrics_providers_.keys();
const QList<LyricsProvider*> providers = lyrics_providers_.keys();
for (LyricsProvider *provider : providers) {
if (provider->name() == name) return provider;
}

View File

@ -88,6 +88,8 @@ void MoodbarBuilder::AddFrame(const double *magnitudes, int size) {
void MoodbarBuilder::Normalize(QList<Rgb> *vals, double Rgb::*member) {
const QList<Rgb> rgb_vals = *vals;
double mini = vals->at(0).*member;
double maxi = vals->at(0).*member;
for (int i = 1; i < vals->count(); i++) {
@ -101,7 +103,7 @@ void MoodbarBuilder::Normalize(QList<Rgb> *vals, double Rgb::*member) {
}
double avg = 0;
for (const Rgb &rgb : *vals) {
for (const Rgb &rgb : rgb_vals) {
const double value = rgb.*member;
if (value != mini && value != maxi) {
avg += value / static_cast<double>(vals->count());
@ -112,7 +114,7 @@ void MoodbarBuilder::Normalize(QList<Rgb> *vals, double Rgb::*member) {
double tb = 0;
double avgu = 0;
double avgb = 0;
for (const Rgb &rgb : *vals) {
for (const Rgb &rgb : rgb_vals) {
const double value = rgb.*member;
if (value != mini && value != maxi) {
if (value > avg) {
@ -132,7 +134,7 @@ void MoodbarBuilder::Normalize(QList<Rgb> *vals, double Rgb::*member) {
tb = 0;
double avguu = 0;
double avgbb = 0;
for (const Rgb &rgb : *vals) {
for (const Rgb &rgb : rgb_vals) {
const double value = rgb.*member;
if (value != mini && value != maxi) {
if (value > avgu) {

View File

@ -16,6 +16,7 @@
*/
#include <algorithm>
#include <utility>
#include <QApplication>
#include <QtConcurrentRun>
@ -177,7 +178,8 @@ bool MoodbarItemDelegate::RemoveFromCacheIfIndexesInvalid(const QUrl &url, Data
void MoodbarItemDelegate::ReloadAllColors() {
for (const QUrl &url : data_.keys()) {
const QList<QUrl> urls = data_.keys();
for (const QUrl &url : urls) {
Data *data = data_[url];
if (data->state_ == Data::State::Loaded) {

View File

@ -114,7 +114,8 @@ MoodbarLoader::Result MoodbarLoader::Load(const QUrl &url, const bool has_cue, Q
// Check if a mood file exists for this file already
const QString filename(url.toLocalFile());
for (const QString &possible_mood_file : MoodFilenames(filename)) {
const QStringList possible_mood_files = MoodFilenames(filename);
for (const QString &possible_mood_file : possible_mood_files) {
QFile f(possible_mood_file);
if (f.exists()) {
if (f.open(QIODevice::ReadOnly)) {
@ -203,7 +204,7 @@ void MoodbarLoader::RequestFinished(MoodbarPipeline *request, const QUrl &url) {
// Save the data alongside the original as well if we're configured to.
if (save_) {
QList<QString> mood_filenames = MoodFilenames(url.toLocalFile());
QStringList mood_filenames = MoodFilenames(url.toLocalFile());
const QString mood_filename(mood_filenames[0]);
QFile mood_file(mood_filename);
if (mood_file.open(QIODevice::WriteOnly)) {

View File

@ -391,7 +391,8 @@ void MoodbarProxyStyle::ShowContextMenu(const QPoint pos) {
}
// Update the currently selected style
for (QAction *action : style_action_group_->actions()) {
const QList<QAction*> actions = style_action_group_->actions();
for (QAction *action : actions) {
if (static_cast<MoodbarRenderer::MoodbarStyle>(action->data().toInt()) == moodbar_style_) {
action->setChecked(true);
break;

View File

@ -181,7 +181,7 @@ void AcoustidClient::RequestFinished(QNetworkReply *reply, const int request_id)
std::stable_sort(id_source_list.begin(), id_source_list.end());
QList<QString> id_list;
QStringList id_list;
id_list.reserve(id_source_list.count());
for (const IdSource &is : id_source_list) {
id_list << is.id_;

View File

@ -22,6 +22,7 @@
#include "config.h"
#include <algorithm>
#include <utility>
#include <QObject>
#include <QtConcurrentMap>
@ -75,7 +76,7 @@ void TagFetcher::StartFetch(const SongList &songs) {
fingerprint_watcher_ = new QFutureWatcher<QString>(this);
QObject::connect(fingerprint_watcher_, &QFutureWatcher<QString>::resultReadyAt, this, &TagFetcher::FingerprintFound);
fingerprint_watcher_->setFuture(future);
for (const Song &song : songs_) {
for (const Song &song : std::as_const(songs_)) {
emit Progress(song, tr("Fingerprinting song"));
}
}

View File

@ -0,0 +1,32 @@
cmake_minimum_required(VERSION 3.14)
set(SOURCES RemoteMessages.proto)
link_directories(
${GLIB_LIBRARY_DIRS}
${PROTOBUF_LIBRARY_DIRS}
)
add_library(lib-networkremote OBJECT ${PROTO_SOURCES} ${SOURCES})
target_include_directories(lib-networkremote SYSTEM PRIVATE
${GLIB_INCLUDE_DIRS}
${PROTOBUF_INCLUDE_DIRS}
)
target_include_directories(lib-networkremote PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_SOURCE_DIR}/src
${CMAKE_BINARY_DIR}/src
)
target_link_libraries(lib-networkremote PRIVATE
${GLIB_LIBRARIES}
${Protobuf_LIBRARIES}
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Network
Qt${QT_VERSION_MAJOR}::Gui
)
protobuf_generate(TARGET lib-networkremote)

View File

@ -0,0 +1,131 @@
syntax = "proto3";
option optimize_for = LITE_RUNTIME;
package nw.remote;
enum MsgType {
MSG_TYPE_UNSPECIFIED = 0;
// Client message
MSG_TYPE_REQUEST_SONG_INFO = 1;
MSG_TYPE_REQUEST_PLAY = 2;
MSG_TYPE_REQUEST_NEXT = 3;
MSG_TYPE_REQUEST_PREVIOUS = 4;
MSG_TYPE_REQUEST_PAUSE = 5;
MSG_TYPE_REQUEST_STOP = 6;
MSG_TYPE_REQUEST_FINISH = 7;
// Server messages
MSG_TYPE_REPLY_SONG_INFO = 8;
MSG_TYPE_REPLY_PLAY = 9;
MSG_TYPE_REPLY_NEXT = 10;
MSG_TYPE_REPLY_PREVIOUS = 11;
MSG_TYPE_REPLY_PAUSE = 12;
MSG_TYPE_REPLY_STOP = 13;
MSG_TYPE_REPLY_FINISH = 14;
MSG_TYPE_ENGINE_STATE_CHANGE = 15;
// Bidirectional messages
MSG_TYPE_DISCONNECT = 16;
}
enum PlayerState{
PLAYER_STATUS_UNSPECIFIED = 0;
PLAYER_STATUS_PLAYING = 1;
}
enum EngineState {
ENGINE_STATE_EMPTY = 0;
ENGINE_STATE_IDELE = 1;
ENGINE_STATE_PLAYING = 2;
ENGINE_STATE_PAUSED = 3;
}
enum ReasonDisconnect {
REASON_DISCONNECT_SERVER_SHUTDOWN = 0;
REASON_DISCONNECT_CLIENT_SHUTDOWN = 1;
}
message RequestDisconnect {
ReasonDisconnect reason_disconnect = 1;
}
message SongMetadata{
uint32 id = 1;
string title = 2;
string album = 3;
string artist = 4;
string albumartist = 5;
uint32 track = 6;
string stryear = 7;
string genre = 8;
uint32 playcount = 9;
string songlength = 10;
}
message RequestSongMetadata {
bool send = 1;
}
message ResponseSongMetadata {
SongMetadata song_metadata = 1;
PlayerState player_state = 2;
}
message RequestNextTrack {
bool next = 1;
}
message ResponseNextTrack {
bool next = 1;
}
message RequestPreviousTrack {
bool previous = 1;
}
message ResponsePreviousTrack {
bool previous = 1;
}
message RequestPlay {
bool play = 1;
}
message ResponsePlay {
bool play = 1;
}
message RequestPause {
bool pause = 1;
}
message ResponsePause {
bool pause = 1;
}
message RequestStop {
bool stop = 1;
}
message EngineStateChange {
EngineState state = 1;
}
message Message {
MsgType type = 1;
RequestSongMetadata request_song_metadata = 2;
ResponseSongMetadata response_song_metadata = 3;
RequestNextTrack request_next_track = 4;
RequestPreviousTrack request_previous_track = 5;
RequestPlay request_play = 6;
RequestPause request_pause = 7;
RequestStop request_stop = 8;
EngineStateChange engine_state_change = 9;
RequestDisconnect request_disconnect = 10;
ResponseNextTrack response_next_track = 11;
ResponsePreviousTrack response_previous_track = 12;
ResponsePlay response_play = 13;
ResponsePause response_pause = 14;
}

View File

@ -0,0 +1,68 @@
#include "client.h"
Client::Client(Application *app, QObject *parent)
: QObject{parent},
app_(app),
incomingMsg_(new IncomingMsg(app)),
outgoingMsg_(new OutgoingMsg(app)),
player_(app_->player())
{
}
Client::~Client()
{
incomingMsg_->deleteLater();
outgoingMsg_->deleteLater();
}
void Client::Init(QTcpSocket *socket)
{
socket_ = socket;
QObject::connect(incomingMsg_,&IncomingMsg::InMsgParsed,this, &Client::ProcessIncoming);
incomingMsg_->Init(socket_);
outgoingMsg_->Init(socket_, player_);
}
QTcpSocket* Client::GetSocket()
{
return socket_;
}
void Client::ProcessIncoming()
{
msgType_ = incomingMsg_->GetMsgType();
switch (msgType_)
{
case nw::remote::MSG_TYPE_REQUEST_SONG_INFO:
outgoingMsg_->SendCurrentTrackInfo();
break;
case nw::remote::MSG_TYPE_REQUEST_PLAY:
player_->Play();
// In case the player was paused when the client started send the song info again
outgoingMsg_->SendCurrentTrackInfo();
break;
case nw::remote::MSG_TYPE_REQUEST_NEXT:
player_->Next();
outgoingMsg_->SendCurrentTrackInfo();
break;
case nw::remote::MSG_TYPE_REQUEST_PREVIOUS:
player_->Previous();
outgoingMsg_->SendCurrentTrackInfo();
break;
case nw::remote::MSG_TYPE_REQUEST_PAUSE:
player_->Pause();
break;
case nw::remote::MSG_TYPE_REQUEST_STOP:
break;
case nw::remote::MSG_TYPE_REQUEST_FINISH:
emit ClientIsLeaving();
break;
case nw::remote::MSG_TYPE_DISCONNECT:
break;
default:
qInfo("Unknown mwessage type");
break;
}
}

View File

@ -0,0 +1,38 @@
#ifndef CLIENT_H
#define CLIENT_H
#include <QObject>
#include <QTcpSocket>
#include "incomingmsg.h"
#include "outgoingmsg.h"
#include "core/player.h"
class Application;
class Client : public QObject
{
Q_OBJECT
public:
explicit Client(Application *app, QObject *parent = nullptr);
~Client();
void Init(QTcpSocket*);
QTcpSocket* GetSocket();
void ProcessIncoming();
signals:
void ReceiveMsg();
void PrepareResponse();
void ClientIsLeaving();
private:
Application *app_;
QTcpSocket *socket_;
IncomingMsg *incomingMsg_;
OutgoingMsg *outgoingMsg_;
qint32 msgType_;
SharedPtr<Player> player_;
};
#endif // CLIENT_H

View File

@ -0,0 +1,74 @@
#include "clientmanager.h"
#include "core/application.h"
#include "core/logging.h"
ClientManager::ClientManager(Application *app, QObject *parent)
: QObject{parent},
app_(app)
{
clients_ = new QVector<Client*>;
}
ClientManager::~ClientManager()
{}
void ClientManager::AddClient(QTcpSocket *socket)
{
qLog(Debug) << "New Client connection +++++++++++++++";
socket_ = socket;
QObject::connect(socket_, &QAbstractSocket::errorOccurred, this, &ClientManager::Error);
QObject::connect(socket_, &QAbstractSocket::stateChanged, this, &ClientManager::StateChanged);
client_ = new Client(app_);
client_->Init(socket_);
clients_->append(client_);
QObject::connect(client_, &Client::ClientIsLeaving, this, &ClientManager::RemoveClient);
qLog(Debug) << "Socket State is " << socket_->state();;
qLog(Debug) << "There are now +++++++++++++++" << clients_->count() << "clients connected";
}
void ClientManager::RemoveClient()
{
for (Client* client : *clients_) {
if (client->GetSocket() == socket_){
clients_->removeAt(clients_->indexOf(client));
client->deleteLater();
}
}
socket_->close();
qLog(Debug) << "There are now +++++++++++++++" << clients_->count() << "clients connected";
}
void ClientManager::Ready()
{
qLog(Debug) << "Socket Ready";
}
void ClientManager::Error(QAbstractSocket::SocketError socketError)
{
switch (socketError) {
case QAbstractSocket::RemoteHostClosedError:
qLog(Debug) << "Remote Host closed";
break;
case QAbstractSocket::HostNotFoundError:
qLog(Debug) << "The host was not found. Please check the host name and port settings.";
break;
case QAbstractSocket::ConnectionRefusedError:
qLog(Debug) << "The connection was refused by the peer. ";
break;
default:
qLog(Debug) << "The following error occurred: %1." << socket_->errorString();
}
}
void ClientManager::StateChanged()
{
qLog(Debug) << socket_->state();
qLog(Debug) << "State Changed";
if (socket_->state() == QAbstractSocket::UnconnectedState){
RemoveClient();
}
}

View File

@ -0,0 +1,32 @@
#ifndef CLIENTMANAGER_H
#define CLIENTMANAGER_H
#include <QObject>
#include <QTcpSocket>
#include <QVector>
#include "networkremote/client.h"
class Application;
class ClientManager : public QObject
{
Q_OBJECT
public:
explicit ClientManager(Application *app, QObject *parent = nullptr);
~ClientManager();
void AddClient(QTcpSocket *socket);
void RemoveClient();
private slots:
void Ready();
void Error(QAbstractSocket::SocketError);
void StateChanged();
private:
Application *app_;
QVector<Client*> *clients_;
Client *client_ = nullptr;
QTcpSocket *socket_ = nullptr;
};
#endif // CLIENTMANAGER_H

View File

@ -0,0 +1,35 @@
#include "incomingmsg.h"
#include "core/logging.h"
#include "core/player.h"
IncomingMsg::IncomingMsg(Application *app, QObject *parent)
: QObject{parent},
msg_(new nw::remote::Message),
app_(app)
{
}
void IncomingMsg::Init(QTcpSocket *socket)
{
socket_ = socket;
QObject::connect(socket_, &QIODevice::readyRead, this, &IncomingMsg::ReadyRead);
}
void IncomingMsg::SetMsgType()
{
msgString_ = msgStream_.toStdString();
msg_->ParseFromString(msgString_);
emit InMsgParsed();
}
qint32 IncomingMsg::GetMsgType()
{
return msg_->type();
}
void IncomingMsg::ReadyRead()
{
qLog(Debug) << "Ready To Read";
msgStream_ = socket_->readAll();
if (msgStream_.length() > 0) SetMsgType();
}

View File

@ -0,0 +1,34 @@
#ifndef INCOMINGMSG_H
#define INCOMINGMSG_H
#include <QObject>
#include <QTcpSocket>
#include "networkremote/RemoteMessages.pb.h"
#include "core/application.h"
class IncomingMsg : public QObject
{
Q_OBJECT
public:
explicit IncomingMsg(Application *app, QObject *parent = nullptr);
void Init(QTcpSocket*);
void SetMsgType();
qint32 GetMsgType();
private slots:
void ReadyRead();
signals:
void InMsgParsed();
private:
nw::remote::Message *msg_;
QTcpSocket *socket_;
long bytesIn_;
QByteArray msgStream_;
std::string msgString_;
Application *app_;
qint32 msgType_;
};
#endif // INCOMINGMSG_H

View File

@ -0,0 +1,84 @@
#include <QThread>
#include "networkremote/networkremote.h"
#include "core/application.h"
#include "core/logging.h"
#include "core/player.h"
NetworkRemote* NetworkRemote::sInstance = nullptr;
const char *NetworkRemote::kSettingsGroup = "Remote";
NetworkRemote::NetworkRemote(Application* app, QObject *parent)
: QObject(parent),
app_(app),
original_thread_(nullptr)
{
setObjectName("Strawberry Remote");
original_thread_ = thread();
sInstance = this;
server_ = new TcpServer(app_);
}
NetworkRemote::~NetworkRemote()
{
stopTcpServer();
}
void NetworkRemote::Init()
{
LoadSettings();
if (use_remote_){
startTcpServer();
}
else {
stopTcpServer();
}
qLog(Debug) << "NetworkRemote Init() ";
}
void NetworkRemote::Update()
{
LoadSettings();
if (use_remote_){
stopTcpServer();
startTcpServer();
}
else {
stopTcpServer();
}
qLog(Debug) << "NetworkRemote Updated ==== ";
}
void NetworkRemote::LoadSettings()
{
s_->Load();
use_remote_ = s_->UserRemote();
local_only_ = s_->LocalOnly();
remote_port_ = s_->GetPort();
ipAddr_.setAddress(s_->GetIpAddress());
}
void NetworkRemote::startTcpServer()
{
server_->StartServer(ipAddr_,remote_port_);
}
void NetworkRemote::stopTcpServer()
{
if (server_->ServerUp()){
qLog(Debug) << "TcpServer stopped ";
server_->StopServer();
}
}
NetworkRemote* NetworkRemote::Instance() {
if (!sInstance) {
// Error
return nullptr;
}
qLog(Debug) << "NetworkRemote instance is up ";
return sInstance;
}

View File

@ -0,0 +1,45 @@
#ifndef NETWORKREMOTE_H
#define NETWORKREMOTE_H
#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>
#include <QHostAddress>
#include <QSettings>
#include "tcpserver.h"
#include "networkremote/remotesettings.h"
class Application;
class QThread;
class NetworkRemote : public QObject
{
Q_OBJECT
public:
static const char* kSettingsGroup;
explicit NetworkRemote(Application* app, QObject *parent = nullptr);
static NetworkRemote* Instance();
~NetworkRemote() override;
public slots:
void Init();
void Update();
void LoadSettings();
void startTcpServer();
void stopTcpServer();
private:
Application *app_;
bool use_remote_;
bool local_only_;
int remote_port_;
QHostAddress ipAddr_;
TcpServer *server_;
QThread *original_thread_;
static NetworkRemote* sInstance;
RemoteSettings *s_ = new RemoteSettings;
};
#endif // NETWORKREMOTE_H

View File

@ -0,0 +1,85 @@
#include "outgoingmsg.h"
#include "core/player.h"
#include "playlist/playlistmanager.h"
OutgoingMsg::OutgoingMsg(Application *app, QObject *parent)
: QObject{parent},
app_(app),
msg_(new nw::remote::Message),
responeSong_(new nw::remote::ResponseSongMetadata)
{
}
OutgoingMsg::~OutgoingMsg()
{
}
void OutgoingMsg::Init(QTcpSocket *socket, SharedPtr<Player> player)
{
socket_ = socket;
player_ = player;
}
void OutgoingMsg::SendCurrentTrackInfo()
{
msg_->Clear();
song_ = new nw::remote::SongMetadata;
responeSong_->Clear();
//PlaylistItemPtr current_item() const;
currentItem_ = app_->playlist_manager()->active()->current_item();
//PlaylistItemPtr prt = player_->GetCurrentItem();
//if (playerState_ == EngineBase::State::Playing){
if (currentItem_ != NULL){
song_->mutable_title()->assign(currentItem_->Metadata().PrettyTitle().toStdString());
song_->mutable_album()->assign(currentItem_->Metadata().album().toStdString());
song_->mutable_artist()->assign(currentItem_->Metadata().artist().toStdString());
song_->mutable_albumartist()->assign(currentItem_->Metadata().albumartist().toStdString());
song_->set_track(currentItem_->Metadata().track());
song_->mutable_stryear()->assign(currentItem_->Metadata().PrettyYear().toStdString());
song_->mutable_genre()->assign(currentItem_->Metadata().genre().toStdString());
song_->set_playcount(currentItem_->Metadata().playcount());
song_->mutable_songlength()->assign(currentItem_->Metadata().PrettyLength().toStdString());
msg_->set_type(nw::remote::MSG_TYPE_REPLY_SONG_INFO);
msg_->mutable_response_song_metadata()->set_player_state(nw::remote::PLAYER_STATUS_PLAYING);
msg_->mutable_response_song_metadata()->set_allocated_song_metadata(song_);
}
else {
/* NOTE: TODO
* I couldn't figure out how to get the song data if the song wasn't playing
*
* */
msg_->set_type(nw::remote::MSG_TYPE_UNSPECIFIED);
msg_->mutable_response_song_metadata()->set_player_state(nw::remote::PLAYER_STATUS_UNSPECIFIED);
}
SendMsg();
}
void OutgoingMsg::SendMsg()
{
std::string msgOut;
msg_->SerializeToString(&msgOut);
bytesOut_ = msg_->ByteSizeLong();
if(socket_->isWritable())
{
socket_->write(QByteArray::fromStdString(msgOut));
qInfo() << socket_->bytesToWrite() << " bytes written to socket " << socket_->socketDescriptor();
statusOk_ = true;
msg_->Clear();
}
else
{
statusOk_ = false;
}
}

View File

@ -0,0 +1,38 @@
#ifndef OUTGOINGMSG_H
#define OUTGOINGMSG_H
#include <QObject>
#include "core/application.h"
#include "playlist/playlist.h"
#include "playlist/playlistitem.h"
#include "qtcpsocket.h"
#include "networkremote/RemoteMessages.pb.h"
class OutgoingMsg : public QObject
{
Q_OBJECT
public:
explicit OutgoingMsg(Application *app, QObject *parent = nullptr);
~OutgoingMsg();
void Init(QTcpSocket*, SharedPtr<Player>);
void SendCurrentTrackInfo();
void SendMsg();
private:
Application *app_;
PlaylistItemPtr currentItem_;
Playlist *playlist_;
QTcpSocket *socket_;
qint32 msgType_;
QByteArray msgStream_;
nw::remote::Message *msg_;
long bytesOut_;
std::string msgString_;
nw::remote::SongMetadata *song_;
nw::remote::ResponseSongMetadata *responeSong_;
SharedPtr<Player> player_ ;
bool statusOk_;
};
#endif // OUTGOINGMSG_H

View File

@ -0,0 +1,102 @@
#include <QHostAddress>
#include <QNetworkInterface>
#include "remotesettings.h"
#include "core/logging.h"
const char *RemoteSettings::kSettingsGroup = "NetworkRemote";
RemoteSettings::RemoteSettings(QObject *parent)
: QObject{parent}
{}
RemoteSettings::~RemoteSettings()
{}
void RemoteSettings::Load()
{
SetIpAdress();
s_.beginGroup(RemoteSettings::kSettingsGroup);
if (!s_.contains("useRemote")){
qLog(Debug) << "First time run the Network Remote";
s_.setValue("useRemote", false);
s_.setValue("localOnly",false);
s_.setValue("remotePort",5050);
s_.setValue("ipAddress",ipAddr_);
}
else {
use_remote_ = s_.value("useRemote").toBool();
local_only_ = s_.value("localOnly").toBool();
remote_port_ = s_.value("remotePort").toInt();
s_.setValue("ipAddress",ipAddr_);
}
s_.endGroup();
qInfo("QSettings Loaded ++++++++++++++++");
}
void RemoteSettings::Save()
{
s_.beginGroup(RemoteSettings::kSettingsGroup);
s_.setValue("useRemote",use_remote_);
s_.setValue("localOnly",local_only_);
s_.setValue("remotePort",remote_port_);
s_.setValue("ipAddress",ipAddr_);
s_.endGroup();
s_.sync();
qInfo("Saving QSettings ++++++++++++++++");
}
bool RemoteSettings::UserRemote()
{
return use_remote_;
}
bool RemoteSettings::LocalOnly()
{
return local_only_;
}
QString RemoteSettings::GetIpAddress()
{
return ipAddr_;
}
int RemoteSettings::GetPort()
{
return remote_port_;
}
void RemoteSettings::SetUseRemote(bool useRemote)
{
use_remote_ = useRemote;
Save();
}
void RemoteSettings::SetLocalOnly(bool localOnly)
{
local_only_ = localOnly;
Save();
}
void RemoteSettings::SetIpAdress()
{
bool found = false;
QList<QHostAddress> hostList = QNetworkInterface::allAddresses();
for (const QHostAddress &address : hostList)
{
if (address.protocol() == QAbstractSocket::IPv4Protocol && address.isLoopback() == false && !found){
// NOTE: this code currently only takes the first ip address it finds
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
qInfo("Warning: The code only picks the first IPv4 address");
found = true;
ipAddr_ = address.toString();
}
}
}
void RemoteSettings::SetPort(int port)
{
remote_port_ = port;
Save();
}

View File

@ -0,0 +1,33 @@
#ifndef REMOTESETTINGS_H
#define REMOTESETTINGS_H
#include <QObject>
#include <QSettings>
class RemoteSettings : public QObject
{
Q_OBJECT
public:
static const char *kSettingsGroup;
explicit RemoteSettings(QObject *parent = nullptr);
~RemoteSettings();
void Load();
void Save();
bool UserRemote();
bool LocalOnly();
QString GetIpAddress();
int GetPort();
void SetUseRemote(bool);
void SetLocalOnly(bool);
void SetIpAdress ();
void SetPort(int);
private:
QSettings s_;
bool use_remote_ = false;
bool local_only_ = false;
int remote_port_ = 5050;
QString ipAddr_ = "0.0.0.0";
};
#endif // REMOTESETTINGS_H

View File

@ -0,0 +1,48 @@
#include "tcpserver.h"
#include "core/logging.h"
#include "networkremote/clientmanager.h"
#include <QNetworkProxy>
TcpServer::TcpServer(Application* app, QObject *parent)
: QObject{parent},
app_(app)
{
server_ = new QTcpServer(this);
clientMgr_ = new ClientManager(app_);
connect(server_,&QTcpServer::newConnection, this, &TcpServer::NewTcpConnection);
}
TcpServer::~TcpServer()
{
}
void TcpServer::StartServer(QHostAddress ipAddr, int port)
{
bool ok = false;
server_->setProxy(QNetworkProxy::NoProxy);
ok = server_->listen(ipAddr, port);
if (ok){
qLog(Debug) << "TCP Server Started on --- " << ipAddr.toString() << " and port -- " << port;
}
}
void TcpServer::NewTcpConnection()
{
socket_ = server_->nextPendingConnection();
clientMgr_->AddClient(socket_);
qLog(Debug) << "New Socket -------------------";
}
void TcpServer::StopServer()
{
server_->close();
qLog(Debug) << "TCP Server Stopped ----------------------";
}
bool TcpServer::ServerUp()
{
return server_->isListening();
}

View File

@ -0,0 +1,38 @@
#ifndef TCPSERVER_H
#define TCPSERVER_H
#include <QObject>
#include <QHostAddress>
#include <QNetworkInterface>
#include <QTcpServer>
#include <QTcpSocket>
#include "networkremote/clientmanager.h"
class Application;
class TcpServer : public QObject
{
Q_OBJECT
public:
static const char *kSettingsGroup;
explicit TcpServer(Application* app, QObject *parent = nullptr);
~TcpServer();
bool ServerUp();
public slots:
void NewTcpConnection();
void StartServer(QHostAddress ipAddr, int port);
void StopServer();
signals:
private:
Application *app_;
QTcpServer *server_;
QTcpSocket *socket_;
ClientManager *clientMgr_;
};
#endif // TCPSERVER_H

View File

@ -22,6 +22,7 @@
#include <QtGlobal>
#include <functional>
#include <utility>
#include <chrono>
#include <QThread>
@ -125,7 +126,7 @@ void Organize::ProcessSomeFiles() {
if (!started_) {
if (!destination_->StartCopy(&supported_filetypes_)) {
// Failed to start - mark everything as failed :(
for (const Task &task : tasks_pending_) {
for (const Task &task : std::as_const(tasks_pending_)) {
files_with_errors_ << task.song_info_.song_.url().toLocalFile();
}
tasks_pending_.clear();
@ -329,7 +330,7 @@ void Organize::UpdateProgress() {
#ifdef HAVE_GSTREAMER
// Update transcoding progress
QMap<QString, float> transcode_progress = transcoder_->GetProgress();
QStringList filenames = transcode_progress.keys();
const QStringList filenames = transcode_progress.keys();
for (const QString &filename : filenames) {
if (!tasks_transcoding_.contains(filename)) continue;
tasks_transcoding_[filename].transcode_progress_ = transcode_progress[filename];
@ -340,11 +341,11 @@ void Organize::UpdateProgress() {
// Files that need transcoding total 50 for the transcode and 50 for the copy, files that only need to be copied total 100.
int progress = tasks_complete_ * 100;
for (const Task &task : tasks_pending_) {
for (const Task &task : std::as_const(tasks_pending_)) {
progress += qBound(0, static_cast<int>(task.transcode_progress_ * 50), 50);
}
#ifdef HAVE_GSTREAMER
QList<Task> tasks_transcoding = tasks_transcoding_.values();
const QList<Task> tasks_transcoding = tasks_transcoding_.values();
for (const Task &task : tasks_transcoding) {
progress += qBound(0, static_cast<int>(task.transcode_progress_ * 50), 50);
}

View File

@ -165,7 +165,8 @@ OSDPretty::~OSDPretty() {
void OSDPretty::showEvent(QShowEvent *e) {
screens_.clear();
for (QScreen *screen : QGuiApplication::screens()) {
const QList<QScreen*> screens = QGuiApplication::screens();
for (QScreen *screen : screens) {
screens_.insert(screen->name(), screen);
}

View File

@ -21,6 +21,7 @@
#include "config.h"
#include <utility>
#include <memory>
#include <QObject>
@ -307,7 +308,7 @@ PlaylistItemPtr PlaylistBackend::RestoreCueData(PlaylistItemPtr item, SharedPtr<
}
}
for (const Song &from_list : song_list) {
for (const Song &from_list : std::as_const(song_list)) {
if (from_list.url().toEncoded() == song.url().toEncoded() && from_list.beginning_nanosec() == song.beginning_nanosec()) {
// We found a matching section; replace the input item with a new one containing CUE metadata
return make_shared<SongPlaylistItem>(from_list);

View File

@ -141,7 +141,8 @@ void PlaylistListContainer::SetApplication(Application *app) {
QObject::connect(player, &Player::Stopped, this, &PlaylistListContainer::ActiveStopped);
// Get all playlists, even ones that are hidden in the UI.
for (const PlaylistBackend::Playlist &p : app->playlist_backend()->GetAllFavoritePlaylists()) {
const QList<PlaylistBackend::Playlist> playlists = app->playlist_backend()->GetAllFavoritePlaylists();
for (const PlaylistBackend::Playlist &p : playlists) {
QStandardItem *playlist_item = model_->NewPlaylist(p.name, p.id);
QStandardItem *parent_folder = model_->FolderByPath(p.ui_path);
parent_folder->appendRow(playlist_item);
@ -407,7 +408,8 @@ void PlaylistListContainer::Delete() {
QSet<int> ids;
QList<QPersistentModelIndex> folders_to_delete;
for (const QModelIndex &proxy_index : ui_->tree->selectionModel()->selectedRows()) {
const QModelIndexList proxy_indexes = ui_->tree->selectionModel()->selectedRows();
for (const QModelIndex &proxy_index : proxy_indexes) {
const QModelIndex idx = proxy_->mapToSource(proxy_index);
// Is it a playlist?
@ -439,7 +441,7 @@ void PlaylistListContainer::Delete() {
}
// Delete the top-level folders.
for (const QPersistentModelIndex &idx : folders_to_delete) {
for (const QPersistentModelIndex &idx : std::as_const(folders_to_delete)) {
if (idx.isValid()) {
model_->removeRow(idx.row(), idx.parent());
}

View File

@ -20,6 +20,8 @@
#include "config.h"
#include <utility>
#include <QtGlobal>
#include <QList>
#include <QUndoStack>
@ -92,7 +94,7 @@ bool RemoveItems::mergeWith(const QUndoCommand *other) {
ranges_.append(remove_command->ranges_);
int sum = 0;
for (const Range &range : ranges_) sum += range.count_;
for (const Range &range : std::as_const(ranges_)) sum += range.count_;
setText(tr("remove %n songs", "", sum));
return true;

View File

@ -865,7 +865,8 @@ void PlaylistView::mousePressEvent(QMouseEvent *event) {
if (selectedIndexes().contains(idx)) {
// Update all the selected item ratings
QModelIndexList src_index_list;
for (const QModelIndex &i : selectedIndexes()) {
const QModelIndexList indexes = selectedIndexes();
for (const QModelIndex &i : indexes) {
if (i.data(Playlist::Role_CanSetRating).toBool()) {
src_index_list << playlist_->filter()->mapToSource(i);
}
@ -1548,7 +1549,8 @@ void PlaylistView::RatingHoverIn(const QModelIndex &idx, const QPoint pos) {
update(idx);
update(old_index);
for (const QModelIndex &i : selectedIndexes()) {
const QModelIndexList indexes = selectedIndexes();
for (const QModelIndex &i : indexes) {
if (i.column() == Playlist::Column_Rating) update(i);
}
@ -1569,7 +1571,8 @@ void PlaylistView::RatingHoverOut() {
setCursor(QCursor());
update(old_index);
for (const QModelIndex &i : selectedIndexes()) {
const QModelIndexList indexes = selectedIndexes();
for (const QModelIndex &i : indexes) {
if (i.column() == Playlist::Column_Rating) {
update(i);
}

View File

@ -33,7 +33,7 @@ SongPlaylistItem::SongPlaylistItem(const Song::Source source) : PlaylistItem(sou
SongPlaylistItem::SongPlaylistItem(const Song &song) : PlaylistItem(song.source()), song_(song) {}
bool SongPlaylistItem::InitFromQuery(const SqlRow &query) {
song_.InitFromQuery(query, false, Song::kRowIdColumns.count() * 3);
song_.InitFromQuery(query, false, static_cast<int>(Song::kRowIdColumns.count()));
return true;
}

View File

@ -402,8 +402,8 @@ bool CueParser::TryMagic(const QByteArray &data) const {
QString CueParser::FindCueFilename(const QString &filename) {
QStringList cue_files = QStringList() << filename + QStringLiteral(".cue")
<< filename.section(QLatin1Char('.'), 0, -2) + QStringLiteral(".cue");
const QStringList cue_files = QStringList() << filename + QStringLiteral(".cue")
<< filename.section(QLatin1Char('.'), 0, -2) + QStringLiteral(".cue");
for (const QString &cuefile : cue_files) {
if (QFileInfo::exists(cuefile)) return cuefile;

View File

@ -22,6 +22,7 @@
#include "config.h"
#include <algorithm>
#include <utility>
#include <QObject>
#include <QIODevice>
@ -230,7 +231,7 @@ void Queue::UpdateTotalLength() {
quint64 total = 0;
for (const QPersistentModelIndex &row : source_indexes_) {
for (const QPersistentModelIndex &row : std::as_const(source_indexes_)) {
int id = row.row();
Q_ASSERT(playlist_->has_item_at(id));
@ -292,7 +293,8 @@ void Queue::Move(const QList<int> &proxy_rows, int pos) {
}
// Update persistent indexes
for (const QModelIndex &pidx : persistentIndexList()) {
const QModelIndexList pindexes = persistentIndexList();
for (const QModelIndex &pidx : pindexes) {
const int dest_offset = static_cast<int>(proxy_rows.indexOf(pidx.row()));
if (dest_offset != -1) {
// This index was moved
@ -379,7 +381,7 @@ bool Queue::dropMimeData(const QMimeData *data, Qt::DropAction action, int row,
stream >> source_rows;
QModelIndexList source_indexes;
for (int source_row : source_rows) {
for (int source_row : std::as_const(source_rows)) {
const QModelIndex source_index = sourceModel()->index(source_row, 0);
const QModelIndex proxy_index = mapFromSource(source_index);
if (proxy_index.isValid()) {

View File

@ -22,6 +22,7 @@
#include "config.h"
#include <algorithm>
#include <utility>
#include <QWidget>
#include <QAbstractItemModel>
@ -133,7 +134,7 @@ void QueueView::MoveUp() {
if (indexes.isEmpty() || indexes.first().row() == 0) return;
for (const QModelIndex &idx : indexes) {
for (const QModelIndex &idx : std::as_const(indexes)) {
current_playlist_->queue()->MoveUp(idx.row());
}
@ -162,7 +163,8 @@ void QueueView::Remove() {
// collect the rows to be removed
QList<int> row_list;
for (const QModelIndex &idx : ui_->list->selectionModel()->selectedRows()) {
const QModelIndexList indexes = ui_->list->selectionModel()->selectedRows();
for (const QModelIndex &idx : indexes) {
if (idx.isValid()) row_list << idx.row();
}

View File

@ -38,7 +38,7 @@ RadioPlaylistItem::RadioPlaylistItem(const Song &metadata)
bool RadioPlaylistItem::InitFromQuery(const SqlRow &query) {
metadata_.InitFromQuery(query, false);
metadata_.InitFromQuery(query, false, static_cast<int>(Song::kRowIdColumns.count()));
InitMetadata();
return true;

View File

@ -58,7 +58,7 @@ void ScrobblerSettings::ReloadSettings() {
prefer_albumartist_ = s.value("albumartist", false).toBool();
show_error_dialog_ = s.value("show_error_dialog", true).toBool();
strip_remastered_ = s.value("strip_remastered", true).toBool();
QStringList sources = s.value("sources").toStringList();
const QStringList sources = s.value("sources").toStringList();
s.endGroup();
sources_.clear();

View File

@ -20,6 +20,7 @@
#include "config.h"
#include <algorithm>
#include <utility>
#include <QObject>
#include <QList>
@ -101,7 +102,7 @@ void CoversSettingsPage::Load() {
QList<CoverProvider*> cover_providers_sorted = dialog()->app()->cover_providers()->List();
std::stable_sort(cover_providers_sorted.begin(), cover_providers_sorted.end(), ProviderCompareOrder);
for (CoverProvider *provider : cover_providers_sorted) {
for (CoverProvider *provider : std::as_const(cover_providers_sorted)) {
QListWidgetItem *item = new QListWidgetItem(ui_->providers);
item->setText(provider->name());
item->setCheckState(provider->is_enabled() ? Qt::Checked : Qt::Unchecked);

View File

@ -153,7 +153,7 @@ void GlobalShortcutsSettingsPage::Load() {
}
#endif // HAVE_X11_GLOBALSHORTCUTS
QList<GlobalShortcutsManager::Shortcut> shortcuts = manager->shortcuts().values();
const QList<GlobalShortcutsManager::Shortcut> shortcuts = manager->shortcuts().values();
for (const GlobalShortcutsManager::Shortcut &i : shortcuts) {
Shortcut shortcut;
shortcut.s = i;
@ -167,7 +167,7 @@ void GlobalShortcutsSettingsPage::Load() {
ItemClicked(ui_->list->topLevelItem(0));
}
QList<Shortcut> shortcuts = shortcuts_.values();
const QList<Shortcut> shortcuts = shortcuts_.values();
for (const Shortcut &shortcut : shortcuts) {
SetShortcut(shortcut.s.id, shortcut.s.action->shortcut());
}
@ -215,7 +215,7 @@ void GlobalShortcutsSettingsPage::Save() {
Settings s;
s.beginGroup(kSettingsGroup);
QList<Shortcut> shortcuts = shortcuts_.values();
const QList<Shortcut> shortcuts = shortcuts_.values();
for (const Shortcut &shortcut : shortcuts) {
shortcut.s.action->setShortcut(shortcut.key);
shortcut.s.shortcut->setKey(shortcut.key);
@ -330,7 +330,7 @@ void GlobalShortcutsSettingsPage::ChangeClicked() {
if (key.isEmpty()) return;
// Check if this key sequence is used by any other actions
QStringList ids = shortcuts_.keys();
const QStringList ids = shortcuts_.keys();
for (const QString &id : ids) {
if (shortcuts_[id].key == key) SetShortcut(id, QKeySequence());
}

View File

@ -20,6 +20,7 @@
#include "config.h"
#include <algorithm>
#include <utility>
#include <QObject>
#include <QList>
@ -81,7 +82,7 @@ void LyricsSettingsPage::Load() {
QList<LyricsProvider*> lyrics_providers_sorted = dialog()->app()->lyrics_providers()->List();
std::stable_sort(lyrics_providers_sorted.begin(), lyrics_providers_sorted.end(), ProviderCompareOrder);
for (LyricsProvider *provider : lyrics_providers_sorted) {
for (LyricsProvider *provider : std::as_const(lyrics_providers_sorted)) {
QListWidgetItem *item = new QListWidgetItem(ui_->providers);
item->setText(provider->name());
item->setCheckState(provider->is_enabled() ? Qt::Checked : Qt::Unchecked);

View File

@ -0,0 +1,98 @@
#include <QHostInfo>
#include <QHostAddress>
#include <QNetworkInterface>
#include "core/iconloader.h"
#include "networkremote/networkremote.h"
#include "settings/settingsdialog.h"
#include "settings/networkremotesettingspage.h"
#include "ui_networkremotesettingspage.h"
NetworkRemoteSettingsPage::NetworkRemoteSettingsPage(SettingsDialog *dialog, QWidget *parent) :
SettingsPage(dialog,parent),
ui_(new Ui_NetworkRemoteSettingsPage)
{
ui_->setupUi(this);
setWindowIcon(IconLoader::Load("network-remote", true, 0,32));
QObject::connect(ui_->useRemoteClient,&QAbstractButton::clicked, this, &NetworkRemoteSettingsPage::RemoteButtonClicked);
QObject::connect(ui_->localConnectionsOnly, &QAbstractButton::clicked, this, &NetworkRemoteSettingsPage::LocalConnectButtonClicked);
QObject::connect(ui_->portSelected, &QAbstractSpinBox::editingFinished, this, &NetworkRemoteSettingsPage::PortChanged);
}
NetworkRemoteSettingsPage::~NetworkRemoteSettingsPage()
{
delete ui_;
}
void NetworkRemoteSettingsPage::Load()
{
ui_->portSelected->setRange(5050, 65535);
ui_->ip_address->setText("0.0.0.0");
s_->Load();
ui_->useRemoteClient->setCheckable(true);
ui_->useRemoteClient->setChecked(s_->UserRemote());
if (s_->UserRemote()){
ui_->localConnectionsOnly->setCheckable(true);
ui_->localConnectionsOnly->setChecked(s_->LocalOnly());
ui_->portSelected->setReadOnly(false);
ui_->portSelected->setValue(s_->GetPort());
}
else{
ui_->localConnectionsOnly->setCheckable(false);
ui_->portSelected->setReadOnly(true);
}
DisplayIP();
qInfo("SettingsPage Loaded QSettings ++++++++++++++++");
Init(ui_->layout_networkremotesettingspage->parentWidget());
}
void NetworkRemoteSettingsPage::Save()
{
qInfo("Saving QSettings ++++++++++++++++");
}
void NetworkRemoteSettingsPage::Refresh()
{
if (NetworkRemote::Instance()) {
qInfo() << "NetworkRemote Instance is up";
NetworkRemote::Instance()->Update();
}
}
void NetworkRemoteSettingsPage::DisplayIP()
{
ui_->ip_address->setText(s_->GetIpAddress());
}
void NetworkRemoteSettingsPage::RemoteButtonClicked()
{
s_->SetUseRemote(ui_->useRemoteClient->isChecked());
ui_->useRemoteClient->setChecked(s_->UserRemote());
if (ui_->useRemoteClient->isChecked()){
ui_->localConnectionsOnly->setCheckable(true);
ui_->portSelected->setReadOnly(false);
}
else{
ui_->localConnectionsOnly->setCheckable(false);
ui_->portSelected->setReadOnly(true);
}
Refresh();
}
void NetworkRemoteSettingsPage::LocalConnectButtonClicked()
{
s_->SetLocalOnly(ui_->localConnectionsOnly->isChecked());
Refresh();
}
void NetworkRemoteSettingsPage::PortChanged()
{
s_->SetPort(ui_->portSelected->value());
Refresh();
}

View File

@ -0,0 +1,39 @@
#ifndef NETWORKREMOTESETTINGSPAGE_H
#define NETWORKREMOTESETTINGSPAGE_H
#include <QWidget>
#include <QObject>
#include "settingspage.h"
#include "networkremote/remotesettings.h"
class SettingsDialog;
class Ui_NetworkRemoteSettingsPage;
class NetworkRemote;
class NetworkRemoteSettingsPage : public SettingsPage
{
Q_OBJECT
public:
explicit NetworkRemoteSettingsPage(SettingsDialog *dialog, QWidget *parent = nullptr);
~NetworkRemoteSettingsPage() override;
void Load() override;
void Save() override;
void Refresh();
signals:
void remoteSettingsChanged();
private:
Ui_NetworkRemoteSettingsPage *ui_;
RemoteSettings *s_ = new RemoteSettings;
private slots:
void RemoteButtonClicked();
void LocalConnectButtonClicked();
void PortChanged();
void DisplayIP();
};
#endif // NETWORKREMOTESETTINGSPAGE_H

View File

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>NetworkRemoteSettingsPage</class>
<widget class="QWidget" name="NetworkRemoteSettingsPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>496</width>
<height>195</height>
</rect>
</property>
<property name="windowTitle">
<string>Remote</string>
</property>
<layout class="QVBoxLayout" name="layout_networkremotesettingspage">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QCheckBox" name="useRemoteClient">
<property name="text">
<string>Use Remote Network Client</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="settingsBox">
<property name="title">
<string/>
</property>
<widget class="QLabel" name="remotePortLabel">
<property name="geometry">
<rect>
<x>20</x>
<y>20</y>
<width>101</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Remote Port</string>
</property>
</widget>
<widget class="QSpinBox" name="portSelected">
<property name="geometry">
<rect>
<x>160</x>
<y>10</y>
<width>71</width>
<height>26</height>
</rect>
</property>
</widget>
<widget class="QCheckBox" name="localConnectionsOnly">
<property name="geometry">
<rect>
<x>20</x>
<y>60</y>
<width>231</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Only allow local connections</string>
</property>
</widget>
<widget class="QLabel" name="ipAddressLabel">
<property name="geometry">
<rect>
<x>30</x>
<y>110</y>
<width>141</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Your IP Address is</string>
</property>
</widget>
<widget class="QLabel" name="ip_address">
<property name="geometry">
<rect>
<x>240</x>
<y>110</y>
<width>191</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -65,6 +65,7 @@
#include "lyricssettingspage.h"
#include "transcodersettingspage.h"
#include "networkproxysettingspage.h"
#include "networkremotesettingspage.h"
#include "appearancesettingspage.h"
#include "contextsettingspage.h"
#include "notificationssettingspage.h"
@ -141,6 +142,7 @@ SettingsDialog::SettingsDialog(Application *app, OSDBase *osd, QMainWindow *main
AddPage(Page::Transcoding, new TranscoderSettingsPage(this, this), general);
#endif
AddPage(Page::Proxy, new NetworkProxySettingsPage(this, this), general);
AddPage(Page::Remote, new NetworkRemoteSettingsPage(this, this), general);
QTreeWidgetItem *iface = AddCategory(tr("User interface"));
AddPage(Page::Appearance, new AppearanceSettingsPage(this, this), iface);
@ -192,7 +194,7 @@ void SettingsDialog::showEvent(QShowEvent *e) {
LoadGeometry();
// Load settings
loading_settings_ = true;
QList<PageData> pages = pages_.values();
const QList<PageData> pages = pages_.values();
for (const PageData &page : pages) {
page.page_->Load();
}
@ -211,7 +213,7 @@ void SettingsDialog::closeEvent(QCloseEvent*) {
void SettingsDialog::accept() {
QList<PageData> pages = pages_.values();
const QList<PageData> pages = pages_.values();
for (const PageData &page : pages) {
page.page_->Accept();
}
@ -226,7 +228,7 @@ void SettingsDialog::accept() {
void SettingsDialog::reject() {
// Notify each page that user clicks on Cancel
QList<PageData> pages = pages_.values();
const QList<PageData> pages = pages_.values();
for (const PageData &page : pages) {
page.page_->Reject();
}
@ -314,7 +316,7 @@ void SettingsDialog::AddPage(const Page id, SettingsPage *page, QTreeWidgetItem
void SettingsDialog::Save() {
QList<PageData> pages = pages_.values();
const QList<PageData> pages = pages_.values();
for (const PageData &page : pages) {
page.page_->Apply();
}
@ -327,7 +329,7 @@ void SettingsDialog::DialogButtonClicked(QAbstractButton *button) {
// While we only connect Apply at the moment, this might change in the future
if (ui_->buttonBox->button(QDialogButtonBox::Apply) == button) {
QList<PageData> pages = pages_.values();
const QList<PageData> pages = pages_.values();
for (const PageData &page : pages) {
page.page_->Apply();
}
@ -357,7 +359,7 @@ void SettingsDialog::CurrentItemChanged(QTreeWidgetItem *item) {
ui_->title->setText(QStringLiteral("<b>") + item->text(0) + QStringLiteral("</b>"));
// Display the right page
QList<PageData> pages = pages_.values();
const QList<PageData> pages = pages_.values();
for (const PageData &page : pages) {
if (page.item_ == item) {
ui_->stacked_widget->setCurrentWidget(page.scroll_area_);

View File

@ -92,6 +92,7 @@ class SettingsDialog : public QDialog {
Subsonic,
Tidal,
Qobuz,
Remote,
};
enum Role {

View File

@ -88,7 +88,7 @@ PlaylistItemPtrList PlaylistQueryGenerator::GenerateMore(const int count) {
current_pos_ += search_copy.limit_;
}
SongList songs = collection_backend_->SmartPlaylistsFindSongs(search_copy);
const SongList songs = collection_backend_->SmartPlaylistsFindSongs(search_copy);
PlaylistItemPtrList items;
items.reserve(songs.count());
for (const Song &song : songs) {

View File

@ -21,6 +21,8 @@
#include "config.h"
#include <utility>
#include <QAbstractListModel>
#include <QVariant>
#include <QStringList>
@ -136,7 +138,7 @@ void SmartPlaylistsModel::Init() {
// Append the new ones
s.beginWriteArray(collection_backend_->songs_table(), playlist_index + unwritten_defaults);
for (; version < default_smart_playlists_.count(); ++version) {
for (PlaylistGeneratorPtr gen : default_smart_playlists_[version]) { // clazy:exclude=range-loop-reference
for (PlaylistGeneratorPtr gen : std::as_const(default_smart_playlists_[version])) {
SaveGenerator(&s, playlist_index++, gen);
}
}
@ -231,7 +233,8 @@ void SmartPlaylistsModel::DeleteGenerator(const QModelIndex &idx) {
// Rewrite all the items to the settings
s.beginWriteArray(collection_backend_->songs_table(), static_cast<int>(root_->children.count()));
int i = 0;
for (SmartPlaylistsItem *item : root_->children) {
const QList<SmartPlaylistsItem*> children = root_->children;
for (SmartPlaylistsItem *item : children) {
s.setArrayIndex(i++);
s.setValue("name", item->display_text);
s.setValue("type", static_cast<int>(item->smart_playlist_type));

View File

@ -22,6 +22,7 @@
#include "config.h"
#include <algorithm>
#include <utility>
#include <QtGlobal>
#include <QWidget>
@ -106,7 +107,7 @@ TranscodeDialog::TranscodeDialog(QMainWindow *mainwindow, QWidget *parent)
// Get presets
QList<TranscoderPreset> presets = Transcoder::GetAllPresets();
std::sort(presets.begin(), presets.end(), ComparePresetsByName);
for (const TranscoderPreset &preset : presets) {
for (const TranscoderPreset &preset : std::as_const(presets)) {
ui_->format->addItem(QStringLiteral("%1 (.%2)").arg(preset.name_, preset.extension_), QVariant::fromValue(preset));
}
@ -289,7 +290,7 @@ void TranscodeDialog::UpdateProgress() {
int progress = (finished_success_ + finished_failed_) * 100;
QMap<QString, float> current_jobs = transcoder_->GetProgress();
QList<float> values = current_jobs.values();
const QList<float> values = current_jobs.values();
for (const float value : values) {
progress += qBound(0, static_cast<int>(value * 100), 99);
}

View File

@ -279,11 +279,7 @@ Song::FileType Transcoder::PickBestFormat(const QList<Song::FileType> &supported
if (supported.isEmpty()) return Song::FileType::Unknown;
QList<Song::FileType> best_formats;
best_formats << Song::FileType::FLAC;
best_formats << Song::FileType::OggFlac;
best_formats << Song::FileType::WavPack;
const QList<Song::FileType> best_formats = QList<Song::FileType>() << Song::FileType::FLAC << Song::FileType::OggFlac << Song::FileType::WavPack;
for (Song::FileType type : best_formats) {
if (supported.contains(type)) return type;
}

Some files were not shown because too many files have changed in this diff Show More