[rhythmbox] rhythmdb: add 'not equal' property query operator (bug #612867)



commit c852f5a51e5990b062af37ddb8e388df436f8e09
Author: Jonathan Matthew <jonathan d14n org>
Date:   Fri Jun 18 18:43:26 2010 +1000

    rhythmdb: add 'not equal' property query operator (bug #612867)

 rhythmdb/rhythmdb-query.c             |   43 ++++++++++++++++
 rhythmdb/rhythmdb-tree.c              |    4 ++
 rhythmdb/rhythmdb.c                   |    2 +
 rhythmdb/rhythmdb.h                   |    2 +
 tests/test-rhythmdb-query-model.c     |   90 ++++++++++++++++++++++++++++++---
 widgets/rb-query-creator-properties.c |    4 ++
 6 files changed, 137 insertions(+), 8 deletions(-)
---
diff --git a/rhythmdb/rhythmdb-query.c b/rhythmdb/rhythmdb-query.c
index dfd5098..487b223 100644
--- a/rhythmdb/rhythmdb-query.c
+++ b/rhythmdb/rhythmdb-query.c
@@ -46,12 +46,14 @@
 #define RB_PARSE_PREFIX (xmlChar *) "prefix"
 #define RB_PARSE_SUFFIX (xmlChar *) "suffix"
 #define RB_PARSE_EQUALS (xmlChar *) "equals"
+#define RB_PARSE_NOT_EQUAL (xmlChar *) "not-equal"
 #define RB_PARSE_DISJ (xmlChar *) "disjunction"
 #define RB_PARSE_GREATER (xmlChar *) "greater"
 #define RB_PARSE_LESS (xmlChar *) "less"
 #define RB_PARSE_CURRENT_TIME_WITHIN (xmlChar *) "current-time-within"
 #define RB_PARSE_CURRENT_TIME_NOT_WITHIN (xmlChar *) "current-time-not-within"
 #define RB_PARSE_YEAR_EQUALS RB_PARSE_EQUALS
+#define RB_PARSE_YEAR_NOT_EQUAL RB_PARSE_NOT_EQUAL
 #define RB_PARSE_YEAR_GREATER RB_PARSE_GREATER
 #define RB_PARSE_YEAR_LESS RB_PARSE_LESS
 
@@ -136,6 +138,7 @@ rhythmdb_query_parse_valist (RhythmDB *db, va_list args)
 			data->subquery = rhythmdb_query_copy (va_arg (args, GPtrArray *));
 			break;
 		case RHYTHMDB_QUERY_PROP_EQUALS:
+		case RHYTHMDB_QUERY_PROP_NOT_EQUAL:
 		case RHYTHMDB_QUERY_PROP_LIKE:
 		case RHYTHMDB_QUERY_PROP_NOT_LIKE:
 		case RHYTHMDB_QUERY_PROP_PREFIX:
@@ -145,6 +148,7 @@ rhythmdb_query_parse_valist (RhythmDB *db, va_list args)
 		case RHYTHMDB_QUERY_PROP_CURRENT_TIME_WITHIN:
 		case RHYTHMDB_QUERY_PROP_CURRENT_TIME_NOT_WITHIN:
 		case RHYTHMDB_QUERY_PROP_YEAR_EQUALS:
+		case RHYTHMDB_QUERY_PROP_YEAR_NOT_EQUAL:
 		case RHYTHMDB_QUERY_PROP_YEAR_GREATER:
 		case RHYTHMDB_QUERY_PROP_YEAR_LESS:
 			data->propid = va_arg (args, guint);
@@ -275,6 +279,7 @@ rhythmdb_query_append_params (RhythmDB *db, GPtrArray *query,
 		data->subquery = rhythmdb_query_copy (g_value_get_pointer (value));
 		break;
 	case RHYTHMDB_QUERY_PROP_EQUALS:
+	case RHYTHMDB_QUERY_PROP_NOT_EQUAL:
 	case RHYTHMDB_QUERY_PROP_LIKE:
 	case RHYTHMDB_QUERY_PROP_NOT_LIKE:
 	case RHYTHMDB_QUERY_PROP_PREFIX:
@@ -284,6 +289,7 @@ rhythmdb_query_append_params (RhythmDB *db, GPtrArray *query,
 	case RHYTHMDB_QUERY_PROP_CURRENT_TIME_WITHIN:
 	case RHYTHMDB_QUERY_PROP_CURRENT_TIME_NOT_WITHIN:
 	case RHYTHMDB_QUERY_PROP_YEAR_EQUALS:
+	case RHYTHMDB_QUERY_PROP_YEAR_NOT_EQUAL:
 	case RHYTHMDB_QUERY_PROP_YEAR_GREATER:
 	case RHYTHMDB_QUERY_PROP_YEAR_LESS:
 		data->propid = prop;
@@ -319,6 +325,7 @@ rhythmdb_query_free (GPtrArray *query)
 			rhythmdb_query_free (data->subquery);
 			break;
 		case RHYTHMDB_QUERY_PROP_EQUALS:
+		case RHYTHMDB_QUERY_PROP_NOT_EQUAL:
 		case RHYTHMDB_QUERY_PROP_LIKE:
 		case RHYTHMDB_QUERY_PROP_NOT_LIKE:
 		case RHYTHMDB_QUERY_PROP_PREFIX:
@@ -328,6 +335,7 @@ rhythmdb_query_free (GPtrArray *query)
 		case RHYTHMDB_QUERY_PROP_CURRENT_TIME_WITHIN:
 		case RHYTHMDB_QUERY_PROP_CURRENT_TIME_NOT_WITHIN:
 		case RHYTHMDB_QUERY_PROP_YEAR_EQUALS:
+		case RHYTHMDB_QUERY_PROP_YEAR_NOT_EQUAL:
 		case RHYTHMDB_QUERY_PROP_YEAR_GREATER:
 		case RHYTHMDB_QUERY_PROP_YEAR_LESS:
 			g_value_unset (data->val);
@@ -524,11 +532,21 @@ rhythmdb_query_serialize (RhythmDB *db, GPtrArray *query,
 			xmlSetProp (subnode, RB_PARSE_PROP, rhythmdb_nice_elt_name_from_propid (db, data->propid));
 			write_encoded_gvalue (db, subnode, data->propid, data->val);
 			break;
+		case RHYTHMDB_QUERY_PROP_NOT_EQUAL:
+			subnode = xmlNewChild (node, NULL, RB_PARSE_NOT_EQUAL, NULL);
+			xmlSetProp (subnode, RB_PARSE_PROP, rhythmdb_nice_elt_name_from_propid (db, data->propid));
+			write_encoded_gvalue (db, subnode, data->propid, data->val);
+			break;
 		case RHYTHMDB_QUERY_PROP_YEAR_EQUALS:
 			subnode = xmlNewChild (node, NULL, RB_PARSE_YEAR_EQUALS, NULL);
 			xmlSetProp (subnode, RB_PARSE_PROP, rhythmdb_nice_elt_name_from_propid (db, data->propid));
 			write_encoded_gvalue (db, subnode, data->propid, data->val);
 			break;
+		case RHYTHMDB_QUERY_PROP_YEAR_NOT_EQUAL:
+			subnode = xmlNewChild (node, NULL, RB_PARSE_YEAR_NOT_EQUAL, NULL);
+			xmlSetProp (subnode, RB_PARSE_PROP, rhythmdb_nice_elt_name_from_propid (db, data->propid));
+			write_encoded_gvalue (db, subnode, data->propid, data->val);
+			break;
 		case RHYTHMDB_QUERY_DISJUNCTION:
 			subnode = xmlNewChild (node, NULL, RB_PARSE_DISJ, NULL);
 			break;
@@ -620,6 +638,15 @@ rhythmdb_query_deserialize (RhythmDB *db, xmlNodePtr parent)
 			else
 				data->type = RHYTHMDB_QUERY_PROP_EQUALS;
 			xmlFree (prop);
+		} else if (!xmlStrcmp (child->name, RB_PARSE_NOT_EQUAL)) {
+			xmlChar* prop;
+
+			prop = xmlGetProp(child, RB_PARSE_PROP);
+			if (!xmlStrcmp(prop, (xmlChar *)"date"))
+				data->type = RHYTHMDB_QUERY_PROP_YEAR_NOT_EQUAL;
+			else
+				data->type = RHYTHMDB_QUERY_PROP_NOT_EQUAL;
+			xmlFree (prop);
 		} else if (!xmlStrcmp (child->name, RB_PARSE_GREATER)) {
 			xmlChar* prop;
 
@@ -650,6 +677,7 @@ rhythmdb_query_deserialize (RhythmDB *db, xmlNodePtr parent)
 		    || !xmlStrcmp (child->name, RB_PARSE_PREFIX)
 		    || !xmlStrcmp (child->name, RB_PARSE_SUFFIX)
 		    || !xmlStrcmp (child->name, RB_PARSE_EQUALS)
+		    || !xmlStrcmp (child->name, RB_PARSE_NOT_EQUAL)
 		    || !xmlStrcmp (child->name, RB_PARSE_GREATER)
 		    || !xmlStrcmp (child->name, RB_PARSE_LESS)
 		    || !xmlStrcmp (child->name, RB_PARSE_YEAR_EQUALS)
@@ -789,6 +817,15 @@ rhythmdb_query_preprocess (RhythmDB *db, GPtrArray *query)
 									       RHYTHMDB_QUERY_PROP_LESS, data->propid, end,
 									       RHYTHMDB_QUERY_END);
 					break;
+				case RHYTHMDB_QUERY_PROP_YEAR_NOT_EQUAL:
+					restart_criteria = TRUE;
+					data->type = RHYTHMDB_QUERY_SUBQUERY;
+					data->subquery = rhythmdb_query_parse (db,
+									       RHYTHMDB_QUERY_PROP_LESS, data->propid, begin-1,
+									       RHYTHMDB_QUERY_DISJUNCTION,
+									       RHYTHMDB_QUERY_PROP_GREATER, data->propid, end+1,
+									       RHYTHMDB_QUERY_END);
+					break;
 
 				case RHYTHMDB_QUERY_PROP_YEAR_LESS:
 					restart_criteria = TRUE;
@@ -954,9 +991,15 @@ rhythmdb_query_to_string (RhythmDB *db, GPtrArray *query)
 		case RHYTHMDB_QUERY_PROP_EQUALS:
 			fmt = "(%s == %s)";
 			break;
+		case RHYTHMDB_QUERY_PROP_NOT_EQUAL:
+			fmt = "(%s != %s)";
+			break;
 		case RHYTHMDB_QUERY_PROP_YEAR_EQUALS:
 			fmt = "(year(%s) == %s)";
 			break;
+		case RHYTHMDB_QUERY_PROP_YEAR_NOT_EQUAL:
+			fmt = "(year(%s) != %s)";
+			break;
 		case RHYTHMDB_QUERY_DISJUNCTION:
 			g_string_append_printf (buf, " || ");
 			break;
diff --git a/rhythmdb/rhythmdb-tree.c b/rhythmdb/rhythmdb-tree.c
index c99e475..92c8889 100644
--- a/rhythmdb/rhythmdb-tree.c
+++ b/rhythmdb/rhythmdb-tree.c
@@ -1993,6 +1993,9 @@ evaluate_conjunctive_subquery (RhythmDBTree *dbtree,
 		case RHYTHMDB_QUERY_PROP_EQUALS:
 			RHYTHMDB_PROPERTY_COMPARE (!=)
 			break;
+		case RHYTHMDB_QUERY_PROP_NOT_EQUAL:
+			RHYTHMDB_PROPERTY_COMPARE (==)
+			break;
 		case RHYTHMDB_QUERY_PROP_GREATER:
 			RHYTHMDB_PROPERTY_COMPARE (<)
 			break;
@@ -2002,6 +2005,7 @@ evaluate_conjunctive_subquery (RhythmDBTree *dbtree,
 		case RHYTHMDB_QUERY_END:
 		case RHYTHMDB_QUERY_DISJUNCTION:
 		case RHYTHMDB_QUERY_PROP_YEAR_EQUALS:
+		case RHYTHMDB_QUERY_PROP_YEAR_NOT_EQUAL:
 		case RHYTHMDB_QUERY_PROP_YEAR_LESS:
 		case RHYTHMDB_QUERY_PROP_YEAR_GREATER:
 			g_assert_not_reached ();
diff --git a/rhythmdb/rhythmdb.c b/rhythmdb/rhythmdb.c
index 206a002..14e789a 100644
--- a/rhythmdb/rhythmdb.c
+++ b/rhythmdb/rhythmdb.c
@@ -4384,6 +4384,7 @@ rhythmdb_query_type_get_type (void)
 			ENUM_ENTRY (RHYTHMDB_QUERY_DISJUNCTION, "disjunctive-marker"),
 			ENUM_ENTRY (RHYTHMDB_QUERY_SUBQUERY, "subquery"),
 			ENUM_ENTRY (RHYTHMDB_QUERY_PROP_EQUALS, "equals"),
+			ENUM_ENTRY (RHYTHMDB_QUERY_PROP_NOT_EQUAL, "not-equal"),
 			ENUM_ENTRY (RHYTHMDB_QUERY_PROP_LIKE, "fuzzy-match"),
 			ENUM_ENTRY (RHYTHMDB_QUERY_PROP_NOT_LIKE, "inverted-fuzzy-match"),
 			ENUM_ENTRY (RHYTHMDB_QUERY_PROP_PREFIX, "starts-with"),
@@ -4393,6 +4394,7 @@ rhythmdb_query_type_get_type (void)
 			ENUM_ENTRY (RHYTHMDB_QUERY_PROP_CURRENT_TIME_WITHIN, "within-current-time"),
 			ENUM_ENTRY (RHYTHMDB_QUERY_PROP_CURRENT_TIME_NOT_WITHIN, "not-within-current-time"),
 			ENUM_ENTRY (RHYTHMDB_QUERY_PROP_YEAR_EQUALS, "year-equals"),
+			ENUM_ENTRY (RHYTHMDB_QUERY_PROP_YEAR_NOT_EQUAL, "year-not-equals"),
 			ENUM_ENTRY (RHYTHMDB_QUERY_PROP_YEAR_GREATER, "year-greater-than"),
 			ENUM_ENTRY (RHYTHMDB_QUERY_PROP_YEAR_LESS, "year-less-than"),
 			{ 0, 0, 0 }
diff --git a/rhythmdb/rhythmdb.h b/rhythmdb/rhythmdb.h
index d2453a2..82eb000 100644
--- a/rhythmdb/rhythmdb.h
+++ b/rhythmdb/rhythmdb.h
@@ -128,6 +128,7 @@ typedef enum
 
 	/* general */
 	RHYTHMDB_QUERY_PROP_EQUALS,
+	RHYTHMDB_QUERY_PROP_NOT_EQUAL,
 
 	/* string */
 	RHYTHMDB_QUERY_PROP_LIKE,
@@ -143,6 +144,7 @@ typedef enum
 	RHYTHMDB_QUERY_PROP_CURRENT_TIME_WITHIN,
 	RHYTHMDB_QUERY_PROP_CURRENT_TIME_NOT_WITHIN,
 	RHYTHMDB_QUERY_PROP_YEAR_EQUALS,
+	RHYTHMDB_QUERY_PROP_YEAR_NOT_EQUAL,
 	RHYTHMDB_QUERY_PROP_YEAR_GREATER,
 	RHYTHMDB_QUERY_PROP_YEAR_LESS,
 } RhythmDBQueryType;
diff --git a/tests/test-rhythmdb-query-model.c b/tests/test-rhythmdb-query-model.c
index c2c6083..5c801b8 100644
--- a/tests/test-rhythmdb-query-model.c
+++ b/tests/test-rhythmdb-query-model.c
@@ -36,11 +36,40 @@
 #include "rb-file-helpers.h"
 #include "rb-util.h"
 
+static void
+test_query_eval (RhythmDB *db, RhythmDBQuery *query, RhythmDBEntry *entry, gboolean expected, const char *what)
+{
+	RhythmDBQueryModel *model;
+	RhythmDBQuery *processed;
+	GtkTreeIter iter = {0,};
+
+	/* direct evaluation - need to preprocess it first */
+	processed = rhythmdb_query_copy (query);
+	rhythmdb_query_preprocess (db, processed);
+	fail_unless (rhythmdb_evaluate_query (db, processed, entry) == expected, what);
+	rhythmdb_query_free (processed);
+
+	/* query evaluation - query is preprocessed by rhythmdb */
+	model = rhythmdb_query_model_new_empty (db);
+	rhythmdb_do_full_query_parsed (db, RHYTHMDB_QUERY_RESULTS (model), query);
+	fail_unless (rhythmdb_query_model_entry_to_iter (model, entry, &iter) == expected, what);
+	g_object_unref (model);
+}
+
+static guint32
+year_to_julian (guint32 year)
+{
+	GDate v = {0,};
+	g_date_set_dmy (&v, 1, G_DATE_JANUARY, year);
+	return g_date_get_julian (&v);
+}
+
 START_TEST (test_rhythmdb_db_queries)
 {
 	RhythmDBEntry *entry = NULL;
 	RhythmDBQuery *query;
 	GValue val = {0,};
+	GDate testdate = {0,};
 
 	start_test_case ();
 
@@ -67,6 +96,12 @@ START_TEST (test_rhythmdb_db_queries)
 	rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_TITLE, &val);
 	g_value_unset (&val);
 
+	g_date_set_dmy (&testdate, 1, 1, 1989);
+	g_value_init (&val, G_TYPE_ULONG);
+	g_value_set_ulong (&val, g_date_get_julian (&testdate));
+	rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_DATE, &val);
+	g_value_unset (&val);
+
 	rhythmdb_commit (db);
 
 	/* basic queries and conjunctions */
@@ -74,7 +109,7 @@ START_TEST (test_rhythmdb_db_queries)
 				      RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TYPE, RHYTHMDB_ENTRY_TYPE_IGNORE,
 				      RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TITLE, "Sin",
 				      RHYTHMDB_QUERY_END);
-	fail_unless (rhythmdb_evaluate_query (db, query, entry), "query evaluated incorrectly");
+	test_query_eval (db, query, entry, TRUE, "title query evaluated incorrectly");
 	rhythmdb_query_free (query);
 
 	end_step ();
@@ -82,7 +117,7 @@ START_TEST (test_rhythmdb_db_queries)
 	query = rhythmdb_query_parse (db,
 				      RHYTHMDB_QUERY_PROP_LIKE, RHYTHMDB_PROP_ARTIST, "Nine Inch",
 				      RHYTHMDB_QUERY_END);
-	fail_unless (rhythmdb_evaluate_query (db, query, entry), "query evaluated incorrectly");
+	test_query_eval (db, query, entry, TRUE, "artist query evaluated incorrectly");
 	rhythmdb_query_free (query);
 
 	end_step ();
@@ -90,7 +125,7 @@ START_TEST (test_rhythmdb_db_queries)
 	query = rhythmdb_query_parse (db,
 				      RHYTHMDB_QUERY_PROP_LIKE, RHYTHMDB_PROP_ALBUM, "Load",
 				      RHYTHMDB_QUERY_END);
-	fail_if (rhythmdb_evaluate_query (db, query, entry), "query evaluated incorrectly");
+	test_query_eval (db, query, entry, FALSE, "album query evaluated incorrectly");
 	rhythmdb_query_free (query);
 
 	end_step ();
@@ -98,8 +133,47 @@ START_TEST (test_rhythmdb_db_queries)
 	query = rhythmdb_query_parse (db,
 				      RHYTHMDB_QUERY_PROP_LIKE, RHYTHMDB_PROP_SEARCH_MATCH, "Pretty Nine",
 				      RHYTHMDB_QUERY_END);
-	rhythmdb_query_preprocess (db, query);
-	fail_unless (rhythmdb_evaluate_query (db, query, entry), "query evaluated incorrectly");
+	test_query_eval (db, query, entry, TRUE, "search query evaluated incorrectly");
+	rhythmdb_query_free (query);
+
+	end_step ();
+
+	query = rhythmdb_query_parse (db,
+				      RHYTHMDB_QUERY_PROP_NOT_EQUAL, RHYTHMDB_PROP_TITLE, "Head Like A Hole",
+				      RHYTHMDB_QUERY_END);
+	test_query_eval (db, query, entry, TRUE, "title != query evaluated incorrectly");
+	rhythmdb_query_free (query);
+
+	end_step ();
+
+	query = rhythmdb_query_parse (db,
+				      RHYTHMDB_QUERY_PROP_YEAR_EQUALS, RHYTHMDB_PROP_DATE, year_to_julian (1989),
+				      RHYTHMDB_QUERY_END);
+	test_query_eval (db, query, entry, TRUE, "year == query evaluated incorrectly");
+	rhythmdb_query_free (query);
+
+	end_step ();
+
+	query = rhythmdb_query_parse (db,
+				      RHYTHMDB_QUERY_PROP_YEAR_NOT_EQUAL, RHYTHMDB_PROP_DATE, year_to_julian (1990),
+				      RHYTHMDB_QUERY_END);
+	test_query_eval (db, query, entry, TRUE, "year != query evaluated incorrectly");
+	rhythmdb_query_free (query);
+
+	end_step ();
+
+	query = rhythmdb_query_parse (db,
+				      RHYTHMDB_QUERY_PROP_YEAR_NOT_EQUAL, RHYTHMDB_PROP_DATE, year_to_julian (1988),
+				      RHYTHMDB_QUERY_END);
+	test_query_eval (db, query, entry, TRUE, "year != query evaluated incorrectly");
+	rhythmdb_query_free (query);
+
+	end_step ();
+
+	query = rhythmdb_query_parse (db,
+				      RHYTHMDB_QUERY_PROP_YEAR_NOT_EQUAL, RHYTHMDB_PROP_DATE, year_to_julian (1989),
+				      RHYTHMDB_QUERY_END);
+	test_query_eval (db, query, entry, FALSE, "year != query evaluated incorrectly");
 	rhythmdb_query_free (query);
 
 	end_step ();
@@ -110,7 +184,7 @@ START_TEST (test_rhythmdb_db_queries)
 				      RHYTHMDB_QUERY_DISJUNCTION,
 				      RHYTHMDB_QUERY_PROP_LIKE, RHYTHMDB_PROP_TITLE, "Son",
 				      RHYTHMDB_QUERY_END);
-	fail_unless (rhythmdb_evaluate_query (db, query, entry), "query evaluated incorrectly");
+	test_query_eval (db, query, entry, TRUE, "title disjunction query evaluated incorrectly");
 	rhythmdb_query_free (query);
 
 	end_step ();
@@ -120,7 +194,7 @@ START_TEST (test_rhythmdb_db_queries)
 				      RHYTHMDB_QUERY_DISJUNCTION,
 				      RHYTHMDB_QUERY_PROP_LIKE, RHYTHMDB_PROP_TITLE, "Sin",
 				      RHYTHMDB_QUERY_END);
-	fail_unless (rhythmdb_evaluate_query (db, query, entry), "query evaluated incorrectly");
+	test_query_eval (db, query, entry, TRUE, "title disjunction query evaluated incorrectly");
 	rhythmdb_query_free (query);
 
 	end_step ();
@@ -130,7 +204,7 @@ START_TEST (test_rhythmdb_db_queries)
 				      RHYTHMDB_QUERY_DISJUNCTION,
 				      RHYTHMDB_QUERY_PROP_LIKE, RHYTHMDB_PROP_TITLE, "Son",
 				      RHYTHMDB_QUERY_END);
