[Xfce4-commits] r25379 - in mousepad/branches/nick_0_3: . mousepad

Nick Schermer nick at xfce.org
Wed Apr 4 17:50:00 CEST 2007


Author: nick
Date: 2007-04-04 15:50:00 +0000 (Wed, 04 Apr 2007)
New Revision: 25379

Added:
   mousepad/branches/nick_0_3/mousepad/mousepad-document.c
   mousepad/branches/nick_0_3/mousepad/mousepad-document.h
   mousepad/branches/nick_0_3/mousepad/mousepad-exo.c
   mousepad/branches/nick_0_3/mousepad/mousepad-exo.h
   mousepad/branches/nick_0_3/mousepad/mousepad-marshal.list
   mousepad/branches/nick_0_3/mousepad/mousepad-search-bar.c
   mousepad/branches/nick_0_3/mousepad/mousepad-search-bar.h
   mousepad/branches/nick_0_3/mousepad/mousepad-statusbar.c
   mousepad/branches/nick_0_3/mousepad/mousepad-statusbar.h
   mousepad/branches/nick_0_3/mousepad/mousepad-types.h
Removed:
   mousepad/branches/nick_0_3/mousepad/mousepad-screen.c
   mousepad/branches/nick_0_3/mousepad/mousepad-screen.h
   mousepad/branches/nick_0_3/mousepad/mousepad-tab-label.c
   mousepad/branches/nick_0_3/mousepad/mousepad-tab-label.h
Modified:
   mousepad/branches/nick_0_3/ChangeLog
   mousepad/branches/nick_0_3/Makefile.am
   mousepad/branches/nick_0_3/NEWS
   mousepad/branches/nick_0_3/TODO
   mousepad/branches/nick_0_3/configure.in.in
   mousepad/branches/nick_0_3/mousepad/Makefile.am
   mousepad/branches/nick_0_3/mousepad/main.c
   mousepad/branches/nick_0_3/mousepad/mousepad-application.c
   mousepad/branches/nick_0_3/mousepad/mousepad-application.h
   mousepad/branches/nick_0_3/mousepad/mousepad-dbus.c
   mousepad/branches/nick_0_3/mousepad/mousepad-dbus.h
   mousepad/branches/nick_0_3/mousepad/mousepad-dialogs.c
   mousepad/branches/nick_0_3/mousepad/mousepad-file.c
   mousepad/branches/nick_0_3/mousepad/mousepad-preferences.c
   mousepad/branches/nick_0_3/mousepad/mousepad-preferences.h
   mousepad/branches/nick_0_3/mousepad/mousepad-private.h
   mousepad/branches/nick_0_3/mousepad/mousepad-view.c
   mousepad/branches/nick_0_3/mousepad/mousepad-window-ui.xml
   mousepad/branches/nick_0_3/mousepad/mousepad-window.c
   mousepad/branches/nick_0_3/mousepad/mousepad-window.h
Log:
	* configure.in.in: Mousepad does not depend on exo anymore. Only
	  when you run in maintainer-mode, exo-csource is required.
	* mousepad/mousepad-document.*: Renamed mousepad-screen to mousepad-document.
	* mousepad/mousepad-{search-bar,document,window).*: Added function for 
	  searching, including the type-ahead search bar.
	* mousepad/mousepad-statusbar.*: A custom statusbar suitable for displaying
	  the tooltips, overwrite/insert and the line- and column-number.
	* mousepad/mousepad-exo.*: The exo-bindings so we don't depend on exo anymore,
	  although I want to get rid of all of them.
	* mousepad/mousepad-marshal.list: Custom marshal for sending search signals.
	* mousepad/mousepad-types.h: Search types (a mousepad-enum-types.{c,h} is
	  generated during build).
	* Various performance inprovements and code cleanups.
	

Modified: mousepad/branches/nick_0_3/ChangeLog
===================================================================
--- mousepad/branches/nick_0_3/ChangeLog	2007-04-04 10:05:00 UTC (rev 25378)
+++ mousepad/branches/nick_0_3/ChangeLog	2007-04-04 15:50:00 UTC (rev 25379)
@@ -1,3 +1,20 @@
+2007-04-04	Nick Schermer <nick at xfce.org>
+
+	* configure.in.in: Mousepad does not depend on exo anymore. Only
+	  when you run in maintainer-mode, exo-csource is required.
+	* mousepad/mousepad-document.*: Renamed mousepad-screen to mousepad-document.
+	* mousepad/mousepad-{search-bar,document,window).*: Added function for 
+	  searching, including the type-ahead search bar.
+	* mousepad/mousepad-statusbar.*: A custom statusbar suitable for displaying
+	  the tooltips, overwrite/insert and the line- and column-number.
+	* mousepad/mousepad-exo.*: The exo-bindings so we don't depend on exo anymore,
+	  although I want to get rid of all of them.
+	* mousepad/mousepad-marshal.list: Custom marshal for sending search signals.
+	* mousepad/mousepad-types.h: Search types (a mousepad-enum-types.{c,h} is
+	  generated during build).
+	* Various performance inprovements and code cleanups.
+	
+
 2007-03-03	Nick Schermer <nick at xfce.org>
 
 	* mousepad/mousepad-dialogs.{c,h}: Add response actions for Mousepad so it's

Modified: mousepad/branches/nick_0_3/Makefile.am
===================================================================
--- mousepad/branches/nick_0_3/Makefile.am	2007-04-04 10:05:00 UTC (rev 25378)
+++ mousepad/branches/nick_0_3/Makefile.am	2007-04-04 15:50:00 UTC (rev 25379)
@@ -1,8 +1,8 @@
 # $Id$
 
-SUBDIRS =								\
-	icons								\
-	mousepad                                                        \
+SUBDIRS =									\
+	icons									\
+	mousepad                                                        	\
 	po
 
 distclean-local:
@@ -13,7 +13,7 @@
 	@rm -f $(PACKAGE)-$(VERSION).tar.gz
 
 desktopdir = $(datadir)/applications
-desktop_in_in_files = 							\
+desktop_in_in_files = 								\
 	Mousepad.desktop.in.in
 desktop_in_files = $(desktop_in_in_files:.desktop.in.in=.desktop.in)
 %.desktop.in: %.desktop.in.in
@@ -21,20 +21,20 @@
 desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
 @INTLTOOL_DESKTOP_RULE@
 
-EXTRA_DIST =								\
-	intltool-extract.in						\
-	intltool-merge.in						\
-	intltool-update.in						\
+EXTRA_DIST =									\
+	intltool-extract.in							\
+	intltool-merge.in							\
+	intltool-update.in							\
 	$(desktop_in_in_files)
 
-DISTCLEANFILES =							\
-	intltool-extract						\
-	intltool-merge							\
-	intltool-update							\
-	$(desktop_in_files)						\
+DISTCLEANFILES =								\
+	intltool-extract							\
+	intltool-merge								\
+	intltool-update								\
+	$(desktop_in_files)							\
 	$(desktop_DATA)
 
-DISTCHECK_CONFIGURE_FLAGS =						\
+DISTCHECK_CONFIGURE_FLAGS =							\
 	--enable-gtk-doc
 
 # vi:set ts=8 sw=8 noet ai nocindent syntax=automake:

Modified: mousepad/branches/nick_0_3/NEWS
===================================================================
--- mousepad/branches/nick_0_3/NEWS	2007-04-04 10:05:00 UTC (rev 25378)
+++ mousepad/branches/nick_0_3/NEWS	2007-04-04 15:50:00 UTC (rev 25379)
@@ -3,6 +3,7 @@
 New core features:
   - Everything is written in GObjects.
   - Run multiple windows in one instance.
+  - Type-ahead find feature like Firefox.
   - Tab support.
   - Loading multiple files at once (in new tabs). Both multiple
     select in the open dialog and by using the command line is supported.

Modified: mousepad/branches/nick_0_3/TODO
===================================================================
--- mousepad/branches/nick_0_3/TODO	2007-04-04 10:05:00 UTC (rev 25378)
+++ mousepad/branches/nick_0_3/TODO	2007-04-04 15:50:00 UTC (rev 25379)
@@ -1,6 +1,5 @@
 - Interface
   - Dialog when closing multiple (modified) tabs.
-  - Right-click menu for the tab label.
   - Tab font color when the file is modified or readonly.
   - Test the application with a screen reader and add Atk objects
     where needed.

Modified: mousepad/branches/nick_0_3/configure.in.in
===================================================================
--- mousepad/branches/nick_0_3/configure.in.in	2007-04-04 10:05:00 UTC (rev 25378)
+++ mousepad/branches/nick_0_3/configure.in.in	2007-04-04 15:50:00 UTC (rev 25379)
@@ -7,6 +7,7 @@
 dnl ***************************
 dnl *** Version information ***
 dnl ***************************
+m4_define([mousepad_version_api], [1])
 m4_define([mousepad_version_major], [0])
 m4_define([mousepad_version_minor], [3])
 m4_define([mousepad_version_micro], [0])
@@ -59,9 +60,11 @@
 dnl **************************************
 dnl *** Substitute version information ***
 dnl **************************************
+MOUSEPAD_VERSION_API=mousepad_version_api()
 MOUSEPAD_VERSION_MAJOR=mousepad_version_major()
 MOUSEPAD_VERSION_MINOR=mousepad_version_minor()
 MOUSEPAD_VERSION_MICRO=mousepad_version_micro()
+AC_SUBST([MOUSEPAD_VERSION_API])
 AC_SUBST([MOUSEPAD_VERSION_MAJOR])
 AC_SUBST([MOUSEPAD_VERSION_MINOR])
 AC_SUBST([MOUSEPAD_VERSION_MICRO])
@@ -86,17 +89,12 @@
 dnl ***********************************
 dnl *** Check for required packages ***
 dnl ***********************************
-XDT_CHECK_PACKAGE([EXO], [exo-0.3], [0.3.2])
 XDT_CHECK_PACKAGE([GLIB], [glib-2.0], [2.12.0])
+XDT_CHECK_PACKAGE([GMODULE], [gmodule-2.0], [2.12.0])
 XDT_CHECK_PACKAGE([GTHREAD], [gthread-2.0], [2.12.0])
 XDT_CHECK_PACKAGE([GTK], [gtk+-2.0], [2.10.0])
 XDT_CHECK_PACKAGE([LIBXFCE4UTIL], [libxfce4util-1.0], [4.4.0])
 
-dnl ********************************************
-dnl *** Check for session management support ***
-dnl ********************************************
-XDT_CHECK_LIBSM()
-
 dnl **********************************
 dnl *** Optional support for D-BUS ***
 dnl **********************************

Modified: mousepad/branches/nick_0_3/mousepad/Makefile.am
===================================================================
--- mousepad/branches/nick_0_3/mousepad/Makefile.am	2007-04-04 10:05:00 UTC (rev 25378)
+++ mousepad/branches/nick_0_3/mousepad/Makefile.am	2007-04-04 15:50:00 UTC (rev 25379)
@@ -1,77 +1,105 @@
 # $Id$
 
-INCLUDES =								\
-	-I$(top_builddir)						\
-	-I$(top_srcdir)							\
-	-DBINDIR=\"$(bindir)\"						\
-	-DDATADIR=\"$(datadir)\"					\
-	-DLIBDIR=\"$(libdir)\"						\
-	-DLIBEXECDIR=\"$(libexecdir)\"					\
-	-DG_LOG_DOMAIN=\"Mousepad\"					\
-	-DLIBEXECDIR=\"$(libexecdir)\"					\
-	-DPACKAGE_LOCALE_DIR=\"$(localedir)\"				\
+INCLUDES =									\
+	-I$(top_builddir)							\
+	-I$(top_srcdir)								\
+	-DBINDIR=\"$(bindir)\"							\
+	-DDATADIR=\"$(datadir)\"						\
+	-DLIBDIR=\"$(libdir)\"							\
+	-DLIBEXECDIR=\"$(libexecdir)\"						\
+	-DG_LOG_DOMAIN=\"Mousepad\"						\
+	-DLIBEXECDIR=\"$(libexecdir)\"						\
+	-DPACKAGE_LOCALE_DIR=\"$(localedir)\"					\
 	$(PLATFORM_CPPFLAGS)
 
-bin_PROGRAMS = 								\
+bin_PROGRAMS = 									\
 	mousepad
 
-mousepad_SOURCES =							\
-	main.c								\
-	mousepad-application.c						\
-	mousepad-application.h						\
-	mousepad-dialogs.c                                              \
-	mousepad-dialogs.h                                              \
-	mousepad-file.c							\
-	mousepad-file.h							\
-	mousepad-preferences.c						\
-	mousepad-preferences.h						\
-	mousepad-private.h						\
-	mousepad-screen.c						\
-	mousepad-screen.h						\
-	mousepad-tab-label.c						\
-	mousepad-tab-label.h						\
-	mousepad-view.c							\
-	mousepad-view.h							\
-	mousepad-window.c						\
-	mousepad-window.h						\
+mousepad_headers = 								\
+	mousepad-types.h
+
+mousepad_built_sources =							\
+	mousepad-enum-types.c							\
+	mousepad-enum-types.h							\
+	mousepad-marshal.c							\
+	mousepad-marshal.h
+
+mousepad_SOURCES =								\
+	$(mousepad_headers)							\
+	$(mousepad_built_sources)						\
+	$(mousepad_dbus_sources)						\
+	main.c									\
+	mousepad-application.c							\
+	mousepad-application.h							\
+	mousepad-dialogs.c							\
+	mousepad-dialogs.h							\
+	mousepad-document.c							\
+	mousepad-document.h							\
+	mousepad-exo.c								\
+	mousepad-exo.h								\
+	mousepad-file.c								\
+	mousepad-file.h								\
+	mousepad-preferences.c							\
+	mousepad-preferences.h							\
+	mousepad-private.h							\
+	mousepad-search-bar.c							\
+	mousepad-search-bar.h							\
+	mousepad-statusbar.c							\
+	mousepad-statusbar.h							\
+	mousepad-view.c								\
+	mousepad-view.h								\
+	mousepad-window.c							\
+	mousepad-window.h							\
 	mousepad-window-ui.h
 
-mousepad_CFLAGS =							\
-	$(EXO_CFLAGS)							\
-	$(GTHREAD_CFLAGS)						\
+mousepad_CFLAGS =								\
+	$(GTK_CFLAGS)								\
+	$(LIBXFCE4UTIL_CFLAGS) \
+	$(GMODULE_CFLAGS)							\
+	$(GTHREAD_CFLAGS)							\
 	$(PLATFORM_CFLAGS)
 
-mousepad_LDFLAGS =							\
-	-no-undefined							\
-	$(LIBSM_LDFLAGS)						\
+mousepad_LDFLAGS =								\
+	-no-undefined								\
 	$(PLATFORM_LDFLAGS)
 
-mousepad_LDADD =							\
-	$(EXO_LIBS)							\
+mousepad_LDADD =								\
+	$(GTK_LIBS)								\
+	$(LIBXFCE4UTIL_LIBS) \
+	$(GMODULE_LIBS)								\
 	$(GTHREAD_LIBS)
 
 if HAVE_DBUS
-mousepad_build_sources =						\
+mousepad_built_sources +=							\
 	mousepad-dbus-infos.h
 
-mousepad_SOURCES +=							\
-	mousepad-dbus.c							\
+mousepad_dbus_sources =								\
+	mousepad-dbus.c								\
 	mousepad-dbus.h
 
-mousepad_CFLAGS +=							\
-	-DDBUS_API_SUBJECT_TO_CHANGE					\
+mousepad_CFLAGS +=								\
+	-DDBUS_API_SUBJECT_TO_CHANGE						\
 	$(DBUS_CFLAGS)
 
-mousepad_LDADD +=							\
+mousepad_LDADD +=								\
 	$(DBUS_LIBS)
 endif
 
 if MAINTAINER_MODE
-DISTCLEANFILES =							\
+CLEANFILES =									\
+	xgen-mmc								\
+	xgen-mmh								\
+	xgen-metc								\
+	xgen-meth
+
+DISTCLEANFILES =								\
+	$(mousepad_built_sources)                                       	\
+	stamp-mousepad-marshal.h						\
+	stamp-mousepad-enum-types.h						\
 	mousepad-window-ui.h
 
-BUILT_SOURCES =								\
-	$(mousepad_build_sources)                                       \
+BUILT_SOURCES =									\
+	$(mousepad_built_sources)                                       	\
 	mousepad-window-ui.h
 
 if HAVE_DBUS
@@ -81,10 +109,51 @@
 
 mousepad-window-ui.h: Makefile $(srcdir)/mousepad-window-ui.xml
 	exo-csource --static --name=mousepad_window_ui $(srcdir)/mousepad-window-ui.xml > mousepad-window-ui.h
+
+mousepad-enum-types.h: stamp-mousepad-enum-types.h
+	@true
+stamp-mousepad-enum-types.h: $(mousepad_headers) Makefile
+	( cd $(srcdir) && glib-mkenums \
+		--fhead "#ifndef __MOUSEPAD_ENUM_TYPES_H__\n#define __MOUSEPAD_ENUM_TYPES_H__\n#include <glib-object.h>\nG_BEGIN_DECLS\n" \
+		--fprod "/* enumerations from \"@filename@\" */\n" \
+		--vhead "GType @enum_name at _get_type (void) G_GNUC_CONST;\n#define MOUSEPAD_TYPE_ at ENUMSHORT@ (@enum_name at _get_type())\n" \
+		--ftail "G_END_DECLS\n\n#endif /* !__MOUSEPAD_ENUM_TYPES_H__ */" \
+		$(mousepad_headers) ) >> xgen-meth \
+	&& ( cmp -s xgen-meth mousepad-enum-types.h || cp xgen-meth mousepad-enum-types.h ) \
+	&& rm -f xgen-meth \
+	&& echo timestamp > $(@F)
+mousepad-enum-types.c: $(mousepad_headers) Makefile
+	( cd $(srcdir) && glib-mkenums \
+		--fhead "#include <mousepad/mousepad-enum-types.h>\n#include <mousepad/mousepad-types.h>" \
+		--fprod "\n/* enumerations from \"@filename@\" */" \
+		--vhead "GType\n at enum_name@_get_type (void)\n{\n\tstatic GType type = 0;\n\tif (type == 0) {\n\tstatic const G at Type@Value values[] = {"\
+		--vprod "\t{ @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
+		--vtail "\t{ 0, NULL, NULL }\n\t};\n\ttype = g_ at type@_register_static (\"@EnumName@\", values);\n  }\n\treturn type;\n}\n" \
+		$(mousepad_headers) ) >> xgen-metc \
+	&& cp xgen-metc mousepad-enum-types.c \
+	&& rm -f xgen-metc
+
+mousepad-marshal.h: stamp-mousepad-marshal.h
+	@true
+stamp-mousepad-marshal.h: mousepad-marshal.list Makefile
+	( cd $(srcdir) && glib-genmarshal \
+		--prefix=_mousepad_marshal \
+		--header mousepad-marshal.list ) >> xgen-mmh \
+	&& ( cmp -s xgen-mmh mousepad-marshal.h || cp xgen-mmh mousepad-marshal.h ) \
+	&& rm -f xgen-mmh \
+	&& echo timestamp > $(@F)
+
+mousepad-marshal.c: mousepad-marshal.list Makefile
+	( cd $(srcdir) && glib-genmarshal \
+		--prefix=_mousepad_marshal \
+		--body mousepad-marshal.list ) >> xgen-mmc \
+	&& cp xgen-mmc mousepad-marshal.c \
+	&& rm -f xgen-mmc
 endif
 
-EXTRA_DIST =								\
-	mousepad-dbus-infos.xml                                         \
+EXTRA_DIST =									\
+	mousepad-dbus-infos.xml							\
+	mousepad-marshal.list							\
 	mousepad-window-ui.xml
 
 # vi:set ts=8 sw=8 noet ai nocindent syntax=automake:

Modified: mousepad/branches/nick_0_3/mousepad/main.c
===================================================================
--- mousepad/branches/nick_0_3/mousepad/main.c	2007-04-04 10:05:00 UTC (rev 25378)
+++ mousepad/branches/nick_0_3/mousepad/main.c	2007-04-04 15:50:00 UTC (rev 25379)
@@ -83,7 +83,7 @@
 #endif
 
   /* initialize the GThread system */
-  if (!g_thread_supported ())
+  if (G_LIKELY (!g_thread_supported ()))
     g_thread_init (NULL);
 
   /* initialize Gtk+ */

Modified: mousepad/branches/nick_0_3/mousepad/mousepad-application.c
===================================================================
--- mousepad/branches/nick_0_3/mousepad/mousepad-application.c	2007-04-04 10:05:00 UTC (rev 25378)
+++ mousepad/branches/nick_0_3/mousepad/mousepad-application.c	2007-04-04 15:50:00 UTC (rev 25379)
@@ -229,6 +229,7 @@
                                   gchar               **filenames)
 {
   GtkWidget *window;
+  gboolean   succeed;
 
   _mousepad_return_if_fail (MOUSEPAD_IS_APPLICATION (application));
   _mousepad_return_if_fail (screen == NULL || GDK_IS_SCREEN (screen));
@@ -245,12 +246,19 @@
 
   /* open the filenames or an empty tab */
   if (filenames != NULL && *filenames != NULL)
-    mousepad_window_open_files (MOUSEPAD_WINDOW (window), working_directory, filenames);
+    {
+      /* try to open the files */
+      succeed = mousepad_window_open_files (MOUSEPAD_WINDOW (window), working_directory, filenames);
+
+      /* if we failed, open an empty tab */
+      if (G_UNLIKELY (succeed == FALSE))
+        mousepad_window_open_tab (MOUSEPAD_WINDOW (window), NULL);
+    }
   else
-    mousepad_window_open_tab (MOUSEPAD_WINDOW (window), NULL);
+    {
+      mousepad_window_open_tab (MOUSEPAD_WINDOW (window), NULL);
+    }
 
-  /* TODO: check if there are actually some tabs in the window, if not, open an empty tab */
-
   /* connect to the "destroy" signal */
   g_signal_connect (G_OBJECT (window), "destroy",
                     G_CALLBACK (mousepad_application_window_destroyed), application);

Modified: mousepad/branches/nick_0_3/mousepad/mousepad-application.h
===================================================================
--- mousepad/branches/nick_0_3/mousepad/mousepad-application.h	2007-04-04 10:05:00 UTC (rev 25378)
+++ mousepad/branches/nick_0_3/mousepad/mousepad-application.h	2007-04-04 15:50:00 UTC (rev 25379)
@@ -20,8 +20,6 @@
 #ifndef __MOUSEPAD_APPLICATION_H__
 #define __MOUSEPAD_APPLICATION_H__
 
-#include <exo/exo.h>
-
 G_BEGIN_DECLS
 
 typedef struct _MousepadApplicationClass MousepadApplicationClass;

Modified: mousepad/branches/nick_0_3/mousepad/mousepad-dbus.c
===================================================================
--- mousepad/branches/nick_0_3/mousepad/mousepad-dbus.c	2007-04-04 10:05:00 UTC (rev 25378)
+++ mousepad/branches/nick_0_3/mousepad/mousepad-dbus.c	2007-04-04 15:50:00 UTC (rev 25379)
@@ -33,8 +33,9 @@
 #include <dbus/dbus-glib.h>
 #include <dbus/dbus.h>
 
+#include <mousepad/mousepad-private.h>
 #include <mousepad/mousepad-dbus.h>
-#include <mousepad/mousepad-private.h>
+#include <mousepad/mousepad-application.h>
 
 
 

Modified: mousepad/branches/nick_0_3/mousepad/mousepad-dbus.h
===================================================================
--- mousepad/branches/nick_0_3/mousepad/mousepad-dbus.h	2007-04-04 10:05:00 UTC (rev 25378)
+++ mousepad/branches/nick_0_3/mousepad/mousepad-dbus.h	2007-04-04 15:50:00 UTC (rev 25379)
@@ -23,8 +23,6 @@
 typedef struct _MousepadDBusServiceClass MousepadDBusServiceClass;
 typedef struct _MousepadDBusService      MousepadDBusService;
 
-#include <mousepad/mousepad-application.h>
-
 #define MOUSEPAD_TYPE_DBUS_SERVICE            (mousepad_dbus_service_get_type ())
 #define MOUSEPAD_DBUS_SERVICE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), MOUSEPAD_TYPE_DBUS_SERVICE, MousepadDBusService))
 #define MOUSEPAD_DBUS_SERVICE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), MOUSEPAD_TYPE_DBUS_SERVICE, MousepadDBusServiceClass))

Modified: mousepad/branches/nick_0_3/mousepad/mousepad-dialogs.c
===================================================================
--- mousepad/branches/nick_0_3/mousepad/mousepad-dialogs.c	2007-04-04 10:05:00 UTC (rev 25378)
+++ mousepad/branches/nick_0_3/mousepad/mousepad-dialogs.c	2007-04-04 15:50:00 UTC (rev 25379)
@@ -50,15 +50,13 @@
 {
   static const gchar *authors[] =
   {
+    "Benedikt Meurer <benny at xfce.org>",
     "Erik Harrison <erikharrison at xfce.org>",
     "Nick Schermer <nick at xfce.org>",
-    "Benedikt Meurer <benny at xfce.org>",
     NULL,
   };
 
   /* show the dialog */
-  gtk_about_dialog_set_email_hook (exo_url_about_dialog_hook, NULL, NULL);
-  gtk_about_dialog_set_url_hook (exo_url_about_dialog_hook, NULL, NULL);
   gtk_show_about_dialog (parent,
                          "authors", authors,
                          "comments", _("Mousepad is a fast text editor for the Xfce Desktop Environment."),
@@ -69,7 +67,7 @@
                          "name", PACKAGE_NAME,
                          "version", PACKAGE_VERSION,
                          "translator-credits", _("translator-credits"),
-                         "website", "http://www.xfce.org/projects/mousepad",
+                         "website", "http://www.xfce.org/",
                          NULL);
 }
 
@@ -162,24 +160,31 @@
 mousepad_dialogs_clear_recent (GtkWindow *parent)
 {
   GtkWidget *dialog;
+  GtkWidget *image;
   gboolean   succeed = FALSE;
 
-  dialog = gtk_message_dialog_new (parent,
-                                   GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
-                                   GTK_MESSAGE_QUESTION,
-                                   GTK_BUTTONS_NONE,
-                                   _("Are you sure you want to clear\nthe Recent History?"));
+  /* the dialog icon */
+  image = gtk_image_new_from_stock (GTK_STOCK_CLEAR, GTK_ICON_SIZE_DIALOG);
+  gtk_widget_show (image);
 
-  gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
-                                            _("This will only remove the items from the "
-                                              "history owned by Mousepad."));
+  /* create the question dialog */
+  dialog = gtk_message_dialog_new (parent, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+                                   GTK_MESSAGE_OTHER, GTK_BUTTONS_NONE,
+                                   _("Remove all entries from the document history?"));
 
   gtk_dialog_add_buttons (GTK_DIALOG (dialog),
                           GTK_STOCK_CANCEL, MOUSEPAD_RESPONSE_CANCEL,
                           GTK_STOCK_CLEAR, MOUSEPAD_RESPONSE_CLEAR,
                           NULL);
+
+  gtk_window_set_title (GTK_WINDOW (dialog), _("Clear Document History"));
   gtk_dialog_set_default_response (GTK_DIALOG (dialog), MOUSEPAD_RESPONSE_CANCEL);
+  gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (dialog), image);
 
+  gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+                                            _("Clearing the document history will permanently "
+                                              "remove all currently listed entries."));
+
   /* popup the dialog */
   if (gtk_dialog_run (GTK_DIALOG (dialog)) == MOUSEPAD_RESPONSE_CLEAR)
     succeed = TRUE;
@@ -196,27 +201,34 @@
 mousepad_dialogs_save_changes (GtkWindow *parent)
 {
   GtkWidget *dialog;
+  GtkWidget *image;
   gint       response;
 
+  /* the dialog icon */
+  image = gtk_image_new_from_stock (GTK_STOCK_SAVE, GTK_ICON_SIZE_DIALOG);
+  gtk_widget_show (image);
+
   /* create the question dialog */
-  dialog = gtk_message_dialog_new (parent,
-                                   GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
-                                   GTK_MESSAGE_QUESTION,
-                                   GTK_BUTTONS_NONE,
-                                   _("Do you want to save changes to this\n"
-                                     "document before closing?"));
-  gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
-                                            _("If you don't save, your changes will be lost."));
+  dialog = gtk_message_dialog_new (parent, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+                                   GTK_MESSAGE_OTHER, GTK_BUTTONS_NONE,
+                                   _("Do you want to save the changes before closing?"));
 
   gtk_dialog_add_action_widget (GTK_DIALOG (dialog),
                                 mousepad_dialogs_image_button (GTK_STOCK_DELETE, _("_Don't Save")),
                                 MOUSEPAD_RESPONSE_DONT_SAVE);
+
   gtk_dialog_add_buttons (GTK_DIALOG (dialog),
                           GTK_STOCK_CANCEL, MOUSEPAD_RESPONSE_CANCEL,
                           GTK_STOCK_SAVE, MOUSEPAD_RESPONSE_SAVE,
                           NULL);
+
+  gtk_window_set_title (GTK_WINDOW (dialog), _("Save Changes"));
+  gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (dialog), image);
   gtk_dialog_set_default_response (GTK_DIALOG (dialog), MOUSEPAD_RESPONSE_SAVE);
 
+  gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+                                            _("If you don't save the document, all the changes will be lost."));
+
   /* run the dialog and wait for a response */
   response = gtk_dialog_run (GTK_DIALOG (dialog));
 
@@ -311,6 +323,7 @@
                                    GTK_BUTTONS_NONE,
                                    _("The file has been externally modified. Are you sure "
                                      "you want to save the file?"));
+
   gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
                                             _("If you save the file, the external changes "
                                               "to \"%s\" will be lost."), filename);

Added: mousepad/branches/nick_0_3/mousepad/mousepad-document.c
===================================================================
--- mousepad/branches/nick_0_3/mousepad/mousepad-document.c	                        (rev 0)
+++ mousepad/branches/nick_0_3/mousepad/mousepad-document.c	2007-04-04 15:50:00 UTC (rev 25379)
@@ -0,0 +1,1132 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
+#include <mousepad/mousepad-private.h>
+#include <mousepad/mousepad-types.h>
+#include <mousepad/mousepad-exo.h>
+#include <mousepad/mousepad-document.h>
+#include <mousepad/mousepad-file.h>
+#include <mousepad/mousepad-marshal.h>
+#include <mousepad/mousepad-view.h>
+#include <mousepad/mousepad-window.h>
+
+
+
+#define DEFAULT_SEARCH_FLAGS  (GTK_TEXT_SEARCH_VISIBLE_ONLY | GTK_TEXT_SEARCH_TEXT_ONLY)
+
+
+
+static void mousepad_document_class_init              (MousepadDocumentClass  *klass);
+static void mousepad_document_init                    (MousepadDocument       *document);
+static void mousepad_document_get_property            (GObject                *object,
+                                                       guint                   prop_id,
+                                                       GValue                 *value,
+                                                       GParamSpec             *pspec);
+static void mousepad_document_set_property            (GObject                *object,
+                                                       guint                   prop_id,
+                                                       const GValue           *value,
+                                                       GParamSpec             *pspec);
+static void mousepad_document_finalize                (GObject                *object);
+static void mousepad_document_modified_changed        (GtkTextBuffer          *buffer,
+                                                       MousepadDocument       *document);
+static void mousepad_document_notify_has_selection    (GtkTextBuffer          *buffer,
+                                                       GParamSpec             *pspec,
+                                                       MousepadDocument       *document);
+static void mousepad_document_notify_cursor_position  (GtkTextBuffer          *buffer,
+                                                       GParamSpec             *pspec,
+                                                       MousepadDocument       *document);
+static void mousepad_document_toggle_overwrite        (GtkTextView            *textview,
+                                                       GParamSpec             *pspec,
+                                                       MousepadDocument       *document);
+static void mousepad_document_scroll_to_visible_area  (MousepadDocument       *document);
+static void mousepad_document_set_font                (MousepadDocument       *document,
+                                                       const gchar            *font_name);
+static void mousepad_document_tab_set_tooltip         (MousepadDocument       *document,
+                                                       GParamSpec             *pspec,
+                                                       GtkWidget              *ebox);
+static void mousepad_document_tab_button_clicked      (GtkWidget              *widget,
+                                                       MousepadDocument       *document);
+
+
+
+enum
+{
+  PROP_0,
+  PROP_FILENAME,
+  PROP_FONT_NAME,
+  PROP_TITLE,
+};
+
+enum
+{
+  CLOSE_TAB,
+  SELECTION_CHANGED,
+  MODIFIED_CHANGED,
+  CURSOR_CHANGED,
+  OVERWRITE_CHANGED,
+  LAST_SIGNAL,
+};
+
+struct _MousepadDocumentClass
+{
+  GtkScrolledWindowClass __parent__;
+};
+
+struct _MousepadDocument
+{
+  GtkScrolledWindow  __parent__;
+
+  /* text view */
+  GtkTextView       *textview;
+  GtkTextBuffer     *buffer;
+
+  /* the highlight tag */
+  GtkTextTag        *tag;
+
+  /* absolute path of the file */
+  gchar             *filename;
+
+  /* name of the file used for the titles */
+  gchar             *display_name;
+
+  /* last document modified time */
+  time_t             mtime;
+
+  /* settings */
+  guint              word_wrap : 1;
+  guint              line_numbers : 1;
+  guint              auto_indent : 1;
+};
+
+
+
+static GObjectClass *mousepad_document_parent_class;
+static guint         document_signals[LAST_SIGNAL];
+
+
+
+GtkWidget *
+mousepad_document_new (void)
+{
+  return g_object_new (MOUSEPAD_TYPE_DOCUMENT, NULL);
+}
+
+
+
+GType
+mousepad_document_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
+
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      type = g_type_register_static_simple (GTK_TYPE_SCROLLED_WINDOW,
+                                            I_("MousepadDocument"),
+                                            sizeof (MousepadDocumentClass),
+                                            (GClassInitFunc) mousepad_document_class_init,
+                                            sizeof (MousepadDocument),
+                                            (GInstanceInitFunc) mousepad_document_init,
+                                            0);
+    }
+
+  return type;
+}
+
+
+
+static void
+mousepad_document_class_init (MousepadDocumentClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  mousepad_document_parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = mousepad_document_finalize;
+  gobject_class->get_property = mousepad_document_get_property;
+  gobject_class->set_property = mousepad_document_set_property;
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_FILENAME,
+                                   g_param_spec_string ("filename",
+                                                        "filename",
+                                                        "filename",
+                                                        NULL,
+                                                        MOUSEPAD_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_FONT_NAME,
+                                   g_param_spec_string ("font-name",
+                                                        "font-name",
+                                                        "font-name",
+                                                        NULL,
+                                                        MOUSEPAD_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_TITLE,
+                                   g_param_spec_string ("title",
+                                                        "title",
+                                                        "title",
+                                                        NULL,
+                                                        MOUSEPAD_PARAM_READWRITE));
+
+  document_signals[CLOSE_TAB] =
+    g_signal_new (I_("close-tab"),
+                  G_TYPE_FROM_CLASS (gobject_class),
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL,
+                  g_cclosure_marshal_VOID__VOID,
+                  G_TYPE_NONE, 0);
+
+  document_signals[SELECTION_CHANGED] =
+    g_signal_new (I_("selection-changed"),
+                  G_TYPE_FROM_CLASS (gobject_class),
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL,
+                  g_cclosure_marshal_VOID__BOOLEAN,
+                  G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+
+  document_signals[MODIFIED_CHANGED] =
+    g_signal_new (I_("modified-changed"),
+                  G_TYPE_FROM_CLASS (gobject_class),
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL,
+                  g_cclosure_marshal_VOID__VOID,
+                  G_TYPE_NONE, 0);
+
+  document_signals[CURSOR_CHANGED] =
+    g_signal_new (I_("cursor-changed"),
+                  G_TYPE_FROM_CLASS (gobject_class),
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL,
+                  _mousepad_marshal_VOID__UINT_UINT,
+                  G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
+
+  document_signals[OVERWRITE_CHANGED] =
+    g_signal_new (I_("overwrite-changed"),
+                  G_TYPE_FROM_CLASS (gobject_class),
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL,
+                  g_cclosure_marshal_VOID__BOOLEAN,
+                  G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+}
+
+
+
+static void
+mousepad_document_init (MousepadDocument *document)
+{
+  /* initialize the variables */
+  document->filename     = NULL;
+  document->display_name = NULL;
+  document->mtime        = 0;
+
+  /* setup the scolled window */
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (document), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (document), GTK_SHADOW_ETCHED_IN);
+  gtk_scrolled_window_set_hadjustment (GTK_SCROLLED_WINDOW (document), NULL);
+  gtk_scrolled_window_set_vadjustment (GTK_SCROLLED_WINDOW (document), NULL);
+
+  /* create a textbuffer */
+  document->buffer = gtk_text_buffer_new (NULL);
+
+  /* create the highlight tag */
+  document->tag = gtk_text_buffer_create_tag (document->buffer, NULL, "background", "#ffff78", NULL);
+
+  /* setup the textview */
+  document->textview = g_object_new (MOUSEPAD_TYPE_VIEW, "buffer", document->buffer, NULL);
+  gtk_container_add (GTK_CONTAINER (document), GTK_WIDGET (document->textview));
+  gtk_widget_show (GTK_WIDGET (document->textview));
+
+  /* attach signals to the text view and buffer */
+  g_signal_connect (G_OBJECT (document->buffer), "modified-changed",
+                    G_CALLBACK (mousepad_document_modified_changed), document);
+  g_signal_connect (G_OBJECT (document->buffer), "notify::has-selection",
+                    G_CALLBACK (mousepad_document_notify_has_selection), document);
+  g_signal_connect (G_OBJECT (document->buffer), "notify::cursor-position",
+                    G_CALLBACK (mousepad_document_notify_cursor_position), document);
+  g_signal_connect (G_OBJECT (document->textview), "notify::overwrite",
+                    G_CALLBACK (mousepad_document_toggle_overwrite), document);
+}
+
+
+
+static void
+mousepad_document_get_property (GObject    *object,
+                                guint       prop_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
+{
+  MousepadDocument *document = MOUSEPAD_DOCUMENT (object);
+
+  switch (prop_id)
+    {
+      case PROP_FILENAME:
+        g_value_set_static_string (value, mousepad_document_get_filename (document));
+        break;
+
+      case PROP_TITLE:
+        g_value_set_static_string (value, mousepad_document_get_title (document, FALSE));
+        break;
+
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+
+
+static void
+mousepad_document_set_property (GObject      *object,
+                                guint         prop_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
+{
+  MousepadDocument *document = MOUSEPAD_DOCUMENT (object);
+
+  switch (prop_id)
+    {
+      case PROP_FONT_NAME:
+        mousepad_document_set_font (document, g_value_get_string (value));
+        break;
+
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+
+
+static void
+mousepad_document_finalize (GObject *object)
+{
+  MousepadDocument *document = MOUSEPAD_DOCUMENT (object);
+
+  /* cleanup */
+  g_free (document->filename);
+  g_free (document->display_name);
+
+  /* release our reference from the buffer */
+  g_object_unref (G_OBJECT (document->buffer));
+
+  (*G_OBJECT_CLASS (mousepad_document_parent_class)->finalize) (object);
+}
+
+
+
+static void
+mousepad_document_modified_changed (GtkTextBuffer    *buffer,
+                                    MousepadDocument *document)
+{
+  _mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (document));
+
+  /* emit the signal */
+  g_signal_emit (G_OBJECT (document), document_signals[MODIFIED_CHANGED], 0);
+}
+
+
+
+static void
+mousepad_document_notify_has_selection (GtkTextBuffer    *buffer,
+                                        GParamSpec       *pspec,
+                                        MousepadDocument *document)
+{
+  gboolean has_selection;
+
+  _mousepad_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
+  _mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (document));
+
+  /* check if we have selected text or not */
+  has_selection = mousepad_document_get_has_selection (document);
+
+  /* emit the signal */
+  g_signal_emit (G_OBJECT (document), document_signals[SELECTION_CHANGED], 0, has_selection);
+}
+
+
+
+static void
+mousepad_document_notify_cursor_position (GtkTextBuffer    *buffer,
+                                          GParamSpec       *pspec,
+                                          MousepadDocument *document)
+{
+  GtkTextIter iter, start;
+  guint       line, column = 0;
+
+  _mousepad_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
+  _mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (document));
+
+  /* get the current iter position */
+  gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_insert (buffer));
+
+  /* get the current line numbr */
+  line = gtk_text_iter_get_line (&iter) + 1;
+
+  /* get the column */
+  start = iter;
+  gtk_text_iter_set_line_offset (&start, 0);
+
+  while (!gtk_text_iter_equal (&start, &iter))
+    {
+      if (gtk_text_iter_get_char (&start) == '\t')
+        column += (8 - (column % 8));
+      else
+        ++column;
+
+      gtk_text_iter_forward_char (&start);
+    }
+
+  /* emit the signal */
+  g_signal_emit (G_OBJECT (document), document_signals[CURSOR_CHANGED], 0, line, column + 1);
+}
+
+
+
+static void
+mousepad_document_toggle_overwrite (GtkTextView      *textview,
+                                    GParamSpec       *pspec,
+                                    MousepadDocument *document)
+{
+  gboolean overwrite;
+
+  _mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (document));
+  _mousepad_return_if_fail (GTK_IS_TEXT_VIEW (textview));
+
+  /* whether overwrite is enabled */
+  overwrite = gtk_text_view_get_overwrite (textview);
+
+  /* emit the signal */
+  g_signal_emit (G_OBJECT (document), document_signals[OVERWRITE_CHANGED], 0, overwrite);
+}
+
+
+
+static void
+mousepad_document_scroll_to_visible_area (MousepadDocument *document)
+{
+	/* scroll to visible area */
+  gtk_text_view_scroll_to_mark (document->textview,
+                                gtk_text_buffer_get_insert (document->buffer),
+                                0.25, FALSE, 0.0, 0.0);
+}
+
+
+
+gboolean
+mousepad_document_reload (MousepadDocument  *document,
+                          GError           **error)
+{
+  GtkTextIter  start, end;
+  gchar       *filename;
+  gboolean     succeed = FALSE;
+
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_DOCUMENT (document), FALSE);
+  _mousepad_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  /* remove the content of the textview */
+  gtk_text_buffer_get_bounds (document->buffer, &start, &end);
+  gtk_text_buffer_delete (document->buffer, &start, &end);
+
+  /* we have to copy the filename, because mousepad_screen_open_file (resets) the name */
+  filename = g_strdup (document->filename);
+
+  /* reload the document */
+  succeed = mousepad_document_open_file (document, filename, error);
+
+  /* cleanup */
+  g_free (filename);
+
+  return succeed;
+}
+
+
+
+gboolean
+mousepad_document_save_file (MousepadDocument  *document,
+                             const gchar       *filename,
+                             GError           **error)
+{
+  gchar       *content;
+  gchar       *converted = NULL;
+  GtkTextIter  start, end;
+  gsize        bytes;
+  gint         new_mtime;
+  gboolean     succeed = FALSE;
+
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_DOCUMENT (document), FALSE);
+  _mousepad_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+  _mousepad_return_val_if_fail (filename != NULL, FALSE);
+
+  /* get the textview content */
+  gtk_text_buffer_get_bounds (document->buffer, &start, &end);
+  content = gtk_text_buffer_get_slice (document->buffer, &start, &end, TRUE);
+
+  if (G_LIKELY (content != NULL))
+    {
+      /* TODO: fix the file encoding here, basic utf8 for testing */
+      converted = g_convert (content,
+                             strlen (content),
+                             "UTF-8",
+                             "UTF-8",
+                             NULL,
+                             &bytes,
+                             error);
+
+      /* cleanup */
+      g_free (content);
+
+      if (G_LIKELY (converted != NULL))
+        {
+          succeed = mousepad_file_save_data (filename, converted, bytes,
+                                             &new_mtime, error);
+
+          /* cleanup */
+          g_free (converted);
+
+          /* saving work w/o problems */
+          if (G_LIKELY (succeed))
+            {
+              /* set the new mtime */
+              document->mtime = new_mtime;
+
+              /* nothing happend */
+              gtk_text_buffer_set_modified (document->buffer, FALSE);
+
+              /* we were allowed to write */
+              gtk_text_view_set_editable (document->textview, TRUE);
+
+              /* emit the modified-changed signal */
+              mousepad_document_modified_changed (NULL, document);
+            }
+        }
+    }
+
+  return succeed;
+}
+
+
+
+void
+mousepad_document_set_filename (MousepadDocument *document,
+                                const gchar      *filename)
+{
+  _mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (document));
+  _mousepad_return_if_fail (filename != NULL);
+
+  /* cleanup the old names */
+  g_free (document->filename);
+  g_free (document->display_name);
+
+  /* create the new names */
+  document->filename = g_strdup (filename);
+  document->display_name = g_filename_display_basename (filename);
+
+  /* tell the listeners */
+  g_object_notify (G_OBJECT (document), "title");
+}
+
+
+
+void
+mousepad_document_set_auto_indent (MousepadDocument *document,
+                                   gboolean          auto_indent)
+{
+  _mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (document));
+
+  /* store the setting */
+  document->auto_indent = auto_indent;
+
+  mousepad_view_set_auto_indent (MOUSEPAD_VIEW (document->textview), auto_indent);
+}
+
+
+
+void
+mousepad_document_set_line_numbers (MousepadDocument *document,
+                                    gboolean          line_numbers)
+{
+  _mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (document));
+
+  /* store the setting */
+  document->line_numbers = line_numbers;
+
+  mousepad_view_set_show_line_numbers (MOUSEPAD_VIEW (document->textview), line_numbers);
+}
+
+
+
+void
+mousepad_document_set_word_wrap (MousepadDocument *document,
+                                 gboolean          word_wrap)
+{
+  _mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (document));
+
+  /* store the setting */
+  document->word_wrap = word_wrap;
+
+  /* set the wrapping mode */
+  gtk_text_view_set_wrap_mode (document->textview,
+                               word_wrap ? GTK_WRAP_WORD : GTK_WRAP_NONE);
+}
+
+
+
+static void
+mousepad_document_set_font (MousepadDocument *document,
+                            const gchar      *font_name)
+{
+  PangoFontDescription *font_desc;
+
+  _mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (document));
+
+  if (G_LIKELY (font_name))
+    {
+      font_desc = pango_font_description_from_string (font_name);
+      gtk_widget_modify_font (GTK_WIDGET (document->textview), font_desc);
+      pango_font_description_free (font_desc);
+    }
+}
+
+
+
+gboolean
+mousepad_document_open_file (MousepadDocument  *document,
+                             const gchar       *filename,
+                             GError           **error)
+{
+  GtkTextIter iter;
+  gboolean    succeed = FALSE;
+  gboolean    readonly;
+  gint        new_mtime;
+
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_DOCUMENT (document), FALSE);
+  _mousepad_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+  _mousepad_return_val_if_fail (filename != NULL, FALSE);
+
+  /* we're going to add the file content */
+  gtk_text_buffer_begin_user_action (document->buffer);
+
+  /* insert the file content */
+  if (mousepad_file_read_to_buffer (filename,
+                                    document->buffer,
+                                    &new_mtime,
+                                    &readonly,
+                                    error))
+    {
+      /* set the new filename */
+      mousepad_document_set_filename (document, filename);
+
+      /* set the new mtime */
+      document->mtime = new_mtime;
+
+      /* whether the textview is editable */
+      gtk_text_view_set_editable (document->textview, !readonly);
+
+      /* move the cursors to the first place and pretend nothing happend */
+      gtk_text_buffer_get_start_iter (document->buffer, &iter);
+      gtk_text_buffer_place_cursor (document->buffer, &iter);
+      gtk_text_buffer_set_modified (document->buffer, FALSE);
+      gtk_text_view_scroll_to_iter (document->textview, &iter, 0, FALSE, 0, 0);
+
+      /* it worked out very well */
+      succeed = TRUE;
+    }
+
+  /* and we're done */
+  gtk_text_buffer_end_user_action (document->buffer);
+
+  return succeed;
+}
+
+
+
+gboolean
+mousepad_document_find (MousepadDocument    *document,
+                        const gchar         *string,
+                        MousepadSearchFlags  flags)
+{
+  gboolean    found;
+  gboolean    already_wrapped = FALSE;
+  GtkTextIter doc_start, doc_end;
+  GtkTextIter sel_start, sel_end;
+  GtkTextIter match_start, match_end;
+  GtkTextIter start, end;
+
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_DOCUMENT (document), FALSE);
+  _mousepad_return_val_if_fail (GTK_IS_TEXT_BUFFER (document->buffer), FALSE);
+
+  /* get the bounds */
+  gtk_text_buffer_get_bounds (document->buffer, &doc_start, &doc_end);
+  gtk_text_buffer_get_selection_bounds (document->buffer, &sel_start, &sel_end);
+
+  if (flags & MOUSEPAD_SEARCH_FORWARDS)
+    {
+      start = sel_end;
+      end   = doc_end;
+    }
+  else if (flags & MOUSEPAD_SEARCH_BACKWARDS)
+    {
+      start = sel_start;
+      end   = doc_start;
+    }
+  else /* type-ahead */
+    {
+      start = sel_start;
+      end   = doc_end;
+    }
+
+search:
+  /* try to find the next occurence of the string */
+  if (flags & MOUSEPAD_SEARCH_BACKWARDS)
+    found = gtk_text_iter_backward_search (&start, string, DEFAULT_SEARCH_FLAGS, &match_start, &match_end, &end);
+  else
+    found = gtk_text_iter_forward_search (&start, string, DEFAULT_SEARCH_FLAGS, &match_start, &match_end, &end);
+
+  /* select the occurence */
+  if (found)
+    {
+      /* set the cursor in from of the matched iter */
+      gtk_text_buffer_place_cursor (document->buffer, &match_start);
+
+      /* select the match */
+      gtk_text_buffer_move_mark_by_name (document->buffer, "insert", &match_end);
+
+      /* scroll document so the cursor is visible */
+      mousepad_document_scroll_to_visible_area (document);
+    }
+  /* wrap around */
+  else if (already_wrapped == FALSE)
+    {
+      /* set the new start and end iter */
+      if (flags & MOUSEPAD_SEARCH_BACKWARDS)
+        {
+          end   = start;
+          start = doc_end;
+        }
+      else
+        {
+          end   = start;
+          start = doc_start;
+        }
+
+      /* set we did the wrap, so we don't end up in a loop */
+      already_wrapped = TRUE;
+
+      /* search again */
+      goto search;
+    }
+
+  return found;
+}
+
+
+
+void
+mousepad_document_replace (MousepadDocument *document)
+{
+  _mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (document));
+
+
+}
+
+
+
+void
+mousepad_document_highlight_all (MousepadDocument    *document,
+                                 const gchar         *string,
+                                 MousepadSearchFlags  flags)
+{
+  GtkTextIter iter;
+  GtkTextIter doc_start, doc_end;
+  GtkTextIter match_start, match_end;
+  gboolean    found;
+
+  _mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (document));
+  _mousepad_return_if_fail (GTK_IS_TEXT_BUFFER (document->buffer));
+
+  /* get the document bounds */
+  gtk_text_buffer_get_bounds (document->buffer, &doc_start, &doc_end);
+
+  /* remove all the highlight tags */
+  gtk_text_buffer_remove_tag (document->buffer, document->tag, &doc_start, &doc_end);
+
+  /* highlight the new string */
+  if (G_LIKELY (string != NULL))
+    {
+      /* set the iter to the beginning of the document */
+      iter = doc_start;
+
+      /* highlight all the occurences of the strings */
+      do
+      {
+        /* search for the next occurence of the string */
+        found = gtk_text_iter_forward_search (&iter, string, DEFAULT_SEARCH_FLAGS, &match_start, &match_end, NULL);
+
+        if (G_LIKELY (found))
+          {
+             /* highlight the found occurence */
+             gtk_text_buffer_apply_tag (document->buffer, document->tag, &match_start, &match_end);
+
+             /* jump to the end of the highlighted string and continue searching */
+             iter = match_end;
+          }
+      } while (found);
+    }
+}
+
+
+
+void
+mousepad_document_cut_selection (MousepadDocument *document)
+{
+  GtkClipboard *clipboard;
+
+  /* get the clipboard */
+  clipboard = gtk_widget_get_clipboard (GTK_WIDGET (document->textview), GDK_SELECTION_CLIPBOARD);
+
+  /* cut the text */
+  gtk_text_buffer_cut_clipboard (document->buffer, clipboard, gtk_text_view_get_editable (document->textview));
+
+  /* make sure the cursor is in the visible area */
+  mousepad_document_scroll_to_visible_area (document);
+}
+
+
+
+
+
+void
+mousepad_document_copy_selection (MousepadDocument *document)
+{
+  GtkClipboard *clipboard;
+
+  /* get the clipboard */
+  clipboard = gtk_widget_get_clipboard (GTK_WIDGET (document->textview), GDK_SELECTION_CLIPBOARD);
+
+  /* copy the selected text */
+  gtk_text_buffer_copy_clipboard (document->buffer, clipboard);
+}
+
+
+
+void
+mousepad_document_paste_clipboard (MousepadDocument *document)
+{
+  GtkClipboard *clipboard;
+
+  /* get the clipboard */
+  clipboard = gtk_widget_get_clipboard (GTK_WIDGET (document->textview), GDK_SELECTION_CLIPBOARD);
+
+  /* paste the clipboard content */
+  gtk_text_buffer_paste_clipboard (document->buffer, clipboard, NULL, gtk_text_view_get_editable (document->textview));
+
+  /* make sure the cursor is in the visible area */
+  mousepad_document_scroll_to_visible_area (document);
+}
+
+
+
+void
+mousepad_document_delete_selection (MousepadDocument *document)
+{
+  /* delete the selected text */
+  gtk_text_buffer_delete_selection (document->buffer, TRUE, gtk_text_view_get_editable (document->textview));
+
+  /* make sure the cursor is in the visible area */
+  mousepad_document_scroll_to_visible_area (document);
+}
+
+
+
+void
+mousepad_document_select_all (MousepadDocument *document)
+{
+	GtkTextIter start, end;
+
+	/* get the start and end iter */
+  gtk_text_buffer_get_bounds (document->buffer, &start, &end);
+
+  /* select everything between those iters */
+  gtk_text_buffer_select_range (document->buffer, &start, &end);
+}
+
+
+
+void
+mousepad_document_focus_textview (MousepadDocument *document)
+{
+	_mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (document));
+
+	/* focus the textview */
+	gtk_widget_grab_focus (GTK_WIDGET (document->textview));
+}
+
+
+
+void
+mousepad_document_jump_to_line (MousepadDocument *document,
+                                gint              line_number)
+{
+	GtkTextIter iter;
+
+	_mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (document));
+
+	/* move the cursor */
+	gtk_text_buffer_get_iter_at_line (document->buffer, &iter, line_number-1);
+  gtk_text_buffer_place_cursor (document->buffer, &iter);
+
+  /* make sure the cursor is in the visible area */
+  mousepad_document_scroll_to_visible_area (document);
+}
+
+
+
+void
+mousepad_document_send_statusbar_signals (MousepadDocument *document)
+{
+  _mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (document));
+
+  /* re-send the cursor changed signal */
+  mousepad_document_notify_cursor_position (document->buffer, NULL, document);
+
+  /* re-send the overwrite signal */
+  mousepad_document_toggle_overwrite (document->textview, NULL, document);
+}
+
+
+
+void
+mousepad_document_line_numbers (MousepadDocument *document,
+                                gint             *current_line,
+                                gint             *last_line)
+{
+  GtkTextIter iter;
+
+  _mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (document));
+
+  /* get the current line number */
+  gtk_text_buffer_get_iter_at_mark (document->buffer, &iter, gtk_text_buffer_get_insert (document->buffer));
+  *current_line = gtk_text_iter_get_line (&iter) + 1;
+
+  /* get the last line number */
+	gtk_text_buffer_get_end_iter (document->buffer, &iter);
+	*last_line = gtk_text_iter_get_line (&iter) + 1;
+}
+
+
+
+gboolean
+mousepad_document_get_externally_modified (MousepadDocument *document)
+{
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_DOCUMENT (document), FALSE);
+  _mousepad_return_val_if_fail (document->filename != NULL, FALSE);
+
+  /* return whether the file has been externally modified */
+  return mousepad_file_get_externally_modified (document->filename, document->mtime);
+}
+
+
+
+const gchar *
+mousepad_document_get_filename (MousepadDocument *document)
+{
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_DOCUMENT (document), NULL);
+
+  return document->filename;
+}
+
+
+
+gboolean
+mousepad_document_get_has_selection (MousepadDocument *document)
+{
+  gboolean       has_selection;
+
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_DOCUMENT (document), FALSE);
+
+  /* check if we have selected text or not */
+  g_object_get (G_OBJECT (document->buffer), "has-selection", &has_selection, NULL);
+
+  return has_selection;
+}
+
+
+
+gboolean
+mousepad_document_get_modified (MousepadDocument *document)
+{
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_DOCUMENT (document), FALSE);
+
+  /* return whether the buffer has been modified */
+  return gtk_text_buffer_get_modified (document->buffer);
+}
+
+
+
+gboolean
+mousepad_document_get_readonly (MousepadDocument *document)
+{
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_DOCUMENT (document), FALSE);
+
+  return !gtk_text_view_get_editable (document->textview);
+}
+
+
+
+GtkWidget *
+mousepad_document_get_tab_label (MousepadDocument *document)
+{
+  GtkWidget *hbox;
+  GtkWidget *label, *ebox;
+  GtkWidget *button, *image;
+
+  /* create the box */
+  hbox = gtk_hbox_new (FALSE, 0);
+  gtk_widget_show (hbox);
+
+  /* the ebox */
+  ebox = g_object_new (GTK_TYPE_EVENT_BOX, "border-width", 2, NULL);
+  gtk_box_pack_start (GTK_BOX (hbox), ebox, TRUE, TRUE, 0);
+  gtk_widget_show (ebox);
+  mousepad_document_tab_set_tooltip (document, NULL, ebox);
+  g_signal_connect (G_OBJECT (document), "notify::title",
+                    G_CALLBACK (mousepad_document_tab_set_tooltip), ebox);
+
+  /* create the label */
+  label = g_object_new (GTK_TYPE_LABEL,
+                        "selectable", FALSE,
+                        "xalign", 0.0, NULL);
+  gtk_container_add (GTK_CONTAINER (ebox), label);
+  exo_binding_new (G_OBJECT (document), "title", G_OBJECT (label), "label");
+  gtk_widget_show (label);
+
+  /* create the button */
+  button = g_object_new (GTK_TYPE_BUTTON,
+                         "relief", GTK_RELIEF_NONE,
+                         "focus-on-click", FALSE,
+                         "border-width", 0,
+                         "can-default", FALSE,
+                         "can-focus", FALSE, NULL);
+  mousepad_gtk_set_tooltip (button, _("Close this tab"));
+  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+  g_signal_connect (G_OBJECT (button), "clicked",
+                    G_CALLBACK (mousepad_document_tab_button_clicked), document);
+  gtk_widget_show (button);
+
+  /* button image */
+  image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU);
+  gtk_container_add (GTK_CONTAINER (button), image);
+  gtk_widget_show (image);
+
+  return hbox;
+}
+
+
+
+static void
+mousepad_document_tab_set_tooltip (MousepadDocument *document,
+                                   GParamSpec       *pspec,
+                                   GtkWidget        *ebox)
+{
+  mousepad_gtk_set_tooltip (ebox, document->filename);
+}
+
+
+
+static void
+mousepad_document_tab_button_clicked (GtkWidget        *widget,
+                                      MousepadDocument *document)
+{
+  g_signal_emit (G_OBJECT (document), document_signals[CLOSE_TAB], 0);
+}
+
+
+
+const gchar *
+mousepad_document_get_title (MousepadDocument *document,
+                             gboolean          show_full_path)
+{
+  const gchar  *title;
+  static guint  untitled_counter = 0;
+
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_DOCUMENT (document), NULL);
+
+  if (G_UNLIKELY (show_full_path && document->filename))
+    {
+      /* return the filename */
+      title = document->filename;
+    }
+  else
+    {
+      /* check if the document is still untitled, if so, fix it */
+      if (G_UNLIKELY (document->display_name == NULL))
+        document->display_name = g_strdup_printf ("%s %d", _("Untitled"), ++untitled_counter);
+
+      /* return the display_name */
+      title = document->display_name;
+    }
+
+  return title;
+}
+
+
+
+gboolean
+mousepad_document_get_word_wrap (MousepadDocument *document)
+{
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_DOCUMENT (document), FALSE);
+
+  return document->word_wrap;
+}
+
+
+
+gboolean
+mousepad_document_get_line_numbers (MousepadDocument *document)
+{
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_DOCUMENT (document), FALSE);
+
+  return document->line_numbers;
+}
+
+
+
+gboolean
+mousepad_document_get_auto_indent (MousepadDocument *document)
+{
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_DOCUMENT (document), FALSE);
+
+  return document->auto_indent;
+}

