Rename utils_start_browser() in utils_open_browser() and add it to the plugin API.

Add plugin symbol plugin_help() which is called by Geany when the plugin should show its documentation (if any). This symbol is optional, plugins can omit it if not needed.
Add a Help button next to the Configure button in the plugin manager dialog to easily open a plugin's documentation if available.

git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@3524 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
Enrico Tröger 2009-01-28 19:30:18 +00:00
parent 8dc9c01f74
commit 5752ee9863
10 changed files with 67 additions and 16 deletions

View File

@ -14,6 +14,16 @@
* doc/plugins.dox, plugins/demoplugin.h: * doc/plugins.dox, plugins/demoplugin.h:
Mention necessary header includes in the plugin signal descriptions. Mention necessary header includes in the plugin signal descriptions.
Add missing header includes for the demoplugin. Add missing header includes for the demoplugin.
* doc/pluginsymbols.c, plugins/geanyfunctions.h, src/about.c,
src/build.c, src/callbacks.c, src/plugindata.h, src/plugins.c,
src/utils.c, src/utils.h:
Rename utils_start_browser() in utils_open_browser() and add it to
the plugin API.
Add plugin symbol plugin_help() which is called by Geany when the
plugin should show its documentation (if any). This symbol is
optional, plugins can omit it if not needed.
Add a Help button next to the Configure button in the plugin manager
dialog to easily open a plugin's documentation if available.
2009-01-27 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de> 2009-01-27 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>

View File

@ -97,3 +97,9 @@ void plugin_init(GeanyData *data);
* everything done in plugin_init() - e.g. destroy menu items, free memory. */ * everything done in plugin_init() - e.g. destroy menu items, free memory. */
void plugin_cleanup(); void plugin_cleanup();
/** Called whenever the plugin should show its documentation (if any). This may open a dialog,
* a browser with a website or a local installed HTML help file(see utils_start_browser())
* or something else.
* Can be omitted when not needed. */
void plugin_help();

View File

@ -164,6 +164,8 @@
geany_functions->p_utils->str_casecmp geany_functions->p_utils->str_casecmp
#define utils_get_date_time \ #define utils_get_date_time \
geany_functions->p_utils->get_date_time geany_functions->p_utils->get_date_time
#define utils_open_browser \
geany_functions->p_utils->open_browser
#define ui_dialog_vbox_new \ #define ui_dialog_vbox_new \
geany_functions->p_ui->dialog_vbox_new geany_functions->p_ui->dialog_vbox_new
#define ui_frame_new_with_alignment \ #define ui_frame_new_with_alignment \

View File

@ -442,6 +442,6 @@ static void header_label_style_set(GtkWidget *widget)
static void homepage_clicked(GtkButton *button, gpointer data) static void homepage_clicked(GtkButton *button, gpointer data)
{ {
utils_start_browser(data); utils_open_browser(data);
} }

View File

@ -1924,7 +1924,7 @@ static gboolean use_html_builtin(GeanyDocument *doc, GeanyFiletype *ft)
if (use_builtin) if (use_builtin)
{ {
gchar *uri = g_strconcat("file:///", g_path_skip_root(doc->file_name), NULL); gchar *uri = g_strconcat("file:///", g_path_skip_root(doc->file_name), NULL);
utils_start_browser(uri); utils_open_browser(uri);
g_free(uri); g_free(uri);
return TRUE; return TRUE;

View File

@ -1274,7 +1274,7 @@ on_help1_activate (GtkMenuItem *menuitem,
uri = g_strconcat(GEANY_HOMEPAGE, "manual/", VERSION, "/index.html", NULL); uri = g_strconcat(GEANY_HOMEPAGE, "manual/", VERSION, "/index.html", NULL);
} }
utils_start_browser(uri); utils_open_browser(uri);
g_free(uri); g_free(uri);
} }
@ -1291,7 +1291,7 @@ void
on_website1_activate (GtkMenuItem *menuitem, on_website1_activate (GtkMenuItem *menuitem,
gpointer user_data) gpointer user_data)
{ {
utils_start_browser(GEANY_HOMEPAGE); utils_open_browser(GEANY_HOMEPAGE);
} }

View File

@ -45,7 +45,7 @@
enum { enum {
/** The Application Programming Interface (API) version, incremented /** The Application Programming Interface (API) version, incremented
* whenever any plugin data types are modified or appended to. */ * whenever any plugin data types are modified or appended to. */
GEANY_API_VERSION = 129, GEANY_API_VERSION = 130,
/** The Application Binary Interface (ABI) version, incremented whenever /** The Application Binary Interface (ABI) version, incremented whenever
* existing fields in the plugin data types have to be changed or reordered. */ * existing fields in the plugin data types have to be changed or reordered. */
@ -353,6 +353,7 @@ typedef struct UtilsFuncs
GError **error); GError **error);
gint (*str_casecmp) (const gchar *s1, const gchar *s2); gint (*str_casecmp) (const gchar *s1, const gchar *s2);
gchar* (*get_date_time) (const gchar *format, time_t *time_to_use); gchar* (*get_date_time) (const gchar *format, time_t *time_to_use);
void (*open_browser) (const gchar *uri);
} }
UtilsFuncs; UtilsFuncs;

