Add sort columns to filter parser
Also pass the filter column enum through to filter tree instead of string.
This commit is contained in:
53
src/filterparser/filtercolumn.h
Normal file
53
src/filterparser/filtercolumn.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Strawberry Music Player
|
||||||
|
* Copyright 2026, 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
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Strawberry is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FILTERCOLUMN_H
|
||||||
|
#define FILTERCOLUMN_H
|
||||||
|
|
||||||
|
enum class FilterColumn {
|
||||||
|
Unknown,
|
||||||
|
Title,
|
||||||
|
TitleSort,
|
||||||
|
Album,
|
||||||
|
AlbumSort,
|
||||||
|
Artist,
|
||||||
|
ArtistSort,
|
||||||
|
AlbumArtist,
|
||||||
|
AlbumArtistSort,
|
||||||
|
Composer,
|
||||||
|
ComposerSort,
|
||||||
|
Performer,
|
||||||
|
PerformerSort,
|
||||||
|
Grouping,
|
||||||
|
Genre,
|
||||||
|
Comment,
|
||||||
|
Filename,
|
||||||
|
URL,
|
||||||
|
Track,
|
||||||
|
Year,
|
||||||
|
Samplerate,
|
||||||
|
Bitdepth,
|
||||||
|
Bitrate,
|
||||||
|
Playcount,
|
||||||
|
Skipcount,
|
||||||
|
Length,
|
||||||
|
Rating,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FILTERCOLUMN_H
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
* Strawberry Music Player
|
* Strawberry Music Player
|
||||||
* This file was part of Clementine.
|
* This file was part of Clementine.
|
||||||
* Copyright 2012, David Sansome <me@davidsansome.com>
|
* Copyright 2012, David Sansome <me@davidsansome.com>
|
||||||
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
* Copyright 2018-2026, Jonas Kvinge <jonas@jkvinge.net>
|
||||||
* Copyright 2023, Daniel Ostertag <daniel.ostertag@dakes.de>
|
* Copyright 2023, Daniel Ostertag <daniel.ostertag@dakes.de>
|
||||||
*
|
*
|
||||||
* Strawberry is free software: you can redistribute it and/or modify
|
* Strawberry is free software: you can redistribute it and/or modify
|
||||||
@@ -33,11 +33,41 @@
|
|||||||
#include "filtertreeterm.h"
|
#include "filtertreeterm.h"
|
||||||
#include "filtertreecolumnterm.h"
|
#include "filtertreecolumnterm.h"
|
||||||
#include "filterparsersearchcomparators.h"
|
#include "filterparsersearchcomparators.h"
|
||||||
|
#include "filtercolumn.h"
|
||||||
|
|
||||||
using namespace Qt::Literals::StringLiterals;
|
using namespace Qt::Literals::StringLiterals;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
enum class FilterOperator {
|
||||||
|
None,
|
||||||
|
Eq,
|
||||||
|
Ne,
|
||||||
|
Gt,
|
||||||
|
Ge,
|
||||||
|
Lt,
|
||||||
|
Le
|
||||||
|
};
|
||||||
|
|
||||||
|
const QMap<QString, FilterOperator> &GetFilterOperatorsMap() {
|
||||||
|
|
||||||
|
static const QMap<QString, FilterOperator> filter_operators_map_ = []() {
|
||||||
|
QMap<QString, FilterOperator> filter_operators_map;
|
||||||
|
filter_operators_map.insert(u"="_s, FilterOperator::Eq);
|
||||||
|
filter_operators_map.insert(u"=="_s, FilterOperator::Eq);
|
||||||
|
filter_operators_map.insert(u"!="_s, FilterOperator::Ne);
|
||||||
|
filter_operators_map.insert(u"<>"_s, FilterOperator::Ne);
|
||||||
|
filter_operators_map.insert(u">"_s, FilterOperator::Gt);
|
||||||
|
filter_operators_map.insert(u">="_s, FilterOperator::Ge);
|
||||||
|
filter_operators_map.insert(u"<"_s, FilterOperator::Lt);
|
||||||
|
filter_operators_map.insert(u"<="_s, FilterOperator::Le);
|
||||||
|
return filter_operators_map;
|
||||||
|
}();
|
||||||
|
|
||||||
|
return filter_operators_map_;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
enum class ColumnType {
|
enum class ColumnType {
|
||||||
Unknown,
|
Unknown,
|
||||||
Text,
|
Text,
|
||||||
@@ -47,32 +77,78 @@ enum class ColumnType {
|
|||||||
Float
|
Float
|
||||||
};
|
};
|
||||||
|
|
||||||
const QMap<QString, ColumnType> &GetColumnTypeMap() {
|
const QMap<QString, FilterColumn> &GetFilterColumnsMap() {
|
||||||
static const QMap<QString, ColumnType> column_types = []() {
|
|
||||||
QMap<QString, ColumnType> map;
|
static const QMap<QString, FilterColumn> filter_columns_map_ = []() {
|
||||||
map.insert(u"title"_s, ColumnType::Text);
|
QMap<QString, FilterColumn> filter_columns_map;
|
||||||
map.insert(u"album"_s, ColumnType::Text);
|
filter_columns_map.insert(u"albumartist"_s, FilterColumn::AlbumArtist);
|
||||||
map.insert(u"artist"_s, ColumnType::Text);
|
filter_columns_map.insert(u"albumartistsort"_s, FilterColumn::AlbumArtistSort);
|
||||||
map.insert(u"albumartist"_s, ColumnType::Text);
|
filter_columns_map.insert(u"artist"_s, FilterColumn::Artist);
|
||||||
map.insert(u"composer"_s, ColumnType::Text);
|
filter_columns_map.insert(u"artistsort"_s, FilterColumn::ArtistSort);
|
||||||
map.insert(u"performer"_s, ColumnType::Text);
|
filter_columns_map.insert(u"album"_s, FilterColumn::Album);
|
||||||
map.insert(u"grouping"_s, ColumnType::Text);
|
filter_columns_map.insert(u"albumsort"_s, FilterColumn::AlbumSort);
|
||||||
map.insert(u"genre"_s, ColumnType::Text);
|
filter_columns_map.insert(u"title"_s, FilterColumn::Title);
|
||||||
map.insert(u"comment"_s, ColumnType::Text);
|
filter_columns_map.insert(u"titlesort"_s, FilterColumn::TitleSort);
|
||||||
map.insert(u"filename"_s, ColumnType::Text);
|
filter_columns_map.insert(u"composer"_s, FilterColumn::Composer);
|
||||||
map.insert(u"url"_s, ColumnType::Text);
|
filter_columns_map.insert(u"composersort"_s, FilterColumn::ComposerSort);
|
||||||
map.insert(u"track"_s, ColumnType::Int);
|
filter_columns_map.insert(u"performer"_s, FilterColumn::Performer);
|
||||||
map.insert(u"year"_s, ColumnType::Int);
|
filter_columns_map.insert(u"performersort"_s, FilterColumn::PerformerSort);
|
||||||
map.insert(u"samplerate"_s, ColumnType::Int);
|
filter_columns_map.insert(u"grouping"_s, FilterColumn::Grouping);
|
||||||
map.insert(u"bitdepth"_s, ColumnType::Int);
|
filter_columns_map.insert(u"genre"_s, FilterColumn::Genre);
|
||||||
map.insert(u"bitrate"_s, ColumnType::Int);
|
filter_columns_map.insert(u"comment"_s, FilterColumn::Comment);
|
||||||
map.insert(u"playcount"_s, ColumnType::UInt);
|
filter_columns_map.insert(u"filename"_s, FilterColumn::Filename);
|
||||||
map.insert(u"skipcount"_s, ColumnType::UInt);
|
filter_columns_map.insert(u"url"_s, FilterColumn::URL);
|
||||||
map.insert(u"length"_s, ColumnType::Int64);
|
filter_columns_map.insert(u"track"_s, FilterColumn::Track);
|
||||||
map.insert(u"rating"_s, ColumnType::Float);
|
filter_columns_map.insert(u"year"_s, FilterColumn::Year);
|
||||||
return map;
|
filter_columns_map.insert(u"samplerate"_s, FilterColumn::Samplerate);
|
||||||
|
filter_columns_map.insert(u"bitdepth"_s, FilterColumn::Bitdepth);
|
||||||
|
filter_columns_map.insert(u"bitrate"_s, FilterColumn::Bitrate);
|
||||||
|
filter_columns_map.insert(u"playcount"_s, FilterColumn::Playcount);
|
||||||
|
filter_columns_map.insert(u"skipcount"_s, FilterColumn::Skipcount);
|
||||||
|
filter_columns_map.insert(u"length"_s, FilterColumn::Length);
|
||||||
|
filter_columns_map.insert(u"rating"_s, FilterColumn::Rating);
|
||||||
|
return filter_columns_map;
|
||||||
}();
|
}();
|
||||||
return column_types;
|
|
||||||
|
return filter_columns_map_;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const QMap<FilterColumn, ColumnType> &GetColumnTypesMap() {
|
||||||
|
|
||||||
|
static const QMap<FilterColumn, ColumnType> column_types_map_ = []() {
|
||||||
|
QMap<FilterColumn, ColumnType> column_types_map;
|
||||||
|
column_types_map.insert(FilterColumn::AlbumArtist, ColumnType::Text);
|
||||||
|
column_types_map.insert(FilterColumn::AlbumArtistSort, ColumnType::Text);
|
||||||
|
column_types_map.insert(FilterColumn::Artist, ColumnType::Text);
|
||||||
|
column_types_map.insert(FilterColumn::ArtistSort, ColumnType::Text);
|
||||||
|
column_types_map.insert(FilterColumn::Album, ColumnType::Text);
|
||||||
|
column_types_map.insert(FilterColumn::AlbumSort, ColumnType::Text);
|
||||||
|
column_types_map.insert(FilterColumn::Title, ColumnType::Text);
|
||||||
|
column_types_map.insert(FilterColumn::TitleSort, ColumnType::Text);
|
||||||
|
column_types_map.insert(FilterColumn::Composer, ColumnType::Text);
|
||||||
|
column_types_map.insert(FilterColumn::ComposerSort, ColumnType::Text);
|
||||||
|
column_types_map.insert(FilterColumn::Performer, ColumnType::Text);
|
||||||
|
column_types_map.insert(FilterColumn::PerformerSort, ColumnType::Text);
|
||||||
|
column_types_map.insert(FilterColumn::Grouping, ColumnType::Text);
|
||||||
|
column_types_map.insert(FilterColumn::Genre, ColumnType::Text);
|
||||||
|
column_types_map.insert(FilterColumn::Comment, ColumnType::Text);
|
||||||
|
column_types_map.insert(FilterColumn::Filename, ColumnType::Text);
|
||||||
|
column_types_map.insert(FilterColumn::URL, ColumnType::Text);
|
||||||
|
column_types_map.insert(FilterColumn::Track, ColumnType::Int);
|
||||||
|
column_types_map.insert(FilterColumn::Year, ColumnType::Int);
|
||||||
|
column_types_map.insert(FilterColumn::Samplerate, ColumnType::Int);
|
||||||
|
column_types_map.insert(FilterColumn::Bitdepth, ColumnType::Int);
|
||||||
|
column_types_map.insert(FilterColumn::Bitrate, ColumnType::Int);
|
||||||
|
column_types_map.insert(FilterColumn::Playcount, ColumnType::UInt);
|
||||||
|
column_types_map.insert(FilterColumn::Skipcount, ColumnType::UInt);
|
||||||
|
column_types_map.insert(FilterColumn::Length, ColumnType::Int64);
|
||||||
|
column_types_map.insert(FilterColumn::Rating, ColumnType::Float);
|
||||||
|
return column_types_map;
|
||||||
|
}();
|
||||||
|
|
||||||
|
return column_types_map_;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@@ -298,133 +374,135 @@ FilterTree *FilterParser::createSearchTermTreeNode(const QString &column, const
|
|||||||
return new FilterTreeNop;
|
return new FilterTreeNop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FilterColumn filter_column = FilterColumn::Unknown;
|
||||||
FilterParserSearchTermComparator *cmp = nullptr;
|
FilterParserSearchTermComparator *cmp = nullptr;
|
||||||
|
|
||||||
if (!column.isEmpty()) {
|
if (!column.isEmpty()) {
|
||||||
const ColumnType column_type = GetColumnTypeMap().value(column, ColumnType::Unknown);
|
filter_column = GetFilterColumnsMap().value(column, FilterColumn::Unknown);
|
||||||
|
const ColumnType column_type = GetColumnTypesMap().value(filter_column, ColumnType::Unknown);
|
||||||
|
const FilterOperator filter_operator = GetFilterOperatorsMap().value(prefix, FilterOperator::None);
|
||||||
switch (column_type) {
|
switch (column_type) {
|
||||||
case ColumnType::Text: {
|
case ColumnType::Text:{
|
||||||
if ((prefix.size() == 1 && prefix[0] == u'=') || prefix == "=="_L1) {
|
switch (filter_operator) {
|
||||||
cmp = new FilterParserTextEqComparator(value);
|
case FilterOperator::Eq:
|
||||||
}
|
cmp = new FilterParserTextEqComparator(value);
|
||||||
else if (prefix == "!="_L1 || prefix == "<>"_L1) {
|
break;
|
||||||
cmp = new FilterParserTextNeComparator(value);
|
case FilterOperator::Ne:
|
||||||
}
|
cmp = new FilterParserTextNeComparator(value);
|
||||||
else {
|
break;
|
||||||
cmp = new FilterParserTextContainsComparator(value);
|
default:
|
||||||
|
cmp = new FilterParserTextContainsComparator(value);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ColumnType::Int: {
|
case ColumnType::Int:{
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
int number = value.toInt(&ok);
|
const int number = value.toInt(&ok);
|
||||||
if (ok) {
|
if (!ok) break;
|
||||||
if ((prefix.size() == 1 && prefix[0] == u'=') || prefix == "=="_L1) {
|
switch (filter_operator) {
|
||||||
|
case FilterOperator::None:
|
||||||
|
case FilterOperator::Eq:
|
||||||
cmp = new FilterParserIntEqComparator(number);
|
cmp = new FilterParserIntEqComparator(number);
|
||||||
}
|
break;
|
||||||
else if (prefix == "!="_L1 || prefix == "<>"_L1) {
|
case FilterOperator::Ne:
|
||||||
cmp = new FilterParserIntNeComparator(number);
|
cmp = new FilterParserIntNeComparator(number);
|
||||||
}
|
break;
|
||||||
else if (prefix.size() == 1 && prefix[0] == u'>') {
|
case FilterOperator::Gt:
|
||||||
cmp = new FilterParserIntGtComparator(number);
|
cmp = new FilterParserIntGtComparator(number);
|
||||||
}
|
break;
|
||||||
else if (prefix == ">="_L1) {
|
case FilterOperator::Ge:
|
||||||
cmp = new FilterParserIntGeComparator(number);
|
cmp = new FilterParserIntGeComparator(number);
|
||||||
}
|
break;
|
||||||
else if (prefix.size() == 1 && prefix[0] == u'<') {
|
case FilterOperator::Lt:
|
||||||
cmp = new FilterParserIntLtComparator(number);
|
cmp = new FilterParserIntLtComparator(number);
|
||||||
}
|
break;
|
||||||
else if (prefix == "<="_L1) {
|
case FilterOperator::Le:
|
||||||
cmp = new FilterParserIntLeComparator(number);
|
cmp = new FilterParserIntLeComparator(number);
|
||||||
}
|
break;
|
||||||
else {
|
|
||||||
cmp = new FilterParserIntEqComparator(number);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ColumnType::UInt: {
|
case ColumnType::UInt:{
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
uint number = value.toUInt(&ok);
|
const uint number = value.toUInt(&ok);
|
||||||
if (ok) {
|
if (!ok) break;
|
||||||
if ((prefix.size() == 1 && prefix[0] == u'=') || prefix == "=="_L1) {
|
switch (filter_operator) {
|
||||||
|
case FilterOperator::None:
|
||||||
|
case FilterOperator::Eq:
|
||||||
cmp = new FilterParserUIntEqComparator(number);
|
cmp = new FilterParserUIntEqComparator(number);
|
||||||
}
|
break;
|
||||||
else if (prefix == "!="_L1 || prefix == "<>"_L1) {
|
case FilterOperator::Ne:
|
||||||
cmp = new FilterParserUIntNeComparator(number);
|
cmp = new FilterParserUIntNeComparator(number);
|
||||||
}
|
break;
|
||||||
else if (prefix.size() == 1 && prefix[0] == u'>') {
|
case FilterOperator::Gt:
|
||||||
cmp = new FilterParserUIntGtComparator(number);
|
cmp = new FilterParserUIntGtComparator(number);
|
||||||
}
|
break;
|
||||||
else if (prefix == ">="_L1) {
|
case FilterOperator::Ge:
|
||||||
cmp = new FilterParserUIntGeComparator(number);
|
cmp = new FilterParserUIntGeComparator(number);
|
||||||
}
|
break;
|
||||||
else if (prefix.size() == 1 && prefix[0] == u'<') {
|
case FilterOperator::Lt:
|
||||||
cmp = new FilterParserUIntLtComparator(number);
|
cmp = new FilterParserUIntLtComparator(number);
|
||||||
}
|
break;
|
||||||
else if (prefix == "<="_L1) {
|
case FilterOperator::Le:
|
||||||
cmp = new FilterParserUIntLeComparator(number);
|
cmp = new FilterParserUIntLeComparator(number);
|
||||||
}
|
break;
|
||||||
else {
|
|
||||||
cmp = new FilterParserUIntEqComparator(number);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ColumnType::Int64: {
|
case ColumnType::Int64:{
|
||||||
qint64 number = 0;
|
qint64 number = 0;
|
||||||
if (column == "length"_L1) {
|
if (filter_column == FilterColumn::Length) {
|
||||||
number = ParseTime(value) * kNsecPerSec;
|
number = ParseTime(value) * kNsecPerSec;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
number = value.toLongLong();
|
number = value.toLongLong();
|
||||||
}
|
}
|
||||||
if ((prefix.size() == 1 && prefix[0] == u'=') || prefix == "=="_L1) {
|
switch (filter_operator) {
|
||||||
cmp = new FilterParserInt64EqComparator(number);
|
case FilterOperator::None:
|
||||||
}
|
case FilterOperator::Eq:
|
||||||
else if (prefix == "!="_L1 || prefix == "<>"_L1) {
|
cmp = new FilterParserInt64EqComparator(number);
|
||||||
cmp = new FilterParserInt64NeComparator(number);
|
break;
|
||||||
}
|
case FilterOperator::Ne:
|
||||||
else if (prefix.size() == 1 && prefix[0] == u'>') {
|
cmp = new FilterParserInt64NeComparator(number);
|
||||||
cmp = new FilterParserInt64GtComparator(number);
|
break;
|
||||||
}
|
case FilterOperator::Gt:
|
||||||
else if (prefix == ">="_L1) {
|
cmp = new FilterParserInt64GtComparator(number);
|
||||||
cmp = new FilterParserInt64GeComparator(number);
|
break;
|
||||||
}
|
case FilterOperator::Ge:
|
||||||
else if (prefix.size() == 1 && prefix[0] == u'<') {
|
cmp = new FilterParserInt64GeComparator(number);
|
||||||
cmp = new FilterParserInt64LtComparator(number);
|
break;
|
||||||
}
|
case FilterOperator::Lt:
|
||||||
else if (prefix == "<="_L1) {
|
cmp = new FilterParserInt64LtComparator(number);
|
||||||
cmp = new FilterParserInt64LeComparator(number);
|
break;
|
||||||
}
|
case FilterOperator::Le:
|
||||||
else {
|
cmp = new FilterParserInt64LeComparator(number);
|
||||||
cmp = new FilterParserInt64EqComparator(number);
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ColumnType::Float: {
|
case ColumnType::Float:{
|
||||||
const float rating = ParseRating(value);
|
const float rating = ParseRating(value);
|
||||||
if ((prefix.size() == 1 && prefix[0] == u'=') || prefix == "=="_L1) {
|
switch (filter_operator) {
|
||||||
cmp = new FilterParserFloatEqComparator(rating);
|
case FilterOperator::None:
|
||||||
}
|
case FilterOperator::Eq:
|
||||||
else if (prefix == "!="_L1 || prefix == "<>"_L1) {
|
cmp = new FilterParserFloatEqComparator(rating);
|
||||||
cmp = new FilterParserFloatNeComparator(rating);
|
break;
|
||||||
}
|
case FilterOperator::Ne:
|
||||||
else if (prefix.size() == 1 && prefix[0] == u'>') {
|
cmp = new FilterParserFloatNeComparator(rating);
|
||||||
cmp = new FilterParserFloatGtComparator(rating);
|
break;
|
||||||
}
|
case FilterOperator::Gt:
|
||||||
else if (prefix == ">="_L1) {
|
cmp = new FilterParserFloatGtComparator(rating);
|
||||||
cmp = new FilterParserFloatGeComparator(rating);
|
break;
|
||||||
}
|
case FilterOperator::Ge:
|
||||||
else if (prefix.size() == 1 && prefix[0] == u'<') {
|
cmp = new FilterParserFloatGeComparator(rating);
|
||||||
cmp = new FilterParserFloatLtComparator(rating);
|
break;
|
||||||
}
|
case FilterOperator::Lt:
|
||||||
else if (prefix == "<="_L1) {
|
cmp = new FilterParserFloatLtComparator(rating);
|
||||||
cmp = new FilterParserFloatLeComparator(rating);
|
break;
|
||||||
}
|
case FilterOperator::Le:
|
||||||
else {
|
cmp = new FilterParserFloatLeComparator(rating);
|
||||||
cmp = new FilterParserFloatEqComparator(rating);
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -433,8 +511,8 @@ FilterTree *FilterParser::createSearchTermTreeNode(const QString &column, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmp) {
|
if (filter_column != FilterColumn::Unknown && cmp != nullptr) {
|
||||||
return new FilterTreeColumnTerm(column, cmp);
|
return new FilterTreeColumnTerm(filter_column, cmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new FilterTreeTerm(new FilterParserTextContainsComparator(value));
|
return new FilterTreeTerm(new FilterParserTextContainsComparator(value));
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Strawberry Music Player
|
* Strawberry Music Player
|
||||||
* This file was part of Clementine.
|
* This file was part of Clementine.
|
||||||
* Copyright 2012, David Sansome <me@davidsansome.com>
|
* Copyright 2012, David Sansome <me@davidsansome.com>
|
||||||
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
* Copyright 2018-2026, Jonas Kvinge <jonas@jkvinge.net>
|
||||||
* Copyright 2023, Daniel Ostertag <daniel.ostertag@dakes.de>
|
* Copyright 2023, Daniel Ostertag <daniel.ostertag@dakes.de>
|
||||||
*
|
*
|
||||||
* Strawberry is free software: you can redistribute it and/or modify
|
* Strawberry is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Strawberry Music Player
|
* Strawberry Music Player
|
||||||
* This file was part of Clementine.
|
* Copyright 2018-2026, Jonas Kvinge <jonas@jkvinge.net>
|
||||||
* Copyright 2012, David Sansome <me@davidsansome.com>
|
|
||||||
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
|
||||||
*
|
*
|
||||||
* Strawberry is free software: you can redistribute it and/or modify
|
* Strawberry is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -22,7 +20,7 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
#include "filtertree.h"
|
#include "filtertree.h"
|
||||||
|
#include "filtercolumn.h"
|
||||||
#include "core/song.h"
|
#include "core/song.h"
|
||||||
|
|
||||||
using namespace Qt::Literals::StringLiterals;
|
using namespace Qt::Literals::StringLiterals;
|
||||||
@@ -30,28 +28,64 @@ using namespace Qt::Literals::StringLiterals;
|
|||||||
FilterTree::FilterTree() = default;
|
FilterTree::FilterTree() = default;
|
||||||
FilterTree::~FilterTree() = default;
|
FilterTree::~FilterTree() = default;
|
||||||
|
|
||||||
QVariant FilterTree::DataFromColumn(const QString &column, const Song &metadata) {
|
QVariant FilterTree::DataFromColumn(const FilterColumn filter_column, const Song &song) {
|
||||||
|
|
||||||
if (column == "albumartist"_L1) return metadata.effective_albumartist();
|
switch (filter_column) {
|
||||||
if (column == "artist"_L1) return metadata.artist();
|
case FilterColumn::AlbumArtist:
|
||||||
if (column == "album"_L1) return metadata.album();
|
return song.effective_albumartist();
|
||||||
if (column == "title"_L1) return metadata.PrettyTitle();
|
case FilterColumn::AlbumArtistSort:
|
||||||
if (column == "composer"_L1) return metadata.composer();
|
return song.effective_albumartistsort();
|
||||||
if (column == "performer"_L1) return metadata.performer();
|
case FilterColumn::Artist:
|
||||||
if (column == "grouping"_L1) return metadata.grouping();
|
return song.artist();
|
||||||
if (column == "genre"_L1) return metadata.genre();
|
case FilterColumn::ArtistSort:
|
||||||
if (column == "comment"_L1) return metadata.comment();
|
return song.effective_artistsort();
|
||||||
if (column == "track"_L1) return metadata.track();
|
case FilterColumn::Album:
|
||||||
if (column == "year"_L1) return metadata.year();
|
return song.album();
|
||||||
if (column == "length"_L1) return metadata.length_nanosec();
|
case FilterColumn::AlbumSort:
|
||||||
if (column == "samplerate"_L1) return metadata.samplerate();
|
return song.effective_albumsort();
|
||||||
if (column == "bitdepth"_L1) return metadata.bitdepth();
|
case FilterColumn::Title:
|
||||||
if (column == "bitrate"_L1) return metadata.bitrate();
|
return song.PrettyTitle();
|
||||||
if (column == "rating"_L1) return metadata.rating();
|
case FilterColumn::TitleSort:
|
||||||
if (column == "playcount"_L1) return metadata.playcount();
|
return song.effective_titlesort();
|
||||||
if (column == "skipcount"_L1) return metadata.skipcount();
|
case FilterColumn::Composer:
|
||||||
if (column == "filename"_L1) return metadata.basefilename();
|
return song.composer();
|
||||||
if (column == "url"_L1) return metadata.effective_url().toString();
|
case FilterColumn::ComposerSort:
|
||||||
|
return song.effective_composersort();
|
||||||
|
case FilterColumn::Performer:
|
||||||
|
return song.performer();
|
||||||
|
case FilterColumn::PerformerSort:
|
||||||
|
return song.effective_performersort();
|
||||||
|
case FilterColumn::Grouping:
|
||||||
|
return song.grouping();
|
||||||
|
case FilterColumn::Genre:
|
||||||
|
return song.genre();
|
||||||
|
case FilterColumn::Comment:
|
||||||
|
return song.comment();
|
||||||
|
case FilterColumn::Track:
|
||||||
|
return song.track();
|
||||||
|
case FilterColumn::Year:
|
||||||
|
return song.year();
|
||||||
|
case FilterColumn::Length:
|
||||||
|
return song.length_nanosec();
|
||||||
|
case FilterColumn::Samplerate:
|
||||||
|
return song.samplerate();
|
||||||
|
case FilterColumn::Bitdepth:
|
||||||
|
return song.bitdepth();
|
||||||
|
case FilterColumn::Bitrate:
|
||||||
|
return song.bitrate();
|
||||||
|
case FilterColumn::Rating:
|
||||||
|
return song.rating();
|
||||||
|
case FilterColumn::Playcount:
|
||||||
|
return song.playcount();
|
||||||
|
case FilterColumn::Skipcount:
|
||||||
|
return song.skipcount();
|
||||||
|
case FilterColumn::Filename:
|
||||||
|
return song.basefilename();
|
||||||
|
case FilterColumn::URL:
|
||||||
|
return song.effective_url().toString();
|
||||||
|
case FilterColumn::Unknown:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Strawberry Music Player
|
* Strawberry Music Player
|
||||||
* This file was part of Clementine.
|
* Copyright 2018-2026, Jonas Kvinge <jonas@jkvinge.net>
|
||||||
* Copyright 2012, David Sansome <me@davidsansome.com>
|
|
||||||
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
|
||||||
*
|
*
|
||||||
* Strawberry is free software: you can redistribute it and/or modify
|
* Strawberry is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -25,6 +23,7 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
#include "core/song.h"
|
#include "core/song.h"
|
||||||
|
#include "filtercolumn.h"
|
||||||
|
|
||||||
class FilterTree {
|
class FilterTree {
|
||||||
public:
|
public:
|
||||||
@@ -45,7 +44,7 @@ class FilterTree {
|
|||||||
virtual bool accept(const Song &song) const = 0;
|
virtual bool accept(const Song &song) const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static QVariant DataFromColumn(const QString &column, const Song &metadata);
|
static QVariant DataFromColumn(const FilterColumn filter_column, const Song &metadata);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Q_DISABLE_COPY(FilterTree)
|
Q_DISABLE_COPY(FilterTree)
|
||||||
|
|||||||
@@ -24,8 +24,8 @@
|
|||||||
#include "filtertreecolumnterm.h"
|
#include "filtertreecolumnterm.h"
|
||||||
#include "filterparsersearchtermcomparator.h"
|
#include "filterparsersearchtermcomparator.h"
|
||||||
|
|
||||||
FilterTreeColumnTerm::FilterTreeColumnTerm(const QString &column, FilterParserSearchTermComparator *comparator) : column_(column), cmp_(comparator) {}
|
FilterTreeColumnTerm::FilterTreeColumnTerm(const FilterColumn filter_column, FilterParserSearchTermComparator *comparator) : filter_column_(filter_column), cmp_(comparator) {}
|
||||||
|
|
||||||
bool FilterTreeColumnTerm::accept(const Song &song) const {
|
bool FilterTreeColumnTerm::accept(const Song &song) const {
|
||||||
return cmp_->Matches(DataFromColumn(column_, song));
|
return cmp_->Matches(DataFromColumn(filter_column_, song));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,20 +26,20 @@
|
|||||||
#include <QScopedPointer>
|
#include <QScopedPointer>
|
||||||
|
|
||||||
#include "filtertree.h"
|
#include "filtertree.h"
|
||||||
|
#include "filtercolumn.h"
|
||||||
#include "core/song.h"
|
#include "core/song.h"
|
||||||
|
|
||||||
class FilterParserSearchTermComparator;
|
class FilterParserSearchTermComparator;
|
||||||
|
|
||||||
class FilterTreeColumnTerm : public FilterTree {
|
class FilterTreeColumnTerm : public FilterTree {
|
||||||
public:
|
public:
|
||||||
explicit FilterTreeColumnTerm(const QString &column, FilterParserSearchTermComparator *comparator);
|
explicit FilterTreeColumnTerm(const FilterColumn filter_column, FilterParserSearchTermComparator *comparator);
|
||||||
|
|
||||||
FilterType type() const override { return FilterType::Column; }
|
FilterType type() const override { return FilterType::Column; }
|
||||||
bool accept(const Song &song) const override;
|
bool accept(const Song &song) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QString column_;
|
const FilterColumn filter_column_;
|
||||||
QScopedPointer<FilterParserSearchTermComparator> cmp_;
|
QScopedPointer<FilterParserSearchTermComparator> cmp_;
|
||||||
|
|
||||||
Q_DISABLE_COPY(FilterTreeColumnTerm)
|
Q_DISABLE_COPY(FilterTreeColumnTerm)
|
||||||
|
|||||||
Reference in New Issue
Block a user