SF.net SVN: geany: [2705] trunk

ntrel at users.sourceforge.net ntrel at xxxxx
Wed Jun 18 17:03:13 UTC 2008


Revision: 2705
          http://geany.svn.sourceforge.net/geany/?rev=2705&view=rev
Author:   ntrel
Date:     2008-06-18 10:03:08 -0700 (Wed, 18 Jun 2008)

Log Message:
-----------
Merge the document-pointer branch.
Note: this breaks the plugin API for document functions,
document signal callbacks, msgwin_msg_add() and navqueue_goto_line().
Make all DocumentFuncs use a GeanyDocument* instead of an integer
index, so there's no need to access the documents array or use
DOC_IDX_VALID() - usually just check for non-NULL.
Pass a document pointer to the callbacks of all document-* signals.
Add GeanyDocument::index field for use with the documents array.
Remove DocumentFuncs::get_cur_idx() - use get_current() instead.
Replace DocumentFuncs::get_n_idx() with get_from_page().
Rename DocumentFuncs::find_by_realpath() to find_by_real_path().
Replace DocumentFuncs::remove() with remove_page().
Add 'changed' argument for DocumentFuncs::set_text_changed().
Make NavQueueFuncs and MsgWinFuncs use a GeanyDocument* instead of an
integer index.
Add DOC_VALID() macro.
Add deprecated DOC_IDX() macro to get the document index from a
possibly NULL pointer; deprecate macro DOC_IDX_VALID. These macros
can make porting outside plugins easier; of course, it is better to
rewrite the code to use document pointers.
Use document pointer instead of an index to the documents array
everywhere in the core code.
Rename utils_check_disk_status() in document_check_disk_status() and
move it into document.c.
Adjust plugins to work with these changes.
Add dox for document_set_filetype().
Rename debugging function doc() doc_at() to avoid conflicts.
Update plugin signals dox.

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/doc/plugins.dox
    trunk/plugins/autosave.c
    trunk/plugins/classbuilder.c
    trunk/plugins/export.c
    trunk/plugins/filebrowser.c
    trunk/plugins/htmlchars.c
    trunk/plugins/vcdiff.c
    trunk/src/build.c
    trunk/src/build.h
    trunk/src/callbacks.c
    trunk/src/callbacks.h
    trunk/src/dialogs.c
    trunk/src/dialogs.h
    trunk/src/document.c
    trunk/src/document.h
    trunk/src/editor.c
    trunk/src/editor.h
    trunk/src/encodings.c
    trunk/src/filetypes.c
    trunk/src/filetypes.h
    trunk/src/geany.h
    trunk/src/geanyobject.c
    trunk/src/geanyobject.h
    trunk/src/keybindings.c
    trunk/src/keyfile.c
    trunk/src/main.c
    trunk/src/msgwindow.c
    trunk/src/msgwindow.h
    trunk/src/navqueue.c
    trunk/src/navqueue.h
    trunk/src/notebook.c
    trunk/src/notebook.h
    trunk/src/plugindata.h
    trunk/src/plugins.c
    trunk/src/prefs.c
    trunk/src/printing.c
    trunk/src/printing.h
    trunk/src/project.c
    trunk/src/search.c
    trunk/src/search.h
    trunk/src/socket.c
    trunk/src/symbols.c
    trunk/src/symbols.h
    trunk/src/tools.c
    trunk/src/tools.h
    trunk/src/treeviews.c
    trunk/src/treeviews.h
    trunk/src/ui_utils.c
    trunk/src/ui_utils.h
    trunk/src/utils.c
    trunk/src/utils.h
    trunk/src/vte.c
    trunk/src/win32.c

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2008-06-18 14:18:26 UTC (rev 2704)
+++ trunk/ChangeLog	2008-06-18 17:03:08 UTC (rev 2705)
@@ -1,3 +1,49 @@
+2008-06-18  Nick Treleaven  <nick(dot)treleaven(at)btinternet(dot)com>
+
+ * src/build.c, src/utils.c, src/win32.c, src/ui_utils.h, src/build.h,
+   src/utils.h, src/keybindings.c, src/printing.c, src/printing.h,
+   src/tools.c, src/tools.h, src/project.c, src/encodings.c,
+   src/prefs.c, src/dialogs.c, src/dialogs.h, src/navqueue.c,
+   src/geanyobject.c, src/plugindata.h, src/navqueue.h,
+   src/geanyobject.h, src/geany.h, src/treeviews.c, src/msgwindow.c,
+   src/callbacks.c, src/notebook.c, src/treeviews.h, src/msgwindow.h,
+   src/callbacks.h, src/notebook.h, src/keyfile.c, src/vte.c,
+   src/filetypes.c, src/search.c, src/filetypes.h, src/search.h,
+   src/document.c, src/plugins.c, src/document.h, src/main.c,
+   src/editor.c, src/symbols.c, src/socket.c, src/editor.h,
+   src/symbols.h, src/ui_utils.c, doc/plugins.dox, plugins/export.c,
+   plugins/vcdiff.c, plugins/filebrowser.c, plugins/htmlchars.c,
+   plugins/autosave.c, plugins/classbuilder.c:
+   Merge the document-pointer branch.
+   Note: this breaks the plugin API for document functions,
+   document signal callbacks, msgwin_msg_add() and navqueue_goto_line().
+   Make all DocumentFuncs use a GeanyDocument* instead of an integer
+   index, so there's no need to access the documents array or use
+   DOC_IDX_VALID() - usually just check for non-NULL.
+   Pass a document pointer to the callbacks of all "document-*" signals.
+   Add GeanyDocument::index field for use with the documents array.
+   Remove DocumentFuncs::get_cur_idx() - use get_current() instead.
+   Replace DocumentFuncs::get_n_idx() with get_from_page().
+   Rename DocumentFuncs::find_by_realpath() to find_by_real_path().
+   Replace DocumentFuncs::remove() with remove_page().
+   Add 'changed' argument for DocumentFuncs::set_text_changed().
+   Make NavQueueFuncs and MsgWinFuncs use a GeanyDocument* instead of an
+   integer index.
+   Add DOC_VALID() macro.
+   Add deprecated DOC_IDX() macro to get the document index from a
+   possibly NULL pointer; deprecate macro DOC_IDX_VALID. These macros
+   can make porting outside plugins easier; of course, it is better to
+   rewrite the code to use document pointers.
+   Use document pointer instead of an index to the documents array
+   everywhere in the core code.
+   Rename utils_check_disk_status() in document_check_disk_status() and
+   move it into document.c.
+   Adjust plugins to work with these changes.
+   Add dox for document_set_filetype().
+   Rename debugging function doc() doc_at() to avoid conflicts.
+   Update plugin signals dox.
+
+
 2008-06-17  Enrico Tröger  <enrico(dot)troeger(at)uvena(dot)de>
 
  * geany.glade, src/interface.c, src/keybindings.c:

Modified: trunk/doc/plugins.dox
===================================================================
--- trunk/doc/plugins.dox	2008-06-18 14:18:26 UTC (rev 2704)
+++ trunk/doc/plugins.dox	2008-06-18 17:03:08 UTC (rev 2705)
@@ -63,9 +63,9 @@
  *  in your plugin code at any desired position.
  *
  *  @code
-static void on_document_open(GObject *obj, gint idx, gpointer user_data)
+static void on_document_open(GObject *obj, GeanyDocument *doc, gpointer user_data)
 {
-	printf("Example: %s was opened\n", DOC_FILENAME(idx));
+	printf("Example: %s was opened\n", DOC_FILENAME(doc));
 }
 
 PluginCallback plugin_callbacks[] =
@@ -79,45 +79,45 @@
  *
  *  @signaldef document-new
  *  @signalproto
- *  void user_function(GObject *obj, gint idx, gpointer user_data);
+ *  void user_function(GObject *obj, GeanyDocument *doc, gpointer user_data);
  *  @endsignalproto
  *  @signaldesc
  *  Sent when a new %document is created.
  *  @param obj a GeanyObject instance, should be ignored.
- *  @param idx the index of the new %document.
+ *  @param doc the new document.
  *  @param user_data user data.
  *  @endsignaldef
  *
  *  @signaldef document-open
  *  @signalproto
- *  void user_function(GObject *obj, gint idx, gpointer user_data);
+ *  void user_function(GObject *obj, GeanyDocument *doc, gpointer user_data);
  *  @endsignalproto
  *  @signaldesc
  *  Sent when a new %document is opened.
  *  @param obj a GeanyObject instance, should be ignored.
- *  @param idx the index of the opened %document.
+ *  @param doc the opened document.
  *  @param user_data user data.
  *  @endsignaldef
  *
  *  @signaldef document-save
  *  @signalproto
- *  void user_function(GObject *obj, gint idx, gpointer user_data);
+ *  void user_function(GObject *obj, GeanyDocument *doc, gpointer user_data);
  *  @endsignalproto
  *  @signaldesc
  *  Sent when a new %document is saved.
  *  @param obj a GeanyObject instance, should be ignored.
- *  @param idx the index of the saved %document.
+ *  @param doc the saved document.
  *  @param user_data user data.
  *  @endsignaldef
  *
  *  @signaldef document-activate
  *  @signalproto
- *  void user_function(GObject *obj, gint idx, gpointer user_data);
+ *  void user_function(GObject *obj, GeanyDocument *doc, gpointer user_data);
  *  @endsignalproto
  *  @signaldesc
  *  Sent when switching notebook pages.
  *  @param obj a GeanyObject instance, should be ignored.
- *  @param idx the index of the new %document.
+ *  @param doc the current document.
  *  @param user_data user data.
  *  @endsignaldef
  *

Modified: trunk/plugins/autosave.c
===================================================================
--- trunk/plugins/autosave.c	2008-06-18 14:18:26 UTC (rev 2704)
+++ trunk/plugins/autosave.c	2008-06-18 17:03:08 UTC (rev 2705)
@@ -37,7 +37,7 @@
 GeanyFunctions	*geany_functions;
 
 
-PLUGIN_VERSION_CHECK(64)
+PLUGIN_VERSION_CHECK(69)
 
 PLUGIN_SET_INFO(_("Auto Save"), _("Save automatically all open files in a given time interval."),
 	VERSION, _("The Geany developer team"))
@@ -52,26 +52,27 @@
 
 gboolean auto_save(gpointer data)
 {
-	gint cur_idx = p_document->get_cur_idx();
-	gint i, idx, max = gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets->notebook));
+	GeanyDocument *doc;
+	GeanyDocument *cur_doc = p_document->get_current();
+	gint i, max = gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets->notebook));
 	gint saved_files = 0;
 
 	if (save_all)
 	{
 		for (i = 0; i < max; i++)
 		{
-			idx = p_document->get_n_idx(i);
+			doc = p_document->get_from_page(i);
 
 			/* skip current file to save it lastly, skip files without name */
-			if (idx != cur_idx && documents[idx]->file_name != NULL)
-				if (p_document->save_file(idx, FALSE))
+			if (doc != cur_doc && cur_doc->file_name != NULL)
+				if (p_document->save_file(doc, FALSE))
 					saved_files++;
 		}
 	}
 	/* finally save current file, do it after all other files to get correct window title and
 	 * symbol list */
-	if (documents[cur_idx]->file_name != NULL)
-		if (p_document->save_file(cur_idx, FALSE))
+	if (cur_doc->file_name != NULL)
+		if (p_document->save_file(cur_doc, FALSE))
 			saved_files++;
 
 	if (saved_files > 0 && print_msg)

Modified: trunk/plugins/classbuilder.c
===================================================================
--- trunk/plugins/classbuilder.c	2008-06-18 14:18:26 UTC (rev 2704)
+++ trunk/plugins/classbuilder.c	2008-06-18 17:03:08 UTC (rev 2705)
@@ -39,7 +39,7 @@
 GeanyFunctions	*geany_functions;
 
 
-PLUGIN_VERSION_CHECK(64)
+PLUGIN_VERSION_CHECK(69)
 
 PLUGIN_SET_INFO(_("Class Builder"), _("Creates source files for new class types."), VERSION,
 	"Alexander Rodin")
@@ -593,7 +593,7 @@
 static void cc_dlg_on_create_class(CreateClassDialog *cc_dlg)
 {
 	ClassInfo *class_info;
-	gint idx;
+	GeanyDocument *doc;
 	gchar *text;
 	gchar *tmp;
 
@@ -731,16 +731,16 @@
 	if (! p_utils->str_equal(class_info->source, ""))
 	{
 		text = get_template_class_source(class_info);
-		idx = p_document->new_file(class_info->source, NULL, NULL);
-		p_sci->set_text(documents[idx]->sci, text);
+		doc = p_document->new_file(class_info->source, NULL, NULL);
+		p_sci->set_text(doc->sci, text);
 		g_free(text);
 	}
 
 	if (! p_utils->str_equal(class_info->header, ""))
 	{
 		text = get_template_class_header(class_info);
-		idx = p_document->new_file(class_info->header, NULL, NULL);
-		p_sci->set_text(documents[idx]->sci, text);
+		doc = p_document->new_file(class_info->header, NULL, NULL);
+		p_sci->set_text(doc->sci, text);
 		g_free(text);
 	}
 

Modified: trunk/plugins/export.c
===================================================================
--- trunk/plugins/export.c	2008-06-18 14:18:26 UTC (rev 2704)
+++ trunk/plugins/export.c	2008-06-18 17:03:08 UTC (rev 2705)
@@ -42,7 +42,7 @@
 GeanyData		*geany_data;
 GeanyFunctions	*geany_functions;
 
-PLUGIN_VERSION_CHECK(64)
+PLUGIN_VERSION_CHECK(69)
 PLUGIN_SET_INFO(_("Export"), _("Exports the current file into different formats."), VERSION,
 	_("The Geany developer team"))
 
@@ -105,17 +105,17 @@
 	DATE_TYPE_HTML
 };
 
-typedef void (*ExportFunc) (gint idx, const gchar *filename, gboolean use_zoom);
+typedef void (*ExportFunc) (GeanyDocument *doc, const gchar *filename, gboolean use_zoom);
 typedef struct
 {
-	gint idx;
+	GeanyDocument *doc;
 	gboolean have_zoom_level_checkbox;
 	ExportFunc export_func;
 } ExportInfo;
 
 static void on_file_save_dialog_response(GtkDialog *dialog, gint response, gpointer user_data);
-static void write_html_file(gint idx, const gchar *filename, gboolean use_zoom);
-static void write_latex_file(gint idx, const gchar *filename, gboolean use_zoom);
+static void write_html_file(GeanyDocument *doc, const gchar *filename, gboolean use_zoom);
+static void write_latex_file(GeanyDocument *doc, const gchar *filename, gboolean use_zoom);
 
 
 /* converts a RGB colour into a LaTeX compatible representation, taken from SciTE */
