[kde-doc-english] [amarok] /: Add new collection filter to find exact matches
Matěj Laitl
matej at laitl.cz
Sat Nov 5 19:40:45 UTC 2011
Git commit 3e7122a2879260b531f9b2df4bdeaf0710ae303f by Matěj Laitl, on behalf of Daniel Faust.
Committed on 05/11/2011 at 20:12.
Pushed by laitl into branch 'master'.
Add new collection filter to find exact matches
Searching for label:=pop finds songs labeled with 'pop' but not with
'electro pop'. While searching for label:pop finds songs labeled with
'pop' and 'electro pop'.
GUI is also updated.
REVIEW: 102252
BUG: 260004
GUI: edit collection search and edit dynamic playlist dialogs changed
slightly
DIGEST: Feature: new "exact" field:=value match in collection search
FIXED-IN: 2.5
M +2 -0 ChangeLog
M +7 -2 src/core-impl/collections/support/Expression.cpp
M +1 -1 src/core-impl/collections/support/Expression.h
M +10 -8 src/core-impl/collections/support/TextualQueryFilter.cpp
M +12 -4 src/dialogs/EditFilterDialog.cpp
M +33 -16 src/widgets/MetaQueryWidget.cpp
M +2 -2 src/widgets/MetaQueryWidget.h
http://commits.kde.org/amarok/3e7122a2879260b531f9b2df4bdeaf0710ae303f
diff --git a/ChangeLog b/ChangeLog
index 128b56a..382d07f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,8 @@ Amarok ChangeLog
Version 2.5.0-Beta 1
FEATURES:
+ * New "equals" match in collection filter - e.g. label:=pop finds songs
+ with label "pop" but not songs with label "electro pop". (BR 260004)
* Enable dropping tracks on empty area in Saved Playlists to create new
playlist.
* Addded a "create new playlist" action in the empty space of the Saved
diff --git a/src/core-impl/collections/support/Expression.cpp b/src/core-impl/collections/support/Expression.cpp
index 531850a..f341aba 100644
--- a/src/core-impl/collections/support/Expression.cpp
+++ b/src/core-impl/collections/support/Expression.cpp
@@ -63,7 +63,7 @@ void ExpressionParser::parseChar( const QChar &c )
handleMinus( c );
else if( c == ':' )
handleColon( c );
- else if( c == '>' || c == '<' )
+ else if( c == '=' || c == '>' || c == '<' )
handleMod( c );
else if( c == '"' )
handleQuote( c );
@@ -104,7 +104,12 @@ void ExpressionParser::handleMod( const QChar &c )
{
if( m_state == ExpectMod )
{
- m_element.match = ( c == '>' ) ? expression_element::More : expression_element::Less;
+ if( c == '=' )
+ m_element.match = expression_element::Equals;
+ else if( c == '>' )
+ m_element.match = expression_element::More;
+ else if( c == '<' )
+ m_element.match = expression_element::Less;
m_state = ExpectText;
}
else
diff --git a/src/core-impl/collections/support/Expression.h b/src/core-impl/collections/support/Expression.h
index 1e49f45..5f825a8 100644
--- a/src/core-impl/collections/support/Expression.h
+++ b/src/core-impl/collections/support/Expression.h
@@ -25,7 +25,7 @@ struct expression_element
QString field;
QString text;
bool negate: 1;
- enum { Contains, Less, More } match: 2;
+ enum { Contains, Equals, Less, More } match: 2;
expression_element(): negate( false ), match( Contains ) { }
};
typedef QList<expression_element> or_list;
diff --git a/src/core-impl/collections/support/TextualQueryFilter.cpp b/src/core-impl/collections/support/TextualQueryFilter.cpp
index 735772b..2a44a30 100644
--- a/src/core-impl/collections/support/TextualQueryFilter.cpp
+++ b/src/core-impl/collections/support/TextualQueryFilter.cpp
@@ -101,40 +101,42 @@ Collections::addTextualFilter( Collections::QueryMaker *qm, const QString &filte
break;
}
+ const bool matchEqual = ( elem.match == expression_element::Equals );
+
// TODO: Once we have MetaConstants.cpp use those functions here
if ( lcField.compare( "album", Qt::CaseInsensitive ) == 0 || lcField.compare( shortI18nForField( Meta::valAlbum ), Qt::CaseInsensitive ) == 0 )
{
if ( ( validFilters & Collections::QueryMaker::AlbumFilter ) == 0 ) continue;
- ADD_OR_EXCLUDE_FILTER( Meta::valAlbum, elem.text, false, false );
+ ADD_OR_EXCLUDE_FILTER( Meta::valAlbum, elem.text, matchEqual, matchEqual );
}
else if ( lcField.compare( "artist", Qt::CaseInsensitive ) == 0 || lcField.compare( shortI18nForField( Meta::valArtist ), Qt::CaseInsensitive ) == 0 )
{
if ( ( validFilters & Collections::QueryMaker::ArtistFilter ) == 0 ) continue;
- ADD_OR_EXCLUDE_FILTER( Meta::valArtist, elem.text, false, false );
+ ADD_OR_EXCLUDE_FILTER( Meta::valArtist, elem.text, matchEqual, matchEqual );
}
else if ( lcField.compare( "albumartist", Qt::CaseInsensitive ) == 0 || lcField.compare( shortI18nForField( Meta::valAlbumArtist ), Qt::CaseInsensitive ) == 0 )
{
if ( ( validFilters & Collections::QueryMaker::AlbumArtistFilter ) == 0 ) continue;
- ADD_OR_EXCLUDE_FILTER( Meta::valAlbumArtist, elem.text, false, false );
+ ADD_OR_EXCLUDE_FILTER( Meta::valAlbumArtist, elem.text, matchEqual, matchEqual );
}
else if ( lcField.compare( "genre", Qt::CaseInsensitive ) == 0 || lcField.compare( shortI18nForField( Meta::valGenre ), Qt::CaseInsensitive ) == 0)
{
if ( ( validFilters & Collections::QueryMaker::GenreFilter ) == 0 ) continue;
- ADD_OR_EXCLUDE_FILTER( Meta::valGenre, elem.text, false, false );
+ ADD_OR_EXCLUDE_FILTER( Meta::valGenre, elem.text, matchEqual, matchEqual );
}
else if ( lcField.compare( "title", Qt::CaseInsensitive ) == 0 || lcField.compare( shortI18nForField( Meta::valTitle ), Qt::CaseInsensitive ) == 0 )
{
if ( ( validFilters & Collections::QueryMaker::TitleFilter ) == 0 ) continue;
- ADD_OR_EXCLUDE_FILTER( Meta::valTitle, elem.text, false, false );
+ ADD_OR_EXCLUDE_FILTER( Meta::valTitle, elem.text, matchEqual, matchEqual );
}
else if ( lcField.compare( "composer", Qt::CaseInsensitive ) == 0 || lcField.compare( shortI18nForField( Meta::valComposer ), Qt::CaseInsensitive ) == 0 )
{
if ( ( validFilters & Collections::QueryMaker::ComposerFilter ) == 0 ) continue;
- ADD_OR_EXCLUDE_FILTER( Meta::valComposer, elem.text, false, false );
+ ADD_OR_EXCLUDE_FILTER( Meta::valComposer, elem.text, matchEqual, matchEqual );
}
else if( lcField.compare( "label", Qt::CaseInsensitive ) == 0 || lcField.compare( shortI18nForField( Meta::valLabel ), Qt::CaseInsensitive ) == 0 )
{
- ADD_OR_EXCLUDE_FILTER( Meta::valLabel, elem.text, false, false );
+ ADD_OR_EXCLUDE_FILTER( Meta::valLabel, elem.text, matchEqual, matchEqual );
}
else if ( lcField.compare( "year", Qt::CaseInsensitive ) == 0 || lcField.compare( shortI18nForField( Meta::valYear ), Qt::CaseInsensitive ) == 0)
{
@@ -147,7 +149,7 @@ Collections::addTextualFilter( Collections::QueryMaker *qm, const QString &filte
}
else if( lcField.compare( "comment", Qt::CaseInsensitive ) == 0 || lcField.compare( shortI18nForField( Meta::valComment ), Qt::CaseInsensitive ) == 0 )
{
- ADD_OR_EXCLUDE_FILTER( Meta::valComment, elem.text, false, false );
+ ADD_OR_EXCLUDE_FILTER( Meta::valComment, elem.text, matchEqual, matchEqual );
}
else if( lcField.compare( "filename", Qt::CaseInsensitive ) == 0 || lcField.compare( shortI18nForField( Meta::valUrl ), Qt::CaseInsensitive ) == 0 )
{
diff --git a/src/dialogs/EditFilterDialog.cpp b/src/dialogs/EditFilterDialog.cpp
index 91628ff..58c2956 100644
--- a/src/dialogs/EditFilterDialog.cpp
+++ b/src/dialogs/EditFilterDialog.cpp
@@ -300,20 +300,28 @@ EditFilterDialog::parseTextFilter( const QString &text )
{
switch( elem.match )
{
- case 0:
+ case expression_element::Equals:
filter.filter.condition = MetaQueryWidget::Equals;
break;
- case 1:
+ case expression_element::Less:
filter.filter.condition = MetaQueryWidget::LessThan;
break;
- case 2:
+ case expression_element::More:
filter.filter.condition = MetaQueryWidget::GreaterThan;
break;
}
}
else
{
- filter.filter.condition = MetaQueryWidget::Contains;
+ switch( elem.match )
+ {
+ case expression_element::Contains:
+ filter.filter.condition = MetaQueryWidget::Contains;
+ break;
+ case expression_element::Equals:
+ filter.filter.condition = MetaQueryWidget::Equals;
+ break;
+ }
filter.filter.value = elem.text;
}
diff --git a/src/widgets/MetaQueryWidget.cpp b/src/widgets/MetaQueryWidget.cpp
index 5db1ded..57b622f 100644
--- a/src/widgets/MetaQueryWidget.cpp
+++ b/src/widgets/MetaQueryWidget.cpp
@@ -463,23 +463,27 @@ MetaQueryWidget::makeCompareSelection()
else if( isDate(field) )
{
m_compareSelection = new KComboBox();
- m_compareSelection->addItem( conditionToString( Equals, true ), (int)Equals );
- m_compareSelection->addItem( conditionToString( LessThan, true ), (int)LessThan );
- m_compareSelection->addItem( conditionToString( GreaterThan, true ), (int)GreaterThan );
-
- m_compareSelection->addItem( conditionToString( Between, true ), (int)Between );
- m_compareSelection->addItem( conditionToString( OlderThan, true ), (int)OlderThan );
+ m_compareSelection->addItem( conditionToString( Equals, field ), (int)Equals );
+ m_compareSelection->addItem( conditionToString( LessThan, field ), (int)LessThan );
+ m_compareSelection->addItem( conditionToString( GreaterThan, field ), (int)GreaterThan );
+
+ m_compareSelection->addItem( conditionToString( Between, field ), (int)Between );
+ m_compareSelection->addItem( conditionToString( OlderThan, field ), (int)OlderThan );
}
else if( isNumeric(field) )
{
m_compareSelection = new KComboBox();
- m_compareSelection->addItem( conditionToString( Equals ), (int)Equals );
- m_compareSelection->addItem( conditionToString( LessThan ), (int)LessThan );
- m_compareSelection->addItem( conditionToString( GreaterThan ), (int)GreaterThan );
- m_compareSelection->addItem( conditionToString( Between ), (int)Between );
+ m_compareSelection->addItem( conditionToString( Equals, field ), (int)Equals );
+ m_compareSelection->addItem( conditionToString( LessThan, field ), (int)LessThan );
+ m_compareSelection->addItem( conditionToString( GreaterThan, field ), (int)GreaterThan );
+ m_compareSelection->addItem( conditionToString( Between, field ), (int)Between );
}
else
- return;
+ {
+ m_compareSelection = new KComboBox();
+ m_compareSelection->addItem( conditionToString( Contains, field ), (int)Contains );
+ m_compareSelection->addItem( conditionToString( Equals, field ), (int)Equals );
+ }
// -- select the correct entry (even if the condition is not one of the selection)
int index = m_compareSelection->findData( int(m_filter.condition) );
@@ -632,7 +636,7 @@ MetaQueryWidget::makeFormatComboSelection()
{
combo->addItem(filetypes.at(listpos),listpos);
}
-
+
int index = m_fieldSelection->findData( (int)m_filter.numValue );
combo->setCurrentIndex( index == -1 ? 0 : index );
@@ -849,9 +853,9 @@ MetaQueryWidget::isDate( qint64 field )
}
QString
-MetaQueryWidget::conditionToString( FilterCondition condition, bool isDate )
+MetaQueryWidget::conditionToString( FilterCondition condition, qint64 field )
{
- if( isDate )
+ if( isDate(field) )
{
switch( condition )
{
@@ -869,7 +873,7 @@ MetaQueryWidget::conditionToString( FilterCondition condition, bool isDate )
; // fall through
}
}
- else
+ else if( isNumeric(field) )
{
switch( condition )
{
@@ -881,6 +885,16 @@ MetaQueryWidget::conditionToString( FilterCondition condition, bool isDate )
return i18n("greater than");
case Between:
return i18nc( "a numerical tag (like year or track number) is between two values", "between" );
+ default:
+ ; // fall through
+ }
+ }
+ else
+ {
+ switch( condition )
+ {
+ case Equals:
+ return i18nc("an alphabetical tag (like title or artist name) equals some string","equals");
case Contains:
return i18nc("an alphabetical tag (like title or artist name) contains some string", "contains");
default:
@@ -932,7 +946,10 @@ QString MetaQueryWidget::Filter::toString( bool invert ) const
{
case Equals:
{
- result += strValue1;
+ if( MetaQueryWidget::isNumeric(field) )
+ result += strValue1;
+ else
+ result += '=' + QString( "\"%1\"" ).arg( value );
if( invert )
result.prepend( QChar('-') );
break;
diff --git a/src/widgets/MetaQueryWidget.h b/src/widgets/MetaQueryWidget.h
index 3db49d3..3974fb7 100644
--- a/src/widgets/MetaQueryWidget.h
+++ b/src/widgets/MetaQueryWidget.h
@@ -129,9 +129,9 @@ class MetaQueryWidget : public QWidget
static bool isDate( qint64 field );
/** Returns a localized text of the condition.
- @param isDate True if the condition is meant for a date (as it has slightly different texts)
+ @param field Needed in order to test whether the field is a date, numeric or a string since the texts differ slightly
*/
- static QString conditionToString( FilterCondition condition, bool isDate = false );
+ static QString conditionToString( FilterCondition condition, qint64 field );
public slots:
More information about the kde-doc-english
mailing list