View File

@ -91,6 +91,7 @@ typedef struct Plugin
void (*init) (GeanyData *data); /* Called when the plugin is enabled */ void (*init) (GeanyData *data); /* Called when the plugin is enabled */
GtkWidget* (*configure) (GtkDialog *dialog); /* plugin configure dialog, optional */ GtkWidget* (*configure) (GtkDialog *dialog); /* plugin configure dialog, optional */
void (*help) (void); /* Called when the plugin should show some help, optional */
void (*cleanup) (void); /* Called when the plugin is disabled or when Geany exits */ void (*cleanup) (void); /* Called when the plugin is disabled or when Geany exits */
} }
Plugin; Plugin;
@ -212,7 +213,8 @@ static UtilsFuncs utils_funcs = {
&utils_spawn_sync, &utils_spawn_sync,
&utils_spawn_async, &utils_spawn_async,
&utils_str_casecmp, &utils_str_casecmp,
&utils_get_date_time &utils_get_date_time,
&utils_open_browser
}; };
static UIUtilsFuncs uiutils_funcs = { static UIUtilsFuncs uiutils_funcs = {
@ -536,6 +538,7 @@ plugin_init(Plugin *plugin)
/* store some function pointers for later use */ /* store some function pointers for later use */
g_module_symbol(plugin->module, "plugin_configure", (void *) &plugin->configure); g_module_symbol(plugin->module, "plugin_configure", (void *) &plugin->configure);
g_module_symbol(plugin->module, "plugin_help", (void *) &plugin->help);
g_module_symbol(plugin->module, "plugin_cleanup", (void *) &plugin->cleanup); g_module_symbol(plugin->module, "plugin_cleanup", (void *) &plugin->cleanup);
if (plugin->cleanup == NULL) if (plugin->cleanup == NULL)
{ {
@ -964,7 +967,9 @@ enum
PLUGIN_COLUMN_NAME, PLUGIN_COLUMN_NAME,
PLUGIN_COLUMN_FILE, PLUGIN_COLUMN_FILE,
PLUGIN_COLUMN_PLUGIN, PLUGIN_COLUMN_PLUGIN,
PLUGIN_N_COLUMNS PLUGIN_N_COLUMNS,
PM_BUTTON_CONFIGURE,
PM_BUTTON_HELP
}; };
typedef struct typedef struct
@ -974,6 +979,7 @@ typedef struct
GtkListStore *store; GtkListStore *store;
GtkWidget *description_label; GtkWidget *description_label;
GtkWidget *configure_button; GtkWidget *configure_button;
GtkWidget *help_button;
} }
PluginManagerWidgets; PluginManagerWidgets;
@ -1005,6 +1011,8 @@ void pm_selection_changed(GtkTreeSelection *selection, gpointer user_data)
gtk_widget_set_sensitive(pm_widgets.configure_button, gtk_widget_set_sensitive(pm_widgets.configure_button,
p->configure != NULL && g_list_find(active_plugin_list, p) != NULL); p->configure != NULL && g_list_find(active_plugin_list, p) != NULL);
gtk_widget_set_sensitive(pm_widgets.help_button,
p->help != NULL && g_list_find(active_plugin_list, p) != NULL);
} }
} }
} }
@ -1032,7 +1040,9 @@ static void pm_plugin_toggled(GtkCellRendererToggle *cell, gchar *pth, gpointer
/* unload plugin module */ /* unload plugin module */
if (!state) if (!state)
keybindings_write_to_file(); /* save shortcuts (only need this group, but it doesn't take long) */ /* save shortcuts (only need this group, but it doesn't take long) */
keybindings_write_to_file();
plugin_free(p); plugin_free(p);
/* reload plugin module and initialize it if item is checked */ /* reload plugin module and initialize it if item is checked */
@ -1149,7 +1159,7 @@ static void configure_plugin(Plugin *p)
} }
void pm_on_configure_button_clicked(GtkButton *button, gpointer user_data) void pm_on_plugin_button_clicked(GtkButton *button, gpointer user_data)
{ {
GtkTreeModel *model; GtkTreeModel *model;
GtkTreeSelection *selection; GtkTreeSelection *selection;
@ -1163,7 +1173,10 @@ void pm_on_configure_button_clicked(GtkButton *button, gpointer user_data)
if (p != NULL) if (p != NULL)
{ {
if (GPOINTER_TO_INT(user_data) == PM_BUTTON_CONFIGURE)
configure_plugin(p); configure_plugin(p);
else if (GPOINTER_TO_INT(user_data) == PM_BUTTON_HELP && p->help != NULL)
p->help();
} }
} }
} }
@ -1228,7 +1241,12 @@ static void pm_show_dialog(GtkMenuItem *menuitem, gpointer user_data)
pm_widgets.configure_button = gtk_button_new_from_stock(GTK_STOCK_PREFERENCES); pm_widgets.configure_button = gtk_button_new_from_stock(GTK_STOCK_PREFERENCES);
gtk_widget_set_sensitive(pm_widgets.configure_button, FALSE); gtk_widget_set_sensitive(pm_widgets.configure_button, FALSE);
g_signal_connect(pm_widgets.configure_button, "clicked", g_signal_connect(pm_widgets.configure_button, "clicked",
G_CALLBACK(pm_on_configure_button_clicked), NULL); G_CALLBACK(pm_on_plugin_button_clicked), GINT_TO_POINTER(PM_BUTTON_CONFIGURE));
pm_widgets.help_button = gtk_button_new_from_stock(GTK_STOCK_HELP);
gtk_widget_set_sensitive(pm_widgets.help_button, FALSE);
g_signal_connect(pm_widgets.help_button, "clicked",
G_CALLBACK(pm_on_plugin_button_clicked), GINT_TO_POINTER(PM_BUTTON_HELP));
label2 = gtk_label_new(_("<b>Plugin details:</b>")); label2 = gtk_label_new(_("<b>Plugin details:</b>"));
gtk_label_set_use_markup(GTK_LABEL(label2), TRUE); gtk_label_set_use_markup(GTK_LABEL(label2), TRUE);
@ -1243,13 +1261,14 @@ static void pm_show_dialog(GtkMenuItem *menuitem, gpointer user_data)
hbox = gtk_hbox_new(FALSE, 0); hbox = gtk_hbox_new(FALSE, 0);
gtk_box_pack_start(GTK_BOX(hbox), label2, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox), label2, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(hbox), pm_widgets.help_button, FALSE, FALSE, 4);
gtk_box_pack_start(GTK_BOX(hbox), pm_widgets.configure_button, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), pm_widgets.configure_button, FALSE, FALSE, 0);
label_vbox = gtk_vbox_new(FALSE, 0); label_vbox = gtk_vbox_new(FALSE, 3);
gtk_box_pack_start(GTK_BOX(label_vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(label_vbox), hbox, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(label_vbox), desc_win, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(label_vbox), desc_win, FALSE, FALSE, 0);
vbox2 = gtk_vbox_new(FALSE, 6); vbox2 = gtk_vbox_new(FALSE, 3);
gtk_box_pack_start(GTK_BOX(vbox2), label, FALSE, FALSE, 5); gtk_box_pack_start(GTK_BOX(vbox2), label, FALSE, FALSE, 5);
gtk_box_pack_start(GTK_BOX(vbox2), swin, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox2), swin, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(vbox2), label_vbox, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox2), label_vbox, FALSE, FALSE, 0);

View File

@ -59,13 +59,26 @@
#include "utils.h" #include "utils.h"
void utils_start_browser(const gchar *uri) /**
* Tries to open the given URI in a browser.
* On Windows, the system's default browser is opened.
* On non-Windows systems, the browser command set in the preferences dialog is used. In case
* that fails or it is unset, @a xdg-open is used as fallback as well as some other known
* browsers.
*
* @param uri The URI to open in the web browser.
**/
void utils_open_browser(const gchar *uri)
{ {
#ifdef G_OS_WIN32 #ifdef G_OS_WIN32
g_return_if_fail(uri != NULL);
win32_open_browser(uri); win32_open_browser(uri);
#else #else
gchar *cmdline = g_strconcat(tool_prefs.browser_cmd, " ", uri, NULL); gchar *cmdline;
g_return_if_fail(uri != NULL);
cmdline = g_strconcat(tool_prefs.browser_cmd, " ", uri, NULL);
if (! g_spawn_command_line_async(cmdline, NULL)) if (! g_spawn_command_line_async(cmdline, NULL))
{ {
const gchar *argv[3]; const gchar *argv[3];

View File

@ -54,7 +54,7 @@
ptr < &ptr_array->pdata[ptr_array->len]; ++ptr, item = *ptr) ptr < &ptr_array->pdata[ptr_array->len]; ++ptr, item = *ptr)
void utils_start_browser(const gchar *uri); void utils_open_browser(const gchar *uri);
gint utils_get_line_endings(const gchar* buffer, glong size); gint utils_get_line_endings(const gchar* buffer, glong size);