Compare commits
40 Commits
8325cf1285
...
05dfd20c88
Author | SHA1 | Date |
---|---|---|
Robert Gingras | 05dfd20c88 | |
Robert Gingras | 20f01c3f8d | |
Robert Gingras | 5db117e129 | |
Robert Gingras | 357d4ce035 | |
Robert Gingras | a368759907 | |
Robert Gingras | b6f0521802 | |
Robert Gingras | 0bf6d4a73d | |
Robert Gingras | 2681b197d2 | |
Jonas Kvinge | 542efa17ff | |
Jonas Kvinge | 6a2c2dbba1 | |
Jonas Kvinge | 426de61525 | |
Jonas Kvinge | 24c8d06d41 | |
Jonas Kvinge | 227f5e5176 | |
Jonas Kvinge | 92e39a3e21 | |
Jonas Kvinge | fb2300e2fa | |
Jonas Kvinge | 78becae5e9 | |
Jonas Kvinge | d10eb4370e | |
Jonas Kvinge | 9c92ef941f | |
Jonas Kvinge | 7aefe3d71b | |
Jonas Kvinge | 398db964b8 | |
Jonas Kvinge | 579349b104 | |
Jonas Kvinge | 5f9a83871d | |
Jonas Kvinge | da0c5e67c5 | |
Jonas Kvinge | a0cfde18c3 | |
Jonas Kvinge | 0ad4889936 | |
Jonas Kvinge | 36e809d530 | |
Jonas Kvinge | 78096658e2 | |
Jonas Kvinge | 3edd218e3a | |
Jonas Kvinge | 569bf6335b | |
Jonas Kvinge | 7b8919d706 | |
Jonas Kvinge | 147fd87d8c | |
Jonas Kvinge | ac0926d40b | |
Jonas Kvinge | 105d472f5d | |
Jonas Kvinge | c1a49da385 | |
Jonas Kvinge | c3f596e64e | |
Jonas Kvinge | adfda84c41 | |
Jonas Kvinge | 345cc118a3 | |
Jonas Kvinge | df070ac0cf | |
Jonas Kvinge | 7b88be2635 | |
Kientz Arnaud | c30a39d29a |
|
@ -15,11 +15,14 @@ jobs:
|
|||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
opensuse_version: [ 'tumbleweed', 'leap:15.6' ]
|
||||
opensuse_version: [ 'tumbleweed', 'leap:15.5', 'leap:15.6' ]
|
||||
qt_version: [ '5', '6' ]
|
||||
container:
|
||||
image: opensuse/${{matrix.opensuse_version}}
|
||||
steps:
|
||||
- name: Add devel tools building repo
|
||||
if: matrix.opensuse_version != 'tumbleweed'
|
||||
run: zypper -n ar -c -f -n 'devel-tools-building' https://download.opensuse.org/repositories/devel:tools:building/$(echo "${{matrix.opensuse_version}}" | cut -d ':' -f 2)/ devel-tools-building
|
||||
- name: Add tagparser repo
|
||||
if: matrix.opensuse_version == 'tumbleweed'
|
||||
run: zypper -n ar -c -f -n 'repo-tagparser' https://download.opensuse.org/repositories/home:/mkittler/openSUSE_Tumbleweed/ repo-tagparser
|
||||
|
@ -368,8 +371,14 @@ jobs:
|
|||
container:
|
||||
image: mageia:${{matrix.mageia_version}}
|
||||
steps:
|
||||
- name: Set media
|
||||
run: |
|
||||
urpmi.removemedia "Core Release"
|
||||
urpmi.removemedia "Core Updates"
|
||||
urpmi.addmedia "Core Release" "https://mirrors.kernel.org/mageia/distrib/${{matrix.mageia_version}}/x86_64/media/core/release/"
|
||||
urpmi.addmedia "Core Updates" "https://mirrors.kernel.org/mageia/distrib/${{matrix.mageia_version}}/x86_64/media/core/updates/"
|
||||
- name: Update repositories
|
||||
run: urpmi.update --auto -a
|
||||
run: urpmi.update -a
|
||||
- name: Upgrade packages
|
||||
run: urpmi --auto --auto-update
|
||||
- name: Install dependencies
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
:strawberry: Strawberry Music Player [![Build Status](https://github.com/strawberrymusicplayer/strawberry/workflows/build/badge.svg)](https://github.com/strawberrymusicplayer/strawberry/actions)
|
||||
:strawberry: Strawberry Music Player [![Build Status](https://github.com/strawberrymusicplayer/strawberry/workflows/Build/badge.svg)](https://github.com/strawberrymusicplayer/strawberry/actions)
|
||||
=======================
|
||||
[![Sponsor](https://img.shields.io/badge/-Sponsor-green?logo=github)](https://github.com/sponsors/jonaski)
|
||||
[![Patreon](https://img.shields.io/badge/patreon-donate-green.svg)](https://patreon.com/jonaskvinge)
|
||||
|
|
|
@ -497,7 +497,7 @@ Section "Strawberry" Strawberry
|
|||
|
||||
; Common files
|
||||
|
||||
File "icudt74.dll"
|
||||
File "icudt75.dll"
|
||||
File "libfftw3-3.dll"
|
||||
!ifdef debug
|
||||
File "libprotobufd.dll"
|
||||
|
@ -505,8 +505,8 @@ Section "Strawberry" Strawberry
|
|||
File "libprotobuf.dll"
|
||||
!endif
|
||||
!ifdef msvc && debug
|
||||
File "icuin74d.dll"
|
||||
File "icuuc74d.dll"
|
||||
File "icuin75d.dll"
|
||||
File "icuuc75d.dll"
|
||||
File "Qt6Concurrentd.dll"
|
||||
File "Qt6Cored.dll"
|
||||
File "Qt6Guid.dll"
|
||||
|
@ -514,8 +514,8 @@ Section "Strawberry" Strawberry
|
|||
File "Qt6Sqld.dll"
|
||||
File "Qt6Widgetsd.dll"
|
||||
!else
|
||||
File "icuin74.dll"
|
||||
File "icuuc74.dll"
|
||||
File "icuin75.dll"
|
||||
File "icuuc75.dll"
|
||||
File "Qt6Concurrent.dll"
|
||||
File "Qt6Core.dll"
|
||||
File "Qt6Gui.dll"
|
||||
|
@ -1065,7 +1065,7 @@ Section "Uninstall"
|
|||
|
||||
; Common files
|
||||
|
||||
Delete "$INSTDIR\icudt74.dll"
|
||||
Delete "$INSTDIR\icudt75.dll"
|
||||
Delete "$INSTDIR\libfftw3-3.dll"
|
||||
!ifdef debug
|
||||
Delete "$INSTDIR\libprotobufd.dll"
|
||||
|
@ -1073,8 +1073,8 @@ Section "Uninstall"
|
|||
Delete "$INSTDIR\libprotobuf.dll"
|
||||
!endif
|
||||
!ifdef msvc && debug
|
||||
Delete "$INSTDIR\icuin74d.dll"
|
||||
Delete "$INSTDIR\icuuc74d.dll"
|
||||
Delete "$INSTDIR\icuin75d.dll"
|
||||
Delete "$INSTDIR\icuuc75d.dll"
|
||||
Delete "$INSTDIR\Qt6Concurrentd.dll"
|
||||
Delete "$INSTDIR\Qt6Cored.dll"
|
||||
Delete "$INSTDIR\Qt6Guid.dll"
|
||||
|
@ -1082,8 +1082,8 @@ Section "Uninstall"
|
|||
Delete "$INSTDIR\Qt6Sqld.dll"
|
||||
Delete "$INSTDIR\Qt6Widgetsd.dll"
|
||||
!else
|
||||
Delete "$INSTDIR\icuin74.dll"
|
||||
Delete "$INSTDIR\icuuc74.dll"
|
||||
Delete "$INSTDIR\icuin75.dll"
|
||||
Delete "$INSTDIR\icuuc75.dll"
|
||||
Delete "$INSTDIR\Qt6Concurrent.dll"
|
||||
Delete "$INSTDIR\Qt6Core.dll"
|
||||
Delete "$INSTDIR\Qt6Gui.dll"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -62,7 +62,7 @@ bool TagReaderWorker::HandleMessage(const spb::tagreader::Message &message, spb:
|
|||
return success;
|
||||
}
|
||||
else if (message.has_read_file_request()) {
|
||||
const QString filename = QString::fromUtf8(message.read_file_request().filename().data(), static_cast<qint64>(static_cast<qint64>(message.read_file_request().filename().size())));
|
||||
const QString filename = QString::fromUtf8(message.read_file_request().filename().data(), static_cast<qint64>(message.read_file_request().filename().size()));
|
||||
bool success = reader->ReadFile(filename, reply.mutable_read_file_response()->mutable_metadata());
|
||||
return success;
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ bool TagReaderWorker::HandleMessage(const spb::tagreader::Message &message, spb:
|
|||
return success;
|
||||
}
|
||||
else if (message.has_load_embedded_art_request()) {
|
||||
const QString filename = QString::fromUtf8(message.load_embedded_art_request().filename().data(), static_cast<qint64>(static_cast<qint64>(message.load_embedded_art_request().filename().size())));
|
||||
const QString filename = QString::fromUtf8(message.load_embedded_art_request().filename().data(), static_cast<qint64>(message.load_embedded_art_request().filename().size()));
|
||||
QByteArray data = reader->LoadEmbeddedArt(filename);
|
||||
reply.mutable_load_embedded_art_response()->set_data(data.constData(), data.size());
|
||||
return true;
|
||||
|
@ -83,7 +83,7 @@ bool TagReaderWorker::HandleMessage(const spb::tagreader::Message &message, spb:
|
|||
return success;
|
||||
}
|
||||
else if (message.has_save_song_playcount_to_file_request()) {
|
||||
const QString filename = QString::fromUtf8(message.save_song_playcount_to_file_request().filename().data(), static_cast<qint64>(static_cast<qint64>(message.save_song_playcount_to_file_request().filename().size())));
|
||||
const QString filename = QString::fromUtf8(message.save_song_playcount_to_file_request().filename().data(), static_cast<qint64>(message.save_song_playcount_to_file_request().filename().size()));
|
||||
bool success = reader->SaveSongPlaycountToFile(filename, message.save_song_playcount_to_file_request().metadata());
|
||||
reply.mutable_save_song_playcount_to_file_response()->set_success(success);
|
||||
return success;
|
||||
|
|
|
@ -490,6 +490,7 @@ set(HEADERS
|
|||
widgets/qsearchfield.h
|
||||
widgets/ratingwidget.h
|
||||
widgets/forcescrollperpixel.h
|
||||
widgets/resizabletextedit.h
|
||||
|
||||
osd/osdbase.h
|
||||
osd/osdpretty.h
|
||||
|
|
|
@ -266,12 +266,12 @@ QColor ensureContrast(const QColor &bg, const QColor &fg, int amount) {
|
|||
|
||||
// value is the best measure of contrast
|
||||
// if there is enough difference in value already, return fg unchanged
|
||||
if (dv > static_cast<int>(amount)) return fg;
|
||||
if (dv > amount) return fg;
|
||||
|
||||
int ds = abs(bs - fs);
|
||||
|
||||
// saturation is good enough too. But not as good. TODO adapt this a little
|
||||
if (ds > static_cast<int>(amount)) return fg;
|
||||
if (ds > amount) return fg;
|
||||
|
||||
int dh = abs(bh - fh);
|
||||
|
||||
|
@ -294,7 +294,7 @@ QColor ensureContrast(const QColor &bg, const QColor &fg, int amount) {
|
|||
// low saturation on a low saturation is sad
|
||||
const int tmp = 50 - fs;
|
||||
fs = 50;
|
||||
if (static_cast<int>(amount) > tmp) {
|
||||
if (amount > tmp) {
|
||||
amount -= tmp;
|
||||
}
|
||||
else {
|
||||
|
@ -310,25 +310,25 @@ QColor ensureContrast(const QColor &bg, const QColor &fg, int amount) {
|
|||
if (amount > 0) adjustToLimits(bs, fs, amount);
|
||||
|
||||
// see if we need to adjust the hue
|
||||
if (static_cast<int>(amount) > 0)
|
||||
fh += static_cast<int>(amount); // cycles around;
|
||||
if (amount > 0)
|
||||
fh += amount; // cycles around;
|
||||
|
||||
return QColor::fromHsv(fh, fs, fv);
|
||||
}
|
||||
|
||||
if (fv > bv && bv > static_cast<int>(amount)) {
|
||||
return QColor::fromHsv(fh, fs, bv - static_cast<int>(amount));
|
||||
if (fv > bv && bv > amount) {
|
||||
return QColor::fromHsv(fh, fs, bv - amount);
|
||||
}
|
||||
|
||||
if (fv < bv && fv > static_cast<int>(amount)) {
|
||||
if (fv < bv && fv > amount) {
|
||||
return QColor::fromHsv(fh, fs, fv - amount);
|
||||
}
|
||||
|
||||
if (fv > bv && (255 - fv > static_cast<int>(amount))) {
|
||||
if (fv > bv && (255 - fv > amount)) {
|
||||
return QColor::fromHsv(fh, fs, fv + amount);
|
||||
}
|
||||
|
||||
if (fv < bv && (255 - bv > static_cast<int>(amount))) {
|
||||
if (fv < bv && (255 - bv > amount)) {
|
||||
return QColor::fromHsv(fh, fs, bv + amount);
|
||||
}
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ void BoomAnalyzer::resizeEvent(QResizeEvent *e) {
|
|||
bands_ = qMin(static_cast<int>(static_cast<double>(width() + 1) / (kColumnWidth + 1)) + 1, kMaxBandCount);
|
||||
scope_.resize(bands_);
|
||||
|
||||
F_ = static_cast<double>(HEIGHT) / (log10(256) * static_cast<double>(1.1) /*<- max. amplitude*/);
|
||||
F_ = static_cast<double>(HEIGHT) / (log10(256) * 1.1 /*<- max. amplitude*/);
|
||||
|
||||
barPixmap_ = QPixmap(kColumnWidth - 2, HEIGHT);
|
||||
canvas_ = QPixmap(size());
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include <QVector>
|
||||
#include <QtMath>
|
||||
|
||||
FHT::FHT(uint n) : num_((n < 3) ? 0 : 1 << n), exp2_((n < 3) ? static_cast<int>(-1) : static_cast<int>(n)) {
|
||||
FHT::FHT(uint n) : num_((n < 3) ? 0 : 1 << n), exp2_((n < 3) ? -1 : static_cast<int>(n)) {
|
||||
|
||||
if (n > 3) {
|
||||
buf_vector_.resize(num_);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Strawberry Music Player
|
||||
* This file was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
* Copyright 2018-2023, Jonas Kvinge <jonas@jkvinge.net>
|
||||
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -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());
|
||||
|
@ -401,7 +402,7 @@ SongList CollectionBackend::FindSongsInDirectory(const int id) {
|
|||
QSqlDatabase db(db_->Connect());
|
||||
|
||||
SqlQuery q(db);
|
||||
q.prepare(QStringLiteral("SELECT ROWID, %1 FROM %2 WHERE directory_id = :directory_id").arg(Song::kColumnSpec, songs_table_));
|
||||
q.prepare(QStringLiteral("SELECT %1 FROM %2 WHERE directory_id = :directory_id").arg(Song::kRowIdColumnSpec, songs_table_));
|
||||
q.BindValue(QStringLiteral(":directory_id"), id);
|
||||
if (!q.Exec()) {
|
||||
db_->ReportErrors(q);
|
||||
|
@ -424,7 +425,7 @@ SongList CollectionBackend::SongsWithMissingFingerprint(const int id) {
|
|||
QSqlDatabase db(db_->Connect());
|
||||
|
||||
SqlQuery q(db);
|
||||
q.prepare(QStringLiteral("SELECT ROWID, %1 FROM %2 WHERE directory_id = :directory_id AND unavailable = 0 AND (fingerprint IS NULL OR fingerprint = '')").arg(Song::kColumnSpec, songs_table_));
|
||||
q.prepare(QStringLiteral("SELECT %1 FROM %2 WHERE directory_id = :directory_id AND unavailable = 0 AND (fingerprint IS NULL OR fingerprint = '')").arg(Song::kRowIdColumnSpec, songs_table_));
|
||||
q.BindValue(QStringLiteral(":directory_id"), id);
|
||||
if (!q.Exec()) {
|
||||
db_->ReportErrors(q);
|
||||
|
@ -447,7 +448,7 @@ SongList CollectionBackend::SongsWithMissingLoudnessCharacteristics(const int id
|
|||
QSqlDatabase db(db_->Connect());
|
||||
|
||||
SqlQuery q(db);
|
||||
q.prepare(QStringLiteral("SELECT ROWID, %1 FROM %2 WHERE directory_id = :directory_id AND unavailable = 0 AND (ebur128_integrated_loudness_lufs IS NULL OR ebur128_loudness_range_lu IS NULL)").arg(Song::kColumnSpec, songs_table_));
|
||||
q.prepare(QStringLiteral("SELECT %1 FROM %2 WHERE directory_id = :directory_id AND unavailable = 0 AND (ebur128_integrated_loudness_lufs IS NULL OR ebur128_loudness_range_lu IS NULL)").arg(Song::kRowIdColumnSpec, songs_table_));
|
||||
q.BindValue(QStringLiteral(":directory_id"), id);
|
||||
if (!q.Exec()) {
|
||||
db_->ReportErrors(q);
|
||||
|
@ -548,7 +549,7 @@ SongList CollectionBackend::GetAllSongs() {
|
|||
QSqlDatabase db(db_->Connect());
|
||||
|
||||
SqlQuery q(db);
|
||||
q.prepare(QStringLiteral("SELECT ROWID, %1 FROM %2").arg(Song::kColumnSpec, songs_table_));
|
||||
q.prepare(QStringLiteral("SELECT %1 FROM %2").arg(Song::kRowIdColumnSpec, songs_table_));
|
||||
if (!q.Exec()) {
|
||||
db_->ReportErrors(q);
|
||||
return SongList();
|
||||
|
@ -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())) {
|
||||
{
|
||||
|
@ -1164,7 +1165,7 @@ SongList CollectionBackend::GetSongsById(const QStringList &ids, QSqlDatabase &d
|
|||
QString in = ids.join(QStringLiteral(","));
|
||||
|
||||
SqlQuery q(db);
|
||||
q.prepare(QStringLiteral("SELECT ROWID, %1 FROM %2 WHERE ROWID IN (%3)").arg(Song::kColumnSpec, songs_table_, in));
|
||||
q.prepare(QStringLiteral("SELECT %1 FROM %2 WHERE ROWID IN (%3)").arg(Song::kRowIdColumnSpec, songs_table_, in));
|
||||
if (!q.Exec()) {
|
||||
db_->ReportErrors(q);
|
||||
return SongList();
|
||||
|
@ -1186,7 +1187,7 @@ Song CollectionBackend::GetSongByUrl(const QUrl &url, const qint64 beginning) {
|
|||
QSqlDatabase db(db_->Connect());
|
||||
|
||||
SqlQuery q(db);
|
||||
q.prepare(QStringLiteral("SELECT ROWID, %1 FROM %2 WHERE (url = :url1 OR url = :url2 OR url = :url3 OR url = :url4) AND beginning = :beginning AND unavailable = 0").arg(Song::kColumnSpec, songs_table_));
|
||||
q.prepare(QStringLiteral("SELECT %1 FROM %2 WHERE (url = :url1 OR url = :url2 OR url = :url3 OR url = :url4) AND beginning = :beginning AND unavailable = 0").arg(Song::kRowIdColumnSpec, songs_table_));
|
||||
|
||||
q.BindValue(QStringLiteral(":url1"), url);
|
||||
q.BindValue(QStringLiteral(":url2"), url.toString());
|
||||
|
@ -1216,7 +1217,7 @@ Song CollectionBackend::GetSongByUrlAndTrack(const QUrl &url, const int track) {
|
|||
QSqlDatabase db(db_->Connect());
|
||||
|
||||
SqlQuery q(db);
|
||||
q.prepare(QStringLiteral("SELECT ROWID, %1 FROM %2 WHERE (url = :url1 OR url = :url2 OR url = :url3 OR url = :url4) AND track = :track AND unavailable = 0").arg(Song::kColumnSpec, songs_table_));
|
||||
q.prepare(QStringLiteral("SELECT %1 FROM %2 WHERE (url = :url1 OR url = :url2 OR url = :url3 OR url = :url4) AND track = :track AND unavailable = 0").arg(Song::kRowIdColumnSpec, songs_table_));
|
||||
|
||||
q.BindValue(QStringLiteral(":url1"), url);
|
||||
q.BindValue(QStringLiteral(":url2"), url.toString());
|
||||
|
@ -1246,7 +1247,7 @@ SongList CollectionBackend::GetSongsByUrl(const QUrl &url, const bool unavailabl
|
|||
QSqlDatabase db(db_->Connect());
|
||||
|
||||
SqlQuery q(db);
|
||||
q.prepare(QStringLiteral("SELECT ROWID, %1 FROM %2 WHERE (url = :url1 OR url = :url2 OR url = :url3 OR url = :url4) AND unavailable = :unavailable").arg(Song::kColumnSpec, songs_table_));
|
||||
q.prepare(QStringLiteral("SELECT %1 FROM %2 WHERE (url = :url1 OR url = :url2 OR url = :url3 OR url = :url4) AND unavailable = :unavailable").arg(Song::kRowIdColumnSpec, songs_table_));
|
||||
|
||||
q.BindValue(QStringLiteral(":url1"), url);
|
||||
q.BindValue(QStringLiteral(":url2"), url.toString());
|
||||
|
@ -1306,7 +1307,7 @@ SongList CollectionBackend::GetSongsBySongId(const QStringList &song_ids, QSqlDa
|
|||
QString in = song_ids2.join(QLatin1Char(','));
|
||||
|
||||
SqlQuery q(db);
|
||||
q.prepare(QStringLiteral("SELECT ROWID, %1 FROM %2 WHERE SONG_ID IN (%3)").arg(Song::kColumnSpec, songs_table_, in));
|
||||
q.prepare(QStringLiteral("SELECT %1 FROM %2 WHERE SONG_ID IN (%3)").arg(Song::kRowIdColumnSpec, songs_table_, in));
|
||||
if (!q.Exec()) {
|
||||
db_->ReportErrors(q);
|
||||
return SongList();
|
||||
|
@ -1329,7 +1330,7 @@ SongList CollectionBackend::GetSongsByFingerprint(const QString &fingerprint) {
|
|||
QSqlDatabase db(db_->Connect());
|
||||
|
||||
SqlQuery q(db);
|
||||
q.prepare(QStringLiteral("SELECT ROWID, %1 FROM %2 WHERE fingerprint = :fingerprint").arg(Song::kColumnSpec, songs_table_));
|
||||
q.prepare(QStringLiteral("SELECT %1 FROM %2 WHERE fingerprint = :fingerprint").arg(Song::kRowIdColumnSpec, songs_table_));
|
||||
q.BindValue(QStringLiteral(":fingerprint"), fingerprint);
|
||||
if (!q.Exec()) {
|
||||
db_->ReportErrors(q);
|
||||
|
@ -1452,7 +1453,7 @@ bool CollectionBackend::UpdateCompilations(const QSqlDatabase &db, SongList &del
|
|||
|
||||
{ // Get song, so we can tell the model its updated
|
||||
SqlQuery q(db);
|
||||
q.prepare(QStringLiteral("SELECT ROWID, %1 FROM %2 WHERE (url = :url1 OR url = :url2 OR url = :url3 OR url = :url4) AND unavailable = 0").arg(Song::kColumnSpec, songs_table_));
|
||||
q.prepare(QStringLiteral("SELECT %1 FROM %2 WHERE (url = :url1 OR url = :url2 OR url = :url3 OR url = :url4) AND unavailable = 0").arg(Song::kRowIdColumnSpec, songs_table_));
|
||||
q.BindValue(QStringLiteral(":url1"), url);
|
||||
q.BindValue(QStringLiteral(":url2"), url.toString());
|
||||
q.BindValue(QStringLiteral(":url3"), url.toString(QUrl::FullyEncoded));
|
||||
|
@ -1622,7 +1623,7 @@ void CollectionBackend::UpdateEmbeddedAlbumArt(const QString &effective_albumart
|
|||
|
||||
// Get the songs before they're updated
|
||||
CollectionQuery query(db, songs_table_, fts_table_);
|
||||
query.SetColumnSpec(QStringLiteral("ROWID, ") + Song::kColumnSpec);
|
||||
query.SetColumnSpec(Song::kRowIdColumnSpec);
|
||||
query.AddWhere(QStringLiteral("effective_albumartist"), effective_albumartist);
|
||||
query.AddWhere(QStringLiteral("album"), album);
|
||||
|
||||
|
@ -1684,7 +1685,7 @@ void CollectionBackend::UpdateManualAlbumArt(const QString &effective_albumartis
|
|||
QSqlDatabase db(db_->Connect());
|
||||
|
||||
CollectionQuery query(db, songs_table_, fts_table_);
|
||||
query.SetColumnSpec(QStringLiteral("ROWID, ") + Song::kColumnSpec);
|
||||
query.SetColumnSpec(Song::kRowIdColumnSpec);
|
||||
query.AddWhere(QStringLiteral("effective_albumartist"), effective_albumartist);
|
||||
query.AddWhere(QStringLiteral("album"), album);
|
||||
|
||||
|
@ -1742,7 +1743,7 @@ void CollectionBackend::UnsetAlbumArt(const QString &effective_albumartist, cons
|
|||
QSqlDatabase db(db_->Connect());
|
||||
|
||||
CollectionQuery query(db, songs_table_, fts_table_);
|
||||
query.SetColumnSpec(QStringLiteral("ROWID, ") + Song::kColumnSpec);
|
||||
query.SetColumnSpec(Song::kRowIdColumnSpec);
|
||||
query.AddWhere(QStringLiteral("effective_albumartist"), effective_albumartist);
|
||||
query.AddWhere(QStringLiteral("album"), album);
|
||||
|
||||
|
@ -1799,7 +1800,7 @@ void CollectionBackend::ClearAlbumArt(const QString &effective_albumartist, cons
|
|||
QSqlDatabase db(db_->Connect());
|
||||
|
||||
CollectionQuery query(db, songs_table_, fts_table_);
|
||||
query.SetColumnSpec(QStringLiteral("ROWID, ") + Song::kColumnSpec);
|
||||
query.SetColumnSpec(Song::kRowIdColumnSpec);
|
||||
query.AddWhere(QStringLiteral("effective_albumartist"), effective_albumartist);
|
||||
query.AddWhere(QStringLiteral("album"), album);
|
||||
|
||||
|
@ -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());
|
||||
|
@ -1854,7 +1855,7 @@ void CollectionBackend::ForceCompilation(const QString &album, const QList<QStri
|
|||
for (const QString &artist : artists) {
|
||||
// Get the songs before they're updated
|
||||
CollectionQuery query(db, songs_table_, fts_table_);
|
||||
query.SetColumnSpec(QStringLiteral("ROWID, ") + Song::kColumnSpec);
|
||||
query.SetColumnSpec(Song::kRowIdColumnSpec);
|
||||
query.AddWhere(QStringLiteral("album"), album);
|
||||
if (!artist.isEmpty()) query.AddWhere(QStringLiteral("artist"), artist);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -2073,10 +2074,10 @@ SongList CollectionBackend::GetSongsBy(const QString &artist, const QString &alb
|
|||
SongList songs;
|
||||
SqlQuery q(db);
|
||||
if (album.isEmpty()) {
|
||||
q.prepare(QStringLiteral("SELECT ROWID, %1 FROM %2 WHERE artist = :artist COLLATE NOCASE AND title = :title COLLATE NOCASE").arg(Song::kColumnSpec, songs_table_));
|
||||
q.prepare(QStringLiteral("SELECT %1 FROM %2 WHERE artist = :artist COLLATE NOCASE AND title = :title COLLATE NOCASE").arg(Song::kRowIdColumnSpec, songs_table_));
|
||||
}
|
||||
else {
|
||||
q.prepare(QStringLiteral("SELECT ROWID, %1 FROM %2 WHERE artist = :artist COLLATE NOCASE AND album = :album COLLATE NOCASE AND title = :title COLLATE NOCASE").arg(Song::kColumnSpec, songs_table_));
|
||||
q.prepare(QStringLiteral("SELECT %1 FROM %2 WHERE artist = :artist COLLATE NOCASE AND album = :album COLLATE NOCASE AND title = :title COLLATE NOCASE").arg(Song::kRowIdColumnSpec, songs_table_));
|
||||
}
|
||||
q.BindValue(QStringLiteral(":artist"), artist);
|
||||
if (!album.isEmpty()) q.BindValue(QStringLiteral(":album"), album);
|
||||
|
@ -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);
|
||||
|
@ -2220,9 +2221,9 @@ void CollectionBackend::ExpireSongs(const int directory_id, const int expire_una
|
|||
QMutexLocker l(db_->Mutex());
|
||||
QSqlDatabase db(db_->Connect());
|
||||
SqlQuery q(db);
|
||||
q.prepare(QStringLiteral("SELECT %1.ROWID, ").arg(songs_table_) + Song::JoinSpec(songs_table_) + QStringLiteral(" FROM %1 LEFT JOIN playlist_items ON %1.ROWID = playlist_items.collection_id WHERE %1.directory_id = :directory_id AND %1.unavailable = 1 AND %1.lastseen > 0 AND %1.lastseen < :time AND playlist_items.collection_id IS NULL").arg(songs_table_));
|
||||
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;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Strawberry Music Player
|
||||
* This file was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
* Copyright 2018-2023, Jonas Kvinge <jonas@jkvinge.net>
|
||||
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Strawberry Music Player
|
||||
* This file was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
* Copyright 2018-2023, Jonas Kvinge <jonas@jkvinge.net>
|
||||
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -1291,7 +1291,7 @@ CollectionItem *CollectionModel::ItemFromQuery(const GroupBy group_by, const boo
|
|||
case GroupBy::Album:{
|
||||
item->metadata.set_album(row.value(0).toString());
|
||||
item->metadata.set_album_id(row.value(1).toString());
|
||||
item->metadata.set_grouping(row.value(2).toString());
|
||||
if (separate_albums_by_grouping) item->metadata.set_grouping(row.value(2).toString());
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, item->metadata));
|
||||
item->display_text = TextOrUnknown(item->metadata.album());
|
||||
item->sort_text = SortTextForArtist(item->metadata.album(), sort_skips_articles_);
|
||||
|
@ -1301,7 +1301,7 @@ CollectionItem *CollectionModel::ItemFromQuery(const GroupBy group_by, const boo
|
|||
item->metadata.set_album(row.value(0).toString());
|
||||
item->metadata.set_album_id(row.value(1).toString());
|
||||
item->metadata.set_disc(row.value(2).toInt());
|
||||
item->metadata.set_grouping(row.value(3).toString());
|
||||
if (separate_albums_by_grouping) item->metadata.set_grouping(row.value(3).toString());
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, item->metadata));
|
||||
item->display_text = PrettyAlbumDisc(item->metadata.album(), item->metadata.disc());
|
||||
item->sort_text = item->metadata.album() + SortTextForNumber(std::max(0, item->metadata.disc()));
|
||||
|
@ -1311,7 +1311,7 @@ CollectionItem *CollectionModel::ItemFromQuery(const GroupBy group_by, const boo
|
|||
item->metadata.set_year(row.value(0).toInt());
|
||||
item->metadata.set_album(row.value(1).toString());
|
||||
item->metadata.set_album_id(row.value(2).toString());
|
||||
item->metadata.set_grouping(row.value(3).toString());
|
||||
if (separate_albums_by_grouping) item->metadata.set_grouping(row.value(3).toString());
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, item->metadata));
|
||||
item->display_text = PrettyYearAlbum(item->metadata.year(), item->metadata.album());
|
||||
item->sort_text = SortTextForNumber(std::max(0, item->metadata.year())) + item->metadata.grouping() + item->metadata.album();
|
||||
|
@ -1322,7 +1322,7 @@ CollectionItem *CollectionModel::ItemFromQuery(const GroupBy group_by, const boo
|
|||
item->metadata.set_album(row.value(1).toString());
|
||||
item->metadata.set_album_id(row.value(2).toString());
|
||||
item->metadata.set_disc(row.value(3).toInt());
|
||||
item->metadata.set_grouping(row.value(4).toString());
|
||||
if (separate_albums_by_grouping) item->metadata.set_grouping(row.value(4).toString());
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, item->metadata));
|
||||
item->display_text = PrettyYearAlbumDisc(item->metadata.year(), item->metadata.album(), item->metadata.disc());
|
||||
item->sort_text = SortTextForNumber(std::max(0, item->metadata.year())) + item->metadata.album() + SortTextForNumber(std::max(0, item->metadata.disc()));
|
||||
|
@ -1333,7 +1333,7 @@ CollectionItem *CollectionModel::ItemFromQuery(const GroupBy group_by, const boo
|
|||
item->metadata.set_originalyear(row.value(1).toInt());
|
||||
item->metadata.set_album(row.value(2).toString());
|
||||
item->metadata.set_album_id(row.value(3).toString());
|
||||
item->metadata.set_grouping(row.value(4).toString());
|
||||
if (separate_albums_by_grouping) item->metadata.set_grouping(row.value(4).toString());
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, item->metadata));
|
||||
item->display_text = PrettyYearAlbum(item->metadata.effective_originalyear(), item->metadata.album());
|
||||
item->sort_text = SortTextForNumber(std::max(0, item->metadata.effective_originalyear())) + item->metadata.grouping() + item->metadata.album();
|
||||
|
@ -1345,7 +1345,7 @@ CollectionItem *CollectionModel::ItemFromQuery(const GroupBy group_by, const boo
|
|||
item->metadata.set_album(row.value(2).toString());
|
||||
item->metadata.set_album_id(row.value(3).toString());
|
||||
item->metadata.set_disc(row.value(4).toInt());
|
||||
item->metadata.set_grouping(row.value(5).toString());
|
||||
if (separate_albums_by_grouping) item->metadata.set_grouping(row.value(5).toString());
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, item->metadata));
|
||||
item->display_text = PrettyYearAlbumDisc(item->metadata.effective_originalyear(), item->metadata.album(), item->metadata.disc());
|
||||
item->sort_text = SortTextForNumber(std::max(0, item->metadata.effective_originalyear())) + item->metadata.album() + SortTextForNumber(std::max(0, item->metadata.disc()));
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Strawberry Music Player
|
||||
* This file was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
* Copyright 2018-2023, Jonas Kvinge <jonas@jkvinge.net>
|
||||
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Strawberry Music Player
|
||||
* This file was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
* Copyright 2018-2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -30,8 +30,8 @@
|
|||
#include <QStringBuilder>
|
||||
#include <QRegularExpression>
|
||||
#include <QSqlDatabase>
|
||||
#include <QSqlQuery>
|
||||
|
||||
#include "core/sqlquery.h"
|
||||
#include "core/song.h"
|
||||
|
||||
#include "collectionquery.h"
|
||||
|
@ -39,7 +39,7 @@
|
|||
#include "utilities/searchparserutils.h"
|
||||
|
||||
CollectionQuery::CollectionQuery(const QSqlDatabase &db, const QString &songs_table, const QString &fts_table, const CollectionFilterOptions &filter_options)
|
||||
: QSqlQuery(db),
|
||||
: SqlQuery(db),
|
||||
songs_table_(songs_table),
|
||||
fts_table_(fts_table),
|
||||
include_unavailable_(false),
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Strawberry Music Player
|
||||
* This file was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
* Copyright 2018-2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -29,11 +29,12 @@
|
|||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QSqlDatabase>
|
||||
#include <QSqlQuery>
|
||||
|
||||
#include "core/sqlquery.h"
|
||||
|
||||
#include "collectionfilteroptions.h"
|
||||
|
||||
class CollectionQuery : public QSqlQuery {
|
||||
class CollectionQuery : public SqlQuery {
|
||||
public:
|
||||
explicit CollectionQuery(const QSqlDatabase &db, const QString &songs_table, const QString &fts_table, const CollectionFilterOptions &filter_options = CollectionFilterOptions());
|
||||
|
||||
|
@ -41,7 +42,7 @@ class CollectionQuery : public QSqlQuery {
|
|||
QVariant value(const int column) const { return Value(column); }
|
||||
|
||||
bool Exec();
|
||||
bool exec() { return QSqlQuery::exec(); }
|
||||
bool exec() { return SqlQuery::exec(); }
|
||||
|
||||
bool Next();
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <utility>
|
||||
#include <memory>
|
||||
|
||||
#include <QtGlobal>
|
||||
|
@ -89,6 +90,7 @@ CollectionView::CollectionView(QWidget *parent)
|
|||
action_add_to_playlist_enqueue_next_(nullptr),
|
||||
action_open_in_new_playlist_(nullptr),
|
||||
action_organize_(nullptr),
|
||||
action_search_for_this_(nullptr),
|
||||
#ifndef Q_OS_WIN
|
||||
action_copy_to_device_(nullptr),
|
||||
#endif
|
||||
|
@ -413,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;
|
||||
|
@ -484,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());
|
||||
}
|
||||
|
@ -494,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())) {
|
||||
|
@ -511,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);
|
||||
|
@ -762,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) {
|
||||
|
@ -787,7 +790,7 @@ void CollectionView::Delete() {
|
|||
|
||||
if (!delete_files_) return;
|
||||
|
||||
SongList selected_songs = GetSelectedSongs();
|
||||
const SongList selected_songs = GetSelectedSongs();
|
||||
|
||||
SongList songs;
|
||||
QStringList files;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -416,7 +416,7 @@ void CommandlineOptions::Load(const QByteArray &serialized) {
|
|||
}
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
QString CommandlineOptions::OptArgToString(wchar_t *opt) {
|
||||
QString CommandlineOptions::OptArgToString(const wchar_t *opt) {
|
||||
|
||||
return QString::fromWCharArray(opt);
|
||||
|
||||
|
@ -427,7 +427,7 @@ QString CommandlineOptions::DecodeName(wchar_t *opt) {
|
|||
return QString::fromWCharArray(opt);
|
||||
}
|
||||
#else
|
||||
QString CommandlineOptions::OptArgToString(char *opt) {
|
||||
QString CommandlineOptions::OptArgToString(const char *opt) {
|
||||
|
||||
return QString::fromUtf8(opt);
|
||||
}
|
||||
|
|
|
@ -108,10 +108,10 @@ class CommandlineOptions {
|
|||
void RemoveArg(const QString &starts_with, int count);
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
static QString OptArgToString(wchar_t *opt);
|
||||
static QString OptArgToString(const wchar_t *opt);
|
||||
static QString DecodeName(wchar_t *opt);
|
||||
#else
|
||||
static QString OptArgToString(char *opt);
|
||||
static QString OptArgToString(const char *opt);
|
||||
static QString DecodeName(char *opt);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -1727,7 +1727,7 @@ void MainWindow::Seeked(const qint64 microseconds) {
|
|||
|
||||
#ifdef HAVE_DBUS
|
||||
if (taskbar_progress_) {
|
||||
UpdateTaskbarProgress(true, position, length);
|
||||
UpdateTaskbarProgress(true, static_cast<double>(position) / static_cast<double>(length));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1747,7 +1747,7 @@ void MainWindow::UpdateTrackPosition() {
|
|||
|
||||
#ifdef HAVE_DBUS
|
||||
if (taskbar_progress_) {
|
||||
UpdateTaskbarProgress(true, position, length);
|
||||
UpdateTaskbarProgress(true, static_cast<double>(position) / static_cast<double>(length));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1778,13 +1778,13 @@ void MainWindow::UpdateTrackSliderPosition() {
|
|||
}
|
||||
|
||||
#ifdef HAVE_DBUS
|
||||
void MainWindow::UpdateTaskbarProgress(const bool visible, const double position, const double length) {
|
||||
void MainWindow::UpdateTaskbarProgress(const bool visible, const double progress) {
|
||||
|
||||
QVariantMap map;
|
||||
QDBusMessage msg = QDBusMessage::createSignal(QStringLiteral("/org/strawberrymusicplayer/strawberry"), QStringLiteral("com.canonical.Unity.LauncherEntry"), QStringLiteral("Update"));
|
||||
|
||||
map.insert(QStringLiteral("progress-visible"), visible);
|
||||
map.insert(QStringLiteral("progress"), position / length);
|
||||
map.insert(QStringLiteral("progress"), progress);
|
||||
msg << QStringLiteral("application://org.strawberrymusicplayer.strawberry.desktop") << map;
|
||||
|
||||
QDBusConnection::sessionBus().send(msg);
|
||||
|
|
|
@ -294,7 +294,7 @@ class MainWindow : public QMainWindow, public PlatformInterface {
|
|||
void SetToggleScrobblingIcon(const bool value);
|
||||
|
||||
#ifdef HAVE_DBUS
|
||||
void UpdateTaskbarProgress(const bool visible, const double position = 0, const double length = 0);
|
||||
void UpdateTaskbarProgress(const bool visible, const double progress = 0);
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Strawberry Music Player
|
||||
* This file was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
* Copyright 2018-2023, Jonas Kvinge <jonas@jkvinge.net>
|
||||
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -46,6 +46,7 @@
|
|||
#include <QUrl>
|
||||
#include <QIcon>
|
||||
#include <QStandardPaths>
|
||||
#include <QSqlRecord>
|
||||
|
||||
#include "core/iconloader.h"
|
||||
#include "engine/enginemetadata.h"
|
||||
|
@ -53,6 +54,7 @@
|
|||
#include "utilities/timeutils.h"
|
||||
#include "utilities/coverutils.h"
|
||||
#include "utilities/timeconstants.h"
|
||||
#include "utilities/sqlhelper.h"
|
||||
#include "song.h"
|
||||
#include "sqlquery.h"
|
||||
#include "sqlrow.h"
|
||||
|
@ -140,7 +142,10 @@ const QStringList Song::kColumns = QStringList() << QStringLiteral("title")
|
|||
|
||||
;
|
||||
|
||||
const QStringList Song::kRowIdColumns = QStringList() << QStringLiteral("ROWID") << kColumns;
|
||||
|
||||
const QString Song::kColumnSpec = Song::kColumns.join(QStringLiteral(", "));
|
||||
const QString Song::kRowIdColumnSpec = Song::kRowIdColumns.join(QStringLiteral(", "));
|
||||
const QString Song::kBindSpec = Utilities::Prepend(QStringLiteral(":"), Song::kColumns).join(QStringLiteral(", "));
|
||||
const QString Song::kUpdateSpec = Utilities::Updateify(Song::kColumns).join(QStringLiteral(", "));
|
||||
|
||||
|
@ -565,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;
|
||||
|
||||
}
|
||||
|
||||
|
@ -580,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;
|
||||
|
||||
}
|
||||
|
||||
|
@ -602,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;
|
||||
|
||||
}
|
||||
|
||||
|
@ -667,8 +675,14 @@ QString Song::sortable(const QString &v) {
|
|||
|
||||
}
|
||||
|
||||
int Song::ColumnIndex(const QString &field) {
|
||||
|
||||
return static_cast<int>(kRowIdColumns.indexOf(field));
|
||||
|
||||
}
|
||||
|
||||
QString Song::JoinSpec(const QString &table) {
|
||||
return Utilities::Prepend(table + QLatin1Char('.'), kColumns).join(QStringLiteral(", "));
|
||||
return Utilities::Prepend(table + QLatin1Char('.'), kRowIdColumns).join(QStringLiteral(", "));
|
||||
}
|
||||
|
||||
QString Song::PrettyTitle() const {
|
||||
|
@ -1364,78 +1378,80 @@ void Song::ToProtobuf(spb::tagreader::SongMetadata *pb) const {
|
|||
|
||||
}
|
||||
|
||||
void Song::InitFromQuery(const SqlRow &q, const bool reliable_metadata) {
|
||||
void Song::InitFromQuery(const QSqlRecord &r, const bool reliable_metadata, const int col) {
|
||||
|
||||
d->id_ = q.value(QStringLiteral("rowid")).isNull() ? -1 : q.value(QStringLiteral("rowid")).toInt();
|
||||
Q_ASSERT(kRowIdColumns.count() + col <= r.count());
|
||||
|
||||
set_title(q.ValueToString(QStringLiteral("title")));
|
||||
set_album(q.ValueToString(QStringLiteral("album")));
|
||||
set_artist(q.ValueToString(QStringLiteral("artist")));
|
||||
set_albumartist(q.ValueToString(QStringLiteral("albumartist")));
|
||||
d->track_ = q.ValueToInt(QStringLiteral("track"));
|
||||
d->disc_ = q.ValueToInt(QStringLiteral("disc"));
|
||||
d->year_ = q.ValueToInt(QStringLiteral("year"));
|
||||
d->originalyear_ = q.ValueToInt(QStringLiteral("originalyear"));
|
||||
d->genre_ = q.ValueToString(QStringLiteral("genre"));
|
||||
d->compilation_ = q.value(QStringLiteral("compilation")).toBool();
|
||||
d->composer_ = q.ValueToString(QStringLiteral("composer"));
|
||||
d->performer_ = q.ValueToString(QStringLiteral("performer"));
|
||||
d->grouping_ = q.ValueToString(QStringLiteral("grouping"));
|
||||
d->comment_ = q.ValueToString(QStringLiteral("comment"));
|
||||
d->lyrics_ = q.ValueToString(QStringLiteral("lyrics"));
|
||||
d->artist_id_ = q.ValueToString(QStringLiteral("artist_id"));
|
||||
d->album_id_ = q.ValueToString(QStringLiteral("album_id"));
|
||||
d->song_id_ = q.ValueToString(QStringLiteral("song_id"));
|
||||
d->beginning_ = q.value(QStringLiteral("beginning")).isNull() ? 0 : q.value(QStringLiteral("beginning")).toLongLong();
|
||||
set_length_nanosec(q.ValueToLongLong(QStringLiteral("length")));
|
||||
d->bitrate_ = q.ValueToInt(QStringLiteral("bitrate"));
|
||||
d->samplerate_ = q.ValueToInt(QStringLiteral("samplerate"));
|
||||
d->bitdepth_ = q.ValueToInt(QStringLiteral("bitdepth"));
|
||||
if (!q.value(QStringLiteral("ebur128_integrated_loudness_lufs")).isNull()) {
|
||||
d->ebur128_integrated_loudness_lufs_ = q.value(QStringLiteral("ebur128_integrated_loudness_lufs")).toDouble();
|
||||
d->id_ = SqlHelper::ValueToInt(r, ColumnIndex(QStringLiteral("ROWID")) + col);
|
||||
|
||||
set_title(SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("title")) + col));
|
||||
set_album(SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("album")) + col));
|
||||
set_artist(SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("artist")) + col));
|
||||
set_albumartist(SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("albumartist")) + col));
|
||||
d->track_ = SqlHelper::ValueToInt(r, ColumnIndex(QStringLiteral("track")) + col);
|
||||
d->disc_ = SqlHelper::ValueToInt(r, ColumnIndex(QStringLiteral("disc")) + col);
|
||||
d->year_ = SqlHelper::ValueToInt(r, ColumnIndex(QStringLiteral("year")) + col);
|
||||
d->originalyear_ = SqlHelper::ValueToInt(r, ColumnIndex(QStringLiteral("originalyear")) + col);
|
||||
d->genre_ = SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("genre")) + col);
|
||||
d->compilation_ = r.value(ColumnIndex(QStringLiteral("compilation")) + col).toBool();
|
||||
d->composer_ = SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("composer")) + col);
|
||||
d->performer_ = SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("performer")) + col);
|
||||
d->grouping_ = SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("grouping")) + col);
|
||||
d->comment_ = SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("comment")) + col);
|
||||
d->lyrics_ = SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("lyrics")) + col);
|
||||
d->artist_id_ = SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("artist_id")) + col);
|
||||
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));
|
||||
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);
|
||||
if (!r.value(ColumnIndex(QStringLiteral("ebur128_integrated_loudness_lufs")) + col).isNull()) {
|
||||
d->ebur128_integrated_loudness_lufs_ = r.value(ColumnIndex(QStringLiteral("ebur128_integrated_loudness_lufs")) + col).toDouble();
|
||||
}
|
||||
if (!q.value(QStringLiteral("ebur128_loudness_range_lu")).isNull()) {
|
||||
d->ebur128_loudness_range_lu_ = q.value(QStringLiteral("ebur128_loudness_range_lu")).toDouble();
|
||||
if (!r.value(ColumnIndex(QStringLiteral("ebur128_loudness_range_lu")) + col).isNull()) {
|
||||
d->ebur128_loudness_range_lu_ = r.value(ColumnIndex(QStringLiteral("ebur128_loudness_range_lu")) + col).toDouble();
|
||||
}
|
||||
d->source_ = static_cast<Source>(q.value(QStringLiteral("source")).isNull() ? 0 : q.value(QStringLiteral("source")).toInt());
|
||||
d->directory_id_ = q.ValueToInt(QStringLiteral("directory_id"));
|
||||
set_url(QUrl::fromEncoded(q.ValueToString(QStringLiteral("url")).toUtf8()));
|
||||
d->source_ = static_cast<Source>(r.value(ColumnIndex(QStringLiteral("source")) + col).isNull() ? 0 : r.value(ColumnIndex(QStringLiteral("source")) + col).toInt());
|
||||
d->directory_id_ = SqlHelper::ValueToInt(r, ColumnIndex(QStringLiteral("directory_id")) + col);
|
||||
set_url(QUrl::fromEncoded(SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("url")) + col).toUtf8()));
|
||||
d->basefilename_ = QFileInfo(d->url_.toLocalFile()).fileName();
|
||||
d->filetype_ = FileType(q.value(QStringLiteral("filetype")).isNull() ? 0 : q.value(QStringLiteral("filetype")).toInt());
|
||||
d->filesize_ = q.ValueToLongLong(QStringLiteral("filesize"));
|
||||
d->mtime_ = q.ValueToLongLong(QStringLiteral("mtime"));
|
||||
d->ctime_ = q.ValueToLongLong(QStringLiteral("ctime"));
|
||||
d->unavailable_ = q.value(QStringLiteral("unavailable")).toBool();
|
||||
d->fingerprint_ = q.ValueToString(QStringLiteral("fingerprint"));
|
||||
d->playcount_ = q.ValueToUInt(QStringLiteral("playcount"));
|
||||
d->skipcount_ = q.ValueToUInt(QStringLiteral("skipcount"));
|
||||
d->lastplayed_ = q.ValueToLongLong(QStringLiteral("lastplayed"));
|
||||
d->lastseen_ = q.ValueToLongLong(QStringLiteral("lastseen"));
|
||||
d->compilation_detected_ = q.ValueToBool(QStringLiteral("compilation_detected"));
|
||||
d->compilation_on_ = q.ValueToBool(QStringLiteral("compilation_on"));
|
||||
d->compilation_off_ = q.ValueToBool(QStringLiteral("compilation_off"));
|
||||
d->filetype_ = FileType(r.value(ColumnIndex(QStringLiteral("filetype")) + col).isNull() ? 0 : r.value(ColumnIndex(QStringLiteral("filetype")) + col).toInt());
|
||||
d->filesize_ = SqlHelper::ValueToLongLong(r, ColumnIndex(QStringLiteral("filesize")) + col);
|
||||
d->mtime_ = SqlHelper::ValueToLongLong(r, ColumnIndex(QStringLiteral("mtime")) + col);
|
||||
d->ctime_ = SqlHelper::ValueToLongLong(r, ColumnIndex(QStringLiteral("ctime")) + col);
|
||||
d->unavailable_ = r.value(ColumnIndex(QStringLiteral("unavailable")) + col).toBool();
|
||||
d->fingerprint_ = SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("fingerprint")) + col);
|
||||
d->playcount_ = SqlHelper::ValueToUInt(r, ColumnIndex(QStringLiteral("playcount")) + col);
|
||||
d->skipcount_ = SqlHelper::ValueToUInt(r, ColumnIndex(QStringLiteral("skipcount")) + col);
|
||||
d->lastplayed_ = SqlHelper::ValueToLongLong(r, ColumnIndex(QStringLiteral("lastplayed")) + col);
|
||||
d->lastseen_ = SqlHelper::ValueToLongLong(r, ColumnIndex(QStringLiteral("lastseen")) + col);
|
||||
d->compilation_detected_ = SqlHelper::ValueToBool(r, ColumnIndex(QStringLiteral("compilation_detected")) + col);
|
||||
d->compilation_on_ = SqlHelper::ValueToBool(r, ColumnIndex(QStringLiteral("compilation_on")) + col);
|
||||
d->compilation_off_ = SqlHelper::ValueToBool(r, ColumnIndex(QStringLiteral("compilation_off")) + col);
|
||||
|
||||
d->art_embedded_ = q.ValueToBool(QStringLiteral("art_embedded"));
|
||||
d->art_automatic_ = QUrl::fromEncoded(q.ValueToString(QStringLiteral("art_automatic")).toUtf8());
|
||||
d->art_manual_ = QUrl::fromEncoded(q.ValueToString(QStringLiteral("art_manual")).toUtf8());
|
||||
d->art_unset_ = q.ValueToBool(QStringLiteral("art_unset"));
|
||||
d->art_embedded_ = SqlHelper::ValueToBool(r, ColumnIndex(QStringLiteral("art_embedded")) + col);
|
||||
d->art_automatic_ = QUrl::fromEncoded(SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("art_automatic")) + col).toUtf8());
|
||||
d->art_manual_ = QUrl::fromEncoded(SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("art_manual")) + col).toUtf8());
|
||||
d->art_unset_ = SqlHelper::ValueToBool(r, ColumnIndex(QStringLiteral("art_unset")) + col);
|
||||
|
||||
d->cue_path_ = q.ValueToString(QStringLiteral("cue_path"));
|
||||
d->rating_ = q.ValueToFloat(QStringLiteral("rating"));
|
||||
d->cue_path_ = SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("cue_path")) + col);
|
||||
d->rating_ = SqlHelper::ValueToFloat(r, ColumnIndex(QStringLiteral("rating")) + col);
|
||||
|
||||
d->acoustid_id_ = q.ValueToString(QStringLiteral("acoustid_id"));
|
||||
d->acoustid_fingerprint_ = q.ValueToString(QStringLiteral("acoustid_fingerprint"));
|
||||
d->acoustid_id_ = SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("acoustid_id")) + col);
|
||||
d->acoustid_fingerprint_ = SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("acoustid_fingerprint")) + col);
|
||||
|
||||
d->musicbrainz_album_artist_id_ = q.ValueToString(QStringLiteral("musicbrainz_album_artist_id"));
|
||||
d->musicbrainz_artist_id_ = q.ValueToString(QStringLiteral("musicbrainz_artist_id"));
|
||||
d->musicbrainz_original_artist_id_ = q.ValueToString(QStringLiteral("musicbrainz_original_artist_id"));
|
||||
d->musicbrainz_album_id_ = q.ValueToString(QStringLiteral("musicbrainz_album_id"));
|
||||
d->musicbrainz_original_album_id_ = q.ValueToString(QStringLiteral("musicbrainz_original_album_id"));
|
||||
d->musicbrainz_recording_id_ = q.ValueToString(QStringLiteral("musicbrainz_recording_id"));
|
||||
d->musicbrainz_track_id_ = q.ValueToString(QStringLiteral("musicbrainz_track_id"));
|
||||
d->musicbrainz_disc_id_ = q.ValueToString(QStringLiteral("musicbrainz_disc_id"));
|
||||
d->musicbrainz_release_group_id_ = q.ValueToString(QStringLiteral("musicbrainz_release_group_id"));
|
||||
d->musicbrainz_work_id_ = q.ValueToString(QStringLiteral("musicbrainz_work_id"));
|
||||
d->musicbrainz_album_artist_id_ = SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("musicbrainz_album_artist_id")) + col);
|
||||
d->musicbrainz_artist_id_ = SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("musicbrainz_artist_id")) + col);
|
||||
d->musicbrainz_original_artist_id_ = SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("musicbrainz_original_artist_id")) + col);
|
||||
d->musicbrainz_album_id_ = SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("musicbrainz_album_id")) + col);
|
||||
d->musicbrainz_original_album_id_ = SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("musicbrainz_original_album_id")) + col);
|
||||
d->musicbrainz_recording_id_ = SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("musicbrainz_recording_id")) + col);
|
||||
d->musicbrainz_track_id_ = SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("musicbrainz_track_id")) + col);
|
||||
d->musicbrainz_disc_id_ = SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("musicbrainz_disc_id")) + col);
|
||||
d->musicbrainz_release_group_id_ = SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("musicbrainz_release_group_id")) + col);
|
||||
d->musicbrainz_work_id_ = SqlHelper::ValueToString(r, ColumnIndex(QStringLiteral("musicbrainz_work_id")) + col);
|
||||
|
||||
d->valid_ = true;
|
||||
d->init_from_file_ = reliable_metadata;
|
||||
|
@ -1444,6 +1460,18 @@ void Song::InitFromQuery(const SqlRow &q, const bool reliable_metadata) {
|
|||
|
||||
}
|
||||
|
||||
void Song::InitFromQuery(const SqlQuery &query, const bool reliable_metadata, const int col) {
|
||||
|
||||
InitFromQuery(query.record(), reliable_metadata, col);
|
||||
|
||||
}
|
||||
|
||||
void Song::InitFromQuery(const SqlRow &row, const bool reliable_metadata, const int col) {
|
||||
|
||||
InitFromQuery(row.record(), reliable_metadata, col);
|
||||
|
||||
}
|
||||
|
||||
void Song::InitFromFilePartial(const QString &filename, const QFileInfo &fileinfo) {
|
||||
|
||||
set_url(QUrl::fromLocalFile(filename));
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Strawberry Music Player
|
||||
* This file was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
* Copyright 2018-2023, Jonas Kvinge <jonas@jkvinge.net>
|
||||
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -42,6 +42,7 @@
|
|||
#include <QIcon>
|
||||
|
||||
class SqlQuery;
|
||||
class QSqlRecord;
|
||||
|
||||
class EngineMetadata;
|
||||
|
||||
|
@ -112,7 +113,9 @@ class Song {
|
|||
};
|
||||
|
||||
static const QStringList kColumns;
|
||||
static const QStringList kRowIdColumns;
|
||||
static const QString kColumnSpec;
|
||||
static const QString kRowIdColumnSpec;
|
||||
static const QString kBindSpec;
|
||||
static const QString kUpdateSpec;
|
||||
|
||||
|
@ -350,6 +353,7 @@ class Song {
|
|||
static bool save_embedded_cover_supported(const FileType filetype);
|
||||
bool save_embedded_cover_supported() const { return url().isLocalFile() && save_embedded_cover_supported(filetype()) && !has_cue(); };
|
||||
|
||||
static int ColumnIndex(const QString &field);
|
||||
static QString JoinSpec(const QString &table);
|
||||
|
||||
// Pretty accessors
|
||||
|
@ -416,7 +420,9 @@ class Song {
|
|||
void Init(const QString &title, const QString &artist, const QString &album, const qint64 length_nanosec);
|
||||
void Init(const QString &title, const QString &artist, const QString &album, const qint64 beginning, const qint64 end);
|
||||
void InitFromProtobuf(const spb::tagreader::SongMetadata &pb);
|
||||
void InitFromQuery(const SqlRow &query, const bool reliable_metadata);
|
||||
void InitFromQuery(const QSqlRecord &r, const bool reliable_metadata, const int col = 0);
|
||||
void InitFromQuery(const SqlQuery &query, const bool reliable_metadata, const int col = 0);
|
||||
void InitFromQuery(const SqlRow &row, const bool reliable_metadata, const int col = 0);
|
||||
void InitFromFilePartial(const QString &filename, const QFileInfo &fileinfo);
|
||||
void InitArtManual();
|
||||
void InitArtAutomatic();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||
* Copyright 2021-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||
* Copyright 2021-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -29,12 +29,15 @@
|
|||
#include <QString>
|
||||
#include <QSqlDatabase>
|
||||
#include <QSqlQuery>
|
||||
#include <QSqlRecord>
|
||||
|
||||
class SqlQuery : public QSqlQuery {
|
||||
|
||||
public:
|
||||
explicit SqlQuery(const QSqlDatabase &db) : QSqlQuery(db) {}
|
||||
|
||||
int columns() const { return QSqlQuery::record().count(); }
|
||||
|
||||
void BindValue(const QString &placeholder, const QVariant &value);
|
||||
void BindStringValue(const QString &placeholder, const QString &value);
|
||||
void BindUrlValue(const QString &placeholder, const QUrl &value);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2018-2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -20,74 +20,22 @@
|
|||
#include "config.h"
|
||||
|
||||
#include <QVariant>
|
||||
#include <QString>
|
||||
#include <QUrl>
|
||||
#include <QSqlQuery>
|
||||
#include <QSqlRecord>
|
||||
|
||||
#include "sqlrow.h"
|
||||
|
||||
SqlRow::SqlRow(const QSqlQuery &query) { Init(query); }
|
||||
SqlRow::SqlRow(const SqlQuery &query) { Init(query); }
|
||||
|
||||
void SqlRow::Init(const QSqlQuery &query) {
|
||||
void SqlRow::Init(const SqlQuery &query) {
|
||||
|
||||
const QSqlRecord r = query.record();
|
||||
for (int i = 0; i < r.count(); ++i) {
|
||||
columns_by_number_.insert(i, query.value(i));
|
||||
const QString field_name = r.fieldName(i);
|
||||
if (!columns_by_name_.contains(field_name) || columns_by_name_[field_name].isNull()) {
|
||||
columns_by_name_.insert(field_name, query.value(i));
|
||||
}
|
||||
}
|
||||
record_ = query.record();
|
||||
|
||||
}
|
||||
|
||||
const QVariant SqlRow::value(const int number) const {
|
||||
const QVariant SqlRow::value(const int n) const {
|
||||
|
||||
if (columns_by_number_.contains(number)) {
|
||||
return columns_by_number_[number];
|
||||
}
|
||||
else {
|
||||
return QVariant();
|
||||
}
|
||||
Q_ASSERT(n < record_.count());
|
||||
|
||||
return record_.value(n);
|
||||
|
||||
}
|
||||
|
||||
const QVariant SqlRow::value(const QString &name) const {
|
||||
|
||||
if (columns_by_name_.contains(name)) {
|
||||
return columns_by_name_[name];
|
||||
}
|
||||
else {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QString SqlRow::ValueToString(const QString &n) const {
|
||||
return value(n).isNull() ? QString() : value(n).toString();
|
||||
}
|
||||
|
||||
QUrl SqlRow::ValueToUrl(const QString &n) const {
|
||||
return value(n).isNull() ? QUrl() : QUrl(value(n).toString());
|
||||
}
|
||||
|
||||
int SqlRow::ValueToInt(const QString &n) const {
|
||||
return value(n).isNull() ? -1 : value(n).toInt();
|
||||
}
|
||||
|
||||
uint SqlRow::ValueToUInt(const QString &n) const {
|
||||
return value(n).isNull() || value(n).toInt() < 0 ? 0 : value(n).toInt();
|
||||
}
|
||||
|
||||
qint64 SqlRow::ValueToLongLong(const QString &n) const {
|
||||
return value(n).isNull() ? -1 : value(n).toLongLong();
|
||||
}
|
||||
|
||||
float SqlRow::ValueToFloat(const QString &n) const {
|
||||
return value(n).isNull() ? -1.0F : value(n).toFloat();
|
||||
}
|
||||
|
||||
bool SqlRow::ValueToBool(const QString &n) const {
|
||||
return !value(n).isNull() && value(n).toInt() == 1;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2018-2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -24,33 +24,23 @@
|
|||
|
||||
#include <QList>
|
||||
#include <QVariant>
|
||||
#include <QUrl>
|
||||
#include <QSqlQuery>
|
||||
#include <QSqlRecord>
|
||||
|
||||
#include "sqlquery.h"
|
||||
|
||||
class SqlRow {
|
||||
|
||||
public:
|
||||
SqlRow(const QSqlQuery &query);
|
||||
explicit SqlRow(const SqlQuery &query);
|
||||
|
||||
const QVariant value(const int number) const;
|
||||
const QVariant value(const QString &name) const;
|
||||
|
||||
QString ValueToString(const QString &n) const;
|
||||
QUrl ValueToUrl(const QString &n) const;
|
||||
int ValueToInt(const QString &n) const;
|
||||
uint ValueToUInt(const QString &n) const;
|
||||
qint64 ValueToLongLong(const QString &n) const;
|
||||
float ValueToFloat(const QString &n) const;
|
||||
bool ValueToBool(const QString& n) const;
|
||||
int columns() const { return record_.count(); }
|
||||
const QSqlRecord &record() const { return record_; }
|
||||
const QVariant value(const int n) const;
|
||||
|
||||
private:
|
||||
SqlRow();
|
||||
|
||||
void Init(const QSqlQuery &query);
|
||||
|
||||
QMap<int, QVariant> columns_by_number_;
|
||||
QMap<QString, QVariant> columns_by_name_;
|
||||
void Init(const SqlQuery &query);
|
||||
|
||||
QSqlRecord record_;
|
||||
};
|
||||
|
||||
using SqlRowList = QList<SqlRow>;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -877,7 +877,7 @@ SongList AlbumCoverManager::GetSongsInAlbum(const QModelIndex &idx) const {
|
|||
QSqlDatabase db(collection_backend_->db()->Connect());
|
||||
|
||||
CollectionQuery q(db, collection_backend_->songs_table(), collection_backend_->fts_table());
|
||||
q.SetColumnSpec(QStringLiteral("ROWID,") + Song::kColumnSpec);
|
||||
q.SetColumnSpec(Song::kRowIdColumnSpec);
|
||||
q.AddWhere(QStringLiteral("album"), idx.data(Role_Album).toString());
|
||||
q.SetOrderBy(QStringLiteral("disc, track, title"));
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
||||
|
|
|
@ -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]));
|
||||
}
|
||||
|
||||
|
|
|
@ -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_);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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/>");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -166,7 +166,7 @@ QString Chromaprinter::CreateFingerprint() {
|
|||
int encoded_size = 0;
|
||||
ret = chromaprint_encode_fingerprint(fprint, size, CHROMAPRINT_ALGORITHM_DEFAULT, &encoded, &encoded_size, 1);
|
||||
if (ret == 1) {
|
||||
fingerprint.append(reinterpret_cast<char*>(encoded), encoded_size);
|
||||
fingerprint.append(encoded, encoded_size);
|
||||
chromaprint_dealloc(encoded);
|
||||
}
|
||||
chromaprint_dealloc(fprint);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -48,7 +48,7 @@ InternetPlaylistItem::InternetPlaylistItem(InternetServicePtr service, const Son
|
|||
|
||||
bool InternetPlaylistItem::InitFromQuery(const SqlRow &query) {
|
||||
|
||||
metadata_.InitFromQuery(query, false);
|
||||
metadata_.InitFromQuery(query, false, static_cast<int>(Song::kRowIdColumns.count()));
|
||||
InitMetadata();
|
||||
return true;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -332,9 +332,9 @@ QVariant Playlist::data(const QModelIndex &idx, int role) const {
|
|||
if (role == Qt::DisplayRole) return song.comment().simplified();
|
||||
return song.comment();
|
||||
|
||||
case Column_EBUR128IntegratedLoudness: return song.ebur128_integrated_loudness_lufs() ? *song.ebur128_integrated_loudness_lufs() : QVariant();
|
||||
case Column_EBUR128IntegratedLoudness: return song.ebur128_integrated_loudness_lufs().has_value() ? song.ebur128_integrated_loudness_lufs().value() : QVariant();
|
||||
|
||||
case Column_EBUR128LoudnessRange: return song.ebur128_loudness_range_lu() ? *song.ebur128_loudness_range_lu() : QVariant();
|
||||
case Column_EBUR128LoudnessRange: return song.ebur128_loudness_range_lu().has_value() ? song.ebur128_loudness_range_lu().value() : QVariant();
|
||||
|
||||
case Column_Source: return QVariant::fromValue(song.source());
|
||||
|
||||
|
@ -975,7 +975,7 @@ void Playlist::MoveItemsWithoutUndo(const QList<int> &source_rows, int pos) {
|
|||
if (ShuffleMode() != PlaylistSequence::ShuffleMode::Off) {
|
||||
const QList<int> old_virtual_items = virtual_items_;
|
||||
for (int i = 0; i < virtual_items_.count(); ++i) {
|
||||
virtual_items_[i] = items_.indexOf(old_items[old_virtual_items[i]]);
|
||||
virtual_items_[i] = static_cast<int>(items_.indexOf(old_items[old_virtual_items[i]]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1047,7 +1047,7 @@ void Playlist::MoveItemsWithoutUndo(int start, const QList<int> &dest_rows) {
|
|||
if (ShuffleMode() != PlaylistSequence::ShuffleMode::Off) {
|
||||
const QList<int> old_virtual_items = virtual_items_;
|
||||
for (int i = 0; i < virtual_items_.count(); ++i) {
|
||||
virtual_items_[i] = items_.indexOf(old_items[old_virtual_items[i]]);
|
||||
virtual_items_[i] = static_cast<int>(items_.indexOf(old_items[old_virtual_items[i]]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1486,7 +1486,7 @@ void Playlist::ReOrderWithoutUndo(const PlaylistItemPtrList &new_items) {
|
|||
if (ShuffleMode() != PlaylistSequence::ShuffleMode::Off) {
|
||||
const QList<int> old_virtual_items = virtual_items_;
|
||||
for (int i = 0; i < virtual_items_.count(); ++i) {
|
||||
virtual_items_[i] = items_.indexOf(old_items[old_virtual_items[i]]);
|
||||
virtual_items_[i] = static_cast<int>(items_.indexOf(old_items[old_virtual_items[i]]));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <utility>
|
||||
#include <memory>
|
||||
|
||||
#include <QObject>
|
||||
|
@ -184,7 +185,8 @@ PlaylistItemPtrList PlaylistBackend::GetPlaylistItems(const int playlist) {
|
|||
QMutexLocker l(db_->Mutex());
|
||||
QSqlDatabase db(db_->Connect());
|
||||
|
||||
QString query = QStringLiteral("SELECT songs.ROWID, ") + Song::JoinSpec(QStringLiteral("songs")) + QStringLiteral(", p.ROWID, ") + Song::JoinSpec(QStringLiteral("p")) + QStringLiteral(", p.type FROM playlist_items AS p LEFT JOIN songs ON p.collection_id = songs.ROWID WHERE p.playlist = :playlist");
|
||||
QString query = QStringLiteral("SELECT %1, %2, p.type FROM playlist_items AS p LEFT JOIN songs ON p.collection_id = songs.ROWID WHERE p.playlist = :playlist").arg(Song::JoinSpec(QStringLiteral("songs")), Song::JoinSpec(QStringLiteral("p")));
|
||||
|
||||
SqlQuery q(db);
|
||||
// Forward iterations only may be faster
|
||||
q.setForwardOnly(true);
|
||||
|
@ -219,7 +221,8 @@ SongList PlaylistBackend::GetPlaylistSongs(const int playlist) {
|
|||
QMutexLocker l(db_->Mutex());
|
||||
QSqlDatabase db(db_->Connect());
|
||||
|
||||
QString query = QStringLiteral("SELECT songs.ROWID, ") + Song::JoinSpec(QStringLiteral("songs")) + QStringLiteral(", p.ROWID, ") + Song::JoinSpec(QStringLiteral("p")) + QStringLiteral(", p.type FROM playlist_items AS p LEFT JOIN songs ON p.collection_id = songs.ROWID WHERE p.playlist = :playlist");
|
||||
QString query = QStringLiteral("SELECT %1, %2, p.type FROM playlist_items AS p LEFT JOIN songs ON p.collection_id = songs.ROWID WHERE p.playlist = :playlist").arg(Song::JoinSpec(QStringLiteral("songs")), Song::JoinSpec(QStringLiteral("p")));
|
||||
|
||||
SqlQuery q(db);
|
||||
// Forward iterations only may be faster
|
||||
q.setForwardOnly(true);
|
||||
|
@ -249,7 +252,7 @@ SongList PlaylistBackend::GetPlaylistSongs(const int playlist) {
|
|||
PlaylistItemPtr PlaylistBackend::NewPlaylistItemFromQuery(const SqlRow &row, SharedPtr<NewSongFromQueryState> state) {
|
||||
|
||||
// The song tables get joined first, plus one each for the song ROWIDs
|
||||
const int playlist_row = static_cast<int>(Song::kColumns.count() + 1) * kSongTableJoins;
|
||||
const int playlist_row = static_cast<int>(Song::kRowIdColumns.count()) * kSongTableJoins;
|
||||
|
||||
PlaylistItemPtr item(PlaylistItem::NewFromSource(static_cast<Song::Source>(row.value(playlist_row).toInt())));
|
||||
if (item) {
|
||||
|
@ -305,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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -37,7 +37,9 @@
|
|||
#include "playlistsequence.h"
|
||||
#include "ui_playlistsequence.h"
|
||||
|
||||
const char *PlaylistSequence::kSettingsGroup = "PlaylistSequence";
|
||||
namespace {
|
||||
constexpr char kSettingsGroup[] = "PlaylistSequence";
|
||||
}
|
||||
|
||||
PlaylistSequence::PlaylistSequence(QWidget *parent, SettingsProvider *settings)
|
||||
: QWidget(parent),
|
||||
|
|
|
@ -60,8 +60,6 @@ class PlaylistSequence : public QWidget {
|
|||
Albums = 3
|
||||
};
|
||||
|
||||
static const char *kSettingsGroup;
|
||||
|
||||
RepeatMode repeat_mode() const;
|
||||
ShuffleMode shuffle_mode() const;
|
||||
|
||||
|
@ -98,7 +96,6 @@ class PlaylistSequence : public QWidget {
|
|||
bool loading_;
|
||||
RepeatMode repeat_mode_;
|
||||
ShuffleMode shuffle_mode_;
|
||||
bool dynamic_;
|
||||
};
|
||||
|
||||
#endif // PLAYLISTSEQUENCE_H
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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_.InitFromQuery(query, false, static_cast<int>(Song::kRowIdColumns.count()));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -192,7 +192,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 +211,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 +226,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 +314,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 +327,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 +357,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_);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -51,7 +51,7 @@ void SmartPlaylistSearch::Reset() {
|
|||
|
||||
QString SmartPlaylistSearch::ToSql(const QString &songs_table) const {
|
||||
|
||||
QString sql = QStringLiteral("SELECT ROWID,") + Song::kColumnSpec + QStringLiteral(" FROM ") + songs_table;
|
||||
QString sql = QStringLiteral("SELECT %1 FROM %2").arg(Song::kRowIdColumnSpec, songs_table);
|
||||
|
||||
// Add search terms
|
||||
QStringList where_clauses;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -1249,7 +1249,7 @@ msgstr "CUE"
|
|||
|
||||
#: ../build/src/ui_lastfmimportdialog.h:157
|
||||
msgid "Cancel"
|
||||
msgstr "Annulé"
|
||||
msgstr "Annuler"
|
||||
|
||||
#: tidal/tidalstreamurlrequest.cpp:105 qobuz/qobuzstreamurlrequest.cpp:101
|
||||
msgid "Cancelled."
|
||||
|
|
|
@ -54,7 +54,7 @@ void OpenInFileManager(const QString &path, const QUrl &url) {
|
|||
if (xdg_data_dirs.isEmpty()) {
|
||||
xdg_data_dirs = QStringLiteral("/usr/local/share/:/usr/share/");
|
||||
}
|
||||
QStringList data_dirs = xdg_data_dirs.split(QStringLiteral(":"));
|
||||
const QStringList data_dirs = xdg_data_dirs.split(QStringLiteral(":"));
|
||||
|
||||
QString command;
|
||||
QStringList command_params;
|
||||
|
|
|
@ -91,19 +91,22 @@ bool CopyRecursive(const QString &source, const QString &destination) {
|
|||
QDir().mkpath(dest_path);
|
||||
|
||||
QDir dir(source);
|
||||
for (const QString &child : dir.entryList(QDir::NoDotAndDotDot | QDir::Dirs)) {
|
||||
const QStringList children_dirs = dir.entryList(QDir::NoDotAndDotDot | QDir::Dirs);
|
||||
for (const QString &child : children_dirs) {
|
||||
if (!CopyRecursive(source + QLatin1Char('/') + child, dest_path)) {
|
||||
qLog(Warning) << "Failed to copy dir" << source + QLatin1Char('/') + child << "to" << dest_path;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (const QString &child : dir.entryList(QDir::NoDotAndDotDot | QDir::Files)) {
|
||||
const QStringList children_files = dir.entryList(QDir::NoDotAndDotDot | QDir::Files);
|
||||
for (const QString &child : children_files) {
|
||||
if (!QFile::copy(source + QLatin1Char('/') + child, dest_path + QLatin1Char('/') + child)) {
|
||||
qLog(Warning) << "Failed to copy file" << source + QLatin1Char('/') + child << "to" << dest_path;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
@ -111,13 +114,15 @@ bool CopyRecursive(const QString &source, const QString &destination) {
|
|||
bool RemoveRecursive(const QString &path) {
|
||||
|
||||
QDir dir(path);
|
||||
for (const QString &child : dir.entryList(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Hidden)) {
|
||||
const QStringList children_dirs = dir.entryList(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Hidden);
|
||||
for (const QString &child : children_dirs) {
|
||||
if (!RemoveRecursive(path + QLatin1Char('/') + child)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (const QString &child : dir.entryList(QDir::NoDotAndDotDot | QDir::Files | QDir::Hidden)) {
|
||||
const QStringList children_files = dir.entryList(QDir::NoDotAndDotDot | QDir::Files | QDir::Hidden);
|
||||
for (const QString &child : children_files) {
|
||||
if (!QFile::remove(path + QLatin1Char('/') + child)) {
|
||||
return false;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue