2 * This file is part of DisOrder.
3 * Copyright (C) 2011 Richard Kettlewell
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 /** @file disobedience/filter.c
19 * @brief Track filtering
22 #include "disobedience.h"
24 static GtkWidget
*filtering_window
;
26 static struct filter_row
{
31 { "Required tags", "required-tags", NULL
},
32 { "Prohibited tags", "prohibited-tags", NULL
},
34 #define NFILTER (sizeof filter_rows / sizeof *filter_rows)
38 /** @brief Called with the latest setting for a row */
39 static void filter_get_completed(void *v
, const char *err
,
42 popup_protocol_error(0, err
);
43 else if(filtering_window
) {
44 struct filter_row
*row
= v
;
45 /* Identify unset and empty lists */
48 /* Skip trivial updates (we'll see one as a consequence of each
49 * update we make...) */
50 if(strcmp(gtk_entry_get_text(GTK_ENTRY(row
->entry
)), value
))
51 gtk_entry_set_text(GTK_ENTRY(row
->entry
), value
);
55 /** @brief Retrieve the latest setting for @p row */
56 static void filter_get(struct filter_row
*row
) {
57 disorder_eclient_get_global(client
, filter_get_completed
, row
->pref
, row
);
60 /** @brief Called when the user changes the contents of some entry */
61 static void filter_entry_changed(GtkEditable
*editable
, gpointer user_data
) {
62 struct filter_row
*row
= user_data
;
63 const char *new_value
= gtk_entry_get_text(GTK_ENTRY(editable
));
65 disorder_eclient_set_global(client
, NULL
, row
->pref
, new_value
, row
);
67 disorder_eclient_unset_global(client
, NULL
, row
->pref
, row
);
70 /** @brief Display the filtering window */
71 void popup_filtering(void) {
72 GtkWidget
*label
, *table
;
73 /* Pop up the window if it already exists */
74 if(filtering_window
) {
75 gtk_window_present(GTK_WINDOW(filtering_window
));
78 /* Create the window */
79 /* TODO loads of this is very similar to (copied from!) users.c - can we
81 filtering_window
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
82 gtk_widget_set_style(filtering_window
, tool_style
);
83 gtk_window_set_title(GTK_WINDOW(filtering_window
), "Filtering");
84 g_signal_connect(filtering_window
, "destroy",
85 G_CALLBACK(gtk_widget_destroyed
), &filtering_window
);
86 table
= gtk_table_new(NFILTER
/*rows*/, 2/*cols*/, FALSE
/*homogeneous*/);
87 gtk_widget_set_style(table
, tool_style
);\
89 for(size_t n
= 0; n
< NFILTER
; ++n
) {
90 label
= gtk_label_new(filter_rows
[n
].label
);
91 gtk_widget_set_style(label
, tool_style
);
92 gtk_misc_set_alignment(GTK_MISC(label
), 1/*right*/, 0/*bottom*/);
93 gtk_table_attach(GTK_TABLE(table
), label
,
94 0, 1, /* left/right_attach */
95 n
, n
+1, /* top/bottom_attach */
96 GTK_FILL
, 0, /* x/yoptions */
97 1, 1); /* x/ypadding */
98 filter_rows
[n
].entry
= gtk_entry_new();
99 gtk_widget_set_style(filter_rows
[n
].entry
, tool_style
);
100 gtk_table_attach(GTK_TABLE(table
), filter_rows
[n
].entry
,
101 1, 2, /* left/right_attach */
102 n
, n
+1, /* top/bottom_attach */
103 GTK_FILL
, 0, /* x/yoptions */
104 1, 1); /* x/ypadding */
105 g_signal_connect(filter_rows
[n
].entry
, "changed",
106 G_CALLBACK(filter_entry_changed
), &filter_rows
[n
]);
107 filter_get(&filter_rows
[n
]);
110 gtk_container_add(GTK_CONTAINER(filtering_window
), frame_widget(table
, NULL
));
111 gtk_widget_show_all(filtering_window
);
114 /** @brief Called when any global pref changes */
115 static void filtering_global_pref_changed(const char *event
,
117 void *callbackdata
) {
118 const char *pref
= eventdata
;
119 if(!filtering_window
)
120 return; /* not paying attention */
121 for(size_t n
= 0; n
< NFILTER
; ++n
) {
122 if(!strcmp(pref
, filter_rows
[n
].pref
))
123 filter_get(&filter_rows
[n
]);
127 /** @brief Initialize filtering infrastructure */
128 void init_filtering() {
129 event_register("global-pref", NULL
, filtering_global_pref_changed
);