@@ -154,19 +154,19 @@
 static void create_file_save_as_dialog(const gchar *extension, ExportFunc func,
 									   gboolean show_zoom_level_checkbox)
 {
-	gint idx;
 	GtkWidget *dialog;
 	GtkTooltips *tooltips;
+	GeanyDocument *doc;
 	ExportInfo *exi;
 
 	if (extension == NULL)
 		return;
 
-	idx = p_document->get_cur_idx();
+	doc = p_document->get_current();
 	tooltips = GTK_TOOLTIPS(p_support->lookup_widget(main_widgets->window, "tooltips"));
 
 	exi = g_new(ExportInfo, 1);
-	exi->idx = idx;
+	exi->doc = doc;
 	exi->export_func = func;
 	exi->have_zoom_level_checkbox = FALSE;
 
@@ -209,20 +209,20 @@
 
 	/* if the current document has a filename we use it as the default. */
 	gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(dialog));
-	if (documents[idx]->file_name != NULL)
+	if (doc->file_name != NULL)
 	{
-		gchar *base_name = g_path_get_basename(documents[idx]->file_name);
+		gchar *base_name = g_path_get_basename(doc->file_name);
 		gchar *short_name = p_utils->remove_ext_from_filename(base_name);
 		gchar *file_name;
 		gchar *locale_filename;
 		gchar *locale_dirname;
 		gchar *suffix = "";
 
-		if (g_str_has_suffix(documents[idx]->file_name, extension))
+		if (g_str_has_suffix(doc->file_name, extension))
 			suffix = "_export";
 
 		file_name = g_strconcat(short_name, suffix, extension, NULL);
-		locale_filename = p_utils->get_locale_from_utf8(documents[idx]->file_name);
+		locale_filename = p_utils->get_locale_from_utf8(doc->file_name);
 		locale_dirname = g_path_get_dirname(locale_filename);
 		/* set the current name to base_name.html which probably doesn't exist yet so
 		 * gtk_file_chooser_set_filename() can't be used and we need
@@ -337,7 +337,7 @@
 				return;
 		}
 
-		exi->export_func(exi->idx, new_filename, use_zoom_level);
+		exi->export_func(exi->doc, new_filename, use_zoom_level);
 
 		g_free(utf8_filename);
 		g_free(new_filename);
@@ -347,7 +347,7 @@
 }
 
 
-static void write_latex_file(gint idx, const gchar *filename, gboolean use_zoom)
+static void write_latex_file(GeanyDocument *doc, const gchar *filename, gboolean use_zoom)
 {
 	gint i, style = -1, old_style = 0, column = 0;
 	gchar c, c_next, *tmp;
@@ -357,25 +357,25 @@
 	GString *body;
 	GString *cmds;
 	GString *latex;
-	gint style_max = pow(2, p_sci->send_message(documents[idx]->sci, SCI_GETSTYLEBITS, 0, 0));
+	gint style_max = pow(2, p_sci->send_message(doc->sci, SCI_GETSTYLEBITS, 0, 0));
 
 	/* first read all styles from Scintilla */
 	for (i = 0; i < style_max; i++)
 	{
-		styles[i][FORE] = p_sci->send_message(documents[idx]->sci, SCI_STYLEGETFORE, i, 0);
-		styles[i][BACK] = p_sci->send_message(documents[idx]->sci, SCI_STYLEGETBACK, i, 0);
-		styles[i][BOLD] = p_sci->send_message(documents[idx]->sci, SCI_STYLEGETBOLD, i, 0);
-		styles[i][ITALIC] = p_sci->send_message(documents[idx]->sci, SCI_STYLEGETITALIC, i, 0);
+		styles[i][FORE] = p_sci->send_message(doc->sci, SCI_STYLEGETFORE, i, 0);
+		styles[i][BACK] = p_sci->send_message(doc->sci, SCI_STYLEGETBACK, i, 0);
+		styles[i][BOLD] = p_sci->send_message(doc->sci, SCI_STYLEGETBOLD, i, 0);
+		styles[i][ITALIC] = p_sci->send_message(doc->sci, SCI_STYLEGETITALIC, i, 0);
 		styles[i][USED] = 0;
 	}
 
 	/* read the document and write the LaTeX code */
 	body = g_string_new("");
-	for (i = 0; i < p_sci->get_length(documents[idx]->sci); i++)
+	for (i = 0; i < p_sci->get_length(doc->sci); i++)
 	{
-		style = p_sci->get_style_at(documents[idx]->sci, i);
-		c = p_sci->get_char_at(documents[idx]->sci, i);
-		c_next = p_sci->get_char_at(documents[idx]->sci, i + 1);
+		style = p_sci->get_style_at(doc->sci, i);
+		c = p_sci->get_char_at(doc->sci, i);
+		c_next = p_sci->get_char_at(doc->sci, i + 1);
 
 		if (style != old_style || ! block_open)
 		{
@@ -538,10 +538,10 @@
 	p_utils->string_replace_all(latex, "{export_content}", body->str);
 	p_utils->string_replace_all(latex, "{export_styles}", cmds->str);
 	p_utils->string_replace_all(latex, "{export_date}", get_date(DATE_TYPE_DEFAULT));
-	if (documents[idx]->file_name == NULL)
+	if (doc->file_name == NULL)
 		p_utils->string_replace_all(latex, "{export_filename}", GEANY_STRING_UNTITLED);
 	else
-		p_utils->string_replace_all(latex, "{export_filename}", documents[idx]->file_name);
+		p_utils->string_replace_all(latex, "{export_filename}", doc->file_name);
 
 	write_data(filename, latex->str);
 
@@ -551,7 +551,7 @@
 }
 
 
-static void write_html_file(gint idx, const gchar *filename, gboolean use_zoom)
+static void write_html_file(GeanyDocument *doc, const gchar *filename, gboolean use_zoom)
 {
 	gint i, style = -1, old_style = 0, column = 0;
 	gchar c, c_next;
@@ -564,15 +564,15 @@
 	GString *body;
 	GString *css;
 	GString *html;
-	gint style_max = pow(2, p_sci->send_message(documents[idx]->sci, SCI_GETSTYLEBITS, 0, 0));
+	gint style_max = pow(2, p_sci->send_message(doc->sci, SCI_GETSTYLEBITS, 0, 0));
 
 	/* first read all styles from Scintilla */
 	for (i = 0; i < style_max; i++)
 	{
-		styles[i][FORE] = ROTATE_RGB(p_sci->send_message(documents[idx]->sci, SCI_STYLEGETFORE, i, 0));
-		styles[i][BACK] = ROTATE_RGB(p_sci->send_message(documents[idx]->sci, SCI_STYLEGETBACK, i, 0));
-		styles[i][BOLD] = p_sci->send_message(documents[idx]->sci, SCI_STYLEGETBOLD, i, 0);
-		styles[i][ITALIC] = p_sci->send_message(documents[idx]->sci, SCI_STYLEGETITALIC, i, 0);
+		styles[i][FORE] = ROTATE_RGB(p_sci->send_message(doc->sci, SCI_STYLEGETFORE, i, 0));
+		styles[i][BACK] = ROTATE_RGB(p_sci->send_message(doc->sci, SCI_STYLEGETBACK, i, 0));
+		styles[i][BOLD] = p_sci->send_message(doc->sci, SCI_STYLEGETBOLD, i, 0);
+		styles[i][ITALIC] = p_sci->send_message(doc->sci, SCI_STYLEGETITALIC, i, 0);
 		styles[i][USED] = 0;
 	}
 
@@ -581,18 +581,18 @@
 	font_name = pango_font_description_get_family(font_desc);
 	/*font_size = pango_font_description_get_size(font_desc) / PANGO_SCALE;*/
 	/* take the zoom level also into account */
-	font_size = p_sci->send_message(documents[idx]->sci, SCI_STYLEGETSIZE, 0, 0);
+	font_size = p_sci->send_message(doc->sci, SCI_STYLEGETSIZE, 0, 0);
 	if (use_zoom)
-		font_size += p_sci->send_message(documents[idx]->sci, SCI_GETZOOM, 0, 0);
+		font_size += p_sci->send_message(doc->sci, SCI_GETZOOM, 0, 0);
 
 	/* read the document and write the HTML body */
 	body = g_string_new("");
-	for (i = 0; i < p_sci->get_length(documents[idx]->sci); i++)
+	for (i = 0; i < p_sci->get_length(doc->sci); i++)
 	{
-		style = p_sci->get_style_at(documents[idx]->sci, i);
-		c = p_sci->get_char_at(documents[idx]->sci, i);
+		style = p_sci->get_style_at(doc->sci, i);
+		c = p_sci->get_char_at(doc->sci, i);
 		/* p_sci->get_char_at() takes care of index boundaries and return 0 if i is too high */
-		c_next = p_sci->get_char_at(documents[idx]->sci, i + 1);
+		c_next = p_sci->get_char_at(doc->sci, i + 1);
 
 		if ((style != old_style || ! span_open) && ! isspace(c))
 		{
@@ -690,10 +690,10 @@
 	p_utils->string_replace_all(html, "{export_date}", get_date(DATE_TYPE_HTML));
 	p_utils->string_replace_all(html, "{export_content}", body->str);
 	p_utils->string_replace_all(html, "{export_styles}", css->str);
-	if (documents[idx]->file_name == NULL)
+	if (doc->file_name == NULL)
 		p_utils->string_replace_all(html, "{export_filename}", GEANY_STRING_UNTITLED);
 	else
-		p_utils->string_replace_all(html, "{export_filename}", documents[idx]->file_name);
+		p_utils->string_replace_all(html, "{export_filename}", doc->file_name);
 
 	write_data(filename, html->str);
 

Modified: trunk/plugins/filebrowser.c
===================================================================
--- trunk/plugins/filebrowser.c	2008-06-18 14:18:26 UTC (rev 2704)
+++ trunk/plugins/filebrowser.c	2008-06-18 17:03:08 UTC (rev 2705)
@@ -46,7 +46,7 @@
 GeanyFunctions	*geany_functions;
 
 
-PLUGIN_VERSION_CHECK(64)
+PLUGIN_VERSION_CHECK(69)
 
 PLUGIN_SET_INFO(_("File Browser"), _("Adds a file browser tab to the sidebar."), VERSION,
 	_("The Geany developer team"))
@@ -275,16 +275,15 @@
 {
 	gchar *fname;
 	gchar *dir;
-	gint idx = p_document->get_cur_idx();
+	GeanyDocument *doc = p_document->get_current();
 
-	if (! DOC_IDX_VALID(idx) || documents[idx]->file_name == NULL ||
-		! g_path_is_absolute(documents[idx]->file_name))
+	if (doc == NULL || doc->file_name == NULL || ! g_path_is_absolute(doc->file_name))
 	{
 		setptr(current_dir, get_default_dir());
 		refresh();
 		return;
 	}
-	fname = documents[idx]->file_name;
+	fname = doc->file_name;
 	fname = p_utils->get_locale_from_utf8(fname);
 	dir = g_path_get_dirname(fname);
 	g_free(fname);

Modified: trunk/plugins/htmlchars.c
===================================================================
--- trunk/plugins/htmlchars.c	2008-06-18 14:18:26 UTC (rev 2704)
+++ trunk/plugins/htmlchars.c	2008-06-18 17:03:08 UTC (rev 2705)
@@ -30,6 +30,7 @@
 #include "document.h"
 #include "keybindings.h"
 #include "ui_utils.h"
+#include "utils.h"
 #include "pluginmacros.h"
 
 
@@ -38,7 +39,7 @@
 GeanyFunctions	*geany_functions;
 
 
-PLUGIN_VERSION_CHECK(64)
+PLUGIN_VERSION_CHECK(69)
 
 PLUGIN_SET_INFO(_("HTML Characters"), _("Inserts HTML character entities like '&'."), VERSION,
 	_("The Geany developer team"))
@@ -438,18 +439,18 @@
  * returns only TRUE if a valid selection(i.e. no category) could be found */
 static gboolean sc_insert(GtkTreeModel *model, GtkTreeIter *iter)
 {
-	gint idx = p_document->get_cur_idx();
+	GeanyDocument *doc = p_document->get_current();
 	gboolean result = FALSE;
 
-	if (DOC_IDX_VALID(idx))
+	if (doc != NULL)
 	{
 		gchar *str;
-		gint pos = p_sci->get_current_position(documents[idx]->sci);
+		gint pos = p_sci->get_current_position(doc->sci);
 
 		gtk_tree_model_get(model, iter, COLUMN_HTML_NAME, &str, -1);
-		if (str && *str)
+		if (NZV(str))
 		{
-			p_sci->insert_text(documents[idx]->sci, pos, str);
+			p_sci->insert_text(doc->sci, pos, str);
 			g_free(str);
 			result = TRUE;
 		}
@@ -507,11 +508,6 @@
 static void
 item_activate(GtkMenuItem *menuitem, gpointer gdata)
 {
-	/* refuse opening the dialog if we don't have an active tab */
-	gint idx = p_document->get_cur_idx();
-
-	if (idx == -1 || ! documents[idx]->is_valid) return;
-
 	tools_show_dialog_insert_special_chars();
 }
 

Modified: trunk/plugins/vcdiff.c
===================================================================
--- trunk/plugins/vcdiff.c	2008-06-18 14:18:26 UTC (rev 2704)
+++ trunk/plugins/vcdiff.c	2008-06-18 17:03:08 UTC (rev 2705)
@@ -45,7 +45,7 @@
 GeanyFunctions	*geany_functions;
 
 
-PLUGIN_VERSION_CHECK(64)
+PLUGIN_VERSION_CHECK(69)
 
 PLUGIN_SET_INFO(_("Version Diff"), _("Creates a patch of a file against version control."), VERSION,
 	_("The Geany developer team"))
@@ -253,7 +253,8 @@
 		const gchar *force_encoding)
 {
 	gchar	*text, *detect_enc = NULL;
-	gint 	idx, page;
+	gint 	page;
+	GeanyDocument *doc;
 	GtkNotebook *book;
 	gchar	*filename;
 
@@ -273,23 +274,22 @@
 	}
 	if (text)
 	{
-		idx = p_document->find_by_filename(filename);
-		if ( idx == -1)
+		doc = p_document->find_by_filename(filename);
+		if (doc == NULL)
 		{
 			GeanyFiletype *ft = p_filetypes->lookup_by_name("Diff");
-			idx = p_document->new_file(filename, ft, text);
+			doc = p_document->new_file(filename, ft, text);
 		}
 		else
 		{
-			p_sci->set_text(documents[idx]->sci, text);
+			p_sci->set_text(doc->sci, text);
 			book = GTK_NOTEBOOK(main_widgets->notebook);
-			page = gtk_notebook_page_num(book, GTK_WIDGET(documents[idx]->sci));
+			page = gtk_notebook_page_num(book, GTK_WIDGET(doc->sci));
 			gtk_notebook_set_current_page(book, page);
-			documents[idx]->changed = FALSE;
-			p_document->set_text_changed(idx);
+			p_document->set_text_changed(doc, FALSE);
 		}
 
-		p_document->set_encoding(idx,
+		p_document->set_encoding(doc,
 			force_encoding ? force_encoding : detect_enc);
 	}
 	else
@@ -382,21 +382,21 @@
 /* Make a diff from the current directory */
 static void vcdirectory_activated(GtkMenuItem *menuitem, gpointer gdata)
 {
-	gint	idx;
+	GeanyDocument *doc;
 	gchar	*base_name = NULL;
 	gchar	*locale_filename = NULL;
 	gchar	*text;
 
-	idx = p_document->get_cur_idx();
+	doc = p_document->get_current();
 
-	g_return_if_fail(DOC_IDX_VALID(idx) && documents[idx]->file_name != NULL);
+	g_return_if_fail(doc != NULL && doc->file_name != NULL);
 
-	if (documents[idx]->changed)
+	if (doc->changed)
 	{
-		p_document->save_file(idx, FALSE);
+		p_document->save_file(doc, FALSE);
 	}
 
-	locale_filename = p_utils->get_locale_from_utf8(documents[idx]->file_name);
+	locale_filename = p_utils->get_locale_from_utf8(doc->file_name);
 	base_name = g_path_get_dirname(locale_filename);
 
 	text = make_diff(base_name, VC_COMMAND_DIFF_DIR);
@@ -415,17 +415,17 @@
 /* Callback if menu item for the current project was activated */
 static void vcproject_activated(GtkMenuItem *menuitem, gpointer gdata)
 {
-	gint	idx;
+	GeanyDocument *doc;
 	gchar	*locale_filename = NULL;
 	gchar	*text;
 
-	idx = p_document->get_cur_idx();
+	doc = p_document->get_current();
 
 	g_return_if_fail(project != NULL && NZV(project->base_path));
 
-	if (DOC_IDX_VALID(idx) && documents[idx]->changed && documents[idx]->file_name != NULL)
+	if (doc != NULL && doc->changed && doc->file_name != NULL)
 	{
-		p_document->save_file(idx, FALSE);
+		p_document->save_file(doc, FALSE);
 	}
 
 	locale_filename = p_utils->get_locale_from_utf8(project->base_path);
@@ -442,24 +442,24 @@
 /* Callback if menu item for a single file was activated */
 static void vcfile_activated(GtkMenuItem *menuitem, gpointer gdata)
 {
-	gint	idx;
-	gchar	*locale_filename, *text;
+	GeanyDocument *doc;
+	gchar *locale_filename, *text;
 
-	idx = p_document->get_cur_idx();
+	doc = p_document->get_current();
 
-	g_return_if_fail(DOC_IDX_VALID(idx) && documents[idx]->file_name != NULL);
+	g_return_if_fail(doc != NULL && doc->file_name != NULL);
 
-	if (documents[idx]->changed)
+	if (doc->changed)
 	{
-		p_document->save_file(idx, FALSE);
+		p_document->save_file(doc, FALSE);
 	}
 
-	locale_filename = p_utils->get_locale_from_utf8(documents[idx]->file_name);
+	locale_filename = p_utils->get_locale_from_utf8(doc->file_name);
 
 	text = make_diff(locale_filename, VC_COMMAND_DIFF_FILE);
 	if (text)
 	{
-		show_output(text, documents[idx]->file_name, documents[idx]->encoding);
+		show_output(text, doc->file_name, doc->encoding);
 		g_free(text);
 	}
 	g_free(locale_filename);

Modified: trunk/src/build.c
===================================================================
--- trunk/src/build.c	2008-06-18 14:18:26 UTC (rev 2704)
+++ trunk/src/build.c	2008-06-18 17:03:08 UTC (rev 2705)
@@ -45,11 +45,11 @@
 
 #include "prefs.h"
 #include "support.h"
+#include "document.h"
 #include "utils.h"
 #include "ui_utils.h"
 #include "dialogs.h"
 #include "msgwindow.h"
-#include "document.h"
 #include "filetypes.h"
 #include "keybindings.h"
 #include "vte.h"
@@ -98,7 +98,7 @@
 
 static gboolean build_iofunc(GIOChannel *ioc, GIOCondition cond, gpointer data);
 static gboolean build_create_shellscript(const gchar *fname, const gchar *cmd, gboolean autoclose);
-static GPid build_spawn_cmd(gint idx, const gchar *cmd, const gchar *dir);
+static GPid build_spawn_cmd(GeanyDocument *doc, const gchar *cmd, const gchar *dir);
 static void set_stop_button(gboolean stop);
 static void build_exit_cb(GPid child_pid, gint status, gpointer user_data);
 static void run_exit_cb(GPid child_pid, gint status, gpointer user_data);
@@ -125,28 +125,29 @@
 }
 
 
-static GPid build_compile_tex_file(gint idx, gint mode)
+static GPid build_compile_tex_file(GeanyDocument *doc, gint mode)
 {
 	const gchar *cmd = NULL;
 
-	if (idx < 0 || documents[idx]->file_name == NULL) return (GPid) 1;
+	if (doc == NULL || doc->file_name == NULL)
+		return (GPid) 1;
 
 	if (mode == LATEX_CMD_TO_DVI)
 	{
-		cmd = documents[idx]->file_type->programs->compiler;
+		cmd = doc->file_type->programs->compiler;
 		build_info.type = GBO_COMPILE;
 	}
 	else
 	{
-		cmd = documents[idx]->file_type->programs->linker;
+		cmd = doc->file_type->programs->linker;
 		build_info.type = GBO_BUILD;
 	}
 
-	return build_spawn_cmd(idx, cmd, NULL);
+	return build_spawn_cmd(doc, cmd, NULL);
 }
 
 
-static GPid build_view_tex_file(gint idx, gint mode)
+static GPid build_view_tex_file(GeanyDocument *doc, gint mode)
 {
 	gchar **argv, **term_argv;
 	gchar  *executable = NULL;
@@ -161,12 +162,12 @@
 	GError *error = NULL;
 	struct stat st;
 
-	if (! DOC_IDX_VALID(idx) || documents[idx]->file_name == NULL)
+	if (doc == NULL || doc->file_name == NULL)
 		return (GPid) 1;
 
 	run_info.file_type_id = GEANY_FILETYPES_LATEX;
 
-	executable = utils_remove_ext_from_filename(documents[idx]->file_name);
+	executable = utils_remove_ext_from_filename(doc->file_name);
 	view_file = g_strconcat(executable, (mode == LATEX_CMD_VIEW_DVI) ? ".dvi" : ".pdf", NULL);
 
 	/* try convert in locale for stat() */
@@ -183,8 +184,8 @@
 
 	/* replace %f and %e in the run_cmd string */
 	cmd_string = g_strdup((mode == LATEX_CMD_VIEW_DVI) ?
-										g_strdup(documents[idx]->file_type->programs->run_cmd) :
-										g_strdup(documents[idx]->file_type->programs->run_cmd2));
+										g_strdup(doc->file_type->programs->run_cmd) :
+										g_strdup(doc->file_type->programs->run_cmd2));
 	cmd_string = utils_str_replace(cmd_string, "%f", view_file);
 	cmd_string = utils_str_replace(cmd_string, "%e", executable);
 
@@ -275,7 +276,7 @@
 	{
 		/*setpgid(0, getppid());*/
 		g_child_watch_add(run_info.pid, (GChildWatchFunc) run_exit_cb, NULL);
-		build_menu_update(idx);
+		build_menu_update(doc);
 	}
 
 	utils_free_pointers(executable, view_file, locale_filename, cmd_string, locale_cmd_string,
@@ -288,13 +289,13 @@
 
 
 /* get curfile.o in locale encoding from document::file_name */
-static gchar *get_object_filename(gint idx)
+static gchar *get_object_filename(GeanyDocument *doc)
 {
 	gchar *locale_filename, *short_file, *noext, *object_file;
 
-	if (documents[idx]->file_name == NULL) return NULL;
+	if (doc->file_name == NULL) return NULL;
 
-	locale_filename = utils_get_locale_from_utf8(documents[idx]->file_name);
+	locale_filename = utils_get_locale_from_utf8(doc->file_name);
 
 	short_file = g_path_get_basename(locale_filename);
 	g_free(locale_filename);
@@ -309,13 +310,14 @@
 }
 
 
-static GPid build_make_file(gint idx, gint build_opts)
+static GPid build_make_file(GeanyDocument *doc, gint build_opts)
 {
 	GString *cmdstr;
 	gchar *dir = NULL;
 	GPid pid;
 
-	if (idx < 0 || documents[idx]->file_name == NULL) return (GPid) 1;
+	if (doc == NULL || doc->file_name == NULL)
+		return (GPid) 1;
 
 	cmdstr = g_string_new(tool_prefs.make_cmd);
 	g_string_append_c(cmdstr, ' ');
@@ -325,7 +327,7 @@
 		gchar *tmp;
 
 		build_info.type = build_opts;
-		tmp = get_object_filename(idx);
+		tmp = get_object_filename(doc);
 		g_string_append(cmdstr, tmp);
 		g_free(tmp);
 	}
@@ -342,42 +344,42 @@
 		dir = project_get_make_dir();
 	}
 
-	pid = build_spawn_cmd(idx, cmdstr->str, dir);	/* if dir is NULL, idx filename is used */
+	pid = build_spawn_cmd(doc, cmdstr->str, dir); /* if dir is NULL, idx filename is used */
 	g_free(dir);
 	g_string_free(cmdstr, TRUE);
 	return pid;
 }
 
 
-static GPid build_compile_file(gint idx)
+static GPid build_compile_file(GeanyDocument *doc)
 {
-	if (! DOC_IDX_VALID(idx) || documents[idx]->file_name == NULL)
+	if (doc == NULL || doc->file_name == NULL)
 		return (GPid) 1;
 
 	build_info.type = GBO_COMPILE;
-	return build_spawn_cmd(idx, documents[idx]->file_type->programs->compiler, NULL);
+	return build_spawn_cmd(doc, doc->file_type->programs->compiler, NULL);
 }
 
 
-static GPid build_link_file(gint idx)
+static GPid build_link_file(GeanyDocument *doc)
 {
-	if (! DOC_IDX_VALID(idx) || documents[idx]->file_name == NULL)
+	if (doc == NULL || doc->file_name == NULL)
 		return (GPid) 1;
 
 	build_info.type = GBO_BUILD;
-	return build_spawn_cmd(idx, documents[idx]->file_type->programs->linker, NULL);
+	return build_spawn_cmd(doc, doc->file_type->programs->linker, NULL);
 }
 
 
 /* If linking, clear all error indicators in all documents.
  * Otherwise, just clear error indicators in document idx. */
-static void clear_errors(gint idx)
+static void clear_errors(GeanyDocument *doc)
 {
 	switch (build_info.type)
 	{
 		case GBO_COMPILE:
 		case GBO_MAKE_OBJECT:
-			editor_clear_indicators(idx);
+			editor_clear_indicators(doc);
 			break;
 
 		case GBO_BUILD:
@@ -389,7 +391,7 @@
 			for (i = 0; i < documents_array->len; i++)
 			{
 				if (documents[i]->is_valid)
-					editor_clear_indicators(i);
+					editor_clear_indicators(documents[i]);
 			}
 			break;
 		}
@@ -422,7 +424,7 @@
 
 /* dir is the UTF-8 working directory to run cmd in. It can be NULL to use the
  * idx document directory */
-static GPid build_spawn_cmd(gint idx, const gchar *cmd, const gchar *dir)
+static GPid build_spawn_cmd(GeanyDocument *doc, const gchar *cmd, const gchar *dir)
 {
 	GError  *error = NULL;
 	gchar  **argv;
@@ -436,12 +438,12 @@
 	gint     stdout_fd;
 	gint     stderr_fd;
 
-	g_return_val_if_fail(DOC_IDX_VALID(idx), (GPid) 1);
+	g_return_val_if_fail(doc != NULL, (GPid) 1);
 
-	clear_errors(idx);
+	clear_errors(doc);
 	setptr(current_dir_entered, NULL);
 
-	locale_filename = utils_get_locale_from_utf8(documents[idx]->file_name);
+	locale_filename = utils_get_locale_from_utf8(doc->file_name);
 	executable = utils_remove_ext_from_filename(locale_filename);
 
 	cmd_string = g_strdup(cmd);
@@ -472,7 +474,7 @@
 
 	utf8_cmd_string = utils_get_utf8_from_locale(cmd_string);
 	utf8_working_dir = (dir != NULL) ? g_strdup(dir) :
-		g_path_get_dirname(documents[idx]->file_name);
+		g_path_get_dirname(doc->file_name);
 	working_dir = utils_get_locale_from_utf8(utf8_working_dir);
 
 	gtk_list_store_clear(msgwindow.store_compiler);
@@ -484,7 +486,7 @@
 	/* set the build info for the message window */
 	g_free(build_info.dir);
 	build_info.dir = g_strdup(working_dir);
-	build_info.file_type_id = FILETYPE_ID(documents[idx]->file_type);
+	build_info.file_type_id = FILETYPE_ID(doc->file_type);
 
 	if (! g_spawn_async_with_pipes(working_dir, argv, NULL, G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
 						NULL, NULL, &(build_info.pid), NULL, &stdout_fd, &stderr_fd, &error))
@@ -502,7 +504,7 @@
 	if (build_info.pid > 0)
 	{
 		g_child_watch_add(build_info.pid, (GChildWatchFunc) build_exit_cb, NULL);
-		build_menu_update(idx);
+		build_menu_update(doc);
 	}
 
 	/* use GIOChannels to monitor stdout and stderr */
@@ -586,12 +588,12 @@
 /* Returns: NULL if there was an error, or the working directory the script was created in.
  * vte_cmd_nonscript is the location of a string which is filled with the command to be used
  * when vc->skip_run_script is set, otherwise it will be set to NULL */
-static gchar *prepare_run_script(gint idx, gchar **vte_cmd_nonscript)
+static gchar *prepare_run_script(GeanyDocument *doc, gchar **vte_cmd_nonscript)
 {
 	gchar	*locale_filename = NULL;
 	gboolean have_project;
 	GeanyProject *project = app->project;
-	GeanyFiletype *ft = documents[idx]->file_type;
+	GeanyFiletype *ft = doc->file_type;
 	gboolean check_exists;
 	gchar	*cmd = NULL;
 	gchar	*executable = NULL;
@@ -603,7 +605,7 @@
 	if (vte_cmd_nonscript != NULL)
 		*vte_cmd_nonscript = NULL;
 
-	locale_filename = utils_get_locale_from_utf8(documents[idx]->file_name);
+	locale_filename = utils_get_locale_from_utf8(doc->file_name);
 
 	have_project = (project != NULL && NZV(project->run_cmd));
 	cmd = (have_project) ?
@@ -688,22 +690,22 @@
 }
 
 
-static GPid build_run_cmd(gint idx)
+static GPid build_run_cmd(GeanyDocument *doc)
 {
 	gchar	*working_dir;
 	gchar	*vte_cmd_nonscript = NULL;
 	GError	*error = NULL;
 
-	if (! DOC_IDX_VALID(idx) || documents[idx]->file_name == NULL)
+	if (doc == NULL || doc->file_name == NULL)
 		return (GPid) 0;
 
-	working_dir = prepare_run_script(idx, &vte_cmd_nonscript);
+	working_dir = prepare_run_script(doc, &vte_cmd_nonscript);
 	if (working_dir == NULL)
 	{
 		return (GPid) 0;
 	}
 
-	run_info.file_type_id = FILETYPE_ID(documents[idx]->file_type);
+	run_info.file_type_id = FILETYPE_ID(doc->file_type);
 
 #ifdef HAVE_VTE
 	if (vte_info.load_vte && vc != NULL && vc->run_in_vte)
@@ -810,7 +812,7 @@
 		if (run_info.pid > 0)
 		{
 			g_child_watch_add(run_info.pid, (GChildWatchFunc) run_exit_cb, NULL);
-			build_menu_update(idx);
+			build_menu_update(doc);
 		}
 		free_strings:
 		g_strfreev(argv);
@@ -853,9 +855,9 @@
 					&filename, &line);
 				if (line != -1 && filename != NULL)
 				{
-					gint idx = document_find_by_filename(filename);
+					GeanyDocument *doc = document_find_by_filename(filename);
 
-					editor_set_indicator_on_line(idx, line - 1);	/* will check valid idx */
+					editor_set_indicator_on_line(doc, line - 1);	/* will check valid idx */
 					color = COLOR_RED;	/* error message parsed on the line */
 				}
 				g_free(filename);
@@ -965,7 +967,7 @@
 
 	build_info.pid = 0;
 	/* enable build items again */
-	build_menu_update(-1);
+	build_menu_update(NULL);
 }
 
 
@@ -975,7 +977,7 @@
 
 	run_info.pid = 0;
 	/* reset the stop button and menu item to the original meaning */
-	build_menu_update(-1);
+	build_menu_update(NULL);
 }
 
 
@@ -1323,11 +1325,12 @@
 static void show_includes_arguments_tex(void)
 {
 	GtkWidget *dialog, *label, *entries[4], *vbox, *table;
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 	gint response;
 	GeanyFiletype *ft = NULL;
 
-	if (DOC_IDX_VALID(idx)) ft = documents[idx]->file_type;
+	if (doc != NULL)
+		ft = doc->file_type;
 	g_return_if_fail(ft != NULL);
 
 	dialog = gtk_dialog_new_with_buttons(_("Set Arguments"), GTK_WINDOW(main_widgets.window),
@@ -1492,11 +1495,12 @@
 	GtkWidget *dialog, *label, *entries[3], *vbox;
 	GtkWidget *ft_table = NULL;
 	gint row = 0;
-	gint idx = document_get_cur_idx();
 	gint response;
+	GeanyDocument *doc = document_get_current();
 	GeanyFiletype *ft = NULL;
 
-	if (DOC_IDX_VALID(idx)) ft = documents[idx]->file_type;
+	if (doc != NULL)
+		ft = doc->file_type;
 	g_return_if_fail(ft != NULL);
 
 	dialog = gtk_dialog_new_with_buttons(_("Set Includes and Arguments"), GTK_WINDOW(main_widgets.window),
@@ -1633,17 +1637,16 @@
 
 /* Call this whenever build menu items need to be enabled/disabled.
  * Uses current document (if there is one) when idx == -1 */
-void build_menu_update(gint idx)
+void build_menu_update(GeanyDocument *doc)
 {
 	GeanyFiletype *ft;
 	gboolean have_path, can_build, can_make, can_run, can_stop, can_set_args, have_errors;
 	BuildMenuItems *menu_items;
 
-	if (idx == -1)
-		idx = document_get_cur_idx();
-	if (idx == -1 ||
-		(FILETYPE_ID(documents[idx]->file_type) == GEANY_FILETYPES_NONE &&
-			documents[idx]->file_name == NULL))
+	if (doc == NULL)
+		doc = document_get_current();
+	if (doc == NULL ||
+		(FILETYPE_ID(doc->file_type) == GEANY_FILETYPES_NONE &&	doc->file_name == NULL))
 	{
 		gtk_widget_set_sensitive(lookup_widget(main_widgets.window, "menu_build1"), FALSE);
 		gtk_menu_item_remove_submenu(GTK_MENU_ITEM(lookup_widget(main_widgets.window, "menu_build1")));
@@ -1654,7 +1657,7 @@
 	else
 		gtk_widget_set_sensitive(lookup_widget(main_widgets.window, "menu_build1"), TRUE);
 
-	ft = documents[idx]->file_type;
+	ft = doc->file_type;
 	g_return_if_fail(ft != NULL);
 
 	menu_items = build_get_menu_items(ft->id);
@@ -1663,13 +1666,13 @@
 	gtk_menu_item_set_submenu(GTK_MENU_ITEM(lookup_widget(main_widgets.window, "menu_build1")),
 		menu_items->menu);
 
-	have_path = (documents[idx]->file_name != NULL);
+	have_path = (doc->file_name != NULL);
 
 	can_make = have_path && build_info.pid <= (GPid) 1;
 
 	/* disable compile and link for C/C++ header files */
 	if (ft->id == GEANY_FILETYPES_C || ft->id == GEANY_FILETYPES_CPP)
-		can_build = can_make && ! is_c_header(documents[idx]->file_name);
+		can_build = can_make && ! is_c_header(doc->file_name);
 	else
 		can_build = can_make;
 
@@ -1783,11 +1786,11 @@
 
 	if (filetype_idx == -1)
 	{
-		gint idx = document_get_cur_idx();
+		GeanyDocument *doc = document_get_current();
 		GeanyFiletype *ft = NULL;
 
-		if (DOC_IDX_VALID(idx))
-			ft = documents[idx]->file_type;
+		if (doc != NULL)
+			ft = doc->file_type;
 		filetype_idx = FILETYPE_ID(ft);
 	}
 
@@ -1811,16 +1814,18 @@
 on_build_compile_activate              (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 
-	if (! DOC_IDX_VALID(idx)) return;
+	if (doc == NULL)
+		return;
 
-	if (documents[idx]->changed) document_save_file(idx, FALSE);
+	if (doc->changed)
+		document_save_file(doc, FALSE);
 
-	if (FILETYPE_ID(documents[idx]->file_type) == GEANY_FILETYPES_LATEX)
-		build_compile_tex_file(idx, 0);
+	if (FILETYPE_ID(doc->file_type) == GEANY_FILETYPES_LATEX)
+		build_compile_tex_file(doc, 0);
 	else
-		build_compile_file(idx);
+		build_compile_file(doc);
 }
 
 
@@ -1828,21 +1833,22 @@
 on_build_tex_activate                  (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 
-	if (! DOC_IDX_VALID(idx))
+	if (doc == NULL)
 		return;
 
-	if (documents[idx]->changed) document_save_file(idx, FALSE);
+	if (doc->changed)
+		document_save_file(doc, FALSE);
 
 	switch (GPOINTER_TO_INT(user_data))
 	{
 		case LATEX_CMD_TO_DVI:
 		case LATEX_CMD_TO_PDF:
-			build_compile_tex_file(idx, GPOINTER_TO_INT(user_data)); break;
+			build_compile_tex_file(doc, GPOINTER_TO_INT(user_data)); break;
 		case LATEX_CMD_VIEW_DVI:
 		case LATEX_CMD_VIEW_PDF:
-			build_view_tex_file(idx, GPOINTER_TO_INT(user_data)); break;
+			build_view_tex_file(doc, GPOINTER_TO_INT(user_data)); break;
 	}
 }
 
@@ -1851,30 +1857,32 @@
 on_build_build_activate                (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 
-	if (! DOC_IDX_VALID(idx)) return;
+	if (doc == NULL)
+		return;
 
-	if (documents[idx]->changed) document_save_file(idx, FALSE);
+	if (doc->changed)
+		document_save_file(doc, FALSE);
 
-	if (FILETYPE_ID(documents[idx]->file_type) == GEANY_FILETYPES_LATEX)
-		build_compile_tex_file(idx, 1);
+	if (FILETYPE_ID(doc->file_type) == GEANY_FILETYPES_LATEX)
+		build_compile_tex_file(doc, 1);
 	else
-		build_link_file(idx);
+		build_link_file(doc);
 }
 
 
 static void
 on_make_custom_input_response(const gchar *input)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 
-	if (documents[idx]->changed)
-		document_save_file(idx, FALSE);
+	if (doc->changed)
+		document_save_file(doc, FALSE);
 
 	setptr(build_info.custom_target, g_strdup(input));
 
-	build_make_file(idx, GBO_MAKE_CUSTOM);
+	build_make_file(doc, GBO_MAKE_CUSTOM);
 }
 
 
@@ -1898,10 +1906,10 @@
 on_build_make_activate                 (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 	gint build_opts = GPOINTER_TO_INT(user_data);
 
-	g_return_if_fail(DOC_IDX_VALID(idx) && documents[idx]->file_name != NULL);
+	g_return_if_fail(doc != NULL && doc->file_name != NULL);
 
 	switch (build_opts)
 	{
@@ -1915,15 +1923,16 @@
 		/* fall through */
 		case GBO_MAKE_ALL:
 		{
-			if (documents[idx]->changed) document_save_file(idx, FALSE);
+			if (doc->changed)
+				document_save_file(doc, FALSE);
 
-			build_make_file(idx, build_opts);
+			build_make_file(doc, build_opts);
 		}
 	}
 }
 
 
-static gboolean use_html_builtin(gint idx, GeanyFiletype *ft)
+static gboolean use_html_builtin(GeanyDocument *doc, GeanyFiletype *ft)
 {
 	gboolean use_builtin = FALSE;
 	if (ft->id == GEANY_FILETYPES_HTML)
@@ -1941,7 +1950,7 @@
 
 	if (use_builtin)
 	{
-		gchar *uri = g_strconcat("file:///", g_path_skip_root(documents[idx]->file_name), NULL);
+		gchar *uri = g_strconcat("file:///", g_path_skip_root(doc->file_name), NULL);
 		utils_start_browser(uri);
 		g_free(uri);
 
@@ -1955,11 +1964,11 @@
 on_build_execute_activate              (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 	filetype_id ft_id;
 	GeanyFiletype *ft;
 
-	if (! DOC_IDX_VALID(idx))
+	if (doc == NULL)
 		return;
 
 	/* make the process "stopable" */
@@ -1969,26 +1978,26 @@
 		return;
 	}
 
-	ft_id = FILETYPE_ID(documents[idx]->file_type);
+	ft_id = FILETYPE_ID(doc->file_type);
 	ft = filetypes[ft_id];
 	if (ft_id == GEANY_FILETYPES_LATEX)
 	{	/* run LaTeX file */
-		if (build_view_tex_file(idx, GPOINTER_TO_INT(user_data)) == (GPid) 0)
+		if (build_view_tex_file(doc, GPOINTER_TO_INT(user_data)) == (GPid) 0)
 		{
 			ui_set_statusbar(TRUE, _("Failed to execute the view program"));
 		}
 	}
 	/* use_html_builtin() checks for HTML builtin request and returns FALSE if not */
-	else if (! use_html_builtin(idx, ft))
+	else if (! use_html_builtin(doc, ft))
 	{	/* run everything else */
 
 		/* save the file only if the run command uses it */
-		if (documents[idx]->changed &&
+		if (doc->changed &&
 			NZV(ft->programs->run_cmd) &&	/* can happen when project is open */
 			strstr(ft->programs->run_cmd, "%f") != NULL)
-				document_save_file(idx, FALSE);
+				document_save_file(doc, FALSE);
 
-		if (build_run_cmd(idx) == (GPid) 0)
+		if (build_run_cmd(doc) == (GPid) 0)
 		{
 			ui_set_statusbar(TRUE, _("Failed to execute the terminal program"));
 		}
@@ -2020,7 +2029,7 @@
 	else
 	{
 		*pid = 0;
-		build_menu_update(-1);
+		build_menu_update(NULL);
 	}
 }
 

Modified: trunk/src/build.h
===================================================================
--- trunk/src/build.h	2008-06-18 14:18:26 UTC (rev 2704)
+++ trunk/src/build.h	2008-06-18 17:03:08 UTC (rev 2705)
@@ -69,7 +69,7 @@
 
 gboolean build_parse_make_dir(const gchar *string, gchar **prefix);
 
-void build_menu_update(gint idx);
+void build_menu_update(GeanyDocument *doc);
 
 BuildMenuItems *build_get_menu_items(gint filetype_idx);
 

Modified: trunk/src/callbacks.c
===================================================================
--- trunk/src/callbacks.c	2008-06-18 14:18:26 UTC (rev 2704)
+++ trunk/src/callbacks.c	2008-06-18 17:03:08 UTC (rev 2705)
@@ -88,7 +88,7 @@
  * the selection-changed signal from tv.tree_openfiles */
 /*static gboolean switch_tv_notebook_page = FALSE; */
 
-CallbacksData callbacks_data = {-1};
+CallbacksData callbacks_data = { NULL };
 
 
 static gboolean check_no_unsaved(void)
@@ -108,11 +108,11 @@
 
 /* set editor_info.click_pos to the current cursor position if insert_callback_from_menu is TRUE
  * to prevent invalid cursor positions which can cause segfaults */
-static void verify_click_pos(gint idx)
+static void verify_click_pos(GeanyDocument *doc)
 {
 	if (insert_callback_from_menu)
 	{
-		editor_info.click_pos = sci_get_current_position(documents[idx]->sci);
+		editor_info.click_pos = sci_get_current_position(doc->sci);
 		insert_callback_from_menu = FALSE;
 	}
 }
@@ -177,14 +177,14 @@
                                         gpointer         user_data)
 {
 	gint cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(main_widgets.notebook));
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 
-	if (cur_page >= 0)
+	if (doc != NULL && cur_page >= 0)
 	{
-		if (documents[idx]->file_name == NULL)
+		if (doc->file_name == NULL)
 			dialogs_show_save_as();
 		else
-			document_save_file(idx, FALSE);
+			document_save_file(doc, FALSE);
 	}
 }
 
@@ -201,28 +201,28 @@
 on_save_all1_activate                  (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint i, idx, max = gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook));
-	gint cur_idx = document_get_cur_idx();
+	gint i, max = gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook));
+	GeanyDocument *doc, *cur_doc = document_get_current();
 
 	document_delay_colourise();	/* avoid recolourising all C files after each save */
 
 	for (i = 0; i < max; i++)
 	{
-		idx = document_get_n_idx(i);
-		if (! documents[idx]->changed) continue;
-		if (documents[idx]->file_name == NULL)
+		doc = document_get_from_page(i);
+		if (! doc->changed) continue;
+		if (doc->file_name == NULL)
 		{
 			/* display unnamed document */
 			gtk_notebook_set_current_page(GTK_NOTEBOOK(main_widgets.notebook),
-				document_get_notebook_page(idx));
+				document_get_notebook_page(doc));
 			dialogs_show_save_as();
 		}
 		else
-			document_save_file(idx, FALSE);
+			document_save_file(doc, FALSE);
 	}
 	document_colourise_new();
-	treeviews_update_tag_list(cur_idx, TRUE);
-	ui_set_window_title(cur_idx);
+	treeviews_update_tag_list(cur_doc, TRUE);
+	ui_set_window_title(cur_doc);
 }
 
 
@@ -239,7 +239,7 @@
                                         gpointer         user_data)
 {
 	guint cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(main_widgets.notebook));
-	document_remove(cur_page);
+	document_remove_page(cur_page);
 }
 
 
@@ -271,9 +271,9 @@
 on_edit1_activate                      (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
-	ui_update_menu_copy_items(idx);
-	ui_update_insert_include_item(idx, 1);
+	GeanyDocument *doc = document_get_current();
+	ui_update_menu_copy_items(doc);
+	ui_update_insert_include_item(doc, 1);
 }
 
 
@@ -281,9 +281,9 @@
 on_undo1_activate                      (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
-	if (idx == -1 || ! documents[idx]->is_valid) return;
-	if (document_can_undo(idx)) document_undo(idx);
+	GeanyDocument *doc = document_get_current();
+	if (doc != NULL && document_can_undo(doc))
+		document_undo(doc);
 }
 
 
@@ -291,9 +291,9 @@
 on_redo1_activate                      (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
-	if (idx == -1 || ! documents[idx]->is_valid) return;
-	if (document_can_redo(idx)) document_redo(idx);
+	GeanyDocument *doc = document_get_current();
+	if (doc != NULL && document_can_redo(doc))
+		document_redo(doc);
 }
 
 
@@ -301,14 +301,14 @@
 on_cut1_activate                       (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 	GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window));
 
 	if (GTK_IS_EDITABLE(focusw))
 		gtk_editable_cut_clipboard(GTK_EDITABLE(focusw));
 	else
-	if (IS_SCINTILLA(focusw) && idx >= 0)
-		sci_cut(documents[idx]->sci);
+	if (IS_SCINTILLA(focusw) && doc != NULL)
+		sci_cut(doc->sci);
 	else
 	if (GTK_IS_TEXT_VIEW(focusw))
 	{
@@ -323,14 +323,14 @@
 on_copy1_activate                      (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 	GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window));
 
 	if (GTK_IS_EDITABLE(focusw))
 		gtk_editable_copy_clipboard(GTK_EDITABLE(focusw));
 	else
-	if (IS_SCINTILLA(focusw) && idx >= 0)
-		sci_copy(documents[idx]->sci);
+	if (IS_SCINTILLA(focusw) && doc != NULL)
+		sci_copy(doc->sci);
 	else
 	if (GTK_IS_TEXT_VIEW(focusw))
 	{
@@ -345,13 +345,13 @@
 on_paste1_activate                     (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 	GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window));
 
 	if (GTK_IS_EDITABLE(focusw))
 		gtk_editable_paste_clipboard(GTK_EDITABLE(focusw));
 	else
-	if (IS_SCINTILLA(focusw) && idx >= 0)
+	if (IS_SCINTILLA(focusw) && doc != NULL)
 	{
 #if 0
 //#ifdef G_OS_WIN32
@@ -363,12 +363,12 @@
 			gchar *content = gtk_clipboard_wait_for_text(gtk_clipboard_get(GDK_NONE));
 			if (content != NULL)
 			{
-				sci_replace_sel(documents[idx]->sci, content);
+				sci_replace_sel(doc->sci, content);
 				g_free(content);
 			}
 		}
 #else
-		sci_paste(documents[idx]->sci);
+		sci_paste(doc->sci);
 #endif
 	}
 	else
@@ -386,14 +386,14 @@
 on_delete1_activate                    (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 	GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window));
 
 	if (GTK_IS_EDITABLE(focusw))
 		gtk_editable_delete_selection(GTK_EDITABLE(focusw));
 	else
-	if (IS_SCINTILLA(focusw) && idx >= 0)
-		sci_clear(documents[idx]->sci);
+	if (IS_SCINTILLA(focusw) && doc != NULL)
+		sci_clear(doc->sci);
 	else
 	if (GTK_IS_TEXT_VIEW(focusw))
 	{
@@ -453,12 +453,12 @@
 on_reload_as_activate                  (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 	gchar *base_name;
 	gint i = GPOINTER_TO_INT(user_data);
 	gchar *charset = NULL;
 
-	if (idx < 0 || ! documents[idx]->is_valid || documents[idx]->file_name == NULL)
+	if (doc == NULL || doc->file_name == NULL)
 		return;
 	if (i >= 0)
 	{
@@ -466,14 +466,14 @@
 		charset = encodings[i].charset;
 	}
 
-	base_name = g_path_get_basename(documents[idx]->file_name);
+	base_name = g_path_get_basename(doc->file_name);
 	if (dialogs_show_question_full(NULL, _("_Reload"), GTK_STOCK_CANCEL,
 		_("Any unsaved changes will be lost."),
 		_("Are you sure you want to reload '%s'?"), base_name))
 	{
-		document_reload_file(idx, charset);
+		document_reload_file(doc, charset);
 		if (charset != NULL)
-			ui_update_statusbar(idx, -1);
+			ui_update_statusbar(doc, -1);
 	}
 	g_free(base_name);
 }
@@ -580,11 +580,11 @@
 on_entry1_activate                     (GtkEntry        *entry,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 	gboolean result;
 
 	setup_find_next(GTK_EDITABLE(entry));
-	result = document_search_bar_find(idx, search_data.text, 0, FALSE);
+	result = document_search_bar_find(doc, search_data.text, 0, FALSE);
 	set_search_bar_background(result);
 }
 
@@ -594,11 +594,11 @@
 on_entry1_changed                      (GtkEditable     *editable,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 	gboolean result;
 
 	setup_find_next(editable);
-	result = document_search_bar_find(idx, search_data.text, 0, TRUE);
+	result = document_search_bar_find(doc, search_data.text, 0, TRUE);
 	set_search_bar_background(result);
 }
 
@@ -608,12 +608,12 @@
 on_toolbutton18_clicked                (GtkToolButton   *toolbutton,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 	gboolean result;
 	GtkWidget *entry = lookup_widget(GTK_WIDGET(main_widgets.window), "entry1");
 
 	setup_find_next(GTK_EDITABLE(entry));
-	result = document_search_bar_find(idx, search_data.text, 0, FALSE);
+	result = document_search_bar_find(doc, search_data.text, 0, FALSE);
 	set_search_bar_background(result);
 }
 
@@ -655,14 +655,15 @@
 on_zoom_in1_activate                   (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 	static gboolean done = 1;
 
-	if (idx >= 0 && documents[idx]->is_valid)
+	if (doc != NULL)
 	{
-		if (done++ % 3 == 0) sci_set_line_numbers(documents[idx]->sci, editor_prefs.show_linenumber_margin,
-				(sci_get_zoom(documents[idx]->sci) / 2));
-		sci_zoom_in(documents[idx]->sci);
+		if (done++ % 3 == 0)
+			sci_set_line_numbers(doc->sci, editor_prefs.show_linenumber_margin,
+				(sci_get_zoom(doc->sci) / 2));
+		sci_zoom_in(doc->sci);
 	}
 }
 
@@ -671,12 +672,12 @@
 on_zoom_out1_activate                   (GtkMenuItem     *menuitem,
                                          gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
-	if (idx >= 0 && documents[idx]->is_valid)
+	GeanyDocument *doc = document_get_current();
+	if (doc != NULL)
 	{
-		if (sci_get_zoom(documents[idx]->sci) == 0)
-			sci_set_line_numbers(documents[idx]->sci, editor_prefs.show_linenumber_margin, 0);
-		sci_zoom_out(documents[idx]->sci);
+		if (sci_get_zoom(doc->sci) == 0)
+			sci_set_line_numbers(doc->sci, editor_prefs.show_linenumber_margin, 0);
+		sci_zoom_out(doc->sci);
 	}
 }
 
@@ -685,11 +686,11 @@
 on_normal_size1_activate               (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
-	if (idx >= 0 && documents[idx]->is_valid)
+	GeanyDocument *doc = document_get_current();
+	if (doc != NULL)
 	{
-		sci_zoom_off(documents[idx]->sci);
-		sci_set_line_numbers(documents[idx]->sci, editor_prefs.show_linenumber_margin, 0);
+		sci_zoom_off(doc->sci);
+		sci_set_line_numbers(doc->sci, editor_prefs.show_linenumber_margin, 0);
 	}
 }
 
@@ -700,7 +701,7 @@
                                         gpointer         user_data)
 {
 	gint cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(main_widgets.notebook));
-	document_remove(cur_page);
+	document_remove_page(cur_page);
 }
 
 
@@ -710,7 +711,7 @@
                                         guint            page_num,
                                         gpointer         user_data)
 {
-	callbacks_data.last_doc_idx = document_get_cur_idx();
+	callbacks_data.last_doc = document_get_current();
 }
 
 
@@ -721,35 +722,34 @@
                                         guint            page_num,
                                         gpointer         user_data)
 {
-	gint idx;
+	GeanyDocument *doc;
 
 	if (main_status.opening_session_files || main_status.closing_all)
 		return;
 
-	/* guint == -1 seems useless, but it isn't! */
 	if (page_num == (guint) -1 && page != NULL)
-		idx = document_find_by_sci(SCINTILLA(page));
+		doc = document_find_by_sci(SCINTILLA(page));
 	else
-		idx = document_get_n_idx(page_num);
+		doc = document_get_from_page(page_num);
 
-	if (idx >= 0)
+	if (doc != NULL)
 	{
-		treeviews_select_openfiles_item(idx);
-		document_set_text_changed(idx);	/* also sets window title and status bar */
-		ui_update_popup_reundo_items(idx);
-		ui_document_show_hide(idx); /* update the document menu */
-		build_menu_update(idx);
-		treeviews_update_tag_list(idx, FALSE);
+		treeviews_select_openfiles_item(doc);
+		document_set_text_changed(doc, doc->changed);	/* also sets window title and status bar */
+		ui_update_popup_reundo_items(doc);
+		ui_document_show_hide(doc); /* update the document menu */
+		build_menu_update(doc);
+		treeviews_update_tag_list(doc, FALSE);
 
-		utils_check_disk_status(idx, FALSE);
+		document_check_disk_status(doc, FALSE);
 
 #ifdef HAVE_VTE
-		vte_cwd(documents[idx]->file_name, FALSE);
+		vte_cwd(DOC_FILENAME(doc), FALSE);
 #endif
 
 		if (geany_object)
 		{
-			g_signal_emit_by_name(geany_object, "document-activate", idx);
+			g_signal_emit_by_name(geany_object, "document-activate", doc);
 		}
 	}
 }
@@ -780,10 +780,10 @@
 on_crlf_activate                       (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
-	if (ignore_callback || idx == -1 || ! documents[idx]->is_valid) return;
-	sci_convert_eols(documents[idx]->sci, SC_EOL_CRLF);
-	sci_set_eol_mode(documents[idx]->sci, SC_EOL_CRLF);
+	GeanyDocument *doc = document_get_current();
+	if (ignore_callback || doc == NULL) return;
+	sci_convert_eols(doc->sci, SC_EOL_CRLF);
+	sci_set_eol_mode(doc->sci, SC_EOL_CRLF);
 }
 
 
@@ -791,10 +791,10 @@
 on_lf_activate                         (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
-	if (ignore_callback || idx == -1 || ! documents[idx]->is_valid) return;
-	sci_convert_eols(documents[idx]->sci, SC_EOL_LF);
-	sci_set_eol_mode(documents[idx]->sci, SC_EOL_LF);
+	GeanyDocument *doc = document_get_current();
+	if (ignore_callback || doc == NULL) return;
+	sci_convert_eols(doc->sci, SC_EOL_LF);
+	sci_set_eol_mode(doc->sci, SC_EOL_LF);
 }
 
 
@@ -802,10 +802,10 @@
 on_cr_activate                         (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
-	if (ignore_callback || idx == -1 || ! documents[idx]->is_valid) return;
-	sci_convert_eols(documents[idx]->sci, SC_EOL_CR);
-	sci_set_eol_mode(documents[idx]->sci, SC_EOL_CR);
+	GeanyDocument *doc = document_get_current();
+	if (ignore_callback || doc == NULL) return;
+	sci_convert_eols(doc->sci, SC_EOL_CR);
+	sci_set_eol_mode(doc->sci, SC_EOL_CR);
 }
 
 
@@ -813,9 +813,9 @@
 on_replace_tabs_activate               (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 
-	editor_replace_tabs(idx);
+	editor_replace_tabs(doc);
 }
 
 
@@ -858,21 +858,21 @@
 
 void on_toggle_case1_activate(GtkMenuItem *menuitem, gpointer user_data)
 {
-	gint idx = document_get_cur_idx();
-	ScintillaObject *sci = documents[idx]->sci;
+	GeanyDocument *doc = document_get_current();
+	ScintillaObject *sci;
 	gchar *text;
 	gboolean keep_sel = TRUE;
 
-	if (! DOC_IDX_VALID(idx))
+	if (doc == NULL)
 		return;
 
+	sci = doc->sci;
 	if (! sci_can_copy(sci))
 	{
 		keybindings_send_command(GEANY_KEY_GROUP_SELECT, GEANY_KEYS_SELECT_WORD);
 		keep_sel = FALSE;
 	}
-
-	if (sci_can_copy(sci))
+	else
 	{
 		gchar *result = NULL;
 		gint cmd = SCI_LOWERCASE;
@@ -970,9 +970,9 @@
 {
 	if (! ignore_callback)
 	{
-		gint idx = document_get_cur_idx();
-		if (! DOC_IDX_VALID(idx)) return;
-		editor_set_line_wrapping(idx, ! documents[idx]->line_wrapping);
+		GeanyDocument *doc = document_get_current();
+		if (doc != NULL)
+			editor_set_line_wrapping(doc, ! doc->line_wrapping);
 	}
 }
 
@@ -983,12 +983,13 @@
 {
 	if (! ignore_callback)
 	{
-		gint idx = document_get_cur_idx();
-		if (! DOC_IDX_VALID(idx)) return;
-		documents[idx]->readonly = ! documents[idx]->readonly;
-		sci_set_readonly(documents[idx]->sci, documents[idx]->readonly);
-		ui_update_tab_status(idx);
-		ui_update_statusbar(idx, -1);
+		GeanyDocument *doc = document_get_current();
+		if (doc == NULL)
+			return;
+		doc->readonly = ! doc->readonly;
+		sci_set_readonly(doc->sci, doc->readonly);
+		ui_update_tab_status(doc);
+		ui_update_statusbar(doc, -1);
 	}
 }
 
@@ -999,9 +1000,9 @@
 {
 	if (! ignore_callback)
 	{
-		gint idx = document_get_cur_idx();
-		if (! DOC_IDX_VALID(idx)) return;
-		documents[idx]->auto_indent = ! documents[idx]->auto_indent;
+		GeanyDocument *doc = document_get_current();
+		if (doc != NULL)
+			doc->auto_indent = ! doc->auto_indent;
 	}
 }
 
@@ -1010,16 +1011,17 @@
 on_find_usage1_activate                (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint flags, idx;
+	gint flags;
 	gchar *search_text;
+	GeanyDocument *doc = document_get_current();
 
-	idx = document_get_cur_idx();
-	if (! DOC_IDX_VALID(idx)) return;
+	if (doc == NULL)
+		return;
 
-	if (sci_can_copy(documents[idx]->sci))
+	if (sci_can_copy(doc->sci))
 	{	/* take selected text if there is a selection */
-		search_text = g_malloc(sci_get_selected_text_length(documents[idx]->sci) + 1);
-		sci_get_selected_text(documents[idx]->sci, search_text);
+		search_text = g_malloc(sci_get_selected_text_length(doc->sci) + 1);
+		sci_get_selected_text(doc->sci, search_text);
 		flags = SCFIND_MATCHCASE;
 	}
 	else
@@ -1041,7 +1043,7 @@
 		GTK_MENU_ITEM(lookup_widget(main_widgets.editor_menu, "goto_tag_definition1")));
 	GeanyDocument *doc = document_get_current();
 
-	g_return_if_fail(doc);
+	g_return_if_fail(doc != NULL);
 
 	sci_set_current_position(doc->sci, editor_info.click_pos, FALSE);
 	symbols_goto_tag(editor_info.current_word, definition);
@@ -1061,13 +1063,14 @@
                                         gpointer         user_data)
 {
 	gchar colour[9];
-	gint idx = document_get_cur_idx();
-	gint pos = sci_get_current_position(documents[idx]->sci);
+	GeanyDocument *doc = document_get_current();
+	gint pos;
 
-	if (idx == -1 || ! documents[idx]->is_valid)
+	if (doc == NULL)
 		return;
 
-	editor_find_current_word(documents[idx]->sci, pos, colour, sizeof colour, GEANY_WORDCHARS"#");
+	pos = sci_get_current_position(doc->sci);
+	editor_find_current_word(doc->sci, pos, colour, sizeof colour, GEANY_WORDCHARS"#");
 	tools_color_chooser(colour);
 }
 
@@ -1090,18 +1093,18 @@
 
 static void find_again(gboolean change_direction)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 
-	g_return_if_fail(DOC_IDX_VALID(idx));
+	g_return_if_fail(doc != NULL);
 
 	if (search_data.text)
 	{
 		gboolean forward = ! search_data.backwards;
-		gint result = document_find_text(idx, search_data.text, search_data.flags,
+		gint result = document_find_text(doc, search_data.text, search_data.flags,
 			change_direction ? forward : !forward, FALSE, NULL);
 
 		if (result > -1)
-			editor_display_current_line(idx, 0.3F);
+			editor_display_current_line(doc, 0.3F);
 
 		set_search_bar_background((result > -1) ? TRUE : FALSE);
 	}
@@ -1132,7 +1135,7 @@
 on_find_nextsel1_activate             (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	search_find_selection(document_get_cur_idx(), FALSE);
+	search_find_selection(document_get_current(), FALSE);
 }
 
 
@@ -1140,7 +1143,7 @@
 on_find_prevsel1_activate             (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	search_find_selection(document_get_cur_idx(), TRUE);
+	search_find_selection(document_get_current(), TRUE);
 }
 
 
@@ -1183,16 +1186,16 @@
 {
 	if (response == GTK_RESPONSE_ACCEPT)
 	{
-		gint idx = document_get_cur_idx();
+		GeanyDocument *doc = document_get_current();
 		gint line = strtol(gtk_entry_get_text(GTK_ENTRY(user_data)), NULL, 10);
 
-		if (line > 0 && line <= sci_get_line_count(documents[idx]->sci))
+		if (doc != NULL && line > 0 && line <= sci_get_line_count(doc->sci))
 		{
 			gint pos;
 
 			line--;	/* the user counts lines from 1, we begin at 0 so bring the user line to our one */
-			pos = sci_get_position_from_line(documents[idx]->sci, line);
-			editor_goto_pos(idx, pos, TRUE);
+			pos = sci_get_position_from_line(doc->sci, line);
+			editor_goto_pos(doc, pos, TRUE);
 		}
 		else
 		{
@@ -1276,25 +1279,26 @@
 on_comments_function_activate          (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 	gchar *text;
 	const gchar *cur_tag = NULL;
 	gint line = -1, pos = 0;
 
-	if (documents[idx]->file_type == NULL)
+	if (doc == NULL || doc->file_type == NULL)
 	{
-		ui_set_statusbar(FALSE, _("Please set the filetype for the current file before using this function."));
+		ui_set_statusbar(FALSE,
+			_("Please set the filetype for the current file before using this function."));
 		return;
 	}
 
 	/* utils_get_current_function returns -1 on failure, so sci_get_position_from_line
 	 * returns the current position, so it should be safe */
-	line = utils_get_current_function(idx, &cur_tag);
-	pos = sci_get_position_from_line(documents[idx]->sci, line - 1);
+	line = utils_get_current_function(doc, &cur_tag);
+	pos = sci_get_position_from_line(doc->sci, line - 1);
 
-	text = templates_get_template_function(documents[idx]->file_type->id, cur_tag);
+	text = templates_get_template_function(doc->file_type->id, cur_tag);
 
-	sci_insert_text(documents[idx]->sci, pos, text);
+	sci_insert_text(doc->sci, pos, text);
 	g_free(text);
 }
 
@@ -1303,17 +1307,18 @@
 on_comments_multiline_activate         (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 
-	if (! DOC_IDX_VALID(idx) || documents[idx]->file_type == NULL)
+	if (doc == NULL || doc->file_type == NULL)
 	{
-		ui_set_statusbar(FALSE, _("Please set the filetype for the current file before using this function."));
+		ui_set_statusbar(FALSE,
+			_("Please set the filetype for the current file before using this function."));
 		return;
 	}
 
-	verify_click_pos(idx); /* make sure that the click_pos is valid */
+	verify_click_pos(doc); /* make sure that the click_pos is valid */
 
-	editor_insert_multiline_comment(idx);
+	editor_insert_multiline_comment(doc);
 }
 
 
@@ -1321,14 +1326,17 @@
 on_comments_gpl_activate               (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 	gchar *text;
 
-	text = templates_get_template_licence(FILETYPE_ID(documents[idx]->file_type), GEANY_TEMPLATE_GPL);
+	if (doc == NULL)
+		return;
 
-	verify_click_pos(idx); /* make sure that the click_pos is valid */
+	text = templates_get_template_licence(FILETYPE_ID(doc->file_type), GEANY_TEMPLATE_GPL);
 
-	sci_insert_text(documents[idx]->sci, editor_info.click_pos, text);
+	verify_click_pos(doc); /* make sure that the click_pos is valid */
+
+	sci_insert_text(doc->sci, editor_info.click_pos, text);
 	g_free(text);
 }
 
@@ -1338,14 +1346,17 @@
                                         gpointer         user_data)
 {
 
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 	gchar *text;
 
-	text = templates_get_template_licence(FILETYPE_ID(documents[idx]->file_type), GEANY_TEMPLATE_BSD);
+	if (doc == NULL)
+		return;
 
-	verify_click_pos(idx); /* make sure that the click_pos is valid */
+	text = templates_get_template_licence(FILETYPE_ID(doc->file_type), GEANY_TEMPLATE_BSD);
 
-	sci_insert_text(documents[idx]->sci, editor_info.click_pos, text);
+	verify_click_pos(doc); /* make sure that the click_pos is valid */
+
+	sci_insert_text(doc->sci, editor_info.click_pos, text);
 	g_free(text);
 
 }
@@ -1355,14 +1366,17 @@
 on_comments_changelog_activate         (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 	gchar *text;
 
+	if (doc == NULL)
+		return;
+
 	text = templates_get_template_changelog();
-	sci_insert_text(documents[idx]->sci, 0, text);
+	sci_insert_text(doc->sci, 0, text);
 	/* sets the cursor to the right position to type the changelog text,
 	 * the template has 21 chars + length of name and email */
-	sci_goto_pos(documents[idx]->sci, 21 + strlen(template_prefs.developer) + strlen(template_prefs.mail), TRUE);
+	sci_goto_pos(doc->sci, 21 + strlen(template_prefs.developer) + strlen(template_prefs.mail), TRUE);
 
 	g_free(text);
 }
@@ -1372,19 +1386,19 @@
 on_comments_fileheader_activate        (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 	gchar *text;
 	gchar *fname;
 	GeanyFiletype *ft;
 
-	g_return_if_fail(DOC_IDX_VALID(idx));
+	g_return_if_fail(doc != NULL);
 
-	ft = documents[idx]->file_type;
-	fname = documents[idx]->file_name;
+	ft = doc->file_type;
+	fname = doc->file_name;
 	text = templates_get_template_fileheader(FILETYPE_ID(ft), fname);
 
-	sci_insert_text(documents[idx]->sci, 0, text);
-	sci_goto_pos(documents[idx]->sci, 0, FALSE);
+	sci_insert_text(doc->sci, 0, text);
+	sci_goto_pos(doc->sci, 0, FALSE);
 	g_free(text);
 }
 
@@ -1400,14 +1414,14 @@
 on_insert_date_activate                (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 	gchar *format;
 	gchar time_str[300]; /* the entered format string can be maximal 256 chars long, so we have
 						  * 44 additional characters for strtime's conversion */
 	time_t t;
 	struct tm *tm;
 
-	if (idx < 0 || ! documents[idx]->is_valid) return;
+	if (doc == NULL) return;
 
 	if (utils_str_equal(_("dd.mm.yyyy"), (gchar*) user_data))
 		format = "%d.%m.%Y";
@@ -1443,10 +1457,10 @@
 	tm = localtime(&t);
 	if (strftime(time_str, sizeof time_str, format, tm) != 0)
 	{
-		verify_click_pos(idx); /* make sure that the click_pos is valid */
+		verify_click_pos(doc); /* make sure that the click_pos is valid */
 
-		sci_insert_text(documents[idx]->sci, editor_info.click_pos, time_str);
-		sci_goto_pos(documents[idx]->sci, editor_info.click_pos + strlen(time_str), FALSE);
+		sci_insert_text(doc->sci, editor_info.click_pos, time_str);
+		sci_goto_pos(doc->sci, editor_info.click_pos + strlen(time_str), FALSE);
 	}
 	else
 	{
@@ -1461,13 +1475,13 @@
 on_insert_include_activate             (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 	gint pos = -1;
 	gchar *text;
 
-	if (! DOC_IDX_VALID(idx) || user_data == NULL) return;
+	if (doc == NULL || user_data == NULL) return;
 
-	verify_click_pos(idx); /* make sure that the click_pos is valid */
+	verify_click_pos(doc); /* make sure that the click_pos is valid */
 
 	if (utils_str_equal(user_data, "blank"))
 	{
@@ -1479,10 +1493,10 @@
 		text = g_strconcat("#include <", user_data, ">\n", NULL);
 	}
 
-	sci_insert_text(documents[idx]->sci, editor_info.click_pos, text);
+	sci_insert_text(doc->sci, editor_info.click_pos, text);
 	g_free(text);
 	if (pos >= 0)
-		sci_goto_pos(documents[idx]->sci, pos, FALSE);
+		sci_goto_pos(doc->sci, pos, FALSE);
 }
 
 
@@ -1490,8 +1504,8 @@
 on_file_properties_activate            (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
-	dialogs_show_file_properties(idx);
+	GeanyDocument *doc = document_get_current();
+	dialogs_show_file_properties(doc);
 }
 
 
@@ -1499,9 +1513,8 @@
 on_menu_fold_all1_activate             (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
-
-	editor_fold_all(idx);
+	GeanyDocument *doc = document_get_current();
+	editor_fold_all(doc);
 }
 
 
@@ -1509,9 +1522,8 @@
 on_menu_unfold_all1_activate           (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
-
-	editor_unfold_all(idx);
+	GeanyDocument *doc = document_get_current();
+	editor_unfold_all(doc);
 }
 
 
@@ -1536,11 +1548,10 @@
 on_menu_remove_indicators1_activate    (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 
-	if (! DOC_IDX_VALID(idx))
-		return;
-	editor_clear_indicators(idx);
+	if (doc != NULL)
+		editor_clear_indicators(doc);
 }
 
 
@@ -1548,20 +1559,21 @@
 on_encoding_change                     (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 	guint i = GPOINTER_TO_INT(user_data);
 
-	if (ignore_callback || ! DOC_IDX_VALID(idx) || encodings[i].charset == NULL ||
-		utils_str_equal(encodings[i].charset, documents[idx]->encoding)) return;
+	if (ignore_callback || doc == NULL || encodings[i].charset == NULL ||
+		utils_str_equal(encodings[i].charset, doc->encoding))
+		return;
 
-	if (documents[idx]->readonly)
+	if (doc->readonly)
 	{
 		utils_beep();
 		return;
 	}
-	document_undo_add(idx, UNDO_ENCODING, g_strdup(documents[idx]->encoding));
+	document_undo_add(doc, UNDO_ENCODING, g_strdup(doc->encoding));
 
-	document_set_encoding(idx, encodings[i].charset);
+	document_set_encoding(doc, encodings[i].charset);
 }
 
 
@@ -1569,10 +1581,9 @@
 on_print1_activate                     (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
-	if (! DOC_IDX_VALID(idx))
-		return;
-	printing_print_doc(idx);
+	GeanyDocument *doc = document_get_current();
+	if (doc != NULL)
+		printing_print_doc(doc);
 }
 
 
@@ -1580,11 +1591,10 @@
 on_menu_select_all1_activate           (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 
-	if (idx < 0 || ! documents[idx]->is_valid) return;
-
-	sci_select_all(documents[idx]->sci);
+	if (doc != NULL)
+		sci_select_all(doc->sci);
 }
 
 
@@ -1622,20 +1632,21 @@
 {
 	if (! ignore_callback)
 	{
-		gint idx = document_get_cur_idx();
+		GeanyDocument *doc = document_get_current();
 
-		if (idx == -1 || ! documents[idx]->is_valid) return;
-		if (documents[idx]->readonly)
+		if (doc == NULL)
+			return;
+		if (doc->readonly)
 		{
 			utils_beep();
 			return;
 		}
 
-		document_undo_add(idx, UNDO_BOM, GINT_TO_POINTER(documents[idx]->has_bom));
+		document_undo_add(doc, UNDO_BOM, GINT_TO_POINTER(doc->has_bom));
 
-		documents[idx]->has_bom = ! documents[idx]->has_bom;
+		doc->has_bom = ! doc->has_bom;
 
-		ui_update_statusbar(idx, -1);
+		ui_update_statusbar(doc, -1);
 	}
 }
 
@@ -1644,9 +1655,9 @@
 on_menu_comment_line1_activate         (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
-	if (idx == -1 || ! documents[idx]->is_valid) return;
-	editor_do_comment(idx, -1, FALSE, FALSE);
+	GeanyDocument *doc = document_get_current();
+	if (doc != NULL)
+		editor_do_comment(doc, -1, FALSE, FALSE);
 }
 
 
@@ -1654,9 +1665,9 @@
 on_menu_uncomment_line1_activate       (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
-	if (idx == -1 || ! documents[idx]->is_valid) return;
-	editor_do_uncomment(idx, -1, FALSE);
+	GeanyDocument *doc = document_get_current();
+	if (doc != NULL)
+		editor_do_uncomment(doc, -1, FALSE);
 }
 
 
@@ -1665,9 +1676,9 @@
                                        (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
-	if (idx == -1 || ! documents[idx]->is_valid) return;
-	editor_do_comment_toggle(idx);
+	GeanyDocument *doc = document_get_current();
+	if (doc != NULL)
+		editor_do_comment_toggle(doc);
 }
 
 
@@ -1683,27 +1694,28 @@
 on_menu_increase_indent1_activate      (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
-	if (! DOC_IDX_VALID(idx)) return;
+	GeanyDocument *doc = document_get_current();
+	if (doc == NULL)
+		return;
 
-	if (sci_get_lines_selected(documents[idx]->sci) > 1)
+	if (sci_get_lines_selected(doc->sci) > 1)
 	{
-		sci_cmd(documents[idx]->sci, SCI_TAB);
+		sci_cmd(doc->sci, SCI_TAB);
 	}
 	else
 	{
 		gint line, ind_pos, old_pos, new_pos, step;
 
-		old_pos = sci_get_current_position(documents[idx]->sci);
-		line = sci_get_line_from_position(documents[idx]->sci, old_pos);
-		ind_pos = sci_get_line_indent_position(documents[idx]->sci, line);
+		old_pos = sci_get_current_position(doc->sci);
+		line = sci_get_line_from_position(doc->sci, old_pos);
+		ind_pos = sci_get_line_indent_position(doc->sci, line);
 		/* when using tabs increase cur pos by 1, when using space increase it by tab_width */
-		step = (documents[idx]->use_tabs) ? 1 : editor_prefs.tab_width;
+		step = (doc->use_tabs) ? 1 : editor_prefs.tab_width;
 		new_pos = (old_pos > ind_pos) ? old_pos + step : old_pos;
 
-		sci_set_current_position(documents[idx]->sci, ind_pos, TRUE);
-		sci_cmd(documents[idx]->sci, SCI_TAB);
-		sci_set_current_position(documents[idx]->sci, new_pos, TRUE);
+		sci_set_current_position(doc->sci, ind_pos, TRUE);
+		sci_cmd(doc->sci, SCI_TAB);
+		sci_set_current_position(doc->sci, new_pos, TRUE);
 	}
 }
 
@@ -1712,34 +1724,35 @@
 on_menu_decrease_indent1_activate      (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
-	if (! DOC_IDX_VALID(idx)) return;
+	GeanyDocument *doc = document_get_current();
+	if (doc == NULL)
+		return;
 
-	if (sci_get_lines_selected(documents[idx]->sci) > 1)
+	if (sci_get_lines_selected(doc->sci) > 1)
 	{
-		sci_cmd(documents[idx]->sci, SCI_BACKTAB);
+		sci_cmd(doc->sci, SCI_BACKTAB);
 	}
 	else
 	{
 		gint line, ind_pos, old_pos, new_pos, step, indent;
 
-		old_pos = sci_get_current_position(documents[idx]->sci);
-		line = sci_get_line_from_position(documents[idx]->sci, old_pos);
-		ind_pos = sci_get_line_indent_position(documents[idx]->sci, line);
-		step = (documents[idx]->use_tabs) ? 1 : editor_prefs.tab_width;
+		old_pos = sci_get_current_position(doc->sci);
+		line = sci_get_line_from_position(doc->sci, old_pos);
+		ind_pos = sci_get_line_indent_position(doc->sci, line);
+		step = (doc->use_tabs) ? 1 : editor_prefs.tab_width;
 		new_pos = (old_pos >= ind_pos) ? old_pos - step : old_pos;
 
-		if (ind_pos == sci_get_position_from_line(documents[idx]->sci, line))
+		if (ind_pos == sci_get_position_from_line(doc->sci, line))
 			return;
 
-		sci_set_current_position(documents[idx]->sci, ind_pos, TRUE);
-		indent = sci_get_line_indentation(documents[idx]->sci, line);
+		sci_set_current_position(doc->sci, ind_pos, TRUE);
+		indent = sci_get_line_indentation(doc->sci, line);
 		indent -= editor_prefs.tab_width;
 		if (indent < 0)
 			indent = 0;
-		sci_set_line_indentation(documents[idx]->sci, line, indent);
+		sci_set_line_indentation(doc->sci, line, indent);
 
-		sci_set_current_position(documents[idx]->sci, new_pos, TRUE);
+		sci_set_current_position(doc->sci, new_pos, TRUE);
 	}
 }
 
@@ -1853,12 +1866,13 @@
 on_menu_open_selected_file1_activate   (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 	gchar *sel = NULL;
 
-	if (! DOC_IDX_VALID(idx)) return;
+	if (doc == NULL)
+		return;
 
-	sel = editor_get_default_selection(idx, TRUE, GEANY_WORDCHARS"./");
+	sel = editor_get_default_selection(doc, TRUE, GEANY_WORDCHARS"./");
 
 	if (sel != NULL)
 	{
@@ -1870,7 +1884,7 @@
 		{	/* relative filename, add the path of the current file */
 			gchar *path;
 
-			path = g_path_get_dirname(documents[idx]->file_name);
+			path = g_path_get_dirname(doc->file_name);
 			filename = g_build_path(G_DIR_SEPARATOR_S, path, sel, NULL);
 
 			if (! g_file_test(filename, G_FILE_TEST_EXISTS) &&
@@ -1897,13 +1911,13 @@
 on_remove_markers1_activate            (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 
-	if (! DOC_IDX_VALID(idx))
+	if (doc == NULL)
 		return;
 
-	sci_marker_delete_all(documents[idx]->sci, 0);	/* delete the yellow tag marker */
-	sci_marker_delete_all(documents[idx]->sci, 1);	/* delete user markers */
+	sci_marker_delete_all(doc->sci, 0);	/* delete the yellow tag marker */
+	sci_marker_delete_all(doc->sci, 1);	/* delete user markers */
 }
 
 
@@ -1919,17 +1933,17 @@
 on_context_action1_activate            (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx;
 	gchar *word, *command;
 	GError *error = NULL;
+	GeanyDocument *doc = document_get_current();
 
-	idx = document_get_cur_idx();
-	if (! DOC_IDX_VALID(idx)) return;
+	if (doc == NULL)
+		return;
 
-	if (sci_can_copy(documents[idx]->sci))
+	if (sci_can_copy(doc->sci))
 	{	/* take selected text if there is a selection */
-		word = g_malloc(sci_get_selected_text_length(documents[idx]->sci) + 1);
-		sci_get_selected_text(documents[idx]->sci, word);
+		word = g_malloc(sci_get_selected_text_length(doc->sci) + 1);
+		sci_get_selected_text(doc->sci, word);
 	}
 	else
 	{
@@ -1937,11 +1951,10 @@
 	}
 
 	/* use the filetype specific command if available, fallback to global command otherwise */
-	if (documents[idx]->file_type != NULL &&
-		documents[idx]->file_type->context_action_cmd != NULL &&
-		*documents[idx]->file_type->context_action_cmd != '\0')
+	if (doc->file_type != NULL &&
+		NZV(doc->file_type->context_action_cmd))
 	{
-		command = g_strdup(documents[idx]->file_type->context_action_cmd);
+		command = g_strdup(doc->file_type->context_action_cmd);
 	}
 	else
 	{
@@ -2049,10 +2062,13 @@
 on_tabs1_activate                      (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 
-	editor_set_use_tabs(idx, TRUE);
-	ui_update_statusbar(idx, -1);
+	if (doc == NULL || ignore_callback)
+		return;
+
+	editor_set_use_tabs(doc, TRUE);
+	ui_update_statusbar(doc, -1);
 }
 
 
@@ -2060,10 +2076,13 @@
 on_spaces1_activate                    (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 
-	editor_set_use_tabs(idx, FALSE);
-	ui_update_statusbar(idx, -1);
+	if (doc == NULL || ignore_callback)
+		return;
+
+	editor_set_use_tabs(doc, FALSE);
+	ui_update_statusbar(doc, -1);
 }
 
 
@@ -2071,9 +2090,12 @@
 on_strip_trailing_spaces1_activate     (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 
-	editor_strip_trailing_spaces(idx);
+	if (doc == NULL || ignore_callback)
+		return;
+
+	editor_strip_trailing_spaces(doc);
 }
 
 
@@ -2122,7 +2144,7 @@
 		return;
 
 	doc = document_get_current();
-	g_return_if_fail(doc);
+	g_return_if_fail(doc != NULL);
 
 	doc->line_breaking = !doc->line_breaking;
 }

Modified: trunk/src/callbacks.h
===================================================================
--- trunk/src/callbacks.h	2008-06-18 14:18:26 UTC (rev 2704)
+++ trunk/src/callbacks.h	2008-06-18 17:03:08 UTC (rev 2705)
@@ -21,9 +21,13 @@
  * $Id$
  */
 
+
+#include "geany.h" /* necessary for interface.c */
+
+
 typedef struct
 {
-	gint last_doc_idx;
+	GeanyDocument *last_doc;
 } CallbacksData;
 
 extern CallbacksData callbacks_data;

Modified: trunk/src/dialogs.c
===================================================================
--- trunk/src/dialogs.c	2008-06-18 14:18:26 UTC (rev 2704)
+++ trunk/src/dialogs.c	2008-06-18 17:03:08 UTC (rev 2705)
@@ -385,22 +385,22 @@
 static void handle_save_as(const gchar *utf8_filename, gboolean open_new_tab,
 		gboolean rename_file)
 {
-	gint idx = document_get_cur_idx();
+	GeanyDocument *doc = document_get_current();
 
 	g_return_if_fail(NZV(utf8_filename));
 
 	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);
+		doc = document_clone(doc, utf8_filename);
+		document_save_file_as(doc, NULL);
 	}
 	else
 	{
-		if (documents[idx]->file_name != NULL)
+		if (doc->file_name != NULL)
 		{
 			if (rename_file)
 			{
-				gchar *old_filename = utils_get_locale_from_utf8(documents[idx]->file_name);
+				gchar *old_filename = utils_get_locale_from_utf8(doc->file_name);
 				gchar *new_filename = utils_get_locale_from_utf8(utf8_filename);
 
 				g_rename(old_filename, new_filename);
@@ -408,14 +408,14 @@
 				g_free(new_filename);
 			}
 			/* create a new tm_source_file object otherwise tagmanager won't work correctly */
-			tm_workspace_remove_object(documents[idx]->tm_file, TRUE, TRUE);
-			documents[idx]->tm_file = NULL;
+			tm_workspace_remove_object(doc->tm_file, TRUE, TRUE);
+			doc->tm_file = NULL;
 		}
-		document_save_file_as(idx, utf8_filename);
+		document_save_file_as(doc, utf8_filename);
 	}
 
 	if (! open_new_tab)
-		build_menu_update(idx);
+		build_menu_update(doc);
 }
 
 
@@ -520,7 +520,8 @@
 #if ! GEANY_USE_WIN32_DIALOG
 static gboolean gtk_show_save_as(const gchar *initdir)
 {
-	gint idx = document_get_cur_idx(), resp;
+	GeanyDocument *doc = document_get_current();
+	gint resp;
 	gboolean folder_set = FALSE;
 
 	if (ui_widgets.save_filesel == NULL)
@@ -528,11 +529,11 @@
 
 	gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(ui_widgets.save_filesel));
 
-	if (documents[idx]->file_name != NULL)
+	if (doc->file_name != NULL)
 	{
-		if (g_path_is_absolute(documents[idx]->file_name))
+		if (g_path_is_absolute(doc->file_name))
 		{
-			gchar *locale_filename = utils_get_locale_from_utf8(documents[idx]->file_name);
+			gchar *locale_filename = utils_get_locale_from_utf8(doc->file_name);
 			gchar *locale_basename = g_path_get_basename(locale_filename);
 			gchar *locale_dirname = g_path_get_dirname(locale_filename);
 
@@ -548,16 +549,16 @@
 		}
 		else
 			gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(ui_widgets.save_filesel),
-				documents[idx]->file_name);
+				doc->file_name);
 	}
 	else
 	{
 		gchar *fname = NULL;
 
-		if (documents[idx]->file_type != NULL && documents[idx]->file_type->id != GEANY_FILETYPES_NONE &&
-			documents[idx]->file_type->extension != NULL)
+		if (doc->file_type != NULL && doc->file_type->id != GEANY_FILETYPES_NONE &&
+			doc->file_type->extension != NULL)
 			fname = g_strconcat(GEANY_STRING_UNTITLED, ".",
-								documents[idx]->file_type->extension, NULL);
+								doc->file_type->extension, NULL);
 		else
 			fname = g_strdup(GEANY_STRING_UNTITLED);
 
@@ -660,7 +661,7 @@
 }
 
 
-gboolean dialogs_show_unsaved_file(gint idx)
+gboolean dialogs_show_unsaved_file(GeanyDocument *doc)
 {
 #ifndef G_OS_WIN32
 	GtkWidget *dialog, *button;
@@ -672,12 +673,12 @@
 	/* display the file tab to remind the user of the document */
 	main_status.quitting = FALSE;
 	gtk_notebook_set_current_page(GTK_NOTEBOOK(main_widgets.notebook),
-		document_get_notebook_page(idx));
+		document_get_notebook_page(doc));
 	main_status.quitting = old_quitting_state;
 
-	if (documents[idx]->file_name != NULL)
+	if (doc->file_name != NULL)
 	{
-		short_fn = g_path_get_basename(documents[idx]->file_name);
+		short_fn = g_path_get_basename(doc->file_name);
 	}
 
 	msg = g_strdup_printf(_("The file '%s' is not saved."),
@@ -711,13 +712,13 @@
 	{
 		case GTK_RESPONSE_YES:
 		{
-			if (documents[idx]->file_name == NULL)
+			if (doc->file_name == NULL)
 			{
 				ret = dialogs_show_save_as();
 			}
 			else
 				/* document_save_file() returns the status if the file could be saved */
-				ret = document_save_file(idx, FALSE);
+				ret = document_save_file(doc, FALSE);
 			break;
 		}
 		case GTK_RESPONSE_NO: ret = TRUE; break;
@@ -943,7 +944,7 @@
 }
 
 
-void dialogs_show_file_properties(gint idx)
+void dialogs_show_file_properties(GeanyDocument *doc)
 {
 	GtkWidget *dialog, *label, *table, *hbox, *image, *perm_table, *check, *vbox;
 	gchar *file_size, *title, *base_name, *time_changed, *time_modified, *time_accessed, *enctext;
@@ -972,7 +973,7 @@
 # define S_IXOTH 0
 #endif
 
-	if (idx == -1 || ! documents[idx]->is_valid || documents[idx]->file_name == NULL)
+	if (doc == NULL || doc->file_name == NULL)
 	{
 		dialogs_show_msgbox(GTK_MESSAGE_ERROR,
 		_("An error occurred or file information could not be retrieved (e.g. from a new file)."));
@@ -981,7 +982,7 @@
 
 
 #ifdef HAVE_SYS_TYPES_H
-	locale_filename = utils_get_locale_from_utf8(documents[idx]->file_name);
+	locale_filename = utils_get_locale_from_utf8(doc->file_name);
 	if (g_stat(locale_filename, &st) == 0)
 	{
 		/* first copy the returned string and the trim it, to not modify the static glibc string
@@ -1007,7 +1008,7 @@
 	time_accessed = g_strdup(_("unknown"));
 #endif
 
-	base_name = g_path_get_basename(documents[idx]->file_name);
+	base_name = g_path_get_basename(doc->file_name);
 	title = g_strconcat(base_name, " ", _("Properties"), NULL);
 	dialog = gtk_dialog_new_with_buttons(title, GTK_WINDOW(main_widgets.window),
 										 GTK_DIALOG_DESTROY_WITH_PARENT,
@@ -1044,7 +1045,7 @@
 	gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
 	gtk_misc_set_alignment(GTK_MISC(label), 1, 0);
 
-	label = gtk_label_new(documents[idx]->file_type->title);
+	label = gtk_label_new(doc->file_type->title);
 	gtk_table_attach(GTK_TABLE(table), label, 1, 2, 0, 1,
 					(GtkAttachOptions) (GTK_FILL),
 					(GtkAttachOptions) (0), 0, 0);
@@ -1072,7 +1073,7 @@
 	gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
 	gtk_misc_set_alignment(GTK_MISC(label), 1, 0);
 
-	label = gtk_label_new(documents[idx]->file_name);
+	label = gtk_label_new(doc->file_name);
 	gtk_table_attach(GTK_TABLE(table), label, 1, 2, 2, 3,
 					(GtkAttachOptions) (GTK_FILL),
 					(GtkAttachOptions) (0), 0, 0);
@@ -1088,7 +1089,7 @@
 	check = gtk_check_button_new_with_label(_("(only inside Geany)"));
 	gtk_widget_set_sensitive(check, FALSE);
 	gtk_button_set_focus_on_click(GTK_BUTTON(check), FALSE);
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), documents[idx]->readonly);
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), doc->readonly);
 	gtk_table_attach(GTK_TABLE(table), check, 1, 2, 3, 4,
 					(GtkAttachOptions) (GTK_FILL),
 					(GtkAttachOptions) (0), 0, 0);
@@ -1102,9 +1103,9 @@
 	gtk_misc_set_alignment(GTK_MISC(label), 1, 0);
 
 	enctext = g_strdup_printf("%s %s",
-		documents[idx]->encoding,
-		(encodings_is_unicode_charset(documents[idx]->encoding)) ?
-			((documents[idx]->has_bom) ? _("(with BOM)") : _("(without BOM)")) : "");
+		doc->encoding,
+		(encodings_is_unicode_charset(doc->encoding)) ?
+			((doc->has_bom) ? _("(with BOM)") : _("(without BOM)")) : "");
 
 	label = gtk_label_new(enctext);
 	g_free(enctext);

Modified: trunk/src/dialogs.h
===================================================================
--- trunk/src/dialogs.h	2008-06-18 14:18:26 UTC (rev 2704)
+++ trunk/src/dialogs.h	2008-06-18 17:03:08 UTC (rev 2705)
@@ -37,7 +37,7 @@
 
 gboolean dialogs_show_save_as(void);
 
-gboolean dialogs_show_unsaved_file(gint idx);
+gboolean dialogs_show_unsaved_file(GeanyDocument *doc);
 
 void dialogs_show_open_font(void);
 
@@ -50,7 +50,7 @@
 
 void dialogs_show_goto_line(void);
 
-void dialogs_show_file_properties(gint idx);
+void dialogs_show_file_properties(GeanyDocument *doc);
 
 gboolean dialogs_show_question(const gchar *text, ...) G_GNUC_PRINTF (1, 2);
 

Modified: trunk/src/document.c
===================================================================
--- trunk/src/document.c	2008-06-18 14:18:26 UTC (rev 2704)
+++ trunk/src/document.c	2008-06-18 17:03:08 UTC (rev 2705)
@@ -93,8 +93,8 @@
 static gboolean delay_colourise = FALSE;
 
 
-static void document_undo_clear(gint idx);
-static void document_redo_add(gint idx, guint type, gpointer data);
+static void document_undo_clear(GeanyDocument *doc);
+static void document_redo_add(GeanyDocument *doc, guint type, gpointer data);
 
 static gboolean update_type_keywords(ScintillaObject *sci, gint lang);
 
@@ -112,18 +112,16 @@
  * @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.
+ * @return The matching document, or NULL.
  * @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)
+GeanyDocument* document_find_by_real_path(const gchar *realname)
 {
 	guint i;
-	gint ret = -1;
 
 	if (! realname)
-		return -1;	/* file doesn't exist on disk */
+		return NULL;	/* file doesn't exist on disk */
 
 	for (i = 0; i < documents_array->len; i++)
 	{
@@ -133,11 +131,10 @@
 
 		if (filenamecmp(realname, doc->real_path) == 0)
 		{
-			ret = i;
-			break;
+			return doc;
 		}
 	}
-	return ret;
+	return NULL;
 }
 
 
@@ -160,66 +157,64 @@
  *
  *  @param utf8_filename The filename to search (in UTF-8 encoding).
  *
- *  @return The %document index which has the given filename or @c -1
- *   if no document was found.
- *  @see document_find_by_realpath().
+ *  @return The matching document, or NULL.
+ *  @see document_find_by_real_path().
  **/
-gint document_find_by_filename(const gchar *utf8_filename)
+GeanyDocument *document_find_by_filename(const gchar *utf8_filename)
 {
 	guint i;
-	gint ret = -1;
+	GeanyDocument *doc;
+	gchar *realname;
 
 	if (! utf8_filename)
-		return -1;
+		return NULL;
 
 	/* 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];
+		doc = documents[i];
 
 		if (! documents[i]->is_valid || doc->file_name == NULL) continue;
 
 		if (filenamecmp(utf8_filename, doc->file_name) == 0)
 		{
-			ret = i;
-			break;
+			return doc;
 		}
 	}
-	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;
+	/* Now try matching based on the realpath(), which is unique per file on disk */
+	realname = get_real_path_from_utf8(utf8_filename);
+	doc = document_find_by_real_path(realname);
+	g_free(realname);
+	return doc;
 }
 
 
-/* returns the document index which has sci */
-gint document_find_by_sci(ScintillaObject *sci)
+/* returns the document which has sci, or NULL. */
+GeanyDocument *document_find_by_sci(ScintillaObject *sci)
 {
 	guint i;
 
-	if (! sci) return -1;
+	if (sci == NULL)
+		return NULL;
 
-	for(i = 0; i < documents_array->len; i++)
+	for (i = 0; i < documents_array->len; i++)
 	{
-		if (documents[i]->is_valid && documents[i]->sci == sci) return i;
+		if (documents[i]->is_valid && documents[i]->sci == sci)
+			return documents[i];
 	}
-	return -1;
+	return NULL;
 }
 
 
 /* returns the index of the notebook page from the document index */
-gint document_get_notebook_page(gint doc_idx)
+gint document_get_notebook_page(GeanyDocument *doc)
 {
-	if (! DOC_IDX_VALID(doc_idx)) return -1;
+	if (doc == NULL)
+		return -1;
 
 	return gtk_notebook_page_num(GTK_NOTEBOOK(main_widgets.notebook),
-		GTK_WIDGET(documents[doc_idx]->sci));
+		GTK_WIDGET(doc->sci));
 }
 
 
@@ -228,14 +223,15 @@
  *
  *  @param page_num The notebook page number to search.
  *
- *  @return The index of the given notebook page @a page_num in the %document list or @c -1
- *   if no documents are opened.
+ *  @return The corresponding document for the given notebook page, or NULL.
  **/
-gint document_get_n_idx(guint page_num)
+GeanyDocument *document_get_from_page(guint page_num)
 {
 	ScintillaObject *sci;
-	if (page_num >= documents_array->len) return -1;
 
+	if (page_num >= documents_array->len)
+		return NULL;
+
 	sci = (ScintillaObject*)gtk_notebook_get_nth_page(
 				GTK_NOTEBOOK(main_widgets.notebook), page_num);
 
@@ -244,17 +240,16 @@
 
 
 /**
- *  Find and retrieve the index of the current %document.
+ *  Find and retrieve the current %document.
  *
- *  @return The index of the current notebook page in the %document list or @c -1
- *   if no documents are opened.
+ *  @return A pointer to the current %document or @c NULL if there are no opened documents.
  **/
-gint document_get_cur_idx()
+GeanyDocument *document_get_current(void)
 {
 	gint cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(main_widgets.notebook));
 
 	if (cur_page == -1)
-		return -1;
+		return NULL;
 	else
 	{
 		ScintillaObject *sci = (ScintillaObject*)
@@ -265,19 +260,6 @@
 }
 
 
-/**
- *  Find and retrieve the current %document.
- *
- *  @return A pointer to the current %document or @c NULL if there are no opened documents.
- **/
-GeanyDocument *document_get_current()
-{
-	gint idx = document_get_cur_idx();
-
-	return DOC_IDX_VALID(idx) ? documents[idx] : NULL;
-}
-
-
 void document_init_doclist()
 {
 	documents_array = g_ptr_array_new();
@@ -295,27 +277,38 @@
  *  according to the document's save state.
  *  This is called by Geany mostly when opening or saving files.
  *
- *  @param idx The %document index to operate on.
+ * @param doc The document to use.
+ * @param changed Whether the document state should indicate changes have been made.
  **/
-void document_set_text_changed(gint idx)
+void document_set_text_changed(GeanyDocument *doc, gboolean changed)
 {
-	if (DOC_IDX_VALID(idx) && ! main_status.quitting)
+	if (doc == NULL)
+		return;
+
+	doc->changed = changed;
+
+	if (! main_status.quitting)
 	{
-		ui_update_tab_status(idx);
-		ui_save_buttons_toggle(documents[idx]->changed);
-		ui_set_window_title(idx);
-		ui_update_statusbar(idx, -1);
+		ui_update_tab_status(doc);
+		ui_save_buttons_toggle(changed);
+		ui_set_window_title(doc);
+		ui_update_statusbar(doc, -1);
 	}
 }
 
 
 /* Apply just the prefs that can change in the Preferences dialog */
-void document_apply_update_prefs(gint idx)
+void document_apply_update_prefs(GeanyDocument *doc)
 {
-	ScintillaObject *sci = documents[idx]->sci;
+	ScintillaObject *sci;
 
-	sci_set_mark_long_lines(sci, editor_prefs.long_line_type, editor_prefs.long_line_column, editor_prefs.long_line_color);
+	g_return_if_fail(doc != NULL);
 
+	sci = doc->sci;
+
+	sci_set_mark_long_lines(sci, editor_prefs.long_line_type,
+		editor_prefs.long_line_column, editor_prefs.long_line_color);
+
 	sci_set_tab_width(sci, editor_prefs.tab_width);
 
 	sci_set_autoc_max_height(sci, editor_prefs.symbolcompletion_max_height);
@@ -326,7 +319,7 @@
 
 	sci_set_folding_margin_visible(sci, editor_prefs.folding);
 
-	documents[idx]->auto_indent = (editor_prefs.indent_mode != INDENT_NONE);
+	doc->auto_indent = (editor_prefs.indent_mode != INDENT_NONE);
 
 	sci_assign_cmdkey(sci, SCK_HOME,
 		editor_prefs.smart_home_key ? SCI_VCHOMEWRAP : SCI_HOMEWRAP);
@@ -369,7 +362,7 @@
 }
 
 
-/* returns the next free place (i.e. index) in the document list,
+/* returns the next free place in the document list,
  * or -1 if the documents_array is full */
 static gint document_get_new_idx(void)
 {
@@ -417,12 +410,12 @@
 
 
 /* Create new editor (the scintilla widget) */
-static ScintillaObject *create_new_sci(gint new_idx)
+static ScintillaObject *create_new_sci(GeanyDocument *doc)
 {
 	ScintillaObject	*sci;
 
 	sci = SCINTILLA(scintilla_new());
-	scintilla_set_id(sci, new_idx);
+	scintilla_set_id(sci, doc->index);
 
 	gtk_widget_show(GTK_WIDGET(sci));
 
@@ -449,7 +442,7 @@
 					 G_CALLBACK(keybindings_got_event), GINT_TO_POINTER(new_idx));*/
 	/* signal for the popup menu */
 	g_signal_connect(G_OBJECT(sci), "button-press-event",
-					G_CALLBACK(on_editor_button_press_event), GINT_TO_POINTER(new_idx));
+					G_CALLBACK(on_editor_button_press_event), doc);
 	g_signal_connect(G_OBJECT(sci), "motion-notify-event", G_CALLBACK(on_motion_event), NULL);
 
 	return sci;
@@ -458,20 +451,20 @@
 
 /* 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)
+static GeanyDocument *document_create(const gchar *utf8_filename)
 {
 	PangoFontDescription *pfd;
 	gchar *fname;
+	GeanyDocument *this;
 	gint new_idx;
-	GeanyDocument *this;
-	gint tabnum;
 	gint cur_pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook));
 
 	if (cur_pages == 1)
 	{
-		gint idx = document_get_cur_idx();
+		GeanyDocument *doc = document_get_current();
 		/* remove the empty document and open a new one */
-		if (documents[idx]->file_name == NULL && ! documents[idx]->changed) document_remove(0);
+		if (doc != NULL && doc->file_name == NULL && ! doc->changed)
+			document_remove_page(0);
 	}
 
 	new_idx = document_get_new_idx();
@@ -484,22 +477,23 @@
 	}
 	this = documents[new_idx];
 	init_doc_struct(this);	/* initialize default document settings */
+	this->index = new_idx;
 
 	this->file_name = g_strdup(utf8_filename);
 
-	this->sci = create_new_sci(new_idx);
+	this->sci = create_new_sci(this);
 
-	document_apply_update_prefs(new_idx);
+	document_apply_update_prefs(this);
 
 	pfd = pango_font_description_from_string(interface_prefs.editor_font);
 	fname = g_strdup_printf("!%s", pango_font_description_get_family(pfd));
-	editor_set_font(new_idx, fname, pango_font_description_get_size(pfd) / PANGO_SCALE);
+	editor_set_font(this, fname, pango_font_description_get_size(pfd) / PANGO_SCALE);
 	pango_font_description_free(pfd);
 	g_free(fname);
 
-	treeviews_openfiles_add(new_idx);	/* sets this->iter */
+	treeviews_openfiles_add(this);	/* sets this->iter */
 
-	tabnum = notebook_new_tab(new_idx);
+	notebook_new_tab(this);
 

@@ Diff output truncated at 100000 characters. @@

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the Commits mailing list