-	fail_if (rhythmdb_evaluate_query (db, query, entry), "query evaluated incorrectly");
+	test_query_eval (db, query, entry, FALSE, "title disjunction query evaluated incorrectly");
 	rhythmdb_query_free (query);
 
 	/* TODO: subqueries */
diff --git a/widgets/rb-query-creator-properties.c b/widgets/rb-query-creator-properties.c
index f6dfbbb..38298c6 100644
--- a/widgets/rb-query-creator-properties.c
+++ b/widgets/rb-query-creator-properties.c
@@ -132,6 +132,7 @@ const RBQueryCreatorCriteriaOption string_criteria_options[] =
 	{ N_("contains"), 0, RHYTHMDB_QUERY_PROP_LIKE },
 	{ N_("does not contain"), 0, RHYTHMDB_QUERY_PROP_NOT_LIKE },
 	{ N_("equals"), 1, RHYTHMDB_QUERY_PROP_EQUALS },
+	{ N_("not equal to"), 1, RHYTHMDB_QUERY_PROP_NOT_EQUAL },
 	{ N_("starts with"), 0, RHYTHMDB_QUERY_PROP_PREFIX },
 	{ N_("ends with"), 0, RHYTHMDB_QUERY_PROP_SUFFIX },
 };
@@ -161,6 +162,7 @@ const RBQueryCreatorPropertyType escaped_string_property_type =
 const RBQueryCreatorCriteriaOption numeric_criteria_options[] =
 {
 	{ N_("equals"), 1, RHYTHMDB_QUERY_PROP_EQUALS },
+	{ N_("not equal to"), 1, RHYTHMDB_QUERY_PROP_NOT_EQUAL },
 	{ N_("at least"), 1, RHYTHMDB_QUERY_PROP_GREATER },	/* matches if A >= B */
 	{ N_("at most"), 1, RHYTHMDB_QUERY_PROP_LESS }		/* matches if A <= B */
 };
@@ -173,6 +175,8 @@ const RBQueryCreatorCriteriaOption year_criteria_options[] =
 {
 	/* Translators: this matches songs within 1-Jan-YEAR to 31-Dec-YEAR */
 	{ N_("in"), 1, RHYTHMDB_QUERY_PROP_YEAR_EQUALS },
+	/* Translators: this matches songs before 1-Jan-YEAR or after 31-Dec-YEAR */
+	{ N_("not in"), 1, RHYTHMDB_QUERY_PROP_YEAR_NOT_EQUAL },
 	/* Translators: this matches songs after 31-Dec-YEAR */
 	{ N_("after"), 1, RHYTHMDB_QUERY_PROP_YEAR_GREATER },
 	/* Translators: this matches songs before 1-Jan-YEAR */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]