st-stream-properties-dialog.c

来自「linux下网络收音机的源码」· C语言 代码 · 共 876 行 · 第 1/2 页

C
876
字号
	  gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), g_value_get_uint(&value));	  break;	case G_TYPE_DOUBLE:	  gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), g_value_get_double(&value));	  break;	case G_TYPE_STRING:	  {	    const char *str = g_value_get_string(&value);	    gtk_entry_set_text(GTK_ENTRY(widget), str ? str : "");	    break;	  }	  	default:	  g_return_if_reached();	}    }  else    {      if (G_VALUE_HOLDS_BOOLEAN(&value))	gtk_label_set_text(GTK_LABEL(widget), g_value_get_boolean(&value) ? _("Yes") : _("No"));      else if (G_VALUE_HOLDS_INT(&value))	{	  char *str = g_strdup_printf("%i", g_value_get_int(&value));	  gtk_label_set_text(GTK_LABEL(widget), str);	  g_free(str);	}      else if (G_VALUE_HOLDS_UINT(&value))	{	  char *str = g_strdup_printf("%u", g_value_get_uint(&value));	  gtk_label_set_text(GTK_LABEL(widget), str);	  g_free(str);	}      else if (G_VALUE_HOLDS_DOUBLE(&value))	{	  char *str = g_strdup_printf("%f", g_value_get_double(&value));	  gtk_label_set_text(GTK_LABEL(widget), str);	  g_free(str);	}      else if (G_VALUE_HOLDS_STRING(&value))	gtk_label_set_text(GTK_LABEL(widget), g_value_get_string(&value));      else if (G_VALUE_HOLDS(&value, GDK_TYPE_PIXBUF))	gtk_image_set_from_pixbuf(GTK_IMAGE(widget), g_value_get_object(&value));      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;	  gtk_label_set_text(GTK_LABEL(widget), str ? str : "");	  g_free(str);	}      else	g_return_if_reached();    }    g_value_unset(&value);}GtkWidget *st_stream_properties_dialog_new (GtkWindow *parent){  STStreamPropertiesDialog *dialog;  dialog = g_object_new(ST_TYPE_STREAM_PROPERTIES_DIALOG, NULL);  if (parent)    gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);  st_stream_properties_dialog_update_sensitivity(dialog);  return GTK_WIDGET(dialog);}voidst_stream_properties_dialog_set_stream (STStreamPropertiesDialog *dialog,					STStreamBag *stream_bag){  g_return_if_fail(ST_IS_STREAM_PROPERTIES_DIALOG(dialog));  g_return_if_fail(ST_IS_STREAM_BAG(stream_bag));  st_stream_properties_dialog_unset_stream(dialog);  if (stream_bag->handler != dialog->priv->table_handler)    {      dialog->priv->table_handler = stream_bag->handler;      st_stream_properties_dialog_construct_table(dialog);    }  dialog->priv->stream_bag = g_object_ref(stream_bag);  g_object_connect(dialog->priv->stream_bag,		   "signal::changed", st_stream_properties_dialog_stream_changed_h, dialog,		   "signal::deleted", st_stream_properties_dialog_stream_deleted_h, dialog,		   NULL);  st_stream_properties_dialog_update_title(dialog);  st_stream_properties_dialog_update_data(dialog);}static voidst_stream_properties_dialog_stream_changed_h (STStreamBag *bag,					      gpointer user_data){  STStreamPropertiesDialog *dialog = user_data;  st_stream_properties_dialog_update_title(dialog);  st_stream_properties_dialog_update_data(dialog);}static voidst_stream_properties_dialog_stream_deleted_h (STStreamBag *bag,					      gpointer user_data){  STStreamPropertiesDialog *dialog = user_data;  gtk_dialog_response(GTK_DIALOG(dialog), GTK_RESPONSE_CANCEL);}voidst_stream_properties_dialog_update_sensitivity (STStreamPropertiesDialog *dialog){  g_return_if_fail(ST_IS_STREAM_PROPERTIES_DIALOG(dialog));  gtk_widget_set_sensitive(dialog->priv->previous_button, st_shell_can_select_previous_stream(st_shell));  gtk_widget_set_sensitive(dialog->priv->next_button, st_shell_can_select_next_stream(st_shell));}static voidst_stream_properties_dialog_get_fields_and_values (STStreamPropertiesDialog *dialog,						   GSList **fields,						   GSList **values){  GSList *l;  g_return_if_fail(ST_IS_STREAM_PROPERTIES_DIALOG(dialog));  g_return_if_fail(fields != NULL);  g_return_if_fail(values != NULL);  *fields = NULL;  *values = NULL;  SG_LIST_FOREACH(l, dialog->priv->widgets)    {      GtkWidget *widget = l->data;      STHandlerField *field = g_object_get_data(G_OBJECT(widget), "field");      if (ST_HANDLER_FIELD_IS_EDITABLE(field))	{	  GValue current_value = { 0, };	  GValue *value;	  	  st_stream_bag_get_field(dialog->priv->stream_bag, field, &current_value);	  value = sg_value_new(st_handler_field_get_type(field));	  switch (G_VALUE_TYPE(value))	    {	    case G_TYPE_BOOLEAN:	      g_value_set_boolean(value, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));	      break;	    case G_TYPE_INT:	      g_value_set_int(value, gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)));	      break;	    case G_TYPE_UINT:	      g_value_set_uint(value, gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)));	      break;	    case G_TYPE_DOUBLE:	      g_value_set_double(value, gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget)));	      break;	    case G_TYPE_STRING:	      {		const char *str = gtk_entry_get_text(GTK_ENTRY(widget));		g_value_set_string(value, *str ? str : NULL);		break;	      }	    default:	      g_return_if_reached();	    }	  *fields = g_slist_append(*fields, field);	  *values = g_slist_append(*values, value);	  g_value_unset(&current_value);	}    }}static gbooleanst_stream_properties_dialog_value_equal (const GValue *value1,					 const GValue *value2){  gboolean equal;  g_return_val_if_fail(G_IS_VALUE(value1), FALSE);  g_return_val_if_fail(G_IS_VALUE(value2), FALSE);  g_return_val_if_fail(G_VALUE_TYPE(value1) == G_VALUE_TYPE(value2), FALSE);  switch (G_VALUE_TYPE(value1))    {    case G_TYPE_BOOLEAN:      equal = g_value_get_boolean(value1) == g_value_get_boolean(value2);      break;    case G_TYPE_INT:      equal = g_value_get_int(value1) == g_value_get_int(value2);      break;    case G_TYPE_UINT:      equal = g_value_get_uint(value1) == g_value_get_uint(value2);      break;    case G_TYPE_DOUBLE:      equal = sg_double_equal(g_value_get_double(value1), g_value_get_double(value2));      break;    case G_TYPE_STRING:      {	const char *str1 = g_value_get_string(value1);	const char *str2 = g_value_get_string(value2);	equal = (str1 == NULL && str2 == NULL) || (str1 && str2 && ! strcmp(str1, str2));	break;      }    default:      g_return_val_if_reached(FALSE);    }  return equal;}/* * Modify FIELDS and VALUES so that only values differing from those * in STREAM_BAG are included. */static voidst_stream_properties_dialog_optimize_fields_and_values (STStreamBag *stream_bag,							GSList **fields,							GSList **values){  GSList *new_fields = NULL;  GSList *new_values = NULL;  GSList *f;  GSList *v;  g_return_if_fail(ST_IS_STREAM_BAG(stream_bag));  g_return_if_fail(fields != NULL);  g_return_if_fail(values != NULL);    for (f = *fields, v = *values; f && v; f = f->next, v = v->next)    {      STHandlerField *field = f->data;      GValue *value = v->data;      GValue current_value = { 0, };      st_stream_bag_get_field(stream_bag, field, &current_value);      if (! st_stream_properties_dialog_value_equal(value, &current_value))	{	  GValue *new_value;	  new_value = sg_value_new(G_VALUE_TYPE(value));	  g_value_copy(value, new_value);	  new_fields = g_slist_append(new_fields, field);	  new_values = g_slist_append(new_values, new_value);	}      g_value_unset(&current_value);    }  g_slist_free(*fields);  g_slist_foreach(*values, (GFunc) sg_value_free, NULL);  g_slist_free(*values);  *fields = new_fields;  *values = new_values;}static CancelInfo *st_stream_properties_dialog_cancel_info_new (STStreamPropertiesDialog *dialog){  CancelInfo *info = g_new0(CancelInfo, 1);  GSList *l;  g_return_val_if_fail(ST_IS_STREAM_PROPERTIES_DIALOG(dialog), NULL);  info->stream_bag = g_object_ref(dialog->priv->stream_bag);  SG_LIST_FOREACH(l, dialog->priv->widgets)    {      STHandlerField *field = g_object_get_data(G_OBJECT(l->data), "field");      if (ST_HANDLER_FIELD_IS_EDITABLE(field))	{	  GValue *value = g_new0(GValue, 1);	  st_stream_bag_get_field(dialog->priv->stream_bag, field, value);	  info->fields = g_slist_append(info->fields, field);	  info->values = g_slist_append(info->values, value);	}    }  return info;}static voidst_stream_properties_dialog_cancel_info_free (CancelInfo *info){  g_return_if_fail(info != NULL);  g_object_unref(info->stream_bag);  g_slist_free(info->fields);  g_slist_foreach(info->values, (GFunc) sg_value_free, NULL);  g_slist_free(info->values);  g_free(info);}static voidst_stream_properties_dialog_cancel_list_append (STStreamPropertiesDialog *dialog, CancelInfo *info){  gboolean already_in_cancel_list = FALSE;  GSList *l;  g_return_if_fail(ST_IS_STREAM_PROPERTIES_DIALOG(dialog));  g_return_if_fail(info != NULL);  SG_LIST_FOREACH(l, dialog->priv->cancel_list)    if (info->stream_bag == ((CancelInfo *) l->data)->stream_bag)      {	already_in_cancel_list = TRUE;	break;      }  if (already_in_cancel_list)    st_stream_properties_dialog_cancel_info_free(info);  else    dialog->priv->cancel_list = g_slist_append(dialog->priv->cancel_list, info);}static voidst_stream_properties_dialog_cancel_list_free (STStreamPropertiesDialog *dialog){  g_return_if_fail(ST_IS_STREAM_PROPERTIES_DIALOG(dialog));  g_slist_foreach(dialog->priv->cancel_list, (GFunc) st_stream_properties_dialog_cancel_info_free, NULL);  g_slist_free(dialog->priv->cancel_list);  dialog->priv->cancel_list = NULL;}voidst_stream_properties_dialog_apply (STStreamPropertiesDialog *dialog){  GSList *fields;  GSList *values;  CancelInfo *info;  gboolean status;  GError *err = NULL;  g_return_if_fail(ST_IS_STREAM_PROPERTIES_DIALOG(dialog));  if (! (dialog->priv->stream_bag	 && st_handler_event_is_bound(dialog->priv->stream_bag->handler, ST_HANDLER_EVENT_STREAM_MODIFY)))    return;  info = st_stream_properties_dialog_cancel_info_new(dialog);  st_stream_properties_dialog_get_fields_and_values(dialog, &fields, &values);  st_stream_properties_dialog_optimize_fields_and_values(dialog->priv->stream_bag, &fields, &values);  status = st_stream_bag_modify(dialog->priv->stream_bag, fields, values, &err);  if (! status)    {      char *normalized;      normalized = st_dialog_normalize(err->message);      g_error_free(err);      st_error_dialog(_("Unable to apply all modifications"), "%s", normalized);      g_free(normalized);    }  g_slist_free(fields);  g_slist_foreach(values, (GFunc) sg_value_free, NULL);  g_slist_free(values);    st_stream_properties_dialog_cancel_list_append(dialog, info);  st_stream_properties_dialog_update_title(dialog);}voidst_stream_properties_dialog_cancel (STStreamPropertiesDialog *dialog){  GSList *l;  g_return_if_fail(ST_IS_STREAM_PROPERTIES_DIALOG(dialog));  if (! (dialog->priv->stream_bag	 && st_handler_event_is_bound(dialog->priv->stream_bag->handler, ST_HANDLER_EVENT_STREAM_MODIFY)))    return;  SG_LIST_FOREACH(l, dialog->priv->cancel_list)    {      CancelInfo *info = l->data;      GError *err = NULL;      gboolean status;      st_stream_properties_dialog_optimize_fields_and_values(info->stream_bag, &info->fields, &info->values);      status = st_stream_bag_modify(info->stream_bag, info->fields, info->values, &err);      if (! status)	{	  char *normalized;	  normalized = st_dialog_normalize(err->message);	  g_error_free(err);	  st_error_dialog(_("Unable to cancel all modifications"), "%s", normalized);	  g_free(normalized);	}    }  st_stream_properties_dialog_cancel_list_free(dialog);  st_stream_properties_dialog_update_title(dialog);}

⌨️ 快捷键说明

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