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, ¤t_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(¤t_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, ¤t_value); if (! st_stream_properties_dialog_value_equal(value, ¤t_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(¤t_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 + -
显示快捷键?