Revision: 2637 http://geany.svn.sourceforge.net/geany/?rev=2637&view=rev Author: ntrel Date: 2008-06-03 10:22:04 -0700 (Tue, 03 Jun 2008)
Log Message: ----------- Note: this breaks the plugin API for plugins using document_find_by_filename(). Make document_find_by_filename() take only a utf8_filename argument, and now match any documents that have a filename set but aren't saved on disk. Add document_find_by_realpath() to the plugin API. Add filename argument for document_save_file_as(). Add GeanyDocument::real_path field, which if non-NULL indicates the file once existed on disk (not just as an unsaved document filename).
Modified Paths: -------------- trunk/ChangeLog trunk/src/build.c trunk/src/dialogs.c trunk/src/document.c trunk/src/document.h trunk/src/msgwindow.c trunk/src/navqueue.c trunk/src/plugindata.h trunk/src/plugins.c trunk/src/symbols.c trunk/src/win32.c
Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2008-06-03 16:30:54 UTC (rev 2636) +++ trunk/ChangeLog 2008-06-03 17:22:04 UTC (rev 2637) @@ -1,3 +1,19 @@ +2008-06-03 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com> + + * src/build.c, src/dialogs.c, src/document.c, src/document.h, + src/msgwindow.c, src/navqueue.c, src/plugindata.h, src/plugins.c, + src/symbols.c, src/win32.c, plugins/vcdiff.c: + Note: this breaks the plugin API for plugins using + document_find_by_filename(). + Make document_find_by_filename() take only a utf8_filename argument, + and now match any documents that have a filename set but aren't saved + on disk. + Add document_find_by_realpath() to the plugin API. + Add filename argument for document_save_file_as(). + Add GeanyDocument::real_path field, which if non-NULL indicates the + file once existed on disk (not just as an unsaved document filename). + + 2008-06-03 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
* src/main.c:
Modified: trunk/src/build.c =================================================================== --- trunk/src/build.c 2008-06-03 16:30:54 UTC (rev 2636) +++ trunk/src/build.c 2008-06-03 17:22:04 UTC (rev 2637) @@ -853,7 +853,7 @@ &filename, &line); if (line != -1 && filename != NULL) { - gint idx = document_find_by_filename(filename, FALSE); + gint idx = document_find_by_filename(filename);
editor_set_indicator_on_line(idx, line - 1); /* will check valid idx */ color = COLOR_RED; /* error message parsed on the line */
Modified: trunk/src/dialogs.c =================================================================== --- trunk/src/dialogs.c 2008-06-03 16:30:54 UTC (rev 2636) +++ trunk/src/dialogs.c 2008-06-03 17:22:04 UTC (rev 2637) @@ -390,6 +390,7 @@ if (open_new_tab) { /* "open" the saved file in a new tab and switch to it */ idx = document_clone(idx, utf8_filename); + document_save_file_as(idx, NULL); } else { @@ -409,11 +410,9 @@ documents[idx]->tm_file = NULL; g_free(documents[idx]->file_name); } - documents[idx]->file_name = g_strdup(utf8_filename); + document_save_file_as(idx, utf8_filename); }
- document_save_file_as(idx); - if (! open_new_tab) build_menu_update(idx); }
Modified: trunk/src/document.c =================================================================== --- trunk/src/document.c 2008-06-03 16:30:54 UTC (rev 2636) +++ trunk/src/document.c 2008-06-03 17:22:04 UTC (rev 2637) @@ -109,23 +109,42 @@ #define filenamecmp(a,b) strcmp((a), (b)) #endif
-static gint find_by_tm_filename(const gchar *filename) +/** + * Find and retrieve the index of the given filename in the %document list. + * + * @param realname The filename to search, which should be identical to the + * string returned by @c tm_get_real_path(). + * + * @return The %document index which has the given filename or @c -1 + * if no document was found. + * @note This is only really useful when passing a @c TMWorkObject::file_name. + * @see document_find_by_filename(). + **/ +gint document_find_by_realpath(const gchar *realname) { guint i; + gint ret = -1;
+ if (! realname) + return -1; /* file doesn't exist on disk */ + for (i = 0; i < documents_array->len; i++) { - TMWorkObject *tm_file = documents[i]->tm_file; + GeanyDocument *doc = documents[i];
- if (tm_file == NULL || tm_file->file_name == NULL) continue; + if (! documents[i]->is_valid || ! doc->real_path) continue;
- if (filenamecmp(filename, tm_file->file_name) == 0) - return i; + if (filenamecmp(realname, doc->real_path) == 0) + { + ret = i; + break; + } } - return -1; + return ret; }
+/* dereference symlinks, /../ junk in path and return locale encoding */ static gchar *get_real_path_from_utf8(const gchar *utf8_filename) { gchar *locale_name = utils_get_locale_from_utf8(utf8_filename); @@ -137,49 +156,47 @@
/** - * Find and retrieve the index of the given filename @a filename in the %document list. + * Find and retrieve the index of the given filename in the %document list. + * This matches either an exact GeanyDocument::file_name string, or variant + * filenames with relative elements in the path (e.g. @c "/dir/..//name" will + * match @c "/name"). * - * @param filename The filename to search (in UTF-8 encoding for non-TagManager filenames, - * else in locale encoding). - * @param is_tm_filename Whether the passed @a filename is a TagManager filename and therefore - * locale-encoded and already a realpath(). + * @param utf8_filename The filename to search (in UTF-8 encoding). * - * @return The %document index which has the given filename @a filename or @c -1 - * if @a filename is not open. + * @return The %document index which has the given filename or @c -1 + * if no document was found. + * @see document_find_by_realpath(). **/ -gint document_find_by_filename(const gchar *filename, gboolean is_tm_filename) +gint document_find_by_filename(const gchar *utf8_filename) { guint i; gint ret = -1; - gchar *realname;
- if (! filename) return -1; + if (! utf8_filename) + return -1;
- if (is_tm_filename) - return find_by_tm_filename(filename); /* more efficient */ - - realname = get_real_path_from_utf8(filename); /* dereference symlinks, /../ junk in path */ - if (! realname) return -1; - + /* First search GeanyDocument::file_name, so we can find documents with a + * filename set but not saved on disk, like vcdiff produces */ for (i = 0; i < documents_array->len; i++) { GeanyDocument *doc = documents[i]; - gchar *docname;
- if (doc->file_name == NULL) continue; + if (! documents[i]->is_valid || doc->file_name == NULL) continue;
- docname = get_real_path_from_utf8(doc->file_name); - if (! docname) continue; - - if (filenamecmp(realname, docname) == 0) + if (filenamecmp(utf8_filename, doc->file_name) == 0) { ret = i; - g_free(docname); break; } - g_free(docname); } - g_free(realname); + if (ret == -1) + { + /* Now try matching based on the realpath(), which is unique per file on disk */ + gchar *realname = get_real_path_from_utf8(utf8_filename); + + ret = document_find_by_realpath(realname); + g_free(realname); + } return ret; }
@@ -344,6 +361,7 @@ new_doc->mtime = 0; new_doc->changed = FALSE; new_doc->last_check = time(NULL); + new_doc->real_path = NULL;
full_doc->tag_store = NULL; full_doc->tag_tree = NULL; @@ -441,6 +459,17 @@ }
+static void set_filename(GeanyDocument *this, const gchar *utf8_filename) +{ + g_free(this->file_name); + this->file_name = g_strdup(utf8_filename); + + g_free(this->real_path); + this->real_path = utils_get_locale_from_utf8(utf8_filename); + setptr(this->real_path, tm_get_real_path(this->real_path)); +} + + /* Creates a new document and editor, adding a tab in the notebook. * @return The index of the created document */ static gint document_create(const gchar *utf8_filename) @@ -470,7 +499,7 @@ this = documents[new_idx]; init_doc_struct(this); /* initialize default document settings */
- this->file_name = (utf8_filename) ? g_strdup(utf8_filename) : NULL; + set_filename(this, utf8_filename);
this->sci = create_new_sci(new_idx);
@@ -531,12 +560,11 @@ msgwin_status_add(_("File %s closed."), DOC_FILENAME(idx)); g_free(documents[idx]->encoding); g_free(fdoc->saved_encoding.encoding); - g_free(documents[idx]->file_name); + set_filename(documents[idx], NULL); /* free and NULL file_name, real_path */ tm_workspace_remove_object(documents[idx]->tm_file, TRUE, TRUE);
documents[idx]->is_valid = FALSE; documents[idx]->sci = NULL; - documents[idx]->file_name = NULL; documents[idx]->file_type = NULL; documents[idx]->encoding = NULL; documents[idx]->has_bom = FALSE; @@ -1037,7 +1065,7 @@ utf8_filename = utils_get_utf8_from_locale(locale_filename);
/* if file is already open, switch to it and go */ - idx = document_find_by_filename(utf8_filename, FALSE); + idx = document_find_by_filename(utf8_filename); if (idx >= 0) { ui_add_recent_file(utf8_filename); /* either add or reorder recent item */ @@ -1288,15 +1316,19 @@ * Save the %document specified by @a idx, detecting the filetype. * * @param idx The %document index for the file to save. + * @param utf8_fname The new name for the document, in UTF-8, or NULL. * @return @c TRUE if the file was saved or @c FALSE if the file could not be saved. * @see document_save_file(). */ -gboolean document_save_file_as(gint idx) +gboolean document_save_file_as(gint idx, const gchar *utf8_fname) { gboolean ret;
if (! DOC_IDX_VALID(idx)) return FALSE;
+ if (utf8_fname) + set_filename(documents[idx], utf8_fname); + /* detect filetype */ if (FILETYPE_ID(documents[idx]->file_type) == GEANY_FILETYPES_NONE) {
Modified: trunk/src/document.h =================================================================== --- trunk/src/document.h 2008-06-03 16:30:54 UTC (rev 2636) +++ trunk/src/document.h 2008-06-03 17:22:04 UTC (rev 2637) @@ -71,9 +71,10 @@ /** Whether this %document support source code symbols(tags) to show in the sidebar. */ gboolean has_tags; /** The UTF-8 encoded file name. Be careful glibc and GLib functions expect the locale - representation of the file name which can be different from this. - For conversion into locale encoding for use with file functions of GLib, you can use - @ref utils_get_locale_from_utf8. */ + * representation of the file name which can be different from this. + * For conversion into locale encoding for use with file functions of GLib, you can use + * @ref utils_get_locale_from_utf8. + * @see real_path. */ gchar *file_name; /** The encoding of the %document, must be a valid string representation of an encoding, can * be retrieved with @ref encodings_get_charset_from_index. */ @@ -104,6 +105,12 @@ /** %Document-specific indentation setting. */ gboolean use_tabs; gboolean line_breaking; /**< Whether to split long lines as you type. */ + /** The link-dereferenced, locale-encoded file name. + * If non-NULL, this indicates the file once existed on disk (not just as an + * unsaved document with a filename set). + * + * @note This is the same as: @c tm_get_real_path(doc->file_name); */ + gchar *real_path; } GeanyDocument;
@@ -135,8 +142,10 @@ GEANY_STRING_UNTITLED)
-gint document_find_by_filename(const gchar *filename, gboolean is_tm_filename); +gint document_find_by_filename(const gchar *utf8_filename);
+gint document_find_by_realpath(const gchar *realname); + gint document_find_by_sci(ScintillaObject *sci);
gint document_get_notebook_page(gint doc_idx); @@ -181,7 +190,7 @@ gboolean document_reload_file(gint idx, const gchar *forced_enc);
-gboolean document_save_file_as(gint idx); +gboolean document_save_file_as(gint idx, const gchar *utf8_fname);
gboolean document_save_file(gint idx, gboolean force);
Modified: trunk/src/msgwindow.c =================================================================== --- trunk/src/msgwindow.c 2008-06-03 16:30:54 UTC (rev 2636) +++ trunk/src/msgwindow.c 2008-06-03 17:22:04 UTC (rev 2637) @@ -534,7 +534,7 @@ if (filename != NULL && line > -1) { gchar *utf8_filename = utils_get_utf8_from_locale(filename); - idx = document_find_by_filename(utf8_filename, FALSE); + idx = document_find_by_filename(utf8_filename); g_free(utf8_filename);
if (idx < 0) /* file not already open */
Modified: trunk/src/navqueue.c =================================================================== --- trunk/src/navqueue.c 2008-06-03 16:30:54 UTC (rev 2636) +++ trunk/src/navqueue.c 2008-06-03 17:22:04 UTC (rev 2637) @@ -171,9 +171,9 @@ }
-static gboolean goto_file_pos(const gchar *file, gboolean is_tm_filename, gint pos) +static gboolean goto_file_pos(const gchar *file, gint pos) { - gint file_idx = document_find_by_filename(file, is_tm_filename); + gint file_idx = document_find_by_filename(file);
if (file_idx < 0) return FALSE;
@@ -192,7 +192,7 @@
/* jump back */ fprev = g_queue_peek_nth(navigation_queue, nav_queue_pos + 1); - if (goto_file_pos(fprev->file, FALSE, fprev->pos)) + if (goto_file_pos(fprev->file, fprev->pos)) { nav_queue_pos++; } @@ -215,7 +215,7 @@
/* jump forward */ fnext = g_queue_peek_nth(navigation_queue, nav_queue_pos - 1); - if (goto_file_pos(fnext->file, FALSE, fnext->pos)) + if (goto_file_pos(fnext->file, fnext->pos)) { nav_queue_pos--; }
Modified: trunk/src/plugindata.h =================================================================== --- trunk/src/plugindata.h 2008-06-03 16:30:54 UTC (rev 2636) +++ trunk/src/plugindata.h 2008-06-03 17:22:04 UTC (rev 2637) @@ -36,12 +36,12 @@
/* The API version should be incremented whenever any plugin data types below are * modified or appended to. */ -static const gint api_version = 67; +static const gint api_version = 68;
/* 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 * are only appended, as this doesn't affect existing fields. */ -static const gint abi_version = 36; +static const gint abi_version = 37;
/** Check the plugin can be loaded by Geany. * This performs runtime checks that try to ensure: @@ -204,7 +204,8 @@ gint (*new_file) (const gchar *filename, struct GeanyFiletype *ft, const gchar *text); gint (*get_cur_idx) (void); gint (*get_n_idx) (guint i); - gint (*find_by_filename) (const gchar *filename, gboolean is_tm_filename); + gint (*find_by_filename) (const gchar *utf8_filename); + gint (*find_by_realpath) (const gchar *realname); struct GeanyDocument* (*get_current) (void); gboolean (*save_file) (gint idx, gboolean force); gint (*open_file) (const gchar *locale_filename, gboolean readonly,
Modified: trunk/src/plugins.c =================================================================== --- trunk/src/plugins.c 2008-06-03 16:30:54 UTC (rev 2636) +++ trunk/src/plugins.c 2008-06-03 17:22:04 UTC (rev 2637) @@ -98,6 +98,7 @@ &document_get_cur_idx, &document_get_n_idx, &document_find_by_filename, + &document_find_by_realpath, &document_get_current, &document_save_file, &document_open_file,
Modified: trunk/src/symbols.c =================================================================== --- trunk/src/symbols.c 2008-06-03 16:30:54 UTC (rev 2636) +++ trunk/src/symbols.c 2008-06-03 17:22:04 UTC (rev 2637) @@ -1194,8 +1194,9 @@
if (tmtag != NULL) { - gint new_idx = document_find_by_filename( - tmtag->atts.entry.file->work_object.file_name, TRUE); + gint new_idx = document_find_by_realpath( + tmtag->atts.entry.file->work_object.file_name); + /* not found in opened document, should open */ if (new_idx == -1) {
Modified: trunk/src/win32.c =================================================================== --- trunk/src/win32.c 2008-06-03 16:30:54 UTC (rev 2636) +++ trunk/src/win32.c 2008-06-03 17:22:04 UTC (rev 2637) @@ -406,8 +406,10 @@ { gint idx = document_get_cur_idx(); /* convert the resulting filename into UTF-8 */ - documents[idx]->file_name = g_locale_to_utf8(fname, -1, NULL, NULL, NULL); - document_save_file_as(idx); + gchar *utf8 = g_locale_to_utf8(fname, -1, NULL, NULL, NULL); + + document_save_file_as(idx, utf8); + g_free(utf8); } g_free(fname); return (retval != 0);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.