Added: mousepad/branches/nick_0_3/mousepad/mousepad-document.h
===================================================================
--- mousepad/branches/nick_0_3/mousepad/mousepad-document.h	                        (rev 0)
+++ mousepad/branches/nick_0_3/mousepad/mousepad-document.h	2007-04-04 15:50:00 UTC (rev 25379)
@@ -0,0 +1,118 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * 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
+ */
+
+#ifndef __MOUSEPAD_DOCUMENT_H__
+#define __MOUSEPAD_DOCUMENT_H__
+
+G_BEGIN_DECLS
+
+typedef struct _MousepadDocumentClass MousepadDocumentClass;
+typedef struct _MousepadDocument      MousepadDocument;
+
+#define MOUSEPAD_SCROLL_MARGIN 0.02
+
+#define MOUSEPAD_TYPE_DOCUMENT            (mousepad_document_get_type ())
+#define MOUSEPAD_DOCUMENT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), MOUSEPAD_TYPE_DOCUMENT, MousepadDocument))
+#define MOUSEPAD_DOCUMENT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), MOUSEPAD_TYPE_DOCUMENT, MousepadDocumentClass))
+#define MOUSEPAD_IS_DOCUMENT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MOUSEPAD_TYPE_DOCUMENT))
+#define MOUSEPAD_IS_DOCUMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MOUSEPAD_TYPE_DOCUMENT))
+#define MOUSEPAD_DOCUMENT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), MOUSEPAD_TYPE_DOCUMENT, MousepadDocumentClass))
+
+GType           mousepad_document_get_type                 (void) G_GNUC_CONST;
+
+GtkWidget      *mousepad_document_new                      (void);
+
+gboolean        mousepad_document_reload                   (MousepadDocument    *document,
+                                                            GError             **error);
+
+gboolean        mousepad_document_save_file                (MousepadDocument    *document,
+                                                            const gchar         *filename,
+                                                            GError             **error);
+
+void            mousepad_document_set_filename             (MousepadDocument    *document,
+                                                            const gchar         *filename);
+
+void            mousepad_document_set_auto_indent          (MousepadDocument    *document,
+                                                            gboolean             auto_indent);
+
+void            mousepad_document_set_line_numbers         (MousepadDocument    *document,
+                                                            gboolean             line_numbers);
+
+void            mousepad_document_set_word_wrap            (MousepadDocument    *document,
+                                                            gboolean             word_wrap);
+
+gboolean        mousepad_document_open_file                (MousepadDocument    *document,
+                                                            const gchar         *filename,
+                                                            GError             **error);
+
+gboolean        mousepad_document_find                     (MousepadDocument    *document,
+                                                            const gchar         *string,
+                                                            MousepadSearchFlags  flags);
+
+void            mousepad_document_replace                  (MousepadDocument    *document);
+
+void            mousepad_document_highlight_all            (MousepadDocument    *document,
+                                                            const gchar         *string,
+                                                            MousepadSearchFlags  flags);
+
+void            mousepad_document_cut_selection            (MousepadDocument    *document);;
+
+void            mousepad_document_copy_selection           (MousepadDocument    *document);
+
+void            mousepad_document_paste_clipboard          (MousepadDocument    *document);
+
+void            mousepad_document_delete_selection         (MousepadDocument    *document);
+
+void            mousepad_document_select_all               (MousepadDocument    *document);
+
+void            mousepad_document_focus_textview           (MousepadDocument    *document);
+
+void            mousepad_document_jump_to_line             (MousepadDocument    *document,
+                                                            gint                 line_number);
+
+void            mousepad_document_send_statusbar_signals   (MousepadDocument    *document);
+
+void            mousepad_document_line_numbers             (MousepadDocument    *document,
+                                                            gint                *current_line,
+                                                            gint                *last_line);
+
+gboolean        mousepad_document_get_externally_modified  (MousepadDocument    *document);
+
+const gchar    *mousepad_document_get_filename             (MousepadDocument    *document);
+
+gboolean        mousepad_document_get_has_selection        (MousepadDocument    *document);
+
+gboolean        mousepad_document_get_modified             (MousepadDocument    *document);
+
+gboolean        mousepad_document_get_readonly             (MousepadDocument    *document);
+
+GtkWidget      *mousepad_document_get_tab_label            (MousepadDocument    *document);
+
+const gchar    *mousepad_document_get_title                (MousepadDocument    *document,
+                                                            gboolean             show_full_path);
+
+gboolean        mousepad_document_get_word_wrap            (MousepadDocument    *document);
+
+gboolean        mousepad_document_get_line_numbers         (MousepadDocument    *document);
+
+gboolean        mousepad_document_get_auto_indent          (MousepadDocument    *document);
+
+G_END_DECLS
+
+#endif /* !__MOUSEPAD_DOCUMENT_H__ */

Added: mousepad/branches/nick_0_3/mousepad/mousepad-exo.c
===================================================================
--- mousepad/branches/nick_0_3/mousepad/mousepad-exo.c	                        (rev 0)
+++ mousepad/branches/nick_0_3/mousepad/mousepad-exo.c	2007-04-04 15:50:00 UTC (rev 25379)
@@ -0,0 +1,447 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2004-2006 os-cillation e.K.
+ * Copyright (c) 2004      Victor Porton (http://ex-code.com/~porton/)
+ *
+ * Written by Benedikt Meurer <benny at xfce.org>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <mousepad/mousepad-private.h>
+#include <mousepad/mousepad-exo.h>
+
+static void
+exo_bind_properties_transfer (GObject             *src_object,
+                              GParamSpec          *src_pspec,
+                              GObject             *dst_object,
+                              GParamSpec          *dst_pspec,
+                              ExoBindingTransform  transform,
+                              gpointer             user_data)
+{
+  const gchar *src_name;
+  const gchar *dst_name;
+  gboolean     result;
+  GValue       src_value = { 0, };
+  GValue       dst_value = { 0, };
+
+  src_name = g_param_spec_get_name (src_pspec);
+  dst_name = g_param_spec_get_name (dst_pspec);
+
+  g_value_init (&src_value, G_PARAM_SPEC_VALUE_TYPE (src_pspec));
+  g_object_get_property (src_object, src_name, &src_value);
+
+  g_value_init (&dst_value, G_PARAM_SPEC_VALUE_TYPE (dst_pspec));
+  result = (*transform) (&src_value, &dst_value, user_data);
+
+  g_value_unset (&src_value);
+
+  g_return_if_fail (result);
+
+  g_param_value_validate (dst_pspec, &dst_value);
+  g_object_set_property (dst_object, dst_name, &dst_value);
+  g_value_unset (&dst_value);
+}
+
+
+
+static void
+exo_bind_properties_notify (GObject    *src_object,
+                            GParamSpec *src_pspec,
+                            gpointer    data)
+{
+  ExoBindingLink *link = data;
+
+  /* block the destination handler for mutual bindings,
+   * so we don't recurse here.
+   */
+  if (link->dst_handler != 0)
+    g_signal_handler_block (link->dst_object, link->dst_handler);
+
+  exo_bind_properties_transfer (src_object,
+                                src_pspec,
+                                link->dst_object,
+                                link->dst_pspec,
+                                link->transform,
+                                link->user_data);
+
+  /* unblock destination handler */
+  if (link->dst_handler != 0)
+    g_signal_handler_unblock (link->dst_object, link->dst_handler);
+}
+
+
+
+static void
+exo_binding_on_dst_object_destroy (gpointer  data,
+                                   GObject  *object)
+{
+  ExoBinding *binding = data;
+
+  binding->link.dst_object = NULL;
+
+  /* calls exo_binding_on_disconnect() */
+  g_signal_handler_disconnect (binding->src_object, binding->link.handler);
+}
+
+
+
+static void
+exo_binding_on_disconnect (gpointer  data,
+                           GClosure *closure)
+{
+  ExoBindingLink *link = data;
+  ExoBinding     *binding;
+
+  binding = (ExoBinding *) (((gchar *) link) - G_STRUCT_OFFSET (ExoBinding, link));
+
+  if (binding->base.destroy != NULL)
+    binding->base.destroy (link->user_data);
+
+  if (link->dst_object != NULL)
+    g_object_weak_unref (link->dst_object, exo_binding_on_dst_object_destroy, binding);
+
+  g_slice_free (ExoBinding, binding);
+}
+
+
+
+/* recursively calls exo_mutual_binding_on_disconnect_object2() */
+static void
+exo_mutual_binding_on_disconnect_object1 (gpointer  data,
+                                          GClosure *closure)
+{
+  ExoMutualBinding *binding;
+  ExoBindingLink   *link = data;
+  GObject          *object2;
+
+  binding = (ExoMutualBinding *) (((gchar *) link) - G_STRUCT_OFFSET (ExoMutualBinding, direct));
+  binding->reverse.dst_object = NULL;
+
+  object2 = binding->direct.dst_object;
+  if (object2 != NULL)
+    {
+      if (binding->base.destroy != NULL)
+        binding->base.destroy (binding->direct.user_data);
+      binding->direct.dst_object = NULL;
+      g_signal_handler_disconnect (object2, binding->reverse.handler);
+      g_slice_free (ExoMutualBinding, binding);
+    }
+}
+
+
+
+/* recursively calls exo_mutual_binding_on_disconnect_object1() */
+static void
+exo_mutual_binding_on_disconnect_object2 (gpointer  data,
+                                          GClosure *closure)
+{
+  ExoMutualBinding *binding;
+  ExoBindingLink   *link = data;
+  GObject          *object1;
+
+  binding = (ExoMutualBinding *) (((gchar *) link) - G_STRUCT_OFFSET (ExoMutualBinding, reverse));
+  binding->direct.dst_object = NULL;
+
+  object1 = binding->reverse.dst_object;
+  if (object1 != NULL)
+    {
+      binding->reverse.dst_object = NULL;
+      g_signal_handler_disconnect (object1, binding->direct.handler);
+    }
+}
+
+
+
+static void
+exo_binding_link_init (ExoBindingLink     *link,
+                       GObject            *src_object,
+                       const gchar        *src_property,
+                       GObject            *dst_object,
+                       GParamSpec         *dst_pspec,
+                       ExoBindingTransform transform,
+                       GClosureNotify      destroy_notify,
+                       gpointer            user_data)
+{
+  gchar *signal_name;
+
+  link->dst_object  = dst_object;
+  link->dst_pspec   = dst_pspec;
+  link->dst_handler = 0;
+  link->transform   = transform;
+  link->user_data   = user_data;
+
+  signal_name = g_strconcat ("notify::", src_property, NULL);
+  link->handler = g_signal_connect_data (src_object,
+                                         signal_name,
+                                         G_CALLBACK (exo_bind_properties_notify),
+                                         link,
+                                         destroy_notify,
+                                         0);
+  g_free (signal_name);
+}
+
+
+
+/**
+ * exo_binding_new:
+ * @src_object    : The source #GObject.
+ * @src_property  : The name of the property to bind from.
+ * @dst_object    : The destination #GObject.
+ * @dst_property  : The name of the property to bind to.
+ *
+ * One-way binds @src_property in @src_object to @dst_property
+ * in @dst_object.
+ *
+ * Before binding the value of @dst_property is set to the
+ * value of @src_property.
+ *
+ * Return value: The descriptor of the binding. It is automatically
+ *               removed if one of the objects is finalized.
+ **/
+ExoBinding*
+exo_binding_new (GObject      *src_object,
+                 const gchar  *src_property,
+                 GObject      *dst_object,
+                 const gchar  *dst_property)
+{
+  return exo_binding_new_full (src_object, src_property,
+                               dst_object, dst_property,
+                               NULL, NULL, NULL);
+}
+
+
+
+/**
+ * exo_binding_new_full:
+ * @src_object      : The source #GObject.
+ * @src_property    : The name of the property to bind from.
+ * @dst_object      : The destination #GObject.
+ * @dst_property    : The name of the property to bind to.
+ * @transform       : Transformation function or %NULL.
+ * @destroy_notify  : Callback function that is called on
+ *                    disconnection with @user_data or %NULL.
+ * @user_data       : User data associated with the binding.
+ *
+ * One-way binds @src_property in @src_object to @dst_property
+ * in @dst_object.
+ *
+ * Before binding the value of @dst_property is set to the
+ * value of @src_property.
+ *
+ * Return value: The descriptor of the binding. It is automatically
+ *               removed if one of the objects is finalized.
+ **/
+ExoBinding*
+exo_binding_new_full (GObject            *src_object,
+                      const gchar        *src_property,
+                      GObject            *dst_object,
+                      const gchar        *dst_property,
+                      ExoBindingTransform transform,
+                      GDestroyNotify      destroy_notify,
+                      gpointer            user_data)
+{
+  ExoBinding  *binding;
+  GParamSpec  *src_pspec;
+  GParamSpec  *dst_pspec;
+
+  g_return_val_if_fail (G_IS_OBJECT (src_object), NULL);
+  g_return_val_if_fail (G_IS_OBJECT (dst_object), NULL);
+
+  src_pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (src_object), src_property);
+  dst_pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (dst_object), dst_property);
+
+  if (transform == NULL)
+    transform = (ExoBindingTransform) g_value_transform;
+
+  exo_bind_properties_transfer (src_object,
+                                src_pspec,
+                                dst_object,
+                                dst_pspec,
+                                transform,
+                                user_data);
+
+  binding = g_slice_new (ExoBinding);
+  binding->src_object = src_object;
+  binding->base.destroy = destroy_notify;
+
+  exo_binding_link_init (&binding->link,
+                         src_object,
+                         src_property,
+                         dst_object,
+                         dst_pspec,
+                         transform,
+                         exo_binding_on_disconnect,
+                         user_data);
+
+  g_object_weak_ref (dst_object, exo_binding_on_dst_object_destroy, binding);
+
+  return binding;
+}
+
+
+
+/**
+ * exo_binding_unbind:
+ * @binding: An #ExoBinding to unbind.
+ *
+ * Disconnects the binding between two properties. Should be
+ * rarely used by applications.
+ *
+ * This functions also calls the @destroy_notify function that
+ * was specified when @binding was created.
+ **/
+void
+exo_binding_unbind (ExoBinding *binding)
+{
+  g_signal_handler_disconnect (binding->src_object, binding->link.handler);
+}
+
+
+
+/**
+ * exo_mutual_binding_new:
+ * @object1   : The first #GObject.
+ * @property1 : The first property to bind.
+ * @object2   : The second #GObject.
+ * @property2 : The second property to bind.
+ *
+ * Mutually binds values of two properties.
+ *
+ * Before binding the value of @property2 is set to the value
+ * of @property1.
+ *
+ * Return value: The descriptor of the binding. It is automatically
+ *               removed if one of the objects is finalized.
+ **/
+ExoMutualBinding*
+exo_mutual_binding_new (GObject     *object1,
+                        const gchar *property1,
+                        GObject     *object2,
+                        const gchar *property2)
+{
+  return exo_mutual_binding_new_full (object1, property1,
+                                      object2, property2,
+                                      NULL, NULL, NULL, NULL);
+}
+
+
+
+/**
+ * exo_mutual_binding_new_full:
+ * @object1           : The first #GObject.
+ * @property1         : The first property to bind.
+ * @object2           : The second #GObject.
+ * @property2         : The second property to bind.
+ * @transform         : Transformation function or %NULL.
+ * @reverse_transform : The inverse transformation function or %NULL.
+ * @destroy_notify    : Callback function called on disconnection with
+ *                      @user_data as argument or %NULL.
+ * @user_data         : User data associated with the binding.
+ *
+ * Mutually binds values of two properties.
+ *
+ * Before binding the value of @property2 is set to the value of
+ * @property1.
+ *
+ * Both @transform and @reverse_transform should simultaneously be
+ * %NULL or non-%NULL. If they are non-%NULL, they should be reverse
+ * in each other.
+ *
+ * Return value: The descriptor of the binding. It is automatically
+ *               removed if one of the objects is finalized.
+ **/
+ExoMutualBinding*
+exo_mutual_binding_new_full (GObject            *object1,
+                             const gchar        *property1,
+                             GObject            *object2,
+                             const gchar        *property2,
+                             ExoBindingTransform transform,
+                             ExoBindingTransform reverse_transform,
+                             GDestroyNotify      destroy_notify,
+                             gpointer            user_data)
+{
+  ExoMutualBinding  *binding;
+  GParamSpec        *pspec1;
+  GParamSpec        *pspec2;
+
+  g_return_val_if_fail (G_IS_OBJECT (object1), NULL);
+  g_return_val_if_fail (G_IS_OBJECT (object2), NULL);
+
+  pspec1 = g_object_class_find_property (G_OBJECT_GET_CLASS (object1), property1);
+  pspec2 = g_object_class_find_property (G_OBJECT_GET_CLASS (object2), property2);
+
+  if (transform == NULL)
+    transform = (ExoBindingTransform) g_value_transform;
+
+  if (reverse_transform == NULL)
+    reverse_transform = (ExoBindingTransform) g_value_transform;
+
+  exo_bind_properties_transfer (object1,
+                                pspec1,
+                                object2,
+                                pspec2,
+                                transform,
+                                user_data);
+
+  binding = g_slice_new (ExoMutualBinding);
+  binding->base.destroy = destroy_notify;
+
+  exo_binding_link_init (&binding->direct,
+                         object1,
+                         property1,
+                         object2,
+                         pspec2,
+                         transform,
+                         exo_mutual_binding_on_disconnect_object1,
+                         user_data);
+
+  exo_binding_link_init (&binding->reverse,
+                         object2,
+                         property2,
+                         object1,
+                         pspec1,
+                         reverse_transform,
+                         exo_mutual_binding_on_disconnect_object2,
+                         user_data);
+
+  /* tell each link about the reverse link for mutual
+   * bindings, to make sure that we do not ever recurse
+   * in notify (yeah, the GObject notify dispatching is
+   * really weird!).
+   */
+  binding->direct.dst_handler = binding->reverse.handler;
+  binding->reverse.dst_handler = binding->direct.handler;
+
+  return binding;
+}
+
+
+/**
+ * exo_mutual_binding_unbind:
+ * @binding: An #ExoMutualBinding to unbind.
+ *
+ * Disconnects the binding between two properties. Should be
+ * rarely used by applications.
+ *
+ * This functions also calls the @destroy_notify function that
+ * was specified when @binding was created.
+ **/
+void
+exo_mutual_binding_unbind (ExoMutualBinding *binding)
+{
+  g_signal_handler_disconnect (binding->direct.dst_object, binding->direct.handler);
+}

Added: mousepad/branches/nick_0_3/mousepad/mousepad-exo.h
===================================================================
--- mousepad/branches/nick_0_3/mousepad/mousepad-exo.h	                        (rev 0)
+++ mousepad/branches/nick_0_3/mousepad/mousepad-exo.h	2007-04-04 15:50:00 UTC (rev 25379)
@@ -0,0 +1,101 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2004-2006 os-cillation e.K.
+ * Copyright (c) 2004      Victor Porton (http://ex-code.com/~porton/)
+ *
+ * Written by Benedikt Meurer <benny at xfce.org>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __MOUSEPAD_EXO_H__
+#define __MOUSEPAD_EXO_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+typedef struct _ExoBindingBase    ExoBindingBase;
+typedef struct _ExoBindingLink    ExoBindingLink;
+typedef struct _ExoBinding        ExoBinding;
+typedef struct _ExoMutualBinding  ExoMutualBinding;
+
+typedef gboolean  (*ExoBindingTransform)  (const GValue *src_value,
+                                           GValue       *dst_value,
+                                           gpointer      user_data);
+
+struct _ExoBindingBase
+{
+  GDestroyNotify  destroy;
+};
+
+struct _ExoBindingLink
+{
+  GObject             *dst_object;
+  GParamSpec          *dst_pspec;
+  gulong               dst_handler; /* only set for mutual bindings */
+  gulong               handler;
+  ExoBindingTransform  transform;
+  gpointer             user_data;
+};
+
+struct _ExoBinding
+{
+  /*< private >*/
+  GObject         *src_object;
+  ExoBindingBase   base;
+  ExoBindingLink   link;
+};
+
+struct _ExoMutualBinding
+{
+  /*< private >*/
+  ExoBindingBase  base;
+  ExoBindingLink  direct;
+  ExoBindingLink  reverse;
+};
+
+
+ExoBinding        *exo_binding_new                      (GObject            *src_object,
+                                                         const gchar        *src_property,
+                                                         GObject            *dst_object,
+                                                         const gchar        *dst_property);
+ExoBinding        *exo_binding_new_full                 (GObject            *src_object,
+                                                         const gchar        *src_property,
+                                                         GObject            *dst_object,
+                                                         const gchar        *dst_property,
+                                                         ExoBindingTransform transform,
+                                                         GDestroyNotify      destroy_notify,
+                                                         gpointer            user_data);
+void               exo_binding_unbind                   (ExoBinding         *binding);
+
+ExoMutualBinding  *exo_mutual_binding_new               (GObject            *object1,
+                                                         const gchar        *property1,
+                                                         GObject            *object2,
+                                                         const gchar        *property2);
+ExoMutualBinding  *exo_mutual_binding_new_full          (GObject            *object1,
+                                                         const gchar        *property1,
+                                                         GObject            *object2,
+                                                         const gchar        *property2,
+                                                         ExoBindingTransform transform,
+                                                         ExoBindingTransform reverse_transform,
+                                                         GDestroyNotify      destroy_notify,
+                                                         gpointer            user_data);
+void               exo_mutual_binding_unbind            (ExoMutualBinding   *binding);
+
+G_END_DECLS
+
+#endif /* !__MOUSEPAD_EXO_H__ */

Modified: mousepad/branches/nick_0_3/mousepad/mousepad-file.c
===================================================================
--- mousepad/branches/nick_0_3/mousepad/mousepad-file.c	2007-04-04 10:05:00 UTC (rev 25378)
+++ mousepad/branches/nick_0_3/mousepad/mousepad-file.c	2007-04-04 15:50:00 UTC (rev 25379)
@@ -253,9 +253,19 @@
   fd = open (filename, O_RDONLY);
   if (G_UNLIKELY (fd < 0))
     {
-      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
-                   _("Failed to open \"%s\" for reading"), filename);
-      return FALSE;
+      /* the file does not exists, so probably the user ran 'mousepad newfile' from the command line */
+      if (G_LIKELY (errno == ENOENT))
+        {
+          /* we can write the new file */
+          *readonly = FALSE;
+          return TRUE;
+        }
+      else
+        {
+          g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+                       _("Failed to open \"%s\" for reading"), filename);
+          return FALSE;
+        }
     }
 
   /* read the file information */

Added: mousepad/branches/nick_0_3/mousepad/mousepad-marshal.list
===================================================================
--- mousepad/branches/nick_0_3/mousepad/mousepad-marshal.list	                        (rev 0)
+++ mousepad/branches/nick_0_3/mousepad/mousepad-marshal.list	2007-04-04 15:50:00 UTC (rev 25379)
@@ -0,0 +1,2 @@
+VOID:UINT,UINT
+BOOLEAN:STRING,FLAGS

Modified: mousepad/branches/nick_0_3/mousepad/mousepad-preferences.c
===================================================================
--- mousepad/branches/nick_0_3/mousepad/mousepad-preferences.c	2007-04-04 10:05:00 UTC (rev 25378)
+++ mousepad/branches/nick_0_3/mousepad/mousepad-preferences.c	2007-04-04 15:50:00 UTC (rev 25379)
@@ -48,11 +48,9 @@
 enum
 {
   PROP_0,
-  PROP_AUTO_INDENT,
   PROP_FONT_NAME,
   PROP_LAST_WINDOW_HEIGHT,
   PROP_LAST_WINDOW_WIDTH,
-  PROP_LINE_NUMBERS,
   PROP_STATUSBAR,
   PROP_WORD_WRAP,
   PROP_MISC_ALWAYS_SHOW_TABS,
@@ -60,7 +58,6 @@
   PROP_MISC_SHOW_FULL_PATH_IN_TITLE,
   PROP_MISC_RECENT_MENU_LIMIT,
   PROP_MISC_REMEMBER_GEOMETRY,
-  PROP_MISC_TAB_CLOSE_BUTTONS,
   N_PROPERTIES,
 };
 
@@ -179,19 +176,6 @@
     g_value_register_transform_func (G_TYPE_STRING, G_TYPE_INT, transform_string_to_int);
 
   /**
-   * MousepadPreferences:auto-indent
-   *
-   * Whether line identation is enabled.
-   **/
-  g_object_class_install_property (gobject_class,
-                                   PROP_AUTO_INDENT,
-                                   g_param_spec_boolean ("auto-indent",
-                                                         "auto-indent",
-                                                         "auto-indent",
-                                                         FALSE,
-                                                         EXO_PARAM_READWRITE));
-
-  /**
    * MousepadPreferences:font-name
    *
    * The font name and size used in the text view. If this value is
@@ -203,9 +187,22 @@
                                                         "font-name",
                                                         "font-name",
                                                         NULL,
-                                                        EXO_PARAM_READWRITE));
+                                                        MOUSEPAD_PARAM_READWRITE));
 
   /**
+   * MousepadPreferences:statusbar
+   *
+   * Whether to display the statusbar in the Mousepad window.
+   **/
+  g_object_class_install_property (gobject_class,
+                                   PROP_STATUSBAR,
+                                   g_param_spec_boolean ("last-statusbar-visible",
+                                                         "last-statusbar-visible",
+                                                         "last-statusbar-visible",
+                                                         TRUE,
+                                                         MOUSEPAD_PARAM_READWRITE));
+
+  /**
    * MousepadPreferences:last-window-height
    *
    * The last known height of a #MousepadWindow, which will be used as
@@ -217,7 +214,7 @@
                                                      "last-window-height",
                                                      "last-window-height",
                                                      1, G_MAXINT, 480,
-                                                     EXO_PARAM_READWRITE));
+                                                     MOUSEPAD_PARAM_READWRITE));
 
   /**
    * MousepadPreferences:last-window-width
@@ -231,35 +228,9 @@
                                                      "last-window-width",
                                                      "last-window-width",
                                                      1, G_MAXINT, 640,
-                                                     EXO_PARAM_READWRITE));
+                                                     MOUSEPAD_PARAM_READWRITE));
 
   /**
-   * MousepadPreferences:line-numbers
-   *
-   * Whether line numbers are visible in the text view.
-   **/
-  g_object_class_install_property (gobject_class,
-                                   PROP_LINE_NUMBERS,
-                                   g_param_spec_boolean ("line-numbers",
-                                                         "line-numbers",
-                                                         "line-numbers",
-                                                         FALSE,
-                                                         EXO_PARAM_READWRITE));
-
-  /**
-   * MousepadPreferences:statusbar
-   *
-   * Whether to display the statusbar in the Mousepad window.
-   **/
-  g_object_class_install_property (gobject_class,
-                                   PROP_STATUSBAR,
-                                   g_param_spec_boolean ("statusbar",
-                                                         "statusbar",
-                                                         "statusbar",
-                                                         TRUE,
-                                                         EXO_PARAM_READWRITE));
-
-  /**
    * MousepadPreferences:word-wrap
    *
    * Whether word wrapping is enabled.
@@ -270,7 +241,7 @@
                                                          "word-wrap",
                                                          "word-wrap",
                                                          FALSE,
-                                                         EXO_PARAM_READWRITE));
+                                                         MOUSEPAD_PARAM_READWRITE));
 
   /**
    * MousepadPreferences:misc-always-show-tabs
@@ -284,7 +255,7 @@
                                                          "misc-always-show-tabs",
                                                          "misc-always-show-tabs",
                                                          FALSE,
-                                                         EXO_PARAM_READWRITE));
+                                                         MOUSEPAD_PARAM_READWRITE));
 
   /**
    * MousepadPreferences:misc-cycle-tabs
@@ -297,7 +268,7 @@
                                                          "misc-cycle-tabs",
                                                          "misc-cycle-tabs",
                                                          FALSE,
-                                                         EXO_PARAM_READWRITE));
+                                                         MOUSEPAD_PARAM_READWRITE));
 
   /**
    * MousepadPreferences:misc-show-full-path-in-title
@@ -310,7 +281,7 @@
                                                          "misc-show-full-path-in-title",
                                                          "misc-show-full-path-in-title",
                                                          FALSE,
-                                                         EXO_PARAM_READWRITE));
+                                                         MOUSEPAD_PARAM_READWRITE));
 
   /**
    * MousepadPreferences:misc-recent-menu-limit
@@ -323,7 +294,7 @@
                                                      "misc-recent-menu-limit",
                                                      "misc-recent-menu-limit",
                                                      1, G_MAXINT, 10,
-                                                     EXO_PARAM_READWRITE));
+                                                     MOUSEPAD_PARAM_READWRITE));
 
   /**
    * MousepadPreferences:misc-remember-geometry
@@ -340,20 +311,7 @@
                                                          "misc-remember-geometry",
                                                          "misc-remember-geometry",
                                                          TRUE,
-                                                         EXO_PARAM_READWRITE));
-
-  /**
-   * MousepadPreferences:misc-tab-close-buttons
-   *
-   * Whether the close buttons are visible in the tabs.
-   **/
-  g_object_class_install_property (gobject_class,
-                                   PROP_MISC_TAB_CLOSE_BUTTONS,
-                                   g_param_spec_boolean ("misc-tab-close-buttons",
-                                                         "misc-tab-close-buttons",
-                                                         "misc-tab-close-buttons",
-                                                         TRUE,
-                                                         EXO_PARAM_READWRITE));
+                                                         MOUSEPAD_PARAM_READWRITE));
 }
 
 

Modified: mousepad/branches/nick_0_3/mousepad/mousepad-preferences.h
===================================================================
--- mousepad/branches/nick_0_3/mousepad/mousepad-preferences.h	2007-04-04 10:05:00 UTC (rev 25378)
+++ mousepad/branches/nick_0_3/mousepad/mousepad-preferences.h	2007-04-04 15:50:00 UTC (rev 25379)
@@ -20,8 +20,6 @@
 #ifndef __MOUSEPAD_PREFERENCIES_H__
 #define __MOUSEPAD_PREFERENCIES_H__
 
-#include <exo/exo.h>
-
 G_BEGIN_DECLS
 
 #define MOUSEPAD_TYPE_PREFERENCES             (mousepad_preferences_get_type ())

Modified: mousepad/branches/nick_0_3/mousepad/mousepad-private.h
===================================================================
--- mousepad/branches/nick_0_3/mousepad/mousepad-private.h	2007-04-04 10:05:00 UTC (rev 25378)
+++ mousepad/branches/nick_0_3/mousepad/mousepad-private.h	2007-04-04 15:50:00 UTC (rev 25379)
@@ -21,13 +21,33 @@
 #ifndef __MOUSEPAD_PRIVATE_H__
 #define __MOUSEPAD_PRIVATE_H__
 
-#include <exo/exo.h>
+#include <gtk/gtk.h>
+#include <libxfce4util/libxfce4util.h>
 
 G_BEGIN_DECLS
 
-#define DEBUG_LINE g_print ("%d\n", __LINE__);
+/* test timers */
+#define TIMER_START \
+  GTimer *__FUNCTION__timer = g_timer_new();
 
+#define TIMER_SPLIT \
+  g_print ("%s (%d): %f\n", __FUNCTION__, __LINE__, g_timer_elapsed (__FUNCTION__timer, NULL));
 
+#define TIMER_STOP \
+  g_print ("%s (%d): %f\n", __FUNCTION__, __LINE__, g_timer_elapsed (__FUNCTION__timer, NULL)); \
+  g_timer_destroy (__FUNCTION__timer);
+
+
+/* optimize the properties */
+#define MOUSEPAD_PARAM_READWRITE (G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)
+
+
+
+/* support for canonical strings */
+#define I_(string) (g_intern_static_string ((string)))
+
+
+
 /* support macros for debugging */
 #ifndef NDEBUG
 #define _mousepad_assert(expr)                  g_assert (expr)
@@ -45,24 +65,9 @@
 
 /* avoid trivial g_value_get_*() function calls */
 #ifdef NDEBUG
-#define g_value_get_boolean(v)  (((const GValue *) (v))->data[0].v_int)
-#define g_value_get_char(v)     (((const GValue *) (v))->data[0].v_int)
-#define g_value_get_uchar(v)    (((const GValue *) (v))->data[0].v_uint)
-#define g_value_get_int(v)      (((const GValue *) (v))->data[0].v_int)
-#define g_value_get_uint(v)     (((const GValue *) (v))->data[0].v_uint)
-#define g_value_get_long(v)     (((const GValue *) (v))->data[0].v_long)
-#define g_value_get_ulong(v)    (((const GValue *) (v))->data[0].v_ulong)
-#define g_value_get_int64(v)    (((const GValue *) (v))->data[0].v_int64)
-#define g_value_get_uint64(v)   (((const GValue *) (v))->data[0].v_uint64)
-#define g_value_get_enum(v)     (((const GValue *) (v))->data[0].v_long)
-#define g_value_get_flags(v)    (((const GValue *) (v))->data[0].v_ulong)
-#define g_value_get_float(v)    (((const GValue *) (v))->data[0].v_float)
-#define g_value_get_double(v)   (((const GValue *) (v))->data[0].v_double)
-#define g_value_get_string(v)   (((const GValue *) (v))->data[0].v_pointer)
-#define g_value_get_param(v)    (((const GValue *) (v))->data[0].v_pointer)
-#define g_value_get_boxed(v)    (((const GValue *) (v))->data[0].v_pointer)
-#define g_value_get_pointer(v)  (((const GValue *) (v))->data[0].v_pointer)
-#define g_value_get_object(v)   (((const GValue *) (v))->data[0].v_pointer)
+#define g_value_get_string(v)  (((const GValue *) (v))->data[0].v_pointer)
+#define g_value_get_boxed(v)   (((const GValue *) (v))->data[0].v_pointer)
+#define g_value_get_pointer(v) (((const GValue *) (v))->data[0].v_pointer)
 #endif
 
 

Deleted: mousepad/branches/nick_0_3/mousepad/mousepad-screen.c

Deleted: mousepad/branches/nick_0_3/mousepad/mousepad-screen.h

Added: mousepad/branches/nick_0_3/mousepad/mousepad-search-bar.c
===================================================================
--- mousepad/branches/nick_0_3/mousepad/mousepad-search-bar.c	                        (rev 0)
+++ mousepad/branches/nick_0_3/mousepad/mousepad-search-bar.c	2007-04-04 15:50:00 UTC (rev 25379)
@@ -0,0 +1,491 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gdk/gdk.h>
+#include <gdk/gdkkeysyms.h>
+
+#include <mousepad/mousepad-private.h>
+#include <mousepad/mousepad-exo.h>
+#include <mousepad/mousepad-marshal.h>
+#include <mousepad/mousepad-types.h>
+#include <mousepad/mousepad-enum-types.h>
+#include <mousepad/mousepad-search-bar.h>
+#include <mousepad/mousepad-window.h>
+
+
+
+#define TOOL_BAR_ICON_SIZE  GTK_ICON_SIZE_MENU
+#define HIGHTLIGHT_TIMEOUT  500
+
+
+
+static void      mousepad_search_bar_class_init                 (MousepadSearchBarClass  *klass);
+static void      mousepad_search_bar_init                       (MousepadSearchBar       *search_bar);
+static void      mousepad_search_bar_finalize                   (GObject                 *object);
+static void      mousepad_search_bar_find_string                (MousepadSearchBar       *search_bar,
+                                                                 MousepadSearchFlags      flags);
+static void      mousepad_search_hide_clicked                   (MousepadSearchBar       *search_bar);
+static void      mousepad_search_bar_entry_changed              (GtkWidget               *entry,
+                                                                 MousepadSearchBar       *search_bar);
+static void      mousepad_search_bar_highlight_toggled          (GtkWidget               *button,
+                                                                 MousepadSearchBar       *search_bar);
+static void      mousepad_search_bar_match_case_toggled         (GtkWidget               *button,
+                                                                 MousepadSearchBar       *search_bar);
+static gboolean  mousepad_search_bar_highlight_timeout          (gpointer                 user_data);
+static void      mousepad_search_bar_highlight_timeout_destroy  (gpointer                 user_data);
+static void      mousepad_search_bar_nothing_found              (MousepadSearchBar       *search_bar,
+                                                                 gboolean                 nothing_found);
+
+
+enum
+{
+  HIDE_BAR,
+  FIND_STRING,
+  HIGHLIGHT_ALL,
+  LAST_SIGNAL,
+};
+
+
+struct _MousepadSearchBarClass
+{
+  GtkToolbarClass __parent__;
+};
+
+struct _MousepadSearchBar
+{
+  GtkToolbar           __parent__;
+
+  /* text entry */
+  GtkWidget           *entry;
+  GtkToolItem         *next;
+  GtkToolItem         *previous;
+
+  /* if something was found */
+  guint                nothing_found : 1;
+
+  /* settings */
+  guint                highlight_all : 1;
+  guint                match_case : 1;
+
+  /* timeout for highlighting while typing */
+  guint                highlight_id;
+};
+
+
+
+static GObjectClass *mousepad_search_bar_parent_class;
+static guint         search_bar_signals[LAST_SIGNAL];
+
+
+
+GtkWidget *
+mousepad_search_bar_new (void)
+{
+  return g_object_new (MOUSEPAD_TYPE_SEARCH_BAR,
+                       "toolbar-style", GTK_TOOLBAR_BOTH_HORIZ,
+                       "icon-size", TOOL_BAR_ICON_SIZE,
+                       NULL);
+}
+
+
+
+GType
+mousepad_search_bar_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
+
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      type = g_type_register_static_simple (GTK_TYPE_TOOLBAR,
+                                            I_("MousepadSearchBar"),
+                                            sizeof (MousepadSearchBarClass),
+                                            (GClassInitFunc) mousepad_search_bar_class_init,
+                                            sizeof (MousepadSearchBar),
+                                            (GInstanceInitFunc) mousepad_search_bar_init,
+                                            0);
+    }
+
+  return type;
+}
+
+
+
+static void
+mousepad_search_bar_class_init (MousepadSearchBarClass *klass)
+{
+  GObjectClass  *gobject_class;
+  GtkBindingSet *binding_set;
+
+  mousepad_search_bar_parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = mousepad_search_bar_finalize;
+
+  /* signals */
+  search_bar_signals[HIDE_BAR] =
+    g_signal_new (I_("hide-bar"),
+                  G_TYPE_FROM_CLASS (gobject_class),
+                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                  0, NULL, NULL,
+                  g_cclosure_marshal_VOID__VOID,
+                  G_TYPE_NONE, 0);
+
+  search_bar_signals[FIND_STRING] =
+    g_signal_new (I_("find-string"),
+                  G_TYPE_FROM_CLASS (gobject_class),
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL,
+                  _mousepad_marshal_BOOLEAN__STRING_FLAGS,
+                  G_TYPE_BOOLEAN, 2,
+                  G_TYPE_STRING, MOUSEPAD_TYPE_SEARCH_FLAGS);
+
+  search_bar_signals[HIGHLIGHT_ALL] =
+    g_signal_new (I_("highlight-all"),
+                  G_TYPE_FROM_CLASS (gobject_class),
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL,
+                  _mousepad_marshal_BOOLEAN__STRING_FLAGS,
+                  G_TYPE_BOOLEAN, 2,
+                  G_TYPE_STRING, MOUSEPAD_TYPE_SEARCH_FLAGS);
+
+  /* setup key bindings for the search bar */
+  binding_set = gtk_binding_set_by_class (klass);
+  gtk_binding_entry_add_signal (binding_set, GDK_Escape, 0, "hide-bar", 0);
+
+  /* style to hide the shadow around the toolbar and to add a 2px space between the label
+   * and the icon in a toolbar button */
+  gtk_rc_parse_string ("style \"mousepad-search-bar-style\"{GtkToolbar::shadow-type=GTK_SHADOW_NONE}\n"
+                       "class\"MousepadSearchBar\"style\"mousepad-search-bar-style\"\n"
+                       "style \"mousepad-button-style\"{GtkToolButton::icon-spacing=2}\n"
+                       "widget \"MousepadWindow.*.Gtk*ToolButton\" style \"mousepad-button-style\"\n");
+}
+
+
+
+static void
+mousepad_search_bar_init (MousepadSearchBar *search_bar)
+{
+  GtkWidget   *label, *image, *check, *menuitem;
+  GtkToolItem *item;
+
+  /* init variables */
+  search_bar->nothing_found = FALSE;
+  search_bar->highlight_id = 0;
+
+  /* the close button */
+  item = gtk_tool_button_new_from_stock (GTK_STOCK_CLOSE);
+  gtk_toolbar_insert (GTK_TOOLBAR (search_bar), item, -1);
+  gtk_widget_show (GTK_WIDGET (item));
+  g_signal_connect_swapped (G_OBJECT (item), "clicked",
+                            G_CALLBACK (mousepad_search_hide_clicked), search_bar);
+
+  /* the find label */
+  item = gtk_tool_item_new ();
+  gtk_toolbar_insert (GTK_TOOLBAR (search_bar), item, -1);
+  gtk_widget_show (GTK_WIDGET (item));
+
+  label = gtk_label_new_with_mnemonic (_("Fi_nd:"));
+  gtk_container_add (GTK_CONTAINER (item), label);
+  gtk_misc_set_padding (GTK_MISC (label), 2, 0);
+  gtk_widget_show (label);
+
+  /* the entry field */
+  item = gtk_tool_item_new ();
+  gtk_toolbar_insert (GTK_TOOLBAR (search_bar), item, -1);
+  gtk_widget_show (GTK_WIDGET (item));
+
+  search_bar->entry = gtk_entry_new ();
+  gtk_container_add (GTK_CONTAINER (item), search_bar->entry);
+  gtk_label_set_mnemonic_widget (GTK_LABEL (label), search_bar->entry);
+  gtk_widget_show (search_bar->entry);
+  g_signal_connect (G_OBJECT (search_bar->entry), "changed",
+                    G_CALLBACK (mousepad_search_bar_entry_changed), search_bar);
+
+  /* next button */
+  image = gtk_image_new_from_stock (GTK_STOCK_GO_DOWN, TOOL_BAR_ICON_SIZE);
+  gtk_widget_show (image);
+
+  item = gtk_tool_button_new (image, _("_Next"));
+  gtk_tool_item_set_is_important (item, TRUE);
+  gtk_tool_button_set_use_underline (GTK_TOOL_BUTTON (item), TRUE);
+  gtk_toolbar_insert (GTK_TOOLBAR (search_bar), item, -1);
+  gtk_widget_show (GTK_WIDGET (item));
+  g_signal_connect_swapped (G_OBJECT (item), "clicked",
+                            G_CALLBACK (mousepad_search_bar_find_next), search_bar);
+
+  /* previous button */
+  image = gtk_image_new_from_stock (GTK_STOCK_GO_UP, TOOL_BAR_ICON_SIZE);
+  gtk_widget_show (image);
+
+  search_bar->previous = item = gtk_tool_button_new (image, _("_Previous"));
+  gtk_tool_item_set_is_important (item, TRUE);
+  gtk_tool_button_set_use_underline (GTK_TOOL_BUTTON (item), TRUE);
+  gtk_toolbar_insert (GTK_TOOLBAR (search_bar), item, -1);
+  gtk_widget_show (GTK_WIDGET (item));
+  g_signal_connect_swapped (G_OBJECT (item), "clicked",
+                            G_CALLBACK (mousepad_search_bar_find_previous), search_bar);
+
+  /* highlight all */
+  item = (GtkToolItem *) gtk_toggle_tool_button_new ();
+  gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (item), GTK_STOCK_SELECT_ALL);
+  gtk_tool_button_set_label (GTK_TOOL_BUTTON (item), _("Highlight _All"));
+  gtk_tool_item_set_is_important (item, TRUE);
+  gtk_tool_button_set_use_underline (GTK_TOOL_BUTTON (item), TRUE);
+  gtk_toolbar_insert (GTK_TOOLBAR (search_bar), item, -1);
+  gtk_widget_show (GTK_WIDGET (item));
+  g_signal_connect (G_OBJECT (item), "clicked",
+                    G_CALLBACK (mousepad_search_bar_highlight_toggled), search_bar);
+
+  /* check button for case sensitive, including the proxy menu item */
+  item = gtk_tool_item_new ();
+  gtk_toolbar_insert (GTK_TOOLBAR (search_bar), item, -1);
+  gtk_widget_show (GTK_WIDGET (item));
+
+  check = gtk_check_button_new_with_mnemonic (_("Mat_ch Case"));
+  gtk_container_add (GTK_CONTAINER (item), check);
+  gtk_widget_show (check);
+  g_signal_connect (G_OBJECT (check), "toggled",
+                    G_CALLBACK (mousepad_search_bar_match_case_toggled), search_bar);
+
+  menuitem = gtk_check_menu_item_new_with_mnemonic (_("Mat_ch Case"));
+  gtk_tool_item_set_proxy_menu_item (item, "case-sensitive", menuitem);
+  exo_mutual_binding_new (G_OBJECT (check), "active", G_OBJECT (menuitem), "active");
+  gtk_widget_show (menuitem);
+}
+
+
+
+static void
+mousepad_search_bar_finalize (GObject *object)
+{
+  MousepadSearchBar *search_bar = MOUSEPAD_SEARCH_BAR (object);
+
+  /* stop a running highlight timeout */
+  if (search_bar->highlight_id != 0)
+    g_source_remove (search_bar->highlight_id);
+
+  (*G_OBJECT_CLASS (mousepad_search_bar_parent_class)->finalize) (object);
+}
+
+
+
+static void
+mousepad_search_bar_find_string (MousepadSearchBar *search_bar,
+                                 MousepadSearchFlags flags)
+{
+  const gchar *string;
+  gboolean     result;
+
+  /* append the insensitive flags when needed */
+  if (!search_bar->match_case)
+    flags |= MOUSEPAD_SEARCH_CASE_INSENSITIVE;
+
+  /* get the entry string */
+  string = gtk_entry_get_text (GTK_ENTRY (search_bar->entry));
+  if (string != NULL && *string != '\0')
+    {
+      /* send the signal and wait for the result */
+      g_signal_emit (G_OBJECT (search_bar), search_bar_signals[FIND_STRING], 0,
+                     string, flags, &result);
+    }
+  else
+    {
+      result = TRUE;
+    }
+
+  /* change the entry style */
+  mousepad_search_bar_nothing_found (search_bar, !result);
+}
+
+
+
+static void
+mousepad_search_hide_clicked (MousepadSearchBar *search_bar)
+{
+  _mousepad_return_if_fail (MOUSEPAD_IS_SEARCH_BAR (search_bar));
+
+  /* emit the signal */
+  g_signal_emit (G_OBJECT (search_bar), search_bar_signals[HIDE_BAR], 0);
+}
+
+
+
+static void
+mousepad_search_bar_entry_changed (GtkWidget         *entry,
+                                   MousepadSearchBar *search_bar)
+{
+  /* stop a running highlight timeout */
+  if (search_bar->highlight_id != 0)
+    g_source_remove (search_bar->highlight_id);
+
+  if (search_bar->highlight_all)
+    {
+      /* start a new highlight timeout */
+      search_bar->highlight_id = g_timeout_add_full (G_PRIORITY_LOW, HIGHTLIGHT_TIMEOUT,
+                                                           mousepad_search_bar_highlight_timeout, search_bar,
+                                                           mousepad_search_bar_highlight_timeout_destroy);
+    }
+
+  /* find */
+  mousepad_search_bar_find_string (search_bar, 0);
+}
+
+
+
+static void
+mousepad_search_bar_highlight_toggled (GtkWidget         *button,
+                                       MousepadSearchBar *search_bar)
+{
+  gboolean active;
+
+  _mousepad_return_if_fail (MOUSEPAD_IS_SEARCH_BAR (search_bar));
+
+  /* get the state of the toggle button */
+  active = gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (button));
+
+  /* stop a running highlight timeout if the button is inactive*/
+  if (search_bar->highlight_id != 0 && !active)
+    g_source_remove (search_bar->highlight_id);
+
+  /* save the state */
+  search_bar->highlight_all = active;
+
+  /* invoke the highlight function to update the buffer */
+  search_bar->highlight_id = g_idle_add_full (G_PRIORITY_LOW, mousepad_search_bar_highlight_timeout,
+                                              search_bar, mousepad_search_bar_highlight_timeout_destroy);
+}
+
+
+
+static void
+mousepad_search_bar_match_case_toggled (GtkWidget         *button,
+                                        MousepadSearchBar *search_bar)
+{
+  gboolean active;
+
+  _mousepad_return_if_fail (MOUSEPAD_IS_SEARCH_BAR (search_bar));
+
+  /* get the state of the toggle button */
+  active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
+
+  /* save the state */
+  search_bar->match_case = active;
+}
+
+
+
+static gboolean
+mousepad_search_bar_highlight_timeout (gpointer user_data)
+{
+  MousepadSearchBar   *search_bar = MOUSEPAD_SEARCH_BAR (user_data);
+  const gchar         *string = NULL;
+  gboolean             dummy;
+  MousepadSearchFlags  flags;
+
+  GDK_THREADS_ENTER ();
+
+  /* append the insensitive case flag if needed */
+  if (!search_bar->match_case)
+    flags |= MOUSEPAD_SEARCH_CASE_INSENSITIVE;
+
+  /* get the string if highlighting is enabled */
+  if (search_bar->highlight_all)
+    {
+      /* get the entry string */
+      string = gtk_entry_get_text (GTK_ENTRY (search_bar->entry));
+      if (string == NULL || *string == '\0')
+        string = NULL;
+    }
+
+  /* send the signal and wait for the result */
+  g_signal_emit (G_OBJECT (search_bar), search_bar_signals[HIGHLIGHT_ALL], 0,
+                 string, flags, &dummy);
+
+  GDK_THREADS_LEAVE ();
+
+  /* stop the timeout */
+  return FALSE;
+}
+
+
+
+static void
+mousepad_search_bar_highlight_timeout_destroy (gpointer user_data)
+{
+  MOUSEPAD_SEARCH_BAR (user_data)->highlight_id = 0;
+}
+
+
+
+static void
+mousepad_search_bar_nothing_found (MousepadSearchBar *search_bar,
+                                   gboolean           nothing_found)
+{
+  const GdkColor red   = {0, 0xffff, 0x6666, 0x6666};
+  const GdkColor white = {0, 0xffff, 0xffff, 0xffff};
+
+  _mousepad_return_if_fail (MOUSEPAD_IS_SEARCH_BAR (search_bar));
+
+  /* only update the style if really needed */
+  if (search_bar->nothing_found != nothing_found)
+    {
+      /* (re)set the base and font color */
+      gtk_widget_modify_base (search_bar->entry, GTK_STATE_NORMAL, nothing_found ? &red : NULL);
+      gtk_widget_modify_text (search_bar->entry, GTK_STATE_NORMAL, nothing_found ? &white : NULL);
+
+      search_bar->nothing_found = nothing_found;
+    }
+}
+
+
+
+void
+mousepad_search_bar_focus (MousepadSearchBar *search_bar)
+{
+  _mousepad_return_if_fail (MOUSEPAD_IS_SEARCH_BAR (search_bar));
+
+  /* focus the entry field */
+  gtk_widget_grab_focus (search_bar->entry);
+}
+
+
+
+void
+mousepad_search_bar_find_next (MousepadSearchBar *search_bar)
+{
+  _mousepad_return_if_fail (MOUSEPAD_IS_SEARCH_BAR (search_bar));
+
+  /* find */
+  mousepad_search_bar_find_string (search_bar, MOUSEPAD_SEARCH_FORWARDS);
+}
+
+
+
+void
+mousepad_search_bar_find_previous (MousepadSearchBar *search_bar)
+{
+  _mousepad_return_if_fail (MOUSEPAD_IS_SEARCH_BAR (search_bar));
+
+  /* find backwards */
+  mousepad_search_bar_find_string (search_bar, MOUSEPAD_SEARCH_BACKWARDS);
+}

Added: mousepad/branches/nick_0_3/mousepad/mousepad-search-bar.h
===================================================================
--- mousepad/branches/nick_0_3/mousepad/mousepad-search-bar.h	                        (rev 0)
+++ mousepad/branches/nick_0_3/mousepad/mousepad-search-bar.h	2007-04-04 15:50:00 UTC (rev 25379)
@@ -0,0 +1,47 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * 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
+ */
+
+#ifndef __MOUSEPAD_SEARCH_BAR_H__
+#define __MOUSEPAD_SEARCH_BAR_H__
+
+G_BEGIN_DECLS
+
+#define MOUSEPAD_TYPE_SEARCH_BAR            (mousepad_search_bar_get_type ())
+#define MOUSEPAD_SEARCH_BAR(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), MOUSEPAD_TYPE_SEARCH_BAR, MousepadSearchBar))
+#define MOUSEPAD_SEARCH_BAR_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), MOUSEPAD_TYPE_SEARCH_BAR, MousepadSearchBarClass))
+#define MOUSEPAD_IS_SEARCH_BAR(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MOUSEPAD_TYPE_SEARCH_BAR))
+#define MOUSEPAD_IS_SEARCH_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MOUSEPADL_TYPE_SEARCH_BAR))
+#define MOUSEPAD_SEARCH_BAR_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), MOUSEPAD_TYPE_SEARCH_BAR, MousepadSearchBarClass))
+
+typedef struct _MousepadSearchBarClass MousepadSearchBarClass;
+typedef struct _MousepadSearchBar      MousepadSearchBar;
+
+GType           mousepad_search_bar_get_type       (void) G_GNUC_CONST;
+
+GtkWidget      *mousepad_search_bar_new            (void);
+
+void            mousepad_search_bar_focus          (MousepadSearchBar *search_bar);
+
+void            mousepad_search_bar_find_next      (MousepadSearchBar *search_bar);
+
+void            mousepad_search_bar_find_previous  (MousepadSearchBar *search_bar);
+
+G_END_DECLS
+
+#endif /* !__MOUSEPAD_SEARCH_BAR_H__ */

Added: mousepad/branches/nick_0_3/mousepad/mousepad-statusbar.c
===================================================================
--- mousepad/branches/nick_0_3/mousepad/mousepad-statusbar.c	                        (rev 0)
+++ mousepad/branches/nick_0_3/mousepad/mousepad-statusbar.c	2007-04-04 15:50:00 UTC (rev 25379)
@@ -0,0 +1,184 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <mousepad/mousepad-private.h>
+#include <mousepad/mousepad-statusbar.h>
+
+static void              mousepad_statusbar_class_init                (MousepadStatusbarClass *klass);
+static void              mousepad_statusbar_init                      (MousepadStatusbar      *statusbar);
+static void              mousepad_statusbar_finalize                  (GObject                *object);
+
+struct _MousepadStatusbarClass
+{
+  GtkHBoxClass __parent__;
+};
+
+struct _MousepadStatusbar
+{
+  GtkHBox             __parent__;
+
+  /* the three statusbar labels */
+  GtkWidget          *label;
+  GtkWidget          *position;
+  GtkWidget          *overwrite;
+};
+
+
+
+static GObjectClass *mousepad_statusbar_parent_class;
+
+
+
+GtkWidget *
+mousepad_statusbar_new (void)
+{
+  return g_object_new (MOUSEPAD_TYPE_STATUSBAR, NULL);
+}
+
+
+
+GType
+mousepad_statusbar_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
+
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      type = g_type_register_static_simple (GTK_TYPE_HBOX,
+                                            I_("MousepadStatusbar"),
+                                            sizeof (MousepadStatusbarClass),
+                                            (GClassInitFunc) mousepad_statusbar_class_init,
+                                            sizeof (MousepadStatusbar),
+                                            (GInstanceInitFunc) mousepad_statusbar_init,
+                                            0);
+    }
+
+  return type;
+}
+
+
+
+static void
+mousepad_statusbar_class_init (MousepadStatusbarClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  mousepad_statusbar_parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = mousepad_statusbar_finalize;
+}
+
+
+
+static void
+mousepad_statusbar_init (MousepadStatusbar *statusbar)
+{
+  GtkWidget *frame;
+
+  /* spacing between the 3 frames */
+  gtk_box_set_spacing (GTK_BOX (statusbar), 3);
+
+  /* tooltip entry */
+  frame = gtk_frame_new (NULL);
+  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
+  gtk_box_pack_start (GTK_BOX (statusbar), frame, TRUE, TRUE, 0);
+  gtk_widget_show (frame);
+
+  statusbar->label = gtk_label_new (NULL);
+  gtk_label_set_single_line_mode (GTK_LABEL (statusbar->label), TRUE);
+  gtk_misc_set_alignment (GTK_MISC (statusbar->label), 0.0, 0.5);
+  gtk_misc_set_padding (GTK_MISC (statusbar->label), 2, 2);
+  gtk_label_set_ellipsize (GTK_LABEL (statusbar->label), PANGO_ELLIPSIZE_END);
+  gtk_container_add (GTK_CONTAINER (frame), statusbar->label);
+  gtk_widget_show (statusbar->label);
+
+  /* line and column numbers */
+  frame = gtk_frame_new (NULL);
+  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
+  gtk_box_pack_start (GTK_BOX (statusbar), frame, FALSE, FALSE, 0);
+  gtk_widget_show (frame);
+
+  statusbar->position = gtk_label_new (NULL);
+  gtk_container_add (GTK_CONTAINER (frame), statusbar->position);
+  gtk_misc_set_padding (GTK_MISC (statusbar->position), 2, 2);
+  gtk_widget_show (statusbar->position);
+