Rename Pluma to Xedit
This commit is contained in:
		
							
								
								
									
										209
									
								
								xedit/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										209
									
								
								xedit/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,209 @@
 | 
			
		||||
## Process this file with automake to produce Makefile.in
 | 
			
		||||
SUBDIRS = dialogs smclient
 | 
			
		||||
 | 
			
		||||
bin_PROGRAMS = xedit
 | 
			
		||||
 | 
			
		||||
noinst_LTLIBRARIES = libxedit.la
 | 
			
		||||
 | 
			
		||||
AM_CPPFLAGS =								\
 | 
			
		||||
	-I$(top_srcdir)							\
 | 
			
		||||
	-I$(srcdir)							\
 | 
			
		||||
	-I$(srcdir)/smclient						\
 | 
			
		||||
	$(XEDIT_CFLAGS)							\
 | 
			
		||||
	$(MATE_DESKTOP_CFLAGS)						\
 | 
			
		||||
	$(WARN_CFLAGS)							\
 | 
			
		||||
	$(DISABLE_DEPRECATED_CFLAGS)					\
 | 
			
		||||
	-DDATADIR=\""$(datadir)"\"					\
 | 
			
		||||
	-DLIBDIR=\""$(libdir)"\"
 | 
			
		||||
 | 
			
		||||
xedit_SOURCES = \
 | 
			
		||||
	xedit.c
 | 
			
		||||
 | 
			
		||||
xedit_LDADD = libxedit.la $(XEDIT_LIBS) $(EGG_SMCLIENT_LIBS)
 | 
			
		||||
 | 
			
		||||
xedit_LDFLAGS = -export-dynamic -no-undefined -export-symbols-regex "^[[^_]].*"
 | 
			
		||||
 | 
			
		||||
libxedit_la_LDFLAGS = -export-dynamic -no-undefined -export-symbols-regex "^[[^_]].*"
 | 
			
		||||
 | 
			
		||||
libxedit_la_LIBADD = \
 | 
			
		||||
	dialogs/libdialogs.la		\
 | 
			
		||||
	smclient/libeggsmclient.la	\
 | 
			
		||||
	$(MATE_DESKTOP_LIBS)
 | 
			
		||||
 | 
			
		||||
# XEDIT_LIBS must be the last to ensure correct order on some platforms
 | 
			
		||||
libxedit_la_LIBADD += $(XEDIT_LIBS) -lICE
 | 
			
		||||
 | 
			
		||||
BUILT_SOURCES = 			\
 | 
			
		||||
	xedit-enum-types.c		\
 | 
			
		||||
	xedit-enum-types.h		\
 | 
			
		||||
	xedit-marshal.c			\
 | 
			
		||||
	xedit-marshal.h
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
NOINST_H_FILES =			\
 | 
			
		||||
	xedit-close-button.h		\
 | 
			
		||||
	xedit-dirs.h			\
 | 
			
		||||
	xedit-document-input-stream.h	\
 | 
			
		||||
	xedit-document-loader.h		\
 | 
			
		||||
	xedit-document-output-stream.h	\
 | 
			
		||||
	xedit-document-saver.h		\
 | 
			
		||||
	xedit-documents-panel.h		\
 | 
			
		||||
	xedit-gio-document-loader.h	\
 | 
			
		||||
	xedit-gio-document-saver.h	\
 | 
			
		||||
	xedit-history-entry.h		\
 | 
			
		||||
	xedit-io-error-message-area.h	\
 | 
			
		||||
	xedit-language-manager.h	\
 | 
			
		||||
	xedit-object-module.h		\
 | 
			
		||||
	xedit-plugin-info.h		\
 | 
			
		||||
	xedit-plugin-info-priv.h	\
 | 
			
		||||
	xedit-plugin-loader.h		\
 | 
			
		||||
	xedit-plugin-manager.h		\
 | 
			
		||||
	xedit-plugins-engine.h		\
 | 
			
		||||
	xedit-prefs-manager-private.h	\
 | 
			
		||||
	xedit-print-job.h		\
 | 
			
		||||
	xedit-print-preview.h		\
 | 
			
		||||
	xedit-session.h			\
 | 
			
		||||
	xedit-smart-charset-converter.h	\
 | 
			
		||||
	xedit-style-scheme-manager.h	\
 | 
			
		||||
	xedit-tab-label.h		\
 | 
			
		||||
	xedittextregion.h		\
 | 
			
		||||
	xedit-ui.h			\
 | 
			
		||||
	xedit-window-private.h
 | 
			
		||||
 | 
			
		||||
INST_H_FILES =				\
 | 
			
		||||
	xedit-app.h			\
 | 
			
		||||
	xedit-commands.h		\
 | 
			
		||||
	xedit-debug.h			\
 | 
			
		||||
	xedit-document.h 		\
 | 
			
		||||
	xedit-encodings.h		\
 | 
			
		||||
	xedit-encodings-combo-box.h	\
 | 
			
		||||
	xedit-file-chooser-dialog.h	\
 | 
			
		||||
	xedit-help.h 			\
 | 
			
		||||
	xedit-message-bus.h		\
 | 
			
		||||
	xedit-message-type.h		\
 | 
			
		||||
	xedit-message.h			\
 | 
			
		||||
	xedit-notebook.h		\
 | 
			
		||||
	xedit-panel.h			\
 | 
			
		||||
	xedit-plugin.h			\
 | 
			
		||||
	xedit-prefs-manager-app.h	\
 | 
			
		||||
	xedit-prefs-manager.h		\
 | 
			
		||||
	xedit-progress-message-area.h	\
 | 
			
		||||
	xedit-statusbar.h		\
 | 
			
		||||
	xedit-status-combo-box.h	\
 | 
			
		||||
	xedit-tab.h 			\
 | 
			
		||||
	xedit-utils.h 			\
 | 
			
		||||
	xedit-view.h 			\
 | 
			
		||||
	xedit-window.h
 | 
			
		||||
 | 
			
		||||
if !ENABLE_GVFS_METADATA
 | 
			
		||||
INST_H_FILES += xedit-metadata-manager.h
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
headerdir = $(prefix)/include/xedit
 | 
			
		||||
 | 
			
		||||
header_DATA = 				\
 | 
			
		||||
	$(INST_H_FILES)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
libxedit_la_SOURCES = 			\
 | 
			
		||||
	$(BUILT_SOURCES)		\
 | 
			
		||||
	$(BACON_FILES)			\
 | 
			
		||||
	$(POSIXIO_FILES)		\
 | 
			
		||||
	xedit-app.c			\
 | 
			
		||||
	xedit-close-button.c		\
 | 
			
		||||
	xedit-commands-documents.c	\
 | 
			
		||||
	xedit-commands-edit.c		\
 | 
			
		||||
	xedit-commands-file.c		\
 | 
			
		||||
	xedit-commands-file-print.c	\
 | 
			
		||||
	xedit-commands-help.c		\
 | 
			
		||||
	xedit-commands-search.c		\
 | 
			
		||||
	xedit-commands-view.c		\
 | 
			
		||||
	xedit-debug.c			\
 | 
			
		||||
	xedit-dirs.c			\
 | 
			
		||||
	xedit-document.c 		\
 | 
			
		||||
	xedit-document-input-stream.c	\
 | 
			
		||||
	xedit-document-loader.c		\
 | 
			
		||||
	xedit-document-output-stream.c	\
 | 
			
		||||
	xedit-gio-document-loader.c	\
 | 
			
		||||
	xedit-document-saver.c		\
 | 
			
		||||
	xedit-gio-document-saver.c	\
 | 
			
		||||
	xedit-documents-panel.c		\
 | 
			
		||||
	xedit-encodings.c		\
 | 
			
		||||
	xedit-encodings-combo-box.c	\
 | 
			
		||||
	xedit-file-chooser-dialog.c	\
 | 
			
		||||
	xedit-help.c			\
 | 
			
		||||
	xedit-history-entry.c		\
 | 
			
		||||
	xedit-io-error-message-area.c	\
 | 
			
		||||
	xedit-language-manager.c	\
 | 
			
		||||
	xedit-message-bus.c		\
 | 
			
		||||
	xedit-message-type.c		\
 | 
			
		||||
	xedit-message.c			\
 | 
			
		||||
	xedit-object-module.c		\
 | 
			
		||||
	xedit-notebook.c		\
 | 
			
		||||
	xedit-panel.c			\
 | 
			
		||||
	xedit-plugin-info.c		\
 | 
			
		||||
	xedit-plugin.c			\
 | 
			
		||||
	xedit-plugin-loader.c		\
 | 
			
		||||
	xedit-plugin-manager.c		\
 | 
			
		||||
	xedit-plugins-engine.c		\
 | 
			
		||||
	xedit-prefs-manager-app.c	\
 | 
			
		||||
	xedit-prefs-manager.c		\
 | 
			
		||||
	xedit-prefs-manager-private.h	\
 | 
			
		||||
	xedit-print-job.c		\
 | 
			
		||||
	xedit-print-preview.c		\
 | 
			
		||||
	xedit-progress-message-area.c	\
 | 
			
		||||
	xedit-session.c			\
 | 
			
		||||
	xedit-smart-charset-converter.c	\
 | 
			
		||||
	xedit-statusbar.c		\
 | 
			
		||||
	xedit-status-combo-box.c	\
 | 
			
		||||
	xedit-style-scheme-manager.c	\
 | 
			
		||||
	xedit-tab.c 			\
 | 
			
		||||
	xedit-tab-label.c		\
 | 
			
		||||
	xedit-utils.c 			\
 | 
			
		||||
	xedit-view.c 			\
 | 
			
		||||
	xedit-window.c			\
 | 
			
		||||
	xedittextregion.c		\
 | 
			
		||||
	$(NOINST_H_FILES)		\
 | 
			
		||||
	$(INST_H_FILES)
 | 
			
		||||
 | 
			
		||||
if !ENABLE_GVFS_METADATA
 | 
			
		||||
libxedit_la_SOURCES += xedit-metadata-manager.c
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
xedit-enum-types.h: xedit-enum-types.h.template $(INST_H_FILES) $(GLIB_MKENUMS)
 | 
			
		||||
	$(AM_V_GEN) (cd $(srcdir) && $(GLIB_MKENUMS) --template xedit-enum-types.h.template $(INST_H_FILES)) > $@
 | 
			
		||||
 | 
			
		||||
xedit-enum-types.c: xedit-enum-types.c.template $(INST_H_FILES) $(GLIB_MKENUMS)
 | 
			
		||||
	$(AM_V_GEN) (cd $(srcdir) && $(GLIB_MKENUMS) --template xedit-enum-types.c.template $(INST_H_FILES)) > $@
 | 
			
		||||
 | 
			
		||||
xedit-marshal.h: xedit-marshal.list $(GLIB_GENMARSHAL)
 | 
			
		||||
	$(AM_V_GEN) $(GLIB_GENMARSHAL) $< --header --prefix=xedit_marshal > $@
 | 
			
		||||
 | 
			
		||||
xedit-marshal.c: xedit-marshal.list $(GLIB_GENMARSHAL)
 | 
			
		||||
	$(AM_V_GEN) echo "#include \"xedit-marshal.h\"" > $@ && \
 | 
			
		||||
	$(GLIB_GENMARSHAL) $< --body --prefix=xedit_marshal >> $@
 | 
			
		||||
 | 
			
		||||
uidir = $(datadir)/xedit/ui/
 | 
			
		||||
ui_DATA = 				\
 | 
			
		||||
	xedit-ui.xml			\
 | 
			
		||||
	xedit-print-preferences.ui
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = 				\
 | 
			
		||||
	$(ui_DATA)			\
 | 
			
		||||
	xedit-enum-types.h.template	\
 | 
			
		||||
	xedit-enum-types.c.template	\
 | 
			
		||||
	xedit-marshal.list		\
 | 
			
		||||
	xedit.rc
 | 
			
		||||
 | 
			
		||||
CLEANFILES = $(BUILT_SOURCES)
 | 
			
		||||
 | 
			
		||||
dist-hook:
 | 
			
		||||
	cd $(distdir); rm -f $(BUILT_SOURCES)
 | 
			
		||||
 | 
			
		||||
BACON_DIR=$(srcdir)/../../libbacon/src/
 | 
			
		||||
BACON_FILES=bacon-message-connection.h bacon-message-connection.c
 | 
			
		||||
 | 
			
		||||
regenerate-built-sources:
 | 
			
		||||
	BACONFILES="$(BACON_FILES)" BACONDIR="$(BACON_DIR)" $(top_srcdir)/xedit/update-from-bacon.sh
 | 
			
		||||
 | 
			
		||||
-include $(top_srcdir)/git.mk
 | 
			
		||||
							
								
								
									
										396
									
								
								xedit/bacon-message-connection.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										396
									
								
								xedit/bacon-message-connection.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,396 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2003 Bastien Nocera <hadess@hadess.net>
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <sys/un.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
#include "bacon-message-connection.h"
 | 
			
		||||
 | 
			
		||||
#ifndef UNIX_PATH_MAX
 | 
			
		||||
#define UNIX_PATH_MAX 108
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
struct BaconMessageConnection {
 | 
			
		||||
	/* A server accepts connections */
 | 
			
		||||
	gboolean is_server;
 | 
			
		||||
 | 
			
		||||
	/* The socket path itself */
 | 
			
		||||
	char *path;
 | 
			
		||||
 | 
			
		||||
	/* File descriptor of the socket */
 | 
			
		||||
	int fd;
 | 
			
		||||
	/* Channel to watch */
 | 
			
		||||
	GIOChannel *chan;
 | 
			
		||||
	/* Event id returned by g_io_add_watch() */
 | 
			
		||||
	int conn_id;
 | 
			
		||||
 | 
			
		||||
	/* Connections accepted by this connection */
 | 
			
		||||
	GSList *accepted_connections;
 | 
			
		||||
 | 
			
		||||
	/* callback */
 | 
			
		||||
	void (*func) (const char *message, gpointer user_data);
 | 
			
		||||
	gpointer data;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
test_is_socket (const char *path)
 | 
			
		||||
{
 | 
			
		||||
	struct stat s;
 | 
			
		||||
 | 
			
		||||
	if (stat (path, &s) == -1)
 | 
			
		||||
		return FALSE;
 | 
			
		||||
 | 
			
		||||
	if (S_ISSOCK (s.st_mode))
 | 
			
		||||
		return TRUE;
 | 
			
		||||
 | 
			
		||||
	return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
is_owned_by_user_and_socket (const char *path)
 | 
			
		||||
{
 | 
			
		||||
	struct stat s;
 | 
			
		||||
 | 
			
		||||
	if (stat (path, &s) == -1)
 | 
			
		||||
		return FALSE;
 | 
			
		||||
 | 
			
		||||
	if (s.st_uid != geteuid ())
 | 
			
		||||
		return FALSE;
 | 
			
		||||
 | 
			
		||||
	if ((s.st_mode & S_IFSOCK) != S_IFSOCK)
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean server_cb (GIOChannel *source,
 | 
			
		||||
			   GIOCondition condition, gpointer data);
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
setup_connection (BaconMessageConnection *conn)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (conn->chan == NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
	conn->chan = g_io_channel_unix_new (conn->fd);
 | 
			
		||||
	if (!conn->chan) {
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
	g_io_channel_set_line_term (conn->chan, "\n", 1);
 | 
			
		||||
	conn->conn_id = g_io_add_watch (conn->chan, G_IO_IN, server_cb, conn);
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
accept_new_connection (BaconMessageConnection *server_conn)
 | 
			
		||||
{
 | 
			
		||||
	BaconMessageConnection *conn;
 | 
			
		||||
	int alen;
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (server_conn->is_server);
 | 
			
		||||
 | 
			
		||||
	conn = g_new0 (BaconMessageConnection, 1);
 | 
			
		||||
	conn->is_server = FALSE;
 | 
			
		||||
	conn->func = server_conn->func;
 | 
			
		||||
	conn->data = server_conn->data;
 | 
			
		||||
 | 
			
		||||
	conn->fd = accept (server_conn->fd, NULL, (guint *)&alen);
 | 
			
		||||
 | 
			
		||||
	server_conn->accepted_connections =
 | 
			
		||||
		g_slist_prepend (server_conn->accepted_connections, conn);
 | 
			
		||||
 | 
			
		||||
	setup_connection (conn);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
server_cb (GIOChannel *source, GIOCondition condition, gpointer data)
 | 
			
		||||
{
 | 
			
		||||
	BaconMessageConnection *conn = (BaconMessageConnection *)data;
 | 
			
		||||
	char *message, *subs, buf;
 | 
			
		||||
	int cd, rc, offset;
 | 
			
		||||
	gboolean finished;
 | 
			
		||||
 | 
			
		||||
	offset = 0;
 | 
			
		||||
	if (conn->is_server && conn->fd == g_io_channel_unix_get_fd (source)) {
 | 
			
		||||
		accept_new_connection (conn);
 | 
			
		||||
		return TRUE;
 | 
			
		||||
	}
 | 
			
		||||
	message = g_malloc (1);
 | 
			
		||||
	cd = conn->fd;
 | 
			
		||||
	rc = read (cd, &buf, 1);
 | 
			
		||||
	while (rc > 0 && buf != '\n')
 | 
			
		||||
	{
 | 
			
		||||
		message = g_realloc (message, rc + offset + 1);
 | 
			
		||||
		message[offset] = buf;
 | 
			
		||||
		offset = offset + rc;
 | 
			
		||||
		rc = read (cd, &buf, 1);
 | 
			
		||||
	}
 | 
			
		||||
	if (rc <= 0) {
 | 
			
		||||
		g_io_channel_shutdown (conn->chan, FALSE, NULL);
 | 
			
		||||
		g_io_channel_unref (conn->chan);
 | 
			
		||||
		conn->chan = NULL;
 | 
			
		||||
		close (conn->fd);
 | 
			
		||||
		conn->fd = -1;
 | 
			
		||||
		g_free (message);
 | 
			
		||||
		conn->conn_id = 0;
 | 
			
		||||
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
	message[offset] = '\0';
 | 
			
		||||
 | 
			
		||||
	subs = message;
 | 
			
		||||
	finished = FALSE;
 | 
			
		||||
 | 
			
		||||
	while (finished == FALSE && *subs != '\0')
 | 
			
		||||
	{
 | 
			
		||||
		if (conn->func != NULL)
 | 
			
		||||
			(*conn->func) (subs, conn->data);
 | 
			
		||||
 | 
			
		||||
		subs += strlen (subs) + 1;
 | 
			
		||||
		if (subs - message >= offset)
 | 
			
		||||
			finished = TRUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_free (message);
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
find_file_with_pattern (const char *dir, const char *pattern)
 | 
			
		||||
{
 | 
			
		||||
	GDir *filedir;
 | 
			
		||||
	char *found_filename;
 | 
			
		||||
	const char *filename;
 | 
			
		||||
	GPatternSpec *pat;
 | 
			
		||||
 | 
			
		||||
	filedir = g_dir_open (dir, 0, NULL);
 | 
			
		||||
	if (filedir == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	pat = g_pattern_spec_new (pattern);
 | 
			
		||||
	if (pat == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		g_dir_close (filedir);
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	found_filename = NULL;
 | 
			
		||||
 | 
			
		||||
	while ((filename = g_dir_read_name (filedir)))
 | 
			
		||||
	{
 | 
			
		||||
		if (g_pattern_match_string (pat, filename))
 | 
			
		||||
		{
 | 
			
		||||
			char *tmp = g_build_filename (dir, filename, NULL);
 | 
			
		||||
			if (is_owned_by_user_and_socket (tmp))
 | 
			
		||||
				found_filename = g_strdup (filename);
 | 
			
		||||
			g_free (tmp);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (found_filename != NULL)
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_pattern_spec_free (pat);
 | 
			
		||||
	g_dir_close (filedir);
 | 
			
		||||
 | 
			
		||||
	return found_filename;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
socket_filename (const char *prefix)
 | 
			
		||||
{
 | 
			
		||||
	char *pattern, *newfile, *path, *filename;
 | 
			
		||||
	const char *tmpdir;
 | 
			
		||||
 | 
			
		||||
	pattern = g_strdup_printf ("%s.%s.*", prefix, g_get_user_name ());
 | 
			
		||||
	tmpdir = g_get_tmp_dir ();
 | 
			
		||||
	filename = find_file_with_pattern (tmpdir, pattern);
 | 
			
		||||
	if (filename == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		newfile = g_strdup_printf ("%s.%s.%u", prefix,
 | 
			
		||||
				g_get_user_name (), g_random_int ());
 | 
			
		||||
		path = g_build_filename (tmpdir, newfile, NULL);
 | 
			
		||||
		g_free (newfile);
 | 
			
		||||
	} else {
 | 
			
		||||
		path = g_build_filename (tmpdir, filename, NULL);
 | 
			
		||||
		g_free (filename);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_free (pattern);
 | 
			
		||||
	return path;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
try_server (BaconMessageConnection *conn)
 | 
			
		||||
{
 | 
			
		||||
	struct sockaddr_un uaddr;
 | 
			
		||||
 | 
			
		||||
	uaddr.sun_family = AF_UNIX;
 | 
			
		||||
	strncpy (uaddr.sun_path, conn->path,
 | 
			
		||||
			MIN (strlen(conn->path)+1, UNIX_PATH_MAX));
 | 
			
		||||
	conn->fd = socket (PF_UNIX, SOCK_STREAM, 0);
 | 
			
		||||
	if (bind (conn->fd, (struct sockaddr *) &uaddr, sizeof (uaddr)) == -1)
 | 
			
		||||
	{
 | 
			
		||||
		conn->fd = -1;
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
	listen (conn->fd, 5);
 | 
			
		||||
 | 
			
		||||
	if (!setup_connection (conn))
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
try_client (BaconMessageConnection *conn)
 | 
			
		||||
{
 | 
			
		||||
	struct sockaddr_un uaddr;
 | 
			
		||||
 | 
			
		||||
	uaddr.sun_family = AF_UNIX;
 | 
			
		||||
	strncpy (uaddr.sun_path, conn->path,
 | 
			
		||||
			MIN(strlen(conn->path)+1, UNIX_PATH_MAX));
 | 
			
		||||
	conn->fd = socket (PF_UNIX, SOCK_STREAM, 0);
 | 
			
		||||
	if (connect (conn->fd, (struct sockaddr *) &uaddr,
 | 
			
		||||
				sizeof (uaddr)) == -1)
 | 
			
		||||
	{
 | 
			
		||||
		conn->fd = -1;
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return setup_connection (conn);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BaconMessageConnection *
 | 
			
		||||
bacon_message_connection_new (const char *prefix)
 | 
			
		||||
{
 | 
			
		||||
	BaconMessageConnection *conn;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (prefix != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	conn = g_new0 (BaconMessageConnection, 1);
 | 
			
		||||
	conn->path = socket_filename (prefix);
 | 
			
		||||
 | 
			
		||||
	if (test_is_socket (conn->path) == FALSE)
 | 
			
		||||
	{
 | 
			
		||||
		if (!try_server (conn))
 | 
			
		||||
		{
 | 
			
		||||
			bacon_message_connection_free (conn);
 | 
			
		||||
			return NULL;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		conn->is_server = TRUE;
 | 
			
		||||
		return conn;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (try_client (conn) == FALSE)
 | 
			
		||||
	{
 | 
			
		||||
		unlink (conn->path);
 | 
			
		||||
		try_server (conn);
 | 
			
		||||
		if (conn->fd == -1)
 | 
			
		||||
		{
 | 
			
		||||
			bacon_message_connection_free (conn);
 | 
			
		||||
			return NULL;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		conn->is_server = TRUE;
 | 
			
		||||
		return conn;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	conn->is_server = FALSE;
 | 
			
		||||
	return conn;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
bacon_message_connection_free (BaconMessageConnection *conn)
 | 
			
		||||
{
 | 
			
		||||
	GSList *child_conn;
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (conn != NULL);
 | 
			
		||||
	/* Only servers can accept other connections */
 | 
			
		||||
	g_return_if_fail (conn->is_server != FALSE ||
 | 
			
		||||
			  conn->accepted_connections == NULL);
 | 
			
		||||
 | 
			
		||||
	child_conn = conn->accepted_connections;
 | 
			
		||||
	while (child_conn != NULL) {
 | 
			
		||||
		bacon_message_connection_free (child_conn->data);
 | 
			
		||||
		child_conn = g_slist_next (child_conn);
 | 
			
		||||
	}
 | 
			
		||||
	g_slist_free (conn->accepted_connections);
 | 
			
		||||
 | 
			
		||||
	if (conn->conn_id) {
 | 
			
		||||
		g_source_remove (conn->conn_id);
 | 
			
		||||
		conn->conn_id = 0;
 | 
			
		||||
	}
 | 
			
		||||
	if (conn->chan) {
 | 
			
		||||
		g_io_channel_shutdown (conn->chan, FALSE, NULL);
 | 
			
		||||
		g_io_channel_unref (conn->chan);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (conn->is_server != FALSE) {
 | 
			
		||||
		unlink (conn->path);
 | 
			
		||||
	}
 | 
			
		||||
	if (conn->fd != -1) {
 | 
			
		||||
		close (conn->fd);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_free (conn->path);
 | 
			
		||||
	g_free (conn);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
bacon_message_connection_set_callback (BaconMessageConnection *conn,
 | 
			
		||||
				       BaconMessageReceivedFunc func,
 | 
			
		||||
				       gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (conn != NULL);
 | 
			
		||||
 | 
			
		||||
	conn->func = func;
 | 
			
		||||
	conn->data = user_data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
bacon_message_connection_send (BaconMessageConnection *conn,
 | 
			
		||||
			       const char *message)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (conn != NULL);
 | 
			
		||||
	g_return_if_fail (message != NULL);
 | 
			
		||||
 | 
			
		||||
	g_io_channel_write_chars (conn->chan, message, strlen (message),
 | 
			
		||||
				  NULL, NULL);
 | 
			
		||||
	g_io_channel_write_chars (conn->chan, "\n", 1, NULL, NULL);
 | 
			
		||||
	g_io_channel_flush (conn->chan, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
bacon_message_connection_get_is_server (BaconMessageConnection *conn)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (conn != NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
	return conn->is_server;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										43
									
								
								xedit/bacon-message-connection.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								xedit/bacon-message-connection.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2003 Bastien Nocera <hadess@hadess.net>
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef BACON_MESSAGE_CONNECTION_H
 | 
			
		||||
#define BACON_MESSAGE_CONNECTION_H
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
typedef void (*BaconMessageReceivedFunc) (const char *message,
 | 
			
		||||
					  gpointer user_data);
 | 
			
		||||
 | 
			
		||||
typedef struct BaconMessageConnection BaconMessageConnection;
 | 
			
		||||
 | 
			
		||||
BaconMessageConnection *bacon_message_connection_new	(const char *prefix);
 | 
			
		||||
void bacon_message_connection_free			(BaconMessageConnection *conn);
 | 
			
		||||
void bacon_message_connection_set_callback		(BaconMessageConnection *conn,
 | 
			
		||||
							 BaconMessageReceivedFunc func,
 | 
			
		||||
							 gpointer user_data);
 | 
			
		||||
void bacon_message_connection_send			(BaconMessageConnection *conn,
 | 
			
		||||
							 const char *message);
 | 
			
		||||
gboolean bacon_message_connection_get_is_server		(BaconMessageConnection *conn);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* BACON_MESSAGE_CONNECTION_H */
 | 
			
		||||
							
								
								
									
										31
									
								
								xedit/dialogs/Makefile.am
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										31
									
								
								xedit/dialogs/Makefile.am
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
uidir = $(datadir)/xedit/ui/
 | 
			
		||||
 | 
			
		||||
AM_CPPFLAGS = 							\
 | 
			
		||||
	-I$(top_srcdir)						\
 | 
			
		||||
	-I$(top_builddir)					\
 | 
			
		||||
	-I$(top_srcdir)/xedit 					\
 | 
			
		||||
	-I$(top_builddir)/xedit					\
 | 
			
		||||
	$(XEDIT_CFLAGS) 					\
 | 
			
		||||
	$(WARN_CFLAGS)						\
 | 
			
		||||
	$(DISABLE_DEPRECATED_CFLAGS)
 | 
			
		||||
 | 
			
		||||
noinst_LTLIBRARIES = libdialogs.la
 | 
			
		||||
 | 
			
		||||
libdialogs_la_SOURCES = 			\
 | 
			
		||||
	xedit-preferences-dialog.h		\
 | 
			
		||||
	xedit-preferences-dialog.c		\
 | 
			
		||||
	xedit-close-confirmation-dialog.c 	\
 | 
			
		||||
	xedit-close-confirmation-dialog.h 	\
 | 
			
		||||
	xedit-encodings-dialog.c		\
 | 
			
		||||
	xedit-encodings-dialog.h		\
 | 
			
		||||
	xedit-search-dialog.h			\
 | 
			
		||||
	xedit-search-dialog.c
 | 
			
		||||
 | 
			
		||||
ui_DATA =					\
 | 
			
		||||
	xedit-encodings-dialog.ui		\
 | 
			
		||||
	xedit-preferences-dialog.ui		\
 | 
			
		||||
	xedit-search-dialog.ui
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = $(ui_DATA)
 | 
			
		||||
 | 
			
		||||
-include $(top_srcdir)/git.mk
 | 
			
		||||
							
								
								
									
										836
									
								
								xedit/dialogs/xedit-close-confirmation-dialog.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										836
									
								
								xedit/dialogs/xedit-close-confirmation-dialog.c
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,836 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-close-confirmation-dialog.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2004-2005 GNOME Foundation
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA. 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2004-2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
 | 
			
		||||
#include "xedit-close-confirmation-dialog.h"
 | 
			
		||||
#include <xedit/xedit-app.h>
 | 
			
		||||
#include <xedit/xedit-utils.h>
 | 
			
		||||
#include <xedit/xedit-window.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Properties */
 | 
			
		||||
enum 
 | 
			
		||||
{
 | 
			
		||||
	PROP_0,	
 | 
			
		||||
	PROP_UNSAVED_DOCUMENTS,
 | 
			
		||||
	PROP_LOGOUT_MODE
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Mode */
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
	SINGLE_DOC_MODE,
 | 
			
		||||
	MULTIPLE_DOCS_MODE
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Columns */
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
	SAVE_COLUMN,
 | 
			
		||||
	NAME_COLUMN,
 | 
			
		||||
	DOC_COLUMN, /* a handy pointer to the document */
 | 
			
		||||
	N_COLUMNS
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _XeditCloseConfirmationDialogPrivate 
 | 
			
		||||
{
 | 
			
		||||
	gboolean     logout_mode;
 | 
			
		||||
 | 
			
		||||
	GList       *unsaved_documents;
 | 
			
		||||
	
 | 
			
		||||
	GList       *selected_documents;
 | 
			
		||||
 | 
			
		||||
	GtkTreeModel *list_store;
 | 
			
		||||
	
 | 
			
		||||
	gboolean     disable_save_to_disk;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define XEDIT_CLOSE_CONFIRMATION_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
 | 
			
		||||
							XEDIT_TYPE_CLOSE_CONFIRMATION_DIALOG, \
 | 
			
		||||
							XeditCloseConfirmationDialogPrivate))
 | 
			
		||||
 | 
			
		||||
#define GET_MODE(priv) (((priv->unsaved_documents != NULL) && \
 | 
			
		||||
			 (priv->unsaved_documents->next == NULL)) ? \
 | 
			
		||||
			  SINGLE_DOC_MODE : MULTIPLE_DOCS_MODE)
 | 
			
		||||
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
#define gtk_hbox_new(X,Y) gtk_box_new(GTK_ORIENTATION_HORIZONTAL,Y)
 | 
			
		||||
#define gtk_vbox_new(X,Y) gtk_box_new(GTK_ORIENTATION_VERTICAL,Y)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE(XeditCloseConfirmationDialog, xedit_close_confirmation_dialog, GTK_TYPE_DIALOG)
 | 
			
		||||
 | 
			
		||||
static void 	 set_unsaved_document 		(XeditCloseConfirmationDialog *dlg,
 | 
			
		||||
						 const GList                  *list);
 | 
			
		||||
 | 
			
		||||
static GList 	*get_selected_docs 		(GtkTreeModel                 *store);
 | 
			
		||||
 | 
			
		||||
/*  Since we connect in the costructor we are sure this handler will be called 
 | 
			
		||||
 *  before the user ones
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
response_cb (XeditCloseConfirmationDialog *dlg,
 | 
			
		||||
             gint                          response_id,
 | 
			
		||||
             gpointer                      data)
 | 
			
		||||
{
 | 
			
		||||
	XeditCloseConfirmationDialogPrivate *priv;
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_CLOSE_CONFIRMATION_DIALOG (dlg));
 | 
			
		||||
 | 
			
		||||
	priv = dlg->priv;
 | 
			
		||||
	
 | 
			
		||||
	if (priv->selected_documents != NULL)
 | 
			
		||||
		g_list_free (priv->selected_documents);
 | 
			
		||||
 | 
			
		||||
	if (response_id == GTK_RESPONSE_YES)
 | 
			
		||||
	{
 | 
			
		||||
		if (GET_MODE (priv) == SINGLE_DOC_MODE)
 | 
			
		||||
		{
 | 
			
		||||
			priv->selected_documents = 
 | 
			
		||||
				g_list_copy (priv->unsaved_documents);
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			g_return_if_fail (priv->list_store);
 | 
			
		||||
 | 
			
		||||
			priv->selected_documents =
 | 
			
		||||
				get_selected_docs (priv->list_store);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
		priv->selected_documents = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_logout_mode (XeditCloseConfirmationDialog *dlg,
 | 
			
		||||
		 gboolean                      logout_mode)
 | 
			
		||||
{
 | 
			
		||||
	dlg->priv->logout_mode = logout_mode;
 | 
			
		||||
	
 | 
			
		||||
	if (logout_mode)
 | 
			
		||||
	{
 | 
			
		||||
		gtk_dialog_add_button (GTK_DIALOG (dlg),
 | 
			
		||||
				       _("Log Out _without Saving"),
 | 
			
		||||
				       GTK_RESPONSE_NO);
 | 
			
		||||
 | 
			
		||||
		xedit_dialog_add_button (GTK_DIALOG (dlg),
 | 
			
		||||
					 _("_Cancel Logout"),
 | 
			
		||||
					 GTK_STOCK_CANCEL,
 | 
			
		||||
					 GTK_RESPONSE_CANCEL);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		gtk_dialog_add_button (GTK_DIALOG (dlg),
 | 
			
		||||
				       _("Close _without Saving"),
 | 
			
		||||
				       GTK_RESPONSE_NO);
 | 
			
		||||
 | 
			
		||||
		gtk_dialog_add_button (GTK_DIALOG (dlg),
 | 
			
		||||
				       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if (dlg->priv->disable_save_to_disk)
 | 
			
		||||
	{
 | 
			
		||||
		gtk_dialog_set_default_response	(GTK_DIALOG (dlg),
 | 
			
		||||
						 GTK_RESPONSE_NO);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		const gchar *stock_id = GTK_STOCK_SAVE;
 | 
			
		||||
		
 | 
			
		||||
		if (GET_MODE (dlg->priv) == SINGLE_DOC_MODE)
 | 
			
		||||
		{
 | 
			
		||||
			XeditDocument *doc;
 | 
			
		||||
			
 | 
			
		||||
			doc = XEDIT_DOCUMENT (dlg->priv->unsaved_documents->data);
 | 
			
		||||
			
 | 
			
		||||
			if (xedit_document_get_readonly (doc) || 
 | 
			
		||||
			    xedit_document_is_untitled (doc))
 | 
			
		||||
				stock_id = GTK_STOCK_SAVE_AS;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		gtk_dialog_add_button (GTK_DIALOG (dlg),
 | 
			
		||||
				       stock_id, 
 | 
			
		||||
				       GTK_RESPONSE_YES);
 | 
			
		||||
 | 
			
		||||
		gtk_dialog_set_default_response	(GTK_DIALOG (dlg), 
 | 
			
		||||
						 GTK_RESPONSE_YES);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
xedit_close_confirmation_dialog_init (XeditCloseConfirmationDialog *dlg)
 | 
			
		||||
{
 | 
			
		||||
	AtkObject *atk_obj;
 | 
			
		||||
 | 
			
		||||
	dlg->priv = XEDIT_CLOSE_CONFIRMATION_DIALOG_GET_PRIVATE (dlg);
 | 
			
		||||
 | 
			
		||||
	dlg->priv->disable_save_to_disk = 
 | 
			
		||||
			xedit_app_get_lockdown (xedit_app_get_default ()) 
 | 
			
		||||
			& XEDIT_LOCKDOWN_SAVE_TO_DISK;
 | 
			
		||||
 | 
			
		||||
	gtk_container_set_border_width (GTK_CONTAINER (dlg), 5);		
 | 
			
		||||
	gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))),
 | 
			
		||||
			     14);
 | 
			
		||||
	gtk_window_set_resizable (GTK_WINDOW (dlg), FALSE);
 | 
			
		||||
	gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dlg), TRUE);
 | 
			
		||||
	
 | 
			
		||||
	gtk_window_set_title (GTK_WINDOW (dlg), "");
 | 
			
		||||
 | 
			
		||||
	gtk_window_set_modal (GTK_WINDOW (dlg), TRUE);
 | 
			
		||||
	gtk_window_set_destroy_with_parent (GTK_WINDOW (dlg), TRUE);
 | 
			
		||||
 | 
			
		||||
	atk_obj = gtk_widget_get_accessible (GTK_WIDGET (dlg));
 | 
			
		||||
	atk_object_set_role (atk_obj, ATK_ROLE_ALERT);
 | 
			
		||||
	atk_object_set_name (atk_obj, _("Question"));
 | 
			
		||||
	
 | 
			
		||||
	g_signal_connect (dlg,
 | 
			
		||||
			  "response",
 | 
			
		||||
			  G_CALLBACK (response_cb),
 | 
			
		||||
			  NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
xedit_close_confirmation_dialog_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
	XeditCloseConfirmationDialogPrivate *priv;
 | 
			
		||||
 | 
			
		||||
	priv = XEDIT_CLOSE_CONFIRMATION_DIALOG (object)->priv;
 | 
			
		||||
 | 
			
		||||
	if (priv->unsaved_documents != NULL)
 | 
			
		||||
		g_list_free (priv->unsaved_documents);
 | 
			
		||||
 | 
			
		||||
	if (priv->selected_documents != NULL)
 | 
			
		||||
		g_list_free (priv->selected_documents);
 | 
			
		||||
 | 
			
		||||
	/* Call the parent's destructor */
 | 
			
		||||
	G_OBJECT_CLASS (xedit_close_confirmation_dialog_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_close_confirmation_dialog_set_property (GObject      *object, 
 | 
			
		||||
					      guint         prop_id, 
 | 
			
		||||
					      const GValue *value, 
 | 
			
		||||
					      GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
	XeditCloseConfirmationDialog *dlg;
 | 
			
		||||
 | 
			
		||||
	dlg = XEDIT_CLOSE_CONFIRMATION_DIALOG (object);
 | 
			
		||||
 | 
			
		||||
	switch (prop_id)
 | 
			
		||||
	{
 | 
			
		||||
		case PROP_UNSAVED_DOCUMENTS:
 | 
			
		||||
			set_unsaved_document (dlg, g_value_get_pointer (value));
 | 
			
		||||
			break;
 | 
			
		||||
			
 | 
			
		||||
		case PROP_LOGOUT_MODE:
 | 
			
		||||
			set_logout_mode (dlg, g_value_get_boolean (value));
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_close_confirmation_dialog_get_property (GObject    *object, 
 | 
			
		||||
					      guint       prop_id, 
 | 
			
		||||
					      GValue     *value, 
 | 
			
		||||
					      GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
	XeditCloseConfirmationDialogPrivate *priv;
 | 
			
		||||
 | 
			
		||||
	priv = XEDIT_CLOSE_CONFIRMATION_DIALOG (object)->priv;
 | 
			
		||||
 | 
			
		||||
	switch( prop_id )
 | 
			
		||||
	{
 | 
			
		||||
		case PROP_UNSAVED_DOCUMENTS:
 | 
			
		||||
			g_value_set_pointer (value, priv->unsaved_documents);
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case PROP_LOGOUT_MODE:
 | 
			
		||||
			g_value_set_boolean (value, priv->logout_mode);
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
xedit_close_confirmation_dialog_class_init (XeditCloseConfirmationDialogClass *klass)
 | 
			
		||||
{
 | 
			
		||||
	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
	gobject_class->set_property = xedit_close_confirmation_dialog_set_property;
 | 
			
		||||
	gobject_class->get_property = xedit_close_confirmation_dialog_get_property;
 | 
			
		||||
	gobject_class->finalize = xedit_close_confirmation_dialog_finalize;
 | 
			
		||||
 | 
			
		||||
	g_type_class_add_private (klass, sizeof (XeditCloseConfirmationDialogPrivate));
 | 
			
		||||
 | 
			
		||||
	g_object_class_install_property (gobject_class,
 | 
			
		||||
					 PROP_UNSAVED_DOCUMENTS,
 | 
			
		||||
					 g_param_spec_pointer ("unsaved_documents",
 | 
			
		||||
						 	       "Unsaved Documents",
 | 
			
		||||
							       "List of Unsaved Documents",
 | 
			
		||||
							       (G_PARAM_READWRITE | 
 | 
			
		||||
							        G_PARAM_CONSTRUCT_ONLY)));
 | 
			
		||||
 | 
			
		||||
	g_object_class_install_property (gobject_class,
 | 
			
		||||
					 PROP_LOGOUT_MODE,
 | 
			
		||||
					 g_param_spec_boolean ("logout_mode",
 | 
			
		||||
						 	       "Logout Mode",
 | 
			
		||||
							       "Whether the dialog is in logout mode",
 | 
			
		||||
							       FALSE,
 | 
			
		||||
							       (G_PARAM_READWRITE | 
 | 
			
		||||
							        G_PARAM_CONSTRUCT_ONLY)));							        
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GList *
 | 
			
		||||
get_selected_docs (GtkTreeModel *store)
 | 
			
		||||
{
 | 
			
		||||
	GList      *list;
 | 
			
		||||
	gboolean     valid;
 | 
			
		||||
	GtkTreeIter  iter;
 | 
			
		||||
 | 
			
		||||
	list = NULL;
 | 
			
		||||
	valid = gtk_tree_model_get_iter_first (store, &iter);
 | 
			
		||||
 | 
			
		||||
	while (valid)
 | 
			
		||||
	{
 | 
			
		||||
		gboolean       to_save;
 | 
			
		||||
		XeditDocument *doc;
 | 
			
		||||
 | 
			
		||||
		gtk_tree_model_get (store, &iter, 
 | 
			
		||||
				    SAVE_COLUMN, &to_save,
 | 
			
		||||
				    DOC_COLUMN, &doc,
 | 
			
		||||
				    -1);
 | 
			
		||||
		if (to_save)
 | 
			
		||||
			list = g_list_prepend (list, doc);
 | 
			
		||||
 | 
			
		||||
		valid = gtk_tree_model_iter_next (store, &iter);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	list = g_list_reverse (list);
 | 
			
		||||
 | 
			
		||||
	return list;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GList *
 | 
			
		||||
xedit_close_confirmation_dialog_get_selected_documents (XeditCloseConfirmationDialog *dlg)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_CLOSE_CONFIRMATION_DIALOG (dlg), NULL);
 | 
			
		||||
 | 
			
		||||
	return g_list_copy (dlg->priv->selected_documents);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GtkWidget *
 | 
			
		||||
xedit_close_confirmation_dialog_new (GtkWindow *parent, 
 | 
			
		||||
				     GList     *unsaved_documents,
 | 
			
		||||
				     gboolean   logout_mode)
 | 
			
		||||
{
 | 
			
		||||
	GtkWidget *dlg;
 | 
			
		||||
	g_return_val_if_fail (unsaved_documents != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	dlg = GTK_WIDGET (g_object_new (XEDIT_TYPE_CLOSE_CONFIRMATION_DIALOG,
 | 
			
		||||
				        "unsaved_documents", unsaved_documents,
 | 
			
		||||
				        "logout_mode", logout_mode,
 | 
			
		||||
				        NULL));
 | 
			
		||||
	g_return_val_if_fail (dlg != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	if (parent != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		gtk_window_group_add_window (xedit_window_get_group (XEDIT_WINDOW (parent)),
 | 
			
		||||
					     GTK_WINDOW (dlg));
 | 
			
		||||
		
 | 
			
		||||
		gtk_window_set_transient_for (GTK_WINDOW (dlg), parent);					     
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return dlg;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GtkWidget *
 | 
			
		||||
xedit_close_confirmation_dialog_new_single (GtkWindow     *parent, 
 | 
			
		||||
					    XeditDocument *doc,
 | 
			
		||||
					    gboolean       logout_mode)
 | 
			
		||||
{
 | 
			
		||||
	GtkWidget *dlg;
 | 
			
		||||
	GList *unsaved_documents;
 | 
			
		||||
	g_return_val_if_fail (doc != NULL, NULL);
 | 
			
		||||
	
 | 
			
		||||
	unsaved_documents = g_list_prepend (NULL, doc);
 | 
			
		||||
 | 
			
		||||
	dlg = xedit_close_confirmation_dialog_new (parent, 
 | 
			
		||||
						   unsaved_documents,
 | 
			
		||||
						   logout_mode);
 | 
			
		||||
	
 | 
			
		||||
	g_list_free (unsaved_documents);
 | 
			
		||||
 | 
			
		||||
	return dlg;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gchar *
 | 
			
		||||
get_text_secondary_label (XeditDocument *doc)
 | 
			
		||||
{
 | 
			
		||||
	glong  seconds;
 | 
			
		||||
	gchar *secondary_msg;
 | 
			
		||||
	
 | 
			
		||||
	seconds = MAX (1, _xedit_document_get_seconds_since_last_save_or_load (doc));
 | 
			
		||||
 | 
			
		||||
	if (seconds < 55)	
 | 
			
		||||
	{
 | 
			
		||||
		secondary_msg = g_strdup_printf (
 | 
			
		||||
					ngettext ("If you don't save, changes from the last %ld second "
 | 
			
		||||
					    	  "will be permanently lost.",
 | 
			
		||||
						  "If you don't save, changes from the last %ld seconds "
 | 
			
		||||
					    	  "will be permanently lost.",
 | 
			
		||||
						  seconds),
 | 
			
		||||
					seconds);
 | 
			
		||||
	}
 | 
			
		||||
	else if (seconds < 75) /* 55 <= seconds < 75 */
 | 
			
		||||
	{
 | 
			
		||||
		secondary_msg = g_strdup (_("If you don't save, changes from the last minute "
 | 
			
		||||
					    "will be permanently lost."));
 | 
			
		||||
	}
 | 
			
		||||
	else if (seconds < 110) /* 75 <= seconds < 110 */
 | 
			
		||||
	{
 | 
			
		||||
		secondary_msg = g_strdup_printf (
 | 
			
		||||
					ngettext ("If you don't save, changes from the last minute and %ld "
 | 
			
		||||
						  "second will be permanently lost.",
 | 
			
		||||
						  "If you don't save, changes from the last minute and %ld "
 | 
			
		||||
						  "seconds will be permanently lost.",
 | 
			
		||||
						  seconds - 60 ),
 | 
			
		||||
					seconds - 60);
 | 
			
		||||
	}
 | 
			
		||||
	else if (seconds < 3600)
 | 
			
		||||
	{
 | 
			
		||||
		secondary_msg = g_strdup_printf (
 | 
			
		||||
					ngettext ("If you don't save, changes from the last %ld minute "
 | 
			
		||||
					    	  "will be permanently lost.",
 | 
			
		||||
						  "If you don't save, changes from the last %ld minutes "
 | 
			
		||||
					    	  "will be permanently lost.",
 | 
			
		||||
						  seconds / 60),
 | 
			
		||||
					seconds / 60);
 | 
			
		||||
	}
 | 
			
		||||
	else if (seconds < 7200)
 | 
			
		||||
	{
 | 
			
		||||
		gint minutes;
 | 
			
		||||
		seconds -= 3600;
 | 
			
		||||
 | 
			
		||||
		minutes = seconds / 60;
 | 
			
		||||
		if (minutes < 5)
 | 
			
		||||
		{
 | 
			
		||||
			secondary_msg = g_strdup (_("If you don't save, changes from the last hour "
 | 
			
		||||
						    "will be permanently lost."));
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			secondary_msg = g_strdup_printf (
 | 
			
		||||
					ngettext ("If you don't save, changes from the last hour and %d "
 | 
			
		||||
						  "minute will be permanently lost.",
 | 
			
		||||
						  "If you don't save, changes from the last hour and %d "
 | 
			
		||||
						  "minutes will be permanently lost.",
 | 
			
		||||
						  minutes),
 | 
			
		||||
					minutes);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		gint hours;
 | 
			
		||||
 | 
			
		||||
		hours = seconds / 3600;
 | 
			
		||||
 | 
			
		||||
		secondary_msg = g_strdup_printf (
 | 
			
		||||
					ngettext ("If you don't save, changes from the last %d hour "
 | 
			
		||||
					    	  "will be permanently lost.",
 | 
			
		||||
						  "If you don't save, changes from the last %d hours "
 | 
			
		||||
					    	  "will be permanently lost.",
 | 
			
		||||
						  hours),
 | 
			
		||||
					hours);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return secondary_msg;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
build_single_doc_dialog (XeditCloseConfirmationDialog *dlg)
 | 
			
		||||
{
 | 
			
		||||
	GtkWidget     *hbox;
 | 
			
		||||
	GtkWidget     *vbox;
 | 
			
		||||
	GtkWidget     *primary_label;
 | 
			
		||||
	GtkWidget     *secondary_label;
 | 
			
		||||
	GtkWidget     *image;
 | 
			
		||||
	XeditDocument *doc;
 | 
			
		||||
	gchar         *doc_name;
 | 
			
		||||
	gchar         *str;
 | 
			
		||||
	gchar         *markup_str;
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (dlg->priv->unsaved_documents->data != NULL);
 | 
			
		||||
	doc = XEDIT_DOCUMENT (dlg->priv->unsaved_documents->data);
 | 
			
		||||
 | 
			
		||||
	/* Image */
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 10, 0)
 | 
			
		||||
	image = gtk_image_new_from_icon_name ("dialog-warning",
 | 
			
		||||
					  GTK_ICON_SIZE_DIALOG);
 | 
			
		||||
#else
 | 
			
		||||
	image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, 
 | 
			
		||||
					  GTK_ICON_SIZE_DIALOG);
 | 
			
		||||
#endif
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
	gtk_widget_set_halign (image, GTK_ALIGN_START);
 | 
			
		||||
	gtk_widget_set_valign (image, GTK_ALIGN_END);
 | 
			
		||||
#else
 | 
			
		||||
	gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* Primary label */
 | 
			
		||||
	primary_label = gtk_label_new (NULL);
 | 
			
		||||
	gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE);
 | 
			
		||||
	gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE);
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 16, 0)
 | 
			
		||||
	gtk_label_set_xalign (GTK_LABEL (primary_label), 0.0);
 | 
			
		||||
#else
 | 
			
		||||
	gtk_misc_set_alignment (GTK_MISC (primary_label), 0.0, 0.5);
 | 
			
		||||
#endif
 | 
			
		||||
	gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE);
 | 
			
		||||
	gtk_widget_set_can_focus (GTK_WIDGET (primary_label), FALSE);
 | 
			
		||||
 | 
			
		||||
	doc_name = xedit_document_get_short_name_for_display (doc);
 | 
			
		||||
 | 
			
		||||
	if (dlg->priv->disable_save_to_disk)
 | 
			
		||||
	{
 | 
			
		||||
		str = g_markup_printf_escaped (_("Changes to document \"%s\" will be permanently lost."),
 | 
			
		||||
					       doc_name);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		str = g_markup_printf_escaped (_("Save changes to document \"%s\" before closing?"),
 | 
			
		||||
					       doc_name);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_free (doc_name);
 | 
			
		||||
 | 
			
		||||
	markup_str = g_strconcat ("<span weight=\"bold\" size=\"larger\">", str, "</span>", NULL);
 | 
			
		||||
	g_free (str);
 | 
			
		||||
 | 
			
		||||
	gtk_label_set_markup (GTK_LABEL (primary_label), markup_str);
 | 
			
		||||
	g_free (markup_str);
 | 
			
		||||
 | 
			
		||||
	/* Secondary label */
 | 
			
		||||
	if (dlg->priv->disable_save_to_disk)
 | 
			
		||||
		str = g_strdup (_("Saving has been disabled by the system administrator."));	
 | 
			
		||||
	else
 | 
			
		||||
		str = get_text_secondary_label (doc);
 | 
			
		||||
	secondary_label = gtk_label_new (str);
 | 
			
		||||
	g_free (str);
 | 
			
		||||
	gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE);
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 16, 0)
 | 
			
		||||
	gtk_label_set_xalign (GTK_LABEL (secondary_label), 0.0);
 | 
			
		||||
#else
 | 
			
		||||
	gtk_misc_set_alignment (GTK_MISC (secondary_label), 0.0, 0.5);
 | 
			
		||||
#endif
 | 
			
		||||
	gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE);
 | 
			
		||||
	gtk_widget_set_can_focus (GTK_WIDGET (secondary_label), FALSE);
 | 
			
		||||
 | 
			
		||||
	hbox = gtk_hbox_new (FALSE, 12);
 | 
			
		||||
	gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
 | 
			
		||||
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
 | 
			
		||||
 | 
			
		||||
	vbox = gtk_vbox_new (FALSE, 12);
 | 
			
		||||
	
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
 | 
			
		||||
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (vbox), primary_label, FALSE, FALSE, 0);
 | 
			
		||||
		      
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (vbox), secondary_label, FALSE, FALSE, 0);
 | 
			
		||||
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))),
 | 
			
		||||
			    hbox, 
 | 
			
		||||
	                    FALSE, 
 | 
			
		||||
			    FALSE, 
 | 
			
		||||
			    0);
 | 
			
		||||
 | 
			
		||||
	gtk_widget_show_all (hbox);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
populate_model (GtkTreeModel *store, GList *docs)
 | 
			
		||||
{
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
 | 
			
		||||
	while (docs != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		XeditDocument *doc;
 | 
			
		||||
		gchar *name;
 | 
			
		||||
 | 
			
		||||
		doc = XEDIT_DOCUMENT (docs->data);
 | 
			
		||||
 | 
			
		||||
		name = xedit_document_get_short_name_for_display (doc);
 | 
			
		||||
 | 
			
		||||
		gtk_list_store_append (GTK_LIST_STORE (store), &iter);
 | 
			
		||||
		gtk_list_store_set (GTK_LIST_STORE (store), &iter,
 | 
			
		||||
				    SAVE_COLUMN, TRUE,
 | 
			
		||||
				    NAME_COLUMN, name,
 | 
			
		||||
				    DOC_COLUMN, doc,
 | 
			
		||||
			            -1);
 | 
			
		||||
 | 
			
		||||
		g_free (name);
 | 
			
		||||
 | 
			
		||||
		docs = g_list_next (docs);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
save_toggled (GtkCellRendererToggle *renderer, gchar *path_str, GtkTreeModel *store)
 | 
			
		||||
{
 | 
			
		||||
	GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
	gboolean active;
 | 
			
		||||
 | 
			
		||||
	gtk_tree_model_get_iter (store, &iter, path);
 | 
			
		||||
	gtk_tree_model_get (store, &iter, SAVE_COLUMN, &active, -1);
 | 
			
		||||
 | 
			
		||||
	active ^= 1;
 | 
			
		||||
 | 
			
		||||
	gtk_list_store_set (GTK_LIST_STORE (store), &iter,
 | 
			
		||||
			    SAVE_COLUMN, active, -1);
 | 
			
		||||
 | 
			
		||||
	gtk_tree_path_free (path);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GtkWidget *
 | 
			
		||||
create_treeview (XeditCloseConfirmationDialogPrivate *priv)
 | 
			
		||||
{
 | 
			
		||||
	GtkListStore *store;
 | 
			
		||||
	GtkWidget *treeview;
 | 
			
		||||
	GtkCellRenderer *renderer;
 | 
			
		||||
	GtkTreeViewColumn *column;
 | 
			
		||||
 | 
			
		||||
	treeview = gtk_tree_view_new ();
 | 
			
		||||
	gtk_widget_set_size_request (treeview, 260, 120);
 | 
			
		||||
	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
 | 
			
		||||
	gtk_tree_view_set_enable_search (GTK_TREE_VIEW (treeview), FALSE);
 | 
			
		||||
 | 
			
		||||
	/* Create and populate the model */
 | 
			
		||||
	store = gtk_list_store_new (N_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_POINTER);
 | 
			
		||||
	populate_model (GTK_TREE_MODEL (store), priv->unsaved_documents);
 | 
			
		||||
 | 
			
		||||
	/* Set model to the treeview */
 | 
			
		||||
	gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (store));
 | 
			
		||||
	g_object_unref (store);
 | 
			
		||||
 | 
			
		||||
	priv->list_store = GTK_TREE_MODEL (store);
 | 
			
		||||
	
 | 
			
		||||
	/* Add columns */
 | 
			
		||||
	if (!priv->disable_save_to_disk)
 | 
			
		||||
	{
 | 
			
		||||
		renderer = gtk_cell_renderer_toggle_new ();
 | 
			
		||||
		g_signal_connect (renderer, "toggled",
 | 
			
		||||
				  G_CALLBACK (save_toggled), store);
 | 
			
		||||
 | 
			
		||||
		column = gtk_tree_view_column_new_with_attributes ("Save?",
 | 
			
		||||
								   renderer,
 | 
			
		||||
								   "active",
 | 
			
		||||
								   SAVE_COLUMN,
 | 
			
		||||
								   NULL);
 | 
			
		||||
		gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	renderer = gtk_cell_renderer_text_new ();
 | 
			
		||||
	column = gtk_tree_view_column_new_with_attributes ("Name",
 | 
			
		||||
							   renderer,
 | 
			
		||||
							   "text",
 | 
			
		||||
							   NAME_COLUMN,
 | 
			
		||||
							   NULL);
 | 
			
		||||
	gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
 | 
			
		||||
 | 
			
		||||
	return treeview;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
build_multiple_docs_dialog (XeditCloseConfirmationDialog *dlg)
 | 
			
		||||
{
 | 
			
		||||
	XeditCloseConfirmationDialogPrivate *priv;
 | 
			
		||||
	GtkWidget *hbox;
 | 
			
		||||
	GtkWidget *image;
 | 
			
		||||
	GtkWidget *vbox;
 | 
			
		||||
	GtkWidget *primary_label;
 | 
			
		||||
	GtkWidget *vbox2;
 | 
			
		||||
	GtkWidget *select_label;
 | 
			
		||||
	GtkWidget *scrolledwindow;
 | 
			
		||||
	GtkWidget *treeview;
 | 
			
		||||
	GtkWidget *secondary_label;
 | 
			
		||||
	gchar     *str;
 | 
			
		||||
	gchar     *markup_str;
 | 
			
		||||
 | 
			
		||||
	priv = dlg->priv;
 | 
			
		||||
 | 
			
		||||
	hbox = gtk_hbox_new (FALSE, 12);
 | 
			
		||||
	gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))),
 | 
			
		||||
			    hbox, TRUE, TRUE, 0);
 | 
			
		||||
 | 
			
		||||
	/* Image */
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 10, 0)
 | 
			
		||||
	image = gtk_image_new_from_icon_name ("dialog-warning",
 | 
			
		||||
					  GTK_ICON_SIZE_DIALOG);
 | 
			
		||||
#else
 | 
			
		||||
	image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, 
 | 
			
		||||
					  GTK_ICON_SIZE_DIALOG);
 | 
			
		||||
#endif
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
	gtk_widget_set_halign (image, GTK_ALIGN_CENTER);
 | 
			
		||||
	gtk_widget_set_valign (image, GTK_ALIGN_START);
 | 
			
		||||
#else
 | 
			
		||||
	gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0);
 | 
			
		||||
#endif
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
 | 
			
		||||
 | 
			
		||||
	vbox = gtk_vbox_new (FALSE, 12);
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
 | 
			
		||||
 | 
			
		||||
	/* Primary label */
 | 
			
		||||
	primary_label = gtk_label_new (NULL);
 | 
			
		||||
	gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE);
 | 
			
		||||
	gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE);
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 16, 0)
 | 
			
		||||
	gtk_label_set_xalign (GTK_LABEL (primary_label), 0.0);
 | 
			
		||||
#else
 | 
			
		||||
	gtk_misc_set_alignment (GTK_MISC (primary_label), 0.0, 0.5);
 | 
			
		||||
#endif
 | 
			
		||||
	gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE);
 | 
			
		||||
 | 
			
		||||
	if (priv->disable_save_to_disk)
 | 
			
		||||
		str = g_strdup_printf (
 | 
			
		||||
				ngettext ("Changes to %d document will be permanently lost.",
 | 
			
		||||
					  "Changes to %d documents will be permanently lost.",
 | 
			
		||||
					  g_list_length (priv->unsaved_documents)),
 | 
			
		||||
				g_list_length (priv->unsaved_documents));
 | 
			
		||||
	else
 | 
			
		||||
		str = g_strdup_printf (
 | 
			
		||||
				ngettext ("There is %d document with unsaved changes. "
 | 
			
		||||
					  "Save changes before closing?",
 | 
			
		||||
					  "There are %d documents with unsaved changes. "
 | 
			
		||||
					  "Save changes before closing?",
 | 
			
		||||
					  g_list_length (priv->unsaved_documents)),
 | 
			
		||||
				g_list_length (priv->unsaved_documents));
 | 
			
		||||
 | 
			
		||||
	markup_str = g_strconcat ("<span weight=\"bold\" size=\"larger\">", str, "</span>", NULL);
 | 
			
		||||
	g_free (str);
 | 
			
		||||
	
 | 
			
		||||
	gtk_label_set_markup (GTK_LABEL (primary_label), markup_str);
 | 
			
		||||
	g_free (markup_str);
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (vbox), primary_label, FALSE, FALSE, 0);
 | 
			
		||||
	
 | 
			
		||||
	vbox2 = gtk_vbox_new (FALSE, 8);
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (vbox), vbox2, FALSE, FALSE, 0);
 | 
			
		||||
 | 
			
		||||
	if (priv->disable_save_to_disk)
 | 
			
		||||
		select_label = gtk_label_new_with_mnemonic (_("Docum_ents with unsaved changes:"));
 | 
			
		||||
	else
 | 
			
		||||
		select_label = gtk_label_new_with_mnemonic (_("S_elect the documents you want to save:"));
 | 
			
		||||
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (vbox2), select_label, FALSE, FALSE, 0);
 | 
			
		||||
	gtk_label_set_line_wrap (GTK_LABEL (select_label), TRUE);
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 16, 0)
 | 
			
		||||
	gtk_label_set_xalign (GTK_LABEL (select_label), 0.0);
 | 
			
		||||
#else
 | 
			
		||||
	gtk_misc_set_alignment (GTK_MISC (select_label), 0.0, 0.5);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (vbox2), scrolledwindow, TRUE, TRUE, 0);
 | 
			
		||||
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow), 
 | 
			
		||||
					GTK_POLICY_AUTOMATIC, 
 | 
			
		||||
					GTK_POLICY_AUTOMATIC);
 | 
			
		||||
	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow), 
 | 
			
		||||
					     GTK_SHADOW_IN);
 | 
			
		||||
 | 
			
		||||
	treeview = create_treeview (priv);
 | 
			
		||||
	gtk_container_add (GTK_CONTAINER (scrolledwindow), treeview);
 | 
			
		||||
 | 
			
		||||
	/* Secondary label */
 | 
			
		||||
	if (priv->disable_save_to_disk)
 | 
			
		||||
		secondary_label = gtk_label_new (_("Saving has been disabled by the system administrator."));
 | 
			
		||||
	else
 | 
			
		||||
		secondary_label = gtk_label_new (_("If you don't save, "
 | 
			
		||||
						   "all your changes will be permanently lost."));
 | 
			
		||||
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (vbox2), secondary_label, FALSE, FALSE, 0);
 | 
			
		||||
	gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE);
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 16, 0)
 | 
			
		||||
	gtk_label_set_xalign (GTK_LABEL (secondary_label), 0.0);
 | 
			
		||||
#else
 | 
			
		||||
	gtk_misc_set_alignment (GTK_MISC (secondary_label), 0.0, 0.5);
 | 
			
		||||
#endif
 | 
			
		||||
	gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE);
 | 
			
		||||
 | 
			
		||||
	gtk_label_set_mnemonic_widget (GTK_LABEL (select_label), treeview);
 | 
			
		||||
 | 
			
		||||
	gtk_widget_show_all (hbox);	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_unsaved_document (XeditCloseConfirmationDialog *dlg,
 | 
			
		||||
		      const GList                  *list)
 | 
			
		||||
{
 | 
			
		||||
	XeditCloseConfirmationDialogPrivate *priv;
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (list != NULL);	
 | 
			
		||||
 | 
			
		||||
	priv = dlg->priv;
 | 
			
		||||
	g_return_if_fail (priv->unsaved_documents == NULL);
 | 
			
		||||
 | 
			
		||||
	priv->unsaved_documents = g_list_copy ((GList *)list);
 | 
			
		||||
 | 
			
		||||
	if (GET_MODE (priv) == SINGLE_DOC_MODE)
 | 
			
		||||
	{
 | 
			
		||||
		build_single_doc_dialog (dlg);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		build_multiple_docs_dialog (dlg);
 | 
			
		||||
	}	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const GList *
 | 
			
		||||
xedit_close_confirmation_dialog_get_unsaved_documents (XeditCloseConfirmationDialog *dlg)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_CLOSE_CONFIRMATION_DIALOG (dlg), NULL);
 | 
			
		||||
 | 
			
		||||
	return dlg->priv->unsaved_documents;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										75
									
								
								xedit/dialogs/xedit-close-confirmation-dialog.h
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										75
									
								
								xedit/dialogs/xedit-close-confirmation-dialog.h
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,75 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-close-confirmation-dialog.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2004-2005 GNOME Foundation
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA. 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2004-2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_CLOSE_CONFIRMATION_DIALOG_H__
 | 
			
		||||
#define __XEDIT_CLOSE_CONFIRMATION_DIALOG_H__
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
#include <xedit/xedit-document.h>
 | 
			
		||||
 | 
			
		||||
#define XEDIT_TYPE_CLOSE_CONFIRMATION_DIALOG		(xedit_close_confirmation_dialog_get_type ())
 | 
			
		||||
#define XEDIT_CLOSE_CONFIRMATION_DIALOG(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), XEDIT_TYPE_CLOSE_CONFIRMATION_DIALOG, XeditCloseConfirmationDialog))
 | 
			
		||||
#define XEDIT_CLOSE_CONFIRMATION_DIALOG_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), XEDIT_TYPE_CLOSE_CONFIRMATION_DIALOG, XeditCloseConfirmationDialogClass))
 | 
			
		||||
#define XEDIT_IS_CLOSE_CONFIRMATION_DIALOG(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), XEDIT_TYPE_CLOSE_CONFIRMATION_DIALOG))
 | 
			
		||||
#define XEDIT_IS_CLOSE_CONFIRMATION_DIALOG_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), XEDIT_TYPE_CLOSE_CONFIRMATION_DIALOG))
 | 
			
		||||
#define XEDIT_CLOSE_CONFIRMATION_DIALOG_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj),XEDIT_TYPE_CLOSE_CONFIRMATION_DIALOG, XeditCloseConfirmationDialogClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _XeditCloseConfirmationDialog 		XeditCloseConfirmationDialog;
 | 
			
		||||
typedef struct _XeditCloseConfirmationDialogClass 	XeditCloseConfirmationDialogClass;
 | 
			
		||||
typedef struct _XeditCloseConfirmationDialogPrivate 	XeditCloseConfirmationDialogPrivate;
 | 
			
		||||
 | 
			
		||||
struct _XeditCloseConfirmationDialog 
 | 
			
		||||
{
 | 
			
		||||
	GtkDialog parent;
 | 
			
		||||
 | 
			
		||||
	/*< private > */
 | 
			
		||||
	XeditCloseConfirmationDialogPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _XeditCloseConfirmationDialogClass 
 | 
			
		||||
{
 | 
			
		||||
	GtkDialogClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType 		 xedit_close_confirmation_dialog_get_type		(void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
GtkWidget	*xedit_close_confirmation_dialog_new			(GtkWindow     *parent,
 | 
			
		||||
									 GList         *unsaved_documents,
 | 
			
		||||
									 gboolean       logout_mode);
 | 
			
		||||
GtkWidget 	*xedit_close_confirmation_dialog_new_single 		(GtkWindow     *parent, 
 | 
			
		||||
									 XeditDocument *doc,
 | 
			
		||||
 									 gboolean       logout_mode);
 | 
			
		||||
 | 
			
		||||
const GList	*xedit_close_confirmation_dialog_get_unsaved_documents  (XeditCloseConfirmationDialog *dlg);
 | 
			
		||||
 | 
			
		||||
GList		*xedit_close_confirmation_dialog_get_selected_documents	(XeditCloseConfirmationDialog *dlg);
 | 
			
		||||
 | 
			
		||||
#endif /* __XEDIT_CLOSE_CONFIRMATION_DIALOG_H__ */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										498
									
								
								xedit/dialogs/xedit-encodings-dialog.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										498
									
								
								xedit/dialogs/xedit-encodings-dialog.c
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,498 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-encodings-dialog.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2002-2005 Paolo Maggi 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA. 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2002-2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
#include "xedit-encodings-dialog.h"
 | 
			
		||||
#include "xedit-encodings.h"
 | 
			
		||||
#include "xedit-prefs-manager.h"
 | 
			
		||||
#include "xedit-utils.h"
 | 
			
		||||
#include "xedit-debug.h"
 | 
			
		||||
#include "xedit-help.h"
 | 
			
		||||
#include "xedit-dirs.h"
 | 
			
		||||
 | 
			
		||||
#define XEDIT_ENCODINGS_DIALOG_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \
 | 
			
		||||
						   XEDIT_TYPE_ENCODINGS_DIALOG,           \
 | 
			
		||||
						   XeditEncodingsDialogPrivate))
 | 
			
		||||
 | 
			
		||||
struct _XeditEncodingsDialogPrivate
 | 
			
		||||
{
 | 
			
		||||
	GtkListStore	*available_liststore;
 | 
			
		||||
	GtkListStore	*displayed_liststore;
 | 
			
		||||
	GtkWidget	*available_treeview;
 | 
			
		||||
	GtkWidget	*displayed_treeview;
 | 
			
		||||
	GtkWidget	*add_button;
 | 
			
		||||
	GtkWidget	*remove_button;
 | 
			
		||||
 | 
			
		||||
	GSList		*show_in_menu_list;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE(XeditEncodingsDialog, xedit_encodings_dialog, GTK_TYPE_DIALOG)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_encodings_dialog_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
	XeditEncodingsDialogPrivate *priv = XEDIT_ENCODINGS_DIALOG (object)->priv;
 | 
			
		||||
 | 
			
		||||
	g_slist_free (priv->show_in_menu_list);
 | 
			
		||||
 | 
			
		||||
	G_OBJECT_CLASS (xedit_encodings_dialog_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_encodings_dialog_class_init (XeditEncodingsDialogClass *klass)
 | 
			
		||||
{
 | 
			
		||||
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
	object_class->finalize = xedit_encodings_dialog_finalize;
 | 
			
		||||
 | 
			
		||||
	g_type_class_add_private (object_class, sizeof (XeditEncodingsDialogPrivate));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
	COLUMN_NAME,
 | 
			
		||||
	COLUMN_CHARSET,
 | 
			
		||||
	N_COLUMNS
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
count_selected_items_func (GtkTreeModel *model,
 | 
			
		||||
			   GtkTreePath  *path,
 | 
			
		||||
			   GtkTreeIter  *iter, 
 | 
			
		||||
			   gpointer      data)
 | 
			
		||||
{
 | 
			
		||||
	int *count = data;
 | 
			
		||||
 | 
			
		||||
	*count += 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
available_selection_changed_callback (GtkTreeSelection     *selection,
 | 
			
		||||
				      XeditEncodingsDialog *dialogs)
 | 
			
		||||
{
 | 
			
		||||
	int count;
 | 
			
		||||
 | 
			
		||||
	count = 0;
 | 
			
		||||
	gtk_tree_selection_selected_foreach (selection,
 | 
			
		||||
					     count_selected_items_func,
 | 
			
		||||
					     &count);
 | 
			
		||||
 | 
			
		||||
	gtk_widget_set_sensitive (dialogs->priv->add_button, count > 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
displayed_selection_changed_callback (GtkTreeSelection     *selection,
 | 
			
		||||
				      XeditEncodingsDialog *dialogs)
 | 
			
		||||
{
 | 
			
		||||
	int count;
 | 
			
		||||
 | 
			
		||||
	count = 0;
 | 
			
		||||
	gtk_tree_selection_selected_foreach (selection,
 | 
			
		||||
					     count_selected_items_func,
 | 
			
		||||
					     &count);
 | 
			
		||||
 | 
			
		||||
	gtk_widget_set_sensitive (dialogs->priv->remove_button, count > 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
get_selected_encodings_func (GtkTreeModel *model,
 | 
			
		||||
			     GtkTreePath  *path,
 | 
			
		||||
			     GtkTreeIter  *iter, 
 | 
			
		||||
			     gpointer      data)
 | 
			
		||||
{
 | 
			
		||||
	GSList **list = data;
 | 
			
		||||
	gchar *charset;
 | 
			
		||||
	const XeditEncoding *enc;
 | 
			
		||||
 | 
			
		||||
	charset = NULL;
 | 
			
		||||
	gtk_tree_model_get (model, iter, COLUMN_CHARSET, &charset, -1);
 | 
			
		||||
 | 
			
		||||
	enc = xedit_encoding_get_from_charset (charset);
 | 
			
		||||
	g_free (charset);
 | 
			
		||||
 | 
			
		||||
	*list = g_slist_prepend (*list, (gpointer)enc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_shown_in_menu_tree_model (GtkListStore *store,
 | 
			
		||||
				 GSList       *list)
 | 
			
		||||
{
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
 | 
			
		||||
	gtk_list_store_clear (store);
 | 
			
		||||
 | 
			
		||||
	while (list != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		const XeditEncoding *enc;
 | 
			
		||||
 | 
			
		||||
		enc = (const XeditEncoding*) list->data;
 | 
			
		||||
 | 
			
		||||
		gtk_list_store_append (store, &iter);
 | 
			
		||||
		gtk_list_store_set (store, &iter,
 | 
			
		||||
				    COLUMN_CHARSET,
 | 
			
		||||
				    xedit_encoding_get_charset (enc),
 | 
			
		||||
				    COLUMN_NAME,
 | 
			
		||||
				    xedit_encoding_get_name (enc), -1);
 | 
			
		||||
 | 
			
		||||
		list = g_slist_next (list);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
add_button_clicked_callback (GtkWidget            *button,
 | 
			
		||||
			     XeditEncodingsDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
	GtkTreeSelection *selection;
 | 
			
		||||
	GSList *encodings;
 | 
			
		||||
	GSList *tmp;
 | 
			
		||||
 | 
			
		||||
	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->priv->available_treeview));
 | 
			
		||||
 | 
			
		||||
	encodings = NULL;
 | 
			
		||||
	gtk_tree_selection_selected_foreach (selection,
 | 
			
		||||
					     get_selected_encodings_func,
 | 
			
		||||
					     &encodings);
 | 
			
		||||
 | 
			
		||||
	tmp = encodings;
 | 
			
		||||
	while (tmp != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		if (g_slist_find (dialog->priv->show_in_menu_list, tmp->data) == NULL)
 | 
			
		||||
			dialog->priv->show_in_menu_list = g_slist_prepend (dialog->priv->show_in_menu_list,
 | 
			
		||||
									   tmp->data);
 | 
			
		||||
 | 
			
		||||
		tmp = g_slist_next (tmp);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_slist_free (encodings);
 | 
			
		||||
 | 
			
		||||
	update_shown_in_menu_tree_model (GTK_LIST_STORE (dialog->priv->displayed_liststore),
 | 
			
		||||
					 dialog->priv->show_in_menu_list);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
remove_button_clicked_callback (GtkWidget            *button,
 | 
			
		||||
				XeditEncodingsDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
	GtkTreeSelection *selection;
 | 
			
		||||
	GSList *encodings;
 | 
			
		||||
	GSList *tmp;
 | 
			
		||||
 | 
			
		||||
	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->priv->displayed_treeview));
 | 
			
		||||
 | 
			
		||||
	encodings = NULL;
 | 
			
		||||
	gtk_tree_selection_selected_foreach (selection,
 | 
			
		||||
					     get_selected_encodings_func,
 | 
			
		||||
					     &encodings);
 | 
			
		||||
 | 
			
		||||
	tmp = encodings;
 | 
			
		||||
	while (tmp != NULL) 
 | 
			
		||||
	{
 | 
			
		||||
		dialog->priv->show_in_menu_list = g_slist_remove (dialog->priv->show_in_menu_list,
 | 
			
		||||
								  tmp->data);
 | 
			
		||||
 | 
			
		||||
		tmp = g_slist_next (tmp);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_slist_free (encodings);
 | 
			
		||||
 | 
			
		||||
	update_shown_in_menu_tree_model (GTK_LIST_STORE (dialog->priv->displayed_liststore),
 | 
			
		||||
					 dialog->priv->show_in_menu_list);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
init_shown_in_menu_tree_model (XeditEncodingsDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
	GSList *list, *tmp;
 | 
			
		||||
 | 
			
		||||
	/* add data to the list store */
 | 
			
		||||
	list = xedit_prefs_manager_get_shown_in_menu_encodings ();
 | 
			
		||||
 | 
			
		||||
	tmp = list;
 | 
			
		||||
 | 
			
		||||
	while (tmp != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		const XeditEncoding *enc;
 | 
			
		||||
 | 
			
		||||
		enc = (const XeditEncoding *) tmp->data;
 | 
			
		||||
 | 
			
		||||
		dialog->priv->show_in_menu_list = g_slist_prepend (dialog->priv->show_in_menu_list,
 | 
			
		||||
								   tmp->data);
 | 
			
		||||
 | 
			
		||||
		gtk_list_store_append (dialog->priv->displayed_liststore,
 | 
			
		||||
				       &iter);
 | 
			
		||||
		gtk_list_store_set (dialog->priv->displayed_liststore,
 | 
			
		||||
				    &iter,
 | 
			
		||||
				    COLUMN_CHARSET,
 | 
			
		||||
				    xedit_encoding_get_charset (enc),
 | 
			
		||||
				    COLUMN_NAME,
 | 
			
		||||
				    xedit_encoding_get_name (enc), -1);
 | 
			
		||||
 | 
			
		||||
		tmp = g_slist_next (tmp);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_slist_free (list);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
response_handler (GtkDialog            *dialog,
 | 
			
		||||
		  gint                  response_id,
 | 
			
		||||
                  XeditEncodingsDialog *dlg)
 | 
			
		||||
{
 | 
			
		||||
	if (response_id == GTK_RESPONSE_HELP)
 | 
			
		||||
	{
 | 
			
		||||
		xedit_help_display (GTK_WINDOW (dialog), "xedit", NULL);
 | 
			
		||||
		g_signal_stop_emission_by_name (dialog, "response");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (response_id == GTK_RESPONSE_OK)
 | 
			
		||||
	{
 | 
			
		||||
		g_return_if_fail (xedit_prefs_manager_shown_in_menu_encodings_can_set ());
 | 
			
		||||
		xedit_prefs_manager_set_shown_in_menu_encodings (dlg->priv->show_in_menu_list);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_encodings_dialog_init (XeditEncodingsDialog *dlg)
 | 
			
		||||
{
 | 
			
		||||
	GtkWidget *content;
 | 
			
		||||
	GtkCellRenderer *cell_renderer;
 | 
			
		||||
	GtkTreeModel *sort_model;
 | 
			
		||||
	GtkTreeViewColumn *column;
 | 
			
		||||
	GtkTreeIter parent_iter;
 | 
			
		||||
	GtkTreeSelection *selection;
 | 
			
		||||
	const XeditEncoding *enc;
 | 
			
		||||
	GtkWidget *error_widget;
 | 
			
		||||
	int i;
 | 
			
		||||
	gboolean ret;
 | 
			
		||||
	gchar *file;
 | 
			
		||||
	gchar *root_objects[] = {
 | 
			
		||||
		"encodings-dialog-contents",
 | 
			
		||||
		NULL
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	dlg->priv = XEDIT_ENCODINGS_DIALOG_GET_PRIVATE (dlg);
 | 
			
		||||
	
 | 
			
		||||
	gtk_dialog_add_buttons (GTK_DIALOG (dlg),
 | 
			
		||||
				GTK_STOCK_CANCEL, 
 | 
			
		||||
				GTK_RESPONSE_CANCEL,
 | 
			
		||||
				GTK_STOCK_OK,
 | 
			
		||||
				GTK_RESPONSE_OK,
 | 
			
		||||
				GTK_STOCK_HELP,
 | 
			
		||||
				GTK_RESPONSE_HELP,
 | 
			
		||||
				NULL);
 | 
			
		||||
 | 
			
		||||
	gtk_window_set_title (GTK_WINDOW (dlg), _("Character Encodings"));
 | 
			
		||||
	gtk_window_set_default_size (GTK_WINDOW (dlg), 650, 400);
 | 
			
		||||
	
 | 
			
		||||
	/* HIG defaults */
 | 
			
		||||
	gtk_container_set_border_width (GTK_CONTAINER (dlg), 5);
 | 
			
		||||
	gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))),
 | 
			
		||||
			     2); /* 2 * 5 + 2 = 12 */
 | 
			
		||||
	gtk_container_set_border_width (GTK_CONTAINER (gtk_dialog_get_action_area (GTK_DIALOG (dlg))),
 | 
			
		||||
					5);
 | 
			
		||||
	gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_action_area (GTK_DIALOG (dlg))), 6);
 | 
			
		||||
 | 
			
		||||
	gtk_dialog_set_default_response (GTK_DIALOG (dlg),
 | 
			
		||||
					 GTK_RESPONSE_OK);
 | 
			
		||||
 | 
			
		||||
	g_signal_connect (dlg,
 | 
			
		||||
			  "response",
 | 
			
		||||
			  G_CALLBACK (response_handler),
 | 
			
		||||
			  dlg);
 | 
			
		||||
 | 
			
		||||
	file = xedit_dirs_get_ui_file ("xedit-encodings-dialog.ui");
 | 
			
		||||
	ret = xedit_utils_get_ui_objects (file,
 | 
			
		||||
					  root_objects,
 | 
			
		||||
					  &error_widget,
 | 
			
		||||
					  "encodings-dialog-contents", &content,
 | 
			
		||||
					  "add-button", &dlg->priv->add_button,
 | 
			
		||||
					  "remove-button", &dlg->priv->remove_button,
 | 
			
		||||
					  "available-treeview", &dlg->priv->available_treeview,
 | 
			
		||||
					  "displayed-treeview", &dlg->priv->displayed_treeview,
 | 
			
		||||
					  NULL);
 | 
			
		||||
	g_free (file);
 | 
			
		||||
 | 
			
		||||
	if (!ret)
 | 
			
		||||
	{
 | 
			
		||||
		gtk_widget_show (error_widget);
 | 
			
		||||
 | 
			
		||||
		gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))),
 | 
			
		||||
		                    error_widget,
 | 
			
		||||
		                    TRUE, TRUE, 0);
 | 
			
		||||
		gtk_container_set_border_width (GTK_CONTAINER (error_widget), 5);			     
 | 
			
		||||
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))),
 | 
			
		||||
			    content, TRUE, TRUE, 0);
 | 
			
		||||
	g_object_unref (content);
 | 
			
		||||
	gtk_container_set_border_width (GTK_CONTAINER (content), 5);			     
 | 
			
		||||
 | 
			
		||||
	g_signal_connect (dlg->priv->add_button,
 | 
			
		||||
			  "clicked",
 | 
			
		||||
			  G_CALLBACK (add_button_clicked_callback),
 | 
			
		||||
			  dlg);
 | 
			
		||||
	g_signal_connect (dlg->priv->remove_button,
 | 
			
		||||
			  "clicked",
 | 
			
		||||
			  G_CALLBACK (remove_button_clicked_callback),
 | 
			
		||||
			  dlg);
 | 
			
		||||
 | 
			
		||||
	/* Tree view of available encodings */
 | 
			
		||||
	dlg->priv->available_liststore = gtk_list_store_new (N_COLUMNS,
 | 
			
		||||
							     G_TYPE_STRING,
 | 
			
		||||
							     G_TYPE_STRING);
 | 
			
		||||
 | 
			
		||||
	cell_renderer = gtk_cell_renderer_text_new ();
 | 
			
		||||
	column = gtk_tree_view_column_new_with_attributes (_("_Description"),
 | 
			
		||||
							   cell_renderer,
 | 
			
		||||
							   "text", COLUMN_NAME,
 | 
			
		||||
							   NULL);
 | 
			
		||||
	gtk_tree_view_append_column (GTK_TREE_VIEW (dlg->priv->available_treeview),
 | 
			
		||||
				     column);
 | 
			
		||||
	gtk_tree_view_column_set_sort_column_id (column, COLUMN_NAME);
 | 
			
		||||
 | 
			
		||||
	cell_renderer = gtk_cell_renderer_text_new ();
 | 
			
		||||
	column = gtk_tree_view_column_new_with_attributes (_("_Encoding"),
 | 
			
		||||
							   cell_renderer,
 | 
			
		||||
							   "text",
 | 
			
		||||
							   COLUMN_CHARSET,
 | 
			
		||||
							   NULL);
 | 
			
		||||
	gtk_tree_view_append_column (GTK_TREE_VIEW (dlg->priv->available_treeview),
 | 
			
		||||
				     column);
 | 
			
		||||
	gtk_tree_view_column_set_sort_column_id (column, COLUMN_CHARSET);
 | 
			
		||||
 | 
			
		||||
	/* Add the data */
 | 
			
		||||
	i = 0;
 | 
			
		||||
	while ((enc = xedit_encoding_get_from_index (i)) != NULL) 
 | 
			
		||||
	{
 | 
			
		||||
		gtk_list_store_append (dlg->priv->available_liststore,
 | 
			
		||||
				       &parent_iter);
 | 
			
		||||
		gtk_list_store_set (dlg->priv->available_liststore,
 | 
			
		||||
				    &parent_iter,
 | 
			
		||||
				    COLUMN_CHARSET,
 | 
			
		||||
				    xedit_encoding_get_charset (enc),
 | 
			
		||||
				    COLUMN_NAME,
 | 
			
		||||
				    xedit_encoding_get_name (enc), -1);
 | 
			
		||||
 | 
			
		||||
		++i;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Sort model */
 | 
			
		||||
	sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (dlg->priv->available_liststore));
 | 
			
		||||
	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
 | 
			
		||||
					      COLUMN_NAME,
 | 
			
		||||
					      GTK_SORT_ASCENDING);
 | 
			
		||||
 | 
			
		||||
	gtk_tree_view_set_model (GTK_TREE_VIEW (dlg->priv->available_treeview),
 | 
			
		||||
				 sort_model);
 | 
			
		||||
	g_object_unref (G_OBJECT (dlg->priv->available_liststore));
 | 
			
		||||
	g_object_unref (G_OBJECT (sort_model));
 | 
			
		||||
 | 
			
		||||
	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->priv->available_treeview));
 | 
			
		||||
	gtk_tree_selection_set_mode (GTK_TREE_SELECTION (selection),
 | 
			
		||||
				     GTK_SELECTION_MULTIPLE);
 | 
			
		||||
 | 
			
		||||
	available_selection_changed_callback (selection, dlg);
 | 
			
		||||
	g_signal_connect (selection,
 | 
			
		||||
			  "changed",
 | 
			
		||||
			  G_CALLBACK (available_selection_changed_callback),
 | 
			
		||||
			  dlg);
 | 
			
		||||
 | 
			
		||||
	/* Tree view of selected encodings */
 | 
			
		||||
	dlg->priv->displayed_liststore = gtk_list_store_new (N_COLUMNS,
 | 
			
		||||
							     G_TYPE_STRING,
 | 
			
		||||
							     G_TYPE_STRING);
 | 
			
		||||
 | 
			
		||||
	cell_renderer = gtk_cell_renderer_text_new ();
 | 
			
		||||
	column = gtk_tree_view_column_new_with_attributes (_("_Description"),
 | 
			
		||||
							   cell_renderer,
 | 
			
		||||
							   "text", COLUMN_NAME,
 | 
			
		||||
							   NULL);
 | 
			
		||||
	gtk_tree_view_append_column (GTK_TREE_VIEW (dlg->priv->displayed_treeview),
 | 
			
		||||
				     column);
 | 
			
		||||
	gtk_tree_view_column_set_sort_column_id (column, COLUMN_NAME);
 | 
			
		||||
 | 
			
		||||
	cell_renderer = gtk_cell_renderer_text_new ();
 | 
			
		||||
	column = gtk_tree_view_column_new_with_attributes (_("_Encoding"),
 | 
			
		||||
							   cell_renderer,
 | 
			
		||||
							   "text",
 | 
			
		||||
							   COLUMN_CHARSET,
 | 
			
		||||
							   NULL);
 | 
			
		||||
	gtk_tree_view_append_column (GTK_TREE_VIEW (dlg->priv->displayed_treeview),
 | 
			
		||||
				     column);
 | 
			
		||||
	gtk_tree_view_column_set_sort_column_id (column, COLUMN_CHARSET);
 | 
			
		||||
 | 
			
		||||
	/* Add the data */
 | 
			
		||||
	init_shown_in_menu_tree_model (dlg);
 | 
			
		||||
 | 
			
		||||
	/* Sort model */
 | 
			
		||||
	sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (dlg->priv->displayed_liststore));
 | 
			
		||||
 | 
			
		||||
	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE
 | 
			
		||||
					      (sort_model), COLUMN_NAME,
 | 
			
		||||
					      GTK_SORT_ASCENDING);
 | 
			
		||||
 | 
			
		||||
	gtk_tree_view_set_model (GTK_TREE_VIEW (dlg->priv->displayed_treeview),
 | 
			
		||||
				 sort_model);
 | 
			
		||||
	g_object_unref (G_OBJECT (sort_model));
 | 
			
		||||
	g_object_unref (G_OBJECT (dlg->priv->displayed_liststore));
 | 
			
		||||
 | 
			
		||||
	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->priv->displayed_treeview));
 | 
			
		||||
	gtk_tree_selection_set_mode (GTK_TREE_SELECTION (selection),
 | 
			
		||||
				     GTK_SELECTION_MULTIPLE);
 | 
			
		||||
 | 
			
		||||
	displayed_selection_changed_callback (selection, dlg);
 | 
			
		||||
	g_signal_connect (selection,
 | 
			
		||||
			  "changed",
 | 
			
		||||
			  G_CALLBACK (displayed_selection_changed_callback),
 | 
			
		||||
			  dlg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GtkWidget *
 | 
			
		||||
xedit_encodings_dialog_new (void)
 | 
			
		||||
{
 | 
			
		||||
	GtkWidget *dlg;
 | 
			
		||||
 | 
			
		||||
	dlg = GTK_WIDGET (g_object_new (XEDIT_TYPE_ENCODINGS_DIALOG, NULL));
 | 
			
		||||
 | 
			
		||||
	return dlg;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										86
									
								
								xedit/dialogs/xedit-encodings-dialog.h
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										86
									
								
								xedit/dialogs/xedit-encodings-dialog.h
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,86 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-encodings-dialog.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2003-2005 Paolo Maggi 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA. 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2003-2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_ENCODINGS_DIALOG_H__
 | 
			
		||||
#define __XEDIT_ENCODINGS_DIALOG_H__
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Type checking and casting macros
 | 
			
		||||
 */
 | 
			
		||||
#define XEDIT_TYPE_ENCODINGS_DIALOG              (xedit_encodings_dialog_get_type())
 | 
			
		||||
#define XEDIT_ENCODINGS_DIALOG(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), XEDIT_TYPE_ENCODINGS_DIALOG, XeditEncodingsDialog))
 | 
			
		||||
#define XEDIT_ENCODINGS_DIALOG_CONST(obj)        (G_TYPE_CHECK_INSTANCE_CAST((obj), XEDIT_TYPE_ENCODINGS_DIALOG, XeditEncodingsDialog const))
 | 
			
		||||
#define XEDIT_ENCODINGS_DIALOG_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), XEDIT_TYPE_ENCODINGS_DIALOG, XeditEncodingsDialogClass))
 | 
			
		||||
#define XEDIT_IS_ENCODINGS_DIALOG(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), XEDIT_TYPE_ENCODINGS_DIALOG))
 | 
			
		||||
#define XEDIT_IS_ENCODINGS_DIALOG_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), XEDIT_TYPE_ENCODINGS_DIALOG))
 | 
			
		||||
#define XEDIT_ENCODINGS_DIALOG_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), XEDIT_TYPE_ENCODINGS_DIALOG, XeditEncodingsDialogClass))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Private structure type */
 | 
			
		||||
typedef struct _XeditEncodingsDialogPrivate XeditEncodingsDialogPrivate;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Main object structure
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _XeditEncodingsDialog XeditEncodingsDialog;
 | 
			
		||||
 | 
			
		||||
struct _XeditEncodingsDialog 
 | 
			
		||||
{
 | 
			
		||||
	GtkDialog dialog;
 | 
			
		||||
 | 
			
		||||
	/*< private > */
 | 
			
		||||
	XeditEncodingsDialogPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Class definition
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _XeditEncodingsDialogClass XeditEncodingsDialogClass;
 | 
			
		||||
 | 
			
		||||
struct _XeditEncodingsDialogClass 
 | 
			
		||||
{
 | 
			
		||||
	GtkDialogClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Public methods
 | 
			
		||||
 */
 | 
			
		||||
GType		 xedit_encodings_dialog_get_type	(void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
GtkWidget	*xedit_encodings_dialog_new		(void);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __XEDIT_ENCODINGS_DIALOG_H__ */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										255
									
								
								xedit/dialogs/xedit-encodings-dialog.ui
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										255
									
								
								xedit/dialogs/xedit-encodings-dialog.ui
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,255 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<!--*- mode: xml -*-->
 | 
			
		||||
<interface>
 | 
			
		||||
  <object class="GtkDialog" id="encodings-dialog">
 | 
			
		||||
    <property name="width_request">650</property>
 | 
			
		||||
    <property name="height_request">400</property>
 | 
			
		||||
    <property name="title" translatable="yes">Character encodings</property>
 | 
			
		||||
    <property name="type">GTK_WINDOW_TOPLEVEL</property>
 | 
			
		||||
    <property name="window_position">GTK_WIN_POS_NONE</property>
 | 
			
		||||
    <property name="modal">True</property>
 | 
			
		||||
    <property name="resizable">True</property>
 | 
			
		||||
    <property name="destroy_with_parent">True</property>
 | 
			
		||||
    <child internal-child="vbox">
 | 
			
		||||
      <object class="GtkVBox" id="dialog-vbox3">
 | 
			
		||||
        <property name="visible">True</property>
 | 
			
		||||
        <property name="homogeneous">False</property>
 | 
			
		||||
        <property name="spacing">0</property>
 | 
			
		||||
        <child internal-child="action_area">
 | 
			
		||||
          <object class="GtkHButtonBox" id="dialog-action_area3">
 | 
			
		||||
            <property name="visible">True</property>
 | 
			
		||||
            <property name="layout_style">GTK_BUTTONBOX_END</property>
 | 
			
		||||
            <child>
 | 
			
		||||
              <object class="GtkButton" id="helpbutton1">
 | 
			
		||||
                <property name="visible">True</property>
 | 
			
		||||
                <property name="can_default">True</property>
 | 
			
		||||
                <property name="can_focus">True</property>
 | 
			
		||||
                <property name="label">gtk-help</property>
 | 
			
		||||
                <property name="use_stock">True</property>
 | 
			
		||||
                <property name="relief">GTK_RELIEF_NORMAL</property>
 | 
			
		||||
              </object>
 | 
			
		||||
            </child>
 | 
			
		||||
            <child>
 | 
			
		||||
              <object class="GtkButton" id="closebutton1">
 | 
			
		||||
                <property name="visible">True</property>
 | 
			
		||||
                <property name="can_default">True</property>
 | 
			
		||||
                <property name="can_focus">True</property>
 | 
			
		||||
                <property name="label">gtk-cancel</property>
 | 
			
		||||
                <property name="use_stock">True</property>
 | 
			
		||||
                <property name="relief">GTK_RELIEF_NORMAL</property>
 | 
			
		||||
              </object>
 | 
			
		||||
            </child>
 | 
			
		||||
            <child>
 | 
			
		||||
              <object class="GtkButton" id="button1">
 | 
			
		||||
                <property name="visible">True</property>
 | 
			
		||||
                <property name="can_default">True</property>
 | 
			
		||||
                <property name="can_focus">True</property>
 | 
			
		||||
                <property name="label">gtk-ok</property>
 | 
			
		||||
                <property name="use_stock">True</property>
 | 
			
		||||
                <property name="relief">GTK_RELIEF_NORMAL</property>
 | 
			
		||||
              </object>
 | 
			
		||||
            </child>
 | 
			
		||||
          </object>
 | 
			
		||||
          <packing>
 | 
			
		||||
            <property name="padding">0</property>
 | 
			
		||||
            <property name="expand">False</property>
 | 
			
		||||
            <property name="fill">True</property>
 | 
			
		||||
            <property name="pack_type">GTK_PACK_END</property>
 | 
			
		||||
          </packing>
 | 
			
		||||
        </child>
 | 
			
		||||
        <child>
 | 
			
		||||
          <object class="GtkHBox" id="encodings-dialog-contents">
 | 
			
		||||
            <property name="border_width">6</property>
 | 
			
		||||
            <property name="visible">True</property>
 | 
			
		||||
            <property name="homogeneous">True</property>
 | 
			
		||||
            <property name="spacing">6</property>
 | 
			
		||||
            <child>
 | 
			
		||||
              <object class="GtkVBox" id="vbox6">
 | 
			
		||||
                <property name="visible">True</property>
 | 
			
		||||
                <property name="homogeneous">False</property>
 | 
			
		||||
                <property name="spacing">6</property>
 | 
			
		||||
                <child>
 | 
			
		||||
                  <object class="GtkLabel" id="available-label">
 | 
			
		||||
                    <property name="visible">True</property>
 | 
			
		||||
                    <property name="label" translatable="yes">A_vailable encodings:</property>
 | 
			
		||||
                    <property name="use_underline">True</property>
 | 
			
		||||
                    <property name="use_markup">False</property>
 | 
			
		||||
                    <property name="justify">GTK_JUSTIFY_LEFT</property>
 | 
			
		||||
                    <property name="wrap">False</property>
 | 
			
		||||
                    <property name="selectable">False</property>
 | 
			
		||||
                    <property name="xalign">0</property>
 | 
			
		||||
                    <property name="yalign">0.5</property>
 | 
			
		||||
                    <property name="xpad">0</property>
 | 
			
		||||
                    <property name="ypad">0</property>
 | 
			
		||||
                    <property name="mnemonic_widget">available-treeview</property>
 | 
			
		||||
                  </object>
 | 
			
		||||
                  <packing>
 | 
			
		||||
                    <property name="padding">0</property>
 | 
			
		||||
                    <property name="expand">False</property>
 | 
			
		||||
                    <property name="fill">False</property>
 | 
			
		||||
                  </packing>
 | 
			
		||||
                </child>
 | 
			
		||||
                <child>
 | 
			
		||||
                  <object class="GtkScrolledWindow" id="scrolledwindow2">
 | 
			
		||||
                    <property name="visible">True</property>
 | 
			
		||||
                    <property name="can_focus">True</property>
 | 
			
		||||
                    <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
 | 
			
		||||
                    <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
 | 
			
		||||
                    <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
 | 
			
		||||
                    <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
 | 
			
		||||
                    <child>
 | 
			
		||||
                      <object class="GtkTreeView" id="available-treeview">
 | 
			
		||||
                        <property name="visible">True</property>
 | 
			
		||||
                        <property name="can_focus">True</property>
 | 
			
		||||
                        <property name="headers_visible">True</property>
 | 
			
		||||
                        <property name="rules_hint">True</property>
 | 
			
		||||
                        <property name="reorderable">False</property>
 | 
			
		||||
                        <property name="enable_search">True</property>
 | 
			
		||||
                      </object>
 | 
			
		||||
                    </child>
 | 
			
		||||
                  </object>
 | 
			
		||||
                  <packing>
 | 
			
		||||
                    <property name="padding">0</property>
 | 
			
		||||
                    <property name="expand">True</property>
 | 
			
		||||
                    <property name="fill">True</property>
 | 
			
		||||
                  </packing>
 | 
			
		||||
                </child>
 | 
			
		||||
                <child>
 | 
			
		||||
                  <object class="GtkHBox" id="hbox6">
 | 
			
		||||
                    <property name="visible">True</property>
 | 
			
		||||
                    <property name="homogeneous">False</property>
 | 
			
		||||
                    <property name="spacing">0</property>
 | 
			
		||||
                    <child>
 | 
			
		||||
                      <object class="GtkButton" id="add-button">
 | 
			
		||||
                        <property name="visible">True</property>
 | 
			
		||||
                        <property name="can_focus">True</property>
 | 
			
		||||
                        <property name="label">gtk-add</property>
 | 
			
		||||
                        <property name="use_stock">True</property>
 | 
			
		||||
                        <property name="relief">GTK_RELIEF_NORMAL</property>
 | 
			
		||||
                      </object>
 | 
			
		||||
                      <packing>
 | 
			
		||||
                        <property name="padding">0</property>
 | 
			
		||||
                        <property name="expand">False</property>
 | 
			
		||||
                        <property name="fill">False</property>
 | 
			
		||||
                      </packing>
 | 
			
		||||
                    </child>
 | 
			
		||||
                    <child>
 | 
			
		||||
                      <placeholder/>
 | 
			
		||||
                    </child>
 | 
			
		||||
                  </object>
 | 
			
		||||
                  <packing>
 | 
			
		||||
                    <property name="padding">0</property>
 | 
			
		||||
                    <property name="expand">False</property>
 | 
			
		||||
                    <property name="fill">False</property>
 | 
			
		||||
                  </packing>
 | 
			
		||||
                </child>
 | 
			
		||||
              </object>
 | 
			
		||||
              <packing>
 | 
			
		||||
                <property name="padding">0</property>
 | 
			
		||||
                <property name="expand">True</property>
 | 
			
		||||
                <property name="fill">True</property>
 | 
			
		||||
              </packing>
 | 
			
		||||
            </child>
 | 
			
		||||
            <child>
 | 
			
		||||
              <object class="GtkVBox" id="vbox7">
 | 
			
		||||
                <property name="visible">True</property>
 | 
			
		||||
                <property name="homogeneous">False</property>
 | 
			
		||||
                <property name="spacing">6</property>
 | 
			
		||||
                <child>
 | 
			
		||||
                  <object class="GtkLabel" id="displayed-label">
 | 
			
		||||
                    <property name="visible">True</property>
 | 
			
		||||
                    <property name="label" translatable="yes">E_ncodings shown in menu:</property>
 | 
			
		||||
                    <property name="use_underline">True</property>
 | 
			
		||||
                    <property name="use_markup">False</property>
 | 
			
		||||
                    <property name="justify">GTK_JUSTIFY_LEFT</property>
 | 
			
		||||
                    <property name="wrap">False</property>
 | 
			
		||||
                    <property name="selectable">False</property>
 | 
			
		||||
                    <property name="xalign">0</property>
 | 
			
		||||
                    <property name="yalign">0.5</property>
 | 
			
		||||
                    <property name="xpad">0</property>
 | 
			
		||||
                    <property name="ypad">0</property>
 | 
			
		||||
                    <property name="mnemonic_widget">displayed-treeview</property>
 | 
			
		||||
                  </object>
 | 
			
		||||
                  <packing>
 | 
			
		||||
                    <property name="padding">0</property>
 | 
			
		||||
                    <property name="expand">False</property>
 | 
			
		||||
                    <property name="fill">False</property>
 | 
			
		||||
                  </packing>
 | 
			
		||||
                </child>
 | 
			
		||||
                <child>
 | 
			
		||||
                  <object class="GtkScrolledWindow" id="scrolledwindow3">
 | 
			
		||||
                    <property name="visible">True</property>
 | 
			
		||||
                    <property name="can_focus">True</property>
 | 
			
		||||
                    <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
 | 
			
		||||
                    <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
 | 
			
		||||
                    <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
 | 
			
		||||
                    <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
 | 
			
		||||
                    <child>
 | 
			
		||||
                      <object class="GtkTreeView" id="displayed-treeview">
 | 
			
		||||
                        <property name="visible">True</property>
 | 
			
		||||
                        <property name="can_focus">True</property>
 | 
			
		||||
                        <property name="headers_visible">True</property>
 | 
			
		||||
                        <property name="rules_hint">True</property>
 | 
			
		||||
                        <property name="reorderable">False</property>
 | 
			
		||||
                        <property name="enable_search">True</property>
 | 
			
		||||
                      </object>
 | 
			
		||||
                    </child>
 | 
			
		||||
                  </object>
 | 
			
		||||
                  <packing>
 | 
			
		||||
                    <property name="padding">0</property>
 | 
			
		||||
                    <property name="expand">True</property>
 | 
			
		||||
                    <property name="fill">True</property>
 | 
			
		||||
                  </packing>
 | 
			
		||||
                </child>
 | 
			
		||||
                <child>
 | 
			
		||||
                  <object class="GtkHBox" id="hbox8">
 | 
			
		||||
                    <property name="visible">True</property>
 | 
			
		||||
                    <property name="homogeneous">False</property>
 | 
			
		||||
                    <property name="spacing">0</property>
 | 
			
		||||
                    <child>
 | 
			
		||||
                      <object class="GtkButton" id="remove-button">
 | 
			
		||||
                        <property name="visible">True</property>
 | 
			
		||||
                        <property name="can_focus">True</property>
 | 
			
		||||
                        <property name="label">gtk-remove</property>
 | 
			
		||||
                        <property name="use_stock">True</property>
 | 
			
		||||
                        <property name="relief">GTK_RELIEF_NORMAL</property>
 | 
			
		||||
                      </object>
 | 
			
		||||
                      <packing>
 | 
			
		||||
                        <property name="padding">0</property>
 | 
			
		||||
                        <property name="expand">False</property>
 | 
			
		||||
                        <property name="fill">False</property>
 | 
			
		||||
                      </packing>
 | 
			
		||||
                    </child>
 | 
			
		||||
                    <child>
 | 
			
		||||
                      <placeholder/>
 | 
			
		||||
                    </child>
 | 
			
		||||
                  </object>
 | 
			
		||||
                  <packing>
 | 
			
		||||
                    <property name="padding">0</property>
 | 
			
		||||
                    <property name="expand">False</property>
 | 
			
		||||
                    <property name="fill">False</property>
 | 
			
		||||
                  </packing>
 | 
			
		||||
                </child>
 | 
			
		||||
              </object>
 | 
			
		||||
              <packing>
 | 
			
		||||
                <property name="padding">0</property>
 | 
			
		||||
                <property name="expand">True</property>
 | 
			
		||||
                <property name="fill">True</property>
 | 
			
		||||
              </packing>
 | 
			
		||||
            </child>
 | 
			
		||||
          </object>
 | 
			
		||||
          <packing>
 | 
			
		||||
            <property name="padding">0</property>
 | 
			
		||||
            <property name="expand">True</property>
 | 
			
		||||
            <property name="fill">True</property>
 | 
			
		||||
          </packing>
 | 
			
		||||
        </child>
 | 
			
		||||
      </object>
 | 
			
		||||
    </child>
 | 
			
		||||
    <action-widgets>
 | 
			
		||||
      <action-widget response="-11">helpbutton1</action-widget>
 | 
			
		||||
      <action-widget response="-6">closebutton1</action-widget>
 | 
			
		||||
      <action-widget response="-5">button1</action-widget>
 | 
			
		||||
    </action-widgets>
 | 
			
		||||
  </object>
 | 
			
		||||
</interface>
 | 
			
		||||
							
								
								
									
										1191
									
								
								xedit/dialogs/xedit-preferences-dialog.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1191
									
								
								xedit/dialogs/xedit-preferences-dialog.c
									
									
									
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										87
									
								
								xedit/dialogs/xedit-preferences-dialog.h
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										87
									
								
								xedit/dialogs/xedit-preferences-dialog.h
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-preferences-dialog.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2001-2005 Paolo Maggi 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA. 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2003. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_PREFERENCES_DIALOG_H__
 | 
			
		||||
#define __XEDIT_PREFERENCES_DIALOG_H__
 | 
			
		||||
 | 
			
		||||
#include "xedit-window.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Type checking and casting macros
 | 
			
		||||
 */
 | 
			
		||||
#define XEDIT_TYPE_PREFERENCES_DIALOG              (xedit_preferences_dialog_get_type())
 | 
			
		||||
#define XEDIT_PREFERENCES_DIALOG(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), XEDIT_TYPE_PREFERENCES_DIALOG, XeditPreferencesDialog))
 | 
			
		||||
#define XEDIT_PREFERENCES_DIALOG_CONST(obj)        (G_TYPE_CHECK_INSTANCE_CAST((obj), XEDIT_TYPE_PREFERENCES_DIALOG, XeditPreferencesDialog const))
 | 
			
		||||
#define XEDIT_PREFERENCES_DIALOG_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), XEDIT_TYPE_PREFERENCES_DIALOG, XeditPreferencesDialogClass))
 | 
			
		||||
#define XEDIT_IS_PREFERENCES_DIALOG(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), XEDIT_TYPE_PREFERENCES_DIALOG))
 | 
			
		||||
#define XEDIT_IS_PREFERENCES_DIALOG_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), XEDIT_TYPE_PREFERENCES_DIALOG))
 | 
			
		||||
#define XEDIT_PREFERENCES_DIALOG_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), XEDIT_TYPE_PREFERENCES_DIALOG, XeditPreferencesDialogClass))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Private structure type */
 | 
			
		||||
typedef struct _XeditPreferencesDialogPrivate XeditPreferencesDialogPrivate;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Main object structure
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _XeditPreferencesDialog XeditPreferencesDialog;
 | 
			
		||||
 | 
			
		||||
struct _XeditPreferencesDialog 
 | 
			
		||||
{
 | 
			
		||||
	GtkDialog dialog;
 | 
			
		||||
	
 | 
			
		||||
	/*< private > */
 | 
			
		||||
	XeditPreferencesDialogPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Class definition
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _XeditPreferencesDialogClass XeditPreferencesDialogClass;
 | 
			
		||||
 | 
			
		||||
struct _XeditPreferencesDialogClass 
 | 
			
		||||
{
 | 
			
		||||
	GtkDialogClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Public methods
 | 
			
		||||
 */
 | 
			
		||||
GType		 xedit_preferences_dialog_get_type	(void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
void		 xedit_show_preferences_dialog		(XeditWindow *parent);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __XEDIT_PREFERENCES_DIALOG_H__ */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1106
									
								
								xedit/dialogs/xedit-preferences-dialog.ui
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1106
									
								
								xedit/dialogs/xedit-preferences-dialog.ui
									
									
									
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										654
									
								
								xedit/dialogs/xedit-search-dialog.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										654
									
								
								xedit/dialogs/xedit-search-dialog.c
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,654 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-search-dialog.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2005 Paolo Maggi
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
#include <gdk/gdkkeysyms.h>
 | 
			
		||||
 | 
			
		||||
#include "xedit-search-dialog.h"
 | 
			
		||||
#include "xedit-history-entry.h"
 | 
			
		||||
#include "xedit-utils.h"
 | 
			
		||||
#include "xedit-marshal.h"
 | 
			
		||||
#include "xedit-dirs.h"
 | 
			
		||||
 | 
			
		||||
#define XEDIT_SEARCH_DIALOG_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \
 | 
			
		||||
						XEDIT_TYPE_SEARCH_DIALOG,              \
 | 
			
		||||
						XeditSearchDialogPrivate))
 | 
			
		||||
 | 
			
		||||
/* Signals */
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
	SHOW_REPLACE,
 | 
			
		||||
	LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint dialog_signals [LAST_SIGNAL] = { 0 };
 | 
			
		||||
 | 
			
		||||
struct _XeditSearchDialogPrivate 
 | 
			
		||||
{
 | 
			
		||||
	gboolean   show_replace;
 | 
			
		||||
 | 
			
		||||
	GtkWidget *table;
 | 
			
		||||
	GtkWidget *search_label;
 | 
			
		||||
	GtkWidget *search_entry;
 | 
			
		||||
	GtkWidget *search_text_entry;
 | 
			
		||||
	GtkWidget *replace_label;
 | 
			
		||||
	GtkWidget *replace_entry;
 | 
			
		||||
	GtkWidget *replace_text_entry;
 | 
			
		||||
	GtkWidget *match_case_checkbutton;
 | 
			
		||||
	GtkWidget *entire_word_checkbutton;
 | 
			
		||||
	GtkWidget *backwards_checkbutton;
 | 
			
		||||
	GtkWidget *wrap_around_checkbutton;
 | 
			
		||||
	GtkWidget *parse_escapes_checkbutton;
 | 
			
		||||
	GtkWidget *find_button;
 | 
			
		||||
	GtkWidget *replace_button;
 | 
			
		||||
	GtkWidget *replace_all_button;
 | 
			
		||||
 | 
			
		||||
	gboolean   ui_error;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE(XeditSearchDialog, xedit_search_dialog, GTK_TYPE_DIALOG)
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
	PROP_0,
 | 
			
		||||
	PROP_SHOW_REPLACE
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_search_dialog_set_property (GObject      *object,
 | 
			
		||||
				  guint         prop_id,
 | 
			
		||||
				  const GValue *value,
 | 
			
		||||
				  GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
	XeditSearchDialog *dlg = XEDIT_SEARCH_DIALOG (object);
 | 
			
		||||
 | 
			
		||||
	switch (prop_id)
 | 
			
		||||
	{
 | 
			
		||||
		case PROP_SHOW_REPLACE:
 | 
			
		||||
			xedit_search_dialog_set_show_replace (dlg,
 | 
			
		||||
							      g_value_get_boolean (value));
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_search_dialog_get_property (GObject    *object,
 | 
			
		||||
				  guint       prop_id,
 | 
			
		||||
				  GValue     *value,
 | 
			
		||||
				  GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
	XeditSearchDialog *dlg = XEDIT_SEARCH_DIALOG (object);
 | 
			
		||||
 | 
			
		||||
	switch (prop_id)
 | 
			
		||||
	{
 | 
			
		||||
		case PROP_SHOW_REPLACE:
 | 
			
		||||
			g_value_set_boolean (value, dlg->priv->show_replace);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_search_dialog_present_with_time (XeditSearchDialog *dialog,
 | 
			
		||||
				       guint32            timestamp)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (XEDIT_SEARCH_DIALOG (dialog));
 | 
			
		||||
 | 
			
		||||
	gtk_window_present_with_time (GTK_WINDOW (dialog), timestamp);
 | 
			
		||||
 | 
			
		||||
	gtk_widget_grab_focus (dialog->priv->search_text_entry);	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
show_replace (XeditSearchDialog *dlg)
 | 
			
		||||
{
 | 
			
		||||
	xedit_search_dialog_set_show_replace (dlg, TRUE);
 | 
			
		||||
	
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
xedit_search_dialog_class_init (XeditSearchDialogClass *klass)
 | 
			
		||||
{
 | 
			
		||||
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
	GtkBindingSet *binding_set;
 | 
			
		||||
	
 | 
			
		||||
	object_class->set_property = xedit_search_dialog_set_property;
 | 
			
		||||
	object_class->get_property = xedit_search_dialog_get_property;
 | 
			
		||||
	
 | 
			
		||||
	klass->show_replace = show_replace;
 | 
			
		||||
	
 | 
			
		||||
	dialog_signals[SHOW_REPLACE] =
 | 
			
		||||
    		g_signal_new ("show_replace",
 | 
			
		||||
		  	      G_TYPE_FROM_CLASS (object_class),
 | 
			
		||||
		  	      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
 | 
			
		||||
		  	      G_STRUCT_OFFSET (XeditSearchDialogClass, show_replace),
 | 
			
		||||
			      NULL, NULL,
 | 
			
		||||
			      xedit_marshal_BOOLEAN__NONE,
 | 
			
		||||
			      G_TYPE_BOOLEAN, 0);
 | 
			
		||||
			      
 | 
			
		||||
	g_object_class_install_property (object_class, PROP_SHOW_REPLACE,
 | 
			
		||||
					 g_param_spec_boolean ("show-replace",
 | 
			
		||||
					 		       "Show Replace",
 | 
			
		||||
					 		       "Whether the dialog is used for Search&Replace",
 | 
			
		||||
					 		       FALSE,
 | 
			
		||||
					 		       G_PARAM_READWRITE));
 | 
			
		||||
 | 
			
		||||
	g_type_class_add_private (object_class, sizeof (XeditSearchDialogPrivate));
 | 
			
		||||
 | 
			
		||||
	binding_set = gtk_binding_set_by_class (klass);
 | 
			
		||||
	
 | 
			
		||||
	/* Note: we cannot use the keyval/modifier associated with the 
 | 
			
		||||
	 * GTK_STOCK_FIND_AND_REPLACE stock item since MATE HIG suggests Ctrl+h
 | 
			
		||||
	 * for Replace while gtk+ uses Ctrl+r */
 | 
			
		||||
	gtk_binding_entry_add_signal (binding_set, GDK_KEY_h, GDK_CONTROL_MASK, "show_replace", 0);
 | 
			
		||||
	gtk_binding_entry_add_signal (binding_set, GDK_KEY_H, GDK_CONTROL_MASK, "show_replace", 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
insert_text_handler (GtkEditable *editable,
 | 
			
		||||
		     const gchar *text,
 | 
			
		||||
		     gint         length,
 | 
			
		||||
		     gint        *position,
 | 
			
		||||
		     gpointer     data)
 | 
			
		||||
{
 | 
			
		||||
	static gboolean insert_text = FALSE;
 | 
			
		||||
	gchar *escaped_text;
 | 
			
		||||
	gint new_len;
 | 
			
		||||
 | 
			
		||||
	/* To avoid recursive behavior */
 | 
			
		||||
	if (insert_text)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	escaped_text = xedit_utils_escape_search_text (text);
 | 
			
		||||
 | 
			
		||||
	new_len = strlen (escaped_text);
 | 
			
		||||
 | 
			
		||||
	if (new_len == length)
 | 
			
		||||
	{
 | 
			
		||||
		g_free (escaped_text);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	insert_text = TRUE;
 | 
			
		||||
 | 
			
		||||
	g_signal_stop_emission_by_name (editable, "insert_text");
 | 
			
		||||
 | 
			
		||||
	gtk_editable_insert_text (editable, escaped_text, new_len, position);
 | 
			
		||||
 | 
			
		||||
	insert_text = FALSE;
 | 
			
		||||
 | 
			
		||||
	g_free (escaped_text);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
search_text_entry_changed (GtkEditable       *editable,
 | 
			
		||||
			   XeditSearchDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
	const gchar *search_string;
 | 
			
		||||
 | 
			
		||||
	search_string = gtk_entry_get_text (GTK_ENTRY (editable));
 | 
			
		||||
	g_return_if_fail (search_string != NULL);
 | 
			
		||||
 | 
			
		||||
	if (*search_string != '\0')
 | 
			
		||||
	{
 | 
			
		||||
		gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), 
 | 
			
		||||
			XEDIT_SEARCH_DIALOG_FIND_RESPONSE, TRUE);
 | 
			
		||||
		gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), 
 | 
			
		||||
			XEDIT_SEARCH_DIALOG_REPLACE_ALL_RESPONSE, TRUE);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), 
 | 
			
		||||
			XEDIT_SEARCH_DIALOG_FIND_RESPONSE, FALSE);
 | 
			
		||||
		gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), 
 | 
			
		||||
			XEDIT_SEARCH_DIALOG_REPLACE_RESPONSE, FALSE);
 | 
			
		||||
		gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), 
 | 
			
		||||
			XEDIT_SEARCH_DIALOG_REPLACE_ALL_RESPONSE, FALSE);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
response_handler (XeditSearchDialog *dialog,
 | 
			
		||||
		  gint               response_id,
 | 
			
		||||
		  gpointer           data)
 | 
			
		||||
{
 | 
			
		||||
	const gchar *str;
 | 
			
		||||
 | 
			
		||||
	switch (response_id)
 | 
			
		||||
	{
 | 
			
		||||
		case XEDIT_SEARCH_DIALOG_REPLACE_RESPONSE:
 | 
			
		||||
		case XEDIT_SEARCH_DIALOG_REPLACE_ALL_RESPONSE:
 | 
			
		||||
			str = gtk_entry_get_text (GTK_ENTRY (dialog->priv->replace_text_entry));
 | 
			
		||||
			if (*str != '\0')
 | 
			
		||||
			{
 | 
			
		||||
				gchar *text;
 | 
			
		||||
 | 
			
		||||
				text = xedit_utils_unescape_search_text (str);
 | 
			
		||||
				xedit_history_entry_prepend_text
 | 
			
		||||
						(XEDIT_HISTORY_ENTRY (dialog->priv->replace_entry),
 | 
			
		||||
						 text);
 | 
			
		||||
 | 
			
		||||
				g_free (text);
 | 
			
		||||
			}
 | 
			
		||||
			/* fall through, so that we also save the find entry */
 | 
			
		||||
		case XEDIT_SEARCH_DIALOG_FIND_RESPONSE:
 | 
			
		||||
			str = gtk_entry_get_text (GTK_ENTRY (dialog->priv->search_text_entry));
 | 
			
		||||
			if (*str != '\0')
 | 
			
		||||
			{
 | 
			
		||||
				gchar *text;
 | 
			
		||||
 | 
			
		||||
				text = xedit_utils_unescape_search_text (str);
 | 
			
		||||
				xedit_history_entry_prepend_text
 | 
			
		||||
						(XEDIT_HISTORY_ENTRY (dialog->priv->search_entry),
 | 
			
		||||
						 text);
 | 
			
		||||
 | 
			
		||||
				g_free (text);
 | 
			
		||||
			}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
show_replace_widgets (XeditSearchDialog *dlg,
 | 
			
		||||
		      gboolean           show_replace)
 | 
			
		||||
{
 | 
			
		||||
	if (show_replace)
 | 
			
		||||
	{
 | 
			
		||||
		gtk_widget_show (dlg->priv->replace_label);
 | 
			
		||||
		gtk_widget_show (dlg->priv->replace_entry);
 | 
			
		||||
		gtk_widget_show (dlg->priv->replace_all_button);
 | 
			
		||||
		gtk_widget_show (dlg->priv->replace_button);
 | 
			
		||||
 | 
			
		||||
		gtk_table_set_row_spacings (GTK_TABLE (dlg->priv->table), 12);
 | 
			
		||||
 | 
			
		||||
		gtk_window_set_title (GTK_WINDOW (dlg), _("Replace"));
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		gtk_widget_hide (dlg->priv->replace_label);
 | 
			
		||||
		gtk_widget_hide (dlg->priv->replace_entry);
 | 
			
		||||
		gtk_widget_hide (dlg->priv->replace_all_button);
 | 
			
		||||
		gtk_widget_hide (dlg->priv->replace_button);
 | 
			
		||||
 | 
			
		||||
		gtk_table_set_row_spacings (GTK_TABLE (dlg->priv->table), 0);
 | 
			
		||||
 | 
			
		||||
		gtk_window_set_title (GTK_WINDOW (dlg), _("Find"));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gtk_widget_show (dlg->priv->find_button);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_search_dialog_init (XeditSearchDialog *dlg)
 | 
			
		||||
{
 | 
			
		||||
	GtkWidget *content;
 | 
			
		||||
	GtkWidget *error_widget;
 | 
			
		||||
	gboolean ret;
 | 
			
		||||
	gchar *file;
 | 
			
		||||
	gchar *root_objects[] = {
 | 
			
		||||
		"search_dialog_content",
 | 
			
		||||
		NULL
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	dlg->priv = XEDIT_SEARCH_DIALOG_GET_PRIVATE (dlg);
 | 
			
		||||
 | 
			
		||||
	gtk_window_set_resizable (GTK_WINDOW (dlg), FALSE);
 | 
			
		||||
	gtk_window_set_destroy_with_parent (GTK_WINDOW (dlg), TRUE);
 | 
			
		||||
 | 
			
		||||
	gtk_dialog_add_buttons (GTK_DIALOG (dlg),
 | 
			
		||||
				GTK_STOCK_CLOSE, GTK_RESPONSE_CANCEL,
 | 
			
		||||
				NULL);
 | 
			
		||||
				
 | 
			
		||||
	/* HIG defaults */
 | 
			
		||||
	gtk_container_set_border_width (GTK_CONTAINER (dlg), 5);
 | 
			
		||||
	gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))),
 | 
			
		||||
			     2); /* 2 * 5 + 2 = 12 */
 | 
			
		||||
	gtk_container_set_border_width (GTK_CONTAINER (gtk_dialog_get_action_area (GTK_DIALOG (dlg))),
 | 
			
		||||
					5);
 | 
			
		||||
	gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_action_area (GTK_DIALOG (dlg))),
 | 
			
		||||
			     6);
 | 
			
		||||
 | 
			
		||||
	file = xedit_dirs_get_ui_file ("xedit-search-dialog.ui");
 | 
			
		||||
	ret = xedit_utils_get_ui_objects (file,
 | 
			
		||||
					  root_objects,
 | 
			
		||||
					  &error_widget,
 | 
			
		||||
					  "search_dialog_content", &content,
 | 
			
		||||
					  "table", &dlg->priv->table,
 | 
			
		||||
					  "search_label", &dlg->priv->search_label,
 | 
			
		||||
					  "replace_with_label", &dlg->priv->replace_label,
 | 
			
		||||
					  "match_case_checkbutton", &dlg->priv->match_case_checkbutton,
 | 
			
		||||
					  "entire_word_checkbutton", &dlg->priv->entire_word_checkbutton,
 | 
			
		||||
					  "search_backwards_checkbutton", &dlg->priv->backwards_checkbutton,
 | 
			
		||||
					  "wrap_around_checkbutton", &dlg->priv->wrap_around_checkbutton,
 | 
			
		||||
					  "parse_escapes_checkbutton", &dlg->priv->parse_escapes_checkbutton,
 | 
			
		||||
					  NULL);
 | 
			
		||||
	g_free (file);
 | 
			
		||||
 | 
			
		||||
	if (!ret)
 | 
			
		||||
	{
 | 
			
		||||
		gtk_widget_show (error_widget);
 | 
			
		||||
 | 
			
		||||
		gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))),
 | 
			
		||||
		                    error_widget,
 | 
			
		||||
		                    TRUE, TRUE, 0);
 | 
			
		||||
		gtk_container_set_border_width (GTK_CONTAINER (error_widget),
 | 
			
		||||
						5);
 | 
			
		||||
 | 
			
		||||
		dlg->priv->ui_error = TRUE;
 | 
			
		||||
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dlg->priv->search_entry = xedit_history_entry_new ("history-search-for",
 | 
			
		||||
							   TRUE);
 | 
			
		||||
	gtk_widget_set_size_request (dlg->priv->search_entry, 300, -1);
 | 
			
		||||
	xedit_history_entry_set_escape_func
 | 
			
		||||
			(XEDIT_HISTORY_ENTRY (dlg->priv->search_entry),
 | 
			
		||||
			 (XeditHistoryEntryEscapeFunc) xedit_utils_escape_search_text);
 | 
			
		||||
 | 
			
		||||
	dlg->priv->search_text_entry = xedit_history_entry_get_entry
 | 
			
		||||
			(XEDIT_HISTORY_ENTRY (dlg->priv->search_entry));
 | 
			
		||||
	gtk_entry_set_activates_default (GTK_ENTRY (dlg->priv->search_text_entry),
 | 
			
		||||
					 TRUE);
 | 
			
		||||
	gtk_widget_show (dlg->priv->search_entry);
 | 
			
		||||
	gtk_table_attach_defaults (GTK_TABLE (dlg->priv->table),
 | 
			
		||||
				   dlg->priv->search_entry,
 | 
			
		||||
				   1, 2, 0, 1);
 | 
			
		||||
 | 
			
		||||
	dlg->priv->replace_entry = xedit_history_entry_new ("history-replace-with",
 | 
			
		||||
							    TRUE);
 | 
			
		||||
	xedit_history_entry_set_escape_func
 | 
			
		||||
			(XEDIT_HISTORY_ENTRY (dlg->priv->replace_entry),
 | 
			
		||||
			 (XeditHistoryEntryEscapeFunc) xedit_utils_escape_search_text);
 | 
			
		||||
 | 
			
		||||
	dlg->priv->replace_text_entry = xedit_history_entry_get_entry
 | 
			
		||||
			(XEDIT_HISTORY_ENTRY (dlg->priv->replace_entry));
 | 
			
		||||
	gtk_entry_set_activates_default (GTK_ENTRY (dlg->priv->replace_text_entry),
 | 
			
		||||
					 TRUE);
 | 
			
		||||
	gtk_widget_show (dlg->priv->replace_entry);
 | 
			
		||||
	gtk_table_attach_defaults (GTK_TABLE (dlg->priv->table),
 | 
			
		||||
				   dlg->priv->replace_entry,
 | 
			
		||||
				   1, 2, 1, 2);
 | 
			
		||||
 | 
			
		||||
	gtk_label_set_mnemonic_widget (GTK_LABEL (dlg->priv->search_label),
 | 
			
		||||
				       dlg->priv->search_entry);
 | 
			
		||||
	gtk_label_set_mnemonic_widget (GTK_LABEL (dlg->priv->replace_label),
 | 
			
		||||
				       dlg->priv->replace_entry);
 | 
			
		||||
 | 
			
		||||
	dlg->priv->find_button = gtk_button_new_from_stock (GTK_STOCK_FIND);
 | 
			
		||||
	dlg->priv->replace_all_button = gtk_button_new_with_mnemonic (_("Replace _All"));
 | 
			
		||||
	dlg->priv->replace_button = xedit_gtk_button_new_with_stock_icon (_("_Replace"),
 | 
			
		||||
									  GTK_STOCK_FIND_AND_REPLACE);
 | 
			
		||||
 | 
			
		||||
	gtk_dialog_add_action_widget (GTK_DIALOG (dlg),
 | 
			
		||||
				      dlg->priv->replace_all_button,
 | 
			
		||||
				      XEDIT_SEARCH_DIALOG_REPLACE_ALL_RESPONSE);
 | 
			
		||||
	gtk_dialog_add_action_widget (GTK_DIALOG (dlg),
 | 
			
		||||
				      dlg->priv->replace_button,
 | 
			
		||||
				      XEDIT_SEARCH_DIALOG_REPLACE_RESPONSE);
 | 
			
		||||
	gtk_dialog_add_action_widget (GTK_DIALOG (dlg),
 | 
			
		||||
				      dlg->priv->find_button,
 | 
			
		||||
				      XEDIT_SEARCH_DIALOG_FIND_RESPONSE);
 | 
			
		||||
	g_object_set (G_OBJECT (dlg->priv->find_button),
 | 
			
		||||
		      "can-default", TRUE,
 | 
			
		||||
		      NULL);
 | 
			
		||||
 | 
			
		||||
	gtk_dialog_set_default_response (GTK_DIALOG (dlg),
 | 
			
		||||
					 XEDIT_SEARCH_DIALOG_FIND_RESPONSE);
 | 
			
		||||
 | 
			
		||||
	/* insensitive by default */
 | 
			
		||||
	gtk_dialog_set_response_sensitive (GTK_DIALOG (dlg),
 | 
			
		||||
					   XEDIT_SEARCH_DIALOG_FIND_RESPONSE,
 | 
			
		||||
					   FALSE);
 | 
			
		||||
	gtk_dialog_set_response_sensitive (GTK_DIALOG (dlg),
 | 
			
		||||
					   XEDIT_SEARCH_DIALOG_REPLACE_RESPONSE,
 | 
			
		||||
					   FALSE);
 | 
			
		||||
	gtk_dialog_set_response_sensitive (GTK_DIALOG (dlg),
 | 
			
		||||
					   XEDIT_SEARCH_DIALOG_REPLACE_ALL_RESPONSE,
 | 
			
		||||
					   FALSE);
 | 
			
		||||
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))),
 | 
			
		||||
			    content, FALSE, FALSE, 0);
 | 
			
		||||
	g_object_unref (content);
 | 
			
		||||
	gtk_container_set_border_width (GTK_CONTAINER (content), 5);
 | 
			
		||||
 | 
			
		||||
	g_signal_connect (dlg->priv->search_text_entry,
 | 
			
		||||
			  "insert_text",
 | 
			
		||||
			  G_CALLBACK (insert_text_handler),
 | 
			
		||||
			  NULL);
 | 
			
		||||
	g_signal_connect (dlg->priv->replace_text_entry,
 | 
			
		||||
			  "insert_text",
 | 
			
		||||
			  G_CALLBACK (insert_text_handler),
 | 
			
		||||
			  NULL);
 | 
			
		||||
	g_signal_connect (dlg->priv->search_text_entry,
 | 
			
		||||
			  "changed",
 | 
			
		||||
			  G_CALLBACK (search_text_entry_changed),
 | 
			
		||||
			  dlg);
 | 
			
		||||
 | 
			
		||||
	g_signal_connect (dlg,
 | 
			
		||||
			  "response",
 | 
			
		||||
			  G_CALLBACK (response_handler),
 | 
			
		||||
			  NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GtkWidget *
 | 
			
		||||
xedit_search_dialog_new (GtkWindow *parent,
 | 
			
		||||
			 gboolean   show_replace)
 | 
			
		||||
{
 | 
			
		||||
	XeditSearchDialog *dlg;
 | 
			
		||||
 | 
			
		||||
	dlg = g_object_new (XEDIT_TYPE_SEARCH_DIALOG,
 | 
			
		||||
			    "show-replace", show_replace,
 | 
			
		||||
			    NULL);
 | 
			
		||||
 | 
			
		||||
	if (parent != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		gtk_window_set_transient_for (GTK_WINDOW (dlg),
 | 
			
		||||
					      parent);
 | 
			
		||||
	
 | 
			
		||||
		gtk_window_set_destroy_with_parent (GTK_WINDOW (dlg),
 | 
			
		||||
						    TRUE);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return GTK_WIDGET (dlg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_search_dialog_get_show_replace (XeditSearchDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_SEARCH_DIALOG (dialog), FALSE);
 | 
			
		||||
 | 
			
		||||
	return dialog->priv->show_replace;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_search_dialog_set_show_replace (XeditSearchDialog *dialog,
 | 
			
		||||
				      gboolean           show_replace)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_SEARCH_DIALOG (dialog));
 | 
			
		||||
 | 
			
		||||
	if (dialog->priv->ui_error)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	dialog->priv->show_replace = show_replace != FALSE;
 | 
			
		||||
	show_replace_widgets (dialog, dialog->priv->show_replace);
 | 
			
		||||
 | 
			
		||||
	g_object_notify (G_OBJECT (dialog), "show-replace");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_search_dialog_set_search_text (XeditSearchDialog *dialog,
 | 
			
		||||
				     const gchar       *text)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_SEARCH_DIALOG (dialog));
 | 
			
		||||
	g_return_if_fail (text != NULL);
 | 
			
		||||
 | 
			
		||||
	gtk_entry_set_text (GTK_ENTRY (dialog->priv->search_text_entry),
 | 
			
		||||
			    text);
 | 
			
		||||
 | 
			
		||||
	gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
 | 
			
		||||
					   XEDIT_SEARCH_DIALOG_FIND_RESPONSE,
 | 
			
		||||
					   (text != '\0'));
 | 
			
		||||
					   
 | 
			
		||||
	gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
 | 
			
		||||
					   XEDIT_SEARCH_DIALOG_REPLACE_ALL_RESPONSE,
 | 
			
		||||
					   (text != '\0'));					   
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The text must be unescaped before searching.
 | 
			
		||||
 */
 | 
			
		||||
const gchar *
 | 
			
		||||
xedit_search_dialog_get_search_text (XeditSearchDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_SEARCH_DIALOG (dialog), NULL);
 | 
			
		||||
 | 
			
		||||
	return gtk_entry_get_text (GTK_ENTRY (dialog->priv->search_text_entry));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_search_dialog_set_replace_text (XeditSearchDialog *dialog,
 | 
			
		||||
				      const gchar       *text)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_SEARCH_DIALOG (dialog));
 | 
			
		||||
	g_return_if_fail (text != NULL);
 | 
			
		||||
 | 
			
		||||
	gtk_entry_set_text (GTK_ENTRY (dialog->priv->replace_text_entry),
 | 
			
		||||
			    text);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const gchar *
 | 
			
		||||
xedit_search_dialog_get_replace_text (XeditSearchDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_SEARCH_DIALOG (dialog), NULL);
 | 
			
		||||
 | 
			
		||||
	return gtk_entry_get_text (GTK_ENTRY (dialog->priv->replace_text_entry));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_search_dialog_set_match_case (XeditSearchDialog *dialog,
 | 
			
		||||
				    gboolean           match_case)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_SEARCH_DIALOG (dialog));
 | 
			
		||||
 | 
			
		||||
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->match_case_checkbutton),
 | 
			
		||||
				      match_case);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_search_dialog_get_match_case (XeditSearchDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_SEARCH_DIALOG (dialog), FALSE);
 | 
			
		||||
 | 
			
		||||
	return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->match_case_checkbutton));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_search_dialog_set_entire_word (XeditSearchDialog *dialog,
 | 
			
		||||
				     gboolean           entire_word)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_SEARCH_DIALOG (dialog));
 | 
			
		||||
 | 
			
		||||
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->entire_word_checkbutton),
 | 
			
		||||
				      entire_word);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_search_dialog_get_entire_word (XeditSearchDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_SEARCH_DIALOG (dialog), FALSE);
 | 
			
		||||
 | 
			
		||||
	return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->entire_word_checkbutton));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_search_dialog_set_backwards (XeditSearchDialog *dialog,
 | 
			
		||||
				  gboolean           backwards)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_SEARCH_DIALOG (dialog));
 | 
			
		||||
 | 
			
		||||
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->backwards_checkbutton),
 | 
			
		||||
				      backwards);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_search_dialog_get_backwards (XeditSearchDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_SEARCH_DIALOG (dialog), FALSE);
 | 
			
		||||
 | 
			
		||||
	return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->backwards_checkbutton));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_search_dialog_set_wrap_around (XeditSearchDialog *dialog,
 | 
			
		||||
				     gboolean           wrap_around)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_SEARCH_DIALOG (dialog));
 | 
			
		||||
 | 
			
		||||
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->wrap_around_checkbutton),
 | 
			
		||||
				      wrap_around);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_search_dialog_get_wrap_around (XeditSearchDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_SEARCH_DIALOG (dialog), FALSE);
 | 
			
		||||
 | 
			
		||||
	return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->wrap_around_checkbutton));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_search_dialog_set_parse_escapes (XeditSearchDialog *dialog,
 | 
			
		||||
				       gboolean           parse_escapes)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_SEARCH_DIALOG (dialog));
 | 
			
		||||
 | 
			
		||||
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->parse_escapes_checkbutton),
 | 
			
		||||
				      parse_escapes);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_search_dialog_get_parse_escapes (XeditSearchDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_SEARCH_DIALOG (dialog), FALSE);
 | 
			
		||||
 | 
			
		||||
	return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->parse_escapes_checkbutton));
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										133
									
								
								xedit/dialogs/xedit-search-dialog.h
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										133
									
								
								xedit/dialogs/xedit-search-dialog.h
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,133 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-search-dialog.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2005 Paolo Maggi
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_SEARCH_DIALOG_H__
 | 
			
		||||
#define __XEDIT_SEARCH_DIALOG_H__
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Type checking and casting macros
 | 
			
		||||
 */
 | 
			
		||||
#define XEDIT_TYPE_SEARCH_DIALOG              (xedit_search_dialog_get_type())
 | 
			
		||||
#define XEDIT_SEARCH_DIALOG(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), XEDIT_TYPE_SEARCH_DIALOG, XeditSearchDialog))
 | 
			
		||||
#define XEDIT_SEARCH_DIALOG_CONST(obj)        (G_TYPE_CHECK_INSTANCE_CAST((obj), XEDIT_TYPE_SEARCH_DIALOG, XeditSearchDialog const))
 | 
			
		||||
#define XEDIT_SEARCH_DIALOG_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), XEDIT_TYPE_SEARCH_DIALOG, XeditSearchDialogClass))
 | 
			
		||||
#define XEDIT_IS_SEARCH_DIALOG(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), XEDIT_TYPE_SEARCH_DIALOG))
 | 
			
		||||
#define XEDIT_IS_SEARCH_DIALOG_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), XEDIT_TYPE_SEARCH_DIALOG))
 | 
			
		||||
#define XEDIT_SEARCH_DIALOG_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), XEDIT_TYPE_SEARCH_DIALOG, XeditSearchDialogClass))
 | 
			
		||||
 | 
			
		||||
/* Private structure type */
 | 
			
		||||
typedef struct _XeditSearchDialogPrivate XeditSearchDialogPrivate;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Main object structure
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _XeditSearchDialog XeditSearchDialog;
 | 
			
		||||
 | 
			
		||||
struct _XeditSearchDialog 
 | 
			
		||||
{
 | 
			
		||||
	GtkDialog dialog;
 | 
			
		||||
 | 
			
		||||
	/*< private > */
 | 
			
		||||
	XeditSearchDialogPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Class definition
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _XeditSearchDialogClass XeditSearchDialogClass;
 | 
			
		||||
 | 
			
		||||
struct _XeditSearchDialogClass 
 | 
			
		||||
{
 | 
			
		||||
	GtkDialogClass parent_class;
 | 
			
		||||
	
 | 
			
		||||
	/* Key bindings */
 | 
			
		||||
	gboolean (* show_replace) (XeditSearchDialog *dlg);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
	XEDIT_SEARCH_DIALOG_FIND_RESPONSE = 100,
 | 
			
		||||
	XEDIT_SEARCH_DIALOG_REPLACE_RESPONSE,
 | 
			
		||||
	XEDIT_SEARCH_DIALOG_REPLACE_ALL_RESPONSE
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Public methods
 | 
			
		||||
 */
 | 
			
		||||
GType 		 xedit_search_dialog_get_type 		(void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
GtkWidget	*xedit_search_dialog_new		(GtkWindow         *parent,
 | 
			
		||||
							 gboolean           show_replace);
 | 
			
		||||
 | 
			
		||||
void		 xedit_search_dialog_present_with_time	(XeditSearchDialog *dialog,
 | 
			
		||||
							 guint32 timestamp);
 | 
			
		||||
 | 
			
		||||
gboolean	 xedit_search_dialog_get_show_replace	(XeditSearchDialog *dialog);
 | 
			
		||||
 | 
			
		||||
void		 xedit_search_dialog_set_show_replace	(XeditSearchDialog *dialog,
 | 
			
		||||
							 gboolean           show_replace);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void		 xedit_search_dialog_set_search_text	(XeditSearchDialog *dialog,
 | 
			
		||||
							 const gchar       *text);
 | 
			
		||||
const gchar	*xedit_search_dialog_get_search_text	(XeditSearchDialog *dialog);
 | 
			
		||||
 | 
			
		||||
void		 xedit_search_dialog_set_replace_text	(XeditSearchDialog *dialog,
 | 
			
		||||
							 const gchar       *text);
 | 
			
		||||
const gchar	*xedit_search_dialog_get_replace_text	(XeditSearchDialog *dialog);
 | 
			
		||||
 | 
			
		||||
void		 xedit_search_dialog_set_match_case	(XeditSearchDialog *dialog,
 | 
			
		||||
							 gboolean           match_case);
 | 
			
		||||
gboolean	 xedit_search_dialog_get_match_case	(XeditSearchDialog *dialog);
 | 
			
		||||
 | 
			
		||||
void		 xedit_search_dialog_set_entire_word	(XeditSearchDialog *dialog,
 | 
			
		||||
							 gboolean           entire_word);
 | 
			
		||||
gboolean	 xedit_search_dialog_get_entire_word	(XeditSearchDialog *dialog);
 | 
			
		||||
 | 
			
		||||
void		 xedit_search_dialog_set_backwards	(XeditSearchDialog *dialog,
 | 
			
		||||
							 gboolean           backwards);
 | 
			
		||||
gboolean	 xedit_search_dialog_get_backwards	(XeditSearchDialog *dialog);
 | 
			
		||||
 | 
			
		||||
void		 xedit_search_dialog_set_wrap_around	(XeditSearchDialog *dialog,
 | 
			
		||||
							 gboolean           wrap_around);
 | 
			
		||||
gboolean	 xedit_search_dialog_get_wrap_around	(XeditSearchDialog *dialog);
 | 
			
		||||
   
 | 
			
		||||
 | 
			
		||||
void		xedit_search_dialog_set_parse_escapes (XeditSearchDialog *dialog,
 | 
			
		||||
                                    		       gboolean           parse_escapes);
 | 
			
		||||
gboolean	xedit_search_dialog_get_parse_escapes (XeditSearchDialog *dialog);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif  /* __XEDIT_SEARCH_DIALOG_H__  */
 | 
			
		||||
							
								
								
									
										272
									
								
								xedit/dialogs/xedit-search-dialog.ui
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										272
									
								
								xedit/dialogs/xedit-search-dialog.ui
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,272 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<!--*- mode: xml -*-->
 | 
			
		||||
<interface>
 | 
			
		||||
  <object class="GtkDialog" id="dialog">
 | 
			
		||||
    <property name="title" translatable="yes">Replace</property>
 | 
			
		||||
    <property name="type">GTK_WINDOW_TOPLEVEL</property>
 | 
			
		||||
    <property name="window_position">GTK_WIN_POS_NONE</property>
 | 
			
		||||
    <property name="modal">False</property>
 | 
			
		||||
    <property name="resizable">False</property>
 | 
			
		||||
    <property name="destroy_with_parent">False</property>
 | 
			
		||||
    <property name="decorated">True</property>
 | 
			
		||||
    <property name="skip_taskbar_hint">False</property>
 | 
			
		||||
    <property name="skip_pager_hint">False</property>
 | 
			
		||||
    <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
 | 
			
		||||
    <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
 | 
			
		||||
    <property name="focus_on_map">True</property>
 | 
			
		||||
    <property name="urgency_hint">False</property>
 | 
			
		||||
    <child internal-child="vbox">
 | 
			
		||||
      <object class="GtkVBox" id="dialog-vbox1">
 | 
			
		||||
        <property name="visible">True</property>
 | 
			
		||||
        <property name="homogeneous">False</property>
 | 
			
		||||
        <property name="spacing">8</property>
 | 
			
		||||
        <child internal-child="action_area">
 | 
			
		||||
          <object class="GtkHButtonBox" id="dialog-action_area1">
 | 
			
		||||
            <property name="visible">True</property>
 | 
			
		||||
            <property name="layout_style">GTK_BUTTONBOX_DEFAULT_STYLE</property>
 | 
			
		||||
            <child>
 | 
			
		||||
              <object class="GtkButton" id="close_button">
 | 
			
		||||
                <property name="visible">True</property>
 | 
			
		||||
                <property name="can_default">True</property>
 | 
			
		||||
                <property name="can_focus">True</property>
 | 
			
		||||
                <property name="label">gtk-close</property>
 | 
			
		||||
                <property name="use_stock">True</property>
 | 
			
		||||
                <property name="relief">GTK_RELIEF_NORMAL</property>
 | 
			
		||||
                <property name="focus_on_click">True</property>
 | 
			
		||||
              </object>
 | 
			
		||||
            </child>
 | 
			
		||||
            <child>
 | 
			
		||||
              <object class="GtkButton" id="replace_all_button">
 | 
			
		||||
                <property name="visible">True</property>
 | 
			
		||||
                <property name="can_default">True</property>
 | 
			
		||||
                <property name="can_focus">True</property>
 | 
			
		||||
                <property name="label" translatable="yes">Replace All</property>
 | 
			
		||||
                <property name="use_underline">True</property>
 | 
			
		||||
                <property name="relief">GTK_RELIEF_NORMAL</property>
 | 
			
		||||
                <property name="focus_on_click">True</property>
 | 
			
		||||
              </object>
 | 
			
		||||
            </child>
 | 
			
		||||
            <child>
 | 
			
		||||
              <object class="GtkButton" id="replace_button">
 | 
			
		||||
                <property name="visible">True</property>
 | 
			
		||||
                <property name="can_default">True</property>
 | 
			
		||||
                <property name="can_focus">True</property>
 | 
			
		||||
                <property name="label" translatable="yes">Replace</property>
 | 
			
		||||
                <property name="use_underline">True</property>
 | 
			
		||||
                <property name="relief">GTK_RELIEF_NORMAL</property>
 | 
			
		||||
                <property name="focus_on_click">True</property>
 | 
			
		||||
              </object>
 | 
			
		||||
            </child>
 | 
			
		||||
            <child>
 | 
			
		||||
              <object class="GtkButton" id="find_next_button">
 | 
			
		||||
                <property name="visible">True</property>
 | 
			
		||||
                <property name="can_default">True</property>
 | 
			
		||||
                <property name="can_focus">True</property>
 | 
			
		||||
                <property name="label">gtk-find</property>
 | 
			
		||||
                <property name="use_stock">True</property>
 | 
			
		||||
                <property name="relief">GTK_RELIEF_NORMAL</property>
 | 
			
		||||
                <property name="focus_on_click">True</property>
 | 
			
		||||
              </object>
 | 
			
		||||
            </child>
 | 
			
		||||
          </object>
 | 
			
		||||
          <packing>
 | 
			
		||||
            <property name="padding">0</property>
 | 
			
		||||
            <property name="expand">False</property>
 | 
			
		||||
            <property name="fill">False</property>
 | 
			
		||||
            <property name="pack_type">GTK_PACK_END</property>
 | 
			
		||||
          </packing>
 | 
			
		||||
        </child>
 | 
			
		||||
        <child>
 | 
			
		||||
          <object class="GtkVBox" id="search_dialog_content">
 | 
			
		||||
            <property name="border_width">5</property>
 | 
			
		||||
            <property name="visible">True</property>
 | 
			
		||||
            <property name="homogeneous">False</property>
 | 
			
		||||
            <property name="spacing">18</property>
 | 
			
		||||
            <child>
 | 
			
		||||
              <object class="GtkTable" id="table">
 | 
			
		||||
                <property name="visible">True</property>
 | 
			
		||||
                <property name="n_rows">2</property>
 | 
			
		||||
                <property name="n_columns">2</property>
 | 
			
		||||
                <property name="homogeneous">False</property>
 | 
			
		||||
                <property name="row_spacing">12</property>
 | 
			
		||||
                <property name="column_spacing">12</property>
 | 
			
		||||
                <child>
 | 
			
		||||
                  <object class="GtkLabel" id="search_label">
 | 
			
		||||
                    <property name="visible">True</property>
 | 
			
		||||
                    <property name="label" translatable="yes">_Search for: </property>
 | 
			
		||||
                    <property name="use_underline">True</property>
 | 
			
		||||
                    <property name="use_markup">False</property>
 | 
			
		||||
                    <property name="justify">GTK_JUSTIFY_LEFT</property>
 | 
			
		||||
                    <property name="wrap">False</property>
 | 
			
		||||
                    <property name="selectable">False</property>
 | 
			
		||||
                    <property name="xalign">0</property>
 | 
			
		||||
                    <property name="yalign">0.5</property>
 | 
			
		||||
                    <property name="xpad">0</property>
 | 
			
		||||
                    <property name="ypad">0</property>
 | 
			
		||||
                    <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
 | 
			
		||||
                    <property name="width_chars">-1</property>
 | 
			
		||||
                    <property name="single_line_mode">False</property>
 | 
			
		||||
                    <property name="angle">0</property>
 | 
			
		||||
                  </object>
 | 
			
		||||
                  <packing>
 | 
			
		||||
                    <property name="left_attach">0</property>
 | 
			
		||||
                    <property name="right_attach">1</property>
 | 
			
		||||
                    <property name="top_attach">0</property>
 | 
			
		||||
                    <property name="bottom_attach">1</property>
 | 
			
		||||
                    <property name="x_options">fill</property>
 | 
			
		||||
                    <property name="y_options"/>
 | 
			
		||||
                  </packing>
 | 
			
		||||
                </child>
 | 
			
		||||
                <child>
 | 
			
		||||
                  <object class="GtkLabel" id="replace_with_label">
 | 
			
		||||
                    <property name="visible">True</property>
 | 
			
		||||
                    <property name="label" translatable="yes">Replace _with: </property>
 | 
			
		||||
                    <property name="use_underline">True</property>
 | 
			
		||||
                    <property name="use_markup">False</property>
 | 
			
		||||
                    <property name="justify">GTK_JUSTIFY_LEFT</property>
 | 
			
		||||
                    <property name="wrap">False</property>
 | 
			
		||||
                    <property name="selectable">False</property>
 | 
			
		||||
                    <property name="xalign">0</property>
 | 
			
		||||
                    <property name="yalign">0.5</property>
 | 
			
		||||
                    <property name="xpad">0</property>
 | 
			
		||||
                    <property name="ypad">0</property>
 | 
			
		||||
                    <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
 | 
			
		||||
                    <property name="width_chars">-1</property>
 | 
			
		||||
                    <property name="single_line_mode">False</property>
 | 
			
		||||
                    <property name="angle">0</property>
 | 
			
		||||
                  </object>
 | 
			
		||||
                  <packing>
 | 
			
		||||
                    <property name="left_attach">0</property>
 | 
			
		||||
                    <property name="right_attach">1</property>
 | 
			
		||||
                    <property name="top_attach">1</property>
 | 
			
		||||
                    <property name="bottom_attach">2</property>
 | 
			
		||||
                    <property name="x_options">fill</property>
 | 
			
		||||
                    <property name="y_options"/>
 | 
			
		||||
                  </packing>
 | 
			
		||||
                </child>
 | 
			
		||||
              </object>
 | 
			
		||||
              <packing>
 | 
			
		||||
                <property name="padding">0</property>
 | 
			
		||||
                <property name="expand">True</property>
 | 
			
		||||
                <property name="fill">True</property>
 | 
			
		||||
              </packing>
 | 
			
		||||
            </child>
 | 
			
		||||
            <child>
 | 
			
		||||
              <object class="GtkVBox" id="vbox3">
 | 
			
		||||
                <property name="visible">True</property>
 | 
			
		||||
                <property name="homogeneous">False</property>
 | 
			
		||||
                <property name="spacing">12</property>
 | 
			
		||||
                <child>
 | 
			
		||||
                  <object class="GtkCheckButton" id="match_case_checkbutton">
 | 
			
		||||
                    <property name="visible">True</property>
 | 
			
		||||
                    <property name="can_focus">True</property>
 | 
			
		||||
                    <property name="label" translatable="yes">_Match case</property>
 | 
			
		||||
                    <property name="use_underline">True</property>
 | 
			
		||||
                    <property name="relief">GTK_RELIEF_NORMAL</property>
 | 
			
		||||
                    <property name="focus_on_click">True</property>
 | 
			
		||||
                    <property name="active">False</property>
 | 
			
		||||
                    <property name="inconsistent">False</property>
 | 
			
		||||
                    <property name="draw_indicator">True</property>
 | 
			
		||||
                  </object>
 | 
			
		||||
                  <packing>
 | 
			
		||||
                    <property name="padding">0</property>
 | 
			
		||||
                    <property name="expand">False</property>
 | 
			
		||||
                    <property name="fill">False</property>
 | 
			
		||||
                  </packing>
 | 
			
		||||
                </child>
 | 
			
		||||
                <child>
 | 
			
		||||
                  <object class="GtkCheckButton" id="entire_word_checkbutton">
 | 
			
		||||
                    <property name="visible">True</property>
 | 
			
		||||
                    <property name="can_focus">True</property>
 | 
			
		||||
                    <property name="label" translatable="yes">Match _entire word only</property>
 | 
			
		||||
                    <property name="use_underline">True</property>
 | 
			
		||||
                    <property name="relief">GTK_RELIEF_NORMAL</property>
 | 
			
		||||
                    <property name="focus_on_click">True</property>
 | 
			
		||||
                    <property name="active">False</property>
 | 
			
		||||
                    <property name="inconsistent">False</property>
 | 
			
		||||
                    <property name="draw_indicator">True</property>
 | 
			
		||||
                  </object>
 | 
			
		||||
                  <packing>
 | 
			
		||||
                    <property name="padding">0</property>
 | 
			
		||||
                    <property name="expand">False</property>
 | 
			
		||||
                    <property name="fill">False</property>
 | 
			
		||||
                  </packing>
 | 
			
		||||
                </child>
 | 
			
		||||
                <child>
 | 
			
		||||
                  <object class="GtkCheckButton" id="search_backwards_checkbutton">
 | 
			
		||||
                    <property name="visible">True</property>
 | 
			
		||||
                    <property name="can_focus">True</property>
 | 
			
		||||
                    <property name="label" translatable="yes">Search _backwards</property>
 | 
			
		||||
                    <property name="use_underline">True</property>
 | 
			
		||||
                    <property name="relief">GTK_RELIEF_NORMAL</property>
 | 
			
		||||
                    <property name="focus_on_click">True</property>
 | 
			
		||||
                    <property name="active">False</property>
 | 
			
		||||
                    <property name="inconsistent">False</property>
 | 
			
		||||
                    <property name="draw_indicator">True</property>
 | 
			
		||||
                  </object>
 | 
			
		||||
                  <packing>
 | 
			
		||||
                    <property name="padding">0</property>
 | 
			
		||||
                    <property name="expand">False</property>
 | 
			
		||||
                    <property name="fill">False</property>
 | 
			
		||||
                  </packing>
 | 
			
		||||
                </child>
 | 
			
		||||
                <child>
 | 
			
		||||
                  <object class="GtkCheckButton" id="wrap_around_checkbutton">
 | 
			
		||||
                    <property name="visible">True</property>
 | 
			
		||||
                    <property name="can_focus">True</property>
 | 
			
		||||
                    <property name="label" translatable="yes">_Wrap around</property>
 | 
			
		||||
                    <property name="use_underline">True</property>
 | 
			
		||||
                    <property name="relief">GTK_RELIEF_NORMAL</property>
 | 
			
		||||
                    <property name="focus_on_click">True</property>
 | 
			
		||||
                    <property name="active">True</property>
 | 
			
		||||
                    <property name="inconsistent">False</property>
 | 
			
		||||
                    <property name="draw_indicator">True</property>
 | 
			
		||||
                  </object>
 | 
			
		||||
                  <packing>
 | 
			
		||||
                    <property name="padding">0</property>
 | 
			
		||||
                    <property name="expand">False</property>
 | 
			
		||||
                    <property name="fill">False</property>
 | 
			
		||||
                  </packing>
 | 
			
		||||
                </child>
 | 
			
		||||
                <child>
 | 
			
		||||
                  <object class="GtkCheckButton" id="parse_escapes_checkbutton">
 | 
			
		||||
                    <property name="visible">True</property>
 | 
			
		||||
                    <property name="can_focus">True</property>
 | 
			
		||||
                    <property name="label" translatable="yes">_Parse escape sequences (e.g. \n)</property>
 | 
			
		||||
                    <property name="use_underline">True</property>
 | 
			
		||||
                    <property name="relief">GTK_RELIEF_NORMAL</property>
 | 
			
		||||
                    <property name="focus_on_click">True</property>
 | 
			
		||||
                    <property name="active">True</property>
 | 
			
		||||
                    <property name="inconsistent">False</property>
 | 
			
		||||
                    <property name="draw_indicator">True</property>
 | 
			
		||||
                  </object>
 | 
			
		||||
                  <packing>
 | 
			
		||||
                    <property name="padding">0</property>
 | 
			
		||||
                    <property name="expand">False</property>
 | 
			
		||||
                    <property name="fill">False</property>
 | 
			
		||||
                  </packing>
 | 
			
		||||
                </child>
 | 
			
		||||
              </object>
 | 
			
		||||
              <packing>
 | 
			
		||||
                <property name="padding">0</property>
 | 
			
		||||
                <property name="expand">True</property>
 | 
			
		||||
                <property name="fill">True</property>
 | 
			
		||||
              </packing>
 | 
			
		||||
            </child>
 | 
			
		||||
          </object>
 | 
			
		||||
          <packing>
 | 
			
		||||
            <property name="padding">0</property>
 | 
			
		||||
            <property name="expand">True</property>
 | 
			
		||||
            <property name="fill">True</property>
 | 
			
		||||
          </packing>
 | 
			
		||||
        </child>
 | 
			
		||||
      </object>
 | 
			
		||||
    </child>
 | 
			
		||||
    <action-widgets>
 | 
			
		||||
      <action-widget response="0">close_button</action-widget>
 | 
			
		||||
      <action-widget response="0">replace_all_button</action-widget>
 | 
			
		||||
      <action-widget response="0">replace_button</action-widget>
 | 
			
		||||
      <action-widget response="0">find_next_button</action-widget>
 | 
			
		||||
    </action-widgets>
 | 
			
		||||
  </object>
 | 
			
		||||
</interface>
 | 
			
		||||
							
								
								
									
										39
									
								
								xedit/smclient/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								xedit/smclient/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
platform_defines = -DEGG_SM_CLIENT_BACKEND_XSMP
 | 
			
		||||
platform_libs = libeggdesktopfile.la
 | 
			
		||||
platform_ltlibraries = libeggdesktopfile.la
 | 
			
		||||
platform_sources = eggsmclient-xsmp.c
 | 
			
		||||
 | 
			
		||||
AM_CPPFLAGS =                               \
 | 
			
		||||
	-DG_LOG_DOMAIN=\""EggSMClient"\" \
 | 
			
		||||
	$(XEDIT_CFLAGS)			 \
 | 
			
		||||
	$(platform_defines)              \
 | 
			
		||||
	$(EGG_SMCLIENT_CFLAGS)
 | 
			
		||||
 | 
			
		||||
noinst_LTLIBRARIES =                     \
 | 
			
		||||
	libeggsmclient.la                \
 | 
			
		||||
	$(platform_ltlibraries)
 | 
			
		||||
 | 
			
		||||
libeggsmclient_la_LIBADD =               \
 | 
			
		||||
	$(EGG_SMCLIENT_LIBS)             \
 | 
			
		||||
	$(platform_libs)
 | 
			
		||||
 | 
			
		||||
libeggsmclient_la_LDFLAGS =              \
 | 
			
		||||
	$(platform_ldflags)
 | 
			
		||||
 | 
			
		||||
libeggsmclient_la_SOURCES =              \
 | 
			
		||||
	eggsmclient.c                    \
 | 
			
		||||
	eggsmclient.h                    \
 | 
			
		||||
	eggsmclient-private.h            \
 | 
			
		||||
	$(platform_sources)
 | 
			
		||||
 | 
			
		||||
libeggdesktopfile_la_LIBADD =            \
 | 
			
		||||
	$(EGG_LIBS)
 | 
			
		||||
 | 
			
		||||
libeggdesktopfile_la_SOURCES =           \
 | 
			
		||||
	eggdesktopfile.c                 \
 | 
			
		||||
	eggdesktopfile.h
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST =                             \
 | 
			
		||||
	eggsmclient-xsmp.c
 | 
			
		||||
 | 
			
		||||
-include $(top_srcdir)/git.mk
 | 
			
		||||
							
								
								
									
										1502
									
								
								xedit/smclient/eggdesktopfile.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1502
									
								
								xedit/smclient/eggdesktopfile.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										160
									
								
								xedit/smclient/eggdesktopfile.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								xedit/smclient/eggdesktopfile.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,160 @@
 | 
			
		||||
/* eggdesktopfile.h - Freedesktop.Org Desktop Files
 | 
			
		||||
 * Copyright (C) 2007 Novell, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser 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
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; see the file COPYING.LIB. If not,
 | 
			
		||||
 * write to the Free Software Foundation, Inc., 151 Franklin Street,
 | 
			
		||||
 * Fifth Floor, Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __EGG_DESKTOP_FILE_H__
 | 
			
		||||
#define __EGG_DESKTOP_FILE_H__
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
typedef struct EggDesktopFile EggDesktopFile;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
	EGG_DESKTOP_FILE_TYPE_UNRECOGNIZED,
 | 
			
		||||
 | 
			
		||||
	EGG_DESKTOP_FILE_TYPE_APPLICATION,
 | 
			
		||||
	EGG_DESKTOP_FILE_TYPE_LINK,
 | 
			
		||||
	EGG_DESKTOP_FILE_TYPE_DIRECTORY
 | 
			
		||||
} EggDesktopFileType;
 | 
			
		||||
 | 
			
		||||
EggDesktopFile     *egg_desktop_file_new                (const char   *desktop_file_path,
 | 
			
		||||
							 GError      **error);
 | 
			
		||||
 | 
			
		||||
EggDesktopFile     *egg_desktop_file_new_from_data_dirs (const char   *desktop_file_path,
 | 
			
		||||
							 GError      **error);
 | 
			
		||||
EggDesktopFile     *egg_desktop_file_new_from_dirs      (const char   *desktop_file_path,
 | 
			
		||||
							 const char  **search_dirs,
 | 
			
		||||
							 GError      **error);
 | 
			
		||||
EggDesktopFile     *egg_desktop_file_new_from_key_file  (GKeyFile     *key_file,
 | 
			
		||||
							 const char   *source,
 | 
			
		||||
							 GError      **error);
 | 
			
		||||
 | 
			
		||||
void                egg_desktop_file_free               (EggDesktopFile  *desktop_file);
 | 
			
		||||
 | 
			
		||||
const char         *egg_desktop_file_get_source         (EggDesktopFile  *desktop_file);
 | 
			
		||||
 | 
			
		||||
EggDesktopFileType  egg_desktop_file_get_desktop_file_type (EggDesktopFile  *desktop_file);
 | 
			
		||||
 | 
			
		||||
const char         *egg_desktop_file_get_name           (EggDesktopFile  *desktop_file);
 | 
			
		||||
const char         *egg_desktop_file_get_icon           (EggDesktopFile  *desktop_file);
 | 
			
		||||
 | 
			
		||||
gboolean            egg_desktop_file_can_launch         (EggDesktopFile  *desktop_file,
 | 
			
		||||
							 const char      *desktop_environment);
 | 
			
		||||
 | 
			
		||||
gboolean            egg_desktop_file_accepts_documents  (EggDesktopFile  *desktop_file);
 | 
			
		||||
gboolean            egg_desktop_file_accepts_multiple   (EggDesktopFile  *desktop_file);
 | 
			
		||||
gboolean            egg_desktop_file_accepts_uris       (EggDesktopFile  *desktop_file);
 | 
			
		||||
 | 
			
		||||
char               *egg_desktop_file_parse_exec         (EggDesktopFile  *desktop_file,
 | 
			
		||||
							 GSList          *documents,
 | 
			
		||||
							 GError         **error);
 | 
			
		||||
 | 
			
		||||
gboolean            egg_desktop_file_launch             (EggDesktopFile  *desktop_file,
 | 
			
		||||
							 GSList          *documents,
 | 
			
		||||
							 GError         **error,
 | 
			
		||||
							 ...) G_GNUC_NULL_TERMINATED;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
	EGG_DESKTOP_FILE_LAUNCH_CLEARENV = 1,
 | 
			
		||||
	EGG_DESKTOP_FILE_LAUNCH_PUTENV,
 | 
			
		||||
	EGG_DESKTOP_FILE_LAUNCH_SCREEN,
 | 
			
		||||
	EGG_DESKTOP_FILE_LAUNCH_WORKSPACE,
 | 
			
		||||
	EGG_DESKTOP_FILE_LAUNCH_DIRECTORY,
 | 
			
		||||
	EGG_DESKTOP_FILE_LAUNCH_TIME,
 | 
			
		||||
	EGG_DESKTOP_FILE_LAUNCH_FLAGS,
 | 
			
		||||
	EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC,
 | 
			
		||||
	EGG_DESKTOP_FILE_LAUNCH_RETURN_PID,
 | 
			
		||||
	EGG_DESKTOP_FILE_LAUNCH_RETURN_STDIN_PIPE,
 | 
			
		||||
	EGG_DESKTOP_FILE_LAUNCH_RETURN_STDOUT_PIPE,
 | 
			
		||||
	EGG_DESKTOP_FILE_LAUNCH_RETURN_STDERR_PIPE,
 | 
			
		||||
	EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID
 | 
			
		||||
} EggDesktopFileLaunchOption;
 | 
			
		||||
 | 
			
		||||
/* Standard Keys */
 | 
			
		||||
#define EGG_DESKTOP_FILE_GROUP			"Desktop Entry"
 | 
			
		||||
 | 
			
		||||
#define EGG_DESKTOP_FILE_KEY_TYPE		"Type"
 | 
			
		||||
#define EGG_DESKTOP_FILE_KEY_VERSION		"Version"
 | 
			
		||||
#define EGG_DESKTOP_FILE_KEY_NAME		"Name"
 | 
			
		||||
#define EGG_DESKTOP_FILE_KEY_GENERIC_NAME	"GenericName"
 | 
			
		||||
#define EGG_DESKTOP_FILE_KEY_NO_DISPLAY		"NoDisplay"
 | 
			
		||||
#define EGG_DESKTOP_FILE_KEY_COMMENT		"Comment"
 | 
			
		||||
#define EGG_DESKTOP_FILE_KEY_ICON		"Icon"
 | 
			
		||||
#define EGG_DESKTOP_FILE_KEY_HIDDEN		"Hidden"
 | 
			
		||||
#define EGG_DESKTOP_FILE_KEY_ONLY_SHOW_IN	"OnlyShowIn"
 | 
			
		||||
#define EGG_DESKTOP_FILE_KEY_NOT_SHOW_IN	"NotShowIn"
 | 
			
		||||
#define EGG_DESKTOP_FILE_KEY_TRY_EXEC		"TryExec"
 | 
			
		||||
#define EGG_DESKTOP_FILE_KEY_EXEC		"Exec"
 | 
			
		||||
#define EGG_DESKTOP_FILE_KEY_PATH		"Path"
 | 
			
		||||
#define EGG_DESKTOP_FILE_KEY_TERMINAL		"Terminal"
 | 
			
		||||
#define EGG_DESKTOP_FILE_KEY_MIME_TYPE		"MimeType"
 | 
			
		||||
#define EGG_DESKTOP_FILE_KEY_CATEGORIES		"Categories"
 | 
			
		||||
#define EGG_DESKTOP_FILE_KEY_STARTUP_NOTIFY	"StartupNotify"
 | 
			
		||||
#define EGG_DESKTOP_FILE_KEY_STARTUP_WM_CLASS	"StartupWMClass"
 | 
			
		||||
#define EGG_DESKTOP_FILE_KEY_URL		"URL"
 | 
			
		||||
 | 
			
		||||
/* Accessors */
 | 
			
		||||
gboolean  egg_desktop_file_has_key                (EggDesktopFile  *desktop_file,
 | 
			
		||||
						   const char      *key,
 | 
			
		||||
						   GError         **error);
 | 
			
		||||
char     *egg_desktop_file_get_string             (EggDesktopFile  *desktop_file,
 | 
			
		||||
						   const char      *key,
 | 
			
		||||
						   GError         **error) G_GNUC_MALLOC;
 | 
			
		||||
char     *egg_desktop_file_get_locale_string      (EggDesktopFile  *desktop_file,
 | 
			
		||||
						   const char      *key,
 | 
			
		||||
						   const char      *locale,
 | 
			
		||||
						   GError         **error) G_GNUC_MALLOC;
 | 
			
		||||
gboolean  egg_desktop_file_get_boolean            (EggDesktopFile  *desktop_file,
 | 
			
		||||
						   const char      *key,
 | 
			
		||||
						   GError         **error);
 | 
			
		||||
double    egg_desktop_file_get_numeric            (EggDesktopFile  *desktop_file,
 | 
			
		||||
						   const char      *key,
 | 
			
		||||
						   GError         **error);
 | 
			
		||||
char    **egg_desktop_file_get_string_list        (EggDesktopFile  *desktop_file,
 | 
			
		||||
						   const char      *key,
 | 
			
		||||
						   gsize           *length,
 | 
			
		||||
						   GError         **error) G_GNUC_MALLOC;
 | 
			
		||||
char    **egg_desktop_file_get_locale_string_list (EggDesktopFile  *desktop_file,
 | 
			
		||||
						   const char      *key,
 | 
			
		||||
						   const char      *locale,
 | 
			
		||||
						   gsize           *length,
 | 
			
		||||
						   GError         **error) G_GNUC_MALLOC;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Errors */
 | 
			
		||||
#define EGG_DESKTOP_FILE_ERROR egg_desktop_file_error_quark()
 | 
			
		||||
 | 
			
		||||
GQuark egg_desktop_file_error_quark (void);
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
	EGG_DESKTOP_FILE_ERROR_INVALID,
 | 
			
		||||
	EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE,
 | 
			
		||||
	EGG_DESKTOP_FILE_ERROR_UNRECOGNIZED_OPTION
 | 
			
		||||
} EggDesktopFileError;
 | 
			
		||||
 | 
			
		||||
/* Global application desktop file */
 | 
			
		||||
void            egg_set_desktop_file                  (const char *desktop_file_path);
 | 
			
		||||
void            egg_set_desktop_file_without_defaults (const char *desktop_file_path);
 | 
			
		||||
EggDesktopFile *egg_get_desktop_file                  (void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __EGG_DESKTOP_FILE_H__ */
 | 
			
		||||
							
								
								
									
										42
									
								
								xedit/smclient/eggsmclient-private.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								xedit/smclient/eggsmclient-private.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
/* eggsmclient-private.h
 | 
			
		||||
 * Copyright (C) 2007 Novell, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser 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
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __EGG_SM_CLIENT_PRIVATE_H__
 | 
			
		||||
#define __EGG_SM_CLIENT_PRIVATE_H__
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
#if !GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
#include <gdkconfig.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include "eggsmclient.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
GKeyFile *egg_sm_client_save_state     (EggSMClient *client);
 | 
			
		||||
void      egg_sm_client_quit_requested (EggSMClient *client);
 | 
			
		||||
void      egg_sm_client_quit_cancelled (EggSMClient *client);
 | 
			
		||||
void      egg_sm_client_quit           (EggSMClient *client);
 | 
			
		||||
 | 
			
		||||
GType        egg_sm_client_xsmp_get_type (void);
 | 
			
		||||
EggSMClient *egg_sm_client_xsmp_new      (void);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* __EGG_SM_CLIENT_PRIVATE_H__ */
 | 
			
		||||
							
								
								
									
										1384
									
								
								xedit/smclient/eggsmclient-xsmp.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1384
									
								
								xedit/smclient/eggsmclient-xsmp.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										573
									
								
								xedit/smclient/eggsmclient.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										573
									
								
								xedit/smclient/eggsmclient.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,573 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2007 Novell, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor,
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
 | 
			
		||||
#include "eggsmclient.h"
 | 
			
		||||
#include "eggsmclient-private.h"
 | 
			
		||||
 | 
			
		||||
static void egg_sm_client_debug_handler (const char *log_domain,
 | 
			
		||||
					 GLogLevelFlags log_level,
 | 
			
		||||
					 const char *message,
 | 
			
		||||
					 gpointer user_data);
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
  SAVE_STATE,
 | 
			
		||||
  QUIT_REQUESTED,
 | 
			
		||||
  QUIT_CANCELLED,
 | 
			
		||||
  QUIT,
 | 
			
		||||
  LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0 };
 | 
			
		||||
 | 
			
		||||
struct _EggSMClientPrivate {
 | 
			
		||||
  GKeyFile *state_file;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define EGG_SM_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), EGG_TYPE_SM_CLIENT, EggSMClientPrivate))
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (EggSMClient, egg_sm_client, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
static EggSMClient *global_client;
 | 
			
		||||
static EggSMClientMode global_client_mode = EGG_SM_CLIENT_MODE_NORMAL;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
egg_sm_client_init (EggSMClient *client)
 | 
			
		||||
{
 | 
			
		||||
  ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
egg_sm_client_class_init (EggSMClientClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  g_type_class_add_private (klass, sizeof (EggSMClientPrivate));
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * EggSMClient::save_state:
 | 
			
		||||
   * @client: the client
 | 
			
		||||
   * @state_file: a #GKeyFile to save state information into
 | 
			
		||||
   *
 | 
			
		||||
   * Emitted when the session manager has requested that the
 | 
			
		||||
   * application save information about its current state. The
 | 
			
		||||
   * application should save its state into @state_file, and then the
 | 
			
		||||
   * session manager may then restart the application in a future
 | 
			
		||||
   * session and tell it to initialize itself from that state.
 | 
			
		||||
   *
 | 
			
		||||
   * You should not save any data into @state_file's "start group"
 | 
			
		||||
   * (ie, the %NULL group). Instead, applications should save their
 | 
			
		||||
   * data into groups with names that start with the application name,
 | 
			
		||||
   * and libraries that connect to this signal should save their data
 | 
			
		||||
   * into groups with names that start with the library name.
 | 
			
		||||
   *
 | 
			
		||||
   * Alternatively, rather than (or in addition to) using @state_file,
 | 
			
		||||
   * the application can save its state by calling
 | 
			
		||||
   * egg_sm_client_set_restart_command() during the processing of this
 | 
			
		||||
   * signal (eg, to include a list of files to open).
 | 
			
		||||
   **/
 | 
			
		||||
  signals[SAVE_STATE] =
 | 
			
		||||
    g_signal_new ("save_state",
 | 
			
		||||
                  G_OBJECT_CLASS_TYPE (object_class),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  G_STRUCT_OFFSET (EggSMClientClass, save_state),
 | 
			
		||||
                  NULL, NULL,
 | 
			
		||||
                  g_cclosure_marshal_VOID__POINTER,
 | 
			
		||||
                  G_TYPE_NONE,
 | 
			
		||||
                  1, G_TYPE_POINTER);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * EggSMClient::quit_requested:
 | 
			
		||||
   * @client: the client
 | 
			
		||||
   *
 | 
			
		||||
   * Emitted when the session manager requests that the application
 | 
			
		||||
   * exit (generally because the user is logging out). The application
 | 
			
		||||
   * should decide whether or not it is willing to quit (perhaps after
 | 
			
		||||
   * asking the user what to do with documents that have unsaved
 | 
			
		||||
   * changes) and then call egg_sm_client_will_quit(), passing %TRUE
 | 
			
		||||
   * or %FALSE to give its answer to the session manager. (It does not
 | 
			
		||||
   * need to give an answer before returning from the signal handler;
 | 
			
		||||
   * it can interact with the user asynchronously and then give its
 | 
			
		||||
   * answer later on.) If the application does not connect to this
 | 
			
		||||
   * signal, then #EggSMClient will automatically return %TRUE on its
 | 
			
		||||
   * behalf.
 | 
			
		||||
   *
 | 
			
		||||
   * The application should not save its session state as part of
 | 
			
		||||
   * handling this signal; if the user has requested that the session
 | 
			
		||||
   * be saved when logging out, then ::save_state will be emitted
 | 
			
		||||
   * separately.
 | 
			
		||||
   * 
 | 
			
		||||
   * If the application agrees to quit, it should then wait for either
 | 
			
		||||
   * the ::quit_cancelled or ::quit signals to be emitted.
 | 
			
		||||
   **/
 | 
			
		||||
  signals[QUIT_REQUESTED] =
 | 
			
		||||
    g_signal_new ("quit_requested",
 | 
			
		||||
                  G_OBJECT_CLASS_TYPE (object_class),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  G_STRUCT_OFFSET (EggSMClientClass, quit_requested),
 | 
			
		||||
                  NULL, NULL,
 | 
			
		||||
                  g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
                  G_TYPE_NONE,
 | 
			
		||||
                  0);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * EggSMClient::quit_cancelled:
 | 
			
		||||
   * @client: the client
 | 
			
		||||
   *
 | 
			
		||||
   * Emitted when the session manager decides to cancel a logout after
 | 
			
		||||
   * the application has already agreed to quit. After receiving this
 | 
			
		||||
   * signal, the application can go back to what it was doing before
 | 
			
		||||
   * receiving the ::quit_requested signal.
 | 
			
		||||
   **/
 | 
			
		||||
  signals[QUIT_CANCELLED] =
 | 
			
		||||
    g_signal_new ("quit_cancelled",
 | 
			
		||||
                  G_OBJECT_CLASS_TYPE (object_class),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  G_STRUCT_OFFSET (EggSMClientClass, quit_cancelled),
 | 
			
		||||
                  NULL, NULL,
 | 
			
		||||
                  g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
                  G_TYPE_NONE,
 | 
			
		||||
                  0);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * EggSMClient::quit:
 | 
			
		||||
   * @client: the client
 | 
			
		||||
   *
 | 
			
		||||
   * Emitted when the session manager wants the application to quit
 | 
			
		||||
   * (generally because the user is logging out). The application
 | 
			
		||||
   * should exit as soon as possible after receiving this signal; if
 | 
			
		||||
   * it does not, the session manager may choose to forcibly kill it.
 | 
			
		||||
   *
 | 
			
		||||
   * Normally a GUI application would only be sent a ::quit if it
 | 
			
		||||
   * agreed to quit in response to a ::quit_requested signal. However,
 | 
			
		||||
   * this is not guaranteed; in some situations the session manager
 | 
			
		||||
   * may decide to end the session without giving applications a
 | 
			
		||||
   * chance to object.
 | 
			
		||||
   **/
 | 
			
		||||
  signals[QUIT] =
 | 
			
		||||
    g_signal_new ("quit",
 | 
			
		||||
                  G_OBJECT_CLASS_TYPE (object_class),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  G_STRUCT_OFFSET (EggSMClientClass, quit),
 | 
			
		||||
                  NULL, NULL,
 | 
			
		||||
                  g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
                  G_TYPE_NONE,
 | 
			
		||||
                  0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean sm_client_disable = FALSE;
 | 
			
		||||
static char *sm_client_state_file = NULL;
 | 
			
		||||
static char *sm_client_id = NULL;
 | 
			
		||||
static char *sm_config_prefix = NULL;
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
sm_client_post_parse_func (GOptionContext  *context,
 | 
			
		||||
			   GOptionGroup    *group,
 | 
			
		||||
			   gpointer         data,
 | 
			
		||||
			   GError         **error)
 | 
			
		||||
{
 | 
			
		||||
  EggSMClient *client = egg_sm_client_get ();
 | 
			
		||||
 | 
			
		||||
  if (sm_client_id == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      const gchar *desktop_autostart_id;
 | 
			
		||||
 | 
			
		||||
      desktop_autostart_id = g_getenv ("DESKTOP_AUTOSTART_ID");
 | 
			
		||||
 | 
			
		||||
      if (desktop_autostart_id != NULL)
 | 
			
		||||
        sm_client_id = g_strdup (desktop_autostart_id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* Unset DESKTOP_AUTOSTART_ID in order to avoid child processes to
 | 
			
		||||
   * use the same client id. */
 | 
			
		||||
  g_unsetenv ("DESKTOP_AUTOSTART_ID");
 | 
			
		||||
 | 
			
		||||
  if (EGG_SM_CLIENT_GET_CLASS (client)->startup)
 | 
			
		||||
    EGG_SM_CLIENT_GET_CLASS (client)->startup (client, sm_client_id);
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * egg_sm_client_get_option_group:
 | 
			
		||||
 *
 | 
			
		||||
 * Creates a %GOptionGroup containing the session-management-related
 | 
			
		||||
 * options. You should add this group to the application's
 | 
			
		||||
 * %GOptionContext if you want to use #EggSMClient.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the %GOptionGroup
 | 
			
		||||
 **/
 | 
			
		||||
GOptionGroup *
 | 
			
		||||
egg_sm_client_get_option_group (void)
 | 
			
		||||
{
 | 
			
		||||
  const GOptionEntry entries[] = {
 | 
			
		||||
    { "sm-client-disable", 0, 0,
 | 
			
		||||
      G_OPTION_ARG_NONE, &sm_client_disable,
 | 
			
		||||
      N_("Disable connection to session manager"), NULL },
 | 
			
		||||
    { "sm-client-state-file", 0, 0,
 | 
			
		||||
      G_OPTION_ARG_FILENAME, &sm_client_state_file,
 | 
			
		||||
      N_("Specify file containing saved configuration"), N_("FILE") },
 | 
			
		||||
    { "sm-client-id", 0, 0,
 | 
			
		||||
      G_OPTION_ARG_STRING, &sm_client_id,
 | 
			
		||||
      N_("Specify session management ID"), N_("ID") },
 | 
			
		||||
    /* MateClient compatibility option */
 | 
			
		||||
    { "sm-disable", 0, G_OPTION_FLAG_HIDDEN,
 | 
			
		||||
      G_OPTION_ARG_NONE, &sm_client_disable,
 | 
			
		||||
      NULL, NULL },
 | 
			
		||||
    /* MateClient compatibility option. This is a dummy option that only
 | 
			
		||||
     * exists so that sessions saved by apps with MateClient can be restored
 | 
			
		||||
     * later when they've switched to EggSMClient. See bug #575308.
 | 
			
		||||
     */
 | 
			
		||||
    { "sm-config-prefix", 0, G_OPTION_FLAG_HIDDEN,
 | 
			
		||||
      G_OPTION_ARG_STRING, &sm_config_prefix,
 | 
			
		||||
      NULL, NULL },
 | 
			
		||||
    { NULL }
 | 
			
		||||
  };
 | 
			
		||||
  GOptionGroup *group;
 | 
			
		||||
 | 
			
		||||
  /* Use our own debug handler for the "EggSMClient" domain. */
 | 
			
		||||
  g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,
 | 
			
		||||
		     egg_sm_client_debug_handler, NULL);
 | 
			
		||||
 | 
			
		||||
  group = g_option_group_new ("sm-client",
 | 
			
		||||
			      _("Session management options:"),
 | 
			
		||||
			      _("Show session management options"),
 | 
			
		||||
			      NULL, NULL);
 | 
			
		||||
  g_option_group_add_entries (group, entries);
 | 
			
		||||
  g_option_group_set_parse_hooks (group, NULL, sm_client_post_parse_func);
 | 
			
		||||
 | 
			
		||||
  return group;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * egg_sm_client_set_mode:
 | 
			
		||||
 * @mode: an #EggSMClient mode
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the "mode" of #EggSMClient as follows:
 | 
			
		||||
 *
 | 
			
		||||
 *    %EGG_SM_CLIENT_MODE_DISABLED: Session management is completely
 | 
			
		||||
 *    disabled. The application will not even connect to the session
 | 
			
		||||
 *    manager. (egg_sm_client_get() will still return an #EggSMClient,
 | 
			
		||||
 *    but it will just be a dummy object.)
 | 
			
		||||
 *
 | 
			
		||||
 *    %EGG_SM_CLIENT_MODE_NO_RESTART: The application will connect to
 | 
			
		||||
 *    the session manager (and thus will receive notification when the
 | 
			
		||||
 *    user is logging out, etc), but will request to not be
 | 
			
		||||
 *    automatically restarted with saved state in future sessions.
 | 
			
		||||
 *
 | 
			
		||||
 *    %EGG_SM_CLIENT_MODE_NORMAL: The default. #EggSMCLient will
 | 
			
		||||
 *    function normally.
 | 
			
		||||
 *
 | 
			
		||||
 * This must be called before the application's main loop begins.
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
egg_sm_client_set_mode (EggSMClientMode mode)
 | 
			
		||||
{
 | 
			
		||||
  global_client_mode = mode;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * egg_sm_client_get_mode:
 | 
			
		||||
 *
 | 
			
		||||
 * Gets the global #EggSMClientMode. See egg_sm_client_set_mode()
 | 
			
		||||
 * for details.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the global #EggSMClientMode
 | 
			
		||||
 **/
 | 
			
		||||
EggSMClientMode
 | 
			
		||||
egg_sm_client_get_mode (void)
 | 
			
		||||
{
 | 
			
		||||
  return global_client_mode;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * egg_sm_client_get:
 | 
			
		||||
 *
 | 
			
		||||
 * Returns the master #EggSMClient for the application.
 | 
			
		||||
 *
 | 
			
		||||
 * On platforms that support saved sessions (ie, POSIX/X11), the
 | 
			
		||||
 * application will only request to be restarted by the session
 | 
			
		||||
 * manager if you call egg_set_desktop_file() to set an application
 | 
			
		||||
 * desktop file. In particular, if the desktop file contains the key
 | 
			
		||||
 * "X
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the master #EggSMClient.
 | 
			
		||||
 **/
 | 
			
		||||
EggSMClient *
 | 
			
		||||
egg_sm_client_get (void)
 | 
			
		||||
{
 | 
			
		||||
  if (!global_client)
 | 
			
		||||
    {
 | 
			
		||||
      if (global_client_mode != EGG_SM_CLIENT_MODE_DISABLED &&
 | 
			
		||||
	  !sm_client_disable)
 | 
			
		||||
	{
 | 
			
		||||
	  global_client = egg_sm_client_xsmp_new ();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      /* Fallback: create a dummy client, so that callers don't have
 | 
			
		||||
       * to worry about a %NULL return value.
 | 
			
		||||
       */
 | 
			
		||||
      if (!global_client)
 | 
			
		||||
	global_client = g_object_new (EGG_TYPE_SM_CLIENT, NULL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return global_client;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * egg_sm_client_is_resumed:
 | 
			
		||||
 * @client: the client
 | 
			
		||||
 *
 | 
			
		||||
 * Checks whether or not the current session has been resumed from
 | 
			
		||||
 * a previous saved session. If so, the application should call
 | 
			
		||||
 * egg_sm_client_get_state_file() and restore its state from the
 | 
			
		||||
 * returned #GKeyFile.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: %TRUE if the session has been resumed
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
egg_sm_client_is_resumed (EggSMClient *client)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (client == global_client, FALSE);
 | 
			
		||||
 | 
			
		||||
  return sm_client_state_file != NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * egg_sm_client_get_state_file:
 | 
			
		||||
 * @client: the client
 | 
			
		||||
 *
 | 
			
		||||
 * If the application was resumed by the session manager, this will
 | 
			
		||||
 * return the #GKeyFile containing its state from the previous
 | 
			
		||||
 * session.
 | 
			
		||||
 *
 | 
			
		||||
 * Note that other libraries and #EggSMClient itself may also store
 | 
			
		||||
 * state in the key file, so if you call egg_sm_client_get_groups(),
 | 
			
		||||
 * on it, the return value will likely include groups that you did not
 | 
			
		||||
 * put there yourself. (It is also not guaranteed that the first
 | 
			
		||||
 * group created by the application will still be the "start group"
 | 
			
		||||
 * when it is resumed.)
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the #GKeyFile containing the application's earlier
 | 
			
		||||
 * state, or %NULL on error. You should not free this key file; it
 | 
			
		||||
 * is owned by @client.
 | 
			
		||||
 **/
 | 
			
		||||
GKeyFile *
 | 
			
		||||
egg_sm_client_get_state_file (EggSMClient *client)
 | 
			
		||||
{
 | 
			
		||||
  EggSMClientPrivate *priv = EGG_SM_CLIENT_GET_PRIVATE (client);
 | 
			
		||||
  char *state_file_path;
 | 
			
		||||
  GError *err = NULL;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (client == global_client, NULL);
 | 
			
		||||
 | 
			
		||||
  if (!sm_client_state_file)
 | 
			
		||||
    return NULL;
 | 
			
		||||
  if (priv->state_file)
 | 
			
		||||
    return priv->state_file;
 | 
			
		||||
 | 
			
		||||
  if (!strncmp (sm_client_state_file, "file://", 7))
 | 
			
		||||
    state_file_path = g_filename_from_uri (sm_client_state_file, NULL, NULL);
 | 
			
		||||
  else
 | 
			
		||||
    state_file_path = g_strdup (sm_client_state_file);
 | 
			
		||||
 | 
			
		||||
  priv->state_file = g_key_file_new ();
 | 
			
		||||
  if (!g_key_file_load_from_file (priv->state_file, state_file_path, 0, &err))
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("Could not load SM state file '%s': %s",
 | 
			
		||||
		 sm_client_state_file, err->message);
 | 
			
		||||
      g_clear_error (&err);
 | 
			
		||||
      g_key_file_free (priv->state_file);
 | 
			
		||||
      priv->state_file = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_free (state_file_path);
 | 
			
		||||
  return priv->state_file;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * egg_sm_client_set_restart_command:
 | 
			
		||||
 * @client: the client
 | 
			
		||||
 * @argc: the length of @argv
 | 
			
		||||
 * @argv: argument vector
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the command used to restart @client if it does not have a
 | 
			
		||||
 * .desktop file that can be used to find its restart command.
 | 
			
		||||
 *
 | 
			
		||||
 * This can also be used when handling the ::save_state signal, to
 | 
			
		||||
 * save the current state via an updated command line. (Eg, providing
 | 
			
		||||
 * a list of filenames to open when the application is resumed.)
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
egg_sm_client_set_restart_command (EggSMClient  *client,
 | 
			
		||||
				   int           argc,
 | 
			
		||||
				   const char  **argv)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (EGG_IS_SM_CLIENT (client));
 | 
			
		||||
 | 
			
		||||
  if (EGG_SM_CLIENT_GET_CLASS (client)->set_restart_command)
 | 
			
		||||
    EGG_SM_CLIENT_GET_CLASS (client)->set_restart_command (client, argc, argv);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * egg_sm_client_will_quit:
 | 
			
		||||
 * @client: the client
 | 
			
		||||
 * @will_quit: whether or not the application is willing to quit
 | 
			
		||||
 *
 | 
			
		||||
 * This MUST be called in response to the ::quit_requested signal, to
 | 
			
		||||
 * indicate whether or not the application is willing to quit. The
 | 
			
		||||
 * application may call it either directly from the signal handler, or
 | 
			
		||||
 * at some later point (eg, after asynchronously interacting with the
 | 
			
		||||
 * user).
 | 
			
		||||
 *
 | 
			
		||||
 * If the application does not connect to ::quit_requested,
 | 
			
		||||
 * #EggSMClient will call this method on its behalf (passing %TRUE
 | 
			
		||||
 * for @will_quit).
 | 
			
		||||
 *
 | 
			
		||||
 * After calling this method, the application should wait to receive
 | 
			
		||||
 * either ::quit_cancelled or ::quit.
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
egg_sm_client_will_quit (EggSMClient *client,
 | 
			
		||||
			 gboolean     will_quit)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (EGG_IS_SM_CLIENT (client));
 | 
			
		||||
 | 
			
		||||
  if (EGG_SM_CLIENT_GET_CLASS (client)->will_quit)
 | 
			
		||||
    EGG_SM_CLIENT_GET_CLASS (client)->will_quit (client, will_quit);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * egg_sm_client_end_session:
 | 
			
		||||
 * @style: a hint at how to end the session
 | 
			
		||||
 * @request_confirmation: whether or not the user should get a chance
 | 
			
		||||
 * to confirm the action
 | 
			
		||||
 *
 | 
			
		||||
 * Requests that the session manager end the current session. @style
 | 
			
		||||
 * indicates how the session should be ended, and
 | 
			
		||||
 * @request_confirmation indicates whether or not the user should be
 | 
			
		||||
 * given a chance to confirm the logout/reboot/shutdown. Both of these
 | 
			
		||||
 * flags are merely hints though; the session manager may choose to
 | 
			
		||||
 * ignore them.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: %TRUE if the request was sent; %FALSE if it could not
 | 
			
		||||
 * be (eg, because it could not connect to the session manager).
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
egg_sm_client_end_session (EggSMClientEndStyle  style,
 | 
			
		||||
			   gboolean             request_confirmation)
 | 
			
		||||
{
 | 
			
		||||
  EggSMClient *client = egg_sm_client_get ();
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (EGG_IS_SM_CLIENT (client), FALSE);
 | 
			
		||||
 | 
			
		||||
  if (EGG_SM_CLIENT_GET_CLASS (client)->end_session)
 | 
			
		||||
    {
 | 
			
		||||
      return EGG_SM_CLIENT_GET_CLASS (client)->end_session (client, style,
 | 
			
		||||
							    request_confirmation);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Signal-emitting callbacks from platform-specific code */
 | 
			
		||||
 | 
			
		||||
GKeyFile *
 | 
			
		||||
egg_sm_client_save_state (EggSMClient *client)
 | 
			
		||||
{
 | 
			
		||||
  GKeyFile *state_file;
 | 
			
		||||
  char *group;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (client == global_client, NULL);
 | 
			
		||||
 | 
			
		||||
  state_file = g_key_file_new ();
 | 
			
		||||
 | 
			
		||||
  g_debug ("Emitting save_state");
 | 
			
		||||
  g_signal_emit (client, signals[SAVE_STATE], 0, state_file);
 | 
			
		||||
  g_debug ("Done emitting save_state");
 | 
			
		||||
 | 
			
		||||
  group = g_key_file_get_start_group (state_file);
 | 
			
		||||
  if (group)
 | 
			
		||||
    {
 | 
			
		||||
      g_free (group);
 | 
			
		||||
      return state_file;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      g_key_file_free (state_file);
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
egg_sm_client_quit_requested (EggSMClient *client)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (client == global_client);
 | 
			
		||||
 | 
			
		||||
  if (!g_signal_has_handler_pending (client, signals[QUIT_REQUESTED], 0, FALSE))
 | 
			
		||||
    {
 | 
			
		||||
      g_debug ("Not emitting quit_requested because no one is listening");
 | 
			
		||||
      egg_sm_client_will_quit (client, TRUE);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_debug ("Emitting quit_requested");
 | 
			
		||||
  g_signal_emit (client, signals[QUIT_REQUESTED], 0);
 | 
			
		||||
  g_debug ("Done emitting quit_requested");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
egg_sm_client_quit_cancelled (EggSMClient *client)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (client == global_client);
 | 
			
		||||
 | 
			
		||||
  g_debug ("Emitting quit_cancelled");
 | 
			
		||||
  g_signal_emit (client, signals[QUIT_CANCELLED], 0);
 | 
			
		||||
  g_debug ("Done emitting quit_cancelled");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
egg_sm_client_quit (EggSMClient *client)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (client == global_client);
 | 
			
		||||
 | 
			
		||||
  g_debug ("Emitting quit");
 | 
			
		||||
  g_signal_emit (client, signals[QUIT], 0);
 | 
			
		||||
  g_debug ("Done emitting quit");
 | 
			
		||||
 | 
			
		||||
  /* FIXME: should we just call gtk_main_quit() here? */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
egg_sm_client_debug_handler (const char *log_domain,
 | 
			
		||||
			     GLogLevelFlags log_level,
 | 
			
		||||
			     const char *message,
 | 
			
		||||
			     gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
  static int debug = -1;
 | 
			
		||||
 | 
			
		||||
  if (debug < 0)
 | 
			
		||||
    debug = (g_getenv ("EGG_SM_CLIENT_DEBUG") != NULL);
 | 
			
		||||
 | 
			
		||||
  if (debug)
 | 
			
		||||
    g_log_default_handler (log_domain, log_level, message, NULL);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										117
									
								
								xedit/smclient/eggsmclient.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								xedit/smclient/eggsmclient.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,117 @@
 | 
			
		||||
/* eggsmclient.h
 | 
			
		||||
 * Copyright (C) 2007 Novell, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser 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
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __EGG_SM_CLIENT_H__
 | 
			
		||||
#define __EGG_SM_CLIENT_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EGG_TYPE_SM_CLIENT            (egg_sm_client_get_type ())
 | 
			
		||||
#define EGG_SM_CLIENT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_SM_CLIENT, EggSMClient))
 | 
			
		||||
#define EGG_SM_CLIENT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_SM_CLIENT, EggSMClientClass))
 | 
			
		||||
#define EGG_IS_SM_CLIENT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_SM_CLIENT))
 | 
			
		||||
#define EGG_IS_SM_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_SM_CLIENT))
 | 
			
		||||
#define EGG_SM_CLIENT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_SM_CLIENT, EggSMClientClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EggSMClient        EggSMClient;
 | 
			
		||||
typedef struct _EggSMClientClass   EggSMClientClass;
 | 
			
		||||
typedef struct _EggSMClientPrivate EggSMClientPrivate;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
  EGG_SM_CLIENT_END_SESSION_DEFAULT,
 | 
			
		||||
  EGG_SM_CLIENT_LOGOUT,
 | 
			
		||||
  EGG_SM_CLIENT_REBOOT,
 | 
			
		||||
  EGG_SM_CLIENT_SHUTDOWN
 | 
			
		||||
} EggSMClientEndStyle;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
  EGG_SM_CLIENT_MODE_DISABLED,
 | 
			
		||||
  EGG_SM_CLIENT_MODE_NO_RESTART,
 | 
			
		||||
  EGG_SM_CLIENT_MODE_NORMAL
 | 
			
		||||
} EggSMClientMode;
 | 
			
		||||
 | 
			
		||||
struct _EggSMClient
 | 
			
		||||
{
 | 
			
		||||
  GObject parent;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _EggSMClientClass
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
  /* signals */
 | 
			
		||||
  void (*save_state)       (EggSMClient *client,
 | 
			
		||||
			    GKeyFile    *state_file);
 | 
			
		||||
 | 
			
		||||
  void (*quit_requested)   (EggSMClient *client);
 | 
			
		||||
  void (*quit_cancelled)   (EggSMClient *client);
 | 
			
		||||
  void (*quit)             (EggSMClient *client);
 | 
			
		||||
 | 
			
		||||
  /* virtual methods */
 | 
			
		||||
  void	   (*startup)             (EggSMClient          *client,
 | 
			
		||||
				   const char           *client_id);
 | 
			
		||||
  void	   (*set_restart_command) (EggSMClient          *client,
 | 
			
		||||
				   int                   argc,
 | 
			
		||||
				   const char          **argv);
 | 
			
		||||
  void	   (*will_quit)           (EggSMClient          *client,
 | 
			
		||||
				   gboolean              will_quit);
 | 
			
		||||
  gboolean (*end_session)         (EggSMClient          *client,
 | 
			
		||||
				   EggSMClientEndStyle   style,
 | 
			
		||||
				   gboolean              request_confirmation);
 | 
			
		||||
 | 
			
		||||
  /* Padding for future expansion */
 | 
			
		||||
  void (*_egg_reserved1) (void);
 | 
			
		||||
  void (*_egg_reserved2) (void);
 | 
			
		||||
  void (*_egg_reserved3) (void);
 | 
			
		||||
  void (*_egg_reserved4) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType            egg_sm_client_get_type            (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
GOptionGroup    *egg_sm_client_get_option_group    (void);
 | 
			
		||||
 | 
			
		||||
/* Initialization */
 | 
			
		||||
void             egg_sm_client_set_mode            (EggSMClientMode mode);
 | 
			
		||||
EggSMClientMode  egg_sm_client_get_mode            (void);
 | 
			
		||||
EggSMClient     *egg_sm_client_get                 (void);
 | 
			
		||||
 | 
			
		||||
/* Resuming a saved session */
 | 
			
		||||
gboolean         egg_sm_client_is_resumed          (EggSMClient *client);
 | 
			
		||||
GKeyFile        *egg_sm_client_get_state_file      (EggSMClient *client);
 | 
			
		||||
 | 
			
		||||
/* Alternate means of saving state */
 | 
			
		||||
void             egg_sm_client_set_restart_command (EggSMClient  *client,
 | 
			
		||||
						    int           argc,
 | 
			
		||||
						    const char  **argv);
 | 
			
		||||
 | 
			
		||||
/* Handling "quit_requested" signal */
 | 
			
		||||
void             egg_sm_client_will_quit           (EggSMClient *client,
 | 
			
		||||
						    gboolean     will_quit);
 | 
			
		||||
 | 
			
		||||
/* Initiate a logout/reboot/shutdown */
 | 
			
		||||
gboolean         egg_sm_client_end_session         (EggSMClientEndStyle  style,
 | 
			
		||||
						    gboolean             request_confirmation);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* __EGG_SM_CLIENT_H__ */
 | 
			
		||||
							
								
								
									
										898
									
								
								xedit/xedit-app.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										898
									
								
								xedit/xedit-app.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,898 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-app.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2005-2006 - Paolo Maggi
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor,
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2005. See the AUTHORS file for a
 | 
			
		||||
 * list of people on the xedit Team.
 | 
			
		||||
 * See the ChangeLog files for a list of changes.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
 | 
			
		||||
#include "xedit-app.h"
 | 
			
		||||
#include "xedit-prefs-manager-app.h"
 | 
			
		||||
#include "xedit-commands.h"
 | 
			
		||||
#include "xedit-notebook.h"
 | 
			
		||||
#include "xedit-debug.h"
 | 
			
		||||
#include "xedit-utils.h"
 | 
			
		||||
#include "xedit-enum-types.h"
 | 
			
		||||
#include "xedit-dirs.h"
 | 
			
		||||
 | 
			
		||||
#define XEDIT_PAGE_SETUP_FILE		"xedit-page-setup"
 | 
			
		||||
#define XEDIT_PRINT_SETTINGS_FILE	"xedit-print-settings"
 | 
			
		||||
 | 
			
		||||
#define XEDIT_APP_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), XEDIT_TYPE_APP, XeditAppPrivate))
 | 
			
		||||
 | 
			
		||||
/* Properties */
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
	PROP_0,
 | 
			
		||||
	PROP_LOCKDOWN
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _XeditAppPrivate
 | 
			
		||||
{
 | 
			
		||||
	GList	          *windows;
 | 
			
		||||
	XeditWindow       *active_window;
 | 
			
		||||
 | 
			
		||||
	XeditLockdownMask  lockdown;
 | 
			
		||||
 | 
			
		||||
	GtkPageSetup      *page_setup;
 | 
			
		||||
	GtkPrintSettings  *print_settings;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE(XeditApp, xedit_app, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_app_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
	XeditApp *app = XEDIT_APP (object);
 | 
			
		||||
 | 
			
		||||
	g_list_free (app->priv->windows);
 | 
			
		||||
 | 
			
		||||
	if (app->priv->page_setup)
 | 
			
		||||
		g_object_unref (app->priv->page_setup);
 | 
			
		||||
	if (app->priv->print_settings)
 | 
			
		||||
		g_object_unref (app->priv->print_settings);
 | 
			
		||||
 | 
			
		||||
	G_OBJECT_CLASS (xedit_app_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_app_get_property (GObject    *object,
 | 
			
		||||
			guint       prop_id,
 | 
			
		||||
			GValue     *value,
 | 
			
		||||
			GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
	XeditApp *app = XEDIT_APP (object);
 | 
			
		||||
 | 
			
		||||
	switch (prop_id)
 | 
			
		||||
	{
 | 
			
		||||
		case PROP_LOCKDOWN:
 | 
			
		||||
			g_value_set_flags (value, xedit_app_get_lockdown (app));
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_app_class_init (XeditAppClass *klass)
 | 
			
		||||
{
 | 
			
		||||
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
	object_class->finalize = xedit_app_finalize;
 | 
			
		||||
	object_class->get_property = xedit_app_get_property;
 | 
			
		||||
 | 
			
		||||
	g_object_class_install_property (object_class,
 | 
			
		||||
					 PROP_LOCKDOWN,
 | 
			
		||||
					 g_param_spec_flags ("lockdown",
 | 
			
		||||
							     "Lockdown",
 | 
			
		||||
							     "The lockdown mask",
 | 
			
		||||
							     XEDIT_TYPE_LOCKDOWN_MASK,
 | 
			
		||||
							     0,
 | 
			
		||||
							     G_PARAM_READABLE |
 | 
			
		||||
							     G_PARAM_STATIC_STRINGS));
 | 
			
		||||
 | 
			
		||||
	g_type_class_add_private (object_class, sizeof(XeditAppPrivate));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
ensure_user_config_dir (void)
 | 
			
		||||
{
 | 
			
		||||
	gchar *config_dir;
 | 
			
		||||
	gboolean ret = TRUE;
 | 
			
		||||
	gint res;
 | 
			
		||||
 | 
			
		||||
	config_dir = xedit_dirs_get_user_config_dir ();
 | 
			
		||||
	if (config_dir == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		g_warning ("Could not get config directory\n");
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	res = g_mkdir_with_parents (config_dir, 0755);
 | 
			
		||||
	if (res < 0)
 | 
			
		||||
	{
 | 
			
		||||
		g_warning ("Could not create config directory\n");
 | 
			
		||||
		ret = FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_free (config_dir);
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
load_accels (void)
 | 
			
		||||
{
 | 
			
		||||
	gchar *filename;
 | 
			
		||||
 | 
			
		||||
	filename = xedit_dirs_get_user_accels_file ();
 | 
			
		||||
	if (filename != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		xedit_debug_message (DEBUG_APP, "Loading keybindings from %s\n", filename);
 | 
			
		||||
		gtk_accel_map_load (filename);
 | 
			
		||||
		g_free (filename);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
save_accels (void)
 | 
			
		||||
{
 | 
			
		||||
	gchar *filename;
 | 
			
		||||
 | 
			
		||||
	filename = xedit_dirs_get_user_accels_file ();
 | 
			
		||||
	if (filename != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		xedit_debug_message (DEBUG_APP, "Saving keybindings in %s\n", filename);
 | 
			
		||||
		gtk_accel_map_save (filename);
 | 
			
		||||
		g_free (filename);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gchar *
 | 
			
		||||
get_page_setup_file (void)
 | 
			
		||||
{
 | 
			
		||||
	gchar *config_dir;
 | 
			
		||||
	gchar *setup = NULL;
 | 
			
		||||
 | 
			
		||||
	config_dir = xedit_dirs_get_user_config_dir ();
 | 
			
		||||
 | 
			
		||||
	if (config_dir != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		setup = g_build_filename (config_dir,
 | 
			
		||||
					  XEDIT_PAGE_SETUP_FILE,
 | 
			
		||||
					  NULL);
 | 
			
		||||
		g_free (config_dir);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return setup;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
load_page_setup (XeditApp *app)
 | 
			
		||||
{
 | 
			
		||||
	gchar *filename;
 | 
			
		||||
	GError *error = NULL;
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (app->priv->page_setup == NULL);
 | 
			
		||||
 | 
			
		||||
	filename = get_page_setup_file ();
 | 
			
		||||
 | 
			
		||||
	app->priv->page_setup = gtk_page_setup_new_from_file (filename,
 | 
			
		||||
							      &error);
 | 
			
		||||
	if (error)
 | 
			
		||||
	{
 | 
			
		||||
		/* Ignore file not found error */
 | 
			
		||||
		if (error->domain != G_FILE_ERROR ||
 | 
			
		||||
		    error->code != G_FILE_ERROR_NOENT)
 | 
			
		||||
		{
 | 
			
		||||
			g_warning ("%s", error->message);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		g_error_free (error);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_free (filename);
 | 
			
		||||
 | 
			
		||||
	/* fall back to default settings */
 | 
			
		||||
	if (app->priv->page_setup == NULL)
 | 
			
		||||
		app->priv->page_setup = gtk_page_setup_new ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
save_page_setup (XeditApp *app)
 | 
			
		||||
{
 | 
			
		||||
	gchar *filename;
 | 
			
		||||
	GError *error = NULL;
 | 
			
		||||
 | 
			
		||||
	if (app->priv->page_setup == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	filename = get_page_setup_file ();
 | 
			
		||||
 | 
			
		||||
	gtk_page_setup_to_file (app->priv->page_setup,
 | 
			
		||||
				filename,
 | 
			
		||||
				&error);
 | 
			
		||||
	if (error)
 | 
			
		||||
	{
 | 
			
		||||
		g_warning ("%s", error->message);
 | 
			
		||||
		g_error_free (error);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_free (filename);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gchar *
 | 
			
		||||
get_print_settings_file (void)
 | 
			
		||||
{
 | 
			
		||||
	gchar *config_dir;
 | 
			
		||||
	gchar *settings = NULL;
 | 
			
		||||
 | 
			
		||||
	config_dir = xedit_dirs_get_user_config_dir ();
 | 
			
		||||
 | 
			
		||||
	if (config_dir != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		settings = g_build_filename (config_dir,
 | 
			
		||||
					     XEDIT_PRINT_SETTINGS_FILE,
 | 
			
		||||
					     NULL);
 | 
			
		||||
		g_free (config_dir);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return settings;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
load_print_settings (XeditApp *app)
 | 
			
		||||
{
 | 
			
		||||
	gchar *filename;
 | 
			
		||||
	GError *error = NULL;
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (app->priv->print_settings == NULL);
 | 
			
		||||
 | 
			
		||||
	filename = get_print_settings_file ();
 | 
			
		||||
 | 
			
		||||
	app->priv->print_settings = gtk_print_settings_new_from_file (filename,
 | 
			
		||||
								      &error);
 | 
			
		||||
	if (error)
 | 
			
		||||
	{
 | 
			
		||||
		/* Ignore file not found error */
 | 
			
		||||
		if (error->domain != G_FILE_ERROR ||
 | 
			
		||||
		    error->code != G_FILE_ERROR_NOENT)
 | 
			
		||||
		{
 | 
			
		||||
			g_warning ("%s", error->message);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		g_error_free (error);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_free (filename);
 | 
			
		||||
 | 
			
		||||
	/* fall back to default settings */
 | 
			
		||||
	if (app->priv->print_settings == NULL)
 | 
			
		||||
		app->priv->print_settings = gtk_print_settings_new ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
save_print_settings (XeditApp *app)
 | 
			
		||||
{
 | 
			
		||||
	gchar *filename;
 | 
			
		||||
	GError *error = NULL;
 | 
			
		||||
 | 
			
		||||
	if (app->priv->print_settings == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	filename = get_print_settings_file ();
 | 
			
		||||
 | 
			
		||||
	gtk_print_settings_to_file (app->priv->print_settings,
 | 
			
		||||
				    filename,
 | 
			
		||||
				    &error);
 | 
			
		||||
	if (error)
 | 
			
		||||
	{
 | 
			
		||||
		g_warning ("%s", error->message);
 | 
			
		||||
		g_error_free (error);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_free (filename);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_app_init (XeditApp *app)
 | 
			
		||||
{
 | 
			
		||||
	app->priv = XEDIT_APP_GET_PRIVATE (app);
 | 
			
		||||
 | 
			
		||||
	load_accels ();
 | 
			
		||||
 | 
			
		||||
	/* initial lockdown state */
 | 
			
		||||
	app->priv->lockdown = xedit_prefs_manager_get_lockdown ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
app_weak_notify (gpointer data,
 | 
			
		||||
		 GObject *where_the_app_was)
 | 
			
		||||
{
 | 
			
		||||
	gtk_main_quit ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_app_get_default:
 | 
			
		||||
 *
 | 
			
		||||
 * Returns the #XeditApp object. This object is a singleton and
 | 
			
		||||
 * represents the running xedit instance.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the #XeditApp pointer
 | 
			
		||||
 */
 | 
			
		||||
XeditApp *
 | 
			
		||||
xedit_app_get_default (void)
 | 
			
		||||
{
 | 
			
		||||
	static XeditApp *app = NULL;
 | 
			
		||||
 | 
			
		||||
	if (app != NULL)
 | 
			
		||||
		return app;
 | 
			
		||||
 | 
			
		||||
	app = XEDIT_APP (g_object_new (XEDIT_TYPE_APP, NULL));
 | 
			
		||||
 | 
			
		||||
	g_object_add_weak_pointer (G_OBJECT (app),
 | 
			
		||||
				   (gpointer) &app);
 | 
			
		||||
	g_object_weak_ref (G_OBJECT (app),
 | 
			
		||||
			   app_weak_notify,
 | 
			
		||||
			   NULL);
 | 
			
		||||
 | 
			
		||||
	return app;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_active_window (XeditApp    *app,
 | 
			
		||||
                   XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	app->priv->active_window = window;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
window_focus_in_event (XeditWindow   *window,
 | 
			
		||||
		       GdkEventFocus *event,
 | 
			
		||||
		       XeditApp      *app)
 | 
			
		||||
{
 | 
			
		||||
	/* updates active_view and active_child when a new toplevel receives focus */
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_WINDOW (window), FALSE);
 | 
			
		||||
 | 
			
		||||
	set_active_window (app, window);
 | 
			
		||||
 | 
			
		||||
	return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
window_delete_event (XeditWindow *window,
 | 
			
		||||
                     GdkEvent    *event,
 | 
			
		||||
                     XeditApp    *app)
 | 
			
		||||
{
 | 
			
		||||
	XeditWindowState ws;
 | 
			
		||||
 | 
			
		||||
	ws = xedit_window_get_state (window);
 | 
			
		||||
 | 
			
		||||
	if (ws &
 | 
			
		||||
	    (XEDIT_WINDOW_STATE_SAVING |
 | 
			
		||||
	     XEDIT_WINDOW_STATE_PRINTING |
 | 
			
		||||
	     XEDIT_WINDOW_STATE_SAVING_SESSION))
 | 
			
		||||
	    	return TRUE;
 | 
			
		||||
 | 
			
		||||
	_xedit_cmd_file_quit (NULL, window);
 | 
			
		||||
 | 
			
		||||
	/* Do not destroy the window */
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
window_destroy (XeditWindow *window,
 | 
			
		||||
		XeditApp    *app)
 | 
			
		||||
{
 | 
			
		||||
	app->priv->windows = g_list_remove (app->priv->windows,
 | 
			
		||||
					    window);
 | 
			
		||||
 | 
			
		||||
	if (window == app->priv->active_window)
 | 
			
		||||
	{
 | 
			
		||||
		set_active_window (app, app->priv->windows != NULL ? app->priv->windows->data : NULL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
/* CHECK: I don't think we have to disconnect this function, since windows
 | 
			
		||||
   is being destroyed */
 | 
			
		||||
/*
 | 
			
		||||
	g_signal_handlers_disconnect_by_func (window,
 | 
			
		||||
					      G_CALLBACK (window_focus_in_event),
 | 
			
		||||
					      app);
 | 
			
		||||
	g_signal_handlers_disconnect_by_func (window,
 | 
			
		||||
					      G_CALLBACK (window_destroy),
 | 
			
		||||
					      app);
 | 
			
		||||
*/
 | 
			
		||||
	if (app->priv->windows == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		/* Last window is gone... save some settings and exit */
 | 
			
		||||
		ensure_user_config_dir ();
 | 
			
		||||
 | 
			
		||||
		save_accels ();
 | 
			
		||||
		save_page_setup (app);
 | 
			
		||||
		save_print_settings (app);
 | 
			
		||||
 | 
			
		||||
		g_object_unref (app);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Generates a unique string for a window role */
 | 
			
		||||
static gchar *
 | 
			
		||||
gen_role (void)
 | 
			
		||||
{
 | 
			
		||||
	GTimeVal result;
 | 
			
		||||
	static gint serial;
 | 
			
		||||
 | 
			
		||||
	g_get_current_time (&result);
 | 
			
		||||
 | 
			
		||||
	return g_strdup_printf ("xedit-window-%ld-%ld-%d-%s",
 | 
			
		||||
				result.tv_sec,
 | 
			
		||||
				result.tv_usec,
 | 
			
		||||
				serial++,
 | 
			
		||||
				g_get_host_name ());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static XeditWindow *
 | 
			
		||||
xedit_app_create_window_real (XeditApp    *app,
 | 
			
		||||
			      gboolean     set_geometry,
 | 
			
		||||
			      const gchar *role)
 | 
			
		||||
{
 | 
			
		||||
	XeditWindow *window;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_APP);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * We need to be careful here, there is a race condition:
 | 
			
		||||
	 * when another xedit is launched it checks active_window,
 | 
			
		||||
	 * so we must do our best to ensure that active_window
 | 
			
		||||
	 * is never NULL when at least a window exists.
 | 
			
		||||
	 */
 | 
			
		||||
	if (app->priv->windows == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		window = g_object_new (XEDIT_TYPE_WINDOW, NULL);
 | 
			
		||||
		set_active_window (app, window);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		window = g_object_new (XEDIT_TYPE_WINDOW, NULL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	app->priv->windows = g_list_prepend (app->priv->windows,
 | 
			
		||||
					     window);
 | 
			
		||||
 | 
			
		||||
	xedit_debug_message (DEBUG_APP, "Window created");
 | 
			
		||||
 | 
			
		||||
	if (role != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		gtk_window_set_role (GTK_WINDOW (window), role);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		gchar *newrole;
 | 
			
		||||
 | 
			
		||||
		newrole = gen_role ();
 | 
			
		||||
		gtk_window_set_role (GTK_WINDOW (window), newrole);
 | 
			
		||||
		g_free (newrole);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (set_geometry)
 | 
			
		||||
	{
 | 
			
		||||
		GdkWindowState state;
 | 
			
		||||
		gint w, h;
 | 
			
		||||
 | 
			
		||||
		state = xedit_prefs_manager_get_window_state ();
 | 
			
		||||
 | 
			
		||||
		if ((state & GDK_WINDOW_STATE_MAXIMIZED) != 0)
 | 
			
		||||
		{
 | 
			
		||||
			xedit_prefs_manager_get_default_window_size (&w, &h);
 | 
			
		||||
			gtk_window_set_default_size (GTK_WINDOW (window), w, h);
 | 
			
		||||
			gtk_window_maximize (GTK_WINDOW (window));
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			xedit_prefs_manager_get_window_size (&w, &h);
 | 
			
		||||
			gtk_window_set_default_size (GTK_WINDOW (window), w, h);
 | 
			
		||||
			gtk_window_unmaximize (GTK_WINDOW (window));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ((state & GDK_WINDOW_STATE_STICKY ) != 0)
 | 
			
		||||
			gtk_window_stick (GTK_WINDOW (window));
 | 
			
		||||
		else
 | 
			
		||||
			gtk_window_unstick (GTK_WINDOW (window));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_signal_connect (window,
 | 
			
		||||
			  "focus_in_event",
 | 
			
		||||
			  G_CALLBACK (window_focus_in_event),
 | 
			
		||||
			  app);
 | 
			
		||||
	g_signal_connect (window,
 | 
			
		||||
			  "delete_event",
 | 
			
		||||
			  G_CALLBACK (window_delete_event),
 | 
			
		||||
			  app);
 | 
			
		||||
	g_signal_connect (window,
 | 
			
		||||
			  "destroy",
 | 
			
		||||
			  G_CALLBACK (window_destroy),
 | 
			
		||||
			  app);
 | 
			
		||||
 | 
			
		||||
	return window;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_app_create_window:
 | 
			
		||||
 * @app: the #XeditApp
 | 
			
		||||
 * @screen: (allow-none):
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new #XeditWindow part of @app.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the new #XeditWindow
 | 
			
		||||
 */
 | 
			
		||||
XeditWindow *
 | 
			
		||||
xedit_app_create_window (XeditApp  *app,
 | 
			
		||||
			 GdkScreen *screen)
 | 
			
		||||
{
 | 
			
		||||
	XeditWindow *window;
 | 
			
		||||
 | 
			
		||||
	window = xedit_app_create_window_real (app, TRUE, NULL);
 | 
			
		||||
 | 
			
		||||
	if (screen != NULL)
 | 
			
		||||
		gtk_window_set_screen (GTK_WINDOW (window), screen);
 | 
			
		||||
 | 
			
		||||
	return window;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Same as _create_window, but doesn't set the geometry.
 | 
			
		||||
 * The session manager takes care of it. Used in mate-session.
 | 
			
		||||
 */
 | 
			
		||||
XeditWindow *
 | 
			
		||||
_xedit_app_restore_window (XeditApp    *app,
 | 
			
		||||
			   const gchar *role)
 | 
			
		||||
{
 | 
			
		||||
	XeditWindow *window;
 | 
			
		||||
 | 
			
		||||
	window = xedit_app_create_window_real (app, FALSE, role);
 | 
			
		||||
 | 
			
		||||
	return window;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_app_get_windows:
 | 
			
		||||
 * @app: the #XeditApp
 | 
			
		||||
 *
 | 
			
		||||
 * Returns all the windows currently present in #XeditApp.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: (transfer none): the list of #XeditWindows objects.
 | 
			
		||||
 * The list should not be freed
 | 
			
		||||
 */
 | 
			
		||||
const GList *
 | 
			
		||||
xedit_app_get_windows (XeditApp *app)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_APP (app), NULL);
 | 
			
		||||
 | 
			
		||||
	return app->priv->windows;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_app_get_active_window:
 | 
			
		||||
 * @app: the #XeditApp
 | 
			
		||||
 *
 | 
			
		||||
 * Retrives the #XeditWindow currently active.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the active #XeditWindow
 | 
			
		||||
 */
 | 
			
		||||
XeditWindow *
 | 
			
		||||
xedit_app_get_active_window (XeditApp *app)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_APP (app), NULL);
 | 
			
		||||
 | 
			
		||||
	/* make sure our active window is always realized:
 | 
			
		||||
	 * this is needed on startup if we launch two xedit fast
 | 
			
		||||
	 * enough that the second instance comes up before the
 | 
			
		||||
	 * first one shows its window.
 | 
			
		||||
	 */
 | 
			
		||||
	if (!gtk_widget_get_realized (GTK_WIDGET (app->priv->active_window)))
 | 
			
		||||
		gtk_widget_realize (GTK_WIDGET (app->priv->active_window));
 | 
			
		||||
 | 
			
		||||
	return app->priv->active_window;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
is_in_viewport (XeditWindow  *window,
 | 
			
		||||
		GdkScreen    *screen,
 | 
			
		||||
		gint          workspace,
 | 
			
		||||
		gint          viewport_x,
 | 
			
		||||
		gint          viewport_y)
 | 
			
		||||
{
 | 
			
		||||
	GdkScreen *s;
 | 
			
		||||
	GdkDisplay *display;
 | 
			
		||||
	GdkWindow *gdkwindow;
 | 
			
		||||
	const gchar *cur_name;
 | 
			
		||||
	const gchar *name;
 | 
			
		||||
	gint cur_n;
 | 
			
		||||
	gint n;
 | 
			
		||||
	gint ws;
 | 
			
		||||
	gint sc_width, sc_height;
 | 
			
		||||
	gint x, y, width, height;
 | 
			
		||||
	gint vp_x, vp_y;
 | 
			
		||||
 | 
			
		||||
	/* Check for screen and display match */
 | 
			
		||||
	display = gdk_screen_get_display (screen);
 | 
			
		||||
	cur_name = gdk_display_get_name (display);
 | 
			
		||||
	cur_n = gdk_screen_get_number (screen);
 | 
			
		||||
 | 
			
		||||
	s = gtk_window_get_screen (GTK_WINDOW (window));
 | 
			
		||||
	display = gdk_screen_get_display (s);
 | 
			
		||||
	name = gdk_display_get_name (display);
 | 
			
		||||
	n = gdk_screen_get_number (s);
 | 
			
		||||
 | 
			
		||||
	if (strcmp (cur_name, name) != 0 || cur_n != n)
 | 
			
		||||
		return FALSE;
 | 
			
		||||
 | 
			
		||||
	/* Check for workspace match */
 | 
			
		||||
	ws = xedit_utils_get_window_workspace (GTK_WINDOW (window));
 | 
			
		||||
	if (ws != workspace && ws != XEDIT_ALL_WORKSPACES)
 | 
			
		||||
		return FALSE;
 | 
			
		||||
 | 
			
		||||
	/* Check for viewport match */
 | 
			
		||||
	gdkwindow = gtk_widget_get_window (GTK_WIDGET (window));
 | 
			
		||||
	gdk_window_get_position (gdkwindow, &x, &y);
 | 
			
		||||
 | 
			
		||||
		width = gdk_window_get_width(gdkwindow);
 | 
			
		||||
		height = gdk_window_get_height(gdkwindow);
 | 
			
		||||
 | 
			
		||||
	xedit_utils_get_current_viewport (screen, &vp_x, &vp_y);
 | 
			
		||||
	x += vp_x;
 | 
			
		||||
	y += vp_y;
 | 
			
		||||
 | 
			
		||||
	sc_width = gdk_screen_get_width (screen);
 | 
			
		||||
	sc_height = gdk_screen_get_height (screen);
 | 
			
		||||
 | 
			
		||||
	return x + width * .25 >= viewport_x &&
 | 
			
		||||
	       x + width * .75 <= viewport_x + sc_width &&
 | 
			
		||||
	       y  >= viewport_y &&
 | 
			
		||||
	       y + height <= viewport_y + sc_height;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * _xedit_app_get_window_in_viewport
 | 
			
		||||
 * @app: the #XeditApp
 | 
			
		||||
 * @screen: the #GdkScreen
 | 
			
		||||
 * @workspace: the workspace number
 | 
			
		||||
 * @viewport_x: the viewport horizontal origin
 | 
			
		||||
 * @viewport_y: the viewport vertical origin
 | 
			
		||||
 *
 | 
			
		||||
 * Since a workspace can be larger than the screen, it is divided into several
 | 
			
		||||
 * equal parts called viewports. This function retrives the #XeditWindow in
 | 
			
		||||
 * the given viewport of the given workspace.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the #XeditWindow in the given viewport of the given workspace.
 | 
			
		||||
 */
 | 
			
		||||
XeditWindow *
 | 
			
		||||
_xedit_app_get_window_in_viewport (XeditApp  *app,
 | 
			
		||||
				   GdkScreen *screen,
 | 
			
		||||
				   gint       workspace,
 | 
			
		||||
				   gint       viewport_x,
 | 
			
		||||
				   gint       viewport_y)
 | 
			
		||||
{
 | 
			
		||||
	XeditWindow *window;
 | 
			
		||||
 | 
			
		||||
	GList *l;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_APP (app), NULL);
 | 
			
		||||
 | 
			
		||||
	/* first try if the active window */
 | 
			
		||||
	window = app->priv->active_window;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_WINDOW (window), NULL);
 | 
			
		||||
 | 
			
		||||
	if (is_in_viewport (window, screen, workspace, viewport_x, viewport_y))
 | 
			
		||||
		return window;
 | 
			
		||||
 | 
			
		||||
	/* otherwise try to see if there is a window on this workspace */
 | 
			
		||||
	for (l = app->priv->windows; l != NULL; l = l->next)
 | 
			
		||||
	{
 | 
			
		||||
		window = l->data;
 | 
			
		||||
 | 
			
		||||
		if (is_in_viewport (window, screen, workspace, viewport_x, viewport_y))
 | 
			
		||||
			return window;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* no window on this workspace... create a new one */
 | 
			
		||||
	return xedit_app_create_window (app, screen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_app_get_documents:
 | 
			
		||||
 * @app: the #XeditApp
 | 
			
		||||
 *
 | 
			
		||||
 * Returns all the documents currently open in #XeditApp.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: (element-type Xedit.Document) (transfer container):
 | 
			
		||||
 * a newly allocated list of #XeditDocument objects
 | 
			
		||||
 */
 | 
			
		||||
GList *
 | 
			
		||||
xedit_app_get_documents	(XeditApp *app)
 | 
			
		||||
{
 | 
			
		||||
	GList *res = NULL;
 | 
			
		||||
	GList *windows;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_APP (app), NULL);
 | 
			
		||||
 | 
			
		||||
	windows = app->priv->windows;
 | 
			
		||||
 | 
			
		||||
	while (windows != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		res = g_list_concat (res,
 | 
			
		||||
				     xedit_window_get_documents (XEDIT_WINDOW (windows->data)));
 | 
			
		||||
 | 
			
		||||
		windows = g_list_next (windows);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_app_get_views:
 | 
			
		||||
 * @app: the #XeditApp
 | 
			
		||||
 *
 | 
			
		||||
 * Returns all the views currently present in #XeditApp.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: (element-type Xedit.View) (transfer container):
 | 
			
		||||
 * a newly allocated list of #XeditView objects
 | 
			
		||||
 */
 | 
			
		||||
GList *
 | 
			
		||||
xedit_app_get_views (XeditApp *app)
 | 
			
		||||
{
 | 
			
		||||
	GList *res = NULL;
 | 
			
		||||
	GList *windows;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_APP (app), NULL);
 | 
			
		||||
 | 
			
		||||
	windows = app->priv->windows;
 | 
			
		||||
 | 
			
		||||
	while (windows != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		res = g_list_concat (res,
 | 
			
		||||
				     xedit_window_get_views (XEDIT_WINDOW (windows->data)));
 | 
			
		||||
 | 
			
		||||
		windows = g_list_next (windows);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_app_get_lockdown:
 | 
			
		||||
 * @app: a #XeditApp
 | 
			
		||||
 *
 | 
			
		||||
 * Gets the lockdown mask (see #XeditLockdownMask) for the application.
 | 
			
		||||
 * The lockdown mask determines which functions are locked down using
 | 
			
		||||
 * the MATE-wise lockdown GSettings keys.
 | 
			
		||||
 **/
 | 
			
		||||
XeditLockdownMask
 | 
			
		||||
xedit_app_get_lockdown (XeditApp *app)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_APP (app), XEDIT_LOCKDOWN_ALL);
 | 
			
		||||
 | 
			
		||||
	return app->priv->lockdown;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
app_lockdown_changed (XeditApp *app)
 | 
			
		||||
{
 | 
			
		||||
	GList *l;
 | 
			
		||||
 | 
			
		||||
	for (l = app->priv->windows; l != NULL; l = l->next)
 | 
			
		||||
		_xedit_window_set_lockdown (XEDIT_WINDOW (l->data),
 | 
			
		||||
					    app->priv->lockdown);
 | 
			
		||||
 | 
			
		||||
	g_object_notify (G_OBJECT (app), "lockdown");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_app_set_lockdown (XeditApp          *app,
 | 
			
		||||
			 XeditLockdownMask  lockdown)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_APP (app));
 | 
			
		||||
 | 
			
		||||
	app->priv->lockdown = lockdown;
 | 
			
		||||
 | 
			
		||||
	app_lockdown_changed (app);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_app_set_lockdown_bit (XeditApp          *app,
 | 
			
		||||
			     XeditLockdownMask  bit,
 | 
			
		||||
			     gboolean           value)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_APP (app));
 | 
			
		||||
 | 
			
		||||
	if (value)
 | 
			
		||||
		app->priv->lockdown |= bit;
 | 
			
		||||
	else
 | 
			
		||||
		app->priv->lockdown &= ~bit;
 | 
			
		||||
 | 
			
		||||
	app_lockdown_changed (app);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Returns a copy */
 | 
			
		||||
GtkPageSetup *
 | 
			
		||||
_xedit_app_get_default_page_setup (XeditApp *app)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_APP (app), NULL);
 | 
			
		||||
 | 
			
		||||
	if (app->priv->page_setup == NULL)
 | 
			
		||||
		load_page_setup (app);
 | 
			
		||||
 | 
			
		||||
	return gtk_page_setup_copy (app->priv->page_setup);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_app_set_default_page_setup (XeditApp     *app,
 | 
			
		||||
				   GtkPageSetup *page_setup)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_APP (app));
 | 
			
		||||
	g_return_if_fail (GTK_IS_PAGE_SETUP (page_setup));
 | 
			
		||||
 | 
			
		||||
	if (app->priv->page_setup != NULL)
 | 
			
		||||
		g_object_unref (app->priv->page_setup);
 | 
			
		||||
 | 
			
		||||
	app->priv->page_setup = g_object_ref (page_setup);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Returns a copy */
 | 
			
		||||
GtkPrintSettings *
 | 
			
		||||
_xedit_app_get_default_print_settings (XeditApp *app)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_APP (app), NULL);
 | 
			
		||||
 | 
			
		||||
	if (app->priv->print_settings == NULL)
 | 
			
		||||
		load_print_settings (app);
 | 
			
		||||
 | 
			
		||||
	return gtk_print_settings_copy (app->priv->print_settings);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_app_set_default_print_settings (XeditApp         *app,
 | 
			
		||||
				       GtkPrintSettings *settings)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_APP (app));
 | 
			
		||||
	g_return_if_fail (GTK_IS_PRINT_SETTINGS (settings));
 | 
			
		||||
 | 
			
		||||
	if (app->priv->print_settings != NULL)
 | 
			
		||||
		g_object_unref (app->priv->print_settings);
 | 
			
		||||
 | 
			
		||||
	app->priv->print_settings = g_object_ref (settings);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										142
									
								
								xedit/xedit-app.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								xedit/xedit-app.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,142 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-app.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2005 - Paolo Maggi 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_APP_H__
 | 
			
		||||
#define __XEDIT_APP_H__
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
#include <xedit/xedit-window.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Type checking and casting macros
 | 
			
		||||
 */
 | 
			
		||||
#define XEDIT_TYPE_APP              (xedit_app_get_type())
 | 
			
		||||
#define XEDIT_APP(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), XEDIT_TYPE_APP, XeditApp))
 | 
			
		||||
#define XEDIT_APP_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), XEDIT_TYPE_APP, XeditAppClass))
 | 
			
		||||
#define XEDIT_IS_APP(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), XEDIT_TYPE_APP))
 | 
			
		||||
#define XEDIT_IS_APP_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), XEDIT_TYPE_APP))
 | 
			
		||||
#define XEDIT_APP_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), XEDIT_TYPE_APP, XeditAppClass))
 | 
			
		||||
 | 
			
		||||
/* Private structure type */
 | 
			
		||||
typedef struct _XeditAppPrivate XeditAppPrivate;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Main object structure
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _XeditApp XeditApp;
 | 
			
		||||
 | 
			
		||||
struct _XeditApp 
 | 
			
		||||
{
 | 
			
		||||
	GObject object;
 | 
			
		||||
 | 
			
		||||
	/*< private > */
 | 
			
		||||
	XeditAppPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Class definition
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _XeditAppClass XeditAppClass;
 | 
			
		||||
 | 
			
		||||
struct _XeditAppClass 
 | 
			
		||||
{
 | 
			
		||||
	GObjectClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Lockdown mask definition
 | 
			
		||||
 */
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
	XEDIT_LOCKDOWN_COMMAND_LINE	= 1 << 0,
 | 
			
		||||
	XEDIT_LOCKDOWN_PRINTING		= 1 << 1,
 | 
			
		||||
	XEDIT_LOCKDOWN_PRINT_SETUP	= 1 << 2,
 | 
			
		||||
	XEDIT_LOCKDOWN_SAVE_TO_DISK	= 1 << 3,
 | 
			
		||||
	XEDIT_LOCKDOWN_ALL		= 0xF
 | 
			
		||||
} XeditLockdownMask;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Public methods
 | 
			
		||||
 */
 | 
			
		||||
GType 		 xedit_app_get_type 			(void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
XeditApp 	*xedit_app_get_default			(void);
 | 
			
		||||
 | 
			
		||||
XeditWindow	*xedit_app_create_window		(XeditApp  *app,
 | 
			
		||||
							 GdkScreen *screen);
 | 
			
		||||
 | 
			
		||||
const GList	*xedit_app_get_windows			(XeditApp *app);
 | 
			
		||||
XeditWindow	*xedit_app_get_active_window		(XeditApp *app);
 | 
			
		||||
 | 
			
		||||
/* Returns a newly allocated list with all the documents */
 | 
			
		||||
GList		*xedit_app_get_documents		(XeditApp *app);
 | 
			
		||||
 | 
			
		||||
/* Returns a newly allocated list with all the views */
 | 
			
		||||
GList		*xedit_app_get_views			(XeditApp *app);
 | 
			
		||||
 | 
			
		||||
/* Lockdown state */
 | 
			
		||||
XeditLockdownMask xedit_app_get_lockdown		(XeditApp *app);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Non exported functions
 | 
			
		||||
 */
 | 
			
		||||
XeditWindow	*_xedit_app_restore_window		(XeditApp    *app,
 | 
			
		||||
							 const gchar *role);
 | 
			
		||||
XeditWindow	*_xedit_app_get_window_in_viewport	(XeditApp     *app,
 | 
			
		||||
							 GdkScreen    *screen,
 | 
			
		||||
							 gint          workspace,
 | 
			
		||||
							 gint          viewport_x,
 | 
			
		||||
							 gint          viewport_y);
 | 
			
		||||
void		 _xedit_app_set_lockdown		(XeditApp          *app,
 | 
			
		||||
							 XeditLockdownMask  lockdown);
 | 
			
		||||
void		 _xedit_app_set_lockdown_bit		(XeditApp          *app,
 | 
			
		||||
							 XeditLockdownMask  bit,
 | 
			
		||||
							 gboolean           value);
 | 
			
		||||
/*
 | 
			
		||||
 * This one is a xedit-window function, but we declare it here to avoid
 | 
			
		||||
 * #include headaches since it needs the XeditLockdownMask declaration.
 | 
			
		||||
 */
 | 
			
		||||
void		 _xedit_window_set_lockdown		(XeditWindow         *window,
 | 
			
		||||
							 XeditLockdownMask    lockdown);
 | 
			
		||||
 | 
			
		||||
/* global print config */
 | 
			
		||||
GtkPageSetup		*_xedit_app_get_default_page_setup	(XeditApp         *app);
 | 
			
		||||
void			 _xedit_app_set_default_page_setup	(XeditApp         *app,
 | 
			
		||||
								 GtkPageSetup     *page_setup);
 | 
			
		||||
GtkPrintSettings	*_xedit_app_get_default_print_settings	(XeditApp         *app);
 | 
			
		||||
void			 _xedit_app_set_default_print_settings	(XeditApp         *app,
 | 
			
		||||
								 GtkPrintSettings *settings);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif  /* __XEDIT_APP_H__  */
 | 
			
		||||
							
								
								
									
										84
									
								
								xedit/xedit-close-button.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								xedit/xedit-close-button.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,84 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-close-button.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2010 - Paolo Borelli
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "xedit-close-button.h"
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (XeditCloseButton, xedit_close_button, GTK_TYPE_BUTTON)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_close_button_style_set (GtkWidget *button,
 | 
			
		||||
			      GtkStyle *previous_style)
 | 
			
		||||
{
 | 
			
		||||
	gint h, w;
 | 
			
		||||
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 10, 0)
 | 
			
		||||
	gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
 | 
			
		||||
#else
 | 
			
		||||
	gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (button),
 | 
			
		||||
					   GTK_ICON_SIZE_MENU, &w, &h);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	gtk_widget_set_size_request (button, w + 2, h + 2);
 | 
			
		||||
 | 
			
		||||
	GTK_WIDGET_CLASS (xedit_close_button_parent_class)->style_set (button, previous_style);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_close_button_class_init (XeditCloseButtonClass *klass)
 | 
			
		||||
{
 | 
			
		||||
	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
	widget_class->style_set = xedit_close_button_style_set;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_close_button_init (XeditCloseButton *button)
 | 
			
		||||
{
 | 
			
		||||
	GtkRcStyle *rcstyle;
 | 
			
		||||
	GtkWidget *image;
 | 
			
		||||
 | 
			
		||||
	/* make it as small as possible */
 | 
			
		||||
	rcstyle = gtk_rc_style_new ();
 | 
			
		||||
	rcstyle->xthickness = rcstyle->ythickness = 0;
 | 
			
		||||
	gtk_widget_modify_style (GTK_WIDGET (button), rcstyle);
 | 
			
		||||
	g_object_unref (rcstyle);
 | 
			
		||||
 | 
			
		||||
	image = gtk_image_new_from_stock (GTK_STOCK_CLOSE,
 | 
			
		||||
					  GTK_ICON_SIZE_MENU);
 | 
			
		||||
	gtk_widget_show (image);
 | 
			
		||||
 | 
			
		||||
	gtk_container_add (GTK_CONTAINER (button), image);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GtkWidget *
 | 
			
		||||
xedit_close_button_new ()
 | 
			
		||||
{
 | 
			
		||||
	XeditCloseButton *button;
 | 
			
		||||
 | 
			
		||||
	button = g_object_new (XEDIT_TYPE_CLOSE_BUTTON,
 | 
			
		||||
			       "relief", GTK_RELIEF_NONE,
 | 
			
		||||
			       "focus-on-click", FALSE,
 | 
			
		||||
			       NULL);
 | 
			
		||||
 | 
			
		||||
	return GTK_WIDGET (button);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										56
									
								
								xedit/xedit-close-button.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								xedit/xedit-close-button.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-close-button.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2010 - Paolo Borelli
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_CLOSE_BUTTON_H__
 | 
			
		||||
#define __XEDIT_CLOSE_BUTTON_H__
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define XEDIT_TYPE_CLOSE_BUTTON			(xedit_close_button_get_type ())
 | 
			
		||||
#define XEDIT_CLOSE_BUTTON(obj)			(G_TYPE_CHECK_INSTANCE_CAST ((obj), XEDIT_TYPE_CLOSE_BUTTON, XeditCloseButton))
 | 
			
		||||
#define XEDIT_CLOSE_BUTTON_CONST(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), XEDIT_TYPE_CLOSE_BUTTON, XeditCloseButton const))
 | 
			
		||||
#define XEDIT_CLOSE_BUTTON_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST ((klass), XEDIT_TYPE_CLOSE_BUTTON, XeditCloseButtonClass))
 | 
			
		||||
#define XEDIT_IS_CLOSE_BUTTON(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), XEDIT_TYPE_CLOSE_BUTTON))
 | 
			
		||||
#define XEDIT_IS_CLOSE_BUTTON_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), XEDIT_TYPE_CLOSE_BUTTON))
 | 
			
		||||
#define XEDIT_CLOSE_BUTTON_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), XEDIT_TYPE_CLOSE_BUTTON, XeditCloseButtonClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _XeditCloseButton	XeditCloseButton;
 | 
			
		||||
typedef struct _XeditCloseButtonClass	XeditCloseButtonClass;
 | 
			
		||||
typedef struct _XeditCloseButtonPrivate	XeditCloseButtonPrivate;
 | 
			
		||||
 | 
			
		||||
struct _XeditCloseButton {
 | 
			
		||||
	GtkButton parent;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _XeditCloseButtonClass {
 | 
			
		||||
	GtkButtonClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType		  xedit_close_button_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
GtkWidget	 *xedit_close_button_new (void);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __XEDIT_CLOSE_BUTTON_H__ */
 | 
			
		||||
							
								
								
									
										87
									
								
								xedit/xedit-commands-documents.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								xedit/xedit-commands-documents.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-documents-commands.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
 | 
			
		||||
 * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi
 | 
			
		||||
 * Copyright (C) 2002-2005 Paolo Maggi
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor,
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 1998-2005. See the AUTHORS file for a
 | 
			
		||||
 * list of people on the xedit Team.
 | 
			
		||||
 * See the ChangeLog files for a list of changes.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
#include "xedit-commands.h"
 | 
			
		||||
#include "xedit-window.h"
 | 
			
		||||
#include "xedit-notebook.h"
 | 
			
		||||
#include "xedit-debug.h"
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_cmd_documents_previous_document (GtkAction   *action,
 | 
			
		||||
				       XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	GtkNotebook *notebook;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	notebook = GTK_NOTEBOOK (_xedit_window_get_notebook (window));
 | 
			
		||||
	gtk_notebook_prev_page (notebook);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_cmd_documents_next_document (GtkAction   *action,
 | 
			
		||||
				   XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	GtkNotebook *notebook;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	notebook = GTK_NOTEBOOK (_xedit_window_get_notebook (window));
 | 
			
		||||
	gtk_notebook_next_page (notebook);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_cmd_documents_move_to_new_window (GtkAction   *action,
 | 
			
		||||
					XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	XeditNotebook *old_notebook;
 | 
			
		||||
	XeditTab *tab;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	tab = xedit_window_get_active_tab (window);
 | 
			
		||||
 | 
			
		||||
	if (tab == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	old_notebook = XEDIT_NOTEBOOK (_xedit_window_get_notebook (window));
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (gtk_notebook_get_n_pages (GTK_NOTEBOOK (old_notebook)) > 1);
 | 
			
		||||
 | 
			
		||||
	_xedit_window_move_tab_to_new_window (window, tab);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										174
									
								
								xedit/xedit-commands-edit.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										174
									
								
								xedit/xedit-commands-edit.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,174 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-commands-edit.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
 | 
			
		||||
 * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi
 | 
			
		||||
 * Copyright (C) 2002-2005 Paolo Maggi
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor,
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 1998-2005. See the AUTHORS file for a
 | 
			
		||||
 * list of people on the xedit Team.
 | 
			
		||||
 * See the ChangeLog files for a list of changes.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
#include "xedit-commands.h"
 | 
			
		||||
#include "xedit-window.h"
 | 
			
		||||
#include "xedit-debug.h"
 | 
			
		||||
#include "xedit-view.h"
 | 
			
		||||
#include "dialogs/xedit-preferences-dialog.h"
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_cmd_edit_undo (GtkAction   *action,
 | 
			
		||||
		     XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	XeditView *active_view;
 | 
			
		||||
	GtkSourceBuffer *active_document;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	active_view = xedit_window_get_active_view (window);
 | 
			
		||||
	g_return_if_fail (active_view);
 | 
			
		||||
 | 
			
		||||
	active_document = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (active_view)));
 | 
			
		||||
 | 
			
		||||
	gtk_source_buffer_undo (active_document);
 | 
			
		||||
 | 
			
		||||
	xedit_view_scroll_to_cursor (active_view);
 | 
			
		||||
 | 
			
		||||
	gtk_widget_grab_focus (GTK_WIDGET (active_view));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_cmd_edit_redo (GtkAction   *action,
 | 
			
		||||
		     XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	XeditView *active_view;
 | 
			
		||||
	GtkSourceBuffer *active_document;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	active_view = xedit_window_get_active_view (window);
 | 
			
		||||
	g_return_if_fail (active_view);
 | 
			
		||||
 | 
			
		||||
	active_document = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (active_view)));
 | 
			
		||||
 | 
			
		||||
	gtk_source_buffer_redo (active_document);
 | 
			
		||||
 | 
			
		||||
	xedit_view_scroll_to_cursor (active_view);
 | 
			
		||||
 | 
			
		||||
	gtk_widget_grab_focus (GTK_WIDGET (active_view));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_cmd_edit_cut (GtkAction   *action,
 | 
			
		||||
		    XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	XeditView *active_view;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	active_view = xedit_window_get_active_view (window);
 | 
			
		||||
	g_return_if_fail (active_view);
 | 
			
		||||
 | 
			
		||||
	xedit_view_cut_clipboard (active_view);
 | 
			
		||||
 | 
			
		||||
	gtk_widget_grab_focus (GTK_WIDGET (active_view));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_cmd_edit_copy (GtkAction   *action,
 | 
			
		||||
		     XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	XeditView *active_view;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	active_view = xedit_window_get_active_view (window);
 | 
			
		||||
	g_return_if_fail (active_view);
 | 
			
		||||
 | 
			
		||||
	xedit_view_copy_clipboard (active_view);
 | 
			
		||||
 | 
			
		||||
	gtk_widget_grab_focus (GTK_WIDGET (active_view));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_cmd_edit_paste (GtkAction   *action,
 | 
			
		||||
		      XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	XeditView *active_view;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	active_view = xedit_window_get_active_view (window);
 | 
			
		||||
	g_return_if_fail (active_view);
 | 
			
		||||
 | 
			
		||||
	xedit_view_paste_clipboard (active_view);
 | 
			
		||||
 | 
			
		||||
	gtk_widget_grab_focus (GTK_WIDGET (active_view));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_cmd_edit_delete (GtkAction   *action,
 | 
			
		||||
		       XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	XeditView *active_view;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	active_view = xedit_window_get_active_view (window);
 | 
			
		||||
	g_return_if_fail (active_view);
 | 
			
		||||
 | 
			
		||||
	xedit_view_delete_selection (active_view);
 | 
			
		||||
 | 
			
		||||
	gtk_widget_grab_focus (GTK_WIDGET (active_view));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_cmd_edit_select_all (GtkAction   *action,
 | 
			
		||||
			   XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	XeditView *active_view;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	active_view = xedit_window_get_active_view (window);
 | 
			
		||||
	g_return_if_fail (active_view);
 | 
			
		||||
 | 
			
		||||
	xedit_view_select_all (active_view);
 | 
			
		||||
 | 
			
		||||
	gtk_widget_grab_focus (GTK_WIDGET (active_view));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_cmd_edit_preferences (GtkAction   *action,
 | 
			
		||||
			    XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	xedit_show_preferences_dialog (window);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										74
									
								
								xedit/xedit-commands-file-print.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								xedit/xedit-commands-file-print.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,74 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-commands-file-print.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
 | 
			
		||||
 * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi
 | 
			
		||||
 * Copyright (C) 2002-2005 Paolo Maggi
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor,
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 1998-2005. See the AUTHORS file for a
 | 
			
		||||
 * list of people on the xedit Team.
 | 
			
		||||
 * See the ChangeLog files for a list of changes.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
#include "xedit-commands.h"
 | 
			
		||||
#include "xedit-window.h"
 | 
			
		||||
#include "xedit-tab.h"
 | 
			
		||||
#include "xedit-debug.h"
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_cmd_file_print_preview (GtkAction   *action,
 | 
			
		||||
			       XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	XeditTab *tab;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	tab = xedit_window_get_active_tab (window);
 | 
			
		||||
	if (tab == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	_xedit_tab_print_preview (tab);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_cmd_file_print (GtkAction   *action,
 | 
			
		||||
		       XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	XeditTab *tab;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	tab = xedit_window_get_active_tab (window);
 | 
			
		||||
	if (tab == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	_xedit_tab_print (tab);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1847
									
								
								xedit/xedit-commands-file.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1847
									
								
								xedit/xedit-commands-file.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										98
									
								
								xedit/xedit-commands-help.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								xedit/xedit-commands-help.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,98 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-help-commands.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
 | 
			
		||||
 * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi
 | 
			
		||||
 * Copyright (C) 2002-2005 Paolo Maggi
 | 
			
		||||
 * Copyright (C) 2011 Perberos
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor,
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the gedit Team, 1998-2005. See the AUTHORS file for a
 | 
			
		||||
 * list of people on the xedit Team.
 | 
			
		||||
 * See the ChangeLog files for a list of changes.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
	#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
#include "xedit-commands.h"
 | 
			
		||||
#include "xedit-debug.h"
 | 
			
		||||
#include "xedit-help.h"
 | 
			
		||||
#include "xedit-dirs.h"
 | 
			
		||||
 | 
			
		||||
void _xedit_cmd_help_contents(GtkAction* action, XeditWindow* window)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug(DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	xedit_help_display(GTK_WINDOW(window), NULL, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void _xedit_cmd_help_about(GtkAction* action, XeditWindow* window)
 | 
			
		||||
{
 | 
			
		||||
	static const gchar* const authors[] = {
 | 
			
		||||
		"Paolo Maggi <paolo@gnome.org>",
 | 
			
		||||
		"Paolo Borelli <pborelli@katamail.com>",
 | 
			
		||||
		"Steve Fr\303\251cinaux  <steve@istique.net>",
 | 
			
		||||
		"Jesse van den Kieboom  <jessevdk@gnome.org>",
 | 
			
		||||
		"Ignacio Casal Quinteiro <icq@gnome.org>",
 | 
			
		||||
		"James Willcox <jwillcox@gnome.org>",
 | 
			
		||||
		"Chema Celorio",
 | 
			
		||||
		"Federico Mena Quintero <federico@novell.com>",
 | 
			
		||||
		"Perberos <perberos@gmail.com>",
 | 
			
		||||
		NULL
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	static const gchar* const documenters[] = {
 | 
			
		||||
		"Sun GNOME Documentation Team <gdocteam@sun.com>",
 | 
			
		||||
		"Eric Baudais <baudais@okstate.edu>",
 | 
			
		||||
		NULL
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	static const gchar copyright[] = \
 | 
			
		||||
		"Copyright \xc2\xa9 1998-2000 Evan Lawrence, Alex Robert\n"
 | 
			
		||||
		"Copyright \xc2\xa9 2000-2002 Chema Celorio, Paolo Maggi\n"
 | 
			
		||||
		"Copyright \xc2\xa9 2003-2006 Paolo Maggi\n"
 | 
			
		||||
		"Copyright \xc2\xa9 2004-2010 Paolo Borelli, Jesse van den Kieboom\nSteve Fr\303\251cinaux, Ignacio Casal Quinteiro\n"
 | 
			
		||||
		"Copyright \xc2\xa9 2011 Perberos\n"
 | 
			
		||||
		"Copyright \xc2\xa9 2012-2014 MATE developers";
 | 
			
		||||
 | 
			
		||||
	static const gchar comments[] = \
 | 
			
		||||
		N_("Xedit is a small and lightweight text editor for the MATE Desktop");
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	gtk_show_about_dialog(GTK_WINDOW(window),
 | 
			
		||||
		"program-name", "Xedit",
 | 
			
		||||
		"authors", authors,
 | 
			
		||||
		"comments", _(comments),
 | 
			
		||||
		"copyright", copyright,
 | 
			
		||||
		"documenters", documenters,
 | 
			
		||||
		"logo_icon_name", "accessories-text-editor",
 | 
			
		||||
		"translator-credits", _("translator-credits"),
 | 
			
		||||
		"version", VERSION,
 | 
			
		||||
		"website", "http://mate-desktop.org",
 | 
			
		||||
		NULL);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										793
									
								
								xedit/xedit-commands-search.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										793
									
								
								xedit/xedit-commands-search.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,793 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-search-commands.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
 | 
			
		||||
 * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi
 | 
			
		||||
 * Copyright (C) 2002-2006 Paolo Maggi
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor,
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 1998-2006. See the AUTHORS file for a
 | 
			
		||||
 * list of people on the xedit Team.
 | 
			
		||||
 * See the ChangeLog files for a list of changes.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
#include <gdk/gdkkeysyms.h>
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
#define GTK_OBJECT G_OBJECT
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "xedit-commands.h"
 | 
			
		||||
#include "xedit-debug.h"
 | 
			
		||||
#include "xedit-statusbar.h"
 | 
			
		||||
#include "xedit-window.h"
 | 
			
		||||
#include "xedit-window-private.h"
 | 
			
		||||
#include "xedit-utils.h"
 | 
			
		||||
#include "dialogs/xedit-search-dialog.h"
 | 
			
		||||
 | 
			
		||||
#define XEDIT_SEARCH_DIALOG_KEY		"xedit-search-dialog-key"
 | 
			
		||||
#define XEDIT_LAST_SEARCH_DATA_KEY	"xedit-last-search-data-key"
 | 
			
		||||
 | 
			
		||||
typedef struct _LastSearchData LastSearchData;
 | 
			
		||||
struct _LastSearchData
 | 
			
		||||
{
 | 
			
		||||
	gint x;
 | 
			
		||||
	gint y;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
last_search_data_free (LastSearchData *data)
 | 
			
		||||
{
 | 
			
		||||
	g_slice_free (LastSearchData, data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
last_search_data_restore_position (XeditSearchDialog *dlg)
 | 
			
		||||
{
 | 
			
		||||
	LastSearchData *data;
 | 
			
		||||
 | 
			
		||||
	data = g_object_get_data (G_OBJECT (dlg), XEDIT_LAST_SEARCH_DATA_KEY);
 | 
			
		||||
 | 
			
		||||
	if (data != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		gtk_window_move (GTK_WINDOW (dlg),
 | 
			
		||||
				 data->x,
 | 
			
		||||
				 data->y);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
last_search_data_store_position (XeditSearchDialog *dlg)
 | 
			
		||||
{
 | 
			
		||||
	LastSearchData *data;
 | 
			
		||||
	
 | 
			
		||||
	data = g_object_get_data (G_OBJECT (dlg), XEDIT_LAST_SEARCH_DATA_KEY);
 | 
			
		||||
	
 | 
			
		||||
	if (data == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		data = g_slice_new (LastSearchData);
 | 
			
		||||
		
 | 
			
		||||
		g_object_set_data_full (G_OBJECT (dlg),
 | 
			
		||||
					XEDIT_LAST_SEARCH_DATA_KEY,
 | 
			
		||||
					data,
 | 
			
		||||
					(GDestroyNotify) last_search_data_free);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	gtk_window_get_position (GTK_WINDOW (dlg),
 | 
			
		||||
				 &data->x,
 | 
			
		||||
				 &data->y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Use occurrences only for Replace All */
 | 
			
		||||
static void
 | 
			
		||||
text_found (XeditWindow *window,
 | 
			
		||||
	    gint         occurrences)
 | 
			
		||||
{
 | 
			
		||||
	if (occurrences > 1)
 | 
			
		||||
	{
 | 
			
		||||
		xedit_statusbar_flash_message (XEDIT_STATUSBAR (window->priv->statusbar),
 | 
			
		||||
					       window->priv->generic_message_cid,
 | 
			
		||||
					       ngettext("Found and replaced %d occurrence",
 | 
			
		||||
					     	        "Found and replaced %d occurrences",
 | 
			
		||||
					     	        occurrences),
 | 
			
		||||
					       occurrences);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		if (occurrences == 1)
 | 
			
		||||
			xedit_statusbar_flash_message (XEDIT_STATUSBAR (window->priv->statusbar),
 | 
			
		||||
						       window->priv->generic_message_cid,
 | 
			
		||||
						       _("Found and replaced one occurrence"));
 | 
			
		||||
		else
 | 
			
		||||
			xedit_statusbar_flash_message (XEDIT_STATUSBAR (window->priv->statusbar),
 | 
			
		||||
						       window->priv->generic_message_cid,
 | 
			
		||||
						       " ");
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define MAX_MSG_LENGTH 40
 | 
			
		||||
static void
 | 
			
		||||
text_not_found (XeditWindow *window,
 | 
			
		||||
		const gchar *text)
 | 
			
		||||
{
 | 
			
		||||
	gchar *searched;
 | 
			
		||||
	
 | 
			
		||||
	searched = xedit_utils_str_end_truncate (text, MAX_MSG_LENGTH);
 | 
			
		||||
 | 
			
		||||
	xedit_statusbar_flash_message (XEDIT_STATUSBAR (window->priv->statusbar),
 | 
			
		||||
				       window->priv->generic_message_cid,
 | 
			
		||||
				       /* Translators: %s is replaced by the text
 | 
			
		||||
				          entered by the user in the search box */
 | 
			
		||||
				       _("\"%s\" not found"), searched);
 | 
			
		||||
	g_free (searched);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
run_search (XeditView   *view,
 | 
			
		||||
	    gboolean     wrap_around,
 | 
			
		||||
	    gboolean     search_backwards)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocument *doc;
 | 
			
		||||
	GtkTextIter start_iter;
 | 
			
		||||
	GtkTextIter match_start;
 | 
			
		||||
	GtkTextIter match_end;
 | 
			
		||||
	gboolean found = FALSE;
 | 
			
		||||
 | 
			
		||||
	doc = XEDIT_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
 | 
			
		||||
 | 
			
		||||
	if (!search_backwards)
 | 
			
		||||
	{
 | 
			
		||||
		gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (doc),
 | 
			
		||||
						      NULL,
 | 
			
		||||
						      &start_iter);
 | 
			
		||||
 | 
			
		||||
		found = xedit_document_search_forward (doc,
 | 
			
		||||
						       &start_iter,
 | 
			
		||||
						       NULL,
 | 
			
		||||
						       &match_start,
 | 
			
		||||
						       &match_end);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (doc),
 | 
			
		||||
						      &start_iter,
 | 
			
		||||
						      NULL);
 | 
			
		||||
 | 
			
		||||
		found = xedit_document_search_backward (doc,
 | 
			
		||||
						        NULL,
 | 
			
		||||
						        &start_iter,
 | 
			
		||||
						        &match_start,
 | 
			
		||||
						        &match_end);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!found && wrap_around)
 | 
			
		||||
	{
 | 
			
		||||
		if (!search_backwards)
 | 
			
		||||
			found = xedit_document_search_forward (doc,
 | 
			
		||||
							       NULL,
 | 
			
		||||
							       NULL, /* FIXME: set the end_inter */
 | 
			
		||||
							       &match_start,
 | 
			
		||||
							       &match_end);
 | 
			
		||||
		else
 | 
			
		||||
			found = xedit_document_search_backward (doc,
 | 
			
		||||
							        NULL, /* FIXME: set the start_inter */
 | 
			
		||||
							        NULL, 
 | 
			
		||||
							        &match_start,
 | 
			
		||||
							        &match_end);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if (found)
 | 
			
		||||
	{
 | 
			
		||||
		gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (doc),
 | 
			
		||||
					      &match_start);
 | 
			
		||||
 | 
			
		||||
		gtk_text_buffer_move_mark_by_name (GTK_TEXT_BUFFER (doc),
 | 
			
		||||
						   "selection_bound",
 | 
			
		||||
						   &match_end);
 | 
			
		||||
 | 
			
		||||
		xedit_view_scroll_to_cursor (view);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (doc),
 | 
			
		||||
					      &start_iter);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return found;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
do_find (XeditSearchDialog *dialog,
 | 
			
		||||
	 XeditWindow       *window)
 | 
			
		||||
{
 | 
			
		||||
	XeditView *active_view;
 | 
			
		||||
	XeditDocument *doc;
 | 
			
		||||
	gchar *search_text;
 | 
			
		||||
	const gchar *entry_text;
 | 
			
		||||
	gboolean match_case;
 | 
			
		||||
	gboolean entire_word;
 | 
			
		||||
	gboolean wrap_around;
 | 
			
		||||
	gboolean search_backwards;
 | 
			
		||||
	gboolean parse_escapes;
 | 
			
		||||
	guint flags = 0;
 | 
			
		||||
	guint old_flags = 0;
 | 
			
		||||
	gboolean found;
 | 
			
		||||
 | 
			
		||||
	/* TODO: make the dialog insensitive when all the tabs are closed
 | 
			
		||||
	 * and assert here that the view is not NULL */
 | 
			
		||||
	active_view = xedit_window_get_active_view (window);
 | 
			
		||||
	if (active_view == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	doc = XEDIT_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (active_view)));
 | 
			
		||||
 | 
			
		||||
	match_case = xedit_search_dialog_get_match_case (dialog);
 | 
			
		||||
	entire_word = xedit_search_dialog_get_entire_word (dialog);
 | 
			
		||||
	search_backwards = xedit_search_dialog_get_backwards (dialog);
 | 
			
		||||
	wrap_around = xedit_search_dialog_get_wrap_around (dialog);
 | 
			
		||||
	parse_escapes = xedit_search_dialog_get_parse_escapes (dialog);
 | 
			
		||||
 | 
			
		||||
	if (!parse_escapes) {
 | 
			
		||||
		entry_text = xedit_utils_escape_search_text (xedit_search_dialog_get_search_text (dialog));
 | 
			
		||||
	} else {
 | 
			
		||||
		entry_text = xedit_search_dialog_get_search_text (dialog);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	XEDIT_SEARCH_SET_CASE_SENSITIVE (flags, match_case);
 | 
			
		||||
	XEDIT_SEARCH_SET_ENTIRE_WORD (flags, entire_word);
 | 
			
		||||
 | 
			
		||||
	search_text = xedit_document_get_search_text (doc, &old_flags);
 | 
			
		||||
 | 
			
		||||
	if ((search_text == NULL) ||
 | 
			
		||||
	    (strcmp (search_text, entry_text) != 0) ||
 | 
			
		||||
	    (flags != old_flags))
 | 
			
		||||
	{
 | 
			
		||||
		xedit_document_set_search_text (doc, entry_text, flags);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_free (search_text);
 | 
			
		||||
	
 | 
			
		||||
	found = run_search (active_view,
 | 
			
		||||
			    wrap_around,
 | 
			
		||||
			    search_backwards);
 | 
			
		||||
 | 
			
		||||
	if (found)
 | 
			
		||||
		text_found (window, 0);
 | 
			
		||||
	else {
 | 
			
		||||
		if (!parse_escapes) {
 | 
			
		||||
			text_not_found (window, xedit_utils_unescape_search_text (entry_text));
 | 
			
		||||
		} else {
 | 
			
		||||
			text_not_found (window, entry_text);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
 | 
			
		||||
					   XEDIT_SEARCH_DIALOG_REPLACE_RESPONSE,
 | 
			
		||||
					   found);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* FIXME: move in xedit-document.c and share it with xedit-view */
 | 
			
		||||
static gboolean
 | 
			
		||||
get_selected_text (GtkTextBuffer  *doc,
 | 
			
		||||
		   gchar         **selected_text,
 | 
			
		||||
		   gint           *len)
 | 
			
		||||
{
 | 
			
		||||
	GtkTextIter start, end;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (selected_text != NULL, FALSE);
 | 
			
		||||
	g_return_val_if_fail (*selected_text == NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
	if (!gtk_text_buffer_get_selection_bounds (doc, &start, &end))
 | 
			
		||||
	{
 | 
			
		||||
		if (len != NULL)
 | 
			
		||||
			len = 0;
 | 
			
		||||
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*selected_text = gtk_text_buffer_get_slice (doc, &start, &end, TRUE);
 | 
			
		||||
 | 
			
		||||
	if (len != NULL)
 | 
			
		||||
		*len = g_utf8_strlen (*selected_text, -1);
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
replace_selected_text (GtkTextBuffer *buffer,
 | 
			
		||||
		       const gchar   *replace)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (gtk_text_buffer_get_selection_bounds (buffer, NULL, NULL));
 | 
			
		||||
	g_return_if_fail (replace != NULL);
 | 
			
		||||
 | 
			
		||||
	gtk_text_buffer_begin_user_action (buffer);
 | 
			
		||||
 | 
			
		||||
	gtk_text_buffer_delete_selection (buffer, FALSE, TRUE);
 | 
			
		||||
 | 
			
		||||
	gtk_text_buffer_insert_at_cursor (buffer, replace, strlen (replace));
 | 
			
		||||
 | 
			
		||||
	gtk_text_buffer_end_user_action (buffer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
do_replace (XeditSearchDialog *dialog,
 | 
			
		||||
	    XeditWindow       *window)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocument *doc;
 | 
			
		||||
	const gchar *search_entry_text;
 | 
			
		||||
	const gchar *replace_entry_text;
 | 
			
		||||
	gchar *unescaped_search_text;
 | 
			
		||||
	gchar *unescaped_replace_text;
 | 
			
		||||
	gchar *selected_text = NULL;
 | 
			
		||||
	gboolean match_case;
 | 
			
		||||
	gboolean parse_escapes;
 | 
			
		||||
 | 
			
		||||
	doc = xedit_window_get_active_document (window);
 | 
			
		||||
	if (doc == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	parse_escapes = xedit_search_dialog_get_parse_escapes (dialog);
 | 
			
		||||
	if (!parse_escapes) {
 | 
			
		||||
		search_entry_text = xedit_utils_escape_search_text (xedit_search_dialog_get_search_text (dialog));
 | 
			
		||||
	} else {
 | 
			
		||||
		search_entry_text = xedit_search_dialog_get_search_text (dialog);
 | 
			
		||||
	}
 | 
			
		||||
	g_return_if_fail ((search_entry_text) != NULL);
 | 
			
		||||
	g_return_if_fail ((*search_entry_text) != '\0');
 | 
			
		||||
 | 
			
		||||
	/* replace text may be "", we just delete */
 | 
			
		||||
	if (!parse_escapes) {
 | 
			
		||||
		replace_entry_text = xedit_utils_escape_search_text (xedit_search_dialog_get_replace_text (dialog));
 | 
			
		||||
	} else {
 | 
			
		||||
		replace_entry_text = xedit_search_dialog_get_replace_text (dialog);
 | 
			
		||||
	}
 | 
			
		||||
	g_return_if_fail ((replace_entry_text) != NULL);
 | 
			
		||||
 | 
			
		||||
	unescaped_search_text = xedit_utils_unescape_search_text (search_entry_text);
 | 
			
		||||
 | 
			
		||||
	get_selected_text (GTK_TEXT_BUFFER (doc), 
 | 
			
		||||
			   &selected_text, 
 | 
			
		||||
			   NULL);
 | 
			
		||||
 | 
			
		||||
	match_case = xedit_search_dialog_get_match_case (dialog);
 | 
			
		||||
 | 
			
		||||
	if ((selected_text == NULL) ||
 | 
			
		||||
	    (match_case && (strcmp (selected_text, unescaped_search_text) != 0)) || 
 | 
			
		||||
	    (!match_case && !g_utf8_caselessnmatch (selected_text,
 | 
			
		||||
						    unescaped_search_text, 
 | 
			
		||||
						    strlen (selected_text), 
 | 
			
		||||
						    strlen (unescaped_search_text)) != 0))
 | 
			
		||||
	{
 | 
			
		||||
		do_find (dialog, window);
 | 
			
		||||
		g_free (unescaped_search_text);
 | 
			
		||||
		g_free (selected_text);	
 | 
			
		||||
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	unescaped_replace_text = xedit_utils_unescape_search_text (replace_entry_text);	
 | 
			
		||||
	replace_selected_text (GTK_TEXT_BUFFER (doc), unescaped_replace_text);
 | 
			
		||||
 | 
			
		||||
	g_free (unescaped_search_text);
 | 
			
		||||
	g_free (selected_text);
 | 
			
		||||
	g_free (unescaped_replace_text);
 | 
			
		||||
	
 | 
			
		||||
	do_find (dialog, window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
do_replace_all (XeditSearchDialog *dialog,
 | 
			
		||||
		XeditWindow       *window)
 | 
			
		||||
{
 | 
			
		||||
	XeditView *active_view;
 | 
			
		||||
	XeditDocument *doc;
 | 
			
		||||
	const gchar *search_entry_text;
 | 
			
		||||
	const gchar *replace_entry_text;
 | 
			
		||||
	gboolean match_case;
 | 
			
		||||
	gboolean entire_word;
 | 
			
		||||
	gboolean parse_escapes;
 | 
			
		||||
	guint flags = 0;
 | 
			
		||||
	gint count;
 | 
			
		||||
 | 
			
		||||
	active_view = xedit_window_get_active_view (window);
 | 
			
		||||
	if (active_view == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	doc = XEDIT_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (active_view)));
 | 
			
		||||
 | 
			
		||||
	parse_escapes = xedit_search_dialog_get_parse_escapes (dialog);
 | 
			
		||||
	if (!parse_escapes) {
 | 
			
		||||
		search_entry_text = xedit_utils_escape_search_text(xedit_search_dialog_get_search_text (dialog));
 | 
			
		||||
	} else {
 | 
			
		||||
		search_entry_text = xedit_search_dialog_get_search_text (dialog);
 | 
			
		||||
	}
 | 
			
		||||
	g_return_if_fail ((search_entry_text) != NULL);
 | 
			
		||||
	g_return_if_fail ((*search_entry_text) != '\0');
 | 
			
		||||
 | 
			
		||||
	/* replace text may be "", we just delete all occurrencies */
 | 
			
		||||
	if (!parse_escapes) {
 | 
			
		||||
		replace_entry_text = xedit_utils_escape_search_text (xedit_search_dialog_get_replace_text (dialog));
 | 
			
		||||
	} else {
 | 
			
		||||
		replace_entry_text = xedit_search_dialog_get_replace_text (dialog);
 | 
			
		||||
	}
 | 
			
		||||
	g_return_if_fail ((replace_entry_text) != NULL);
 | 
			
		||||
 | 
			
		||||
	match_case = xedit_search_dialog_get_match_case (dialog);
 | 
			
		||||
	entire_word = xedit_search_dialog_get_entire_word (dialog);
 | 
			
		||||
 | 
			
		||||
	XEDIT_SEARCH_SET_CASE_SENSITIVE (flags, match_case);
 | 
			
		||||
	XEDIT_SEARCH_SET_ENTIRE_WORD (flags, entire_word);
 | 
			
		||||
 | 
			
		||||
	count = xedit_document_replace_all (doc, 
 | 
			
		||||
					    search_entry_text,
 | 
			
		||||
					    replace_entry_text,
 | 
			
		||||
					    flags);
 | 
			
		||||
 | 
			
		||||
	if (count > 0)
 | 
			
		||||
	{
 | 
			
		||||
		text_found (window, count);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		if (!parse_escapes) {
 | 
			
		||||
			text_not_found (window, xedit_utils_unescape_search_text (search_entry_text));
 | 
			
		||||
		} else {
 | 
			
		||||
			text_not_found (window, search_entry_text);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
 | 
			
		||||
					   XEDIT_SEARCH_DIALOG_REPLACE_RESPONSE,
 | 
			
		||||
					   FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
search_dialog_response_cb (XeditSearchDialog *dialog,
 | 
			
		||||
			   gint               response_id,
 | 
			
		||||
			   XeditWindow       *window)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	switch (response_id)
 | 
			
		||||
	{
 | 
			
		||||
		case XEDIT_SEARCH_DIALOG_FIND_RESPONSE:
 | 
			
		||||
			do_find (dialog, window);
 | 
			
		||||
			break;
 | 
			
		||||
		case XEDIT_SEARCH_DIALOG_REPLACE_RESPONSE:
 | 
			
		||||
			do_replace (dialog, window);
 | 
			
		||||
			break;
 | 
			
		||||
		case XEDIT_SEARCH_DIALOG_REPLACE_ALL_RESPONSE:
 | 
			
		||||
			do_replace_all (dialog, window);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			last_search_data_store_position (dialog);
 | 
			
		||||
			gtk_widget_hide (GTK_WIDGET (dialog));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
search_dialog_delete_event_cb (GtkWidget   *widget,
 | 
			
		||||
			       GdkEventAny *event,
 | 
			
		||||
			       gpointer     user_data)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	/* prevent destruction */
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
search_dialog_destroyed (XeditWindow       *window,
 | 
			
		||||
			 XeditSearchDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	g_object_set_data (G_OBJECT (window),
 | 
			
		||||
			   XEDIT_SEARCH_DIALOG_KEY,
 | 
			
		||||
			   NULL);
 | 
			
		||||
	g_object_set_data (G_OBJECT (dialog),
 | 
			
		||||
			   XEDIT_LAST_SEARCH_DATA_KEY,
 | 
			
		||||
			   NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GtkWidget *
 | 
			
		||||
create_dialog (XeditWindow *window, gboolean show_replace)
 | 
			
		||||
{
 | 
			
		||||
	GtkWidget *dialog;
 | 
			
		||||
 | 
			
		||||
	dialog = xedit_search_dialog_new (GTK_WINDOW (window), show_replace);
 | 
			
		||||
 | 
			
		||||
	g_signal_connect (dialog,
 | 
			
		||||
			  "response",
 | 
			
		||||
			  G_CALLBACK (search_dialog_response_cb),
 | 
			
		||||
			  window);
 | 
			
		||||
	g_signal_connect (dialog,
 | 
			
		||||
			 "delete-event",
 | 
			
		||||
			 G_CALLBACK (search_dialog_delete_event_cb),
 | 
			
		||||
			 NULL);
 | 
			
		||||
 | 
			
		||||
	g_object_set_data (G_OBJECT (window),
 | 
			
		||||
			   XEDIT_SEARCH_DIALOG_KEY,
 | 
			
		||||
			   dialog);
 | 
			
		||||
 | 
			
		||||
	g_object_weak_ref (G_OBJECT (dialog),
 | 
			
		||||
			   (GWeakNotify) search_dialog_destroyed,
 | 
			
		||||
			   window);
 | 
			
		||||
 | 
			
		||||
	return dialog;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_cmd_search_find (GtkAction   *action,
 | 
			
		||||
			XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	gpointer data;
 | 
			
		||||
	GtkWidget *search_dialog;
 | 
			
		||||
	XeditDocument *doc;
 | 
			
		||||
	gboolean selection_exists;
 | 
			
		||||
	gboolean parse_escapes;
 | 
			
		||||
	gchar *find_text = NULL;
 | 
			
		||||
	const gchar *search_text = NULL;
 | 
			
		||||
	gint sel_len;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	data = g_object_get_data (G_OBJECT (window), XEDIT_SEARCH_DIALOG_KEY);
 | 
			
		||||
 | 
			
		||||
	if (data == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		search_dialog = create_dialog (window, FALSE);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		g_return_if_fail (XEDIT_IS_SEARCH_DIALOG (data));
 | 
			
		||||
		
 | 
			
		||||
		search_dialog = GTK_WIDGET (data);
 | 
			
		||||
		
 | 
			
		||||
		/* turn the dialog into a find dialog if needed */
 | 
			
		||||
		if (xedit_search_dialog_get_show_replace (XEDIT_SEARCH_DIALOG (search_dialog)))
 | 
			
		||||
			xedit_search_dialog_set_show_replace (XEDIT_SEARCH_DIALOG (search_dialog),
 | 
			
		||||
							      FALSE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	doc = xedit_window_get_active_document (window);
 | 
			
		||||
	g_return_if_fail (doc != NULL);
 | 
			
		||||
 | 
			
		||||
	selection_exists = get_selected_text (GTK_TEXT_BUFFER (doc),
 | 
			
		||||
					      &find_text,
 | 
			
		||||
					      &sel_len);
 | 
			
		||||
 | 
			
		||||
	if (selection_exists && find_text != NULL && sel_len < 80)
 | 
			
		||||
	{
 | 
			
		||||
		/*
 | 
			
		||||
		 * Special case: if the currently selected text
 | 
			
		||||
		 * is the same as the unescaped search text and
 | 
			
		||||
		 * escape sequence parsing is activated, use the
 | 
			
		||||
		 * same old search text. (Without this, if you e.g.
 | 
			
		||||
		 * search for '\n' in escaped mode and then open
 | 
			
		||||
		 * the search dialog again, you'll get an unprintable
 | 
			
		||||
		 * single-character literal '\n' in the "search for"
 | 
			
		||||
		 * box).
 | 
			
		||||
		 */
 | 
			
		||||
		parse_escapes = xedit_search_dialog_get_parse_escapes (XEDIT_SEARCH_DIALOG (search_dialog));
 | 
			
		||||
		search_text = xedit_search_dialog_get_search_text (XEDIT_SEARCH_DIALOG (search_dialog));
 | 
			
		||||
		if (!(search_text != NULL
 | 
			
		||||
		      && !strcmp(xedit_utils_unescape_search_text(search_text), find_text)
 | 
			
		||||
		      && parse_escapes)) {
 | 
			
		||||
			/* General case */
 | 
			
		||||
			xedit_search_dialog_set_search_text (XEDIT_SEARCH_DIALOG (search_dialog),
 | 
			
		||||
							     find_text);
 | 
			
		||||
		}
 | 
			
		||||
		g_free (find_text);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		g_free (find_text);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gtk_widget_show (search_dialog);
 | 
			
		||||
	last_search_data_restore_position (XEDIT_SEARCH_DIALOG (search_dialog));
 | 
			
		||||
	xedit_search_dialog_present_with_time (XEDIT_SEARCH_DIALOG (search_dialog),
 | 
			
		||||
					       GDK_CURRENT_TIME);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_cmd_search_replace (GtkAction   *action,
 | 
			
		||||
			   XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	gpointer data;
 | 
			
		||||
	GtkWidget *replace_dialog;
 | 
			
		||||
	XeditDocument *doc;
 | 
			
		||||
	gboolean selection_exists;
 | 
			
		||||
	gboolean parse_escapes;
 | 
			
		||||
	gchar *find_text = NULL;
 | 
			
		||||
	const gchar *search_text = NULL;
 | 
			
		||||
	gint sel_len;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	data = g_object_get_data (G_OBJECT (window), XEDIT_SEARCH_DIALOG_KEY);
 | 
			
		||||
 | 
			
		||||
	if (data == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		replace_dialog = create_dialog (window, TRUE);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		g_return_if_fail (XEDIT_IS_SEARCH_DIALOG (data));
 | 
			
		||||
		
 | 
			
		||||
		replace_dialog = GTK_WIDGET (data);
 | 
			
		||||
		
 | 
			
		||||
		/* turn the dialog into a find dialog if needed */
 | 
			
		||||
		if (!xedit_search_dialog_get_show_replace (XEDIT_SEARCH_DIALOG (replace_dialog)))
 | 
			
		||||
			xedit_search_dialog_set_show_replace (XEDIT_SEARCH_DIALOG (replace_dialog),
 | 
			
		||||
							      TRUE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	doc = xedit_window_get_active_document (window);
 | 
			
		||||
	g_return_if_fail (doc != NULL);
 | 
			
		||||
 | 
			
		||||
	selection_exists = get_selected_text (GTK_TEXT_BUFFER (doc),
 | 
			
		||||
					      &find_text,
 | 
			
		||||
					      &sel_len);
 | 
			
		||||
 | 
			
		||||
	if (selection_exists && find_text != NULL && sel_len < 80)
 | 
			
		||||
	{
 | 
			
		||||
		/*
 | 
			
		||||
		 * Special case: if the currently selected text
 | 
			
		||||
		 * is the same as the unescaped search text and
 | 
			
		||||
		 * escape sequence parsing is activated, use the
 | 
			
		||||
		 * same old search text. (Without this, if you e.g.
 | 
			
		||||
		 * search for '\n' in escaped mode and then open
 | 
			
		||||
		 * the search dialog again, you'll get an unprintable
 | 
			
		||||
		 * single-character literal '\n' in the "search for"
 | 
			
		||||
		 * box).
 | 
			
		||||
		 */
 | 
			
		||||
		parse_escapes = xedit_search_dialog_get_parse_escapes (XEDIT_SEARCH_DIALOG (replace_dialog));
 | 
			
		||||
		search_text = xedit_search_dialog_get_search_text (XEDIT_SEARCH_DIALOG (replace_dialog));
 | 
			
		||||
		if (!(search_text != NULL
 | 
			
		||||
		      && !strcmp(xedit_utils_unescape_search_text(search_text), find_text)
 | 
			
		||||
		      && parse_escapes)) {
 | 
			
		||||
			/* General case */
 | 
			
		||||
			xedit_search_dialog_set_search_text (XEDIT_SEARCH_DIALOG (replace_dialog),
 | 
			
		||||
							     find_text);
 | 
			
		||||
		}
 | 
			
		||||
		g_free (find_text);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		g_free (find_text);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gtk_widget_show (replace_dialog);
 | 
			
		||||
	last_search_data_restore_position (XEDIT_SEARCH_DIALOG (replace_dialog));
 | 
			
		||||
	xedit_search_dialog_present_with_time (XEDIT_SEARCH_DIALOG (replace_dialog),
 | 
			
		||||
					       GDK_CURRENT_TIME);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
do_find_again (XeditWindow *window,
 | 
			
		||||
	       gboolean     backward)
 | 
			
		||||
{
 | 
			
		||||
	XeditView *active_view;
 | 
			
		||||
	gboolean wrap_around = TRUE;
 | 
			
		||||
	gpointer data;
 | 
			
		||||
	
 | 
			
		||||
	active_view = xedit_window_get_active_view (window);
 | 
			
		||||
	g_return_if_fail (active_view != NULL);
 | 
			
		||||
 | 
			
		||||
	data = g_object_get_data (G_OBJECT (window), XEDIT_SEARCH_DIALOG_KEY);
 | 
			
		||||
	
 | 
			
		||||
	if (data != NULL)
 | 
			
		||||
		wrap_around = xedit_search_dialog_get_wrap_around (XEDIT_SEARCH_DIALOG (data));
 | 
			
		||||
	
 | 
			
		||||
	run_search (active_view,
 | 
			
		||||
		    wrap_around,
 | 
			
		||||
		    backward);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_cmd_search_find_next (GtkAction   *action,
 | 
			
		||||
			     XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	do_find_again (window, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_cmd_search_find_prev (GtkAction   *action,
 | 
			
		||||
			     XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	do_find_again (window, TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_cmd_search_clear_highlight (GtkAction   *action,
 | 
			
		||||
				   XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocument *doc;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	doc = xedit_window_get_active_document (window);
 | 
			
		||||
	xedit_document_set_search_text (XEDIT_DOCUMENT (doc),
 | 
			
		||||
					"",
 | 
			
		||||
					XEDIT_SEARCH_DONT_SET_FLAGS);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_cmd_search_goto_line (GtkAction   *action,
 | 
			
		||||
			     XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	XeditView *active_view;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	active_view = xedit_window_get_active_view (window);
 | 
			
		||||
	if (active_view == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	/* Focus the view if needed: we need to focus the view otherwise 
 | 
			
		||||
	   activating the binding for goto line has no effect */
 | 
			
		||||
	gtk_widget_grab_focus (GTK_WIDGET (active_view));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/* goto line is builtin in XeditView, just activate
 | 
			
		||||
	 * the corrisponding binding.
 | 
			
		||||
	 */
 | 
			
		||||
	gtk_bindings_activate (GTK_OBJECT (active_view),
 | 
			
		||||
			       GDK_KEY_i,
 | 
			
		||||
			       GDK_CONTROL_MASK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_cmd_search_incremental_search (GtkAction   *action,
 | 
			
		||||
				      XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	XeditView *active_view;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	active_view = xedit_window_get_active_view (window);
 | 
			
		||||
	if (active_view == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	/* Focus the view if needed: we need to focus the view otherwise 
 | 
			
		||||
	   activating the binding for incremental search has no effect */
 | 
			
		||||
	gtk_widget_grab_focus (GTK_WIDGET (active_view));
 | 
			
		||||
	
 | 
			
		||||
	/* incremental search is builtin in XeditView, just activate
 | 
			
		||||
	 * the corrisponding binding.
 | 
			
		||||
	 */
 | 
			
		||||
	gtk_bindings_activate (GTK_OBJECT (active_view),
 | 
			
		||||
			       GDK_KEY_k,
 | 
			
		||||
			       GDK_CONTROL_MASK);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										154
									
								
								xedit/xedit-commands-view.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								xedit/xedit-commands-view.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,154 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-view-commands.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
 | 
			
		||||
 * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi
 | 
			
		||||
 * Copyright (C) 2002-2005 Paolo Maggi
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor,
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 1998-2005. See the AUTHORS file for a
 | 
			
		||||
 * list of people on the xedit Team.
 | 
			
		||||
 * See the ChangeLog files for a list of changes.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
#include "xedit-commands.h"
 | 
			
		||||
#include "xedit-debug.h"
 | 
			
		||||
#include "xedit-window.h"
 | 
			
		||||
#include "xedit-window-private.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_cmd_view_show_toolbar (GtkAction   *action,
 | 
			
		||||
			     XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	gboolean visible;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	visible = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
 | 
			
		||||
 | 
			
		||||
	if (visible)
 | 
			
		||||
		gtk_widget_show (window->priv->toolbar);
 | 
			
		||||
	else
 | 
			
		||||
		gtk_widget_hide (window->priv->toolbar);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_cmd_view_show_statusbar (GtkAction   *action,
 | 
			
		||||
			       XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	gboolean visible;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	visible = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
 | 
			
		||||
 | 
			
		||||
	if (visible)
 | 
			
		||||
		gtk_widget_show (window->priv->statusbar);
 | 
			
		||||
	else
 | 
			
		||||
		gtk_widget_hide (window->priv->statusbar);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_cmd_view_show_side_pane (GtkAction   *action,
 | 
			
		||||
			       XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	gboolean visible;
 | 
			
		||||
	XeditPanel *panel;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	visible = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
 | 
			
		||||
 | 
			
		||||
	panel = xedit_window_get_side_panel (window);
 | 
			
		||||
 | 
			
		||||
	if (visible)
 | 
			
		||||
	{
 | 
			
		||||
		gtk_widget_show (GTK_WIDGET (panel));
 | 
			
		||||
		gtk_widget_grab_focus (GTK_WIDGET (panel));
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		gtk_widget_hide (GTK_WIDGET (panel));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_cmd_view_show_bottom_pane (GtkAction   *action,
 | 
			
		||||
				 XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	gboolean visible;
 | 
			
		||||
	XeditPanel *panel;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	visible = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
 | 
			
		||||
 | 
			
		||||
	panel = xedit_window_get_bottom_panel (window);
 | 
			
		||||
 | 
			
		||||
	if (visible)
 | 
			
		||||
	{
 | 
			
		||||
		gtk_widget_show (GTK_WIDGET (panel));
 | 
			
		||||
		gtk_widget_grab_focus (GTK_WIDGET (panel));
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		gtk_widget_hide (GTK_WIDGET (panel));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_cmd_view_toggle_fullscreen_mode (GtkAction *action,
 | 
			
		||||
					XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_COMMANDS);
 | 
			
		||||
 | 
			
		||||
	if (_xedit_window_is_fullscreen (window))
 | 
			
		||||
		_xedit_window_unfullscreen (window);
 | 
			
		||||
	else
 | 
			
		||||
		_xedit_window_fullscreen (window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_cmd_view_leave_fullscreen_mode (GtkAction *action,
 | 
			
		||||
				       XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	GtkAction *view_action;
 | 
			
		||||
 | 
			
		||||
	view_action = gtk_action_group_get_action (window->priv->always_sensitive_action_group,
 | 
			
		||||
						   "ViewFullscreen");
 | 
			
		||||
	g_signal_handlers_block_by_func
 | 
			
		||||
		(view_action, G_CALLBACK (_xedit_cmd_view_toggle_fullscreen_mode),
 | 
			
		||||
		 window);
 | 
			
		||||
	gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (view_action),
 | 
			
		||||
				      FALSE);
 | 
			
		||||
	_xedit_window_unfullscreen (window);
 | 
			
		||||
	g_signal_handlers_unblock_by_func
 | 
			
		||||
		(view_action, G_CALLBACK (_xedit_cmd_view_toggle_fullscreen_mode),
 | 
			
		||||
		 window);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										159
									
								
								xedit/xedit-commands.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								xedit/xedit-commands.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,159 @@
 | 
			
		||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-commands.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
 | 
			
		||||
 * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi 
 | 
			
		||||
 * Copyright (C) 2002-2005 Paolo Maggi 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA. 
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 1998-2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_COMMANDS_H__
 | 
			
		||||
#define __XEDIT_COMMANDS_H__
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
#include <xedit/xedit-window.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/* Do nothing if URI does not exist */
 | 
			
		||||
void		 xedit_commands_load_uri		(XeditWindow         *window,
 | 
			
		||||
							 const gchar         *uri,
 | 
			
		||||
							 const XeditEncoding *encoding,
 | 
			
		||||
							 gint                 line_pos);
 | 
			
		||||
 | 
			
		||||
/* Ignore non-existing URIs */
 | 
			
		||||
gint		 xedit_commands_load_uris		(XeditWindow         *window,
 | 
			
		||||
							 const GSList        *uris,
 | 
			
		||||
							 const XeditEncoding *encoding,
 | 
			
		||||
							 gint                 line_pos);
 | 
			
		||||
 | 
			
		||||
void		 xedit_commands_save_document		(XeditWindow         *window,
 | 
			
		||||
                                                         XeditDocument       *document);
 | 
			
		||||
 | 
			
		||||
void		 xedit_commands_save_all_documents 	(XeditWindow         *window);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Non-exported functions
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Create titled documens for non-existing URIs */
 | 
			
		||||
gint		_xedit_cmd_load_files_from_prompt	(XeditWindow         *window,
 | 
			
		||||
							 GSList              *files,
 | 
			
		||||
							 const XeditEncoding *encoding,
 | 
			
		||||
							 gint                 line_pos);
 | 
			
		||||
 | 
			
		||||
void		_xedit_cmd_file_new			(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_file_open			(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_file_save			(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_file_save_as			(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_file_save_all		(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_file_revert			(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_file_open_uri		(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_file_print_preview		(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_file_print			(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_file_close			(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_file_close_all		(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_file_quit			(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
 | 
			
		||||
void		_xedit_cmd_edit_undo			(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_edit_redo			(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_edit_cut			(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_edit_copy			(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_edit_paste			(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_edit_delete			(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_edit_select_all		(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_edit_preferences		(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
 | 
			
		||||
void		_xedit_cmd_view_show_toolbar		(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_view_show_statusbar		(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_view_show_side_pane		(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_view_show_bottom_pane	(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_view_toggle_fullscreen_mode	(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_view_leave_fullscreen_mode	(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
 | 
			
		||||
void		_xedit_cmd_search_find			(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_search_find_next		(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_search_find_prev		(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_search_replace		(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_search_clear_highlight	(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_search_goto_line		(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_search_incremental_search	(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);							 
 | 
			
		||||
							 
 | 
			
		||||
void		_xedit_cmd_documents_previous_document	(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_documents_next_document	(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_documents_move_to_new_window	(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
 | 
			
		||||
void		_xedit_cmd_help_contents		(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
void		_xedit_cmd_help_about			(GtkAction   *action,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
 | 
			
		||||
void		_xedit_cmd_file_close_tab 		(XeditTab    *tab,
 | 
			
		||||
							 XeditWindow *window);
 | 
			
		||||
 | 
			
		||||
void		_xedit_cmd_file_save_documents_list	(XeditWindow *window,
 | 
			
		||||
							 GList       *docs);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __XEDIT_COMMANDS_H__ */ 
 | 
			
		||||
							
								
								
									
										158
									
								
								xedit/xedit-debug.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								xedit/xedit-debug.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,158 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-debug.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
 | 
			
		||||
 * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi
 | 
			
		||||
 * Copyright (C) 2002 - 2005 Paolo Maggi  
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 1998-2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "xedit-debug.h"
 | 
			
		||||
 | 
			
		||||
#define ENABLE_PROFILING
 | 
			
		||||
 | 
			
		||||
#ifdef ENABLE_PROFILING
 | 
			
		||||
static GTimer *timer = NULL;
 | 
			
		||||
static gdouble last = 0.0;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static XeditDebugSection debug = XEDIT_NO_DEBUG;
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_debug_init (void)
 | 
			
		||||
{
 | 
			
		||||
	if (g_getenv ("XEDIT_DEBUG") != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		/* enable all debugging */
 | 
			
		||||
		debug = ~XEDIT_NO_DEBUG;
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (g_getenv ("XEDIT_DEBUG_VIEW") != NULL)
 | 
			
		||||
		debug = debug | XEDIT_DEBUG_VIEW;
 | 
			
		||||
	if (g_getenv ("XEDIT_DEBUG_SEARCH") != NULL)
 | 
			
		||||
		debug = debug | XEDIT_DEBUG_SEARCH;
 | 
			
		||||
	if (g_getenv ("XEDIT_DEBUG_PREFS") != NULL)
 | 
			
		||||
		debug = debug | XEDIT_DEBUG_PREFS;
 | 
			
		||||
	if (g_getenv ("XEDIT_DEBUG_PRINT") != NULL)
 | 
			
		||||
		debug = debug | XEDIT_DEBUG_PRINT;
 | 
			
		||||
	if (g_getenv ("XEDIT_DEBUG_PLUGINS") != NULL)
 | 
			
		||||
		debug = debug | XEDIT_DEBUG_PLUGINS;
 | 
			
		||||
	if (g_getenv ("XEDIT_DEBUG_TAB") != NULL)
 | 
			
		||||
		debug = debug | XEDIT_DEBUG_TAB;
 | 
			
		||||
	if (g_getenv ("XEDIT_DEBUG_DOCUMENT") != NULL)
 | 
			
		||||
		debug = debug | XEDIT_DEBUG_DOCUMENT;
 | 
			
		||||
	if (g_getenv ("XEDIT_DEBUG_COMMANDS") != NULL)
 | 
			
		||||
		debug = debug | XEDIT_DEBUG_COMMANDS;
 | 
			
		||||
	if (g_getenv ("XEDIT_DEBUG_APP") != NULL)
 | 
			
		||||
		debug = debug | XEDIT_DEBUG_APP;
 | 
			
		||||
	if (g_getenv ("XEDIT_DEBUG_SESSION") != NULL)
 | 
			
		||||
		debug = debug | XEDIT_DEBUG_SESSION;
 | 
			
		||||
	if (g_getenv ("XEDIT_DEBUG_UTILS") != NULL)
 | 
			
		||||
		debug = debug | XEDIT_DEBUG_UTILS;
 | 
			
		||||
	if (g_getenv ("XEDIT_DEBUG_METADATA") != NULL)
 | 
			
		||||
		debug = debug | XEDIT_DEBUG_METADATA;
 | 
			
		||||
	if (g_getenv ("XEDIT_DEBUG_WINDOW") != NULL)
 | 
			
		||||
		debug = debug | XEDIT_DEBUG_WINDOW;
 | 
			
		||||
	if (g_getenv ("XEDIT_DEBUG_LOADER") != NULL)
 | 
			
		||||
		debug = debug | XEDIT_DEBUG_LOADER;
 | 
			
		||||
	if (g_getenv ("XEDIT_DEBUG_SAVER") != NULL)
 | 
			
		||||
		debug = debug | XEDIT_DEBUG_SAVER;
 | 
			
		||||
 | 
			
		||||
out:		
 | 
			
		||||
 | 
			
		||||
#ifdef ENABLE_PROFILING
 | 
			
		||||
	if (debug != XEDIT_NO_DEBUG)
 | 
			
		||||
		timer = g_timer_new ();
 | 
			
		||||
#endif
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_debug_message (XeditDebugSection  section,
 | 
			
		||||
		     const gchar       *file,
 | 
			
		||||
		     gint               line,
 | 
			
		||||
		     const gchar       *function,
 | 
			
		||||
		     const gchar       *format, ...)
 | 
			
		||||
{
 | 
			
		||||
	if (G_UNLIKELY (debug & section))
 | 
			
		||||
	{	
 | 
			
		||||
#ifdef ENABLE_PROFILING
 | 
			
		||||
		gdouble seconds;
 | 
			
		||||
		g_return_if_fail (timer != NULL);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		va_list args;
 | 
			
		||||
		gchar *msg;
 | 
			
		||||
 | 
			
		||||
		g_return_if_fail (format != NULL);
 | 
			
		||||
 | 
			
		||||
		va_start (args, format);
 | 
			
		||||
		msg = g_strdup_vprintf (format, args);
 | 
			
		||||
		va_end (args);
 | 
			
		||||
 | 
			
		||||
#ifdef ENABLE_PROFILING
 | 
			
		||||
		seconds = g_timer_elapsed (timer, NULL);
 | 
			
		||||
		g_print ("[%f (%f)] %s:%d (%s) %s\n", 
 | 
			
		||||
			 seconds, seconds - last,  file, line, function, msg);
 | 
			
		||||
		last = seconds;			 
 | 
			
		||||
#else
 | 
			
		||||
		g_print ("%s:%d (%s) %s\n", file, line, function, msg);	
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		fflush (stdout);
 | 
			
		||||
 | 
			
		||||
		g_free (msg);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void xedit_debug (XeditDebugSection  section,
 | 
			
		||||
		  const gchar       *file,
 | 
			
		||||
		  gint               line,
 | 
			
		||||
		  const gchar       *function)
 | 
			
		||||
{
 | 
			
		||||
	if (G_UNLIKELY (debug & section))
 | 
			
		||||
	{
 | 
			
		||||
#ifdef ENABLE_PROFILING
 | 
			
		||||
		gdouble seconds;
 | 
			
		||||
 | 
			
		||||
		g_return_if_fail (timer != NULL);
 | 
			
		||||
 | 
			
		||||
		seconds = g_timer_elapsed (timer, NULL);		
 | 
			
		||||
		g_print ("[%f (%f)] %s:%d (%s)\n", 
 | 
			
		||||
			 seconds, seconds - last, file, line, function);
 | 
			
		||||
		last = seconds;
 | 
			
		||||
#else
 | 
			
		||||
		g_print ("%s:%d (%s)\n", file, line, function);
 | 
			
		||||
#endif		
 | 
			
		||||
		fflush (stdout);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										94
									
								
								xedit/xedit-debug.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								xedit/xedit-debug.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,94 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-debug.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
 | 
			
		||||
 * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi
 | 
			
		||||
 * Copyright (C) 2002 - 2005 Paolo Maggi  
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 1998-2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_DEBUG_H__
 | 
			
		||||
#define __XEDIT_DEBUG_H__
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Set an environmental var of the same name to turn on
 | 
			
		||||
 * debugging output. Setting XEDIT_DEBUG will turn on all
 | 
			
		||||
 * sections.
 | 
			
		||||
 */
 | 
			
		||||
typedef enum {
 | 
			
		||||
	XEDIT_NO_DEBUG       = 0,
 | 
			
		||||
	XEDIT_DEBUG_VIEW     = 1 << 0,
 | 
			
		||||
	XEDIT_DEBUG_SEARCH   = 1 << 1,
 | 
			
		||||
	XEDIT_DEBUG_PRINT    = 1 << 2,
 | 
			
		||||
	XEDIT_DEBUG_PREFS    = 1 << 3,
 | 
			
		||||
	XEDIT_DEBUG_PLUGINS  = 1 << 4,
 | 
			
		||||
	XEDIT_DEBUG_TAB      = 1 << 5,
 | 
			
		||||
	XEDIT_DEBUG_DOCUMENT = 1 << 6,
 | 
			
		||||
	XEDIT_DEBUG_COMMANDS = 1 << 7,
 | 
			
		||||
	XEDIT_DEBUG_APP      = 1 << 8,
 | 
			
		||||
	XEDIT_DEBUG_SESSION  = 1 << 9,
 | 
			
		||||
	XEDIT_DEBUG_UTILS    = 1 << 10,
 | 
			
		||||
	XEDIT_DEBUG_METADATA = 1 << 11,
 | 
			
		||||
	XEDIT_DEBUG_WINDOW   = 1 << 12,
 | 
			
		||||
	XEDIT_DEBUG_LOADER   = 1 << 13,
 | 
			
		||||
	XEDIT_DEBUG_SAVER    = 1 << 14
 | 
			
		||||
} XeditDebugSection;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* FIXME this is an issue for introspection */
 | 
			
		||||
#define	DEBUG_VIEW	XEDIT_DEBUG_VIEW,    __FILE__, __LINE__, G_STRFUNC
 | 
			
		||||
#define	DEBUG_SEARCH	XEDIT_DEBUG_SEARCH,  __FILE__, __LINE__, G_STRFUNC
 | 
			
		||||
#define	DEBUG_PRINT	XEDIT_DEBUG_PRINT,   __FILE__, __LINE__, G_STRFUNC
 | 
			
		||||
#define	DEBUG_PREFS	XEDIT_DEBUG_PREFS,   __FILE__, __LINE__, G_STRFUNC
 | 
			
		||||
#define	DEBUG_PLUGINS	XEDIT_DEBUG_PLUGINS, __FILE__, __LINE__, G_STRFUNC
 | 
			
		||||
#define	DEBUG_TAB	XEDIT_DEBUG_TAB,     __FILE__, __LINE__, G_STRFUNC
 | 
			
		||||
#define	DEBUG_DOCUMENT	XEDIT_DEBUG_DOCUMENT,__FILE__, __LINE__, G_STRFUNC
 | 
			
		||||
#define	DEBUG_COMMANDS	XEDIT_DEBUG_COMMANDS,__FILE__, __LINE__, G_STRFUNC
 | 
			
		||||
#define	DEBUG_APP	XEDIT_DEBUG_APP,     __FILE__, __LINE__, G_STRFUNC
 | 
			
		||||
#define	DEBUG_SESSION	XEDIT_DEBUG_SESSION, __FILE__, __LINE__, G_STRFUNC
 | 
			
		||||
#define	DEBUG_UTILS	XEDIT_DEBUG_UTILS,   __FILE__, __LINE__, G_STRFUNC
 | 
			
		||||
#define	DEBUG_METADATA	XEDIT_DEBUG_METADATA,__FILE__, __LINE__, G_STRFUNC
 | 
			
		||||
#define	DEBUG_WINDOW	XEDIT_DEBUG_WINDOW,  __FILE__, __LINE__, G_STRFUNC
 | 
			
		||||
#define	DEBUG_LOADER	XEDIT_DEBUG_LOADER,  __FILE__, __LINE__, G_STRFUNC
 | 
			
		||||
#define	DEBUG_SAVER	XEDIT_DEBUG_SAVER,   __FILE__, __LINE__, G_STRFUNC
 | 
			
		||||
 | 
			
		||||
void xedit_debug_init (void);
 | 
			
		||||
 | 
			
		||||
void xedit_debug (XeditDebugSection  section,
 | 
			
		||||
		  const gchar       *file,
 | 
			
		||||
		  gint               line,
 | 
			
		||||
		  const gchar       *function);
 | 
			
		||||
 | 
			
		||||
void xedit_debug_message (XeditDebugSection  section,
 | 
			
		||||
			  const gchar       *file,
 | 
			
		||||
			  gint               line,
 | 
			
		||||
			  const gchar       *function,
 | 
			
		||||
			  const gchar       *format, ...) G_GNUC_PRINTF(5, 6);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* __XEDIT_DEBUG_H__ */
 | 
			
		||||
							
								
								
									
										123
									
								
								xedit/xedit-dirs.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								xedit/xedit-dirs.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,123 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-dirs.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2008 Ignacio Casal Quinteiro
 | 
			
		||||
 * Copyright (C) 2011 Perberos
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor,
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "xedit-dirs.h"
 | 
			
		||||
 | 
			
		||||
gchar* xedit_dirs_get_user_config_dir(void)
 | 
			
		||||
{
 | 
			
		||||
	gchar* config_dir = NULL;
 | 
			
		||||
 | 
			
		||||
	config_dir = g_build_filename(g_get_user_config_dir(), "xedit", NULL);
 | 
			
		||||
 | 
			
		||||
	return config_dir;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gchar* xedit_dirs_get_user_cache_dir(void)
 | 
			
		||||
{
 | 
			
		||||
	const gchar* cache_dir;
 | 
			
		||||
 | 
			
		||||
	cache_dir = g_get_user_cache_dir();
 | 
			
		||||
 | 
			
		||||
	return g_build_filename(cache_dir, "xedit", NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gchar* xedit_dirs_get_user_plugins_dir(void)
 | 
			
		||||
{
 | 
			
		||||
	gchar* plugin_dir;
 | 
			
		||||
 | 
			
		||||
	plugin_dir = g_build_filename(g_get_user_data_dir(), "xedit", "plugins", NULL);
 | 
			
		||||
 | 
			
		||||
	return plugin_dir;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gchar* xedit_dirs_get_user_accels_file(void)
 | 
			
		||||
{
 | 
			
		||||
	gchar* accels = NULL;
 | 
			
		||||
	gchar *config_dir = NULL;
 | 
			
		||||
 | 
			
		||||
	config_dir = xedit_dirs_get_user_config_dir();
 | 
			
		||||
	accels = g_build_filename(config_dir, "accels", NULL);
 | 
			
		||||
 | 
			
		||||
	g_free(config_dir);
 | 
			
		||||
 | 
			
		||||
	return accels;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gchar* xedit_dirs_get_xedit_data_dir(void)
 | 
			
		||||
{
 | 
			
		||||
	return g_build_filename(DATADIR, "xedit", NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gchar* xedit_dirs_get_xedit_locale_dir(void)
 | 
			
		||||
{
 | 
			
		||||
	return g_build_filename(DATADIR, "locale", NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gchar* xedit_dirs_get_xedit_lib_dir(void)
 | 
			
		||||
{
 | 
			
		||||
	return g_build_filename(LIBDIR, "xedit", NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gchar* xedit_dirs_get_xedit_plugins_dir(void)
 | 
			
		||||
{
 | 
			
		||||
	gchar* lib_dir;
 | 
			
		||||
	gchar* plugin_dir;
 | 
			
		||||
 | 
			
		||||
	lib_dir = xedit_dirs_get_xedit_lib_dir();
 | 
			
		||||
 | 
			
		||||
	plugin_dir = g_build_filename(lib_dir, "plugins", NULL);
 | 
			
		||||
	g_free(lib_dir);
 | 
			
		||||
 | 
			
		||||
	return plugin_dir;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gchar* xedit_dirs_get_xedit_plugin_loaders_dir(void)
 | 
			
		||||
{
 | 
			
		||||
	gchar* lib_dir;
 | 
			
		||||
	gchar* loader_dir;
 | 
			
		||||
 | 
			
		||||
	lib_dir = xedit_dirs_get_xedit_lib_dir();
 | 
			
		||||
 | 
			
		||||
	loader_dir = g_build_filename(lib_dir, "plugin-loaders", NULL);
 | 
			
		||||
	g_free(lib_dir);
 | 
			
		||||
 | 
			
		||||
	return loader_dir;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gchar* xedit_dirs_get_ui_file(const gchar* file)
 | 
			
		||||
{
 | 
			
		||||
	gchar* datadir;
 | 
			
		||||
	gchar* ui_file;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail(file != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	datadir = xedit_dirs_get_xedit_data_dir();
 | 
			
		||||
	ui_file = g_build_filename(datadir, "ui", file, NULL);
 | 
			
		||||
	g_free(datadir);
 | 
			
		||||
 | 
			
		||||
	return ui_file;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										54
									
								
								xedit/xedit-dirs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								xedit/xedit-dirs.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-dirs.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2008 Ignacio Casal Quinteiro
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA. 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_DIRS_H__
 | 
			
		||||
#define __XEDIT_DIRS_H__
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
gchar		*xedit_dirs_get_user_config_dir		(void);
 | 
			
		||||
 | 
			
		||||
gchar		*xedit_dirs_get_user_cache_dir		(void);
 | 
			
		||||
 | 
			
		||||
gchar		*xedit_dirs_get_user_plugins_dir	(void);
 | 
			
		||||
 | 
			
		||||
gchar		*xedit_dirs_get_user_accels_file	(void);
 | 
			
		||||
 | 
			
		||||
gchar		*xedit_dirs_get_xedit_data_dir		(void);
 | 
			
		||||
 | 
			
		||||
gchar		*xedit_dirs_get_xedit_locale_dir	(void);
 | 
			
		||||
 | 
			
		||||
gchar		*xedit_dirs_get_xedit_lib_dir		(void);
 | 
			
		||||
 | 
			
		||||
gchar		*xedit_dirs_get_xedit_plugins_dir	(void);
 | 
			
		||||
 | 
			
		||||
gchar		*xedit_dirs_get_xedit_plugin_loaders_dir
 | 
			
		||||
							(void);
 | 
			
		||||
 | 
			
		||||
gchar		*xedit_dirs_get_ui_file			(const gchar *file);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __XEDIT_DIRS_H__ */
 | 
			
		||||
							
								
								
									
										479
									
								
								xedit/xedit-document-input-stream.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										479
									
								
								xedit/xedit-document-input-stream.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,479 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-document-input-stream.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2010 - Ignacio Casal Quinteiro
 | 
			
		||||
 *
 | 
			
		||||
 * xedit 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.
 | 
			
		||||
 *
 | 
			
		||||
 * xedit 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 xedit; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA  02110-1301  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "xedit-document-input-stream.h"
 | 
			
		||||
#include "xedit-enum-types.h"
 | 
			
		||||
 | 
			
		||||
/* NOTE: never use async methods on this stream, the stream is just
 | 
			
		||||
 * a wrapper around GtkTextBuffer api so that we can use GIO Stream
 | 
			
		||||
 * methods, but the undelying code operates on a GtkTextBuffer, so
 | 
			
		||||
 * there is no I/O involved and should be accessed only by the main
 | 
			
		||||
 * thread */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (XeditDocumentInputStream, xedit_document_input_stream, G_TYPE_INPUT_STREAM);
 | 
			
		||||
 | 
			
		||||
struct _XeditDocumentInputStreamPrivate
 | 
			
		||||
{
 | 
			
		||||
	GtkTextBuffer *buffer;
 | 
			
		||||
	GtkTextMark   *pos;
 | 
			
		||||
	gint           bytes_partial;
 | 
			
		||||
 | 
			
		||||
	XeditDocumentNewlineType newline_type;
 | 
			
		||||
 | 
			
		||||
	guint newline_added : 1;
 | 
			
		||||
	guint is_initialized : 1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
	PROP_0,
 | 
			
		||||
	PROP_BUFFER,
 | 
			
		||||
	PROP_NEWLINE_TYPE
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static gssize     xedit_document_input_stream_read     (GInputStream      *stream,
 | 
			
		||||
							void              *buffer,
 | 
			
		||||
							gsize              count,
 | 
			
		||||
							GCancellable      *cancellable,
 | 
			
		||||
							GError           **error);
 | 
			
		||||
static gboolean   xedit_document_input_stream_close    (GInputStream      *stream,
 | 
			
		||||
							GCancellable      *cancellable,
 | 
			
		||||
							GError           **error);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_document_input_stream_set_property (GObject      *object,
 | 
			
		||||
					  guint         prop_id,
 | 
			
		||||
					  const GValue *value,
 | 
			
		||||
					  GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentInputStream *stream = XEDIT_DOCUMENT_INPUT_STREAM (object);
 | 
			
		||||
 | 
			
		||||
	switch (prop_id)
 | 
			
		||||
	{
 | 
			
		||||
		case PROP_BUFFER:
 | 
			
		||||
			stream->priv->buffer = GTK_TEXT_BUFFER (g_value_get_object (value));
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case PROP_NEWLINE_TYPE:
 | 
			
		||||
			stream->priv->newline_type = g_value_get_enum (value);
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_document_input_stream_get_property (GObject    *object,
 | 
			
		||||
					  guint       prop_id,
 | 
			
		||||
					  GValue     *value,
 | 
			
		||||
					  GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentInputStream *stream = XEDIT_DOCUMENT_INPUT_STREAM (object);
 | 
			
		||||
 | 
			
		||||
	switch (prop_id)
 | 
			
		||||
	{
 | 
			
		||||
		case PROP_BUFFER:
 | 
			
		||||
			g_value_set_object (value, stream->priv->buffer);
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case PROP_NEWLINE_TYPE:
 | 
			
		||||
			g_value_set_enum (value, stream->priv->newline_type);
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_document_input_stream_class_init (XeditDocumentInputStreamClass *klass)
 | 
			
		||||
{
 | 
			
		||||
	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
	GInputStreamClass *stream_class = G_INPUT_STREAM_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
	g_type_class_add_private (klass, sizeof (XeditDocumentInputStreamPrivate));
 | 
			
		||||
 | 
			
		||||
	gobject_class->get_property = xedit_document_input_stream_get_property;
 | 
			
		||||
	gobject_class->set_property = xedit_document_input_stream_set_property;
 | 
			
		||||
 | 
			
		||||
	stream_class->read_fn = xedit_document_input_stream_read;
 | 
			
		||||
	stream_class->close_fn = xedit_document_input_stream_close;
 | 
			
		||||
 | 
			
		||||
	g_object_class_install_property (gobject_class,
 | 
			
		||||
					 PROP_BUFFER,
 | 
			
		||||
					 g_param_spec_object ("buffer",
 | 
			
		||||
							      "Buffer",
 | 
			
		||||
							      "The buffer which is read",
 | 
			
		||||
							      GTK_TYPE_TEXT_BUFFER,
 | 
			
		||||
							      G_PARAM_READWRITE |
 | 
			
		||||
							      G_PARAM_CONSTRUCT_ONLY));
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * XeditDocumentInputStream:newline-type:
 | 
			
		||||
	 *
 | 
			
		||||
	 * The :newline-type property determines what is considered
 | 
			
		||||
	 * as a line ending when reading complete lines from the stream.
 | 
			
		||||
	 */ 
 | 
			
		||||
	g_object_class_install_property (gobject_class,
 | 
			
		||||
					 PROP_NEWLINE_TYPE,
 | 
			
		||||
					 g_param_spec_enum ("newline-type",
 | 
			
		||||
							    "Newline type",
 | 
			
		||||
							    "The accepted types of line ending",
 | 
			
		||||
							    XEDIT_TYPE_DOCUMENT_NEWLINE_TYPE,
 | 
			
		||||
							    XEDIT_DOCUMENT_NEWLINE_TYPE_LF,
 | 
			
		||||
							    G_PARAM_READWRITE |
 | 
			
		||||
							    G_PARAM_STATIC_NAME |
 | 
			
		||||
							    G_PARAM_STATIC_BLURB |
 | 
			
		||||
							    G_PARAM_CONSTRUCT_ONLY));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_document_input_stream_init (XeditDocumentInputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
	stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream,
 | 
			
		||||
						    XEDIT_TYPE_DOCUMENT_INPUT_STREAM,
 | 
			
		||||
						    XeditDocumentInputStreamPrivate);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gsize
 | 
			
		||||
get_new_line_size (XeditDocumentInputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
	gsize ret;
 | 
			
		||||
 | 
			
		||||
	switch (stream->priv->newline_type)
 | 
			
		||||
	{
 | 
			
		||||
		case XEDIT_DOCUMENT_NEWLINE_TYPE_CR:
 | 
			
		||||
		case XEDIT_DOCUMENT_NEWLINE_TYPE_LF:
 | 
			
		||||
			ret = 1;
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case XEDIT_DOCUMENT_NEWLINE_TYPE_CR_LF:
 | 
			
		||||
			ret = 2;
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			g_warn_if_reached ();
 | 
			
		||||
			ret = 1;
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_document_input_stream_new:
 | 
			
		||||
 * @buffer: a #GtkTextBuffer
 | 
			
		||||
 *
 | 
			
		||||
 * Reads the data from @buffer.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: a new #GInputStream to read @buffer
 | 
			
		||||
 */
 | 
			
		||||
GInputStream *
 | 
			
		||||
xedit_document_input_stream_new (GtkTextBuffer           *buffer,
 | 
			
		||||
				 XeditDocumentNewlineType type)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentInputStream *stream;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
 | 
			
		||||
 | 
			
		||||
	stream = g_object_new (XEDIT_TYPE_DOCUMENT_INPUT_STREAM,
 | 
			
		||||
			       "buffer", buffer,
 | 
			
		||||
			       "newline-type", type,
 | 
			
		||||
			       NULL);
 | 
			
		||||
 | 
			
		||||
	return G_INPUT_STREAM (stream);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gsize
 | 
			
		||||
xedit_document_input_stream_get_total_size (XeditDocumentInputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_DOCUMENT_INPUT_STREAM (stream), 0);
 | 
			
		||||
 | 
			
		||||
	return gtk_text_buffer_get_char_count (stream->priv->buffer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gsize
 | 
			
		||||
xedit_document_input_stream_tell (XeditDocumentInputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_DOCUMENT_INPUT_STREAM (stream), 0);
 | 
			
		||||
 | 
			
		||||
	/* FIXME: is this potentially inefficient? If yes, we could keep
 | 
			
		||||
	   track of the offset internally, assuming the mark doesn't move
 | 
			
		||||
	   during the operation */
 | 
			
		||||
	if (!stream->priv->is_initialized)
 | 
			
		||||
	{
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		GtkTextIter iter;
 | 
			
		||||
 | 
			
		||||
		gtk_text_buffer_get_iter_at_mark (stream->priv->buffer,
 | 
			
		||||
						  &iter,
 | 
			
		||||
						  stream->priv->pos);
 | 
			
		||||
		return gtk_text_iter_get_offset (&iter);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const gchar *
 | 
			
		||||
get_new_line (XeditDocumentInputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
	const gchar *ret;
 | 
			
		||||
 | 
			
		||||
	switch (stream->priv->newline_type)
 | 
			
		||||
	{
 | 
			
		||||
		case XEDIT_DOCUMENT_NEWLINE_TYPE_CR:
 | 
			
		||||
			ret = "\r";
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case XEDIT_DOCUMENT_NEWLINE_TYPE_LF:
 | 
			
		||||
			ret = "\n";
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case XEDIT_DOCUMENT_NEWLINE_TYPE_CR_LF:
 | 
			
		||||
			ret = "\r\n";
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			g_warn_if_reached ();
 | 
			
		||||
			ret = "\n";
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gsize
 | 
			
		||||
read_line (XeditDocumentInputStream *stream,
 | 
			
		||||
	   gchar                    *outbuf,
 | 
			
		||||
	   gsize                     space_left)
 | 
			
		||||
{
 | 
			
		||||
	GtkTextIter start, next, end;
 | 
			
		||||
	gchar *buf;
 | 
			
		||||
	gint bytes; /* int since it's what iter_get_offset returns */
 | 
			
		||||
	gsize bytes_to_write, newline_size, read;
 | 
			
		||||
	const gchar *newline;
 | 
			
		||||
	gboolean is_last;
 | 
			
		||||
 | 
			
		||||
	gtk_text_buffer_get_iter_at_mark (stream->priv->buffer,
 | 
			
		||||
					  &start,
 | 
			
		||||
					  stream->priv->pos);
 | 
			
		||||
 | 
			
		||||
	if (gtk_text_iter_is_end (&start))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	end = next = start;
 | 
			
		||||
	newline = get_new_line (stream);
 | 
			
		||||
 | 
			
		||||
	/* Check needed for empty lines */
 | 
			
		||||
	if (!gtk_text_iter_ends_line (&end))
 | 
			
		||||
		gtk_text_iter_forward_to_line_end (&end);
 | 
			
		||||
 | 
			
		||||
	gtk_text_iter_forward_line (&next);
 | 
			
		||||
 | 
			
		||||
	buf = gtk_text_iter_get_slice (&start, &end);
 | 
			
		||||
 | 
			
		||||
	/* the bytes of a line includes also the newline, so with the
 | 
			
		||||
	   offsets we remove the newline and we add the new newline size */
 | 
			
		||||
	bytes = gtk_text_iter_get_bytes_in_line (&start) - stream->priv->bytes_partial;
 | 
			
		||||
 | 
			
		||||
	/* bytes_in_line includes the newlines, so we remove that assuming that
 | 
			
		||||
	   they are single byte characters */
 | 
			
		||||
	bytes = bytes - (gtk_text_iter_get_offset (&next) - gtk_text_iter_get_offset (&end));
 | 
			
		||||
	is_last = gtk_text_iter_is_end (&end);
 | 
			
		||||
 | 
			
		||||
	/* bytes_to_write contains the amount of bytes we would like to write.
 | 
			
		||||
	   This means its the amount of bytes in the line (without the newline
 | 
			
		||||
	   in the buffer) + the amount of bytes for the newline we want to
 | 
			
		||||
	   write (newline_size) */
 | 
			
		||||
	bytes_to_write = bytes;
 | 
			
		||||
 | 
			
		||||
	/* do not add the new newline_size for the last line */
 | 
			
		||||
	newline_size = get_new_line_size (stream);
 | 
			
		||||
	if (!is_last)
 | 
			
		||||
		bytes_to_write += newline_size;
 | 
			
		||||
 | 
			
		||||
	if (bytes_to_write > space_left)
 | 
			
		||||
	{
 | 
			
		||||
		gchar *ptr;
 | 
			
		||||
		gint char_offset;
 | 
			
		||||
		gint written;
 | 
			
		||||
		gsize to_write;
 | 
			
		||||
 | 
			
		||||
		/* Here the line does not fit in the buffer, we thus write
 | 
			
		||||
		   the amount of bytes we can still fit, storing the position
 | 
			
		||||
		   for the next read with the mark. Do not try to write the
 | 
			
		||||
		   new newline in this case, it will be handled in the next
 | 
			
		||||
		   iteration */
 | 
			
		||||
		to_write = MIN (space_left, bytes);
 | 
			
		||||
		ptr = buf;
 | 
			
		||||
		written = 0;
 | 
			
		||||
		char_offset = 0;
 | 
			
		||||
 | 
			
		||||
		while (written < to_write)
 | 
			
		||||
		{
 | 
			
		||||
			gint w;
 | 
			
		||||
 | 
			
		||||
			ptr = g_utf8_next_char (ptr);
 | 
			
		||||
			w = (ptr - buf);
 | 
			
		||||
			if (w > to_write)
 | 
			
		||||
			{
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				written = w;
 | 
			
		||||
				++char_offset;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		memcpy (outbuf, buf, written);
 | 
			
		||||
 | 
			
		||||
		/* Note: offset is one past what we wrote */
 | 
			
		||||
		gtk_text_iter_forward_chars (&start, char_offset);
 | 
			
		||||
		stream->priv->bytes_partial += written;
 | 
			
		||||
		read = written;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		/* First just copy the bytes without the newline */
 | 
			
		||||
		memcpy (outbuf, buf, bytes);
 | 
			
		||||
 | 
			
		||||
		/* Then add the newline, but not for the last line */
 | 
			
		||||
		if (!is_last)
 | 
			
		||||
		{
 | 
			
		||||
			memcpy (outbuf + bytes, newline, newline_size);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		start = next;
 | 
			
		||||
		stream->priv->bytes_partial = 0;
 | 
			
		||||
		read = bytes_to_write;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gtk_text_buffer_move_mark (stream->priv->buffer,
 | 
			
		||||
				   stream->priv->pos,
 | 
			
		||||
				   &start);
 | 
			
		||||
 | 
			
		||||
	g_free (buf);
 | 
			
		||||
	return read;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gssize
 | 
			
		||||
xedit_document_input_stream_read (GInputStream  *stream,
 | 
			
		||||
				  void          *buffer,
 | 
			
		||||
				  gsize          count,
 | 
			
		||||
				  GCancellable  *cancellable,
 | 
			
		||||
				  GError       **error)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentInputStream *dstream;
 | 
			
		||||
	GtkTextIter iter;
 | 
			
		||||
	gssize space_left, read, n;
 | 
			
		||||
 | 
			
		||||
	dstream = XEDIT_DOCUMENT_INPUT_STREAM (stream);
 | 
			
		||||
 | 
			
		||||
	if (count < 6)
 | 
			
		||||
	{
 | 
			
		||||
		g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE,
 | 
			
		||||
				     "Not enougth space in destination");
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (g_cancellable_set_error_if_cancelled (cancellable, error))
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	/* Initialize the mark to the first char in the text buffer */
 | 
			
		||||
	if (!dstream->priv->is_initialized)
 | 
			
		||||
	{
 | 
			
		||||
		gtk_text_buffer_get_start_iter (dstream->priv->buffer, &iter);
 | 
			
		||||
		dstream->priv->pos = gtk_text_buffer_create_mark (dstream->priv->buffer,
 | 
			
		||||
								 NULL,
 | 
			
		||||
								 &iter,
 | 
			
		||||
								 FALSE);
 | 
			
		||||
 | 
			
		||||
		dstream->priv->is_initialized = TRUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	space_left = count;
 | 
			
		||||
	read = 0;
 | 
			
		||||
 | 
			
		||||
	do
 | 
			
		||||
	{
 | 
			
		||||
		n = read_line (dstream, buffer + read, space_left);
 | 
			
		||||
		read += n;
 | 
			
		||||
		space_left -= n;
 | 
			
		||||
	} while (space_left > 0 && n != 0 && dstream->priv->bytes_partial == 0);
 | 
			
		||||
 | 
			
		||||
	/* Make sure that non-empty files are always terminated with \n (see bug #95676).
 | 
			
		||||
	 * Note that we strip the trailing \n when loading the file */
 | 
			
		||||
	gtk_text_buffer_get_iter_at_mark (dstream->priv->buffer,
 | 
			
		||||
					  &iter,
 | 
			
		||||
					  dstream->priv->pos);
 | 
			
		||||
 | 
			
		||||
	if (gtk_text_iter_is_end (&iter) &&
 | 
			
		||||
	    !gtk_text_iter_is_start (&iter))
 | 
			
		||||
	{
 | 
			
		||||
		gssize newline_size;
 | 
			
		||||
 | 
			
		||||
		newline_size = get_new_line_size (dstream);
 | 
			
		||||
 | 
			
		||||
		if (space_left >= newline_size &&
 | 
			
		||||
		    !dstream->priv->newline_added)
 | 
			
		||||
		{
 | 
			
		||||
			const gchar *newline;
 | 
			
		||||
 | 
			
		||||
			newline = get_new_line (dstream);
 | 
			
		||||
 | 
			
		||||
			memcpy (buffer + read, newline, newline_size);
 | 
			
		||||
 | 
			
		||||
			read += newline_size;
 | 
			
		||||
			dstream->priv->newline_added = TRUE;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return read;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
xedit_document_input_stream_close (GInputStream  *stream,
 | 
			
		||||
				   GCancellable  *cancellable,
 | 
			
		||||
				   GError       **error)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentInputStream *dstream = XEDIT_DOCUMENT_INPUT_STREAM (stream);
 | 
			
		||||
 | 
			
		||||
	dstream->priv->newline_added = FALSE;
 | 
			
		||||
 | 
			
		||||
	if (dstream->priv->is_initialized)
 | 
			
		||||
	{
 | 
			
		||||
		gtk_text_buffer_delete_mark (dstream->priv->buffer, dstream->priv->pos);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										68
									
								
								xedit/xedit-document-input-stream.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								xedit/xedit-document-input-stream.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-document-input-stream.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2010 - Ignacio Casal Quinteiro
 | 
			
		||||
 *
 | 
			
		||||
 * xedit 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.
 | 
			
		||||
 *
 | 
			
		||||
 * xedit 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 xedit; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA  02110-1301  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_DOCUMENT_INPUT_STREAM_H__
 | 
			
		||||
#define __XEDIT_DOCUMENT_INPUT_STREAM_H__
 | 
			
		||||
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
#include "xedit-document.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define XEDIT_TYPE_DOCUMENT_INPUT_STREAM		(xedit_document_input_stream_get_type ())
 | 
			
		||||
#define XEDIT_DOCUMENT_INPUT_STREAM(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), XEDIT_TYPE_DOCUMENT_INPUT_STREAM, XeditDocumentInputStream))
 | 
			
		||||
#define XEDIT_DOCUMENT_INPUT_STREAM_CONST(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), XEDIT_TYPE_DOCUMENT_INPUT_STREAM, XeditDocumentInputStream const))
 | 
			
		||||
#define XEDIT_DOCUMENT_INPUT_STREAM_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), XEDIT_TYPE_DOCUMENT_INPUT_STREAM, XeditDocumentInputStreamClass))
 | 
			
		||||
#define XEDIT_IS_DOCUMENT_INPUT_STREAM(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), XEDIT_TYPE_DOCUMENT_INPUT_STREAM))
 | 
			
		||||
#define XEDIT_IS_DOCUMENT_INPUT_STREAM_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), XEDIT_TYPE_DOCUMENT_INPUT_STREAM))
 | 
			
		||||
#define XEDIT_DOCUMENT_INPUT_STREAM_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), XEDIT_TYPE_DOCUMENT_INPUT_STREAM, XeditDocumentInputStreamClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _XeditDocumentInputStream	XeditDocumentInputStream;
 | 
			
		||||
typedef struct _XeditDocumentInputStreamClass	XeditDocumentInputStreamClass;
 | 
			
		||||
typedef struct _XeditDocumentInputStreamPrivate	XeditDocumentInputStreamPrivate;
 | 
			
		||||
 | 
			
		||||
struct _XeditDocumentInputStream
 | 
			
		||||
{
 | 
			
		||||
	GInputStream parent;
 | 
			
		||||
	
 | 
			
		||||
	XeditDocumentInputStreamPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _XeditDocumentInputStreamClass
 | 
			
		||||
{
 | 
			
		||||
	GInputStreamClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType				 xedit_document_input_stream_get_type		(void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
GInputStream			*xedit_document_input_stream_new		(GtkTextBuffer           *buffer,
 | 
			
		||||
										 XeditDocumentNewlineType type);
 | 
			
		||||
 | 
			
		||||
gsize				 xedit_document_input_stream_get_total_size	(XeditDocumentInputStream *stream);
 | 
			
		||||
 | 
			
		||||
gsize				 xedit_document_input_stream_tell		(XeditDocumentInputStream *stream);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __XEDIT_DOCUMENT_INPUT_STREAM_H__ */
 | 
			
		||||
							
								
								
									
										357
									
								
								xedit/xedit-document-loader.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										357
									
								
								xedit/xedit-document-loader.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,357 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-document-loader.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2005 - Paolo Maggi
 | 
			
		||||
 * Copyright (C) 2007 - Paolo Maggi, Steve Frécinaux
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2005-2007. See the AUTHORS file for a
 | 
			
		||||
 * list of people on the xedit Team.
 | 
			
		||||
 * See the ChangeLog files for a list of changes.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
 | 
			
		||||
#include "xedit-document-loader.h"
 | 
			
		||||
#include "xedit-debug.h"
 | 
			
		||||
#include "xedit-metadata-manager.h"
 | 
			
		||||
#include "xedit-utils.h"
 | 
			
		||||
#include "xedit-marshal.h"
 | 
			
		||||
#include "xedit-enum-types.h"
 | 
			
		||||
 | 
			
		||||
/* Those are for the the xedit_document_loader_new() factory */
 | 
			
		||||
#include "xedit-gio-document-loader.h"
 | 
			
		||||
 | 
			
		||||
G_DEFINE_ABSTRACT_TYPE(XeditDocumentLoader, xedit_document_loader, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
/* Signals */
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
	LOADING,
 | 
			
		||||
	LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0 };
 | 
			
		||||
 | 
			
		||||
/* Properties */
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
	PROP_0,
 | 
			
		||||
	PROP_DOCUMENT,
 | 
			
		||||
	PROP_URI,
 | 
			
		||||
	PROP_ENCODING,
 | 
			
		||||
	PROP_NEWLINE_TYPE
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_document_loader_set_property (GObject      *object,
 | 
			
		||||
				    guint         prop_id,
 | 
			
		||||
				    const GValue *value,
 | 
			
		||||
				    GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentLoader *loader = XEDIT_DOCUMENT_LOADER (object);
 | 
			
		||||
 | 
			
		||||
	switch (prop_id)
 | 
			
		||||
	{
 | 
			
		||||
		case PROP_DOCUMENT:
 | 
			
		||||
			g_return_if_fail (loader->document == NULL);
 | 
			
		||||
			loader->document = g_value_get_object (value);
 | 
			
		||||
			break;
 | 
			
		||||
		case PROP_URI:
 | 
			
		||||
			g_return_if_fail (loader->uri == NULL);
 | 
			
		||||
			loader->uri = g_value_dup_string (value);
 | 
			
		||||
			break;
 | 
			
		||||
		case PROP_ENCODING:
 | 
			
		||||
			g_return_if_fail (loader->encoding == NULL);
 | 
			
		||||
			loader->encoding = g_value_get_boxed (value);
 | 
			
		||||
			break;
 | 
			
		||||
		case PROP_NEWLINE_TYPE:
 | 
			
		||||
			loader->auto_detected_newline_type = g_value_get_enum (value);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_document_loader_get_property (GObject    *object,
 | 
			
		||||
				    guint       prop_id,
 | 
			
		||||
				    GValue     *value,
 | 
			
		||||
				    GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentLoader *loader = XEDIT_DOCUMENT_LOADER (object);
 | 
			
		||||
 | 
			
		||||
	switch (prop_id)
 | 
			
		||||
	{
 | 
			
		||||
		case PROP_DOCUMENT:
 | 
			
		||||
			g_value_set_object (value, loader->document);
 | 
			
		||||
			break;
 | 
			
		||||
		case PROP_URI:
 | 
			
		||||
			g_value_set_string (value, loader->uri);
 | 
			
		||||
			break;
 | 
			
		||||
		case PROP_ENCODING:
 | 
			
		||||
			g_value_set_boxed (value, xedit_document_loader_get_encoding (loader));
 | 
			
		||||
			break;
 | 
			
		||||
		case PROP_NEWLINE_TYPE:
 | 
			
		||||
			g_value_set_enum (value, loader->auto_detected_newline_type);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_document_loader_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentLoader *loader = XEDIT_DOCUMENT_LOADER (object);
 | 
			
		||||
 | 
			
		||||
	g_free (loader->uri);
 | 
			
		||||
 | 
			
		||||
	if (loader->info)
 | 
			
		||||
		g_object_unref (loader->info);
 | 
			
		||||
 | 
			
		||||
	G_OBJECT_CLASS (xedit_document_loader_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_document_loader_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentLoader *loader = XEDIT_DOCUMENT_LOADER (object);
 | 
			
		||||
 | 
			
		||||
	if (loader->info != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		g_object_unref (loader->info);
 | 
			
		||||
		loader->info = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	G_OBJECT_CLASS (xedit_document_loader_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_document_loader_class_init (XeditDocumentLoaderClass *klass)
 | 
			
		||||
{
 | 
			
		||||
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
	object_class->finalize = xedit_document_loader_finalize;
 | 
			
		||||
	object_class->dispose = xedit_document_loader_dispose;
 | 
			
		||||
	object_class->get_property = xedit_document_loader_get_property;
 | 
			
		||||
	object_class->set_property = xedit_document_loader_set_property;
 | 
			
		||||
 | 
			
		||||
	g_object_class_install_property (object_class,
 | 
			
		||||
					 PROP_DOCUMENT,
 | 
			
		||||
					 g_param_spec_object ("document",
 | 
			
		||||
							      "Document",
 | 
			
		||||
							      "The XeditDocument this XeditDocumentLoader is associated with",
 | 
			
		||||
							      XEDIT_TYPE_DOCUMENT,
 | 
			
		||||
							      G_PARAM_READWRITE |
 | 
			
		||||
							      G_PARAM_CONSTRUCT_ONLY |
 | 
			
		||||
							      G_PARAM_STATIC_STRINGS));
 | 
			
		||||
 | 
			
		||||
	g_object_class_install_property (object_class,
 | 
			
		||||
					 PROP_URI,
 | 
			
		||||
					 g_param_spec_string ("uri",
 | 
			
		||||
							      "URI",
 | 
			
		||||
							      "The URI this XeditDocumentLoader loads the document from",
 | 
			
		||||
							      "",
 | 
			
		||||
							      G_PARAM_READWRITE |
 | 
			
		||||
							      G_PARAM_CONSTRUCT_ONLY));
 | 
			
		||||
 | 
			
		||||
	g_object_class_install_property (object_class,
 | 
			
		||||
					 PROP_ENCODING,
 | 
			
		||||
					 g_param_spec_boxed ("encoding",
 | 
			
		||||
							     "Encoding",
 | 
			
		||||
							     "The encoding of the saved file",
 | 
			
		||||
							     XEDIT_TYPE_ENCODING,
 | 
			
		||||
							     G_PARAM_READWRITE |
 | 
			
		||||
							     G_PARAM_CONSTRUCT_ONLY |
 | 
			
		||||
							     G_PARAM_STATIC_STRINGS));
 | 
			
		||||
 | 
			
		||||
	g_object_class_install_property (object_class, PROP_NEWLINE_TYPE,
 | 
			
		||||
	                                 g_param_spec_enum ("newline-type",
 | 
			
		||||
	                                                    "Newline type",
 | 
			
		||||
	                                                    "The accepted types of line ending",
 | 
			
		||||
	                                                    XEDIT_TYPE_DOCUMENT_NEWLINE_TYPE,
 | 
			
		||||
	                                                    XEDIT_DOCUMENT_NEWLINE_TYPE_LF,
 | 
			
		||||
	                                                    G_PARAM_READWRITE |
 | 
			
		||||
	                                                    G_PARAM_STATIC_NAME |
 | 
			
		||||
	                                                    G_PARAM_STATIC_BLURB));
 | 
			
		||||
 | 
			
		||||
	signals[LOADING] =
 | 
			
		||||
		g_signal_new ("loading",
 | 
			
		||||
			      G_OBJECT_CLASS_TYPE (object_class),
 | 
			
		||||
			      G_SIGNAL_RUN_LAST,
 | 
			
		||||
			      G_STRUCT_OFFSET (XeditDocumentLoaderClass, loading),
 | 
			
		||||
			      NULL, NULL,
 | 
			
		||||
			      xedit_marshal_VOID__BOOLEAN_POINTER,
 | 
			
		||||
			      G_TYPE_NONE,
 | 
			
		||||
			      2,
 | 
			
		||||
			      G_TYPE_BOOLEAN,
 | 
			
		||||
			      G_TYPE_POINTER);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_document_loader_init (XeditDocumentLoader *loader)
 | 
			
		||||
{
 | 
			
		||||
	loader->used = FALSE;
 | 
			
		||||
	loader->auto_detected_newline_type = XEDIT_DOCUMENT_NEWLINE_TYPE_DEFAULT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_document_loader_loading (XeditDocumentLoader *loader,
 | 
			
		||||
			       gboolean             completed,
 | 
			
		||||
			       GError              *error)
 | 
			
		||||
{
 | 
			
		||||
	/* the object will be unrefed in the callback of the loading signal
 | 
			
		||||
	 * (when completed == TRUE), so we need to prevent finalization.
 | 
			
		||||
	 */
 | 
			
		||||
	if (completed)
 | 
			
		||||
	{
 | 
			
		||||
		g_object_ref (loader);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_signal_emit (loader, signals[LOADING], 0, completed, error);
 | 
			
		||||
 | 
			
		||||
	if (completed)
 | 
			
		||||
	{
 | 
			
		||||
		if (error == NULL)
 | 
			
		||||
			xedit_debug_message (DEBUG_LOADER, "load completed");
 | 
			
		||||
		else
 | 
			
		||||
			xedit_debug_message (DEBUG_LOADER, "load failed");
 | 
			
		||||
 | 
			
		||||
		g_object_unref (loader);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This is a factory method that returns an appopriate loader
 | 
			
		||||
 * for the given uri.
 | 
			
		||||
 */
 | 
			
		||||
XeditDocumentLoader *
 | 
			
		||||
xedit_document_loader_new (XeditDocument       *doc,
 | 
			
		||||
			   const gchar         *uri,
 | 
			
		||||
			   const XeditEncoding *encoding)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentLoader *loader;
 | 
			
		||||
	GType loader_type;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_DOCUMENT (doc), NULL);
 | 
			
		||||
 | 
			
		||||
	/* At the moment we just use gio loader in all cases...
 | 
			
		||||
	 * In the future it would be great to have a PolicyKit
 | 
			
		||||
	 * loader to get permission to save systen files etc */
 | 
			
		||||
	loader_type = XEDIT_TYPE_GIO_DOCUMENT_LOADER;
 | 
			
		||||
 | 
			
		||||
	loader = XEDIT_DOCUMENT_LOADER (g_object_new (loader_type,
 | 
			
		||||
						      "document", doc,
 | 
			
		||||
						      "uri", uri,
 | 
			
		||||
						      "encoding", encoding,
 | 
			
		||||
						      NULL));
 | 
			
		||||
 | 
			
		||||
	return loader;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* If enconding == NULL, the encoding will be autodetected */
 | 
			
		||||
void
 | 
			
		||||
xedit_document_loader_load (XeditDocumentLoader *loader)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_LOADER);
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_DOCUMENT_LOADER (loader));
 | 
			
		||||
 | 
			
		||||
	/* the loader can be used just once, then it must be thrown away */
 | 
			
		||||
	g_return_if_fail (loader->used == FALSE);
 | 
			
		||||
	loader->used = TRUE;
 | 
			
		||||
 | 
			
		||||
	XEDIT_DOCUMENT_LOADER_GET_CLASS (loader)->load (loader);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean 
 | 
			
		||||
xedit_document_loader_cancel (XeditDocumentLoader *loader)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_LOADER);
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_DOCUMENT_LOADER (loader), FALSE);
 | 
			
		||||
 | 
			
		||||
	return XEDIT_DOCUMENT_LOADER_GET_CLASS (loader)->cancel (loader);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
XeditDocument *
 | 
			
		||||
xedit_document_loader_get_document (XeditDocumentLoader *loader)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_DOCUMENT_LOADER (loader), NULL);
 | 
			
		||||
 | 
			
		||||
	return loader->document;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Returns STDIN_URI if loading from stdin */
 | 
			
		||||
const gchar *
 | 
			
		||||
xedit_document_loader_get_uri (XeditDocumentLoader *loader)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_DOCUMENT_LOADER (loader), NULL);
 | 
			
		||||
 | 
			
		||||
	return loader->uri;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
goffset
 | 
			
		||||
xedit_document_loader_get_bytes_read (XeditDocumentLoader *loader)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_DOCUMENT_LOADER (loader), 0);
 | 
			
		||||
 | 
			
		||||
	return XEDIT_DOCUMENT_LOADER_GET_CLASS (loader)->get_bytes_read (loader);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const XeditEncoding *
 | 
			
		||||
xedit_document_loader_get_encoding (XeditDocumentLoader *loader)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_DOCUMENT_LOADER (loader), NULL);
 | 
			
		||||
 | 
			
		||||
	if (loader->encoding != NULL)
 | 
			
		||||
		return loader->encoding;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (loader->auto_detected_encoding != NULL, 
 | 
			
		||||
			      xedit_encoding_get_current ());
 | 
			
		||||
 | 
			
		||||
	return loader->auto_detected_encoding;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
XeditDocumentNewlineType
 | 
			
		||||
xedit_document_loader_get_newline_type (XeditDocumentLoader *loader)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_DOCUMENT_LOADER (loader),
 | 
			
		||||
			      XEDIT_DOCUMENT_NEWLINE_TYPE_LF);
 | 
			
		||||
 | 
			
		||||
	return loader->auto_detected_newline_type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GFileInfo *
 | 
			
		||||
xedit_document_loader_get_info (XeditDocumentLoader *loader)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_DOCUMENT_LOADER (loader), NULL);
 | 
			
		||||
 | 
			
		||||
	return loader->info;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										130
									
								
								xedit/xedit-document-loader.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								xedit/xedit-document-loader.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,130 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-document-loader.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2005 - Paolo Maggi
 | 
			
		||||
 * Copyright (C) 2007 - Paolo Maggi, Steve Frécinaux
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2005-2007. See the AUTHORS file for a
 | 
			
		||||
 * list of people on the xedit Team.
 | 
			
		||||
 * See the ChangeLog files for a list of changes.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_DOCUMENT_LOADER_H__
 | 
			
		||||
#define __XEDIT_DOCUMENT_LOADER_H__
 | 
			
		||||
 | 
			
		||||
#include <xedit/xedit-document.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Type checking and casting macros
 | 
			
		||||
 */
 | 
			
		||||
#define XEDIT_TYPE_DOCUMENT_LOADER              (xedit_document_loader_get_type())
 | 
			
		||||
#define XEDIT_DOCUMENT_LOADER(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), XEDIT_TYPE_DOCUMENT_LOADER, XeditDocumentLoader))
 | 
			
		||||
#define XEDIT_DOCUMENT_LOADER_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), XEDIT_TYPE_DOCUMENT_LOADER, XeditDocumentLoaderClass))
 | 
			
		||||
#define XEDIT_IS_DOCUMENT_LOADER(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), XEDIT_TYPE_DOCUMENT_LOADER))
 | 
			
		||||
#define XEDIT_IS_DOCUMENT_LOADER_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), XEDIT_TYPE_DOCUMENT_LOADER))
 | 
			
		||||
#define XEDIT_DOCUMENT_LOADER_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), XEDIT_TYPE_DOCUMENT_LOADER, XeditDocumentLoaderClass))
 | 
			
		||||
 | 
			
		||||
/* Private structure type */
 | 
			
		||||
typedef struct _XeditDocumentLoaderPrivate XeditDocumentLoaderPrivate;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Main object structure
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _XeditDocumentLoader XeditDocumentLoader;
 | 
			
		||||
 | 
			
		||||
struct _XeditDocumentLoader 
 | 
			
		||||
{
 | 
			
		||||
	GObject object;
 | 
			
		||||
 | 
			
		||||
	XeditDocument		 *document;
 | 
			
		||||
	gboolean		  used;
 | 
			
		||||
 | 
			
		||||
	/* Info on the current file */
 | 
			
		||||
	GFileInfo		 *info;
 | 
			
		||||
	gchar			 *uri;
 | 
			
		||||
	const XeditEncoding	 *encoding;
 | 
			
		||||
	const XeditEncoding	 *auto_detected_encoding;
 | 
			
		||||
	XeditDocumentNewlineType  auto_detected_newline_type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Class definition
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _XeditDocumentLoaderClass XeditDocumentLoaderClass;
 | 
			
		||||
 | 
			
		||||
struct _XeditDocumentLoaderClass 
 | 
			
		||||
{
 | 
			
		||||
	GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
	/* Signals */
 | 
			
		||||
	void (* loading) (XeditDocumentLoader *loader,
 | 
			
		||||
			  gboolean             completed,
 | 
			
		||||
			  const GError        *error);
 | 
			
		||||
 | 
			
		||||
	/* VTable */
 | 
			
		||||
	void			(* load)		(XeditDocumentLoader *loader);
 | 
			
		||||
	gboolean		(* cancel)		(XeditDocumentLoader *loader);
 | 
			
		||||
	goffset			(* get_bytes_read)	(XeditDocumentLoader *loader);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Public methods
 | 
			
		||||
 */
 | 
			
		||||
GType 		 	 xedit_document_loader_get_type		(void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
/* If enconding == NULL, the encoding will be autodetected */
 | 
			
		||||
XeditDocumentLoader 	*xedit_document_loader_new 		(XeditDocument       *doc,
 | 
			
		||||
								 const gchar         *uri,
 | 
			
		||||
								 const XeditEncoding *encoding);
 | 
			
		||||
 | 
			
		||||
void			 xedit_document_loader_loading		(XeditDocumentLoader *loader,
 | 
			
		||||
								 gboolean             completed,
 | 
			
		||||
								 GError              *error);
 | 
			
		||||
 | 
			
		||||
void			 xedit_document_loader_load		(XeditDocumentLoader *loader);
 | 
			
		||||
#if 0
 | 
			
		||||
gboolean		 xedit_document_loader_load_from_stdin	(XeditDocumentLoader *loader);
 | 
			
		||||
#endif		 
 | 
			
		||||
gboolean		 xedit_document_loader_cancel		(XeditDocumentLoader *loader);
 | 
			
		||||
 | 
			
		||||
XeditDocument		*xedit_document_loader_get_document	(XeditDocumentLoader *loader);
 | 
			
		||||
 | 
			
		||||
/* Returns STDIN_URI if loading from stdin */
 | 
			
		||||
#define STDIN_URI "stdin:" 
 | 
			
		||||
const gchar		*xedit_document_loader_get_uri		(XeditDocumentLoader *loader);
 | 
			
		||||
 | 
			
		||||
const XeditEncoding	*xedit_document_loader_get_encoding	(XeditDocumentLoader *loader);
 | 
			
		||||
 | 
			
		||||
XeditDocumentNewlineType xedit_document_loader_get_newline_type (XeditDocumentLoader *loader);
 | 
			
		||||
 | 
			
		||||
goffset			 xedit_document_loader_get_bytes_read	(XeditDocumentLoader *loader);
 | 
			
		||||
 | 
			
		||||
/* You can get from the info: content_type, time_modified, standard_size, access_can_write 
 | 
			
		||||
   and also the metadata*/
 | 
			
		||||
GFileInfo		*xedit_document_loader_get_info		(XeditDocumentLoader *loader);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif  /* __XEDIT_DOCUMENT_LOADER_H__  */
 | 
			
		||||
							
								
								
									
										419
									
								
								xedit/xedit-document-output-stream.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										419
									
								
								xedit/xedit-document-output-stream.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,419 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-document-output-stream.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2010 - Ignacio Casal Quinteiro
 | 
			
		||||
 *
 | 
			
		||||
 * xedit 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.
 | 
			
		||||
 *
 | 
			
		||||
 * xedit 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 xedit; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA  02110-1301  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
#include "xedit-document-output-stream.h"
 | 
			
		||||
 | 
			
		||||
/* NOTE: never use async methods on this stream, the stream is just
 | 
			
		||||
 * a wrapper around GtkTextBuffer api so that we can use GIO Stream
 | 
			
		||||
 * methods, but the undelying code operates on a GtkTextBuffer, so
 | 
			
		||||
 * there is no I/O involved and should be accessed only by the main
 | 
			
		||||
 * thread */
 | 
			
		||||
 | 
			
		||||
#define XEDIT_DOCUMENT_OUTPUT_STREAM_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object),\
 | 
			
		||||
							 XEDIT_TYPE_DOCUMENT_OUTPUT_STREAM,\
 | 
			
		||||
							 XeditDocumentOutputStreamPrivate))
 | 
			
		||||
 | 
			
		||||
#define MAX_UNICHAR_LEN 6
 | 
			
		||||
 | 
			
		||||
struct _XeditDocumentOutputStreamPrivate
 | 
			
		||||
{
 | 
			
		||||
	XeditDocument *doc;
 | 
			
		||||
	GtkTextIter    pos;
 | 
			
		||||
 | 
			
		||||
	gchar *buffer;
 | 
			
		||||
	gsize buflen;
 | 
			
		||||
 | 
			
		||||
	guint is_initialized : 1;
 | 
			
		||||
	guint is_closed : 1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
	PROP_0,
 | 
			
		||||
	PROP_DOCUMENT
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (XeditDocumentOutputStream, xedit_document_output_stream, G_TYPE_OUTPUT_STREAM)
 | 
			
		||||
 | 
			
		||||
static gssize	xedit_document_output_stream_write (GOutputStream            *stream,
 | 
			
		||||
						    const void               *buffer,
 | 
			
		||||
						    gsize                     count,
 | 
			
		||||
						    GCancellable             *cancellable,
 | 
			
		||||
						    GError                  **error);
 | 
			
		||||
 | 
			
		||||
static gboolean xedit_document_output_stream_flush (GOutputStream *stream,
 | 
			
		||||
                                                    GCancellable  *cancellable,
 | 
			
		||||
                                                    GError        **error);
 | 
			
		||||
 | 
			
		||||
static gboolean	xedit_document_output_stream_close (GOutputStream     *stream,
 | 
			
		||||
						    GCancellable      *cancellable,
 | 
			
		||||
						    GError           **error);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_document_output_stream_set_property (GObject      *object,
 | 
			
		||||
					   guint         prop_id,
 | 
			
		||||
					   const GValue *value,
 | 
			
		||||
					   GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentOutputStream *stream = XEDIT_DOCUMENT_OUTPUT_STREAM (object);
 | 
			
		||||
 | 
			
		||||
	switch (prop_id)
 | 
			
		||||
	{
 | 
			
		||||
		case PROP_DOCUMENT:
 | 
			
		||||
			stream->priv->doc = XEDIT_DOCUMENT (g_value_get_object (value));
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_document_output_stream_get_property (GObject    *object,
 | 
			
		||||
					   guint       prop_id,
 | 
			
		||||
					   GValue     *value,
 | 
			
		||||
					   GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentOutputStream *stream = XEDIT_DOCUMENT_OUTPUT_STREAM (object);
 | 
			
		||||
 | 
			
		||||
	switch (prop_id)
 | 
			
		||||
	{
 | 
			
		||||
		case PROP_DOCUMENT:
 | 
			
		||||
			g_value_set_object (value, stream->priv->doc);
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_document_output_stream_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentOutputStream *stream = XEDIT_DOCUMENT_OUTPUT_STREAM (object);
 | 
			
		||||
 | 
			
		||||
	g_free (stream->priv->buffer);
 | 
			
		||||
 | 
			
		||||
	G_OBJECT_CLASS (xedit_document_output_stream_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_document_output_stream_constructed (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentOutputStream *stream = XEDIT_DOCUMENT_OUTPUT_STREAM (object);
 | 
			
		||||
 | 
			
		||||
	if (!stream->priv->doc)
 | 
			
		||||
	{
 | 
			
		||||
		g_critical ("This should never happen, a problem happened constructing the Document Output Stream!");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Init the undoable action */
 | 
			
		||||
	gtk_source_buffer_begin_not_undoable_action (GTK_SOURCE_BUFFER (stream->priv->doc));
 | 
			
		||||
	/* clear the buffer */
 | 
			
		||||
	gtk_text_buffer_set_text (GTK_TEXT_BUFFER (stream->priv->doc),
 | 
			
		||||
				  "", 0);
 | 
			
		||||
	gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (stream->priv->doc),
 | 
			
		||||
				      FALSE);
 | 
			
		||||
 | 
			
		||||
	gtk_source_buffer_end_not_undoable_action (GTK_SOURCE_BUFFER (stream->priv->doc));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_document_output_stream_class_init (XeditDocumentOutputStreamClass *klass)
 | 
			
		||||
{
 | 
			
		||||
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
	GOutputStreamClass *stream_class = G_OUTPUT_STREAM_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
	object_class->get_property = xedit_document_output_stream_get_property;
 | 
			
		||||
	object_class->set_property = xedit_document_output_stream_set_property;
 | 
			
		||||
	object_class->finalize = xedit_document_output_stream_finalize;
 | 
			
		||||
	object_class->constructed = xedit_document_output_stream_constructed;
 | 
			
		||||
 | 
			
		||||
	stream_class->write_fn = xedit_document_output_stream_write;
 | 
			
		||||
	stream_class->flush = xedit_document_output_stream_flush;
 | 
			
		||||
	stream_class->close_fn = xedit_document_output_stream_close;
 | 
			
		||||
 | 
			
		||||
	g_object_class_install_property (object_class,
 | 
			
		||||
					 PROP_DOCUMENT,
 | 
			
		||||
					 g_param_spec_object ("document",
 | 
			
		||||
							      "Document",
 | 
			
		||||
							      "The document which is written",
 | 
			
		||||
							      XEDIT_TYPE_DOCUMENT,
 | 
			
		||||
							      G_PARAM_READWRITE |
 | 
			
		||||
							      G_PARAM_CONSTRUCT_ONLY));
 | 
			
		||||
 | 
			
		||||
	g_type_class_add_private (object_class, sizeof (XeditDocumentOutputStreamPrivate));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_document_output_stream_init (XeditDocumentOutputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
	stream->priv = XEDIT_DOCUMENT_OUTPUT_STREAM_GET_PRIVATE (stream);
 | 
			
		||||
 | 
			
		||||
	stream->priv->buffer = NULL;
 | 
			
		||||
	stream->priv->buflen = 0;
 | 
			
		||||
 | 
			
		||||
	stream->priv->is_initialized = FALSE;
 | 
			
		||||
	stream->priv->is_closed = FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static XeditDocumentNewlineType
 | 
			
		||||
get_newline_type (GtkTextIter *end)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentNewlineType res;
 | 
			
		||||
	GtkTextIter copy;
 | 
			
		||||
	gunichar c;
 | 
			
		||||
 | 
			
		||||
	copy = *end;
 | 
			
		||||
	c = gtk_text_iter_get_char (©);
 | 
			
		||||
 | 
			
		||||
	if (g_unichar_break_type (c) == G_UNICODE_BREAK_CARRIAGE_RETURN)
 | 
			
		||||
	{
 | 
			
		||||
		if (gtk_text_iter_forward_char (©) &&
 | 
			
		||||
		    g_unichar_break_type (gtk_text_iter_get_char (©)) == G_UNICODE_BREAK_LINE_FEED)
 | 
			
		||||
		{
 | 
			
		||||
			res = XEDIT_DOCUMENT_NEWLINE_TYPE_CR_LF;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			res = XEDIT_DOCUMENT_NEWLINE_TYPE_CR;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		res = XEDIT_DOCUMENT_NEWLINE_TYPE_LF;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GOutputStream *
 | 
			
		||||
xedit_document_output_stream_new (XeditDocument *doc)
 | 
			
		||||
{
 | 
			
		||||
	return G_OUTPUT_STREAM (g_object_new (XEDIT_TYPE_DOCUMENT_OUTPUT_STREAM,
 | 
			
		||||
					      "document", doc, NULL));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
XeditDocumentNewlineType
 | 
			
		||||
xedit_document_output_stream_detect_newline_type (XeditDocumentOutputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentNewlineType type;
 | 
			
		||||
	GtkTextIter iter;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_DOCUMENT_OUTPUT_STREAM (stream),
 | 
			
		||||
			      XEDIT_DOCUMENT_NEWLINE_TYPE_DEFAULT);
 | 
			
		||||
 | 
			
		||||
	type = XEDIT_DOCUMENT_NEWLINE_TYPE_DEFAULT;
 | 
			
		||||
 | 
			
		||||
	gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (stream->priv->doc),
 | 
			
		||||
					&iter);
 | 
			
		||||
 | 
			
		||||
	if (gtk_text_iter_ends_line (&iter) || gtk_text_iter_forward_to_line_end (&iter))
 | 
			
		||||
	{
 | 
			
		||||
		type = get_newline_type (&iter);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* If the last char is a newline, remove it from the buffer (otherwise
 | 
			
		||||
   GtkTextView shows it as an empty line). See bug #324942. */
 | 
			
		||||
static void
 | 
			
		||||
remove_ending_newline (XeditDocumentOutputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
	GtkTextIter end;
 | 
			
		||||
	GtkTextIter start;
 | 
			
		||||
 | 
			
		||||
	gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (stream->priv->doc), &end);
 | 
			
		||||
	start = end;
 | 
			
		||||
 | 
			
		||||
	gtk_text_iter_set_line_offset (&start, 0);
 | 
			
		||||
 | 
			
		||||
	if (gtk_text_iter_ends_line (&start) &&
 | 
			
		||||
	    gtk_text_iter_backward_line (&start))
 | 
			
		||||
	{
 | 
			
		||||
		if (!gtk_text_iter_ends_line (&start))
 | 
			
		||||
		{
 | 
			
		||||
			gtk_text_iter_forward_to_line_end (&start);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Delete the empty line which is from 'start' to 'end' */
 | 
			
		||||
		gtk_text_buffer_delete (GTK_TEXT_BUFFER (stream->priv->doc),
 | 
			
		||||
		                        &start,
 | 
			
		||||
		                        &end);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
end_append_text_to_document (XeditDocumentOutputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
	remove_ending_newline (stream);
 | 
			
		||||
 | 
			
		||||
	gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (stream->priv->doc),
 | 
			
		||||
				      FALSE);
 | 
			
		||||
 | 
			
		||||
	gtk_source_buffer_end_not_undoable_action (GTK_SOURCE_BUFFER (stream->priv->doc));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gssize
 | 
			
		||||
xedit_document_output_stream_write (GOutputStream            *stream,
 | 
			
		||||
				    const void               *buffer,
 | 
			
		||||
				    gsize                     count,
 | 
			
		||||
				    GCancellable             *cancellable,
 | 
			
		||||
				    GError                  **error)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentOutputStream *ostream;
 | 
			
		||||
	gchar *text;
 | 
			
		||||
	gsize len;
 | 
			
		||||
	gboolean freetext = FALSE;
 | 
			
		||||
	const gchar *end;
 | 
			
		||||
	gboolean valid;
 | 
			
		||||
 | 
			
		||||
	if (g_cancellable_set_error_if_cancelled (cancellable, error))
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	ostream = XEDIT_DOCUMENT_OUTPUT_STREAM (stream);
 | 
			
		||||
 | 
			
		||||
	if (!ostream->priv->is_initialized)
 | 
			
		||||
	{
 | 
			
		||||
		/* Init the undoable action */
 | 
			
		||||
		gtk_source_buffer_begin_not_undoable_action (GTK_SOURCE_BUFFER (ostream->priv->doc));
 | 
			
		||||
 | 
			
		||||
		gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (ostream->priv->doc),
 | 
			
		||||
						&ostream->priv->pos);
 | 
			
		||||
		ostream->priv->is_initialized = TRUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ostream->priv->buflen > 0)
 | 
			
		||||
	{
 | 
			
		||||
		len = ostream->priv->buflen + count;
 | 
			
		||||
		text = g_new (gchar , len + 1);
 | 
			
		||||
		memcpy (text, ostream->priv->buffer, ostream->priv->buflen);
 | 
			
		||||
		memcpy (text + ostream->priv->buflen, buffer, count);
 | 
			
		||||
		text[len] = '\0';
 | 
			
		||||
		g_free (ostream->priv->buffer);
 | 
			
		||||
		ostream->priv->buffer = NULL;
 | 
			
		||||
		ostream->priv->buflen = 0;
 | 
			
		||||
		freetext = TRUE;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		text = (gchar *) buffer;
 | 
			
		||||
		len = count;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* validate */
 | 
			
		||||
	valid = g_utf8_validate (text, len, &end);
 | 
			
		||||
 | 
			
		||||
	/* Avoid keeping a CRLF across two buffers. */
 | 
			
		||||
	if (valid && len > 1 && end[-1] == '\r')
 | 
			
		||||
	{
 | 
			
		||||
		valid = FALSE;
 | 
			
		||||
		end--;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!valid)
 | 
			
		||||
	{
 | 
			
		||||
		gsize nvalid = end - text;
 | 
			
		||||
		gsize remainder = len - nvalid;
 | 
			
		||||
		gunichar ch;
 | 
			
		||||
 | 
			
		||||
		if ((remainder < MAX_UNICHAR_LEN) &&
 | 
			
		||||
		    ((ch = g_utf8_get_char_validated (text + nvalid, remainder)) == (gunichar)-2 ||
 | 
			
		||||
		     ch == (gunichar)'\r'))
 | 
			
		||||
		{
 | 
			
		||||
			ostream->priv->buffer = g_strndup (end, remainder);
 | 
			
		||||
			ostream->priv->buflen = remainder;
 | 
			
		||||
			len -= remainder;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			/* TODO: we could escape invalid text and tag it in red
 | 
			
		||||
			 * and make the doc readonly.
 | 
			
		||||
			 */
 | 
			
		||||
			g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
 | 
			
		||||
				     _("Invalid UTF-8 sequence in input"));
 | 
			
		||||
 | 
			
		||||
			if (freetext)
 | 
			
		||||
				g_free (text);
 | 
			
		||||
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gtk_text_buffer_insert (GTK_TEXT_BUFFER (ostream->priv->doc),
 | 
			
		||||
				&ostream->priv->pos, text, len);
 | 
			
		||||
 | 
			
		||||
	if (freetext)
 | 
			
		||||
		g_free (text);
 | 
			
		||||
 | 
			
		||||
	return count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
xedit_document_output_stream_flush (GOutputStream *stream,
 | 
			
		||||
                                    GCancellable  *cancellable,
 | 
			
		||||
                                    GError        **error)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentOutputStream *ostream = XEDIT_DOCUMENT_OUTPUT_STREAM (stream);
 | 
			
		||||
 | 
			
		||||
	/* Flush deferred data if some. */
 | 
			
		||||
	if (!ostream->priv->is_closed && ostream->priv->is_initialized &&
 | 
			
		||||
	    ostream->priv->buflen > 0 &&
 | 
			
		||||
	    xedit_document_output_stream_write (stream, "", 0, cancellable,
 | 
			
		||||
						error) == -1)
 | 
			
		||||
		return FALSE;
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
xedit_document_output_stream_close (GOutputStream     *stream,
 | 
			
		||||
				    GCancellable      *cancellable,
 | 
			
		||||
				    GError           **error)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentOutputStream *ostream = XEDIT_DOCUMENT_OUTPUT_STREAM (stream);
 | 
			
		||||
 | 
			
		||||
	if (!ostream->priv->is_closed && ostream->priv->is_initialized)
 | 
			
		||||
	{
 | 
			
		||||
		end_append_text_to_document (ostream);
 | 
			
		||||
		ostream->priv->is_closed = TRUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ostream->priv->buflen > 0)
 | 
			
		||||
	{
 | 
			
		||||
		g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
 | 
			
		||||
			     _("Incomplete UTF-8 sequence in input"));
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										64
									
								
								xedit/xedit-document-output-stream.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								xedit/xedit-document-output-stream.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-document-output-stream.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2010 - Ignacio Casal Quinteiro
 | 
			
		||||
 *
 | 
			
		||||
 * xedit 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.
 | 
			
		||||
 *
 | 
			
		||||
 * xedit 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 xedit; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA  02110-1301  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_DOCUMENT_OUTPUT_STREAM_H__
 | 
			
		||||
#define __XEDIT_DOCUMENT_OUTPUT_STREAM_H__
 | 
			
		||||
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
#include "xedit-document.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define XEDIT_TYPE_DOCUMENT_OUTPUT_STREAM		(xedit_document_output_stream_get_type ())
 | 
			
		||||
#define XEDIT_DOCUMENT_OUTPUT_STREAM(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), XEDIT_TYPE_DOCUMENT_OUTPUT_STREAM, XeditDocumentOutputStream))
 | 
			
		||||
#define XEDIT_DOCUMENT_OUTPUT_STREAM_CONST(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), XEDIT_TYPE_DOCUMENT_OUTPUT_STREAM, XeditDocumentOutputStream const))
 | 
			
		||||
#define XEDIT_DOCUMENT_OUTPUT_STREAM_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), XEDIT_TYPE_DOCUMENT_OUTPUT_STREAM, XeditDocumentOutputStreamClass))
 | 
			
		||||
#define XEDIT_IS_DOCUMENT_OUTPUT_STREAM(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), XEDIT_TYPE_DOCUMENT_OUTPUT_STREAM))
 | 
			
		||||
#define XEDIT_IS_DOCUMENT_OUTPUT_STREAM_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), XEDIT_TYPE_DOCUMENT_OUTPUT_STREAM))
 | 
			
		||||
#define XEDIT_DOCUMENT_OUTPUT_STREAM_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), XEDIT_TYPE_DOCUMENT_OUTPUT_STREAM, XeditDocumentOutputStreamClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _XeditDocumentOutputStream		XeditDocumentOutputStream;
 | 
			
		||||
typedef struct _XeditDocumentOutputStreamClass		XeditDocumentOutputStreamClass;
 | 
			
		||||
typedef struct _XeditDocumentOutputStreamPrivate	XeditDocumentOutputStreamPrivate;
 | 
			
		||||
 | 
			
		||||
struct _XeditDocumentOutputStream
 | 
			
		||||
{
 | 
			
		||||
	GOutputStream parent;
 | 
			
		||||
 | 
			
		||||
	XeditDocumentOutputStreamPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _XeditDocumentOutputStreamClass
 | 
			
		||||
{
 | 
			
		||||
	GOutputStreamClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType			 xedit_document_output_stream_get_type		(void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
GOutputStream		*xedit_document_output_stream_new		(XeditDocument *doc);
 | 
			
		||||
 | 
			
		||||
XeditDocumentNewlineType xedit_document_output_stream_detect_newline_type (XeditDocumentOutputStream *stream);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __XEDIT_DOCUMENT_OUTPUT_STREAM_H__ */
 | 
			
		||||
							
								
								
									
										359
									
								
								xedit/xedit-document-saver.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										359
									
								
								xedit/xedit-document-saver.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,359 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-document-saver.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2005-2006 - Paolo Borelli and Paolo Maggi
 | 
			
		||||
 * Copyright (C) 2007 - Paolo Borelli, Paolo Maggi, Steve Frécinaux
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor,
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2005-2006. See the AUTHORS file for a
 | 
			
		||||
 * list of people on the xedit Team.
 | 
			
		||||
 * See the ChangeLog files for a list of changes.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
 | 
			
		||||
#include "xedit-document-saver.h"
 | 
			
		||||
#include "xedit-debug.h"
 | 
			
		||||
#include "xedit-prefs-manager.h"
 | 
			
		||||
#include "xedit-marshal.h"
 | 
			
		||||
#include "xedit-utils.h"
 | 
			
		||||
#include "xedit-enum-types.h"
 | 
			
		||||
#include "xedit-gio-document-saver.h"
 | 
			
		||||
 | 
			
		||||
G_DEFINE_ABSTRACT_TYPE(XeditDocumentSaver, xedit_document_saver, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
/* Signals */
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
	SAVING,
 | 
			
		||||
	LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0 };
 | 
			
		||||
 | 
			
		||||
/* Properties */
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
	PROP_0,
 | 
			
		||||
	PROP_DOCUMENT,
 | 
			
		||||
	PROP_URI,
 | 
			
		||||
	PROP_ENCODING,
 | 
			
		||||
	PROP_NEWLINE_TYPE,
 | 
			
		||||
	PROP_FLAGS
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_document_saver_set_property (GObject      *object,
 | 
			
		||||
				   guint         prop_id,
 | 
			
		||||
				   const GValue *value,
 | 
			
		||||
				   GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentSaver *saver = XEDIT_DOCUMENT_SAVER (object);
 | 
			
		||||
 | 
			
		||||
	switch (prop_id)
 | 
			
		||||
	{
 | 
			
		||||
		case PROP_DOCUMENT:
 | 
			
		||||
			g_return_if_fail (saver->document == NULL);
 | 
			
		||||
			saver->document = g_value_get_object (value);
 | 
			
		||||
			break;
 | 
			
		||||
		case PROP_URI:
 | 
			
		||||
			g_return_if_fail (saver->uri == NULL);
 | 
			
		||||
			saver->uri = g_value_dup_string (value);
 | 
			
		||||
			break;
 | 
			
		||||
		case PROP_ENCODING:
 | 
			
		||||
			g_return_if_fail (saver->encoding == NULL);
 | 
			
		||||
			saver->encoding = g_value_get_boxed (value);
 | 
			
		||||
			break;
 | 
			
		||||
		case PROP_NEWLINE_TYPE:
 | 
			
		||||
			saver->newline_type = g_value_get_enum (value);
 | 
			
		||||
			break;
 | 
			
		||||
		case PROP_FLAGS:
 | 
			
		||||
			saver->flags = g_value_get_flags (value);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_document_saver_get_property (GObject    *object,
 | 
			
		||||
				   guint       prop_id,
 | 
			
		||||
				   GValue     *value,
 | 
			
		||||
				   GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentSaver *saver = XEDIT_DOCUMENT_SAVER (object);
 | 
			
		||||
 | 
			
		||||
	switch (prop_id)
 | 
			
		||||
	{
 | 
			
		||||
		case PROP_DOCUMENT:
 | 
			
		||||
			g_value_set_object (value, saver->document);
 | 
			
		||||
			break;
 | 
			
		||||
		case PROP_URI:
 | 
			
		||||
			g_value_set_string (value, saver->uri);
 | 
			
		||||
			break;
 | 
			
		||||
		case PROP_ENCODING:
 | 
			
		||||
			g_value_set_boxed (value, saver->encoding);
 | 
			
		||||
			break;
 | 
			
		||||
		case PROP_NEWLINE_TYPE:
 | 
			
		||||
			g_value_set_enum (value, saver->newline_type);
 | 
			
		||||
			break;
 | 
			
		||||
		case PROP_FLAGS:
 | 
			
		||||
			g_value_set_flags (value, saver->flags);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_document_saver_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentSaver *saver = XEDIT_DOCUMENT_SAVER (object);
 | 
			
		||||
 | 
			
		||||
	g_free (saver->uri);
 | 
			
		||||
 | 
			
		||||
	G_OBJECT_CLASS (xedit_document_saver_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_document_saver_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentSaver *saver = XEDIT_DOCUMENT_SAVER (object);
 | 
			
		||||
 | 
			
		||||
	if (saver->info != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		g_object_unref (saver->info);
 | 
			
		||||
		saver->info = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	G_OBJECT_CLASS (xedit_document_saver_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
xedit_document_saver_class_init (XeditDocumentSaverClass *klass)
 | 
			
		||||
{
 | 
			
		||||
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
	object_class->finalize = xedit_document_saver_finalize;
 | 
			
		||||
	object_class->dispose = xedit_document_saver_dispose;
 | 
			
		||||
	object_class->set_property = xedit_document_saver_set_property;
 | 
			
		||||
	object_class->get_property = xedit_document_saver_get_property;
 | 
			
		||||
 | 
			
		||||
	g_object_class_install_property (object_class,
 | 
			
		||||
					 PROP_DOCUMENT,
 | 
			
		||||
					 g_param_spec_object ("document",
 | 
			
		||||
							      "Document",
 | 
			
		||||
							      "The XeditDocument this XeditDocumentSaver is associated with",
 | 
			
		||||
							      XEDIT_TYPE_DOCUMENT,
 | 
			
		||||
							      G_PARAM_READWRITE |
 | 
			
		||||
							      G_PARAM_CONSTRUCT_ONLY |
 | 
			
		||||
							      G_PARAM_STATIC_STRINGS));
 | 
			
		||||
 | 
			
		||||
	g_object_class_install_property (object_class,
 | 
			
		||||
					 PROP_URI,
 | 
			
		||||
					 g_param_spec_string ("uri",
 | 
			
		||||
							      "URI",
 | 
			
		||||
							      "The URI this XeditDocumentSaver saves the document to",
 | 
			
		||||
							      "",
 | 
			
		||||
							      G_PARAM_READWRITE |
 | 
			
		||||
							      G_PARAM_CONSTRUCT_ONLY |
 | 
			
		||||
							      G_PARAM_STATIC_STRINGS));
 | 
			
		||||
 | 
			
		||||
	g_object_class_install_property (object_class,
 | 
			
		||||
					 PROP_ENCODING,
 | 
			
		||||
					 g_param_spec_boxed ("encoding",
 | 
			
		||||
							     "URI",
 | 
			
		||||
							     "The encoding of the saved file",
 | 
			
		||||
							     XEDIT_TYPE_ENCODING,
 | 
			
		||||
							     G_PARAM_READWRITE |
 | 
			
		||||
							     G_PARAM_CONSTRUCT_ONLY |
 | 
			
		||||
							     G_PARAM_STATIC_STRINGS));
 | 
			
		||||
 | 
			
		||||
	g_object_class_install_property (object_class,
 | 
			
		||||
					 PROP_NEWLINE_TYPE,
 | 
			
		||||
					 g_param_spec_enum ("newline-type",
 | 
			
		||||
					                    "Newline type",
 | 
			
		||||
					                    "The accepted types of line ending",
 | 
			
		||||
					                    XEDIT_TYPE_DOCUMENT_NEWLINE_TYPE,
 | 
			
		||||
					                    XEDIT_DOCUMENT_NEWLINE_TYPE_LF,
 | 
			
		||||
					                    G_PARAM_READWRITE |
 | 
			
		||||
					                    G_PARAM_STATIC_NAME |
 | 
			
		||||
					                    G_PARAM_STATIC_BLURB |
 | 
			
		||||
					                    G_PARAM_CONSTRUCT_ONLY));
 | 
			
		||||
 | 
			
		||||
	g_object_class_install_property (object_class,
 | 
			
		||||
					 PROP_FLAGS,
 | 
			
		||||
					 g_param_spec_flags ("flags",
 | 
			
		||||
							     "Flags",
 | 
			
		||||
							     "The flags for the saving operation",
 | 
			
		||||
							     XEDIT_TYPE_DOCUMENT_SAVE_FLAGS,
 | 
			
		||||
							     0,
 | 
			
		||||
							     G_PARAM_READWRITE |
 | 
			
		||||
							     G_PARAM_CONSTRUCT_ONLY));
 | 
			
		||||
 | 
			
		||||
	signals[SAVING] =
 | 
			
		||||
		g_signal_new ("saving",
 | 
			
		||||
			      G_OBJECT_CLASS_TYPE (object_class),
 | 
			
		||||
			      G_SIGNAL_RUN_LAST,
 | 
			
		||||
			      G_STRUCT_OFFSET (XeditDocumentSaverClass, saving),
 | 
			
		||||
			      NULL, NULL,
 | 
			
		||||
			      xedit_marshal_VOID__BOOLEAN_POINTER,
 | 
			
		||||
			      G_TYPE_NONE,
 | 
			
		||||
			      2,
 | 
			
		||||
			      G_TYPE_BOOLEAN,
 | 
			
		||||
			      G_TYPE_POINTER);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_document_saver_init (XeditDocumentSaver *saver)
 | 
			
		||||
{
 | 
			
		||||
	saver->used = FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
XeditDocumentSaver *
 | 
			
		||||
xedit_document_saver_new (XeditDocument           *doc,
 | 
			
		||||
			  const gchar             *uri,
 | 
			
		||||
			  const XeditEncoding     *encoding,
 | 
			
		||||
			  XeditDocumentNewlineType newline_type,
 | 
			
		||||
			  XeditDocumentSaveFlags   flags)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentSaver *saver;
 | 
			
		||||
	GType saver_type;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_DOCUMENT (doc), NULL);
 | 
			
		||||
 | 
			
		||||
	saver_type = XEDIT_TYPE_GIO_DOCUMENT_SAVER;
 | 
			
		||||
 | 
			
		||||
	if (encoding == NULL)
 | 
			
		||||
		encoding = xedit_encoding_get_utf8 ();
 | 
			
		||||
 | 
			
		||||
	saver = XEDIT_DOCUMENT_SAVER (g_object_new (saver_type,
 | 
			
		||||
						    "document", doc,
 | 
			
		||||
						    "uri", uri,
 | 
			
		||||
						    "encoding", encoding,
 | 
			
		||||
						    "newline_type", newline_type,
 | 
			
		||||
						    "flags", flags,
 | 
			
		||||
						    NULL));
 | 
			
		||||
 | 
			
		||||
	return saver;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_document_saver_saving (XeditDocumentSaver *saver,
 | 
			
		||||
			     gboolean            completed,
 | 
			
		||||
			     GError             *error)
 | 
			
		||||
{
 | 
			
		||||
	/* the object will be unrefed in the callback of the saving
 | 
			
		||||
	 * signal, so we need to prevent finalization.
 | 
			
		||||
	 */
 | 
			
		||||
	if (completed)
 | 
			
		||||
	{
 | 
			
		||||
		g_object_ref (saver);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_signal_emit (saver, signals[SAVING], 0, completed, error);
 | 
			
		||||
 | 
			
		||||
	if (completed)
 | 
			
		||||
	{
 | 
			
		||||
		if (error == NULL)
 | 
			
		||||
			xedit_debug_message (DEBUG_SAVER, "save completed");
 | 
			
		||||
		else
 | 
			
		||||
			xedit_debug_message (DEBUG_SAVER, "save failed");
 | 
			
		||||
 | 
			
		||||
		g_object_unref (saver);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_document_saver_save (XeditDocumentSaver     *saver,
 | 
			
		||||
			   GTimeVal               *old_mtime)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_SAVER);
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_DOCUMENT_SAVER (saver));
 | 
			
		||||
	g_return_if_fail (saver->uri != NULL && strlen (saver->uri) > 0);
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (saver->used == FALSE);
 | 
			
		||||
	saver->used = TRUE;
 | 
			
		||||
 | 
			
		||||
	// CHECK:
 | 
			
		||||
	// - sanity check a max len for the uri?
 | 
			
		||||
	// report async (in an idle handler) or sync (bool ret)
 | 
			
		||||
	// async is extra work here, sync is special casing in the caller
 | 
			
		||||
 | 
			
		||||
	/* never keep backup of autosaves */
 | 
			
		||||
	if ((saver->flags & XEDIT_DOCUMENT_SAVE_PRESERVE_BACKUP) != 0)
 | 
			
		||||
		saver->keep_backup = FALSE;
 | 
			
		||||
	else
 | 
			
		||||
		saver->keep_backup = xedit_prefs_manager_get_create_backup_copy ();
 | 
			
		||||
 | 
			
		||||
	XEDIT_DOCUMENT_SAVER_GET_CLASS (saver)->save (saver, old_mtime);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
XeditDocument *
 | 
			
		||||
xedit_document_saver_get_document (XeditDocumentSaver *saver)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_DOCUMENT_SAVER (saver), NULL);
 | 
			
		||||
 | 
			
		||||
	return saver->document;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const gchar *
 | 
			
		||||
xedit_document_saver_get_uri (XeditDocumentSaver *saver)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_DOCUMENT_SAVER (saver), NULL);
 | 
			
		||||
 | 
			
		||||
	return saver->uri;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Returns 0 if file size is unknown */
 | 
			
		||||
goffset
 | 
			
		||||
xedit_document_saver_get_file_size (XeditDocumentSaver *saver)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_DOCUMENT_SAVER (saver), 0);
 | 
			
		||||
 | 
			
		||||
	return XEDIT_DOCUMENT_SAVER_GET_CLASS (saver)->get_file_size (saver);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
goffset
 | 
			
		||||
xedit_document_saver_get_bytes_written (XeditDocumentSaver *saver)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_DOCUMENT_SAVER (saver), 0);
 | 
			
		||||
 | 
			
		||||
	return XEDIT_DOCUMENT_SAVER_GET_CLASS (saver)->get_bytes_written (saver);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GFileInfo *
 | 
			
		||||
xedit_document_saver_get_info (XeditDocumentSaver *saver)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_DOCUMENT_SAVER (saver), NULL);
 | 
			
		||||
 | 
			
		||||
	return saver->info;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										133
									
								
								xedit/xedit-document-saver.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								xedit/xedit-document-saver.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,133 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-document-saver.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2005 - Paolo Maggi
 | 
			
		||||
 * Copyrhing (C) 2007 - Paolo Maggi, Steve Frécinaux
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor,
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2005. See the AUTHORS file for a
 | 
			
		||||
 * list of people on the xedit Team.
 | 
			
		||||
 * See the ChangeLog files for a list of changes.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_DOCUMENT_SAVER_H__
 | 
			
		||||
#define __XEDIT_DOCUMENT_SAVER_H__
 | 
			
		||||
 | 
			
		||||
#include <xedit/xedit-document.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Type checking and casting macros
 | 
			
		||||
 */
 | 
			
		||||
#define XEDIT_TYPE_DOCUMENT_SAVER              (xedit_document_saver_get_type())
 | 
			
		||||
#define XEDIT_DOCUMENT_SAVER(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), XEDIT_TYPE_DOCUMENT_SAVER, XeditDocumentSaver))
 | 
			
		||||
#define XEDIT_DOCUMENT_SAVER_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), XEDIT_TYPE_DOCUMENT_SAVER, XeditDocumentSaverClass))
 | 
			
		||||
#define XEDIT_IS_DOCUMENT_SAVER(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), XEDIT_TYPE_DOCUMENT_SAVER))
 | 
			
		||||
#define XEDIT_IS_DOCUMENT_SAVER_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), XEDIT_TYPE_DOCUMENT_SAVER))
 | 
			
		||||
#define XEDIT_DOCUMENT_SAVER_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), XEDIT_TYPE_DOCUMENT_SAVER, XeditDocumentSaverClass))
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Main object structure
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _XeditDocumentSaver XeditDocumentSaver;
 | 
			
		||||
 | 
			
		||||
struct _XeditDocumentSaver 
 | 
			
		||||
{
 | 
			
		||||
	GObject object;
 | 
			
		||||
 | 
			
		||||
	/*< private >*/
 | 
			
		||||
	GFileInfo		 *info;
 | 
			
		||||
	XeditDocument		 *document;
 | 
			
		||||
	gboolean		  used;
 | 
			
		||||
 | 
			
		||||
	gchar			 *uri;
 | 
			
		||||
	const XeditEncoding      *encoding;
 | 
			
		||||
	XeditDocumentNewlineType  newline_type;
 | 
			
		||||
 | 
			
		||||
	XeditDocumentSaveFlags    flags;
 | 
			
		||||
 | 
			
		||||
	gboolean		  keep_backup;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Class definition
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _XeditDocumentSaverClass XeditDocumentSaverClass;
 | 
			
		||||
 | 
			
		||||
struct _XeditDocumentSaverClass 
 | 
			
		||||
{
 | 
			
		||||
	GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
	/* Signals */
 | 
			
		||||
	void (* saving) (XeditDocumentSaver *saver,
 | 
			
		||||
			 gboolean             completed,
 | 
			
		||||
			 const GError        *error);
 | 
			
		||||
 | 
			
		||||
	/* VTable */
 | 
			
		||||
	void			(* save)		(XeditDocumentSaver *saver,
 | 
			
		||||
							 GTimeVal           *old_mtime);
 | 
			
		||||
	goffset			(* get_file_size)	(XeditDocumentSaver *saver);
 | 
			
		||||
	goffset			(* get_bytes_written)	(XeditDocumentSaver *saver);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Public methods
 | 
			
		||||
 */
 | 
			
		||||
GType 		 	 xedit_document_saver_get_type		(void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
/* If enconding == NULL, the encoding will be autodetected */
 | 
			
		||||
XeditDocumentSaver 	*xedit_document_saver_new 		(XeditDocument           *doc,
 | 
			
		||||
								 const gchar             *uri,
 | 
			
		||||
								 const XeditEncoding     *encoding,
 | 
			
		||||
								 XeditDocumentNewlineType newline_type,
 | 
			
		||||
								 XeditDocumentSaveFlags   flags);
 | 
			
		||||
 | 
			
		||||
void			 xedit_document_saver_saving		(XeditDocumentSaver *saver,
 | 
			
		||||
								 gboolean            completed,
 | 
			
		||||
								 GError             *error);
 | 
			
		||||
void			 xedit_document_saver_save		(XeditDocumentSaver  *saver,
 | 
			
		||||
								 GTimeVal            *old_mtime);
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
void			 xedit_document_saver_cancel		(XeditDocumentSaver  *saver);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
XeditDocument		*xedit_document_saver_get_document	(XeditDocumentSaver  *saver);
 | 
			
		||||
 | 
			
		||||
const gchar		*xedit_document_saver_get_uri		(XeditDocumentSaver  *saver);
 | 
			
		||||
 | 
			
		||||
/* If backup_uri is NULL no backup will be made */
 | 
			
		||||
const gchar		*xedit_document_saver_get_backup_uri	(XeditDocumentSaver  *saver);
 | 
			
		||||
void			*xedit_document_saver_set_backup_uri	(XeditDocumentSaver  *saver,
 | 
			
		||||
							 	 const gchar         *backup_uri);
 | 
			
		||||
 | 
			
		||||
/* Returns 0 if file size is unknown */
 | 
			
		||||
goffset			 xedit_document_saver_get_file_size	(XeditDocumentSaver  *saver);
 | 
			
		||||
 | 
			
		||||
goffset			 xedit_document_saver_get_bytes_written	(XeditDocumentSaver  *saver);
 | 
			
		||||
 | 
			
		||||
GFileInfo		*xedit_document_saver_get_info		(XeditDocumentSaver  *saver);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif  /* __XEDIT_DOCUMENT_SAVER_H__  */
 | 
			
		||||
							
								
								
									
										2901
									
								
								xedit/xedit-document.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2901
									
								
								xedit/xedit-document.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										333
									
								
								xedit/xedit-document.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										333
									
								
								xedit/xedit-document.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,333 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-document.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
 | 
			
		||||
 * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi 
 | 
			
		||||
 * Copyright (C) 2002-2005 Paolo Maggi 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 1998-2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
#ifndef __XEDIT_DOCUMENT_H__
 | 
			
		||||
#define __XEDIT_DOCUMENT_H__
 | 
			
		||||
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
#include <gtksourceview/gtksourcebuffer.h>
 | 
			
		||||
 | 
			
		||||
#include <xedit/xedit-encodings.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Type checking and casting macros
 | 
			
		||||
 */
 | 
			
		||||
#define XEDIT_TYPE_DOCUMENT              (xedit_document_get_type())
 | 
			
		||||
#define XEDIT_DOCUMENT(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), XEDIT_TYPE_DOCUMENT, XeditDocument))
 | 
			
		||||
#define XEDIT_DOCUMENT_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), XEDIT_TYPE_DOCUMENT, XeditDocumentClass))
 | 
			
		||||
#define XEDIT_IS_DOCUMENT(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), XEDIT_TYPE_DOCUMENT))
 | 
			
		||||
#define XEDIT_IS_DOCUMENT_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), XEDIT_TYPE_DOCUMENT))
 | 
			
		||||
#define XEDIT_DOCUMENT_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), XEDIT_TYPE_DOCUMENT, XeditDocumentClass))
 | 
			
		||||
 | 
			
		||||
#define XEDIT_METADATA_ATTRIBUTE_POSITION "metadata::xedit-position"
 | 
			
		||||
#define XEDIT_METADATA_ATTRIBUTE_ENCODING "metadata::xedit-encoding"
 | 
			
		||||
#define XEDIT_METADATA_ATTRIBUTE_LANGUAGE "metadata::xedit-language"
 | 
			
		||||
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
	XEDIT_DOCUMENT_NEWLINE_TYPE_LF,
 | 
			
		||||
	XEDIT_DOCUMENT_NEWLINE_TYPE_CR,
 | 
			
		||||
	XEDIT_DOCUMENT_NEWLINE_TYPE_CR_LF
 | 
			
		||||
} XeditDocumentNewlineType;
 | 
			
		||||
 | 
			
		||||
#define XEDIT_DOCUMENT_NEWLINE_TYPE_DEFAULT XEDIT_DOCUMENT_NEWLINE_TYPE_LF
 | 
			
		||||
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
	XEDIT_SEARCH_DONT_SET_FLAGS	= 1 << 0, 
 | 
			
		||||
	XEDIT_SEARCH_ENTIRE_WORD	= 1 << 1,
 | 
			
		||||
	XEDIT_SEARCH_CASE_SENSITIVE	= 1 << 2,
 | 
			
		||||
	XEDIT_SEARCH_PARSE_ESCAPES	= 1 << 3
 | 
			
		||||
 | 
			
		||||
} XeditSearchFlags;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * XeditDocumentSaveFlags:
 | 
			
		||||
 * @XEDIT_DOCUMENT_SAVE_IGNORE_MTIME: save file despite external modifications.
 | 
			
		||||
 * @XEDIT_DOCUMENT_SAVE_IGNORE_BACKUP: write the file directly without attempting to backup.
 | 
			
		||||
 * @XEDIT_DOCUMENT_SAVE_PRESERVE_BACKUP: preserve previous backup file, needed to support autosaving.
 | 
			
		||||
 */
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
	XEDIT_DOCUMENT_SAVE_IGNORE_MTIME 	= 1 << 0,
 | 
			
		||||
	XEDIT_DOCUMENT_SAVE_IGNORE_BACKUP	= 1 << 1,
 | 
			
		||||
	XEDIT_DOCUMENT_SAVE_PRESERVE_BACKUP	= 1 << 2
 | 
			
		||||
} XeditDocumentSaveFlags;
 | 
			
		||||
 | 
			
		||||
/* Private structure type */
 | 
			
		||||
typedef struct _XeditDocumentPrivate    XeditDocumentPrivate;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Main object structure
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _XeditDocument           XeditDocument;
 | 
			
		||||
 
 | 
			
		||||
struct _XeditDocument
 | 
			
		||||
{
 | 
			
		||||
	GtkSourceBuffer buffer;
 | 
			
		||||
	
 | 
			
		||||
	/*< private > */
 | 
			
		||||
	XeditDocumentPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Class definition
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _XeditDocumentClass 	XeditDocumentClass;
 | 
			
		||||
 | 
			
		||||
struct _XeditDocumentClass
 | 
			
		||||
{
 | 
			
		||||
	GtkSourceBufferClass parent_class;
 | 
			
		||||
 | 
			
		||||
	/* Signals */ // CHECK: ancora da rivedere
 | 
			
		||||
 | 
			
		||||
	void (* cursor_moved)		(XeditDocument    *document);
 | 
			
		||||
 | 
			
		||||
	/* Document load */
 | 
			
		||||
	void (* load)			(XeditDocument       *document,
 | 
			
		||||
					 const gchar         *uri,
 | 
			
		||||
					 const XeditEncoding *encoding,
 | 
			
		||||
					 gint                 line_pos,
 | 
			
		||||
					 gboolean             create);
 | 
			
		||||
 | 
			
		||||
	void (* loading)		(XeditDocument    *document,
 | 
			
		||||
					 goffset	   size,
 | 
			
		||||
					 goffset	   total_size);
 | 
			
		||||
 | 
			
		||||
	void (* loaded)			(XeditDocument    *document,
 | 
			
		||||
					 const GError     *error);
 | 
			
		||||
 | 
			
		||||
	/* Document save */
 | 
			
		||||
	void (* save)			(XeditDocument          *document,
 | 
			
		||||
					 const gchar            *uri,
 | 
			
		||||
					 const XeditEncoding    *encoding,
 | 
			
		||||
					 XeditDocumentSaveFlags  flags);
 | 
			
		||||
 | 
			
		||||
	void (* saving)			(XeditDocument    *document,
 | 
			
		||||
					 goffset	   size,
 | 
			
		||||
					 goffset	   total_size);
 | 
			
		||||
 | 
			
		||||
	void (* saved)  		(XeditDocument    *document,
 | 
			
		||||
					 const GError     *error);
 | 
			
		||||
 | 
			
		||||
	void (* search_highlight_updated)
 | 
			
		||||
					(XeditDocument    *document,
 | 
			
		||||
					 GtkTextIter      *start,
 | 
			
		||||
					 GtkTextIter      *end);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define XEDIT_DOCUMENT_ERROR xedit_document_error_quark ()
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
	XEDIT_DOCUMENT_ERROR_EXTERNALLY_MODIFIED,
 | 
			
		||||
	XEDIT_DOCUMENT_ERROR_CANT_CREATE_BACKUP,
 | 
			
		||||
	XEDIT_DOCUMENT_ERROR_TOO_BIG,
 | 
			
		||||
	XEDIT_DOCUMENT_ERROR_ENCODING_AUTO_DETECTION_FAILED,
 | 
			
		||||
	XEDIT_DOCUMENT_ERROR_CONVERSION_FALLBACK,
 | 
			
		||||
	XEDIT_DOCUMENT_NUM_ERRORS
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GQuark		 xedit_document_error_quark	(void);
 | 
			
		||||
 | 
			
		||||
GType		 xedit_document_get_type      	(void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
XeditDocument   *xedit_document_new 		(void);
 | 
			
		||||
 | 
			
		||||
GFile		*xedit_document_get_location	(XeditDocument       *doc);
 | 
			
		||||
 | 
			
		||||
gchar		*xedit_document_get_uri 	(XeditDocument       *doc);
 | 
			
		||||
void		 xedit_document_set_uri		(XeditDocument       *doc,
 | 
			
		||||
						 const gchar 	     *uri);
 | 
			
		||||
 | 
			
		||||
gchar		*xedit_document_get_uri_for_display
 | 
			
		||||
						(XeditDocument       *doc);
 | 
			
		||||
gchar		*xedit_document_get_short_name_for_display
 | 
			
		||||
					 	(XeditDocument       *doc);
 | 
			
		||||
 | 
			
		||||
void		 xedit_document_set_short_name_for_display
 | 
			
		||||
						(XeditDocument       *doc,
 | 
			
		||||
						 const gchar         *name);
 | 
			
		||||
 | 
			
		||||
gchar		*xedit_document_get_content_type
 | 
			
		||||
					 	(XeditDocument       *doc);
 | 
			
		||||
 | 
			
		||||
void		 xedit_document_set_content_type
 | 
			
		||||
					 	(XeditDocument       *doc,
 | 
			
		||||
					 	 const gchar         *content_type);
 | 
			
		||||
 | 
			
		||||
gchar		*xedit_document_get_mime_type 	(XeditDocument       *doc);
 | 
			
		||||
 | 
			
		||||
gboolean	 xedit_document_get_readonly 	(XeditDocument       *doc);
 | 
			
		||||
 | 
			
		||||
void		 xedit_document_load 		(XeditDocument       *doc,
 | 
			
		||||
						 const gchar         *uri,
 | 
			
		||||
						 const XeditEncoding *encoding,
 | 
			
		||||
						 gint                 line_pos,
 | 
			
		||||
						 gboolean             create); 
 | 
			
		||||
 | 
			
		||||
gboolean	 xedit_document_insert_file	(XeditDocument       *doc,
 | 
			
		||||
						 GtkTextIter         *iter, 
 | 
			
		||||
						 const gchar         *uri, 
 | 
			
		||||
						 const XeditEncoding *encoding);
 | 
			
		||||
 | 
			
		||||
gboolean	 xedit_document_load_cancel	(XeditDocument       *doc);
 | 
			
		||||
 | 
			
		||||
void		 xedit_document_save 		(XeditDocument       *doc,
 | 
			
		||||
						 XeditDocumentSaveFlags flags);
 | 
			
		||||
 | 
			
		||||
void		 xedit_document_save_as 	(XeditDocument       *doc,	
 | 
			
		||||
						 const gchar         *uri, 
 | 
			
		||||
						 const XeditEncoding *encoding,
 | 
			
		||||
						 XeditDocumentSaveFlags flags);
 | 
			
		||||
 | 
			
		||||
gboolean	 xedit_document_is_untouched 	(XeditDocument       *doc);
 | 
			
		||||
gboolean	 xedit_document_is_untitled 	(XeditDocument       *doc);
 | 
			
		||||
 | 
			
		||||
gboolean	 xedit_document_is_local	(XeditDocument       *doc);
 | 
			
		||||
 | 
			
		||||
gboolean	 xedit_document_get_deleted	(XeditDocument       *doc);
 | 
			
		||||
 | 
			
		||||
gboolean	 xedit_document_goto_line 	(XeditDocument       *doc, 
 | 
			
		||||
						 gint                 line);
 | 
			
		||||
 | 
			
		||||
gboolean	 xedit_document_goto_line_offset(XeditDocument *doc,
 | 
			
		||||
						 gint           line,
 | 
			
		||||
						 gint           line_offset);
 | 
			
		||||
 | 
			
		||||
void		 xedit_document_set_search_text	(XeditDocument       *doc,
 | 
			
		||||
						 const gchar         *text,
 | 
			
		||||
						 guint                flags);
 | 
			
		||||
						 
 | 
			
		||||
gchar		*xedit_document_get_search_text	(XeditDocument       *doc,
 | 
			
		||||
						 guint               *flags);
 | 
			
		||||
 | 
			
		||||
gboolean	 xedit_document_get_can_search_again
 | 
			
		||||
						(XeditDocument       *doc);
 | 
			
		||||
 | 
			
		||||
gboolean	 xedit_document_search_forward	(XeditDocument       *doc,
 | 
			
		||||
						 const GtkTextIter   *start,
 | 
			
		||||
						 const GtkTextIter   *end,
 | 
			
		||||
						 GtkTextIter         *match_start,
 | 
			
		||||
						 GtkTextIter         *match_end);
 | 
			
		||||
						 
 | 
			
		||||
gboolean	 xedit_document_search_backward	(XeditDocument       *doc,
 | 
			
		||||
						 const GtkTextIter   *start,
 | 
			
		||||
						 const GtkTextIter   *end,
 | 
			
		||||
						 GtkTextIter         *match_start,
 | 
			
		||||
						 GtkTextIter         *match_end);
 | 
			
		||||
 | 
			
		||||
gint		 xedit_document_replace_all 	(XeditDocument       *doc,
 | 
			
		||||
				            	 const gchar         *find, 
 | 
			
		||||
						 const gchar         *replace, 
 | 
			
		||||
					    	 guint                flags);
 | 
			
		||||
 | 
			
		||||
void 		 xedit_document_set_language 	(XeditDocument       *doc,
 | 
			
		||||
						 GtkSourceLanguage   *lang);
 | 
			
		||||
GtkSourceLanguage 
 | 
			
		||||
		*xedit_document_get_language 	(XeditDocument       *doc);
 | 
			
		||||
 | 
			
		||||
const XeditEncoding 
 | 
			
		||||
		*xedit_document_get_encoding	(XeditDocument       *doc);
 | 
			
		||||
 | 
			
		||||
void		 xedit_document_set_enable_search_highlighting 
 | 
			
		||||
						(XeditDocument       *doc,
 | 
			
		||||
						 gboolean             enable);
 | 
			
		||||
 | 
			
		||||
gboolean	 xedit_document_get_enable_search_highlighting
 | 
			
		||||
						(XeditDocument       *doc);
 | 
			
		||||
 | 
			
		||||
void		 xedit_document_set_newline_type (XeditDocument           *doc,
 | 
			
		||||
						  XeditDocumentNewlineType newline_type);
 | 
			
		||||
 | 
			
		||||
XeditDocumentNewlineType
 | 
			
		||||
		 xedit_document_get_newline_type (XeditDocument *doc);
 | 
			
		||||
 | 
			
		||||
gchar		*xedit_document_get_metadata	(XeditDocument *doc,
 | 
			
		||||
						 const gchar   *key);
 | 
			
		||||
 | 
			
		||||
void		 xedit_document_set_metadata	(XeditDocument *doc,
 | 
			
		||||
						 const gchar   *first_key,
 | 
			
		||||
						 ...);
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 * Non exported functions
 | 
			
		||||
 */
 | 
			
		||||
void		 _xedit_document_set_readonly 	(XeditDocument       *doc,
 | 
			
		||||
						 gboolean             readonly);
 | 
			
		||||
 | 
			
		||||
glong		 _xedit_document_get_seconds_since_last_save_or_load 
 | 
			
		||||
						(XeditDocument       *doc);
 | 
			
		||||
 | 
			
		||||
/* Note: this is a sync stat: use only on local files */
 | 
			
		||||
gboolean	_xedit_document_check_externally_modified
 | 
			
		||||
						(XeditDocument       *doc);
 | 
			
		||||
 | 
			
		||||
void		_xedit_document_search_region   (XeditDocument       *doc,
 | 
			
		||||
						 const GtkTextIter   *start,
 | 
			
		||||
						 const GtkTextIter   *end);
 | 
			
		||||
						  
 | 
			
		||||
/* Search macros */
 | 
			
		||||
#define XEDIT_SEARCH_IS_DONT_SET_FLAGS(sflags) ((sflags & XEDIT_SEARCH_DONT_SET_FLAGS) != 0)
 | 
			
		||||
#define XEDIT_SEARCH_SET_DONT_SET_FLAGS(sflags,state) ((state == TRUE) ? \
 | 
			
		||||
(sflags |= XEDIT_SEARCH_DONT_SET_FLAGS) : (sflags &= ~XEDIT_SEARCH_DONT_SET_FLAGS))
 | 
			
		||||
 | 
			
		||||
#define XEDIT_SEARCH_IS_ENTIRE_WORD(sflags) ((sflags & XEDIT_SEARCH_ENTIRE_WORD) != 0)
 | 
			
		||||
#define XEDIT_SEARCH_SET_ENTIRE_WORD(sflags,state) ((state == TRUE) ? \
 | 
			
		||||
(sflags |= XEDIT_SEARCH_ENTIRE_WORD) : (sflags &= ~XEDIT_SEARCH_ENTIRE_WORD))
 | 
			
		||||
 | 
			
		||||
#define XEDIT_SEARCH_IS_CASE_SENSITIVE(sflags) ((sflags &  XEDIT_SEARCH_CASE_SENSITIVE) != 0)
 | 
			
		||||
#define XEDIT_SEARCH_SET_CASE_SENSITIVE(sflags,state) ((state == TRUE) ? \
 | 
			
		||||
(sflags |= XEDIT_SEARCH_CASE_SENSITIVE) : (sflags &= ~XEDIT_SEARCH_CASE_SENSITIVE))
 | 
			
		||||
 | 
			
		||||
#define XEDIT_SEARCH_IS_PARSE_ESCAPES(sflags) ((sflags &  XEDIT_SEARCH_PARSE_ESCAPES) != 0)
 | 
			
		||||
#define XEDIT_SEARCH_SET_PARSE_ESCAPES(sflags,state) ((state == TRUE) ? \
 | 
			
		||||
(sflags |= XEDIT_SEARCH_PARSE_ESCAPES) : (sflags &= ~XEDIT_SEARCH_PARSE_ESCAPES))
 | 
			
		||||
 | 
			
		||||
typedef GMountOperation *(*XeditMountOperationFactory)(XeditDocument *doc, 
 | 
			
		||||
						       gpointer       userdata);
 | 
			
		||||
 | 
			
		||||
void		 _xedit_document_set_mount_operation_factory
 | 
			
		||||
						(XeditDocument	            *doc,
 | 
			
		||||
						 XeditMountOperationFactory  callback,
 | 
			
		||||
						 gpointer	             userdata);
 | 
			
		||||
GMountOperation
 | 
			
		||||
		*_xedit_document_create_mount_operation
 | 
			
		||||
						(XeditDocument	     *doc);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __XEDIT_DOCUMENT_H__ */
 | 
			
		||||
							
								
								
									
										844
									
								
								xedit/xedit-documents-panel.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										844
									
								
								xedit/xedit-documents-panel.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,844 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-documents-panel.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2005 - Paolo Maggi 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "xedit-documents-panel.h"
 | 
			
		||||
#include "xedit-utils.h"
 | 
			
		||||
#include "xedit-notebook.h"
 | 
			
		||||
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
 | 
			
		||||
#define XEDIT_DOCUMENTS_PANEL_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \
 | 
			
		||||
						  XEDIT_TYPE_DOCUMENTS_PANEL,            \
 | 
			
		||||
						  XeditDocumentsPanelPrivate))
 | 
			
		||||
 | 
			
		||||
struct _XeditDocumentsPanelPrivate
 | 
			
		||||
{
 | 
			
		||||
	XeditWindow  *window;
 | 
			
		||||
 | 
			
		||||
	GtkWidget    *treeview;
 | 
			
		||||
	GtkTreeModel *model;
 | 
			
		||||
 | 
			
		||||
	guint         adding_tab : 1;
 | 
			
		||||
	guint         is_reodering : 1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
G_DEFINE_TYPE(XeditDocumentsPanel, xedit_documents_panel, GTK_TYPE_BOX)
 | 
			
		||||
#else
 | 
			
		||||
G_DEFINE_TYPE(XeditDocumentsPanel, xedit_documents_panel, GTK_TYPE_VBOX)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
	PROP_0,
 | 
			
		||||
	PROP_WINDOW
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
	PIXBUF_COLUMN,
 | 
			
		||||
	NAME_COLUMN,
 | 
			
		||||
	TAB_COLUMN,
 | 
			
		||||
	N_COLUMNS
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define MAX_DOC_NAME_LENGTH 60
 | 
			
		||||
 | 
			
		||||
static gchar *
 | 
			
		||||
tab_get_name (XeditTab *tab)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocument *doc;
 | 
			
		||||
	gchar *name;
 | 
			
		||||
	gchar *docname;
 | 
			
		||||
	gchar *tab_name;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_TAB (tab), NULL);
 | 
			
		||||
 | 
			
		||||
	doc = xedit_tab_get_document (tab);
 | 
			
		||||
 | 
			
		||||
	name = xedit_document_get_short_name_for_display (doc);
 | 
			
		||||
 | 
			
		||||
	/* Truncate the name so it doesn't get insanely wide. */
 | 
			
		||||
	docname = xedit_utils_str_middle_truncate (name, MAX_DOC_NAME_LENGTH);
 | 
			
		||||
 | 
			
		||||
	if (gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc)))
 | 
			
		||||
	{
 | 
			
		||||
		if (xedit_document_get_readonly (doc))
 | 
			
		||||
		{
 | 
			
		||||
			tab_name = g_markup_printf_escaped ("<i>%s</i> [<i>%s</i>]",
 | 
			
		||||
							    docname,
 | 
			
		||||
							    _("Read-Only"));
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			tab_name = g_markup_printf_escaped ("<i>%s</i>", 
 | 
			
		||||
							    docname);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		if (xedit_document_get_readonly (doc))
 | 
			
		||||
		{
 | 
			
		||||
			tab_name = g_markup_printf_escaped ("%s [<i>%s</i>]",
 | 
			
		||||
							    docname,
 | 
			
		||||
							    _("Read-Only"));
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			tab_name = g_markup_escape_text (docname, -1);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_free (docname);
 | 
			
		||||
	g_free (name);
 | 
			
		||||
 | 
			
		||||
	return tab_name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
get_iter_from_tab (XeditDocumentsPanel *panel, XeditTab *tab, GtkTreeIter *iter)
 | 
			
		||||
{
 | 
			
		||||
	gint num;
 | 
			
		||||
	GtkWidget *nb;
 | 
			
		||||
	GtkTreePath *path;
 | 
			
		||||
 | 
			
		||||
	nb = _xedit_window_get_notebook (panel->priv->window);
 | 
			
		||||
	num = gtk_notebook_page_num (GTK_NOTEBOOK (nb),
 | 
			
		||||
				     GTK_WIDGET (tab));
 | 
			
		||||
 | 
			
		||||
	path = gtk_tree_path_new_from_indices (num, -1);
 | 
			
		||||
	gtk_tree_model_get_iter (panel->priv->model,
 | 
			
		||||
		                 iter,
 | 
			
		||||
		                 path);
 | 
			
		||||
	gtk_tree_path_free (path);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
window_active_tab_changed (XeditWindow         *window,
 | 
			
		||||
			   XeditTab            *tab,
 | 
			
		||||
			   XeditDocumentsPanel *panel)
 | 
			
		||||
{	
 | 
			
		||||
	g_return_if_fail (tab != NULL);
 | 
			
		||||
 | 
			
		||||
	if (!_xedit_window_is_removing_tabs (window))
 | 
			
		||||
	{
 | 
			
		||||
		GtkTreeIter iter;
 | 
			
		||||
		GtkTreeSelection *selection;
 | 
			
		||||
 | 
			
		||||
		get_iter_from_tab (panel, tab, &iter);
 | 
			
		||||
 | 
			
		||||
		if (gtk_list_store_iter_is_valid (GTK_LIST_STORE (panel->priv->model),
 | 
			
		||||
						  &iter))
 | 
			
		||||
		{
 | 
			
		||||
			selection = gtk_tree_view_get_selection (
 | 
			
		||||
					GTK_TREE_VIEW (panel->priv->treeview));
 | 
			
		||||
 | 
			
		||||
			gtk_tree_selection_select_iter (selection, &iter);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
refresh_list (XeditDocumentsPanel *panel)
 | 
			
		||||
{
 | 
			
		||||
	/* TODO: refresh the list only if the panel is visible */
 | 
			
		||||
 | 
			
		||||
	GList *tabs;
 | 
			
		||||
	GList *l;
 | 
			
		||||
	GtkWidget *nb;
 | 
			
		||||
	GtkListStore *list_store;
 | 
			
		||||
	XeditTab *active_tab;
 | 
			
		||||
 | 
			
		||||
	/* g_debug ("refresh_list"); */
 | 
			
		||||
	
 | 
			
		||||
	list_store = GTK_LIST_STORE (panel->priv->model);
 | 
			
		||||
 | 
			
		||||
	gtk_list_store_clear (list_store);
 | 
			
		||||
 | 
			
		||||
	active_tab = xedit_window_get_active_tab (panel->priv->window);
 | 
			
		||||
 | 
			
		||||
	nb = _xedit_window_get_notebook (panel->priv->window);
 | 
			
		||||
 | 
			
		||||
	tabs = gtk_container_get_children (GTK_CONTAINER (nb));
 | 
			
		||||
	l = tabs;
 | 
			
		||||
 | 
			
		||||
	panel->priv->adding_tab = TRUE;
 | 
			
		||||
	
 | 
			
		||||
	while (l != NULL)
 | 
			
		||||
	{	
 | 
			
		||||
		GdkPixbuf *pixbuf;
 | 
			
		||||
		gchar *name;
 | 
			
		||||
		GtkTreeIter iter;
 | 
			
		||||
 | 
			
		||||
		name = tab_get_name (XEDIT_TAB (l->data));
 | 
			
		||||
		pixbuf = _xedit_tab_get_icon (XEDIT_TAB (l->data));
 | 
			
		||||
 | 
			
		||||
		/* Add a new row to the model */
 | 
			
		||||
		gtk_list_store_append (list_store, &iter);
 | 
			
		||||
		gtk_list_store_set (list_store,
 | 
			
		||||
				    &iter,
 | 
			
		||||
				    PIXBUF_COLUMN, pixbuf,
 | 
			
		||||
				    NAME_COLUMN, name,
 | 
			
		||||
				    TAB_COLUMN, l->data,
 | 
			
		||||
				    -1);
 | 
			
		||||
 | 
			
		||||
		g_free (name);
 | 
			
		||||
		if (pixbuf != NULL)
 | 
			
		||||
			g_object_unref (pixbuf);
 | 
			
		||||
 | 
			
		||||
		if (l->data == active_tab)
 | 
			
		||||
		{
 | 
			
		||||
			GtkTreeSelection *selection;
 | 
			
		||||
 | 
			
		||||
			selection = gtk_tree_view_get_selection (
 | 
			
		||||
					GTK_TREE_VIEW (panel->priv->treeview));
 | 
			
		||||
 | 
			
		||||
			gtk_tree_selection_select_iter (selection, &iter);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		l = g_list_next (l);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	panel->priv->adding_tab = FALSE;
 | 
			
		||||
 | 
			
		||||
	g_list_free (tabs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
sync_name_and_icon (XeditTab            *tab,
 | 
			
		||||
		    GParamSpec          *pspec,
 | 
			
		||||
		    XeditDocumentsPanel *panel)
 | 
			
		||||
{
 | 
			
		||||
	GdkPixbuf *pixbuf;
 | 
			
		||||
	gchar *name;
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
 | 
			
		||||
	get_iter_from_tab (panel, tab, &iter);
 | 
			
		||||
 | 
			
		||||
	name = tab_get_name (tab);
 | 
			
		||||
	pixbuf = _xedit_tab_get_icon (tab);
 | 
			
		||||
 | 
			
		||||
	gtk_list_store_set (GTK_LIST_STORE (panel->priv->model),
 | 
			
		||||
			    &iter,
 | 
			
		||||
			    PIXBUF_COLUMN, pixbuf,
 | 
			
		||||
			    NAME_COLUMN, name,
 | 
			
		||||
			    TAB_COLUMN, tab,
 | 
			
		||||
			    -1);
 | 
			
		||||
 | 
			
		||||
	g_free (name);
 | 
			
		||||
	if (pixbuf != NULL)
 | 
			
		||||
		g_object_unref (pixbuf);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
window_tab_removed (XeditWindow         *window,
 | 
			
		||||
		    XeditTab            *tab,
 | 
			
		||||
		    XeditDocumentsPanel *panel)
 | 
			
		||||
{
 | 
			
		||||
	g_signal_handlers_disconnect_by_func (tab,
 | 
			
		||||
					      G_CALLBACK (sync_name_and_icon),
 | 
			
		||||
					      panel);
 | 
			
		||||
 | 
			
		||||
	if (_xedit_window_is_removing_tabs (window))
 | 
			
		||||
		gtk_list_store_clear (GTK_LIST_STORE (panel->priv->model));
 | 
			
		||||
	else
 | 
			
		||||
		refresh_list (panel);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
window_tab_added (XeditWindow         *window,
 | 
			
		||||
		  XeditTab            *tab,
 | 
			
		||||
		  XeditDocumentsPanel *panel)
 | 
			
		||||
{
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
	GtkTreeIter sibling;
 | 
			
		||||
	GdkPixbuf *pixbuf;
 | 
			
		||||
	gchar *name;
 | 
			
		||||
 | 
			
		||||
	g_signal_connect (tab,
 | 
			
		||||
			 "notify::name",
 | 
			
		||||
			  G_CALLBACK (sync_name_and_icon),
 | 
			
		||||
			  panel);
 | 
			
		||||
 | 
			
		||||
	g_signal_connect (tab,
 | 
			
		||||
			 "notify::state",
 | 
			
		||||
			  G_CALLBACK (sync_name_and_icon),
 | 
			
		||||
			  panel);
 | 
			
		||||
 | 
			
		||||
	get_iter_from_tab (panel, tab, &sibling);
 | 
			
		||||
 | 
			
		||||
	panel->priv->adding_tab = TRUE;
 | 
			
		||||
	
 | 
			
		||||
	if (gtk_list_store_iter_is_valid (GTK_LIST_STORE (panel->priv->model), 
 | 
			
		||||
					  &sibling))
 | 
			
		||||
	{
 | 
			
		||||
		gtk_list_store_insert_after (GTK_LIST_STORE (panel->priv->model),
 | 
			
		||||
					     &iter,
 | 
			
		||||
					     &sibling);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		XeditTab *active_tab;
 | 
			
		||||
 | 
			
		||||
		gtk_list_store_append (GTK_LIST_STORE (panel->priv->model), 
 | 
			
		||||
				       &iter);
 | 
			
		||||
 | 
			
		||||
		active_tab = xedit_window_get_active_tab (panel->priv->window);
 | 
			
		||||
 | 
			
		||||
		if (tab == active_tab)
 | 
			
		||||
		{
 | 
			
		||||
			GtkTreeSelection *selection;
 | 
			
		||||
 | 
			
		||||
			selection = gtk_tree_view_get_selection (
 | 
			
		||||
						GTK_TREE_VIEW (panel->priv->treeview));
 | 
			
		||||
 | 
			
		||||
			gtk_tree_selection_select_iter (selection, &iter);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	name = tab_get_name (tab);
 | 
			
		||||
	pixbuf = _xedit_tab_get_icon (tab);
 | 
			
		||||
 | 
			
		||||
	gtk_list_store_set (GTK_LIST_STORE (panel->priv->model),
 | 
			
		||||
			    &iter,
 | 
			
		||||
		            PIXBUF_COLUMN, pixbuf,
 | 
			
		||||
		            NAME_COLUMN, name,
 | 
			
		||||
		            TAB_COLUMN, tab,
 | 
			
		||||
		            -1);
 | 
			
		||||
 | 
			
		||||
	g_free (name);
 | 
			
		||||
	if (pixbuf != NULL)
 | 
			
		||||
		g_object_unref (pixbuf);
 | 
			
		||||
 | 
			
		||||
	panel->priv->adding_tab = FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
window_tabs_reordered (XeditWindow         *window,
 | 
			
		||||
		       XeditDocumentsPanel *panel)
 | 
			
		||||
{
 | 
			
		||||
	if (panel->priv->is_reodering)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	refresh_list (panel);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_window (XeditDocumentsPanel *panel,
 | 
			
		||||
	    XeditWindow         *window)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (panel->priv->window == NULL);
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_WINDOW (window));
 | 
			
		||||
 | 
			
		||||
	panel->priv->window = g_object_ref (window);
 | 
			
		||||
 | 
			
		||||
	g_signal_connect (window,
 | 
			
		||||
			  "tab_added",
 | 
			
		||||
			  G_CALLBACK (window_tab_added),
 | 
			
		||||
			  panel);
 | 
			
		||||
	g_signal_connect (window,
 | 
			
		||||
			  "tab_removed",
 | 
			
		||||
			  G_CALLBACK (window_tab_removed),
 | 
			
		||||
			  panel);
 | 
			
		||||
	g_signal_connect (window,
 | 
			
		||||
			  "tabs_reordered",
 | 
			
		||||
			  G_CALLBACK (window_tabs_reordered),
 | 
			
		||||
			  panel);
 | 
			
		||||
	g_signal_connect (window,
 | 
			
		||||
			  "active_tab_changed",
 | 
			
		||||
			  G_CALLBACK (window_active_tab_changed),
 | 
			
		||||
			  panel);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
treeview_cursor_changed (GtkTreeView         *view,
 | 
			
		||||
			 XeditDocumentsPanel *panel)
 | 
			
		||||
{
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
	GtkTreeSelection *selection;
 | 
			
		||||
	gpointer tab;
 | 
			
		||||
 | 
			
		||||
	selection = gtk_tree_view_get_selection (
 | 
			
		||||
				GTK_TREE_VIEW (panel->priv->treeview));
 | 
			
		||||
 | 
			
		||||
	if (gtk_tree_selection_get_selected (selection, NULL, &iter))
 | 
			
		||||
	{
 | 
			
		||||
		gtk_tree_model_get (panel->priv->model,
 | 
			
		||||
				    &iter,
 | 
			
		||||
				    TAB_COLUMN,
 | 
			
		||||
				    &tab,
 | 
			
		||||
				    -1);
 | 
			
		||||
 | 
			
		||||
		if (xedit_window_get_active_tab (panel->priv->window) != tab)
 | 
			
		||||
		{
 | 
			
		||||
			xedit_window_set_active_tab (panel->priv->window,
 | 
			
		||||
						     XEDIT_TAB (tab));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_documents_panel_set_property (GObject      *object,
 | 
			
		||||
				    guint         prop_id,
 | 
			
		||||
				    const GValue *value,
 | 
			
		||||
				    GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentsPanel *panel = XEDIT_DOCUMENTS_PANEL (object);
 | 
			
		||||
 | 
			
		||||
	switch (prop_id)
 | 
			
		||||
	{
 | 
			
		||||
		case PROP_WINDOW:
 | 
			
		||||
			set_window (panel, g_value_get_object (value));
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_documents_panel_get_property (GObject    *object,
 | 
			
		||||
				    guint       prop_id,
 | 
			
		||||
				    GValue     *value,
 | 
			
		||||
				    GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentsPanel *panel = XEDIT_DOCUMENTS_PANEL (object);
 | 
			
		||||
 | 
			
		||||
	switch (prop_id)
 | 
			
		||||
	{
 | 
			
		||||
		case PROP_WINDOW:
 | 
			
		||||
			g_value_set_object (value,
 | 
			
		||||
					    XEDIT_DOCUMENTS_PANEL_GET_PRIVATE (panel)->window);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_documents_panel_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
	/* XeditDocumentsPanel *tab = XEDIT_DOCUMENTS_PANEL (object); */
 | 
			
		||||
	
 | 
			
		||||
	/* TODO: disconnect signal with window */
 | 
			
		||||
 | 
			
		||||
	G_OBJECT_CLASS (xedit_documents_panel_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_documents_panel_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentsPanel *panel = XEDIT_DOCUMENTS_PANEL (object);
 | 
			
		||||
 | 
			
		||||
	if (panel->priv->window != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		g_object_unref (panel->priv->window);
 | 
			
		||||
		panel->priv->window = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	G_OBJECT_CLASS (xedit_documents_panel_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
xedit_documents_panel_class_init (XeditDocumentsPanelClass *klass)
 | 
			
		||||
{
 | 
			
		||||
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
	object_class->finalize = xedit_documents_panel_finalize;
 | 
			
		||||
	object_class->dispose = xedit_documents_panel_dispose;
 | 
			
		||||
	object_class->get_property = xedit_documents_panel_get_property;
 | 
			
		||||
	object_class->set_property = xedit_documents_panel_set_property;
 | 
			
		||||
 | 
			
		||||
	g_object_class_install_property (object_class,
 | 
			
		||||
					 PROP_WINDOW,
 | 
			
		||||
					 g_param_spec_object ("window",
 | 
			
		||||
							      "Window",
 | 
			
		||||
							      "The XeditWindow this XeditDocumentsPanel is associated with",
 | 
			
		||||
							      XEDIT_TYPE_WINDOW,
 | 
			
		||||
							      G_PARAM_READWRITE |
 | 
			
		||||
							      G_PARAM_CONSTRUCT_ONLY |
 | 
			
		||||
							      G_PARAM_STATIC_STRINGS));
 | 
			
		||||
 | 
			
		||||
	g_type_class_add_private (object_class, sizeof (XeditDocumentsPanelPrivate));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GtkTreePath *
 | 
			
		||||
get_current_path (XeditDocumentsPanel *panel)
 | 
			
		||||
{
 | 
			
		||||
	gint num;
 | 
			
		||||
	GtkWidget *nb;
 | 
			
		||||
	GtkTreePath *path;
 | 
			
		||||
 | 
			
		||||
	nb = _xedit_window_get_notebook (panel->priv->window);
 | 
			
		||||
	num = gtk_notebook_get_current_page (GTK_NOTEBOOK (nb));
 | 
			
		||||
 | 
			
		||||
	path = gtk_tree_path_new_from_indices (num, -1);
 | 
			
		||||
 | 
			
		||||
	return path;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
menu_position (GtkMenu             *menu,
 | 
			
		||||
	       gint                *x,
 | 
			
		||||
	       gint                *y,
 | 
			
		||||
	       gboolean            *push_in,
 | 
			
		||||
	       XeditDocumentsPanel *panel)
 | 
			
		||||
{
 | 
			
		||||
	GtkTreePath *path;
 | 
			
		||||
	GdkRectangle rect;
 | 
			
		||||
	gint wx, wy;
 | 
			
		||||
	GtkAllocation allocation;
 | 
			
		||||
	GtkRequisition requisition;
 | 
			
		||||
	GtkWidget *w;
 | 
			
		||||
 | 
			
		||||
	w = panel->priv->treeview;
 | 
			
		||||
 | 
			
		||||
	gtk_widget_get_allocation(w, &allocation);
 | 
			
		||||
 | 
			
		||||
	path = get_current_path (panel);
 | 
			
		||||
 | 
			
		||||
	gtk_tree_view_get_cell_area (GTK_TREE_VIEW (w),
 | 
			
		||||
				     path,
 | 
			
		||||
				     NULL,
 | 
			
		||||
				     &rect);
 | 
			
		||||
 | 
			
		||||
	wx = rect.x;
 | 
			
		||||
	wy = rect.y;
 | 
			
		||||
 | 
			
		||||
	gdk_window_get_origin (gtk_widget_get_window (w), x, y);
 | 
			
		||||
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
	gtk_widget_get_preferred_size (GTK_WIDGET (menu), NULL, &requisition);
 | 
			
		||||
#else
 | 
			
		||||
	gtk_widget_size_request (GTK_WIDGET (menu), &requisition);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if (gtk_widget_get_direction (w) == GTK_TEXT_DIR_RTL)
 | 
			
		||||
	{
 | 
			
		||||
		*x += allocation.x + allocation.width - requisition.width - 10;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		*x += allocation.x + 10;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wy = MAX (*y + 5, *y + wy + 5);
 | 
			
		||||
	wy = MIN (wy, *y + allocation.height - requisition.height - 5);
 | 
			
		||||
	
 | 
			
		||||
	*y = wy;
 | 
			
		||||
 | 
			
		||||
	*push_in = TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
show_popup_menu (XeditDocumentsPanel *panel,
 | 
			
		||||
		 GdkEventButton      *event)
 | 
			
		||||
{
 | 
			
		||||
	GtkWidget *menu;
 | 
			
		||||
 | 
			
		||||
	menu = gtk_ui_manager_get_widget (xedit_window_get_ui_manager (panel->priv->window),
 | 
			
		||||
					 "/NotebookPopup");
 | 
			
		||||
	g_return_val_if_fail (menu != NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
	if (event != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		gtk_menu_popup (GTK_MENU (menu),
 | 
			
		||||
				NULL,
 | 
			
		||||
				NULL,
 | 
			
		||||
				NULL,
 | 
			
		||||
				NULL,
 | 
			
		||||
				event->button,
 | 
			
		||||
				event->time);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		gtk_menu_popup (GTK_MENU (menu),
 | 
			
		||||
				NULL,
 | 
			
		||||
				NULL,
 | 
			
		||||
				(GtkMenuPositionFunc) menu_position,
 | 
			
		||||
				panel,
 | 
			
		||||
				0,
 | 
			
		||||
				gtk_get_current_event_time ());
 | 
			
		||||
 | 
			
		||||
		gtk_menu_shell_select_first (GTK_MENU_SHELL (menu), FALSE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
panel_button_press_event (GtkTreeView         *treeview,
 | 
			
		||||
			  GdkEventButton      *event,
 | 
			
		||||
			  XeditDocumentsPanel *panel)
 | 
			
		||||
{
 | 
			
		||||
	if ((GDK_BUTTON_PRESS == event->type) && (3 == event->button))
 | 
			
		||||
	{
 | 
			
		||||
		GtkTreePath* path = NULL;
 | 
			
		||||
 | 
			
		||||
		if (event->window == gtk_tree_view_get_bin_window (treeview))
 | 
			
		||||
		{
 | 
			
		||||
			/* Change the cursor position */
 | 
			
		||||
			if (gtk_tree_view_get_path_at_pos (treeview,
 | 
			
		||||
							   event->x,
 | 
			
		||||
							   event->y,
 | 
			
		||||
							   &path,
 | 
			
		||||
							   NULL,
 | 
			
		||||
							   NULL,
 | 
			
		||||
							   NULL))
 | 
			
		||||
			{				
 | 
			
		||||
 | 
			
		||||
				gtk_tree_view_set_cursor (treeview,
 | 
			
		||||
							  path,
 | 
			
		||||
							  NULL,
 | 
			
		||||
							  FALSE);
 | 
			
		||||
 | 
			
		||||
				gtk_tree_path_free (path);
 | 
			
		||||
 | 
			
		||||
				/* A row exists at mouse position */
 | 
			
		||||
				return show_popup_menu (panel, event);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
panel_popup_menu (GtkWidget           *treeview,
 | 
			
		||||
		  XeditDocumentsPanel *panel)
 | 
			
		||||
{
 | 
			
		||||
	/* Only respond if the treeview is the actual focus */
 | 
			
		||||
	if (gtk_window_get_focus (GTK_WINDOW (panel->priv->window)) == treeview)
 | 
			
		||||
	{
 | 
			
		||||
		return show_popup_menu (panel, NULL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
treeview_query_tooltip (GtkWidget  *widget,
 | 
			
		||||
			gint        x,
 | 
			
		||||
			gint        y,
 | 
			
		||||
			gboolean    keyboard_tip,
 | 
			
		||||
			GtkTooltip *tooltip,
 | 
			
		||||
			gpointer    data)
 | 
			
		||||
{
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
	GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
 | 
			
		||||
	GtkTreeModel *model = gtk_tree_view_get_model (tree_view);
 | 
			
		||||
	GtkTreePath *path = NULL;
 | 
			
		||||
	gpointer *tab;
 | 
			
		||||
	gchar *tip;
 | 
			
		||||
 | 
			
		||||
	if (keyboard_tip)
 | 
			
		||||
	{
 | 
			
		||||
		gtk_tree_view_get_cursor (tree_view, &path, NULL);
 | 
			
		||||
 | 
			
		||||
		if (path == NULL)
 | 
			
		||||
		{
 | 
			
		||||
			return FALSE;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		gint bin_x, bin_y;
 | 
			
		||||
 | 
			
		||||
		gtk_tree_view_convert_widget_to_bin_window_coords (tree_view,
 | 
			
		||||
								   x, y,
 | 
			
		||||
								   &bin_x, &bin_y);
 | 
			
		||||
 | 
			
		||||
		if (!gtk_tree_view_get_path_at_pos (tree_view,
 | 
			
		||||
						    bin_x, bin_y,
 | 
			
		||||
						    &path,
 | 
			
		||||
						    NULL, NULL, NULL))
 | 
			
		||||
		{
 | 
			
		||||
			return FALSE;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gtk_tree_model_get_iter (model, &iter, path);
 | 
			
		||||
	gtk_tree_model_get (model,
 | 
			
		||||
			    &iter,
 | 
			
		||||
			    TAB_COLUMN,
 | 
			
		||||
			    &tab,
 | 
			
		||||
			    -1);
 | 
			
		||||
 | 
			
		||||
	tip = _xedit_tab_get_tooltips (XEDIT_TAB (tab));
 | 
			
		||||
	gtk_tooltip_set_markup (tooltip, tip);
 | 
			
		||||
 | 
			
		||||
	g_free (tip);
 | 
			
		||||
	gtk_tree_path_free (path);
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
treeview_row_inserted (GtkTreeModel        *tree_model,
 | 
			
		||||
		       GtkTreePath         *path,
 | 
			
		||||
		       GtkTreeIter         *iter,
 | 
			
		||||
		       XeditDocumentsPanel *panel)
 | 
			
		||||
{
 | 
			
		||||
	XeditTab *tab;
 | 
			
		||||
	gint *indeces;
 | 
			
		||||
	GtkWidget *nb;
 | 
			
		||||
	gint old_position;
 | 
			
		||||
	gint new_position;
 | 
			
		||||
	
 | 
			
		||||
	if (panel->priv->adding_tab)
 | 
			
		||||
		return;
 | 
			
		||||
		
 | 
			
		||||
	tab = xedit_window_get_active_tab (panel->priv->window);
 | 
			
		||||
	g_return_if_fail (tab != NULL);
 | 
			
		||||
 | 
			
		||||
	panel->priv->is_reodering = TRUE;
 | 
			
		||||
	
 | 
			
		||||
	indeces = gtk_tree_path_get_indices (path);
 | 
			
		||||
	
 | 
			
		||||
	/* g_debug ("New Index: %d (path: %s)", indeces[0], gtk_tree_path_to_string (path));*/
 | 
			
		||||
	
 | 
			
		||||
	nb = _xedit_window_get_notebook (panel->priv->window);
 | 
			
		||||
 | 
			
		||||
	new_position = indeces[0];
 | 
			
		||||
	old_position = gtk_notebook_page_num (GTK_NOTEBOOK (nb),
 | 
			
		||||
				    	      GTK_WIDGET (tab));
 | 
			
		||||
	if (new_position > old_position)
 | 
			
		||||
		new_position = MAX (0, new_position - 1);
 | 
			
		||||
		
 | 
			
		||||
	xedit_notebook_reorder_tab (XEDIT_NOTEBOOK (nb),
 | 
			
		||||
				    tab,
 | 
			
		||||
				    new_position);
 | 
			
		||||
 | 
			
		||||
	panel->priv->is_reodering = FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_documents_panel_init (XeditDocumentsPanel *panel)
 | 
			
		||||
{
 | 
			
		||||
	GtkWidget 		*sw;
 | 
			
		||||
	GtkTreeViewColumn	*column;
 | 
			
		||||
	GtkCellRenderer 	*cell;
 | 
			
		||||
	GtkTreeSelection 	*selection;
 | 
			
		||||
 | 
			
		||||
	panel->priv = XEDIT_DOCUMENTS_PANEL_GET_PRIVATE (panel);
 | 
			
		||||
	
 | 
			
		||||
	panel->priv->adding_tab = FALSE;
 | 
			
		||||
	panel->priv->is_reodering = FALSE;
 | 
			
		||||
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
	gtk_orientable_set_orientation (GTK_ORIENTABLE (panel),
 | 
			
		||||
	                                GTK_ORIENTATION_VERTICAL);
 | 
			
		||||
#endif
 | 
			
		||||
	
 | 
			
		||||
	/* Create the scrolled window */
 | 
			
		||||
	sw = gtk_scrolled_window_new (NULL, NULL);
 | 
			
		||||
	g_return_if_fail (sw != NULL);
 | 
			
		||||
	
 | 
			
		||||
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
 | 
			
		||||
					GTK_POLICY_AUTOMATIC,
 | 
			
		||||
					GTK_POLICY_AUTOMATIC);
 | 
			
		||||
	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
 | 
			
		||||
                                             GTK_SHADOW_IN);
 | 
			
		||||
	gtk_widget_show (sw);
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (panel), sw, TRUE, TRUE, 0);
 | 
			
		||||
	
 | 
			
		||||
	/* Create the empty model */
 | 
			
		||||
	panel->priv->model = GTK_TREE_MODEL (gtk_list_store_new (N_COLUMNS,
 | 
			
		||||
								 GDK_TYPE_PIXBUF,
 | 
			
		||||
								 G_TYPE_STRING,
 | 
			
		||||
								 G_TYPE_POINTER));
 | 
			
		||||
 | 
			
		||||
	/* Create the treeview */
 | 
			
		||||
	panel->priv->treeview = gtk_tree_view_new_with_model (panel->priv->model);
 | 
			
		||||
	g_object_unref (G_OBJECT (panel->priv->model));
 | 
			
		||||
	gtk_container_add (GTK_CONTAINER (sw), panel->priv->treeview);
 | 
			
		||||
	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (panel->priv->treeview), FALSE);
 | 
			
		||||
	gtk_tree_view_set_reorderable (GTK_TREE_VIEW (panel->priv->treeview), TRUE);
 | 
			
		||||
 | 
			
		||||
	g_object_set (panel->priv->treeview, "has-tooltip", TRUE, NULL);
 | 
			
		||||
 | 
			
		||||
	gtk_widget_show (panel->priv->treeview);
 | 
			
		||||
	
 | 
			
		||||
	column = gtk_tree_view_column_new ();
 | 
			
		||||
	gtk_tree_view_column_set_title (column, _("Documents"));
 | 
			
		||||
 | 
			
		||||
	cell = gtk_cell_renderer_pixbuf_new ();
 | 
			
		||||
	gtk_tree_view_column_pack_start (column, cell, FALSE);
 | 
			
		||||
	gtk_tree_view_column_add_attribute (column, cell, "pixbuf", PIXBUF_COLUMN);
 | 
			
		||||
	cell = gtk_cell_renderer_text_new ();
 | 
			
		||||
	gtk_tree_view_column_pack_start (column, cell, TRUE);
 | 
			
		||||
	gtk_tree_view_column_add_attribute (column, cell, "markup", NAME_COLUMN);
 | 
			
		||||
 | 
			
		||||
	gtk_tree_view_append_column (GTK_TREE_VIEW (panel->priv->treeview),
 | 
			
		||||
				     column);
 | 
			
		||||
				     
 | 
			
		||||
	selection = gtk_tree_view_get_selection (
 | 
			
		||||
			GTK_TREE_VIEW (panel->priv->treeview));
 | 
			
		||||
 | 
			
		||||
	gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
 | 
			
		||||
	
 | 
			
		||||
	g_signal_connect (panel->priv->treeview,
 | 
			
		||||
			  "cursor_changed",
 | 
			
		||||
			  G_CALLBACK (treeview_cursor_changed),
 | 
			
		||||
			  panel);
 | 
			
		||||
	g_signal_connect (panel->priv->treeview,
 | 
			
		||||
			  "button-press-event",
 | 
			
		||||
			  G_CALLBACK (panel_button_press_event),
 | 
			
		||||
			  panel);
 | 
			
		||||
	g_signal_connect (panel->priv->treeview,
 | 
			
		||||
			  "popup-menu",
 | 
			
		||||
			  G_CALLBACK (panel_popup_menu),
 | 
			
		||||
			  panel);
 | 
			
		||||
	g_signal_connect (panel->priv->treeview,
 | 
			
		||||
			  "query-tooltip",
 | 
			
		||||
			  G_CALLBACK (treeview_query_tooltip),
 | 
			
		||||
			  NULL);
 | 
			
		||||
 | 
			
		||||
	g_signal_connect (panel->priv->model,
 | 
			
		||||
			  "row-inserted",
 | 
			
		||||
			  G_CALLBACK (treeview_row_inserted),
 | 
			
		||||
			  panel);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GtkWidget *
 | 
			
		||||
xedit_documents_panel_new (XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_WINDOW (window), NULL);
 | 
			
		||||
 | 
			
		||||
	return GTK_WIDGET (g_object_new (XEDIT_TYPE_DOCUMENTS_PANEL,
 | 
			
		||||
					 "window", window,
 | 
			
		||||
					 NULL));
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										93
									
								
								xedit/xedit-documents-panel.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								xedit/xedit-documents-panel.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,93 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-documents-panel.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2005 - Paolo Maggi 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_DOCUMENTS_PANEL_H__
 | 
			
		||||
#define __XEDIT_DOCUMENTS_PANEL_H__
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
#include <xedit/xedit-window.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Type checking and casting macros
 | 
			
		||||
 */
 | 
			
		||||
#define XEDIT_TYPE_DOCUMENTS_PANEL              (xedit_documents_panel_get_type())
 | 
			
		||||
#define XEDIT_DOCUMENTS_PANEL(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), XEDIT_TYPE_DOCUMENTS_PANEL, XeditDocumentsPanel))
 | 
			
		||||
#define XEDIT_DOCUMENTS_PANEL_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), XEDIT_TYPE_DOCUMENTS_PANEL, XeditDocumentsPanelClass))
 | 
			
		||||
#define XEDIT_IS_DOCUMENTS_PANEL(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), XEDIT_TYPE_DOCUMENTS_PANEL))
 | 
			
		||||
#define XEDIT_IS_DOCUMENTS_PANEL_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), XEDIT_TYPE_DOCUMENTS_PANEL))
 | 
			
		||||
#define XEDIT_DOCUMENTS_PANEL_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), XEDIT_TYPE_DOCUMENTS_PANEL, XeditDocumentsPanelClass))
 | 
			
		||||
 | 
			
		||||
/* Private structure type */
 | 
			
		||||
typedef struct _XeditDocumentsPanelPrivate XeditDocumentsPanelPrivate;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Main object structure
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _XeditDocumentsPanel XeditDocumentsPanel;
 | 
			
		||||
 | 
			
		||||
struct _XeditDocumentsPanel 
 | 
			
		||||
{
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
	GtkBox vbox;
 | 
			
		||||
#else
 | 
			
		||||
	GtkVBox vbox;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/*< private > */
 | 
			
		||||
	XeditDocumentsPanelPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Class definition
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _XeditDocumentsPanelClass XeditDocumentsPanelClass;
 | 
			
		||||
 | 
			
		||||
struct _XeditDocumentsPanelClass 
 | 
			
		||||
{
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
	GtkBoxClass parent_class;
 | 
			
		||||
#else
 | 
			
		||||
	GtkVBoxClass parent_class;
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Public methods
 | 
			
		||||
 */
 | 
			
		||||
GType 		 xedit_documents_panel_get_type	(void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
GtkWidget	*xedit_documents_panel_new 	(XeditWindow *window);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif  /* __XEDIT_DOCUMENTS_PANEL_H__  */
 | 
			
		||||
							
								
								
									
										469
									
								
								xedit/xedit-encodings-combo-box.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										469
									
								
								xedit/xedit-encodings-combo-box.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,469 @@
 | 
			
		||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-encodings-combo-box.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2003-2005 - Paolo Maggi
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2003-2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: xedit-encodings-combo-box.c 6112 2008-01-23 08:26:24Z sfre $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
#include <xedit/xedit-encodings-combo-box.h>
 | 
			
		||||
#include <xedit/xedit-prefs-manager.h>
 | 
			
		||||
#include <xedit/dialogs/xedit-encodings-dialog.h>
 | 
			
		||||
 | 
			
		||||
#define ENCODING_KEY "Enconding"
 | 
			
		||||
 | 
			
		||||
#define XEDIT_ENCODINGS_COMBO_BOX_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object),	\
 | 
			
		||||
							XEDIT_TYPE_ENCODINGS_COMBO_BOX,	\
 | 
			
		||||
							XeditEncodingsComboBoxPrivate))
 | 
			
		||||
 | 
			
		||||
struct _XeditEncodingsComboBoxPrivate
 | 
			
		||||
{
 | 
			
		||||
	GtkListStore *store;
 | 
			
		||||
	glong changed_id;
 | 
			
		||||
 | 
			
		||||
	guint activated_item;
 | 
			
		||||
 | 
			
		||||
	guint save_mode : 1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
	NAME_COLUMN,
 | 
			
		||||
	ENCODING_COLUMN,
 | 
			
		||||
	ADD_COLUMN,
 | 
			
		||||
	N_COLUMNS
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Properties */
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
	PROP_0,
 | 
			
		||||
	PROP_SAVE_MODE
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE(XeditEncodingsComboBox, xedit_encodings_combo_box, GTK_TYPE_COMBO_BOX)
 | 
			
		||||
 | 
			
		||||
static void	  update_menu 		(XeditEncodingsComboBox       *combo_box);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_encodings_combo_box_set_property (GObject    *object,
 | 
			
		||||
					guint       prop_id,
 | 
			
		||||
					const       GValue *value,
 | 
			
		||||
					GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
	XeditEncodingsComboBox *combo;
 | 
			
		||||
 | 
			
		||||
	combo = XEDIT_ENCODINGS_COMBO_BOX (object);
 | 
			
		||||
 | 
			
		||||
	switch (prop_id)
 | 
			
		||||
	{
 | 
			
		||||
		case PROP_SAVE_MODE:
 | 
			
		||||
			combo->priv->save_mode = g_value_get_boolean (value);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_encodings_combo_box_get_property (GObject    *object,
 | 
			
		||||
					guint       prop_id,
 | 
			
		||||
					GValue 	   *value,
 | 
			
		||||
					GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
	XeditEncodingsComboBox *combo;
 | 
			
		||||
 | 
			
		||||
	combo = XEDIT_ENCODINGS_COMBO_BOX (object);
 | 
			
		||||
 | 
			
		||||
	switch (prop_id)
 | 
			
		||||
	{	
 | 
			
		||||
		case PROP_SAVE_MODE:
 | 
			
		||||
			g_value_set_boolean (value, combo->priv->save_mode);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_encodings_combo_box_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
	XeditEncodingsComboBox *combo = XEDIT_ENCODINGS_COMBO_BOX (object);
 | 
			
		||||
 | 
			
		||||
	if (combo->priv->store != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		g_object_unref (combo->priv->store);
 | 
			
		||||
		combo->priv->store = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	G_OBJECT_CLASS (xedit_encodings_combo_box_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_encodings_combo_box_class_init (XeditEncodingsComboBoxClass *klass)
 | 
			
		||||
{
 | 
			
		||||
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
	object_class->set_property = xedit_encodings_combo_box_set_property;
 | 
			
		||||
	object_class->get_property = xedit_encodings_combo_box_get_property;
 | 
			
		||||
	object_class->dispose = xedit_encodings_combo_box_dispose;
 | 
			
		||||
 | 
			
		||||
	g_object_class_install_property (object_class,
 | 
			
		||||
					 PROP_SAVE_MODE,
 | 
			
		||||
					 g_param_spec_boolean ("save-mode",
 | 
			
		||||
							       "Save Mode",
 | 
			
		||||
							       "Save Mode",
 | 
			
		||||
							       FALSE,
 | 
			
		||||
							       G_PARAM_READWRITE |
 | 
			
		||||
							       G_PARAM_CONSTRUCT |
 | 
			
		||||
							       G_PARAM_STATIC_STRINGS));
 | 
			
		||||
 | 
			
		||||
	g_type_class_add_private (object_class, sizeof (XeditEncodingsComboBoxPrivate));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
dialog_response_cb (GtkDialog              *dialog,
 | 
			
		||||
                    gint                    response_id,
 | 
			
		||||
                    XeditEncodingsComboBox *menu)
 | 
			
		||||
{
 | 
			
		||||
	if (response_id == GTK_RESPONSE_OK)
 | 
			
		||||
	{
 | 
			
		||||
		update_menu (menu);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gtk_widget_destroy (GTK_WIDGET (dialog));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
add_or_remove (XeditEncodingsComboBox *menu,
 | 
			
		||||
	       GtkTreeModel           *model)
 | 
			
		||||
{
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
	gboolean add_item = FALSE;
 | 
			
		||||
 | 
			
		||||
	if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (menu), &iter))
 | 
			
		||||
	{
 | 
			
		||||
		gtk_tree_model_get (model, &iter,
 | 
			
		||||
				    ADD_COLUMN, &add_item,
 | 
			
		||||
				    -1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!add_item)
 | 
			
		||||
	{
 | 
			
		||||
		menu->priv->activated_item = gtk_combo_box_get_active (GTK_COMBO_BOX (menu));
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		GtkWidget *dialog;
 | 
			
		||||
 | 
			
		||||
		GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (menu));
 | 
			
		||||
 | 
			
		||||
		if (!gtk_widget_is_toplevel (toplevel))
 | 
			
		||||
			toplevel = NULL;
 | 
			
		||||
 | 
			
		||||
		g_signal_handler_block (menu, menu->priv->changed_id);
 | 
			
		||||
		gtk_combo_box_set_active (GTK_COMBO_BOX (menu),
 | 
			
		||||
					  menu->priv->activated_item);
 | 
			
		||||
		g_signal_handler_unblock (menu, menu->priv->changed_id);
 | 
			
		||||
 | 
			
		||||
		dialog = xedit_encodings_dialog_new();
 | 
			
		||||
 | 
			
		||||
		if (toplevel != NULL)
 | 
			
		||||
		{
 | 
			
		||||
			GtkWindowGroup *wg;
 | 
			
		||||
 | 
			
		||||
			gtk_window_set_transient_for (GTK_WINDOW (dialog),
 | 
			
		||||
						      GTK_WINDOW (toplevel));
 | 
			
		||||
 | 
			
		||||
			wg = gtk_window_get_group (GTK_WINDOW (toplevel));
 | 
			
		||||
			if (wg == NULL)
 | 
			
		||||
			{
 | 
			
		||||
				wg = gtk_window_group_new ();
 | 
			
		||||
				gtk_window_group_add_window (wg,
 | 
			
		||||
							     GTK_WINDOW (toplevel));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			gtk_window_group_add_window (wg,
 | 
			
		||||
						     GTK_WINDOW (dialog));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
 | 
			
		||||
 | 
			
		||||
		g_signal_connect (dialog,
 | 
			
		||||
				  "response",
 | 
			
		||||
				  G_CALLBACK (dialog_response_cb),
 | 
			
		||||
				  menu);
 | 
			
		||||
 | 
			
		||||
		gtk_widget_show (dialog);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
separator_func (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
 | 
			
		||||
{
 | 
			
		||||
	gchar *str;
 | 
			
		||||
	gboolean ret;
 | 
			
		||||
 | 
			
		||||
	gtk_tree_model_get (model, iter, NAME_COLUMN, &str, -1);
 | 
			
		||||
	ret = (str == NULL || *str == '\0');
 | 
			
		||||
	g_free (str);
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_menu (XeditEncodingsComboBox *menu)
 | 
			
		||||
{
 | 
			
		||||
	GtkListStore *store;
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
	GSList *encodings, *l;
 | 
			
		||||
	gchar *str;
 | 
			
		||||
	const XeditEncoding *utf8_encoding;
 | 
			
		||||
	const XeditEncoding *current_encoding;
 | 
			
		||||
 | 
			
		||||
	store = menu->priv->store;
 | 
			
		||||
 | 
			
		||||
	/* Unset the previous model */
 | 
			
		||||
	g_signal_handler_block (menu, menu->priv->changed_id);
 | 
			
		||||
	gtk_list_store_clear (store);
 | 
			
		||||
	gtk_combo_box_set_model (GTK_COMBO_BOX (menu),
 | 
			
		||||
				 NULL);
 | 
			
		||||
 | 
			
		||||
	utf8_encoding = xedit_encoding_get_utf8 ();
 | 
			
		||||
	current_encoding = xedit_encoding_get_current ();
 | 
			
		||||
 | 
			
		||||
	if (!menu->priv->save_mode)
 | 
			
		||||
	{
 | 
			
		||||
		gtk_list_store_append (store, &iter);
 | 
			
		||||
		gtk_list_store_set (store, &iter,
 | 
			
		||||
				    NAME_COLUMN, _("Automatically Detected"),
 | 
			
		||||
				    ENCODING_COLUMN, NULL,
 | 
			
		||||
				    ADD_COLUMN, FALSE,
 | 
			
		||||
				    -1);
 | 
			
		||||
 | 
			
		||||
		gtk_list_store_append (store, &iter);
 | 
			
		||||
		gtk_list_store_set (store, &iter,
 | 
			
		||||
				    NAME_COLUMN, "",
 | 
			
		||||
				    ENCODING_COLUMN, NULL,
 | 
			
		||||
				    ADD_COLUMN, FALSE,
 | 
			
		||||
				    -1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (current_encoding != utf8_encoding)
 | 
			
		||||
		str = xedit_encoding_to_string (utf8_encoding);
 | 
			
		||||
	else
 | 
			
		||||
		str = g_strdup_printf (_("Current Locale (%s)"),
 | 
			
		||||
				       xedit_encoding_get_charset (utf8_encoding));
 | 
			
		||||
 | 
			
		||||
	gtk_list_store_append (store, &iter);
 | 
			
		||||
	gtk_list_store_set (store, &iter,
 | 
			
		||||
			    NAME_COLUMN, str,
 | 
			
		||||
			    ENCODING_COLUMN, utf8_encoding,
 | 
			
		||||
			    ADD_COLUMN, FALSE,
 | 
			
		||||
			    -1);
 | 
			
		||||
 | 
			
		||||
	g_free (str);
 | 
			
		||||
 | 
			
		||||
	if ((utf8_encoding != current_encoding) &&
 | 
			
		||||
	    (current_encoding != NULL))
 | 
			
		||||
	{
 | 
			
		||||
		str = g_strdup_printf (_("Current Locale (%s)"),
 | 
			
		||||
				       xedit_encoding_get_charset (current_encoding));
 | 
			
		||||
 | 
			
		||||
		gtk_list_store_append (store, &iter);
 | 
			
		||||
		gtk_list_store_set (store, &iter,
 | 
			
		||||
				    NAME_COLUMN, str,
 | 
			
		||||
				    ENCODING_COLUMN, current_encoding,
 | 
			
		||||
				    ADD_COLUMN, FALSE,
 | 
			
		||||
				    -1);
 | 
			
		||||
 | 
			
		||||
		g_free (str);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	encodings = xedit_prefs_manager_get_shown_in_menu_encodings ();
 | 
			
		||||
 | 
			
		||||
	for (l = encodings; l != NULL; l = g_slist_next (l))
 | 
			
		||||
	{
 | 
			
		||||
		const XeditEncoding *enc = (const XeditEncoding *)l->data;
 | 
			
		||||
 | 
			
		||||
		if ((enc != current_encoding) &&
 | 
			
		||||
		    (enc != utf8_encoding) &&
 | 
			
		||||
		    (enc != NULL))
 | 
			
		||||
		{
 | 
			
		||||
			str = xedit_encoding_to_string (enc);
 | 
			
		||||
 | 
			
		||||
			gtk_list_store_append (store, &iter);
 | 
			
		||||
			gtk_list_store_set (store, &iter,
 | 
			
		||||
					    NAME_COLUMN, str,
 | 
			
		||||
					    ENCODING_COLUMN, enc,
 | 
			
		||||
					    ADD_COLUMN, FALSE,
 | 
			
		||||
					    -1);
 | 
			
		||||
 | 
			
		||||
			g_free (str);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_slist_free (encodings);
 | 
			
		||||
 | 
			
		||||
	if (xedit_prefs_manager_shown_in_menu_encodings_can_set ())
 | 
			
		||||
	{
 | 
			
		||||
		gtk_list_store_append (store, &iter);
 | 
			
		||||
		/* separator */
 | 
			
		||||
		gtk_list_store_set (store, &iter,
 | 
			
		||||
				    NAME_COLUMN, "",
 | 
			
		||||
				    ENCODING_COLUMN, NULL,
 | 
			
		||||
				    ADD_COLUMN, FALSE,
 | 
			
		||||
				    -1);
 | 
			
		||||
 | 
			
		||||
		gtk_list_store_append (store, &iter);
 | 
			
		||||
		gtk_list_store_set (store, &iter,
 | 
			
		||||
				    NAME_COLUMN, _("Add or Remove..."),
 | 
			
		||||
				    ENCODING_COLUMN, NULL,
 | 
			
		||||
				    ADD_COLUMN, TRUE,
 | 
			
		||||
				    -1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* set the model back */
 | 
			
		||||
	gtk_combo_box_set_model (GTK_COMBO_BOX (menu),
 | 
			
		||||
				 GTK_TREE_MODEL (menu->priv->store));
 | 
			
		||||
	gtk_combo_box_set_active (GTK_COMBO_BOX (menu), 0);
 | 
			
		||||
 | 
			
		||||
	g_signal_handler_unblock (menu, menu->priv->changed_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_encodings_combo_box_init (XeditEncodingsComboBox *menu)
 | 
			
		||||
{
 | 
			
		||||
	GtkCellRenderer *text_renderer;
 | 
			
		||||
 | 
			
		||||
	menu->priv = XEDIT_ENCODINGS_COMBO_BOX_GET_PRIVATE (menu);
 | 
			
		||||
 | 
			
		||||
	menu->priv->store = gtk_list_store_new (N_COLUMNS,
 | 
			
		||||
						G_TYPE_STRING,
 | 
			
		||||
						G_TYPE_POINTER,
 | 
			
		||||
						G_TYPE_BOOLEAN);
 | 
			
		||||
 | 
			
		||||
	/* Setup up the cells */
 | 
			
		||||
	text_renderer = gtk_cell_renderer_text_new ();
 | 
			
		||||
	gtk_cell_layout_pack_end (GTK_CELL_LAYOUT (menu),
 | 
			
		||||
				  text_renderer, TRUE);
 | 
			
		||||
 | 
			
		||||
	gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (menu),
 | 
			
		||||
					text_renderer,
 | 
			
		||||
					"text",
 | 
			
		||||
					NAME_COLUMN,
 | 
			
		||||
					NULL);
 | 
			
		||||
 | 
			
		||||
	gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (menu),
 | 
			
		||||
					      separator_func, NULL,
 | 
			
		||||
					      NULL);
 | 
			
		||||
 | 
			
		||||
	menu->priv->changed_id = g_signal_connect (menu, "changed",
 | 
			
		||||
						   G_CALLBACK (add_or_remove),
 | 
			
		||||
						   menu->priv->store);
 | 
			
		||||
 | 
			
		||||
	update_menu (menu);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GtkWidget *
 | 
			
		||||
xedit_encodings_combo_box_new (gboolean save_mode)
 | 
			
		||||
{
 | 
			
		||||
	return g_object_new (XEDIT_TYPE_ENCODINGS_COMBO_BOX,
 | 
			
		||||
			     "save_mode", save_mode,
 | 
			
		||||
			     NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const XeditEncoding *
 | 
			
		||||
xedit_encodings_combo_box_get_selected_encoding (XeditEncodingsComboBox *menu)
 | 
			
		||||
{
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_ENCODINGS_COMBO_BOX (menu), NULL);
 | 
			
		||||
 | 
			
		||||
	if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (menu), &iter))
 | 
			
		||||
	{
 | 
			
		||||
		const XeditEncoding *ret;
 | 
			
		||||
		GtkTreeModel *model;
 | 
			
		||||
 | 
			
		||||
		model = gtk_combo_box_get_model (GTK_COMBO_BOX (menu));
 | 
			
		||||
 | 
			
		||||
		gtk_tree_model_get (model, &iter,
 | 
			
		||||
				    ENCODING_COLUMN, &ret,
 | 
			
		||||
				    -1);
 | 
			
		||||
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_encodings_combo_box_set_selected_encoding:
 | 
			
		||||
 * @menu:
 | 
			
		||||
 * @encoding: (allow-none):
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
xedit_encodings_combo_box_set_selected_encoding (XeditEncodingsComboBox *menu,
 | 
			
		||||
						 const XeditEncoding    *encoding)
 | 
			
		||||
{
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
	GtkTreeModel *model;
 | 
			
		||||
	gboolean b;
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_ENCODINGS_COMBO_BOX (menu));
 | 
			
		||||
	g_return_if_fail (GTK_IS_COMBO_BOX (menu));
 | 
			
		||||
 | 
			
		||||
	model = gtk_combo_box_get_model (GTK_COMBO_BOX (menu));
 | 
			
		||||
	b = gtk_tree_model_get_iter_first (model, &iter);
 | 
			
		||||
 | 
			
		||||
	while (b)
 | 
			
		||||
	{
 | 
			
		||||
		const XeditEncoding *enc;
 | 
			
		||||
 | 
			
		||||
		gtk_tree_model_get (model, &iter,
 | 
			
		||||
				    ENCODING_COLUMN, &enc,
 | 
			
		||||
				    -1);
 | 
			
		||||
 | 
			
		||||
		if (enc == encoding)
 | 
			
		||||
		{
 | 
			
		||||
			gtk_combo_box_set_active_iter (GTK_COMBO_BOX (menu),
 | 
			
		||||
						       &iter);
 | 
			
		||||
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		b = gtk_tree_model_iter_next (model, &iter);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										78
									
								
								xedit/xedit-encodings-combo-box.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								xedit/xedit-encodings-combo-box.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
			
		||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-encodings-combo-box.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2003-2005 - Paolo Maggi
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2003-2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: xedit-encodings-option-menu.h 4429 2005-12-12 17:28:04Z pborelli $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_ENCODINGS_COMBO_BOX_H__
 | 
			
		||||
#define __XEDIT_ENCODINGS_COMBO_BOX_H__
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
#include <xedit/xedit-encodings.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define XEDIT_TYPE_ENCODINGS_COMBO_BOX             (xedit_encodings_combo_box_get_type ())
 | 
			
		||||
#define XEDIT_ENCODINGS_COMBO_BOX(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), XEDIT_TYPE_ENCODINGS_COMBO_BOX, XeditEncodingsComboBox))
 | 
			
		||||
#define XEDIT_ENCODINGS_COMBO_BOX_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), XEDIT_TYPE_ENCODINGS_COMBO_BOX, XeditEncodingsComboBoxClass))
 | 
			
		||||
#define XEDIT_IS_ENCODINGS_COMBO_BOX(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XEDIT_TYPE_ENCODINGS_COMBO_BOX))
 | 
			
		||||
#define XEDIT_IS_ENCODINGS_COMBO_BOX_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), XEDIT_TYPE_ENCODINGS_COMBO_BOX))
 | 
			
		||||
#define XEDIT_ENCODINGS_COMBO_BOX_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), XEDIT_TYPE_ENCODINGS_COMBO_BOX, XeditEncodingsComboBoxClass))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct _XeditEncodingsComboBox 	XeditEncodingsComboBox;
 | 
			
		||||
typedef struct _XeditEncodingsComboBoxClass 	XeditEncodingsComboBoxClass;
 | 
			
		||||
 | 
			
		||||
typedef struct _XeditEncodingsComboBoxPrivate	XeditEncodingsComboBoxPrivate;
 | 
			
		||||
 | 
			
		||||
struct _XeditEncodingsComboBox
 | 
			
		||||
{
 | 
			
		||||
	GtkComboBox			 parent;
 | 
			
		||||
 | 
			
		||||
	XeditEncodingsComboBoxPrivate	*priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _XeditEncodingsComboBoxClass
 | 
			
		||||
{
 | 
			
		||||
	GtkComboBoxClass		 parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType		     xedit_encodings_combo_box_get_type		(void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
/* Constructor */
 | 
			
		||||
GtkWidget 	    *xedit_encodings_combo_box_new 			(gboolean save_mode);
 | 
			
		||||
 | 
			
		||||
const XeditEncoding *xedit_encodings_combo_box_get_selected_encoding	(XeditEncodingsComboBox *menu);
 | 
			
		||||
void		     xedit_encodings_combo_box_set_selected_encoding	(XeditEncodingsComboBox *menu,
 | 
			
		||||
									 const XeditEncoding      *encoding);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __XEDIT_ENCODINGS_COMBO_BOX_H__ */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										473
									
								
								xedit/xedit-encodings.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										473
									
								
								xedit/xedit-encodings.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,473 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-encodings.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2002-2005 Paolo Maggi 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2002-2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
 | 
			
		||||
#include "xedit-encodings.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct _XeditEncoding
 | 
			
		||||
{
 | 
			
		||||
	gint   index;
 | 
			
		||||
	const gchar *charset;
 | 
			
		||||
	const gchar *name;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 * The original versions of the following tables are taken from profterm 
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2002 Red Hat, Inc.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
  XEDIT_ENCODING_ISO_8859_1,
 | 
			
		||||
  XEDIT_ENCODING_ISO_8859_2,
 | 
			
		||||
  XEDIT_ENCODING_ISO_8859_3,
 | 
			
		||||
  XEDIT_ENCODING_ISO_8859_4,
 | 
			
		||||
  XEDIT_ENCODING_ISO_8859_5,
 | 
			
		||||
  XEDIT_ENCODING_ISO_8859_6,
 | 
			
		||||
  XEDIT_ENCODING_ISO_8859_7,
 | 
			
		||||
  XEDIT_ENCODING_ISO_8859_8,
 | 
			
		||||
  XEDIT_ENCODING_ISO_8859_9,
 | 
			
		||||
  XEDIT_ENCODING_ISO_8859_10,
 | 
			
		||||
  XEDIT_ENCODING_ISO_8859_13,
 | 
			
		||||
  XEDIT_ENCODING_ISO_8859_14,
 | 
			
		||||
  XEDIT_ENCODING_ISO_8859_15,
 | 
			
		||||
  XEDIT_ENCODING_ISO_8859_16,
 | 
			
		||||
 | 
			
		||||
  XEDIT_ENCODING_UTF_7,
 | 
			
		||||
  XEDIT_ENCODING_UTF_16,
 | 
			
		||||
  XEDIT_ENCODING_UTF_16_BE,
 | 
			
		||||
  XEDIT_ENCODING_UTF_16_LE,
 | 
			
		||||
  XEDIT_ENCODING_UTF_32,
 | 
			
		||||
  XEDIT_ENCODING_UCS_2,
 | 
			
		||||
  XEDIT_ENCODING_UCS_4,
 | 
			
		||||
 | 
			
		||||
  XEDIT_ENCODING_ARMSCII_8,
 | 
			
		||||
  XEDIT_ENCODING_BIG5,
 | 
			
		||||
  XEDIT_ENCODING_BIG5_HKSCS,
 | 
			
		||||
  XEDIT_ENCODING_CP_866,
 | 
			
		||||
 | 
			
		||||
  XEDIT_ENCODING_EUC_JP,
 | 
			
		||||
  XEDIT_ENCODING_EUC_JP_MS,
 | 
			
		||||
  XEDIT_ENCODING_CP932,
 | 
			
		||||
  XEDIT_ENCODING_EUC_KR,
 | 
			
		||||
  XEDIT_ENCODING_EUC_TW,
 | 
			
		||||
 | 
			
		||||
  XEDIT_ENCODING_GB18030,
 | 
			
		||||
  XEDIT_ENCODING_GB2312,
 | 
			
		||||
  XEDIT_ENCODING_GBK,
 | 
			
		||||
  XEDIT_ENCODING_GEOSTD8,
 | 
			
		||||
 | 
			
		||||
  XEDIT_ENCODING_IBM_850,
 | 
			
		||||
  XEDIT_ENCODING_IBM_852,
 | 
			
		||||
  XEDIT_ENCODING_IBM_855,
 | 
			
		||||
  XEDIT_ENCODING_IBM_857,
 | 
			
		||||
  XEDIT_ENCODING_IBM_862,
 | 
			
		||||
  XEDIT_ENCODING_IBM_864,
 | 
			
		||||
 | 
			
		||||
  XEDIT_ENCODING_ISO_2022_JP,
 | 
			
		||||
  XEDIT_ENCODING_ISO_2022_KR,
 | 
			
		||||
  XEDIT_ENCODING_ISO_IR_111,
 | 
			
		||||
  XEDIT_ENCODING_JOHAB,
 | 
			
		||||
  XEDIT_ENCODING_KOI8_R,
 | 
			
		||||
  XEDIT_ENCODING_KOI8__R,
 | 
			
		||||
  XEDIT_ENCODING_KOI8_U,
 | 
			
		||||
  
 | 
			
		||||
  XEDIT_ENCODING_SHIFT_JIS,
 | 
			
		||||
  XEDIT_ENCODING_TCVN,
 | 
			
		||||
  XEDIT_ENCODING_TIS_620,
 | 
			
		||||
  XEDIT_ENCODING_UHC,
 | 
			
		||||
  XEDIT_ENCODING_VISCII,
 | 
			
		||||
 | 
			
		||||
  XEDIT_ENCODING_WINDOWS_1250,
 | 
			
		||||
  XEDIT_ENCODING_WINDOWS_1251,
 | 
			
		||||
  XEDIT_ENCODING_WINDOWS_1252,
 | 
			
		||||
  XEDIT_ENCODING_WINDOWS_1253,
 | 
			
		||||
  XEDIT_ENCODING_WINDOWS_1254,
 | 
			
		||||
  XEDIT_ENCODING_WINDOWS_1255,
 | 
			
		||||
  XEDIT_ENCODING_WINDOWS_1256,
 | 
			
		||||
  XEDIT_ENCODING_WINDOWS_1257,
 | 
			
		||||
  XEDIT_ENCODING_WINDOWS_1258,
 | 
			
		||||
 | 
			
		||||
  XEDIT_ENCODING_LAST,
 | 
			
		||||
 | 
			
		||||
  XEDIT_ENCODING_UTF_8,
 | 
			
		||||
  XEDIT_ENCODING_UNKNOWN
 | 
			
		||||
  
 | 
			
		||||
} XeditEncodingIndex;
 | 
			
		||||
 | 
			
		||||
static const XeditEncoding utf8_encoding =  {
 | 
			
		||||
	XEDIT_ENCODING_UTF_8,
 | 
			
		||||
	"UTF-8",
 | 
			
		||||
	N_("Unicode")
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* initialized in xedit_encoding_lazy_init() */
 | 
			
		||||
static XeditEncoding unknown_encoding = {
 | 
			
		||||
	XEDIT_ENCODING_UNKNOWN,
 | 
			
		||||
	NULL, 
 | 
			
		||||
	NULL 
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const XeditEncoding encodings [] = {
 | 
			
		||||
 | 
			
		||||
  { XEDIT_ENCODING_ISO_8859_1,
 | 
			
		||||
    "ISO-8859-1", N_("Western") },
 | 
			
		||||
  { XEDIT_ENCODING_ISO_8859_2,
 | 
			
		||||
   "ISO-8859-2", N_("Central European") },
 | 
			
		||||
  { XEDIT_ENCODING_ISO_8859_3,
 | 
			
		||||
    "ISO-8859-3", N_("South European") },
 | 
			
		||||
  { XEDIT_ENCODING_ISO_8859_4,
 | 
			
		||||
    "ISO-8859-4", N_("Baltic") },
 | 
			
		||||
  { XEDIT_ENCODING_ISO_8859_5,
 | 
			
		||||
    "ISO-8859-5", N_("Cyrillic") },
 | 
			
		||||
  { XEDIT_ENCODING_ISO_8859_6,
 | 
			
		||||
    "ISO-8859-6", N_("Arabic") },
 | 
			
		||||
  { XEDIT_ENCODING_ISO_8859_7,
 | 
			
		||||
    "ISO-8859-7", N_("Greek") },
 | 
			
		||||
  { XEDIT_ENCODING_ISO_8859_8,
 | 
			
		||||
    "ISO-8859-8", N_("Hebrew Visual") },
 | 
			
		||||
  { XEDIT_ENCODING_ISO_8859_9,
 | 
			
		||||
    "ISO-8859-9", N_("Turkish") },
 | 
			
		||||
  { XEDIT_ENCODING_ISO_8859_10,
 | 
			
		||||
    "ISO-8859-10", N_("Nordic") },
 | 
			
		||||
  { XEDIT_ENCODING_ISO_8859_13,
 | 
			
		||||
    "ISO-8859-13", N_("Baltic") },
 | 
			
		||||
  { XEDIT_ENCODING_ISO_8859_14,
 | 
			
		||||
    "ISO-8859-14", N_("Celtic") },
 | 
			
		||||
  { XEDIT_ENCODING_ISO_8859_15,
 | 
			
		||||
    "ISO-8859-15", N_("Western") },
 | 
			
		||||
  { XEDIT_ENCODING_ISO_8859_16,
 | 
			
		||||
    "ISO-8859-16", N_("Romanian") },
 | 
			
		||||
 | 
			
		||||
  { XEDIT_ENCODING_UTF_7,
 | 
			
		||||
    "UTF-7", N_("Unicode") },
 | 
			
		||||
  { XEDIT_ENCODING_UTF_16,
 | 
			
		||||
    "UTF-16", N_("Unicode") },
 | 
			
		||||
  { XEDIT_ENCODING_UTF_16_BE,
 | 
			
		||||
    "UTF-16BE", N_("Unicode") },
 | 
			
		||||
  { XEDIT_ENCODING_UTF_16_LE,
 | 
			
		||||
    "UTF-16LE", N_("Unicode") },
 | 
			
		||||
  { XEDIT_ENCODING_UTF_32,
 | 
			
		||||
    "UTF-32", N_("Unicode") },
 | 
			
		||||
  { XEDIT_ENCODING_UCS_2,
 | 
			
		||||
    "UCS-2", N_("Unicode") },
 | 
			
		||||
  { XEDIT_ENCODING_UCS_4,
 | 
			
		||||
    "UCS-4", N_("Unicode") },
 | 
			
		||||
 | 
			
		||||
  { XEDIT_ENCODING_ARMSCII_8,
 | 
			
		||||
    "ARMSCII-8", N_("Armenian") },
 | 
			
		||||
  { XEDIT_ENCODING_BIG5,
 | 
			
		||||
    "BIG5", N_("Chinese Traditional") },
 | 
			
		||||
  { XEDIT_ENCODING_BIG5_HKSCS,
 | 
			
		||||
    "BIG5-HKSCS", N_("Chinese Traditional") },
 | 
			
		||||
  { XEDIT_ENCODING_CP_866,
 | 
			
		||||
    "CP866", N_("Cyrillic/Russian") },
 | 
			
		||||
 | 
			
		||||
  { XEDIT_ENCODING_EUC_JP,
 | 
			
		||||
    "EUC-JP", N_("Japanese") },
 | 
			
		||||
  { XEDIT_ENCODING_EUC_JP_MS,
 | 
			
		||||
    "EUC-JP-MS", N_("Japanese") },
 | 
			
		||||
  { XEDIT_ENCODING_CP932,
 | 
			
		||||
    "CP932", N_("Japanese") },
 | 
			
		||||
 | 
			
		||||
  { XEDIT_ENCODING_EUC_KR,
 | 
			
		||||
    "EUC-KR", N_("Korean") },
 | 
			
		||||
  { XEDIT_ENCODING_EUC_TW,
 | 
			
		||||
    "EUC-TW", N_("Chinese Traditional") },
 | 
			
		||||
 | 
			
		||||
  { XEDIT_ENCODING_GB18030,
 | 
			
		||||
    "GB18030", N_("Chinese Simplified") },
 | 
			
		||||
  { XEDIT_ENCODING_GB2312,
 | 
			
		||||
    "GB2312", N_("Chinese Simplified") },
 | 
			
		||||
  { XEDIT_ENCODING_GBK,
 | 
			
		||||
    "GBK", N_("Chinese Simplified") },
 | 
			
		||||
  { XEDIT_ENCODING_GEOSTD8,
 | 
			
		||||
    "GEORGIAN-ACADEMY", N_("Georgian") }, /* FIXME GEOSTD8 ? */
 | 
			
		||||
 | 
			
		||||
  { XEDIT_ENCODING_IBM_850,
 | 
			
		||||
    "IBM850", N_("Western") },
 | 
			
		||||
  { XEDIT_ENCODING_IBM_852,
 | 
			
		||||
    "IBM852", N_("Central European") },
 | 
			
		||||
  { XEDIT_ENCODING_IBM_855,
 | 
			
		||||
    "IBM855", N_("Cyrillic") },
 | 
			
		||||
  { XEDIT_ENCODING_IBM_857,
 | 
			
		||||
    "IBM857", N_("Turkish") },
 | 
			
		||||
  { XEDIT_ENCODING_IBM_862,
 | 
			
		||||
    "IBM862", N_("Hebrew") },
 | 
			
		||||
  { XEDIT_ENCODING_IBM_864,
 | 
			
		||||
    "IBM864", N_("Arabic") },
 | 
			
		||||
 | 
			
		||||
  { XEDIT_ENCODING_ISO_2022_JP,
 | 
			
		||||
    "ISO-2022-JP", N_("Japanese") },
 | 
			
		||||
  { XEDIT_ENCODING_ISO_2022_KR,
 | 
			
		||||
    "ISO-2022-KR", N_("Korean") },
 | 
			
		||||
  { XEDIT_ENCODING_ISO_IR_111,
 | 
			
		||||
    "ISO-IR-111", N_("Cyrillic") },
 | 
			
		||||
  { XEDIT_ENCODING_JOHAB,
 | 
			
		||||
    "JOHAB", N_("Korean") },
 | 
			
		||||
  { XEDIT_ENCODING_KOI8_R,
 | 
			
		||||
    "KOI8R", N_("Cyrillic") },
 | 
			
		||||
  { XEDIT_ENCODING_KOI8__R,
 | 
			
		||||
    "KOI8-R", N_("Cyrillic") },
 | 
			
		||||
  { XEDIT_ENCODING_KOI8_U,
 | 
			
		||||
    "KOI8U", N_("Cyrillic/Ukrainian") },
 | 
			
		||||
  
 | 
			
		||||
  { XEDIT_ENCODING_SHIFT_JIS,
 | 
			
		||||
    "SHIFT_JIS", N_("Japanese") },
 | 
			
		||||
  { XEDIT_ENCODING_TCVN,
 | 
			
		||||
    "TCVN", N_("Vietnamese") },
 | 
			
		||||
  { XEDIT_ENCODING_TIS_620,
 | 
			
		||||
    "TIS-620", N_("Thai") },
 | 
			
		||||
  { XEDIT_ENCODING_UHC,
 | 
			
		||||
    "UHC", N_("Korean") },
 | 
			
		||||
  { XEDIT_ENCODING_VISCII,
 | 
			
		||||
    "VISCII", N_("Vietnamese") },
 | 
			
		||||
 | 
			
		||||
  { XEDIT_ENCODING_WINDOWS_1250,
 | 
			
		||||
    "WINDOWS-1250", N_("Central European") },
 | 
			
		||||
  { XEDIT_ENCODING_WINDOWS_1251,
 | 
			
		||||
    "WINDOWS-1251", N_("Cyrillic") },
 | 
			
		||||
  { XEDIT_ENCODING_WINDOWS_1252,
 | 
			
		||||
    "WINDOWS-1252", N_("Western") },
 | 
			
		||||
  { XEDIT_ENCODING_WINDOWS_1253,
 | 
			
		||||
    "WINDOWS-1253", N_("Greek") },
 | 
			
		||||
  { XEDIT_ENCODING_WINDOWS_1254,
 | 
			
		||||
    "WINDOWS-1254", N_("Turkish") },
 | 
			
		||||
  { XEDIT_ENCODING_WINDOWS_1255,
 | 
			
		||||
    "WINDOWS-1255", N_("Hebrew") },
 | 
			
		||||
  { XEDIT_ENCODING_WINDOWS_1256,
 | 
			
		||||
    "WINDOWS-1256", N_("Arabic") },
 | 
			
		||||
  { XEDIT_ENCODING_WINDOWS_1257,
 | 
			
		||||
    "WINDOWS-1257", N_("Baltic") },
 | 
			
		||||
  { XEDIT_ENCODING_WINDOWS_1258,
 | 
			
		||||
    "WINDOWS-1258", N_("Vietnamese") }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_encoding_lazy_init (void)
 | 
			
		||||
{
 | 
			
		||||
	static gboolean initialized = FALSE;
 | 
			
		||||
	const gchar *locale_charset;
 | 
			
		||||
 | 
			
		||||
	if (initialized)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (g_get_charset (&locale_charset) == FALSE)
 | 
			
		||||
	{
 | 
			
		||||
		unknown_encoding.charset = g_strdup (locale_charset);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	initialized = TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const XeditEncoding *
 | 
			
		||||
xedit_encoding_get_from_charset (const gchar *charset)
 | 
			
		||||
{
 | 
			
		||||
	gint i;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (charset != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	xedit_encoding_lazy_init ();
 | 
			
		||||
 | 
			
		||||
	if (charset == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	if (g_ascii_strcasecmp (charset, "UTF-8") == 0)
 | 
			
		||||
		return xedit_encoding_get_utf8 ();
 | 
			
		||||
 | 
			
		||||
	i = 0; 
 | 
			
		||||
	while (i < XEDIT_ENCODING_LAST)
 | 
			
		||||
	{
 | 
			
		||||
		if (g_ascii_strcasecmp (charset, encodings[i].charset) == 0)
 | 
			
		||||
			return &encodings[i];
 | 
			
		||||
      
 | 
			
		||||
		++i;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (unknown_encoding.charset != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		if (g_ascii_strcasecmp (charset, unknown_encoding.charset) == 0)
 | 
			
		||||
			return &unknown_encoding;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const XeditEncoding *
 | 
			
		||||
xedit_encoding_get_from_index (gint idx)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (idx >= 0, NULL);
 | 
			
		||||
 | 
			
		||||
	if (idx >= XEDIT_ENCODING_LAST)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	xedit_encoding_lazy_init ();
 | 
			
		||||
 | 
			
		||||
	return &encodings[idx];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const XeditEncoding *
 | 
			
		||||
xedit_encoding_get_utf8 (void)
 | 
			
		||||
{
 | 
			
		||||
	xedit_encoding_lazy_init ();
 | 
			
		||||
 | 
			
		||||
	return &utf8_encoding;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const XeditEncoding *
 | 
			
		||||
xedit_encoding_get_current (void)
 | 
			
		||||
{
 | 
			
		||||
	static gboolean initialized = FALSE;
 | 
			
		||||
	static const XeditEncoding *locale_encoding = NULL;
 | 
			
		||||
 | 
			
		||||
	const gchar *locale_charset;
 | 
			
		||||
 | 
			
		||||
	xedit_encoding_lazy_init ();
 | 
			
		||||
 | 
			
		||||
	if (initialized != FALSE)
 | 
			
		||||
		return locale_encoding;
 | 
			
		||||
 | 
			
		||||
	if (g_get_charset (&locale_charset) == FALSE) 
 | 
			
		||||
	{
 | 
			
		||||
		g_return_val_if_fail (locale_charset != NULL, &utf8_encoding);
 | 
			
		||||
		
 | 
			
		||||
		locale_encoding = xedit_encoding_get_from_charset (locale_charset);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		locale_encoding = &utf8_encoding;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if (locale_encoding == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		locale_encoding = &unknown_encoding;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (locale_encoding != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	initialized = TRUE;
 | 
			
		||||
 | 
			
		||||
	return locale_encoding;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gchar *
 | 
			
		||||
xedit_encoding_to_string (const XeditEncoding* enc)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (enc != NULL, NULL);
 | 
			
		||||
	
 | 
			
		||||
	xedit_encoding_lazy_init ();
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (enc->charset != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	if (enc->name != NULL)
 | 
			
		||||
	{
 | 
			
		||||
	    	return g_strdup_printf ("%s (%s)", _(enc->name), enc->charset);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		if (g_ascii_strcasecmp (enc->charset, "ANSI_X3.4-1968") == 0)
 | 
			
		||||
			return g_strdup_printf ("US-ASCII (%s)", enc->charset);
 | 
			
		||||
		else
 | 
			
		||||
			return g_strdup (enc->charset);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const gchar *
 | 
			
		||||
xedit_encoding_get_charset (const XeditEncoding* enc)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (enc != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	xedit_encoding_lazy_init ();
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (enc->charset != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	return enc->charset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const gchar *
 | 
			
		||||
xedit_encoding_get_name (const XeditEncoding* enc)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (enc != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	xedit_encoding_lazy_init ();
 | 
			
		||||
 | 
			
		||||
	return (enc->name == NULL) ? _("Unknown") : _(enc->name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* These are to make language bindings happy. Since Encodings are
 | 
			
		||||
 * const, copy() just returns the same pointer and fres() doesn't
 | 
			
		||||
 * do nothing */
 | 
			
		||||
 | 
			
		||||
XeditEncoding *
 | 
			
		||||
xedit_encoding_copy (const XeditEncoding *enc)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (enc != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	return (XeditEncoding *) enc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void 
 | 
			
		||||
xedit_encoding_free (XeditEncoding *enc)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (enc != NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_encoding_get_type:
 | 
			
		||||
 * 
 | 
			
		||||
 * Retrieves the GType object which is associated with the
 | 
			
		||||
 * #XeditEncoding class.
 | 
			
		||||
 * 
 | 
			
		||||
 * Return value: the GType associated with #XeditEncoding.
 | 
			
		||||
 **/
 | 
			
		||||
GType 
 | 
			
		||||
xedit_encoding_get_type (void)
 | 
			
		||||
{
 | 
			
		||||
	static GType our_type = 0;
 | 
			
		||||
 | 
			
		||||
	if (!our_type)
 | 
			
		||||
		our_type = g_boxed_type_register_static (
 | 
			
		||||
			"XeditEncoding",
 | 
			
		||||
			(GBoxedCopyFunc) xedit_encoding_copy,
 | 
			
		||||
			(GBoxedFreeFunc) xedit_encoding_free);
 | 
			
		||||
 | 
			
		||||
	return our_type;
 | 
			
		||||
} 
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										62
									
								
								xedit/xedit-encodings.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								xedit/xedit-encodings.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-encodings.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2002-2005 Paolo Maggi 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2002-2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_ENCODINGS_H__
 | 
			
		||||
#define __XEDIT_ENCODINGS_H__
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
typedef struct _XeditEncoding XeditEncoding;
 | 
			
		||||
 | 
			
		||||
#define XEDIT_TYPE_ENCODING     (xedit_encoding_get_type ())
 | 
			
		||||
 | 
			
		||||
GType              	 xedit_encoding_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
const XeditEncoding	*xedit_encoding_get_from_charset (const gchar         *charset);
 | 
			
		||||
const XeditEncoding	*xedit_encoding_get_from_index	 (gint                 index);
 | 
			
		||||
 | 
			
		||||
gchar 			*xedit_encoding_to_string	 (const XeditEncoding *enc);
 | 
			
		||||
 | 
			
		||||
const gchar		*xedit_encoding_get_name	 (const XeditEncoding *enc);
 | 
			
		||||
const gchar		*xedit_encoding_get_charset	 (const XeditEncoding *enc);
 | 
			
		||||
 | 
			
		||||
const XeditEncoding 	*xedit_encoding_get_utf8	 (void);
 | 
			
		||||
const XeditEncoding 	*xedit_encoding_get_current	 (void);
 | 
			
		||||
 | 
			
		||||
/* These should not be used, they are just to make python bindings happy */
 | 
			
		||||
XeditEncoding		*xedit_encoding_copy		 (const XeditEncoding *enc);
 | 
			
		||||
void               	 xedit_encoding_free		 (XeditEncoding       *enc);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif  /* __XEDIT_ENCODINGS_H__ */
 | 
			
		||||
							
								
								
									
										39
									
								
								xedit/xedit-enum-types.c.template
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								xedit/xedit-enum-types.c.template
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
/*** BEGIN file-header ***/
 | 
			
		||||
#include "xedit-enum-types.h"
 | 
			
		||||
 | 
			
		||||
/*** END file-header ***/
 | 
			
		||||
 | 
			
		||||
/*** BEGIN file-production ***/
 | 
			
		||||
/* enumerations from "@filename@" */
 | 
			
		||||
#include "@filename@"
 | 
			
		||||
 | 
			
		||||
/*** END file-production ***/
 | 
			
		||||
 | 
			
		||||
/*** BEGIN value-header ***/
 | 
			
		||||
GType
 | 
			
		||||
@enum_name@_get_type (void)
 | 
			
		||||
{
 | 
			
		||||
	static GType the_type = 0;
 | 
			
		||||
	
 | 
			
		||||
	if (the_type == 0)
 | 
			
		||||
	{
 | 
			
		||||
		static const G@Type@Value values[] = {
 | 
			
		||||
/*** END value-header ***/
 | 
			
		||||
 | 
			
		||||
/*** BEGIN value-production ***/
 | 
			
		||||
			{ @VALUENAME@,
 | 
			
		||||
			  "@VALUENAME@",
 | 
			
		||||
			  "@valuenick@" },
 | 
			
		||||
/*** END value-production ***/
 | 
			
		||||
 | 
			
		||||
/*** BEGIN value-tail ***/
 | 
			
		||||
			{ 0, NULL, NULL }
 | 
			
		||||
		};
 | 
			
		||||
		the_type = g_@type@_register_static (
 | 
			
		||||
				g_intern_static_string ("@EnumName@"),
 | 
			
		||||
				values);
 | 
			
		||||
	}
 | 
			
		||||
	return the_type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*** END value-tail ***/
 | 
			
		||||
							
								
								
									
										27
									
								
								xedit/xedit-enum-types.h.template
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								xedit/xedit-enum-types.h.template
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
/*** BEGIN file-header ***/
 | 
			
		||||
#ifndef __XEDIT_ENUM_TYPES_H__
 | 
			
		||||
#define __XEDIT_ENUM_TYPES_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/*** END file-header ***/
 | 
			
		||||
 | 
			
		||||
/*** BEGIN file-production ***/
 | 
			
		||||
/* Enumerations from "@filename@" */
 | 
			
		||||
 | 
			
		||||
/*** END file-production ***/
 | 
			
		||||
 | 
			
		||||
/*** BEGIN enumeration-production ***/
 | 
			
		||||
#define XEDIT_TYPE_@ENUMSHORT@	(@enum_name@_get_type())
 | 
			
		||||
GType @enum_name@_get_type	(void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
/*** END enumeration-production ***/
 | 
			
		||||
 | 
			
		||||
/*** BEGIN file-tail ***/
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __XEDIT_ENUM_TYPES_H__ */
 | 
			
		||||
/*** END file-tail ***/
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										586
									
								
								xedit/xedit-file-chooser-dialog.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										586
									
								
								xedit/xedit-file-chooser-dialog.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,586 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-file-chooser-dialog.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2005-2007 - Paolo Maggi
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor,
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2005-2007. See the AUTHORS file for a
 | 
			
		||||
 * list of people on the xedit Team.
 | 
			
		||||
 * See the ChangeLog files for a list of changes.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* TODO: Override set_extra_widget */
 | 
			
		||||
/* TODO: add encoding property */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
#include <gtksourceview/gtksource.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "xedit-file-chooser-dialog.h"
 | 
			
		||||
#include "xedit-encodings-combo-box.h"
 | 
			
		||||
#include "xedit-language-manager.h"
 | 
			
		||||
#include "xedit-prefs-manager-app.h"
 | 
			
		||||
#include "xedit-debug.h"
 | 
			
		||||
#include "xedit-enum-types.h"
 | 
			
		||||
 | 
			
		||||
#define XEDIT_FILE_CHOOSER_DIALOG_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), XEDIT_TYPE_FILE_CHOOSER_DIALOG, XeditFileChooserDialogPrivate))
 | 
			
		||||
 | 
			
		||||
#define ALL_FILES		_("All Files")
 | 
			
		||||
#define ALL_TEXT_FILES		_("All Text Files")
 | 
			
		||||
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
#define gtk_hbox_new(X,Y) gtk_box_new(GTK_ORIENTATION_HORIZONTAL,Y)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
struct _XeditFileChooserDialogPrivate
 | 
			
		||||
{
 | 
			
		||||
	GtkWidget *option_menu;
 | 
			
		||||
	GtkWidget *extra_widget;
 | 
			
		||||
 | 
			
		||||
	GtkWidget *newline_label;
 | 
			
		||||
	GtkWidget *newline_combo;
 | 
			
		||||
	GtkListStore *newline_store;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE(XeditFileChooserDialog, xedit_file_chooser_dialog, GTK_TYPE_FILE_CHOOSER_DIALOG)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_file_chooser_dialog_class_init (XeditFileChooserDialogClass *klass)
 | 
			
		||||
{
 | 
			
		||||
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
	g_type_class_add_private (object_class, sizeof(XeditFileChooserDialogPrivate));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
create_option_menu (XeditFileChooserDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
	GtkWidget *label;
 | 
			
		||||
	GtkWidget *menu;
 | 
			
		||||
 | 
			
		||||
	label = gtk_label_new_with_mnemonic (_("C_haracter Encoding:"));
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 16, 0)
 | 
			
		||||
	gtk_label_set_xalign (GTK_LABEL (label), 0.0);
 | 
			
		||||
#else
 | 
			
		||||
	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	menu = xedit_encodings_combo_box_new (
 | 
			
		||||
		gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) == GTK_FILE_CHOOSER_ACTION_SAVE);
 | 
			
		||||
 | 
			
		||||
	gtk_label_set_mnemonic_widget (GTK_LABEL (label), menu);
 | 
			
		||||
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (dialog->priv->extra_widget),
 | 
			
		||||
	                    label,
 | 
			
		||||
	                    FALSE,
 | 
			
		||||
	                    TRUE,
 | 
			
		||||
	                    0);
 | 
			
		||||
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (dialog->priv->extra_widget),
 | 
			
		||||
	                    menu,
 | 
			
		||||
	                    TRUE,
 | 
			
		||||
	                    TRUE,
 | 
			
		||||
	                    0);
 | 
			
		||||
 | 
			
		||||
	gtk_widget_show (label);
 | 
			
		||||
	gtk_widget_show (menu);
 | 
			
		||||
 | 
			
		||||
	dialog->priv->option_menu = menu;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_newline_visibility (XeditFileChooserDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
	if (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) == GTK_FILE_CHOOSER_ACTION_SAVE)
 | 
			
		||||
	{
 | 
			
		||||
		gtk_widget_show (dialog->priv->newline_label);
 | 
			
		||||
		gtk_widget_show (dialog->priv->newline_combo);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		gtk_widget_hide (dialog->priv->newline_label);
 | 
			
		||||
		gtk_widget_hide (dialog->priv->newline_combo);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
newline_combo_append (GtkComboBox              *combo,
 | 
			
		||||
                      GtkListStore             *store,
 | 
			
		||||
                      GtkTreeIter              *iter,
 | 
			
		||||
                      const gchar              *label,
 | 
			
		||||
                      XeditDocumentNewlineType  newline_type)
 | 
			
		||||
{
 | 
			
		||||
	gtk_list_store_append (store, iter);
 | 
			
		||||
	gtk_list_store_set (store, iter, 0, label, 1, newline_type, -1);
 | 
			
		||||
 | 
			
		||||
	if (newline_type == XEDIT_DOCUMENT_NEWLINE_TYPE_DEFAULT)
 | 
			
		||||
	{
 | 
			
		||||
		gtk_combo_box_set_active_iter (combo, iter);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
create_newline_combo (XeditFileChooserDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
	GtkWidget *label, *combo;
 | 
			
		||||
	GtkListStore *store;
 | 
			
		||||
	GtkCellRenderer *renderer;
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
 | 
			
		||||
	label = gtk_label_new_with_mnemonic (_("L_ine Ending:"));
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 16, 0)
 | 
			
		||||
	gtk_label_set_xalign (GTK_LABEL (label), 0.0);
 | 
			
		||||
#else
 | 
			
		||||
	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	store = gtk_list_store_new (2, G_TYPE_STRING, XEDIT_TYPE_DOCUMENT_NEWLINE_TYPE);
 | 
			
		||||
	combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
 | 
			
		||||
	renderer = gtk_cell_renderer_text_new ();
 | 
			
		||||
 | 
			
		||||
	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo),
 | 
			
		||||
	                            renderer,
 | 
			
		||||
	                            TRUE);
 | 
			
		||||
 | 
			
		||||
	gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo),
 | 
			
		||||
	                               renderer,
 | 
			
		||||
	                               "text",
 | 
			
		||||
	                               0);
 | 
			
		||||
 | 
			
		||||
	newline_combo_append (GTK_COMBO_BOX (combo),
 | 
			
		||||
	                      store,
 | 
			
		||||
	                      &iter,
 | 
			
		||||
	                      _("Unix/Linux"),
 | 
			
		||||
	                      XEDIT_DOCUMENT_NEWLINE_TYPE_LF);
 | 
			
		||||
 | 
			
		||||
	newline_combo_append (GTK_COMBO_BOX (combo),
 | 
			
		||||
	                      store,
 | 
			
		||||
	                      &iter,
 | 
			
		||||
	                      _("Mac OS Classic"),
 | 
			
		||||
	                      XEDIT_DOCUMENT_NEWLINE_TYPE_CR);
 | 
			
		||||
 | 
			
		||||
	newline_combo_append (GTK_COMBO_BOX (combo),
 | 
			
		||||
	                      store,
 | 
			
		||||
	                      &iter,
 | 
			
		||||
	                      _("Windows"),
 | 
			
		||||
	                      XEDIT_DOCUMENT_NEWLINE_TYPE_CR_LF);
 | 
			
		||||
 | 
			
		||||
	gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
 | 
			
		||||
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (dialog->priv->extra_widget),
 | 
			
		||||
	                    label,
 | 
			
		||||
	                    FALSE,
 | 
			
		||||
	                    TRUE,
 | 
			
		||||
	                    0);
 | 
			
		||||
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (dialog->priv->extra_widget),
 | 
			
		||||
	                    combo,
 | 
			
		||||
	                    TRUE,
 | 
			
		||||
	                    TRUE,
 | 
			
		||||
	                    0);
 | 
			
		||||
 | 
			
		||||
	dialog->priv->newline_combo = combo;
 | 
			
		||||
	dialog->priv->newline_label = label;
 | 
			
		||||
	dialog->priv->newline_store = store;
 | 
			
		||||
 | 
			
		||||
	update_newline_visibility (dialog);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
create_extra_widget (XeditFileChooserDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
	dialog->priv->extra_widget = gtk_hbox_new (FALSE, 6);
 | 
			
		||||
 | 
			
		||||
	gtk_widget_show (dialog->priv->extra_widget);
 | 
			
		||||
 | 
			
		||||
	create_option_menu (dialog);
 | 
			
		||||
	create_newline_combo (dialog);
 | 
			
		||||
 | 
			
		||||
	gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog),
 | 
			
		||||
					   dialog->priv->extra_widget);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
action_changed (XeditFileChooserDialog *dialog,
 | 
			
		||||
		GParamSpec	       *pspec,
 | 
			
		||||
		gpointer		data)
 | 
			
		||||
{
 | 
			
		||||
	GtkFileChooserAction action;
 | 
			
		||||
 | 
			
		||||
	action = gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog));
 | 
			
		||||
 | 
			
		||||
	switch (action)
 | 
			
		||||
	{
 | 
			
		||||
		case GTK_FILE_CHOOSER_ACTION_OPEN:
 | 
			
		||||
			g_object_set (dialog->priv->option_menu,
 | 
			
		||||
				      "save_mode", FALSE,
 | 
			
		||||
				      NULL);
 | 
			
		||||
			gtk_widget_show (dialog->priv->option_menu);
 | 
			
		||||
			break;
 | 
			
		||||
		case GTK_FILE_CHOOSER_ACTION_SAVE:
 | 
			
		||||
			g_object_set (dialog->priv->option_menu,
 | 
			
		||||
				      "save_mode", TRUE,
 | 
			
		||||
				      NULL);
 | 
			
		||||
			gtk_widget_show (dialog->priv->option_menu);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			gtk_widget_hide (dialog->priv->option_menu);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	update_newline_visibility (dialog);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
filter_changed (XeditFileChooserDialog *dialog,
 | 
			
		||||
		GParamSpec	       *pspec,
 | 
			
		||||
		gpointer		data)
 | 
			
		||||
{
 | 
			
		||||
	GtkFileFilter *filter;
 | 
			
		||||
 | 
			
		||||
	if (!xedit_prefs_manager_active_file_filter_can_set ())
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	filter = gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog));
 | 
			
		||||
	if (filter != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		const gchar *name;
 | 
			
		||||
		gint id = 0;
 | 
			
		||||
 | 
			
		||||
		name = gtk_file_filter_get_name (filter);
 | 
			
		||||
		g_return_if_fail (name != NULL);
 | 
			
		||||
 | 
			
		||||
		if (strcmp (name, ALL_TEXT_FILES) == 0)
 | 
			
		||||
			id = 1;
 | 
			
		||||
 | 
			
		||||
		xedit_debug_message (DEBUG_COMMANDS, "Active filter: %s (%d)", name, id);
 | 
			
		||||
 | 
			
		||||
		xedit_prefs_manager_set_active_file_filter (id);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* FIXME: use globs too - Paolo (Aug. 27, 2007) */
 | 
			
		||||
static gboolean
 | 
			
		||||
all_text_files_filter (const GtkFileFilterInfo *filter_info,
 | 
			
		||||
		       gpointer                 data)
 | 
			
		||||
{
 | 
			
		||||
	static GSList *known_mime_types = NULL;
 | 
			
		||||
	GSList *mime_types;
 | 
			
		||||
 | 
			
		||||
	if (known_mime_types == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		GtkSourceLanguageManager *lm;
 | 
			
		||||
		const gchar * const *languages;
 | 
			
		||||
 | 
			
		||||
		lm = xedit_get_language_manager ();
 | 
			
		||||
		languages = gtk_source_language_manager_get_language_ids (lm);
 | 
			
		||||
 | 
			
		||||
		while ((languages != NULL) && (*languages != NULL))
 | 
			
		||||
		{
 | 
			
		||||
			gchar **mime_types;
 | 
			
		||||
			gint i;
 | 
			
		||||
			GtkSourceLanguage *lang;
 | 
			
		||||
 | 
			
		||||
			lang = gtk_source_language_manager_get_language (lm, *languages);
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
			g_return_val_if_fail (GTK_SOURCE_IS_LANGUAGE (lang), FALSE);
 | 
			
		||||
#else
 | 
			
		||||
			g_return_val_if_fail (GTK_IS_SOURCE_LANGUAGE (lang), FALSE);
 | 
			
		||||
#endif
 | 
			
		||||
			++languages;
 | 
			
		||||
 | 
			
		||||
			mime_types = gtk_source_language_get_mime_types (lang);
 | 
			
		||||
			if (mime_types == NULL)
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			for (i = 0; mime_types[i] != NULL; i++)
 | 
			
		||||
			{
 | 
			
		||||
				if (!g_content_type_is_a (mime_types[i], "text/plain"))
 | 
			
		||||
				{
 | 
			
		||||
					xedit_debug_message (DEBUG_COMMANDS,
 | 
			
		||||
							     "Mime-type %s is not related to text/plain",
 | 
			
		||||
							     mime_types[i]);
 | 
			
		||||
 | 
			
		||||
					known_mime_types = g_slist_prepend (known_mime_types,
 | 
			
		||||
									    g_strdup (mime_types[i]));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			g_strfreev (mime_types);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* known_mime_types always has "text/plain" as first item" */
 | 
			
		||||
		known_mime_types = g_slist_prepend (known_mime_types, g_strdup ("text/plain"));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* known mime_types contains "text/plain" and then the list of mime-types unrelated to "text/plain"
 | 
			
		||||
	 * that xedit recognizes */
 | 
			
		||||
 | 
			
		||||
	if (filter_info->mime_type == NULL)
 | 
			
		||||
		return FALSE;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * The filter is matching:
 | 
			
		||||
	 * - the mime-types beginning with "text/"
 | 
			
		||||
	 * - the mime-types inheriting from a known mime-type (note the text/plain is
 | 
			
		||||
	 *   the first known mime-type)
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	if (strncmp (filter_info->mime_type, "text/", 5) == 0)
 | 
			
		||||
		return TRUE;
 | 
			
		||||
 | 
			
		||||
	mime_types = known_mime_types;
 | 
			
		||||
	while (mime_types != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		if (g_content_type_is_a (filter_info->mime_type, (const gchar*)mime_types->data))
 | 
			
		||||
			return TRUE;
 | 
			
		||||
 | 
			
		||||
		mime_types = g_slist_next (mime_types);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_file_chooser_dialog_init (XeditFileChooserDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
	dialog->priv = XEDIT_FILE_CHOOSER_DIALOG_GET_PRIVATE (dialog);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GtkWidget *
 | 
			
		||||
xedit_file_chooser_dialog_new_valist (const gchar          *title,
 | 
			
		||||
				      GtkWindow            *parent,
 | 
			
		||||
				      GtkFileChooserAction  action,
 | 
			
		||||
				      const XeditEncoding  *encoding,
 | 
			
		||||
				      const gchar          *first_button_text,
 | 
			
		||||
				      va_list               varargs)
 | 
			
		||||
{
 | 
			
		||||
	GtkWidget *result;
 | 
			
		||||
	const char *button_text = first_button_text;
 | 
			
		||||
	gint response_id;
 | 
			
		||||
	GtkFileFilter *filter;
 | 
			
		||||
	gint active_filter;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (parent != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	result = g_object_new (XEDIT_TYPE_FILE_CHOOSER_DIALOG,
 | 
			
		||||
			       "title", title,
 | 
			
		||||
#if !GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
			       "file-system-backend", NULL,
 | 
			
		||||
#endif
 | 
			
		||||
			       "local-only", FALSE,
 | 
			
		||||
			       "action", action,
 | 
			
		||||
			       "select-multiple", action == GTK_FILE_CHOOSER_ACTION_OPEN,
 | 
			
		||||
			       NULL);
 | 
			
		||||
 | 
			
		||||
	create_extra_widget (XEDIT_FILE_CHOOSER_DIALOG (result));
 | 
			
		||||
 | 
			
		||||
	g_signal_connect (result,
 | 
			
		||||
			  "notify::action",
 | 
			
		||||
			  G_CALLBACK (action_changed),
 | 
			
		||||
			  NULL);
 | 
			
		||||
 | 
			
		||||
	if (encoding != NULL)
 | 
			
		||||
		xedit_encodings_combo_box_set_selected_encoding (
 | 
			
		||||
				XEDIT_ENCODINGS_COMBO_BOX (XEDIT_FILE_CHOOSER_DIALOG (result)->priv->option_menu),
 | 
			
		||||
				encoding);
 | 
			
		||||
 | 
			
		||||
	active_filter = xedit_prefs_manager_get_active_file_filter ();
 | 
			
		||||
	xedit_debug_message (DEBUG_COMMANDS, "Active filter: %d", active_filter);
 | 
			
		||||
 | 
			
		||||
	/* Filters */
 | 
			
		||||
	filter = gtk_file_filter_new ();
 | 
			
		||||
 | 
			
		||||
	gtk_file_filter_set_name (filter, ALL_FILES);
 | 
			
		||||
	gtk_file_filter_add_pattern (filter, "*");
 | 
			
		||||
	gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (result), filter);
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
	gtk_file_chooser_set_action (GTK_FILE_CHOOSER (result), action);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if (active_filter != 1)
 | 
			
		||||
	{
 | 
			
		||||
		/* Make this filter the default */
 | 
			
		||||
		gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (result), filter);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	filter = gtk_file_filter_new ();
 | 
			
		||||
	gtk_file_filter_set_name (filter, ALL_TEXT_FILES);
 | 
			
		||||
	gtk_file_filter_add_custom (filter,
 | 
			
		||||
				    GTK_FILE_FILTER_MIME_TYPE,
 | 
			
		||||
				    all_text_files_filter,
 | 
			
		||||
				    NULL,
 | 
			
		||||
				    NULL);
 | 
			
		||||
	gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (result), filter);
 | 
			
		||||
 | 
			
		||||
	if (active_filter == 1)
 | 
			
		||||
	{
 | 
			
		||||
		/* Make this filter the default */
 | 
			
		||||
		gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (result), filter);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_signal_connect (result,
 | 
			
		||||
			  "notify::filter",
 | 
			
		||||
			  G_CALLBACK (filter_changed),
 | 
			
		||||
			  NULL);
 | 
			
		||||
 | 
			
		||||
	gtk_window_set_transient_for (GTK_WINDOW (result), parent);
 | 
			
		||||
	gtk_window_set_destroy_with_parent (GTK_WINDOW (result), TRUE);
 | 
			
		||||
 | 
			
		||||
	while (button_text)
 | 
			
		||||
	{
 | 
			
		||||
		response_id = va_arg (varargs, gint);
 | 
			
		||||
 | 
			
		||||
		gtk_dialog_add_button (GTK_DIALOG (result), button_text, response_id);
 | 
			
		||||
		if ((response_id == GTK_RESPONSE_OK) ||
 | 
			
		||||
		    (response_id == GTK_RESPONSE_ACCEPT) ||
 | 
			
		||||
		    (response_id == GTK_RESPONSE_YES) ||
 | 
			
		||||
		    (response_id == GTK_RESPONSE_APPLY))
 | 
			
		||||
			gtk_dialog_set_default_response (GTK_DIALOG (result), response_id);
 | 
			
		||||
 | 
			
		||||
		button_text = va_arg (varargs, const gchar *);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_file_chooser_dialog_new:
 | 
			
		||||
 * @title: (allow-none): Title of the dialog, or %NULL
 | 
			
		||||
 * @parent: (allow-none): Transient parent of the dialog, or %NULL
 | 
			
		||||
 * @action: Open or save mode for the dialog
 | 
			
		||||
 * @first_button_text: (allow-none): stock ID or text to go in
 | 
			
		||||
 * the first button, or %NULL
 | 
			
		||||
 * @Varargs: (allow-none): response ID for the first button, then
 | 
			
		||||
 * additional (button, id) pairs, ending with %NULL
 | 
			
		||||
 *
 | 
			
		||||
 * Creates a new #XeditFileChooserDialog.  This function is analogous to
 | 
			
		||||
 * gtk_dialog_new_with_buttons().
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: a new #XeditFileChooserDialog
 | 
			
		||||
 *
 | 
			
		||||
 **/
 | 
			
		||||
GtkWidget *
 | 
			
		||||
xedit_file_chooser_dialog_new (const gchar          *title,
 | 
			
		||||
			       GtkWindow            *parent,
 | 
			
		||||
			       GtkFileChooserAction  action,
 | 
			
		||||
			       const XeditEncoding  *encoding,
 | 
			
		||||
			       const gchar          *first_button_text,
 | 
			
		||||
			       ...)
 | 
			
		||||
{
 | 
			
		||||
	GtkWidget *result;
 | 
			
		||||
	va_list varargs;
 | 
			
		||||
 | 
			
		||||
	va_start (varargs, first_button_text);
 | 
			
		||||
	result = xedit_file_chooser_dialog_new_valist (title, parent, action,
 | 
			
		||||
						       encoding, first_button_text,
 | 
			
		||||
						       varargs);
 | 
			
		||||
	va_end (varargs);
 | 
			
		||||
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_file_chooser_dialog_set_encoding (XeditFileChooserDialog *dialog,
 | 
			
		||||
					const XeditEncoding    *encoding)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_FILE_CHOOSER_DIALOG (dialog));
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_ENCODINGS_COMBO_BOX (dialog->priv->option_menu));
 | 
			
		||||
 | 
			
		||||
	xedit_encodings_combo_box_set_selected_encoding (
 | 
			
		||||
				XEDIT_ENCODINGS_COMBO_BOX (dialog->priv->option_menu),
 | 
			
		||||
				encoding);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const XeditEncoding *
 | 
			
		||||
xedit_file_chooser_dialog_get_encoding (XeditFileChooserDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_FILE_CHOOSER_DIALOG (dialog), NULL);
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_ENCODINGS_COMBO_BOX (dialog->priv->option_menu), NULL);
 | 
			
		||||
	g_return_val_if_fail ((gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) == GTK_FILE_CHOOSER_ACTION_OPEN ||
 | 
			
		||||
			       gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) == GTK_FILE_CHOOSER_ACTION_SAVE), NULL);
 | 
			
		||||
 | 
			
		||||
	return xedit_encodings_combo_box_get_selected_encoding (
 | 
			
		||||
				XEDIT_ENCODINGS_COMBO_BOX (dialog->priv->option_menu));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_file_chooser_dialog_set_newline_type (XeditFileChooserDialog  *dialog,
 | 
			
		||||
					    XeditDocumentNewlineType newline_type)
 | 
			
		||||
{
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
	GtkTreeModel *model;
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_FILE_CHOOSER_DIALOG (dialog));
 | 
			
		||||
	g_return_if_fail (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) == GTK_FILE_CHOOSER_ACTION_SAVE);
 | 
			
		||||
 | 
			
		||||
	model = GTK_TREE_MODEL (dialog->priv->newline_store);
 | 
			
		||||
 | 
			
		||||
	if (!gtk_tree_model_get_iter_first (model, &iter))
 | 
			
		||||
	{
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	do
 | 
			
		||||
	{
 | 
			
		||||
		XeditDocumentNewlineType nt;
 | 
			
		||||
 | 
			
		||||
		gtk_tree_model_get (model, &iter, 1, &nt, -1);
 | 
			
		||||
 | 
			
		||||
		if (newline_type == nt)
 | 
			
		||||
		{
 | 
			
		||||
			gtk_combo_box_set_active_iter (GTK_COMBO_BOX (dialog->priv->newline_combo),
 | 
			
		||||
			                               &iter);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	} while (gtk_tree_model_iter_next (model, &iter));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
XeditDocumentNewlineType
 | 
			
		||||
xedit_file_chooser_dialog_get_newline_type (XeditFileChooserDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
	XeditDocumentNewlineType newline_type;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_FILE_CHOOSER_DIALOG (dialog), XEDIT_DOCUMENT_NEWLINE_TYPE_DEFAULT);
 | 
			
		||||
	g_return_val_if_fail (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) == GTK_FILE_CHOOSER_ACTION_SAVE,
 | 
			
		||||
	                      XEDIT_DOCUMENT_NEWLINE_TYPE_DEFAULT);
 | 
			
		||||
 | 
			
		||||
	gtk_combo_box_get_active_iter (GTK_COMBO_BOX (dialog->priv->newline_combo),
 | 
			
		||||
	                               &iter);
 | 
			
		||||
 | 
			
		||||
	gtk_tree_model_get (GTK_TREE_MODEL (dialog->priv->newline_store),
 | 
			
		||||
	                    &iter,
 | 
			
		||||
	                    1,
 | 
			
		||||
	                    &newline_type,
 | 
			
		||||
	                    -1);
 | 
			
		||||
 | 
			
		||||
	return newline_type;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										89
									
								
								xedit/xedit-file-chooser-dialog.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								xedit/xedit-file-chooser-dialog.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,89 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-file-chooser-dialog.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2005 - Paolo Maggi 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_FILE_CHOOSER_DIALOG_H__
 | 
			
		||||
#define __XEDIT_FILE_CHOOSER_DIALOG_H__
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
#include <xedit/xedit-encodings.h>
 | 
			
		||||
#include <xedit/xedit-enum-types.h>
 | 
			
		||||
#include <xedit/xedit-document.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define XEDIT_TYPE_FILE_CHOOSER_DIALOG             (xedit_file_chooser_dialog_get_type ())
 | 
			
		||||
#define XEDIT_FILE_CHOOSER_DIALOG(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), XEDIT_TYPE_FILE_CHOOSER_DIALOG, XeditFileChooserDialog))
 | 
			
		||||
#define XEDIT_FILE_CHOOSER_DIALOG_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), XEDIT_TYPE_FILE_CHOOSER_DIALOG, XeditFileChooserDialogClass))
 | 
			
		||||
#define XEDIT_IS_FILE_CHOOSER_DIALOG(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XEDIT_TYPE_FILE_CHOOSER_DIALOG))
 | 
			
		||||
#define XEDIT_IS_FILE_CHOOSER_DIALOG_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), XEDIT_TYPE_FILE_CHOOSER_DIALOG))
 | 
			
		||||
#define XEDIT_FILE_CHOOSER_DIALOG_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), XEDIT_TYPE_FILE_CHOOSER_DIALOG, XeditFileChooserDialogClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _XeditFileChooserDialog      XeditFileChooserDialog;
 | 
			
		||||
typedef struct _XeditFileChooserDialogClass XeditFileChooserDialogClass;
 | 
			
		||||
 | 
			
		||||
typedef struct _XeditFileChooserDialogPrivate XeditFileChooserDialogPrivate;
 | 
			
		||||
 | 
			
		||||
struct _XeditFileChooserDialogClass
 | 
			
		||||
{
 | 
			
		||||
	GtkFileChooserDialogClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _XeditFileChooserDialog
 | 
			
		||||
{
 | 
			
		||||
	GtkFileChooserDialog parent_instance;
 | 
			
		||||
 | 
			
		||||
	XeditFileChooserDialogPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType		 xedit_file_chooser_dialog_get_type	(void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
GtkWidget	*xedit_file_chooser_dialog_new		(const gchar            *title,
 | 
			
		||||
							 GtkWindow              *parent,
 | 
			
		||||
							 GtkFileChooserAction    action,
 | 
			
		||||
							 const XeditEncoding    *encoding,
 | 
			
		||||
							 const gchar            *first_button_text,
 | 
			
		||||
							 ...);
 | 
			
		||||
 | 
			
		||||
void		 xedit_file_chooser_dialog_set_encoding (XeditFileChooserDialog *dialog,
 | 
			
		||||
							 const XeditEncoding    *encoding);
 | 
			
		||||
 | 
			
		||||
const XeditEncoding
 | 
			
		||||
		*xedit_file_chooser_dialog_get_encoding (XeditFileChooserDialog *dialog);
 | 
			
		||||
 | 
			
		||||
void		 xedit_file_chooser_dialog_set_newline_type (XeditFileChooserDialog  *dialog,
 | 
			
		||||
							     XeditDocumentNewlineType newline_type);
 | 
			
		||||
 | 
			
		||||
XeditDocumentNewlineType
 | 
			
		||||
		 xedit_file_chooser_dialog_get_newline_type (XeditFileChooserDialog *dialog);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __XEDIT_FILE_CHOOSER_DIALOG_H__ */
 | 
			
		||||
							
								
								
									
										712
									
								
								xedit/xedit-gio-document-loader.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										712
									
								
								xedit/xedit-gio-document-loader.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,712 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-gio-document-loader.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2005 - Paolo Maggi
 | 
			
		||||
 * Copyright (C) 2007 - Paolo Maggi, Steve Frécinaux
 | 
			
		||||
 * Copyright (C) 2008 - Jesse van den Kieboom
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor,
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2005-2008. See the AUTHORS file for a
 | 
			
		||||
 * list of people on the xedit Team.
 | 
			
		||||
 * See the ChangeLog files for a list of changes.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
#include <glib/gstdio.h>
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
 | 
			
		||||
#include "xedit-gio-document-loader.h"
 | 
			
		||||
#include "xedit-document-output-stream.h"
 | 
			
		||||
#include "xedit-smart-charset-converter.h"
 | 
			
		||||
#include "xedit-prefs-manager.h"
 | 
			
		||||
#include "xedit-debug.h"
 | 
			
		||||
#include "xedit-utils.h"
 | 
			
		||||
 | 
			
		||||
#ifndef ENABLE_GVFS_METADATA
 | 
			
		||||
#include "xedit-metadata-manager.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
	XeditGioDocumentLoader *loader;
 | 
			
		||||
	GCancellable 	       *cancellable;
 | 
			
		||||
 | 
			
		||||
	gssize			read;
 | 
			
		||||
	gboolean		tried_mount;
 | 
			
		||||
} AsyncData;
 | 
			
		||||
 | 
			
		||||
#define READ_CHUNK_SIZE 8192
 | 
			
		||||
#define REMOTE_QUERY_ATTRIBUTES G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE "," \
 | 
			
		||||
				G_FILE_ATTRIBUTE_STANDARD_TYPE "," \
 | 
			
		||||
				G_FILE_ATTRIBUTE_TIME_MODIFIED "," \
 | 
			
		||||
				G_FILE_ATTRIBUTE_STANDARD_SIZE "," \
 | 
			
		||||
				G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE "," \
 | 
			
		||||
				XEDIT_METADATA_ATTRIBUTE_ENCODING
 | 
			
		||||
 | 
			
		||||
#define XEDIT_GIO_DOCUMENT_LOADER_GET_PRIVATE(object) \
 | 
			
		||||
				(G_TYPE_INSTANCE_GET_PRIVATE ((object), \
 | 
			
		||||
				 XEDIT_TYPE_GIO_DOCUMENT_LOADER,   \
 | 
			
		||||
				 XeditGioDocumentLoaderPrivate))
 | 
			
		||||
 | 
			
		||||
static void	    xedit_gio_document_loader_load		(XeditDocumentLoader *loader);
 | 
			
		||||
static gboolean     xedit_gio_document_loader_cancel		(XeditDocumentLoader *loader);
 | 
			
		||||
static goffset      xedit_gio_document_loader_get_bytes_read	(XeditDocumentLoader *loader);
 | 
			
		||||
 | 
			
		||||
static void open_async_read (AsyncData *async);
 | 
			
		||||
 | 
			
		||||
struct _XeditGioDocumentLoaderPrivate
 | 
			
		||||
{
 | 
			
		||||
	/* Info on the current file */
 | 
			
		||||
	GFile            *gfile;
 | 
			
		||||
 | 
			
		||||
	goffset           bytes_read;
 | 
			
		||||
 | 
			
		||||
	/* Handle for remote files */
 | 
			
		||||
	GCancellable 	 *cancellable;
 | 
			
		||||
	GInputStream	 *stream;
 | 
			
		||||
	GOutputStream    *output;
 | 
			
		||||
	XeditSmartCharsetConverter *converter;
 | 
			
		||||
 | 
			
		||||
	gchar             buffer[READ_CHUNK_SIZE];
 | 
			
		||||
 | 
			
		||||
	GError           *error;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE(XeditGioDocumentLoader, xedit_gio_document_loader, XEDIT_TYPE_DOCUMENT_LOADER)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_gio_document_loader_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
	XeditGioDocumentLoaderPrivate *priv;
 | 
			
		||||
 | 
			
		||||
	priv = XEDIT_GIO_DOCUMENT_LOADER (object)->priv;
 | 
			
		||||
 | 
			
		||||
	if (priv->cancellable != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		g_cancellable_cancel (priv->cancellable);
 | 
			
		||||
		g_object_unref (priv->cancellable);
 | 
			
		||||
		priv->cancellable = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (priv->stream != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		g_object_unref (priv->stream);
 | 
			
		||||
		priv->stream = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (priv->output != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		g_object_unref (priv->output);
 | 
			
		||||
		priv->output = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (priv->converter != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		g_object_unref (priv->converter);
 | 
			
		||||
		priv->converter = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (priv->gfile != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		g_object_unref (priv->gfile);
 | 
			
		||||
		priv->gfile = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (priv->error != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		g_error_free (priv->error);
 | 
			
		||||
		priv->error = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	G_OBJECT_CLASS (xedit_gio_document_loader_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_gio_document_loader_class_init (XeditGioDocumentLoaderClass *klass)
 | 
			
		||||
{
 | 
			
		||||
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
	XeditDocumentLoaderClass *loader_class = XEDIT_DOCUMENT_LOADER_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
	object_class->dispose = xedit_gio_document_loader_dispose;
 | 
			
		||||
 | 
			
		||||
	loader_class->load = xedit_gio_document_loader_load;
 | 
			
		||||
	loader_class->cancel = xedit_gio_document_loader_cancel;
 | 
			
		||||
	loader_class->get_bytes_read = xedit_gio_document_loader_get_bytes_read;
 | 
			
		||||
 | 
			
		||||
	g_type_class_add_private (object_class, sizeof(XeditGioDocumentLoaderPrivate));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_gio_document_loader_init (XeditGioDocumentLoader *gvloader)
 | 
			
		||||
{
 | 
			
		||||
	gvloader->priv = XEDIT_GIO_DOCUMENT_LOADER_GET_PRIVATE (gvloader);
 | 
			
		||||
 | 
			
		||||
	gvloader->priv->converter = NULL;
 | 
			
		||||
	gvloader->priv->error = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static AsyncData *
 | 
			
		||||
async_data_new (XeditGioDocumentLoader *gvloader)
 | 
			
		||||
{
 | 
			
		||||
	AsyncData *async;
 | 
			
		||||
	
 | 
			
		||||
	async = g_slice_new (AsyncData);
 | 
			
		||||
	async->loader = gvloader;
 | 
			
		||||
	async->cancellable = g_object_ref (gvloader->priv->cancellable);
 | 
			
		||||
	async->tried_mount = FALSE;
 | 
			
		||||
	
 | 
			
		||||
	return async;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
async_data_free (AsyncData *async)
 | 
			
		||||
{
 | 
			
		||||
	g_object_unref (async->cancellable);
 | 
			
		||||
	g_slice_free (AsyncData, async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const XeditEncoding *
 | 
			
		||||
get_metadata_encoding (XeditDocumentLoader *loader)
 | 
			
		||||
{
 | 
			
		||||
	const XeditEncoding *enc = NULL;
 | 
			
		||||
 | 
			
		||||
#ifndef ENABLE_GVFS_METADATA
 | 
			
		||||
	gchar *charset;
 | 
			
		||||
	const gchar *uri;
 | 
			
		||||
 | 
			
		||||
	uri = xedit_document_loader_get_uri (loader);
 | 
			
		||||
 | 
			
		||||
	charset = xedit_metadata_manager_get (uri, "encoding");
 | 
			
		||||
 | 
			
		||||
	if (charset == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	enc = xedit_encoding_get_from_charset (charset);
 | 
			
		||||
 | 
			
		||||
	g_free (charset);
 | 
			
		||||
#else
 | 
			
		||||
	GFileInfo *info;
 | 
			
		||||
 | 
			
		||||
	info = xedit_document_loader_get_info (loader);
 | 
			
		||||
 | 
			
		||||
	/* check if the encoding was set in the metadata */
 | 
			
		||||
	if (g_file_info_has_attribute (info, XEDIT_METADATA_ATTRIBUTE_ENCODING))
 | 
			
		||||
	{
 | 
			
		||||
		const gchar *charset;
 | 
			
		||||
 | 
			
		||||
		charset = g_file_info_get_attribute_string (info,
 | 
			
		||||
							    XEDIT_METADATA_ATTRIBUTE_ENCODING);
 | 
			
		||||
 | 
			
		||||
		if (charset == NULL)
 | 
			
		||||
			return NULL;
 | 
			
		||||
		
 | 
			
		||||
		enc = xedit_encoding_get_from_charset (charset);
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	return enc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
remote_load_completed_or_failed (XeditGioDocumentLoader *loader, AsyncData *async)
 | 
			
		||||
{
 | 
			
		||||
	xedit_document_loader_loading (XEDIT_DOCUMENT_LOADER (loader),
 | 
			
		||||
				       TRUE,
 | 
			
		||||
				       loader->priv->error);
 | 
			
		||||
 | 
			
		||||
	if (async)
 | 
			
		||||
		async_data_free (async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
async_failed (AsyncData *async, GError *error)
 | 
			
		||||
{
 | 
			
		||||
	g_propagate_error (&async->loader->priv->error, error);
 | 
			
		||||
	remote_load_completed_or_failed (async->loader, async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
close_input_stream_ready_cb (GInputStream *stream,
 | 
			
		||||
			     GAsyncResult  *res,
 | 
			
		||||
			     AsyncData     *async)
 | 
			
		||||
{
 | 
			
		||||
	GError *error = NULL;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_LOADER);
 | 
			
		||||
 | 
			
		||||
	/* check cancelled state manually */
 | 
			
		||||
	if (g_cancellable_is_cancelled (async->cancellable))
 | 
			
		||||
	{
 | 
			
		||||
		async_data_free (async);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	xedit_debug_message (DEBUG_SAVER, "Finished closing input stream");
 | 
			
		||||
	
 | 
			
		||||
	if (!g_input_stream_close_finish (stream, res, &error))
 | 
			
		||||
	{
 | 
			
		||||
		xedit_debug_message (DEBUG_SAVER, "Closing input stream error: %s", error->message);
 | 
			
		||||
 | 
			
		||||
		async_failed (async, error);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	xedit_debug_message (DEBUG_SAVER, "Close output stream");
 | 
			
		||||
	if (!g_output_stream_close (async->loader->priv->output,
 | 
			
		||||
				    async->cancellable, &error))
 | 
			
		||||
	{
 | 
			
		||||
		async_failed (async, error);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	remote_load_completed_or_failed (async->loader, async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
write_complete (AsyncData *async)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentLoader *loader;
 | 
			
		||||
 | 
			
		||||
	loader = XEDIT_DOCUMENT_LOADER (async->loader);
 | 
			
		||||
 | 
			
		||||
	if (async->loader->priv->stream)
 | 
			
		||||
		g_input_stream_close_async (G_INPUT_STREAM (async->loader->priv->stream),
 | 
			
		||||
					    G_PRIORITY_HIGH,
 | 
			
		||||
					    async->cancellable,
 | 
			
		||||
					    (GAsyncReadyCallback)close_input_stream_ready_cb,
 | 
			
		||||
					    async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* prototype, because they call each other... isn't C lovely */
 | 
			
		||||
static void	read_file_chunk		(AsyncData *async);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
write_file_chunk (AsyncData *async)
 | 
			
		||||
{
 | 
			
		||||
	XeditGioDocumentLoader *gvloader;
 | 
			
		||||
	gssize bytes_written;
 | 
			
		||||
	GError *error = NULL;
 | 
			
		||||
 | 
			
		||||
	gvloader = async->loader;
 | 
			
		||||
 | 
			
		||||
	/* we use sync methods on doc stream since it is in memory. Using async
 | 
			
		||||
	   would be racy and we can endup with invalidated iters */
 | 
			
		||||
	bytes_written = g_output_stream_write (G_OUTPUT_STREAM (gvloader->priv->output),
 | 
			
		||||
					       gvloader->priv->buffer,
 | 
			
		||||
					       async->read,
 | 
			
		||||
					       async->cancellable,
 | 
			
		||||
					       &error);
 | 
			
		||||
 | 
			
		||||
	xedit_debug_message (DEBUG_SAVER, "Written: %" G_GSSIZE_FORMAT, bytes_written);
 | 
			
		||||
	if (bytes_written == -1)
 | 
			
		||||
	{
 | 
			
		||||
		xedit_debug_message (DEBUG_SAVER, "Write error: %s", error->message);
 | 
			
		||||
		async_failed (async, error);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* note that this signal blocks the read... check if it isn't
 | 
			
		||||
	 * a performance problem
 | 
			
		||||
	 */
 | 
			
		||||
	xedit_document_loader_loading (XEDIT_DOCUMENT_LOADER (gvloader),
 | 
			
		||||
				       FALSE,
 | 
			
		||||
				       NULL);
 | 
			
		||||
 | 
			
		||||
	read_file_chunk (async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
async_read_cb (GInputStream *stream,
 | 
			
		||||
	       GAsyncResult *res,
 | 
			
		||||
	       AsyncData    *async)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_LOADER);
 | 
			
		||||
	XeditGioDocumentLoader *gvloader;
 | 
			
		||||
	GError *error = NULL;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_LOADER);
 | 
			
		||||
 | 
			
		||||
	/* manually check cancelled state */
 | 
			
		||||
	if (g_cancellable_is_cancelled (async->cancellable))
 | 
			
		||||
	{
 | 
			
		||||
		async_data_free (async);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gvloader = async->loader;
 | 
			
		||||
 | 
			
		||||
	async->read = g_input_stream_read_finish (stream, res, &error);
 | 
			
		||||
 | 
			
		||||
	/* error occurred */
 | 
			
		||||
	if (async->read == -1)
 | 
			
		||||
	{
 | 
			
		||||
		async_failed (async, error);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Check for the extremely unlikely case where the file size overflows. */
 | 
			
		||||
	if (gvloader->priv->bytes_read + async->read < gvloader->priv->bytes_read)
 | 
			
		||||
	{
 | 
			
		||||
		g_set_error (&gvloader->priv->error,
 | 
			
		||||
			     XEDIT_DOCUMENT_ERROR,
 | 
			
		||||
			     XEDIT_DOCUMENT_ERROR_TOO_BIG,
 | 
			
		||||
			     "File too big");
 | 
			
		||||
 | 
			
		||||
		async_failed (async, gvloader->priv->error);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Bump the size. */
 | 
			
		||||
	gvloader->priv->bytes_read += async->read;
 | 
			
		||||
 | 
			
		||||
	/* end of the file, we are done! */
 | 
			
		||||
	if (async->read == 0)
 | 
			
		||||
	{
 | 
			
		||||
		XeditDocumentLoader *loader;
 | 
			
		||||
 | 
			
		||||
		loader = XEDIT_DOCUMENT_LOADER (gvloader);
 | 
			
		||||
 | 
			
		||||
		g_output_stream_flush (gvloader->priv->output,
 | 
			
		||||
				       NULL,
 | 
			
		||||
				       &gvloader->priv->error);
 | 
			
		||||
 | 
			
		||||
		loader->auto_detected_encoding =
 | 
			
		||||
			xedit_smart_charset_converter_get_guessed (gvloader->priv->converter);
 | 
			
		||||
 | 
			
		||||
		loader->auto_detected_newline_type =
 | 
			
		||||
			xedit_document_output_stream_detect_newline_type (XEDIT_DOCUMENT_OUTPUT_STREAM (gvloader->priv->output));
 | 
			
		||||
 | 
			
		||||
		/* Check if we needed some fallback char, if so, check if there was
 | 
			
		||||
		   a previous error and if not set a fallback used error */
 | 
			
		||||
		/* FIXME Uncomment this when we want to manage conversion fallback */
 | 
			
		||||
		/*if ((xedit_smart_charset_converter_get_num_fallbacks (gvloader->priv->converter) != 0) &&
 | 
			
		||||
		    gvloader->priv->error == NULL)
 | 
			
		||||
		{
 | 
			
		||||
			g_set_error_literal (&gvloader->priv->error,
 | 
			
		||||
					     XEDIT_DOCUMENT_ERROR,
 | 
			
		||||
					     XEDIT_DOCUMENT_ERROR_CONVERSION_FALLBACK,
 | 
			
		||||
					     "There was a conversion error and it was "
 | 
			
		||||
					     "needed to use a fallback char");
 | 
			
		||||
		}*/
 | 
			
		||||
 | 
			
		||||
		write_complete (async);
 | 
			
		||||
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	write_file_chunk (async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
read_file_chunk (AsyncData *async)
 | 
			
		||||
{
 | 
			
		||||
	XeditGioDocumentLoader *gvloader;
 | 
			
		||||
	
 | 
			
		||||
	gvloader = async->loader;
 | 
			
		||||
 | 
			
		||||
	g_input_stream_read_async (G_INPUT_STREAM (gvloader->priv->stream),
 | 
			
		||||
				   gvloader->priv->buffer,
 | 
			
		||||
				   READ_CHUNK_SIZE,
 | 
			
		||||
				   G_PRIORITY_HIGH,
 | 
			
		||||
				   async->cancellable,
 | 
			
		||||
				   (GAsyncReadyCallback) async_read_cb,
 | 
			
		||||
				   async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GSList *
 | 
			
		||||
get_candidate_encodings (XeditGioDocumentLoader *gvloader)
 | 
			
		||||
{
 | 
			
		||||
	const XeditEncoding *metadata;
 | 
			
		||||
	GSList *encodings = NULL;
 | 
			
		||||
 | 
			
		||||
	encodings = xedit_prefs_manager_get_auto_detected_encodings ();
 | 
			
		||||
 | 
			
		||||
	metadata = get_metadata_encoding (XEDIT_DOCUMENT_LOADER (gvloader));
 | 
			
		||||
	if (metadata != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		encodings = g_slist_prepend (encodings, (gpointer)metadata);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return encodings;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
finish_query_info (AsyncData *async)
 | 
			
		||||
{
 | 
			
		||||
	XeditGioDocumentLoader *gvloader;
 | 
			
		||||
	XeditDocumentLoader *loader;
 | 
			
		||||
	GInputStream *conv_stream;
 | 
			
		||||
	GFileInfo *info;
 | 
			
		||||
	GSList *candidate_encodings;
 | 
			
		||||
	
 | 
			
		||||
	gvloader = async->loader;
 | 
			
		||||
	loader = XEDIT_DOCUMENT_LOADER (gvloader);
 | 
			
		||||
	info = loader->info;
 | 
			
		||||
 | 
			
		||||
	/* if it's not a regular file, error out... */
 | 
			
		||||
	if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_TYPE) &&
 | 
			
		||||
	    g_file_info_get_file_type (info) != G_FILE_TYPE_REGULAR)
 | 
			
		||||
	{
 | 
			
		||||
		g_set_error (&gvloader->priv->error,
 | 
			
		||||
			     G_IO_ERROR,
 | 
			
		||||
			     G_IO_ERROR_NOT_REGULAR_FILE,
 | 
			
		||||
			     "Not a regular file");
 | 
			
		||||
 | 
			
		||||
		remote_load_completed_or_failed (gvloader, async);
 | 
			
		||||
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Get the candidate encodings */
 | 
			
		||||
	if (loader->encoding == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		candidate_encodings = get_candidate_encodings (gvloader);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		candidate_encodings = g_slist_prepend (NULL, (gpointer) loader->encoding);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gvloader->priv->converter = xedit_smart_charset_converter_new (candidate_encodings);
 | 
			
		||||
	g_slist_free (candidate_encodings);
 | 
			
		||||
	
 | 
			
		||||
	conv_stream = g_converter_input_stream_new (gvloader->priv->stream,
 | 
			
		||||
						    G_CONVERTER (gvloader->priv->converter));
 | 
			
		||||
	g_object_unref (gvloader->priv->stream);
 | 
			
		||||
 | 
			
		||||
	gvloader->priv->stream = conv_stream;
 | 
			
		||||
 | 
			
		||||
	/* Output stream */
 | 
			
		||||
	gvloader->priv->output = xedit_document_output_stream_new (loader->document);
 | 
			
		||||
 | 
			
		||||
	/* start reading */
 | 
			
		||||
	read_file_chunk (async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
query_info_cb (GFile        *source,
 | 
			
		||||
	       GAsyncResult *res,
 | 
			
		||||
	       AsyncData    *async)
 | 
			
		||||
{
 | 
			
		||||
	XeditGioDocumentLoader *gvloader;
 | 
			
		||||
	GFileInfo *info;
 | 
			
		||||
	GError *error = NULL;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_LOADER);
 | 
			
		||||
 | 
			
		||||
	/* manually check the cancelled state */
 | 
			
		||||
	if (g_cancellable_is_cancelled (async->cancellable))
 | 
			
		||||
	{
 | 
			
		||||
		async_data_free (async);
 | 
			
		||||
		return;
 | 
			
		||||
	}	
 | 
			
		||||
 | 
			
		||||
	gvloader = async->loader;
 | 
			
		||||
 | 
			
		||||
	/* finish the info query */
 | 
			
		||||
	info = g_file_query_info_finish (gvloader->priv->gfile,
 | 
			
		||||
	                                 res,
 | 
			
		||||
	                                 &error);
 | 
			
		||||
 | 
			
		||||
	if (info == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		/* propagate the error and clean up */
 | 
			
		||||
		async_failed (async, error);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	XEDIT_DOCUMENT_LOADER (gvloader)->info = info;
 | 
			
		||||
	
 | 
			
		||||
	finish_query_info (async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
mount_ready_callback (GFile        *file,
 | 
			
		||||
		      GAsyncResult *res,
 | 
			
		||||
		      AsyncData    *async)
 | 
			
		||||
{
 | 
			
		||||
	GError *error = NULL;
 | 
			
		||||
	gboolean mounted;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_LOADER);
 | 
			
		||||
 | 
			
		||||
	/* manual check for cancelled state */
 | 
			
		||||
	if (g_cancellable_is_cancelled (async->cancellable))
 | 
			
		||||
	{
 | 
			
		||||
		async_data_free (async);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mounted = g_file_mount_enclosing_volume_finish (file, res, &error);
 | 
			
		||||
	
 | 
			
		||||
	if (!mounted)
 | 
			
		||||
	{
 | 
			
		||||
		async_failed (async, error);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		/* try again to open the file for reading */
 | 
			
		||||
		open_async_read (async);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
recover_not_mounted (AsyncData *async)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocument *doc;
 | 
			
		||||
	GMountOperation *mount_operation;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_LOADER);
 | 
			
		||||
 | 
			
		||||
	doc = xedit_document_loader_get_document (XEDIT_DOCUMENT_LOADER (async->loader));
 | 
			
		||||
	mount_operation = _xedit_document_create_mount_operation (doc);
 | 
			
		||||
 | 
			
		||||
	async->tried_mount = TRUE;
 | 
			
		||||
	g_file_mount_enclosing_volume (async->loader->priv->gfile,
 | 
			
		||||
				       G_MOUNT_MOUNT_NONE,
 | 
			
		||||
				       mount_operation,
 | 
			
		||||
				       async->cancellable,
 | 
			
		||||
				       (GAsyncReadyCallback) mount_ready_callback,
 | 
			
		||||
				       async);
 | 
			
		||||
 | 
			
		||||
	g_object_unref (mount_operation);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
async_read_ready_callback (GObject      *source,
 | 
			
		||||
			   GAsyncResult *res,
 | 
			
		||||
		           AsyncData    *async)
 | 
			
		||||
{
 | 
			
		||||
	GError *error = NULL;
 | 
			
		||||
	XeditGioDocumentLoader *gvloader;
 | 
			
		||||
	
 | 
			
		||||
	xedit_debug (DEBUG_LOADER);
 | 
			
		||||
 | 
			
		||||
	/* manual check for cancelled state */
 | 
			
		||||
	if (g_cancellable_is_cancelled (async->cancellable))
 | 
			
		||||
	{
 | 
			
		||||
		async_data_free (async);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gvloader = async->loader;
 | 
			
		||||
	
 | 
			
		||||
	gvloader->priv->stream = G_INPUT_STREAM (g_file_read_finish (gvloader->priv->gfile,
 | 
			
		||||
								     res, &error));
 | 
			
		||||
 | 
			
		||||
	if (!gvloader->priv->stream)
 | 
			
		||||
	{		
 | 
			
		||||
		if (error->code == G_IO_ERROR_NOT_MOUNTED && !async->tried_mount)
 | 
			
		||||
		{
 | 
			
		||||
			recover_not_mounted (async);
 | 
			
		||||
			g_error_free (error);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		/* Propagate error */
 | 
			
		||||
		g_propagate_error (&gvloader->priv->error, error);
 | 
			
		||||
		xedit_document_loader_loading (XEDIT_DOCUMENT_LOADER (gvloader),
 | 
			
		||||
					       TRUE,
 | 
			
		||||
					       gvloader->priv->error);
 | 
			
		||||
 | 
			
		||||
		async_data_free (async);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* get the file info: note we cannot use 
 | 
			
		||||
	 * g_file_input_stream_query_info_async since it is not able to get the
 | 
			
		||||
	 * content type etc, beside it is not supported by gvfs.
 | 
			
		||||
	 * Using the file instead of the stream is slightly racy, but for
 | 
			
		||||
	 * loading this is not too bad...
 | 
			
		||||
	 */
 | 
			
		||||
	g_file_query_info_async (gvloader->priv->gfile,
 | 
			
		||||
				 REMOTE_QUERY_ATTRIBUTES,
 | 
			
		||||
                                 G_FILE_QUERY_INFO_NONE,
 | 
			
		||||
				 G_PRIORITY_HIGH,
 | 
			
		||||
				 async->cancellable,
 | 
			
		||||
				 (GAsyncReadyCallback) query_info_cb,
 | 
			
		||||
				 async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
open_async_read (AsyncData *async)
 | 
			
		||||
{
 | 
			
		||||
	g_file_read_async (async->loader->priv->gfile, 
 | 
			
		||||
	                   G_PRIORITY_HIGH,
 | 
			
		||||
	                   async->cancellable,
 | 
			
		||||
	                   (GAsyncReadyCallback) async_read_ready_callback,
 | 
			
		||||
	                   async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_gio_document_loader_load (XeditDocumentLoader *loader)
 | 
			
		||||
{
 | 
			
		||||
	XeditGioDocumentLoader *gvloader = XEDIT_GIO_DOCUMENT_LOADER (loader);
 | 
			
		||||
	AsyncData *async;
 | 
			
		||||
	
 | 
			
		||||
	xedit_debug (DEBUG_LOADER);
 | 
			
		||||
 | 
			
		||||
	/* make sure no load operation is currently running */
 | 
			
		||||
	g_return_if_fail (gvloader->priv->cancellable == NULL);
 | 
			
		||||
 | 
			
		||||
	gvloader->priv->gfile = g_file_new_for_uri (loader->uri);
 | 
			
		||||
 | 
			
		||||
	/* loading start */
 | 
			
		||||
	xedit_document_loader_loading (XEDIT_DOCUMENT_LOADER (gvloader),
 | 
			
		||||
				       FALSE,
 | 
			
		||||
				       NULL);
 | 
			
		||||
 | 
			
		||||
	gvloader->priv->cancellable = g_cancellable_new ();
 | 
			
		||||
	async = async_data_new (gvloader);
 | 
			
		||||
	
 | 
			
		||||
	open_async_read (async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static goffset
 | 
			
		||||
xedit_gio_document_loader_get_bytes_read (XeditDocumentLoader *loader)
 | 
			
		||||
{
 | 
			
		||||
	return XEDIT_GIO_DOCUMENT_LOADER (loader)->priv->bytes_read;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
xedit_gio_document_loader_cancel (XeditDocumentLoader *loader)
 | 
			
		||||
{
 | 
			
		||||
	XeditGioDocumentLoader *gvloader = XEDIT_GIO_DOCUMENT_LOADER (loader);
 | 
			
		||||
 | 
			
		||||
	if (gvloader->priv->cancellable == NULL)
 | 
			
		||||
		return FALSE;
 | 
			
		||||
 | 
			
		||||
	g_cancellable_cancel (gvloader->priv->cancellable);
 | 
			
		||||
 | 
			
		||||
	g_set_error (&gvloader->priv->error,
 | 
			
		||||
		     G_IO_ERROR,
 | 
			
		||||
		     G_IO_ERROR_CANCELLED,
 | 
			
		||||
		     "Operation cancelled");
 | 
			
		||||
 | 
			
		||||
	remote_load_completed_or_failed (gvloader, NULL);
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										79
									
								
								xedit/xedit-gio-document-loader.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								xedit/xedit-gio-document-loader.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-gio-document-loader.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2005 - Paolo Maggi
 | 
			
		||||
 * Copyright (C) 2007 - Paolo Maggi, Steve Frécinaux
 | 
			
		||||
 * Copyright (C) 2008 - Jesse van den Kieboom
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2005-2008. See the AUTHORS file for a
 | 
			
		||||
 * list of people on the xedit Team.
 | 
			
		||||
 * See the ChangeLog files for a list of changes.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_GIO_DOCUMENT_LOADER_H__
 | 
			
		||||
#define __XEDIT_GIO_DOCUMENT_LOADER_H__
 | 
			
		||||
 | 
			
		||||
#include <xedit/xedit-document.h>
 | 
			
		||||
#include "xedit-document-loader.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Type checking and casting macros
 | 
			
		||||
 */
 | 
			
		||||
#define XEDIT_TYPE_GIO_DOCUMENT_LOADER              (xedit_gio_document_loader_get_type())
 | 
			
		||||
#define XEDIT_GIO_DOCUMENT_LOADER(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), XEDIT_TYPE_GIO_DOCUMENT_LOADER, XeditGioDocumentLoader))
 | 
			
		||||
#define XEDIT_GIO_DOCUMENT_LOADER_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), XEDIT_TYPE_GIO_DOCUMENT_LOADER, XeditGioDocumentLoaderClass))
 | 
			
		||||
#define XEDIT_IS_GIO_DOCUMENT_LOADER(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), XEDIT_TYPE_GIO_DOCUMENT_LOADER))
 | 
			
		||||
#define XEDIT_IS_GIO_DOCUMENT_LOADER_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), XEDIT_TYPE_GIO_DOCUMENT_LOADER))
 | 
			
		||||
#define XEDIT_GIO_DOCUMENT_LOADER_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), XEDIT_TYPE_GIO_DOCUMENT_LOADER, XeditGioDocumentLoaderClass))
 | 
			
		||||
 | 
			
		||||
/* Private structure type */
 | 
			
		||||
typedef struct _XeditGioDocumentLoaderPrivate XeditGioDocumentLoaderPrivate;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Main object structure
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _XeditGioDocumentLoader XeditGioDocumentLoader;
 | 
			
		||||
 | 
			
		||||
struct _XeditGioDocumentLoader
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentLoader loader;
 | 
			
		||||
 | 
			
		||||
	/*< private > */
 | 
			
		||||
	XeditGioDocumentLoaderPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Class definition
 | 
			
		||||
 */
 | 
			
		||||
typedef XeditDocumentLoaderClass XeditGioDocumentLoaderClass;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Public methods
 | 
			
		||||
 */
 | 
			
		||||
GType 		 	 xedit_gio_document_loader_get_type	(void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif  /* __XEDIT_GIO_DOCUMENT_LOADER_H__  */
 | 
			
		||||
							
								
								
									
										775
									
								
								xedit/xedit-gio-document-saver.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										775
									
								
								xedit/xedit-gio-document-saver.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,775 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-gio-document-saver.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2005-2006 - Paolo Borelli and Paolo Maggi
 | 
			
		||||
 * Copyright (C) 2007 - Paolo Borelli, Paolo Maggi, Steve Frécinaux
 | 
			
		||||
 * Copyright (C) 2008 - Jesse van den Kieboom
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor,
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2005-2006. See the AUTHORS file for a
 | 
			
		||||
 * list of people on the xedit Team.
 | 
			
		||||
 * See the ChangeLog files for a list of changes.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "xedit-gio-document-saver.h"
 | 
			
		||||
#include "xedit-document-input-stream.h"
 | 
			
		||||
#include "xedit-debug.h"
 | 
			
		||||
 | 
			
		||||
#define WRITE_CHUNK_SIZE 8192
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
	XeditGioDocumentSaver *saver;
 | 
			
		||||
	gchar 		       buffer[WRITE_CHUNK_SIZE];
 | 
			
		||||
	GCancellable 	      *cancellable;
 | 
			
		||||
	gboolean	       tried_mount;
 | 
			
		||||
	gssize		       written;
 | 
			
		||||
	gssize		       read;
 | 
			
		||||
	GError                *error;
 | 
			
		||||
} AsyncData;
 | 
			
		||||
 | 
			
		||||
#define REMOTE_QUERY_ATTRIBUTES G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE "," \
 | 
			
		||||
				G_FILE_ATTRIBUTE_TIME_MODIFIED
 | 
			
		||||
				
 | 
			
		||||
#define XEDIT_GIO_DOCUMENT_SAVER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \
 | 
			
		||||
							  XEDIT_TYPE_GIO_DOCUMENT_SAVER, \
 | 
			
		||||
							  XeditGioDocumentSaverPrivate))
 | 
			
		||||
 | 
			
		||||
static void	     xedit_gio_document_saver_save		    (XeditDocumentSaver *saver,
 | 
			
		||||
								     GTimeVal           *old_mtime);
 | 
			
		||||
static goffset	     xedit_gio_document_saver_get_file_size	    (XeditDocumentSaver *saver);
 | 
			
		||||
static goffset	     xedit_gio_document_saver_get_bytes_written	    (XeditDocumentSaver *saver);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void 	    check_modified_async 			    (AsyncData          *async);
 | 
			
		||||
 | 
			
		||||
struct _XeditGioDocumentSaverPrivate
 | 
			
		||||
{
 | 
			
		||||
	GTimeVal		  old_mtime;
 | 
			
		||||
 | 
			
		||||
	goffset			  size;
 | 
			
		||||
	goffset			  bytes_written;
 | 
			
		||||
 | 
			
		||||
	GFile			 *gfile;
 | 
			
		||||
	GCancellable		 *cancellable;
 | 
			
		||||
	GOutputStream		 *stream;
 | 
			
		||||
	GInputStream		 *input;
 | 
			
		||||
	
 | 
			
		||||
	GError                   *error;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE(XeditGioDocumentSaver, xedit_gio_document_saver, XEDIT_TYPE_DOCUMENT_SAVER)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_gio_document_saver_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
	XeditGioDocumentSaverPrivate *priv = XEDIT_GIO_DOCUMENT_SAVER (object)->priv;
 | 
			
		||||
 | 
			
		||||
	if (priv->cancellable != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		g_cancellable_cancel (priv->cancellable);
 | 
			
		||||
		g_object_unref (priv->cancellable);
 | 
			
		||||
		priv->cancellable = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (priv->gfile != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		g_object_unref (priv->gfile);
 | 
			
		||||
		priv->gfile = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (priv->error != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		g_error_free (priv->error);
 | 
			
		||||
		priv->error = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (priv->stream != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		g_object_unref (priv->stream);
 | 
			
		||||
		priv->stream = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (priv->input != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		g_object_unref (priv->input);
 | 
			
		||||
		priv->input = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	G_OBJECT_CLASS (xedit_gio_document_saver_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static AsyncData *
 | 
			
		||||
async_data_new (XeditGioDocumentSaver *gvsaver)
 | 
			
		||||
{
 | 
			
		||||
	AsyncData *async;
 | 
			
		||||
	
 | 
			
		||||
	async = g_slice_new (AsyncData);
 | 
			
		||||
	async->saver = gvsaver;
 | 
			
		||||
	async->cancellable = g_object_ref (gvsaver->priv->cancellable);
 | 
			
		||||
 | 
			
		||||
	async->tried_mount = FALSE;
 | 
			
		||||
	async->written = 0;
 | 
			
		||||
	async->read = 0;
 | 
			
		||||
 | 
			
		||||
	async->error = NULL;
 | 
			
		||||
 | 
			
		||||
	return async;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
async_data_free (AsyncData *async)
 | 
			
		||||
{
 | 
			
		||||
	g_object_unref (async->cancellable);
 | 
			
		||||
 | 
			
		||||
	if (async->error)
 | 
			
		||||
	{
 | 
			
		||||
		g_error_free (async->error);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_slice_free (AsyncData, async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
xedit_gio_document_saver_class_init (XeditGioDocumentSaverClass *klass)
 | 
			
		||||
{
 | 
			
		||||
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
	XeditDocumentSaverClass *saver_class = XEDIT_DOCUMENT_SAVER_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
	object_class->dispose = xedit_gio_document_saver_dispose;
 | 
			
		||||
 | 
			
		||||
	saver_class->save = xedit_gio_document_saver_save;
 | 
			
		||||
	saver_class->get_file_size = xedit_gio_document_saver_get_file_size;
 | 
			
		||||
	saver_class->get_bytes_written = xedit_gio_document_saver_get_bytes_written;
 | 
			
		||||
 | 
			
		||||
	g_type_class_add_private (object_class, sizeof(XeditGioDocumentSaverPrivate));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_gio_document_saver_init (XeditGioDocumentSaver *gvsaver)
 | 
			
		||||
{
 | 
			
		||||
	gvsaver->priv = XEDIT_GIO_DOCUMENT_SAVER_GET_PRIVATE (gvsaver);
 | 
			
		||||
 | 
			
		||||
	gvsaver->priv->cancellable = g_cancellable_new ();
 | 
			
		||||
	gvsaver->priv->error = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
remote_save_completed_or_failed (XeditGioDocumentSaver *gvsaver, 
 | 
			
		||||
				 AsyncData 	       *async)
 | 
			
		||||
{
 | 
			
		||||
	xedit_document_saver_saving (XEDIT_DOCUMENT_SAVER (gvsaver),
 | 
			
		||||
				     TRUE,
 | 
			
		||||
				     gvsaver->priv->error);
 | 
			
		||||
 | 
			
		||||
	if (async)
 | 
			
		||||
		async_data_free (async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
async_failed (AsyncData *async,
 | 
			
		||||
	      GError    *error)
 | 
			
		||||
{
 | 
			
		||||
	g_propagate_error (&async->saver->priv->error, error);
 | 
			
		||||
	remote_save_completed_or_failed (async->saver, async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* BEGIN NOTE:
 | 
			
		||||
 *
 | 
			
		||||
 * This fixes an issue in GOutputStream that applies the atomic replace
 | 
			
		||||
 * save strategy. The stream moves the written file to the original file
 | 
			
		||||
 * when the stream is closed. However, there is no way currently to tell
 | 
			
		||||
 * the stream that the save should be aborted (there could be a
 | 
			
		||||
 * conversion error). The patch explicitly closes the output stream
 | 
			
		||||
 * in all these cases with a GCancellable in the cancelled state, causing
 | 
			
		||||
 * the output stream to close, but not move the file. This makes use
 | 
			
		||||
 * of an implementation detail in the local gio file stream and should be
 | 
			
		||||
 * properly fixed by adding the appropriate API in gio. Until then, at least
 | 
			
		||||
 * we prevent data corruption for now.
 | 
			
		||||
 *
 | 
			
		||||
 * Relevant bug reports:
 | 
			
		||||
 *
 | 
			
		||||
 * Bug 615110 - write file ignore encoding errors (xedit)
 | 
			
		||||
 * https://bugzilla.gnome.org/show_bug.cgi?id=615110
 | 
			
		||||
 *
 | 
			
		||||
 * Bug 602412 - g_file_replace does not restore original file when there is
 | 
			
		||||
 *              errors while writing (glib/gio)
 | 
			
		||||
 * https://bugzilla.gnome.org/show_bug.cgi?id=602412
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
cancel_output_stream_ready_cb (GOutputStream *stream,
 | 
			
		||||
                               GAsyncResult  *result,
 | 
			
		||||
                               AsyncData     *async)
 | 
			
		||||
{
 | 
			
		||||
	GError *error;
 | 
			
		||||
 | 
			
		||||
	g_output_stream_close_finish (stream, result, NULL);
 | 
			
		||||
 | 
			
		||||
	/* check cancelled state manually */
 | 
			
		||||
	if (g_cancellable_is_cancelled (async->cancellable) || async->error == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		async_data_free (async);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	error = async->error;
 | 
			
		||||
	async->error = NULL;
 | 
			
		||||
 | 
			
		||||
	async_failed (async, error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
cancel_output_stream (AsyncData *async)
 | 
			
		||||
{
 | 
			
		||||
	GCancellable *cancellable;
 | 
			
		||||
 | 
			
		||||
	xedit_debug_message (DEBUG_SAVER, "Cancel output stream");
 | 
			
		||||
 | 
			
		||||
	cancellable = g_cancellable_new ();
 | 
			
		||||
	g_cancellable_cancel (cancellable);
 | 
			
		||||
 | 
			
		||||
	g_output_stream_close_async (async->saver->priv->stream,
 | 
			
		||||
				     G_PRIORITY_HIGH,
 | 
			
		||||
				     cancellable,
 | 
			
		||||
				     (GAsyncReadyCallback)cancel_output_stream_ready_cb,
 | 
			
		||||
				     async);
 | 
			
		||||
 | 
			
		||||
	g_object_unref (cancellable);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
cancel_output_stream_and_fail (AsyncData *async,
 | 
			
		||||
                               GError    *error)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	xedit_debug_message (DEBUG_SAVER, "Cancel output stream and fail");
 | 
			
		||||
 | 
			
		||||
	g_propagate_error (&async->error, error);
 | 
			
		||||
	cancel_output_stream (async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * END NOTE
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
remote_get_info_cb (GFile        *source,
 | 
			
		||||
		    GAsyncResult *res,
 | 
			
		||||
		    AsyncData    *async)
 | 
			
		||||
{
 | 
			
		||||
	XeditGioDocumentSaver *saver;
 | 
			
		||||
	GFileInfo *info;
 | 
			
		||||
	GError *error = NULL;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_SAVER);
 | 
			
		||||
 | 
			
		||||
	/* check cancelled state manually */
 | 
			
		||||
	if (g_cancellable_is_cancelled (async->cancellable))
 | 
			
		||||
	{
 | 
			
		||||
		async_data_free (async);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	saver = async->saver;
 | 
			
		||||
 | 
			
		||||
	xedit_debug_message (DEBUG_SAVER, "Finished query info on file");
 | 
			
		||||
	info = g_file_query_info_finish (source, res, &error);
 | 
			
		||||
 | 
			
		||||
	if (info != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		if (XEDIT_DOCUMENT_SAVER (saver)->info != NULL)
 | 
			
		||||
			g_object_unref (XEDIT_DOCUMENT_SAVER (saver)->info);
 | 
			
		||||
 | 
			
		||||
		XEDIT_DOCUMENT_SAVER (saver)->info = info;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		xedit_debug_message (DEBUG_SAVER, "Query info failed: %s", error->message);
 | 
			
		||||
		g_propagate_error (&saver->priv->error, error);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	remote_save_completed_or_failed (saver, async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
close_async_ready_get_info_cb (GOutputStream *stream,
 | 
			
		||||
			       GAsyncResult  *res,
 | 
			
		||||
			       AsyncData     *async)
 | 
			
		||||
{
 | 
			
		||||
	GError *error = NULL;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_SAVER);
 | 
			
		||||
 | 
			
		||||
	/* check cancelled state manually */
 | 
			
		||||
	if (g_cancellable_is_cancelled (async->cancellable))
 | 
			
		||||
	{
 | 
			
		||||
		async_data_free (async);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	xedit_debug_message (DEBUG_SAVER, "Finished closing stream");
 | 
			
		||||
	
 | 
			
		||||
	if (!g_output_stream_close_finish (stream, res, &error))
 | 
			
		||||
	{
 | 
			
		||||
		xedit_debug_message (DEBUG_SAVER, "Closing stream error: %s", error->message);
 | 
			
		||||
 | 
			
		||||
		async_failed (async, error);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* get the file info: note we cannot use 
 | 
			
		||||
	 * g_file_output_stream_query_info_async since it is not able to get the
 | 
			
		||||
	 * content type etc, beside it is not supported by gvfs.
 | 
			
		||||
	 * I'm not sure this is actually necessary, can't we just use
 | 
			
		||||
	 * g_content_type_guess (since we have the file name and the data)
 | 
			
		||||
	 */
 | 
			
		||||
	xedit_debug_message (DEBUG_SAVER, "Query info on file");
 | 
			
		||||
	g_file_query_info_async (async->saver->priv->gfile,
 | 
			
		||||
			         REMOTE_QUERY_ATTRIBUTES,
 | 
			
		||||
			         G_FILE_QUERY_INFO_NONE,
 | 
			
		||||
			         G_PRIORITY_HIGH,
 | 
			
		||||
			         async->cancellable,
 | 
			
		||||
			         (GAsyncReadyCallback) remote_get_info_cb,
 | 
			
		||||
			         async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
write_complete (AsyncData *async)
 | 
			
		||||
{
 | 
			
		||||
	GError *error = NULL;
 | 
			
		||||
 | 
			
		||||
	/* first we close the input stream */
 | 
			
		||||
	xedit_debug_message (DEBUG_SAVER, "Close input stream");
 | 
			
		||||
	if (!g_input_stream_close (async->saver->priv->input,
 | 
			
		||||
				   async->cancellable, &error))
 | 
			
		||||
	{
 | 
			
		||||
		xedit_debug_message (DEBUG_SAVER, "Closing input stream error: %s", error->message);
 | 
			
		||||
		cancel_output_stream_and_fail (async, error);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* now we close the output stream */
 | 
			
		||||
	xedit_debug_message (DEBUG_SAVER, "Close output stream");
 | 
			
		||||
	g_output_stream_close_async (async->saver->priv->stream,
 | 
			
		||||
				     G_PRIORITY_HIGH,
 | 
			
		||||
				     async->cancellable,
 | 
			
		||||
				     (GAsyncReadyCallback)close_async_ready_get_info_cb,
 | 
			
		||||
				     async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* prototype, because they call each other... isn't C lovely */
 | 
			
		||||
static void read_file_chunk (AsyncData *async);
 | 
			
		||||
static void write_file_chunk (AsyncData *async);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
async_write_cb (GOutputStream *stream,
 | 
			
		||||
		GAsyncResult  *res,
 | 
			
		||||
		AsyncData     *async)
 | 
			
		||||
{
 | 
			
		||||
	XeditGioDocumentSaver *gvsaver;
 | 
			
		||||
	gssize bytes_written;
 | 
			
		||||
	GError *error = NULL;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_SAVER);
 | 
			
		||||
 | 
			
		||||
	/* Check cancelled state manually */
 | 
			
		||||
	if (g_cancellable_is_cancelled (async->cancellable))
 | 
			
		||||
	{
 | 
			
		||||
		cancel_output_stream (async);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bytes_written = g_output_stream_write_finish (stream, res, &error);
 | 
			
		||||
 | 
			
		||||
	xedit_debug_message (DEBUG_SAVER, "Written: %" G_GSSIZE_FORMAT, bytes_written);
 | 
			
		||||
 | 
			
		||||
	if (bytes_written == -1)
 | 
			
		||||
	{
 | 
			
		||||
		xedit_debug_message (DEBUG_SAVER, "Write error: %s", error->message);
 | 
			
		||||
		cancel_output_stream_and_fail (async, error);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gvsaver = async->saver;
 | 
			
		||||
	async->written += bytes_written;
 | 
			
		||||
 | 
			
		||||
	/* write again */
 | 
			
		||||
	if (async->written != async->read)
 | 
			
		||||
	{
 | 
			
		||||
		write_file_chunk (async);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* note that this signal blocks the write... check if it isn't
 | 
			
		||||
	 * a performance problem
 | 
			
		||||
	 */
 | 
			
		||||
	xedit_document_saver_saving (XEDIT_DOCUMENT_SAVER (gvsaver),
 | 
			
		||||
				     FALSE,
 | 
			
		||||
				     NULL);
 | 
			
		||||
 | 
			
		||||
	read_file_chunk (async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
write_file_chunk (AsyncData *async)
 | 
			
		||||
{
 | 
			
		||||
	XeditGioDocumentSaver *gvsaver;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_SAVER);
 | 
			
		||||
 | 
			
		||||
	gvsaver = async->saver;
 | 
			
		||||
 | 
			
		||||
	g_output_stream_write_async (G_OUTPUT_STREAM (gvsaver->priv->stream),
 | 
			
		||||
				     async->buffer + async->written,
 | 
			
		||||
				     async->read - async->written,
 | 
			
		||||
				     G_PRIORITY_HIGH,
 | 
			
		||||
				     async->cancellable,
 | 
			
		||||
				     (GAsyncReadyCallback) async_write_cb,
 | 
			
		||||
				     async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
read_file_chunk (AsyncData *async)
 | 
			
		||||
{
 | 
			
		||||
	XeditGioDocumentSaver *gvsaver;
 | 
			
		||||
	XeditDocumentInputStream *dstream;
 | 
			
		||||
	GError *error = NULL;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_SAVER);
 | 
			
		||||
 | 
			
		||||
	gvsaver = async->saver;
 | 
			
		||||
	async->written = 0;
 | 
			
		||||
 | 
			
		||||
	/* we use sync methods on doc stream since it is in memory. Using async
 | 
			
		||||
	   would be racy and we can endup with invalidated iters */
 | 
			
		||||
	async->read = g_input_stream_read (gvsaver->priv->input,
 | 
			
		||||
					   async->buffer,
 | 
			
		||||
					   WRITE_CHUNK_SIZE,
 | 
			
		||||
					   async->cancellable,
 | 
			
		||||
					   &error);
 | 
			
		||||
 | 
			
		||||
	if (error != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		cancel_output_stream_and_fail (async, error);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Check if we finished reading and writing */
 | 
			
		||||
	if (async->read == 0)
 | 
			
		||||
	{
 | 
			
		||||
		write_complete (async);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Get how many chars have been read */
 | 
			
		||||
	dstream = XEDIT_DOCUMENT_INPUT_STREAM (gvsaver->priv->input);
 | 
			
		||||
	gvsaver->priv->bytes_written = xedit_document_input_stream_tell (dstream);
 | 
			
		||||
 | 
			
		||||
	write_file_chunk (async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
async_replace_ready_callback (GFile        *source,
 | 
			
		||||
			      GAsyncResult *res,
 | 
			
		||||
			      AsyncData    *async)
 | 
			
		||||
{
 | 
			
		||||
	XeditGioDocumentSaver *gvsaver;
 | 
			
		||||
	XeditDocumentSaver *saver;
 | 
			
		||||
	GCharsetConverter *converter;
 | 
			
		||||
	GFileOutputStream *file_stream;
 | 
			
		||||
	GError *error = NULL;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_SAVER);
 | 
			
		||||
 | 
			
		||||
	/* Check cancelled state manually */
 | 
			
		||||
	if (g_cancellable_is_cancelled (async->cancellable))
 | 
			
		||||
	{
 | 
			
		||||
		async_data_free (async);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	gvsaver = async->saver;
 | 
			
		||||
	saver = XEDIT_DOCUMENT_SAVER (gvsaver);
 | 
			
		||||
	file_stream = g_file_replace_finish (source, res, &error);
 | 
			
		||||
	
 | 
			
		||||
	/* handle any error that might occur */
 | 
			
		||||
	if (!file_stream)
 | 
			
		||||
	{
 | 
			
		||||
		xedit_debug_message (DEBUG_SAVER, "Opening file failed: %s", error->message);
 | 
			
		||||
		async_failed (async, error);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* FIXME: manage converter error? */
 | 
			
		||||
	xedit_debug_message (DEBUG_SAVER, "Encoding charset: %s",
 | 
			
		||||
			     xedit_encoding_get_charset (saver->encoding));
 | 
			
		||||
 | 
			
		||||
	if (saver->encoding != xedit_encoding_get_utf8 ())
 | 
			
		||||
	{
 | 
			
		||||
		converter = g_charset_converter_new (xedit_encoding_get_charset (saver->encoding),
 | 
			
		||||
						     "UTF-8",
 | 
			
		||||
						     NULL);
 | 
			
		||||
		gvsaver->priv->stream = g_converter_output_stream_new (G_OUTPUT_STREAM (file_stream),
 | 
			
		||||
								       G_CONVERTER (converter));
 | 
			
		||||
 | 
			
		||||
		g_object_unref (file_stream);
 | 
			
		||||
		g_object_unref (converter);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		gvsaver->priv->stream = G_OUTPUT_STREAM (file_stream);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	gvsaver->priv->input = xedit_document_input_stream_new (GTK_TEXT_BUFFER (saver->document),
 | 
			
		||||
								saver->newline_type);
 | 
			
		||||
 | 
			
		||||
	gvsaver->priv->size = xedit_document_input_stream_get_total_size (XEDIT_DOCUMENT_INPUT_STREAM (gvsaver->priv->input));
 | 
			
		||||
 | 
			
		||||
	read_file_chunk (async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
begin_write (AsyncData *async)
 | 
			
		||||
{
 | 
			
		||||
	XeditGioDocumentSaver *gvsaver;
 | 
			
		||||
	XeditDocumentSaver *saver;
 | 
			
		||||
	gboolean backup;
 | 
			
		||||
 | 
			
		||||
	xedit_debug_message (DEBUG_SAVER, "Start replacing file contents");
 | 
			
		||||
 | 
			
		||||
	/* For remote files we simply use g_file_replace_async. There is no
 | 
			
		||||
	 * backup as of yet
 | 
			
		||||
	 */
 | 
			
		||||
	gvsaver = async->saver;
 | 
			
		||||
	saver = XEDIT_DOCUMENT_SAVER (gvsaver);
 | 
			
		||||
 | 
			
		||||
	/* Do not make backups for remote files so they do not clutter remote systems */
 | 
			
		||||
	backup = (saver->keep_backup && xedit_document_is_local (saver->document));
 | 
			
		||||
 | 
			
		||||
	xedit_debug_message (DEBUG_SAVER, "File contents size: %" G_GINT64_FORMAT, gvsaver->priv->size);
 | 
			
		||||
	xedit_debug_message (DEBUG_SAVER, "Calling replace_async");
 | 
			
		||||
	xedit_debug_message (DEBUG_SAVER, backup ? "Keep backup" : "Discard backup");
 | 
			
		||||
 | 
			
		||||
	g_file_replace_async (gvsaver->priv->gfile,
 | 
			
		||||
			      NULL,
 | 
			
		||||
			      backup,
 | 
			
		||||
			      G_FILE_CREATE_NONE,
 | 
			
		||||
			      G_PRIORITY_HIGH,
 | 
			
		||||
			      async->cancellable,
 | 
			
		||||
			      (GAsyncReadyCallback) async_replace_ready_callback,
 | 
			
		||||
			      async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
mount_ready_callback (GFile        *file,
 | 
			
		||||
		      GAsyncResult *res,
 | 
			
		||||
		      AsyncData    *async)
 | 
			
		||||
{
 | 
			
		||||
	GError *error = NULL;
 | 
			
		||||
	gboolean mounted;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_SAVER);
 | 
			
		||||
 | 
			
		||||
	/* manual check for cancelled state */
 | 
			
		||||
	if (g_cancellable_is_cancelled (async->cancellable))
 | 
			
		||||
	{
 | 
			
		||||
		async_data_free (async);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mounted = g_file_mount_enclosing_volume_finish (file, res, &error);
 | 
			
		||||
	
 | 
			
		||||
	if (!mounted)
 | 
			
		||||
	{
 | 
			
		||||
		async_failed (async, error);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		/* try again to get the modified state */
 | 
			
		||||
		check_modified_async (async);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
recover_not_mounted (AsyncData *async)
 | 
			
		||||
{
 | 
			
		||||
	XeditDocument *doc;
 | 
			
		||||
	GMountOperation *mount_operation;
 | 
			
		||||
	
 | 
			
		||||
	xedit_debug (DEBUG_LOADER);
 | 
			
		||||
 | 
			
		||||
	doc = xedit_document_saver_get_document (XEDIT_DOCUMENT_SAVER (async->saver));
 | 
			
		||||
	mount_operation = _xedit_document_create_mount_operation (doc);
 | 
			
		||||
 | 
			
		||||
	async->tried_mount = TRUE;
 | 
			
		||||
	g_file_mount_enclosing_volume (async->saver->priv->gfile,
 | 
			
		||||
				       G_MOUNT_MOUNT_NONE,
 | 
			
		||||
				       mount_operation,
 | 
			
		||||
				       async->cancellable,
 | 
			
		||||
				       (GAsyncReadyCallback) mount_ready_callback,
 | 
			
		||||
				       async);
 | 
			
		||||
 | 
			
		||||
	g_object_unref (mount_operation);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
check_modification_callback (GFile        *source,
 | 
			
		||||
			     GAsyncResult *res,
 | 
			
		||||
			     AsyncData    *async)
 | 
			
		||||
{
 | 
			
		||||
	XeditGioDocumentSaver *gvsaver;
 | 
			
		||||
	GError *error = NULL;
 | 
			
		||||
	GFileInfo *info;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_SAVER);
 | 
			
		||||
 | 
			
		||||
	/* manually check cancelled state */
 | 
			
		||||
	if (g_cancellable_is_cancelled (async->cancellable))
 | 
			
		||||
	{
 | 
			
		||||
		async_data_free (async);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	gvsaver = async->saver;
 | 
			
		||||
	info = g_file_query_info_finish (source, res, &error);
 | 
			
		||||
	if (info == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		if (error->code == G_IO_ERROR_NOT_MOUNTED && !async->tried_mount)
 | 
			
		||||
		{
 | 
			
		||||
			recover_not_mounted (async);
 | 
			
		||||
			g_error_free (error);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		/* it's perfectly fine if the file doesn't exist yet */
 | 
			
		||||
		if (error->code != G_IO_ERROR_NOT_FOUND)
 | 
			
		||||
		{
 | 
			
		||||
			xedit_debug_message (DEBUG_SAVER, "Error getting modification: %s", error->message);
 | 
			
		||||
 | 
			
		||||
			async_failed (async, error);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* check if the mtime is > what we know about it (if we have it) */
 | 
			
		||||
	if (info != NULL && g_file_info_has_attribute (info,
 | 
			
		||||
				       G_FILE_ATTRIBUTE_TIME_MODIFIED))
 | 
			
		||||
	{
 | 
			
		||||
		GTimeVal mtime;
 | 
			
		||||
		GTimeVal old_mtime;
 | 
			
		||||
 | 
			
		||||
		g_file_info_get_modification_time (info, &mtime);
 | 
			
		||||
		old_mtime = gvsaver->priv->old_mtime;
 | 
			
		||||
 | 
			
		||||
		if ((old_mtime.tv_sec > 0 || old_mtime.tv_usec > 0) &&
 | 
			
		||||
		    (mtime.tv_sec != old_mtime.tv_sec || mtime.tv_usec != old_mtime.tv_usec) &&
 | 
			
		||||
		    (XEDIT_DOCUMENT_SAVER (gvsaver)->flags & XEDIT_DOCUMENT_SAVE_IGNORE_MTIME) == 0)
 | 
			
		||||
		{
 | 
			
		||||
			xedit_debug_message (DEBUG_SAVER, "File is externally modified");
 | 
			
		||||
			g_set_error (&gvsaver->priv->error,
 | 
			
		||||
				     XEDIT_DOCUMENT_ERROR,
 | 
			
		||||
				     XEDIT_DOCUMENT_ERROR_EXTERNALLY_MODIFIED,
 | 
			
		||||
				     "Externally modified");
 | 
			
		||||
 | 
			
		||||
			remote_save_completed_or_failed (gvsaver, async);
 | 
			
		||||
			g_object_unref (info);
 | 
			
		||||
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (info != NULL)
 | 
			
		||||
		g_object_unref (info);
 | 
			
		||||
 | 
			
		||||
	/* modification check passed, start write */
 | 
			
		||||
	begin_write (async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
check_modified_async (AsyncData *async)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug_message (DEBUG_SAVER, "Check externally modified");
 | 
			
		||||
 | 
			
		||||
	g_file_query_info_async (async->saver->priv->gfile, 
 | 
			
		||||
				 G_FILE_ATTRIBUTE_TIME_MODIFIED,
 | 
			
		||||
				 G_FILE_QUERY_INFO_NONE,
 | 
			
		||||
				 G_PRIORITY_HIGH,
 | 
			
		||||
				 async->cancellable,
 | 
			
		||||
				 (GAsyncReadyCallback) check_modification_callback,
 | 
			
		||||
				 async);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
save_remote_file_real (XeditGioDocumentSaver *gvsaver)
 | 
			
		||||
{
 | 
			
		||||
	AsyncData *async;
 | 
			
		||||
 | 
			
		||||
	xedit_debug_message (DEBUG_SAVER, "Starting gio save");
 | 
			
		||||
	
 | 
			
		||||
	/* First find out if the file is modified externally. This requires
 | 
			
		||||
	 * a stat, but I don't think we can do this any other way
 | 
			
		||||
	 */
 | 
			
		||||
	async = async_data_new (gvsaver);
 | 
			
		||||
	
 | 
			
		||||
	check_modified_async (async);
 | 
			
		||||
	
 | 
			
		||||
	/* return false to stop timeout */
 | 
			
		||||
	return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_gio_document_saver_save (XeditDocumentSaver *saver,
 | 
			
		||||
			       GTimeVal           *old_mtime)
 | 
			
		||||
{
 | 
			
		||||
	XeditGioDocumentSaver *gvsaver = XEDIT_GIO_DOCUMENT_SAVER (saver);
 | 
			
		||||
 | 
			
		||||
	gvsaver->priv->old_mtime = *old_mtime;
 | 
			
		||||
	gvsaver->priv->gfile = g_file_new_for_uri (saver->uri);
 | 
			
		||||
 | 
			
		||||
	/* saving start */
 | 
			
		||||
	xedit_document_saver_saving (saver, FALSE, NULL);
 | 
			
		||||
 | 
			
		||||
	g_timeout_add_full (G_PRIORITY_HIGH,
 | 
			
		||||
			    0,
 | 
			
		||||
			    (GSourceFunc) save_remote_file_real,
 | 
			
		||||
			    gvsaver,
 | 
			
		||||
			    NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static goffset
 | 
			
		||||
xedit_gio_document_saver_get_file_size (XeditDocumentSaver *saver)
 | 
			
		||||
{
 | 
			
		||||
	return XEDIT_GIO_DOCUMENT_SAVER (saver)->priv->size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static goffset
 | 
			
		||||
xedit_gio_document_saver_get_bytes_written (XeditDocumentSaver *saver)
 | 
			
		||||
{
 | 
			
		||||
	return XEDIT_GIO_DOCUMENT_SAVER (saver)->priv->bytes_written;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										76
									
								
								xedit/xedit-gio-document-saver.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								xedit/xedit-gio-document-saver.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,76 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-gio-document-saver.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2005 - Paolo Maggi
 | 
			
		||||
 * Copyrhing (C) 2007 - Paolo Maggi, Steve Frécinaux
 | 
			
		||||
 * Copyright (C) 2008 - Jesse van den Kieboom
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor,
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2005-2007. See the AUTHORS file for a
 | 
			
		||||
 * list of people on the xedit Team.
 | 
			
		||||
 * See the ChangeLog files for a list of changes.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_GIO_DOCUMENT_SAVER_H__
 | 
			
		||||
#define __XEDIT_GIO_DOCUMENT_SAVER_H__
 | 
			
		||||
 | 
			
		||||
#include <xedit/xedit-document-saver.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Type checking and casting macros
 | 
			
		||||
 */
 | 
			
		||||
#define XEDIT_TYPE_GIO_DOCUMENT_SAVER              (xedit_gio_document_saver_get_type())
 | 
			
		||||
#define XEDIT_GIO_DOCUMENT_SAVER(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), XEDIT_TYPE_GIO_DOCUMENT_SAVER, XeditGioDocumentSaver))
 | 
			
		||||
#define XEDIT_GIO_DOCUMENT_SAVER_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), XEDIT_TYPE_GIO_DOCUMENT_SAVER, XeditGioDocumentSaverClass))
 | 
			
		||||
#define XEDIT_IS_GIO_DOCUMENT_SAVER(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), XEDIT_TYPE_GIO_DOCUMENT_SAVER))
 | 
			
		||||
#define XEDIT_IS_GIO_DOCUMENT_SAVER_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), XEDIT_TYPE_GIO_DOCUMENT_SAVER))
 | 
			
		||||
#define XEDIT_GIO_DOCUMENT_SAVER_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), XEDIT_TYPE_GIO_DOCUMENT_SAVER, XeditGioDocumentSaverClass))
 | 
			
		||||
 | 
			
		||||
/* Private structure type */
 | 
			
		||||
typedef struct _XeditGioDocumentSaverPrivate XeditGioDocumentSaverPrivate;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Main object structure
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _XeditGioDocumentSaver XeditGioDocumentSaver;
 | 
			
		||||
 | 
			
		||||
struct _XeditGioDocumentSaver 
 | 
			
		||||
{
 | 
			
		||||
	XeditDocumentSaver saver;
 | 
			
		||||
 | 
			
		||||
	/*< private > */
 | 
			
		||||
	XeditGioDocumentSaverPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Class definition
 | 
			
		||||
 */
 | 
			
		||||
typedef XeditDocumentSaverClass XeditGioDocumentSaverClass;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Public methods
 | 
			
		||||
 */
 | 
			
		||||
GType 		 	 xedit_gio_document_saver_get_type	(void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif  /* __XEDIT_GIO_DOCUMENT_SAVER_H__  */
 | 
			
		||||
							
								
								
									
										99
									
								
								xedit/xedit-help.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								xedit/xedit-help.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,99 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-help.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2005 - Paolo Maggi 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "xedit-help.h"
 | 
			
		||||
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
gboolean    
 | 
			
		||||
xedit_help_display (GtkWindow   *parent,
 | 
			
		||||
		    const gchar *name, /* "xedit" if NULL */
 | 
			
		||||
		    const gchar *link_id)
 | 
			
		||||
{
 | 
			
		||||
	GError *error = NULL;
 | 
			
		||||
	gboolean ret;
 | 
			
		||||
	gchar *link;
 | 
			
		||||
	
 | 
			
		||||
	g_return_val_if_fail ((parent == NULL) || GTK_IS_WINDOW (parent), FALSE);
 | 
			
		||||
 | 
			
		||||
	if (name == NULL)
 | 
			
		||||
		name = "xedit";
 | 
			
		||||
	else if (strcmp (name, "xedit.xml") == 0)
 | 
			
		||||
	{
 | 
			
		||||
		g_warning ("%s: Using \"xedit.xml\" for the help name is deprecated, use \"xedit\" or simply NULL instead", G_STRFUNC);
 | 
			
		||||
		
 | 
			
		||||
		name = "xedit";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (link_id)
 | 
			
		||||
		link = g_strdup_printf ("help:%s/%s", name, link_id);
 | 
			
		||||
	else
 | 
			
		||||
		link = g_strdup_printf ("help:%s", name);
 | 
			
		||||
 | 
			
		||||
	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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										44
									
								
								xedit/xedit-help.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								xedit/xedit-help.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-help.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2005 - Paolo Maggi 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_HELP_H__
 | 
			
		||||
#define __XEDIT_HELP_H__
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
gboolean	xedit_help_display (GtkWindow   *parent,
 | 
			
		||||
				    const gchar *name, /* "xedit" if NULL */
 | 
			
		||||
				    const gchar *link_id);
 | 
			
		||||
				    
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __XEDIT_HELP_H__ */
 | 
			
		||||
							
								
								
									
										599
									
								
								xedit/xedit-history-entry.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										599
									
								
								xedit/xedit-history-entry.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,599 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-history-entry.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2006 - Paolo Borelli
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2006. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
 | 
			
		||||
#include "xedit-history-entry.h"
 | 
			
		||||
#include "xedit-prefs-manager.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
	PROP_0,
 | 
			
		||||
	PROP_HISTORY_ID,
 | 
			
		||||
	PROP_HISTORY_LENGTH
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define MIN_ITEM_LEN 3
 | 
			
		||||
 | 
			
		||||
#define XEDIT_HISTORY_ENTRY_HISTORY_LENGTH_DEFAULT 10
 | 
			
		||||
 | 
			
		||||
#define XEDIT_HISTORY_ENTRY_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \
 | 
			
		||||
						XEDIT_TYPE_HISTORY_ENTRY, \
 | 
			
		||||
						XeditHistoryEntryPrivate))
 | 
			
		||||
 | 
			
		||||
struct _XeditHistoryEntryPrivate
 | 
			
		||||
{
 | 
			
		||||
	gchar              *history_id;
 | 
			
		||||
	guint               history_length;
 | 
			
		||||
	
 | 
			
		||||
	GtkEntryCompletion *completion;
 | 
			
		||||
	
 | 
			
		||||
	GSettings          *settings;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE(XeditHistoryEntry, xedit_history_entry, GTK_TYPE_COMBO_BOX_TEXT)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_history_entry_set_property (GObject      *object,
 | 
			
		||||
				  guint         prop_id,
 | 
			
		||||
				  const GValue *value,
 | 
			
		||||
				  GParamSpec   *spec)
 | 
			
		||||
{
 | 
			
		||||
	XeditHistoryEntry *entry;
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_HISTORY_ENTRY (object));
 | 
			
		||||
 | 
			
		||||
	entry = XEDIT_HISTORY_ENTRY (object);
 | 
			
		||||
 | 
			
		||||
	switch (prop_id) {
 | 
			
		||||
	case PROP_HISTORY_ID:
 | 
			
		||||
		entry->priv->history_id = g_value_dup_string (value);
 | 
			
		||||
		break;
 | 
			
		||||
	case PROP_HISTORY_LENGTH:
 | 
			
		||||
		xedit_history_entry_set_history_length (entry,
 | 
			
		||||
						     g_value_get_uint (value));
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_history_entry_get_property (GObject    *object,
 | 
			
		||||
				  guint       prop_id,
 | 
			
		||||
				  GValue     *value,
 | 
			
		||||
				  GParamSpec *spec)
 | 
			
		||||
{
 | 
			
		||||
	XeditHistoryEntryPrivate *priv;
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_HISTORY_ENTRY (object));
 | 
			
		||||
 | 
			
		||||
	priv = XEDIT_HISTORY_ENTRY (object)->priv;
 | 
			
		||||
 | 
			
		||||
	switch (prop_id) {
 | 
			
		||||
	case PROP_HISTORY_ID:
 | 
			
		||||
		g_value_set_string (value, priv->history_id);
 | 
			
		||||
		break;
 | 
			
		||||
	case PROP_HISTORY_LENGTH:
 | 
			
		||||
		g_value_set_uint (value, priv->history_length);
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, spec);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_history_entry_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
	xedit_history_entry_set_enable_completion (XEDIT_HISTORY_ENTRY (object),
 | 
			
		||||
						   FALSE);
 | 
			
		||||
 | 
			
		||||
	G_OBJECT_CLASS (xedit_history_entry_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_history_entry_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
	XeditHistoryEntryPrivate *priv;
 | 
			
		||||
 | 
			
		||||
	priv = XEDIT_HISTORY_ENTRY (object)->priv;
 | 
			
		||||
	
 | 
			
		||||
	g_free (priv->history_id);
 | 
			
		||||
 | 
			
		||||
	if (priv->settings != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		g_object_unref (G_OBJECT (priv->settings));
 | 
			
		||||
		priv->settings = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	G_OBJECT_CLASS (xedit_history_entry_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
xedit_history_entry_class_init (XeditHistoryEntryClass *klass)
 | 
			
		||||
{
 | 
			
		||||
	GObjectClass   *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
	
 | 
			
		||||
	object_class->set_property = xedit_history_entry_set_property;
 | 
			
		||||
	object_class->get_property = xedit_history_entry_get_property;
 | 
			
		||||
	object_class->finalize = xedit_history_entry_finalize;
 | 
			
		||||
	object_class->dispose = xedit_history_entry_dispose;
 | 
			
		||||
	
 | 
			
		||||
	g_object_class_install_property (object_class,
 | 
			
		||||
					 PROP_HISTORY_ID,
 | 
			
		||||
					 g_param_spec_string ("history-id",
 | 
			
		||||
							      "History ID",
 | 
			
		||||
							      "History ID",
 | 
			
		||||
							      NULL,
 | 
			
		||||
							      G_PARAM_READWRITE |
 | 
			
		||||
							      G_PARAM_STATIC_STRINGS));
 | 
			
		||||
 | 
			
		||||
	g_object_class_install_property (object_class,
 | 
			
		||||
					 PROP_HISTORY_LENGTH,
 | 
			
		||||
					 g_param_spec_uint ("history-length",
 | 
			
		||||
							    "Max History Length",
 | 
			
		||||
							    "Max History Length",
 | 
			
		||||
							    0,
 | 
			
		||||
							    G_MAXUINT,
 | 
			
		||||
							    XEDIT_HISTORY_ENTRY_HISTORY_LENGTH_DEFAULT,
 | 
			
		||||
							    G_PARAM_READWRITE |
 | 
			
		||||
							    G_PARAM_STATIC_STRINGS));
 | 
			
		||||
 | 
			
		||||
	/* TODO: Add enable-completion property */
 | 
			
		||||
 | 
			
		||||
	g_type_class_add_private (object_class, sizeof(XeditHistoryEntryPrivate));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GtkListStore *
 | 
			
		||||
get_history_store (XeditHistoryEntry *entry)
 | 
			
		||||
{
 | 
			
		||||
	GtkTreeModel *store;
 | 
			
		||||
 | 
			
		||||
	store = gtk_combo_box_get_model (GTK_COMBO_BOX (entry));
 | 
			
		||||
	g_return_val_if_fail (GTK_IS_LIST_STORE (store), NULL);
 | 
			
		||||
 | 
			
		||||
	return (GtkListStore *) store;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GSList *
 | 
			
		||||
get_history_list (XeditHistoryEntry *entry)
 | 
			
		||||
{
 | 
			
		||||
	GtkListStore *store;
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
	gboolean valid;
 | 
			
		||||
	GSList *list = NULL;
 | 
			
		||||
 | 
			
		||||
	store = get_history_store (entry);
 | 
			
		||||
 | 
			
		||||
	valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store),
 | 
			
		||||
					       &iter);
 | 
			
		||||
 | 
			
		||||
	while (valid)
 | 
			
		||||
	{
 | 
			
		||||
		gchar *str;
 | 
			
		||||
 | 
			
		||||
		gtk_tree_model_get (GTK_TREE_MODEL (store),
 | 
			
		||||
				    &iter,
 | 
			
		||||
				    0, &str,
 | 
			
		||||
				    -1);
 | 
			
		||||
 | 
			
		||||
		list = g_slist_prepend (list, str);
 | 
			
		||||
 | 
			
		||||
		valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store),
 | 
			
		||||
						  &iter);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return g_slist_reverse (list);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_history_entry_save_history (XeditHistoryEntry *entry)
 | 
			
		||||
{
 | 
			
		||||
	GSList *settings_items;
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_HISTORY_ENTRY (entry));
 | 
			
		||||
 | 
			
		||||
	settings_items = get_history_list (entry);
 | 
			
		||||
 | 
			
		||||
	xedit_prefs_manager_set_gslist (entry->priv->settings,
 | 
			
		||||
			      entry->priv->history_id,
 | 
			
		||||
			      settings_items);
 | 
			
		||||
 | 
			
		||||
	g_slist_foreach (settings_items, (GFunc) g_free, NULL);
 | 
			
		||||
	g_slist_free (settings_items);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
remove_item (GtkListStore *store,
 | 
			
		||||
	     const gchar  *text)
 | 
			
		||||
{
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (text != NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
	if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
 | 
			
		||||
		return FALSE;
 | 
			
		||||
 | 
			
		||||
	do
 | 
			
		||||
	{
 | 
			
		||||
		gchar *item_text;
 | 
			
		||||
 | 
			
		||||
		gtk_tree_model_get (GTK_TREE_MODEL (store),
 | 
			
		||||
				    &iter,
 | 
			
		||||
				    0,
 | 
			
		||||
				    &item_text,
 | 
			
		||||
				    -1);
 | 
			
		||||
 | 
			
		||||
		if (item_text != NULL &&
 | 
			
		||||
		    strcmp (item_text, text) == 0)
 | 
			
		||||
		{
 | 
			
		||||
			gtk_list_store_remove (store, &iter);
 | 
			
		||||
			g_free (item_text);
 | 
			
		||||
			return TRUE;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		g_free (item_text);
 | 
			
		||||
 | 
			
		||||
	} while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
 | 
			
		||||
 | 
			
		||||
	return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clamp_list_store (GtkListStore *store,
 | 
			
		||||
		  guint         max)
 | 
			
		||||
{
 | 
			
		||||
	GtkTreePath *path;
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
 | 
			
		||||
	/* -1 because TreePath counts from 0 */
 | 
			
		||||
	path = gtk_tree_path_new_from_indices (max - 1, -1);
 | 
			
		||||
 | 
			
		||||
	if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path))
 | 
			
		||||
	{
 | 
			
		||||
		while (1)
 | 
			
		||||
		{
 | 
			
		||||
			if (!gtk_list_store_remove (store, &iter))
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gtk_tree_path_free (path);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
insert_history_item (XeditHistoryEntry *entry,
 | 
			
		||||
		     const gchar       *text,
 | 
			
		||||
		     gboolean           prepend)
 | 
			
		||||
{
 | 
			
		||||
	GtkListStore *store;
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
 | 
			
		||||
	if (g_utf8_strlen (text, -1) <= MIN_ITEM_LEN)
 | 
			
		||||
		return;
 | 
			
		||||
		
 | 
			
		||||
	store = get_history_store (entry);
 | 
			
		||||
 | 
			
		||||
	/* remove the text from the store if it was already
 | 
			
		||||
	 * present. If it wasn't, clamp to max history - 1
 | 
			
		||||
	 * before inserting the new row, otherwise appending
 | 
			
		||||
	 * would not work */
 | 
			
		||||
 | 
			
		||||
	if (!remove_item (store, text))
 | 
			
		||||
		clamp_list_store (store,
 | 
			
		||||
				  entry->priv->history_length - 1);
 | 
			
		||||
 | 
			
		||||
	if (prepend)
 | 
			
		||||
		gtk_list_store_insert (store, &iter, 0);
 | 
			
		||||
	else
 | 
			
		||||
		gtk_list_store_append (store, &iter);
 | 
			
		||||
 | 
			
		||||
	gtk_list_store_set (store,
 | 
			
		||||
			    &iter,
 | 
			
		||||
			    0,
 | 
			
		||||
			    text,
 | 
			
		||||
			    -1);
 | 
			
		||||
 | 
			
		||||
	xedit_history_entry_save_history (entry);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_history_entry_prepend_text (XeditHistoryEntry *entry,
 | 
			
		||||
				  const gchar       *text)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_HISTORY_ENTRY (entry));
 | 
			
		||||
	g_return_if_fail (text != NULL);
 | 
			
		||||
 | 
			
		||||
	insert_history_item (entry, text, TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_history_entry_append_text (XeditHistoryEntry *entry,
 | 
			
		||||
				 const gchar       *text)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_HISTORY_ENTRY (entry));
 | 
			
		||||
	g_return_if_fail (text != NULL);
 | 
			
		||||
 | 
			
		||||
	insert_history_item (entry, text, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_history_entry_load_history (XeditHistoryEntry *entry)
 | 
			
		||||
{
 | 
			
		||||
	GSList *settings_items, *l;
 | 
			
		||||
	GtkListStore *store;
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
	guint i;
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_HISTORY_ENTRY (entry));
 | 
			
		||||
 | 
			
		||||
	store = get_history_store (entry);
 | 
			
		||||
 | 
			
		||||
	settings_items = xedit_prefs_manager_get_gslist (entry->priv->settings,
 | 
			
		||||
					     entry->priv->history_id);
 | 
			
		||||
 | 
			
		||||
	gtk_list_store_clear (store);
 | 
			
		||||
 | 
			
		||||
	for (l = settings_items, i = 0;
 | 
			
		||||
	     l != NULL && i < entry->priv->history_length;
 | 
			
		||||
	     l = l->next, i++)
 | 
			
		||||
	{
 | 
			
		||||
		gtk_list_store_append (store, &iter);
 | 
			
		||||
		gtk_list_store_set (store, 
 | 
			
		||||
				    &iter,
 | 
			
		||||
				    0,
 | 
			
		||||
				    l->data,
 | 
			
		||||
				    -1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_slist_foreach (settings_items, (GFunc) g_free, NULL);
 | 
			
		||||
	g_slist_free (settings_items);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_history_entry_clear (XeditHistoryEntry *entry)
 | 
			
		||||
{
 | 
			
		||||
	GtkListStore *store;
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_HISTORY_ENTRY (entry));
 | 
			
		||||
 | 
			
		||||
	store = get_history_store (entry);
 | 
			
		||||
	gtk_list_store_clear (store);
 | 
			
		||||
 | 
			
		||||
	xedit_history_entry_save_history (entry);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_history_entry_init (XeditHistoryEntry *entry)
 | 
			
		||||
{
 | 
			
		||||
	XeditHistoryEntryPrivate *priv;
 | 
			
		||||
 | 
			
		||||
	priv = XEDIT_HISTORY_ENTRY_GET_PRIVATE (entry);
 | 
			
		||||
	entry->priv = priv;
 | 
			
		||||
 | 
			
		||||
	priv->history_id = NULL;
 | 
			
		||||
	priv->history_length = XEDIT_HISTORY_ENTRY_HISTORY_LENGTH_DEFAULT;
 | 
			
		||||
 | 
			
		||||
	priv->completion = NULL;
 | 
			
		||||
 | 
			
		||||
	priv->settings = g_settings_new (XEDIT_SCHEMA);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_history_entry_set_history_length (XeditHistoryEntry *entry,
 | 
			
		||||
					guint              history_length)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_HISTORY_ENTRY (entry));
 | 
			
		||||
	g_return_if_fail (history_length > 0);
 | 
			
		||||
 | 
			
		||||
	entry->priv->history_length = history_length;
 | 
			
		||||
 | 
			
		||||
	/* TODO: update if we currently have more items than max */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
guint
 | 
			
		||||
xedit_history_entry_get_history_length (XeditHistoryEntry *entry)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_HISTORY_ENTRY (entry), 0);
 | 
			
		||||
 | 
			
		||||
	return entry->priv->history_length;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gchar *
 | 
			
		||||
xedit_history_entry_get_history_id (XeditHistoryEntry *entry)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_HISTORY_ENTRY (entry), NULL);
 | 
			
		||||
 | 
			
		||||
	return g_strdup (entry->priv->history_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_history_entry_set_enable_completion (XeditHistoryEntry *entry,
 | 
			
		||||
					   gboolean           enable)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_HISTORY_ENTRY (entry));
 | 
			
		||||
	
 | 
			
		||||
	if (enable)
 | 
			
		||||
	{
 | 
			
		||||
		if (entry->priv->completion != NULL)
 | 
			
		||||
			return;
 | 
			
		||||
		
 | 
			
		||||
		entry->priv->completion = gtk_entry_completion_new ();
 | 
			
		||||
		gtk_entry_completion_set_model (entry->priv->completion, 
 | 
			
		||||
						GTK_TREE_MODEL (get_history_store (entry)));
 | 
			
		||||
		
 | 
			
		||||
		/* Use model column 0 as the text column */
 | 
			
		||||
		gtk_entry_completion_set_text_column (entry->priv->completion, 0);
 | 
			
		||||
 | 
			
		||||
		gtk_entry_completion_set_minimum_key_length (entry->priv->completion,
 | 
			
		||||
							     MIN_ITEM_LEN);
 | 
			
		||||
 | 
			
		||||
		gtk_entry_completion_set_popup_completion (entry->priv->completion, FALSE);
 | 
			
		||||
		gtk_entry_completion_set_inline_completion (entry->priv->completion, TRUE);
 | 
			
		||||
	
 | 
			
		||||
		/* Assign the completion to the entry */
 | 
			
		||||
		gtk_entry_set_completion (GTK_ENTRY (xedit_history_entry_get_entry(entry)), 
 | 
			
		||||
					  entry->priv->completion);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		if (entry->priv->completion == NULL)
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		gtk_entry_set_completion (GTK_ENTRY (xedit_history_entry_get_entry (entry)), 
 | 
			
		||||
					  NULL);
 | 
			
		||||
		
 | 
			
		||||
		g_object_unref (entry->priv->completion);
 | 
			
		||||
		
 | 
			
		||||
		entry->priv->completion = NULL;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							 
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_history_entry_get_enable_completion (XeditHistoryEntry *entry)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_HISTORY_ENTRY (entry), FALSE);
 | 
			
		||||
	
 | 
			
		||||
	return entry->priv->completion != NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GtkWidget *
 | 
			
		||||
xedit_history_entry_new (const gchar *history_id,
 | 
			
		||||
			 gboolean     enable_completion)
 | 
			
		||||
{
 | 
			
		||||
	GtkWidget *ret;
 | 
			
		||||
	GtkListStore *store;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (history_id != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	/* Note that we are setting the model, so
 | 
			
		||||
	 * user must be careful to always manipulate
 | 
			
		||||
	 * data in the history through xedit_history_entry_
 | 
			
		||||
	 * functions.
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	store = gtk_list_store_new (1, G_TYPE_STRING);
 | 
			
		||||
 | 
			
		||||
	ret = g_object_new (XEDIT_TYPE_HISTORY_ENTRY,
 | 
			
		||||
			    "history-id", history_id,
 | 
			
		||||
	                    "model", store,
 | 
			
		||||
			    "has-entry", TRUE,
 | 
			
		||||
			    "entry-text-column", 0,
 | 
			
		||||
	                    NULL);
 | 
			
		||||
 | 
			
		||||
	g_object_unref (store);
 | 
			
		||||
 | 
			
		||||
	/* loading has to happen after the model
 | 
			
		||||
	 * has been set. However the model is not a 
 | 
			
		||||
	 * G_PARAM_CONSTRUCT property of GtkComboBox
 | 
			
		||||
	 * so we cannot do this in the constructor.
 | 
			
		||||
	 * For now we simply do here since this widget is 
 | 
			
		||||
	 * not bound to other programming languages.
 | 
			
		||||
	 * A maybe better alternative is to override the 
 | 
			
		||||
	 * model property of combobox and mark CONTRUCT_ONLY.
 | 
			
		||||
	 * This would also ensure that the model cannot be
 | 
			
		||||
	 * set explicitely at a later time.
 | 
			
		||||
	 */
 | 
			
		||||
	xedit_history_entry_load_history (XEDIT_HISTORY_ENTRY (ret));
 | 
			
		||||
 | 
			
		||||
	xedit_history_entry_set_enable_completion (XEDIT_HISTORY_ENTRY (ret),
 | 
			
		||||
						   enable_completion);
 | 
			
		||||
						   
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Utility function to get the editable text entry internal widget.
 | 
			
		||||
 * I would prefer to not expose this implementation detail and 
 | 
			
		||||
 * simply make the XeditHistoryEntry widget implement the 
 | 
			
		||||
 * GtkEditable interface. Unfortunately both GtkEditable and
 | 
			
		||||
 * GtkComboBox have a "changed" signal and I am not sure how to
 | 
			
		||||
 * handle the conflict.
 | 
			
		||||
 */
 | 
			
		||||
GtkWidget *
 | 
			
		||||
xedit_history_entry_get_entry (XeditHistoryEntry *entry)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_HISTORY_ENTRY (entry), NULL);
 | 
			
		||||
 | 
			
		||||
	return gtk_bin_get_child (GTK_BIN (entry));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
escape_cell_data_func (GtkTreeViewColumn           *col,
 | 
			
		||||
		       GtkCellRenderer             *renderer,
 | 
			
		||||
		       GtkTreeModel                *model,
 | 
			
		||||
		       GtkTreeIter                 *iter,
 | 
			
		||||
		       XeditHistoryEntryEscapeFunc  escape_func)
 | 
			
		||||
{
 | 
			
		||||
	gchar *str;
 | 
			
		||||
	gchar *escaped;
 | 
			
		||||
 | 
			
		||||
	gtk_tree_model_get (model, iter, 0, &str, -1);
 | 
			
		||||
	escaped = escape_func (str);
 | 
			
		||||
	g_object_set (renderer, "text", escaped, NULL);
 | 
			
		||||
 | 
			
		||||
	g_free (str);
 | 
			
		||||
	g_free (escaped);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_history_entry_set_escape_func (XeditHistoryEntry           *entry,
 | 
			
		||||
				     XeditHistoryEntryEscapeFunc  escape_func)
 | 
			
		||||
{
 | 
			
		||||
	GList *cells;
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_HISTORY_ENTRY (entry));
 | 
			
		||||
 | 
			
		||||
	cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (entry));
 | 
			
		||||
 | 
			
		||||
	/* We only have one cell renderer */
 | 
			
		||||
	g_return_if_fail (cells->data != NULL && cells->next == NULL);
 | 
			
		||||
 | 
			
		||||
	if (escape_func != NULL)
 | 
			
		||||
		gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (entry),
 | 
			
		||||
						    GTK_CELL_RENDERER (cells->data),
 | 
			
		||||
						    (GtkCellLayoutDataFunc) escape_cell_data_func,
 | 
			
		||||
						    escape_func,
 | 
			
		||||
						    NULL);
 | 
			
		||||
	else
 | 
			
		||||
		gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (entry),
 | 
			
		||||
						    GTK_CELL_RENDERER (cells->data),
 | 
			
		||||
						    NULL,
 | 
			
		||||
						    NULL,
 | 
			
		||||
						    NULL);
 | 
			
		||||
 | 
			
		||||
	g_list_free (cells);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										96
									
								
								xedit/xedit-history-entry.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								xedit/xedit-history-entry.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,96 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-history-entry.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2006 - Paolo Borelli
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2006. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_HISTORY_ENTRY_H__
 | 
			
		||||
#define __XEDIT_HISTORY_ENTRY_H__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define XEDIT_TYPE_HISTORY_ENTRY             (xedit_history_entry_get_type ())
 | 
			
		||||
#define XEDIT_HISTORY_ENTRY(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), XEDIT_TYPE_HISTORY_ENTRY, XeditHistoryEntry))
 | 
			
		||||
#define XEDIT_HISTORY_ENTRY_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), XEDIT_TYPE_HISTORY_ENTRY, XeditHistoryEntryClass))
 | 
			
		||||
#define XEDIT_IS_HISTORY_ENTRY(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XEDIT_TYPE_HISTORY_ENTRY))
 | 
			
		||||
#define XEDIT_IS_HISTORY_ENTRY_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), XEDIT_TYPE_HISTORY_ENTRY))
 | 
			
		||||
#define XEDIT_HISTORY_ENTRY_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), XEDIT_TYPE_HISTORY_ENTRY, XeditHistoryEntryClass))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct _XeditHistoryEntry        XeditHistoryEntry;
 | 
			
		||||
typedef struct _XeditHistoryEntryClass   XeditHistoryEntryClass;
 | 
			
		||||
typedef struct _XeditHistoryEntryPrivate XeditHistoryEntryPrivate;
 | 
			
		||||
 | 
			
		||||
struct _XeditHistoryEntryClass
 | 
			
		||||
{
 | 
			
		||||
	GtkComboBoxTextClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _XeditHistoryEntry
 | 
			
		||||
{
 | 
			
		||||
	GtkComboBoxText parent_instance;
 | 
			
		||||
 | 
			
		||||
	XeditHistoryEntryPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType		 xedit_history_entry_get_type	(void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
GtkWidget	*xedit_history_entry_new		(const gchar       *history_id,
 | 
			
		||||
							 gboolean           enable_completion);
 | 
			
		||||
 | 
			
		||||
void		 xedit_history_entry_prepend_text	(XeditHistoryEntry *entry,
 | 
			
		||||
							 const gchar       *text);
 | 
			
		||||
 | 
			
		||||
void		 xedit_history_entry_append_text	(XeditHistoryEntry *entry,
 | 
			
		||||
							 const gchar       *text);
 | 
			
		||||
 | 
			
		||||
void		 xedit_history_entry_clear		(XeditHistoryEntry *entry);
 | 
			
		||||
 | 
			
		||||
void		 xedit_history_entry_set_history_length	(XeditHistoryEntry *entry,
 | 
			
		||||
							 guint              max_saved);
 | 
			
		||||
 | 
			
		||||
guint		 xedit_history_entry_get_history_length	(XeditHistoryEntry *gentry);
 | 
			
		||||
 | 
			
		||||
gchar		*xedit_history_entry_get_history_id	(XeditHistoryEntry *entry);
 | 
			
		||||
 | 
			
		||||
void             xedit_history_entry_set_enable_completion 
 | 
			
		||||
							(XeditHistoryEntry *entry,
 | 
			
		||||
							 gboolean           enable);
 | 
			
		||||
							 
 | 
			
		||||
gboolean         xedit_history_entry_get_enable_completion 
 | 
			
		||||
							(XeditHistoryEntry *entry);
 | 
			
		||||
 | 
			
		||||
GtkWidget	*xedit_history_entry_get_entry		(XeditHistoryEntry *entry);
 | 
			
		||||
 | 
			
		||||
typedef gchar * (* XeditHistoryEntryEscapeFunc) (const gchar *str);
 | 
			
		||||
void		xedit_history_entry_set_escape_func	(XeditHistoryEntry *entry,
 | 
			
		||||
							 XeditHistoryEntryEscapeFunc escape_func);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __XEDIT_HISTORY_ENTRY_H__ */
 | 
			
		||||
							
								
								
									
										1260
									
								
								xedit/xedit-io-error-message-area.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1260
									
								
								xedit/xedit-io-error-message-area.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										68
									
								
								xedit/xedit-io-error-message-area.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								xedit/xedit-io-error-message-area.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-io-error-message-area.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2005 - Paolo Maggi 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_IO_ERROR_MESSAGE_AREA_H__
 | 
			
		||||
#define __XEDIT_IO_ERROR_MESSAGE_AREA_H__
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
GtkWidget	*xedit_io_loading_error_message_area_new		 (const gchar         *uri,
 | 
			
		||||
									  const XeditEncoding *encoding,
 | 
			
		||||
									  const GError        *error);
 | 
			
		||||
 | 
			
		||||
GtkWidget	*xedit_unrecoverable_reverting_error_message_area_new	 (const gchar         *uri,
 | 
			
		||||
									  const GError        *error);
 | 
			
		||||
 | 
			
		||||
GtkWidget	*xedit_conversion_error_while_saving_message_area_new	 (const gchar         *uri,
 | 
			
		||||
									  const XeditEncoding *encoding,
 | 
			
		||||
									  const GError        *error);
 | 
			
		||||
 | 
			
		||||
const XeditEncoding 
 | 
			
		||||
		*xedit_conversion_error_message_area_get_encoding	 (GtkWidget           *message_area);
 | 
			
		||||
 | 
			
		||||
GtkWidget	*xedit_file_already_open_warning_message_area_new	 (const gchar         *uri);
 | 
			
		||||
 | 
			
		||||
GtkWidget	*xedit_externally_modified_saving_error_message_area_new (const gchar         *uri,
 | 
			
		||||
									  const GError        *error);
 | 
			
		||||
 | 
			
		||||
GtkWidget	*xedit_no_backup_saving_error_message_area_new		 (const gchar         *uri,
 | 
			
		||||
									  const GError        *error);
 | 
			
		||||
 | 
			
		||||
GtkWidget	*xedit_unrecoverable_saving_error_message_area_new	 (const gchar         *uri,
 | 
			
		||||
									  const GError        *error);
 | 
			
		||||
 | 
			
		||||
GtkWidget	*xedit_externally_modified_message_area_new		 (const gchar         *uri,
 | 
			
		||||
									  gboolean             document_modified);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif  /* __XEDIT_IO_ERROR_MESSAGE_AREA_H__  */
 | 
			
		||||
							
								
								
									
										97
									
								
								xedit/xedit-language-manager.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								xedit/xedit-language-manager.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
			
		||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-languages-manager.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2003-2006 - Paolo Maggi 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2003-2006. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
#include <gtksourceview/gtksource.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include "xedit-language-manager.h"
 | 
			
		||||
#include "xedit-prefs-manager.h"
 | 
			
		||||
#include "xedit-utils.h"
 | 
			
		||||
#include "xedit-debug.h"
 | 
			
		||||
 | 
			
		||||
static GtkSourceLanguageManager *language_manager = NULL;
 | 
			
		||||
 | 
			
		||||
GtkSourceLanguageManager *
 | 
			
		||||
xedit_get_language_manager (void)
 | 
			
		||||
{
 | 
			
		||||
	if (language_manager == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		language_manager = gtk_source_language_manager_new ();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return language_manager;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gint
 | 
			
		||||
language_compare (gconstpointer a, gconstpointer b)
 | 
			
		||||
{
 | 
			
		||||
	GtkSourceLanguage *lang_a = (GtkSourceLanguage *)a;
 | 
			
		||||
	GtkSourceLanguage *lang_b = (GtkSourceLanguage *)b;
 | 
			
		||||
	const gchar *name_a = gtk_source_language_get_name (lang_a);
 | 
			
		||||
	const gchar *name_b = gtk_source_language_get_name (lang_b);
 | 
			
		||||
 | 
			
		||||
	return g_utf8_collate (name_a, name_b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GSList *
 | 
			
		||||
xedit_language_manager_list_languages_sorted (GtkSourceLanguageManager *lm,
 | 
			
		||||
					      gboolean                  include_hidden)
 | 
			
		||||
{
 | 
			
		||||
	GSList *languages = NULL;
 | 
			
		||||
	const gchar * const *ids;
 | 
			
		||||
 | 
			
		||||
	ids = gtk_source_language_manager_get_language_ids (lm);
 | 
			
		||||
	if (ids == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	while (*ids != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		GtkSourceLanguage *lang;
 | 
			
		||||
 | 
			
		||||
		lang = gtk_source_language_manager_get_language (lm, *ids);
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
		g_return_val_if_fail (GTK_SOURCE_IS_LANGUAGE (lang), NULL);
 | 
			
		||||
#else
 | 
			
		||||
		g_return_val_if_fail (GTK_IS_SOURCE_LANGUAGE (lang), NULL);
 | 
			
		||||
#endif
 | 
			
		||||
		++ids;
 | 
			
		||||
 | 
			
		||||
		if (include_hidden || !gtk_source_language_get_hidden (lang))
 | 
			
		||||
		{
 | 
			
		||||
			languages = g_slist_prepend (languages, lang);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return g_slist_sort (languages, (GCompareFunc)language_compare);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										48
									
								
								xedit/xedit-language-manager.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								xedit/xedit-language-manager.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-languages-manager.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2003-2005 - Paolo Maggi 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2003-2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_LANGUAGES_MANAGER_H__
 | 
			
		||||
#define __XEDIT_LANGUAGES_MANAGER_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <gtksourceview/gtksourcelanguagemanager.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
GtkSourceLanguageManager	*xedit_get_language_manager	(void);
 | 
			
		||||
 | 
			
		||||
GSList				*xedit_language_manager_list_languages_sorted
 | 
			
		||||
								(GtkSourceLanguageManager	*lm,
 | 
			
		||||
								 gboolean			 include_hidden);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __XEDIT_LANGUAGES_MANAGER_H__ */
 | 
			
		||||
							
								
								
									
										13
									
								
								xedit/xedit-marshal.list
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								xedit/xedit-marshal.list
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
BOOLEAN:NONE
 | 
			
		||||
BOOLEAN:OBJECT
 | 
			
		||||
VOID:BOOLEAN
 | 
			
		||||
VOID:BOOLEAN,POINTER
 | 
			
		||||
VOID:BOXED,BOXED
 | 
			
		||||
VOID:OBJECT
 | 
			
		||||
VOID:POINTER
 | 
			
		||||
VOID:STRING,BOXED,FLAGS
 | 
			
		||||
VOID:STRING,BOXED,INT,BOOLEAN
 | 
			
		||||
VOID:UINT,POINTER
 | 
			
		||||
VOID:UINT64,UINT64
 | 
			
		||||
VOID:VOID
 | 
			
		||||
VOID:INT,INT
 | 
			
		||||
							
								
								
									
										1158
									
								
								xedit/xedit-message-bus.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1158
									
								
								xedit/xedit-message-bus.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										129
									
								
								xedit/xedit-message-bus.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								xedit/xedit-message-bus.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,129 @@
 | 
			
		||||
#ifndef __XEDIT_MESSAGE_BUS_H__
 | 
			
		||||
#define __XEDIT_MESSAGE_BUS_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <xedit/xedit-message.h>
 | 
			
		||||
#include <xedit/xedit-message-type.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define XEDIT_TYPE_MESSAGE_BUS			(xedit_message_bus_get_type ())
 | 
			
		||||
#define XEDIT_MESSAGE_BUS(obj)			(G_TYPE_CHECK_INSTANCE_CAST ((obj), XEDIT_TYPE_MESSAGE_BUS, XeditMessageBus))
 | 
			
		||||
#define XEDIT_MESSAGE_BUS_CONST(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), XEDIT_TYPE_MESSAGE_BUS, XeditMessageBus const))
 | 
			
		||||
#define XEDIT_MESSAGE_BUS_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST ((klass), XEDIT_TYPE_MESSAGE_BUS, XeditMessageBusClass))
 | 
			
		||||
#define XEDIT_IS_MESSAGE_BUS(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), XEDIT_TYPE_MESSAGE_BUS))
 | 
			
		||||
#define XEDIT_IS_MESSAGE_BUS_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), XEDIT_TYPE_MESSAGE_BUS))
 | 
			
		||||
#define XEDIT_MESSAGE_BUS_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), XEDIT_TYPE_MESSAGE_BUS, XeditMessageBusClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _XeditMessageBus		XeditMessageBus;
 | 
			
		||||
typedef struct _XeditMessageBusClass	XeditMessageBusClass;
 | 
			
		||||
typedef struct _XeditMessageBusPrivate	XeditMessageBusPrivate;
 | 
			
		||||
 | 
			
		||||
struct _XeditMessageBus {
 | 
			
		||||
	GObject parent;
 | 
			
		||||
	
 | 
			
		||||
	XeditMessageBusPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _XeditMessageBusClass {
 | 
			
		||||
	GObjectClass parent_class;
 | 
			
		||||
	
 | 
			
		||||
	void (*dispatch)		(XeditMessageBus  *bus,
 | 
			
		||||
					 XeditMessage     *message);
 | 
			
		||||
	void (*registered)		(XeditMessageBus  *bus,
 | 
			
		||||
					 XeditMessageType *message_type);
 | 
			
		||||
	void (*unregistered)		(XeditMessageBus  *bus,
 | 
			
		||||
					 XeditMessageType *message_type);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef void (* XeditMessageCallback) 	(XeditMessageBus *bus,
 | 
			
		||||
					 XeditMessage	 *message,
 | 
			
		||||
					 gpointer	  userdata);
 | 
			
		||||
 | 
			
		||||
typedef void (* XeditMessageBusForeach) (XeditMessageType *message_type,
 | 
			
		||||
					 gpointer	   userdata);
 | 
			
		||||
 | 
			
		||||
GType xedit_message_bus_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
XeditMessageBus *xedit_message_bus_get_default	(void);
 | 
			
		||||
XeditMessageBus *xedit_message_bus_new		(void);
 | 
			
		||||
 | 
			
		||||
/* registering messages */
 | 
			
		||||
XeditMessageType *xedit_message_bus_lookup	(XeditMessageBus 	*bus,
 | 
			
		||||
						 const gchar		*object_path,
 | 
			
		||||
						 const gchar		*method);
 | 
			
		||||
XeditMessageType *xedit_message_bus_register	(XeditMessageBus		*bus,
 | 
			
		||||
					   	 const gchar 		*object_path,
 | 
			
		||||
					  	 const gchar		*method,
 | 
			
		||||
					  	 guint		 	 num_optional,
 | 
			
		||||
					  	 ...) G_GNUC_NULL_TERMINATED;
 | 
			
		||||
 | 
			
		||||
void xedit_message_bus_unregister	  (XeditMessageBus	*bus,
 | 
			
		||||
					   XeditMessageType	*message_type);
 | 
			
		||||
 | 
			
		||||
void xedit_message_bus_unregister_all	  (XeditMessageBus	*bus,
 | 
			
		||||
					   const gchar		*object_path);
 | 
			
		||||
 | 
			
		||||
gboolean xedit_message_bus_is_registered  (XeditMessageBus	*bus,
 | 
			
		||||
					   const gchar		*object_path,
 | 
			
		||||
					   const gchar		*method);
 | 
			
		||||
 | 
			
		||||
void xedit_message_bus_foreach		  (XeditMessageBus        *bus,
 | 
			
		||||
					   XeditMessageBusForeach  func,
 | 
			
		||||
					   gpointer		   userdata);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* connecting to message events */		   
 | 
			
		||||
guint xedit_message_bus_connect	 	  (XeditMessageBus	*bus, 
 | 
			
		||||
					   const gchar		*object_path,
 | 
			
		||||
					   const gchar		*method,
 | 
			
		||||
					   XeditMessageCallback	 callback,
 | 
			
		||||
					   gpointer		 userdata,
 | 
			
		||||
					   GDestroyNotify        destroy_data);
 | 
			
		||||
 | 
			
		||||
void xedit_message_bus_disconnect	  (XeditMessageBus	*bus,
 | 
			
		||||
					   guint		 id);
 | 
			
		||||
 | 
			
		||||
void xedit_message_bus_disconnect_by_func (XeditMessageBus	*bus,
 | 
			
		||||
					   const gchar		*object_path,
 | 
			
		||||
					   const gchar		*method,
 | 
			
		||||
					   XeditMessageCallback	 callback,
 | 
			
		||||
					   gpointer		 userdata);
 | 
			
		||||
 | 
			
		||||
/* blocking message event callbacks */
 | 
			
		||||
void xedit_message_bus_block		  (XeditMessageBus	*bus,
 | 
			
		||||
					   guint		 id);
 | 
			
		||||
void xedit_message_bus_block_by_func	  (XeditMessageBus	*bus,
 | 
			
		||||
					   const gchar		*object_path,
 | 
			
		||||
					   const gchar		*method,
 | 
			
		||||
					   XeditMessageCallback	 callback,
 | 
			
		||||
					   gpointer		 userdata);
 | 
			
		||||
 | 
			
		||||
void xedit_message_bus_unblock		  (XeditMessageBus	*bus,
 | 
			
		||||
					   guint		 id);
 | 
			
		||||
void xedit_message_bus_unblock_by_func	  (XeditMessageBus	*bus,
 | 
			
		||||
					   const gchar		*object_path,
 | 
			
		||||
					   const gchar		*method,
 | 
			
		||||
					   XeditMessageCallback	 callback,
 | 
			
		||||
					   gpointer		 userdata);
 | 
			
		||||
 | 
			
		||||
/* sending messages */
 | 
			
		||||
void xedit_message_bus_send_message	  (XeditMessageBus	*bus,
 | 
			
		||||
					   XeditMessage		*message);
 | 
			
		||||
void xedit_message_bus_send_message_sync  (XeditMessageBus	*bus,
 | 
			
		||||
					   XeditMessage		*message);
 | 
			
		||||
					  
 | 
			
		||||
void xedit_message_bus_send		  (XeditMessageBus	*bus,
 | 
			
		||||
					   const gchar		*object_path,
 | 
			
		||||
					   const gchar		*method,
 | 
			
		||||
					   ...) G_GNUC_NULL_TERMINATED;
 | 
			
		||||
XeditMessage *xedit_message_bus_send_sync (XeditMessageBus	*bus,
 | 
			
		||||
					   const gchar		*object_path,
 | 
			
		||||
					   const gchar		*method,
 | 
			
		||||
					   ...) G_GNUC_NULL_TERMINATED;
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __XEDIT_MESSAGE_BUS_H__ */
 | 
			
		||||
 | 
			
		||||
// ex:ts=8:noet:
 | 
			
		||||
							
								
								
									
										527
									
								
								xedit/xedit-message-type.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										527
									
								
								xedit/xedit-message-type.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,527 @@
 | 
			
		||||
#include "xedit-message-type.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:xedit-message-type
 | 
			
		||||
 * @short_description: message type description
 | 
			
		||||
 * @include: xedit/xedit-message-type.h
 | 
			
		||||
 *
 | 
			
		||||
 * A message type is a prototype description for a #XeditMessage used to
 | 
			
		||||
 * transmit messages on a #XeditMessageBus. The message type describes
 | 
			
		||||
 * the Object Path, Method and Arguments of the message.
 | 
			
		||||
 *
 | 
			
		||||
 * A message type can contain any number of required and optional arguments.
 | 
			
		||||
 * To instantiate a #XeditMessage from a #XeditMessageType, use 
 | 
			
		||||
 * xedit_message_type_instantiate().
 | 
			
		||||
 *
 | 
			
		||||
 * Registering a new message type on a #XeditMessageBus with
 | 
			
		||||
 * xedit_message_bus_register() internally creates a new #XeditMessageType. When
 | 
			
		||||
 * then using xedit_message_bus_send(), an actual instantiation of the 
 | 
			
		||||
 * registered type is internally created and send over the bus.
 | 
			
		||||
 *
 | 
			
		||||
 * <example>
 | 
			
		||||
 * <programlisting>
 | 
			
		||||
 * // Defining a new message type
 | 
			
		||||
 * XeditMessageType *message_type = xedit_message_type_new ("/plugins/example",
 | 
			
		||||
 *                                                          "method",
 | 
			
		||||
 *                                                          0,
 | 
			
		||||
 *                                                          "arg1", G_TYPE_STRING,
 | 
			
		||||
 *                                                          NULL);
 | 
			
		||||
 *
 | 
			
		||||
 * // Instantiating an actual message from the type
 | 
			
		||||
 * XeditMessage *message = xedit_message_type_instantiate (message_type,
 | 
			
		||||
 *                                                         "arg1", "Hello World",
 | 
			
		||||
 *                                                         NULL);
 | 
			
		||||
 * </programlisting>
 | 
			
		||||
 * </example>
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.25.3
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
	GType type;
 | 
			
		||||
	gboolean required;
 | 
			
		||||
} ArgumentInfo;
 | 
			
		||||
 | 
			
		||||
struct _XeditMessageType
 | 
			
		||||
{
 | 
			
		||||
	/* FIXME this is an issue for introspection */
 | 
			
		||||
	gint ref_count;
 | 
			
		||||
 | 
			
		||||
	gchar *object_path;
 | 
			
		||||
	gchar *method;
 | 
			
		||||
	
 | 
			
		||||
	guint num_arguments;
 | 
			
		||||
	guint num_required;
 | 
			
		||||
	
 | 
			
		||||
	GHashTable *arguments; // mapping of key -> ArgumentInfo
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_type_ref:
 | 
			
		||||
 * @message_type: the #XeditMessageType
 | 
			
		||||
 *
 | 
			
		||||
 * Increases the reference count on @message_type.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: @message_type
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
XeditMessageType *
 | 
			
		||||
xedit_message_type_ref (XeditMessageType *message_type)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (message_type != NULL, NULL);
 | 
			
		||||
	g_atomic_int_inc (&message_type->ref_count);
 | 
			
		||||
	
 | 
			
		||||
	return message_type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_type_unref:
 | 
			
		||||
 * @message_type: the #XeditMessageType
 | 
			
		||||
 *
 | 
			
		||||
 * Decreases the reference count on @message_type. When the reference count
 | 
			
		||||
 * drops to 0, @message_type is destroyed.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void 
 | 
			
		||||
xedit_message_type_unref (XeditMessageType *message_type)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (message_type != NULL);
 | 
			
		||||
 | 
			
		||||
	if (!g_atomic_int_dec_and_test (&message_type->ref_count))
 | 
			
		||||
		return;
 | 
			
		||||
	
 | 
			
		||||
	g_free (message_type->object_path);
 | 
			
		||||
	g_free (message_type->method);
 | 
			
		||||
	
 | 
			
		||||
	g_hash_table_destroy (message_type->arguments);
 | 
			
		||||
	g_free (message_type);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_type_get_type:
 | 
			
		||||
 * 
 | 
			
		||||
 * Retrieves the GType object which is associated with the
 | 
			
		||||
 * #XeditMessageType class.
 | 
			
		||||
 * 
 | 
			
		||||
 * Return value: the GType associated with #XeditMessageType.
 | 
			
		||||
 **/
 | 
			
		||||
GType 
 | 
			
		||||
xedit_message_type_get_type (void)
 | 
			
		||||
{
 | 
			
		||||
	static GType our_type = 0;
 | 
			
		||||
 | 
			
		||||
	if (!our_type)
 | 
			
		||||
		our_type = g_boxed_type_register_static (
 | 
			
		||||
			"XeditMessageType",
 | 
			
		||||
			(GBoxedCopyFunc) xedit_message_type_ref,
 | 
			
		||||
			(GBoxedFreeFunc) xedit_message_type_unref);
 | 
			
		||||
 | 
			
		||||
	return our_type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_type_identifier:
 | 
			
		||||
 * @object_path: (allow-none): the object path
 | 
			
		||||
 * @method: (allow-none): the method
 | 
			
		||||
 *
 | 
			
		||||
 * Get the string identifier for @method at @object_path.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the identifier for @method at @object_path
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
gchar *
 | 
			
		||||
xedit_message_type_identifier (const gchar *object_path,
 | 
			
		||||
			       const gchar *method)
 | 
			
		||||
{
 | 
			
		||||
	return g_strconcat (object_path, ".", method, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_type_is_valid_object_path:
 | 
			
		||||
 * @object_path: (allow-none): the object path
 | 
			
		||||
 *
 | 
			
		||||
 * Returns whether @object_path is a valid object path
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: %TRUE if @object_path is a valid object path
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_message_type_is_valid_object_path (const gchar *object_path)
 | 
			
		||||
{
 | 
			
		||||
	if (!object_path)
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	
 | 
			
		||||
	/* needs to start with / */
 | 
			
		||||
	if (*object_path != '/')
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	
 | 
			
		||||
	while (*object_path)
 | 
			
		||||
	{
 | 
			
		||||
		if (*object_path == '/')
 | 
			
		||||
		{
 | 
			
		||||
			++object_path;
 | 
			
		||||
			
 | 
			
		||||
			if (!*object_path || !(g_ascii_isalpha (*object_path) || *object_path == '_'))
 | 
			
		||||
				return FALSE;
 | 
			
		||||
		}
 | 
			
		||||
		else if (!(g_ascii_isalnum (*object_path) || *object_path == '_'))
 | 
			
		||||
		{
 | 
			
		||||
			return FALSE;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		++object_path;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_type_is_supported:
 | 
			
		||||
 * @type: the #GType
 | 
			
		||||
 *
 | 
			
		||||
 * Returns if @type is #GType supported by the message system.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: %TRUE if @type is a supported #GType
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_message_type_is_supported (GType type)
 | 
			
		||||
{
 | 
			
		||||
	gint i = 0;
 | 
			
		||||
  
 | 
			
		||||
	static const GType type_list[] =
 | 
			
		||||
	{
 | 
			
		||||
		G_TYPE_BOOLEAN,
 | 
			
		||||
		G_TYPE_CHAR,
 | 
			
		||||
		G_TYPE_UCHAR,
 | 
			
		||||
		G_TYPE_INT,
 | 
			
		||||
		G_TYPE_UINT,
 | 
			
		||||
		G_TYPE_LONG,
 | 
			
		||||
		G_TYPE_ULONG,
 | 
			
		||||
		G_TYPE_INT64,
 | 
			
		||||
		G_TYPE_UINT64,
 | 
			
		||||
		G_TYPE_ENUM,
 | 
			
		||||
		G_TYPE_FLAGS,
 | 
			
		||||
		G_TYPE_FLOAT,
 | 
			
		||||
		G_TYPE_DOUBLE,
 | 
			
		||||
		G_TYPE_STRING,
 | 
			
		||||
		G_TYPE_POINTER,
 | 
			
		||||
		G_TYPE_BOXED,
 | 
			
		||||
		G_TYPE_OBJECT,
 | 
			
		||||
		G_TYPE_INVALID
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	if (!G_TYPE_IS_VALUE_TYPE (type))
 | 
			
		||||
		return FALSE;
 | 
			
		||||
 | 
			
		||||
	while (type_list[i] != G_TYPE_INVALID)
 | 
			
		||||
	{
 | 
			
		||||
		if (g_type_is_a (type, type_list[i]))
 | 
			
		||||
			return TRUE;
 | 
			
		||||
		i++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_type_new_valist:
 | 
			
		||||
 * @object_path: (allow-none): the object path
 | 
			
		||||
 * @method: (allow-none): the method
 | 
			
		||||
 * @num_optional: number of optional arguments
 | 
			
		||||
 * @var_args: key/gtype pair variable argument list
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new #XeditMessageType for @method at @object_path. Argument names
 | 
			
		||||
 * and values are supplied by the NULL terminated variable argument list.
 | 
			
		||||
 * The last @num_optional provided arguments are considered optional.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the newly constructed #XeditMessageType
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
XeditMessageType *
 | 
			
		||||
xedit_message_type_new_valist (const gchar *object_path,
 | 
			
		||||
			       const gchar *method,
 | 
			
		||||
			       guint        num_optional,
 | 
			
		||||
			       va_list      var_args)
 | 
			
		||||
{
 | 
			
		||||
	XeditMessageType *message_type;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (object_path != NULL, NULL);
 | 
			
		||||
	g_return_val_if_fail (method != NULL, NULL);
 | 
			
		||||
	g_return_val_if_fail (xedit_message_type_is_valid_object_path (object_path), NULL);
 | 
			
		||||
 | 
			
		||||
	message_type = g_new0(XeditMessageType, 1);
 | 
			
		||||
	
 | 
			
		||||
	message_type->ref_count = 1;
 | 
			
		||||
	message_type->object_path = g_strdup(object_path);
 | 
			
		||||
	message_type->method = g_strdup(method);
 | 
			
		||||
	message_type->num_arguments = 0;
 | 
			
		||||
	message_type->arguments = g_hash_table_new_full (g_str_hash,
 | 
			
		||||
							 g_str_equal,
 | 
			
		||||
							 (GDestroyNotify)g_free,
 | 
			
		||||
							 (GDestroyNotify)g_free);
 | 
			
		||||
 | 
			
		||||
	xedit_message_type_set_valist (message_type, num_optional, var_args);
 | 
			
		||||
	return message_type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_type_new:
 | 
			
		||||
 * @object_path: (allow-none): the object path
 | 
			
		||||
 * @method: (allow-none): the method
 | 
			
		||||
 * @num_optional: number of optional arguments
 | 
			
		||||
 * @...: key/gtype pair variable argument list
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new #XeditMessageType for @method at @object_path. Argument names
 | 
			
		||||
 * and values are supplied by the NULL terminated variable argument list.
 | 
			
		||||
 * The last @num_optional provided arguments are considered optional.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the newly constructed #XeditMessageType
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
XeditMessageType *
 | 
			
		||||
xedit_message_type_new (const gchar *object_path,
 | 
			
		||||
			const gchar *method,
 | 
			
		||||
			guint        num_optional,
 | 
			
		||||
			...)
 | 
			
		||||
{
 | 
			
		||||
	XeditMessageType *message_type;
 | 
			
		||||
	va_list var_args;
 | 
			
		||||
	
 | 
			
		||||
	va_start(var_args, num_optional);
 | 
			
		||||
	message_type = xedit_message_type_new_valist (object_path, method, num_optional, var_args);
 | 
			
		||||
	va_end(var_args);
 | 
			
		||||
	
 | 
			
		||||
	return message_type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_type_set:
 | 
			
		||||
 * @message_type: the #XeditMessageType
 | 
			
		||||
 * @num_optional: number of optional arguments
 | 
			
		||||
 * @...: key/gtype pair variable argument list
 | 
			
		||||
 *
 | 
			
		||||
 * Sets argument names/types supplied by the NULL terminated variable
 | 
			
		||||
 * argument list. The last @num_optional provided arguments are considered
 | 
			
		||||
 * optional.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
xedit_message_type_set (XeditMessageType *message_type,
 | 
			
		||||
			guint		  num_optional,
 | 
			
		||||
			...)
 | 
			
		||||
{
 | 
			
		||||
	va_list va_args;
 | 
			
		||||
	
 | 
			
		||||
	va_start (va_args, num_optional);
 | 
			
		||||
	xedit_message_type_set_valist (message_type, num_optional, va_args);
 | 
			
		||||
	va_end (va_args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_type_set_valist:
 | 
			
		||||
 * @message_type: the #XeditMessageType
 | 
			
		||||
 * @num_optional: number of optional arguments
 | 
			
		||||
 * @var_args: key/gtype pair variable argument list
 | 
			
		||||
 *
 | 
			
		||||
 * Sets argument names/types supplied by the NULL terminated variable
 | 
			
		||||
 * argument list @var_args. The last @num_optional provided arguments are 
 | 
			
		||||
 * considered optional.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void 
 | 
			
		||||
xedit_message_type_set_valist (XeditMessageType *message_type,
 | 
			
		||||
			       guint             num_optional,
 | 
			
		||||
			       va_list	         var_args)
 | 
			
		||||
{
 | 
			
		||||
	const gchar *key;
 | 
			
		||||
	ArgumentInfo **optional = g_new0(ArgumentInfo *, num_optional);
 | 
			
		||||
	guint i;
 | 
			
		||||
	guint added = 0;
 | 
			
		||||
 | 
			
		||||
	// parse key -> gtype pair arguments
 | 
			
		||||
	while ((key = va_arg (var_args, const gchar *)) != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		// get corresponding GType
 | 
			
		||||
		GType gtype = va_arg (var_args, GType);
 | 
			
		||||
		ArgumentInfo *info;
 | 
			
		||||
		
 | 
			
		||||
		if (!xedit_message_type_is_supported (gtype))
 | 
			
		||||
		{
 | 
			
		||||
			g_error ("Message type '%s' is not supported", g_type_name (gtype));
 | 
			
		||||
 | 
			
		||||
			xedit_message_type_unref (message_type);
 | 
			
		||||
			g_free (optional);
 | 
			
		||||
			
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		info = g_new(ArgumentInfo, 1);
 | 
			
		||||
		info->type = gtype;
 | 
			
		||||
		info->required = TRUE;
 | 
			
		||||
 | 
			
		||||
		g_hash_table_insert (message_type->arguments, g_strdup (key), info);
 | 
			
		||||
		
 | 
			
		||||
		++message_type->num_arguments;
 | 
			
		||||
		++added;
 | 
			
		||||
		
 | 
			
		||||
		if (num_optional > 0)
 | 
			
		||||
		{
 | 
			
		||||
			for (i = num_optional - 1; i > 0; --i)
 | 
			
		||||
				optional[i] = optional[i - 1];
 | 
			
		||||
		
 | 
			
		||||
			*optional = info;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	message_type->num_required += added;
 | 
			
		||||
 | 
			
		||||
	// set required for last num_optional arguments
 | 
			
		||||
	for (i = 0; i < num_optional; ++i)
 | 
			
		||||
	{
 | 
			
		||||
		if (optional[i])
 | 
			
		||||
		{
 | 
			
		||||
			optional[i]->required = FALSE;
 | 
			
		||||
			--message_type->num_required;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	g_free (optional);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_type_instantiate_valist:
 | 
			
		||||
 * @message_type: the #XeditMessageType
 | 
			
		||||
 * @va_args: NULL terminated variable list of key/value pairs
 | 
			
		||||
 *
 | 
			
		||||
 * Instantiate a new message from the message type with specific values
 | 
			
		||||
 * for the message arguments.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the newly created message
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
XeditMessage *
 | 
			
		||||
xedit_message_type_instantiate_valist (XeditMessageType *message_type,
 | 
			
		||||
				       va_list		 va_args)
 | 
			
		||||
{
 | 
			
		||||
	XeditMessage *message;
 | 
			
		||||
	
 | 
			
		||||
	g_return_val_if_fail (message_type != NULL, NULL);
 | 
			
		||||
	
 | 
			
		||||
	message = XEDIT_MESSAGE (g_object_new (XEDIT_TYPE_MESSAGE, "type", message_type, NULL));
 | 
			
		||||
	xedit_message_set_valist (message, va_args);
 | 
			
		||||
	
 | 
			
		||||
	return message;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_type_instantiate:
 | 
			
		||||
 * @message_type: the #XeditMessageType
 | 
			
		||||
 * @...: NULL terminated variable list of key/value pairs
 | 
			
		||||
 *
 | 
			
		||||
 * Instantiate a new message from the message type with specific values
 | 
			
		||||
 * for the message arguments.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the newly created message
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
XeditMessage *
 | 
			
		||||
xedit_message_type_instantiate (XeditMessageType *message_type,
 | 
			
		||||
				...)
 | 
			
		||||
{
 | 
			
		||||
	XeditMessage *message;
 | 
			
		||||
	va_list va_args;
 | 
			
		||||
	
 | 
			
		||||
	va_start (va_args, message_type);
 | 
			
		||||
	message = xedit_message_type_instantiate_valist (message_type, va_args);
 | 
			
		||||
	va_end (va_args);
 | 
			
		||||
	
 | 
			
		||||
	return message;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_type_get_object_path:
 | 
			
		||||
 * @message_type: the #XeditMessageType
 | 
			
		||||
 *
 | 
			
		||||
 * Get the message type object path.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the message type object path
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
const gchar *
 | 
			
		||||
xedit_message_type_get_object_path (XeditMessageType *message_type)
 | 
			
		||||
{
 | 
			
		||||
	return message_type->object_path;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_type_get_method:
 | 
			
		||||
 * @message_type: the #XeditMessageType
 | 
			
		||||
 *
 | 
			
		||||
 * Get the message type method.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the message type method
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
const gchar *
 | 
			
		||||
xedit_message_type_get_method (XeditMessageType *message_type)
 | 
			
		||||
{
 | 
			
		||||
	return message_type->method;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_type_lookup:
 | 
			
		||||
 * @message_type: the #XeditMessageType
 | 
			
		||||
 * @key: the argument key
 | 
			
		||||
 *
 | 
			
		||||
 * Get the argument key #GType.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the #GType of @key
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
GType
 | 
			
		||||
xedit_message_type_lookup (XeditMessageType *message_type,
 | 
			
		||||
			   const gchar      *key)
 | 
			
		||||
{
 | 
			
		||||
	ArgumentInfo *info = g_hash_table_lookup (message_type->arguments, key);
 | 
			
		||||
	
 | 
			
		||||
	if (!info)
 | 
			
		||||
		return G_TYPE_INVALID;
 | 
			
		||||
	
 | 
			
		||||
	return info->type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
	XeditMessageTypeForeach func;
 | 
			
		||||
	gpointer user_data;
 | 
			
		||||
} ForeachInfo;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
foreach_gtype (const gchar  *key,
 | 
			
		||||
	       ArgumentInfo *info,
 | 
			
		||||
	       ForeachInfo  *finfo)
 | 
			
		||||
{
 | 
			
		||||
	finfo->func (key, info->type, info->required, finfo->user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_type_foreach:
 | 
			
		||||
 * @message_type: the #XeditMessageType
 | 
			
		||||
 * @func: the callback function
 | 
			
		||||
 * @user_data: user data supplied to the callback function
 | 
			
		||||
 *
 | 
			
		||||
 * Calls @func for each argument in the message type.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void 
 | 
			
		||||
xedit_message_type_foreach (XeditMessageType 	    *message_type,
 | 
			
		||||
			    XeditMessageTypeForeach  func,
 | 
			
		||||
			    gpointer		     user_data)
 | 
			
		||||
{
 | 
			
		||||
	ForeachInfo info = {func, user_data};
 | 
			
		||||
	g_hash_table_foreach (message_type->arguments, (GHFunc)foreach_gtype, &info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ex:ts=8:noet:
 | 
			
		||||
							
								
								
									
										67
									
								
								xedit/xedit-message-type.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								xedit/xedit-message-type.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
			
		||||
#ifndef __XEDIT_MESSAGE_TYPE_H__
 | 
			
		||||
#define __XEDIT_MESSAGE_TYPE_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
 | 
			
		||||
#include "xedit-message.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define XEDIT_TYPE_MESSAGE_TYPE			(xedit_message_type_get_type ())
 | 
			
		||||
#define XEDIT_MESSAGE_TYPE(x)			((XeditMessageType *)(x))
 | 
			
		||||
 | 
			
		||||
typedef void (*XeditMessageTypeForeach)		(const gchar *key, 
 | 
			
		||||
						 GType 	      type, 
 | 
			
		||||
						 gboolean     required, 
 | 
			
		||||
						 gpointer     user_data);
 | 
			
		||||
 | 
			
		||||
typedef struct _XeditMessageType			XeditMessageType;
 | 
			
		||||
 | 
			
		||||
GType xedit_message_type_get_type 		 (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
gboolean xedit_message_type_is_supported 	 (GType type);
 | 
			
		||||
gchar *xedit_message_type_identifier		 (const gchar *object_path,
 | 
			
		||||
						  const gchar *method);
 | 
			
		||||
gboolean xedit_message_type_is_valid_object_path (const gchar *object_path);
 | 
			
		||||
 | 
			
		||||
XeditMessageType *xedit_message_type_new	 (const gchar *object_path, 
 | 
			
		||||
						  const gchar *method,
 | 
			
		||||
						  guint	      num_optional,
 | 
			
		||||
						  ...) G_GNUC_NULL_TERMINATED;
 | 
			
		||||
XeditMessageType *xedit_message_type_new_valist	 (const gchar *object_path,
 | 
			
		||||
						  const gchar *method,
 | 
			
		||||
						  guint	      num_optional,
 | 
			
		||||
						  va_list      va_args);
 | 
			
		||||
 | 
			
		||||
void xedit_message_type_set			 (XeditMessageType *message_type,
 | 
			
		||||
						  guint		   num_optional,
 | 
			
		||||
						  ...) G_GNUC_NULL_TERMINATED;
 | 
			
		||||
void xedit_message_type_set_valist		 (XeditMessageType *message_type,
 | 
			
		||||
						  guint		   num_optional,
 | 
			
		||||
						  va_list	           va_args);
 | 
			
		||||
 | 
			
		||||
XeditMessageType *xedit_message_type_ref 	 (XeditMessageType *message_type);
 | 
			
		||||
void xedit_message_type_unref			 (XeditMessageType *message_type);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
XeditMessage *xedit_message_type_instantiate_valist (XeditMessageType *message_type,
 | 
			
		||||
				       		     va_list	      va_args);
 | 
			
		||||
XeditMessage *xedit_message_type_instantiate 	 (XeditMessageType *message_type,
 | 
			
		||||
				       		  ...) G_GNUC_NULL_TERMINATED;
 | 
			
		||||
 | 
			
		||||
const gchar *xedit_message_type_get_object_path	 (XeditMessageType *message_type);
 | 
			
		||||
const gchar *xedit_message_type_get_method	 (XeditMessageType *message_type);
 | 
			
		||||
 | 
			
		||||
GType xedit_message_type_lookup			 (XeditMessageType *message_type,
 | 
			
		||||
						  const gchar      *key);
 | 
			
		||||
						 
 | 
			
		||||
void xedit_message_type_foreach 		 (XeditMessageType 	  *message_type,
 | 
			
		||||
						  XeditMessageTypeForeach  func,
 | 
			
		||||
						  gpointer	   	   user_data);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __XEDIT_MESSAGE_TYPE_H__ */
 | 
			
		||||
 | 
			
		||||
// ex:ts=8:noet:
 | 
			
		||||
							
								
								
									
										594
									
								
								xedit/xedit-message.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										594
									
								
								xedit/xedit-message.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,594 @@
 | 
			
		||||
#include "xedit-message.h"
 | 
			
		||||
#include "xedit-message-type.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <gobject/gvaluecollector.h>
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:xedit-message
 | 
			
		||||
 * @short_description: message bus message object
 | 
			
		||||
 * @include: xedit/xedit-message.h
 | 
			
		||||
 *
 | 
			
		||||
 * Communication on a #XeditMessageBus is done through messages. Messages are
 | 
			
		||||
 * sent over the bus and received by connecting callbacks on the message bus.
 | 
			
		||||
 * A #XeditMessage is an instantiation of a #XeditMessageType, containing
 | 
			
		||||
 * values for the arguments as specified in the message type.
 | 
			
		||||
 *
 | 
			
		||||
 * A message can be seen as a method call, or signal emission depending on
 | 
			
		||||
 * who is the sender and who is the receiver. There is no explicit distinction
 | 
			
		||||
 * between methods and signals.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.25.3
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
#define XEDIT_MESSAGE_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), XEDIT_TYPE_MESSAGE, XeditMessagePrivate))
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
	PROP_0,
 | 
			
		||||
 | 
			
		||||
	PROP_OBJECT_PATH,
 | 
			
		||||
	PROP_METHOD,
 | 
			
		||||
	PROP_TYPE
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _XeditMessagePrivate
 | 
			
		||||
{
 | 
			
		||||
	XeditMessageType *type;
 | 
			
		||||
	gboolean valid;
 | 
			
		||||
 | 
			
		||||
	GHashTable *values;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (XeditMessage, xedit_message, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_message_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
	XeditMessage *message = XEDIT_MESSAGE (object);
 | 
			
		||||
	
 | 
			
		||||
	xedit_message_type_unref (message->priv->type);
 | 
			
		||||
	g_hash_table_destroy (message->priv->values);
 | 
			
		||||
 | 
			
		||||
	G_OBJECT_CLASS (xedit_message_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_message_get_property (GObject    *object,
 | 
			
		||||
			    guint       prop_id,
 | 
			
		||||
			    GValue     *value,
 | 
			
		||||
			    GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
	XeditMessage *msg = XEDIT_MESSAGE (object);
 | 
			
		||||
 | 
			
		||||
	switch (prop_id)
 | 
			
		||||
	{
 | 
			
		||||
		case PROP_OBJECT_PATH:
 | 
			
		||||
			g_value_set_string (value, xedit_message_type_get_object_path (msg->priv->type));
 | 
			
		||||
			break;
 | 
			
		||||
		case PROP_METHOD:
 | 
			
		||||
			g_value_set_string (value, xedit_message_type_get_method (msg->priv->type));
 | 
			
		||||
			break;
 | 
			
		||||
		case PROP_TYPE:
 | 
			
		||||
			g_value_set_boxed (value, msg->priv->type);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_message_set_property (GObject      *object,
 | 
			
		||||
			    guint         prop_id,
 | 
			
		||||
			    const GValue *value,
 | 
			
		||||
			    GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
	XeditMessage *msg = XEDIT_MESSAGE (object);
 | 
			
		||||
 | 
			
		||||
	switch (prop_id)
 | 
			
		||||
	{
 | 
			
		||||
		case PROP_TYPE:
 | 
			
		||||
			msg->priv->type = XEDIT_MESSAGE_TYPE (g_value_dup_boxed (value));
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GValue *
 | 
			
		||||
add_value (XeditMessage *message,
 | 
			
		||||
	   const gchar  *key)
 | 
			
		||||
{
 | 
			
		||||
	GValue *value;
 | 
			
		||||
	GType type = xedit_message_type_lookup (message->priv->type, key);
 | 
			
		||||
	
 | 
			
		||||
	if (type == G_TYPE_INVALID)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	
 | 
			
		||||
	value = g_new0 (GValue, 1);
 | 
			
		||||
	g_value_init (value, type);
 | 
			
		||||
	g_value_reset (value);
 | 
			
		||||
 | 
			
		||||
	g_hash_table_insert (message->priv->values, g_strdup (key), value);
 | 
			
		||||
	
 | 
			
		||||
	return value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_message_class_init (XeditMessageClass *klass)
 | 
			
		||||
{
 | 
			
		||||
	GObjectClass *object_class = G_OBJECT_CLASS(klass);
 | 
			
		||||
	
 | 
			
		||||
	object_class->finalize = xedit_message_finalize;
 | 
			
		||||
	object_class->get_property = xedit_message_get_property;
 | 
			
		||||
	object_class->set_property = xedit_message_set_property;
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * XeditMessage:object_path:
 | 
			
		||||
	 *
 | 
			
		||||
	 * The messages object path (e.g. /xedit/object/path).
 | 
			
		||||
	 *
 | 
			
		||||
	 */
 | 
			
		||||
	g_object_class_install_property (object_class, PROP_OBJECT_PATH,
 | 
			
		||||
					 g_param_spec_string ("object-path",
 | 
			
		||||
							      "OBJECT_PATH",
 | 
			
		||||
							      "The message object path",
 | 
			
		||||
							      NULL,
 | 
			
		||||
							      G_PARAM_READABLE |
 | 
			
		||||
							      G_PARAM_STATIC_STRINGS));
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * XeditMessage:method:
 | 
			
		||||
	 *
 | 
			
		||||
	 * The messages method.
 | 
			
		||||
	 *
 | 
			
		||||
	 */
 | 
			
		||||
	g_object_class_install_property (object_class, PROP_METHOD,
 | 
			
		||||
					 g_param_spec_string ("method",
 | 
			
		||||
							      "METHOD",
 | 
			
		||||
							      "The message method",
 | 
			
		||||
							      NULL,
 | 
			
		||||
							      G_PARAM_READABLE |
 | 
			
		||||
							      G_PARAM_STATIC_STRINGS));
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * XeditMEssage:type:
 | 
			
		||||
	 *
 | 
			
		||||
	 * The message type.
 | 
			
		||||
	 *
 | 
			
		||||
	 */
 | 
			
		||||
	g_object_class_install_property (object_class, PROP_TYPE,
 | 
			
		||||
					 g_param_spec_boxed ("type",
 | 
			
		||||
					 		     "TYPE",
 | 
			
		||||
					 		     "The message type",
 | 
			
		||||
					 		     XEDIT_TYPE_MESSAGE_TYPE,
 | 
			
		||||
					 		     G_PARAM_READWRITE |
 | 
			
		||||
					 		     G_PARAM_CONSTRUCT_ONLY |
 | 
			
		||||
					 		     G_PARAM_STATIC_STRINGS));
 | 
			
		||||
 | 
			
		||||
	g_type_class_add_private (object_class, sizeof(XeditMessagePrivate));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
destroy_value (GValue *value)
 | 
			
		||||
{
 | 
			
		||||
	g_value_unset (value);
 | 
			
		||||
	g_free (value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_message_init (XeditMessage *self)
 | 
			
		||||
{
 | 
			
		||||
	self->priv = XEDIT_MESSAGE_GET_PRIVATE (self);
 | 
			
		||||
 | 
			
		||||
	self->priv->values = g_hash_table_new_full (g_str_hash,
 | 
			
		||||
						    g_str_equal,
 | 
			
		||||
						    (GDestroyNotify)g_free,
 | 
			
		||||
						    (GDestroyNotify)destroy_value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
set_value_real (GValue 	     *to, 
 | 
			
		||||
		const GValue *from)
 | 
			
		||||
{
 | 
			
		||||
	GType from_type;
 | 
			
		||||
	GType to_type;
 | 
			
		||||
	
 | 
			
		||||
	from_type = G_VALUE_TYPE (from);
 | 
			
		||||
	to_type = G_VALUE_TYPE (to);
 | 
			
		||||
 | 
			
		||||
	if (!g_type_is_a (from_type, to_type))
 | 
			
		||||
	{		
 | 
			
		||||
		if (!g_value_transform (from, to))
 | 
			
		||||
		{
 | 
			
		||||
			g_warning ("%s: Unable to make conversion from %s to %s",
 | 
			
		||||
				   G_STRLOC,
 | 
			
		||||
				   g_type_name (from_type),
 | 
			
		||||
				   g_type_name (to_type));
 | 
			
		||||
			return FALSE;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		return TRUE;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	g_value_copy (from, to);
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline static GValue *
 | 
			
		||||
value_lookup (XeditMessage *message,
 | 
			
		||||
	      const gchar  *key,
 | 
			
		||||
	      gboolean	    create)
 | 
			
		||||
{
 | 
			
		||||
	GValue *ret = (GValue *)g_hash_table_lookup (message->priv->values, key);
 | 
			
		||||
	
 | 
			
		||||
	if (!ret && create)
 | 
			
		||||
		ret = add_value (message, key);
 | 
			
		||||
	
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_get_method:
 | 
			
		||||
 * @message: the #XeditMessage
 | 
			
		||||
 *
 | 
			
		||||
 * Get the message method.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the message method
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
const gchar *
 | 
			
		||||
xedit_message_get_method (XeditMessage *message)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_MESSAGE (message), NULL);
 | 
			
		||||
	
 | 
			
		||||
	return xedit_message_type_get_method (message->priv->type);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_get_object_path:
 | 
			
		||||
 * @message: the #XeditMessage
 | 
			
		||||
 *
 | 
			
		||||
 * Get the message object path.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the message object path
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
const gchar *
 | 
			
		||||
xedit_message_get_object_path (XeditMessage *message)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_MESSAGE (message), NULL);
 | 
			
		||||
	
 | 
			
		||||
	return xedit_message_type_get_object_path (message->priv->type);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_set:
 | 
			
		||||
 * @message: the #XeditMessage
 | 
			
		||||
 * @...: a %NULL terminated variable list of key/value pairs
 | 
			
		||||
 *
 | 
			
		||||
 * Set values of message arguments. The supplied @var_args should contain
 | 
			
		||||
 * pairs of keys and argument values.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
xedit_message_set (XeditMessage *message,
 | 
			
		||||
		   ...)
 | 
			
		||||
{
 | 
			
		||||
	va_list ap;
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_MESSAGE (message));
 | 
			
		||||
 | 
			
		||||
	va_start (ap, message);
 | 
			
		||||
	xedit_message_set_valist (message, ap);
 | 
			
		||||
	va_end (ap);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_set_valist:
 | 
			
		||||
 * @message: the #XeditMessage
 | 
			
		||||
 * @var_args: a %NULL terminated variable list of key/value pairs
 | 
			
		||||
 *
 | 
			
		||||
 * Set values of message arguments. The supplied @var_args should contain
 | 
			
		||||
 * pairs of keys and argument values.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
xedit_message_set_valist (XeditMessage *message,
 | 
			
		||||
			  va_list	var_args)
 | 
			
		||||
{
 | 
			
		||||
	const gchar *key;
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_MESSAGE (message));
 | 
			
		||||
 | 
			
		||||
	while ((key = va_arg (var_args, const gchar *)) != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		/* lookup the key */
 | 
			
		||||
		GValue *container = value_lookup (message, key, TRUE);
 | 
			
		||||
		GValue value = {0,};
 | 
			
		||||
		gchar *error = NULL;
 | 
			
		||||
		
 | 
			
		||||
		if (!container)
 | 
			
		||||
		{
 | 
			
		||||
			g_warning ("%s: Cannot set value for %s, does not exist", 
 | 
			
		||||
				   G_STRLOC,
 | 
			
		||||
				   key);
 | 
			
		||||
			
 | 
			
		||||
			/* skip value */
 | 
			
		||||
			va_arg (var_args, gpointer);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		g_value_init (&value, G_VALUE_TYPE (container));
 | 
			
		||||
		G_VALUE_COLLECT (&value, var_args, 0, &error);
 | 
			
		||||
		
 | 
			
		||||
		if (error)
 | 
			
		||||
		{
 | 
			
		||||
			g_warning ("%s: %s", G_STRLOC, error);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		set_value_real (container, &value);
 | 
			
		||||
		g_value_unset (&value);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_set_value:
 | 
			
		||||
 * @message: the #XeditMessage
 | 
			
		||||
 * @key: the argument key
 | 
			
		||||
 * @value: (out): the argument value
 | 
			
		||||
 *
 | 
			
		||||
 * Set value of message argument @key to @value.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
xedit_message_set_value (XeditMessage *message,
 | 
			
		||||
			 const gchar  *key,
 | 
			
		||||
			 GValue	      *value)
 | 
			
		||||
{
 | 
			
		||||
	GValue *container;
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_MESSAGE (message));
 | 
			
		||||
	
 | 
			
		||||
	container = value_lookup (message, key, TRUE);
 | 
			
		||||
	
 | 
			
		||||
	if (!container)
 | 
			
		||||
	{
 | 
			
		||||
		g_warning ("%s: Cannot set value for %s, does not exist", 
 | 
			
		||||
			   G_STRLOC, 
 | 
			
		||||
			   key);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	set_value_real (container, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_set_valuesv:
 | 
			
		||||
 * @message: the #XeditMessage
 | 
			
		||||
 * @keys: (array-length=n_values): keys to set values for
 | 
			
		||||
 * @values: (array-length=n_values): values to set
 | 
			
		||||
 * @n_values: number of arguments to set values for
 | 
			
		||||
 *
 | 
			
		||||
 * Set message argument values.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
xedit_message_set_valuesv (XeditMessage	 *message,
 | 
			
		||||
			   const gchar	**keys,
 | 
			
		||||
			   GValue        *values,
 | 
			
		||||
			   gint		  n_values)
 | 
			
		||||
{
 | 
			
		||||
	gint i;
 | 
			
		||||
	
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_MESSAGE (message));
 | 
			
		||||
	
 | 
			
		||||
	for (i = 0; i < n_values; i++)
 | 
			
		||||
	{
 | 
			
		||||
		xedit_message_set_value (message, keys[i], &values[i]);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* FIXME this is an issue for introspection */
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_get:
 | 
			
		||||
 * @message: the #XeditMessage
 | 
			
		||||
 * @...: a %NULL variable argument list of key/value container pairs
 | 
			
		||||
 *
 | 
			
		||||
 * Get values of message arguments. The supplied @var_args should contain
 | 
			
		||||
 * pairs of keys and pointers to variables which are set to the argument
 | 
			
		||||
 * value for the specified key.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void 
 | 
			
		||||
xedit_message_get (XeditMessage	*message,
 | 
			
		||||
		   ...)
 | 
			
		||||
{
 | 
			
		||||
	va_list ap;
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_MESSAGE (message));
 | 
			
		||||
	
 | 
			
		||||
	va_start (ap, message);
 | 
			
		||||
	xedit_message_get_valist (message, ap);
 | 
			
		||||
	va_end (ap);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_get_valist:
 | 
			
		||||
 * @message: the #XeditMessage
 | 
			
		||||
 * @var_args: a %NULL variable argument list of key/value container pairs
 | 
			
		||||
 *
 | 
			
		||||
 * Get values of message arguments. The supplied @var_args should contain
 | 
			
		||||
 * pairs of keys and pointers to variables which are set to the argument
 | 
			
		||||
 * value for the specified key.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
xedit_message_get_valist (XeditMessage *message,
 | 
			
		||||
			  va_list 	var_args)
 | 
			
		||||
{
 | 
			
		||||
	const gchar *key;
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_MESSAGE (message));
 | 
			
		||||
	
 | 
			
		||||
	while ((key = va_arg (var_args, const gchar *)) != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		GValue *container;
 | 
			
		||||
		GValue copy = {0,};
 | 
			
		||||
		gchar *error = NULL;
 | 
			
		||||
 | 
			
		||||
		container = value_lookup (message, key, FALSE);
 | 
			
		||||
	
 | 
			
		||||
		if (!container)
 | 
			
		||||
		{		
 | 
			
		||||
			/* skip value */
 | 
			
		||||
			va_arg (var_args, gpointer);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		/* copy the value here, to be sure it isn't tainted */
 | 
			
		||||
		g_value_init (©, G_VALUE_TYPE (container));
 | 
			
		||||
		g_value_copy (container, ©);
 | 
			
		||||
		
 | 
			
		||||
		G_VALUE_LCOPY (©, var_args, 0, &error);
 | 
			
		||||
		
 | 
			
		||||
		if (error)
 | 
			
		||||
		{
 | 
			
		||||
			g_warning ("%s: %s", G_STRLOC, error);
 | 
			
		||||
			g_free (error);
 | 
			
		||||
			
 | 
			
		||||
			/* purposely leak the value here, because it might
 | 
			
		||||
			   be in a bad state */
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		g_value_unset (©);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_get_value:
 | 
			
		||||
 * @message: the #XeditMessage
 | 
			
		||||
 * @key: the argument key
 | 
			
		||||
 * @value: (out): value return container
 | 
			
		||||
 *
 | 
			
		||||
 * Get the value of a specific message argument. @value will be initialized
 | 
			
		||||
 * with the correct type.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void 
 | 
			
		||||
xedit_message_get_value (XeditMessage *message,
 | 
			
		||||
			 const gchar  *key,
 | 
			
		||||
			 GValue	      *value)
 | 
			
		||||
{
 | 
			
		||||
	GValue *container;
 | 
			
		||||
	
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_MESSAGE (message));
 | 
			
		||||
	
 | 
			
		||||
	container = value_lookup (message, key, FALSE);
 | 
			
		||||
	
 | 
			
		||||
	if (!container)
 | 
			
		||||
	{
 | 
			
		||||
		g_warning ("%s: Invalid key `%s'",
 | 
			
		||||
			   G_STRLOC,
 | 
			
		||||
			   key);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	g_value_init (value, G_VALUE_TYPE (container));
 | 
			
		||||
	set_value_real (value, container);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_get_key_type:
 | 
			
		||||
 * @message: the #XeditMessage
 | 
			
		||||
 * @key: the argument key
 | 
			
		||||
 *
 | 
			
		||||
 * Get the type of a message argument.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the type of @key
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
GType 
 | 
			
		||||
xedit_message_get_key_type (XeditMessage    *message,
 | 
			
		||||
			    const gchar	    *key)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_MESSAGE (message), G_TYPE_INVALID);
 | 
			
		||||
	g_return_val_if_fail (message->priv->type != NULL, G_TYPE_INVALID);
 | 
			
		||||
 | 
			
		||||
	return xedit_message_type_lookup (message->priv->type, key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_has_key:
 | 
			
		||||
 * @message: the #XeditMessage
 | 
			
		||||
 * @key: the argument key
 | 
			
		||||
 *
 | 
			
		||||
 * Check whether the message has a specific key.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: %TRUE if @message has argument @key
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_message_has_key (XeditMessage *message,
 | 
			
		||||
		       const gchar  *key)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_MESSAGE (message), FALSE);
 | 
			
		||||
	
 | 
			
		||||
	return value_lookup (message, key, FALSE) != NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
	XeditMessage *message;
 | 
			
		||||
	gboolean valid;	
 | 
			
		||||
} ValidateInfo;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
validate_key (const gchar  *key,
 | 
			
		||||
	      GType         type,
 | 
			
		||||
	      gboolean	    required,
 | 
			
		||||
	      ValidateInfo *info)
 | 
			
		||||
{
 | 
			
		||||
	GValue *value;
 | 
			
		||||
	
 | 
			
		||||
	if (!info->valid || !required)
 | 
			
		||||
		return;
 | 
			
		||||
	
 | 
			
		||||
	value = value_lookup (info->message, key, FALSE);
 | 
			
		||||
	
 | 
			
		||||
	if (!value)
 | 
			
		||||
		info->valid = FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_message_validate:
 | 
			
		||||
 * @message: the #XeditMessage
 | 
			
		||||
 *
 | 
			
		||||
 * Validates the message arguments according to the message type.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: %TRUE if the message is valid
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_message_validate (XeditMessage *message)
 | 
			
		||||
{
 | 
			
		||||
	ValidateInfo info = {message, TRUE};
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_MESSAGE (message), FALSE);
 | 
			
		||||
	g_return_val_if_fail (message->priv->type != NULL, FALSE);
 | 
			
		||||
	
 | 
			
		||||
	if (!message->priv->valid)
 | 
			
		||||
	{
 | 
			
		||||
		xedit_message_type_foreach (message->priv->type, 
 | 
			
		||||
					    (XeditMessageTypeForeach)validate_key,
 | 
			
		||||
					    &info);
 | 
			
		||||
 | 
			
		||||
		message->priv->valid = info.valid;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return message->priv->valid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ex:ts=8:noet:
 | 
			
		||||
							
								
								
									
										71
									
								
								xedit/xedit-message.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								xedit/xedit-message.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
			
		||||
#ifndef __XEDIT_MESSAGE_H__
 | 
			
		||||
#define __XEDIT_MESSAGE_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define XEDIT_TYPE_MESSAGE			(xedit_message_get_type ())
 | 
			
		||||
#define XEDIT_MESSAGE(obj)			(G_TYPE_CHECK_INSTANCE_CAST ((obj), XEDIT_TYPE_MESSAGE, XeditMessage))
 | 
			
		||||
#define XEDIT_MESSAGE_CONST(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), XEDIT_TYPE_MESSAGE, XeditMessage const))
 | 
			
		||||
#define XEDIT_MESSAGE_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST ((klass), XEDIT_TYPE_MESSAGE, XeditMessageClass))
 | 
			
		||||
#define XEDIT_IS_MESSAGE(obj)			(G_TYPE_CHECK_INSTANCE_TYPE ((obj), XEDIT_TYPE_MESSAGE))
 | 
			
		||||
#define XEDIT_IS_MESSAGE_CLASS(klass)		(G_TYPE_CHECK_CLASS_TYPE ((klass), XEDIT_TYPE_MESSAGE))
 | 
			
		||||
#define XEDIT_MESSAGE_GET_CLASS(obj)		(G_TYPE_INSTANCE_GET_CLASS ((obj), XEDIT_TYPE_MESSAGE, XeditMessageClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _XeditMessage		XeditMessage;
 | 
			
		||||
typedef struct _XeditMessageClass	XeditMessageClass;
 | 
			
		||||
typedef struct _XeditMessagePrivate	XeditMessagePrivate;
 | 
			
		||||
 | 
			
		||||
struct _XeditMessage {
 | 
			
		||||
	GObject parent;
 | 
			
		||||
	
 | 
			
		||||
	XeditMessagePrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _XeditMessageClass {
 | 
			
		||||
	GObjectClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType xedit_message_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
struct _XeditMessageType xedit_message_get_message_type (XeditMessage *message);
 | 
			
		||||
 | 
			
		||||
void xedit_message_get			(XeditMessage	 *message,
 | 
			
		||||
					 ...) G_GNUC_NULL_TERMINATED;
 | 
			
		||||
void xedit_message_get_valist		(XeditMessage	 *message,
 | 
			
		||||
					 va_list 	  var_args);
 | 
			
		||||
void xedit_message_get_value		(XeditMessage	 *message,
 | 
			
		||||
					 const gchar	 *key,
 | 
			
		||||
					 GValue		 *value);
 | 
			
		||||
 | 
			
		||||
void xedit_message_set			(XeditMessage	 *message,
 | 
			
		||||
					 ...) G_GNUC_NULL_TERMINATED;
 | 
			
		||||
void xedit_message_set_valist		(XeditMessage	 *message,
 | 
			
		||||
					 va_list	  	  var_args);
 | 
			
		||||
void xedit_message_set_value		(XeditMessage	 *message,
 | 
			
		||||
					 const gchar 	 *key,
 | 
			
		||||
					 GValue		 *value);
 | 
			
		||||
void xedit_message_set_valuesv		(XeditMessage	 *message,
 | 
			
		||||
					 const gchar	**keys,
 | 
			
		||||
					 GValue		 *values,
 | 
			
		||||
					 gint		  n_values);
 | 
			
		||||
 | 
			
		||||
const gchar *xedit_message_get_object_path (XeditMessage	*message);
 | 
			
		||||
const gchar *xedit_message_get_method	(XeditMessage	 *message);
 | 
			
		||||
 | 
			
		||||
gboolean xedit_message_has_key		(XeditMessage	 *message,
 | 
			
		||||
					 const gchar     *key);
 | 
			
		||||
 | 
			
		||||
GType xedit_message_get_key_type 	(XeditMessage    *message,
 | 
			
		||||
			    		 const gchar     *key);
 | 
			
		||||
 | 
			
		||||
gboolean xedit_message_validate		(XeditMessage	 *message);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __XEDIT_MESSAGE_H__ */
 | 
			
		||||
 | 
			
		||||
// ex:ts=8:noet:
 | 
			
		||||
							
								
								
									
										563
									
								
								xedit/xedit-metadata-manager.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										563
									
								
								xedit/xedit-metadata-manager.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,563 @@
 | 
			
		||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-metadata-manager.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2003-2007  Paolo Maggi 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA. 
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2003-2007. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <libxml/xmlreader.h>
 | 
			
		||||
#include "xedit-metadata-manager.h"
 | 
			
		||||
#include "xedit-debug.h"
 | 
			
		||||
#include "xedit-dirs.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
#define XEDIT_METADATA_VERBOSE_DEBUG	1
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#define METADATA_FILE 	"xedit-metadata.xml"
 | 
			
		||||
 | 
			
		||||
#define MAX_ITEMS	50
 | 
			
		||||
 | 
			
		||||
typedef struct _XeditMetadataManager XeditMetadataManager;
 | 
			
		||||
 | 
			
		||||
typedef struct _Item Item;
 | 
			
		||||
 | 
			
		||||
struct _Item
 | 
			
		||||
{
 | 
			
		||||
	time_t	 	 atime; /* time of last access */
 | 
			
		||||
 | 
			
		||||
	GHashTable	*values;
 | 
			
		||||
};
 | 
			
		||||
	
 | 
			
		||||
struct _XeditMetadataManager
 | 
			
		||||
{
 | 
			
		||||
	gboolean	 values_loaded; /* It is true if the file 
 | 
			
		||||
					   has been read */
 | 
			
		||||
 | 
			
		||||
	guint 		 timeout_id;
 | 
			
		||||
 | 
			
		||||
	GHashTable	*items;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static gboolean xedit_metadata_manager_save (gpointer data);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static XeditMetadataManager *xedit_metadata_manager = NULL;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
item_free (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
	Item *item;
 | 
			
		||||
	
 | 
			
		||||
	g_return_if_fail (data != NULL);
 | 
			
		||||
 | 
			
		||||
#ifdef XEDIT_METADATA_VERBOSE_DEBUG
 | 
			
		||||
	xedit_debug (DEBUG_METADATA);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	item = (Item *)data;
 | 
			
		||||
 | 
			
		||||
	if (item->values != NULL)
 | 
			
		||||
		g_hash_table_destroy (item->values);
 | 
			
		||||
 | 
			
		||||
	g_free (item);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_metadata_manager_arm_timeout (void)
 | 
			
		||||
{
 | 
			
		||||
	if (xedit_metadata_manager->timeout_id == 0)
 | 
			
		||||
	{
 | 
			
		||||
		xedit_metadata_manager->timeout_id = 
 | 
			
		||||
			g_timeout_add_seconds_full (G_PRIORITY_DEFAULT_IDLE,
 | 
			
		||||
						    2,
 | 
			
		||||
						    (GSourceFunc)xedit_metadata_manager_save,
 | 
			
		||||
						    NULL,
 | 
			
		||||
						    NULL);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
xedit_metadata_manager_init (void)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_METADATA);
 | 
			
		||||
 | 
			
		||||
	if (xedit_metadata_manager != NULL)
 | 
			
		||||
		return TRUE;
 | 
			
		||||
 | 
			
		||||
	xedit_metadata_manager = g_new0 (XeditMetadataManager, 1);
 | 
			
		||||
 | 
			
		||||
	xedit_metadata_manager->values_loaded = FALSE;
 | 
			
		||||
 | 
			
		||||
	xedit_metadata_manager->items = 
 | 
			
		||||
		g_hash_table_new_full (g_str_hash, 
 | 
			
		||||
				       g_str_equal, 
 | 
			
		||||
				       g_free,
 | 
			
		||||
				       item_free);
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This function must be called before exiting xedit */
 | 
			
		||||
void
 | 
			
		||||
xedit_metadata_manager_shutdown (void)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_METADATA);
 | 
			
		||||
 | 
			
		||||
	if (xedit_metadata_manager == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (xedit_metadata_manager->timeout_id)
 | 
			
		||||
	{
 | 
			
		||||
		g_source_remove (xedit_metadata_manager->timeout_id);
 | 
			
		||||
		xedit_metadata_manager->timeout_id = 0;
 | 
			
		||||
		xedit_metadata_manager_save (NULL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (xedit_metadata_manager->items != NULL)
 | 
			
		||||
		g_hash_table_destroy (xedit_metadata_manager->items);
 | 
			
		||||
 | 
			
		||||
	g_free (xedit_metadata_manager);
 | 
			
		||||
	xedit_metadata_manager = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
parseItem (xmlDocPtr doc, xmlNodePtr cur)
 | 
			
		||||
{
 | 
			
		||||
	Item *item;
 | 
			
		||||
	
 | 
			
		||||
	xmlChar *uri;
 | 
			
		||||
	xmlChar *atime;
 | 
			
		||||
	
 | 
			
		||||
#ifdef XEDIT_METADATA_VERBOSE_DEBUG
 | 
			
		||||
	xedit_debug (DEBUG_METADATA);
 | 
			
		||||
#endif	
 | 
			
		||||
 | 
			
		||||
	if (xmlStrcmp (cur->name, (const xmlChar *)"document") != 0)
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
	uri = xmlGetProp (cur, (const xmlChar *)"uri");
 | 
			
		||||
	if (uri == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
	
 | 
			
		||||
	atime = xmlGetProp (cur, (const xmlChar *)"atime");
 | 
			
		||||
	if (atime == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		xmlFree (uri);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	item = g_new0 (Item, 1);
 | 
			
		||||
 | 
			
		||||
	item->atime = g_ascii_strtoull ((char *)atime, NULL, 0);
 | 
			
		||||
 | 
			
		||||
	item->values = g_hash_table_new_full (g_str_hash, 
 | 
			
		||||
					      g_str_equal, 
 | 
			
		||||
					      g_free, 
 | 
			
		||||
					      g_free);
 | 
			
		||||
 | 
			
		||||
	cur = cur->xmlChildrenNode;
 | 
			
		||||
 | 
			
		||||
	while (cur != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		if (xmlStrcmp (cur->name, (const xmlChar *)"entry") == 0)
 | 
			
		||||
		{
 | 
			
		||||
			xmlChar *key;
 | 
			
		||||
			xmlChar *value;
 | 
			
		||||
 | 
			
		||||
			key = xmlGetProp (cur, (const xmlChar *)"key");
 | 
			
		||||
			value = xmlGetProp (cur, (const xmlChar *)"value");
 | 
			
		||||
 | 
			
		||||
			if ((key != NULL) && (value != NULL))
 | 
			
		||||
				g_hash_table_insert (item->values,
 | 
			
		||||
						     g_strdup ((gchar *)key), 
 | 
			
		||||
						     g_strdup ((gchar *)value));
 | 
			
		||||
 | 
			
		||||
			if (key != NULL)
 | 
			
		||||
				xmlFree (key);
 | 
			
		||||
			if (value != NULL)
 | 
			
		||||
				xmlFree (value);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		cur = cur->next;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_hash_table_insert (xedit_metadata_manager->items,
 | 
			
		||||
			     g_strdup ((gchar *)uri),
 | 
			
		||||
			     item);
 | 
			
		||||
 | 
			
		||||
	xmlFree (uri);
 | 
			
		||||
	xmlFree (atime);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gchar *
 | 
			
		||||
get_metadata_filename (void)
 | 
			
		||||
{
 | 
			
		||||
	gchar *cache_dir;
 | 
			
		||||
	gchar *metadata;
 | 
			
		||||
 | 
			
		||||
	cache_dir = xedit_dirs_get_user_cache_dir ();
 | 
			
		||||
 | 
			
		||||
	metadata = g_build_filename (cache_dir,
 | 
			
		||||
				     METADATA_FILE,
 | 
			
		||||
				     NULL);
 | 
			
		||||
 | 
			
		||||
	g_free (cache_dir);
 | 
			
		||||
 | 
			
		||||
	return metadata;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
load_values (void)
 | 
			
		||||
{
 | 
			
		||||
	xmlDocPtr doc;
 | 
			
		||||
	xmlNodePtr cur;
 | 
			
		||||
	gchar *file_name;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_METADATA);
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (xedit_metadata_manager != NULL, FALSE);
 | 
			
		||||
	g_return_val_if_fail (xedit_metadata_manager->values_loaded == FALSE, FALSE);
 | 
			
		||||
 | 
			
		||||
	xedit_metadata_manager->values_loaded = TRUE;
 | 
			
		||||
		
 | 
			
		||||
	xmlKeepBlanksDefault (0);
 | 
			
		||||
 | 
			
		||||
	/* FIXME: file locking - Paolo */
 | 
			
		||||
	file_name = get_metadata_filename ();
 | 
			
		||||
	if ((file_name == NULL) ||
 | 
			
		||||
	    (!g_file_test (file_name, G_FILE_TEST_EXISTS)))
 | 
			
		||||
	{
 | 
			
		||||
		g_free (file_name);
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	doc = xmlParseFile (file_name);
 | 
			
		||||
	g_free (file_name);
 | 
			
		||||
 | 
			
		||||
	if (doc == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cur = xmlDocGetRootElement (doc);
 | 
			
		||||
	if (cur == NULL) 
 | 
			
		||||
	{
 | 
			
		||||
		g_message ("The metadata file '%s' is empty", METADATA_FILE);
 | 
			
		||||
		xmlFreeDoc (doc);
 | 
			
		||||
	
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (xmlStrcmp (cur->name, (const xmlChar *) "metadata")) 
 | 
			
		||||
	{
 | 
			
		||||
		g_message ("File '%s' is of the wrong type", METADATA_FILE);
 | 
			
		||||
		xmlFreeDoc (doc);
 | 
			
		||||
		
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cur = xmlDocGetRootElement (doc);
 | 
			
		||||
	cur = cur->xmlChildrenNode;
 | 
			
		||||
	
 | 
			
		||||
	while (cur != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		parseItem (doc, cur);
 | 
			
		||||
 | 
			
		||||
		cur = cur->next;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	xmlFreeDoc (doc);
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gchar *
 | 
			
		||||
xedit_metadata_manager_get (const gchar *uri,
 | 
			
		||||
			    const gchar *key)
 | 
			
		||||
{
 | 
			
		||||
	Item *item;
 | 
			
		||||
	gchar *value;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (uri != NULL, NULL);
 | 
			
		||||
	g_return_val_if_fail (key != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	xedit_debug_message (DEBUG_METADATA, "URI: %s --- key: %s", uri, key );
 | 
			
		||||
 | 
			
		||||
	xedit_metadata_manager_init ();
 | 
			
		||||
 | 
			
		||||
	if (!xedit_metadata_manager->values_loaded)
 | 
			
		||||
	{
 | 
			
		||||
		gboolean res;
 | 
			
		||||
 | 
			
		||||
		res = load_values ();
 | 
			
		||||
 | 
			
		||||
		if (!res)
 | 
			
		||||
			return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	item = (Item *)g_hash_table_lookup (xedit_metadata_manager->items,
 | 
			
		||||
					    uri);
 | 
			
		||||
 | 
			
		||||
	if (item == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	item->atime = time (NULL);
 | 
			
		||||
	
 | 
			
		||||
	if (item->values == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	value = g_hash_table_lookup (item->values, key);
 | 
			
		||||
 | 
			
		||||
	if (value == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	else
 | 
			
		||||
		return g_strdup (value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_metadata_manager_set (const gchar *uri,
 | 
			
		||||
			    const gchar *key,
 | 
			
		||||
			    const gchar *value)
 | 
			
		||||
{
 | 
			
		||||
	Item *item;
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (uri != NULL);
 | 
			
		||||
	g_return_if_fail (key != NULL);
 | 
			
		||||
 | 
			
		||||
	xedit_debug_message (DEBUG_METADATA, "URI: %s --- key: %s --- value: %s", uri, key, value);
 | 
			
		||||
	
 | 
			
		||||
	xedit_metadata_manager_init ();
 | 
			
		||||
 | 
			
		||||
	if (!xedit_metadata_manager->values_loaded)
 | 
			
		||||
	{
 | 
			
		||||
		gboolean res;
 | 
			
		||||
 | 
			
		||||
		res = load_values ();
 | 
			
		||||
 | 
			
		||||
		if (!res)
 | 
			
		||||
			return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	item = (Item *)g_hash_table_lookup (xedit_metadata_manager->items,
 | 
			
		||||
					    uri);
 | 
			
		||||
 | 
			
		||||
	if (item == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		item = g_new0 (Item, 1);
 | 
			
		||||
 | 
			
		||||
		g_hash_table_insert (xedit_metadata_manager->items,
 | 
			
		||||
				     g_strdup (uri),
 | 
			
		||||
				     item);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if (item->values == NULL)
 | 
			
		||||
		 item->values = g_hash_table_new_full (g_str_hash, 
 | 
			
		||||
				 		       g_str_equal, 
 | 
			
		||||
						       g_free, 
 | 
			
		||||
						       g_free);
 | 
			
		||||
	if (value != NULL)
 | 
			
		||||
		g_hash_table_insert (item->values,
 | 
			
		||||
				     g_strdup (key),
 | 
			
		||||
				     g_strdup (value));
 | 
			
		||||
	else
 | 
			
		||||
		g_hash_table_remove (item->values,
 | 
			
		||||
				     key);
 | 
			
		||||
 | 
			
		||||
	item->atime = time (NULL);
 | 
			
		||||
 | 
			
		||||
	xedit_metadata_manager_arm_timeout ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
save_values (const gchar *key, const gchar *value, xmlNodePtr parent)
 | 
			
		||||
{
 | 
			
		||||
	xmlNodePtr xml_node;
 | 
			
		||||
 | 
			
		||||
#ifdef XEDIT_METADATA_VERBOSE_DEBUG
 | 
			
		||||
	xedit_debug (DEBUG_METADATA);
 | 
			
		||||
#endif	
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (key != NULL);
 | 
			
		||||
	
 | 
			
		||||
	if (value == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
		
 | 
			
		||||
	xml_node = xmlNewChild (parent,
 | 
			
		||||
				NULL,
 | 
			
		||||
				(const xmlChar *)"entry",
 | 
			
		||||
				NULL);
 | 
			
		||||
 | 
			
		||||
	xmlSetProp (xml_node,
 | 
			
		||||
		    (const xmlChar *)"key",
 | 
			
		||||
		    (const xmlChar *)key);
 | 
			
		||||
	xmlSetProp (xml_node,
 | 
			
		||||
		    (const xmlChar *)"value",
 | 
			
		||||
		    (const xmlChar *)value);
 | 
			
		||||
 | 
			
		||||
#ifdef XEDIT_METADATA_VERBOSE_DEBUG
 | 
			
		||||
	xedit_debug_message (DEBUG_METADATA, "entry: %s = %s", key, value);
 | 
			
		||||
#endif	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
save_item (const gchar *key, const gpointer *data, xmlNodePtr parent)
 | 
			
		||||
{
 | 
			
		||||
	xmlNodePtr xml_node;
 | 
			
		||||
	const Item *item = (const Item *)data;
 | 
			
		||||
	gchar *atime;
 | 
			
		||||
 | 
			
		||||
#ifdef XEDIT_METADATA_VERBOSE_DEBUG
 | 
			
		||||
	xedit_debug (DEBUG_METADATA);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (key != NULL);
 | 
			
		||||
 | 
			
		||||
	if (item == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	xml_node = xmlNewChild (parent, NULL, (const xmlChar *)"document", NULL);
 | 
			
		||||
 | 
			
		||||
	xmlSetProp (xml_node, (const xmlChar *)"uri", (const xmlChar *)key);
 | 
			
		||||
 | 
			
		||||
#ifdef XEDIT_METADATA_VERBOSE_DEBUG
 | 
			
		||||
	xedit_debug_message (DEBUG_METADATA, "uri: %s", key);
 | 
			
		||||
#endif	
 | 
			
		||||
 | 
			
		||||
	atime = g_strdup_printf ("%ld", item->atime);
 | 
			
		||||
	xmlSetProp (xml_node, (const xmlChar *)"atime", (const xmlChar *)atime);	
 | 
			
		||||
 | 
			
		||||
#ifdef XEDIT_METADATA_VERBOSE_DEBUG
 | 
			
		||||
	xedit_debug_message (DEBUG_METADATA, "atime: %s", atime);
 | 
			
		||||
#endif	
 | 
			
		||||
 | 
			
		||||
	g_free (atime);
 | 
			
		||||
 | 
			
		||||
    	g_hash_table_foreach (item->values,
 | 
			
		||||
			      (GHFunc)save_values,
 | 
			
		||||
			      xml_node);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
get_oldest (const gchar *key, const gpointer value, const gchar ** key_to_remove)
 | 
			
		||||
{
 | 
			
		||||
	const Item *item = (const Item *)value;
 | 
			
		||||
 | 
			
		||||
	if (*key_to_remove == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		*key_to_remove = key;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		const Item *item_to_remove = 
 | 
			
		||||
			g_hash_table_lookup (xedit_metadata_manager->items,
 | 
			
		||||
					     *key_to_remove);
 | 
			
		||||
 | 
			
		||||
		g_return_if_fail (item_to_remove != NULL);
 | 
			
		||||
 | 
			
		||||
		if (item->atime < item_to_remove->atime)
 | 
			
		||||
		{
 | 
			
		||||
			*key_to_remove = key;
 | 
			
		||||
		}
 | 
			
		||||
	}	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
resize_items (void)
 | 
			
		||||
{
 | 
			
		||||
	while (g_hash_table_size (xedit_metadata_manager->items) > MAX_ITEMS)
 | 
			
		||||
	{
 | 
			
		||||
		gpointer key_to_remove = NULL;
 | 
			
		||||
 | 
			
		||||
		g_hash_table_foreach (xedit_metadata_manager->items,
 | 
			
		||||
				      (GHFunc)get_oldest,
 | 
			
		||||
				      &key_to_remove);
 | 
			
		||||
 | 
			
		||||
		g_return_if_fail (key_to_remove != NULL);
 | 
			
		||||
		
 | 
			
		||||
		g_hash_table_remove (xedit_metadata_manager->items,
 | 
			
		||||
				     key_to_remove);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
xedit_metadata_manager_save (gpointer data)
 | 
			
		||||
{	
 | 
			
		||||
	xmlDocPtr  doc;
 | 
			
		||||
	xmlNodePtr root;
 | 
			
		||||
	gchar *file_name;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_METADATA);
 | 
			
		||||
 | 
			
		||||
	xedit_metadata_manager->timeout_id = 0;
 | 
			
		||||
 | 
			
		||||
	resize_items ();
 | 
			
		||||
		
 | 
			
		||||
	xmlIndentTreeOutput = TRUE;
 | 
			
		||||
 | 
			
		||||
	doc = xmlNewDoc ((const xmlChar *)"1.0");
 | 
			
		||||
	if (doc == NULL)
 | 
			
		||||
		return TRUE;
 | 
			
		||||
 | 
			
		||||
	/* Create metadata root */
 | 
			
		||||
	root = xmlNewDocNode (doc, NULL, (const xmlChar *)"metadata", NULL);
 | 
			
		||||
	xmlDocSetRootElement (doc, root);
 | 
			
		||||
 | 
			
		||||
    	g_hash_table_foreach (xedit_metadata_manager->items,
 | 
			
		||||
			      (GHFunc)save_item,
 | 
			
		||||
			      root);        
 | 
			
		||||
 | 
			
		||||
	/* FIXME: lock file - Paolo */
 | 
			
		||||
	file_name = get_metadata_filename ();
 | 
			
		||||
	if (file_name != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		gchar *cache_dir;
 | 
			
		||||
		int res;
 | 
			
		||||
 | 
			
		||||
		/* make sure the cache dir exists */
 | 
			
		||||
		cache_dir = xedit_dirs_get_user_cache_dir ();
 | 
			
		||||
		res = g_mkdir_with_parents (cache_dir, 0755);
 | 
			
		||||
		if (res != -1)
 | 
			
		||||
		{
 | 
			
		||||
			xmlSaveFormatFile (file_name, doc, 1);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		g_free (cache_dir);
 | 
			
		||||
		g_free (file_name);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	xmlFreeDoc (doc); 
 | 
			
		||||
 | 
			
		||||
	xedit_debug_message (DEBUG_METADATA, "DONE");
 | 
			
		||||
 | 
			
		||||
	return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										50
									
								
								xedit/xedit-metadata-manager.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								xedit/xedit-metadata-manager.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
			
		||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-metadata-manager.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2003  Paolo Maggi 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA. 
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2003. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_METADATA_MANAGER_H__
 | 
			
		||||
#define __XEDIT_METADATA_MANAGER_H__
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* This function must be called before exiting xedit */
 | 
			
		||||
void		 xedit_metadata_manager_shutdown 	(void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
gchar		*xedit_metadata_manager_get 		(const gchar *uri,
 | 
			
		||||
					     		 const gchar *key);
 | 
			
		||||
void		 xedit_metadata_manager_set		(const gchar *uri,
 | 
			
		||||
							 const gchar *key,
 | 
			
		||||
							 const gchar *value);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __XEDIT_METADATA_MANAGER_H__ */
 | 
			
		||||
							
								
								
									
										1092
									
								
								xedit/xedit-notebook.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1092
									
								
								xedit/xedit-notebook.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										143
									
								
								xedit/xedit-notebook.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								xedit/xedit-notebook.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,143 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-notebook.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2005 - Paolo Maggi 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* This file is a modified version of the epiphany file ephy-notebook.h
 | 
			
		||||
 * Here the relevant copyright:
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (C) 2002 Christophe Fergeau
 | 
			
		||||
 *  Copyright (C) 2003 Marco Pesenti Gritti
 | 
			
		||||
 *  Copyright (C) 2003, 2004 Christian Persch
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
#ifndef XEDIT_NOTEBOOK_H
 | 
			
		||||
#define XEDIT_NOTEBOOK_H
 | 
			
		||||
 | 
			
		||||
#include <xedit/xedit-tab.h>
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Type checking and casting macros
 | 
			
		||||
 */
 | 
			
		||||
#define XEDIT_TYPE_NOTEBOOK		(xedit_notebook_get_type ())
 | 
			
		||||
#define XEDIT_NOTEBOOK(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), XEDIT_TYPE_NOTEBOOK, XeditNotebook))
 | 
			
		||||
#define XEDIT_NOTEBOOK_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST((k), XEDIT_TYPE_NOTEBOOK, XeditNotebookClass))
 | 
			
		||||
#define XEDIT_IS_NOTEBOOK(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), XEDIT_TYPE_NOTEBOOK))
 | 
			
		||||
#define XEDIT_IS_NOTEBOOK_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), XEDIT_TYPE_NOTEBOOK))
 | 
			
		||||
#define XEDIT_NOTEBOOK_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), XEDIT_TYPE_NOTEBOOK, XeditNotebookClass))
 | 
			
		||||
 | 
			
		||||
/* Private structure type */
 | 
			
		||||
typedef struct _XeditNotebookPrivate	XeditNotebookPrivate;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Main object structure
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _XeditNotebook		XeditNotebook;
 | 
			
		||||
 
 | 
			
		||||
struct _XeditNotebook
 | 
			
		||||
{
 | 
			
		||||
	GtkNotebook notebook;
 | 
			
		||||
 | 
			
		||||
	/*< private >*/
 | 
			
		||||
        XeditNotebookPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Class definition
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _XeditNotebookClass	XeditNotebookClass;
 | 
			
		||||
 | 
			
		||||
struct _XeditNotebookClass
 | 
			
		||||
{
 | 
			
		||||
        GtkNotebookClass parent_class;
 | 
			
		||||
 | 
			
		||||
	/* Signals */
 | 
			
		||||
	void	 (* tab_added)      (XeditNotebook *notebook,
 | 
			
		||||
				     XeditTab      *tab);
 | 
			
		||||
	void	 (* tab_removed)    (XeditNotebook *notebook,
 | 
			
		||||
				     XeditTab      *tab);
 | 
			
		||||
	void	 (* tab_detached)   (XeditNotebook *notebook,
 | 
			
		||||
				     XeditTab      *tab);
 | 
			
		||||
	void	 (* tabs_reordered) (XeditNotebook *notebook);
 | 
			
		||||
	void	 (* tab_close_request)
 | 
			
		||||
				    (XeditNotebook *notebook,
 | 
			
		||||
				     XeditTab      *tab);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Public methods
 | 
			
		||||
 */
 | 
			
		||||
GType		xedit_notebook_get_type		(void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
GtkWidget      *xedit_notebook_new		(void);
 | 
			
		||||
 | 
			
		||||
void		xedit_notebook_add_tab		(XeditNotebook *nb,
 | 
			
		||||
						 XeditTab      *tab,
 | 
			
		||||
						 gint           position,
 | 
			
		||||
						 gboolean       jump_to);
 | 
			
		||||
 | 
			
		||||
void		xedit_notebook_remove_tab	(XeditNotebook *nb,
 | 
			
		||||
						 XeditTab      *tab);
 | 
			
		||||
 | 
			
		||||
void		xedit_notebook_remove_all_tabs 	(XeditNotebook *nb);
 | 
			
		||||
 | 
			
		||||
void		xedit_notebook_reorder_tab	(XeditNotebook *src,
 | 
			
		||||
			    			 XeditTab      *tab,
 | 
			
		||||
			    			 gint           dest_position);
 | 
			
		||||
			    			 
 | 
			
		||||
void            xedit_notebook_move_tab		(XeditNotebook *src,
 | 
			
		||||
						 XeditNotebook *dest,
 | 
			
		||||
						 XeditTab      *tab,
 | 
			
		||||
						 gint           dest_position);
 | 
			
		||||
 | 
			
		||||
/* FIXME: do we really need this function ? */
 | 
			
		||||
void		xedit_notebook_set_always_show_tabs	
 | 
			
		||||
						(XeditNotebook *nb,
 | 
			
		||||
						 gboolean       show_tabs);
 | 
			
		||||
 | 
			
		||||
void		xedit_notebook_set_close_buttons_sensitive
 | 
			
		||||
						(XeditNotebook *nb,
 | 
			
		||||
						 gboolean       sensitive);
 | 
			
		||||
 | 
			
		||||
gboolean	xedit_notebook_get_close_buttons_sensitive
 | 
			
		||||
						(XeditNotebook *nb);
 | 
			
		||||
 | 
			
		||||
void		xedit_notebook_set_tab_drag_and_drop_enabled
 | 
			
		||||
						(XeditNotebook *nb,
 | 
			
		||||
						 gboolean       enable);
 | 
			
		||||
 | 
			
		||||
gboolean	xedit_notebook_get_tab_drag_and_drop_enabled
 | 
			
		||||
						(XeditNotebook *nb);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* XEDIT_NOTEBOOK_H */
 | 
			
		||||
							
								
								
									
										343
									
								
								xedit/xedit-object-module.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										343
									
								
								xedit/xedit-object-module.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,343 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-object-module.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2005 - Paolo Maggi
 | 
			
		||||
 * Copyright (C) 2008 - Jesse van den Kieboom
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA. 
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/* This is a modified version of ephy-module.c from Epiphany source code.
 | 
			
		||||
 * Here the original copyright assignment:
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (C) 2003 Marco Pesenti Gritti
 | 
			
		||||
 *  Copyright (C) 2003, 2004 Christian Persch
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: xedit-module.c 6314 2008-06-05 12:57:53Z pborelli $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include "xedit-object-module.h"
 | 
			
		||||
#include "xedit-debug.h"
 | 
			
		||||
 | 
			
		||||
typedef GType (*XeditObjectModuleRegisterFunc) (GTypeModule *);
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
	PROP_0,
 | 
			
		||||
	PROP_MODULE_NAME,
 | 
			
		||||
	PROP_PATH,
 | 
			
		||||
	PROP_TYPE_REGISTRATION,
 | 
			
		||||
	PROP_RESIDENT
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _XeditObjectModulePrivate
 | 
			
		||||
{
 | 
			
		||||
	GModule *library;
 | 
			
		||||
 | 
			
		||||
	GType type;
 | 
			
		||||
	gchar *path;
 | 
			
		||||
	gchar *module_name;
 | 
			
		||||
	gchar *type_registration;
 | 
			
		||||
 | 
			
		||||
	gboolean resident;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (XeditObjectModule, xedit_object_module, G_TYPE_TYPE_MODULE);
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
xedit_object_module_load (GTypeModule *gmodule)
 | 
			
		||||
{
 | 
			
		||||
	XeditObjectModule *module = XEDIT_OBJECT_MODULE (gmodule);
 | 
			
		||||
	XeditObjectModuleRegisterFunc register_func;
 | 
			
		||||
	gchar *path;
 | 
			
		||||
 | 
			
		||||
	xedit_debug_message (DEBUG_PLUGINS, "Loading %s module from %s",
 | 
			
		||||
			     module->priv->module_name, module->priv->path);
 | 
			
		||||
 | 
			
		||||
	path = g_module_build_path (module->priv->path, module->priv->module_name);
 | 
			
		||||
	g_return_val_if_fail (path != NULL, FALSE);
 | 
			
		||||
	xedit_debug_message (DEBUG_PLUGINS, "Module filename: %s", path);
 | 
			
		||||
 | 
			
		||||
	module->priv->library = g_module_open (path, 
 | 
			
		||||
					       G_MODULE_BIND_LAZY);
 | 
			
		||||
	g_free (path);
 | 
			
		||||
 | 
			
		||||
	if (module->priv->library == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		g_warning ("%s: %s", module->priv->module_name, g_module_error());
 | 
			
		||||
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* extract symbols from the lib */
 | 
			
		||||
	if (!g_module_symbol (module->priv->library, module->priv->type_registration,
 | 
			
		||||
			      (void *) ®ister_func))
 | 
			
		||||
	{
 | 
			
		||||
		g_warning ("%s: %s", module->priv->module_name, g_module_error());
 | 
			
		||||
		g_module_close (module->priv->library);
 | 
			
		||||
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* symbol can still be NULL even though g_module_symbol
 | 
			
		||||
	 * returned TRUE */
 | 
			
		||||
	if (register_func == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		g_warning ("Symbol '%s' should not be NULL", module->priv->type_registration);
 | 
			
		||||
		g_module_close (module->priv->library);
 | 
			
		||||
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	module->priv->type = register_func (gmodule);
 | 
			
		||||
 | 
			
		||||
	if (module->priv->type == 0)
 | 
			
		||||
	{
 | 
			
		||||
		g_warning ("Invalid object contained by module %s", module->priv->module_name);
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (module->priv->resident)
 | 
			
		||||
	{
 | 
			
		||||
		g_module_make_resident (module->priv->library);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_object_module_unload (GTypeModule *gmodule)
 | 
			
		||||
{
 | 
			
		||||
	XeditObjectModule *module = XEDIT_OBJECT_MODULE (gmodule);
 | 
			
		||||
 | 
			
		||||
	xedit_debug_message (DEBUG_PLUGINS, "Unloading %s", module->priv->path);
 | 
			
		||||
 | 
			
		||||
	g_module_close (module->priv->library);
 | 
			
		||||
 | 
			
		||||
	module->priv->library = NULL;
 | 
			
		||||
	module->priv->type = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_object_module_init (XeditObjectModule *module)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug_message (DEBUG_PLUGINS, "XeditObjectModule %p initialising", module);
 | 
			
		||||
	
 | 
			
		||||
	module->priv = G_TYPE_INSTANCE_GET_PRIVATE (module,
 | 
			
		||||
						    XEDIT_TYPE_OBJECT_MODULE,
 | 
			
		||||
						    XeditObjectModulePrivate);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_object_module_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
	XeditObjectModule *module = XEDIT_OBJECT_MODULE (object);
 | 
			
		||||
 | 
			
		||||
	xedit_debug_message (DEBUG_PLUGINS, "XeditObjectModule %p finalising", module);
 | 
			
		||||
 | 
			
		||||
	g_free (module->priv->path);
 | 
			
		||||
	g_free (module->priv->module_name);
 | 
			
		||||
	g_free (module->priv->type_registration);
 | 
			
		||||
 | 
			
		||||
	G_OBJECT_CLASS (xedit_object_module_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_object_module_get_property (GObject    *object,
 | 
			
		||||
			          guint       prop_id,
 | 
			
		||||
			          GValue     *value,
 | 
			
		||||
			          GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
	XeditObjectModule *module = XEDIT_OBJECT_MODULE (object);
 | 
			
		||||
 | 
			
		||||
	switch (prop_id)
 | 
			
		||||
	{
 | 
			
		||||
		case PROP_MODULE_NAME:
 | 
			
		||||
			g_value_set_string (value, module->priv->module_name);
 | 
			
		||||
			break;
 | 
			
		||||
		case PROP_PATH:
 | 
			
		||||
			g_value_set_string (value, module->priv->path);
 | 
			
		||||
			break;
 | 
			
		||||
		case PROP_TYPE_REGISTRATION:
 | 
			
		||||
			g_value_set_string (value, module->priv->type_registration);
 | 
			
		||||
			break;
 | 
			
		||||
		case PROP_RESIDENT:
 | 
			
		||||
			g_value_set_boolean (value, module->priv->resident);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			g_return_if_reached ();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_object_module_set_property (GObject      *object,
 | 
			
		||||
				  guint         prop_id,
 | 
			
		||||
				  const GValue *value,
 | 
			
		||||
				  GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
	XeditObjectModule *module = XEDIT_OBJECT_MODULE (object);
 | 
			
		||||
 | 
			
		||||
	switch (prop_id)
 | 
			
		||||
	{
 | 
			
		||||
		case PROP_MODULE_NAME:
 | 
			
		||||
			module->priv->module_name = g_value_dup_string (value);
 | 
			
		||||
			g_type_module_set_name (G_TYPE_MODULE (object),
 | 
			
		||||
						module->priv->module_name);
 | 
			
		||||
			break;
 | 
			
		||||
		case PROP_PATH:
 | 
			
		||||
			module->priv->path = g_value_dup_string (value);
 | 
			
		||||
			break;
 | 
			
		||||
		case PROP_TYPE_REGISTRATION:
 | 
			
		||||
			module->priv->type_registration = g_value_dup_string (value);
 | 
			
		||||
			break;
 | 
			
		||||
		case PROP_RESIDENT:
 | 
			
		||||
			module->priv->resident = g_value_get_boolean (value);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			g_return_if_reached ();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_object_module_class_init (XeditObjectModuleClass *klass)
 | 
			
		||||
{
 | 
			
		||||
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
	GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
	object_class->set_property = xedit_object_module_set_property;
 | 
			
		||||
	object_class->get_property = xedit_object_module_get_property;
 | 
			
		||||
	object_class->finalize = xedit_object_module_finalize;
 | 
			
		||||
 | 
			
		||||
	module_class->load = xedit_object_module_load;
 | 
			
		||||
	module_class->unload = xedit_object_module_unload;
 | 
			
		||||
 | 
			
		||||
	g_object_class_install_property (object_class,
 | 
			
		||||
					 PROP_MODULE_NAME,
 | 
			
		||||
					 g_param_spec_string ("module-name",
 | 
			
		||||
							      "Module Name",
 | 
			
		||||
							      "The module to load for this object",
 | 
			
		||||
							      NULL,
 | 
			
		||||
							      G_PARAM_READWRITE |
 | 
			
		||||
							      G_PARAM_CONSTRUCT_ONLY));
 | 
			
		||||
 | 
			
		||||
	g_object_class_install_property (object_class,
 | 
			
		||||
					 PROP_PATH,
 | 
			
		||||
					 g_param_spec_string ("path",
 | 
			
		||||
							      "Path",
 | 
			
		||||
							      "The path to use when loading this module",
 | 
			
		||||
							      NULL,
 | 
			
		||||
							      G_PARAM_READWRITE |
 | 
			
		||||
							      G_PARAM_CONSTRUCT_ONLY));
 | 
			
		||||
							      
 | 
			
		||||
	g_object_class_install_property (object_class,
 | 
			
		||||
					 PROP_TYPE_REGISTRATION,
 | 
			
		||||
					 g_param_spec_string ("type-registration",
 | 
			
		||||
							      "Type Registration",
 | 
			
		||||
							      "The name of the type registration function",
 | 
			
		||||
							      NULL,
 | 
			
		||||
							      G_PARAM_READWRITE |
 | 
			
		||||
							      G_PARAM_CONSTRUCT_ONLY));
 | 
			
		||||
 | 
			
		||||
	g_object_class_install_property (object_class,
 | 
			
		||||
					 PROP_RESIDENT,
 | 
			
		||||
					 g_param_spec_boolean ("resident",
 | 
			
		||||
							       "Resident",
 | 
			
		||||
							       "Whether the module is resident",
 | 
			
		||||
							       FALSE,
 | 
			
		||||
							       G_PARAM_READWRITE |
 | 
			
		||||
							       G_PARAM_CONSTRUCT_ONLY));
 | 
			
		||||
 | 
			
		||||
	g_type_class_add_private (klass, sizeof (XeditObjectModulePrivate));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
XeditObjectModule *
 | 
			
		||||
xedit_object_module_new (const gchar *module_name,
 | 
			
		||||
			 const gchar *path,
 | 
			
		||||
			 const gchar *type_registration,
 | 
			
		||||
			 gboolean     resident)
 | 
			
		||||
{
 | 
			
		||||
	return (XeditObjectModule *)g_object_new (XEDIT_TYPE_OBJECT_MODULE,
 | 
			
		||||
						  "module-name",
 | 
			
		||||
						  module_name,
 | 
			
		||||
						  "path",
 | 
			
		||||
						  path,
 | 
			
		||||
						  "type-registration",
 | 
			
		||||
						  type_registration,
 | 
			
		||||
						  "resident",
 | 
			
		||||
						  resident,
 | 
			
		||||
						  NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GObject *
 | 
			
		||||
xedit_object_module_new_object (XeditObjectModule *module,
 | 
			
		||||
				const gchar       *first_property_name,
 | 
			
		||||
				...)
 | 
			
		||||
{
 | 
			
		||||
	va_list var_args;
 | 
			
		||||
	GObject *result;
 | 
			
		||||
	
 | 
			
		||||
	g_return_val_if_fail (module->priv->type != 0, NULL);
 | 
			
		||||
 | 
			
		||||
	xedit_debug_message (DEBUG_PLUGINS, "Creating object of type %s",
 | 
			
		||||
			     g_type_name (module->priv->type));
 | 
			
		||||
 | 
			
		||||
	va_start (var_args, first_property_name);
 | 
			
		||||
	result = g_object_new_valist (module->priv->type, first_property_name, var_args);
 | 
			
		||||
	va_end (var_args);
 | 
			
		||||
	
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const gchar *
 | 
			
		||||
xedit_object_module_get_path (XeditObjectModule *module)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_OBJECT_MODULE (module), NULL);
 | 
			
		||||
 | 
			
		||||
	return module->priv->path;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const gchar *
 | 
			
		||||
xedit_object_module_get_module_name (XeditObjectModule *module)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_OBJECT_MODULE (module), NULL);
 | 
			
		||||
 | 
			
		||||
	return module->priv->module_name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const gchar *
 | 
			
		||||
xedit_object_module_get_type_registration (XeditObjectModule *module)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_OBJECT_MODULE (module), NULL);
 | 
			
		||||
 | 
			
		||||
	return module->priv->type_registration;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GType
 | 
			
		||||
xedit_object_module_get_object_type (XeditObjectModule *module)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_OBJECT_MODULE (module), 0);
 | 
			
		||||
	
 | 
			
		||||
	return module->priv->type;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										94
									
								
								xedit/xedit-object-module.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								xedit/xedit-object-module.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,94 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-object-module.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2005 - Paolo Maggi
 | 
			
		||||
 * Copyright (C) 2008 - Jesse van den Kieboom
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA. 
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/* This is a modified version of xedit-module.h from Epiphany source code.
 | 
			
		||||
 * Here the original copyright assignment:
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (C) 2003 Marco Pesenti Gritti
 | 
			
		||||
 *  Copyright (C) 2003, 2004 Christian Persch
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: xedit-module.h 6263 2008-05-05 10:52:10Z sfre $
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
#ifndef __XEDIT_OBJECT_MODULE_H__
 | 
			
		||||
#define __XEDIT_OBJECT_MODULE_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <gmodule.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define XEDIT_TYPE_OBJECT_MODULE		(xedit_object_module_get_type ())
 | 
			
		||||
#define XEDIT_OBJECT_MODULE(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), XEDIT_TYPE_OBJECT_MODULE, XeditObjectModule))
 | 
			
		||||
#define XEDIT_OBJECT_MODULE_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), XEDIT_TYPE_OBJECT_MODULE, XeditObjectModuleClass))
 | 
			
		||||
#define XEDIT_IS_OBJECT_MODULE(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), XEDIT_TYPE_OBJECT_MODULE))
 | 
			
		||||
#define XEDIT_IS_OBJECT_MODULE_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), XEDIT_TYPE_OBJECT_MODULE))
 | 
			
		||||
#define XEDIT_OBJECT_MODULE_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), XEDIT_TYPE_OBJECT_MODULE, XeditObjectModuleClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _XeditObjectModule 		XeditObjectModule;
 | 
			
		||||
typedef struct _XeditObjectModulePrivate	XeditObjectModulePrivate;
 | 
			
		||||
 | 
			
		||||
struct _XeditObjectModule
 | 
			
		||||
{
 | 
			
		||||
	GTypeModule parent;
 | 
			
		||||
 | 
			
		||||
	XeditObjectModulePrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct _XeditObjectModuleClass XeditObjectModuleClass;
 | 
			
		||||
 | 
			
		||||
struct _XeditObjectModuleClass
 | 
			
		||||
{
 | 
			
		||||
	GTypeModuleClass parent_class;
 | 
			
		||||
 | 
			
		||||
	/* Virtual class methods */
 | 
			
		||||
	void		 (* garbage_collect)	();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType		 xedit_object_module_get_type			(void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
XeditObjectModule *xedit_object_module_new			(const gchar *module_name,
 | 
			
		||||
								 const gchar *path,
 | 
			
		||||
								 const gchar *type_registration,
 | 
			
		||||
								 gboolean     resident);
 | 
			
		||||
 | 
			
		||||
GObject		*xedit_object_module_new_object			(XeditObjectModule *module, 
 | 
			
		||||
								 const gchar	   *first_property_name,
 | 
			
		||||
								 ...);
 | 
			
		||||
 | 
			
		||||
GType		 xedit_object_module_get_object_type		(XeditObjectModule *module);
 | 
			
		||||
const gchar	*xedit_object_module_get_path			(XeditObjectModule *module);
 | 
			
		||||
const gchar	*xedit_object_module_get_module_name		(XeditObjectModule *module);
 | 
			
		||||
const gchar 	*xedit_object_module_get_type_registration 	(XeditObjectModule *module);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										986
									
								
								xedit/xedit-panel.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										986
									
								
								xedit/xedit-panel.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,986 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-panel.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2005 - Paolo Maggi 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "xedit-panel.h"
 | 
			
		||||
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
#include <gdk/gdk.h>
 | 
			
		||||
#include <gdk/gdkkeysyms.h>
 | 
			
		||||
 | 
			
		||||
#include "xedit-close-button.h"
 | 
			
		||||
#include "xedit-window.h"
 | 
			
		||||
#include "xedit-debug.h"
 | 
			
		||||
 | 
			
		||||
#define PANEL_ITEM_KEY "XeditPanelItemKey"
 | 
			
		||||
 | 
			
		||||
#define XEDIT_PANEL_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), XEDIT_TYPE_PANEL, XeditPanelPrivate))
 | 
			
		||||
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
#define gtk_hbox_new(X,Y) gtk_box_new(GTK_ORIENTATION_HORIZONTAL,Y)
 | 
			
		||||
#define gtk_vbox_new(X,Y) gtk_box_new(GTK_ORIENTATION_VERTICAL,Y)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
struct _XeditPanelPrivate 
 | 
			
		||||
{
 | 
			
		||||
	GtkOrientation orientation;
 | 
			
		||||
	
 | 
			
		||||
	/* Title bar (vertical panel only) */
 | 
			
		||||
	GtkWidget *title_image;
 | 
			
		||||
	GtkWidget *title_label;
 | 
			
		||||
 | 
			
		||||
	/* Notebook */
 | 
			
		||||
	GtkWidget *notebook;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct _XeditPanelItem XeditPanelItem;
 | 
			
		||||
 | 
			
		||||
struct _XeditPanelItem 
 | 
			
		||||
{
 | 
			
		||||
	gchar *name;
 | 
			
		||||
	GtkWidget *icon;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Properties */
 | 
			
		||||
enum {
 | 
			
		||||
	PROP_0,
 | 
			
		||||
	PROP_ORIENTATION
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Signals */
 | 
			
		||||
enum {
 | 
			
		||||
	ITEM_ADDED,
 | 
			
		||||
	ITEM_REMOVED,
 | 
			
		||||
	CLOSE,
 | 
			
		||||
	FOCUS_DOCUMENT,
 | 
			
		||||
	LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0 };
 | 
			
		||||
 | 
			
		||||
static GObject	*xedit_panel_constructor	(GType type,
 | 
			
		||||
						 guint n_construct_properties,
 | 
			
		||||
						 GObjectConstructParam *construct_properties);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
G_DEFINE_TYPE(XeditPanel, xedit_panel, GTK_TYPE_BOX)
 | 
			
		||||
#else
 | 
			
		||||
G_DEFINE_TYPE(XeditPanel, xedit_panel, GTK_TYPE_VBOX)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_panel_finalize (GObject *obj)
 | 
			
		||||
{
 | 
			
		||||
	if (G_OBJECT_CLASS (xedit_panel_parent_class)->finalize)
 | 
			
		||||
		(*G_OBJECT_CLASS (xedit_panel_parent_class)->finalize) (obj);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_panel_get_property (GObject    *object,
 | 
			
		||||
			  guint       prop_id,
 | 
			
		||||
			  GValue     *value,
 | 
			
		||||
			  GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
	XeditPanel *panel = XEDIT_PANEL (object);
 | 
			
		||||
	
 | 
			
		||||
	switch (prop_id)
 | 
			
		||||
	{
 | 
			
		||||
		case PROP_ORIENTATION:
 | 
			
		||||
			g_value_set_enum(value, panel->priv->orientation);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_panel_set_property (GObject      *object,
 | 
			
		||||
			  guint         prop_id,
 | 
			
		||||
			  const GValue *value,
 | 
			
		||||
			  GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
	XeditPanel *panel = XEDIT_PANEL (object);
 | 
			
		||||
 | 
			
		||||
	switch (prop_id)
 | 
			
		||||
	{
 | 
			
		||||
		case PROP_ORIENTATION:
 | 
			
		||||
			panel->priv->orientation = g_value_get_enum (value);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_panel_close (XeditPanel *panel)
 | 
			
		||||
{
 | 
			
		||||
	gtk_widget_hide (GTK_WIDGET (panel));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_panel_focus_document (XeditPanel *panel)
 | 
			
		||||
{
 | 
			
		||||
	GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (panel));
 | 
			
		||||
	if (gtk_widget_is_toplevel (toplevel) && XEDIT_IS_WINDOW (toplevel))
 | 
			
		||||
	{
 | 
			
		||||
		XeditView *view;
 | 
			
		||||
 | 
			
		||||
		view = xedit_window_get_active_view (XEDIT_WINDOW (toplevel));
 | 
			
		||||
		if (view != NULL)
 | 
			
		||||
			gtk_widget_grab_focus (GTK_WIDGET (view));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_panel_grab_focus (GtkWidget *w)
 | 
			
		||||
{
 | 
			
		||||
	gint n;
 | 
			
		||||
	GtkWidget *tab;
 | 
			
		||||
	XeditPanel *panel = XEDIT_PANEL (w);
 | 
			
		||||
 | 
			
		||||
	n = gtk_notebook_get_current_page (GTK_NOTEBOOK (panel->priv->notebook));
 | 
			
		||||
	if (n == -1)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	tab = gtk_notebook_get_nth_page (GTK_NOTEBOOK (panel->priv->notebook),
 | 
			
		||||
					 n);
 | 
			
		||||
	g_return_if_fail (tab != NULL);
 | 
			
		||||
 | 
			
		||||
	gtk_widget_grab_focus (tab);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_panel_class_init (XeditPanelClass *klass)
 | 
			
		||||
{
 | 
			
		||||
	GtkBindingSet *binding_set;
 | 
			
		||||
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
	g_type_class_add_private (klass, sizeof (XeditPanelPrivate));
 | 
			
		||||
 | 
			
		||||
	object_class->constructor = xedit_panel_constructor;
 | 
			
		||||
	object_class->finalize = xedit_panel_finalize;
 | 
			
		||||
	object_class->get_property = xedit_panel_get_property;
 | 
			
		||||
	object_class->set_property = xedit_panel_set_property;
 | 
			
		||||
 | 
			
		||||
	g_object_class_install_property (object_class,
 | 
			
		||||
					 PROP_ORIENTATION,
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
					 g_param_spec_enum ("panel-orientation",
 | 
			
		||||
							    "Panel Orientation",
 | 
			
		||||
#else
 | 
			
		||||
					 g_param_spec_enum ("orientation",
 | 
			
		||||
							    "Orientation",
 | 
			
		||||
#endif
 | 
			
		||||
							    "The panel's orientation",
 | 
			
		||||
							    GTK_TYPE_ORIENTATION,
 | 
			
		||||
							    GTK_ORIENTATION_VERTICAL,
 | 
			
		||||
							    G_PARAM_WRITABLE |
 | 
			
		||||
							    G_PARAM_READABLE |
 | 
			
		||||
							    G_PARAM_CONSTRUCT_ONLY |
 | 
			
		||||
							    G_PARAM_STATIC_STRINGS));
 | 
			
		||||
 | 
			
		||||
	widget_class->grab_focus = xedit_panel_grab_focus;
 | 
			
		||||
 | 
			
		||||
	klass->close = xedit_panel_close;
 | 
			
		||||
	klass->focus_document = xedit_panel_focus_document;
 | 
			
		||||
 | 
			
		||||
	signals[ITEM_ADDED] =
 | 
			
		||||
		g_signal_new ("item_added",
 | 
			
		||||
			      G_OBJECT_CLASS_TYPE (klass),
 | 
			
		||||
			      G_SIGNAL_RUN_FIRST,
 | 
			
		||||
			      G_STRUCT_OFFSET (XeditPanelClass, item_added),
 | 
			
		||||
			      NULL, NULL,
 | 
			
		||||
			      g_cclosure_marshal_VOID__OBJECT,
 | 
			
		||||
			      G_TYPE_NONE,
 | 
			
		||||
			      1,
 | 
			
		||||
			      GTK_TYPE_WIDGET);
 | 
			
		||||
	signals[ITEM_REMOVED] =
 | 
			
		||||
		g_signal_new ("item_removed",
 | 
			
		||||
			      G_OBJECT_CLASS_TYPE (klass),
 | 
			
		||||
			      G_SIGNAL_RUN_FIRST,
 | 
			
		||||
			      G_STRUCT_OFFSET (XeditPanelClass, item_removed),
 | 
			
		||||
			      NULL, NULL,
 | 
			
		||||
			      g_cclosure_marshal_VOID__OBJECT,
 | 
			
		||||
			      G_TYPE_NONE,
 | 
			
		||||
			      1,
 | 
			
		||||
			      GTK_TYPE_WIDGET);
 | 
			
		||||
 | 
			
		||||
	/* Keybinding signals */
 | 
			
		||||
	signals[CLOSE] =
 | 
			
		||||
		g_signal_new ("close",
 | 
			
		||||
			      G_OBJECT_CLASS_TYPE (klass),
 | 
			
		||||
			      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
 | 
			
		||||
			      G_STRUCT_OFFSET (XeditPanelClass, close),
 | 
			
		||||
		  	      NULL, NULL,
 | 
			
		||||
		  	      g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
			      G_TYPE_NONE, 0);
 | 
			
		||||
	signals[FOCUS_DOCUMENT] =
 | 
			
		||||
		g_signal_new ("focus_document",
 | 
			
		||||
			      G_OBJECT_CLASS_TYPE (klass),
 | 
			
		||||
			      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
 | 
			
		||||
			      G_STRUCT_OFFSET (XeditPanelClass, focus_document),
 | 
			
		||||
		  	      NULL, NULL,
 | 
			
		||||
		  	      g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
			      G_TYPE_NONE, 0);					
 | 
			
		||||
	binding_set = gtk_binding_set_by_class (klass);
 | 
			
		||||
 | 
			
		||||
	gtk_binding_entry_add_signal (binding_set,
 | 
			
		||||
				      GDK_KEY_Escape,
 | 
			
		||||
				      0,
 | 
			
		||||
				      "close",
 | 
			
		||||
				      0);
 | 
			
		||||
	gtk_binding_entry_add_signal (binding_set,
 | 
			
		||||
				      GDK_KEY_Return,
 | 
			
		||||
				      GDK_CONTROL_MASK,
 | 
			
		||||
				      "focus_document",
 | 
			
		||||
				      0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This is ugly, since it supports only known
 | 
			
		||||
 * storage types of GtkImage, otherwise fall back
 | 
			
		||||
 * to the empty icon.
 | 
			
		||||
 * See http://bugzilla.gnome.org/show_bug.cgi?id=317520.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
set_gtk_image_from_gtk_image (GtkImage *image,
 | 
			
		||||
			      GtkImage *source)
 | 
			
		||||
{
 | 
			
		||||
	switch (gtk_image_get_storage_type (source))
 | 
			
		||||
	{
 | 
			
		||||
	case GTK_IMAGE_EMPTY:
 | 
			
		||||
		gtk_image_clear (image);
 | 
			
		||||
		break;
 | 
			
		||||
#if !GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
	case GTK_IMAGE_PIXMAP:
 | 
			
		||||
		{
 | 
			
		||||
			GdkPixmap *pm;
 | 
			
		||||
			GdkBitmap *bm;
 | 
			
		||||
 | 
			
		||||
			gtk_image_get_pixmap (source, &pm, &bm);
 | 
			
		||||
			gtk_image_set_from_pixmap (image, pm, bm);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case GTK_IMAGE_IMAGE:
 | 
			
		||||
		{
 | 
			
		||||
			GdkImage *i;
 | 
			
		||||
			GdkBitmap *bm;
 | 
			
		||||
 | 
			
		||||
			gtk_image_get_image (source, &i, &bm);
 | 
			
		||||
			gtk_image_set_from_image (image, i, bm);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
#endif
 | 
			
		||||
	case GTK_IMAGE_PIXBUF:
 | 
			
		||||
		{
 | 
			
		||||
			GdkPixbuf *pb;
 | 
			
		||||
 | 
			
		||||
			pb = gtk_image_get_pixbuf (source);
 | 
			
		||||
			gtk_image_set_from_pixbuf (image, pb);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case GTK_IMAGE_STOCK:
 | 
			
		||||
		{
 | 
			
		||||
			gchar *s_id;
 | 
			
		||||
			GtkIconSize s;
 | 
			
		||||
 | 
			
		||||
			gtk_image_get_stock (source, &s_id, &s);
 | 
			
		||||
			gtk_image_set_from_stock (image, s_id, s);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case GTK_IMAGE_ICON_SET:
 | 
			
		||||
		{
 | 
			
		||||
			GtkIconSet *is;
 | 
			
		||||
			GtkIconSize s;
 | 
			
		||||
 | 
			
		||||
			gtk_image_get_icon_set (source, &is, &s);
 | 
			
		||||
			gtk_image_set_from_icon_set (image, is, s);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case GTK_IMAGE_ANIMATION:
 | 
			
		||||
		{
 | 
			
		||||
			GdkPixbufAnimation *a;
 | 
			
		||||
 | 
			
		||||
			a = gtk_image_get_animation (source);
 | 
			
		||||
			gtk_image_set_from_animation (image, a);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case GTK_IMAGE_ICON_NAME:
 | 
			
		||||
		{
 | 
			
		||||
			const gchar *n;
 | 
			
		||||
			GtkIconSize s;
 | 
			
		||||
 | 
			
		||||
			gtk_image_get_icon_name (source, &n, &s);
 | 
			
		||||
			gtk_image_set_from_icon_name (image, n, s);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		gtk_image_set_from_stock (image,
 | 
			
		||||
					  GTK_STOCK_FILE,
 | 
			
		||||
					  GTK_ICON_SIZE_MENU);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
sync_title (XeditPanel     *panel,
 | 
			
		||||
	    XeditPanelItem *item)
 | 
			
		||||
{
 | 
			
		||||
	if (panel->priv->orientation != GTK_ORIENTATION_VERTICAL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (item != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		gtk_label_set_text (GTK_LABEL (panel->priv->title_label), 
 | 
			
		||||
				    item->name);
 | 
			
		||||
 | 
			
		||||
		set_gtk_image_from_gtk_image (GTK_IMAGE (panel->priv->title_image),
 | 
			
		||||
					      GTK_IMAGE (item->icon));
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		gtk_label_set_text (GTK_LABEL (panel->priv->title_label), 
 | 
			
		||||
				    _("Empty"));
 | 
			
		||||
 | 
			
		||||
		gtk_image_set_from_stock (GTK_IMAGE (panel->priv->title_image),
 | 
			
		||||
					  GTK_STOCK_FILE,
 | 
			
		||||
					  GTK_ICON_SIZE_MENU);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
notebook_page_changed (GtkNotebook     *notebook,
 | 
			
		||||
                       GtkWidget       *page,
 | 
			
		||||
                       guint            page_num,
 | 
			
		||||
                       XeditPanel      *panel)
 | 
			
		||||
{
 | 
			
		||||
	GtkWidget *item;
 | 
			
		||||
	XeditPanelItem *data;
 | 
			
		||||
 | 
			
		||||
	item = gtk_notebook_get_nth_page (notebook, page_num);
 | 
			
		||||
	g_return_if_fail (item != NULL);
 | 
			
		||||
 | 
			
		||||
	data = (XeditPanelItem *)g_object_get_data (G_OBJECT (item),
 | 
			
		||||
						    PANEL_ITEM_KEY);
 | 
			
		||||
	g_return_if_fail (data != NULL);
 | 
			
		||||
 | 
			
		||||
	sync_title (panel, data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
panel_show (XeditPanel *panel,
 | 
			
		||||
	    gpointer    user_data)
 | 
			
		||||
{
 | 
			
		||||
	gint page;
 | 
			
		||||
	GtkNotebook *nb;
 | 
			
		||||
 | 
			
		||||
	nb = GTK_NOTEBOOK (panel->priv->notebook);
 | 
			
		||||
 | 
			
		||||
	page = gtk_notebook_get_current_page (nb);
 | 
			
		||||
 | 
			
		||||
	if (page != -1)
 | 
			
		||||
		notebook_page_changed (nb, NULL, page, panel);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_panel_init (XeditPanel *panel)
 | 
			
		||||
{
 | 
			
		||||
	panel->priv = XEDIT_PANEL_GET_PRIVATE (panel);
 | 
			
		||||
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
	gtk_orientable_set_orientation (GTK_ORIENTABLE (panel),
 | 
			
		||||
									GTK_ORIENTATION_VERTICAL);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
close_button_clicked_cb (GtkWidget *widget,
 | 
			
		||||
			 GtkWidget *panel)
 | 
			
		||||
{
 | 
			
		||||
	gtk_widget_hide (panel);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GtkWidget *
 | 
			
		||||
create_close_button (XeditPanel *panel)
 | 
			
		||||
{
 | 
			
		||||
	GtkWidget *button;
 | 
			
		||||
 | 
			
		||||
	button = xedit_close_button_new ();
 | 
			
		||||
 | 
			
		||||
	gtk_widget_set_tooltip_text (button, _("Hide panel"));
 | 
			
		||||
 | 
			
		||||
	g_signal_connect (button,
 | 
			
		||||
			  "clicked",
 | 
			
		||||
			  G_CALLBACK (close_button_clicked_cb),
 | 
			
		||||
			  panel);
 | 
			
		||||
 | 
			
		||||
	return button;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
build_notebook_for_panel (XeditPanel *panel)
 | 
			
		||||
{
 | 
			
		||||
	/* Create the panel notebook */
 | 
			
		||||
	panel->priv->notebook = gtk_notebook_new ();
 | 
			
		||||
 | 
			
		||||
	gtk_notebook_set_tab_pos (GTK_NOTEBOOK (panel->priv->notebook),
 | 
			
		||||
				  GTK_POS_BOTTOM);
 | 
			
		||||
	gtk_notebook_set_scrollable (GTK_NOTEBOOK (panel->priv->notebook),
 | 
			
		||||
				     TRUE);
 | 
			
		||||
	gtk_notebook_popup_enable (GTK_NOTEBOOK (panel->priv->notebook));
 | 
			
		||||
 | 
			
		||||
	gtk_widget_show (GTK_WIDGET (panel->priv->notebook));
 | 
			
		||||
 | 
			
		||||
	g_signal_connect (panel->priv->notebook,
 | 
			
		||||
			  "switch-page",
 | 
			
		||||
			  G_CALLBACK (notebook_page_changed),
 | 
			
		||||
			  panel);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
build_horizontal_panel (XeditPanel *panel)
 | 
			
		||||
{
 | 
			
		||||
	GtkWidget *box;
 | 
			
		||||
	GtkWidget *sidebar;
 | 
			
		||||
	GtkWidget *close_button;
 | 
			
		||||
 | 
			
		||||
	box = gtk_hbox_new(FALSE, 0);
 | 
			
		||||
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (box), 
 | 
			
		||||
			    panel->priv->notebook, 
 | 
			
		||||
			    TRUE, 
 | 
			
		||||
			    TRUE, 
 | 
			
		||||
			    0);
 | 
			
		||||
 | 
			
		||||
	/* Toolbar, close button and first separator */
 | 
			
		||||
	sidebar = gtk_vbox_new(FALSE, 6);
 | 
			
		||||
	gtk_container_set_border_width (GTK_CONTAINER (sidebar), 4);
 | 
			
		||||
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (box),
 | 
			
		||||
			    sidebar,
 | 
			
		||||
			    FALSE, 
 | 
			
		||||
			    FALSE, 
 | 
			
		||||
			    0);
 | 
			
		||||
 | 
			
		||||
	close_button = create_close_button (panel);
 | 
			
		||||
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (sidebar),
 | 
			
		||||
			    close_button,
 | 
			
		||||
			    FALSE, 
 | 
			
		||||
			    FALSE, 
 | 
			
		||||
			    0);
 | 
			
		||||
 | 
			
		||||
	gtk_widget_show_all (box);
 | 
			
		||||
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (panel),
 | 
			
		||||
			    box,
 | 
			
		||||
			    TRUE,
 | 
			
		||||
			    TRUE,
 | 
			
		||||
			    0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
build_vertical_panel (XeditPanel *panel)
 | 
			
		||||
{
 | 
			
		||||
	GtkWidget *close_button;
 | 
			
		||||
	GtkWidget *title_hbox;
 | 
			
		||||
	GtkWidget *icon_name_hbox;
 | 
			
		||||
	GtkWidget *dummy_label;
 | 
			
		||||
 | 
			
		||||
	/* Create title hbox */
 | 
			
		||||
	title_hbox = gtk_hbox_new (FALSE, 6);
 | 
			
		||||
	gtk_container_set_border_width (GTK_CONTAINER (title_hbox), 5);
 | 
			
		||||
					
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (panel), title_hbox, FALSE, FALSE, 0);
 | 
			
		||||
	
 | 
			
		||||
	icon_name_hbox = gtk_hbox_new (FALSE, 0);
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (title_hbox), 
 | 
			
		||||
			    icon_name_hbox, 
 | 
			
		||||
			    TRUE, 
 | 
			
		||||
			    TRUE, 
 | 
			
		||||
			    0);
 | 
			
		||||
		
 | 
			
		||||
	panel->priv->title_image = 
 | 
			
		||||
				gtk_image_new_from_stock (GTK_STOCK_FILE,
 | 
			
		||||
							  GTK_ICON_SIZE_MENU);
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (icon_name_hbox), 
 | 
			
		||||
			    panel->priv->title_image, 
 | 
			
		||||
			    FALSE, 
 | 
			
		||||
			    TRUE, 
 | 
			
		||||
			    0);
 | 
			
		||||
 | 
			
		||||
	dummy_label = gtk_label_new (" ");
 | 
			
		||||
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (icon_name_hbox), 
 | 
			
		||||
			    dummy_label, 
 | 
			
		||||
			    FALSE, 
 | 
			
		||||
			    FALSE, 
 | 
			
		||||
			    0);	
 | 
			
		||||
 | 
			
		||||
	panel->priv->title_label = gtk_label_new (_("Empty"));
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 16, 0)
 | 
			
		||||
	gtk_label_set_xalign (GTK_LABEL (panel->priv->title_label), 0.0);
 | 
			
		||||
#else
 | 
			
		||||
	gtk_misc_set_alignment (GTK_MISC (panel->priv->title_label), 0, 0.5);
 | 
			
		||||
#endif
 | 
			
		||||
	gtk_label_set_ellipsize(GTK_LABEL (panel->priv->title_label), PANGO_ELLIPSIZE_END);
 | 
			
		||||
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (icon_name_hbox),
 | 
			
		||||
			    panel->priv->title_label,
 | 
			
		||||
			    TRUE,
 | 
			
		||||
			    TRUE,
 | 
			
		||||
			    0);
 | 
			
		||||
 | 
			
		||||
	close_button = create_close_button (panel);
 | 
			
		||||
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (title_hbox),
 | 
			
		||||
			    close_button, 
 | 
			
		||||
			    FALSE, 
 | 
			
		||||
			    FALSE, 
 | 
			
		||||
			    0);
 | 
			
		||||
 | 
			
		||||
	gtk_widget_show_all (title_hbox);
 | 
			
		||||
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (panel),
 | 
			
		||||
			    panel->priv->notebook,
 | 
			
		||||
			    TRUE,
 | 
			
		||||
			    TRUE,
 | 
			
		||||
			    0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GObject *
 | 
			
		||||
xedit_panel_constructor (GType type,
 | 
			
		||||
			 guint n_construct_properties,
 | 
			
		||||
			 GObjectConstructParam *construct_properties)
 | 
			
		||||
{
 | 
			
		||||
	
 | 
			
		||||
	/* Invoke parent constructor. */
 | 
			
		||||
	XeditPanelClass *klass = XEDIT_PANEL_CLASS (g_type_class_peek (XEDIT_TYPE_PANEL));
 | 
			
		||||
	GObjectClass *parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
 | 
			
		||||
	GObject *obj = parent_class->constructor (type,
 | 
			
		||||
						  n_construct_properties,
 | 
			
		||||
						  construct_properties);
 | 
			
		||||
 | 
			
		||||
	/* Build the panel, now that we know the orientation 
 | 
			
		||||
			   (_init has been called previously) */
 | 
			
		||||
	XeditPanel *panel = XEDIT_PANEL (obj);
 | 
			
		||||
 | 
			
		||||
	build_notebook_for_panel (panel);
 | 
			
		||||
  	if (panel->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
 | 
			
		||||
  		build_horizontal_panel (panel);
 | 
			
		||||
	else
 | 
			
		||||
		build_vertical_panel (panel);
 | 
			
		||||
 | 
			
		||||
	g_signal_connect (panel,
 | 
			
		||||
			  "show",
 | 
			
		||||
			  G_CALLBACK (panel_show),
 | 
			
		||||
			  NULL);
 | 
			
		||||
 | 
			
		||||
	return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_panel_new:
 | 
			
		||||
 * @orientation: a #GtkOrientation
 | 
			
		||||
 *
 | 
			
		||||
 * Creates a new #XeditPanel with the given @orientation. You shouldn't create
 | 
			
		||||
 * a new panel use xedit_window_get_side_panel() or xedit_window_get_bottom_panel()
 | 
			
		||||
 * instead.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: a new #XeditPanel object.
 | 
			
		||||
 */
 | 
			
		||||
GtkWidget *
 | 
			
		||||
xedit_panel_new (GtkOrientation orientation)
 | 
			
		||||
{
 | 
			
		||||
	return GTK_WIDGET (g_object_new (XEDIT_TYPE_PANEL, "orientation", orientation, NULL));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GtkWidget *
 | 
			
		||||
build_tab_label (XeditPanel  *panel,
 | 
			
		||||
		 GtkWidget   *item,
 | 
			
		||||
		 const gchar *name,
 | 
			
		||||
		 GtkWidget   *icon)
 | 
			
		||||
{
 | 
			
		||||
	GtkWidget *hbox, *label_hbox, *label_ebox;
 | 
			
		||||
	GtkWidget *label;
 | 
			
		||||
 | 
			
		||||
	/* set hbox spacing and label padding (see below) so that there's an
 | 
			
		||||
	 * equal amount of space around the label */
 | 
			
		||||
	hbox = gtk_hbox_new (FALSE, 4);
 | 
			
		||||
 | 
			
		||||
	label_ebox = gtk_event_box_new ();
 | 
			
		||||
	gtk_event_box_set_visible_window (GTK_EVENT_BOX (label_ebox), FALSE);
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (hbox), label_ebox, TRUE, TRUE, 0);
 | 
			
		||||
 | 
			
		||||
	label_hbox = gtk_hbox_new (FALSE, 4);
 | 
			
		||||
	gtk_container_add (GTK_CONTAINER (label_ebox), label_hbox);
 | 
			
		||||
 | 
			
		||||
	/* setup icon */
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (label_hbox), icon, FALSE, FALSE, 0);
 | 
			
		||||
 | 
			
		||||
	/* setup label */
 | 
			
		||||
        label = gtk_label_new (name);
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 16, 0)
 | 
			
		||||
	gtk_label_set_xalign (GTK_LABEL (label), 0.0);
 | 
			
		||||
#else
 | 
			
		||||
	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
 | 
			
		||||
#endif
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
	gtk_widget_set_margin_left (label, 0);
 | 
			
		||||
	gtk_widget_set_margin_right (label, 0);
 | 
			
		||||
	gtk_widget_set_margin_top (label, 0);
 | 
			
		||||
	gtk_widget_set_margin_bottom (label, 0);
 | 
			
		||||
#else
 | 
			
		||||
	gtk_misc_set_padding (GTK_MISC (label), 0, 0);
 | 
			
		||||
#endif
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (label_hbox), label, TRUE, TRUE, 0);
 | 
			
		||||
 | 
			
		||||
	gtk_widget_set_tooltip_text (label_ebox, name);
 | 
			
		||||
 | 
			
		||||
	gtk_widget_show_all (hbox);
 | 
			
		||||
 | 
			
		||||
	if (panel->priv->orientation == GTK_ORIENTATION_VERTICAL)
 | 
			
		||||
		gtk_widget_hide(label);
 | 
			
		||||
 | 
			
		||||
	g_object_set_data (G_OBJECT (item), "label", label);
 | 
			
		||||
	g_object_set_data (G_OBJECT (item), "hbox", hbox);
 | 
			
		||||
 | 
			
		||||
	return hbox;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_panel_add_item:
 | 
			
		||||
 * @panel: a #XeditPanel
 | 
			
		||||
 * @item: the #GtkWidget to add to the @panel
 | 
			
		||||
 * @name: the name to be shown in the @panel
 | 
			
		||||
 * @image: the image to be shown in the @panel
 | 
			
		||||
 *
 | 
			
		||||
 * Adds a new item to the @panel.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
xedit_panel_add_item (XeditPanel  *panel, 
 | 
			
		||||
		      GtkWidget   *item, 
 | 
			
		||||
		      const gchar *name,
 | 
			
		||||
		      GtkWidget   *image)
 | 
			
		||||
{
 | 
			
		||||
	XeditPanelItem *data;
 | 
			
		||||
	GtkWidget *tab_label;
 | 
			
		||||
	GtkWidget *menu_label;
 | 
			
		||||
	gint w, h;
 | 
			
		||||
	
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_PANEL (panel));
 | 
			
		||||
	g_return_if_fail (GTK_IS_WIDGET (item));
 | 
			
		||||
	g_return_if_fail (name != NULL);
 | 
			
		||||
	g_return_if_fail (image == NULL || GTK_IS_IMAGE (image));
 | 
			
		||||
 | 
			
		||||
	data = g_new (XeditPanelItem, 1);
 | 
			
		||||
 | 
			
		||||
	data->name = g_strdup (name);
 | 
			
		||||
 | 
			
		||||
	if (image == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		/* default to empty */
 | 
			
		||||
		data->icon = gtk_image_new_from_stock (GTK_STOCK_FILE,
 | 
			
		||||
						       GTK_ICON_SIZE_MENU);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		data->icon = image;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
 | 
			
		||||
	gtk_widget_set_size_request (data->icon, w, h);
 | 
			
		||||
	
 | 
			
		||||
	g_object_set_data (G_OBJECT (item),
 | 
			
		||||
		           PANEL_ITEM_KEY,
 | 
			
		||||
		           data);
 | 
			
		||||
 | 
			
		||||
	tab_label = build_tab_label (panel, item, data->name, data->icon);
 | 
			
		||||
 | 
			
		||||
	menu_label = gtk_label_new (name);
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 16, 0)
 | 
			
		||||
	gtk_label_set_xalign (GTK_LABEL (menu_label), 0.0);
 | 
			
		||||
#else
 | 
			
		||||
	gtk_misc_set_alignment (GTK_MISC (menu_label), 0.0, 0.5);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if (!gtk_widget_get_visible (item))
 | 
			
		||||
		gtk_widget_show (item);
 | 
			
		||||
 | 
			
		||||
	gtk_notebook_append_page_menu (GTK_NOTEBOOK (panel->priv->notebook),
 | 
			
		||||
				       item,
 | 
			
		||||
				       tab_label,
 | 
			
		||||
				       menu_label);
 | 
			
		||||
 | 
			
		||||
	g_signal_emit (G_OBJECT (panel), signals[ITEM_ADDED], 0, item);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_panel_add_item_with_stock_icon:
 | 
			
		||||
 * @panel: a #XeditPanel
 | 
			
		||||
 * @item: the #GtkWidget to add to the @panel
 | 
			
		||||
 * @name: the name to be shown in the @panel
 | 
			
		||||
 * @stock_id: a stock id
 | 
			
		||||
 *
 | 
			
		||||
 * Same as xedit_panel_add_item() but using an image from stock.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
xedit_panel_add_item_with_stock_icon (XeditPanel  *panel, 
 | 
			
		||||
				      GtkWidget   *item, 
 | 
			
		||||
				      const gchar *name,
 | 
			
		||||
				      const gchar *stock_id)
 | 
			
		||||
{
 | 
			
		||||
	GtkWidget *icon = NULL;
 | 
			
		||||
 | 
			
		||||
	if (stock_id != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		icon = gtk_image_new_from_stock (stock_id,
 | 
			
		||||
						 GTK_ICON_SIZE_MENU);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	xedit_panel_add_item (panel, item, name, icon);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_panel_remove_item:
 | 
			
		||||
 * @panel: a #XeditPanel
 | 
			
		||||
 * @item: the item to be removed from the panel
 | 
			
		||||
 *
 | 
			
		||||
 * Removes the widget @item from the panel if it is in the @panel and returns
 | 
			
		||||
 * %TRUE if there was not any problem.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: %TRUE if it was well removed.
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_panel_remove_item (XeditPanel *panel,
 | 
			
		||||
			 GtkWidget  *item)
 | 
			
		||||
{
 | 
			
		||||
	XeditPanelItem *data;
 | 
			
		||||
	gint page_num;
 | 
			
		||||
	
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_PANEL (panel), FALSE);
 | 
			
		||||
	g_return_val_if_fail (GTK_IS_WIDGET (item), FALSE);
 | 
			
		||||
 | 
			
		||||
	page_num = gtk_notebook_page_num (GTK_NOTEBOOK (panel->priv->notebook),
 | 
			
		||||
					  item);
 | 
			
		||||
					  
 | 
			
		||||
	if (page_num == -1)
 | 
			
		||||
		return FALSE;
 | 
			
		||||
		
 | 
			
		||||
	data = (XeditPanelItem *)g_object_get_data (G_OBJECT (item),
 | 
			
		||||
					            PANEL_ITEM_KEY);
 | 
			
		||||
	g_return_val_if_fail (data != NULL, FALSE);
 | 
			
		||||
	
 | 
			
		||||
	g_free (data->name);
 | 
			
		||||
	g_free (data);
 | 
			
		||||
 | 
			
		||||
	g_object_set_data (G_OBJECT (item),
 | 
			
		||||
		           PANEL_ITEM_KEY,
 | 
			
		||||
		           NULL);
 | 
			
		||||
 | 
			
		||||
	/* ref the item to keep it alive during signal emission */
 | 
			
		||||
	g_object_ref (G_OBJECT (item));
 | 
			
		||||
 | 
			
		||||
	gtk_notebook_remove_page (GTK_NOTEBOOK (panel->priv->notebook), 
 | 
			
		||||
				  page_num);
 | 
			
		||||
 | 
			
		||||
	/* if we removed all the pages, reset the title */
 | 
			
		||||
	if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (panel->priv->notebook)) == 0)
 | 
			
		||||
		sync_title (panel, NULL);
 | 
			
		||||
 | 
			
		||||
	g_signal_emit (G_OBJECT (panel), signals[ITEM_REMOVED], 0, item);
 | 
			
		||||
 | 
			
		||||
	g_object_unref (G_OBJECT (item));
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_panel_activate_item:
 | 
			
		||||
 * @panel: a #XeditPanel
 | 
			
		||||
 * @item: the item to be activated
 | 
			
		||||
 *
 | 
			
		||||
 * Switches to the page that contains @item.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: %TRUE if it was activated
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_panel_activate_item (XeditPanel *panel,
 | 
			
		||||
			   GtkWidget  *item)
 | 
			
		||||
{
 | 
			
		||||
	gint page_num;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_PANEL (panel), FALSE);
 | 
			
		||||
	g_return_val_if_fail (GTK_IS_WIDGET (item), FALSE);
 | 
			
		||||
 | 
			
		||||
	page_num = gtk_notebook_page_num (GTK_NOTEBOOK (panel->priv->notebook),
 | 
			
		||||
					  item);
 | 
			
		||||
 | 
			
		||||
	if (page_num == -1)
 | 
			
		||||
		return FALSE;
 | 
			
		||||
 | 
			
		||||
	gtk_notebook_set_current_page (GTK_NOTEBOOK (panel->priv->notebook),
 | 
			
		||||
				       page_num);
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_panel_item_is_active:
 | 
			
		||||
 * @panel: a #XeditPanel
 | 
			
		||||
 * @item: a #GtkWidget
 | 
			
		||||
 *
 | 
			
		||||
 * Returns whether @item is the active widget in @panel
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: %TRUE if @item is the active widget
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_panel_item_is_active (XeditPanel *panel,
 | 
			
		||||
			    GtkWidget  *item)
 | 
			
		||||
{
 | 
			
		||||
	gint cur_page;
 | 
			
		||||
	gint page_num;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_PANEL (panel), FALSE);
 | 
			
		||||
	g_return_val_if_fail (GTK_IS_WIDGET (item), FALSE);
 | 
			
		||||
 | 
			
		||||
	page_num = gtk_notebook_page_num (GTK_NOTEBOOK (panel->priv->notebook),
 | 
			
		||||
					  item);
 | 
			
		||||
 | 
			
		||||
	if (page_num == -1)
 | 
			
		||||
		return FALSE;
 | 
			
		||||
 | 
			
		||||
	cur_page = gtk_notebook_get_current_page (
 | 
			
		||||
				GTK_NOTEBOOK (panel->priv->notebook));
 | 
			
		||||
 | 
			
		||||
	return (page_num == cur_page);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_panel_get_orientation:
 | 
			
		||||
 * @panel: a #XeditPanel
 | 
			
		||||
 *
 | 
			
		||||
 * Gets the orientation of the @panel. 
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: the #GtkOrientation of #XeditPanel
 | 
			
		||||
 */
 | 
			
		||||
GtkOrientation
 | 
			
		||||
xedit_panel_get_orientation (XeditPanel *panel)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_PANEL (panel), GTK_ORIENTATION_VERTICAL);
 | 
			
		||||
 | 
			
		||||
	return panel->priv->orientation;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_panel_get_n_items:
 | 
			
		||||
 * @panel: a #XeditPanel
 | 
			
		||||
 *
 | 
			
		||||
 * Gets the number of items in a @panel.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: the number of items contained in #XeditPanel
 | 
			
		||||
 */
 | 
			
		||||
gint
 | 
			
		||||
xedit_panel_get_n_items (XeditPanel *panel)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_PANEL (panel), -1);
 | 
			
		||||
 | 
			
		||||
	return gtk_notebook_get_n_pages (GTK_NOTEBOOK (panel->priv->notebook));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gint
 | 
			
		||||
_xedit_panel_get_active_item_id (XeditPanel *panel)
 | 
			
		||||
{
 | 
			
		||||
	gint cur_page;
 | 
			
		||||
	GtkWidget *item;
 | 
			
		||||
	XeditPanelItem *data;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_PANEL (panel), 0);
 | 
			
		||||
 | 
			
		||||
	cur_page = gtk_notebook_get_current_page (
 | 
			
		||||
				GTK_NOTEBOOK (panel->priv->notebook));
 | 
			
		||||
	if (cur_page == -1)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	item = gtk_notebook_get_nth_page (
 | 
			
		||||
				GTK_NOTEBOOK (panel->priv->notebook),
 | 
			
		||||
				cur_page);
 | 
			
		||||
 | 
			
		||||
	/* FIXME: for now we use as the hash of the name as id.
 | 
			
		||||
	 * However the name is not guaranteed to be unique and
 | 
			
		||||
	 * it is a translated string, so it's subotimal, but should
 | 
			
		||||
	 * be good enough for now since we don't want to add an
 | 
			
		||||
	 * ad hoc id argument.
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	data = (XeditPanelItem *)g_object_get_data (G_OBJECT (item),
 | 
			
		||||
					            PANEL_ITEM_KEY);
 | 
			
		||||
	g_return_val_if_fail (data != NULL, 0);
 | 
			
		||||
 | 
			
		||||
	return g_str_hash (data->name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_panel_set_active_item_by_id (XeditPanel *panel,
 | 
			
		||||
				    gint        id)
 | 
			
		||||
{
 | 
			
		||||
	gint n, i;
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_PANEL (panel));
 | 
			
		||||
 | 
			
		||||
	if (id == 0)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	n = gtk_notebook_get_n_pages (
 | 
			
		||||
				GTK_NOTEBOOK (panel->priv->notebook));
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < n; i++)
 | 
			
		||||
	{
 | 
			
		||||
		GtkWidget *item;
 | 
			
		||||
		XeditPanelItem *data;
 | 
			
		||||
 | 
			
		||||
		item = gtk_notebook_get_nth_page (
 | 
			
		||||
				GTK_NOTEBOOK (panel->priv->notebook), i);
 | 
			
		||||
 | 
			
		||||
		data = (XeditPanelItem *)g_object_get_data (G_OBJECT (item),
 | 
			
		||||
						            PANEL_ITEM_KEY);
 | 
			
		||||
		g_return_if_fail (data != NULL);
 | 
			
		||||
 | 
			
		||||
		if (g_str_hash (data->name) == id)
 | 
			
		||||
		{
 | 
			
		||||
			gtk_notebook_set_current_page (
 | 
			
		||||
				GTK_NOTEBOOK (panel->priv->notebook), i);
 | 
			
		||||
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										138
									
								
								xedit/xedit-panel.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								xedit/xedit-panel.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,138 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-panel.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2005 - Paolo Maggi 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_PANEL_H__
 | 
			
		||||
#define __XEDIT_PANEL_H__
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Type checking and casting macros
 | 
			
		||||
 */
 | 
			
		||||
#define XEDIT_TYPE_PANEL		(xedit_panel_get_type())
 | 
			
		||||
#define XEDIT_PANEL(obj)		(G_TYPE_CHECK_INSTANCE_CAST((obj), XEDIT_TYPE_PANEL, XeditPanel))
 | 
			
		||||
#define XEDIT_PANEL_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST((klass), XEDIT_TYPE_PANEL, XeditPanelClass))
 | 
			
		||||
#define XEDIT_IS_PANEL(obj)		(G_TYPE_CHECK_INSTANCE_TYPE((obj), XEDIT_TYPE_PANEL))
 | 
			
		||||
#define XEDIT_IS_PANEL_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), XEDIT_TYPE_PANEL))
 | 
			
		||||
#define XEDIT_PANEL_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), XEDIT_TYPE_PANEL, XeditPanelClass))
 | 
			
		||||
 | 
			
		||||
/* Private structure type */
 | 
			
		||||
typedef struct _XeditPanelPrivate XeditPanelPrivate;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Main object structure
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _XeditPanel XeditPanel;
 | 
			
		||||
 | 
			
		||||
struct _XeditPanel 
 | 
			
		||||
{
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
	GtkBox vbox;
 | 
			
		||||
#else
 | 
			
		||||
	GtkVBox vbox;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/*< private > */
 | 
			
		||||
	XeditPanelPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Class definition
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _XeditPanelClass XeditPanelClass;
 | 
			
		||||
 | 
			
		||||
struct _XeditPanelClass 
 | 
			
		||||
{
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
	GtkBoxClass parent_class;
 | 
			
		||||
#else
 | 
			
		||||
	GtkVBoxClass parent_class;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	void (* item_added)     (XeditPanel     *panel,
 | 
			
		||||
				 GtkWidget      *item);
 | 
			
		||||
	void (* item_removed)   (XeditPanel     *panel,
 | 
			
		||||
				 GtkWidget      *item);
 | 
			
		||||
 | 
			
		||||
	/* Keybinding signals */
 | 
			
		||||
	void (* close)          (XeditPanel     *panel);
 | 
			
		||||
	void (* focus_document) (XeditPanel     *panel);
 | 
			
		||||
 | 
			
		||||
	/* Padding for future expansion */
 | 
			
		||||
	void (*_xedit_reserved1) (void);
 | 
			
		||||
	void (*_xedit_reserved2) (void);
 | 
			
		||||
	void (*_xedit_reserved3) (void);
 | 
			
		||||
	void (*_xedit_reserved4) (void);	
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Public methods
 | 
			
		||||
 */
 | 
			
		||||
GType 		 xedit_panel_get_type 			(void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
GtkWidget 	*xedit_panel_new 			(GtkOrientation	 orientation);
 | 
			
		||||
 | 
			
		||||
void		 xedit_panel_add_item			(XeditPanel     *panel,
 | 
			
		||||
						      	 GtkWidget      *item,
 | 
			
		||||
						      	 const gchar    *name,
 | 
			
		||||
							 GtkWidget      *image);
 | 
			
		||||
 | 
			
		||||
void		 xedit_panel_add_item_with_stock_icon	(XeditPanel     *panel,
 | 
			
		||||
							 GtkWidget      *item,
 | 
			
		||||
						      	 const gchar    *name,
 | 
			
		||||
						      	 const gchar    *stock_id);
 | 
			
		||||
 | 
			
		||||
gboolean	 xedit_panel_remove_item	(XeditPanel     *panel,
 | 
			
		||||
					  	 GtkWidget      *item);
 | 
			
		||||
 | 
			
		||||
gboolean	 xedit_panel_activate_item 	(XeditPanel     *panel,
 | 
			
		||||
					    	 GtkWidget      *item);
 | 
			
		||||
 | 
			
		||||
gboolean	 xedit_panel_item_is_active 	(XeditPanel     *panel,
 | 
			
		||||
					    	 GtkWidget      *item);
 | 
			
		||||
 | 
			
		||||
GtkOrientation	 xedit_panel_get_orientation	(XeditPanel	*panel);
 | 
			
		||||
 | 
			
		||||
gint		 xedit_panel_get_n_items	(XeditPanel	*panel);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Non exported functions
 | 
			
		||||
 */
 | 
			
		||||
gint		 _xedit_panel_get_active_item_id	(XeditPanel	*panel);
 | 
			
		||||
 | 
			
		||||
void		 _xedit_panel_set_active_item_by_id	(XeditPanel	*panel,
 | 
			
		||||
							 gint		 id);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif  /* __XEDIT_PANEL_H__  */
 | 
			
		||||
							
								
								
									
										68
									
								
								xedit/xedit-plugin-info-priv.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								xedit/xedit-plugin-info-priv.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-plugin-info-priv.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2002-2005 - Paolo Maggi 
 | 
			
		||||
 * Copyright (C) 2007 - Paolo Maggi, Steve Frécinaux
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA. 
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2002-2007. See the AUTHORS file for a
 | 
			
		||||
 * list of people on the xedit Team.
 | 
			
		||||
 * See the ChangeLog files for a list of changes.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_PLUGIN_INFO_PRIV_H__
 | 
			
		||||
#define __XEDIT_PLUGIN_INFO_PRIV_H__
 | 
			
		||||
 | 
			
		||||
#include "xedit-plugin-info.h"
 | 
			
		||||
#include "xedit-plugin.h"
 | 
			
		||||
 | 
			
		||||
struct _XeditPluginInfo
 | 
			
		||||
{
 | 
			
		||||
	gint               refcount;
 | 
			
		||||
 | 
			
		||||
	XeditPlugin       *plugin;
 | 
			
		||||
	gchar             *file;
 | 
			
		||||
 | 
			
		||||
	gchar             *module_name;
 | 
			
		||||
	gchar		  *loader;
 | 
			
		||||
	gchar            **dependencies;
 | 
			
		||||
 | 
			
		||||
	gchar             *name;
 | 
			
		||||
	gchar             *desc;
 | 
			
		||||
	gchar             *icon_name;
 | 
			
		||||
	gchar            **authors;
 | 
			
		||||
	gchar             *copyright;
 | 
			
		||||
	gchar             *website;
 | 
			
		||||
	gchar             *version;
 | 
			
		||||
 | 
			
		||||
	/* A plugin is unavailable if it is not possible to activate it
 | 
			
		||||
	   due to an error loading the plugin module (e.g. for Python plugins
 | 
			
		||||
	   when the interpreter has not been correctly initializated) */
 | 
			
		||||
	gint               available : 1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
XeditPluginInfo		*_xedit_plugin_info_new		(const gchar *file);
 | 
			
		||||
void			 _xedit_plugin_info_ref		(XeditPluginInfo *info);
 | 
			
		||||
void			 _xedit_plugin_info_unref	(XeditPluginInfo *info);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* __XEDIT_PLUGIN_INFO_PRIV_H__ */
 | 
			
		||||
							
								
								
									
										396
									
								
								xedit/xedit-plugin-info.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										396
									
								
								xedit/xedit-plugin-info.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,396 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-plugin-info.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2002-2005 - Paolo Maggi 
 | 
			
		||||
 * Copyright (C) 2007 - Paolo Maggi, Steve Frécinaux
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA. 
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2002-2007. See the AUTHORS file for a
 | 
			
		||||
 * list of people on the xedit Team.
 | 
			
		||||
 * See the ChangeLog files for a list of changes.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
 | 
			
		||||
#include "xedit-plugin-info.h"
 | 
			
		||||
#include "xedit-plugin-info-priv.h"
 | 
			
		||||
#include "xedit-debug.h"
 | 
			
		||||
#include "xedit-plugin.h"
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_plugin_info_ref (XeditPluginInfo *info)
 | 
			
		||||
{
 | 
			
		||||
	g_atomic_int_inc (&info->refcount);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static XeditPluginInfo *
 | 
			
		||||
xedit_plugin_info_copy (XeditPluginInfo *info)
 | 
			
		||||
{
 | 
			
		||||
	_xedit_plugin_info_ref (info);
 | 
			
		||||
	return info;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_xedit_plugin_info_unref (XeditPluginInfo *info)
 | 
			
		||||
{
 | 
			
		||||
	if (!g_atomic_int_dec_and_test (&info->refcount))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (info->plugin != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		xedit_debug_message (DEBUG_PLUGINS, "Unref plugin %s", info->name);
 | 
			
		||||
 | 
			
		||||
		g_object_unref (info->plugin);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_free (info->file);
 | 
			
		||||
	g_free (info->module_name);
 | 
			
		||||
	g_strfreev (info->dependencies);
 | 
			
		||||
	g_free (info->name);
 | 
			
		||||
	g_free (info->desc);
 | 
			
		||||
	g_free (info->icon_name);
 | 
			
		||||
	g_free (info->website);
 | 
			
		||||
	g_free (info->copyright);
 | 
			
		||||
	g_free (info->loader);
 | 
			
		||||
	g_free (info->version);
 | 
			
		||||
	g_strfreev (info->authors);
 | 
			
		||||
 | 
			
		||||
	g_free (info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_plugin_info_get_type:
 | 
			
		||||
 *
 | 
			
		||||
 * Retrieves the #GType object which is associated with the #XeditPluginInfo
 | 
			
		||||
 * class.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the GType associated with #XeditPluginInfo.
 | 
			
		||||
 **/
 | 
			
		||||
GType
 | 
			
		||||
xedit_plugin_info_get_type (void)
 | 
			
		||||
{
 | 
			
		||||
	static GType the_type = 0;
 | 
			
		||||
 | 
			
		||||
	if (G_UNLIKELY (!the_type))
 | 
			
		||||
		the_type = g_boxed_type_register_static (
 | 
			
		||||
					"XeditPluginInfo",
 | 
			
		||||
					(GBoxedCopyFunc) xedit_plugin_info_copy,
 | 
			
		||||
					(GBoxedFreeFunc) _xedit_plugin_info_unref);
 | 
			
		||||
 | 
			
		||||
	return the_type;
 | 
			
		||||
} 
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_plugin_info_new:
 | 
			
		||||
 * @filename: the filename where to read the plugin information
 | 
			
		||||
 *
 | 
			
		||||
 * Creates a new #XeditPluginInfo from a file on the disk.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: a newly created #XeditPluginInfo.
 | 
			
		||||
 */
 | 
			
		||||
XeditPluginInfo *
 | 
			
		||||
_xedit_plugin_info_new (const gchar *file)
 | 
			
		||||
{
 | 
			
		||||
	XeditPluginInfo *info;
 | 
			
		||||
	GKeyFile *plugin_file = NULL;
 | 
			
		||||
	gchar *str;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (file != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	xedit_debug_message (DEBUG_PLUGINS, "Loading plugin: %s", file);
 | 
			
		||||
 | 
			
		||||
	info = g_new0 (XeditPluginInfo, 1);
 | 
			
		||||
	info->refcount = 1;
 | 
			
		||||
	info->file = g_strdup (file);
 | 
			
		||||
 | 
			
		||||
	plugin_file = g_key_file_new ();
 | 
			
		||||
	if (!g_key_file_load_from_file (plugin_file, file, G_KEY_FILE_NONE, NULL))
 | 
			
		||||
	{
 | 
			
		||||
		g_warning ("Bad plugin file: %s", file);
 | 
			
		||||
		goto error;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!g_key_file_has_key (plugin_file,
 | 
			
		||||
			   	 "Xedit Plugin",
 | 
			
		||||
				 "IAge",
 | 
			
		||||
				 NULL))
 | 
			
		||||
	{
 | 
			
		||||
		xedit_debug_message (DEBUG_PLUGINS,
 | 
			
		||||
				     "IAge key does not exist in file: %s", file);
 | 
			
		||||
		goto error;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/* Check IAge=2 */
 | 
			
		||||
	if (g_key_file_get_integer (plugin_file,
 | 
			
		||||
				    "Xedit Plugin",
 | 
			
		||||
				    "IAge",
 | 
			
		||||
				    NULL) != 2)
 | 
			
		||||
	{
 | 
			
		||||
		xedit_debug_message (DEBUG_PLUGINS,
 | 
			
		||||
				     "Wrong IAge in file: %s", file);
 | 
			
		||||
		goto error;
 | 
			
		||||
	}
 | 
			
		||||
				    
 | 
			
		||||
	/* Get module name */
 | 
			
		||||
	str = g_key_file_get_string (plugin_file,
 | 
			
		||||
				     "Xedit Plugin",
 | 
			
		||||
				     "Module",
 | 
			
		||||
				     NULL);
 | 
			
		||||
 | 
			
		||||
	if ((str != NULL) && (*str != '\0'))
 | 
			
		||||
	{
 | 
			
		||||
		info->module_name = str;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		g_warning ("Could not find 'Module' in %s", file);
 | 
			
		||||
		g_free (str);
 | 
			
		||||
		goto error;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Get the dependency list */
 | 
			
		||||
	info->dependencies = g_key_file_get_string_list (plugin_file,
 | 
			
		||||
							 "Xedit Plugin",
 | 
			
		||||
							 "Depends",
 | 
			
		||||
							 NULL,
 | 
			
		||||
							 NULL);
 | 
			
		||||
	if (info->dependencies == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		xedit_debug_message (DEBUG_PLUGINS, "Could not find 'Depends' in %s", file);
 | 
			
		||||
		info->dependencies = g_new0 (gchar *, 1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Get the loader for this plugin */
 | 
			
		||||
	str = g_key_file_get_string (plugin_file,
 | 
			
		||||
				     "Xedit Plugin",
 | 
			
		||||
				     "Loader",
 | 
			
		||||
				     NULL);
 | 
			
		||||
	
 | 
			
		||||
	if ((str != NULL) && (*str != '\0'))
 | 
			
		||||
	{
 | 
			
		||||
		info->loader = str;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		/* default to the C loader */
 | 
			
		||||
		info->loader = g_strdup("c");
 | 
			
		||||
		g_free (str);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Get Name */
 | 
			
		||||
	str = g_key_file_get_locale_string (plugin_file,
 | 
			
		||||
					    "Xedit Plugin",
 | 
			
		||||
					    "Name",
 | 
			
		||||
					    NULL, NULL);
 | 
			
		||||
	if (str)
 | 
			
		||||
		info->name = str;
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		g_warning ("Could not find 'Name' in %s", file);
 | 
			
		||||
		goto error;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Get Description */
 | 
			
		||||
	str = g_key_file_get_locale_string (plugin_file,
 | 
			
		||||
					    "Xedit Plugin",
 | 
			
		||||
					    "Description",
 | 
			
		||||
					    NULL, NULL);
 | 
			
		||||
	if (str)
 | 
			
		||||
		info->desc = str;
 | 
			
		||||
	else
 | 
			
		||||
		xedit_debug_message (DEBUG_PLUGINS, "Could not find 'Description' in %s", file);
 | 
			
		||||
 | 
			
		||||
	/* Get Icon */
 | 
			
		||||
	str = g_key_file_get_locale_string (plugin_file,
 | 
			
		||||
					    "Xedit Plugin",
 | 
			
		||||
					    "Icon",
 | 
			
		||||
					    NULL, NULL);
 | 
			
		||||
	if (str)
 | 
			
		||||
		info->icon_name = str;
 | 
			
		||||
	else
 | 
			
		||||
		xedit_debug_message (DEBUG_PLUGINS, "Could not find 'Icon' in %s, using 'xedit-plugin'", file);
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	/* Get Authors */
 | 
			
		||||
	info->authors = g_key_file_get_string_list (plugin_file,
 | 
			
		||||
						    "Xedit Plugin",
 | 
			
		||||
						    "Authors",
 | 
			
		||||
						    NULL,
 | 
			
		||||
						    NULL);
 | 
			
		||||
	if (info->authors == NULL)
 | 
			
		||||
		xedit_debug_message (DEBUG_PLUGINS, "Could not find 'Authors' in %s", file);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/* Get Copyright */
 | 
			
		||||
	str = g_key_file_get_string (plugin_file,
 | 
			
		||||
				     "Xedit Plugin",
 | 
			
		||||
				     "Copyright",
 | 
			
		||||
				     NULL);
 | 
			
		||||
	if (str)
 | 
			
		||||
		info->copyright = str;
 | 
			
		||||
	else
 | 
			
		||||
		xedit_debug_message (DEBUG_PLUGINS, "Could not find 'Copyright' in %s", file);
 | 
			
		||||
 | 
			
		||||
	/* Get Website */
 | 
			
		||||
	str = g_key_file_get_string (plugin_file,
 | 
			
		||||
				     "Xedit Plugin",
 | 
			
		||||
				     "Website",
 | 
			
		||||
				     NULL);
 | 
			
		||||
	if (str)
 | 
			
		||||
		info->website = str;
 | 
			
		||||
	else
 | 
			
		||||
		xedit_debug_message (DEBUG_PLUGINS, "Could not find 'Website' in %s", file);
 | 
			
		||||
	
 | 
			
		||||
	/* Get Version */
 | 
			
		||||
	str = g_key_file_get_string (plugin_file,
 | 
			
		||||
				     "Xedit Plugin",
 | 
			
		||||
				     "Version",
 | 
			
		||||
				     NULL);
 | 
			
		||||
	if (str)
 | 
			
		||||
		info->version = str;
 | 
			
		||||
	else
 | 
			
		||||
		xedit_debug_message (DEBUG_PLUGINS, "Could not find 'Version' in %s", file);
 | 
			
		||||
	
 | 
			
		||||
	g_key_file_free (plugin_file);
 | 
			
		||||
	
 | 
			
		||||
	/* If we know nothing about the availability of the plugin,
 | 
			
		||||
	   set it as available */
 | 
			
		||||
	info->available = TRUE;
 | 
			
		||||
	
 | 
			
		||||
	return info;
 | 
			
		||||
 | 
			
		||||
error:
 | 
			
		||||
	g_free (info->file);
 | 
			
		||||
	g_free (info->module_name);
 | 
			
		||||
	g_free (info->name);
 | 
			
		||||
	g_free (info->loader);
 | 
			
		||||
	g_free (info);
 | 
			
		||||
	g_key_file_free (plugin_file);
 | 
			
		||||
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_plugin_info_is_active (XeditPluginInfo *info)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (info != NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
	return info->available && info->plugin != NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_plugin_info_is_available (XeditPluginInfo *info)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (info != NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
	return info->available != FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_plugin_info_is_configurable (XeditPluginInfo *info)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug_message (DEBUG_PLUGINS, "Is '%s' configurable?", info->name);
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (info != NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
	if (info->plugin == NULL || !info->available)
 | 
			
		||||
		return FALSE;
 | 
			
		||||
 | 
			
		||||
	return xedit_plugin_is_configurable (info->plugin);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const gchar *
 | 
			
		||||
xedit_plugin_info_get_module_name (XeditPluginInfo *info)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (info != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	return info->module_name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const gchar *
 | 
			
		||||
xedit_plugin_info_get_name (XeditPluginInfo *info)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (info != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	return info->name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const gchar *
 | 
			
		||||
xedit_plugin_info_get_description (XeditPluginInfo *info)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (info != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	return info->desc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const gchar *
 | 
			
		||||
xedit_plugin_info_get_icon_name (XeditPluginInfo *info)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (info != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	/* use the xedit-plugin icon as a default if the plugin does not
 | 
			
		||||
	   have its own */
 | 
			
		||||
	if (info->icon_name != NULL && 
 | 
			
		||||
	    gtk_icon_theme_has_icon (gtk_icon_theme_get_default (),
 | 
			
		||||
				     info->icon_name))
 | 
			
		||||
		return info->icon_name;
 | 
			
		||||
	else
 | 
			
		||||
		return "xedit-plugin";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const gchar **
 | 
			
		||||
xedit_plugin_info_get_authors (XeditPluginInfo *info)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (info != NULL, (const gchar **)NULL);
 | 
			
		||||
 | 
			
		||||
	return (const gchar **) info->authors;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const gchar *
 | 
			
		||||
xedit_plugin_info_get_website (XeditPluginInfo *info)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (info != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	return info->website;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const gchar *
 | 
			
		||||
xedit_plugin_info_get_copyright (XeditPluginInfo *info)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (info != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	return info->copyright;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const gchar *
 | 
			
		||||
xedit_plugin_info_get_version (XeditPluginInfo *info)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (info != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	return info->version;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										63
									
								
								xedit/xedit-plugin-info.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								xedit/xedit-plugin-info.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-plugin-info.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2002-2005 - Paolo Maggi 
 | 
			
		||||
 * Copyright (C) 2007 - Paolo Maggi, Steve Frécinaux
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor,
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2002-2007. See the AUTHORS file for a
 | 
			
		||||
 * list of people on the xedit Team.
 | 
			
		||||
 * See the ChangeLog files for a list of changes.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_PLUGIN_INFO_H__
 | 
			
		||||
#define __XEDIT_PLUGIN_INFO_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define XEDIT_TYPE_PLUGIN_INFO			(xedit_plugin_info_get_type ())
 | 
			
		||||
#define XEDIT_PLUGIN_INFO(obj)			((XeditPluginInfo *) (obj))
 | 
			
		||||
 | 
			
		||||
typedef struct _XeditPluginInfo			XeditPluginInfo;
 | 
			
		||||
 | 
			
		||||
GType		 xedit_plugin_info_get_type		(void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
gboolean 	 xedit_plugin_info_is_active		(XeditPluginInfo *info);
 | 
			
		||||
gboolean 	 xedit_plugin_info_is_available		(XeditPluginInfo *info);
 | 
			
		||||
gboolean	 xedit_plugin_info_is_configurable	(XeditPluginInfo *info);
 | 
			
		||||
 | 
			
		||||
const gchar	*xedit_plugin_info_get_module_name	(XeditPluginInfo *info);
 | 
			
		||||
 | 
			
		||||
const gchar	*xedit_plugin_info_get_name		(XeditPluginInfo *info);
 | 
			
		||||
const gchar	*xedit_plugin_info_get_description	(XeditPluginInfo *info);
 | 
			
		||||
const gchar	*xedit_plugin_info_get_icon_name	(XeditPluginInfo *info);
 | 
			
		||||
const gchar    **xedit_plugin_info_get_authors		(XeditPluginInfo *info);
 | 
			
		||||
const gchar	*xedit_plugin_info_get_website		(XeditPluginInfo *info);
 | 
			
		||||
const gchar	*xedit_plugin_info_get_copyright	(XeditPluginInfo *info);
 | 
			
		||||
const gchar	*xedit_plugin_info_get_version		(XeditPluginInfo *info);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __XEDIT_PLUGIN_INFO_H__ */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										131
									
								
								xedit/xedit-plugin-loader.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								xedit/xedit-plugin-loader.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,131 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-plugin-loader.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2008 - Jesse van den Kieboom
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA. 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "xedit-plugin-loader.h"
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_plugin_loader_base_init (gpointer g_class)
 | 
			
		||||
{
 | 
			
		||||
	static gboolean initialized = FALSE;
 | 
			
		||||
 | 
			
		||||
	if (G_UNLIKELY (!initialized))
 | 
			
		||||
	{
 | 
			
		||||
		/* create interface signals here. */
 | 
			
		||||
		initialized = TRUE;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GType
 | 
			
		||||
xedit_plugin_loader_get_type (void)
 | 
			
		||||
{
 | 
			
		||||
	static GType type = 0;
 | 
			
		||||
 | 
			
		||||
	if (G_UNLIKELY (type == 0))
 | 
			
		||||
	{
 | 
			
		||||
		static const GTypeInfo info =
 | 
			
		||||
		{
 | 
			
		||||
			sizeof (XeditPluginLoaderInterface),
 | 
			
		||||
			xedit_plugin_loader_base_init,   /* base_init */
 | 
			
		||||
			NULL,   /* base_finalize */
 | 
			
		||||
			NULL,   /* class_init */
 | 
			
		||||
			NULL,   /* class_finalize */
 | 
			
		||||
			NULL,   /* class_data */
 | 
			
		||||
			0,
 | 
			
		||||
			0,      /* n_preallocs */
 | 
			
		||||
			NULL    /* instance_init */
 | 
			
		||||
		};
 | 
			
		||||
		
 | 
			
		||||
		type = g_type_register_static (G_TYPE_INTERFACE, "XeditPluginLoader", &info, 0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const gchar *
 | 
			
		||||
xedit_plugin_loader_type_get_id (GType type)
 | 
			
		||||
{
 | 
			
		||||
	GTypeClass *klass;
 | 
			
		||||
	XeditPluginLoaderInterface *iface;
 | 
			
		||||
	
 | 
			
		||||
	klass = g_type_class_ref (type);
 | 
			
		||||
	
 | 
			
		||||
	if (klass == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		g_warning ("Could not get class info for plugin loader");
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	iface = g_type_interface_peek (klass, XEDIT_TYPE_PLUGIN_LOADER);
 | 
			
		||||
	
 | 
			
		||||
	if (iface == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		g_warning ("Could not get plugin loader interface");
 | 
			
		||||
		g_type_class_unref (klass);
 | 
			
		||||
		
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	g_return_val_if_fail (iface->get_id != NULL, NULL);
 | 
			
		||||
	return iface->get_id ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
XeditPlugin *
 | 
			
		||||
xedit_plugin_loader_load (XeditPluginLoader *loader,
 | 
			
		||||
			  XeditPluginInfo   *info,
 | 
			
		||||
			  const gchar       *path)
 | 
			
		||||
{
 | 
			
		||||
	XeditPluginLoaderInterface *iface;
 | 
			
		||||
	
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_PLUGIN_LOADER (loader), NULL);
 | 
			
		||||
	
 | 
			
		||||
	iface = XEDIT_PLUGIN_LOADER_GET_INTERFACE (loader);
 | 
			
		||||
	g_return_val_if_fail (iface->load != NULL, NULL);
 | 
			
		||||
	
 | 
			
		||||
	return iface->load (loader, info, path);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_plugin_loader_unload (XeditPluginLoader *loader,
 | 
			
		||||
			    XeditPluginInfo   *info)
 | 
			
		||||
{
 | 
			
		||||
	XeditPluginLoaderInterface *iface;
 | 
			
		||||
	
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_PLUGIN_LOADER (loader));
 | 
			
		||||
	
 | 
			
		||||
	iface = XEDIT_PLUGIN_LOADER_GET_INTERFACE (loader);
 | 
			
		||||
	g_return_if_fail (iface->unload != NULL);
 | 
			
		||||
	
 | 
			
		||||
	iface->unload (loader, info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_plugin_loader_garbage_collect (XeditPluginLoader *loader)
 | 
			
		||||
{
 | 
			
		||||
	XeditPluginLoaderInterface *iface;
 | 
			
		||||
	
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_PLUGIN_LOADER (loader));
 | 
			
		||||
	
 | 
			
		||||
	iface = XEDIT_PLUGIN_LOADER_GET_INTERFACE (loader);
 | 
			
		||||
	
 | 
			
		||||
	if (iface->garbage_collect != NULL)
 | 
			
		||||
		iface->garbage_collect (loader);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										106
									
								
								xedit/xedit-plugin-loader.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								xedit/xedit-plugin-loader.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,106 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-plugin-loader.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2008 - Jesse van den Kieboom
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA. 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_PLUGIN_LOADER_H__
 | 
			
		||||
#define __XEDIT_PLUGIN_LOADER_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <xedit/xedit-plugin.h>
 | 
			
		||||
#include <xedit/xedit-plugin-info.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define XEDIT_TYPE_PLUGIN_LOADER                (xedit_plugin_loader_get_type ())
 | 
			
		||||
#define XEDIT_PLUGIN_LOADER(obj)                (G_TYPE_CHECK_INSTANCE_CAST ((obj), XEDIT_TYPE_PLUGIN_LOADER, XeditPluginLoader))
 | 
			
		||||
#define XEDIT_IS_PLUGIN_LOADER(obj)             (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XEDIT_TYPE_PLUGIN_LOADER))
 | 
			
		||||
#define XEDIT_PLUGIN_LOADER_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), XEDIT_TYPE_PLUGIN_LOADER, XeditPluginLoaderInterface))
 | 
			
		||||
 | 
			
		||||
typedef struct _XeditPluginLoader XeditPluginLoader; /* dummy object */
 | 
			
		||||
typedef struct _XeditPluginLoaderInterface XeditPluginLoaderInterface;
 | 
			
		||||
 | 
			
		||||
struct _XeditPluginLoaderInterface {
 | 
			
		||||
	GTypeInterface parent;
 | 
			
		||||
 | 
			
		||||
	const gchar *(*get_id)		(void);
 | 
			
		||||
 | 
			
		||||
	XeditPlugin *(*load) 		(XeditPluginLoader 	*loader,
 | 
			
		||||
			     		 XeditPluginInfo	*info,
 | 
			
		||||
			      		 const gchar       	*path);
 | 
			
		||||
 | 
			
		||||
	void 	     (*unload)		(XeditPluginLoader 	*loader,
 | 
			
		||||
					 XeditPluginInfo       	*info);
 | 
			
		||||
 | 
			
		||||
	void         (*garbage_collect) 	(XeditPluginLoader	*loader);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType xedit_plugin_loader_get_type (void);
 | 
			
		||||
 | 
			
		||||
const gchar *xedit_plugin_loader_type_get_id	(GType 			 type);
 | 
			
		||||
XeditPlugin *xedit_plugin_loader_load		(XeditPluginLoader 	*loader,
 | 
			
		||||
						 XeditPluginInfo 	*info,
 | 
			
		||||
						 const gchar		*path);
 | 
			
		||||
void xedit_plugin_loader_unload			(XeditPluginLoader 	*loader,
 | 
			
		||||
						 XeditPluginInfo	*info);
 | 
			
		||||
void xedit_plugin_loader_garbage_collect	(XeditPluginLoader 	*loader);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * XEDIT_PLUGIN_LOADER_IMPLEMENT_INTERFACE(TYPE_IFACE, iface_init):
 | 
			
		||||
 *
 | 
			
		||||
 * Utility macro used to register interfaces for gobject types in plugin loaders.
 | 
			
		||||
 */
 | 
			
		||||
#define XEDIT_PLUGIN_LOADER_IMPLEMENT_INTERFACE(TYPE_IFACE, iface_init)		\
 | 
			
		||||
	const GInterfaceInfo g_implement_interface_info = 			\
 | 
			
		||||
	{ 									\
 | 
			
		||||
		(GInterfaceInitFunc) iface_init,				\
 | 
			
		||||
		NULL, 								\
 | 
			
		||||
		NULL								\
 | 
			
		||||
	};									\
 | 
			
		||||
										\
 | 
			
		||||
	g_type_module_add_interface (type_module,				\
 | 
			
		||||
				     g_define_type_id, 				\
 | 
			
		||||
				     TYPE_IFACE, 				\
 | 
			
		||||
				     &g_implement_interface_info);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * XEDIT_PLUGIN_LOADER_REGISTER_TYPE(PluginLoaderName, plugin_loader_name, PARENT_TYPE, loader_interface_init):
 | 
			
		||||
 *
 | 
			
		||||
 * Utility macro used to register plugin loaders.
 | 
			
		||||
 */
 | 
			
		||||
#define XEDIT_PLUGIN_LOADER_REGISTER_TYPE(PluginLoaderName, plugin_loader_name, PARENT_TYPE, loader_iface_init) 	\
 | 
			
		||||
	G_DEFINE_DYNAMIC_TYPE_EXTENDED (PluginLoaderName,			\
 | 
			
		||||
					plugin_loader_name,			\
 | 
			
		||||
					PARENT_TYPE,			\
 | 
			
		||||
					0,					\
 | 
			
		||||
					XEDIT_PLUGIN_LOADER_IMPLEMENT_INTERFACE(XEDIT_TYPE_PLUGIN_LOADER, loader_iface_init));	\
 | 
			
		||||
										\
 | 
			
		||||
										\
 | 
			
		||||
G_MODULE_EXPORT GType								\
 | 
			
		||||
register_xedit_plugin_loader (GTypeModule *type_module)				\
 | 
			
		||||
{										\
 | 
			
		||||
	plugin_loader_name##_register_type (type_module);			\
 | 
			
		||||
										\
 | 
			
		||||
	return plugin_loader_name##_get_type();					\
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __XEDIT_PLUGIN_LOADER_H__ */
 | 
			
		||||
							
								
								
									
										906
									
								
								xedit/xedit-plugin-manager.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										906
									
								
								xedit/xedit-plugin-manager.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,906 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-plugin-manager.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2002 Paolo Maggi and James Willcox
 | 
			
		||||
 * Copyright (C) 2003-2006 Paolo Maggi
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA. 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 1998-2006. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
 | 
			
		||||
#include "xedit-plugin-manager.h"
 | 
			
		||||
#include "xedit-utils.h"
 | 
			
		||||
#include "xedit-plugins-engine.h"
 | 
			
		||||
#include "xedit-plugin.h"
 | 
			
		||||
#include "xedit-debug.h"
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
	ACTIVE_COLUMN,
 | 
			
		||||
	AVAILABLE_COLUMN,
 | 
			
		||||
	INFO_COLUMN,
 | 
			
		||||
	N_COLUMNS
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define PLUGIN_MANAGER_NAME_TITLE _("Plugin")
 | 
			
		||||
#define PLUGIN_MANAGER_ACTIVE_TITLE _("Enabled")
 | 
			
		||||
 | 
			
		||||
#define XEDIT_PLUGIN_MANAGER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), XEDIT_TYPE_PLUGIN_MANAGER, XeditPluginManagerPrivate))
 | 
			
		||||
 | 
			
		||||
struct _XeditPluginManagerPrivate
 | 
			
		||||
{
 | 
			
		||||
	GtkWidget	*tree;
 | 
			
		||||
 | 
			
		||||
	GtkWidget	*about_button;
 | 
			
		||||
	GtkWidget	*configure_button;
 | 
			
		||||
 | 
			
		||||
	XeditPluginsEngine *engine;
 | 
			
		||||
 | 
			
		||||
	GtkWidget 	*about;
 | 
			
		||||
	
 | 
			
		||||
	GtkWidget	*popup_menu;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
G_DEFINE_TYPE(XeditPluginManager, xedit_plugin_manager, GTK_TYPE_BOX)
 | 
			
		||||
#else
 | 
			
		||||
G_DEFINE_TYPE(XeditPluginManager, xedit_plugin_manager, GTK_TYPE_VBOX)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static XeditPluginInfo *plugin_manager_get_selected_plugin (XeditPluginManager *pm); 
 | 
			
		||||
static void plugin_manager_toggle_active (XeditPluginManager *pm, GtkTreeIter *iter, GtkTreeModel *model);
 | 
			
		||||
static void xedit_plugin_manager_finalize (GObject *object);
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
xedit_plugin_manager_class_init (XeditPluginManagerClass *klass)
 | 
			
		||||
{
 | 
			
		||||
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
	object_class->finalize = xedit_plugin_manager_finalize;
 | 
			
		||||
 | 
			
		||||
	g_type_class_add_private (object_class, sizeof (XeditPluginManagerPrivate));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
about_button_cb (GtkWidget          *button,
 | 
			
		||||
		 XeditPluginManager *pm)
 | 
			
		||||
{
 | 
			
		||||
	XeditPluginInfo *info;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_PLUGINS);
 | 
			
		||||
 | 
			
		||||
	info = plugin_manager_get_selected_plugin (pm);
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (info != NULL);
 | 
			
		||||
 | 
			
		||||
	/* if there is another about dialog already open destroy it */
 | 
			
		||||
	if (pm->priv->about)
 | 
			
		||||
		gtk_widget_destroy (pm->priv->about);
 | 
			
		||||
 | 
			
		||||
	pm->priv->about = g_object_new (GTK_TYPE_ABOUT_DIALOG,
 | 
			
		||||
		"program-name", xedit_plugin_info_get_name (info),
 | 
			
		||||
		"copyright", xedit_plugin_info_get_copyright (info),
 | 
			
		||||
		"authors", xedit_plugin_info_get_authors (info),
 | 
			
		||||
		"comments", xedit_plugin_info_get_description (info),
 | 
			
		||||
		"website", xedit_plugin_info_get_website (info),
 | 
			
		||||
		"logo-icon-name", xedit_plugin_info_get_icon_name (info),
 | 
			
		||||
		"version", xedit_plugin_info_get_version (info),
 | 
			
		||||
		NULL);
 | 
			
		||||
 | 
			
		||||
	gtk_window_set_destroy_with_parent (GTK_WINDOW (pm->priv->about),
 | 
			
		||||
					    TRUE);
 | 
			
		||||
 | 
			
		||||
	g_signal_connect (pm->priv->about,
 | 
			
		||||
			  "response",
 | 
			
		||||
			  G_CALLBACK (gtk_widget_destroy),
 | 
			
		||||
			  NULL);
 | 
			
		||||
	g_signal_connect (pm->priv->about,
 | 
			
		||||
			  "destroy",
 | 
			
		||||
			  G_CALLBACK (gtk_widget_destroyed),
 | 
			
		||||
			  &pm->priv->about);
 | 
			
		||||
 | 
			
		||||
	gtk_window_set_transient_for (GTK_WINDOW (pm->priv->about),
 | 
			
		||||
				      GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET(pm))));
 | 
			
		||||
	gtk_widget_show (pm->priv->about);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
configure_button_cb (GtkWidget          *button,
 | 
			
		||||
		     XeditPluginManager *pm)
 | 
			
		||||
{
 | 
			
		||||
	XeditPluginInfo *info;
 | 
			
		||||
	GtkWindow *toplevel;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_PLUGINS);
 | 
			
		||||
 | 
			
		||||
	info = plugin_manager_get_selected_plugin (pm);
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (info != NULL);
 | 
			
		||||
 | 
			
		||||
	xedit_debug_message (DEBUG_PLUGINS, "Configuring: %s\n", 
 | 
			
		||||
			     xedit_plugin_info_get_name (info));
 | 
			
		||||
 | 
			
		||||
	toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET(pm)));
 | 
			
		||||
 | 
			
		||||
	xedit_plugins_engine_configure_plugin (pm->priv->engine,
 | 
			
		||||
					       info, toplevel);
 | 
			
		||||
 | 
			
		||||
	xedit_debug_message (DEBUG_PLUGINS, "Done");	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
plugin_manager_view_info_cell_cb (GtkTreeViewColumn *tree_column,
 | 
			
		||||
				  GtkCellRenderer   *cell,
 | 
			
		||||
				  GtkTreeModel      *tree_model,
 | 
			
		||||
				  GtkTreeIter       *iter,
 | 
			
		||||
				  gpointer           data)
 | 
			
		||||
{
 | 
			
		||||
	XeditPluginInfo *info;
 | 
			
		||||
	gchar *text;
 | 
			
		||||
	
 | 
			
		||||
	g_return_if_fail (tree_model != NULL);
 | 
			
		||||
	g_return_if_fail (tree_column != NULL);
 | 
			
		||||
 | 
			
		||||
	gtk_tree_model_get (tree_model, iter, INFO_COLUMN, &info, -1);
 | 
			
		||||
 | 
			
		||||
	if (info == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	text = g_markup_printf_escaped ("<b>%s</b>\n%s",
 | 
			
		||||
					xedit_plugin_info_get_name (info),
 | 
			
		||||
					xedit_plugin_info_get_description (info));
 | 
			
		||||
	g_object_set (G_OBJECT (cell),
 | 
			
		||||
		      "markup", text,
 | 
			
		||||
		      "sensitive", xedit_plugin_info_is_available (info),
 | 
			
		||||
		      NULL);
 | 
			
		||||
 | 
			
		||||
	g_free (text);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
plugin_manager_view_icon_cell_cb (GtkTreeViewColumn *tree_column,
 | 
			
		||||
				  GtkCellRenderer   *cell,
 | 
			
		||||
				  GtkTreeModel      *tree_model,
 | 
			
		||||
				  GtkTreeIter       *iter,
 | 
			
		||||
				  gpointer           data)
 | 
			
		||||
{
 | 
			
		||||
	XeditPluginInfo *info;
 | 
			
		||||
	
 | 
			
		||||
	g_return_if_fail (tree_model != NULL);
 | 
			
		||||
	g_return_if_fail (tree_column != NULL);
 | 
			
		||||
 | 
			
		||||
	gtk_tree_model_get (tree_model, iter, INFO_COLUMN, &info, -1);
 | 
			
		||||
 | 
			
		||||
	if (info == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	g_object_set (G_OBJECT (cell),
 | 
			
		||||
		      "icon-name", xedit_plugin_info_get_icon_name (info),
 | 
			
		||||
		      "sensitive", xedit_plugin_info_is_available (info),
 | 
			
		||||
		      NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
active_toggled_cb (GtkCellRendererToggle *cell,
 | 
			
		||||
		   gchar                 *path_str,
 | 
			
		||||
		   XeditPluginManager    *pm)
 | 
			
		||||
{
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
	GtkTreePath *path;
 | 
			
		||||
	GtkTreeModel *model;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_PLUGINS);
 | 
			
		||||
 | 
			
		||||
	path = gtk_tree_path_new_from_string (path_str);
 | 
			
		||||
 | 
			
		||||
	model = gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree));
 | 
			
		||||
	g_return_if_fail (model != NULL);
 | 
			
		||||
 | 
			
		||||
	gtk_tree_model_get_iter (model, &iter, path);
 | 
			
		||||
 | 
			
		||||
	if (&iter != NULL)
 | 
			
		||||
		plugin_manager_toggle_active (pm, &iter, model);
 | 
			
		||||
 | 
			
		||||
	gtk_tree_path_free (path);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
cursor_changed_cb (GtkTreeView *view,
 | 
			
		||||
		   gpointer     data)
 | 
			
		||||
{
 | 
			
		||||
	XeditPluginManager *pm = data;
 | 
			
		||||
	XeditPluginInfo *info;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_PLUGINS);
 | 
			
		||||
 | 
			
		||||
	info = plugin_manager_get_selected_plugin (pm);
 | 
			
		||||
 | 
			
		||||
	gtk_widget_set_sensitive (GTK_WIDGET (pm->priv->about_button),
 | 
			
		||||
				  info != NULL);
 | 
			
		||||
	gtk_widget_set_sensitive (GTK_WIDGET (pm->priv->configure_button),
 | 
			
		||||
				  (info != NULL) && 
 | 
			
		||||
				   xedit_plugin_info_is_configurable (info));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
row_activated_cb (GtkTreeView       *tree_view,
 | 
			
		||||
		  GtkTreePath       *path,
 | 
			
		||||
		  GtkTreeViewColumn *column,
 | 
			
		||||
		  gpointer           data)
 | 
			
		||||
{
 | 
			
		||||
	XeditPluginManager *pm = data;
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
	GtkTreeModel *model;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_PLUGINS);
 | 
			
		||||
 | 
			
		||||
	model = gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree));
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (model != NULL);
 | 
			
		||||
 | 
			
		||||
	gtk_tree_model_get_iter (model, &iter, path);
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (&iter != NULL);
 | 
			
		||||
 | 
			
		||||
	plugin_manager_toggle_active (pm, &iter, model);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
plugin_manager_populate_lists (XeditPluginManager *pm)
 | 
			
		||||
{
 | 
			
		||||
	const GList *plugins;
 | 
			
		||||
	GtkListStore *model;
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_PLUGINS);
 | 
			
		||||
 | 
			
		||||
	plugins = xedit_plugins_engine_get_plugin_list (pm->priv->engine);
 | 
			
		||||
 | 
			
		||||
	model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree)));
 | 
			
		||||
 | 
			
		||||
	while (plugins)
 | 
			
		||||
	{
 | 
			
		||||
		XeditPluginInfo *info;
 | 
			
		||||
		info = (XeditPluginInfo *)plugins->data;
 | 
			
		||||
 | 
			
		||||
		gtk_list_store_append (model, &iter);
 | 
			
		||||
		gtk_list_store_set (model, &iter,
 | 
			
		||||
				    ACTIVE_COLUMN, xedit_plugin_info_is_active (info),
 | 
			
		||||
				    AVAILABLE_COLUMN, xedit_plugin_info_is_available (info),
 | 
			
		||||
				    INFO_COLUMN, info,
 | 
			
		||||
				    -1);
 | 
			
		||||
 | 
			
		||||
		plugins = plugins->next;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter))
 | 
			
		||||
	{
 | 
			
		||||
		GtkTreeSelection *selection;
 | 
			
		||||
		XeditPluginInfo* info;
 | 
			
		||||
 | 
			
		||||
		selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (pm->priv->tree));
 | 
			
		||||
		g_return_if_fail (selection != NULL);
 | 
			
		||||
		
 | 
			
		||||
		gtk_tree_selection_select_iter (selection, &iter);
 | 
			
		||||
 | 
			
		||||
		gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
 | 
			
		||||
				    INFO_COLUMN, &info, -1);
 | 
			
		||||
 | 
			
		||||
		gtk_widget_set_sensitive (GTK_WIDGET (pm->priv->configure_button),
 | 
			
		||||
					  xedit_plugin_info_is_configurable (info));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
plugin_manager_set_active (XeditPluginManager *pm,
 | 
			
		||||
			   GtkTreeIter        *iter,
 | 
			
		||||
			   GtkTreeModel       *model,
 | 
			
		||||
			   gboolean            active)
 | 
			
		||||
{
 | 
			
		||||
	XeditPluginInfo *info;
 | 
			
		||||
	gboolean res = TRUE;
 | 
			
		||||
	
 | 
			
		||||
	xedit_debug (DEBUG_PLUGINS);
 | 
			
		||||
 | 
			
		||||
	gtk_tree_model_get (model, iter, INFO_COLUMN, &info, -1);
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (info != NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
	if (active)
 | 
			
		||||
	{
 | 
			
		||||
		/* activate the plugin */
 | 
			
		||||
		if (!xedit_plugins_engine_activate_plugin (pm->priv->engine, info)) {
 | 
			
		||||
			xedit_debug_message (DEBUG_PLUGINS, "Could not activate %s.\n", 
 | 
			
		||||
					     xedit_plugin_info_get_name (info));
 | 
			
		||||
 | 
			
		||||
			res = FALSE;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		/* deactivate the plugin */
 | 
			
		||||
		if (!xedit_plugins_engine_deactivate_plugin (pm->priv->engine, info)) {
 | 
			
		||||
			xedit_debug_message (DEBUG_PLUGINS, "Could not deactivate %s.\n", 
 | 
			
		||||
					     xedit_plugin_info_get_name (info));
 | 
			
		||||
 | 
			
		||||
			res = FALSE;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
plugin_manager_toggle_active (XeditPluginManager *pm,
 | 
			
		||||
			      GtkTreeIter        *iter,
 | 
			
		||||
			      GtkTreeModel       *model)
 | 
			
		||||
{
 | 
			
		||||
	gboolean active;
 | 
			
		||||
	
 | 
			
		||||
	xedit_debug (DEBUG_PLUGINS);
 | 
			
		||||
 | 
			
		||||
	gtk_tree_model_get (model, iter, ACTIVE_COLUMN, &active, -1);
 | 
			
		||||
 | 
			
		||||
	active ^= 1;
 | 
			
		||||
 | 
			
		||||
	plugin_manager_set_active (pm, iter, model, active);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static XeditPluginInfo *
 | 
			
		||||
plugin_manager_get_selected_plugin (XeditPluginManager *pm)
 | 
			
		||||
{
 | 
			
		||||
	XeditPluginInfo *info = NULL;
 | 
			
		||||
	GtkTreeModel *model;
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
	GtkTreeSelection *selection;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_PLUGINS);
 | 
			
		||||
 | 
			
		||||
	model = gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree));
 | 
			
		||||
	g_return_val_if_fail (model != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (pm->priv->tree));
 | 
			
		||||
	g_return_val_if_fail (selection != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	if (gtk_tree_selection_get_selected (selection, NULL, &iter))
 | 
			
		||||
	{
 | 
			
		||||
		gtk_tree_model_get (model, &iter, INFO_COLUMN, &info, -1);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return info;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
plugin_manager_set_active_all (XeditPluginManager *pm,
 | 
			
		||||
			       gboolean            active)
 | 
			
		||||
{
 | 
			
		||||
	GtkTreeModel *model;
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_PLUGINS);
 | 
			
		||||
 | 
			
		||||
	model = gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree));
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (model != NULL);
 | 
			
		||||
 | 
			
		||||
	gtk_tree_model_get_iter_first (model, &iter);
 | 
			
		||||
 | 
			
		||||
	do {
 | 
			
		||||
		plugin_manager_set_active (pm, &iter, model, active);
 | 
			
		||||
	}
 | 
			
		||||
	while (gtk_tree_model_iter_next (model, &iter));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Callback used as the interactive search comparison function */
 | 
			
		||||
static gboolean
 | 
			
		||||
name_search_cb (GtkTreeModel *model,
 | 
			
		||||
		gint          column,
 | 
			
		||||
		const gchar  *key,
 | 
			
		||||
		GtkTreeIter  *iter,
 | 
			
		||||
		gpointer      data)
 | 
			
		||||
{
 | 
			
		||||
	XeditPluginInfo *info;
 | 
			
		||||
	gchar *normalized_string;
 | 
			
		||||
	gchar *normalized_key;
 | 
			
		||||
	gchar *case_normalized_string;
 | 
			
		||||
	gchar *case_normalized_key;
 | 
			
		||||
	gint key_len;
 | 
			
		||||
	gboolean retval;
 | 
			
		||||
 | 
			
		||||
	gtk_tree_model_get (model, iter, INFO_COLUMN, &info, -1);
 | 
			
		||||
	if (!info)
 | 
			
		||||
		return FALSE;
 | 
			
		||||
 | 
			
		||||
	normalized_string = g_utf8_normalize (xedit_plugin_info_get_name (info), -1, G_NORMALIZE_ALL);
 | 
			
		||||
	normalized_key = g_utf8_normalize (key, -1, G_NORMALIZE_ALL);
 | 
			
		||||
	case_normalized_string = g_utf8_casefold (normalized_string, -1);
 | 
			
		||||
	case_normalized_key = g_utf8_casefold (normalized_key, -1);
 | 
			
		||||
 | 
			
		||||
	key_len = strlen (case_normalized_key);
 | 
			
		||||
 | 
			
		||||
	/* Oddly enough, this callback must return whether to stop the search
 | 
			
		||||
	 * because we found a match, not whether we actually matched.
 | 
			
		||||
	 */
 | 
			
		||||
	retval = (strncmp (case_normalized_key, case_normalized_string, key_len) != 0);
 | 
			
		||||
 | 
			
		||||
	g_free (normalized_key);
 | 
			
		||||
	g_free (normalized_string);
 | 
			
		||||
	g_free (case_normalized_key);
 | 
			
		||||
	g_free (case_normalized_string);
 | 
			
		||||
 | 
			
		||||
	return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
enable_plugin_menu_cb (GtkMenu            *menu,
 | 
			
		||||
		       XeditPluginManager *pm)
 | 
			
		||||
{
 | 
			
		||||
	GtkTreeModel *model;
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
	GtkTreeSelection *selection;
 | 
			
		||||
 | 
			
		||||
	model = gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree));
 | 
			
		||||
	g_return_if_fail (model != NULL);
 | 
			
		||||
 | 
			
		||||
	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (pm->priv->tree));
 | 
			
		||||
	g_return_if_fail (selection != NULL);
 | 
			
		||||
 | 
			
		||||
	if (gtk_tree_selection_get_selected (selection, NULL, &iter))
 | 
			
		||||
		plugin_manager_toggle_active (pm, &iter, model);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
enable_all_menu_cb (GtkMenu            *menu,
 | 
			
		||||
		    XeditPluginManager *pm)
 | 
			
		||||
{
 | 
			
		||||
	plugin_manager_set_active_all (pm, TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
disable_all_menu_cb (GtkMenu            *menu,
 | 
			
		||||
		     XeditPluginManager *pm)
 | 
			
		||||
{
 | 
			
		||||
	plugin_manager_set_active_all (pm, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GtkWidget *
 | 
			
		||||
create_tree_popup_menu (XeditPluginManager *pm)
 | 
			
		||||
{
 | 
			
		||||
	GtkWidget *menu;
 | 
			
		||||
	GtkWidget *item;
 | 
			
		||||
	GtkWidget *image;
 | 
			
		||||
	XeditPluginInfo *info;
 | 
			
		||||
 | 
			
		||||
	info = plugin_manager_get_selected_plugin (pm);
 | 
			
		||||
 | 
			
		||||
	menu = gtk_menu_new ();
 | 
			
		||||
 | 
			
		||||
	item = gtk_image_menu_item_new_with_mnemonic (_("_About"));
 | 
			
		||||
	image = gtk_image_new_from_stock (GTK_STOCK_ABOUT,
 | 
			
		||||
					  GTK_ICON_SIZE_MENU);
 | 
			
		||||
	gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
 | 
			
		||||
	g_signal_connect (item, "activate",
 | 
			
		||||
			  G_CALLBACK (about_button_cb), pm);
 | 
			
		||||
	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
 | 
			
		||||
 | 
			
		||||
	item = gtk_image_menu_item_new_with_mnemonic (_("C_onfigure"));
 | 
			
		||||
	image = gtk_image_new_from_stock (GTK_STOCK_PREFERENCES,
 | 
			
		||||
					  GTK_ICON_SIZE_MENU);
 | 
			
		||||
	gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
 | 
			
		||||
	g_signal_connect (item, "activate",
 | 
			
		||||
			  G_CALLBACK (configure_button_cb), pm);
 | 
			
		||||
	gtk_widget_set_sensitive (item, xedit_plugin_info_is_configurable (info));
 | 
			
		||||
	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
 | 
			
		||||
 | 
			
		||||
	item = gtk_check_menu_item_new_with_mnemonic (_("A_ctivate"));
 | 
			
		||||
	gtk_widget_set_sensitive (item, xedit_plugin_info_is_available (info));
 | 
			
		||||
	gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
 | 
			
		||||
					xedit_plugin_info_is_active (info));
 | 
			
		||||
	g_signal_connect (item, "toggled",
 | 
			
		||||
			  G_CALLBACK (enable_plugin_menu_cb), pm);
 | 
			
		||||
	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
 | 
			
		||||
 | 
			
		||||
	item = gtk_separator_menu_item_new ();
 | 
			
		||||
	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
 | 
			
		||||
 | 
			
		||||
	item = gtk_menu_item_new_with_mnemonic (_("Ac_tivate All"));
 | 
			
		||||
	g_signal_connect (item, "activate",
 | 
			
		||||
			  G_CALLBACK (enable_all_menu_cb), pm);
 | 
			
		||||
	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
 | 
			
		||||
 | 
			
		||||
	item = gtk_menu_item_new_with_mnemonic (_("_Deactivate All"));
 | 
			
		||||
	g_signal_connect (item, "activate",
 | 
			
		||||
			  G_CALLBACK (disable_all_menu_cb), pm);
 | 
			
		||||
	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
 | 
			
		||||
	
 | 
			
		||||
	gtk_widget_show_all (menu);
 | 
			
		||||
	
 | 
			
		||||
	return menu;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
tree_popup_menu_detach (XeditPluginManager *pm,
 | 
			
		||||
			GtkMenu            *menu)
 | 
			
		||||
{
 | 
			
		||||
	pm->priv->popup_menu = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
show_tree_popup_menu (GtkTreeView        *tree,
 | 
			
		||||
		      XeditPluginManager *pm,
 | 
			
		||||
		      GdkEventButton     *event)
 | 
			
		||||
{
 | 
			
		||||
	if (pm->priv->popup_menu)
 | 
			
		||||
		gtk_widget_destroy (pm->priv->popup_menu);
 | 
			
		||||
 | 
			
		||||
	pm->priv->popup_menu = create_tree_popup_menu (pm);
 | 
			
		||||
	
 | 
			
		||||
	gtk_menu_attach_to_widget (GTK_MENU (pm->priv->popup_menu),
 | 
			
		||||
				   GTK_WIDGET (pm),
 | 
			
		||||
				   (GtkMenuDetachFunc) tree_popup_menu_detach);
 | 
			
		||||
 | 
			
		||||
	if (event != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		gtk_menu_popup (GTK_MENU (pm->priv->popup_menu), NULL, NULL,
 | 
			
		||||
				NULL, NULL,
 | 
			
		||||
				event->button, event->time);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		gtk_menu_popup (GTK_MENU (pm->priv->popup_menu), NULL, NULL,
 | 
			
		||||
				xedit_utils_menu_position_under_tree_view, tree,
 | 
			
		||||
				0, gtk_get_current_event_time ());
 | 
			
		||||
 | 
			
		||||
		gtk_menu_shell_select_first (GTK_MENU_SHELL (pm->priv->popup_menu),
 | 
			
		||||
					     FALSE);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
button_press_event_cb (GtkWidget          *tree,
 | 
			
		||||
		       GdkEventButton     *event,
 | 
			
		||||
		       XeditPluginManager *pm)
 | 
			
		||||
{
 | 
			
		||||
	/* We want the treeview selection to be updated before showing the menu.
 | 
			
		||||
	 * This code is evil, thanks to Federico Mena Quintero's black magic.
 | 
			
		||||
	 * See: http://mail.gnome.org/archives/gtk-devel-list/2006-February/msg00168.html
 | 
			
		||||
	 * FIXME: Let's remove it asap.
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	static gboolean in_press = FALSE;
 | 
			
		||||
	gboolean handled;
 | 
			
		||||
 | 
			
		||||
	if (in_press)
 | 
			
		||||
		return FALSE; /* we re-entered */
 | 
			
		||||
 | 
			
		||||
	if (GDK_BUTTON_PRESS != event->type || 3 != event->button)
 | 
			
		||||
		return FALSE; /* let the normal handler run */
 | 
			
		||||
 | 
			
		||||
	in_press = TRUE;
 | 
			
		||||
	handled = gtk_widget_event (tree, (GdkEvent *) event);
 | 
			
		||||
	in_press = FALSE;
 | 
			
		||||
 | 
			
		||||
	if (!handled)
 | 
			
		||||
		return FALSE;
 | 
			
		||||
		
 | 
			
		||||
	/* The selection is fully updated by now */
 | 
			
		||||
	show_tree_popup_menu (GTK_TREE_VIEW (tree), pm, event);
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
popup_menu_cb (GtkTreeView        *tree,
 | 
			
		||||
	       XeditPluginManager *pm)
 | 
			
		||||
{
 | 
			
		||||
	show_tree_popup_menu (tree, pm, NULL);
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gint 
 | 
			
		||||
model_name_sort_func (GtkTreeModel *model,
 | 
			
		||||
		      GtkTreeIter  *iter1,
 | 
			
		||||
		      GtkTreeIter  *iter2,
 | 
			
		||||
		      gpointer      user_data)
 | 
			
		||||
{
 | 
			
		||||
	XeditPluginInfo *info1, *info2;
 | 
			
		||||
	
 | 
			
		||||
	gtk_tree_model_get (model, iter1, INFO_COLUMN, &info1, -1);
 | 
			
		||||
	gtk_tree_model_get (model, iter2, INFO_COLUMN, &info2, -1);
 | 
			
		||||
 | 
			
		||||
	return g_utf8_collate (xedit_plugin_info_get_name (info1),
 | 
			
		||||
			       xedit_plugin_info_get_name (info2));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
plugin_manager_construct_tree (XeditPluginManager *pm)
 | 
			
		||||
{
 | 
			
		||||
	GtkTreeViewColumn *column;
 | 
			
		||||
	GtkCellRenderer *cell;
 | 
			
		||||
	GtkListStore *model;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_PLUGINS);
 | 
			
		||||
 | 
			
		||||
	model = gtk_list_store_new (N_COLUMNS,
 | 
			
		||||
				    G_TYPE_BOOLEAN,
 | 
			
		||||
				    G_TYPE_BOOLEAN,
 | 
			
		||||
				    G_TYPE_POINTER);
 | 
			
		||||
 | 
			
		||||
	gtk_tree_view_set_model (GTK_TREE_VIEW (pm->priv->tree),
 | 
			
		||||
				 GTK_TREE_MODEL (model));
 | 
			
		||||
	g_object_unref (model);
 | 
			
		||||
 | 
			
		||||
	gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (pm->priv->tree), TRUE);
 | 
			
		||||
	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (pm->priv->tree), FALSE);
 | 
			
		||||
 | 
			
		||||
	/* first column */
 | 
			
		||||
	cell = gtk_cell_renderer_toggle_new ();
 | 
			
		||||
	g_object_set (cell, "xpad", 6, NULL);
 | 
			
		||||
	g_signal_connect (cell,
 | 
			
		||||
			  "toggled",
 | 
			
		||||
			  G_CALLBACK (active_toggled_cb),
 | 
			
		||||
			  pm);
 | 
			
		||||
	column = gtk_tree_view_column_new_with_attributes (PLUGIN_MANAGER_ACTIVE_TITLE,
 | 
			
		||||
							   cell,
 | 
			
		||||
							   "active",
 | 
			
		||||
							   ACTIVE_COLUMN,
 | 
			
		||||
							   "activatable",
 | 
			
		||||
							   AVAILABLE_COLUMN,
 | 
			
		||||
							   "sensitive",
 | 
			
		||||
							   AVAILABLE_COLUMN,
 | 
			
		||||
							   NULL);
 | 
			
		||||
	gtk_tree_view_append_column (GTK_TREE_VIEW (pm->priv->tree), column);
 | 
			
		||||
 | 
			
		||||
	/* second column */
 | 
			
		||||
	column = gtk_tree_view_column_new ();
 | 
			
		||||
	gtk_tree_view_column_set_title (column, PLUGIN_MANAGER_NAME_TITLE);
 | 
			
		||||
	gtk_tree_view_column_set_resizable (column, TRUE);
 | 
			
		||||
 | 
			
		||||
	cell = gtk_cell_renderer_pixbuf_new ();
 | 
			
		||||
	gtk_tree_view_column_pack_start (column, cell, FALSE);
 | 
			
		||||
	g_object_set (cell, "stock-size", GTK_ICON_SIZE_SMALL_TOOLBAR, NULL);
 | 
			
		||||
	gtk_tree_view_column_set_cell_data_func (column, cell,
 | 
			
		||||
						 plugin_manager_view_icon_cell_cb,
 | 
			
		||||
						 pm, NULL);
 | 
			
		||||
	
 | 
			
		||||
	cell = gtk_cell_renderer_text_new ();
 | 
			
		||||
	gtk_tree_view_column_pack_start (column, cell, TRUE);
 | 
			
		||||
	g_object_set (cell, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
 | 
			
		||||
	gtk_tree_view_column_set_cell_data_func (column, cell,
 | 
			
		||||
						 plugin_manager_view_info_cell_cb,
 | 
			
		||||
						 pm, NULL);
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	gtk_tree_view_column_set_spacing (column, 6);
 | 
			
		||||
	gtk_tree_view_append_column (GTK_TREE_VIEW (pm->priv->tree), column);
 | 
			
		||||
 | 
			
		||||
	/* Sort on the plugin names */
 | 
			
		||||
	gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (model),
 | 
			
		||||
	                                         model_name_sort_func,
 | 
			
		||||
        	                                 NULL,
 | 
			
		||||
                	                         NULL);
 | 
			
		||||
	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
 | 
			
		||||
					      GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
 | 
			
		||||
					      GTK_SORT_ASCENDING);
 | 
			
		||||
 | 
			
		||||
	/* Enable search for our non-string column */
 | 
			
		||||
	gtk_tree_view_set_search_column (GTK_TREE_VIEW (pm->priv->tree),
 | 
			
		||||
					 INFO_COLUMN);
 | 
			
		||||
	gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (pm->priv->tree),
 | 
			
		||||
					     name_search_cb,
 | 
			
		||||
					     NULL,
 | 
			
		||||
					     NULL);
 | 
			
		||||
 | 
			
		||||
	g_signal_connect (pm->priv->tree,
 | 
			
		||||
			  "cursor_changed",
 | 
			
		||||
			  G_CALLBACK (cursor_changed_cb),
 | 
			
		||||
			  pm);
 | 
			
		||||
	g_signal_connect (pm->priv->tree,
 | 
			
		||||
			  "row_activated",
 | 
			
		||||
			  G_CALLBACK (row_activated_cb),
 | 
			
		||||
			  pm);
 | 
			
		||||
 | 
			
		||||
	g_signal_connect (pm->priv->tree,
 | 
			
		||||
			  "button-press-event",
 | 
			
		||||
			  G_CALLBACK (button_press_event_cb),
 | 
			
		||||
			  pm);
 | 
			
		||||
	g_signal_connect (pm->priv->tree,
 | 
			
		||||
			  "popup-menu",
 | 
			
		||||
			  G_CALLBACK (popup_menu_cb),
 | 
			
		||||
			  pm);
 | 
			
		||||
	gtk_widget_show (pm->priv->tree);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
plugin_toggled_cb (XeditPluginsEngine *engine,
 | 
			
		||||
		   XeditPluginInfo    *info,
 | 
			
		||||
		   XeditPluginManager *pm)
 | 
			
		||||
{
 | 
			
		||||
	GtkTreeSelection *selection;
 | 
			
		||||
	GtkTreeModel *model;
 | 
			
		||||
	GtkTreeIter iter;
 | 
			
		||||
	gboolean info_found = FALSE;
 | 
			
		||||
 | 
			
		||||
	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (pm->priv->tree));
 | 
			
		||||
 | 
			
		||||
	if (gtk_tree_selection_get_selected (selection, &model, &iter))
 | 
			
		||||
	{
 | 
			
		||||
		/* There is an item selected: it's probably the one we want! */
 | 
			
		||||
		XeditPluginInfo *tinfo;
 | 
			
		||||
		gtk_tree_model_get (model, &iter, INFO_COLUMN, &tinfo, -1);
 | 
			
		||||
		info_found = info == tinfo;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!info_found)
 | 
			
		||||
	{
 | 
			
		||||
		gtk_tree_model_get_iter_first (model, &iter);
 | 
			
		||||
 | 
			
		||||
		do
 | 
			
		||||
		{
 | 
			
		||||
			XeditPluginInfo *tinfo;
 | 
			
		||||
			gtk_tree_model_get (model, &iter, INFO_COLUMN, &tinfo, -1);
 | 
			
		||||
			info_found = info == tinfo;
 | 
			
		||||
		}
 | 
			
		||||
		while (!info_found && gtk_tree_model_iter_next (model, &iter));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!info_found)
 | 
			
		||||
	{
 | 
			
		||||
		g_warning ("XeditPluginManager: plugin '%s' not found in the tree model",
 | 
			
		||||
			   xedit_plugin_info_get_name (info));
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gtk_list_store_set (GTK_LIST_STORE (model), &iter, ACTIVE_COLUMN, xedit_plugin_info_is_active (info), -1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
xedit_plugin_manager_init (XeditPluginManager *pm)
 | 
			
		||||
{
 | 
			
		||||
	GtkWidget *label;
 | 
			
		||||
	GtkWidget *viewport;
 | 
			
		||||
	GtkWidget *hbuttonbox;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_PLUGINS);
 | 
			
		||||
 | 
			
		||||
	pm->priv = XEDIT_PLUGIN_MANAGER_GET_PRIVATE (pm);
 | 
			
		||||
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
	gtk_orientable_set_orientation (GTK_ORIENTABLE (pm),
 | 
			
		||||
	                                GTK_ORIENTATION_VERTICAL);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Always we create the manager, firstly we rescan the plugins directory
 | 
			
		||||
	 */
 | 
			
		||||
	xedit_plugins_engine_rescan_plugins (xedit_plugins_engine_get_default ());
 | 
			
		||||
 | 
			
		||||
	gtk_box_set_spacing (GTK_BOX (pm), 6);
 | 
			
		||||
 | 
			
		||||
	label = gtk_label_new_with_mnemonic (_("Active _Plugins:"));
 | 
			
		||||
	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 16, 0)
 | 
			
		||||
	gtk_label_set_xalign (GTK_LABEL (label), 0.0);
 | 
			
		||||
#else
 | 
			
		||||
	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
 | 
			
		||||
#endif
 | 
			
		||||
	
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (pm), label, FALSE, TRUE, 0);
 | 
			
		||||
	
 | 
			
		||||
	viewport = gtk_scrolled_window_new (NULL, NULL);
 | 
			
		||||
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (viewport),
 | 
			
		||||
					GTK_POLICY_AUTOMATIC,
 | 
			
		||||
					GTK_POLICY_AUTOMATIC);
 | 
			
		||||
	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (viewport), 
 | 
			
		||||
					     GTK_SHADOW_IN);
 | 
			
		||||
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (pm), viewport, TRUE, TRUE, 0);
 | 
			
		||||
 | 
			
		||||
	pm->priv->tree = gtk_tree_view_new ();
 | 
			
		||||
	gtk_container_add (GTK_CONTAINER (viewport), pm->priv->tree);
 | 
			
		||||
 | 
			
		||||
	gtk_label_set_mnemonic_widget (GTK_LABEL (label), pm->priv->tree);
 | 
			
		||||
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
	hbuttonbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
 | 
			
		||||
#else
 | 
			
		||||
	hbuttonbox = gtk_hbutton_box_new ();
 | 
			
		||||
#endif
 | 
			
		||||
	gtk_box_pack_start (GTK_BOX (pm), hbuttonbox, FALSE, FALSE, 0);
 | 
			
		||||
	gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox), GTK_BUTTONBOX_END);
 | 
			
		||||
	gtk_box_set_spacing (GTK_BOX (hbuttonbox), 8);
 | 
			
		||||
 | 
			
		||||
	pm->priv->about_button = xedit_gtk_button_new_with_stock_icon (_("_About Plugin"),
 | 
			
		||||
								       GTK_STOCK_ABOUT);
 | 
			
		||||
	gtk_container_add (GTK_CONTAINER (hbuttonbox), pm->priv->about_button);
 | 
			
		||||
 | 
			
		||||
	pm->priv->configure_button = xedit_gtk_button_new_with_stock_icon (_("C_onfigure Plugin"),
 | 
			
		||||
									   GTK_STOCK_PREFERENCES);
 | 
			
		||||
	gtk_container_add (GTK_CONTAINER (hbuttonbox), pm->priv->configure_button);
 | 
			
		||||
 | 
			
		||||
	/* setup a window of a sane size. */
 | 
			
		||||
	gtk_widget_set_size_request (GTK_WIDGET (viewport), 270, 100);
 | 
			
		||||
 | 
			
		||||
	g_signal_connect (pm->priv->about_button,
 | 
			
		||||
			  "clicked",
 | 
			
		||||
			  G_CALLBACK (about_button_cb),
 | 
			
		||||
			  pm);
 | 
			
		||||
	g_signal_connect (pm->priv->configure_button,
 | 
			
		||||
			  "clicked",
 | 
			
		||||
			  G_CALLBACK (configure_button_cb),
 | 
			
		||||
			  pm);
 | 
			
		||||
 | 
			
		||||
	plugin_manager_construct_tree (pm);
 | 
			
		||||
 | 
			
		||||
	/* get the plugin engine and populate the treeview */
 | 
			
		||||
	pm->priv->engine = xedit_plugins_engine_get_default ();
 | 
			
		||||
 | 
			
		||||
	g_signal_connect_after (pm->priv->engine,
 | 
			
		||||
				"activate-plugin",
 | 
			
		||||
				G_CALLBACK (plugin_toggled_cb),
 | 
			
		||||
				pm);
 | 
			
		||||
	g_signal_connect_after (pm->priv->engine,
 | 
			
		||||
				"deactivate-plugin",
 | 
			
		||||
				G_CALLBACK (plugin_toggled_cb),
 | 
			
		||||
				pm);
 | 
			
		||||
 | 
			
		||||
	if (xedit_plugins_engine_get_plugin_list (pm->priv->engine) != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		plugin_manager_populate_lists (pm);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		gtk_widget_set_sensitive (pm->priv->about_button, FALSE);
 | 
			
		||||
		gtk_widget_set_sensitive (pm->priv->configure_button, FALSE);		
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_plugin_manager_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
	XeditPluginManager *pm = XEDIT_PLUGIN_MANAGER (object);
 | 
			
		||||
 | 
			
		||||
	g_signal_handlers_disconnect_by_func (pm->priv->engine,
 | 
			
		||||
					      plugin_toggled_cb,
 | 
			
		||||
					      pm);
 | 
			
		||||
 | 
			
		||||
	if (pm->priv->popup_menu)
 | 
			
		||||
		gtk_widget_destroy (pm->priv->popup_menu);
 | 
			
		||||
 | 
			
		||||
	G_OBJECT_CLASS (xedit_plugin_manager_parent_class)->finalize (object);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GtkWidget *xedit_plugin_manager_new (void)
 | 
			
		||||
{
 | 
			
		||||
	return g_object_new (XEDIT_TYPE_PLUGIN_MANAGER,0);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										91
									
								
								xedit/xedit-plugin-manager.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								xedit/xedit-plugin-manager.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,91 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-plugin-manager.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2002-2005 Paolo Maggi
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA. 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2002-2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_PLUGIN_MANAGER_H__
 | 
			
		||||
#define __XEDIT_PLUGIN_MANAGER_H__
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Type checking and casting macros
 | 
			
		||||
 */
 | 
			
		||||
#define XEDIT_TYPE_PLUGIN_MANAGER              (xedit_plugin_manager_get_type())
 | 
			
		||||
#define XEDIT_PLUGIN_MANAGER(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), XEDIT_TYPE_PLUGIN_MANAGER, XeditPluginManager))
 | 
			
		||||
#define XEDIT_PLUGIN_MANAGER_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), XEDIT_TYPE_PLUGIN_MANAGER, XeditPluginManagerClass))
 | 
			
		||||
#define XEDIT_IS_PLUGIN_MANAGER(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), XEDIT_TYPE_PLUGIN_MANAGER))
 | 
			
		||||
#define XEDIT_IS_PLUGIN_MANAGER_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), XEDIT_TYPE_PLUGIN_MANAGER))
 | 
			
		||||
#define XEDIT_PLUGIN_MANAGER_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), XEDIT_TYPE_PLUGIN_MANAGER, XeditPluginManagerClass))
 | 
			
		||||
 | 
			
		||||
/* Private structure type */
 | 
			
		||||
typedef struct _XeditPluginManagerPrivate XeditPluginManagerPrivate;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Main object structure
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _XeditPluginManager XeditPluginManager;
 | 
			
		||||
 | 
			
		||||
struct _XeditPluginManager 
 | 
			
		||||
{
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
	GtkBox vbox;
 | 
			
		||||
#else
 | 
			
		||||
	GtkVBox vbox;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/*< private > */
 | 
			
		||||
	XeditPluginManagerPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Class definition
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _XeditPluginManagerClass XeditPluginManagerClass;
 | 
			
		||||
 | 
			
		||||
struct _XeditPluginManagerClass 
 | 
			
		||||
{
 | 
			
		||||
#if GTK_CHECK_VERSION (3, 0, 0)
 | 
			
		||||
	GtkBoxClass parent_class;
 | 
			
		||||
#else
 | 
			
		||||
	GtkVBoxClass parent_class;
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Public methods
 | 
			
		||||
 */
 | 
			
		||||
GType		 xedit_plugin_manager_get_type		(void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
GtkWidget	*xedit_plugin_manager_new		(void);
 | 
			
		||||
   
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif  /* __XEDIT_PLUGIN_MANAGER_H__  */
 | 
			
		||||
							
								
								
									
										334
									
								
								xedit/xedit-plugin.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										334
									
								
								xedit/xedit-plugin.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,334 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-plugin.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2002-2005 Paolo Maggi
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor,
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2002-2005. See the AUTHORS file for a
 | 
			
		||||
 * list of people on the xedit Team.
 | 
			
		||||
 * See the ChangeLog files for a list of changes.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "xedit-plugin.h"
 | 
			
		||||
#include "xedit-dirs.h"
 | 
			
		||||
 | 
			
		||||
/* properties */
 | 
			
		||||
enum {
 | 
			
		||||
	PROP_0,
 | 
			
		||||
	PROP_INSTALL_DIR,
 | 
			
		||||
	PROP_DATA_DIR_NAME,
 | 
			
		||||
	PROP_DATA_DIR
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct _XeditPluginPrivate XeditPluginPrivate;
 | 
			
		||||
 | 
			
		||||
struct _XeditPluginPrivate
 | 
			
		||||
{
 | 
			
		||||
	gchar *install_dir;
 | 
			
		||||
	gchar *data_dir_name;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define XEDIT_PLUGIN_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), XEDIT_TYPE_PLUGIN, XeditPluginPrivate))
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE(XeditPlugin, xedit_plugin, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
dummy (XeditPlugin *plugin, XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	/* Empty */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GtkWidget *
 | 
			
		||||
create_configure_dialog	(XeditPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
is_configurable (XeditPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
	return (XEDIT_PLUGIN_GET_CLASS (plugin)->create_configure_dialog !=
 | 
			
		||||
		create_configure_dialog);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_plugin_get_property (GObject    *object,
 | 
			
		||||
			   guint       prop_id,
 | 
			
		||||
			   GValue     *value,
 | 
			
		||||
			   GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
	switch (prop_id)
 | 
			
		||||
	{
 | 
			
		||||
		case PROP_INSTALL_DIR:
 | 
			
		||||
			g_value_take_string (value, xedit_plugin_get_install_dir (XEDIT_PLUGIN (object)));
 | 
			
		||||
			break;
 | 
			
		||||
		case PROP_DATA_DIR:
 | 
			
		||||
			g_value_take_string (value, xedit_plugin_get_data_dir (XEDIT_PLUGIN (object)));
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			g_return_if_reached ();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_plugin_set_property (GObject      *object,
 | 
			
		||||
			   guint         prop_id,
 | 
			
		||||
			   const GValue *value,
 | 
			
		||||
			   GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
	XeditPluginPrivate *priv = XEDIT_PLUGIN_GET_PRIVATE (object);
 | 
			
		||||
 | 
			
		||||
	switch (prop_id)
 | 
			
		||||
	{
 | 
			
		||||
		case PROP_INSTALL_DIR:
 | 
			
		||||
			priv->install_dir = g_value_dup_string (value);
 | 
			
		||||
			break;
 | 
			
		||||
		case PROP_DATA_DIR_NAME:
 | 
			
		||||
			priv->data_dir_name = g_value_dup_string (value);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			g_return_if_reached ();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_plugin_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
	XeditPluginPrivate *priv = XEDIT_PLUGIN_GET_PRIVATE (object);
 | 
			
		||||
 | 
			
		||||
	g_free (priv->install_dir);
 | 
			
		||||
	g_free (priv->data_dir_name);
 | 
			
		||||
 | 
			
		||||
	G_OBJECT_CLASS (xedit_plugin_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_plugin_class_init (XeditPluginClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
	klass->activate = dummy;
 | 
			
		||||
	klass->deactivate = dummy;
 | 
			
		||||
	klass->update_ui = dummy;
 | 
			
		||||
 | 
			
		||||
	klass->create_configure_dialog = create_configure_dialog;
 | 
			
		||||
	klass->is_configurable = is_configurable;
 | 
			
		||||
 | 
			
		||||
	object_class->get_property = xedit_plugin_get_property;
 | 
			
		||||
	object_class->set_property = xedit_plugin_set_property;
 | 
			
		||||
	object_class->finalize = xedit_plugin_finalize;
 | 
			
		||||
 | 
			
		||||
	g_object_class_install_property (object_class,
 | 
			
		||||
					 PROP_INSTALL_DIR,
 | 
			
		||||
					 g_param_spec_string ("install-dir",
 | 
			
		||||
							      "Install Directory",
 | 
			
		||||
							      "The directory where the plugin is installed",
 | 
			
		||||
							      NULL,
 | 
			
		||||
							      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 | 
			
		||||
 | 
			
		||||
	/* the basename of the data dir is set at construction time by the plugin loader
 | 
			
		||||
	 * while the full path is constructed on the fly to take into account relocability
 | 
			
		||||
	 * that's why we have a writeonly prop and a readonly prop */
 | 
			
		||||
	g_object_class_install_property (object_class,
 | 
			
		||||
					 PROP_DATA_DIR_NAME,
 | 
			
		||||
					 g_param_spec_string ("data-dir-name",
 | 
			
		||||
							      "Basename of the data directory",
 | 
			
		||||
							      "The basename of the directory where the plugin should look for its data files",
 | 
			
		||||
							      NULL,
 | 
			
		||||
							      G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
 | 
			
		||||
	g_object_class_install_property (object_class,
 | 
			
		||||
					 PROP_DATA_DIR,
 | 
			
		||||
					 g_param_spec_string ("data-dir",
 | 
			
		||||
							      "Data Directory",
 | 
			
		||||
							      "The full path of the directory where the plugin should look for its data files",
 | 
			
		||||
							      NULL,
 | 
			
		||||
							      G_PARAM_READABLE));
 | 
			
		||||
 | 
			
		||||
	g_type_class_add_private (klass, sizeof (XeditPluginPrivate));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_plugin_init (XeditPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
	/* Empty */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_plugin_get_install_dir:
 | 
			
		||||
 * @plugin: a #XeditPlugin
 | 
			
		||||
 *
 | 
			
		||||
 * Get the path of the directory where the plugin is installed.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: a newly allocated string with the path of the
 | 
			
		||||
 * directory where the plugin is installed
 | 
			
		||||
 */
 | 
			
		||||
gchar *
 | 
			
		||||
xedit_plugin_get_install_dir (XeditPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_PLUGIN (plugin), NULL);
 | 
			
		||||
 | 
			
		||||
	return g_strdup (XEDIT_PLUGIN_GET_PRIVATE (plugin)->install_dir);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_plugin_get_data_dir:
 | 
			
		||||
 * @plugin: a #XeditPlugin
 | 
			
		||||
 *
 | 
			
		||||
 * Get the path of the directory where the plugin should look for
 | 
			
		||||
 * its data files.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: a newly allocated string with the path of the
 | 
			
		||||
 * directory where the plugin should look for its data files
 | 
			
		||||
 */
 | 
			
		||||
gchar *
 | 
			
		||||
xedit_plugin_get_data_dir (XeditPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
	XeditPluginPrivate *priv;
 | 
			
		||||
	gchar *xedit_lib_dir;
 | 
			
		||||
	gchar *data_dir;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_PLUGIN (plugin), NULL);
 | 
			
		||||
 | 
			
		||||
	priv = XEDIT_PLUGIN_GET_PRIVATE (plugin);
 | 
			
		||||
 | 
			
		||||
	/* If it's a "user" plugin the data dir is
 | 
			
		||||
	 * install_dir/data_dir_name if instead it's a
 | 
			
		||||
	 * "system" plugin the data dir is under xedit_data_dir,
 | 
			
		||||
	 * so it's under $prefix/share/xedit/plugins/data_dir_name
 | 
			
		||||
	 * where data_dir_name usually it's the name of the plugin
 | 
			
		||||
	 */
 | 
			
		||||
	xedit_lib_dir = xedit_dirs_get_xedit_lib_dir ();
 | 
			
		||||
 | 
			
		||||
	/* CHECK: is checking the prefix enough or should we be more
 | 
			
		||||
	 * careful about normalizing paths etc? */
 | 
			
		||||
	if (g_str_has_prefix (priv->install_dir, xedit_lib_dir))
 | 
			
		||||
	{
 | 
			
		||||
		gchar *xedit_data_dir;
 | 
			
		||||
 | 
			
		||||
		xedit_data_dir = xedit_dirs_get_xedit_data_dir ();
 | 
			
		||||
 | 
			
		||||
		data_dir = g_build_filename (xedit_data_dir,
 | 
			
		||||
					     "plugins",
 | 
			
		||||
					     priv->data_dir_name,
 | 
			
		||||
					     NULL);
 | 
			
		||||
 | 
			
		||||
		g_free (xedit_data_dir);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		data_dir = g_build_filename (priv->install_dir,
 | 
			
		||||
					     priv->data_dir_name,
 | 
			
		||||
					     NULL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_free (xedit_lib_dir);
 | 
			
		||||
 | 
			
		||||
	return data_dir;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_plugin_activate:
 | 
			
		||||
 * @plugin: a #XeditPlugin
 | 
			
		||||
 * @window: a #XeditWindow
 | 
			
		||||
 *
 | 
			
		||||
 * Activates the plugin.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
xedit_plugin_activate (XeditPlugin *plugin,
 | 
			
		||||
		       XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_PLUGIN (plugin));
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_WINDOW (window));
 | 
			
		||||
 | 
			
		||||
	XEDIT_PLUGIN_GET_CLASS (plugin)->activate (plugin, window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_plugin_deactivate:
 | 
			
		||||
 * @plugin: a #XeditPlugin
 | 
			
		||||
 * @window: a #XeditWindow
 | 
			
		||||
 *
 | 
			
		||||
 * Deactivates the plugin.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
xedit_plugin_deactivate	(XeditPlugin *plugin,
 | 
			
		||||
			 XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_PLUGIN (plugin));
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_WINDOW (window));
 | 
			
		||||
 | 
			
		||||
	XEDIT_PLUGIN_GET_CLASS (plugin)->deactivate (plugin, window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_plugin_update_ui:
 | 
			
		||||
 * @plugin: a #XeditPlugin
 | 
			
		||||
 * @window: a #XeditWindow
 | 
			
		||||
 *
 | 
			
		||||
 * Triggers an update of the user interface to take into account state changes
 | 
			
		||||
 * caused by the plugin.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
xedit_plugin_update_ui	(XeditPlugin *plugin,
 | 
			
		||||
			 XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_PLUGIN (plugin));
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_WINDOW (window));
 | 
			
		||||
 | 
			
		||||
	XEDIT_PLUGIN_GET_CLASS (plugin)->update_ui (plugin, window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_plugin_is_configurable:
 | 
			
		||||
 * @plugin: a #XeditPlugin
 | 
			
		||||
 *
 | 
			
		||||
 * Whether the plugin is configurable.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: TRUE if the plugin is configurable:
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_plugin_is_configurable (XeditPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_PLUGIN (plugin), FALSE);
 | 
			
		||||
 | 
			
		||||
	return XEDIT_PLUGIN_GET_CLASS (plugin)->is_configurable (plugin);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xedit_plugin_create_configure_dialog:
 | 
			
		||||
 * @plugin: a #XeditPlugin
 | 
			
		||||
 *
 | 
			
		||||
 * Creates the configure dialog widget for the plugin.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: the configure dialog widget for the plugin.
 | 
			
		||||
 */
 | 
			
		||||
GtkWidget *
 | 
			
		||||
xedit_plugin_create_configure_dialog (XeditPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
	g_return_val_if_fail (XEDIT_IS_PLUGIN (plugin), NULL);
 | 
			
		||||
 | 
			
		||||
	return XEDIT_PLUGIN_GET_CLASS (plugin)->create_configure_dialog (plugin);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										240
									
								
								xedit/xedit-plugin.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										240
									
								
								xedit/xedit-plugin.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,240 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-plugin.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2002-2005 - Paolo Maggi 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA. 
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2002-2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_PLUGIN_H__
 | 
			
		||||
#define __XEDIT_PLUGIN_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
#include <xedit/xedit-window.h>
 | 
			
		||||
#include <xedit/xedit-debug.h>
 | 
			
		||||
 | 
			
		||||
/* TODO: add a .h file that includes all the .h files normally needed to
 | 
			
		||||
 * develop a plugin */ 
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Type checking and casting macros
 | 
			
		||||
 */
 | 
			
		||||
#define XEDIT_TYPE_PLUGIN              (xedit_plugin_get_type())
 | 
			
		||||
#define XEDIT_PLUGIN(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), XEDIT_TYPE_PLUGIN, XeditPlugin))
 | 
			
		||||
#define XEDIT_PLUGIN_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), XEDIT_TYPE_PLUGIN, XeditPluginClass))
 | 
			
		||||
#define XEDIT_IS_PLUGIN(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), XEDIT_TYPE_PLUGIN))
 | 
			
		||||
#define XEDIT_IS_PLUGIN_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), XEDIT_TYPE_PLUGIN))
 | 
			
		||||
#define XEDIT_PLUGIN_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), XEDIT_TYPE_PLUGIN, XeditPluginClass))
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Main object structure
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _XeditPlugin XeditPlugin;
 | 
			
		||||
 | 
			
		||||
struct _XeditPlugin 
 | 
			
		||||
{
 | 
			
		||||
	GObject parent;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Class definition
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _XeditPluginClass XeditPluginClass;
 | 
			
		||||
 | 
			
		||||
struct _XeditPluginClass 
 | 
			
		||||
{
 | 
			
		||||
	GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
	/* Virtual public methods */
 | 
			
		||||
	
 | 
			
		||||
	void 		(*activate)		(XeditPlugin *plugin,
 | 
			
		||||
						 XeditWindow *window);
 | 
			
		||||
	void 		(*deactivate)		(XeditPlugin *plugin,
 | 
			
		||||
						 XeditWindow *window);
 | 
			
		||||
 | 
			
		||||
	void 		(*update_ui)		(XeditPlugin *plugin,
 | 
			
		||||
						 XeditWindow *window);
 | 
			
		||||
 | 
			
		||||
	GtkWidget 	*(*create_configure_dialog)
 | 
			
		||||
						(XeditPlugin *plugin);
 | 
			
		||||
 | 
			
		||||
	/* Plugins should not override this, it's handled automatically by
 | 
			
		||||
	   the XeditPluginClass */
 | 
			
		||||
	gboolean 	(*is_configurable)
 | 
			
		||||
						(XeditPlugin *plugin);
 | 
			
		||||
 | 
			
		||||
	/* Padding for future expansion */
 | 
			
		||||
	void		(*_xedit_reserved1)	(void);
 | 
			
		||||
	void		(*_xedit_reserved2)	(void);
 | 
			
		||||
	void		(*_xedit_reserved3)	(void);
 | 
			
		||||
	void		(*_xedit_reserved4)	(void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Public methods
 | 
			
		||||
 */
 | 
			
		||||
GType 		 xedit_plugin_get_type 		(void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
gchar 		*xedit_plugin_get_install_dir	(XeditPlugin *plugin);
 | 
			
		||||
gchar 		*xedit_plugin_get_data_dir	(XeditPlugin *plugin);
 | 
			
		||||
 | 
			
		||||
void 		 xedit_plugin_activate		(XeditPlugin *plugin,
 | 
			
		||||
						 XeditWindow *window);
 | 
			
		||||
void 		 xedit_plugin_deactivate	(XeditPlugin *plugin,
 | 
			
		||||
						 XeditWindow *window);
 | 
			
		||||
				 
 | 
			
		||||
void 		 xedit_plugin_update_ui		(XeditPlugin *plugin,
 | 
			
		||||
						 XeditWindow *window);
 | 
			
		||||
 | 
			
		||||
gboolean	 xedit_plugin_is_configurable	(XeditPlugin *plugin);
 | 
			
		||||
GtkWidget	*xedit_plugin_create_configure_dialog		
 | 
			
		||||
						(XeditPlugin *plugin);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * XEDIT_PLUGIN_REGISTER_TYPE_WITH_CODE(PluginName, plugin_name, CODE):
 | 
			
		||||
 *
 | 
			
		||||
 * Utility macro used to register plugins with additional code.
 | 
			
		||||
 */
 | 
			
		||||
#define XEDIT_PLUGIN_REGISTER_TYPE_WITH_CODE(PluginName, plugin_name, CODE) 	\
 | 
			
		||||
	G_DEFINE_DYNAMIC_TYPE_EXTENDED (PluginName,				\
 | 
			
		||||
					plugin_name,				\
 | 
			
		||||
					XEDIT_TYPE_PLUGIN,			\
 | 
			
		||||
					0,					\
 | 
			
		||||
					GTypeModule *module G_GNUC_UNUSED = type_module; /* back compat */	\
 | 
			
		||||
					CODE)					\
 | 
			
		||||
										\
 | 
			
		||||
/* This is not very nice, but G_DEFINE_DYNAMIC wants it and our old macro	\
 | 
			
		||||
 * did not support it */							\
 | 
			
		||||
static void									\
 | 
			
		||||
plugin_name##_class_finalize (PluginName##Class *klass)				\
 | 
			
		||||
{										\
 | 
			
		||||
}										\
 | 
			
		||||
										\
 | 
			
		||||
										\
 | 
			
		||||
G_MODULE_EXPORT GType								\
 | 
			
		||||
register_xedit_plugin (GTypeModule *type_module)				\
 | 
			
		||||
{										\
 | 
			
		||||
	plugin_name##_register_type (type_module);				\
 | 
			
		||||
										\
 | 
			
		||||
	return plugin_name##_get_type();					\
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * XEDIT_PLUGIN_REGISTER_TYPE(PluginName, plugin_name):
 | 
			
		||||
 * 
 | 
			
		||||
 * Utility macro used to register plugins.
 | 
			
		||||
 */
 | 
			
		||||
#define XEDIT_PLUGIN_REGISTER_TYPE(PluginName, plugin_name)			\
 | 
			
		||||
	XEDIT_PLUGIN_REGISTER_TYPE_WITH_CODE(PluginName, plugin_name, ;)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * XEDIT_PLUGIN_DEFINE_TYPE_WITH_CODE(ObjectName, object_name, PARENT_TYPE, CODE):
 | 
			
		||||
 *
 | 
			
		||||
 * Utility macro used to register gobject types in plugins with additional code.
 | 
			
		||||
 *
 | 
			
		||||
 * Deprecated: use G_DEFINE_DYNAMIC_TYPE_EXTENDED instead
 | 
			
		||||
 */
 | 
			
		||||
#define XEDIT_PLUGIN_DEFINE_TYPE_WITH_CODE(ObjectName, object_name, PARENT_TYPE, CODE) \
 | 
			
		||||
										\
 | 
			
		||||
static GType g_define_type_id = 0;						\
 | 
			
		||||
										\
 | 
			
		||||
GType										\
 | 
			
		||||
object_name##_get_type (void)							\
 | 
			
		||||
{										\
 | 
			
		||||
	return g_define_type_id;						\
 | 
			
		||||
}										\
 | 
			
		||||
										\
 | 
			
		||||
static void     object_name##_init              (ObjectName        *self);	\
 | 
			
		||||
static void     object_name##_class_init        (ObjectName##Class *klass);	\
 | 
			
		||||
static gpointer object_name##_parent_class = NULL;				\
 | 
			
		||||
static void     object_name##_class_intern_init (gpointer klass)		\
 | 
			
		||||
{										\
 | 
			
		||||
	object_name##_parent_class = g_type_class_peek_parent (klass);		\
 | 
			
		||||
	object_name##_class_init ((ObjectName##Class *) klass);			\
 | 
			
		||||
}										\
 | 
			
		||||
										\
 | 
			
		||||
GType										\
 | 
			
		||||
object_name##_register_type (GTypeModule *type_module)				\
 | 
			
		||||
{										\
 | 
			
		||||
	GTypeModule *module G_GNUC_UNUSED = type_module; /* back compat */			\
 | 
			
		||||
	static const GTypeInfo our_info =					\
 | 
			
		||||
	{									\
 | 
			
		||||
		sizeof (ObjectName##Class),					\
 | 
			
		||||
		NULL, /* base_init */						\
 | 
			
		||||
		NULL, /* base_finalize */					\
 | 
			
		||||
		(GClassInitFunc) object_name##_class_intern_init,		\
 | 
			
		||||
		NULL,								\
 | 
			
		||||
		NULL, /* class_data */						\
 | 
			
		||||
		sizeof (ObjectName),						\
 | 
			
		||||
		0, /* n_preallocs */						\
 | 
			
		||||
		(GInstanceInitFunc) object_name##_init				\
 | 
			
		||||
	};									\
 | 
			
		||||
										\
 | 
			
		||||
	g_define_type_id = g_type_module_register_type (type_module,		\
 | 
			
		||||
					   	        PARENT_TYPE,		\
 | 
			
		||||
					                #ObjectName,		\
 | 
			
		||||
					                &our_info,		\
 | 
			
		||||
					                0);			\
 | 
			
		||||
										\
 | 
			
		||||
	CODE									\
 | 
			
		||||
										\
 | 
			
		||||
	return g_define_type_id;						\
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * XEDIT_PLUGIN_DEFINE_TYPE(ObjectName, object_name, PARENT_TYPE):
 | 
			
		||||
 *
 | 
			
		||||
 * Utility macro used to register gobject types in plugins.
 | 
			
		||||
 *
 | 
			
		||||
 * Deprecated: use G_DEFINE_DYNAMIC instead
 | 
			
		||||
 */
 | 
			
		||||
#define XEDIT_PLUGIN_DEFINE_TYPE(ObjectName, object_name, PARENT_TYPE)		\
 | 
			
		||||
	XEDIT_PLUGIN_DEFINE_TYPE_WITH_CODE(ObjectName, object_name, PARENT_TYPE, ;)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * XEDIT_PLUGIN_IMPLEMENT_INTERFACE(TYPE_IFACE, iface_init):
 | 
			
		||||
 *
 | 
			
		||||
 * Utility macro used to register interfaces for gobject types in plugins.
 | 
			
		||||
 */
 | 
			
		||||
#define XEDIT_PLUGIN_IMPLEMENT_INTERFACE(object_name, TYPE_IFACE, iface_init)	\
 | 
			
		||||
	const GInterfaceInfo object_name##_interface_info = 			\
 | 
			
		||||
	{ 									\
 | 
			
		||||
		(GInterfaceInitFunc) iface_init,				\
 | 
			
		||||
		NULL, 								\
 | 
			
		||||
		NULL								\
 | 
			
		||||
	};									\
 | 
			
		||||
										\
 | 
			
		||||
	g_type_module_add_interface (type_module, 					\
 | 
			
		||||
				     g_define_type_id, 				\
 | 
			
		||||
				     TYPE_IFACE, 				\
 | 
			
		||||
				     &object_name##_interface_info);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif  /* __XEDIT_PLUGIN_H__ */
 | 
			
		||||
							
								
								
									
										861
									
								
								xedit/xedit-plugins-engine.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										861
									
								
								xedit/xedit-plugins-engine.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,861 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-plugins-engine.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2002-2005 Paolo Maggi
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor,
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2002-2005. See the AUTHORS file for a
 | 
			
		||||
 * list of people on the xedit Team.
 | 
			
		||||
 * See the ChangeLog files for a list of changes.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
 | 
			
		||||
#include "xedit-plugins-engine.h"
 | 
			
		||||
#include "xedit-plugin-info-priv.h"
 | 
			
		||||
#include "xedit-plugin.h"
 | 
			
		||||
#include "xedit-debug.h"
 | 
			
		||||
#include "xedit-app.h"
 | 
			
		||||
#include "xedit-prefs-manager.h"
 | 
			
		||||
#include "xedit-plugin-loader.h"
 | 
			
		||||
#include "xedit-object-module.h"
 | 
			
		||||
#include "xedit-dirs.h"
 | 
			
		||||
 | 
			
		||||
#define XEDIT_PLUGINS_ENGINE_BASE_KEY "/apps/xedit/plugins"
 | 
			
		||||
#define XEDIT_PLUGINS_ENGINE_KEY XEDIT_PLUGINS_ENGINE_BASE_KEY "/active-plugins"
 | 
			
		||||
 | 
			
		||||
#define PLUGIN_EXT	".xedit-plugin"
 | 
			
		||||
#define LOADER_EXT	G_MODULE_SUFFIX
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
	XeditPluginLoader *loader;
 | 
			
		||||
	XeditObjectModule *module;
 | 
			
		||||
} LoaderInfo;
 | 
			
		||||
 | 
			
		||||
/* Signals */
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
	ACTIVATE_PLUGIN,
 | 
			
		||||
	DEACTIVATE_PLUGIN,
 | 
			
		||||
	LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0 };
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE(XeditPluginsEngine, xedit_plugins_engine, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
struct _XeditPluginsEnginePrivate
 | 
			
		||||
{
 | 
			
		||||
	GList *plugin_list;
 | 
			
		||||
	GHashTable *loaders;
 | 
			
		||||
 | 
			
		||||
	gboolean activate_from_prefs;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
XeditPluginsEngine *default_engine = NULL;
 | 
			
		||||
 | 
			
		||||
static void	xedit_plugins_engine_activate_plugin_real (XeditPluginsEngine *engine,
 | 
			
		||||
							   XeditPluginInfo    *info);
 | 
			
		||||
static void	xedit_plugins_engine_deactivate_plugin_real (XeditPluginsEngine *engine,
 | 
			
		||||
							     XeditPluginInfo    *info);
 | 
			
		||||
 | 
			
		||||
typedef gboolean (*LoadDirCallback)(XeditPluginsEngine *engine, const gchar *filename, gpointer userdata);
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
load_dir_real (XeditPluginsEngine *engine,
 | 
			
		||||
	       const gchar        *dir,
 | 
			
		||||
	       const gchar        *suffix,
 | 
			
		||||
	       LoadDirCallback     callback,
 | 
			
		||||
	       gpointer            userdata)
 | 
			
		||||
{
 | 
			
		||||
	GError *error = NULL;
 | 
			
		||||
	GDir *d;
 | 
			
		||||
	const gchar *dirent;
 | 
			
		||||
	gboolean ret = TRUE;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (dir != NULL, TRUE);
 | 
			
		||||
 | 
			
		||||
	xedit_debug_message (DEBUG_PLUGINS, "DIR: %s", dir);
 | 
			
		||||
 | 
			
		||||
	d = g_dir_open (dir, 0, &error);
 | 
			
		||||
	if (!d)
 | 
			
		||||
	{
 | 
			
		||||
		g_warning ("%s", error->message);
 | 
			
		||||
		g_error_free (error);
 | 
			
		||||
		return TRUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	while ((dirent = g_dir_read_name (d)))
 | 
			
		||||
	{
 | 
			
		||||
		gchar *filename;
 | 
			
		||||
 | 
			
		||||
		if (!g_str_has_suffix (dirent, suffix))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		filename = g_build_filename (dir, dirent, NULL);
 | 
			
		||||
 | 
			
		||||
		ret = callback (engine, filename, userdata);
 | 
			
		||||
 | 
			
		||||
		g_free (filename);
 | 
			
		||||
 | 
			
		||||
		if (!ret)
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_dir_close (d);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
load_plugin_info (XeditPluginsEngine *engine,
 | 
			
		||||
		  const gchar        *filename,
 | 
			
		||||
		  gpointer            userdata)
 | 
			
		||||
{
 | 
			
		||||
	XeditPluginInfo *info;
 | 
			
		||||
 | 
			
		||||
	info = _xedit_plugin_info_new (filename);
 | 
			
		||||
 | 
			
		||||
	if (info == NULL)
 | 
			
		||||
		return TRUE;
 | 
			
		||||
 | 
			
		||||
	/* If a plugin with this name has already been loaded
 | 
			
		||||
	 * drop this one (user plugins override system plugins) */
 | 
			
		||||
	if (xedit_plugins_engine_get_plugin_info (engine, xedit_plugin_info_get_module_name (info)) != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		xedit_debug_message (DEBUG_PLUGINS, "Two or more plugins named '%s'. "
 | 
			
		||||
				     "Only the first will be considered.\n",
 | 
			
		||||
				     xedit_plugin_info_get_module_name (info));
 | 
			
		||||
 | 
			
		||||
		_xedit_plugin_info_unref (info);
 | 
			
		||||
 | 
			
		||||
		return TRUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	engine->priv->plugin_list = g_list_prepend (engine->priv->plugin_list, info);
 | 
			
		||||
 | 
			
		||||
	xedit_debug_message (DEBUG_PLUGINS, "Plugin %s loaded", info->name);
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
load_all_plugins (XeditPluginsEngine *engine)
 | 
			
		||||
{
 | 
			
		||||
	gchar *plugin_dir;
 | 
			
		||||
	const gchar *pdirs_env = NULL;
 | 
			
		||||
 | 
			
		||||
	/* load user plugins */
 | 
			
		||||
	plugin_dir = xedit_dirs_get_user_plugins_dir ();
 | 
			
		||||
	if (g_file_test (plugin_dir, G_FILE_TEST_IS_DIR))
 | 
			
		||||
	{
 | 
			
		||||
		load_dir_real (engine,
 | 
			
		||||
			       plugin_dir,
 | 
			
		||||
			       PLUGIN_EXT,
 | 
			
		||||
			       load_plugin_info,
 | 
			
		||||
			       NULL);
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	g_free (plugin_dir);
 | 
			
		||||
 | 
			
		||||
	/* load system plugins */
 | 
			
		||||
	pdirs_env = g_getenv ("XEDIT_PLUGINS_PATH");
 | 
			
		||||
 | 
			
		||||
	xedit_debug_message (DEBUG_PLUGINS, "XEDIT_PLUGINS_PATH=%s", pdirs_env);
 | 
			
		||||
 | 
			
		||||
	if (pdirs_env != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		gchar **pdirs;
 | 
			
		||||
		gint i;
 | 
			
		||||
 | 
			
		||||
		pdirs = g_strsplit (pdirs_env, G_SEARCHPATH_SEPARATOR_S, 0);
 | 
			
		||||
 | 
			
		||||
		for (i = 0; pdirs[i] != NULL; i++)
 | 
			
		||||
		{
 | 
			
		||||
			if (!load_dir_real (engine,
 | 
			
		||||
					    pdirs[i],
 | 
			
		||||
					    PLUGIN_EXT,
 | 
			
		||||
					    load_plugin_info,
 | 
			
		||||
					    NULL))
 | 
			
		||||
			{
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		g_strfreev (pdirs);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		plugin_dir = xedit_dirs_get_xedit_plugins_dir ();
 | 
			
		||||
 | 
			
		||||
		load_dir_real (engine,
 | 
			
		||||
			       plugin_dir,
 | 
			
		||||
			       PLUGIN_EXT,
 | 
			
		||||
			       load_plugin_info,
 | 
			
		||||
			       NULL);
 | 
			
		||||
 | 
			
		||||
		g_free (plugin_dir);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static guint
 | 
			
		||||
hash_lowercase (gconstpointer data)
 | 
			
		||||
{
 | 
			
		||||
	gchar *lowercase;
 | 
			
		||||
	guint ret;
 | 
			
		||||
 | 
			
		||||
	lowercase = g_ascii_strdown ((const gchar *)data, -1);
 | 
			
		||||
	ret = g_str_hash (lowercase);
 | 
			
		||||
	g_free (lowercase);
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
equal_lowercase (gconstpointer a, gconstpointer b)
 | 
			
		||||
{
 | 
			
		||||
	return g_ascii_strcasecmp ((const gchar *)a, (const gchar *)b) == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
loader_destroy (LoaderInfo *info)
 | 
			
		||||
{
 | 
			
		||||
	if (!info)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (info->loader)
 | 
			
		||||
		g_object_unref (info->loader);
 | 
			
		||||
 | 
			
		||||
	g_free (info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
add_loader (XeditPluginsEngine *engine,
 | 
			
		||||
	    const gchar        *loader_id,
 | 
			
		||||
	    XeditObjectModule  *module)
 | 
			
		||||
{
 | 
			
		||||
	LoaderInfo *info;
 | 
			
		||||
 | 
			
		||||
	info = g_new (LoaderInfo, 1);
 | 
			
		||||
	info->loader = NULL;
 | 
			
		||||
	info->module = module;
 | 
			
		||||
 | 
			
		||||
	g_hash_table_insert (engine->priv->loaders, g_strdup (loader_id), info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_plugins_engine_init (XeditPluginsEngine *engine)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_PLUGINS);
 | 
			
		||||
 | 
			
		||||
	if (!g_module_supported ())
 | 
			
		||||
	{
 | 
			
		||||
		g_warning ("xedit is not able to initialize the plugins engine.");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	engine->priv = G_TYPE_INSTANCE_GET_PRIVATE (engine,
 | 
			
		||||
						    XEDIT_TYPE_PLUGINS_ENGINE,
 | 
			
		||||
						    XeditPluginsEnginePrivate);
 | 
			
		||||
 | 
			
		||||
	load_all_plugins (engine);
 | 
			
		||||
 | 
			
		||||
	/* make sure that the first reactivation will read active plugins
 | 
			
		||||
	   from the prefs */
 | 
			
		||||
	engine->priv->activate_from_prefs = TRUE;
 | 
			
		||||
 | 
			
		||||
	/* mapping from loadername -> loader object */
 | 
			
		||||
	engine->priv->loaders = g_hash_table_new_full (hash_lowercase,
 | 
			
		||||
						       equal_lowercase,
 | 
			
		||||
						       (GDestroyNotify)g_free,
 | 
			
		||||
						       (GDestroyNotify)loader_destroy);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
loader_garbage_collect (const char *id, LoaderInfo *info)
 | 
			
		||||
{
 | 
			
		||||
	if (info->loader)
 | 
			
		||||
		xedit_plugin_loader_garbage_collect (info->loader);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_plugins_engine_garbage_collect (XeditPluginsEngine *engine)
 | 
			
		||||
{
 | 
			
		||||
	g_hash_table_foreach (engine->priv->loaders,
 | 
			
		||||
			      (GHFunc) loader_garbage_collect,
 | 
			
		||||
			      NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_plugins_engine_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
	XeditPluginsEngine *engine = XEDIT_PLUGINS_ENGINE (object);
 | 
			
		||||
	GList *item;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_PLUGINS);
 | 
			
		||||
 | 
			
		||||
	/* Firs deactivate all plugins */
 | 
			
		||||
	for (item = engine->priv->plugin_list; item; item = item->next)
 | 
			
		||||
	{
 | 
			
		||||
		XeditPluginInfo *info = XEDIT_PLUGIN_INFO (item->data);
 | 
			
		||||
 | 
			
		||||
		if (xedit_plugin_info_is_active (info))
 | 
			
		||||
			xedit_plugins_engine_deactivate_plugin_real (engine, info);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* unref the loaders */
 | 
			
		||||
	g_hash_table_destroy (engine->priv->loaders);
 | 
			
		||||
 | 
			
		||||
	/* and finally free the infos */
 | 
			
		||||
	for (item = engine->priv->plugin_list; item; item = item->next)
 | 
			
		||||
	{
 | 
			
		||||
		XeditPluginInfo *info = XEDIT_PLUGIN_INFO (item->data);
 | 
			
		||||
 | 
			
		||||
		_xedit_plugin_info_unref (info);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_list_free (engine->priv->plugin_list);
 | 
			
		||||
 | 
			
		||||
	G_OBJECT_CLASS (xedit_plugins_engine_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_plugins_engine_class_init (XeditPluginsEngineClass *klass)
 | 
			
		||||
{
 | 
			
		||||
	GType the_type = G_TYPE_FROM_CLASS (klass);
 | 
			
		||||
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
	object_class->finalize = xedit_plugins_engine_finalize;
 | 
			
		||||
	klass->activate_plugin = xedit_plugins_engine_activate_plugin_real;
 | 
			
		||||
	klass->deactivate_plugin = xedit_plugins_engine_deactivate_plugin_real;
 | 
			
		||||
 | 
			
		||||
	signals[ACTIVATE_PLUGIN] =
 | 
			
		||||
		g_signal_new ("activate-plugin",
 | 
			
		||||
			      the_type,
 | 
			
		||||
			      G_SIGNAL_RUN_LAST,
 | 
			
		||||
			      G_STRUCT_OFFSET (XeditPluginsEngineClass, activate_plugin),
 | 
			
		||||
			      NULL, NULL,
 | 
			
		||||
			      g_cclosure_marshal_VOID__BOXED,
 | 
			
		||||
			      G_TYPE_NONE,
 | 
			
		||||
			      1,
 | 
			
		||||
			      XEDIT_TYPE_PLUGIN_INFO | G_SIGNAL_TYPE_STATIC_SCOPE);
 | 
			
		||||
 | 
			
		||||
	signals[DEACTIVATE_PLUGIN] =
 | 
			
		||||
		g_signal_new ("deactivate-plugin",
 | 
			
		||||
			      the_type,
 | 
			
		||||
			      G_SIGNAL_RUN_LAST,
 | 
			
		||||
			      G_STRUCT_OFFSET (XeditPluginsEngineClass, deactivate_plugin),
 | 
			
		||||
			      NULL, NULL,
 | 
			
		||||
			      g_cclosure_marshal_VOID__BOXED,
 | 
			
		||||
			      G_TYPE_NONE,
 | 
			
		||||
			      1,
 | 
			
		||||
			      XEDIT_TYPE_PLUGIN_INFO | G_SIGNAL_TYPE_STATIC_SCOPE);
 | 
			
		||||
 | 
			
		||||
	g_type_class_add_private (klass, sizeof (XeditPluginsEnginePrivate));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
load_loader (XeditPluginsEngine *engine,
 | 
			
		||||
	     const gchar        *filename,
 | 
			
		||||
	     gpointer		 data)
 | 
			
		||||
{
 | 
			
		||||
	XeditObjectModule *module;
 | 
			
		||||
	gchar *base;
 | 
			
		||||
	gchar *path;
 | 
			
		||||
	const gchar *id;
 | 
			
		||||
	GType type;
 | 
			
		||||
 | 
			
		||||
	/* try to load in the module */
 | 
			
		||||
	path = g_path_get_dirname (filename);
 | 
			
		||||
	base = g_path_get_basename (filename);
 | 
			
		||||
 | 
			
		||||
	/* for now they are all resident */
 | 
			
		||||
	module = xedit_object_module_new (base,
 | 
			
		||||
					  path,
 | 
			
		||||
					  "register_xedit_plugin_loader",
 | 
			
		||||
					  TRUE);
 | 
			
		||||
 | 
			
		||||
	g_free (base);
 | 
			
		||||
	g_free (path);
 | 
			
		||||
 | 
			
		||||
	/* make sure to load the type definition */
 | 
			
		||||
	if (!g_type_module_use (G_TYPE_MODULE (module)))
 | 
			
		||||
	{
 | 
			
		||||
		g_object_unref (module);
 | 
			
		||||
		g_warning ("Plugin loader module `%s' could not be loaded", filename);
 | 
			
		||||
 | 
			
		||||
		return TRUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* get the exported type and check the name as exported by the
 | 
			
		||||
	 * loader interface */
 | 
			
		||||
	type = xedit_object_module_get_object_type (module);
 | 
			
		||||
	id = xedit_plugin_loader_type_get_id (type);
 | 
			
		||||
 | 
			
		||||
	add_loader (engine, id, module);
 | 
			
		||||
	g_type_module_unuse (G_TYPE_MODULE (module));
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
ensure_loader (LoaderInfo *info)
 | 
			
		||||
{
 | 
			
		||||
	if (info->loader == NULL && info->module != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		/* create a new loader object */
 | 
			
		||||
		XeditPluginLoader *loader;
 | 
			
		||||
		loader = (XeditPluginLoader *)xedit_object_module_new_object (info->module, NULL);
 | 
			
		||||
 | 
			
		||||
		if (loader == NULL || !XEDIT_IS_PLUGIN_LOADER (loader))
 | 
			
		||||
		{
 | 
			
		||||
			g_warning ("Loader object is not a valid XeditPluginLoader instance");
 | 
			
		||||
 | 
			
		||||
			if (loader != NULL && G_IS_OBJECT (loader))
 | 
			
		||||
				g_object_unref (loader);
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			info->loader = loader;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static XeditPluginLoader *
 | 
			
		||||
get_plugin_loader (XeditPluginsEngine *engine, XeditPluginInfo *info)
 | 
			
		||||
{
 | 
			
		||||
	const gchar *loader_id;
 | 
			
		||||
	LoaderInfo *loader_info;
 | 
			
		||||
 | 
			
		||||
	loader_id = info->loader;
 | 
			
		||||
 | 
			
		||||
	loader_info = (LoaderInfo *)g_hash_table_lookup (
 | 
			
		||||
			engine->priv->loaders,
 | 
			
		||||
			loader_id);
 | 
			
		||||
 | 
			
		||||
	if (loader_info == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		gchar *loader_dir;
 | 
			
		||||
 | 
			
		||||
		loader_dir = xedit_dirs_get_xedit_plugin_loaders_dir ();
 | 
			
		||||
 | 
			
		||||
		/* loader could not be found in the hash, try to find it by
 | 
			
		||||
		   scanning */
 | 
			
		||||
		load_dir_real (engine,
 | 
			
		||||
			       loader_dir,
 | 
			
		||||
			       LOADER_EXT,
 | 
			
		||||
			       (LoadDirCallback)load_loader,
 | 
			
		||||
			       NULL);
 | 
			
		||||
		g_free (loader_dir);
 | 
			
		||||
 | 
			
		||||
		loader_info = (LoaderInfo *)g_hash_table_lookup (
 | 
			
		||||
				engine->priv->loaders,
 | 
			
		||||
				loader_id);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (loader_info == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		/* cache non-existent so we don't scan again */
 | 
			
		||||
		add_loader (engine, loader_id, NULL);
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ensure_loader (loader_info);
 | 
			
		||||
	return loader_info->loader;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
XeditPluginsEngine *
 | 
			
		||||
xedit_plugins_engine_get_default (void)
 | 
			
		||||
{
 | 
			
		||||
	if (default_engine != NULL)
 | 
			
		||||
		return default_engine;
 | 
			
		||||
 | 
			
		||||
	default_engine = XEDIT_PLUGINS_ENGINE (g_object_new (XEDIT_TYPE_PLUGINS_ENGINE, NULL));
 | 
			
		||||
	g_object_add_weak_pointer (G_OBJECT (default_engine),
 | 
			
		||||
				   (gpointer) &default_engine);
 | 
			
		||||
	return default_engine;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const GList *
 | 
			
		||||
xedit_plugins_engine_get_plugin_list (XeditPluginsEngine *engine)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_PLUGINS);
 | 
			
		||||
 | 
			
		||||
	return engine->priv->plugin_list;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gint
 | 
			
		||||
compare_plugin_info_and_name (XeditPluginInfo *info,
 | 
			
		||||
			      const gchar *module_name)
 | 
			
		||||
{
 | 
			
		||||
	return strcmp (xedit_plugin_info_get_module_name (info), module_name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
XeditPluginInfo *
 | 
			
		||||
xedit_plugins_engine_get_plugin_info (XeditPluginsEngine *engine,
 | 
			
		||||
				      const gchar        *name)
 | 
			
		||||
{
 | 
			
		||||
	GList *l = g_list_find_custom (engine->priv->plugin_list,
 | 
			
		||||
				       name,
 | 
			
		||||
				       (GCompareFunc) compare_plugin_info_and_name);
 | 
			
		||||
 | 
			
		||||
	return l == NULL ? NULL : (XeditPluginInfo *) l->data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
save_active_plugin_list (XeditPluginsEngine *engine)
 | 
			
		||||
{
 | 
			
		||||
	GSList *active_plugins = NULL;
 | 
			
		||||
	GList *l;
 | 
			
		||||
 | 
			
		||||
	for (l = engine->priv->plugin_list; l != NULL; l = l->next)
 | 
			
		||||
	{
 | 
			
		||||
		XeditPluginInfo *info = (XeditPluginInfo *) l->data;
 | 
			
		||||
 | 
			
		||||
		if (xedit_plugin_info_is_active (info))
 | 
			
		||||
		{
 | 
			
		||||
			active_plugins = g_slist_prepend (active_plugins,
 | 
			
		||||
							  (gpointer)xedit_plugin_info_get_module_name (info));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	xedit_prefs_manager_set_active_plugins (active_plugins);
 | 
			
		||||
 | 
			
		||||
	g_slist_free (active_plugins);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
load_plugin (XeditPluginsEngine *engine,
 | 
			
		||||
	     XeditPluginInfo    *info)
 | 
			
		||||
{
 | 
			
		||||
	XeditPluginLoader *loader;
 | 
			
		||||
	gchar *path;
 | 
			
		||||
 | 
			
		||||
	if (xedit_plugin_info_is_active (info))
 | 
			
		||||
		return TRUE;
 | 
			
		||||
 | 
			
		||||
	if (!xedit_plugin_info_is_available (info))
 | 
			
		||||
		return FALSE;
 | 
			
		||||
 | 
			
		||||
	loader = get_plugin_loader (engine, info);
 | 
			
		||||
 | 
			
		||||
	if (loader == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		g_warning ("Could not find loader `%s' for plugin `%s'", info->loader, info->name);
 | 
			
		||||
		info->available = FALSE;
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	path = g_path_get_dirname (info->file);
 | 
			
		||||
	g_return_val_if_fail (path != NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
	info->plugin = xedit_plugin_loader_load (loader, info, path);
 | 
			
		||||
 | 
			
		||||
	g_free (path);
 | 
			
		||||
 | 
			
		||||
	if (info->plugin == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		g_warning ("Error loading plugin '%s'", info->name);
 | 
			
		||||
		info->available = FALSE;
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_plugins_engine_activate_plugin_real (XeditPluginsEngine *engine,
 | 
			
		||||
					   XeditPluginInfo *info)
 | 
			
		||||
{
 | 
			
		||||
	const GList *wins;
 | 
			
		||||
 | 
			
		||||
	if (!load_plugin (engine, info))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	for (wins = xedit_app_get_windows (xedit_app_get_default ());
 | 
			
		||||
	     wins != NULL;
 | 
			
		||||
	     wins = wins->next)
 | 
			
		||||
	{
 | 
			
		||||
		xedit_plugin_activate (info->plugin, XEDIT_WINDOW (wins->data));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_plugins_engine_activate_plugin (XeditPluginsEngine *engine,
 | 
			
		||||
				      XeditPluginInfo    *info)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_PLUGINS);
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (info != NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
	if (!xedit_plugin_info_is_available (info))
 | 
			
		||||
		return FALSE;
 | 
			
		||||
 | 
			
		||||
	if (xedit_plugin_info_is_active (info))
 | 
			
		||||
		return TRUE;
 | 
			
		||||
 | 
			
		||||
	g_signal_emit (engine, signals[ACTIVATE_PLUGIN], 0, info);
 | 
			
		||||
 | 
			
		||||
	if (xedit_plugin_info_is_active (info))
 | 
			
		||||
		save_active_plugin_list (engine);
 | 
			
		||||
 | 
			
		||||
	return xedit_plugin_info_is_active (info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
call_plugin_deactivate (XeditPlugin *plugin,
 | 
			
		||||
			XeditWindow *window)
 | 
			
		||||
{
 | 
			
		||||
	xedit_plugin_deactivate (plugin, window);
 | 
			
		||||
 | 
			
		||||
	/* ensure update of ui manager, because we suspect it does something
 | 
			
		||||
	   with expected static strings in the type module (when unloaded the
 | 
			
		||||
	   strings don't exist anymore, and ui manager updates in an idle
 | 
			
		||||
	   func) */
 | 
			
		||||
	gtk_ui_manager_ensure_update (xedit_window_get_ui_manager (window));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xedit_plugins_engine_deactivate_plugin_real (XeditPluginsEngine *engine,
 | 
			
		||||
					     XeditPluginInfo *info)
 | 
			
		||||
{
 | 
			
		||||
	const GList *wins;
 | 
			
		||||
	XeditPluginLoader *loader;
 | 
			
		||||
 | 
			
		||||
	if (!xedit_plugin_info_is_active (info) ||
 | 
			
		||||
	    !xedit_plugin_info_is_available (info))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	for (wins = xedit_app_get_windows (xedit_app_get_default ());
 | 
			
		||||
	     wins != NULL;
 | 
			
		||||
	     wins = wins->next)
 | 
			
		||||
	{
 | 
			
		||||
		call_plugin_deactivate (info->plugin, XEDIT_WINDOW (wins->data));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* first unref the plugin (the loader still has one) */
 | 
			
		||||
	g_object_unref (info->plugin);
 | 
			
		||||
 | 
			
		||||
	/* find the loader and tell it to gc and unload the plugin */
 | 
			
		||||
	loader = get_plugin_loader (engine, info);
 | 
			
		||||
 | 
			
		||||
	xedit_plugin_loader_garbage_collect (loader);
 | 
			
		||||
	xedit_plugin_loader_unload (loader, info);
 | 
			
		||||
 | 
			
		||||
	info->plugin = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_plugins_engine_deactivate_plugin (XeditPluginsEngine *engine,
 | 
			
		||||
					XeditPluginInfo    *info)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_PLUGINS);
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (info != NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
	if (!xedit_plugin_info_is_active (info))
 | 
			
		||||
		return TRUE;
 | 
			
		||||
 | 
			
		||||
	g_signal_emit (engine, signals[DEACTIVATE_PLUGIN], 0, info);
 | 
			
		||||
	if (!xedit_plugin_info_is_active (info))
 | 
			
		||||
		save_active_plugin_list (engine);
 | 
			
		||||
 | 
			
		||||
	return !xedit_plugin_info_is_active (info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_plugins_engine_activate_plugins (XeditPluginsEngine *engine,
 | 
			
		||||
					XeditWindow        *window)
 | 
			
		||||
{
 | 
			
		||||
	GSList *active_plugins = NULL;
 | 
			
		||||
	GList *pl;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_PLUGINS);
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_PLUGINS_ENGINE (engine));
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_WINDOW (window));
 | 
			
		||||
 | 
			
		||||
	/* the first time, we get the 'active' plugins from GSettings */
 | 
			
		||||
	if (engine->priv->activate_from_prefs)
 | 
			
		||||
	{
 | 
			
		||||
		active_plugins = xedit_prefs_manager_get_active_plugins ();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (pl = engine->priv->plugin_list; pl; pl = pl->next)
 | 
			
		||||
	{
 | 
			
		||||
		XeditPluginInfo *info = (XeditPluginInfo*)pl->data;
 | 
			
		||||
 | 
			
		||||
		if (engine->priv->activate_from_prefs &&
 | 
			
		||||
		    g_slist_find_custom (active_plugins,
 | 
			
		||||
					 xedit_plugin_info_get_module_name (info),
 | 
			
		||||
					 (GCompareFunc)strcmp) == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		/* If plugin is not active, don't try to activate/load it */
 | 
			
		||||
		if (!engine->priv->activate_from_prefs &&
 | 
			
		||||
		    !xedit_plugin_info_is_active (info))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (load_plugin (engine, info))
 | 
			
		||||
			xedit_plugin_activate (info->plugin,
 | 
			
		||||
					       window);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (engine->priv->activate_from_prefs)
 | 
			
		||||
	{
 | 
			
		||||
		g_slist_foreach (active_plugins, (GFunc) g_free, NULL);
 | 
			
		||||
		g_slist_free (active_plugins);
 | 
			
		||||
		engine->priv->activate_from_prefs = FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	xedit_debug_message (DEBUG_PLUGINS, "End");
 | 
			
		||||
 | 
			
		||||
	/* also call update_ui after activation */
 | 
			
		||||
	xedit_plugins_engine_update_plugins_ui (engine, window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_plugins_engine_deactivate_plugins (XeditPluginsEngine *engine,
 | 
			
		||||
					  XeditWindow        *window)
 | 
			
		||||
{
 | 
			
		||||
	GList *pl;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_PLUGINS);
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_PLUGINS_ENGINE (engine));
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_WINDOW (window));
 | 
			
		||||
 | 
			
		||||
	for (pl = engine->priv->plugin_list; pl; pl = pl->next)
 | 
			
		||||
	{
 | 
			
		||||
		XeditPluginInfo *info = (XeditPluginInfo*)pl->data;
 | 
			
		||||
 | 
			
		||||
		/* check if the plugin is actually active */
 | 
			
		||||
		if (!xedit_plugin_info_is_active (info))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		/* call deactivate for the plugin for this window */
 | 
			
		||||
		xedit_plugin_deactivate (info->plugin, window);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	xedit_debug_message (DEBUG_PLUGINS, "End");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_plugins_engine_update_plugins_ui (XeditPluginsEngine *engine,
 | 
			
		||||
					 XeditWindow        *window)
 | 
			
		||||
{
 | 
			
		||||
	GList *pl;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_PLUGINS);
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_PLUGINS_ENGINE (engine));
 | 
			
		||||
	g_return_if_fail (XEDIT_IS_WINDOW (window));
 | 
			
		||||
 | 
			
		||||
	/* call update_ui for all active plugins */
 | 
			
		||||
	for (pl = engine->priv->plugin_list; pl; pl = pl->next)
 | 
			
		||||
	{
 | 
			
		||||
		XeditPluginInfo *info = (XeditPluginInfo*)pl->data;
 | 
			
		||||
 | 
			
		||||
		if (!xedit_plugin_info_is_active (info))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
	       	xedit_debug_message (DEBUG_PLUGINS, "Updating UI of %s", info->name);
 | 
			
		||||
		xedit_plugin_update_ui (info->plugin, window);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_plugins_engine_configure_plugin (XeditPluginsEngine *engine,
 | 
			
		||||
				       XeditPluginInfo    *info,
 | 
			
		||||
				       GtkWindow          *parent)
 | 
			
		||||
{
 | 
			
		||||
	GtkWidget *conf_dlg;
 | 
			
		||||
 | 
			
		||||
	GtkWindowGroup *wg;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_PLUGINS);
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (info != NULL);
 | 
			
		||||
 | 
			
		||||
	conf_dlg = xedit_plugin_create_configure_dialog (info->plugin);
 | 
			
		||||
	g_return_if_fail (conf_dlg != NULL);
 | 
			
		||||
	gtk_window_set_transient_for (GTK_WINDOW (conf_dlg),
 | 
			
		||||
				      parent);
 | 
			
		||||
 | 
			
		||||
	wg = gtk_window_get_group (parent);
 | 
			
		||||
	if (wg == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		wg = gtk_window_group_new ();
 | 
			
		||||
		gtk_window_group_add_window (wg, parent);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gtk_window_group_add_window (wg,
 | 
			
		||||
				     GTK_WINDOW (conf_dlg));
 | 
			
		||||
 | 
			
		||||
	gtk_window_set_modal (GTK_WINDOW (conf_dlg), TRUE);
 | 
			
		||||
	gtk_widget_show (conf_dlg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_plugins_engine_active_plugins_changed (XeditPluginsEngine *engine)
 | 
			
		||||
{
 | 
			
		||||
	gboolean to_activate;
 | 
			
		||||
	GSList *active_plugins;
 | 
			
		||||
	GList *pl;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_PLUGINS);
 | 
			
		||||
 | 
			
		||||
	active_plugins = xedit_prefs_manager_get_active_plugins ();
 | 
			
		||||
 | 
			
		||||
	for (pl = engine->priv->plugin_list; pl; pl = pl->next)
 | 
			
		||||
	{
 | 
			
		||||
		XeditPluginInfo *info = (XeditPluginInfo*)pl->data;
 | 
			
		||||
 | 
			
		||||
		if (!xedit_plugin_info_is_available (info))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		to_activate = (g_slist_find_custom (active_plugins,
 | 
			
		||||
						    xedit_plugin_info_get_module_name (info),
 | 
			
		||||
						    (GCompareFunc)strcmp) != NULL);
 | 
			
		||||
 | 
			
		||||
		if (!xedit_plugin_info_is_active (info) && to_activate)
 | 
			
		||||
			g_signal_emit (engine, signals[ACTIVATE_PLUGIN], 0, info);
 | 
			
		||||
		else if (xedit_plugin_info_is_active (info) && !to_activate)
 | 
			
		||||
			g_signal_emit (engine, signals[DEACTIVATE_PLUGIN], 0, info);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_slist_foreach (active_plugins, (GFunc) g_free, NULL);
 | 
			
		||||
	g_slist_free (active_plugins);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_plugins_engine_rescan_plugins (XeditPluginsEngine *engine)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_PLUGINS);
 | 
			
		||||
 | 
			
		||||
	load_all_plugins (engine);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										107
									
								
								xedit/xedit-plugins-engine.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								xedit/xedit-plugins-engine.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,107 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-plugins-engine.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2002-2005 - Paolo Maggi 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA. 
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2002-2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_PLUGINS_ENGINE_H__
 | 
			
		||||
#define __XEDIT_PLUGINS_ENGINE_H__
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
#include "xedit-window.h"
 | 
			
		||||
#include "xedit-plugin-info.h"
 | 
			
		||||
#include "xedit-plugin.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define XEDIT_TYPE_PLUGINS_ENGINE              (xedit_plugins_engine_get_type ())
 | 
			
		||||
#define XEDIT_PLUGINS_ENGINE(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), XEDIT_TYPE_PLUGINS_ENGINE, XeditPluginsEngine))
 | 
			
		||||
#define XEDIT_PLUGINS_ENGINE_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), XEDIT_TYPE_PLUGINS_ENGINE, XeditPluginsEngineClass))
 | 
			
		||||
#define XEDIT_IS_PLUGINS_ENGINE(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), XEDIT_TYPE_PLUGINS_ENGINE))
 | 
			
		||||
#define XEDIT_IS_PLUGINS_ENGINE_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), XEDIT_TYPE_PLUGINS_ENGINE))
 | 
			
		||||
#define XEDIT_PLUGINS_ENGINE_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), XEDIT_TYPE_PLUGINS_ENGINE, XeditPluginsEngineClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _XeditPluginsEngine		XeditPluginsEngine;
 | 
			
		||||
typedef struct _XeditPluginsEnginePrivate	XeditPluginsEnginePrivate;
 | 
			
		||||
 | 
			
		||||
struct _XeditPluginsEngine
 | 
			
		||||
{
 | 
			
		||||
	GObject parent;
 | 
			
		||||
	XeditPluginsEnginePrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct _XeditPluginsEngineClass		XeditPluginsEngineClass;
 | 
			
		||||
 | 
			
		||||
struct _XeditPluginsEngineClass
 | 
			
		||||
{
 | 
			
		||||
	GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
	void	 (* activate_plugin)		(XeditPluginsEngine *engine,
 | 
			
		||||
						 XeditPluginInfo    *info);
 | 
			
		||||
 | 
			
		||||
	void	 (* deactivate_plugin)		(XeditPluginsEngine *engine,
 | 
			
		||||
						 XeditPluginInfo    *info);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType			 xedit_plugins_engine_get_type		(void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
XeditPluginsEngine	*xedit_plugins_engine_get_default	(void);
 | 
			
		||||
 | 
			
		||||
void		 xedit_plugins_engine_garbage_collect	(XeditPluginsEngine *engine);
 | 
			
		||||
 | 
			
		||||
const GList	*xedit_plugins_engine_get_plugin_list 	(XeditPluginsEngine *engine);
 | 
			
		||||
 | 
			
		||||
XeditPluginInfo	*xedit_plugins_engine_get_plugin_info	(XeditPluginsEngine *engine,
 | 
			
		||||
							 const gchar        *name);
 | 
			
		||||
 | 
			
		||||
/* plugin load and unloading (overall, for all windows) */
 | 
			
		||||
gboolean 	 xedit_plugins_engine_activate_plugin 	(XeditPluginsEngine *engine,
 | 
			
		||||
							 XeditPluginInfo    *info);
 | 
			
		||||
gboolean 	 xedit_plugins_engine_deactivate_plugin	(XeditPluginsEngine *engine,
 | 
			
		||||
							 XeditPluginInfo    *info);
 | 
			
		||||
 | 
			
		||||
void	 	 xedit_plugins_engine_configure_plugin	(XeditPluginsEngine *engine,
 | 
			
		||||
							 XeditPluginInfo    *info,
 | 
			
		||||
							 GtkWindow          *parent);
 | 
			
		||||
 | 
			
		||||
/* plugin activation/deactivation per window, private to XeditWindow */
 | 
			
		||||
void 		 xedit_plugins_engine_activate_plugins   (XeditPluginsEngine *engine,
 | 
			
		||||
							  XeditWindow        *window);
 | 
			
		||||
void 		 xedit_plugins_engine_deactivate_plugins (XeditPluginsEngine *engine,
 | 
			
		||||
							  XeditWindow        *window);
 | 
			
		||||
void		 xedit_plugins_engine_update_plugins_ui  (XeditPluginsEngine *engine,
 | 
			
		||||
							  XeditWindow        *window);
 | 
			
		||||
 | 
			
		||||
/* private for GSettings notification */
 | 
			
		||||
void		 xedit_plugins_engine_active_plugins_changed
 | 
			
		||||
							(XeditPluginsEngine *engine);
 | 
			
		||||
 | 
			
		||||
void		 xedit_plugins_engine_rescan_plugins	(XeditPluginsEngine *engine);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif  /* __XEDIT_PLUGINS_ENGINE_H__ */
 | 
			
		||||
							
								
								
									
										1475
									
								
								xedit/xedit-prefs-manager-app.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1475
									
								
								xedit/xedit-prefs-manager-app.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										84
									
								
								xedit/xedit-prefs-manager-app.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								xedit/xedit-prefs-manager-app.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,84 @@
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-prefs-manager-app.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2002-2005  Paolo Maggi 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA. 
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2002-2005. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_PREFS_MANAGER_APP_H__
 | 
			
		||||
#define __XEDIT_PREFS_MANAGER_APP_H__
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
#include <xedit/xedit-prefs-manager.h>
 | 
			
		||||
 | 
			
		||||
/** LIFE CYCLE MANAGEMENT FUNCTIONS **/
 | 
			
		||||
 | 
			
		||||
gboolean	 xedit_prefs_manager_app_init			(void);
 | 
			
		||||
 | 
			
		||||
/* This function must be called before exiting xedit */
 | 
			
		||||
void		 xedit_prefs_manager_app_shutdown		(void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Window state */
 | 
			
		||||
gint		 xedit_prefs_manager_get_window_state		(void);
 | 
			
		||||
void 		 xedit_prefs_manager_set_window_state		(gint ws);
 | 
			
		||||
gboolean	 xedit_prefs_manager_window_state_can_set	(void);
 | 
			
		||||
 | 
			
		||||
/* Window size */
 | 
			
		||||
void		 xedit_prefs_manager_get_window_size		(gint *width,
 | 
			
		||||
								 gint *height);
 | 
			
		||||
void		 xedit_prefs_manager_get_default_window_size	(gint *width,
 | 
			
		||||
								 gint *height);
 | 
			
		||||
void 		 xedit_prefs_manager_set_window_size		(gint width,
 | 
			
		||||
								 gint height);
 | 
			
		||||
gboolean	 xedit_prefs_manager_window_size_can_set	(void);
 | 
			
		||||
 | 
			
		||||
/* Side panel */
 | 
			
		||||
gint	 	 xedit_prefs_manager_get_side_panel_size	(void);
 | 
			
		||||
gint	 	 xedit_prefs_manager_get_default_side_panel_size(void);
 | 
			
		||||
void 		 xedit_prefs_manager_set_side_panel_size	(gint ps);
 | 
			
		||||
gboolean	 xedit_prefs_manager_side_panel_size_can_set	(void);
 | 
			
		||||
gint		 xedit_prefs_manager_get_side_panel_active_page (void);
 | 
			
		||||
void 		 xedit_prefs_manager_set_side_panel_active_page (gint id);
 | 
			
		||||
gboolean	 xedit_prefs_manager_side_panel_active_page_can_set (void);
 | 
			
		||||
 | 
			
		||||
/* Bottom panel */
 | 
			
		||||
gint	 	 xedit_prefs_manager_get_bottom_panel_size	(void);
 | 
			
		||||
gint	 	 xedit_prefs_manager_get_default_bottom_panel_size(void);
 | 
			
		||||
void 		 xedit_prefs_manager_set_bottom_panel_size	(gint ps);
 | 
			
		||||
gboolean	 xedit_prefs_manager_bottom_panel_size_can_set	(void);
 | 
			
		||||
gint		 xedit_prefs_manager_get_bottom_panel_active_page (void);
 | 
			
		||||
void 		 xedit_prefs_manager_set_bottom_panel_active_page (gint id);
 | 
			
		||||
gboolean	 xedit_prefs_manager_bottom_panel_active_page_can_set (void);
 | 
			
		||||
 | 
			
		||||
/* File filter */
 | 
			
		||||
gint		 xedit_prefs_manager_get_active_file_filter	(void);
 | 
			
		||||
void 		 xedit_prefs_manager_set_active_file_filter	(gint id);
 | 
			
		||||
gboolean	 xedit_prefs_manager_active_file_filter_can_set	(void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* __XEDIT_PREFS_MANAGER_APP_H__ */
 | 
			
		||||
							
								
								
									
										47
									
								
								xedit/xedit-prefs-manager-private.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								xedit/xedit-prefs-manager-private.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-prefs-manager-private.h
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2002  Paolo Maggi 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA. 
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2002. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __XEDIT_PREFS_MANAGER_PRIVATE_H__
 | 
			
		||||
#define __XEDIT_PREFS_MANAGER_PRIVATE_H__
 | 
			
		||||
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
 | 
			
		||||
typedef struct _XeditPrefsManager 	XeditPrefsManager;
 | 
			
		||||
 | 
			
		||||
struct _XeditPrefsManager {
 | 
			
		||||
	GSettings *settings;
 | 
			
		||||
	GSettings *lockdown_settings;
 | 
			
		||||
	GSettings *interface_settings;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern XeditPrefsManager *xedit_prefs_manager;
 | 
			
		||||
 | 
			
		||||
#endif /* __XEDIT_PREFS_MANAGER_PRIVATE_H__ */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										941
									
								
								xedit/xedit-prefs-manager.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										941
									
								
								xedit/xedit-prefs-manager.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,941 @@
 | 
			
		||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 | 
			
		||||
/*
 | 
			
		||||
 * xedit-prefs-manager.c
 | 
			
		||||
 * This file is part of xedit
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2002  Paolo Maggi 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 | 
			
		||||
 * Boston, MA 02110-1301, USA. 
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/*
 | 
			
		||||
 * Modified by the xedit Team, 2002. See the AUTHORS file for a 
 | 
			
		||||
 * list of people on the xedit Team.  
 | 
			
		||||
 * See the ChangeLog files for a list of changes. 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
 | 
			
		||||
#include "xedit-prefs-manager.h"
 | 
			
		||||
#include "xedit-prefs-manager-private.h"
 | 
			
		||||
#include "xedit-debug.h"
 | 
			
		||||
#include "xedit-encodings.h"
 | 
			
		||||
#include "xedit-utils.h"
 | 
			
		||||
 | 
			
		||||
#define DEFINE_BOOL_PREF(name, key) gboolean 				\
 | 
			
		||||
xedit_prefs_manager_get_ ## name (void)					\
 | 
			
		||||
{									\
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);					\
 | 
			
		||||
									\
 | 
			
		||||
	return xedit_prefs_manager_get_bool (key);			\
 | 
			
		||||
}									\
 | 
			
		||||
									\
 | 
			
		||||
void 									\
 | 
			
		||||
xedit_prefs_manager_set_ ## name (gboolean v)				\
 | 
			
		||||
{									\
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);					\
 | 
			
		||||
									\
 | 
			
		||||
	xedit_prefs_manager_set_bool (key,				\
 | 
			
		||||
				      v);				\
 | 
			
		||||
}									\
 | 
			
		||||
				      					\
 | 
			
		||||
gboolean								\
 | 
			
		||||
xedit_prefs_manager_ ## name ## _can_set (void)				\
 | 
			
		||||
{									\
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);					\
 | 
			
		||||
									\
 | 
			
		||||
	return xedit_prefs_manager_key_is_writable (key);		\
 | 
			
		||||
}	
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define DEFINE_INT_PREF(name, key) gint					\
 | 
			
		||||
xedit_prefs_manager_get_ ## name (void)			 		\
 | 
			
		||||
{									\
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);					\
 | 
			
		||||
									\
 | 
			
		||||
	return xedit_prefs_manager_get_int (key);			\
 | 
			
		||||
}									\
 | 
			
		||||
									\
 | 
			
		||||
void 									\
 | 
			
		||||
xedit_prefs_manager_set_ ## name (gint v)				\
 | 
			
		||||
{									\
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);					\
 | 
			
		||||
									\
 | 
			
		||||
	xedit_prefs_manager_set_int (key,				\
 | 
			
		||||
				     v);				\
 | 
			
		||||
}									\
 | 
			
		||||
				      					\
 | 
			
		||||
gboolean								\
 | 
			
		||||
xedit_prefs_manager_ ## name ## _can_set (void)				\
 | 
			
		||||
{									\
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);					\
 | 
			
		||||
									\
 | 
			
		||||
	return xedit_prefs_manager_key_is_writable (key);		\
 | 
			
		||||
}		
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define DEFINE_STRING_PREF(name, key) gchar*				\
 | 
			
		||||
xedit_prefs_manager_get_ ## name (void)			 		\
 | 
			
		||||
{									\
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);					\
 | 
			
		||||
									\
 | 
			
		||||
	return xedit_prefs_manager_get_string (key);			\
 | 
			
		||||
}									\
 | 
			
		||||
									\
 | 
			
		||||
void 									\
 | 
			
		||||
xedit_prefs_manager_set_ ## name (const gchar* v)			\
 | 
			
		||||
{									\
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);					\
 | 
			
		||||
									\
 | 
			
		||||
	xedit_prefs_manager_set_string (key,				\
 | 
			
		||||
				        v);				\
 | 
			
		||||
}									\
 | 
			
		||||
				      					\
 | 
			
		||||
gboolean								\
 | 
			
		||||
xedit_prefs_manager_ ## name ## _can_set (void)				\
 | 
			
		||||
{									\
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);					\
 | 
			
		||||
									\
 | 
			
		||||
	return xedit_prefs_manager_key_is_writable (key);		\
 | 
			
		||||
}		
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
XeditPrefsManager *xedit_prefs_manager = NULL;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static GtkWrapMode 	 get_wrap_mode_from_string 		(const gchar* str);
 | 
			
		||||
 | 
			
		||||
static gboolean		 xedit_prefs_manager_get_bool		(const gchar* key);
 | 
			
		||||
 | 
			
		||||
static gint		 xedit_prefs_manager_get_int		(const gchar* key);
 | 
			
		||||
 | 
			
		||||
static gchar		*xedit_prefs_manager_get_string		(const gchar* key);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_prefs_manager_init (void)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
 | 
			
		||||
	if (xedit_prefs_manager == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		xedit_prefs_manager = g_new0 (XeditPrefsManager, 1);
 | 
			
		||||
		xedit_prefs_manager->settings = g_settings_new (XEDIT_SCHEMA);
 | 
			
		||||
		xedit_prefs_manager->lockdown_settings = g_settings_new (GPM_LOCKDOWN_SCHEMA);
 | 
			
		||||
		xedit_prefs_manager->interface_settings = g_settings_new (GPM_INTERFACE_SCHEMA);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return xedit_prefs_manager != NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_prefs_manager_shutdown (void)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (xedit_prefs_manager != NULL);
 | 
			
		||||
 | 
			
		||||
	g_object_unref (xedit_prefs_manager->settings);
 | 
			
		||||
	xedit_prefs_manager->settings = NULL;
 | 
			
		||||
	g_object_unref (xedit_prefs_manager->lockdown_settings);
 | 
			
		||||
	xedit_prefs_manager->lockdown_settings = NULL;
 | 
			
		||||
	g_object_unref (xedit_prefs_manager->interface_settings);
 | 
			
		||||
	xedit_prefs_manager->interface_settings = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean		 
 | 
			
		||||
xedit_prefs_manager_get_bool (const gchar* key)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
 | 
			
		||||
	return g_settings_get_boolean (xedit_prefs_manager->settings, key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gint 
 | 
			
		||||
xedit_prefs_manager_get_int (const gchar* key)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
 | 
			
		||||
	return g_settings_get_int (xedit_prefs_manager->settings, key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gchar *
 | 
			
		||||
xedit_prefs_manager_get_string (const gchar* key)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
 | 
			
		||||
	return g_settings_get_string (xedit_prefs_manager->settings, key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void		 
 | 
			
		||||
xedit_prefs_manager_set_bool (const gchar* key, gboolean value)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (g_settings_is_writable (
 | 
			
		||||
				xedit_prefs_manager->settings, key));
 | 
			
		||||
 | 
			
		||||
	g_settings_set_boolean (xedit_prefs_manager->settings, key, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void		 
 | 
			
		||||
xedit_prefs_manager_set_int (const gchar* key, gint value)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (g_settings_is_writable (
 | 
			
		||||
				xedit_prefs_manager->settings, key));
 | 
			
		||||
 | 
			
		||||
	g_settings_set_int (xedit_prefs_manager->settings, key, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void		 
 | 
			
		||||
xedit_prefs_manager_set_string (const gchar* key, const gchar* value)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (value != NULL);
 | 
			
		||||
	
 | 
			
		||||
	g_return_if_fail (g_settings_is_writable (
 | 
			
		||||
				xedit_prefs_manager->settings, key));
 | 
			
		||||
 | 
			
		||||
	g_settings_set_string (xedit_prefs_manager->settings, key, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean 
 | 
			
		||||
xedit_prefs_manager_key_is_writable (const gchar* key)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (xedit_prefs_manager != NULL, FALSE);
 | 
			
		||||
	g_return_val_if_fail (xedit_prefs_manager->settings != NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
	return g_settings_is_writable (xedit_prefs_manager->settings, key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Use default font */
 | 
			
		||||
DEFINE_BOOL_PREF (use_default_font,
 | 
			
		||||
		  GPM_USE_DEFAULT_FONT)
 | 
			
		||||
 | 
			
		||||
/* Editor font */
 | 
			
		||||
DEFINE_STRING_PREF (editor_font,
 | 
			
		||||
		    GPM_EDITOR_FONT)
 | 
			
		||||
 | 
			
		||||
/* System font */
 | 
			
		||||
gchar *
 | 
			
		||||
xedit_prefs_manager_get_system_font (void)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
 | 
			
		||||
	return g_settings_get_string (xedit_prefs_manager->interface_settings,
 | 
			
		||||
				      GPM_SYSTEM_FONT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Create backup copy */
 | 
			
		||||
DEFINE_BOOL_PREF (create_backup_copy,
 | 
			
		||||
		  GPM_CREATE_BACKUP_COPY)
 | 
			
		||||
 | 
			
		||||
/* Auto save */
 | 
			
		||||
DEFINE_BOOL_PREF (auto_save,
 | 
			
		||||
		  GPM_AUTO_SAVE)
 | 
			
		||||
 | 
			
		||||
/* Auto save interval */
 | 
			
		||||
DEFINE_INT_PREF (auto_save_interval,
 | 
			
		||||
		 GPM_AUTO_SAVE_INTERVAL)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Undo actions limit: if < 1 then no limits */
 | 
			
		||||
DEFINE_INT_PREF (undo_actions_limit,
 | 
			
		||||
		 GPM_UNDO_ACTIONS_LIMIT)
 | 
			
		||||
 | 
			
		||||
static GtkWrapMode 
 | 
			
		||||
get_wrap_mode_from_string (const gchar* str)
 | 
			
		||||
{
 | 
			
		||||
	GtkWrapMode res;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (str != NULL, GTK_WRAP_WORD);
 | 
			
		||||
	
 | 
			
		||||
	if (strcmp (str, "GTK_WRAP_NONE") == 0)
 | 
			
		||||
		res = GTK_WRAP_NONE;
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		if (strcmp (str, "GTK_WRAP_CHAR") == 0)
 | 
			
		||||
			res = GTK_WRAP_CHAR;
 | 
			
		||||
		else
 | 
			
		||||
			res = GTK_WRAP_WORD;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Wrap mode */
 | 
			
		||||
GtkWrapMode
 | 
			
		||||
xedit_prefs_manager_get_wrap_mode (void)
 | 
			
		||||
{
 | 
			
		||||
	gchar *str;
 | 
			
		||||
	GtkWrapMode res;
 | 
			
		||||
	
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
	
 | 
			
		||||
	str = xedit_prefs_manager_get_string (GPM_WRAP_MODE);
 | 
			
		||||
 | 
			
		||||
	res = get_wrap_mode_from_string (str);
 | 
			
		||||
 | 
			
		||||
	g_free (str);
 | 
			
		||||
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
	
 | 
			
		||||
void
 | 
			
		||||
xedit_prefs_manager_set_wrap_mode (GtkWrapMode wp)
 | 
			
		||||
{
 | 
			
		||||
	const gchar * str;
 | 
			
		||||
	
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
 | 
			
		||||
	switch (wp)
 | 
			
		||||
	{
 | 
			
		||||
		case GTK_WRAP_NONE:
 | 
			
		||||
			str = "GTK_WRAP_NONE";
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case GTK_WRAP_CHAR:
 | 
			
		||||
			str = "GTK_WRAP_CHAR";
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		default: /* GTK_WRAP_WORD */
 | 
			
		||||
			str = "GTK_WRAP_WORD";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	xedit_prefs_manager_set_string (GPM_WRAP_MODE,
 | 
			
		||||
					str);
 | 
			
		||||
}
 | 
			
		||||
	
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_prefs_manager_wrap_mode_can_set (void)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
	
 | 
			
		||||
	return xedit_prefs_manager_key_is_writable (GPM_WRAP_MODE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Tabs size */
 | 
			
		||||
DEFINE_INT_PREF (tabs_size, 
 | 
			
		||||
		 GPM_TABS_SIZE)
 | 
			
		||||
 | 
			
		||||
/* Insert spaces */
 | 
			
		||||
DEFINE_BOOL_PREF (insert_spaces, 
 | 
			
		||||
		  GPM_INSERT_SPACES)
 | 
			
		||||
 | 
			
		||||
/* Auto indent */
 | 
			
		||||
DEFINE_BOOL_PREF (auto_indent, 
 | 
			
		||||
		  GPM_AUTO_INDENT)
 | 
			
		||||
 | 
			
		||||
/* Display line numbers */
 | 
			
		||||
DEFINE_BOOL_PREF (display_line_numbers, 
 | 
			
		||||
		  GPM_DISPLAY_LINE_NUMBERS)
 | 
			
		||||
 | 
			
		||||
/* Toolbar visibility */
 | 
			
		||||
DEFINE_BOOL_PREF (toolbar_visible,
 | 
			
		||||
		  GPM_TOOLBAR_VISIBLE)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Toolbar suttons style */
 | 
			
		||||
XeditToolbarSetting 
 | 
			
		||||
xedit_prefs_manager_get_toolbar_buttons_style (void) 
 | 
			
		||||
{
 | 
			
		||||
	gchar *str;
 | 
			
		||||
	XeditToolbarSetting res;
 | 
			
		||||
	
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
	
 | 
			
		||||
	str = xedit_prefs_manager_get_string (GPM_TOOLBAR_BUTTONS_STYLE);
 | 
			
		||||
 | 
			
		||||
	if (strcmp (str, "XEDIT_TOOLBAR_ICONS") == 0)
 | 
			
		||||
		res = XEDIT_TOOLBAR_ICONS;
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		if (strcmp (str, "XEDIT_TOOLBAR_ICONS_AND_TEXT") == 0)
 | 
			
		||||
			res = XEDIT_TOOLBAR_ICONS_AND_TEXT;
 | 
			
		||||
		else 
 | 
			
		||||
		{
 | 
			
		||||
			if (strcmp (str, "XEDIT_TOOLBAR_ICONS_BOTH_HORIZ") == 0)
 | 
			
		||||
				res = XEDIT_TOOLBAR_ICONS_BOTH_HORIZ;
 | 
			
		||||
			else
 | 
			
		||||
				res = XEDIT_TOOLBAR_SYSTEM;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_free (str);
 | 
			
		||||
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_prefs_manager_set_toolbar_buttons_style (XeditToolbarSetting tbs)
 | 
			
		||||
{
 | 
			
		||||
	const gchar * str;
 | 
			
		||||
	
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
 | 
			
		||||
	switch (tbs)
 | 
			
		||||
	{
 | 
			
		||||
		case XEDIT_TOOLBAR_ICONS:
 | 
			
		||||
			str = "XEDIT_TOOLBAR_ICONS";
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case XEDIT_TOOLBAR_ICONS_AND_TEXT:
 | 
			
		||||
			str = "XEDIT_TOOLBAR_ICONS_AND_TEXT";
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
	        case XEDIT_TOOLBAR_ICONS_BOTH_HORIZ:
 | 
			
		||||
			str = "XEDIT_TOOLBAR_ICONS_BOTH_HORIZ";
 | 
			
		||||
			break;
 | 
			
		||||
		default: /* XEDIT_TOOLBAR_SYSTEM */
 | 
			
		||||
			str = "XEDIT_TOOLBAR_SYSTEM";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	xedit_prefs_manager_set_string (GPM_TOOLBAR_BUTTONS_STYLE,
 | 
			
		||||
					str);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_prefs_manager_toolbar_buttons_style_can_set (void)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
	
 | 
			
		||||
	return xedit_prefs_manager_key_is_writable (GPM_TOOLBAR_BUTTONS_STYLE);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Statusbar visiblity */
 | 
			
		||||
DEFINE_BOOL_PREF (statusbar_visible,
 | 
			
		||||
		  GPM_STATUSBAR_VISIBLE)
 | 
			
		||||
		  
 | 
			
		||||
/* Side Pane visiblity */
 | 
			
		||||
DEFINE_BOOL_PREF (side_pane_visible,
 | 
			
		||||
		  GPM_SIDE_PANE_VISIBLE)
 | 
			
		||||
		  
 | 
			
		||||
/* Bottom Panel visiblity */
 | 
			
		||||
DEFINE_BOOL_PREF (bottom_panel_visible,
 | 
			
		||||
		  GPM_BOTTOM_PANEL_VISIBLE)
 | 
			
		||||
 | 
			
		||||
/* Print syntax highlighting */
 | 
			
		||||
DEFINE_BOOL_PREF (print_syntax_hl,
 | 
			
		||||
		  GPM_PRINT_SYNTAX)
 | 
			
		||||
 | 
			
		||||
/* Print header */
 | 
			
		||||
DEFINE_BOOL_PREF (print_header,
 | 
			
		||||
		  GPM_PRINT_HEADER)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Print Wrap mode */
 | 
			
		||||
GtkWrapMode
 | 
			
		||||
xedit_prefs_manager_get_print_wrap_mode (void)
 | 
			
		||||
{
 | 
			
		||||
	gchar *str;
 | 
			
		||||
	GtkWrapMode res;
 | 
			
		||||
	
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
	
 | 
			
		||||
	str = xedit_prefs_manager_get_string (GPM_PRINT_WRAP_MODE);
 | 
			
		||||
 | 
			
		||||
	if (strcmp (str, "GTK_WRAP_NONE") == 0)
 | 
			
		||||
		res = GTK_WRAP_NONE;
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		if (strcmp (str, "GTK_WRAP_WORD") == 0)
 | 
			
		||||
			res = GTK_WRAP_WORD;
 | 
			
		||||
		else
 | 
			
		||||
			res = GTK_WRAP_CHAR;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_free (str);
 | 
			
		||||
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
	
 | 
			
		||||
void
 | 
			
		||||
xedit_prefs_manager_set_print_wrap_mode (GtkWrapMode pwp)
 | 
			
		||||
{
 | 
			
		||||
	const gchar *str;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
 | 
			
		||||
	switch (pwp)
 | 
			
		||||
	{
 | 
			
		||||
		case GTK_WRAP_NONE:
 | 
			
		||||
			str = "GTK_WRAP_NONE";
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case GTK_WRAP_WORD:
 | 
			
		||||
			str = "GTK_WRAP_WORD";
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		default: /* GTK_WRAP_CHAR */
 | 
			
		||||
			str = "GTK_WRAP_CHAR";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	xedit_prefs_manager_set_string (GPM_PRINT_WRAP_MODE, str);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_prefs_manager_print_wrap_mode_can_set (void)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
	
 | 
			
		||||
	return xedit_prefs_manager_key_is_writable (GPM_PRINT_WRAP_MODE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Print line numbers */	
 | 
			
		||||
DEFINE_INT_PREF (print_line_numbers,
 | 
			
		||||
		 GPM_PRINT_LINE_NUMBERS)
 | 
			
		||||
 | 
			
		||||
/* Printing fonts */
 | 
			
		||||
DEFINE_STRING_PREF (print_font_body,
 | 
			
		||||
		    GPM_PRINT_FONT_BODY)
 | 
			
		||||
 | 
			
		||||
gchar *
 | 
			
		||||
xedit_prefs_manager_get_default_string_value (const gchar *key)
 | 
			
		||||
{
 | 
			
		||||
	gchar *font = NULL;
 | 
			
		||||
	g_settings_delay (xedit_prefs_manager->settings);
 | 
			
		||||
	g_settings_reset (xedit_prefs_manager->settings, key);
 | 
			
		||||
	font = g_settings_get_string (xedit_prefs_manager->settings, key);
 | 
			
		||||
	g_settings_revert (xedit_prefs_manager->settings);
 | 
			
		||||
	return font;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gchar *
 | 
			
		||||
xedit_prefs_manager_get_default_print_font_body (void)
 | 
			
		||||
{
 | 
			
		||||
	return xedit_prefs_manager_get_default_string_value (GPM_PRINT_FONT_BODY);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DEFINE_STRING_PREF (print_font_header,
 | 
			
		||||
		    GPM_PRINT_FONT_HEADER)
 | 
			
		||||
 | 
			
		||||
gchar *
 | 
			
		||||
xedit_prefs_manager_get_default_print_font_header (void)
 | 
			
		||||
{
 | 
			
		||||
	return xedit_prefs_manager_get_default_string_value (GPM_PRINT_FONT_HEADER);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DEFINE_STRING_PREF (print_font_numbers,
 | 
			
		||||
		    GPM_PRINT_FONT_NUMBERS)
 | 
			
		||||
 | 
			
		||||
gchar *
 | 
			
		||||
xedit_prefs_manager_get_default_print_font_numbers (void)
 | 
			
		||||
{
 | 
			
		||||
	return xedit_prefs_manager_get_default_string_value (GPM_PRINT_FONT_NUMBERS);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Max number of files in "Recent Files" menu. 
 | 
			
		||||
 * This is configurable only using gsettings, dconf or dconf-editor 
 | 
			
		||||
 */
 | 
			
		||||
gint
 | 
			
		||||
xedit_prefs_manager_get_max_recents (void)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
 | 
			
		||||
	return xedit_prefs_manager_get_int (GPM_MAX_RECENTS);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* GSettings/GSList utility functions from mate-panel */
 | 
			
		||||
 | 
			
		||||
GSList*
 | 
			
		||||
xedit_prefs_manager_get_gslist (GSettings *settings, const gchar *key)
 | 
			
		||||
{
 | 
			
		||||
    gchar **array;
 | 
			
		||||
    GSList *list = NULL;
 | 
			
		||||
    gint i;
 | 
			
		||||
    array = g_settings_get_strv (settings, key);
 | 
			
		||||
    if (array != NULL) {
 | 
			
		||||
        for (i = 0; array[i]; i++) {
 | 
			
		||||
            list = g_slist_append (list, g_strdup (array[i]));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    g_strfreev (array);
 | 
			
		||||
    return list;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_prefs_manager_set_gslist (GSettings *settings, const gchar *key, GSList *list)
 | 
			
		||||
{
 | 
			
		||||
    GArray *array;
 | 
			
		||||
    GSList *l;
 | 
			
		||||
    array = g_array_new (TRUE, TRUE, sizeof (gchar *));
 | 
			
		||||
    for (l = list; l; l = l->next) {
 | 
			
		||||
        array = g_array_append_val (array, l->data);
 | 
			
		||||
    }
 | 
			
		||||
    g_settings_set_strv (settings, key, (const gchar **) array->data);
 | 
			
		||||
    g_array_free (array, TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Encodings */
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
data_exists (GSList         *list,
 | 
			
		||||
	    const gpointer  data)
 | 
			
		||||
{
 | 
			
		||||
	while (list != NULL)
 | 
			
		||||
	{
 | 
			
		||||
      		if (list->data == data)
 | 
			
		||||
			return TRUE;
 | 
			
		||||
 | 
			
		||||
		list = g_slist_next (list);
 | 
			
		||||
    	}
 | 
			
		||||
 | 
			
		||||
  	return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GSList *
 | 
			
		||||
xedit_prefs_manager_get_auto_detected_encodings (void)
 | 
			
		||||
{
 | 
			
		||||
	GSList *strings;
 | 
			
		||||
	GSList *res = NULL;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (xedit_prefs_manager != NULL, NULL);
 | 
			
		||||
	g_return_val_if_fail (xedit_prefs_manager->settings != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	strings = xedit_prefs_manager_get_gslist (xedit_prefs_manager->settings, GPM_AUTO_DETECTED_ENCODINGS);
 | 
			
		||||
 | 
			
		||||
	if (strings != NULL)
 | 
			
		||||
	{	
 | 
			
		||||
		GSList *tmp;
 | 
			
		||||
		const XeditEncoding *enc;
 | 
			
		||||
 | 
			
		||||
		tmp = strings;
 | 
			
		||||
		
 | 
			
		||||
		while (tmp)
 | 
			
		||||
		{
 | 
			
		||||
		      const char *charset = tmp->data;
 | 
			
		||||
      
 | 
			
		||||
		      if (strcmp (charset, "CURRENT") == 0)
 | 
			
		||||
			      g_get_charset (&charset);
 | 
			
		||||
 | 
			
		||||
		      g_return_val_if_fail (charset != NULL, NULL);
 | 
			
		||||
		      enc = xedit_encoding_get_from_charset (charset);
 | 
			
		||||
 | 
			
		||||
		      if (enc != NULL)
 | 
			
		||||
		      {
 | 
			
		||||
			      if (!data_exists (res, (gpointer)enc))
 | 
			
		||||
				      res = g_slist_prepend (res, (gpointer)enc);
 | 
			
		||||
 | 
			
		||||
		      }
 | 
			
		||||
 | 
			
		||||
		      tmp = g_slist_next (tmp);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		g_slist_foreach (strings, (GFunc) g_free, NULL);
 | 
			
		||||
		g_slist_free (strings);    
 | 
			
		||||
 | 
			
		||||
	 	res = g_slist_reverse (res);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	xedit_debug_message (DEBUG_PREFS, "Done");
 | 
			
		||||
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GSList *
 | 
			
		||||
xedit_prefs_manager_get_shown_in_menu_encodings (void)
 | 
			
		||||
{
 | 
			
		||||
	GSList *strings;
 | 
			
		||||
	GSList *res = NULL;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (xedit_prefs_manager != NULL, NULL);
 | 
			
		||||
	g_return_val_if_fail (xedit_prefs_manager->settings != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	strings = xedit_prefs_manager_get_gslist (xedit_prefs_manager->settings, GPM_SHOWN_IN_MENU_ENCODINGS);
 | 
			
		||||
 | 
			
		||||
	if (strings != NULL)
 | 
			
		||||
	{	
 | 
			
		||||
		GSList *tmp;
 | 
			
		||||
		const XeditEncoding *enc;
 | 
			
		||||
 | 
			
		||||
		tmp = strings;
 | 
			
		||||
		
 | 
			
		||||
		while (tmp)
 | 
			
		||||
		{
 | 
			
		||||
		      const char *charset = tmp->data;
 | 
			
		||||
 | 
			
		||||
		      if (strcmp (charset, "CURRENT") == 0)
 | 
			
		||||
			      g_get_charset (&charset);
 | 
			
		||||
 | 
			
		||||
		      g_return_val_if_fail (charset != NULL, NULL);
 | 
			
		||||
		      enc = xedit_encoding_get_from_charset (charset);
 | 
			
		||||
 | 
			
		||||
		      if (enc != NULL)
 | 
			
		||||
		      {
 | 
			
		||||
			      if (!data_exists (res, (gpointer)enc))
 | 
			
		||||
				      res = g_slist_prepend (res, (gpointer)enc);
 | 
			
		||||
		      }
 | 
			
		||||
 | 
			
		||||
		      tmp = g_slist_next (tmp);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		g_slist_foreach (strings, (GFunc) g_free, NULL);
 | 
			
		||||
		g_slist_free (strings);    
 | 
			
		||||
 | 
			
		||||
	 	res = g_slist_reverse (res);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_prefs_manager_set_shown_in_menu_encodings (const GSList *encs)
 | 
			
		||||
{	
 | 
			
		||||
	GSList *list = NULL;
 | 
			
		||||
	
 | 
			
		||||
	g_return_if_fail (xedit_prefs_manager != NULL);
 | 
			
		||||
	g_return_if_fail (xedit_prefs_manager->settings != NULL);
 | 
			
		||||
	g_return_if_fail (xedit_prefs_manager_shown_in_menu_encodings_can_set ());
 | 
			
		||||
 | 
			
		||||
	while (encs != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		const XeditEncoding *enc;
 | 
			
		||||
		const gchar *charset;
 | 
			
		||||
		
 | 
			
		||||
		enc = (const XeditEncoding *)encs->data;
 | 
			
		||||
 | 
			
		||||
		charset = xedit_encoding_get_charset (enc);
 | 
			
		||||
		g_return_if_fail (charset != NULL);
 | 
			
		||||
 | 
			
		||||
		list = g_slist_prepend (list, (gpointer)charset);
 | 
			
		||||
 | 
			
		||||
		encs = g_slist_next (encs);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	list = g_slist_reverse (list);
 | 
			
		||||
 | 
			
		||||
	xedit_prefs_manager_set_gslist (xedit_prefs_manager->settings, GPM_SHOWN_IN_MENU_ENCODINGS, list);
 | 
			
		||||
 | 
			
		||||
	g_slist_free (list);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_prefs_manager_shown_in_menu_encodings_can_set (void)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
	
 | 
			
		||||
	return xedit_prefs_manager_key_is_writable (GPM_SHOWN_IN_MENU_ENCODINGS);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Highlight current line */
 | 
			
		||||
DEFINE_BOOL_PREF (highlight_current_line,
 | 
			
		||||
		  GPM_HIGHLIGHT_CURRENT_LINE)
 | 
			
		||||
 | 
			
		||||
/* Highlight matching bracket */
 | 
			
		||||
DEFINE_BOOL_PREF (bracket_matching,
 | 
			
		||||
		  GPM_BRACKET_MATCHING)
 | 
			
		||||
	
 | 
			
		||||
/* Display Right Margin */
 | 
			
		||||
DEFINE_BOOL_PREF (display_right_margin,
 | 
			
		||||
		  GPM_DISPLAY_RIGHT_MARGIN)
 | 
			
		||||
 | 
			
		||||
/* Right Margin Position */	
 | 
			
		||||
DEFINE_INT_PREF (right_margin_position,
 | 
			
		||||
		 GPM_RIGHT_MARGIN_POSITION)
 | 
			
		||||
 | 
			
		||||
static GtkSourceSmartHomeEndType
 | 
			
		||||
get_smart_home_end_from_string (const gchar *str)
 | 
			
		||||
{
 | 
			
		||||
	GtkSourceSmartHomeEndType res;
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (str != NULL, GTK_SOURCE_SMART_HOME_END_AFTER);
 | 
			
		||||
 | 
			
		||||
	if (strcmp (str, "DISABLED") == 0)
 | 
			
		||||
		res = GTK_SOURCE_SMART_HOME_END_DISABLED;
 | 
			
		||||
	else if (strcmp (str, "BEFORE") == 0)
 | 
			
		||||
		res = GTK_SOURCE_SMART_HOME_END_BEFORE;
 | 
			
		||||
	else if (strcmp (str, "ALWAYS") == 0)
 | 
			
		||||
		res = GTK_SOURCE_SMART_HOME_END_ALWAYS;
 | 
			
		||||
	else
 | 
			
		||||
		res = GTK_SOURCE_SMART_HOME_END_AFTER;
 | 
			
		||||
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GtkSourceSmartHomeEndType
 | 
			
		||||
xedit_prefs_manager_get_smart_home_end (void)
 | 
			
		||||
{
 | 
			
		||||
	gchar *str;
 | 
			
		||||
	GtkSourceSmartHomeEndType res;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
 | 
			
		||||
	str = xedit_prefs_manager_get_string (GPM_SMART_HOME_END);
 | 
			
		||||
 | 
			
		||||
	res = get_smart_home_end_from_string (str);
 | 
			
		||||
 | 
			
		||||
	g_free (str);
 | 
			
		||||
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
	
 | 
			
		||||
void
 | 
			
		||||
xedit_prefs_manager_set_smart_home_end (GtkSourceSmartHomeEndType smart_he)
 | 
			
		||||
{
 | 
			
		||||
	const gchar *str;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
 | 
			
		||||
	switch (smart_he)
 | 
			
		||||
	{
 | 
			
		||||
		case GTK_SOURCE_SMART_HOME_END_DISABLED:
 | 
			
		||||
			str = "DISABLED";
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case GTK_SOURCE_SMART_HOME_END_BEFORE:
 | 
			
		||||
			str = "BEFORE";
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case GTK_SOURCE_SMART_HOME_END_ALWAYS:
 | 
			
		||||
			str = "ALWAYS";
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		default: /* GTK_SOURCE_SMART_HOME_END_AFTER */
 | 
			
		||||
			str = "AFTER";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	xedit_prefs_manager_set_string (GPM_WRAP_MODE, str);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_prefs_manager_smart_home_end_can_set (void)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
	
 | 
			
		||||
	return xedit_prefs_manager_key_is_writable (GPM_SMART_HOME_END);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Enable syntax highlighting */
 | 
			
		||||
DEFINE_BOOL_PREF (enable_syntax_highlighting,
 | 
			
		||||
		  GPM_SYNTAX_HL_ENABLE)
 | 
			
		||||
 | 
			
		||||
/* Enable search highlighting */
 | 
			
		||||
DEFINE_BOOL_PREF (enable_search_highlighting,
 | 
			
		||||
		  GPM_SEARCH_HIGHLIGHTING_ENABLE)
 | 
			
		||||
 | 
			
		||||
/* Source style scheme */
 | 
			
		||||
DEFINE_STRING_PREF (source_style_scheme,
 | 
			
		||||
		    GPM_SOURCE_STYLE_SCHEME)
 | 
			
		||||
 | 
			
		||||
GSList *
 | 
			
		||||
xedit_prefs_manager_get_writable_vfs_schemes (void)
 | 
			
		||||
{
 | 
			
		||||
	GSList *strings;
 | 
			
		||||
	
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (xedit_prefs_manager != NULL, NULL);
 | 
			
		||||
	g_return_val_if_fail (xedit_prefs_manager->settings != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	strings = xedit_prefs_manager_get_gslist (xedit_prefs_manager->settings, GPM_WRITABLE_VFS_SCHEMES);
 | 
			
		||||
 | 
			
		||||
	/* The 'file' scheme is writable by default. */
 | 
			
		||||
	strings = g_slist_prepend (strings, g_strdup ("file")); 
 | 
			
		||||
	
 | 
			
		||||
	xedit_debug_message (DEBUG_PREFS, "Done");
 | 
			
		||||
 | 
			
		||||
	return strings;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_prefs_manager_get_restore_cursor_position (void)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
 | 
			
		||||
	return xedit_prefs_manager_get_bool (GPM_RESTORE_CURSOR_POSITION);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Plugins: we just store/return a list of strings, all the magic has to
 | 
			
		||||
 * happen in the plugin engine */
 | 
			
		||||
 | 
			
		||||
GSList *
 | 
			
		||||
xedit_prefs_manager_get_active_plugins (void)
 | 
			
		||||
{
 | 
			
		||||
	GSList *plugins;
 | 
			
		||||
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
 | 
			
		||||
	g_return_val_if_fail (xedit_prefs_manager != NULL, NULL);
 | 
			
		||||
	g_return_val_if_fail (xedit_prefs_manager->settings != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	plugins = xedit_prefs_manager_get_gslist (xedit_prefs_manager->settings, GPM_ACTIVE_PLUGINS);
 | 
			
		||||
 | 
			
		||||
	return plugins;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
xedit_prefs_manager_set_active_plugins (const GSList *plugins)
 | 
			
		||||
{	
 | 
			
		||||
	g_return_if_fail (xedit_prefs_manager != NULL);
 | 
			
		||||
	g_return_if_fail (xedit_prefs_manager->settings != NULL);
 | 
			
		||||
	g_return_if_fail (xedit_prefs_manager_active_plugins_can_set ());
 | 
			
		||||
 | 
			
		||||
	xedit_prefs_manager_set_gslist (xedit_prefs_manager->settings, GPM_ACTIVE_PLUGINS, (GSList *) plugins);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
xedit_prefs_manager_active_plugins_can_set (void)
 | 
			
		||||
{
 | 
			
		||||
	xedit_debug (DEBUG_PREFS);
 | 
			
		||||
 | 
			
		||||
	return xedit_prefs_manager_key_is_writable (GPM_ACTIVE_PLUGINS);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Global Lockdown */
 | 
			
		||||
 | 
			
		||||
XeditLockdownMask
 | 
			
		||||
xedit_prefs_manager_get_lockdown (void)
 | 
			
		||||
{
 | 
			
		||||
	guint lockdown = 0;
 | 
			
		||||
 | 
			
		||||
	if (g_settings_get_boolean (xedit_prefs_manager->lockdown_settings, GPM_LOCKDOWN_COMMAND_LINE))
 | 
			
		||||
		lockdown |= XEDIT_LOCKDOWN_COMMAND_LINE;
 | 
			
		||||
 | 
			
		||||
	if (g_settings_get_boolean (xedit_prefs_manager->lockdown_settings, GPM_LOCKDOWN_PRINTING))
 | 
			
		||||
		lockdown |= XEDIT_LOCKDOWN_PRINTING;
 | 
			
		||||
 | 
			
		||||
	if (g_settings_get_boolean (xedit_prefs_manager->lockdown_settings, GPM_LOCKDOWN_PRINT_SETUP))
 | 
			
		||||
		lockdown |= XEDIT_LOCKDOWN_PRINT_SETUP;
 | 
			
		||||
 | 
			
		||||
	if (g_settings_get_boolean (xedit_prefs_manager->lockdown_settings, GPM_LOCKDOWN_SAVE_TO_DISK))
 | 
			
		||||
		lockdown |= XEDIT_LOCKDOWN_SAVE_TO_DISK;
 | 
			
		||||
 | 
			
		||||
	return lockdown;
 | 
			
		||||
}
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user