1 /* gmpc-serverstats (GMPC plugin)
2 * Copyright (C) 2006-2011 Qball Cow <qball@gmpclient.org>
3 * Project homepage: http://gmpclient.org/
4
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 2 of the License, or
8 * (at your option) any later version.
9
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.
14
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include <gtk/gtk.h>
21 #include <gdk/gdkkeysyms.h>
22 #include <config.h>
23 #include "main.h"
24 #include "plugin.h"
25 #include "playlist3-messages.h"
26 #include "playlist3.h"
27 #include "misc.h"
28
29 gmpcPlugin statistics_plugin;
30 enum
31 {
32 SERVERSTATS_MPD_VERSION,
33 SERVERSTATS_MPD_UPTIME,
34 SERVERSTATS_MPD_PLAYTIME,
35 SERVERSTATS_MPD_DB_PLAYTIME,
36 SERVERSTATS_MPD_DB_ARTISTS,
37 SERVERSTATS_MPD_DB_ALBUMS,
38 SERVERSTATS_MPD_DB_SONGS,
39 SERVERSTATS_MPD_URLHANDLERS,
40 SERVERSTATS_MPD_TAG_TYPES,
41 SERVERSTATS_NUM_FIELDS
42 };
43
44 static GtkWidget *serverstats_sw = NULL, *serverstats_tree = NULL;
45 static GtkWidget *serverstats_labels[SERVERSTATS_NUM_FIELDS];
46 static gboolean cancel_query = FALSE;
47
48 /**
49 * Playlist browser functions
50 */
51
serverstats_clear(void)52 static void serverstats_clear(void)
53 {
54 int i;
55 for (i = 0; i < SERVERSTATS_NUM_FIELDS; i++)
56 {
57 gtk_label_set_text(GTK_LABEL(serverstats_labels[i]), "");
58 }
59
60 }
61
serverstats_update(void)62 static void serverstats_update(void)
63 {
64 gchar **handlers = NULL;
65 gchar *value = NULL;
66
67 serverstats_clear();
68 if (!mpd_check_connected(connection))
69 return;
70 mpd_stats_update(connection);
71 /** Version */
72 value = mpd_server_get_version(connection);
73 gtk_label_set_text(GTK_LABEL(serverstats_labels[SERVERSTATS_MPD_VERSION]), value);
74 free(value);
75 /** Uptime */
76 value = format_time_real(mpd_stats_get_uptime(connection), "");
77 gtk_label_set_text(GTK_LABEL(serverstats_labels[SERVERSTATS_MPD_UPTIME]), value);
78 g_free(value);
79 /** Playtime*/
80 value = format_time_real(mpd_stats_get_playtime(connection), "");
81 gtk_label_set_text(GTK_LABEL(serverstats_labels[SERVERSTATS_MPD_PLAYTIME]), value);
82 g_free(value);
83 /** DB Playtime*/
84 value = format_time_real(mpd_stats_get_db_playtime(connection), "");
85 gtk_label_set_text(GTK_LABEL(serverstats_labels[SERVERSTATS_MPD_DB_PLAYTIME]), value);
86 g_free(value);
87 /** DB ARTIST*/
88 value = g_strdup_printf("%i", mpd_stats_get_total_artists(connection));
89 gtk_label_set_text(GTK_LABEL(serverstats_labels[SERVERSTATS_MPD_DB_ARTISTS]), value);
90 g_free(value);
91 /** DB ALBUMS*/
92 value = g_strdup_printf("%i", mpd_stats_get_total_albums(connection));
93 gtk_label_set_text(GTK_LABEL(serverstats_labels[SERVERSTATS_MPD_DB_ALBUMS]), value);
94 g_free(value);
95 /** DB SONGS*/
96 value = g_strdup_printf("%i", mpd_stats_get_total_songs(connection));
97 gtk_label_set_text(GTK_LABEL(serverstats_labels[SERVERSTATS_MPD_DB_SONGS]), value);
98 g_free(value);
99 /** URL_HANDLERS*/
100 handlers = mpd_server_get_url_handlers(connection);
101 if (handlers)
102 {
103 value = g_strjoinv(",", handlers);
104 g_strfreev(handlers);
105 handlers = NULL;
106 } else
107 value = g_strdup("N/A");
108 gtk_label_set_text(GTK_LABEL(serverstats_labels[SERVERSTATS_MPD_URLHANDLERS]), value);
109 g_free(value);
110
111 if (mpd_server_check_version(connection, 0, 13, 0))
112 handlers = mpd_server_get_tag_types(connection);
113 if (handlers)
114 {
115 value = g_strjoinv(", ", handlers);
116 g_strfreev(handlers);
117 handlers = NULL;
118 } else
119 value = g_strdup("N/A");
120 gtk_label_set_text(GTK_LABEL(serverstats_labels[SERVERSTATS_MPD_TAG_TYPES]), value);
121 g_free(value);
122
123 }
124
125 typedef struct _ss_str
126 {
127 int total;
128 int tag;
129 int hits;
130 MpdData *data;
131 GtkTreeModel *model;
132 GtkWidget *box, *pb;
133 long unsigned max_i;
134 } ss_str;
135
serverstats_idle_handler(ss_str * s)136 static gboolean serverstats_idle_handler(ss_str * s)
137 {
138 GtkTreeIter iter;
139 MpdDBStats *stats = NULL;
140 if (s->data == NULL || !mpd_check_connected(connection) || cancel_query)
141 {
142
143 if (gtk_tree_model_get_iter_first(s->model, &iter))
144 {
145 do
146 {
147 guint d;
148 gulong i;
149 gchar *value = NULL;
150 gtk_tree_model_get(s->model, &iter, 0, &i, -1);
151 d = (guint) 100 *(i / (double)s->max_i);
152 value = format_time_real(i, "");
153 gtk_list_store_set(GTK_LIST_STORE(s->model), &iter, 2, d, 3, value, -1);
154 g_free(value);
155 } while (gtk_tree_model_iter_next(s->model, &iter));
156 }
157
158 if (s->data)
159 mpd_data_free(s->data);
160 gtk_tree_view_set_model(GTK_TREE_VIEW(serverstats_tree), s->model);
161 gtk_tree_view_set_search_column(GTK_TREE_VIEW(serverstats_tree), 1);
162 gtk_widget_set_sensitive(GTK_WIDGET(s->box), TRUE);
163 gtk_widget_hide(gtk_widget_get_parent(s->pb));
164
165 if (cancel_query)
166 gtk_list_store_clear(GTK_LIST_STORE(s->model));
167 g_free(s);
168 cancel_query = FALSE;
169 return FALSE;
170 }
171 mpd_database_search_stats_start(connection);
172 mpd_database_search_add_constraint(connection, s->tag, s->data->tag);
173
174 stats = mpd_database_search_stats_commit(connection);
175 if (stats)
176 {
177 gtk_list_store_prepend(GTK_LIST_STORE(s->model), &iter);
178 gtk_list_store_set(GTK_LIST_STORE(s->model), &iter, 0, (unsigned long)(stats->playTime), 1, s->data->tag, -1);
179 s->max_i = MAX(s->max_i, stats->playTime);
180
181 mpd_database_search_free_stats(stats);
182 }
183 /* limit the amount of updating to 0.2 % */
184 if ((int)((1000 * s->hits) / s->total) % 5 == 0)
185 {
186 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(s->pb), s->hits / (double)s->total);
187 }
188 s->hits++;
189 s->data = mpd_data_get_next(s->data);
190 return TRUE;
191 }
192
serverstats_combo_changed(GtkComboBox * box,GtkWidget * pb)193 static void serverstats_combo_changed(GtkComboBox * box, GtkWidget * pb)
194 {
195 ss_str *s;
196 int hits, total;
197 gulong max_i;
198 MpdData *node, *data;
199 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(serverstats_tree));
200 int tag = gtk_combo_box_get_active(box);
201
202 if (!mpd_check_connected(connection))
203 return;
204 if (!mpd_server_check_version(connection, 0, 13, 0))
205 {
206 playlist3_show_error_message("This feature is not supported in mpd older then version 0.13.0.", ERROR_WARNING);
207 return;
208 }
209 /* reset the cancel flag */
210 cancel_query = FALSE;
211 /* show progress bar */
212
213 gtk_widget_show_all(gtk_widget_get_parent(pb));
214
215 /** make the combo box insensitive and remove the model from the treeview */
216 gtk_tree_view_set_model(GTK_TREE_VIEW(serverstats_tree), NULL);
217 gtk_widget_set_sensitive(GTK_WIDGET(box), FALSE);
218
219 gtk_list_store_clear(GTK_LIST_STORE(model));
220 mpd_database_search_field_start(connection, tag);
221 data = mpd_database_search_commit(connection);
222 max_i = 0;
223
224 hits = 0;
225 total = 0;
226 for (node = mpd_data_get_first(data); node != NULL; node = (MpdData *) mpd_data_get_next_real(node, FALSE))
227 total++;
228 s = g_malloc0(sizeof(*s));
229 s->total = total;
230 s->model = model;
231 s->data = data;
232 s->hits = 0;
233 s->tag = tag;
234 s->pb = pb;
235 s->box = GTK_WIDGET(box);
236 g_idle_add((GSourceFunc) serverstats_idle_handler, s);
237
238 }
239
serverstats_header_style_changed(GtkWidget * vbox,GtkStyle * style,GtkWidget * vp)240 static void serverstats_header_style_changed(GtkWidget * vbox, GtkStyle * style, GtkWidget * vp)
241 {
242 gtk_widget_modify_bg(vp, GTK_STATE_NORMAL, &(GTK_WIDGET(vbox)->style->base[GTK_STATE_NORMAL]));
243 }
244
cancel_clicked(GtkWidget * cancel,gpointer data)245 static void cancel_clicked(GtkWidget * cancel, gpointer data)
246 {
247 cancel_query = TRUE;
248 }
249
serverstats_add_entry(GtkWidget * table,int i,const char * name,int stats)250 static void serverstats_add_entry(GtkWidget * table, int i, const char *name, int stats)
251 {
252 char *markup;
253 GtkWidget *label;
254 /** Mpd Uptime */
255 label = gtk_label_new("");
256 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.0);
257 gtk_misc_set_padding(GTK_MISC(label), 12, 0);
258 markup = g_markup_printf_escaped("<b>%s:</b>", name);
259 gtk_label_set_markup(GTK_LABEL(label), markup);
260 g_free(markup);
261 gtk_table_attach(GTK_TABLE(table), label, 0, 1, i, i + 1, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
262 label = serverstats_labels[stats] = gtk_label_new("");
263 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
264 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
265 gtk_table_attach(GTK_TABLE(table), label, 1, 2, i, i + 1, GTK_EXPAND | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
266 }
267
serverstats_init(void)268 static void serverstats_init(void)
269 {
270 /** Get an allready exposed widgets to grab theme colors from. */
271 GtkWidget *colw = (GtkWidget *) playlist3_get_category_tree_view();
272 GtkWidget *label = NULL;
273 GtkWidget *table = NULL;
274 GtkWidget *hbox = NULL;
275 GtkWidget *event = NULL;
276 GtkWidget *serverstats_vbox = gtk_vbox_new(FALSE, 0);
277 GtkWidget *serverstats_event;
278 gchar *markup = NULL;
279 int i = 0;
280
281 serverstats_sw = gtk_scrolled_window_new(NULL, NULL);
282 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(serverstats_sw), GTK_SHADOW_IN);
283 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(serverstats_sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
284
285 serverstats_event = gtk_event_box_new();
286 gtk_event_box_set_visible_window(GTK_EVENT_BOX(serverstats_event), TRUE);
287 gtk_container_add(GTK_CONTAINER(serverstats_event), serverstats_vbox);
288
289 /* wrap in event box to set bg color */
290 event = gtk_event_box_new();
291 gtk_widget_set_app_paintable(event, TRUE);
292 gtk_event_box_set_visible_window(GTK_EVENT_BOX(event), TRUE);
293 gtk_widget_set_state(GTK_WIDGET(event), GTK_STATE_SELECTED);
294 g_signal_connect(G_OBJECT(event), "expose-event", G_CALLBACK(misc_header_expose_event), NULL);
295
296 gtk_widget_modify_bg(serverstats_event, GTK_STATE_NORMAL, &(colw->style->base[GTK_STATE_NORMAL]));
297 g_signal_connect(G_OBJECT(serverstats_vbox), "style-set", G_CALLBACK(serverstats_header_style_changed),
298 serverstats_event);
299
300 /* set label and padding */
301 hbox = gtk_hbox_new(FALSE, 6);
302 label = gtk_image_new_from_icon_name("mpd", GTK_ICON_SIZE_DND);
303 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
304 label = gtk_label_new("");
305 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
306 markup = g_markup_printf_escaped("<span size='xx-large' weight='bold'>%s</span>", _("Server Information"));
307 gtk_label_set_markup(GTK_LABEL(label), markup);
308 g_free(markup);
309 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
310 gtk_container_add(GTK_CONTAINER(event), hbox);
311
312 gtk_container_set_border_width(GTK_CONTAINER(hbox), 6);
313 gtk_box_pack_start(GTK_BOX(serverstats_vbox), event, FALSE, TRUE, 0);
314 gtk_widget_show_all(event);
315
316 label = gtk_hseparator_new();
317 gtk_box_pack_start(GTK_BOX(serverstats_vbox), label, FALSE, TRUE, 0);
318 gtk_widget_show(label);
319 /**
320 * Data list
321 */
322 table = gtk_table_new(SERVERSTATS_NUM_FIELDS + 2, 2, FALSE);
323 gtk_table_set_col_spacings(GTK_TABLE(table), 6);
324 gtk_table_set_row_spacings(GTK_TABLE(table), 6);
325 gtk_container_set_border_width(GTK_CONTAINER(table), 12);
326
327 /** Database */
328 label = gtk_label_new("");
329 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
330 markup = g_markup_printf_escaped("<span size='x-large' weight='bold'>%s</span>", _("Server"));
331 gtk_label_set_markup(GTK_LABEL(label), markup);
332 g_free(markup);
333 gtk_table_attach(GTK_TABLE(table), label, 0, 2, 0, 1, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
334
335 i = 1;
336 /** Mpd version */
337 serverstats_add_entry(table, i++, _("Version"), SERVERSTATS_MPD_VERSION);
338
339 serverstats_add_entry(table, i++, _("Uptime"), SERVERSTATS_MPD_UPTIME);
340 serverstats_add_entry(table, i++, _("Time Playing"), SERVERSTATS_MPD_PLAYTIME);
341
342 /** Database */
343 label = gtk_label_new("");
344 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
345
346 markup = g_markup_printf_escaped("<span size='x-large' weight='bold'>%s</span>", _("Database"));
347 gtk_label_set_markup(GTK_LABEL(label), markup);
348 g_free(markup);
349 gtk_table_attach(GTK_TABLE(table), label, 0, 2, i, i + 1, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
350 i++;
351
352 /** Mpd Playtime */
353 serverstats_add_entry(table, i++, _("Total Playtime"), SERVERSTATS_MPD_DB_PLAYTIME);
354 /** Mpd Artists*/
355 serverstats_add_entry(table, i++, _("Number of artists"), SERVERSTATS_MPD_DB_ARTISTS);
356 /** Mpd Albums */
357 serverstats_add_entry(table, i++, _("Number of albums"), SERVERSTATS_MPD_DB_ALBUMS);
358 /** Mpd Songs */
359 serverstats_add_entry(table, i++, _("Number of songs"), SERVERSTATS_MPD_DB_SONGS);
360 /** Mpd Songs */
361 serverstats_add_entry(table, i++, _("URL Handlers"), SERVERSTATS_MPD_URLHANDLERS);
362 /** Mpd Songs */
363 serverstats_add_entry(table, i++, _("Tag Types"), SERVERSTATS_MPD_TAG_TYPES);
364 /** Stats */
365 label = gtk_label_new("");
366 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
367
368 markup = g_markup_printf_escaped("<span size='x-large' weight='bold'>%s</span>", _("Tag statistics"));
369 gtk_label_set_markup(GTK_LABEL(label), markup);
370 g_free(markup);
371 gtk_table_attach(GTK_TABLE(table), label, 0, 2, i, i + 1, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
372 i++;
373 gtk_widget_show_all(table);
374
375 /**
376 * Stats treeview
377 */
378 {
379 GtkWidget *combo = NULL;
380 GtkWidget *sw = NULL, *cancel;
381 GtkListStore *store;
382 GtkCellRenderer *renderer;
383 GtkWidget *pb = gtk_progress_bar_new();
384 combo = gtk_combo_box_new_text();
385 for (i = 0; i < MPD_TAG_NUM_OF_ITEM_TYPES - 1; i++)
386 {
387 if (mpd_server_tag_supported(connection, i))
388 {
389 gtk_combo_box_append_text(GTK_COMBO_BOX(combo), mpdTagItemKeys[i]);
390 }
391 }
392
393 gtk_table_attach(GTK_TABLE(table), combo, 0, 2, 12, 13, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
394 gtk_widget_show(combo);
395
396 hbox = gtk_hbox_new(FALSE, 6);
397 cancel = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
398 g_signal_connect(G_OBJECT(cancel), "clicked", G_CALLBACK(cancel_clicked), NULL);
399 gtk_box_pack_start(GTK_BOX(hbox), pb, TRUE, TRUE, 0);
400 gtk_box_pack_start(GTK_BOX(hbox), cancel, FALSE, TRUE, 0);
401
402 gtk_table_attach(GTK_TABLE(table), hbox, 0, 2, 13, 14, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
403 g_signal_connect(G_OBJECT(combo), "changed", G_CALLBACK(serverstats_combo_changed), pb);
404
405 sw = gtk_scrolled_window_new(NULL, NULL);
406 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
407 gtk_container_set_border_width(GTK_CONTAINER(sw), 6);
408
409 store = gtk_list_store_new(4, G_TYPE_ULONG, G_TYPE_STRING, G_TYPE_ULONG, G_TYPE_STRING);
410 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), 0, GTK_SORT_DESCENDING);
411 serverstats_tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
412 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(serverstats_tree), FALSE);
413 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(serverstats_tree), TRUE);
414 renderer = gtk_cell_renderer_text_new();
415 g_object_set(G_OBJECT(renderer), "ellipsize", PANGO_ELLIPSIZE_END, "ellipsize-set", TRUE, "width-chars", 30,
416 NULL);
417 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(serverstats_tree), -1, "", renderer, "text", 1, NULL);
418 renderer = gtk_cell_renderer_progress_new();
419 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(serverstats_tree),
420 -1, "", renderer, "value", 2, "text", 3, NULL);
421
422 gtk_tree_view_set_search_column(GTK_TREE_VIEW(serverstats_tree), 1);
423
424 gtk_container_add(GTK_CONTAINER(sw), serverstats_tree);
425
426 gtk_table_attach(GTK_TABLE(table), sw, 0, 2, 14, 15, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
427 gtk_widget_show_all(sw);
428 }
429 /**
430 * Add table
431 */
432 gtk_box_pack_start(GTK_BOX(serverstats_vbox), table, TRUE, TRUE, 0);
433 /* maintain my own reference to the widget, so it won't get destroyed removing
434 * from view
435 */
436 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(serverstats_sw), serverstats_event);
437 gtk_widget_show(serverstats_vbox);
438 gtk_widget_show(serverstats_event);
439 gtk_widget_show(serverstats_sw);
440 g_object_ref_sink(serverstats_sw);
441 }
442
443 static guint timeout_source = 0;
444
serverstats_selected(GtkWidget * container)445 static void serverstats_selected(GtkWidget * container)
446 {
447 if (serverstats_sw == NULL)
448 {
449 serverstats_init();
450 }
451 serverstats_update();
452 gtk_container_add(GTK_CONTAINER(container), serverstats_sw);
453 gtk_widget_show(serverstats_sw);
454 if (timeout_source)
455 g_source_remove(timeout_source);
456 timeout_source = g_timeout_add_seconds(5, (GSourceFunc) serverstats_update, NULL);
457 }
458
serverstats_unselected(GtkWidget * container)459 static void serverstats_unselected(GtkWidget * container)
460 {
461 if (timeout_source)
462 g_source_remove(timeout_source);
463 timeout_source = 0;
464 gtk_container_remove(GTK_CONTAINER(container), serverstats_sw);
465 }
466
467 /**
468 * public function
469 */
serverinformation_popup_close(GtkWidget * dialog,gint response_id,gpointer data)470 static void serverinformation_popup_close(GtkWidget * dialog, gint response_id, gpointer data)
471 {
472 int width, height;
473 /* Save windows size */
474 gtk_window_get_size(GTK_WINDOW(dialog), &width, &height);
475 cfg_set_single_value_as_int(config, "serverstats", "dialog-width", width);
476 cfg_set_single_value_as_int(config, "serverstats", "dialog-height", height);
477
478 /* Remove info window, and keep it */
479 serverstats_unselected(GTK_DIALOG(dialog)->vbox);
480
481 /* destroy dialog */
482 gtk_widget_destroy(dialog);
483
484 }
485
serverstats_connection_changed(MpdObj * mi,int connect,void * usedata)486 static void serverstats_connection_changed(MpdObj * mi, int connect, void *usedata)
487 {
488 if (!connect && serverstats_tree)
489 {
490 GtkWidget *dialog = gtk_widget_get_parent(serverstats_sw);
491 if (dialog)
492 gtk_dialog_response(GTK_DIALOG(gtk_widget_get_toplevel(dialog)), 0);
493 if (serverstats_sw)
494 {
495 gtk_widget_destroy(serverstats_sw);
496 serverstats_sw = NULL;
497 serverstats_tree = NULL;
498 }
499 }
500 }
501
serverinformation_show_popup(void)502 void serverinformation_show_popup(void)
503 {
504 GtkWidget *dialog = NULL;
505 if (serverstats_sw)
506 {
507 GtkWidget *win = gtk_widget_get_parent(serverstats_sw);
508 if (win)
509 {
510 gtk_window_present(GTK_WINDOW(win));
511 return;
512 }
513 }
514
515 dialog = gtk_dialog_new_with_buttons(_("Server Information"),
516 GTK_WINDOW(playlist3_get_window()),
517 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
518 GTK_STOCK_CLOSE, GTK_RESPONSE_OK, NULL);
519 /* Add info window */
520 serverstats_selected(GTK_DIALOG(dialog)->vbox);
521 /* Restore size */
522 gtk_window_resize(GTK_WINDOW(dialog),
523 cfg_get_single_value_as_int_with_default(config, "serverstats", "dialog-width", 400),
524 cfg_get_single_value_as_int_with_default(config, "serverstats", "dialog-height", 400));
525 /* handle close */
526 g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(serverinformation_popup_close), NULL);
527 gtk_widget_show(dialog);
528
529 }
530
serverstats_destroy(void)531 static void serverstats_destroy(void)
532 {
533 serverstats_connection_changed(connection, 0, NULL);
534 }
535
536 /**
537 * Define the plugin structure
538 */
539 gmpcPlugin statistics_plugin = {
540 /* name */
541 .name = N_("Server Information"),
542 /* version */
543 .version = {0, 1, 2},
544 .destroy = serverstats_destroy,
545 /* type */
546 .plugin_type = GMPC_INTERNALL,
547 /** Connection changed */
548 .mpd_connection_changed = serverstats_connection_changed
549 };
550