[gedit/multiviews: 106/107] Merge branch 'master' into multiviews



commit 1e18b374e730153a122cf8da7abe2044a50ae7db
Merge: 3da1078 597b4bc
Author: Ignacio Casal Quinteiro <icq gnome org>
Date:   Mon Jan 4 17:25:14 2010 +0100

    Merge branch 'master' into multiviews
    
    Conflicts:
    	gedit/gedit-commands-file.c
    	gedit/gedit-document.h
    	gedit/gedit-tab.c
    	gedit/gedit-text-buffer.c
    	gedit/gedit-window.c
    	gedit/gedit.c

 Makefile.am                                        |    6 +-
 NEWS                                               |   40 +
 README                                             |    6 +-
 configure.ac                                       |   96 +-
 gedit/Makefile.am                                  |   38 +-
 gedit/gedit-app.c                                  |   32 +-
 gedit/gedit-commands-file.c                        |   56 +-
 gedit/gedit-dirs.c                                 |   83 +-
 gedit/gedit-document-interface.c                   |   34 +
 gedit/gedit-document-interface.h                   |   17 +
 gedit/gedit-document-loader.c                      |  144 +-
 gedit/gedit-document-loader.h                      |   21 +-
 gedit/gedit-document-saver.c                       |   41 +-
 gedit/gedit-document-saver.h                       |   13 +-
 gedit/gedit-gio-document-loader.c                  |  104 +-
 gedit/gedit-gio-document-saver.c                   |   70 +-
 gedit/gedit-help.c                                 |   15 +
 gedit/gedit-io-error-message-area.c                |  150 +-
 gedit/gedit-local-document-saver.c                 |   64 +-
 gedit/gedit-prefs-manager.h                        |   11 +
 gedit/gedit-text-buffer.c                          |  583 ++-
 gedit/gedit-ui.h                                   |   16 +-
 gedit/gedit-view-container.c                       |   71 +-
 gedit/gedit-window-private.h                       |   10 +
 gedit/gedit-window.c                               |  188 +-
 gedit/gedit.c                                      |   23 +-
 gedit/osx/Makefile.am                              |   23 +
 gedit/osx/gedit-osx-delegate.h                     |   16 +
 gedit/osx/gedit-osx-delegate.m                     |   84 +
 gedit/osx/gedit-osx.c                              |   94 +
 gedit/osx/gedit-osx.h                              |   17 +
 gedit/smclient/Makefile.am                         |    2 +-
 osx/Info.plist.in                                  |  260 ++
 osx/Makefile.am                                    |    3 +
 osx/dmg-data/background.png                        |  Bin 0 -> 31115 bytes
 osx/dmg-data/background.svg                        |  395 ++
 osx/gedit.bundle                                   |  110 +
 osx/gedit.icns                                     |  Bin 0 -> 175597 bytes
 osx/geditdoc.icns                                  |  Bin 0 -> 38861 bytes
 osx/gtkrc                                          |  429 ++
 osx/gtkrc.key.osx                                  |   55 +
 osx/launcher.sh                                    |   58 +
 osx/makebundle.sh                                  |   12 +
 osx/makedmg.sh                                     |   64 +
 osx/template.dmg                                   |  Bin 0 -> 19345408 bytes
 plugin-loaders/python/bindings/Makefile.am         |    1 +
 plugin-loaders/python/bindings/gedit.defs          |    6 +
 plugin-loaders/python/bindings/gedit.override      |    2 +-
 plugin-loaders/python/gedit-plugin-loader-python.c |   10 +-
 plugins/Makefile.am                                |    2 -
 plugins/checkupdate/gedit-check-update-plugin.c    |   24 +-
 plugins/externaltools/data/Makefile.am             |   52 +-
 .../data/open-terminal-here-osx.desktop.in         |    8 +
 .../data/open-terminal-here-osx.tool.in            |   16 +
 plugins/externaltools/tools/ElementTree.py         | 1254 -----
 plugins/externaltools/tools/Makefile.am            |    5 +-
 plugins/externaltools/tools/__init__.py            |   11 +-
 plugins/externaltools/tools/capture.py             |   14 +-
 plugins/externaltools/tools/filelookup.py          |  145 +
 plugins/externaltools/tools/functions.py           |   11 +-
 plugins/externaltools/tools/library.py             |   17 +-
 plugins/externaltools/tools/linkparsing.py         |  231 +
 plugins/externaltools/tools/linkparsing_test.py    |  177 +
 plugins/externaltools/tools/manager.py             |   22 +-
 plugins/externaltools/tools/outputpanel.py         |  156 +-
 plugins/filebrowser/gedit-file-browser-store.c     |   26 +-
 plugins/filebrowser/gedit-file-browser-view.c      |   14 +-
 plugins/filebrowser/gedit-file-browser-widget.c    |   16 +
 plugins/indent/Makefile.am                         |   34 -
 plugins/indent/gedit-indent-plugin.c               |  332 --
 plugins/indent/gedit-indent-plugin.h               |   75 -
 plugins/indent/indent.gedit-plugin.desktop.in      |    9 -
 plugins/quickopen/quickopen/windowhelper.py        |    2 +-
 plugins/snippets/data/c.xml                        |   34 +-
 plugins/snippets/data/chdr.xml                     |    8 +-
 plugins/snippets/data/html.xml                     |   69 +-
 plugins/snippets/data/lang/snippets.lang           |   32 +-
 plugins/snippets/data/xslt.xml                     |  143 +
 plugins/snippets/snippets/Document.py              |   40 +-
 plugins/snippets/snippets/ElementTree.py           | 1254 -----
 plugins/snippets/snippets/Exporter.py              |    2 +-
 plugins/snippets/snippets/Helper.py                |    6 +-
 plugins/snippets/snippets/Library.py               |    2 +-
 plugins/snippets/snippets/Makefile.am              |    1 -
 plugins/snippets/snippets/Placeholder.py           |    5 +-
 plugins/spell/Makefile.am                          |    2 +
 plugins/spell/gedit-automatic-spell-checker.c      |    9 +-
 plugins/spell/gedit-spell-checker-language.c       |    2 +-
 plugins/spell/gedit-spell-plugin.c                 |  241 +-
 plugins/spell/gedit-spell-utils.c                  |   40 +
 plugins/spell/gedit-spell-utils.h                  |   35 +
 po/LINGUAS                                         |    1 +
 po/POTFILES.in                                     |    3 +-
 po/POTFILES.skip                                   |    1 -
 po/cs.po                                           |  820 ++--
 po/el.po                                           | 2306 +++++------
 po/es.po                                           |  293 +-
 po/et.po                                           |  160 +-
 po/hu.po                                           |  527 +--
 po/nds.po                                          | 4800 ++++++++++++++++++++
 po/ro.po                                           | 1531 +++----
 po/sl.po                                           |  205 +-
 po/ta.po                                           |  269 +-
 po/zh_CN.po                                        |  302 +-
 win32/build-installer.sh                           |    2 -
 105 files changed, 12086 insertions(+), 7285 deletions(-)
---
diff --cc configure.ac
index 05ca39d,92fc4ad..b7a705f
--- a/configure.ac
+++ b/configure.ac
@@@ -247,13 -276,12 +276,13 @@@ dnl ===================================
  
  PKG_CHECK_MODULES(GEDIT, [
  	libxml-2.0 >= 2.5.0
- 	glib-2.0 >= 2.18.0
+ 	glib-2.0 >= 2.22.0
  	gthread-2.0 >= 2.13.0
- 	gio-2.0 >= 2.16.0
+ 	gio-2.0 >= 2.22.0
  	gtk+-2.0 >= 2.16.0
- 	gtksourceview-2.0 >= 2.4.0
+ 	gtksourceview-2.0 >= 2.8.0
  	gconf-2.0 >= 1.1.11
 +	webkit-1.0
  ])
  
  dnl FIXME: Remove this when removing gedit-message-area
diff --cc gedit/Makefile.am
index d2fafad,007dbf0..d30ad2d
--- a/gedit/Makefile.am
+++ b/gedit/Makefile.am
@@@ -102,14 -109,15 +111,18 @@@ INST_H_FILES =				
  	gedit-progress-message-area.h	\
  	gedit-statusbar.h		\
  	gedit-status-combo-box.h	\
 -	gedit-tab.h 			\
 +	gedit-view-container.h 		\
  	gedit-utils.h 			\
 -	gedit-view.h 			\
 +	gedit-view-interface.h 		\
 +	gedit-text-view.h		\
 +	gedit-text-buffer.h		\
 +	gedit-page.h			\
  	gedit-window.h
  
+ if OS_WIN32
+ INST_H_FILES += gedit-metadata-manager.h
+ endif
+ 
  headerdir = $(prefix)/include/gedit- GEDIT_API_VERSION@/gedit
  
  header_DATA = 				\
diff --cc gedit/gedit-commands-file.c
index 2cd30c2,b8f6de3..7b95433
--- a/gedit/gedit-commands-file.c
+++ b/gedit/gedit-commands-file.c
@@@ -52,16 -52,16 +52,16 @@@
  
  /* Defined constants */
  #define GEDIT_OPEN_DIALOG_KEY 		"gedit-open-dialog-key"
 -#define GEDIT_TAB_TO_SAVE_AS  		"gedit-tab-to-save-as"
 -#define GEDIT_LIST_OF_TABS_TO_SAVE_AS   "gedit-list-of-tabs-to-save-as"
 +#define GEDIT_PAGE_TO_SAVE_AS  		"gedit-page-to-save-as"
 +#define GEDIT_LIST_OF_PAGES_TO_SAVE_AS  "gedit-list-of-pages-to-save-as"
  #define GEDIT_IS_CLOSING_ALL            "gedit-is-closing-all"
  #define GEDIT_IS_QUITTING 	        "gedit-is-quitting"
 -#define GEDIT_IS_CLOSING_TAB		"gedit-is-closing-tab"
 +#define GEDIT_IS_CLOSING_PAGE		"gedit-is-closing-page"
- 
+ #define GEDIT_IS_QUITTING_ALL		"gedit-is-quitting-all"
  
 -static void tab_state_changed_while_saving (GeditTab    *tab,
 -					    GParamSpec  *pspec,
 -					    GeditWindow *window);
 +static void view_container_state_changed_while_saving (GeditViewContainer *container,
 +						       GParamSpec         *pspec,
 +						       GeditWindow        *window);
  
  void
  _gedit_cmd_file_new (GtkAction   *action,
@@@ -1753,8 -1710,13 +1759,12 @@@ _gedit_cmd_file_close_page (GeditPag
  			   GEDIT_IS_QUITTING,
  			   GBOOLEAN_TO_POINTER (FALSE));
  
+ 	g_object_set_data (G_OBJECT (window), 
+ 	                   GEDIT_IS_QUITTING_ALL, 
+ 	                   GINT_TO_POINTER (FALSE));
+ 
 -
 -	if (tab_can_close (tab, GTK_WINDOW (window)))
 -		gedit_window_close_tab (window, tab);
 +	if (page_can_close (page, GTK_WINDOW (window)))
 +		gedit_window_close_page (window, page);
  }
  
  void
@@@ -1765,11 -1727,18 +1775,17 @@@ _gedit_cmd_file_close (GtkAction   *act
  
  	gedit_debug (DEBUG_COMMANDS);
  
 -	active_tab = gedit_window_get_active_tab (window);
 -
 -	if (active_tab == NULL)
 +	active_page = gedit_window_get_active_page (window);
 +	if (active_page == NULL)
+ 	{
+ #ifdef OS_OSX
+ 		/* Close the window on OS X */
+ 		gtk_widget_destroy (GTK_WIDGET (window));
+ #endif
  		return;
+ 	}
  
 -	_gedit_cmd_file_close_tab (active_tab, window);
 +	_gedit_cmd_file_close_page (active_page, window);
  }
  
  /* Close all tabs */
@@@ -1861,9 -1827,39 +1877,39 @@@ _gedit_cmd_file_close_all (GtkAction   
  }
  
  /* Quit */
+ #ifdef OS_OSX
+ static void
+ quit_all ()
+ {
+ 	GList *windows;
+ 	GList *item;
+ 	GeditApp *app;
+ 
+ 	app = gedit_app_get_default ();
+ 	windows = g_list_copy ((GList *)gedit_app_get_windows (app));
+ 
+ 	for (item = windows; item; item = g_list_next (item))
+ 	{
+ 		GeditWindow *window = GEDIT_WINDOW (item->data);
+ 	
+ 		g_object_set_data (G_OBJECT (window),
+ 		                   GEDIT_IS_QUITTING_ALL,
+ 		                   GINT_TO_POINTER (TRUE));
+ 
+ 		if (!(gedit_window_get_state (window) &
+ 		                    (GEDIT_WINDOW_STATE_SAVING |
+ 		                     GEDIT_WINDOW_STATE_PRINTING |
+ 		                     GEDIT_WINDOW_STATE_SAVING_SESSION)))
+ 		{
+ 			file_close_all (window, TRUE);
+ 		}
+ 	}
+ }
+ #endif
+ 
  void
  _gedit_cmd_file_quit (GtkAction   *action,
 -		     GeditWindow *window)
 +		      GeditWindow *window)
  {
  	gedit_debug (DEBUG_COMMANDS);
  
diff --cc gedit/gedit-document-interface.c
index db487d9,0000000..f34eccf
mode 100644,000000..100644
--- a/gedit/gedit-document-interface.c
+++ b/gedit/gedit-document-interface.c
@@@ -1,734 -1,0 +1,768 @@@
 +/*
 + * gedit-document-interface.c
 + * This file is part of gedit
 + *
 + * Copyright (C) 2009 - Ignacio Casal Quinteiro
 + *
 + * gedit is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
 + * the Free Software Foundation; either version 2 of the License, or
 + * (at your option) any later version.
 + *
 + * gedit is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + * GNU General Public License for more details.
 + *
 + * You should have received a copy of the GNU General Public License
 + * along with gedit; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 + * Boston, MA  02110-1301  USA
 + */
 +
 +
 +#include "gedit-document-interface.h"
 +#include "gedit-marshal.h"
 +#include "gedit-enum-types.h"
 +#include "gedit-utils.h"
 +
 +enum {
 +	MODIFIED_CHANGED,
 +	LOAD,
 +	LOADING,
 +	LOADED,
 +	SAVE,
 +	SAVING,
 +	SAVED,
 +	LAST_SIGNAL
 +};
 +
 +static guint document_signals[LAST_SIGNAL] = { 0 };
 +
 +/* Default implementation */
 +
 +static GFile *
 +gedit_document_get_location_default (GeditDocument *doc)
 +{
 +	g_return_val_if_reached (NULL);
 +}
 +
 +static gchar *
 +gedit_document_get_uri_default (GeditDocument *doc)
 +{
 +	g_return_val_if_reached (NULL);
 +}
 +
 +static void
 +gedit_document_set_uri_default (GeditDocument *doc,
 +				const gchar   *uri)
 +{
 +	g_return_if_reached ();
 +}
 +
 +static gchar *
 +gedit_document_get_uri_for_display_default (GeditDocument *doc)
 +{
 +	g_return_val_if_reached (NULL);
 +}
 +
 +static gchar *
 +gedit_document_get_short_name_for_display_default (GeditDocument *doc)
 +{
 +	g_return_val_if_reached (NULL);
 +}
 +
 +static gchar *
 +gedit_document_get_content_type_default (GeditDocument *doc)
 +{
 +	g_return_val_if_reached (NULL);
 +}
 +
 +static gchar *
 +gedit_document_get_mime_type_default (GeditDocument *doc)
 +{
 +	g_return_val_if_reached (NULL);
 +}
 +
 +static gboolean
 +gedit_document_get_readonly_default (GeditDocument *doc)
 +{
 +	g_return_val_if_reached (FALSE);
 +}
 +
 +static gboolean
 +gedit_document_load_cancel_default (GeditDocument *doc)
 +{
 +	g_return_val_if_reached (FALSE);
 +}
 +
 +static gboolean
 +gedit_document_is_untouched_default (GeditDocument *doc)
 +{
 +	g_return_val_if_reached (FALSE);
 +}
 +
 +static gboolean
 +gedit_document_is_untitled_default (GeditDocument *doc)
 +{
 +	g_return_val_if_reached (FALSE);
 +}
 +
 +static gboolean
 +gedit_document_is_local_default (GeditDocument *doc)
 +{
 +	g_return_val_if_reached (FALSE);
 +}
 +
 +static gboolean
 +gedit_document_get_deleted_default (GeditDocument *doc)
 +{
 +	g_return_val_if_reached (FALSE);
 +}
 +
 +static gboolean
 +gedit_document_goto_line_default (GeditDocument *doc,
 +				  gint           line)
 +{
 +	g_return_val_if_reached (FALSE);
 +}
 +
 +static gboolean
 +gedit_document_goto_line_offset_default (GeditDocument *doc,
 +					 gint           line,
 +					 gint           line_offset)
 +{
 +	g_return_val_if_reached (FALSE);
 +}
 +
 +static const GeditEncoding *
 +gedit_document_get_encoding_default (GeditDocument *doc)
 +{
 +	g_return_val_if_reached (NULL);
 +}
 +
 +static glong
 +gedit_document_get_seconds_since_last_save_or_load_default (GeditDocument *doc)
 +{
 +	g_return_val_if_reached (0);
 +}
 +
 +static gboolean
 +gedit_document_check_externally_modified_default (GeditDocument *doc)
 +{
 +	g_return_val_if_reached (FALSE);
 +}
 +
 +static void
 +gedit_document_undo_default (GeditDocument *doc)
 +{
 +	g_return_if_reached ();
 +}
 +
 +static void
 +gedit_document_redo_default (GeditDocument *doc)
 +{
 +	g_return_if_reached ();
 +}
 +
 +static gboolean
 +gedit_document_can_undo_default (GeditDocument *doc)
 +{
 +	g_return_val_if_reached (FALSE);
 +}
 +
 +static gboolean
 +gedit_document_can_redo_default (GeditDocument *doc)
 +{
 +	g_return_val_if_reached (FALSE);
 +}
 +
 +static void
 +gedit_document_begin_not_undoable_action_default (GeditDocument *doc)
 +{
 +	g_return_if_reached ();
 +}
 +
 +static void
 +gedit_document_end_not_undoable_action_default (GeditDocument *doc)
 +{
 +	g_return_if_reached ();
 +}
 +
 +static void
 +gedit_document_set_text_default (GeditDocument *doc,
 +				 const gchar   *text,
 +				 gint           len)
 +{
 +	g_return_if_reached ();
 +}
 +
 +static void
 +gedit_document_set_modified_default (GeditDocument *doc,
 +				     gboolean       setting)
 +{
 +	g_return_if_reached ();
 +}
 +
 +static gboolean
 +gedit_document_get_modified_default (GeditDocument *doc)
 +{
 +	g_return_val_if_reached (FALSE);
 +}
 +
 +static gboolean
 +gedit_document_get_has_selection_default (GeditDocument *doc)
 +{
 +	g_return_val_if_reached (FALSE);
 +}
 +
++static gchar *
++gedit_document_get_metadata_default (GeditDocument *doc,
++				     const gchar   *key)
++{
++	g_return_val_if_reached (NULL);
++}
++
++void
++gedit_document_set_metadata_default (GeditDocument *doc,
++				     const gchar   *first_key,
++				     ...)
++{
++	g_return_if_reached ();
++}
++
 +static void 
 +gedit_document_init (GeditDocumentIface *iface)
 +{
 +	static gboolean initialized = FALSE;
 +	
 +	iface->get_location = gedit_document_get_location_default;
 +	iface->get_uri = gedit_document_get_uri_default;
 +	iface->set_uri = gedit_document_set_uri_default;
 +	iface->get_uri_for_display = gedit_document_get_uri_for_display_default;
 +	iface->get_short_name_for_display = gedit_document_get_short_name_for_display_default;
 +	iface->get_content_type = gedit_document_get_content_type_default;
 +	iface->get_mime_type = gedit_document_get_mime_type_default;
 +	iface->get_readonly = gedit_document_get_readonly_default;
 +	iface->load_cancel = gedit_document_load_cancel_default;
 +	iface->is_untouched = gedit_document_is_untouched_default;
 +	iface->is_untitled = gedit_document_is_untitled_default;
 +	iface->is_local = gedit_document_is_local_default;
 +	iface->get_deleted = gedit_document_get_deleted_default;
 +	iface->goto_line = gedit_document_goto_line_default;
 +	iface->goto_line_offset = gedit_document_goto_line_offset_default;
 +	iface->get_encoding = gedit_document_get_encoding_default;
 +	iface->get_seconds_since_last_save_or_load = gedit_document_get_seconds_since_last_save_or_load_default;
 +	iface->check_externally_modified = gedit_document_check_externally_modified_default;
 +	iface->undo = gedit_document_undo_default;
 +	iface->redo = gedit_document_redo_default;
 +	iface->can_undo = gedit_document_can_undo_default;
 +	iface->can_redo = gedit_document_can_redo_default;
 +	iface->begin_not_undoable_action = gedit_document_begin_not_undoable_action_default;
 +	iface->end_not_undoable_action = gedit_document_end_not_undoable_action_default;
 +	iface->set_text = gedit_document_set_text_default;
 +	iface->set_modified = gedit_document_set_modified_default;
 +	iface->get_modified = gedit_document_get_modified_default;
 +	iface->get_has_selection = gedit_document_get_has_selection_default;
++	iface->get_metadata = gedit_document_get_metadata_default;
++	iface->set_metadata = gedit_document_set_metadata_default;
 +	
 +	if (!initialized)
 +	{
 +		g_object_interface_install_property (iface,
 +						     g_param_spec_string ("uri",
 +									  "URI",
 +									  "The document's URI",
 +									  NULL,
 +									  G_PARAM_READABLE |
 +									  G_PARAM_STATIC_STRINGS));
 +
 +		g_object_interface_install_property (iface,
 +						     g_param_spec_string ("shortname",
 +									  "Short Name",
 +									  "The document's short name",
 +									  NULL,
 +									  G_PARAM_READABLE |
 +									  G_PARAM_STATIC_STRINGS));
 +
 +		g_object_interface_install_property (iface,
 +						     g_param_spec_string ("content-type",
 +									  "Content Type",
 +									  "The document's Content Type",
 +									  NULL,
 +									  G_PARAM_READABLE |
 +									  G_PARAM_STATIC_STRINGS));
 +
 +		g_object_interface_install_property (iface,
 +						     g_param_spec_boolean ("read-only",
 +									   "Read Only",
 +									   "Whether the document is read only or not",
 +									   FALSE,
 +									   G_PARAM_READABLE |
 +									   G_PARAM_STATIC_STRINGS));
 +	
 +		document_signals[MODIFIED_CHANGED] =
 +			g_signal_new ("modified-changed",
 +				      G_TYPE_FROM_INTERFACE (iface),
 +				      G_SIGNAL_RUN_LAST,
 +				      G_STRUCT_OFFSET (GeditDocumentIface, modified_changed),
 +				      NULL, NULL,
 +				      gedit_marshal_VOID__VOID,
 +				      G_TYPE_NONE,
 +				      0);
 +		
 +		/**
 +		 * GeditDocument::load:
 +		 * @document: the #GeditDocument.
 +		 * @uri: the uri where to load the document from.
 +		 * @encoding: the #GeditEncoding to encode the document.
 +		 * @line_pos: the line to show.
 +		 * @create: whether the document should be created if it doesn't exist.
 +		 *
 +		 * The "load" signal is emitted when a document is loaded.
 +		 */
 +		document_signals[LOAD] =
 +			g_signal_new ("load",
 +				      G_TYPE_FROM_INTERFACE (iface),
 +				      G_SIGNAL_RUN_LAST,
 +				      G_STRUCT_OFFSET (GeditDocumentIface, load),
 +				      NULL, NULL,
 +				      gedit_marshal_VOID__STRING_BOXED_INT_BOOLEAN,
 +				      G_TYPE_NONE,
 +				      4,
 +				      G_TYPE_STRING,
 +				      /* we rely on the fact that the GeditEncoding pointer stays
 +				       * the same forever */
 +				      GEDIT_TYPE_ENCODING | G_SIGNAL_TYPE_STATIC_SCOPE,
 +				      G_TYPE_INT,
 +				      G_TYPE_BOOLEAN);
 +
 +
 +		document_signals[LOADING] =
 +	   		g_signal_new ("loading",
 +				      G_TYPE_FROM_INTERFACE (iface),
 +				      G_SIGNAL_RUN_LAST,
 +				      G_STRUCT_OFFSET (GeditDocumentIface, loading),
 +				      NULL, NULL,
 +				      gedit_marshal_VOID__UINT64_UINT64,
 +				      G_TYPE_NONE,
 +				      2,
 +				      G_TYPE_UINT64,
 +				      G_TYPE_UINT64);
 +
 +		document_signals[LOADED] =
 +	   		g_signal_new ("loaded",
 +				      G_TYPE_FROM_INTERFACE (iface),
 +				      G_SIGNAL_RUN_LAST,
 +				      G_STRUCT_OFFSET (GeditDocumentIface, loaded),
 +				      NULL, NULL,
 +				      g_cclosure_marshal_VOID__POINTER,
 +				      G_TYPE_NONE,
 +				      1,
 +				      G_TYPE_POINTER);
 +
 +		/**
 +		 * GeditDocument::save:
 +		 * @document: the #GeditDocument.
 +		 * @uri: the uri where the document is about to be saved.
 +		 * @encoding: the #GeditEncoding used to save the document.
 +		 * @flags: the #GeditDocumentSaveFlags for the save operation.
 +		 *
 +		 * The "save" signal is emitted when the document is saved.
 +		 */
 +		document_signals[SAVE] =
 +			g_signal_new ("save",
 +				      G_TYPE_FROM_INTERFACE (iface),
 +				      G_SIGNAL_RUN_LAST,
 +				      G_STRUCT_OFFSET (GeditDocumentIface, save),
 +				      NULL, NULL,
 +				      gedit_marshal_VOID__STRING_BOXED_FLAGS,
 +				      G_TYPE_NONE,
 +				      3,
 +				      G_TYPE_STRING,
 +				      /* we rely on the fact that the GeditEncoding pointer stays
 +				       * the same forever */
 +				      GEDIT_TYPE_ENCODING | G_SIGNAL_TYPE_STATIC_SCOPE,
 +				      GEDIT_TYPE_DOCUMENT_SAVE_FLAGS);
 +
 +		document_signals[SAVING] =
 +			g_signal_new ("saving",
 +				      G_TYPE_FROM_INTERFACE (iface),
 +				      G_SIGNAL_RUN_LAST,
 +				      G_STRUCT_OFFSET (GeditDocumentIface, saving),
 +				      NULL, NULL,
 +				      gedit_marshal_VOID__UINT64_UINT64,
 +				      G_TYPE_NONE,
 +				      2,
 +				      G_TYPE_UINT64,
 +				      G_TYPE_UINT64);
 +
 +		document_signals[SAVED] =
 +			g_signal_new ("saved",
 +				      G_TYPE_FROM_INTERFACE (iface),
 +				      G_SIGNAL_RUN_LAST,
 +				      G_STRUCT_OFFSET (GeditDocumentIface, saved),
 +				      NULL, NULL,
 +				      g_cclosure_marshal_VOID__POINTER,
 +				      G_TYPE_NONE,
 +				      1,
 +				      G_TYPE_POINTER);
 +	
 +		initialized = TRUE;
 +	}
 +}
 +
 +GType 
 +gedit_document_get_type ()
 +{
 +	static GType gedit_document_type_id = 0;
 +	
 +	if (!gedit_document_type_id)
 +	{
 +		static const GTypeInfo g_define_type_info =
 +		{
 +			sizeof (GeditDocumentIface),
 +			(GBaseInitFunc) gedit_document_init, 
 +			NULL,
 +			NULL,
 +			NULL,
 +			NULL,
 +			0,
 +			0,
 +			NULL
 +		};
 +		
 +		gedit_document_type_id = 
 +			g_type_register_static (G_TYPE_INTERFACE,
 +						"GeditDocument",
 +						&g_define_type_info,
 +						0);
 +	
 +		g_type_interface_add_prerequisite (gedit_document_type_id,
 +						   G_TYPE_OBJECT);
 +	}
 +	
 +	return gedit_document_type_id;
 +}
 +
 +
 +GQuark
 +gedit_document_error_quark (void)
 +{
 +	static GQuark quark = 0;
 +
 +	if (G_UNLIKELY (quark == 0))
 +		quark = g_quark_from_static_string ("gedit_io_load_error");
 +
 +	return quark;
 +}
 +
 +GFile *
 +gedit_document_get_location (GeditDocument *doc)
 +{
 +	g_return_val_if_fail (GEDIT_DOCUMENT (doc), NULL);
 +	return GEDIT_DOCUMENT_GET_INTERFACE (doc)->get_location (doc);
 +}
 +
 +gchar *
 +gedit_document_get_uri (GeditDocument *doc)
 +{
 +	g_return_val_if_fail (GEDIT_DOCUMENT (doc), NULL);
 +	return GEDIT_DOCUMENT_GET_INTERFACE (doc)->get_uri (doc);
 +}
 +
 +void
 +gedit_document_set_uri (GeditDocument *doc,
 +			const gchar   *uri)
 +{
 +	g_return_if_fail (GEDIT_DOCUMENT (doc));
 +	GEDIT_DOCUMENT_GET_INTERFACE (doc)->set_uri (doc, uri);
 +}
 +
 +gchar *
 +gedit_document_get_uri_for_display (GeditDocument *doc)
 +{
 +	g_return_val_if_fail (GEDIT_DOCUMENT (doc), g_strdup (""));
 +	return GEDIT_DOCUMENT_GET_INTERFACE (doc)->get_uri_for_display (doc);
 +}
 +
 +gchar *
 +gedit_document_get_short_name_for_display (GeditDocument *doc)
 +{
 +	g_return_val_if_fail (GEDIT_DOCUMENT (doc), g_strdup (""));
 +	return GEDIT_DOCUMENT_GET_INTERFACE (doc)->get_short_name_for_display (doc);
 +}
 +
 +/* FIXME: Only gedit-text-buffer? */
 +gchar *
 +gedit_document_get_content_type (GeditDocument *doc)
 +{
 +	g_return_val_if_fail (GEDIT_DOCUMENT (doc), NULL);
 +	return GEDIT_DOCUMENT_GET_INTERFACE (doc)->get_content_type (doc);
 +}
 +
 +/* FIXME: Only gedit-text-buffer? */
 +gchar *
 +gedit_document_get_mime_type (GeditDocument *doc)
 +{
 +	g_return_val_if_fail (GEDIT_DOCUMENT (doc), g_strdup ("text/plain"));
 +	return GEDIT_DOCUMENT_GET_INTERFACE (doc)->get_mime_type (doc);
 +}
 +
 +gboolean
 +gedit_document_get_readonly (GeditDocument *doc)
 +{
 +	g_return_val_if_fail (GEDIT_DOCUMENT (doc), FALSE);
 +	return GEDIT_DOCUMENT_GET_INTERFACE (doc)->get_readonly (doc);
 +}
 +
 +/**
 + * gedit_document_load_document:
 + * @doc: the #GeditDocument.
 + * @uri: the uri where to load the document from.
 + * @encoding: the #GeditEncoding to encode the document.
 + * @line_pos: the line to show.
 + * @create: whether the document should be created if it doesn't exist.
 + *
 + * Load a document. This results in the "load" signal to be emitted.
 + */
 +void
 +gedit_document_load (GeditDocument       *doc,
 +		     const gchar         *uri,
 +		     const GeditEncoding *encoding,
 +		     gint                 line_pos,
 +		     gboolean             create)
 +{
 +	g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
 +	g_return_if_fail (uri != NULL);
 +	g_return_if_fail (gedit_utils_is_valid_uri (uri));
 +	
 +	g_signal_emit (doc, document_signals[LOAD], 0, uri, encoding, line_pos, create);
 +}
 +
 +/**
 + * gedit_document_load_cancel:
 + * @doc: the #GeditDocument.
 + *
 + * Cancel load of a document.
 + */
 +gboolean
 +gedit_document_load_cancel (GeditDocument *doc)
 +{
 +	g_return_val_if_fail (GEDIT_DOCUMENT (doc), FALSE);
 +	return GEDIT_DOCUMENT_GET_INTERFACE (doc)->load_cancel (doc);
 +}
 +
 +/**
 + * gedit_document_save:
 + * @doc: the #GeditDocument.
 + * @flags: optionnal #GeditDocumentSaveFlags.
 + *
 + * Save the document to its previous location. This results in the "save"
 + * signal to be emitted.
 + */
 +void
 +gedit_document_save (GeditDocument       *doc,
 +		     GeditDocumentSaveFlags flags)
 +{
 +	g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
 +	g_return_if_fail (gedit_document_get_uri (doc) != NULL);
 +
 +	g_signal_emit (doc,
 +		       document_signals[SAVE],
 +		       0,
 +		       gedit_document_get_uri (doc),
 +		       gedit_document_get_encoding (doc),
 +		       flags);
 +}
 +
 +/**
 + * gedit_document_save_as:
 + * @doc: the #GeditDocument.
 + * @uri: the uri where to save the document.
 + * @encoding: the #GeditEncoding to encode the document.
 + * @flags: optionnal #GeditDocumentSaveFlags.
 + *
 + * Save the document to a new location. This results in the "save" signal
 + * to be emitted.
 + */
 +void
 +gedit_document_save_as (GeditDocument       *doc,
 +			const gchar         *uri,
 +			const GeditEncoding *encoding,
 +			GeditDocumentSaveFlags flags)
 +{
 +	g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
 +	g_return_if_fail (uri != NULL);
 +	g_return_if_fail (encoding != NULL);
 +
 +	/* priv->mtime refers to the the old uri (if any). Thus, it should be
 +	 * ignored when saving as. */
 +	g_signal_emit (doc,
 +		       document_signals[SAVE],
 +		       0,
 +		       uri,
 +		       encoding,
 +		       flags | GEDIT_DOCUMENT_SAVE_IGNORE_MTIME);
 +}
 +
 +gboolean
 +gedit_document_is_untouched (GeditDocument *doc)
 +{
 +	g_return_val_if_fail (GEDIT_DOCUMENT (doc), FALSE);
 +	return GEDIT_DOCUMENT_GET_INTERFACE (doc)->is_untouched (doc);
 +}
 +
 +gboolean
 +gedit_document_is_untitled (GeditDocument *doc)
 +{
 +	g_return_val_if_fail (GEDIT_DOCUMENT (doc), FALSE);
 +	return GEDIT_DOCUMENT_GET_INTERFACE (doc)->is_untitled (doc);
 +}
 +
 +gboolean
 +gedit_document_is_local (GeditDocument *doc)
 +{
 +	g_return_val_if_fail (GEDIT_DOCUMENT (doc), FALSE);
 +	return GEDIT_DOCUMENT_GET_INTERFACE (doc)->is_local (doc);
 +}
 +
 +gboolean
 +gedit_document_get_deleted (GeditDocument *doc)
 +{
 +	g_return_val_if_fail (GEDIT_DOCUMENT (doc), FALSE);
 +	return GEDIT_DOCUMENT_GET_INTERFACE (doc)->get_deleted (doc);
 +}
 +
 +gboolean
 +gedit_document_goto_line (GeditDocument *doc,
 +			  gint           line)
 +{
 +	g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), FALSE);
 +	g_return_val_if_fail (line >= -1, FALSE);
 +	return GEDIT_DOCUMENT_GET_INTERFACE (doc)->goto_line (doc, line);
 +}
 +
 +gboolean
 +gedit_document_goto_line_offset (GeditDocument *doc,
 +				 gint           line,
 +				 gint           line_offset)
 +{
 +	g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), FALSE);
 +	g_return_val_if_fail (line >= -1, FALSE);
 +	g_return_val_if_fail (line_offset >= -1, FALSE);
 +	return GEDIT_DOCUMENT_GET_INTERFACE (doc)->goto_line_offset (doc, line,
 +								     line_offset);
 +}
 +
 +const GeditEncoding *
 +gedit_document_get_encoding (GeditDocument *doc)
 +{
 +	g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), NULL);
 +	return GEDIT_DOCUMENT_GET_INTERFACE (doc)->get_encoding (doc);
 +}
 +
 +glong
 +gedit_document_get_seconds_since_last_save_or_load (GeditDocument *doc)
 +{
 +	g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), -1);
 +	return GEDIT_DOCUMENT_GET_INTERFACE (doc)->get_seconds_since_last_save_or_load (doc);
 +}
 +
 +gboolean
 +gedit_document_check_externally_modified (GeditDocument *doc)
 +{
 +	g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), FALSE);
 +	return GEDIT_DOCUMENT_GET_INTERFACE (doc)->check_externally_modified (doc);
 +}
 +
 +void
 +gedit_document_undo (GeditDocument *doc)
 +{
 +	g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
 +	GEDIT_DOCUMENT_GET_INTERFACE (doc)->undo (doc);
 +}
 +
 +void
 +gedit_document_redo (GeditDocument *doc)
 +{
 +	g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
 +	GEDIT_DOCUMENT_GET_INTERFACE (doc)->redo (doc);
 +}
 +
 +gboolean
 +gedit_document_can_undo (GeditDocument *doc)
 +{
 +	g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), FALSE);
 +	return GEDIT_DOCUMENT_GET_INTERFACE (doc)->can_undo (doc);
 +}
 +
 +gboolean
 +gedit_document_can_redo (GeditDocument *doc)
 +{
 +	g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), FALSE);
 +	return GEDIT_DOCUMENT_GET_INTERFACE (doc)->can_redo (doc);
 +}
 +
 +void
 +gedit_document_begin_not_undoable_action (GeditDocument *doc)
 +{
 +	g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
 +	GEDIT_DOCUMENT_GET_INTERFACE (doc)->begin_not_undoable_action (doc);
 +}
 +
 +void
 +gedit_document_end_not_undoable_action (GeditDocument *doc)
 +{
 +	g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
 +	GEDIT_DOCUMENT_GET_INTERFACE (doc)->end_not_undoable_action (doc);
 +}
 +
 +void
 +gedit_document_set_text (GeditDocument *doc,
 +			 const gchar   *text,
 +			 gint           len)
 +{
 +	g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
 +	g_return_if_fail (text != NULL);
 +	GEDIT_DOCUMENT_GET_INTERFACE (doc)->set_text (doc, text, len);
 +}
 +
 +void
 +gedit_document_set_modified (GeditDocument *doc,
 +			     gboolean       setting)
 +{
 +	g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
 +	GEDIT_DOCUMENT_GET_INTERFACE (doc)->set_modified (doc, setting);
 +}
 +
 +gboolean
 +gedit_document_get_modified (GeditDocument *doc)
 +{
 +	g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), FALSE);
 +	return GEDIT_DOCUMENT_GET_INTERFACE (doc)->get_modified (doc);
 +}
 +
 +gboolean
 +gedit_document_get_has_selection (GeditDocument *doc)
 +{
 +	g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), FALSE);
 +	return GEDIT_DOCUMENT_GET_INTERFACE (doc)->get_has_selection (doc);
 +}
++
++gchar *
++gedit_document_get_metadata (GeditDocument *doc,
++			     const gchar   *key)
++{
++	g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), NULL);
++	return GEDIT_DOCUMENT_GET_INTERFACE (doc)->get_metadata (doc, key);
++}
++
++void
++gedit_document_set_metadata (GeditDocument *doc,
++			     const gchar   *first_key,
++			     ...)
++{
++	g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
++	GEDIT_DOCUMENT_GET_INTERFACE (doc)->set_metadata (doc, first_key, ...);
++}
diff --cc gedit/gedit-document-interface.h
index a07d139,e3016b8..dc5f47a
--- a/gedit/gedit-document-interface.h
+++ b/gedit/gedit-document-interface.h
@@@ -39,14 -41,26 +39,24 @@@
  
  G_BEGIN_DECLS
  
 -/*
 - * Type checking and casting macros
 - */
 -#define GEDIT_TYPE_DOCUMENT              (gedit_document_get_type())
 -#define GEDIT_DOCUMENT(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), GEDIT_TYPE_DOCUMENT, GeditDocument))
 -#define GEDIT_DOCUMENT_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), GEDIT_TYPE_DOCUMENT, GeditDocumentClass))
 -#define GEDIT_IS_DOCUMENT(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), GEDIT_TYPE_DOCUMENT))
 -#define GEDIT_IS_DOCUMENT_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GEDIT_TYPE_DOCUMENT))
 -#define GEDIT_DOCUMENT_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), GEDIT_TYPE_DOCUMENT, GeditDocumentClass))
 +#define GEDIT_TYPE_DOCUMENT			(gedit_document_get_type ())
 +#define GEDIT_DOCUMENT(obj)			(G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_DOCUMENT, GeditDocument))
 +#define GEDIT_IS_DOCUMENT(obj)			(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEDIT_TYPE_DOCUMENT))
 +#define GEDIT_DOCUMENT_GET_INTERFACE(obj)	(G_TYPE_INSTANCE_GET_INTERFACE ((obj), GEDIT_TYPE_DOCUMENT, GeditDocumentIface))
 +
 +typedef struct _GeditDocument		GeditDocument;
 +typedef struct _GeditDocumentIface	GeditDocumentIface;
  
+ #ifdef G_OS_WIN32
+ #define GEDIT_METADATA_ATTRIBUTE_POSITION "position"
+ #define GEDIT_METADATA_ATTRIBUTE_ENCODING "encoding"
+ #define GEDIT_METADATA_ATTRIBUTE_LANGUAGE "language"
+ #else
+ #define GEDIT_METADATA_ATTRIBUTE_POSITION "metadata::gedit-position"
+ #define GEDIT_METADATA_ATTRIBUTE_ENCODING "metadata::gedit-encoding"
+ #define GEDIT_METADATA_ATTRIBUTE_LANGUAGE "metadata::gedit-language"
+ #endif
+ 
  typedef enum
  {
  	GEDIT_SEARCH_DONT_SET_FLAGS	= 1 << 0, 
@@@ -231,43 -210,97 +241,50 @@@ gboolean	 gedit_document_get_deleted	(G
  gboolean	 gedit_document_goto_line 	(GeditDocument       *doc, 
  						 gint                 line);
  
 -gboolean	 gedit_document_goto_line_offset(GeditDocument *doc,
 -						 gint           line,
 -						 gint           line_offset);
 +gboolean	 gedit_document_goto_line_offset(GeditDocument       *doc,
 +						 gint                 line,
 +						 gint                 line_offset);
  
 -void		 gedit_document_set_search_text	(GeditDocument       *doc,
 -						 const gchar         *text,
 -						 guint                flags);
 -						 
 -gchar		*gedit_document_get_search_text	(GeditDocument       *doc,
 -						 guint               *flags);
 +const GeditEncoding 
 +		*gedit_document_get_encoding	(GeditDocument       *doc);
  
 -gboolean	 gedit_document_get_can_search_again
 +glong		 gedit_document_get_seconds_since_last_save_or_load 
  						(GeditDocument       *doc);
  
 -gboolean	 gedit_document_search_forward	(GeditDocument       *doc,
 -						 const GtkTextIter   *start,
 -						 const GtkTextIter   *end,
 -						 GtkTextIter         *match_start,
 -						 GtkTextIter         *match_end);
 -						 
 -gboolean	 gedit_document_search_backward	(GeditDocument       *doc,
 -						 const GtkTextIter   *start,
 -						 const GtkTextIter   *end,
 -						 GtkTextIter         *match_start,
 -						 GtkTextIter         *match_end);
 -
 -gint		 gedit_document_replace_all 	(GeditDocument       *doc,
 -				            	 const gchar         *find, 
 -						 const gchar         *replace, 
 -					    	 guint                flags);
 -
 -void 		 gedit_document_set_language 	(GeditDocument       *doc,
 -						 GtkSourceLanguage   *lang);
 -GtkSourceLanguage 
 -		*gedit_document_get_language 	(GeditDocument       *doc);
 +/* Note: this is a sync stat: use only on local files */
 +gboolean	 gedit_document_check_externally_modified
 +						(GeditDocument       *doc);
  
 -const GeditEncoding 
 -		*gedit_document_get_encoding	(GeditDocument       *doc);
  
 -void		 gedit_document_set_enable_search_highlighting 
 -						(GeditDocument       *doc,
 -						 gboolean             enable);
 +void		 gedit_document_undo		(GeditDocument       *doc);
 +void		 gedit_document_redo		(GeditDocument       *doc);
  
 -gboolean	 gedit_document_get_enable_search_highlighting
 +gboolean	 gedit_document_can_undo	(GeditDocument       *doc);
 +gboolean	 gedit_document_can_redo	(GeditDocument       *doc);
 +
 +void		 gedit_document_begin_not_undoable_action
 +						(GeditDocument       *doc);
 +void		 gedit_document_end_not_undoable_action
  						(GeditDocument       *doc);
  
 +void		 gedit_document_set_text	(GeditDocument       *doc,
 +						 const gchar         *text,
 +						 gint                 len);
 +
 +void		 gedit_document_set_modified	(GeditDocument       *doc,
 +						 gboolean             setting);
 +
 +gboolean	 gedit_document_get_modified	(GeditDocument       *doc);
 +
 +gboolean	 gedit_document_get_has_selection(GeditDocument      *doc);
 +
+ gchar		*gedit_document_get_metadata	(GeditDocument *doc,
+ 						 const gchar   *key);
+ 
+ void		 gedit_document_set_metadata	(GeditDocument *doc,
+ 						 const gchar   *first_key,
+ 						 ...);
+ 
 -/* 
 - * Non exported functions
 - */
 -glong		 _gedit_document_get_seconds_since_last_save_or_load 
 -						(GeditDocument       *doc);
 -
 -/* Note: this is a sync stat: use only on local files */
 -gboolean	_gedit_document_check_externally_modified
 -						(GeditDocument       *doc);
 -
 -void		_gedit_document_search_region   (GeditDocument       *doc,
 -						 const GtkTextIter   *start,
 -						 const GtkTextIter   *end);
 -						  
 -/* Search macros */
 -#define GEDIT_SEARCH_IS_DONT_SET_FLAGS(sflags) ((sflags & GEDIT_SEARCH_DONT_SET_FLAGS) != 0)
 -#define GEDIT_SEARCH_SET_DONT_SET_FLAGS(sflags,state) ((state == TRUE) ? \
 -(sflags |= GEDIT_SEARCH_DONT_SET_FLAGS) : (sflags &= ~GEDIT_SEARCH_DONT_SET_FLAGS))
 -
 -#define GEDIT_SEARCH_IS_ENTIRE_WORD(sflags) ((sflags & GEDIT_SEARCH_ENTIRE_WORD) != 0)
 -#define GEDIT_SEARCH_SET_ENTIRE_WORD(sflags,state) ((state == TRUE) ? \
 -(sflags |= GEDIT_SEARCH_ENTIRE_WORD) : (sflags &= ~GEDIT_SEARCH_ENTIRE_WORD))
 -
 -#define GEDIT_SEARCH_IS_CASE_SENSITIVE(sflags) ((sflags &  GEDIT_SEARCH_CASE_SENSITIVE) != 0)
 -#define GEDIT_SEARCH_SET_CASE_SENSITIVE(sflags,state) ((state == TRUE) ? \
 -(sflags |= GEDIT_SEARCH_CASE_SENSITIVE) : (sflags &= ~GEDIT_SEARCH_CASE_SENSITIVE))
 -
 -typedef GMountOperation *(*GeditMountOperationFactory)(GeditDocument *doc, 
 -						       gpointer       userdata);
 -
 -void		 _gedit_document_set_mount_operation_factory
 -						(GeditDocument	            *doc,
 -						 GeditMountOperationFactory  callback,
 -						 gpointer	             userdata);
 -GMountOperation
 -		*_gedit_document_create_mount_operation
 -						(GeditDocument	     *doc);
 -
  G_END_DECLS
  
  #endif /* __GEDIT_DOCUMENT_H__ */
diff --cc gedit/gedit-document-loader.c
index eab7db2,923eb6a..71a6622
--- a/gedit/gedit-document-loader.c
+++ b/gedit/gedit-document-loader.c
@@@ -203,13 -221,55 +221,55 @@@ insert_text_in_document (GeditDocumentL
  		len--;
  
  	/* Insert text in the buffer */
 -	gtk_text_buffer_set_text (GTK_TEXT_BUFFER (doc), text, len);
 +	gedit_document_set_text (doc, text, len);
  
 -	gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (doc), FALSE);
 +	gedit_document_set_modified (doc, FALSE);
  
 -	gtk_source_buffer_end_not_undoable_action (GTK_SOURCE_BUFFER (doc));
 +	gedit_document_end_not_undoable_action (doc);
  }
  
+ static const GeditEncoding *
+ get_metadata_encoding (GeditDocumentLoader *loader)
+ {
+ 	const GeditEncoding *enc = NULL;
+ 
+ #ifdef G_OS_WIN32
+ 	gchar *charset;
+ 	const gchar *uri;
+ 
+ 	uri = gedit_document_loader_get_uri (loader);
+ 
+ 	charset = gedit_metadata_manager_get (uri, "encoding");
+ 
+ 	if (charset == NULL)
+ 		return NULL;
+ 
+ 	enc = gedit_encoding_get_from_charset (charset);
+ 
+ 	g_free (charset);
+ #else
+ 	GFileInfo *info;
+ 
+ 	info = gedit_document_loader_get_info (loader);
+ 
+ 	/* check if the encoding was set in the metadata */
+ 	if (g_file_info_has_attribute (info, GEDIT_METADATA_ATTRIBUTE_ENCODING))
+ 	{
+ 		const gchar *charset;
+ 
+ 		charset = g_file_info_get_attribute_string (info,
+ 							    GEDIT_METADATA_ATTRIBUTE_ENCODING);
+ 
+ 		if (charset == NULL)
+ 			return NULL;
+ 		
+ 		enc = gedit_encoding_get_from_charset (charset);
+ 	}
+ #endif
+ 
+ 	return enc;
+ }
+ 
  /* This function is only meant to be called by child classes */
  gboolean
  gedit_document_loader_update_document_contents (GeditDocumentLoader  *loader,
diff --cc gedit/gedit-text-buffer.c
index 75f574e,6078101..ff11384
--- a/gedit/gedit-text-buffer.c
+++ b/gedit/gedit-text-buffer.c
@@@ -41,11 -41,9 +41,10 @@@
  #include <gtksourceview/gtksourceiter.h>
  
  #include "gedit-prefs-manager-app.h"
 -#include "gedit-document.h"
 +#include "gedit-document-interface.h"
 +#include "gedit-text-buffer.h"
  #include "gedit-debug.h"
  #include "gedit-utils.h"
- #include "gedit-metadata-manager.h"
  #include "gedit-language-manager.h"
  #include "gedit-style-scheme-manager.h"
  #include "gedit-document-loader.h"
@@@ -83,30 -87,22 +88,24 @@@ static void	gedit_text_buffer_save_rea
  						 const gchar            *uri,
  						 const GeditEncoding    *encoding,
  						 GeditDocumentSaveFlags  flags);
 -static void	gedit_document_set_readonly	(GeditDocument *doc,
 +static void	gedit_text_buffer_set_readonly	(GeditTextBuffer *doc,
  						 gboolean       readonly);
 -static void	to_search_region_range 		(GeditDocument *doc,
 -						 GtkTextIter   *start, 
 +static void	to_search_region_range 		(GeditTextBuffer *doc,
 +						 GtkTextIter     *start, 
  						 GtkTextIter   *end);
 -static void 	insert_text_cb		 	(GeditDocument *doc, 
 -						 GtkTextIter   *pos,
 -						 const gchar   *text, 
 +static void 	insert_text_cb		 	(GeditTextBuffer *doc, 
 +						 GtkTextIter     *pos,
 +						 const gchar     *text, 
  						 gint           length);
  						 
 -static void	delete_range_cb 		(GeditDocument *doc, 
 -						 GtkTextIter   *start,
 -						 GtkTextIter   *end);
 +static void	delete_range_cb 		(GeditTextBuffer *doc, 
 +						 GtkTextIter     *start,
 +						 GtkTextIter     *end);
  			     
 -struct _GeditDocumentPrivate
 +static void	gedit_text_buffer_iface_init	(GeditDocumentIface  *iface);
 +
 +struct _GeditTextBufferPrivate
  {
- 	gint	     readonly : 1;
- 	gint	     last_save_was_manually : 1;
- 	gint	     language_set_by_user : 1;
- 	gint         stop_cursor_moved_emission : 1;
- 	gint         dispose_has_run : 1;
- 
  	gchar	    *uri;
  	gint 	     untitled_number;
  
@@@ -135,10 -132,16 +135,16 @@@
  	/* Search highlighting support variables */
  	GeditTextRegion *to_search_region;
  	GtkTextTag      *found_tag;
- 	
+ 
  	/* Mount operation factory */
 -	GeditMountOperationFactory  mount_operation_factory;
 -	gpointer		    mount_operation_userdata;
 +	/*GeditMountOperationFactory  mount_operation_factory;
 +	gpointer		    mount_operation_userdata;*/
+ 
+ 	gint readonly : 1;
+ 	gint last_save_was_manually : 1; 
+ 	gint language_set_by_user : 1;
+ 	gint stop_cursor_moved_emission : 1;
+ 	gint dispose_has_run : 1;
  };
  
  enum {
@@@ -249,9 -272,15 +261,15 @@@ gedit_text_buffer_dispose (GObject *obj
  		doc->priv->loader = NULL;
  	}
  
+ 	if (doc->priv->metadata_info != NULL)
+ 	{
+ 		g_object_unref (doc->priv->metadata_info);
+ 		doc->priv->metadata_info = NULL;
+ 	}
+ 
  	doc->priv->dispose_has_run = TRUE;
  
 -	G_OBJECT_CLASS (gedit_document_parent_class)->dispose (object);
 +	G_OBJECT_CLASS (gedit_text_buffer_parent_class)->dispose (object);
  }
  
  static void
@@@ -845,254 -1096,10 +1063,256 @@@ gedit_text_buffer_check_externally_modi
  
  	g_file_info_get_modification_time (info, &timeval);
  	g_object_unref (info);
- 	
- 	return timeval.tv_sec > buf->priv->mtime;
++
++	return (timeval.tv_sec > buf->priv->mtime.tv_sec) ||
++	       (timeval.tv_sec == buf->priv->mtime.tv_sec &&
++	       timeval.tv_usec > buf->priv->mtime.tv_usec);
 +}
 +
 +static void
 +gedit_text_buffer_undo_impl (GeditDocument *doc)
 +{
 +	gtk_source_buffer_undo (GTK_SOURCE_BUFFER (doc));
 +}
 +
 +static void
 +gedit_text_buffer_redo_impl (GeditDocument *doc)
 +{
 +	gtk_source_buffer_redo (GTK_SOURCE_BUFFER (doc));
 +}
 +
 +static gboolean
 +gedit_text_buffer_can_undo_impl (GeditDocument *doc)
 +{
 +	return gtk_source_buffer_can_undo (GTK_SOURCE_BUFFER (doc));
 +}
 +
 +static gboolean
 +gedit_text_buffer_can_redo_impl (GeditDocument *doc)
 +{
 +	return gtk_source_buffer_can_redo (GTK_SOURCE_BUFFER (doc));
 +}
 +
 +static void
 +gedit_text_buffer_begin_not_undoable_action_impl (GeditDocument *doc)
 +{
 +	gtk_source_buffer_begin_not_undoable_action (GTK_SOURCE_BUFFER (doc));
 +}
 +
 +static void
 +gedit_text_buffer_end_not_undoable_action_impl (GeditDocument *doc)
 +{
 +	gtk_source_buffer_end_not_undoable_action (GTK_SOURCE_BUFFER (doc));
 +}
 +
 +static void
 +gedit_text_buffer_set_text_impl (GeditDocument *doc,
 +				 const gchar   *text,
 +				 gint           len)
 +{
 +	gtk_text_buffer_set_text (GTK_TEXT_BUFFER (doc), text, len);
 +}
 +
 +static void
 +gedit_text_buffer_set_modified_impl (GeditDocument *doc,
 +				     gboolean       setting)
 +{
 +	gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (doc), setting);
 +}
 +
 +static gboolean
 +gedit_text_buffer_get_modified_impl (GeditDocument *doc)
 +{
 +	return gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc));
 +}
 +
 +static gboolean
 +gedit_text_buffer_get_has_selection_impl (GeditDocument *doc)
 +{
 +	return gtk_text_buffer_get_has_selection (GTK_TEXT_BUFFER (doc));
 +}
 +
 +static void
 +gedit_text_buffer_iface_init (GeditDocumentIface  *iface)
 +{
 +	iface->get_location = gedit_text_buffer_get_location_impl;
 +	iface->get_uri = gedit_text_buffer_get_uri_impl;
 +	iface->set_uri = gedit_text_buffer_set_uri_impl;
 +	iface->get_uri_for_display = gedit_text_buffer_get_uri_for_display_impl;
 +	iface->get_short_name_for_display = gedit_text_buffer_get_short_name_for_display_impl;
 +	iface->get_content_type = gedit_text_buffer_get_content_type_impl;
 +	iface->get_mime_type = gedit_text_buffer_get_mime_type_impl;
 +	iface->get_readonly = gedit_text_buffer_get_readonly_impl;
 +	iface->load_cancel = gedit_text_buffer_load_cancel_impl;
 +	iface->is_untouched = gedit_text_buffer_is_untouched_impl;
 +	iface->is_untitled = gedit_text_buffer_is_untitled_impl;
 +	iface->is_local = gedit_text_buffer_is_local_impl;
 +	iface->get_deleted = gedit_text_buffer_get_deleted_impl;
 +	iface->goto_line = gedit_text_buffer_goto_line_impl;
 +	iface->goto_line_offset = gedit_text_buffer_goto_line_offset_impl;
 +	iface->get_encoding = gedit_text_buffer_get_encoding_impl;
 +	iface->get_seconds_since_last_save_or_load = gedit_text_buffer_get_seconds_since_last_save_or_load_impl;
 +	iface->check_externally_modified = gedit_text_buffer_check_externally_modified_impl;
 +	iface->undo = gedit_text_buffer_undo_impl;
 +	iface->redo = gedit_text_buffer_redo_impl;
 +	iface->can_undo = gedit_text_buffer_can_undo_impl;
 +	iface->can_redo = gedit_text_buffer_can_redo_impl;
 +	iface->begin_not_undoable_action = gedit_text_buffer_begin_not_undoable_action_impl;
 +	iface->end_not_undoable_action = gedit_text_buffer_end_not_undoable_action_impl;
 +	iface->set_text = gedit_text_buffer_set_text_impl;
 +	iface->set_modified = gedit_text_buffer_set_modified_impl;
 +	iface->get_modified = gedit_text_buffer_get_modified_impl;
 +	iface->get_has_selection = gedit_text_buffer_get_has_selection_impl;
 +	
 +	/* signals */
 +	iface->load = gedit_text_buffer_load_real;
 +	iface->save = gedit_text_buffer_save_real;
 +}
 +
 +static void
 +set_encoding (GeditTextBuffer     *doc, 
 +	      const GeditEncoding *encoding,
 +	      gboolean             set_by_user)
 +{
 +	g_return_if_fail (encoding != NULL);
 +
 +	gedit_debug (DEBUG_DOCUMENT);
 +
 +	if (doc->priv->encoding == encoding)
 +		return;
 +
 +	doc->priv->encoding = encoding;
 +
 +	if (set_by_user)
 +	{
 +		const gchar *charset;
 +
 +		charset = gedit_encoding_get_charset (encoding);
 +
 +		gedit_metadata_manager_set (doc->priv->uri,
 +					    "encoding",
 +					    charset);
 +	}
 +
 +	g_object_notify (G_OBJECT (doc), "encoding");
 +}
 +
 +static GtkSourceStyleScheme *
 +get_default_style_scheme (void)
 +{
 +	gchar *scheme_id;
 +	GtkSourceStyleScheme *def_style;
 +	GtkSourceStyleSchemeManager *manager;
 +
 +	manager = gedit_get_style_scheme_manager ();
 +	scheme_id = gedit_prefs_manager_get_source_style_scheme ();
 +	def_style = gtk_source_style_scheme_manager_get_scheme (manager,
 +								scheme_id);
 +
 +	if (def_style == NULL)
 +	{
 +		g_warning ("Default style scheme '%s' cannot be found, falling back to 'classic' style scheme ", scheme_id);
 +
 +		def_style = gtk_source_style_scheme_manager_get_scheme (manager, "classic");
 +		if (def_style == NULL) 
 +		{
 +			g_warning ("Style scheme 'classic' cannot be found, check your GtkSourceView installation.");
 +		}
 +	}
 +
 +	g_free (scheme_id);
 +
 +	return def_style;
 +}
 +
 +static void
 +gedit_text_buffer_init (GeditTextBuffer *doc)
 +{
 +	GtkSourceStyleScheme *style_scheme;
 +
 +	gedit_debug (DEBUG_DOCUMENT);
 +
 +	doc->priv = GEDIT_TEXT_BUFFER_GET_PRIVATE (doc);
 +
 +	doc->priv->uri = NULL;
 +	doc->priv->untitled_number = get_untitled_number ();
 +
 +	doc->priv->content_type = g_content_type_from_mime_type ("text/plain");
 +
 +	doc->priv->readonly = FALSE;
 +
 +	doc->priv->stop_cursor_moved_emission = FALSE;
 +
 +	doc->priv->last_save_was_manually = TRUE;
 +	doc->priv->language_set_by_user = FALSE;
 +
 +	doc->priv->dispose_has_run = FALSE;
 +
 +	doc->priv->mtime = 0;
 +
 +	g_get_current_time (&doc->priv->time_of_last_save_or_load);
 +
 +	doc->priv->encoding = gedit_encoding_get_utf8 ();
 +
 +	gtk_source_buffer_set_max_undo_levels (GTK_SOURCE_BUFFER (doc), 
 +					       gedit_prefs_manager_get_undo_actions_limit ());
 +
 +	gtk_source_buffer_set_highlight_matching_brackets (GTK_SOURCE_BUFFER (doc), 
 +							   gedit_prefs_manager_get_bracket_matching ());
 +
 +	gedit_text_buffer_set_enable_search_highlighting (doc,
 +						          gedit_prefs_manager_get_enable_search_highlighting ());
 +
 +	style_scheme = get_default_style_scheme ();
 +	if (style_scheme != NULL)
 +		gtk_source_buffer_set_style_scheme (GTK_SOURCE_BUFFER (doc),
 +						    style_scheme);
 +
 +	g_signal_connect_after (doc, 
 +			  	"insert-text",
 +			  	G_CALLBACK (insert_text_cb),
 +			  	NULL);
 +
 +	g_signal_connect_after (doc, 
 +			  	"delete-range",
 +			  	G_CALLBACK (delete_range_cb),
 +			  	NULL);		
 +}
 +
 +GeditDocument *
 +gedit_text_buffer_new (void)
 +{
 +	gedit_debug (DEBUG_DOCUMENT);
 +
 +	return GEDIT_DOCUMENT (g_object_new (GEDIT_TYPE_TEXT_BUFFER, NULL));
 +}
 +
 +/* Note: do not emit the notify::read-only signal */
 +static void
 +set_readonly (GeditTextBuffer *doc,
 +	      gboolean         readonly)
 +{
 +	gedit_debug (DEBUG_DOCUMENT);
  	
 -	return (timeval.tv_sec > doc->priv->mtime.tv_sec) ||
 -	       (timeval.tv_sec == doc->priv->mtime.tv_sec && 
 -	       timeval.tv_usec > doc->priv->mtime.tv_usec);
 +	readonly = (readonly != FALSE);
 +
 +	if (doc->priv->readonly == readonly) 
 +		return;
 +
 +	doc->priv->readonly = readonly;
 +}
 +
 +static void
 +gedit_text_buffer_set_readonly (GeditTextBuffer *doc,
 +				gboolean       readonly)
 +{
 +	gedit_debug (DEBUG_DOCUMENT);
 +
 +	g_return_if_fail (GEDIT_IS_TEXT_BUFFER (doc));
 +
 +	set_readonly (doc, readonly);
 +
 +	g_object_notify (G_OBJECT (doc), "read-only");
  }
  
  static void
@@@ -1209,16 -1232,23 +1443,22 @@@ document_loader_loading (GeditDocumentL
  	}
  	else
  	{
- 		goffset size;
+ 		goffset size = 0;
  		goffset read;
+ 		GFileInfo *info;
+ 
+ 		info = gedit_document_loader_get_info (loader);
+ 
+ 		if (info && g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SIZE))
+ 			size = g_file_info_get_attribute_uint64 (info,
+ 								 G_FILE_ATTRIBUTE_STANDARD_SIZE);
  
- 		size = gedit_document_loader_get_file_size (loader);
  		read = gedit_document_loader_get_bytes_read (loader);
  
 -		g_signal_emit (doc, 
 -			       document_signals[LOADING],
 -			       0,
 -			       read,
 -			       size);
 +		g_signal_emit_by_name (GEDIT_DOCUMENT (doc),
 +				       "loading",
 +				       read,
 +				       size);
  	}
  }
  
@@@ -1243,13 -1271,55 +1483,14 @@@ gedit_text_buffer_load_real (GeditDocum
  			  G_CALLBACK (document_loader_loading),
  			  doc);
  
 -	doc->priv->create = create;
 -	doc->priv->requested_encoding = encoding;
 -	doc->priv->requested_line_pos = line_pos;
 -
 -	set_uri (doc, uri);
 -	set_content_type (doc, NULL);
 +	buf->priv->create = create;
 +	buf->priv->requested_encoding = encoding;
 +	buf->priv->requested_line_pos = line_pos;
  
- 	set_uri (buf, uri, NULL);
 -	gedit_document_loader_load (doc->priv->loader);
 -}
 -
 -/**
 - * gedit_document_load:
 - * @doc: the #GeditDocument.
 - * @uri: the uri where to load the document from.
 - * @encoding: the #GeditEncoding to encode the document.
 - * @line_pos: the line to show.
 - * @create: whether the document should be created if it doesn't exist.
 - *
 - * Load a document. This results in the "load" signal to be emitted.
 - */
 -void
 -gedit_document_load (GeditDocument       *doc,
 -		     const gchar         *uri,
 -		     const GeditEncoding *encoding,
 -		     gint                 line_pos,
 -		     gboolean             create)
 -{
 -	g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
 -	g_return_if_fail (uri != NULL);
 -	g_return_if_fail (gedit_utils_is_valid_uri (uri));
++	set_uri (buf, uri);
++	set_content_type (buf, NULL);
  
 -	g_signal_emit (doc, document_signals[LOAD], 0, uri, encoding, line_pos, create);
 -}
 -
 -/**
 - * gedit_document_load_cancel:
 - * @doc: the #GeditDocument.
 - *
 - * Cancel load of a document.
 - */
 -gboolean
 -gedit_document_load_cancel (GeditDocument *doc)
 -{
 -	g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), FALSE);
 -
 -	if (doc->priv->loader == NULL)
 -		return FALSE;
 -
 -	return gedit_document_loader_cancel (doc->priv->loader);
 +	gedit_document_loader_load (buf->priv->loader);
  }
  
  static void
@@@ -2141,36 -2420,156 +2394,188 @@@ _gedit_text_buffer_create_mount_operati
  	else
  		return doc->priv->mount_operation_factory (doc, 
  						           doc->priv->mount_operation_userdata);
 +}*/
 +
 +void
 +gedit_text_buffer_get_cursor_position (GeditTextBuffer *buffer,
 +				       gint  tab_size,
 +				       gint *row,
 +				       gint *col)
 +{
 +	GtkTextIter iter;
 +	GtkTextIter start;
 +
 +	gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (buffer),
 +					  &iter,
 +					  gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (buffer)));
 +	
 +	*row = gtk_text_iter_get_line (&iter);
 +	
 +	start = iter;
 +	gtk_text_iter_set_line_offset (&start, 0);
 +	*col = 0;
 +
 +	while (!gtk_text_iter_equal (&start, &iter))
 +	{
 +		/* FIXME: Are we Unicode compliant here? */
 +		if (gtk_text_iter_get_char (&start) == '\t')
 +					
 +			*col += (tab_size - (*col  % tab_size));
 +		else
 +			++(*col);
 +
 +		gtk_text_iter_forward_char (&start);
 +	}
  }
+ 
+ #ifdef G_OS_WIN32
+ gchar *
+ gedit_document_get_metadata (GeditDocument *doc,
+ 			     const gchar   *key)
+ {
+ 	gchar *value = NULL;
+ 
+ 	g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), NULL);
+ 	g_return_val_if_fail (key != NULL, NULL);
+ 
+ 	if (doc->priv->uri != NULL)
+ 		value = gedit_metadata_manager_get (doc->priv->uri, key);
+ 
+ 	return value;
+ }
+ 
+ void
+ gedit_document_set_metadata (GeditDocument *doc,
+ 			     const gchar   *first_key,
+ 			     ...)
+ {
+ 	const gchar *key;
+ 	const gchar *value;
+ 	va_list var_args;
+ 
+ 	g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
+ 	g_return_if_fail (first_key != NULL);
+ 
+ 	va_start (var_args, first_key);
+ 
+ 	for (key = first_key; key; key = va_arg (var_args, const gchar *))
+ 	{
+ 		value = va_arg (var_args, const gchar *);
+ 		
+ 		gedit_metadata_manager_set (doc->priv->uri,
+ 					    key,
+ 					    value);
+ 	}
+ 
+ 	va_end (var_args);
+ }
+ 
+ #else
+ 
+ /**
+  * gedit_document_get_metadata:
+  * @doc: a #GeditDocument
+  * @key: name of the key
+  *
+  * Gets the metadata assigned to @key.
+  *
+  * Returns: the value assigned to @key.
+  */
+ gchar *
+ gedit_document_get_metadata (GeditDocument *doc,
+ 			     const gchar   *key)
+ {
+ 	gchar *value = NULL;
+ 
+ 	g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), NULL);
+ 	g_return_val_if_fail (key != NULL, NULL);
+ 
+ 	if (doc->priv->metadata_info && g_file_info_has_attribute (doc->priv->metadata_info,
+ 								   key))
+ 	{
+ 		value = g_strdup (g_file_info_get_attribute_string (doc->priv->metadata_info,
+ 								    key));
+ 	}
+ 
+ 	return value;
+ }
+ 
+ static void
+ set_attributes_cb (GObject      *source,
+ 		   GAsyncResult *res,
+ 		   gpointer      useless)
+ {
+ 	g_file_set_attributes_finish (G_FILE (source),
+ 				      res,
+ 				      NULL,
+ 				      NULL);
+ }
+ 
+ /**
+  * gedit_document_set_metadata:
+  * @doc: a #GeditDocument
+  * @first_key: name of the first key to set
+  * @...: value for the first key, followed optionally by more key/value pairs,
+  * followed by %NULL.
+  *
+  * Sets metadata on a document.
+  */
+ void
+ gedit_document_set_metadata (GeditDocument *doc,
+ 			     const gchar   *first_key,
+ 			     ...)
+ {
+ 	const gchar *key;
+ 	const gchar *value;
+ 	va_list var_args;
+ 	GFileInfo *info;
+ 	GFile *location;
+ 
+ 	g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
+ 	g_return_if_fail (first_key != NULL);
+ 
+ 	info = g_file_info_new ();
+ 
+ 	va_start (var_args, first_key);
+ 
+ 	for (key = first_key; key; key = va_arg (var_args, const gchar *))
+ 	{
+ 		value = va_arg (var_args, const gchar *);
+ 		
+ 		if (value != NULL)
+ 		{
+ 			g_file_info_set_attribute_string (info,
+ 							  key, value);
+ 		}
+ 		else
+ 		{
+ 			/* Unset the key */
+ 			g_file_info_set_attribute (info, key,
+ 						   G_FILE_ATTRIBUTE_TYPE_INVALID,
+ 						   NULL);
+ 		}
+ 	}
+ 
+ 	va_end (var_args);
+ 
+ 	if (doc->priv->metadata_info != NULL)
+ 		g_file_info_copy_into (info, doc->priv->metadata_info);
+ 
+ 	location = gedit_document_get_location (doc);
+ 
+ 	if (location != NULL)
+ 	{
+ 		g_file_set_attributes_async (location,
+ 					     info,
+ 					     G_FILE_QUERY_INFO_NONE,
+ 					     G_PRIORITY_DEFAULT,
+ 					     NULL,
+ 					     set_attributes_cb,
+ 					     NULL);
+ 
+ 		g_object_unref (location);
+ 	}
+ 	
+ 	g_object_unref (info);
+ }
+ #endif
diff --cc gedit/gedit-view-container.c
index a1b4352,0000000..3a1f518
mode 100644,000000..100644
--- a/gedit/gedit-view-container.c
+++ b/gedit/gedit-view-container.c
@@@ -1,3049 -1,0 +1,3060 @@@
 +/*
 + * gedit-view-container.c
 + * This file is part of gedit
 + *
 + * Copyright (C) 2005 - Paolo Maggi 
 + *
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
 + * the Free Software Foundation; either version 2 of the License, or
 + * (at your option) any later version.
 + *
 + * This program is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + * GNU General Public License for more details.
 + *
 + * You should have received a copy of the GNU General Public License
 + * along with this program; if not, write to the Free Software
 + * Foundation, Inc., 59 Temple Place, Suite 330, 
 + * Boston, MA 02111-1307, USA.
 + */
 + 
 +/*
 + * Modified by the gedit Team, 2005. See the AUTHORS file for a 
 + * list of people on the gedit Team.  
 + * See the ChangeLog files for a list of changes. 
 + */
 +
 +#ifdef HAVE_CONFIG_H
 +#include <config.h>
 +#endif
 +
 +#include <glib/gi18n.h>
 +#include <gio/gio.h>
 +
 +#include "gedit-app.h"
 +#include "gedit-notebook.h"
 +#include "gedit-view-container.h"
 +#include "gedit-utils.h"
 +#include "gedit-io-error-message-area.h"
 +#include "gedit-print-job.h"
 +#include "gedit-print-preview.h"
 +#include "gedit-progress-message-area.h"
 +#include "gedit-debug.h"
 +#include "gedit-prefs-manager-app.h"
 +#include "gedit-convert.h"
 +#include "gedit-enum-types.h"
 +#include "gedit-text-view.h"
 +#include "gedit-web-view.h"
 +
 +#if !GTK_CHECK_VERSION (2, 17, 1)
 +#include "gedit-message-area.h"
 +#endif
 +
 +#define GEDIT_VIEW_CONTAINER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), GEDIT_TYPE_VIEW_CONTAINER,\
 +						 GeditViewContainerPrivate))
 +
 +#define GEDIT_VIEW_CONTAINER_KEY "GEDIT_VIEW_CONTAINER_KEY"
 +
 +struct _GeditViewContainerPrivate
 +{
 +	GeditViewContainerState state;
 +	GeditViewContainerMode  mode;
 +	
 +	GeditDocument	       *doc;
 +	
 +	GtkWidget	       *notebook;
 +	GList		       *views;
 +	GtkWidget	       *active_view;
 +	GtkWidget	       *active_view_scrolled_window;
 +
 +	GtkWidget	       *message_area;
 +	GtkWidget	       *print_preview;
 +
 +	GeditPrintJob          *print_job;
 +
 +	/* tmp data for saving */
 +	gchar		       *tmp_save_uri;
 +
 +	/* tmp data for loading */
 +	gint                    tmp_line_pos;
 +	const GeditEncoding    *tmp_encoding;
 +	
 +	GTimer 		       *timer;
 +	guint		        times_called;
 +
 +	GeditDocumentSaveFlags	save_flags;
 +
 +	gint                    auto_save_interval;
 +	guint                   auto_save_timeout;
 +
 +	gint	                not_editable : 1;
 +	gint                    auto_save : 1;
 +
 +	gint                    ask_if_externally_modified : 1;
 +};
 +
 +/* Signals */
 +enum
 +{
 +	VIEW_ADDED,
 +	VIEW_REMOVED,
 +	ACTIVE_VIEW_CHANGED,
 +	LAST_SIGNAL
 +};
 +
 +static guint signals[LAST_SIGNAL] = { 0 };
 +
 +G_DEFINE_TYPE(GeditViewContainer, gedit_view_container, GTK_TYPE_VBOX)
 +
 +enum
 +{
 +	PROP_0,
 +	PROP_DOCUMENT,
 +	PROP_MODE,
 +	PROP_NAME,
 +	PROP_STATE,
 +	PROP_AUTO_SAVE,
 +	PROP_AUTO_SAVE_INTERVAL
 +};
 +
 +static gboolean gedit_view_container_auto_save (GeditViewContainer *container);
 +
 +static void
 +install_auto_save_timeout (GeditViewContainer *container)
 +{
 +	gint timeout;
 +
 +	gedit_debug (DEBUG_VIEW_CONTAINER);
 +
 +	g_return_if_fail (container->priv->auto_save_timeout <= 0);
 +	g_return_if_fail (container->priv->auto_save);
 +	g_return_if_fail (container->priv->auto_save_interval > 0);
 +	
 +	g_return_if_fail (container->priv->state != GEDIT_VIEW_CONTAINER_STATE_LOADING);
 +	g_return_if_fail (container->priv->state != GEDIT_VIEW_CONTAINER_STATE_SAVING);
 +	g_return_if_fail (container->priv->state != GEDIT_VIEW_CONTAINER_STATE_REVERTING);
 +	g_return_if_fail (container->priv->state != GEDIT_VIEW_CONTAINER_STATE_LOADING_ERROR);
 +	g_return_if_fail (container->priv->state != GEDIT_VIEW_CONTAINER_STATE_SAVING_ERROR);
 +	g_return_if_fail (container->priv->state != GEDIT_VIEW_CONTAINER_STATE_SAVING_ERROR);
 +	g_return_if_fail (container->priv->state != GEDIT_VIEW_CONTAINER_STATE_REVERTING_ERROR);
 +
 +	/* Add a new timeout */
 +	timeout = g_timeout_add_seconds (container->priv->auto_save_interval * 60,
 +					 (GSourceFunc) gedit_view_container_auto_save,
 +					 container);
 +
 +	container->priv->auto_save_timeout = timeout;
 +}
 +
 +static gboolean
 +install_auto_save_timeout_if_needed (GeditViewContainer *container)
 +{
 +	GeditDocument *doc;
 +
 +	gedit_debug (DEBUG_VIEW_CONTAINER);
 +	
 +	g_return_val_if_fail (container->priv->auto_save_timeout <= 0, FALSE);
 +	g_return_val_if_fail ((container->priv->state == GEDIT_VIEW_CONTAINER_STATE_NORMAL) ||
 +			      (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_SHOWING_PRINT_PREVIEW) ||
 +			      (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_CLOSING), FALSE);
 +
 +	if (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_CLOSING)
 +		return FALSE;
 +
 +	doc = gedit_view_container_get_document (container);
 +
 + 	if (container->priv->auto_save && 
 + 	    !gedit_document_is_untitled (doc) &&
 + 	    !gedit_document_get_readonly (doc))
 + 	{ 
 + 		install_auto_save_timeout (container);
 + 		
 + 		return TRUE;
 + 	}
 + 	
 + 	return FALSE;
 +}
 +
 +static void
 +remove_auto_save_timeout (GeditViewContainer *container)
 +{
 +	gedit_debug (DEBUG_VIEW_CONTAINER);
 +
 +	/* FIXME: check sugli stati */
 +	
 +	g_return_if_fail (container->priv->auto_save_timeout > 0);
 +	
 +	g_source_remove (container->priv->auto_save_timeout);
 +	container->priv->auto_save_timeout = 0;
 +}
 +
 +static void
 +gedit_view_container_get_property (GObject    *object,
 +				   guint       prop_id,
 +				   GValue     *value,
 +				   GParamSpec *pspec)
 +{
 +	GeditViewContainer *container = GEDIT_VIEW_CONTAINER (object);
 +
 +	switch (prop_id)
 +	{
 +		case PROP_DOCUMENT:
 +			g_value_take_object (value,
 +					     gedit_view_container_get_document (container));
 +			break;
 +		case PROP_MODE:
 +			g_value_set_enum (value,
 +					  gedit_view_container_get_mode (container));
 +			break;
 +		case PROP_NAME:
 +			g_value_take_string (value,
 +					     _gedit_view_container_get_name (container));
 +			break;
 +		case PROP_STATE:
 +			g_value_set_enum (value,
 +					  gedit_view_container_get_state (container));
 +			break;
 +		case PROP_AUTO_SAVE:
 +			g_value_set_boolean (value,
 +					     gedit_view_container_get_auto_save_enabled (container));
 +			break;
 +		case PROP_AUTO_SAVE_INTERVAL:
 +			g_value_set_int (value,
 +					 gedit_view_container_get_auto_save_interval (container));
 +			break;
 +		default:
 +			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 +			break;
 +	}
 +}
 +
 +static void
 +gedit_view_container_set_property (GObject      *object,
 +				   guint         prop_id,
 +				   const GValue *value,
 +				   GParamSpec   *pspec)
 +{
 +	GeditViewContainer *container = GEDIT_VIEW_CONTAINER (object);
 +
 +	switch (prop_id)
 +	{
 +		case PROP_AUTO_SAVE:
 +			gedit_view_container_set_auto_save_enabled (container,
 +								    g_value_get_boolean (value));
 +			break;
 +		case PROP_AUTO_SAVE_INTERVAL:
 +			gedit_view_container_set_auto_save_interval (container,
 +								     g_value_get_int (value));
 +			break;
 +		default:
 +			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 +			break;
 +	}
 +}
 +
 +static void
 +gedit_view_container_finalize (GObject *object)
 +{
 +	GeditViewContainer *container = GEDIT_VIEW_CONTAINER (object);
 +
 +	if (container->priv->timer != NULL)
 +		g_timer_destroy (container->priv->timer);
 +
 +	g_free (container->priv->tmp_save_uri);
 +
 +	if (container->priv->auto_save_timeout > 0)
 +		remove_auto_save_timeout (container);
 +
 +	g_list_free (container->priv->views);
 +
 +	G_OBJECT_CLASS (gedit_view_container_parent_class)->finalize (object);
 +}
 +
 +static void 
 +gedit_view_container_class_init (GeditViewContainerClass *klass)
 +{
 +	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 +
 +	object_class->finalize = gedit_view_container_finalize;
 +	object_class->get_property = gedit_view_container_get_property;
 +	object_class->set_property = gedit_view_container_set_property;
 +	
 +	g_object_class_install_property (object_class,
 +					 PROP_DOCUMENT,
 +					 g_param_spec_object ("document",
 +							      "Document",
 +							      "The container's document",
 +							      GEDIT_TYPE_DOCUMENT,
 +							      G_PARAM_READABLE));
 +	
 +	g_object_class_install_property (object_class,
 +					 PROP_MODE,
 +					 g_param_spec_enum ("mode",
 +							    "Mode",
 +							    "The container's mode",
 +							    GEDIT_TYPE_VIEW_CONTAINER_MODE,
 +							    GEDIT_VIEW_CONTAINER_MODE_TEXT,
 +							    G_PARAM_READABLE |
 +							    G_PARAM_STATIC_STRINGS));
 +	
 +	g_object_class_install_property (object_class,
 +					 PROP_NAME,
 +					 g_param_spec_string ("name",
 +							      "Name",
 +							      "The container's name",
 +							      NULL,
 +							      G_PARAM_READABLE |
 +							      G_PARAM_STATIC_STRINGS));
 +
 +	g_object_class_install_property (object_class,
 +					 PROP_STATE,
 +					 g_param_spec_enum ("state",
 +							    "State",
 +							    "The container's state",
 +							    GEDIT_TYPE_VIEW_CONTAINER_STATE,
 +							    GEDIT_VIEW_CONTAINER_STATE_NORMAL,
 +							    G_PARAM_READABLE |
 +							    G_PARAM_STATIC_STRINGS));
 +
 +	g_object_class_install_property (object_class,
 +					 PROP_AUTO_SAVE,
 +					 g_param_spec_boolean ("autosave",
 +							       "Autosave",
 +							       "Autosave feature",
 +							       TRUE,
 +							       G_PARAM_READWRITE |
 +							       G_PARAM_STATIC_STRINGS));
 +
 +	g_object_class_install_property (object_class,
 +					 PROP_AUTO_SAVE_INTERVAL,
 +					 g_param_spec_int ("autosave-interval",
 +							   "AutosaveInterval",
 +							   "Time between two autosaves",
 +							   0,
 +							   G_MAXINT,
 +							   0,
 +							   G_PARAM_READWRITE |
 +							   G_PARAM_STATIC_STRINGS));
 +
 +	signals[VIEW_ADDED] =
 +		g_signal_new ("view-added",
 +			      G_OBJECT_CLASS_TYPE (object_class),
 +			      G_SIGNAL_RUN_FIRST,
 +			      G_STRUCT_OFFSET (GeditViewContainerClass, view_added),
 +			      NULL, NULL,
 +			      g_cclosure_marshal_VOID__OBJECT,
 +			      G_TYPE_NONE,
 +			      1,
 +			      GEDIT_TYPE_VIEW);
 +
 +	signals[VIEW_ADDED] =
 +		g_signal_new ("view-removed",
 +			      G_OBJECT_CLASS_TYPE (object_class),
 +			      G_SIGNAL_RUN_FIRST,
 +			      G_STRUCT_OFFSET (GeditViewContainerClass, view_removed),
 +			      NULL, NULL,
 +			      g_cclosure_marshal_VOID__OBJECT,
 +			      G_TYPE_NONE,
 +			      1,
 +			      GEDIT_TYPE_VIEW);
 +
 +	signals[ACTIVE_VIEW_CHANGED] =
 +		g_signal_new ("active-view-changed",
 +			      G_OBJECT_CLASS_TYPE (object_class),
 +			      G_SIGNAL_RUN_FIRST,
 +			      G_STRUCT_OFFSET (GeditViewContainerClass, active_view_changed),
 +			      NULL, NULL,
 +			      g_cclosure_marshal_VOID__OBJECT,
 +			      G_TYPE_NONE,
 +			      1,
 +			      GEDIT_TYPE_VIEW);
 +
 +	g_type_class_add_private (object_class, sizeof (GeditViewContainerPrivate));
 +}
 +
 +/**
 + * gedit_view_container_get_state:
 + * @container: a #GeditViewContainer
 + *
 + * Gets the #GeditViewContainerState of @container.
 + *
 + * Returns: the #GeditViewContainerState of @container
 + */
 +GeditViewContainerState
 +gedit_view_container_get_state (GeditViewContainer *container)
 +{
 +	g_return_val_if_fail (GEDIT_IS_VIEW_CONTAINER (container), GEDIT_VIEW_CONTAINER_STATE_NORMAL);
 +	
 +	return container->priv->state;
 +}
 +
 +GeditViewContainerMode
 +gedit_view_container_get_mode (GeditViewContainer *container)
 +{
 +	g_return_val_if_fail (GEDIT_IS_VIEW_CONTAINER (container), GEDIT_VIEW_CONTAINER_MODE_TEXT);
 +	
 +	return container->priv->mode;
 +}
 +
 +static void
 +set_cursor_according_to_state (GtkTextView   *view,
 +			       GeditViewContainerState  state)
 +{
 +	GdkCursor *cursor;
 +	GdkWindow *text_window;
 +	GdkWindow *left_window;
 +
 +	text_window = gtk_text_view_get_window (view, GTK_TEXT_WINDOW_TEXT);
 +	left_window = gtk_text_view_get_window (view, GTK_TEXT_WINDOW_LEFT);
 +
 +	if ((state == GEDIT_VIEW_CONTAINER_STATE_LOADING)          ||
 +	    (state == GEDIT_VIEW_CONTAINER_STATE_REVERTING)        ||
 +	    (state == GEDIT_VIEW_CONTAINER_STATE_SAVING)           ||
 +	    (state == GEDIT_VIEW_CONTAINER_STATE_PRINTING)         ||
 +	    (state == GEDIT_VIEW_CONTAINER_STATE_PRINT_PREVIEWING) ||
 +	    (state == GEDIT_VIEW_CONTAINER_STATE_CLOSING))
 +	{
 +		cursor = gdk_cursor_new_for_display (
 +				gtk_widget_get_display (GTK_WIDGET (view)),
 +				GDK_WATCH);
 +
 +		if (text_window != NULL)
 +			gdk_window_set_cursor (text_window, cursor);
 +		if (left_window != NULL)
 +			gdk_window_set_cursor (left_window, cursor);
 +
 +		gdk_cursor_unref (cursor);
 +	}
 +	else
 +	{
 +		cursor = gdk_cursor_new_for_display (
 +				gtk_widget_get_display (GTK_WIDGET (view)),
 +				GDK_XTERM);
 +
 +		if (text_window != NULL)
 +			gdk_window_set_cursor (text_window, cursor);
 +		if (left_window != NULL)
 +			gdk_window_set_cursor (left_window, NULL);
 +
 +		gdk_cursor_unref (cursor);
 +	}
 +}
 +
 +static void
 +view_realized (GtkWidget *view,
 +	       GeditViewContainer  *container)
 +{
 +	/* FIXME: Maybe we should take care of all views? */
 +	if (GTK_IS_TEXT_VIEW (view))
 +		set_cursor_according_to_state (GTK_TEXT_VIEW (view), container->priv->state);
 +}
 +
 +static void
 +set_view_properties_according_to_state (GeditViewContainer      *container,
 +					GeditViewContainerState  state)
 +{
 +	gboolean val;
 +
 +	val = ((state == GEDIT_VIEW_CONTAINER_STATE_NORMAL) &&
 +	       (container->priv->print_preview == NULL) &&
 +	       !container->priv->not_editable);
 +	gedit_view_set_editable (GEDIT_VIEW (container->priv->active_view), val);
 +
 +	if (GEDIT_IS_TEXT_VIEW (GEDIT_TEXT_VIEW (container->priv->active_view)))
 +	{
 +		val = ((state != GEDIT_VIEW_CONTAINER_STATE_LOADING) &&
 +		       (state != GEDIT_VIEW_CONTAINER_STATE_CLOSING));
 +		gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (container->priv->active_view), val);
 +
 +
 +		val = ((state != GEDIT_VIEW_CONTAINER_STATE_LOADING) &&
 +		       (state != GEDIT_VIEW_CONTAINER_STATE_CLOSING) &&
 +		       (gedit_prefs_manager_get_highlight_current_line ()));
 +		gtk_source_view_set_highlight_current_line (GTK_SOURCE_VIEW (container->priv->active_view), val);
 +	}
 +}
 +
 +static void
 +gedit_view_container_set_state (GeditViewContainer      *container,
 +				GeditViewContainerState  state)
 +{
 +	g_return_if_fail (GEDIT_IS_VIEW_CONTAINER (container));
 +	g_return_if_fail ((state >= 0) && (state < GEDIT_VIEW_CONTAINER_NUM_OF_STATES));
 +
 +	if (container->priv->state == state)
 +		return;
 +
 +	container->priv->state = state;
 +
 +	set_view_properties_according_to_state (container, state);
 +
 +	if ((state == GEDIT_VIEW_CONTAINER_STATE_LOADING_ERROR) || /* FIXME: add other states if needed */
 +	    (state == GEDIT_VIEW_CONTAINER_STATE_SHOWING_PRINT_PREVIEW))
 +	{
 +		gtk_widget_hide (container->priv->active_view_scrolled_window);
 +	}
 +	else
 +	{
 +		if (container->priv->print_preview == NULL)
 +			gtk_widget_show (container->priv->active_view_scrolled_window);
 +	}
 +
 +	/* FIXME: Should we take care of all views? */
 +	if (GTK_IS_TEXT_VIEW (container->priv->active_view))
 +		set_cursor_according_to_state (GTK_TEXT_VIEW (container->priv->active_view),
 +					       state);
 +
 +	g_object_notify (G_OBJECT (container), "state");
 +}
 +
 +static void 
 +document_uri_notify_handler (GeditDocument      *document,
 +			     GParamSpec         *pspec,
 +			     GeditViewContainer *container)
 +{
 +	gedit_debug (DEBUG_VIEW_CONTAINER);
 +	
 +	/* Notify the change in the URI */
 +	g_object_notify (G_OBJECT (container), "name");
 +}
 +
 +static void
 +document_modified_changed (GtkTextBuffer      *document,
 +			   GeditViewContainer *container)
 +{
 +	g_object_notify (G_OBJECT (container), "name");
 +}
 +
 +static void
 +set_message_area (GeditViewContainer  *container,
 +		  GtkWidget *message_area)
 +{
 +	if (container->priv->message_area == message_area)
 +		return;
 +
 +	if (container->priv->message_area != NULL)
 +		gtk_widget_destroy (container->priv->message_area);
 +
 +	container->priv->message_area = message_area;
 +
 +	if (message_area == NULL)
 +		return;
 +
 +	gtk_box_pack_start (GTK_BOX (container),
 +			    container->priv->message_area,
 +			    FALSE,
 +			    FALSE,
 +			    0);
 +
 +	g_object_add_weak_pointer (G_OBJECT (container->priv->message_area), 
 +				   (gpointer *)&container->priv->message_area);
 +}
 +
 +/* FIXME: This can't be here when we add GeditPage */
 +static void
 +remove_container (GeditViewContainer *container)
 +{
 +	/*GeditNotebook *notebook;
 +
 +	notebook = GEDIT_NOTEBOOK (gtk_widget_get_parent (GTK_WIDGET (container)));
 +
 +	gedit_notebook_remove_page (notebook, container);*/
 +}
 +
 +static void 
 +io_loading_error_message_area_response (GtkWidget          *message_area,
 +					gint                response_id,
 +					GeditViewContainer *container)
 +{
 +	if (response_id == GTK_RESPONSE_OK)
 +	{
 +		GeditDocument *doc;
 +		gchar *uri;
 +
 +		doc = gedit_view_container_get_document (container);
 +		g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
 +
 +		uri = gedit_document_get_uri (doc);
 +		g_return_if_fail (uri != NULL);
 +
 +		set_message_area (container, NULL);
 +		gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_LOADING);
 +
 +		g_return_if_fail (container->priv->auto_save_timeout <= 0);
 +
 +		gedit_document_load (doc,
 +				     uri,
 +				     container->priv->tmp_encoding,
 +				     container->priv->tmp_line_pos,
 +				     FALSE);
 +	}
 +	else
 +	{
 +		remove_container (container);
 +	}
 +}
 +
 +static void 
 +conversion_loading_error_message_area_response (GtkWidget          *message_area,
 +						gint                response_id,
 +						GeditViewContainer *container)
 +{
 +	GeditDocument *doc;
 +	gchar *uri;
 +
 +	doc = gedit_view_container_get_document (container);
 +	g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
 +
 +	uri = gedit_document_get_uri (doc);
 +	g_return_if_fail (uri != NULL);
 +
 +	if (response_id == GTK_RESPONSE_OK)
 +	{
 +		const GeditEncoding *encoding;
 +
 +		encoding = gedit_conversion_error_message_area_get_encoding (
 +				GTK_WIDGET (message_area));
 +
 +		g_return_if_fail (encoding != NULL);
 +
 +		set_message_area (container, NULL);
 +		gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_LOADING);
 +
 +		container->priv->tmp_encoding = encoding;
 +
 +		g_return_if_fail (container->priv->auto_save_timeout <= 0);
 +
 +		gedit_document_load (doc,
 +				     uri,
 +				     encoding,
 +				     container->priv->tmp_line_pos,
 +				     FALSE);
 +	}
 +	else
 +	{
 +		_gedit_recent_remove (GEDIT_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (container))), uri);
 +
 +		remove_container (container);
 +	}
 +
 +	g_free (uri);
 +}
 +
 +static void 
 +file_already_open_warning_message_area_response (GtkWidget          *message_area,
 +						 gint                response_id,
 +						 GeditViewContainer *container)
 +{
 +	GeditView *view;
 +	
 +	view = gedit_view_container_get_view (container);
 +	
 +	if (response_id == GTK_RESPONSE_YES)
 +	{
 +		container->priv->not_editable = FALSE;
 +		
 +		gedit_view_set_editable (GEDIT_VIEW (view),
 +					 TRUE);
 +	}
 +
 +	gtk_widget_destroy (message_area);
 +
 +	gtk_widget_grab_focus (GTK_WIDGET (view));
 +}
 +
 +static void
 +load_cancelled (GtkWidget          *area,
 +                gint                response_id,
 +                GeditViewContainer *container)
 +{
 +	g_return_if_fail (GEDIT_IS_PROGRESS_MESSAGE_AREA (container->priv->message_area));
 +	
 +	g_object_ref (container);
 +	gedit_document_load_cancel (gedit_view_container_get_document (container));
 +	g_object_unref (container);
 +}
 +
 +static void 
 +unrecoverable_reverting_error_message_area_response (GtkWidget          *message_area,
 +						     gint                response_id,
 +						     GeditViewContainer *container)
 +{
 +	GeditView *view;
 +	
 +	gedit_view_container_set_state (container,
 +			     GEDIT_VIEW_CONTAINER_STATE_NORMAL);
 +
 +	set_message_area (container, NULL);
 +
 +	view = gedit_view_container_get_view (container);
 +
 +	gtk_widget_grab_focus (GTK_WIDGET (view));
 +	
 +	install_auto_save_timeout_if_needed (container);
 +}
 +
 +#define MAX_MSG_LENGTH 100
 +
 +static void
 +show_loading_message_area (GeditViewContainer *container)
 +{
 +	GtkWidget *area;
 +	GeditDocument *doc = NULL;
 +	gchar *name;
 +	gchar *dirname = NULL;
 +	gchar *msg = NULL;
 +	gchar *name_markup;
 +	gchar *dirname_markup;
 +	gint len;
 +
 +	if (container->priv->message_area != NULL)
 +		return;
 +
 +	gedit_debug (DEBUG_VIEW_CONTAINER);
 +		
 +	doc = gedit_view_container_get_document (container);
 +	g_return_if_fail (doc != NULL);
 +
 +	name = gedit_document_get_short_name_for_display (doc);
 +	len = g_utf8_strlen (name, -1);
 +
 +	/* if the name is awfully long, truncate it and be done with it,
 +	 * otherwise also show the directory (ellipsized if needed)
 +	 */
 +	if (len > MAX_MSG_LENGTH)
 +	{
 +		gchar *str;
 +
 +		str = gedit_utils_str_middle_truncate (name, MAX_MSG_LENGTH);
 +		g_free (name);
 +		name = str;
 +	}
 +	else
 +	{
 +		GFile *file;
 +
 +		file = gedit_document_get_location (doc);
 +		if (file != NULL)
 +		{
 +			gchar *str;
 +
 +			str = gedit_utils_location_get_dirname_for_display (file);
 +			g_object_unref (file);
 +
 +			/* use the remaining space for the dir, but use a min of 20 chars
 +			 * so that we do not end up with a dirname like "(a...b)".
 +			 * This means that in the worst case when the filename is long 99
 +			 * we have a title long 99 + 20, but I think it's a rare enough
 +			 * case to be accepcontainerle. It's justa darn title afterall :)
 +			 */
 +			dirname = gedit_utils_str_middle_truncate (str, 
 +								   MAX (20, MAX_MSG_LENGTH - len));
 +			g_free (str);
 +		}
 +	}
 +
 +	name_markup = g_markup_printf_escaped ("<b>%s</b>", name);
 +
 +	if (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_REVERTING)
 +	{
 +		if (dirname != NULL)
 +		{
 +			dirname_markup = g_markup_printf_escaped ("<b>%s</b>", dirname);
 +
 +			/* Translators: the first %s is a file name (e.g. test.txt) the second one
 +			   is a directory (e.g. ssh://master.gnome.org/home/users/paolo) */
 +			msg = g_strdup_printf (_("Reverting %s from %s"),
 +					       name_markup,
 +					       dirname_markup);
 +			g_free (dirname_markup);
 +		}
 +		else
 +		{
 +			msg = g_strdup_printf (_("Reverting %s"),
 +					       name_markup);
 +		}
 +		
 +		area = gedit_progress_message_area_new (GTK_STOCK_REVERT_TO_SAVED,
 +							msg,
 +							TRUE);
 +	}
 +	else
 +	{
 +		if (dirname != NULL)
 +		{
 +			dirname_markup = g_markup_printf_escaped ("<b>%s</b>", dirname);
 +
 +			/* Translators: the first %s is a file name (e.g. test.txt) the second one
 +			   is a directory (e.g. ssh://master.gnome.org/home/users/paolo) */
 +			msg = g_strdup_printf (_("Loading %s from %s"),
 +					       name_markup,
 +					       dirname_markup);
 +			g_free (dirname_markup);
 +		}
 +		else
 +		{
 +			msg = g_strdup_printf (_("Loading %s"),
 +					       name_markup);
 +		}
 +
 +		area = gedit_progress_message_area_new (GTK_STOCK_OPEN,
 +							msg,
 +							TRUE);
 +	}
 +
 +	g_signal_connect (area,
 +			  "response",
 +			  G_CALLBACK (load_cancelled),
 +			  container);
 +
 +	gtk_widget_show (area);
 +
 +	set_message_area (container, area);
 +
 +	g_free (msg);
 +	g_free (name);
 +	g_free (name_markup);
 +	g_free (dirname);
 +}
 +
 +static void
 +show_saving_message_area (GeditViewContainer *container)
 +{
 +	GtkWidget *area;
 +	GeditDocument *doc = NULL;
 +	gchar *short_name;
 +	gchar *from;
 +	gchar *to = NULL;
 +	gchar *from_markup;
 +	gchar *to_markup;
 +	gchar *msg = NULL;
 +	gint len;
 +
 +	g_return_if_fail (container->priv->tmp_save_uri != NULL);
 +	
 +	if (container->priv->message_area != NULL)
 +		return;
 +	
 +	gedit_debug (DEBUG_VIEW_CONTAINER);
 +	
 +	doc = gedit_view_container_get_document (container);
 +	g_return_if_fail (doc != NULL);
 +
 +	short_name = gedit_document_get_short_name_for_display (doc);
 +
 +	len = g_utf8_strlen (short_name, -1);
 +
 +	/* if the name is awfully long, truncate it and be done with it,
 +	 * otherwise also show the directory (ellipsized if needed)
 +	 */
 +	if (len > MAX_MSG_LENGTH)
 +	{
 +		from = gedit_utils_str_middle_truncate (short_name, 
 +							MAX_MSG_LENGTH);
 +		g_free (short_name);
 +	}
 +	else
 +	{
 +		gchar *str;
 +
 +		from = short_name;
 +
 +		to = gedit_utils_uri_for_display (container->priv->tmp_save_uri);
 +
 +		str = gedit_utils_str_middle_truncate (to,
 +						       MAX (20, MAX_MSG_LENGTH - len));
 +		g_free (to);
 +			
 +		to = str;
 +	}
 +
 +	from_markup = g_markup_printf_escaped ("<b>%s</b>", from);
 +
 +	if (to != NULL)
 +	{
 +		to_markup = g_markup_printf_escaped ("<b>%s</b>", to);
 +
 +		/* Translators: the first %s is a file name (e.g. test.txt) the second one
 +		   is a directory (e.g. ssh://master.gnome.org/home/users/paolo) */
 +		msg = g_strdup_printf (_("Saving %s to %s"),
 +				       from_markup,
 +				       to_markup);
 +		g_free (to_markup);
 +	}
 +	else
 +	{
 +		msg = g_strdup_printf (_("Saving %s"), from_markup);
 +	}
 +
 +	area = gedit_progress_message_area_new (GTK_STOCK_SAVE,
 +						msg,
 +						FALSE);
 +
 +	gtk_widget_show (area);
 +
 +	set_message_area (container, area);
 +
 +	g_free (msg);
 +	g_free (to);
 +	g_free (from);
 +	g_free (from_markup);
 +}
 +
 +static void
 +message_area_set_progress (GeditViewContainer *container,
 +			   goffset   size,
 +			   goffset   total_size)
 +{
 +	if (container->priv->message_area == NULL)
 +		return;
 +
 +	gedit_debug_message (DEBUG_VIEW_CONTAINER, "%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT, size, total_size);
 +
 +	g_return_if_fail (GEDIT_IS_PROGRESS_MESSAGE_AREA (container->priv->message_area));
 +	
 +	if (total_size == 0)
 +	{
 +		if (size != 0)
 +			gedit_progress_message_area_pulse (
 +					GEDIT_PROGRESS_MESSAGE_AREA (container->priv->message_area));
 +		else
 +			gedit_progress_message_area_set_fraction (
 +				GEDIT_PROGRESS_MESSAGE_AREA (container->priv->message_area),
 +				0);
 +	}
 +	else
 +	{
 +		gdouble frac;
 +
 +		frac = (gdouble)size / (gdouble)total_size;
 +
 +		gedit_progress_message_area_set_fraction (
 +				GEDIT_PROGRESS_MESSAGE_AREA (container->priv->message_area),
 +				frac);
 +	}
 +}
 +
 +static void
 +document_loading (GeditDocument      *document,
 +		  goffset             size,
 +		  goffset             total_size,
 +		  GeditViewContainer *container)
 +{
 +	double et;
 +
 +	g_return_if_fail ((container->priv->state == GEDIT_VIEW_CONTAINER_STATE_LOADING) ||
 +		 	  (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_REVERTING));
 +
 +	gedit_debug_message (DEBUG_VIEW_CONTAINER, "%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT, size, total_size);
 +
 +	if (container->priv->timer == NULL)
 +	{
 +		g_return_if_fail (container->priv->times_called == 0);
 +		container->priv->timer = g_timer_new ();
 +	}
 +
 +	et = g_timer_elapsed (container->priv->timer, NULL);
 +
 +	if (container->priv->times_called == 1)
 +	{
 +		if ((total_size == 0) || (total_size > 51200UL) /* 50 KB */)
 +		{
 +			show_loading_message_area (container);
 +		}
 +	}
 +	else
 +	{
 +		if ((container->priv->times_called == 3) && (total_size != 0))
 +		{
 +			gdouble total_time;
 +
 +			/* et : total_time = size : total_size */
 +			total_time = (et * total_size)/size;
 +
 +			if ((total_time - et) > 3.0)
 +			{
 +				show_loading_message_area (container);
 +			}
 +		}
 +		else
 +		{
 +			if (et > 3.0)
 +			{
 +				show_loading_message_area (container);
 +			}
 +		}
 +	}
 +	
 +	message_area_set_progress (container, size, total_size);
 +
 +	container->priv->times_called++;
 +}
 +
 +static gboolean
 +remove_container_idle (GeditViewContainer *container)
 +{
 +	remove_container (container);
 +
 +	return FALSE;
 +}
 +
 +static void
 +document_loaded (GeditDocument      *document,
 +		 const GError       *error,
 +		 GeditViewContainer *container)
 +{
 +	GtkWidget *emsg;
 +	GFile *location;
 +	gchar *uri;
 +	const GeditEncoding *encoding;
 +
 +	g_return_if_fail ((container->priv->state == GEDIT_VIEW_CONTAINER_STATE_LOADING) ||
 +			  (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_REVERTING));
 +	g_return_if_fail (container->priv->auto_save_timeout <= 0);
 +
 +	if (container->priv->timer != NULL)
 +	{
 +		g_timer_destroy (container->priv->timer);
 +		container->priv->timer = NULL;
 +	}
 +	container->priv->times_called = 0;
 +
 +	set_message_area (container, NULL);
 +
 +	location = gedit_document_get_location (document);
 +	uri = gedit_document_get_uri (document);
 +
 +	if (error != NULL)
 +	{
 +		if (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_LOADING)
 +			gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_LOADING_ERROR);
 +		else
 +			gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_REVERTING_ERROR);
 +
 +		encoding = gedit_document_get_encoding (document);
 +
 +		if (error->domain == G_IO_ERROR && 
 +		    error->code == G_IO_ERROR_CANCELLED)
 +		{
 +			/* remove the container, but in an idle handler, since
 +			 * we are in the handler of doc loaded and we 
 +			 * don't want doc and container to be finalized now.
 +			 */
 +			g_idle_add ((GSourceFunc) remove_container_idle, container);
 +
 +			goto end;
 +		}
 +		else if (error->domain == G_IO_ERROR || 
 +			 error->domain == GEDIT_DOCUMENT_ERROR)
 +		{
 +			_gedit_recent_remove (GEDIT_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (container))), uri);
 +
 +			if (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_LOADING_ERROR)
 +			{
 +				emsg = gedit_io_loading_error_message_area_new (uri, 
 +										error);
 +				g_signal_connect (emsg,
 +						  "response",
 +						  G_CALLBACK (io_loading_error_message_area_response),
 +						  container);
 +			}
 +			else
 +			{
 +				g_return_if_fail (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_REVERTING_ERROR);
 +				
 +				emsg = gedit_unrecoverable_reverting_error_message_area_new (uri, 
 +											     error);
 +
 +				g_signal_connect (emsg,
 +						  "response",
 +						  G_CALLBACK (unrecoverable_reverting_error_message_area_response),
 +						  container);
 +			}
 +
 +			set_message_area (container, emsg);
 +		}
 +		else
 +		{
 +			g_return_if_fail ((error->domain == G_CONVERT_ERROR) ||
 +			      		  (error->domain == GEDIT_CONVERT_ERROR));
 +
 +			// TODO: different error messages if container->priv->state == GEDIT_VIEW_CONTAINER_STATE_REVERTING?
 +			// note that while reverting encoding should be ok, so this is unlikely to happen
 +			emsg = gedit_conversion_error_while_loading_message_area_new (
 +									uri,
 +									container->priv->tmp_encoding,
 +									error);
 +
 +			set_message_area (container, emsg);
 +
 +			g_signal_connect (emsg,
 +					  "response",
 +					  G_CALLBACK (conversion_loading_error_message_area_response),
 +					  container);
 +		}
 +
 +#if !GTK_CHECK_VERSION (2, 17, 1)
 +		gedit_message_area_set_default_response (GEDIT_MESSAGE_AREA (emsg),
 +							 GTK_RESPONSE_CANCEL);
 +#else
 +		gtk_info_bar_set_default_response (GTK_INFO_BAR (emsg),
 +						   GTK_RESPONSE_CANCEL);
 +#endif
 +
 +		gtk_widget_show (emsg);
 +
 +		g_object_unref (location);
 +		g_free (uri);
 +
 +		return;
 +	}
 +	else
 +	{
 +		gchar *mime;
 +		GList *all_documents;
 +		GList *l;
 +
 +		g_return_if_fail (uri != NULL);
 +
 +		mime = gedit_document_get_mime_type (document);
 +		_gedit_recent_add (GEDIT_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (container))),
 +				   uri,
 +				   mime);
 +		g_free (mime);
 +		
 +		/* Scroll to the cursor when the document is loaded */
 +		for (l = container->priv->views; l != NULL; l = g_list_next (l))
 +		{
 +			gedit_view_scroll_to_cursor (GEDIT_VIEW (l->data));
 +		}
 +
 +		all_documents = gedit_app_get_documents (gedit_app_get_default ());
 +
 +		for (l = all_documents; l != NULL; l = g_list_next (l))
 +		{
 +			GeditDocument *d = GEDIT_DOCUMENT (l->data);
 +			
 +			if (d != document)
 +			{
 +				GFile *loc;
 +
 +				loc = gedit_document_get_location (d);
 +
 +				if ((loc != NULL) &&
 +			    	    g_file_equal (location, loc))
 +			    	{
 +			    		GtkWidget *w;
 +			    		GeditView *view;
 +
 +			    		view = gedit_view_container_get_view (container);
 +
 +			    		container->priv->not_editable = TRUE;
 +
 +			    		w = gedit_file_already_open_warning_message_area_new (uri);
 +
 +					set_message_area (container, w);
 +
 +#if !GTK_CHECK_VERSION (2, 17, 1)
 +					gedit_message_area_set_default_response (GEDIT_MESSAGE_AREA (w),
 +										 GTK_RESPONSE_CANCEL);
 +#else
 +					gtk_info_bar_set_default_response (GTK_INFO_BAR (w),
 +									   GTK_RESPONSE_CANCEL);
 +#endif
 +
 +					gtk_widget_show (w);
 +
 +					g_signal_connect (w,
 +							  "response",
 +							  G_CALLBACK (file_already_open_warning_message_area_response),
 +							  container);
 +
 +			    		g_object_unref (loc);
 +			    		break;
 +			    	}
 +			    	
 +			    	if (loc != NULL)
 +					g_object_unref (loc);
 +			}
 +		}
 +
 +		g_list_free (all_documents);
 +
 +		gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_NORMAL);
 +		
 +		install_auto_save_timeout_if_needed (container);
 +
 +		container->priv->ask_if_externally_modified = TRUE;
 +	}
 +
 + end:
 +	g_object_unref (location);
 +	g_free (uri);
 +
 +	container->priv->tmp_line_pos = 0;
 +	container->priv->tmp_encoding = NULL;
 +}
 +
 +static void
 +document_saving (GeditDocument      *document,
 +		 goffset             size,
 +		 goffset             total_size,
 +		 GeditViewContainer *container)
 +{
 +	double et;
 +
 +	g_return_if_fail (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_SAVING);
 +
 +	gedit_debug_message (DEBUG_VIEW_CONTAINER, "%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT, size, total_size);
 +
 +
 +	if (container->priv->timer == NULL)
 +	{
 +		g_return_if_fail (container->priv->times_called == 0);
 +		container->priv->timer = g_timer_new ();
 +	}
 +
 +	et = g_timer_elapsed (container->priv->timer, NULL);
 +
 +	if (container->priv->times_called == 1)
 +	{
 +		if ((total_size == 0) || (total_size > 51200UL) /* 50 KB */)
 +		{
 +			show_saving_message_area (container);
 +		}
 +	}
 +	else
 +	{
 +		if ((container->priv->times_called == 3) && (total_size != 0))
 +		{
 +			gdouble total_time;
 +
 +			/* et : total_time = size : total_size */
 +			total_time = (et * total_size)/size;
 +
 +			if ((total_time - et) > 3.0)
 +			{
 +				show_saving_message_area (container);
 +			}
 +		}
 +		else
 +		{
 +			if (et > 3.0)
 +			{
 +				show_saving_message_area (container);
 +			}
 +		}
 +	}
 +	
 +	message_area_set_progress (container, size, total_size);
 +
 +	container->priv->times_called++;
 +}
 +
 +static void
 +end_saving (GeditViewContainer *container)
 +{
 +	/* Reset tmp data for saving */
 +	g_free (container->priv->tmp_save_uri);
 +	container->priv->tmp_save_uri = NULL;
 +	container->priv->tmp_encoding = NULL;
 +	
 +	install_auto_save_timeout_if_needed (container);
 +}
 +
 +static void 
 +unrecoverable_saving_error_message_area_response (GtkWidget          *message_area,
 +						  gint                response_id,
 +						  GeditViewContainer *container)
 +{
 +	GeditView *view;
 +	
 +	if (container->priv->print_preview != NULL)
 +		gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_SHOWING_PRINT_PREVIEW);
 +	else
 +		gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_NORMAL);
 +
 +	end_saving (container);
 +	
 +	set_message_area (container, NULL);
 +
 +	view = gedit_view_container_get_view (container);
 +
 +	gtk_widget_grab_focus (GTK_WIDGET (view));
 +}
 +
 +static void 
 +no_backup_error_message_area_response (GtkWidget          *message_area,
 +				       gint                response_id,
 +				       GeditViewContainer *container)
 +{
 +	if (response_id == GTK_RESPONSE_YES)
 +	{
 +		GeditDocument *doc;
 +
 +		doc = gedit_view_container_get_document (container);
 +		g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
 +
 +		set_message_area (container, NULL);
 +
 +		g_return_if_fail (container->priv->tmp_save_uri != NULL);
 +		g_return_if_fail (container->priv->tmp_encoding != NULL);
 +
 +		gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_SAVING);
 +
 +		/* don't bug the user again with this... */
 +		container->priv->save_flags |= GEDIT_DOCUMENT_SAVE_IGNORE_BACKUP;
 +
 +		g_return_if_fail (container->priv->auto_save_timeout <= 0);
 +		
 +		/* Force saving */
 +		gedit_document_save (doc, container->priv->save_flags);
 +	}
 +	else
 +	{
 +		unrecoverable_saving_error_message_area_response (message_area,
 +								  response_id,
 +								  container);
 +	}
 +}
 +
 +static void
 +externally_modified_error_message_area_response (GtkWidget          *message_area,
 +						 gint                response_id,
 +						 GeditViewContainer *container)
 +{
 +	if (response_id == GTK_RESPONSE_YES)
 +	{
 +		GeditDocument *doc;
 +
 +		doc = gedit_view_container_get_document (container);
 +		g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
 +		
 +		set_message_area (container, NULL);
 +
 +		g_return_if_fail (container->priv->tmp_save_uri != NULL);
 +		g_return_if_fail (container->priv->tmp_encoding != NULL);
 +
 +		gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_SAVING);
 +
 +		g_return_if_fail (container->priv->auto_save_timeout <= 0);
 +		
 +		/* ignore mtime should not be persisted in save flags across saves */
 +
 +		/* Force saving */
 +		gedit_document_save (doc, container->priv->save_flags | GEDIT_DOCUMENT_SAVE_IGNORE_MTIME);
 +	}
 +	else
 +	{		
 +		unrecoverable_saving_error_message_area_response (message_area,
 +								  response_id,
 +								  container);
 +	}
 +}
 +
 +static void 
 +recoverable_saving_error_message_area_response (GtkWidget          *message_area,
 +						gint                response_id,
 +						GeditViewContainer *container)
 +{
 +	GeditDocument *doc;
 +
 +	doc = gedit_view_container_get_document (container);
 +	g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
 +	
 +	if (response_id == GTK_RESPONSE_OK)
 +	{
 +		const GeditEncoding *encoding;
 +		
 +		encoding = gedit_conversion_error_message_area_get_encoding (
 +									GTK_WIDGET (message_area));
 +
 +		g_return_if_fail (encoding != NULL);
 +
 +		set_message_area (container, NULL);
 +
 +		g_return_if_fail (container->priv->tmp_save_uri != NULL);
 +				
 +		gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_SAVING);
 +			
 +		container->priv->tmp_encoding = encoding;
 +
 +		gedit_debug_message (DEBUG_VIEW_CONTAINER, "Force saving with URI '%s'", container->priv->tmp_save_uri);
 +			 
 +		g_return_if_fail (container->priv->auto_save_timeout <= 0);
 +		
 +		gedit_document_save_as (doc,
 +					container->priv->tmp_save_uri,
 +					container->priv->tmp_encoding,
 +					container->priv->save_flags);
 +	}
 +	else
 +	{		
 +		unrecoverable_saving_error_message_area_response (message_area,
 +								  response_id,
 +								  container);
 +	}
 +}
 +
 +static void
 +document_saved (GeditDocument      *document,
 +		const GError       *error,
 +		GeditViewContainer *container)
 +{
 +	GtkWidget *emsg;
 +
 +	g_return_if_fail (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_SAVING);
 +
 +	g_return_if_fail (container->priv->tmp_save_uri != NULL);
 +	g_return_if_fail (container->priv->tmp_encoding != NULL);
 +	g_return_if_fail (container->priv->auto_save_timeout <= 0);
 +	
 +	g_timer_destroy (container->priv->timer);
 +	container->priv->timer = NULL;
 +	container->priv->times_called = 0;
 +	
 +	set_message_area (container, NULL);
 +	
 +	if (error != NULL)
 +	{
 +		gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_SAVING_ERROR);
 +		
 +		if (error->domain == GEDIT_DOCUMENT_ERROR &&
 +		    error->code == GEDIT_DOCUMENT_ERROR_EXTERNALLY_MODIFIED)
 +		{
 +			/* This error is recoverable */
 +			emsg = gedit_externally_modified_saving_error_message_area_new (
 +							container->priv->tmp_save_uri,
 +							error);
 +			g_return_if_fail (emsg != NULL);
 +
 +			set_message_area (container, emsg);
 +
 +			g_signal_connect (emsg,
 +					  "response",
 +					  G_CALLBACK (externally_modified_error_message_area_response),
 +					  container);
 +		}
 +		else if ((error->domain == GEDIT_DOCUMENT_ERROR &&
 +			  error->code == GEDIT_DOCUMENT_ERROR_CANT_CREATE_BACKUP) ||
 +		         (error->domain == G_IO_ERROR &&
 +			  error->code == G_IO_ERROR_CANT_CREATE_BACKUP))
 +		{
 +			/* This error is recoverable */
 +			emsg = gedit_no_backup_saving_error_message_area_new (
 +							container->priv->tmp_save_uri,
 +							error);
 +			g_return_if_fail (emsg != NULL);
 +
 +			set_message_area (container, emsg);
 +
 +			g_signal_connect (emsg,
 +					  "response",
 +					  G_CALLBACK (no_backup_error_message_area_response),
 +					  container);
 +		}
 +		else if (error->domain == GEDIT_DOCUMENT_ERROR || 
 +			 error->domain == G_IO_ERROR)
 +		{
 +			/* These errors are _NOT_ recoverable */
 +			_gedit_recent_remove  (GEDIT_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (container))),
 +					       container->priv->tmp_save_uri);
 +
 +			emsg = gedit_unrecoverable_saving_error_message_area_new (container->priv->tmp_save_uri,
 +										  error);
 +			g_return_if_fail (emsg != NULL);
 +	
 +			set_message_area (container, emsg);
 +
 +			g_signal_connect (emsg,
 +					  "response",
 +					  G_CALLBACK (unrecoverable_saving_error_message_area_response),
 +					  container);
 +		}
 +		else
 +		{
 +			/* This error is recoverable */
 +			g_return_if_fail (error->domain == G_CONVERT_ERROR);
 +
 +			emsg = gedit_conversion_error_while_saving_message_area_new (
 +									container->priv->tmp_save_uri,
 +									container->priv->tmp_encoding,
 +									error);
 +
 +			set_message_area (container, emsg);
 +
 +			g_signal_connect (emsg,
 +					  "response",
 +					  G_CALLBACK (recoverable_saving_error_message_area_response),
 +					  container);
 +		}
 +
 +#if !GTK_CHECK_VERSION (2, 17, 1)
 +		gedit_message_area_set_default_response (GEDIT_MESSAGE_AREA (emsg),
 +							 GTK_RESPONSE_CANCEL);
 +#else
 +		gtk_info_bar_set_default_response (GTK_INFO_BAR (emsg),
 +						   GTK_RESPONSE_CANCEL);
 +#endif
 +
 +		gtk_widget_show (emsg);
 +	}
 +	else
 +	{
 +		gchar *mime = gedit_document_get_mime_type (document);
 +
 +		_gedit_recent_add (GEDIT_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (container))),
 +				   container->priv->tmp_save_uri,
 +				   mime);
 +		g_free (mime);
 +
 +		if (container->priv->print_preview != NULL)
 +			gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_SHOWING_PRINT_PREVIEW);
 +		else
 +			gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_NORMAL);
 +
 +		container->priv->ask_if_externally_modified = TRUE;
 +			
 +		end_saving (container);
 +	}
 +}
 +
 +static void 
 +externally_modified_notification_message_area_response (GtkWidget          *message_area,
 +							gint                response_id,
 +							GeditViewContainer *container)
 +{
 +	GeditView *view;
 +
 +	set_message_area (container, NULL);
 +	view = gedit_view_container_get_view (container);
 +
 +	if (response_id == GTK_RESPONSE_OK)
 +	{
 +		_gedit_view_container_revert (container);
 +	}
 +	else
 +	{
 +		container->priv->ask_if_externally_modified = FALSE;
 +
 +		/* go back to normal state */
 +		gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_NORMAL);
 +	}
 +
 +	gtk_widget_grab_focus (GTK_WIDGET (view));
 +}
 +
 +static void
 +display_externally_modified_notification (GeditViewContainer *container)
 +{
 +	GtkWidget *message_area;
 +	GeditDocument *doc;
 +	gchar *uri;
 +	gboolean document_modified;
 +
 +	doc = gedit_view_container_get_document (container);
 +	g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
 +
 +	/* uri cannot be NULL, we're here because
 +	 * the file we're editing changed on disk */
 +	uri = gedit_document_get_uri (doc);
 +	g_return_if_fail (uri != NULL);
 +
 +	document_modified = gedit_document_get_modified (doc);
 +	message_area = gedit_externally_modified_message_area_new (uri, document_modified);
 +	g_free (uri);
 +
 +	container->priv->message_area = NULL;
 +	set_message_area (container, message_area);
 +	gtk_widget_show (message_area);
 +
 +	g_signal_connect (message_area,
 +			  "response",
 +			  G_CALLBACK (externally_modified_notification_message_area_response),
 +			  container);
 +}
 +
 +static gboolean
 +view_focused_in (GtkWidget          *widget,
 +                 GdkEventFocus      *event,
 +                 GeditViewContainer *container)
 +{
 +	GeditDocument *doc;
 +
 +	g_return_val_if_fail (GEDIT_IS_VIEW_CONTAINER (container), FALSE);
 +
 +	/* we try to detect file changes only in the normal state */
 +	if (container->priv->state != GEDIT_VIEW_CONTAINER_STATE_NORMAL)
 +	{
 +		return FALSE;
 +	}
 +
 +	/* we already asked, don't bug the user again */
 +	if (!container->priv->ask_if_externally_modified)
 +	{
 +		return FALSE;
 +	}
 +
 +	doc = gedit_view_container_get_document (container);
 +
 +	/* If file was never saved or is remote we do not check */
 +	if (!gedit_document_is_local (doc))
 +	{
 +		return FALSE;
 +	}
 +
 +	if (gedit_document_check_externally_modified (doc))
 +	{
 +		gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_EXTERNALLY_MODIFIED_NOTIFICATION);
 +
 +		display_externally_modified_notification (container);
 +
 +		return FALSE;
 +	}
 +
 +	return FALSE;
 +}
 +/*
 +static GMountOperation *
 +container_mount_operation_factory (GeditDocument *doc,
 +			     gpointer userdata)
 +{
 +	GeditViewContainer *container = GEDIT_VIEW_CONTAINER (userdata);
 +	GtkWidget *window;
 +
 +	window = gtk_widget_get_toplevel (GTK_WIDGET (container));
 +	return gtk_mount_operation_new (GTK_WINDOW (window));
 +}*/
 +
 +static void
 +install_view (GeditViewContainer *container,
 +	      GtkWidget          *view)
 +{
 +	GtkWidget *sw;
 +
 +	container->priv->views = g_list_append (container->priv->views, view);
 +	if (!GTK_WIDGET_VISIBLE (view))
 +		gtk_widget_show (view);
 +	
 +	g_object_set_data (G_OBJECT (view), GEDIT_VIEW_CONTAINER_KEY, container);
 +
 +	/* FIXME: We need to know if we need viewport */
 +	/* Create the scrolled window */
 +	sw = gtk_scrolled_window_new (NULL, NULL);
 +
 +	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
 +					GTK_POLICY_AUTOMATIC,
 +					GTK_POLICY_AUTOMATIC);
 +	
 +	gtk_container_add (GTK_CONTAINER (sw), view);
 +	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
 +					     GTK_SHADOW_IN);
 +	gtk_widget_show (sw);
 +	
 +	/* Add view to notebook */
 +	gtk_notebook_append_page (GTK_NOTEBOOK (container->priv->notebook),
 +				  sw, NULL);
 +
 +	g_signal_connect_after (view,
 +				"focus-in-event",
 +				G_CALLBACK (view_focused_in),
 +				container);
 +
 +	g_signal_connect_after (view,
 +				"realize",
 +				G_CALLBACK (view_realized),
 +				container);
 +
 +	g_signal_emit (G_OBJECT (container),
 +		       signals[VIEW_ADDED],
 +		       0,
 +		       view);
 +}
 +
 +static void
 +uninstall_view (GeditViewContainer *container,
 +		GtkWidget          *view)
 +{
 +	GtkWidget *sw;
 +	gint page_num;
 +	
 +	/* FIXME: Check that the parent is indeed a scrolled window */
 +	sw = gtk_widget_get_parent (view);
 +	
 +	page_num = gtk_notebook_page_num (GTK_NOTEBOOK (container->priv->notebook),
 +					  sw);
 +
 +	g_object_ref (view);
 +	
 +	gtk_notebook_remove_page (GTK_NOTEBOOK (container->priv->notebook),
 +				  page_num);
 +
 +	g_signal_emit (G_OBJECT (container),
 +		       signals[VIEW_REMOVED],
 +		       0,
 +		       view);
 +	
 +	g_object_unref (view);
 +}
 +
 +static void
 +on_switch_page_cb (GtkNotebook        *notebook,
 +		   GtkNotebookPage    *page,
 +		   guint               page_num,
 +		   GeditViewContainer *container)
 +{
 +	GtkWidget *sw;
 +	GtkWidget *view;
 +
 +	sw = gtk_notebook_get_nth_page (notebook, page_num);
 +	
 +	if (sw == container->priv->active_view_scrolled_window)
 +		return;
 +
 +	view = gtk_bin_get_child (GTK_BIN (sw));
 +
 +	container->priv->active_view = view;
 +	container->priv->active_view_scrolled_window = sw;
 +
 +	g_signal_emit (G_OBJECT (container),
 +		       signals[ACTIVE_VIEW_CHANGED],
 +		       0,
 +		       container->priv->active_view);
 +}
 +
 +static void
 +gedit_view_container_init (GeditViewContainer *container)
 +{
 +	GeditLockdownMask lockdown;
 +	GtkWidget *view;
 +
 +	container->priv = GEDIT_VIEW_CONTAINER_GET_PRIVATE (container);
 +
 +	container->priv->active_view = NULL;
 +	container->priv->state = GEDIT_VIEW_CONTAINER_STATE_NORMAL;
 +	container->priv->mode = GEDIT_VIEW_CONTAINER_MODE_TEXT;
 +
 +	container->priv->not_editable = FALSE;
 +
 +	container->priv->save_flags = 0;
 +
 +	container->priv->ask_if_externally_modified = TRUE;
 +
 +	/* Manage auto save data */
 +	lockdown = gedit_app_get_lockdown (gedit_app_get_default ());
 +	container->priv->auto_save = gedit_prefs_manager_get_auto_save () &&
 +			       !(lockdown & GEDIT_LOCKDOWN_SAVE_TO_DISK);
 +	container->priv->auto_save = (container->priv->auto_save != FALSE);
 +
 +	container->priv->auto_save_interval = gedit_prefs_manager_get_auto_save_interval ();
 +	if (container->priv->auto_save_interval <= 0)
 +		container->priv->auto_save_interval = GPM_DEFAULT_AUTO_SAVE_INTERVAL;
 +
 +	/*FIXME
 +	_gedit_document_set_mount_operation_factory (doc,
 +						     container_mount_operation_factory,
 +						     container);*/
 +
 +	/* Create the notebook */
 +	container->priv->notebook = gtk_notebook_new ();
 +	gtk_widget_show (container->priv->notebook);
 +	gtk_box_pack_end (GTK_BOX (container),
 +			  container->priv->notebook,
 +			  TRUE, TRUE, 0);
 +
 +	g_signal_connect (container->priv->notebook,
 +			  "switch-page",
 +			  G_CALLBACK (on_switch_page_cb),
 +			  container);
 +
 +	/* Create the main document */
 +	container->priv->doc = gedit_text_buffer_new ();
 +	
 +	g_object_set_data (G_OBJECT (container->priv->doc),
 +			   GEDIT_VIEW_CONTAINER_KEY, container);
 +	
 +	g_signal_connect (container->priv->doc,
 +			  "notify::uri",
 +			  G_CALLBACK (document_uri_notify_handler),
 +			  container);
 +	g_signal_connect (container->priv->doc,
 +			  "modified_changed",
 +			  G_CALLBACK (document_modified_changed),
 +			  container);
 +	g_signal_connect (container->priv->doc,
 +			  "loading",
 +			  G_CALLBACK (document_loading),
 +			  container);
 +	g_signal_connect (container->priv->doc,
 +			  "loaded",
 +			  G_CALLBACK (document_loaded),
 +			  container);
 +	g_signal_connect (container->priv->doc,
 +			  "saving",
 +			  G_CALLBACK (document_saving),
 +			  container);
 +	g_signal_connect (container->priv->doc,
 +			  "saved",
 +			  G_CALLBACK (document_saved),
 +			  container);
 +
 +	/* Add the text view */
 +	view = gedit_text_view_new (GEDIT_TEXT_BUFFER (container->priv->doc));
 +	install_view (container, view);
 +	
 +	/* FIXME: This is only for testing */
 +	view = GTK_WIDGET (gedit_web_view_new ());
 +	install_view (container, view);
 +}
 +
 +GtkWidget *
 +_gedit_view_container_new ()
 +{
 +	return GTK_WIDGET (g_object_new (GEDIT_TYPE_VIEW_CONTAINER, NULL));
 +}
 +
 +/* Whether create is TRUE, creates a new empty document if location does 
 +   not refer to an existing file */
 +GtkWidget *
 +_gedit_view_container_new_from_uri (const gchar         *uri,
 +				    const GeditEncoding *encoding,
 +				    gint                 line_pos,
 +				    gboolean             create)
 +{
 +	GeditViewContainer *container;
 +
 +	g_return_val_if_fail (uri != NULL, NULL);
 +
 +	container = GEDIT_VIEW_CONTAINER (_gedit_view_container_new ());
 +
 +	_gedit_view_container_load (container,
 +				    uri,
 +				    encoding,
 +				    line_pos,
 +				    create);
 +
 +	return GTK_WIDGET (container);
 +}
 +
 +/**
 + * gedit_view_container_get_view:
 + * @container: a #GeditViewContainer
 + *
 + * Gets the #GeditView inside @container.
 + *
 + * Returns: the #GeditView inside @container
 + */
 +GeditView *
 +gedit_view_container_get_view (GeditViewContainer *container)
 +{
 +	g_return_val_if_fail (GEDIT_IS_VIEW_CONTAINER (container), NULL);
 +
 +	return GEDIT_VIEW (container->priv->active_view);
 +}
 +
 +GList *
 +gedit_view_container_get_views (GeditViewContainer *container)
 +{
 +	g_return_val_if_fail (GEDIT_IS_VIEW_CONTAINER (container), NULL);
 +	
 +	return container->priv->views;
 +}
 +
 +/**
 + * gedit_view_container_get_document:
 + * @container: a #GeditViewContainer
 + *
 + * Gets the #GeditDocument associated to @container.
 + *
 + * Returns: the #GeditDocument associated to @container
 + */
 +GeditDocument *
 +gedit_view_container_get_document (GeditViewContainer *container)
 +{
 +	g_return_val_if_fail (GEDIT_IS_VIEW_CONTAINER (container), NULL);
 +
 +	return container->priv->doc;
 +}
 +
 +#define MAX_DOC_NAME_LENGTH 40
 +
 +gchar *
 +_gedit_view_container_get_name (GeditViewContainer *container)
 +{
 +	GeditDocument *doc;
 +	gchar *name;
 +	gchar *docname;
 +	gchar *container_name;
 +
 +	g_return_val_if_fail (GEDIT_IS_VIEW_CONTAINER (container), NULL);
 +
 +	doc = gedit_view_container_get_document (container);
 +
 +	name = gedit_document_get_short_name_for_display (doc);
 +
 +	/* Truncate the name so it doesn't get insanely wide. */
 +	docname = gedit_utils_str_middle_truncate (name, MAX_DOC_NAME_LENGTH);
 +
 +	if (gedit_document_get_modified (doc))
 +	{
 +		container_name = g_strdup_printf ("*%s", docname);
 +	} 
 +	else 
 +	{
 + #if 0		
 +		if (gedit_document_get_readonly (doc)) 
 +		{
 +			container_name = g_strdup_printf ("%s [%s]", docname, 
 +						/*Read only*/ _("RO"));
 +		} 
 +		else 
 +		{
 +			container_name = g_strdup_printf ("%s", docname);
 +		}
 +#endif
 +		container_name = g_strdup (docname);
 +	}
 +	
 +	g_free (docname);
 +	g_free (name);
 +
 +	return container_name;
 +}
 +
 +gchar *
 +_gedit_view_container_get_tooltips (GeditViewContainer *container)
 +{
 +	GeditDocument *doc;
 +	gchar *tip;
 +	gchar *uri;
 +	gchar *ruri;
 +	gchar *ruri_markup;
 +
 +	g_return_val_if_fail (GEDIT_IS_VIEW_CONTAINER (container), NULL);
 +
 +	doc = gedit_view_container_get_document (container);
 +
 +	uri = gedit_document_get_uri_for_display (doc);
 +	g_return_val_if_fail (uri != NULL, NULL);
 +
 +	ruri = 	gedit_utils_replace_home_dir_with_tilde (uri);
 +	g_free (uri);
 +
 +	ruri_markup = g_markup_printf_escaped ("<i>%s</i>", ruri);
 +
 +	switch (container->priv->state)
 +	{
 +		gchar *content_type;
 +		gchar *mime_type;
 +		gchar *content_description;
 +		gchar *content_full_description; 
 +		gchar *encoding;
 +		const GeditEncoding *enc;
 +
 +		case GEDIT_VIEW_CONTAINER_STATE_LOADING_ERROR:
 +			tip = g_strdup_printf (_("Error opening file %s"),
 +					       ruri_markup);
 +			break;
 +
 +		case GEDIT_VIEW_CONTAINER_STATE_REVERTING_ERROR:
 +			tip = g_strdup_printf (_("Error reverting file %s"),
 +					       ruri_markup);
 +			break;			
 +
 +		case GEDIT_VIEW_CONTAINER_STATE_SAVING_ERROR:
 +			tip =  g_strdup_printf (_("Error saving file %s"),
 +						ruri_markup);
 +			break;			
 +		default:
 +			content_type = gedit_document_get_content_type (doc);
 +			mime_type = gedit_document_get_mime_type (doc);
 +			content_description = g_content_type_get_description (content_type);
 +
 +			if (content_description == NULL)
 +				content_full_description = g_strdup (mime_type);
 +			else
 +				content_full_description = g_strdup_printf ("%s (%s)",
 +						content_description, mime_type);
 +
 +			g_free (content_type);
 +			g_free (mime_type);
 +			g_free (content_description);
 +
 +			enc = gedit_document_get_encoding (doc);
 +
 +			if (enc == NULL)
 +				encoding = g_strdup (_("Unicode (UTF-8)"));
 +			else
 +				encoding = gedit_encoding_to_string (enc);
 +
 +			tip =  g_markup_printf_escaped ("<b>%s</b> %s\n\n"
 +						        "<b>%s</b> %s\n"
 +						        "<b>%s</b> %s",
 +						        _("Name:"), ruri,
 +						        _("MIME Type:"), content_full_description,
 +						        _("Encoding:"), encoding);
 +
 +			g_free (encoding);
 +			g_free (content_full_description);
 +
 +			break;
 +	}
 +
 +	g_free (ruri);
 +	g_free (ruri_markup);
 +	
 +	return tip;
 +}
 +
 +static GdkPixbuf *
 +resize_icon (GdkPixbuf *pixbuf,
 +	     gint       size)
 +{
 +	gint width, height;
 +
 +	width = gdk_pixbuf_get_width (pixbuf); 
 +	height = gdk_pixbuf_get_height (pixbuf);
 +
 +	/* if the icon is larger than the nominal size, scale down */
 +	if (MAX (width, height) > size) 
 +	{
 +		GdkPixbuf *scaled_pixbuf;
 +		
 +		if (width > height) 
 +		{
 +			height = height * size / width;
 +			width = size;
 +		} 
 +		else 
 +		{
 +			width = width * size / height;
 +			height = size;
 +		}
 +		
 +		scaled_pixbuf = gdk_pixbuf_scale_simple	(pixbuf,
 +							 width,
 +							 height,
 +							 GDK_INTERP_BILINEAR);
 +		g_object_unref (pixbuf);
 +		pixbuf = scaled_pixbuf;
 +	}
 +
 +	return pixbuf;
 +}
 +
 +static GdkPixbuf *
 +get_stock_icon (GtkIconTheme *theme,
 +		const gchar  *stock,
 +		gint          size)
 +{
 +	GdkPixbuf *pixbuf;
 +	
 +	pixbuf = gtk_icon_theme_load_icon (theme, stock, size, 0, NULL);
 +	if (pixbuf == NULL)
 +		return NULL;
 +		
 +	return resize_icon (pixbuf, size);
 +}
 +
 +static GdkPixbuf *
 +get_icon (GtkIconTheme *theme,
 +	  GFile        *location,
 +	  gint          size)
 +{
 +	GdkPixbuf *pixbuf;
 +	GtkIconInfo *icon_info;
 +	GFileInfo *info;
 +	GIcon *gicon;
 +
 +	if (location == NULL)
 +		return get_stock_icon (theme, GTK_STOCK_FILE, size);
 +
 +	/* FIXME: Doing a sync stat is bad, this should be fixed */
 +	info = g_file_query_info (location, 
 +	                          G_FILE_ATTRIBUTE_STANDARD_ICON, 
 +	                          G_FILE_QUERY_INFO_NONE, 
 +	                          NULL, 
 +	                          NULL);
 +	if (info == NULL)
 +		return get_stock_icon (theme, GTK_STOCK_FILE, size);
 +
 +	gicon = g_file_info_get_icon (info);
 +
 +	if (gicon == NULL)
 +	{
 +		g_object_unref (info);
 +		return get_stock_icon (theme, GTK_STOCK_FILE, size);
 +	}
 +
 +	icon_info = gtk_icon_theme_lookup_by_gicon (theme, gicon, size, 0);
 +	g_object_unref (info);
 +	
 +	if (icon_info == NULL)
 +		return get_stock_icon (theme, GTK_STOCK_FILE, size);
 +	
 +	pixbuf = gtk_icon_info_load_icon (icon_info, NULL);
 +	gtk_icon_info_free (icon_info);
 +	
 +	if (pixbuf == NULL)
 +		return get_stock_icon (theme, GTK_STOCK_FILE, size);
 +		
 +	return resize_icon (pixbuf, size);
 +}
 +
 +/* FIXME: add support for theme changed. I think it should be as easy as
 +   call g_object_notify (container, "name") when the icon theme changes */
 +GdkPixbuf *
 +_gedit_view_container_get_icon (GeditViewContainer *container)
 +{
 +	GdkPixbuf *pixbuf;
 +	GtkIconTheme *theme;
 +	GdkScreen *screen;
 +	gint icon_size;
 +
 +	g_return_val_if_fail (GEDIT_IS_VIEW_CONTAINER (container), NULL);
 +
 +	screen = gtk_widget_get_screen (GTK_WIDGET (container));
 +
 +	theme = gtk_icon_theme_get_for_screen (screen);
 +	g_return_val_if_fail (theme != NULL, NULL);
 +
 +	gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (GTK_WIDGET (container)),
 +					   GTK_ICON_SIZE_MENU,
 +					   NULL,
 +					   &icon_size);
 +
 +	switch (container->priv->state)
 +	{
 +		case GEDIT_VIEW_CONTAINER_STATE_LOADING:
 +			pixbuf = get_stock_icon (theme,
 +						 GTK_STOCK_OPEN,
 +						 icon_size);
 +			break;
 +
 +		case GEDIT_VIEW_CONTAINER_STATE_REVERTING:
 +			pixbuf = get_stock_icon (theme,
 +						 GTK_STOCK_REVERT_TO_SAVED,
 +						 icon_size);
 +			break;
 +
 +		case GEDIT_VIEW_CONTAINER_STATE_SAVING:
 +			pixbuf = get_stock_icon (theme,
 +						 GTK_STOCK_SAVE,
 +						 icon_size);
 +			break;
 +
 +		case GEDIT_VIEW_CONTAINER_STATE_PRINTING:
 +			pixbuf = get_stock_icon (theme,
 +						 GTK_STOCK_PRINT,
 +						 icon_size);
 +			break;
 +
 +		case GEDIT_VIEW_CONTAINER_STATE_PRINT_PREVIEWING:
 +		case GEDIT_VIEW_CONTAINER_STATE_SHOWING_PRINT_PREVIEW:
 +			pixbuf = get_stock_icon (theme,
 +						 GTK_STOCK_PRINT_PREVIEW,
 +						 icon_size);
 +			break;
 +
 +		case GEDIT_VIEW_CONTAINER_STATE_LOADING_ERROR:
 +		case GEDIT_VIEW_CONTAINER_STATE_REVERTING_ERROR:
 +		case GEDIT_VIEW_CONTAINER_STATE_SAVING_ERROR:
 +		case GEDIT_VIEW_CONTAINER_STATE_GENERIC_ERROR:
 +			pixbuf = get_stock_icon (theme,
 +						 GTK_STOCK_DIALOG_ERROR,
 +						 icon_size);
 +			break;
 +
 +		case GEDIT_VIEW_CONTAINER_STATE_EXTERNALLY_MODIFIED_NOTIFICATION:
 +			pixbuf = get_stock_icon (theme,
 +						 GTK_STOCK_DIALOG_WARNING,
 +						 icon_size);
 +			break;
 +
 +		default:
 +		{
 +			GFile *location;
 +			GeditDocument *doc;
 +
 +			doc = gedit_view_container_get_document (container);
 +
 +			location = gedit_document_get_location (doc);
 +			pixbuf = get_icon (theme, location, icon_size);
 +
 +			if (location)
 +				g_object_unref (location);
 +		}
 +	}
 +
 +	return pixbuf;
 +}
 +
 +/**
 + * gedit_view_container_get_from_document:
 + * @doc: a #GeditDocument
 + *
 + * Gets the #GeditViewContainer associated with @doc.
 + *
 + * Returns: the #GeditViewContainer associated with @doc
 + */
 +GeditViewContainer *
 +gedit_view_container_get_from_document (GeditDocument *doc)
 +{
 +	gpointer res;
 +	
 +	g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), NULL);
 +	
 +	res = g_object_get_data (G_OBJECT (doc), GEDIT_VIEW_CONTAINER_KEY);
 +	
 +	return (res != NULL) ? GEDIT_VIEW_CONTAINER (res) : NULL;
 +}
 +
 +GeditViewContainer *
 +gedit_view_container_get_from_view (GeditView *view)
 +{
 +	gpointer res;
 +	
 +	g_return_val_if_fail (GEDIT_IS_VIEW (view), NULL);
 +	
 +	res = g_object_get_data (G_OBJECT (view), GEDIT_VIEW_CONTAINER_KEY);
 +	
 +	return (res != NULL) ? GEDIT_VIEW_CONTAINER (res) : NULL;
 +}
 +
 +void
 +_gedit_view_container_load (GeditViewContainer *container,
 +			    const gchar         *uri,
 +			    const GeditEncoding *encoding,
 +			    gint                 line_pos,
 +			    gboolean             create)
 +{
 +	g_return_if_fail (GEDIT_IS_VIEW_CONTAINER (container));
 +	g_return_if_fail (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_NORMAL);
 +
 +	gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_LOADING);
 +
 +	container->priv->tmp_line_pos = line_pos;
 +	container->priv->tmp_encoding = encoding;
 +
 +	if (container->priv->auto_save_timeout > 0)
 +		remove_auto_save_timeout (container);
 +
 +	gedit_document_load (container->priv->doc,
 +			     uri,
 +			     encoding,
 +			     line_pos,
 +			     create);
 +}
 +
 +void
 +_gedit_view_container_revert (GeditViewContainer *container)
 +{
 +	GeditDocument *doc;
 +	gchar *uri;
 +
 +	g_return_if_fail (GEDIT_IS_VIEW_CONTAINER (container));
 +	g_return_if_fail ((container->priv->state == GEDIT_VIEW_CONTAINER_STATE_NORMAL) ||
 +			  (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_EXTERNALLY_MODIFIED_NOTIFICATION));
 +
 +	if (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_EXTERNALLY_MODIFIED_NOTIFICATION)
 +	{
 +		set_message_area (container, NULL);
 +	}
 +
 +	doc = gedit_view_container_get_document (container);
 +	g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
 +
 +	gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_REVERTING);
 +
 +	uri = gedit_document_get_uri (doc);
 +	g_return_if_fail (uri != NULL);
 +
 +	container->priv->tmp_line_pos = 0;
 +	container->priv->tmp_encoding = gedit_document_get_encoding (doc);
 +
 +	if (container->priv->auto_save_timeout > 0)
 +		remove_auto_save_timeout (container);
 +
 +	gedit_document_load (doc,
 +			     uri,
 +			     container->priv->tmp_encoding,
 +			     0,
 +			     FALSE);
 +
 +	g_free (uri);
 +}
 +
 +void
 +_gedit_view_container_save (GeditViewContainer *container)
 +{
 +	GeditDocument *doc;
 +	GeditDocumentSaveFlags save_flags;
 +
 +	g_return_if_fail (GEDIT_IS_VIEW_CONTAINER (container));
 +	g_return_if_fail ((container->priv->state == GEDIT_VIEW_CONTAINER_STATE_NORMAL) ||
 +			  (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_EXTERNALLY_MODIFIED_NOTIFICATION) ||
 +			  (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_SHOWING_PRINT_PREVIEW));
 +	g_return_if_fail (container->priv->tmp_save_uri == NULL);
 +	g_return_if_fail (container->priv->tmp_encoding == NULL);
 +
 +	doc = gedit_view_container_get_document (container);
 +	g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
 +	g_return_if_fail (!gedit_document_is_untitled (doc));
 +
 +	if (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_EXTERNALLY_MODIFIED_NOTIFICATION)
 +	{
 +		/* We already told the user about the external
 +		 * modification: hide the message area and set
 +		 * the save flag.
 +		 */
 +
 +		set_message_area (container, NULL);
 +		save_flags = container->priv->save_flags | GEDIT_DOCUMENT_SAVE_IGNORE_MTIME;
 +	}
 +	else
 +	{
 +		save_flags = container->priv->save_flags;
 +	}
 +
 +	gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_SAVING);
 +
 +	/* uri used in error messages, will be freed in document_saved */
 +	container->priv->tmp_save_uri = gedit_document_get_uri (doc);
 +	container->priv->tmp_encoding = gedit_document_get_encoding (doc);
 +
 +	if (container->priv->auto_save_timeout > 0)
 +		remove_auto_save_timeout (container);
 +		
 +	gedit_document_save (doc, save_flags);
 +}
 +
 +static gboolean
 +gedit_view_container_auto_save (GeditViewContainer *container)
 +{
 +	GeditDocument *doc;
 +
 +	gedit_debug (DEBUG_VIEW_CONTAINER);
 +	
 +	g_return_val_if_fail (container->priv->tmp_save_uri == NULL, FALSE);
 +	g_return_val_if_fail (container->priv->tmp_encoding == NULL, FALSE);
 +	
 +	doc = gedit_view_container_get_document (container);
 +	
 +	g_return_val_if_fail (!gedit_document_is_untitled (doc), FALSE);
 +	g_return_val_if_fail (!gedit_document_get_readonly (doc), FALSE);
 +
 +	g_return_val_if_fail (container->priv->auto_save_timeout > 0, FALSE);
 +	g_return_val_if_fail (container->priv->auto_save, FALSE);
 +	g_return_val_if_fail (container->priv->auto_save_interval > 0, FALSE);
 +
 +	if (!gedit_document_get_modified (doc))
 +	{
 +		gedit_debug_message (DEBUG_VIEW_CONTAINER, "Document not modified");
 +
 +		return TRUE;
 +	}
 +			
 +	if ((container->priv->state != GEDIT_VIEW_CONTAINER_STATE_NORMAL) &&
 +	    (container->priv->state != GEDIT_VIEW_CONTAINER_STATE_SHOWING_PRINT_PREVIEW))
 +	{
 +		/* Retry after 30 seconds */
 +		guint timeout;
 +
 +		gedit_debug_message (DEBUG_VIEW_CONTAINER, "Retry after 30 seconds");
 +
 +		/* Add a new timeout */
 +		timeout = g_timeout_add_seconds (30,
 +						 (GSourceFunc) gedit_view_container_auto_save,
 +						 container);
 +
 +		container->priv->auto_save_timeout = timeout;
 +
 +	    	/* Returns FALSE so the old timeout is "destroyed" */
 +		return FALSE;
 +	}
 +	
 +	gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_SAVING);
 +
 +	/* uri used in error messages, will be freed in document_saved */
 +	container->priv->tmp_save_uri = gedit_document_get_uri (doc);
 +	container->priv->tmp_encoding = gedit_document_get_encoding (doc);
 +
 +	/* Set auto_save_timeout to 0 since the timeout is going to be destroyed */
 +	container->priv->auto_save_timeout = 0;
 +
 +	/* Since we are autosaving, we need to preserve the backup that was produced
 +	   the last time the user "manually" saved the file. In the case a recoverable
 +	   error happens while saving, the last backup is not preserved since the user
 +	   expressed his willing of saving the file */
 +	gedit_document_save (doc, container->priv->save_flags | GEDIT_DOCUMENT_SAVE_PRESERVE_BACKUP);
 +	
 +	gedit_debug_message (DEBUG_VIEW_CONTAINER, "Done");
 +	
 +	/* Returns FALSE so the old timeout is "destroyed" */
 +	return FALSE;
 +}
 +
 +void
 +_gedit_view_container_save_as (GeditViewContainer *container,
 +			       const gchar         *uri,
 +			       const GeditEncoding *encoding)
 +{
 +	GeditDocument *doc;
 +	GeditDocumentSaveFlags save_flags;
 +
 +	g_return_if_fail (GEDIT_IS_VIEW_CONTAINER (container));
 +	g_return_if_fail ((container->priv->state == GEDIT_VIEW_CONTAINER_STATE_NORMAL) ||
 +			  (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_EXTERNALLY_MODIFIED_NOTIFICATION) ||
 +			  (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_SHOWING_PRINT_PREVIEW));
 +	g_return_if_fail (encoding != NULL);
 +
 +	g_return_if_fail (container->priv->tmp_save_uri == NULL);
 +	g_return_if_fail (container->priv->tmp_encoding == NULL);
 +
 +	doc = gedit_view_container_get_document (container);
 +	g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
 +
 +	/* reset the save flags, when saving as */
 +	container->priv->save_flags = 0;
 +
 +	if (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_EXTERNALLY_MODIFIED_NOTIFICATION)
 +	{
 +		/* We already told the user about the external
 +		 * modification: hide the message area and set
 +		 * the save flag.
 +		 */
 +
 +		set_message_area (container, NULL);
 +		save_flags = container->priv->save_flags | GEDIT_DOCUMENT_SAVE_IGNORE_MTIME;
 +	}
 +	else
 +	{
 +		save_flags = container->priv->save_flags;
 +	}
 +
 +	gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_SAVING);
 +
 +	/* uri used in error messages... strdup because errors are async
 +	 * and the string can go away, will be freed in document_saved */
 +	container->priv->tmp_save_uri = g_strdup (uri);
 +	container->priv->tmp_encoding = encoding;
 +
 +	if (container->priv->auto_save_timeout > 0)
 +		remove_auto_save_timeout (container);
 +
 +	gedit_document_save_as (doc, uri, encoding, container->priv->save_flags);
 +}
 +
 +#define GEDIT_PAGE_SETUP_KEY "gedit-page-setup-key"
 +#define GEDIT_PRINT_SETTINGS_KEY "gedit-print-settings-key"
 +
 +static GtkPageSetup *
 +get_page_setup (GeditViewContainer *container)
 +{
 +	gpointer data;
 +	GeditDocument *doc;
 +
 +	doc = gedit_view_container_get_document (container);
 +
 +	data = g_object_get_data (G_OBJECT (doc),
 +				  GEDIT_PAGE_SETUP_KEY);
 +
 +	if (data == NULL)
 +	{
 +		return _gedit_app_get_default_page_setup (gedit_app_get_default());
 +	}
 +	else
 +	{
 +		return gtk_page_setup_copy (GTK_PAGE_SETUP (data));
 +	}
 +}
 +
 +static GtkPrintSettings *
 +get_print_settings (GeditViewContainer *container)
 +{
 +	gpointer data;
 +	GeditDocument *doc;
 +
 +	doc = gedit_view_container_get_document (container);
 +
 +	data = g_object_get_data (G_OBJECT (doc),
 +				  GEDIT_PRINT_SETTINGS_KEY);
 +
 +	if (data == NULL)
 +	{
 +		return _gedit_app_get_default_print_settings (gedit_app_get_default());
 +	}
 +	else
 +	{
 +		return gtk_print_settings_copy (GTK_PRINT_SETTINGS (data));
 +	}
 +}
 +
 +/* FIXME: show the message area only if the operation will be "long" */
 +static void
 +printing_cb (GeditPrintJob       *job,
 +	     GeditPrintJobStatus  status,
 +	     GeditViewContainer  *container)
 +{
 +	g_return_if_fail (GEDIT_IS_PROGRESS_MESSAGE_AREA (container->priv->message_area));
 +
 +	gtk_widget_show (container->priv->message_area);
 +
 +	gedit_progress_message_area_set_text (GEDIT_PROGRESS_MESSAGE_AREA (container->priv->message_area),
 +					      gedit_print_job_get_status_string (job));
 +
 +	gedit_progress_message_area_set_fraction (GEDIT_PROGRESS_MESSAGE_AREA (container->priv->message_area),
 +						  gedit_print_job_get_progress (job));
 +}
 +
 +static void
++store_print_settings (GeditViewContainer *container,
++		      GeditPrintJob      *job)
++{
++	GeditDocument *doc;
++	GtkPrintSettings *settings;
++	GtkPageSetup *page_setup;
++
++	doc = gedit_view_container_get_document (container);
++
++	settings = gedit_print_job_get_print_settings (job);
++
++	/* clear n-copies settings since we do not want to
++	 * persist that one */
++	gtk_print_settings_unset (settings,
++				  GTK_PRINT_SETTINGS_N_COPIES);
++
++	/* remember settings for this document */
++	g_object_set_data_full (G_OBJECT (doc),
++				GEDIT_PRINT_SETTINGS_KEY,
++				g_object_ref (settings),
++				(GDestroyNotify)g_object_unref);
++
++	/* make them the default */
++	_gedit_app_set_default_print_settings (gedit_app_get_default (),
++					       settings);
++
++	page_setup = gedit_print_job_get_page_setup (job);
++
++	/* remember page setup for this document */
++	g_object_set_data_full (G_OBJECT (doc),
++				GEDIT_PAGE_SETUP_KEY,
++				g_object_ref (page_setup),
++				(GDestroyNotify)g_object_unref);
++
++	/* make it the default */
++	_gedit_app_set_default_page_setup (gedit_app_get_default (),
++					   page_setup);
++}
++
++static void
 +done_printing_cb (GeditPrintJob       *job,
 +		  GeditPrintJobResult  result,
 +		  const GError        *error,
 +		  GeditViewContainer  *container)
 +{
 +	GeditView *view;
 +
 +	g_return_if_fail (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_PRINT_PREVIEWING ||
 +			  container->priv->state == GEDIT_VIEW_CONTAINER_STATE_SHOWING_PRINT_PREVIEW ||
 +			  container->priv->state == GEDIT_VIEW_CONTAINER_STATE_PRINTING);
 +
 +	if (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_SHOWING_PRINT_PREVIEW)
 +	{
 +		/* print preview has been destroyed... */
 +		container->priv->print_preview = NULL;
 +	}
 +	else
 +	{
 +		g_return_if_fail (GEDIT_IS_PROGRESS_MESSAGE_AREA (container->priv->message_area));
 +
 +		set_message_area (container, NULL); /* destroy the message area */
 +	}
 +
 +	// TODO: check status and error
 +
- 	/* Save the print settings and the page setup */ 
 +	if (result ==  GEDIT_PRINT_JOB_RESULT_OK)
 +	{
- 		GeditDocument *doc;
- 		GtkPrintSettings *settings;
- 		GtkPageSetup *page_setup;
- 
- 		doc = gedit_view_container_get_document (container);
- 
- 		settings = gedit_print_job_get_print_settings (job);
- 
- 		/* remember settings for this document */
- 		g_object_set_data_full (G_OBJECT (doc),
- 					GEDIT_PRINT_SETTINGS_KEY,
- 					g_object_ref (settings),
- 					(GDestroyNotify)g_object_unref);
- 
- 		/* make them the default */
- 		_gedit_app_set_default_print_settings (gedit_app_get_default (),
- 						       settings);
- 
- 		page_setup = gedit_print_job_get_page_setup (job);
- 
- 		/* remember page setup for this document */
- 		g_object_set_data_full (G_OBJECT (doc),
- 					GEDIT_PAGE_SETUP_KEY,
- 					g_object_ref (page_setup),
- 					(GDestroyNotify)g_object_unref);
- 
- 		/* make it the default */
- 		_gedit_app_set_default_page_setup (gedit_app_get_default (),
- 						   page_setup);
++		store_print_settings (container, job);
 +	}
 +
 +#if 0
 +	if (container->priv->print_preview != NULL)
 +	{
 +		/* If we were printing while showing the print preview,
 +		   see bug #352658 */
 +		gtk_widget_destroy (container->priv->print_preview);
 +		g_return_if_fail (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_PRINTING);
 +	}
 +#endif
 +
 +	gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_NORMAL);
 +
 +	view = gedit_view_container_get_view (container);
 +	gtk_widget_grab_focus (GTK_WIDGET (view));
 +
 + 	g_object_unref (container->priv->print_job);
 +	container->priv->print_job = NULL;
 +}
 +
 +#if 0
 +static void
 +print_preview_destroyed (GtkWidget *preview,
 +			 GeditViewContainer  *container)
 +{
 +	container->priv->print_preview = NULL;
 +
 +	if (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_SHOWING_PRINT_PREVIEW)
 +	{
 +		GeditView *view;
 +
 +		gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_NORMAL);
 +
 +		view = gedit_view_container_get_view (container);
 +		gtk_widget_grab_focus (GTK_WIDGET (view));
 +	}
 +	else
 +	{
 +		/* This should happen only when printing while showing the print
 +		 * preview. In this case let us continue whithout changing
 +		 * the state and show the document. See bug #352658 */
 +		gtk_widget_show (container->priv->view_scrolled_window);
 +		
 +		g_return_if_fail (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_PRINTING);
 +	}	
 +}
 +#endif
 +
 +static void
 +show_preview_cb (GeditPrintJob       *job,
 +		 GeditPrintPreview   *preview,
 +		 GeditViewContainer            *container)
 +{
 +//	g_return_if_fail (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_PRINT_PREVIEWING);
 +	g_return_if_fail (container->priv->print_preview == NULL);
 +
 +	set_message_area (container, NULL); /* destroy the message area */
 +
 +	container->priv->print_preview = GTK_WIDGET (preview);
 +	gtk_box_pack_end (GTK_BOX (container),
 +			  container->priv->print_preview,
 +			  TRUE,
 +			  TRUE,
 +			  0);
 +	gtk_widget_show (container->priv->print_preview);
 +	gtk_widget_grab_focus (container->priv->print_preview);
 +
 +/* when the preview gets destroyed we get "done" signal
 +	g_signal_connect (container->priv->print_preview,
 +			  "destroy",
 +			  G_CALLBACK (print_preview_destroyed),
 +			  container);
 +*/
 +	gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_SHOWING_PRINT_PREVIEW);
 +}
 +
 +#if 0
 +
 +static void
 +set_print_preview (GeditViewContainer  *container,
 +		   GtkWidget *print_preview)
 +{
 +	if (container->priv->print_preview == print_preview)
 +		return;
 +		
 +	if (container->priv->print_preview != NULL)
 +		gtk_widget_destroy (container->priv->print_preview);
 +
 +	container->priv->print_preview = print_preview;
 +
 +	gtk_box_pack_end (GTK_BOX (container),
 +			  container->priv->print_preview,
 +			  TRUE,
 +			  TRUE,
 +			  0);		
 +
 +	gtk_widget_grab_focus (container->priv->print_preview);
 +
 +	g_signal_connect (container->priv->print_preview,
 +			  "destroy",
 +			  G_CALLBACK (print_preview_destroyed),
 +			  container);
 +}
 +
 +static void
 +preview_finished_cb (GtkSourcePrintJob *pjob, GeditViewContainer *container)
 +{
 +	GnomePrintJob *gjob;
 +	GtkWidget *preview = NULL;
 +
 +	g_return_if_fail (GEDIT_IS_PROGRESS_MESSAGE_AREA (container->priv->message_area));
 +	set_message_area (container, NULL); /* destroy the message area */
 +	
 +	gjob = gtk_source_print_job_get_print_job (pjob);
 +
 +	preview = gedit_print_job_preview_new (gjob);	
 + 	g_object_unref (gjob);
 +	
 +	set_print_preview (container, preview);
 +	
 +	gtk_widget_show (preview);
 +	g_object_unref (pjob);
 +	
 +	gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_SHOWING_PRINT_PREVIEW);
 +}
 +
 +
 +#endif
 +
 +static void
 +print_cancelled (GtkWidget          *area,
 +                 gint                response_id,
 +                 GeditViewContainer *container)
 +{
 +	g_return_if_fail (GEDIT_IS_PROGRESS_MESSAGE_AREA (container->priv->message_area));
 +
 +	gedit_print_job_cancel (container->priv->print_job);
 +
 +	g_debug ("print_cancelled");
 +}
 +
 +static void
 +show_printing_message_area (GeditViewContainer *container,
 +			    gboolean preview)
 +{
 +	GtkWidget *area;
 +
 +	if (preview)
 +		area = gedit_progress_message_area_new (GTK_STOCK_PRINT_PREVIEW,
 +							"",
 +							TRUE);
 +	else
 +		area = gedit_progress_message_area_new (GTK_STOCK_PRINT,
 +							"",
 +							TRUE);
 +
 +	g_signal_connect (area,
 +			  "response",
 +			  G_CALLBACK (print_cancelled),
 +			  container);
 +	
 +	set_message_area (container, area);
 +}
 +
 +#if !GTK_CHECK_VERSION (2, 17, 4)
 +
 +static void
 +page_setup_done_cb (GtkPageSetup       *setup,
 +		    GeditViewContainer *container)
 +{
 +	if (setup != NULL)
 +	{
 +		GeditDocument *doc;
 +
 +		doc = gedit_view_container_get_document (container);
 +
 +		/* remember it for this document */
 +		g_object_set_data_full (G_OBJECT (doc),
 +					GEDIT_PAGE_SETUP_KEY,
 +					g_object_ref (setup),
 +					(GDestroyNotify)g_object_unref);
 +
 +		/* make it the default */
 +		_gedit_app_set_default_page_setup (gedit_app_get_default(),
 +						   setup);
 +	}
 +}
 +
 +void 
 +_gedit_view_container_page_setup (GeditViewContainer *container)
 +{
 +	GtkPageSetup *setup;
 +	GtkPrintSettings *settings;
 +
 +	g_return_if_fail (GEDIT_IS_VIEW_CONTAINER (container));
 +
 +	setup = get_page_setup (container);
 +	settings = get_print_settings (container);
 +
 +	gtk_print_run_page_setup_dialog_async (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (container))),
 +					       setup,
 +					       settings,
 +					       (GtkPageSetupDoneFunc) page_setup_done_cb,
 +					       container);
 +
 +	/* CHECK: should we unref setup and settings? */
 +}
 +
 +#endif
 +
 +static void
 +gedit_view_container_print_or_print_preview (GeditViewContainer      *container,
 +					     GtkPrintOperationAction  print_action)
 +{
 +	GeditView *view;
 +	gboolean is_preview;
 +	GtkPageSetup *setup;
 +	GtkPrintSettings *settings;
 +	GtkPrintOperationResult res;
 +	GError *error = NULL;
 +
 +	g_return_if_fail (container->priv->print_job == NULL);
 +	g_return_if_fail (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_NORMAL);
 +
 +	view = gedit_view_container_get_view (container);
 +
 +	is_preview = (print_action == GTK_PRINT_OPERATION_ACTION_PREVIEW);
 +
 +	container->priv->print_job = gedit_print_job_new (view);
 +	g_object_add_weak_pointer (G_OBJECT (container->priv->print_job),
 +				   (gpointer *) &container->priv->print_job);
 +
 +	show_printing_message_area (container, is_preview);
 +
 +	g_signal_connect (container->priv->print_job,
 +			  "printing",
 +			  G_CALLBACK (printing_cb),
 +			  container);
 +	g_signal_connect (container->priv->print_job,
 +			  "show-preview",
 +			  G_CALLBACK (show_preview_cb),
 +			  container);
 +	g_signal_connect (container->priv->print_job,
 +			  "done",
 +			  G_CALLBACK (done_printing_cb),
 +			  container);
 +
 +	if (is_preview)
 +		gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_PRINT_PREVIEWING);
 +	else
 +		gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_PRINTING);
 +
 +	setup = get_page_setup (container);
 +	settings = get_print_settings (container);
 +
 +	res = gedit_print_job_print (container->priv->print_job,
 +				     print_action,
 +				     setup,
 +				     settings,
 +				     GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (container))),
 +				     &error);
 +
 +	// TODO: manage res in the correct way
 +	if (res == GTK_PRINT_OPERATION_RESULT_ERROR)
 +	{
 +		/* FIXME: go in error state */
 +		gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_NORMAL);
 +		g_warning ("Async print preview failed (%s)", error->message);
 +		g_object_unref (container->priv->print_job);
 +		g_error_free (error);
 +	}
 +}
 +
 +void 
 +_gedit_view_container_print (GeditViewContainer *container)
 +{
 +	g_return_if_fail (GEDIT_IS_VIEW_CONTAINER (container));
 +
 +	/* FIXME: currently we can have just one printoperation going on
 +	 * at a given time, so before starting the print we close the preview.
 +	 * Would be nice to handle it properly though */
 +	if (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_SHOWING_PRINT_PREVIEW)
 +	{
 +		gtk_widget_destroy (container->priv->print_preview);
 +	}
 +
 +	gedit_view_container_print_or_print_preview (container,
 +						     GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG);
 +}
 +
 +void
 +_gedit_view_container_print_preview (GeditViewContainer *container)
 +{
 +	g_return_if_fail (GEDIT_IS_VIEW_CONTAINER (container));
 +
 +	gedit_view_container_print_or_print_preview (container,
 +						     GTK_PRINT_OPERATION_ACTION_PREVIEW);
 +}
 +
 +void 
 +_gedit_view_container_mark_for_closing (GeditViewContainer *container)
 +{
 +	g_return_if_fail (GEDIT_IS_VIEW_CONTAINER (container));
 +	g_return_if_fail (container->priv->state == GEDIT_VIEW_CONTAINER_STATE_NORMAL);
 +	
 +	gedit_view_container_set_state (container, GEDIT_VIEW_CONTAINER_STATE_CLOSING);
 +}
 +
 +gboolean
 +_gedit_view_container_can_close (GeditViewContainer *container)
 +{
 +	GeditDocument *doc;
 +	GeditViewContainerState ts;
 +
 +	g_return_val_if_fail (GEDIT_IS_VIEW_CONTAINER (container), FALSE);
 +
 +	ts = gedit_view_container_get_state (container);
 +
 +	/* if we are loading or reverting, the container can be closed */
 +	if ((ts == GEDIT_VIEW_CONTAINER_STATE_LOADING)       ||
 +	    (ts == GEDIT_VIEW_CONTAINER_STATE_LOADING_ERROR) ||
 +	    (ts == GEDIT_VIEW_CONTAINER_STATE_REVERTING)     ||
 +	    (ts == GEDIT_VIEW_CONTAINER_STATE_REVERTING_ERROR)) /* CHECK: I'm not sure this is the right behavior for REVERTING ERROR */
 +		return TRUE;
 +
 +	/* Do not close container with saving errors */
 +	if (ts == GEDIT_VIEW_CONTAINER_STATE_SAVING_ERROR)
 +		return FALSE;
 +		
 +	doc = gedit_view_container_get_document (container);
 +
 +	/* TODO: we need to save the file also if it has been externally
 +	   modified - Paolo (Oct 10, 2005) */
 +
 +	return (!gedit_document_get_modified (doc) &&
 +		!gedit_document_get_deleted (doc));
 +}
 +
 +/**
 + * gedit_view_container_get_auto_save_enabled:
 + * @container: a #GeditViewContainer
 + * 
 + * Gets the current state for the autosave feature
 + * 
 + * Return value: %TRUE if the autosave is enabled, else %FALSE
 + **/
 +gboolean
 +gedit_view_container_get_auto_save_enabled (GeditViewContainer *container)
 +{
 +	gedit_debug (DEBUG_VIEW_CONTAINER);
 +
 +	g_return_val_if_fail (GEDIT_IS_VIEW_CONTAINER (container), FALSE);
 +
 +	return container->priv->auto_save;
 +}
 +
 +/**
 + * gedit_view_container_set_auto_save_enabled:
 + * @container: a #GeditViewContainer
 + * @enable: enable (%TRUE) or disable (%FALSE) auto save
 + * 
 + * Enables or disables the autosave feature. It does not install an
 + * autosave timeout if the document is new or is read-only
 + **/
 +void
 +gedit_view_container_set_auto_save_enabled (GeditViewContainer *container, 
 +					    gboolean enable)
 +{
 +	GeditDocument *doc = NULL;
 +	GeditLockdownMask lockdown;
 +	
 +	gedit_debug (DEBUG_VIEW_CONTAINER);
 +
 +	g_return_if_fail (GEDIT_IS_VIEW_CONTAINER (container));
 +
 +	/* Force disabling when lockdown is active */
 +	lockdown = gedit_app_get_lockdown (gedit_app_get_default());
 +	if (lockdown & GEDIT_LOCKDOWN_SAVE_TO_DISK)
 +		enable = FALSE;
 +	
 +	doc = gedit_view_container_get_document (container);
 +
 +	if (container->priv->auto_save == enable)
 +		return;
 +
 +	container->priv->auto_save = enable;
 +
 + 	if (enable && 
 + 	    (container->priv->auto_save_timeout <=0) &&
 + 	    !gedit_document_is_untitled (doc) &&
 + 	    !gedit_document_get_readonly (doc))
 + 	{
 + 		if ((container->priv->state != GEDIT_VIEW_CONTAINER_STATE_LOADING) &&
 +		    (container->priv->state != GEDIT_VIEW_CONTAINER_STATE_SAVING) &&
 +		    (container->priv->state != GEDIT_VIEW_CONTAINER_STATE_REVERTING) &&
 +		    (container->priv->state != GEDIT_VIEW_CONTAINER_STATE_LOADING_ERROR) &&
 +		    (container->priv->state != GEDIT_VIEW_CONTAINER_STATE_SAVING_ERROR) &&
 +		    (container->priv->state != GEDIT_VIEW_CONTAINER_STATE_REVERTING_ERROR))
 +		{
 +			install_auto_save_timeout (container);
 +		}
 +		/* else: the timeout will be installed when loading/saving/reverting
 +		         will terminate */
 +		
 +		return;
 +	}
 + 		
 + 	if (!enable && (container->priv->auto_save_timeout > 0))
 + 	{
 +		remove_auto_save_timeout (container);
 +		
 + 		return; 
 + 	} 
 +
 + 	g_return_if_fail ((!enable && (container->priv->auto_save_timeout <= 0)) ||  
 + 			  gedit_document_is_untitled (doc) || gedit_document_get_readonly (doc)); 
 +}
 +
 +/**
 + * gedit_view_container_get_auto_save_interval:
 + * @container: a #GeditViewContainer
 + * 
 + * Gets the current interval for the autosaves
 + * 
 + * Return value: the value of the autosave
 + **/
 +gint 
 +gedit_view_container_get_auto_save_interval (GeditViewContainer *container)
 +{
 +	gedit_debug (DEBUG_VIEW_CONTAINER);
 +
 +	g_return_val_if_fail (GEDIT_IS_VIEW_CONTAINER (container), 0);
 +
 +	return container->priv->auto_save_interval;
 +}
 +
 +/**
 + * gedit_view_container_set_auto_save_interval:
 + * @container: a #GeditViewContainer
 + * @interval: the new interval
 + * 
 + * Sets the interval for the autosave feature. It does nothing if the
 + * interval is the same as the one already present. It removes the old
 + * interval timeout and adds a new one with the autosave passed as
 + * argument.
 + **/
 +void 
 +gedit_view_container_set_auto_save_interval (GeditViewContainer *container, 
 +					     gint interval)
 +{
 +	GeditDocument *doc = NULL;
 +	
 +	gedit_debug (DEBUG_VIEW_CONTAINER);
 +	
 +	g_return_if_fail (GEDIT_IS_VIEW_CONTAINER (container));
 +
 +	doc = gedit_view_container_get_document (container);
 +
 +	g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
 +	g_return_if_fail (interval > 0);
 +
 +	if (container->priv->auto_save_interval == interval)
 +		return;
 +
 +	container->priv->auto_save_interval = interval;
 +		
 +	if (!container->priv->auto_save)
 +		return;
 +
 +	if (container->priv->auto_save_timeout > 0)
 +	{
 +		g_return_if_fail (!gedit_document_is_untitled (doc));
 +		g_return_if_fail (!gedit_document_get_readonly (doc));
 +
 +		remove_auto_save_timeout (container);
 +
 +		install_auto_save_timeout (container);
 +	}
 +}
diff --cc gedit/gedit-window-private.h
index 819e659,f577438..da21671
--- a/gedit/gedit-window-private.h
+++ b/gedit/gedit-window-private.h
@@@ -106,8 -111,12 +112,12 @@@ struct _GeditWindowPrivat
  
  	GFile          *default_location;
  
 -	gboolean        removing_tabs : 1;
 +	gboolean        removing_pages : 1;
  	gboolean        dispose_has_run : 1;
+ 
+ #ifdef OS_OSX
+ 	IgeMacMenuGroup *mac_menu_group;
+ #endif
  };
  
  G_END_DECLS
diff --cc gedit/gedit-window.c
index 14784ca,98ebbf5..18e4808
--- a/gedit/gedit-window.c
+++ b/gedit/gedit-window.c
@@@ -56,9 -56,11 +56,13 @@@
  #include "gedit-enum-types.h"
  #include "gedit-dirs.h"
  #include "gedit-status-combo-box.h"
 +#include "gedit-text-buffer.h"
 +#include "gedit-text-view.h"
  
+ #ifdef OS_OSX
+ #include "osx/gedit-osx.h"
+ #endif
+ 
  #define LANGUAGE_NONE (const gchar *)"LangNone"
  #define GEDIT_UIFILE "gedit-ui.xml"
  #define TAB_WIDTH_DATA "GeditWindowTabWidthData"
@@@ -344,11 -402,16 +404,16 @@@ gedit_window_class_init (GeditWindowCla
  	widget_class->configure_event = gedit_window_configure_event;
  	widget_class->key_press_event = gedit_window_key_press_event;
  
+ #ifdef OS_OSX
+ 	widget_class->focus_in_event = gedit_window_focus_in_event;
+ 	widget_class->focus_out_event = gedit_window_focus_out_event;
+ #endif
+ 
 -	signals[TAB_ADDED] =
 -		g_signal_new ("tab_added",
 +	signals[PAGE_ADDED] =
 +		g_signal_new ("page_added",
  			      G_OBJECT_CLASS_TYPE (object_class),
  			      G_SIGNAL_RUN_FIRST,
 -			      G_STRUCT_OFFSET (GeditWindowClass, tab_added),
 +			      G_STRUCT_OFFSET (GeditWindowClass, page_added),
  			      NULL, NULL,
  			      g_cclosure_marshal_VOID__OBJECT,
  			      G_TYPE_NONE,
@@@ -780,10 -780,10 +845,10 @@@ set_sensitivity_according_to_page (Gedi
  					      "FilePrint");
  	gtk_action_set_sensitive (action,
  				  (state_normal ||
 -				  (state == GEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW)) &&
 +				  (state == GEDIT_VIEW_CONTAINER_STATE_SHOWING_PRINT_PREVIEW)) &&
  				  !(lockdown & GEDIT_LOCKDOWN_PRINTING));
  				  
- 	action = gtk_action_group_get_action (window->priv->action_group,
+ 	action = gtk_action_group_get_action (window->priv->close_action_group,
  					      "FileClose");
  
  	gtk_action_set_sensitive (action,
@@@ -2132,9 -2199,13 +2207,13 @@@ set_title (GeditWindow *window
  	gchar *title = NULL;
  	gint len;
  
 -	if (window->priv->active_tab == NULL)
 +	if (window->priv->active_page == NULL)
  	{
+ #ifdef OS_OSX
+ 		gedit_osx_set_window_title (window, "gedit", NULL);
+ #else
  		gtk_window_set_title (GTK_WINDOW (window), "gedit");
+ #endif
  		return;
  	}
  
@@@ -2573,10 -2595,21 +2659,21 @@@ set_sensitivity_according_to_window_sta
  	{
  		if (!gtk_action_group_get_sensitive (window->priv->action_group))
  			gtk_action_group_set_sensitive (window->priv->action_group,
 -							window->priv->num_tabs > 0);
 +							window->priv->num_pages > 0);
  		if (!gtk_action_group_get_sensitive (window->priv->quit_action_group))
  			gtk_action_group_set_sensitive (window->priv->quit_action_group,
 -							window->priv->num_tabs > 0);
 +							window->priv->num_pages > 0);
+ 		if (!gtk_action_group_get_sensitive (window->priv->close_action_group))
+ 		{
+ #ifdef OS_OSX
+ 			/* On OS X, File Close is always sensitive */
+ 			gtk_action_group_set_sensitive (window->priv->close_action_group,
+ 							TRUE);
+ #else
+ 			gtk_action_group_set_sensitive (window->priv->close_action_group,
 -							window->priv->num_tabs > 0);
++							window->priv->num_pages > 0);
+ #endif
+ 		}
  	}
  }
  
@@@ -3185,40 -3210,65 +3282,61 @@@ editable_changed (GeditView  *view
  }
  
  static void
 -update_sensitivity_according_to_open_tabs (GeditWindow *window)
++update_sensitivity_according_to_open_pages (GeditWindow *window)
+ {
+ 	GtkAction *action;
+ 
+ 	/* Set sensitivity */
+ 	gtk_action_group_set_sensitive (window->priv->action_group,
 -					window->priv->num_tabs != 0);
++					window->priv->num_pages != 0);
+ 
+ 	action = gtk_action_group_get_action (window->priv->action_group,
+ 					     "DocumentsMoveToNewWindow");
+ 	gtk_action_set_sensitive (action,
 -				  window->priv->num_tabs > 1);
++				  window->priv->num_pages > 1);
+ 
+ 	/* Do not set close action insensitive on OS X */
+ #ifndef OS_OSX
+ 	gtk_action_group_set_sensitive (window->priv->close_action_group,
 -	                                window->priv->num_tabs != 0);
