📄 st-action.c
字号:
/* * 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 <glib.h>#include <glib/gi18n.h>#include "sg-util.h"#include "st-thread.h"#include "st-action.h"/*** variable declarations ***************************************************/static GHashTable *actions;/*** function declarations ***************************************************/static void st_action_register_real (const char *id, const char *label, const char *command);static void st_action_list_cb (gpointer key, gpointer value, gpointer user_data);static char *st_action_subst (const char *command, const char *uri);/*** API implementation ******************************************************//** * st_action_register: * @id: an unique id for the action. * @label: a human-readable label for the action. * @command: the default command for the action, or %NULL. * * Registers a new action. The action will appear in the applications * page of the streamtuner preferences, and the user will be able to * modify its associated command. **/voidst_action_register (const char *id, const char *label, const char *command){ g_return_if_fail(id != NULL); g_return_if_fail(label != NULL); st_action_register_real(id, label, command);}/** * st_action_run: * @id: the id of the action to run. * @uri: the URI to run the action on. * @err: a location to report errors, or %NULL. * * Runs action @id with @uri as parameter. The action must have been * previously registered with st_action_register(). * * Return value: %TRUE on success, %FALSE on failure. **/gbooleanst_action_run (const char *id, const char *uri, GError **err){ STAction *action; gboolean status; char *subst; g_return_val_if_fail(id != NULL, FALSE); g_return_val_if_fail(uri != NULL, FALSE); action = g_hash_table_lookup(actions, id); g_return_val_if_fail(action != NULL, FALSE); g_return_val_if_fail(action->label != NULL, FALSE); g_mutex_lock(action->mutex); subst = action->command ? st_action_subst(action->command, uri) : NULL; g_mutex_unlock(action->mutex); if (subst) { status = g_spawn_command_line_async(subst, err); g_free(subst); } else { status = FALSE; g_set_error(err, 0, 0, _("no command is set for \"%s\""), action->label); } return status;}/*** private implementation **************************************************/voidst_action_init (void){ actions = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); st_action_register("view-web", _("Open a web page"), "epiphany %q"); st_action_register("view-ghelp", _("Open a GNOME help document"), "yelp %q");}static voidst_action_register_real (const char *id, const char *label, const char *command){ g_return_if_fail(id != NULL); if (! g_hash_table_lookup(actions, id)) { /* don't register an action twice */ STAction *action; action = g_new(STAction, 1); action->mutex = g_mutex_new(); action->label = g_strdup(label); action->command = g_strdup(command); g_hash_table_insert(actions, g_strdup(id), action); }}voidst_action_associate (const char *id, const char *command){ STAction *action; g_return_if_fail(id != NULL); action = g_hash_table_lookup(actions, id); if (action) { g_mutex_lock(action->mutex); g_free(action->command); action->command = g_strdup(command); g_mutex_unlock(action->mutex); } else st_action_register_real(id, NULL, command); /* dummy action */}GSList *st_action_list (void){ GSList *list = NULL; g_hash_table_foreach(actions, st_action_list_cb, &list); return list;}static voidst_action_list_cb (gpointer key, gpointer value, gpointer user_data){ GSList **list = user_data; *list = g_slist_append(*list, key);}STAction *st_action_get (const char *id){ g_return_val_if_fail(id != NULL, NULL); return g_hash_table_lookup(actions, id);}static char *st_action_subst (const char *command, const char *uri){ GString *string; gboolean attn = FALSE; int i; char *quoted_uri = NULL; g_return_val_if_fail(command != NULL, NULL); g_return_val_if_fail(uri != NULL, NULL); string = g_string_new(NULL); for (i = 0; command[i]; i++) if (attn) { attn = FALSE; switch (command[i]) { case 'u': g_string_append(string, uri); break; case 'q': if (! quoted_uri) quoted_uri = g_shell_quote(uri); g_string_append(string, quoted_uri); break; case '%': g_string_append_c(string, '%'); break; default: g_string_append_printf(string, "%%%c", command[i]); } } else if (command[i] == '%') attn = TRUE; else g_string_append_c(string, command[i]); g_free(quoted_uri); return g_string_free(string, FALSE);}char *st_action_convert_old_style_command (const char *command){ GString *string; int i; gboolean quoted = FALSE; if (! command) return NULL; string = g_string_new(NULL); for (i = 0; command[i]; i++) { if (! quoted && command[i] == '\\') quoted = TRUE; else if (! quoted && command[i] == '%') g_string_append(string, "%u"); else { quoted = FALSE; g_string_append_c(string, command[i]); } } return g_string_free(string, FALSE);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -