Branch: refs/heads/master Author: Nick Treleaven nick.treleaven@btinternet.com Committer: Nick Treleaven nick.treleaven@btinternet.com Date: Wed, 27 Aug 2014 15:19:33 UTC Commit: 2f6815841de2d0abea7fdb0629802a0dad54af14 https://github.com/geany/geany/commit/2f6815841de2d0abea7fdb0629802a0dad54af...
Log Message: ----------- Merge pull request #256 from ntrel/doc-id
Support pseudo-unique IDs for documents
Modified Paths: -------------- plugins/geanyfunctions.h src/document.c src/document.h src/msgwindow.c src/plugindata.h src/plugins.c
Modified: plugins/geanyfunctions.h 2 lines changed, 2 insertions(+), 0 deletions(-) =================================================================== @@ -80,6 +80,8 @@ geany_functions->p_document->document_compare_by_tab_order #define document_compare_by_tab_order_reverse \ geany_functions->p_document->document_compare_by_tab_order_reverse +#define document_find_by_id \ + geany_functions->p_document->document_find_by_id #define editor_get_indent_prefs \ geany_functions->p_editor->editor_get_indent_prefs #define editor_create_widget \
Modified: src/document.c 45 lines changed, 42 insertions(+), 3 deletions(-) =================================================================== @@ -84,9 +84,11 @@ GeanyFilePrefs file_prefs;
/** Dynamic array of GeanyDocument pointers. - * Once a pointer is added to this, it is never freed. This means you can keep a pointer - * to a document over time, but it may represent a different - * document later on, or may have been closed and become invalid. + * Once a pointer is added to this, it is never freed. This means the same document pointer + * can represent a different document later on, or it may have been closed and become invalid. + * For this reason, you should use document_find_by_id() instead of storing + * document pointers over time if there is a chance the user can close the + * document. * * @warning You must check @c GeanyDocument::is_valid when iterating over this array. * This is done automatically if you use the foreach_document() macro. @@ -110,6 +112,9 @@ typedef struct } undo_action;
+static guint doc_id_counter = 0; + + static void document_undo_clear(GeanyDocument *doc); static void document_redo_add(GeanyDocument *doc, guint type, gpointer data); static gboolean remove_page(guint page_num); @@ -225,6 +230,38 @@ GeanyDocument *document_find_by_sci(ScintillaObject *sci) }
+/** Lookup an old document by its ID. + * Useful when the corresponding document may have been closed since the + * ID was retrieved. + * @return @c NULL if the document is no longer open. + * + * Example: + * @code + * static guint id; + * GeanyDocument *doc = ...; + * id = doc->id; // store ID + * ... + * // time passes - the document may have been closed by now + * GeanyDocument *doc = document_find_by_id(id); + * gboolean still_open = (doc != NULL); + * @endcode + * @since 1.25. */ +GeanyDocument *document_find_by_id(guint id) +{ + guint i; + + if (!id) + return NULL; + + foreach_document(i) + { + if (documents[i]->id == id) + return documents[i]; + } + return NULL; +} + + /** Gets the notebook page index for a document. * @param doc The document. * @return The index. @@ -586,6 +623,7 @@ static GeanyDocument *document_create(const gchar *utf8_filename)
/* initialize default document settings */ doc->priv = g_new0(GeanyDocumentPrivate, 1); + doc->id = ++doc_id_counter; doc->index = new_idx; doc->file_name = g_strdup(utf8_filename); doc->editor = editor_create(doc); @@ -648,6 +686,7 @@ static gboolean remove_page(guint page_num) ui_add_recent_document(doc);
doc->is_valid = FALSE; + doc->id = 0;
if (main_status.quitting) {
Modified: src/document.h 6 lines changed, 6 insertions(+), 0 deletions(-) =================================================================== @@ -118,6 +118,10 @@ typedef struct GeanyDocument * not be set elsewhere. * @see file_name. */ gchar *real_path; + /** A pseudo-unique ID for this document. + * @c 0 is reserved as an unused value. + * @see document_find_by_id(). */ + guint id;
struct GeanyDocumentPrivate *priv; /* should be last, append fields before this item */ } @@ -208,6 +212,8 @@ GeanyDocument *document_index(gint idx);
GeanyDocument *document_find_by_sci(ScintillaObject *sci);
+GeanyDocument *document_find_by_id(guint id); + gint document_get_notebook_page(GeanyDocument *doc);
GeanyDocument* document_get_from_page(guint page_num);
Modified: src/msgwindow.c 40 lines changed, 31 insertions(+), 9 deletions(-) =================================================================== @@ -66,6 +66,15 @@ ParseData;
MessageWindow msgwindow;
+enum +{ + MSG_COL_LINE = 0, + MSG_COL_DOC_ID, + MSG_COL_COLOR, + MSG_COL_STRING, + MSG_COL_COUNT +}; +
static void prepare_msg_tree_view(void); static void prepare_status_tree_view(void); @@ -177,8 +186,8 @@ static void prepare_msg_tree_view(void) GtkTreeViewColumn *column; GtkTreeSelection *selection;
- /* line, doc, fg, str */ - msgwindow.store_msg = gtk_list_store_new(4, G_TYPE_INT, G_TYPE_POINTER, + /* line, doc id, fg, str */ + msgwindow.store_msg = gtk_list_store_new(MSG_COL_COUNT, G_TYPE_INT, G_TYPE_UINT, GDK_TYPE_COLOR, G_TYPE_STRING); gtk_tree_view_set_model(GTK_TREE_VIEW(msgwindow.tree_msg), GTK_TREE_MODEL(msgwindow.store_msg)); g_object_unref(msgwindow.store_msg); @@ -382,7 +391,9 @@ void msgwin_msg_add_string(gint msg_color, gint line, GeanyDocument *doc, const utf8_msg = tmp;
gtk_list_store_append(msgwindow.store_msg, &iter); - gtk_list_store_set(msgwindow.store_msg, &iter, 0, line, 1, doc, 2, color, 3, utf8_msg, -1); + gtk_list_store_set(msgwindow.store_msg, &iter, + MSG_COL_LINE, line, MSG_COL_DOC_ID, doc ? doc->id : 0, MSG_COL_COLOR, + color, MSG_COL_STRING, utf8_msg, -1);
g_free(tmp); if (utf8_msg != tmp) @@ -1069,17 +1080,28 @@ gboolean msgwin_goto_messages_file_line(gboolean focus_editor) if (gtk_tree_selection_get_selected(selection, &model, &iter)) { gint line; + guint id; gchar *string; GeanyDocument *doc; GeanyDocument *old_doc = document_get_current();
- gtk_tree_model_get(model, &iter, 0, &line, 1, &doc, 3, &string, -1); - /* doc may have been closed, so check doc->index: */ - if (line >= 0 && DOC_VALID(doc)) + gtk_tree_model_get(model, &iter, + MSG_COL_LINE, &line, MSG_COL_DOC_ID, &id, MSG_COL_STRING, &string, -1); + if (line >= 0 && id > 0) { - ret = navqueue_goto_line(old_doc, doc, line); - if (ret && focus_editor) - gtk_widget_grab_focus(GTK_WIDGET(doc->editor->sci)); + /* check doc is still open */ + doc = document_find_by_id(id); + if (!doc) + { + ui_set_statusbar(FALSE, _("The document has been closed.")); + utils_beep(); + } + else + { + ret = navqueue_goto_line(old_doc, doc, line); + if (ret && focus_editor) + gtk_widget_grab_focus(GTK_WIDGET(doc->editor->sci)); + } } else if (line < 0 && string != NULL) {
Modified: src/plugindata.h 3 lines changed, 2 insertions(+), 1 deletions(-) =================================================================== @@ -58,7 +58,7 @@ G_BEGIN_DECLS * @warning You should not test for values below 200 as previously * @c GEANY_API_VERSION was defined as an enum value, not a macro. */ -#define GEANY_API_VERSION 218 +#define GEANY_API_VERSION 219
/* hack to have a different ABI when built with GTK3 because loading GTK2-linked plugins * with GTK3-linked Geany leads to crash */ @@ -324,6 +324,7 @@ typedef struct DocumentFuncs gint (*document_compare_by_display_name) (gconstpointer a, gconstpointer b); gint (*document_compare_by_tab_order) (gconstpointer a, gconstpointer b); gint (*document_compare_by_tab_order_reverse) (gconstpointer a, gconstpointer b); + GeanyDocument* (*document_find_by_id)(guint id); } DocumentFuncs;
Modified: src/plugins.c 3 lines changed, 2 insertions(+), 1 deletions(-) =================================================================== @@ -111,7 +111,8 @@ static DocumentFuncs doc_funcs = { &document_get_notebook_page, &document_compare_by_display_name, &document_compare_by_tab_order, - &document_compare_by_tab_order_reverse + &document_compare_by_tab_order_reverse, + &document_find_by_id };
static EditorFuncs editor_funcs = {
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).