📄 st-util.c
字号:
/* * 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 <string.h>#include <glib/gi18n.h>#include <gtk/gtk.h>#include "sgtk-hig.h"#include "st-action.h"#include "st-dialog-api.h"#include "st-util.h"/*** API implementation ******************************************************//** * st_format_bitrate: * @bitrate: a bitrate to format, expressed in kilobits per seconds. * * Formats @bitrate as a string. * * Return value: @bitrate formatted as a string, which should be freed * when no longer needed. **/char *st_format_bitrate (int bitrate){ g_return_val_if_fail(bitrate > 0, NULL); return g_strdup_printf(_("%i kbps"), bitrate);}/** * st_format_samplerate: * @samplerate: a samplerate to format, expressed in Hz. * * Formats @samplerate as a string. * * Return value: @samplerate formatted as a string, which should be * freed when no longer needed. **/char *st_format_samplerate (int samplerate){ g_return_val_if_fail(samplerate > 0, NULL); return g_strdup_printf(_("%i Hz"), samplerate);}/** * st_format_channels: * @channels: a number of audio channels, which must be greater than * 0. * * Formats @channels as a string. * * Return value: @channels formatted as a string, which should be * freed when no longer needed. **/char *st_format_channels (int channels){ g_return_val_if_fail(channels > 0, NULL); switch (channels) { case 1: return g_strdup(_("Mono")); case 2: return g_strdup(_("Stereo")); default: return g_strdup_printf(ngettext("%i channel", "%i channels", channels), channels); }}/** * st_format_audio_properties: * @bitrate: a bitrate expressed in kbps, or 0. * @samplerate: a samplerate expressed in kbps, or 0. * @channels: a number of audio channels, or 0. * * Formats @bitrate, @samplerate and @channels as a string. * * Return value: a formatted string, which should be freed when no * longer needed. **/char *st_format_audio_properties (int bitrate, int samplerate, int channels){ GString *audio; char *str; audio = g_string_new(NULL); if (bitrate > 0) { str = st_format_bitrate(bitrate); g_string_append(audio, str); g_free(str); } if (samplerate > 0) { if (*audio->str) g_string_append(audio, ", "); str = st_format_samplerate(samplerate); g_string_append(audio, str); g_free(str); } if (channels > 0) { if (*audio->str) g_string_append(audio, ", "); str = st_format_channels(channels); g_string_append(audio, str); g_free(str); } if (*audio->str) return g_string_free(audio, FALSE); else { g_string_free(audio, TRUE); return NULL; }}/** * st_strchr_span: * @str: a string. * @c: a character to locate, which must not be 0. * * Locates the first occurrence of @c (converted to a char) in @str. * * Return value: a pointer to the character following the first * occurrence of @c in @str, or %NULL if @c does not appear in @str. **/char *st_strchr_span (const char *str, int c){ char *s; g_return_val_if_fail(str != NULL, NULL); g_return_val_if_fail(c != 0, NULL); s = strchr(str, c); if (s) s++; return s;}/** * st_strstr_span: * @big: a string. * @little: a string to search for in @big. * * Locates the first occurrence of @little in @big. * * Return value: a pointer to the character following the first * occurrence of @little in @big, or %NULL if @little does not appear * in @big. **/char *st_strstr_span (const char *big, const char *little){ char *s; g_return_val_if_fail(big != NULL, NULL); g_return_val_if_fail(little != NULL, NULL); s = strstr(big, little); if (s) s += strlen(little); return s;}/** * st_str_has_prefix_span: * @str: a string. * @prefix: the prefix to look for. * * Checks if @str begins with @prefix. * * Return value: a pointer to the character following @prefix in @str, * or %NULL if @str does not begin with @prefix. **/char *st_str_has_prefix_span (const char *str, const char *prefix){ g_return_val_if_fail(str != NULL, NULL); g_return_val_if_fail(prefix != NULL, NULL); return g_str_has_prefix(str, prefix) ? (char *) str + strlen(prefix) : NULL;}/** * st_str_like: * @str: a string. * @charset: a set of characters. * * Checks if all the characters of @str are members of @charset. * * Return value: %TRUE if all the characters of @str are members of * @charset. **/gbooleanst_str_like (const char *str, const char *charset){ g_return_val_if_fail(str != NULL, FALSE); g_return_val_if_fail(charset != NULL, FALSE); return strspn(str, charset) == strlen(str);}/** * st_pixbuf_new_from_file: * @filename: the name of the file to load. * * Creates a new pixbuf by loading an image from a file. If the file * cannot be loaded, st_notice() will be used to print the error. * * Return value: a new #GdkPixbuf, or %NULL on error. **/GdkPixbuf *st_pixbuf_new_from_file (const char *filename){ GdkPixbuf *pixbuf; GError *err = NULL; pixbuf = gdk_pixbuf_new_from_file(filename, &err); if (! pixbuf) { st_notice(_("error loading image: %s"), err->message); g_error_free(err); } return pixbuf;}/** * st_hig_section_new: * @title: the section title. * @contents: the widget to use as section contents. * * Creates a new HIG-compliant section, as defined by * <ulink url="http://developer.gnome.org/projects/gup/hig/2.0/design-window.html" type="http">Window Layout</ulink>. * * Return value: a new #GtkVBox containing @title and @contents. **/GtkWidget *st_hig_section_new (const char *title, GtkWidget *contents){ GtkWidget *vbox; char *markup; GtkWidget *label; GtkWidget *alignment; g_return_val_if_fail(title != NULL, NULL); g_return_val_if_fail(GTK_IS_WIDGET(contents), NULL); vbox = gtk_vbox_new(FALSE, SGTK_HIG_CONTROL_SPACING); markup = g_markup_printf_escaped("<span weight=\"bold\">%s</span>", title); label = gtk_label_new(markup); g_free(markup); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_label_set_use_markup(GTK_LABEL(label), TRUE); gtk_widget_show(label); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); alignment = gtk_alignment_new(0.5, 0.5, 1, 1); gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 12, 0); gtk_container_add(GTK_CONTAINER(alignment), contents); gtk_widget_show(alignment); gtk_box_pack_start(GTK_BOX(vbox), alignment, TRUE, TRUE, 0); return vbox;}/** * st_set_tooltip: * @widget: a widget. * @tooltip: a tooltip text. * * Sets the tooltip of @widget using the global #GtkTooltips object * used by streamtuner. **/voidst_set_tooltip (GtkWidget *widget, const char *tooltip){ GtkTooltips *tooltips = NULL; g_return_if_fail(GTK_IS_WIDGET(widget)); if (! tooltips) tooltips = gtk_tooltips_new(); gtk_tooltips_set_tip(tooltips, widget, tooltip, NULL);}/*** private implementation **************************************************/GtkWidget *st_logo_new (void){ GdkPixbuf *logo; GtkWidget *image; logo = st_pixbuf_new_from_file(ST_PNG("logo")); if (logo) { image = gtk_image_new_from_pixbuf(logo); g_object_unref(logo); } else image = gtk_image_new(); return image;}voidst_show_help (const char *link_id){#define filename BASEDOCDIR G_DIR_SEPARATOR_S "C" G_DIR_SEPARATOR_S "streamtuner.xml" if (g_file_test(filename, G_FILE_TEST_EXISTS)) { char *uri; gboolean status; GError *err = NULL; uri = link_id ? g_strconcat("ghelp://", filename, "?", link_id, NULL) : g_strconcat("ghelp://", filename, NULL); status = st_action_run("view-ghelp", uri, &err); g_free(uri); if (! status) { char *normalized; normalized = st_dialog_normalize(err->message); g_error_free(err); st_error_dialog(_("Unable to view the manual"), "%s", normalized); g_free(normalized); } } else st_error_dialog(_("Unable to view the manual"), _("The manual file %s does not exist."), filename);#undef filename}voidst_visit_homepage (const char *url){ GError *err = NULL; g_return_if_fail(url != NULL); if (! st_action_run("view-web", url, &err)) { char *normalized; normalized = st_dialog_normalize(err->message); st_error_dialog(_("Unable to visit the homepage"), "%s", normalized); g_free(normalized); g_error_free(err); }}voidst_parser_msg_cb (GScanner *scanner, char *message, gboolean error){ st_notice("%s:%i: %s", scanner->input_name, scanner->line, message);}voidst_window_set_icon (GtkWindow *window){ GdkPixbuf *icon; g_return_if_fail(GTK_IS_WINDOW(window)); icon = st_pixbuf_new_from_file(ST_PNG("streamtuner")); if (icon) { gtk_window_set_icon(window, icon); g_object_unref(icon); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -