[gedit] Make GeditAppX11, GeditAppOSX and GeditAppWin32



commit 26bbb85ef80dad35f046a1d20a0c252841e23a0c
Author: Jesse van den Kieboom <jessevdk gnome org>
Date:   Mon May 3 23:44:56 2010 +0200

    Make GeditAppX11, GeditAppOSX and GeditAppWin32
    
    This specializes GeditApp for each (native) platform, implemeting
    relevant bits specific to each platform.

 configure.ac                             |    3 +-
 gedit/Makefile.am                        |   65 +++++++---
 gedit/dialogs/gedit-encodings-dialog.c   |    7 +-
 gedit/dialogs/gedit-preferences-dialog.c |    8 +-
 gedit/gedit-app-osx.c                    |  142 +++++++++++++++++++++
 gedit/gedit-app-osx.h                    |   38 ++++++
 gedit/gedit-app-win32.c                  |  106 ++++++++++++++++
 gedit/gedit-app-win32.h                  |   57 +++++++++
 gedit/gedit-app-x11.c                    |   26 ++++
 gedit/gedit-app-x11.h                    |   34 +++++
 gedit/gedit-app.c                        |  202 ++++++++++++++++++++++++++----
 gedit/gedit-app.h                        |   26 ++++-
 gedit/gedit-commands-help.c              |    7 +-
 gedit/gedit-help.c                       |  123 ------------------
 gedit/gedit-help.h                       |   45 -------
 gedit/{osx => }/gedit-osx-delegate.h     |    0
 gedit/{osx => }/gedit-osx-delegate.m     |    0
 gedit/gedit-window.c                     |   14 +--
 gedit/osx/Makefile.am                    |   23 ----
 gedit/osx/gedit-osx.c                    |   96 --------------
 gedit/osx/gedit-osx.h                    |   19 ---
 21 files changed, 668 insertions(+), 373 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 4e95a33..9c52eea 100644
--- a/configure.ac
+++ b/configure.ac
@@ -112,6 +112,8 @@ fi
 AC_MSG_RESULT([$os_osx])
 AM_CONDITIONAL(OS_OSX, test "$os_osx" = "yes")
 
+AM_CONDITIONAL(GDK_WINDOWING_X11, test "$gdk_windowing" = "x11")
+
 if test "$platform_osx" = "yes"; then
 	AC_DEFINE([PLATFORM_OSX],[1],[Defined if platform is Mac OSX])
 fi
@@ -520,7 +522,6 @@ docs/Makefile
 docs/reference/Makefile
 gedit/dialogs/Makefile
 gedit/smclient/Makefile
-gedit/osx/Makefile
 gedit/Makefile
 help/Makefile
 pixmaps/Makefile
diff --git a/gedit/Makefile.am b/gedit/Makefile.am
index 5a2da38..8605561 100644
--- a/gedit/Makefile.am
+++ b/gedit/Makefile.am
@@ -1,10 +1,6 @@
 ## Process this file with automake to produce Makefile.in
 SUBDIRS = dialogs smclient
 
-if OS_OSX
-SUBDIRS += osx
-endif
-
 bin_PROGRAMS = gedit
 
 noinst_LTLIBRARIES = libgedit.la
@@ -18,18 +14,15 @@ INCLUDES =								\
 	$(WARN_CFLAGS)							\
 	$(DISABLE_DEPRECATED_CFLAGS)					\
 	-DDATADIR=\""$(datadir)"\"					\
-	-DLIBDIR=\""$(libdir)"\"					
+	-DLIBDIR=\""$(libdir)"\"
 
 gedit_SOURCES = \
 	gedit.c
 
 gedit_LDADD = libgedit.la $(GEDIT_LIBS) $(IGE_MAC_LIBS) $(EGG_SMCLIENT_LIBS)
- 
+
 if PLATFORM_WIN32
 gedit_LDFLAGS = -Wl,--export-all-symbols -Wl,--out-implib,libgedit-$(GEDIT_API_VERSION).a
-if OS_WIN32
-gedit_LDFLAGS += -mwindows
-endif
 else
 gedit_LDFLAGS = -export-dynamic -no-undefined -export-symbols-regex "^[[^_]].*"
 endif
@@ -43,25 +36,60 @@ libgedit_la_LIBADD = \
 # GEDIT_LIBS must be the last to ensure correct order on some platforms
 libgedit_la_LIBADD += $(GEDIT_LIBS)
 
+# Mac OSX convenience library and ldflags
 if OS_OSX
 gedit_LDFLAGS += -framework Carbon
 
-libgedit_la_LIBADD += osx/libosx.la
-endif
+noinst_LTLIBRARIES += libosx.la
 
-BUILT_SOURCES = 			\
-	gedit-enum-types.c		\
-	gedit-enum-types.h		\
-	gedit-marshal.c			\
-	gedit-marshal.h
+libosx_la_LDFLAGS = -framework Carbon -framework ApplicationServices -framework Cocoa
+libosx_la_LIBADD = -lobjc
+libosx_la_CFLAGS = -xobjective-c
+
+libosx_la_SOURCES = 		\
+	gedit-app-osx.c		\
+	gedit-app-osx.h		\
+	gedit-osx-delegate.m 	\
+	gedit-osx-delegate.h
+
+libgedit_la_LIBADD += libosx.la
+endif
 
+# Win32 convenience library and ldflags
 if OS_WIN32
+gedit_LDFLAGS += -mwindows
+
+noinst_LTLIBRARIES += libwin32.la
+
+libwin32_la_SOURCES =		\
+	gedit-app-win32.c	\
+	gedit-app-win32.h
+
+libgedit_la_LIBADD += libwin32.la
+
 gedit-res.o: gedit.rc
 	$(WINDRES) -i gedit.rc --input-format=rc -o gedit-res.o -O coff
 
 gedit_LDADD += gedit-res.o
 endif
 
+# X11 convenience library
+if GDK_WINDOWING_X11
+noinst_LTLIBRARIES += libx11.la
+
+libx11_la_SOURCES =		\
+	gedit-app-x11.c		\
+	gedit-app-x11.h
+
+libgedit_la_LIBADD += libx11.la
+endif
+
+BUILT_SOURCES = 			\
+	gedit-enum-types.c		\
+	gedit-enum-types.h		\
+	gedit-marshal.c			\
+	gedit-marshal.h
+
 NOINST_H_FILES =			\
 	gedit-close-button.h		\
 	gedit-dirs.h			\
@@ -99,7 +127,6 @@ INST_H_FILES =				\
 	gedit-encodings.h		\
 	gedit-encodings-combo-box.h	\
 	gedit-file-chooser-dialog.h	\
-	gedit-help.h 			\
 	gedit-message-bus.h		\
 	gedit-message-type.h		\
 	gedit-message.h			\
@@ -125,7 +152,6 @@ headerdir = $(prefix)/include/gedit- GEDIT_API_VERSION@/gedit
 header_DATA = 				\
 	$(INST_H_FILES)
 
-
 libgedit_la_SOURCES = 			\
 	$(BUILT_SOURCES)		\
 	$(BACON_FILES)			\
@@ -150,7 +176,6 @@ libgedit_la_SOURCES = 			\
 	gedit-encodings.c		\
 	gedit-encodings-combo-box.c	\
 	gedit-file-chooser-dialog.c	\
-	gedit-help.c			\
 	gedit-history-entry.c		\
 	gedit-io-error-message-area.c	\
 	gedit-language-manager.c	\
@@ -186,7 +211,7 @@ libgedit_la_SOURCES = 			\
 	$(INST_H_FILES)
 
 if !ENABLE_GVFS_METADATA
-libgedit_la_SOURCES += gedit-metadata-manager.c 
+libgedit_la_SOURCES += gedit-metadata-manager.c
 endif
 
 gedit-enum-types.h: gedit-enum-types.h.template $(INST_H_FILES) $(GLIB_MKENUMS)
diff --git a/gedit/dialogs/gedit-encodings-dialog.c b/gedit/dialogs/gedit-encodings-dialog.c
index 71f3825..31abcc5 100644
--- a/gedit/dialogs/gedit-encodings-dialog.c
+++ b/gedit/dialogs/gedit-encodings-dialog.c
@@ -43,7 +43,6 @@
 #include "gedit-prefs-manager.h"
 #include "gedit-utils.h"
 #include "gedit-debug.h"
-#include "gedit-help.h"
 #include "gedit-dirs.h"
 
 #define GEDIT_ENCODINGS_DIALOG_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \
@@ -276,7 +275,11 @@ response_handler (GtkDialog            *dialog,
 {
 	if (response_id == GTK_RESPONSE_HELP)
 	{
-		gedit_help_display (GTK_WINDOW (dialog), "gedit", NULL);
+		gedit_app_show_help (gedit_app_get_default(),
+		                     GTK_WINDOW (dialog),
+		                     "gedit",
+		                     NULL);
+
 		g_signal_stop_emission_by_name (dialog, "response");
 		return;
 	}
diff --git a/gedit/dialogs/gedit-preferences-dialog.c b/gedit/dialogs/gedit-preferences-dialog.c
index 40d66d5..b74adf6 100644
--- a/gedit/dialogs/gedit-preferences-dialog.c
+++ b/gedit/dialogs/gedit-preferences-dialog.c
@@ -47,7 +47,6 @@
 #include "gedit-document.h"
 #include "gedit-style-scheme-manager.h"
 #include "gedit-plugin-manager.h"
-#include "gedit-help.h"
 #include "gedit-dirs.h"
 
 /*
@@ -152,9 +151,10 @@ dialog_response_handler (GtkDialog *dlg,
 	switch (res_id)
 	{
 		case GTK_RESPONSE_HELP:
-			gedit_help_display (GTK_WINDOW (dlg),
-					    NULL,
-					    "gedit-prefs");
+			gedit_app_show_help (gedit_app_get_default (),
+			                     GTK_WINDOW (dlg),
+			                     NULL,
+			                     "gedit-prefs");
 
 			g_signal_stop_emission_by_name (dlg, "response");
 
diff --git a/gedit/gedit-app-osx.c b/gedit/gedit-app-osx.c
new file mode 100644
index 0000000..5712ca8
--- /dev/null
+++ b/gedit/gedit-app-osx.c
@@ -0,0 +1,142 @@
+#include "gedit-app-osx.h"
+
+#include <gdk/gdkquartz.h>
+#include <Carbon/Carbon.h>
+
+#import "gedit-osx-delegate.h"
+
+G_DEFINE_TYPE (GeditAppOSX, gedit_app_osx, GEDIT_TYPE_APP)
+
+static void
+gedit_app_osx_finalize (GObject *object)
+{
+	G_OBJECT_CLASS (gedit_app_osx_parent_class)->finalize (object);
+}
+
+static gboolean
+gedit_app_osx_last_window_destroyed_impl (GeditApp *app)
+{
+	if (!GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "gedit-is-quitting-all")))
+	{
+		/* Create hidden proxy window on OS X to handle the menu */
+		gedit_app_create_window (app, NULL);
+		return FALSE;
+	}
+
+	return GEDIT_APP_CLASS (gedit_app_osx_parent_class)->last_window_destroyed (app);
+}
+
+static gboolean
+gedit_app_osx_show_url (GeditAppOSX *app,
+                        const gchar *url)
+{
+	return [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[NSString stringWithUTF8String:url]]];
+}
+
+static gboolean
+gedit_app_osx_show_help_impl (GeditApp    *app,
+                              GtkWindow   *parent,
+                              const gchar *name,
+                              const gchar *link_id)
+{
+	gboolean ret = FALSE;
+
+	if (name == NULL || strcmp(name, "gedit.xml") == NULL || strcmp(name, "gedit") == 0)
+	{
+		gchar *link;
+
+		if (link_id)
+		{
+			link = g_strdup_printf ("http://library.gnome.org/users/gedit/stable/%s";,
+						link_id);
+		}
+		else
+		{
+			link = g_strdup ("http://library.gnome.org/users/gedit/stable/";);
+		}
+
+		ret = gedit_osx_show_url (link);
+		g_free (link);
+	}
+
+	return ret;
+}
+
+static void
+gedit_app_osx_set_window_title_impl (GeditApp    *app,
+                                     GeditWindow *window,
+                                     const gchar *title)
+{
+	NSWindow *native;
+	GeditDocument *document;
+
+	g_return_if_fail (GEDIT_IS_WINDOW (window));
+
+	if (GTK_WIDGET (window)->window == NULL)
+	{
+		return;
+	}
+
+	native = gdk_quartz_window_get_nswindow (GTK_WIDGET (window)->window);
+	document = gedit_app_get_active_document (app);
+
+	if (document)
+	{
+		bool ismodified;
+
+		if (gedit_document_is_untitled (document))
+		{
+			[native setRepresentedURL:nil];
+		}
+		else
+		{
+			const gchar *uri = gedit_document_get_uri (document);
+			NSURL *nsurl = [NSURL URLWithString:[NSString stringWithUTF8String:uri]];
+			
+			[native setRepresentedURL:nsurl];
+		}
+
+		ismodified = !gedit_document_is_untouched (document); 
+		[native setDocumentEdited:ismodified];
+	}
+	else
+	{
+		[native setRepresentedURL:nil];
+		[native setDocumentEdited:false];
+	}
+
+	GEDIT_APP (gedit_app_osx_parent_class)->set_window_title (app, window, title);
+}
+
+static void
+gedit_app_osx_class_init (GeditAppOSXClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	GeditAppClass *app_class = GEDIT_APP_CLASS (klass);
+
+	object_class->finalize = gedit_app_osx_finalize;
+
+	app_class->last_window_destroyed = gedit_app_osx_last_window_destroyed_impl;
+	app_class->show_help = gedit_app_show_help_impl;
+}
+
+static void
+destroy_delegate (GeditOSXDelegate *delegate)
+{
+	[delegate dealloc];
+}
+
+static void
+gedit_app_osx_init (GeditAppOSX *self)
+{
+	GeditOSXDelegate *delegate = [[GeditOSXDelegate alloc] init];
+
+	g_object_set_data_full (G_OBJECT (app),
+	                        "GeditOSXDelegate",
+	                        delegate,
+	                        (GDestroyNotify)destroy_delegate);
+
+	ige_mac_menu_set_global_key_handler_enabled (FALSE);
+}
+
+/* ex:ts=8:noet: */
diff --git a/gedit/gedit-app-osx.h b/gedit/gedit-app-osx.h
new file mode 100644
index 0000000..e7e4674
--- /dev/null
+++ b/gedit/gedit-app-osx.h
@@ -0,0 +1,38 @@
+#ifndef __GEDIT_APP_OSX_H__
+#define __GEDIT_APP_OSX_H__
+
+#include "gedit-app.h"
+#include <ige-mac-integration.h>
+
+G_BEGIN_DECLS
+
+#define GEDIT_TYPE_APP_OSX		(gedit_app_osx_get_type ())
+#define GEDIT_APP_OSX(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_APP_OSX, GeditAppOSX))
+#define GEDIT_APP_OSX_CONST(obj)	(G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_APP_OSX, GeditAppOSX const))
+#define GEDIT_APP_OSX_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), GEDIT_TYPE_APP_OSX, GeditAppOSXClass))
+#define GEDIT_IS_APP_OSX(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEDIT_TYPE_APP_OSX))
+#define GEDIT_IS_APP_OSX_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), GEDIT_TYPE_APP_OSX))
+#define GEDIT_APP_OSX_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), GEDIT_TYPE_APP_OSX, GeditAppOSXClass))
+
+typedef struct _GeditAppOSX		GeditAppOSX;
+typedef struct _GeditAppOSXClass	GeditAppOSXClass;
+typedef struct _GeditAppOSXPrivate	GeditAppOSXPrivate;
+
+struct _GeditAppOSX {
+	GeditApp parent;
+};
+
+struct _GeditAppOSXClass {
+	GeditAppClass parent_class;
+};
+
+GType gedit_app_osx_get_type (void) G_GNUC_CONST;
+void gedit_app_osx_set_window_title (GeditAppOSX *app, GeditWindow *window, const gchar *title, GeditDocument *document);
+gboolean gedit_app_osx_show_url (GeditAppOSX *app, const gchar *url);
+gboolean gedit_app_osx_show_help (GeditAppOSX *app, const gchar *link_id);
+
+G_END_DECLS
+
+#endif /* __GEDIT_APP_OSX_H__ */
+
+/* ex:ts=8:noet: */
diff --git a/gedit/gedit-app-win32.c b/gedit/gedit-app-win32.c
new file mode 100644
index 0000000..6d9c221
--- /dev/null
+++ b/gedit/gedit-app-win32.c
@@ -0,0 +1,106 @@
+#include "gedit-app-win32.h"
+
+#define SAVE_DATADIR DATADIR
+#undef DATADIR
+#include <io.h>
+#include <conio.h>
+#define _WIN32_WINNT 0x0500
+#include <windows.h>
+#define DATADIR SAVE_DATADIR
+#undef SAVE_DATADIR
+
+
+G_DEFINE_TYPE (GeditAppWin32, gedit_app_win32, GEDIT_TYPE_APP)
+
+static void
+gedit_app_win32_finalize (GObject *object)
+{
+	G_OBJECT_CLASS (gedit_app_win32_parent_class)->finalize (object);
+}
+
+static gchar *
+gedit_app_win32_help_link_id_impl (GeditApp    *app,
+                                   const gchar *name,
+                                   const gchar *link_id)
+{
+	if (link_id)
+	{
+		return g_strdup_printf ("http://library.gnome.org/users/gedit/stable/%s";,
+		                        link_id);
+	}
+	else
+	{
+		return g_strdup ("http://library.gnome.org/users/gedit/stable/";);
+	}
+}
+
+static void
+gedit_app_win32_class_init (GeditAppWin32Class *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	GeditAppClass *app_class = GEDIT_APP_CLASS (klass);
+
+	object_class->finalize = gedit_app_win32_finalize;
+
+	app_class->help_link_id = gedit_app_win32_help_link_id_impl;
+}
+
+static void
+setup_path (void)
+{
+	gchar *path;
+	gchar *installdir;
+	gchar *bin;
+
+	installdir = g_win32_get_package_installation_directory_of_module (NULL);
+
+	bin = g_build_filename (installdir, "bin", NULL);
+	g_free (installdir);
+
+	/* Set PATH to include the gedit executable's folder */
+	path = g_build_path (";", bin, g_getenv ("PATH"), NULL);
+	g_free (bin);
+
+	if (!g_setenv ("PATH", path, TRUE))
+	{
+		g_warning ("Could not set PATH for gedit");
+	}
+
+	g_free (path);
+}
+
+static void
+prep_console (void)
+{
+	/* If we open gedit from a console get the stdout printing */
+	if (fileno (stdout) != -1 &&
+		_get_osfhandle (fileno (stdout)) != -1)
+	{
+		/* stdout is fine, presumably redirected to a file or pipe */
+	}
+	else
+	{
+		typedef BOOL (* WINAPI AttachConsole_t) (DWORD);
+
+		AttachConsole_t p_AttachConsole =
+			(AttachConsole_t) GetProcAddress (GetModuleHandle ("kernel32.dll"),
+							  "AttachConsole");
+
+		if (p_AttachConsole != NULL && p_AttachConsole (ATTACH_PARENT_PROCESS))
+		{
+			freopen ("CONOUT$", "w", stdout);
+			dup2 (fileno (stdout), 1);
+			freopen ("CONOUT$", "w", stderr);
+			dup2 (fileno (stderr), 2);
+		}
+	}
+}
+
+static void
+gedit_app_win32_init (GeditAppWin32 *self)
+{
+	setup_path ();
+	prep_console ();
+}
+
+/* ex:ts=8:noet: */
diff --git a/gedit/gedit-app-win32.h b/gedit/gedit-app-win32.h
new file mode 100644
index 0000000..23ef3c1
--- /dev/null
+++ b/gedit/gedit-app-win32.h
@@ -0,0 +1,57 @@
+/*
+ * gedit-win32.h
+ * This file is part of gedit
+ *
+ * Copyright (C) 2010 - Jesse van den Kieboom
+ *
+ * gedit is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * gedit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with gedit; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifndef __GEDIT_APP_WIN32_H__
+#define __GEDIT_APP_WIN32_H__
+
+#include "gedit-app.h"
+
+G_BEGIN_DECLS
+
+#define GEDIT_TYPE_APP_WIN32		(gedit_app_win32_get_type ())
+#define GEDIT_APP_WIN32(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_APP_WIN32, GeditAppWin32))
+#define GEDIT_APP_WIN32_CONST(obj)	(G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_APP_WIN32, GeditAppWin32 const))
+#define GEDIT_APP_WIN32_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), GEDIT_TYPE_APP_WIN32, GeditAppWin32Class))
+#define GEDIT_IS_APP_WIN32(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEDIT_TYPE_APP_WIN32))
+#define GEDIT_IS_APP_WIN32_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), GEDIT_TYPE_APP_WIN32))
+#define GEDIT_APP_WIN32_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), GEDIT_TYPE_APP_WIN32, GeditAppWin32Class))
+
+typedef struct _GeditAppWin32		GeditAppWin32;
+typedef struct _GeditAppWin32Class	GeditAppWin32Class;
+typedef struct _GeditAppWin32Private	GeditAppWin32Private;
+
+struct _GeditAppWin32 {
+	GeditApp parent;
+};
+
+struct _GeditAppWin32Class {
+	GeditAppClass parent_class;
+};
+
+GType gedit_app_win32_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __GEDIT_APP_WIN32_H__ */
+
+
+/* ex:ts=8:noet: */
diff --git a/gedit/gedit-app-x11.c b/gedit/gedit-app-x11.c
new file mode 100644
index 0000000..8f304a7
--- /dev/null
+++ b/gedit/gedit-app-x11.c
@@ -0,0 +1,26 @@
+#include "gedit-app-x11.h"
+
+#define GEDIT_APP_X11_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GEDIT_TYPE_APP_X11, GeditAppX11Private))
+
+G_DEFINE_TYPE (GeditAppX11, gedit_app_x11, GEDIT_TYPE_APP)
+
+static void
+gedit_app_x11_finalize (GObject *object)
+{
+	G_OBJECT_CLASS (gedit_app_x11_parent_class)->finalize (object);
+}
+
+static void
+gedit_app_x11_class_init (GeditAppX11Class *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	object_class->finalize = gedit_app_x11_finalize;
+}
+
+static void
+gedit_app_x11_init (GeditAppX11 *self)
+{
+}
+
+/* ex:ts=8:noet: */
diff --git a/gedit/gedit-app-x11.h b/gedit/gedit-app-x11.h
new file mode 100644
index 0000000..fe82ceb
--- /dev/null
+++ b/gedit/gedit-app-x11.h
@@ -0,0 +1,34 @@
+#ifndef __GEDIT_APP_X11_H__
+#define __GEDIT_APP_X11_H__
+
+#include "gedit-app.h"
+
+G_BEGIN_DECLS
+
+#define GEDIT_TYPE_APP_X11		(gedit_app_x11_get_type ())
+#define GEDIT_APP_X11(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_APP_X11, GeditAppX11))
+#define GEDIT_APP_X11_CONST(obj)	(G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_APP_X11, GeditAppX11 const))
+#define GEDIT_APP_X11_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), GEDIT_TYPE_APP_X11, GeditAppX11Class))
+#define GEDIT_IS_APP_X11(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEDIT_TYPE_APP_X11))
+#define GEDIT_IS_APP_X11_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), GEDIT_TYPE_APP_X11))
+#define GEDIT_APP_X11_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), GEDIT_TYPE_APP_X11, GeditAppX11Class))
+
+typedef struct _GeditAppX11		GeditAppX11;
+typedef struct _GeditAppX11Class	GeditAppX11Class;
+typedef struct _GeditAppX11Private	GeditAppX11Private;
+
+struct _GeditAppX11 {
+	GeditApp parent;
+};
+
+struct _GeditAppX11Class {
+	GeditAppClass parent_class;
+};
+
+GType gedit_app_x11_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __GEDIT_APP_X11_H__ */
+
+/* ex:ts=8:noet: */
diff --git a/gedit/gedit-app.c b/gedit/gedit-app.c
index 941fa42..2789067 100644
--- a/gedit/gedit-app.c
+++ b/gedit/gedit-app.c
@@ -48,7 +48,13 @@
 #include "gseal-gtk-compat.h"
 
 #ifdef OS_OSX
-#include <ige-mac-integration.h>
+#include "gedit-app-osx.h"
+#else
+#ifdef OS_WIN32
+#include "gedit-app-win32.h"
+#else
+#include "gedit-app-x11.h"
+#endif
 #endif
 
 #define GEDIT_PAGE_SETUP_FILE		"gedit-page-setup"
@@ -74,7 +80,7 @@ struct _GeditAppPrivate
 	GtkPrintSettings  *print_settings;
 };
 
-G_DEFINE_TYPE(GeditApp, gedit_app, G_TYPE_OBJECT)
+G_DEFINE_ABSTRACT_TYPE(GeditApp, gedit_app, G_TYPE_INITIALLY_UNOWNED)
 
 static void
 gedit_app_finalize (GObject *object)
@@ -110,14 +116,135 @@ gedit_app_get_property (GObject    *object,
 	}
 }
 
-static void 
+static void
+app_weak_notify (gpointer  data,
+                 GObject  *where_the_app_was)
+{
+	gtk_main_quit ();
+}
+
+static GObject *
+gedit_app_constructor (GType                  gtype,
+                       guint                  n_construct_params,
+                       GObjectConstructParam *construct_params)
+{
+	static GObject *app = NULL;
+
+	if (!app)
+	{
+		app = G_OBJECT_CLASS (gedit_app_parent_class)->constructor (gtype,
+		                                                            n_construct_params,
+		                                                            construct_params);
+
+		g_object_add_weak_pointer (app, (gpointer *) &app);
+		g_object_weak_ref (app, app_weak_notify, NULL);
+
+		return app;
+	}
+
+	return g_object_ref (app);
+}
+
+static gboolean
+gedit_app_last_window_destroyed_impl (GeditApp *app)
+{
+	return TRUE;
+}
+
+static gchar *
+gedit_app_help_link_id_impl (GeditApp    *app,
+                             const gchar *name,
+                             const gchar *link_id)
+{
+	if (link_id)
+	{
+		return g_strdup_printf ("ghelp:%s?%s", name, link_id);
+	}
+	else
+	{
+		return g_strdup_printf ("ghelp:%s", name);
+	}
+}
+
+static gboolean
+gedit_app_show_help_impl (GeditApp    *app,
+                          GtkWindow   *parent,
+                          const gchar *name,
+                          const gchar *link_id)
+{
+	GError *error = NULL;
+	gboolean ret;
+	gchar *link;
+
+	if (name == NULL)
+	{
+		name = "gedit";
+	}
+	else if (strcmp (name, "gedit.xml") == 0)
+	{
+		g_warning ("%s: Using \"gedit.xml\" for the help name is deprecated, use \"gedit\" or simply NULL instead", G_STRFUNC);
+		name = "gedit";
+	}
+
+	link = GEDIT_APP_GET_CLASS (app)->help_link_id (app, name, link_id);
+
+	ret = gtk_show_uri (gtk_widget_get_screen (GTK_WIDGET (parent)),
+	                    link,
+	                    GDK_CURRENT_TIME,
+	                    &error);
+
+	g_free (link);
+
+	if (error != NULL)
+	{
+		GtkWidget *dialog;
+
+		dialog = gtk_message_dialog_new (parent,
+						 GTK_DIALOG_DESTROY_WITH_PARENT,
+						 GTK_MESSAGE_ERROR,
+						 GTK_BUTTONS_CLOSE, 
+						 _("There was an error displaying the help."));
+
+		gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+							  "%s", error->message);
+
+		g_signal_connect (G_OBJECT (dialog),
+				  "response",
+				  G_CALLBACK (gtk_widget_destroy),
+				  NULL);
+
+		gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
+
+		gtk_widget_show (dialog);
+
+		g_error_free (error);
+	}
+
+	return ret;
+}
+
+static void
+gedit_app_set_window_title_impl (GeditApp    *app,
+                                 GeditWindow *window,
+                                 const gchar *title)
+{
+	gtk_window_set_title (GTK_WINDOW (window), title);
+}
+
+static void
 gedit_app_class_init (GeditAppClass *klass)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
 	object_class->finalize = gedit_app_finalize;
 	object_class->get_property = gedit_app_get_property;
-	
+	object_class->constructor = gedit_app_constructor;
+
+	klass->last_window_destroyed = gedit_app_last_window_destroyed_impl;
+	klass->show_help = gedit_app_show_help_impl;
+	klass->help_link_id = gedit_app_help_link_id_impl;
+	klass->set_window_title = gedit_app_set_window_title_impl;
+
 	g_object_class_install_property (object_class,
 					 PROP_LOCKDOWN,
 					 g_param_spec_flags ("lockdown",
@@ -165,7 +292,7 @@ load_accels (void)
 	filename = gedit_dirs_get_user_accels_file ();
 	if (filename != NULL)
 	{
-		gedit_debug_message (DEBUG_APP, "Loading keybindings from %s\n", filename);		
+		gedit_debug_message (DEBUG_APP, "Loading keybindings from %s\n", filename);
 		gtk_accel_map_load (filename);
 		g_free (filename);
 	}
@@ -179,7 +306,7 @@ save_accels (void)
 	filename = gedit_dirs_get_user_accels_file ();
 	if (filename != NULL)
 	{
-		gedit_debug_message (DEBUG_APP, "Saving keybindings in %s\n", filename);		
+		gedit_debug_message (DEBUG_APP, "Saving keybindings in %s\n", filename);
 		gtk_accel_map_save (filename);
 		g_free (filename);
 	}
@@ -342,13 +469,6 @@ gedit_app_init (GeditApp *app)
 	app->priv->lockdown = gedit_prefs_manager_get_lockdown ();
 }
 
-static void
-app_weak_notify (gpointer data,
-		 GObject *where_the_app_was)
-{
-	gtk_main_quit ();
-}
-
 /**
  * gedit_app_get_default:
  *
@@ -360,18 +480,29 @@ app_weak_notify (gpointer data,
 GeditApp *
 gedit_app_get_default (void)
 {
-	static GeditApp *app = NULL;
+	GeditApp *app;
+	GType type;
 
-	if (app != NULL)
-		return app;
+#ifdef OS_OSX
+	type = GEDIT_TYPE_APP_OSX;
+#else
+#ifdef OS_WIN32
+	type = GEDIT_TYPE_APP_WIN32;
+#else
+	type = GEDIT_TYPE_APP_X11;
+#endif
+#endif
 
-	app = GEDIT_APP (g_object_new (GEDIT_TYPE_APP, NULL));	
+	app = GEDIT_APP (g_object_new (type, NULL));
 
-	g_object_add_weak_pointer (G_OBJECT (app),
-				   (gpointer) &app);
-	g_object_weak_ref (G_OBJECT (app),
-			   app_weak_notify,
-			   NULL);
+	if (g_object_is_floating (app))
+	{
+		g_object_ref_sink (app);
+	}
+	else
+	{
+		g_object_unref (app);
+	}
 
 	return app;
 }
@@ -441,14 +572,11 @@ window_destroy (GeditWindow *window,
 */
 	if (app->priv->windows == NULL)
 	{
-#ifdef OS_OSX
-		if (!GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "gedit-is-quitting-all")))
+		if (!GEDIT_APP_GET_CLASS (app)->last_window_destroyed (app))
 		{
-			/* Create hidden proxy window on OS X to handle the menu */
-			gedit_app_create_window (app, NULL);
 			return;
 		}
-#endif
+
 		/* Last window is gone... save some settings and exit */
 		ensure_user_config_dir ();
 
@@ -815,6 +943,26 @@ gedit_app_get_lockdown (GeditApp *app)
 	return app->priv->lockdown;
 }
 
+gboolean
+gedit_app_show_help (GeditApp    *app,
+                     GtkWindow   *parent,
+                     const gchar *name,
+                     const gchar *link_id)
+{
+	g_return_val_if_fail (GEDIT_IS_APP (app), FALSE);
+	g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), FALSE);
+
+	return GEDIT_APP_GET_CLASS (app)->show_help (app, parent, name, link_id);
+}
+
+void
+gedit_app_set_window_title (GeditApp    *app,
+                            GeditWindow *window,
+                            const gchar *title)
+{
+	GEDIT_APP_GET_CLASS (app)->set_window_title (app, window, title);
+}
+
 static void
 app_lockdown_changed (GeditApp *app)
 {
diff --git a/gedit/gedit-app.h b/gedit/gedit-app.h
index 7072597..07368b3 100644
--- a/gedit/gedit-app.h
+++ b/gedit/gedit-app.h
@@ -57,7 +57,7 @@ typedef struct _GeditApp GeditApp;
 
 struct _GeditApp 
 {
-	GObject object;
+	GInitiallyUnowned parent;
 
 	/*< private > */
 	GeditAppPrivate *priv;
@@ -71,6 +71,21 @@ typedef struct _GeditAppClass GeditAppClass;
 struct _GeditAppClass 
 {
 	GObjectClass parent_class;
+
+	gboolean (*last_window_destroyed)	(GeditApp *app);
+
+	gboolean (*show_help)			(GeditApp    *app,
+	                                         GtkWindow   *parent,
+	                                         const gchar *name,
+	                                         const gchar *link_id);
+
+	gchar *(*help_link_id)			(GeditApp    *app,
+	                                         const gchar *name,
+	                                         const gchar *link_id);
+
+	void (*set_window_title)		(GeditApp    *app,
+	                                         GeditWindow *window,
+	                                         const gchar *title);
 };
 
 /*
@@ -107,6 +122,15 @@ GList		*gedit_app_get_views			(GeditApp *app);
 /* Lockdown state */
 GeditLockdownMask gedit_app_get_lockdown		(GeditApp *app);
 
+gboolean	 gedit_app_show_help			(GeditApp    *app,
+                                                         GtkWindow   *parent,
+                                                         const gchar *name,
+                                                         const gchar *link_id);
+
+void		 gedit_app_set_window_title		(GeditApp    *app,
+                                                         GeditWindow *window,
+                                                         const gchar *title);
+
 /*
  * Non exported functions
  */
diff --git a/gedit/gedit-commands-help.c b/gedit/gedit-commands-help.c
index d5cdf09..2c71f87 100644
--- a/gedit/gedit-commands-help.c
+++ b/gedit/gedit-commands-help.c
@@ -39,7 +39,7 @@
 
 #include "gedit-commands.h"
 #include "gedit-debug.h"
-#include "gedit-help.h"
+#include "gedit-app.h"
 #include "gedit-dirs.h"
 
 void
@@ -48,7 +48,10 @@ _gedit_cmd_help_contents (GtkAction   *action,
 {
 	gedit_debug (DEBUG_COMMANDS);
 
-	gedit_help_display (GTK_WINDOW (window), NULL, NULL);
+	gedit_app_show_help (gedit_app_get_default (),
+	                     GTK_WINDOW (window),
+	                     NULL,
+	                     NULL);
 }
 
 void
diff --git a/gedit/osx/gedit-osx-delegate.h b/gedit/gedit-osx-delegate.h
similarity index 100%
rename from gedit/osx/gedit-osx-delegate.h
rename to gedit/gedit-osx-delegate.h
diff --git a/gedit/osx/gedit-osx-delegate.m b/gedit/gedit-osx-delegate.m
similarity index 100%
rename from gedit/osx/gedit-osx-delegate.m
rename to gedit/gedit-osx-delegate.m
diff --git a/gedit/gedit-window.c b/gedit/gedit-window.c
index bdd919d..1faa446 100644
--- a/gedit/gedit-window.c
+++ b/gedit/gedit-window.c
@@ -2221,11 +2221,9 @@ set_title (GeditWindow *window)
 
 	if (window->priv->active_tab == NULL)
 	{
-#ifdef OS_OSX
-		gedit_osx_set_window_title (window, "gedit", NULL);
-#else
-		gtk_window_set_title (GTK_WINDOW (window), "gedit");
-#endif
+		gedit_app_set_window_title (gedit_app_get_default (),
+		                            window,
+		                            "gedit");
 		return;
 	}
 
@@ -2305,11 +2303,7 @@ set_title (GeditWindow *window)
 						 name);
 	}
 
-#ifdef OS_OSX
-	gedit_osx_set_window_title (window, title, doc);
-#else
-	gtk_window_set_title (GTK_WINDOW (window), title);
-#endif
+	gedit_app_set_window_title (gedit_app_get_default (), window, title);
 
 	g_free (dirname);
 	g_free (name);



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