From 4ab6f359d50bb23c116b6dca2a8fc02f26f5cd7a Mon Sep 17 00:00:00 2001 From: kleinfreund Date: Mon, 12 Feb 2018 17:59:43 +0100 Subject: [PATCH] Smart Playlists: Add empty/not empty operators --- src/smartplaylists/searchterm.cpp | 16 ++++++++++++- src/smartplaylists/searchterm.h | 5 ++++- src/smartplaylists/searchtermwidget.cpp | 30 ++++++++++++++++++++++--- src/smartplaylists/searchtermwidget.ui | 10 +++++++++ 4 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/smartplaylists/searchterm.cpp b/src/smartplaylists/searchterm.cpp index c75cfb368..9e3675c0a 100644 --- a/src/smartplaylists/searchterm.cpp +++ b/src/smartplaylists/searchterm.cpp @@ -128,6 +128,10 @@ QString SearchTerm::ToSql() const { } else { return col + " <> " + value; } + case Op_Empty: + return col + " = ''"; + case Op_NotEmpty: + return col + " <> ''"; } return QString(); @@ -143,6 +147,11 @@ bool SearchTerm::is_valid() const { switch (TypeOf(field_)) { case Type_Text: + if (operator_ == SearchTerm::Op_Empty || operator_ == SearchTerm::Op_NotEmpty) { + return true; + } + // Empty fields should be possible. + // All values for Type_Text should be valid. return !value_.toString().isEmpty(); case Type_Date: return value_.toInt() != 0; @@ -199,7 +208,8 @@ OperatorList SearchTerm::OperatorsForType(Type type) { switch (type) { case Type_Text: return OperatorList() << Op_Contains << Op_NotContains << Op_Equals - << Op_NotEquals << Op_StartsWith << Op_EndsWith; + << Op_NotEquals << Op_Empty << Op_NotEmpty + << Op_StartsWith << Op_EndsWith; case Type_Date: return OperatorList() << Op_Equals << Op_NotEquals << Op_GreaterThan << Op_LessThan << Op_NumericDate @@ -249,6 +259,10 @@ QString SearchTerm::OperatorText(Type type, Operator op) { return QObject::tr("equals"); case Op_NotEquals: return QObject::tr("not equals"); + case Op_Empty: + return QObject::tr("empty"); + case Op_NotEmpty: + return QObject::tr("not empty"); default: return QString(); } diff --git a/src/smartplaylists/searchterm.h b/src/smartplaylists/searchterm.h index 07914ba1a..c3b031a70 100644 --- a/src/smartplaylists/searchterm.h +++ b/src/smartplaylists/searchterm.h @@ -80,7 +80,10 @@ class SearchTerm { // For numeric dates (e.g. not in the last X days) Op_NumericDateNot = 10, - // Next value = 11 + Op_Empty = 11, + Op_NotEmpty = 12, + + // Next value = 13 }; enum Type { diff --git a/src/smartplaylists/searchtermwidget.cpp b/src/smartplaylists/searchtermwidget.cpp index 80bc4aa2f..7153e418f 100644 --- a/src/smartplaylists/searchtermwidget.cpp +++ b/src/smartplaylists/searchtermwidget.cpp @@ -163,7 +163,11 @@ void SearchTermWidget::FieldChanged(int index) { page = ui_->page_rating; break; case SearchTerm::Type_Text: - page = ui_->page_text; + if (ui_->op->currentIndex() == 4 || ui_->op->currentIndex() == 5) { + page = ui_->page_empty; + } else { + page = ui_->page_text; + } break; case SearchTerm::Type_Invalid: page = nullptr; @@ -189,8 +193,21 @@ void SearchTermWidget::FieldChanged(int index) { } void SearchTermWidget::OpChanged(int index) { + if ((ui_->value_stack->currentWidget() == ui_->page_text) || + (ui_->value_stack->currentWidget() == ui_->page_empty)) { + QWidget* page = nullptr; + // This assumes the operators always appear in the same order. + // Needs a better way for checking which is the current operator. + if (index == 4 || index == 5) { + page = ui_->page_empty; + } else { + page = ui_->page_text; + } + ui_->value_stack->setCurrentWidget(page); + } + // We need to change the page only in the following case - if ((ui_->value_stack->currentWidget() == ui_->page_date) || + else if ((ui_->value_stack->currentWidget() == ui_->page_date) || (ui_->value_stack->currentWidget() == ui_->page_date_numeric) || (ui_->value_stack->currentWidget() == ui_->page_date_relative)) { QWidget* page = nullptr; @@ -203,6 +220,7 @@ void SearchTermWidget::OpChanged(int index) { } ui_->value_stack->setCurrentWidget(page); } + emit Changed(); } @@ -267,7 +285,11 @@ void SearchTermWidget::SetTerm(const SearchTerm& term) { // The value depends on the data type switch (SearchTerm::TypeOf(term.field_)) { case SearchTerm::Type_Text: - ui_->value_text->setText(term.value_.toString()); + if (ui_->value_stack->currentWidget() == ui_->page_empty) { + ui_->value_text->setText(""); + } else { + ui_->value_text->setText(term.value_.toString()); + } break; case SearchTerm::Type_Number: @@ -313,6 +335,8 @@ SearchTerm SearchTermWidget::Term() const { const QWidget* value_page = ui_->value_stack->currentWidget(); if (value_page == ui_->page_text) { ret.value_ = ui_->value_text->text(); + } else if (value_page == ui_->page_empty) { + ret.value_ = ""; } else if (value_page == ui_->page_number) { ret.value_ = ui_->value_number->value(); } else if (value_page == ui_->page_date) { diff --git a/src/smartplaylists/searchtermwidget.ui b/src/smartplaylists/searchtermwidget.ui index 544b50e19..4609e16f3 100644 --- a/src/smartplaylists/searchtermwidget.ui +++ b/src/smartplaylists/searchtermwidget.ui @@ -71,6 +71,16 @@ + + + + 0 + + + 0 + + +