diff --git a/ChangeLog b/ChangeLog index 4029162bd..5d05cb63c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,16 @@ * src/symbols.c, src/treeviews.c, src/treeviews.h: Revert the change to make symbol sections bold and use some small indentation when expanders are hidden. + * src/geanyobject.c, src/geanyobject.h, src/main.c, src/plugindata.h, + src/plugins.c, src/project.c, src/project.h: + Remove ununsed function project_save(). + Fix typo in plugin API at utils_mkdir(). + Add document_get_n_idx() to the plugin API. + Fix display of plugin separator in the Tools menu when only plugins + without menu item are loaded. + Add three new signals: project_open, project_save, project_close. + On Shutdown close the project before plugins are unloaded to let + plugins work on the last project closed event. 2007-11-20 Enrico Tröger diff --git a/src/geanyobject.c b/src/geanyobject.c index 1dd7addab..4c2963192 100644 --- a/src/geanyobject.c +++ b/src/geanyobject.c @@ -116,6 +116,33 @@ static void create_signals(GObjectClass *g_object_class) gtk_marshal_NONE__INT, G_TYPE_NONE, 1, G_TYPE_INT); + + geany_object_signals[GCB_PROJECT_OPEN] = g_signal_new ( + "project-open", + G_OBJECT_CLASS_TYPE (g_object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GeanyObjectClass, project_open), + NULL, NULL, + gtk_marshal_NONE__INT, + G_TYPE_NONE, 1, + G_TYPE_POINTER); + geany_object_signals[GCB_PROJECT_SAVE] = g_signal_new ( + "project-save", + G_OBJECT_CLASS_TYPE (g_object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GeanyObjectClass, project_save), + NULL, NULL, + gtk_marshal_NONE__INT, + G_TYPE_NONE, 1, + G_TYPE_POINTER); + geany_object_signals[GCB_PROJECT_CLOSE] = g_signal_new ( + "project-close", + G_OBJECT_CLASS_TYPE (g_object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GeanyObjectClass, project_close), + NULL, NULL, + gtk_marshal_NONE__NONE, + G_TYPE_NONE, 0); } @@ -146,7 +173,7 @@ GObject* geany_object_new(void) } -void geany_object_finalize(GObject *object) +static void geany_object_finalize(GObject *object) { GeanyObject *self; diff --git a/src/geanyobject.h b/src/geanyobject.h index 4ab50f28f..756f51b3e 100644 --- a/src/geanyobject.h +++ b/src/geanyobject.h @@ -38,6 +38,9 @@ typedef enum GCB_DOCUMENT_OPEN, GCB_DOCUMENT_SAVE, GCB_DOCUMENT_ACTIVATE, + GCB_PROJECT_OPEN, + GCB_PROJECT_SAVE, + GCB_PROJECT_CLOSE, GCB_MAX } GeanyCallbackId; @@ -71,10 +74,13 @@ struct _GeanyObjectClass void (*document_open)(gint idx); void (*document_save)(gint idx); void (*document_activate)(gint idx); + void (*project_open)(GKeyFile *keyfile); + void (*project_save)(GKeyFile *keyfile); + void (*project_close)(); }; GType geany_object_get_type (void); -GObject* geany_object_new (void); +GObject* geany_object_new (void); G_END_DECLS diff --git a/src/main.c b/src/main.c index 9629ef5dd..8f892ca75 100644 --- a/src/main.c +++ b/src/main.c @@ -795,12 +795,13 @@ void main_quit() socket_finalize(); #endif + if (app->project != NULL) + project_close(FALSE); + #ifdef HAVE_PLUGINS if (want_plugins) plugins_free(); #endif - if (app->project != NULL) - project_close(FALSE); navqueue_free(); keybindings_free(); diff --git a/src/plugindata.h b/src/plugindata.h index dda2ba4cf..27e9d7ea0 100644 --- a/src/plugindata.h +++ b/src/plugindata.h @@ -61,21 +61,39 @@ * * "document-new" * Sent when a new document is created. + * Handler: void user_function(GObject *obj, gint idx, gpointer user_data); * * "document-open" * Sent when a file is opened. + * Handler: void user_function(GObject *obj, gint idx, gpointer user_data); * * "document-save" * Sent when a file is saved. + * Handler: void user_function(GObject *obj, gint idx, gpointer user_data); * * "document-activate" * Sent when switching notebook pages. + * Handler: void user_function(GObject *obj, gint idx, gpointer user_data); + * + * "project-open" + * Sent after a project is opened but before session files are loaded. + * Handler: void user_function(GObject *obj, GKeyFile *config, gpointer user_data); + * + * "project-save" + * Sent when a project is saved(happens when the project is created, the properties + * dialog is closed or Geany is exited). This signal is emitted shortly before Geany + * will write the contents of the GKeyFile to the disc. + * Handler: void user_function(GObject *obj, GKeyFile *config, gpointer user_data); + * + * "project-close" + * Sent after a project is closed. + * Handler: void user_function(GObject *obj, gpointer user_data); */ /* The API version should be incremented whenever any plugin data types below are * modified or appended to. */ -static const gint api_version = 31; +static const gint api_version = 32; /* The ABI version should be incremented whenever existing fields in the plugin * data types below have to be changed or reordered. It should stay the same if fields @@ -192,6 +210,7 @@ typedef struct DocumentFuncs { gint (*new_file) (const gchar *filename, struct filetype *ft, const gchar *text); gint (*get_cur_idx) (); + gint (*get_n_idx) (guint i); struct document* (*get_current) (); gboolean (*save_file)(gint idx, gboolean force); gint (*open_file)(const gchar *locale_filename, gboolean readonly, @@ -262,7 +281,7 @@ typedef struct UtilsFuncs gchar* (*get_locale_from_utf8) (const gchar *utf8_text); gchar* (*get_utf8_from_locale) (const gchar *locale_text); gchar* (*remove_ext_from_filename) (const gchar *filename); - gint (*utils_mkdir) (const gchar *path, gboolean create_parent_dirs); + gint (*mkdir) (const gchar *path, gboolean create_parent_dirs); } UtilsFuncs; diff --git a/src/plugins.c b/src/plugins.c index 38fb55d50..3b31860d3 100644 --- a/src/plugins.c +++ b/src/plugins.c @@ -79,13 +79,13 @@ Plugin; static GList *plugin_list = NULL; // list of all available, loadable plugins static GList *active_plugin_list = NULL; // list of only actually loaded plugins -static GtkWidget *separator = NULL; // separator in the Tools menu static void pm_show_dialog(GtkMenuItem *menuitem, gpointer user_data); static DocumentFuncs doc_funcs = { &document_new_file, &document_get_cur_idx, + &document_get_n_idx, &document_get_current, &document_save_file, &document_open_file, @@ -456,8 +456,8 @@ plugin_unload(Plugin *plugin) remove_callbacks(plugin); active_plugin_list = g_list_remove(active_plugin_list, plugin); + geany_debug("Unloaded: %s", plugin->filename); } - geany_debug("Unloaded: %s", plugin->filename); } @@ -467,13 +467,8 @@ plugin_free(Plugin *plugin) g_return_if_fail(plugin); g_return_if_fail(plugin->module); - if (g_list_find(active_plugin_list, plugin) != NULL) - { // only do cleanup if the plugin was actually loaded - if (plugin->cleanup) - plugin->cleanup(); + plugin_unload(plugin); - remove_callbacks(plugin); - } if (! g_module_close(plugin->module)) g_warning("%s: %s", plugin->filename, g_module_error()); @@ -555,9 +550,6 @@ void plugins_init() gtk_widget_show(widget); g_signal_connect((gpointer) widget, "activate", G_CALLBACK(pm_show_dialog), NULL); - separator = gtk_separator_menu_item_new(); - gtk_container_add(GTK_CONTAINER(geany_data.tools_menu), separator); - load_plugin_paths(); plugins_update_tools_menu(); @@ -599,6 +591,7 @@ void plugins_free() g_list_free(active_plugin_list); g_object_unref(geany_object); + geany_object = NULL; // to mark the object as invalid for any code which tries to emit signals } @@ -616,12 +609,29 @@ void plugins_update_document_sensitive(gboolean enabled) } +static gint +plugin_has_menu(Plugin *a, Plugin *b) +{ + if (((PluginFields)a->fields).menu_item != NULL) + return 0; + + return 1; +} + + void plugins_update_tools_menu() { - if (separator == NULL) - return; + gboolean found; + static GtkWidget *separator = NULL; - ui_widget_show_hide(separator, g_list_length(active_plugin_list) > 0); + if (separator == NULL) + { + separator = gtk_separator_menu_item_new(); + gtk_container_add(GTK_CONTAINER(geany_data.tools_menu), separator); + } + + found = (g_list_find_custom(active_plugin_list, NULL, (GCompareFunc) plugin_has_menu) != NULL); + ui_widget_show_hide(separator, found); } diff --git a/src/project.c b/src/project.c index db201d871..0083163f4 100644 --- a/src/project.c +++ b/src/project.c @@ -43,6 +43,7 @@ #endif #include "build.h" #include "document.h" +#include "geanyobject.h" ProjectPrefs project_prefs = {NULL}; @@ -290,16 +291,6 @@ static void update_ui() } -void project_save() -{ - g_return_if_fail(app->project != NULL); - - write_config(); - - ui_set_statusbar(TRUE, _("Project \"%s\" saved."), app->project->name); -} - - // open_default will make function reload default session files on close void project_close(gboolean open_default) { @@ -331,6 +322,11 @@ void project_close(gboolean open_default) configuration_open_files(); } + if (geany_object) + { + g_signal_emit_by_name(geany_object, "project-close"); + } + tm_workspace_update(TM_WORK_OBJECT(app->tm_workspace), TRUE, TRUE, FALSE); update_ui(); } @@ -872,6 +868,10 @@ static gboolean load_config(const gchar *filename) // fetch session files too configuration_load_session_files(config); + if (geany_object) + { + g_signal_emit_by_name(geany_object, "project-open", config); + } g_key_file_free(config); update_ui(); @@ -912,6 +912,10 @@ static gboolean write_config() /// TODO maybe it is useful to store relative file names if base_path is relative configuration_save_session_files(config); + if (geany_object) + { + g_signal_emit_by_name(geany_object, "project-save", config); + } // write the file data = g_key_file_to_data(config, NULL, NULL); ret = (utils_write_file(filename, data) == 0); diff --git a/src/project.h b/src/project.h index 629bdbfbb..b382a2170 100644 --- a/src/project.h +++ b/src/project.h @@ -53,8 +53,6 @@ void project_new(); void project_open(); -void project_save(); - void project_close(gboolean open_default); void project_properties();