st-stream-store.c

来自「linux下网络收音机的源码」· C语言 代码 · 共 405 行

C
405
字号
/* * Copyright (c) 2004 Jean-Yves Lefort * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. Neither the name of Jean-Yves Lefort nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */#include "config.h"#include <glib/gi18n.h>#include "sg-util.h"#include "sgtk-util.h"#include "st-stream-store.h"#include "st-handler-field.h"#include "st-handler.h"/*** type definitions ********************************************************/struct _STStreamStorePrivate{  gboolean touched;};/*** variable declarations ***************************************************/static GdkPixbuf *blank_pixbuf = NULL;/*** function declarations ***************************************************/static void st_stream_store_class_init (STStreamStoreClass *class);static void st_stream_store_init (STStreamStore *store);static void st_stream_store_sort_column_changed_h (GtkTreeSortable *treesortable,						   gpointer user_data);static void st_stream_store_weak_notify (gpointer data, GObject *former_store);static void st_stream_store_stream_weak_notify (gpointer data, GObject *former_bag);static void st_stream_store_stream_changed_h (STStreamBag *bag,					      gpointer user_data);static void st_stream_store_stream_state_changed_h (STStreamBag *bag,						    gboolean running,						    gpointer user_data);static void st_stream_store_stream_deleted_h (STStreamBag *bag,					      gpointer user_data);static void st_stream_store_update (STStreamStore *store, STStreamBag *bag);/*** implementation **********************************************************/GTypest_stream_store_get_type (void){  static GType stream_store_type = 0;    if (! stream_store_type)    {      static const GTypeInfo stream_store_info = {	sizeof(STStreamStoreClass),	NULL,	NULL,	(GClassInitFunc) st_stream_store_class_init,	NULL,	NULL,	sizeof(STStreamStore),	0,	(GInstanceInitFunc) st_stream_store_init      };            stream_store_type = g_type_register_static(GTK_TYPE_LIST_STORE,						 "STStreamStore",						 &stream_store_info,						 0);    }  return stream_store_type;}static voidst_stream_store_class_init (STStreamStoreClass *class){  gboolean status;  int width;  int height;  g_type_class_add_private(class, sizeof(STStreamStorePrivate));  /* create a blank pixbuf for ST_STREAM_BAG_STATE_NORMAL */  status = gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);  g_return_if_fail(status == TRUE);  blank_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height);  gdk_pixbuf_fill(blank_pixbuf, 0); /* fill with transparent black */}static voidst_stream_store_init (STStreamStore *store){  store->priv = G_TYPE_INSTANCE_GET_PRIVATE(store, ST_TYPE_STREAM_STORE, STStreamStorePrivate);}STStreamStore *st_stream_store_new (STHandler *handler){  STStreamStore *store;  GType *types;  int i = ST_STREAM_STORE_N_STOCK_COLUMNS;  GSList *fields;  GSList *l;  int sort_index;    g_return_val_if_fail(ST_IS_HANDLER(handler), NULL);  store = g_object_new(ST_TYPE_STREAM_STORE, NULL);  fields = st_handler_get_fields(handler);  /* create the store */  types = g_new(GType, ST_STREAM_STORE_N_STOCK_COLUMNS + g_slist_length(fields));  types[ST_STREAM_STORE_COLUMN_BAG] = ST_TYPE_STREAM_BAG;  types[ST_STREAM_STORE_COLUMN_STOCK_ID] = G_TYPE_STRING;  types[ST_STREAM_STORE_COLUMN_PIXBUF] = GDK_TYPE_PIXBUF;  SG_LIST_FOREACH(l, fields)    {      STHandlerField *field = l->data;      if (ST_HANDLER_FIELD_IS_VISIBLE(field))	{	  GType type = st_handler_field_get_type(field);	  /* keep in sync with st_stream_store_update() */	  if (type == G_TYPE_BOOLEAN || type == G_TYPE_VALUE_ARRAY)	    type = G_TYPE_STRING;	    	  types[i++] = type;	}    }  gtk_list_store_set_column_types(GTK_LIST_STORE(store), i, types);  g_free(types);  /* set the sort column, if any */  sort_index = st_handler_get_fields_sort_index(handler);  if (sort_index)    gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store),					 sort_index + ST_STREAM_STORE_N_STOCK_COLUMNS - 1, /* we substract 1 because 0 means "no sort column" */					 st_handler_get_fields_sort_order(handler));  /* bind signals */  g_signal_connect(store,		   "sort-column-changed",		   G_CALLBACK(st_stream_store_sort_column_changed_h),		   handler);  sgtk_tree_model_make_countable(GTK_TREE_MODEL(store));  return store;}static voidst_stream_store_sort_column_changed_h (GtkTreeSortable *treesortable,				       gpointer user_data){  int sort_column_id;  GtkSortType order;  if (gtk_tree_sortable_get_sort_column_id(treesortable, &sort_column_id, &order))    {      STHandler *handler = user_data;      st_handler_set_fields_sort_index(handler, sort_column_id - ST_STREAM_STORE_N_STOCK_COLUMNS + 1); /* we add 1 because 0 means "no sort column" */      st_handler_set_fields_sort_order(handler, order);    }}voidst_stream_store_append (STStreamStore *store, STStreamBag *bag){  GtkTreeIter iter;  g_return_if_fail(ST_IS_STREAM_STORE(store));  g_return_if_fail(ST_IS_STREAM_BAG(bag));  gtk_list_store_append(GTK_LIST_STORE(store), &iter);  bag->iter = iter;  gtk_list_store_set(GTK_LIST_STORE(store), &iter, ST_STREAM_STORE_COLUMN_BAG, bag, -1);  gtk_list_store_set(GTK_LIST_STORE(store), &iter, ST_STREAM_STORE_COLUMN_PIXBUF, blank_pixbuf, -1);  st_stream_store_update(store, bag);  g_object_connect(bag,		   "signal::changed", st_stream_store_stream_changed_h, store,		   "signal::state-changed", st_stream_store_stream_state_changed_h, store,		   "signal::deleted", st_stream_store_stream_deleted_h, store,		   NULL);  g_object_weak_ref(G_OBJECT(store), st_stream_store_weak_notify, bag);  g_object_weak_ref(G_OBJECT(bag), st_stream_store_stream_weak_notify, store);}static voidst_stream_store_weak_notify (gpointer data, GObject *former_store){  STStreamBag *bag = data;  g_object_weak_unref(G_OBJECT(bag), st_stream_store_stream_weak_notify, former_store);  g_object_disconnect(bag,		      "any-signal", st_stream_store_stream_changed_h, former_store,		      "any-signal", st_stream_store_stream_state_changed_h, former_store,		      "any-signal", st_stream_store_stream_deleted_h, former_store,		      NULL);}static voidst_stream_store_stream_weak_notify (gpointer data, GObject *former_bag){  STStreamStore *store = data;  g_object_weak_unref(G_OBJECT(store), st_stream_store_weak_notify, former_bag);}static voidst_stream_store_stream_changed_h (STStreamBag *bag,				  gpointer user_data){  STStreamStore *store = user_data;  st_stream_store_update(store, bag);  st_stream_store_touch(store);}static voidst_stream_store_stream_state_changed_h (STStreamBag *bag,					gboolean running,					gpointer user_data){  STStreamStore *store = user_data;  gtk_list_store_set(GTK_LIST_STORE(store), &bag->iter,		     ST_STREAM_STORE_COLUMN_STOCK_ID, running ? GTK_STOCK_EXECUTE : NULL,		     ST_STREAM_STORE_COLUMN_PIXBUF, running ? NULL : blank_pixbuf,		     -1);}static voidst_stream_store_stream_deleted_h (STStreamBag *bag,				  gpointer user_data){  STStreamStore *store = user_data;    g_object_disconnect(bag,		      "any-signal", st_stream_store_stream_changed_h, store,		      "any-signal", st_stream_store_stream_state_changed_h, store,		      "any-signal", st_stream_store_stream_deleted_h, store,		      NULL);  gtk_list_store_remove(GTK_LIST_STORE(store), &bag->iter);  st_stream_store_touch(store);}voidst_stream_store_append_list (STStreamStore *store, GSList *list){  GSList *l;  g_return_if_fail(ST_IS_STREAM_STORE(store));  SG_LIST_FOREACH(l, list)    st_stream_store_append(store, l->data);}static voidst_stream_store_update (STStreamStore *store, STStreamBag *bag){  int i = ST_STREAM_STORE_N_STOCK_COLUMNS;  GSList *l;  g_return_if_fail(ST_IS_STREAM_STORE(store));  g_return_if_fail(ST_IS_STREAM_BAG(bag));  SG_LIST_FOREACH(l, st_handler_get_fields(bag->handler))    {      STHandlerField *field = l->data;          if (ST_HANDLER_FIELD_IS_VISIBLE(field))	{	  GValue value = { 0, };	  st_stream_bag_get_field(bag, field, &value);	  if (G_VALUE_HOLDS_BOOLEAN(&value))	    {	      gboolean b = g_value_get_boolean(&value);	      g_value_unset(&value);	      g_value_init(&value, G_TYPE_STRING);	      g_value_set_string(&value, b ? _("Yes") : _("No"));	    }	  else if (G_VALUE_HOLDS(&value, G_TYPE_VALUE_ARRAY))	    {	      GValueArray *value_array;	      char *str;	      value_array = g_value_get_boxed(&value);	      str = value_array ? sg_value_array_get_string(value_array) : NULL;	      g_value_unset(&value);	      g_value_init(&value, G_TYPE_STRING);	      g_value_take_string(&value, str);	    }	  	  gtk_list_store_set_value(GTK_LIST_STORE(store), &bag->iter, i++, &value);	  g_value_unset(&value);	}    }}voidst_stream_store_foreach (STStreamStore *store,			 STStreamStoreForeachCallback cb,			 gpointer data){  GtkTreeIter iter;  gboolean valid;  g_return_if_fail(ST_IS_STREAM_STORE(store));    valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);  while (valid)    {      STStreamBag *bag;      gboolean status;      gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, ST_STREAM_STORE_COLUMN_BAG, &bag, -1);      status = cb(store, bag, data);      g_object_unref(bag);      if (status)	break;      valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter);    }}gbooleanst_stream_store_search_equal_func (GtkTreeModel *model,				   int column,				   const char *key,				   GtkTreeIter *iter,				   gpointer search_data){  STStreamBag *bag;  gboolean matches;  gtk_tree_model_get(model, iter, ST_STREAM_STORE_COLUMN_BAG, &bag, -1);  matches = st_stream_bag_matches(bag, key, FALSE);  g_object_unref(bag);  return ! matches;}voidst_stream_store_touch (STStreamStore *store){  g_return_if_fail(ST_IS_STREAM_STORE(store));  store->priv->touched = TRUE;}gbooleanst_stream_store_is_touched (STStreamStore *store){  g_return_val_if_fail(ST_IS_STREAM_STORE(store), FALSE);  return store->priv->touched;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?