st-stream-properties-dialog.c
来自「linux下网络收音机的源码」· C语言 代码 · 共 876 行 · 第 1/2 页
C
876 行
/* * Copyright (c) 2003, 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 <string.h>#include <glib/gi18n.h>#include <gtk/gtk.h>#include "sg-util.h"#include "st-stream-properties-dialog.h"#include "st-handler.h"#include "st-settings.h"#include "sgtk-hig.h"#include "sgtk-util.h"#include "st-stream-bag.h"#include "st-shell.h"#include "st-dialog-api.h"#include "st-handler-field.h"#include "st-util-api.h"/*** cpp *********************************************************************/#define LABEL_DEFAULT_WIDTH 300/*** type definitions ********************************************************/struct _STStreamPropertiesDialogPrivate{ STStreamBag *stream_bag; GtkWidget *previous_button; GtkWidget *next_button; GtkWidget *ok_button; STHandler *table_handler; GtkWidget *table; GSList *widgets; GSList *cancel_list;};typedef struct{ STStreamBag *stream_bag; GSList *fields; GSList *values;} CancelInfo;/*** variable declarations ***************************************************/static GObjectClass *parent_class = NULL;/*** function declarations ***************************************************/static void st_stream_properties_dialog_class_init (STStreamPropertiesDialogClass *class);static void st_stream_properties_dialog_init (STStreamPropertiesDialog *dialog);static void st_stream_properties_dialog_finalize (GObject *object);static void st_stream_properties_dialog_unset_stream (STStreamPropertiesDialog *dialog);static void st_stream_properties_dialog_construct_table (STStreamPropertiesDialog *dialog);static void st_stream_properties_dialog_update_title (STStreamPropertiesDialog *dialog);static void st_stream_properties_dialog_update_data (STStreamPropertiesDialog *dialog);static void st_stream_properties_dialog_set_widget_data (GtkWidget *widget, STStreamBag *stream_bag, STHandlerField *field);static void st_stream_properties_dialog_get_fields_and_values (STStreamPropertiesDialog *dialog, GSList **fields, GSList **values);static gboolean st_stream_properties_dialog_value_equal (const GValue *value1, const GValue *value2);static void st_stream_properties_dialog_optimize_fields_and_values (STStreamBag *stream_bag, GSList **fields, GSList **values);static CancelInfo *st_stream_properties_dialog_cancel_info_new (STStreamPropertiesDialog *dialog);static void st_stream_properties_dialog_cancel_info_free (CancelInfo *info);static void st_stream_properties_dialog_cancel_list_append (STStreamPropertiesDialog *dialog, CancelInfo *info);static void st_stream_properties_dialog_cancel_list_free (STStreamPropertiesDialog *dialog);static void st_stream_properties_dialog_stream_changed_h (STStreamBag *bag, gpointer user_data);static void st_stream_properties_dialog_stream_deleted_h (STStreamBag *bag, gpointer user_data);/*** implementation **********************************************************/GTypest_stream_properties_dialog_get_type (void){ static GType stream_properties_dialog_type = 0; if (! stream_properties_dialog_type) { static const GTypeInfo stream_properties_dialog_info = { sizeof(STStreamPropertiesDialogClass), NULL, NULL, (GClassInitFunc) st_stream_properties_dialog_class_init, NULL, NULL, sizeof(STStreamPropertiesDialog), 0, (GInstanceInitFunc) st_stream_properties_dialog_init, }; stream_properties_dialog_type = g_type_register_static(SGTK_TYPE_DIALOG, "STStreamPropertiesDialog", &stream_properties_dialog_info, 0); } return stream_properties_dialog_type;}static voidst_stream_properties_dialog_class_init (STStreamPropertiesDialogClass *class){ GObjectClass *object_class = G_OBJECT_CLASS(class); parent_class = g_type_class_peek_parent(class); g_type_class_add_private(class, sizeof(STStreamPropertiesDialogPrivate)); object_class->finalize = st_stream_properties_dialog_finalize;}static voidst_stream_properties_dialog_init (STStreamPropertiesDialog *dialog){ dialog->priv = G_TYPE_INSTANCE_GET_PRIVATE(dialog, ST_TYPE_STREAM_PROPERTIES_DIALOG, STStreamPropertiesDialogPrivate); dialog->priv->previous_button = gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_GO_BACK, SGTK_RESPONSE_PREVIOUS); dialog->priv->next_button = gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_GO_FORWARD, SGTK_RESPONSE_NEXT); gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_APPLY, GTK_RESPONSE_APPLY); gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); dialog->priv->ok_button = gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_OK, GTK_RESPONSE_OK); sgtk_window_link_size(GTK_WINDOW(dialog), &st_settings.stream_properties_window_width, NULL);}static voidst_stream_properties_dialog_finalize (GObject *object){ STStreamPropertiesDialog *dialog = ST_STREAM_PROPERTIES_DIALOG(object); st_stream_properties_dialog_unset_stream(dialog); g_slist_free(dialog->priv->widgets); st_stream_properties_dialog_cancel_list_free(dialog); parent_class->finalize(object);}static voidst_stream_properties_dialog_unset_stream (STStreamPropertiesDialog *dialog){ g_return_if_fail(ST_IS_STREAM_PROPERTIES_DIALOG(dialog)); if (dialog->priv->stream_bag) { g_object_disconnect(dialog->priv->stream_bag, "any-signal", st_stream_properties_dialog_stream_changed_h, dialog, "any-signal", st_stream_properties_dialog_stream_deleted_h, dialog, NULL); g_object_unref(dialog->priv->stream_bag); }}static voidst_stream_properties_dialog_construct_table (STStreamPropertiesDialog *dialog){ GSList *l; int n_fields; int vi = 0; int width; int height; GtkWidget *first_widget = NULL; GtkWidget *prev_widget = NULL; GtkWidget *focused_widget = NULL; GSList *pending_widgets = NULL; g_return_if_fail(ST_IS_STREAM_PROPERTIES_DIALOG(dialog)); g_return_if_fail(dialog->priv->table_handler != NULL); if (dialog->priv->table) gtk_container_remove(GTK_CONTAINER(SGTK_DIALOG(dialog)->contents), dialog->priv->table); if (dialog->priv->widgets) { g_slist_free(dialog->priv->widgets); dialog->priv->widgets = NULL; } n_fields = st_handler_count_fields(dialog->priv->table_handler, ST_HANDLER_FIELD_VISIBLE | ST_HANDLER_FIELD_EDITABLE); dialog->priv->table = gtk_table_new(n_fields, 2, FALSE); gtk_table_set_row_spacings(GTK_TABLE(dialog->priv->table), SGTK_HIG_CONTROL_SPACING); gtk_table_set_col_spacings(GTK_TABLE(dialog->priv->table), SGTK_HIG_CONTROL_LABEL_SPACING); SG_LIST_FOREACH(l, st_handler_get_fields(dialog->priv->table_handler)) { STHandlerField *field = l->data; if (ST_HANDLER_FIELD_IS_VISIBLE(field) || ST_HANDLER_FIELD_IS_EDITABLE(field)) { GtkWidget *widget; if (ST_HANDLER_FIELD_IS_EDITABLE(field)) { const char *description; switch (st_handler_field_get_type(field)) { case G_TYPE_BOOLEAN: widget = gtk_check_button_new(); break; case G_TYPE_INT: widget = gtk_spin_button_new_with_range(G_MININT, G_MAXINT, 1); break; case G_TYPE_UINT: widget = gtk_spin_button_new_with_range(0, G_MAXUINT, 1); break; case G_TYPE_DOUBLE: widget = gtk_spin_button_new_with_range(G_MINDOUBLE, G_MAXDOUBLE, 1); break; case G_TYPE_STRING: widget = gtk_entry_new(); break; default: g_return_if_reached(); } if (! focused_widget) gtk_widget_grab_focus(focused_widget = widget); if (! first_widget) first_widget = widget; if (prev_widget && GTK_IS_ENTRY(prev_widget)) sgtk_entry_set_next_widget(GTK_ENTRY(prev_widget), widget); prev_widget = widget; description = st_handler_field_get_description(field); if (description) st_set_tooltip(widget, description); } else { if (st_handler_field_get_type(field) == GDK_TYPE_PIXBUF) widget = gtk_image_new(); else { widget = gtk_label_new(NULL); gtk_widget_set_size_request(widget, LABEL_DEFAULT_WIDTH, -1); gtk_misc_set_alignment(GTK_MISC(widget), 0.0, 0.5); gtk_label_set_selectable(GTK_LABEL(widget), TRUE); } } g_object_set_data(G_OBJECT(widget), "field", field); dialog->priv->widgets = g_slist_append(dialog->priv->widgets, widget); gtk_widget_show(widget); if (ST_HANDLER_FIELD_HAS_DEDICATED_COLUMN(field)) { GtkWidget *label; char *str; GtkWidget *hbox; GSList *m; str = g_markup_printf_escaped("<span weight=\"bold\">%s:</span>", st_handler_field_get_label(field)); label = gtk_label_new(str); g_free(str); gtk_label_set_use_markup(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); hbox = gtk_hbox_new(FALSE, 0); SG_LIST_FOREACH(m, pending_widgets) /* padding is 2, matching the default GtkCellRenderer::xpad */ gtk_box_pack_start(GTK_BOX(hbox), m->data, FALSE, FALSE, 2); g_slist_free(pending_widgets); pending_widgets = NULL; gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, 0); gtk_widget_show(label); gtk_widget_show(hbox); gtk_table_attach(GTK_TABLE(dialog->priv->table), label, 0, 1, vi, vi + 1, GTK_FILL, 0, 0, 0); gtk_table_attach(GTK_TABLE(dialog->priv->table), hbox, 1, 2, vi, vi + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0); vi++; } else pending_widgets = g_slist_append(pending_widgets, widget); } } g_slist_free(pending_widgets); if (! focused_widget) gtk_widget_grab_focus(dialog->priv->ok_button); if (prev_widget && GTK_IS_ENTRY(prev_widget) && prev_widget != first_widget) sgtk_entry_set_next_widget(GTK_ENTRY(prev_widget), first_widget); gtk_widget_show(dialog->priv->table); gtk_container_add(GTK_CONTAINER(SGTK_DIALOG(dialog)->contents), dialog->priv->table); /* force the dialog to recalculate its height */ gtk_window_get_size(GTK_WINDOW(dialog), &width, &height); gtk_window_resize(GTK_WINDOW(dialog), width, 1);}static voidst_stream_properties_dialog_update_title (STStreamPropertiesDialog *dialog){ char *title = NULL; g_return_if_fail(ST_IS_STREAM_PROPERTIES_DIALOG(dialog)); if (st_handler_event_is_bound(dialog->priv->stream_bag->handler, ST_HANDLER_EVENT_STREAM_STOCK_FIELD_GET)) { GValue value = { 0, }; st_stream_bag_get_stock_field(dialog->priv->stream_bag, ST_HANDLER_STOCK_FIELD_NAME, &value); if (g_value_get_string(&value)) title = g_strdup_printf(_("%s Properties"), g_value_get_string(&value)); g_value_unset(&value); } if (title) { gtk_window_set_title(GTK_WINDOW(dialog), title); g_free(title); } else gtk_window_set_title(GTK_WINDOW(dialog), _("Stream Properties"));}static voidst_stream_properties_dialog_update_data (STStreamPropertiesDialog *dialog){ GSList *l; g_return_if_fail(ST_IS_STREAM_PROPERTIES_DIALOG(dialog)); SG_LIST_FOREACH(l, dialog->priv->widgets) { GtkWidget *widget = l->data; if (dialog->priv->stream_bag) { STHandlerField *field = g_object_get_data(G_OBJECT(widget), "field"); gtk_widget_set_sensitive(widget, TRUE); st_stream_properties_dialog_set_widget_data(widget, dialog->priv->stream_bag, field); } else gtk_widget_set_sensitive(widget, FALSE); }}static voidst_stream_properties_dialog_set_widget_data (GtkWidget *widget, STStreamBag *stream_bag, STHandlerField *field){ GValue value = { 0, }; g_return_if_fail(GTK_IS_WIDGET(widget)); g_return_if_fail(ST_IS_STREAM_BAG(stream_bag)); g_return_if_fail(field != NULL); st_stream_bag_get_field(stream_bag, field, &value); if (ST_HANDLER_FIELD_IS_EDITABLE(field)) { switch (G_VALUE_TYPE(&value)) { case G_TYPE_BOOLEAN: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), g_value_get_boolean(&value)); break; case G_TYPE_INT: gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), g_value_get_int(&value)); break; case G_TYPE_UINT:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?