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 + -
显示快捷键?