++	                                window->priv->num_pages != 0);
+ #endif
+ }
+ 
+ static void
 -notebook_tab_added (GeditNotebook *notebook,
 -		    GeditTab      *tab,
 -		    GeditWindow   *window)
 +connect_per_container_signals (GeditWindow        *window,
 +			       GeditViewContainer *container)
  {
 -	GeditView *view;
 +	GList *views, *l;
  	GeditDocument *doc;
  
 -	gedit_debug (DEBUG_WINDOW);
 +	views = gedit_view_container_get_views (container);
 +	doc = gedit_view_container_get_document (container);
  
 -	g_return_if_fail ((window->priv->state & GEDIT_WINDOW_STATE_SAVING_SESSION) == 0);
 -	
 -	++window->priv->num_tabs;
 -
 -	update_sensitivity_according_to_open_tabs (window);
 -
 -	view = gedit_tab_get_view (tab);
 -	doc = gedit_tab_get_document (tab);
 -
 -	/* IMPORTANT: remember to disconnect the signal in notebook_tab_removed
 -	 * if a new signal is connected here */
 -
 -	g_signal_connect (tab, 
 +	g_signal_connect (container,
  			 "notify::name",
 -			  G_CALLBACK (sync_name), 
 +			  G_CALLBACK (sync_name),
  			  window);
 -	g_signal_connect (tab, 
 +	g_signal_connect (container, 
  			 "notify::state",
 -			  G_CALLBACK (sync_state), 
 +			  G_CALLBACK (sync_state),
  			  window);
  
 -	g_signal_connect (doc,
 -			  "cursor-moved",
 -			  G_CALLBACK (update_cursor_position_statusbar),
 -			  window);
 -	g_signal_connect (doc,
 -			  "notify::can-search-again",
 -			  G_CALLBACK (can_search_again),
 -			  window);
 +	if (GEDIT_IS_TEXT_BUFFER (doc))
 +	{
 +		g_signal_connect (doc,
 +				  "cursor-moved",
 +				  G_CALLBACK (update_cursor_position_statusbar),
 +				  window);
 +		g_signal_connect (doc,
 +				  "notify::language",
 +				  G_CALLBACK (sync_languages_menu),
 +				  window);
 +		g_signal_connect (doc,
 +				  "notify::can-search-again",
 +				  G_CALLBACK (can_search_again),
 +				  window);
 +	}
 +	
  	g_signal_connect (doc,
  			  "notify::can-undo",
  			  G_CALLBACK (can_undo),
@@@ -3479,32 -3410,17 +3597,17 @@@ notebook_page_removed (GeditNotebook *n
  		}
  	}
  
- 	/* Set sensitivity */
 -	update_sensitivity_according_to_open_tabs (window);
++	update_sensitivity_according_to_open_pages (window);
+ 
 -	if (window->priv->num_tabs == 0)
 +	if (window->priv->num_pages == 0)
  	{
- 		if (gtk_action_group_get_sensitive (window->priv->action_group))
- 			gtk_action_group_set_sensitive (window->priv->action_group,
- 							FALSE);
- 
- 		action = gtk_action_group_get_action (window->priv->action_group,
- 						      "ViewHighlightMode");
- 		gtk_action_set_sensitive (action, FALSE);
- 
  		gedit_plugins_engine_update_plugins_ui (gedit_plugins_engine_get_default (),
 -							 window);
 +							window);
  	}
  
- 	if (window->priv->num_pages <= 1)
- 	{
- 		action = gtk_action_group_get_action (window->priv->action_group,
- 						     "DocumentsMoveToNewWindow");
- 		gtk_action_set_sensitive (action,
- 					  FALSE);
- 	}
- 
  	update_window_state (window);
  
 -	g_signal_emit (G_OBJECT (window), signals[TAB_REMOVED], 0, tab);	
 +	g_signal_emit (G_OBJECT (window), signals[PAGE_REMOVED], 0, page);
  }
  
  static void
@@@ -4101,6 -4027,12 +4225,12 @@@ gedit_window_init (GeditWindow *window
  	 * This needs to be done after plugins activatation */
  	init_panels_visibility (window);
  
 -	update_sensitivity_according_to_open_tabs (window);
++	update_sensitivity_according_to_open_pages (window);
+ 
+ #ifdef OS_OSX
+ 	setup_mac_menu (window);
+ #endif
+ 
  	gedit_debug_message (DEBUG_WINDOW, "END");
  }
  
@@@ -4192,15 -4107,20 +4322,20 @@@ gedit_window_create_page (GeditWindow *
  
  	g_return_val_if_fail (GEDIT_IS_WINDOW (window), NULL);
  
 -	tab = GEDIT_TAB (_gedit_tab_new ());	
 -	gtk_widget_show (GTK_WIDGET (tab));	
 +	page = GEDIT_PAGE (_gedit_page_new (NULL));
 +	gtk_widget_show (GTK_WIDGET (page));
  
 -	gedit_notebook_add_tab (GEDIT_NOTEBOOK (window->priv->notebook),
 -				tab,
 -				-1,
 -				jump_to);
 +	gedit_notebook_add_page (GEDIT_NOTEBOOK (window->priv->notebook),
 +				 page,
 +				 -1,
 +				 jump_to);
  
+ 	if (!GTK_WIDGET_VISIBLE (window))
+ 	{
+ 		gtk_window_present (GTK_WINDOW (window));
+ 	}
+ 
 -	return tab;
 +	return page;
  }
  
  /**
@@@ -4233,34 -4152,39 +4368,39 @@@ gedit_window_create_page_from_uri (Gedi
  	g_return_val_if_fail (GEDIT_IS_WINDOW (window), NULL);
  	g_return_val_if_fail (uri != NULL, NULL);
  
 -	tab = _gedit_tab_new_from_uri (uri,
 -				       encoding,
 -				       line_pos,
 -				       create);	
 -	if (tab == NULL)
 +	container = _gedit_view_container_new_from_uri (uri,
 +							encoding,
 +							line_pos,
 +							create);
 +	if (container == NULL)
  		return NULL;
  
 -	gtk_widget_show (tab);	
 -	
 -	gedit_notebook_add_tab (GEDIT_NOTEBOOK (window->priv->notebook),
 -				GEDIT_TAB (tab),
 -				-1,
 -				jump_to);
 +	page = _gedit_page_new (GEDIT_VIEW_CONTAINER (container));
 +	gtk_widget_show (page);
  
 +	gedit_notebook_add_page (GEDIT_NOTEBOOK (window->priv->notebook),
 +				 GEDIT_PAGE (page),
 +				 -1,
 +				 jump_to);
  
+ 	if (!GTK_WIDGET_VISIBLE (window))
+ 	{
+ 		gtk_window_present (GTK_WINDOW (window));
+ 	}
+ 
 -	return GEDIT_TAB (tab);
 -}				  
 +	return GEDIT_PAGE (page);
 +}
  
  /**
 - * gedit_window_get_active_tab:
 + * gedit_window_get_active_page:
   * @window: a GeditWindow
   *
 - * Gets the active #GeditTab in the @window.
 + * Gets the active #GeditPage in the @window.
   *
 - * Returns: the active #GeditTab in the @window.
 + * Returns: the active #GeditPage in the @window.
   */
 -GeditTab *
 -gedit_window_get_active_tab (GeditWindow *window)
 +GeditPage *
 +gedit_window_get_active_page (GeditWindow *window)
  {
  	g_return_val_if_fail (GEDIT_IS_WINDOW (window), NULL);
  	
@@@ -4824,4 -4733,31 +4963,3 @@@ gedit_window_get_message_bus (GeditWind
  	
  	return window->priv->message_bus;
  }
--
 -/**
 - * gedit_window_get_tab_from_uri:
 - * @window: a #GeditWindow
 - * @uri: the uri to get the #GeditTab
 - *
 - * Gets the #GeditTab that matches @uri.
 - *
 - * Returns: the #GeditTab associated with @uri.
 - *
 - * Deprecated: 2.24: Use gedit_window_get_tab_from_location() instead.
 - */
 -GeditTab *
 -gedit_window_get_tab_from_uri (GeditWindow *window,
 -			       const gchar *uri)
 -{
 -	GFile *f;
 -	GeditTab *tab;
 -
 -	g_return_val_if_fail (GEDIT_IS_WINDOW (window), NULL);
 -	g_return_val_if_fail (uri != NULL, NULL);
 -
 -	f = g_file_new_for_uri (uri);
 -	tab = gedit_window_get_tab_from_location (window, f);
 -	g_object_unref (f);
 -
 -	return tab;
 -}
diff --cc gedit/gedit.c
index e912768,96069e3..0ed0788
--- a/gedit/gedit.c
+++ b/gedit/gedit.c
@@@ -726,6 -739,10 +739,11 @@@ main (int argc, char *argv[]
  	}
  
  	gedit_debug_message (DEBUG_APP, "Start gtk-main");
 -	
++
+ #ifdef OS_OSX
+ 	gedit_osx_init(gedit_app_get_default ());
+ #endif
++
  	gtk_main();
  
  #ifndef G_OS_WIN32



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]