[gupnp-tools/wip/search: 24/33] av-cp: Use local search criteria parser
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gupnp-tools/wip/search: 24/33] av-cp: Use local search criteria parser
- Date: Sat, 17 Dec 2016 09:47:04 +0000 (UTC)
commit 616a041a0d745a150ee3d16f765dcfe4f16d8748
Author: Jens Georg <mail jensge org>
Date: Thu Aug 18 18:44:11 2016 +0200
av-cp: Use local search criteria parser
Validate search criteria before sending it to the server. This is slightly
better than a possible remote message, but best would be to port the search
criteria parser from Rygel to GUPnP-AV.
Signed-off-by: Jens Georg <mail jensge org>
src/av-cp/search-dialog.c | 107 ++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 95 insertions(+), 12 deletions(-)
---
diff --git a/src/av-cp/search-dialog.c b/src/av-cp/search-dialog.c
index 34988b5..d67f70e 100644
--- a/src/av-cp/search-dialog.c
+++ b/src/av-cp/search-dialog.c
@@ -45,6 +45,8 @@ struct _SearchDialogPrivate {
AVCPMediaServer *server;
guint pulse_timer;
SearchTask *task;
+ GUPnPSearchCriteriaParser *parser;
+ GRegex *position_re;
};
typedef struct _SearchDialogPrivate SearchDialogPrivate;
@@ -56,6 +58,9 @@ search_dialog_on_search_activate (SearchDialog *self, GtkEntry *entry);
static void
search_dialog_finalize (GObject *object);
+static void
+search_dialog_dispose (GObject *object);
+
struct _SearchTask {
AVCPMediaServer *server;
char *search_expression;
@@ -335,12 +340,42 @@ search_dialog_class_init (SearchDialogClass *klass)
search_dialog_entry);
object_class->finalize = search_dialog_finalize;
+ object_class->dispose = search_dialog_dispose;
}
static void
search_dialog_init (SearchDialog *self)
{
+ SearchDialogPrivate *priv = NULL;
+
gtk_widget_init_template (GTK_WIDGET (self));
+ priv = search_dialog_get_instance_private (self);
+
+ priv->parser = gupnp_search_criteria_parser_new ();
+}
+
+static void
+search_dialog_dispose (GObject *object)
+{
+ SearchDialog *self = SEARCH_DIALOG (object);
+ SearchDialogPrivate *priv = search_dialog_get_instance_private (self);
+ GObjectClass *parent_class =
+ G_OBJECT_CLASS (search_dialog_parent_class);
+
+ if (priv->task != NULL) {
+ search_task_cancel (priv->task);
+ }
+
+ if (priv->pulse_timer != 0) {
+ g_source_remove (priv->pulse_timer);
+ priv->pulse_timer = 0;
+ }
+
+ g_clear_object (&priv->parser);
+
+ if (parent_class->dispose != NULL) {
+ parent_class->dispose (object);
+ }
}
static void
@@ -353,6 +388,8 @@ search_dialog_finalize (GObject *object)
g_clear_pointer (&priv->id, g_free);
g_clear_pointer (&priv->title, g_free);
+ g_clear_pointer (&priv->task, search_task_free);
+ g_clear_pointer (&priv->position_re, g_regex_unref);
if (parent_class->finalize != NULL) {
parent_class->finalize (object);
@@ -477,19 +514,65 @@ G_MODULE_EXPORT
void
search_dialog_on_search_activate (SearchDialog *self, GtkEntry *entry)
{
+ GError *error = NULL;
+ const char *text = gtk_entry_get_text (entry);
SearchDialogPrivate *priv = search_dialog_get_instance_private (self);
- gtk_list_store_clear (priv->search_dialog_liststore);
- gtk_widget_set_sensitive (GTK_WIDGET (entry), FALSE);
- priv->pulse_timer = g_timeout_add_seconds (1, pulse_timer, self);
- g_clear_pointer (&priv->task, search_task_free);
+ gupnp_search_criteria_parser_parse_text (priv->parser, text, &error);
+ if (error == NULL) {
+ gtk_list_store_clear (priv->search_dialog_liststore);
+ gtk_widget_set_sensitive (GTK_WIDGET (entry), FALSE);
+ priv->pulse_timer = g_timeout_add_seconds (1, pulse_timer, self);
+
+ g_clear_pointer (&priv->task, search_task_free);
+
+ priv->task = search_task_new (priv->server,
+ priv->search_dialog_liststore,
+ priv->id,
+ gtk_entry_get_text (entry),
+ 30,
+ search_dialog_on_search_task_done,
+ self);
+ search_task_run (priv->task);
+ } else {
+ GtkWidget *dialog = NULL;
+ GMatchInfo *info = NULL;
+ char *position = NULL;
+
+ if (priv->position_re == NULL) {
+ priv->position_re = g_regex_new ("([0-9]+)$", 0, 0, NULL);
+ }
+
+ if (!g_regex_match (priv->position_re, error->message, 0, &info)) {
+ position = g_strdup ("-1");
+ } else {
+ position = g_match_info_fetch (info, 0);
+ }
+
+ g_match_info_free (info);
+
+ dialog = gtk_message_dialog_new (GTK_WINDOW (self),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_CLOSE,
+ "%s",
+ _("Search failed"));
+
+ gtk_message_dialog_format_secondary_text
+ (GTK_MESSAGE_DIALOG (dialog),
+ _("Search criteria invalid: %s"),
+ error->message);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+
+ g_error_free (error);
+ error = NULL;
+
+ gtk_editable_set_position (GTK_EDITABLE (entry),
+ atoi (position));
+ g_free (position);
+
+ return;
+ }
- priv->task = search_task_new (priv->server,
- priv->search_dialog_liststore,
- priv->id,
- gtk_entry_get_text (entry),
- 30,
- search_dialog_on_search_task_done,
- self);
- search_task_run (priv->task);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]