Port xed to dbus and GtkApplication
This further improves on the port to GtkSource API's and cleans up a ton of legacy code in xed based on upstream changes in Gedit.
This commit is contained in:
parent
f05ddd7b63
commit
2aa009cb76
28
configure.ac
28
configure.ac
|
@ -49,12 +49,6 @@ dnl toolbar style for GSettings schemas
|
|||
TOOLBAR_STYLE="XED_TOOLBAR_SYSTEM"
|
||||
AC_SUBST(TOOLBAR_STYLE)
|
||||
|
||||
# GLib min/max required versions
|
||||
AC_DEFINE([GLIB_VERSION_MAX_ALLOWED], [GLIB_VERSION_2_36],
|
||||
[Warn on use of APIs added after GLib 2.36])
|
||||
AC_DEFINE([GLIB_VERSION_MIN_REQUIRED], [GLIB_VERSION_2_36],
|
||||
[Warn on use of APIs deprecated before GLib 2.36])
|
||||
|
||||
dnl ===============================================================
|
||||
dnl Expanded dirs
|
||||
dnl ===============================================================
|
||||
|
@ -151,12 +145,12 @@ dnl ================================================================
|
|||
PKG_CHECK_MODULES(GMODULE,gmodule-2.0,[GMODULE_ADD="gmodule-2.0"],[GMODULE_ADD=""])
|
||||
PKG_CHECK_MODULES(XED, [
|
||||
libxml-2.0 >= 2.5.0
|
||||
glib-2.0 >= 2.36.0
|
||||
glib-2.0 >= 2.40.0
|
||||
$GMODULE_ADD
|
||||
gthread-2.0 >= 2.13.0
|
||||
gio-2.0 >= 2.26.0
|
||||
gtk+-3.0 >= 3.10.0
|
||||
gtksourceview-3.0 >= 2.9.7
|
||||
gio-2.0 >= 2.40.0
|
||||
gtk+-3.0 >= 3.14.0
|
||||
gtksourceview-3.0 >= 3.14.3
|
||||
libpeas-1.0 >= 1.12.0
|
||||
libpeas-gtk-1.0 >= 1.12.0
|
||||
])
|
||||
|
@ -169,19 +163,14 @@ XED_LIBS="$XED_LIBS $X11_LIBS"
|
|||
AC_SUBST(XED_CFLAGS)
|
||||
AC_SUBST(XED_LIBS)
|
||||
|
||||
PKG_CHECK_MODULES(EGG_SMCLIENT, [sm >= 1.0.0])
|
||||
|
||||
AC_SUBST(EGG_SMCLIENT_CFLAGS)
|
||||
AC_SUBST(EGG_SMCLIENT_LIBS)
|
||||
|
||||
# Introspection
|
||||
GOBJECT_INTROSPECTION_CHECK([0.9.3])
|
||||
|
||||
if test "$found_introspection" = "yes"; then
|
||||
have_introspection=yes
|
||||
AC_DEFINE([HAVE_INTROSPECTION], [1], [Define to enable GObject Introspection])
|
||||
enable_introspection=yes
|
||||
AC_DEFINE([ENABLE_INTROSPECTION], [1], [Define to enable GObject Introspection])
|
||||
else
|
||||
have_introspection=no
|
||||
enable_introspection=no
|
||||
fi
|
||||
|
||||
dnl ================================================================
|
||||
|
@ -235,7 +224,6 @@ data/Makefile
|
|||
docs/Makefile
|
||||
docs/reference/Makefile
|
||||
xed/dialogs/Makefile
|
||||
xed/smclient/Makefile
|
||||
xed/Makefile
|
||||
help/Makefile
|
||||
pixmaps/Makefile
|
||||
|
@ -264,5 +252,5 @@ Configuration:
|
|||
Compiler: ${CC}
|
||||
Spell Plugin enabled: $enable_enchant
|
||||
Gvfs metadata enabled: $enable_gvfs_metadata
|
||||
GObject Introspection: ${have_introspection}
|
||||
GObject Introspection: ${enable_introspection}
|
||||
"
|
||||
|
|
|
@ -13,6 +13,13 @@ gsettings_SCHEMAS = org.x.editor.gschema.xml
|
|||
|
||||
@GSETTINGS_RULES@
|
||||
|
||||
servicedir = $(datadir)/dbus-1/services
|
||||
service_in_files = org.x.editor.service.in
|
||||
service_DATA = $(service_in_files:.service.in=.service)
|
||||
|
||||
$(service_DATA): $(service_in_files) Makefile
|
||||
@sed -e "s|\@bindir\@|$(bindir)|" $<> $@
|
||||
|
||||
man_MANS = xed.1
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
|
@ -24,12 +31,14 @@ bugreport_SCRIPTS = xed-bugreport.sh
|
|||
EXTRA_DIST = \
|
||||
$(appdata_in_files) \
|
||||
$(desktop_in_files) \
|
||||
$(service_in_files) \
|
||||
$(man_MANS) \
|
||||
xed.pc.in \
|
||||
xed-bugreport.sh.in
|
||||
|
||||
CLEANFILES = \
|
||||
$(desktop_DATA) \
|
||||
$(service_DATA) \
|
||||
$(gsettings_SCHEMAS) \
|
||||
$(pkgconfig_DATA) \
|
||||
$(appdata_DATA)
|
||||
|
|
|
@ -4,4 +4,5 @@ usr/lib/xed/xed-bugreport.sh
|
|||
usr/lib/*/xed/plugins/*.plugin
|
||||
usr/lib/*/xed/plugins/*.so
|
||||
usr/share/applications/xed.desktop
|
||||
usr/share/dbus-1/
|
||||
usr/share/man/
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
egg_sm_client_get_type
|
||||
egg_sm_client_xsmp_get_type
|
||||
xed_app_activatable_get_type
|
||||
xed_app_get_type
|
||||
xed_close_button_get_type
|
||||
|
|
|
@ -761,13 +761,11 @@ on_rename_cb (XedFileBrowserStore *store,
|
|||
GFile *newfile,
|
||||
XedWindow *window)
|
||||
{
|
||||
XedApp *app;
|
||||
GList *documents;
|
||||
GList *item;
|
||||
|
||||
/* Find all documents and set its uri to newuri where it matches olduri */
|
||||
app = xed_app_get_default ();
|
||||
documents = xed_app_get_documents (app);
|
||||
documents = xed_app_get_documents (XED_APP (g_application_get_default ()));
|
||||
|
||||
for (item = documents; item; item = item->next)
|
||||
{
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include <xed/xed-window-activatable.h>
|
||||
#include <xed/xed-debug.h>
|
||||
#include <xed/xed-utils.h>
|
||||
#include <xed/xed-help.h>
|
||||
#include <xed/xed-app.h>
|
||||
|
||||
#define XED_SORT_PLUGIN_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), XED_TYPE_SORT_PLUGIN, XedSortPluginPrivate))
|
||||
|
||||
|
@ -110,7 +110,7 @@ sort_dialog_response_handler (GtkDialog *dlg,
|
|||
break;
|
||||
|
||||
case GTK_RESPONSE_HELP:
|
||||
xed_help_display (GTK_WINDOW (dlg), NULL, "xed-sort-plugin");
|
||||
xed_app_show_help (XED_APP (g_application_get_default ()), GTK_WINDOW (dlg), NULL, "xed-sort-plugin");
|
||||
break;
|
||||
|
||||
case GTK_RESPONSE_CANCEL:
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <xed/xed-utils.h>
|
||||
#include <xed/xed-help.h>
|
||||
#include <xed/xed-app.h>
|
||||
#include "xed-spell-language-dialog.h"
|
||||
#include "xed-spell-checker-language.h"
|
||||
|
||||
|
@ -70,7 +70,7 @@ dialog_response_handler (GtkDialog *dlg,
|
|||
{
|
||||
if (res_id == GTK_RESPONSE_HELP)
|
||||
{
|
||||
xed_help_display (GTK_WINDOW (dlg), NULL, "xed-spell-checker-plugin");
|
||||
xed_app_show_help (XED_APP (g_application_get_default ()), GTK_WINDOW (dlg), NULL, "xed-spell-checker-plugin");
|
||||
|
||||
g_signal_stop_emission_by_name (dlg, "response");
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include <time.h>
|
||||
|
||||
#include "xed-time-plugin.h"
|
||||
#include <xed/xed-help.h>
|
||||
#include <xed/xed-app.h>
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include <glib.h>
|
||||
|
@ -916,7 +916,7 @@ choose_format_dialog_response_cb (GtkWidget *widget,
|
|||
case GTK_RESPONSE_HELP:
|
||||
{
|
||||
xed_debug_message (DEBUG_PLUGINS, "GTK_RESPONSE_HELP");
|
||||
xed_help_display (GTK_WINDOW (widget), NULL, "xed-insert-date-time-plugin");
|
||||
xed_app_show_help (XED_APP (g_application_get_default ()), GTK_WINDOW (widget), NULL, "xed-insert-date-time-plugin");
|
||||
break;
|
||||
}
|
||||
case GTK_RESPONSE_OK:
|
||||
|
|
|
@ -17,7 +17,6 @@ xed/xed-commands-search.c
|
|||
xed/xed-debug.c
|
||||
xed/xed-document.c
|
||||
xed/xed-documents-panel.c
|
||||
xed/xed-encodings.c
|
||||
xed/xed-encodings-combo-box.c
|
||||
xed/xed-file-chooser-dialog.c
|
||||
xed/xed-gio-document-loader.c
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
SUBDIRS = dialogs smclient
|
||||
SUBDIRS = dialogs
|
||||
|
||||
bin_PROGRAMS = xed
|
||||
|
||||
|
@ -8,7 +8,6 @@ noinst_LTLIBRARIES = libxed.la
|
|||
AM_CPPFLAGS = \
|
||||
-I$(top_srcdir) \
|
||||
-I$(srcdir) \
|
||||
-I$(srcdir)/smclient \
|
||||
$(XED_CFLAGS) \
|
||||
$(WARN_CFLAGS) \
|
||||
$(INTROSPECTION_CFLAGS) \
|
||||
|
@ -22,7 +21,6 @@ xed_SOURCES = \
|
|||
xed_LDADD = \
|
||||
libxed.la \
|
||||
$(XED_LIBS) \
|
||||
$(EGG_SMCLIENT_LIBS) \
|
||||
$(INTROSPECTION_LIBS)
|
||||
|
||||
xed_LDFLAGS = -export-dynamic -no-undefined -export-symbols-regex "^[[^_]].*"
|
||||
|
@ -30,8 +28,7 @@ xed_LDFLAGS = -export-dynamic -no-undefined -export-symbols-regex "^[[^_]].*"
|
|||
libxed_la_LDFLAGS = -export-dynamic -no-undefined -export-symbols-regex "^[[^_]].*"
|
||||
|
||||
libxed_la_LIBADD = \
|
||||
dialogs/libdialogs.la \
|
||||
smclient/libeggsmclient.la
|
||||
dialogs/libdialogs.la
|
||||
|
||||
# XED_LIBS must be the last to ensure correct order on some platforms
|
||||
libxed_la_LIBADD += $(XED_LIBS) -lICE
|
||||
|
@ -52,7 +49,6 @@ NOINST_H_FILES = \
|
|||
xed-plugins-engine.h \
|
||||
xed-print-job.h \
|
||||
xed-print-preview.h \
|
||||
xed-session.h \
|
||||
xed-settings.h \
|
||||
xed-status-combo-box.h \
|
||||
xed-tab-label.h \
|
||||
|
@ -69,7 +65,6 @@ INST_H_FILES = \
|
|||
xed-document.h \
|
||||
xed-encodings-combo-box.h \
|
||||
xed-file-chooser-dialog.h \
|
||||
xed-help.h \
|
||||
xed-message-bus.h \
|
||||
xed-message-type.h \
|
||||
xed-message.h \
|
||||
|
@ -111,7 +106,6 @@ libxed_c_files = \
|
|||
xed-documents-panel.c \
|
||||
xed-encodings-combo-box.c \
|
||||
xed-file-chooser-dialog.c \
|
||||
xed-help.c \
|
||||
xed-history-entry.c \
|
||||
xed-io-error-message-area.c \
|
||||
xed-message-bus.c \
|
||||
|
@ -123,7 +117,6 @@ libxed_c_files = \
|
|||
xed-print-job.c \
|
||||
xed-print-preview.c \
|
||||
xed-progress-message-area.c \
|
||||
xed-session.c \
|
||||
xed-settings.c \
|
||||
xed-searchbar.c \
|
||||
xed-statusbar.c \
|
||||
|
@ -140,7 +133,6 @@ libxed_c_files = \
|
|||
libxed_la_SOURCES = \
|
||||
$(BUILT_SOURCES) \
|
||||
$(libxed_c_files) \
|
||||
$(BACON_FILES) \
|
||||
$(POSIXIO_FILES) \
|
||||
$(NOINST_H_FILES) \
|
||||
$(INST_H_FILES)
|
||||
|
@ -205,10 +197,4 @@ endif
|
|||
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)/xed/update-from-bacon.sh
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
||||
|
|
|
@ -1,396 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* 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 */
|
|
@ -40,7 +40,6 @@
|
|||
#include "xed-encodings-dialog.h"
|
||||
#include "xed-utils.h"
|
||||
#include "xed-debug.h"
|
||||
#include "xed-help.h"
|
||||
#include "xed-dirs.h"
|
||||
#include "xed-settings.h"
|
||||
|
||||
|
@ -271,7 +270,7 @@ response_handler (GtkDialog *dialog,
|
|||
{
|
||||
if (response_id == GTK_RESPONSE_HELP)
|
||||
{
|
||||
xed_help_display (GTK_WINDOW (dialog), "xed", NULL);
|
||||
xed_app_show_help (XED_APP (g_application_get_default ()), GTK_WINDOW (dialog), "xed", NULL);
|
||||
g_signal_stop_emission_by_name (dialog, "response");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,6 @@
|
|||
#include "xed-utils.h"
|
||||
#include "xed-debug.h"
|
||||
#include "xed-document.h"
|
||||
#include "xed-help.h"
|
||||
#include "xed-dirs.h"
|
||||
#include "xed-settings.h"
|
||||
#include "xed-utils.h"
|
||||
|
@ -172,11 +171,11 @@ dialog_response_handler (GtkDialog *dlg,
|
|||
switch (res_id)
|
||||
{
|
||||
case GTK_RESPONSE_HELP:
|
||||
xed_help_display (GTK_WINDOW (dlg), NULL, "xed-prefs");
|
||||
xed_app_show_help (XED_APP (g_application_get_default ()), GTK_WINDOW (dlg), NULL, "xed-prefs");
|
||||
g_signal_stop_emission_by_name (dlg, "response");
|
||||
break;
|
||||
default:
|
||||
gtk_widget_destroy (GTK_WIDGET(dlg));
|
||||
gtk_widget_destroy (GTK_WIDGET (dlg));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -308,13 +307,11 @@ setup_view_page (XedPreferencesDialog *dlg)
|
|||
{
|
||||
GtkWrapMode wrap_mode;
|
||||
gboolean display_right_margin;
|
||||
guint right_margin_position;
|
||||
|
||||
xed_debug (DEBUG_PREFS);
|
||||
|
||||
/* Get values */
|
||||
display_right_margin = g_settings_get_boolean (dlg->priv->editor, XED_SETTINGS_DISPLAY_RIGHT_MARGIN);
|
||||
right_margin_position = g_settings_get_uint (dlg->priv->editor, XED_SETTINGS_RIGHT_MARGIN_POSITION);
|
||||
|
||||
/* Set initial state */
|
||||
wrap_mode = g_settings_get_enum (dlg->priv->editor, XED_SETTINGS_WRAP_MODE);
|
||||
|
@ -400,7 +397,7 @@ setup_font_colors_page_font_section (XedPreferencesDialog *dlg)
|
|||
ATK_RELATION_CONTROLLER_FOR);
|
||||
|
||||
/* Get values */
|
||||
settings = _xed_app_get_settings (xed_app_get_default ());
|
||||
settings = _xed_app_get_settings (XED_APP (g_application_get_default ()));
|
||||
system_font = xed_settings_get_system_font (XED_SETTINGS (settings));
|
||||
use_default_font = g_settings_get_boolean (dlg->priv->editor, XED_SETTINGS_USE_DEFAULT_FONT);
|
||||
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
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"\" \
|
||||
$(XED_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
|
File diff suppressed because it is too large
Load Diff
|
@ -1,160 +0,0 @@
|
|||
/* 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__ */
|
|
@ -1,39 +0,0 @@
|
|||
/* 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>
|
||||
#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__ */
|
File diff suppressed because it is too large
Load Diff
|
@ -1,573 +0,0 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
/* 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__ */
|
1117
xed/xed-app.c
1117
xed/xed-app.c
File diff suppressed because it is too large
Load Diff
|
@ -50,7 +50,7 @@ typedef struct _XedAppClass XedAppClass;
|
|||
|
||||
struct _XedApp
|
||||
{
|
||||
GObject object;
|
||||
GtkApplication parent;
|
||||
|
||||
/*< private > */
|
||||
XedAppPrivate *priv;
|
||||
|
@ -58,38 +58,49 @@ struct _XedApp
|
|||
|
||||
struct _XedAppClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
GtkApplicationClass parent_class;
|
||||
|
||||
// gboolean (*last_window_destroyed) (XedApp *app);
|
||||
|
||||
gboolean (*show_help) (XedApp *app,
|
||||
GtkWindow *parent,
|
||||
const gchar *name,
|
||||
const gchar *link_id);
|
||||
|
||||
gchar *(*help_link_id) (XedApp *app,
|
||||
const gchar *name,
|
||||
const gchar *link_id);
|
||||
|
||||
void (*set_window_title) (XedApp *app,
|
||||
XedWindow *window,
|
||||
const gchar *title);
|
||||
};
|
||||
|
||||
/*
|
||||
* Public methods
|
||||
*/
|
||||
/* Public methods */
|
||||
GType xed_app_get_type (void) G_GNUC_CONST;
|
||||
|
||||
XedApp *xed_app_get_default (void);
|
||||
|
||||
XedWindow *xed_app_create_window (XedApp *app,
|
||||
GdkScreen *screen);
|
||||
|
||||
const GList *xed_app_get_windows (XedApp *app);
|
||||
XedWindow *xed_app_get_active_window (XedApp *app);
|
||||
GList *xed_app_get_main_windows (XedApp *app);
|
||||
|
||||
/* Returns a newly allocated list with all the documents */
|
||||
GList *xed_app_get_documents (XedApp *app);
|
||||
|
||||
/* Returns a newly allocated list with all the views */
|
||||
GList *xed_app_get_views (XedApp *app);
|
||||
|
||||
/*
|
||||
* Non exported functions
|
||||
*/
|
||||
gboolean xed_app_show_help (XedApp *app,
|
||||
GtkWindow *parent,
|
||||
const gchar *name,
|
||||
const gchar *link_id);
|
||||
|
||||
void xed_app_set_window_title (XedApp *app,
|
||||
XedWindow *window,
|
||||
const gchar *title);
|
||||
|
||||
/* Non exported functions */
|
||||
XedWindow *_xed_app_restore_window (XedApp *app,
|
||||
const gchar *role);
|
||||
XedWindow *_xed_app_get_window_in_viewport (XedApp *app,
|
||||
GdkScreen *screen,
|
||||
gint workspace,
|
||||
gint viewport_x,
|
||||
gint viewport_y);
|
||||
|
||||
/* global print config */
|
||||
GtkPageSetup *_xed_app_get_default_page_setup (XedApp *app);
|
||||
|
|
|
@ -61,6 +61,9 @@ static void tab_state_changed_while_saving (XedTab *tab,
|
|||
GParamSpec *pspec,
|
||||
XedWindow *window);
|
||||
|
||||
static void save_as_tab (XedTab *tab,
|
||||
XedWindow *window);
|
||||
|
||||
void
|
||||
_xed_cmd_file_new (GtkAction *action,
|
||||
XedWindow *window)
|
||||
|
@ -116,7 +119,7 @@ is_duplicated_file (GSList *files,
|
|||
}
|
||||
|
||||
/* File loading */
|
||||
static gint
|
||||
static GSList *
|
||||
load_file_list (XedWindow *window,
|
||||
const GSList *files,
|
||||
const GtkSourceEncoding *encoding,
|
||||
|
@ -124,11 +127,12 @@ load_file_list (XedWindow *window,
|
|||
gboolean create)
|
||||
{
|
||||
XedTab *tab;
|
||||
gint loaded_files = 0; /* Number of files to load */
|
||||
GSList *loaded_files = NULL; /* Number of files to load */
|
||||
gboolean jump_to = TRUE; /* Whether to jump to the new tab */
|
||||
GList *win_docs;
|
||||
GSList *files_to_load = NULL;
|
||||
const GSList *l;
|
||||
gint num_loaded_files = 0;
|
||||
|
||||
xed_debug (DEBUG_COMMANDS);
|
||||
|
||||
|
@ -145,29 +149,25 @@ load_file_list (XedWindow *window,
|
|||
{
|
||||
if (l == files)
|
||||
{
|
||||
XedDocument *doc;
|
||||
|
||||
xed_window_set_active_tab (window, tab);
|
||||
jump_to = FALSE;
|
||||
doc = xed_tab_get_document (tab);
|
||||
|
||||
if (line_pos > 0)
|
||||
{
|
||||
XedDocument *doc;
|
||||
XedView *view;
|
||||
|
||||
doc = xed_tab_get_document (tab);
|
||||
view = xed_tab_get_view (tab);
|
||||
|
||||
/* document counts lines starting from 0 */
|
||||
xed_document_goto_line (doc, line_pos - 1);
|
||||
xed_view_scroll_to_cursor (view);
|
||||
xed_view_scroll_to_cursor (xed_tab_get_view (tab));
|
||||
}
|
||||
}
|
||||
|
||||
++loaded_files;
|
||||
++num_loaded_files;
|
||||
loaded_files = g_slist_prepend (loaded_files, xed_tab_get_document (tab));
|
||||
}
|
||||
else
|
||||
{
|
||||
files_to_load = g_slist_prepend (files_to_load,
|
||||
l->data);
|
||||
files_to_load = g_slist_prepend (files_to_load, l->data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ load_file_list (XedWindow *window,
|
|||
|
||||
if (files_to_load == NULL)
|
||||
{
|
||||
return loaded_files;
|
||||
return g_slist_reverse (loaded_files);
|
||||
}
|
||||
|
||||
files_to_load = g_slist_reverse (files_to_load);
|
||||
|
@ -196,7 +196,8 @@ load_file_list (XedWindow *window,
|
|||
l = g_slist_next (l);
|
||||
jump_to = FALSE;
|
||||
|
||||
++loaded_files;
|
||||
++num_loaded_files;
|
||||
loaded_files = g_slist_prepend (loaded_files, xed_tab_get_document (tab));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -209,13 +210,16 @@ load_file_list (XedWindow *window,
|
|||
if (tab != NULL)
|
||||
{
|
||||
jump_to = FALSE;
|
||||
++loaded_files;
|
||||
++num_loaded_files;
|
||||
loaded_files = g_slist_prepend (loaded_files, xed_tab_get_document (tab));
|
||||
}
|
||||
|
||||
l = g_slist_next (l);
|
||||
}
|
||||
|
||||
if (loaded_files == 1)
|
||||
loaded_files = g_slist_reverse (loaded_files);
|
||||
|
||||
if (num_loaded_files == 1)
|
||||
{
|
||||
XedDocument *doc;
|
||||
gchar *uri_for_display;
|
||||
|
@ -238,8 +242,8 @@ load_file_list (XedWindow *window,
|
|||
window->priv->generic_message_cid,
|
||||
ngettext("Loading %d file\342\200\246",
|
||||
"Loading %d files\342\200\246",
|
||||
loaded_files),
|
||||
loaded_files);
|
||||
num_loaded_files),
|
||||
num_loaded_files);
|
||||
}
|
||||
|
||||
/* Free uris_to_load. Note that l points to the first element of uris_to_load */
|
||||
|
@ -265,6 +269,7 @@ xed_commands_load_location (XedWindow *window,
|
|||
{
|
||||
GSList *locations = NULL;
|
||||
gchar *uri;
|
||||
GSList *ret;
|
||||
|
||||
g_return_if_fail (XED_IS_WINDOW (window));
|
||||
g_return_if_fail (G_IS_FILE (location));
|
||||
|
@ -276,7 +281,8 @@ xed_commands_load_location (XedWindow *window,
|
|||
|
||||
locations = g_slist_prepend (locations, location);
|
||||
|
||||
load_file_list (window, locations, encoding, line_pos, FALSE);
|
||||
ret = load_file_list (window, locations, encoding, line_pos, FALSE);
|
||||
g_slist_free (ret);
|
||||
|
||||
g_slist_free (locations);
|
||||
}
|
||||
|
@ -292,7 +298,7 @@ xed_commands_load_location (XedWindow *window,
|
|||
*
|
||||
* Returns:
|
||||
*/
|
||||
gint
|
||||
GSList *
|
||||
xed_commands_load_locations (XedWindow *window,
|
||||
const GSList *locations,
|
||||
const GtkSourceEncoding *encoding,
|
||||
|
@ -311,7 +317,7 @@ xed_commands_load_locations (XedWindow *window,
|
|||
* first doc. Beside specifying a not existing uri creates a
|
||||
* titled document.
|
||||
*/
|
||||
gint
|
||||
GSList *
|
||||
_xed_cmd_load_files_from_prompt (XedWindow *window,
|
||||
GSList *files,
|
||||
const GtkSourceEncoding *encoding,
|
||||
|
@ -338,6 +344,7 @@ open_dialog_response_cb (XedFileChooserDialog *dialog,
|
|||
{
|
||||
GSList *files;
|
||||
const GtkSourceEncoding *encoding;
|
||||
GSList *loaded;
|
||||
|
||||
xed_debug (DEBUG_COMMANDS);
|
||||
|
||||
|
@ -358,7 +365,9 @@ open_dialog_response_cb (XedFileChooserDialog *dialog,
|
|||
/* Remember the folder we navigated to */
|
||||
_xed_window_set_default_location (window, files->data);
|
||||
|
||||
xed_commands_load_locations (window, files, encoding, 0);
|
||||
loaded = xed_commands_load_locations (window, files, encoding, 0);
|
||||
|
||||
g_slist_free (loaded);
|
||||
|
||||
g_slist_foreach (files, (GFunc) g_object_unref, NULL);
|
||||
g_slist_free (files);
|
||||
|
@ -433,9 +442,6 @@ _xed_cmd_file_open (GtkAction *action,
|
|||
gtk_widget_show (open_dialog);
|
||||
}
|
||||
|
||||
/* File saving */
|
||||
static void file_save_as (XedTab *tab, XedWindow *window);
|
||||
|
||||
static gboolean
|
||||
is_read_only (GFile *location)
|
||||
{
|
||||
|
@ -511,6 +517,14 @@ replace_read_only_file (GtkWindow *parent,
|
|||
return (ret == GTK_RESPONSE_YES);
|
||||
}
|
||||
|
||||
static void
|
||||
save_finish_cb (XedTab *tab,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
_xed_tab_save_finish (tab, result);
|
||||
}
|
||||
|
||||
static void
|
||||
save_dialog_response_cb (XedFileChooserDialog *dialog,
|
||||
gint response_id,
|
||||
|
@ -535,13 +549,11 @@ save_dialog_response_cb (XedFileChooserDialog *dialog,
|
|||
{
|
||||
GFile *location;
|
||||
XedDocument *doc;
|
||||
GtkSourceFile *file;
|
||||
gchar *parse_name;
|
||||
GtkSourceNewlineType newline_type;
|
||||
const GtkSourceEncoding *encoding;
|
||||
|
||||
doc = xed_tab_get_document (tab);
|
||||
file = xed_document_get_file (doc);
|
||||
|
||||
location = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
|
||||
g_return_if_fail (location != NULL);
|
||||
|
@ -567,7 +579,13 @@ save_dialog_response_cb (XedFileChooserDialog *dialog,
|
|||
* even if the saving fails... */
|
||||
_xed_window_set_default_location (window, location);
|
||||
|
||||
_xed_tab_save_as (tab, location, encoding, newline_type);
|
||||
_xed_tab_save_as_async (tab,
|
||||
location,
|
||||
encoding,
|
||||
newline_type,
|
||||
NULL,
|
||||
(GAsyncReadyCallback) save_finish_cb,
|
||||
NULL);
|
||||
|
||||
g_object_unref (location);
|
||||
}
|
||||
|
@ -602,7 +620,7 @@ save_next_tab:
|
|||
}
|
||||
|
||||
xed_window_set_active_tab (window, tab);
|
||||
file_save_as (tab, window);
|
||||
save_as_tab (tab, window);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -643,7 +661,7 @@ confirm_overwrite_callback (GtkFileChooser *dialog,
|
|||
}
|
||||
|
||||
static void
|
||||
file_save_as (XedTab *tab,
|
||||
save_as_tab (XedTab *tab,
|
||||
XedWindow *window)
|
||||
{
|
||||
GtkWidget *save_dialog;
|
||||
|
@ -715,7 +733,11 @@ file_save_as (XedTab *tab,
|
|||
|
||||
/* Set suggested encoding */
|
||||
encoding = gtk_source_file_get_encoding (file);
|
||||
g_return_if_fail (encoding != NULL);
|
||||
|
||||
if (encoding == NULL)
|
||||
{
|
||||
encoding = gtk_source_encoding_get_utf8 ();
|
||||
}
|
||||
|
||||
newline_type = gtk_source_file_get_newline_type (file);
|
||||
|
||||
|
@ -731,7 +753,7 @@ file_save_as (XedTab *tab,
|
|||
}
|
||||
|
||||
static void
|
||||
file_save (XedTab *tab,
|
||||
save_tab (XedTab *tab,
|
||||
XedWindow *window)
|
||||
{
|
||||
XedDocument *doc;
|
||||
|
@ -750,7 +772,7 @@ file_save (XedTab *tab,
|
|||
{
|
||||
xed_debug_message (DEBUG_COMMANDS, "Untitled or Readonly");
|
||||
|
||||
file_save_as (tab, window);
|
||||
save_as_tab (tab, window);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -763,7 +785,10 @@ file_save (XedTab *tab,
|
|||
|
||||
g_free (uri_for_display);
|
||||
|
||||
_xed_tab_save (tab);
|
||||
_xed_tab_save_async (tab,
|
||||
NULL,
|
||||
(GAsyncReadyCallback) save_finish_cb,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -780,7 +805,7 @@ _xed_cmd_file_save (GtkAction *action,
|
|||
return;
|
||||
}
|
||||
|
||||
file_save (tab, window);
|
||||
save_tab (tab, window);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -797,14 +822,14 @@ _xed_cmd_file_save_as (GtkAction *action,
|
|||
return;
|
||||
}
|
||||
|
||||
file_save_as (tab, window);
|
||||
save_as_tab (tab, window);
|
||||
}
|
||||
|
||||
/*
|
||||
* The docs in the list must belong to the same XedWindow.
|
||||
*/
|
||||
void
|
||||
_xed_cmd_file_save_documents_list (XedWindow *window,
|
||||
static void
|
||||
save_documents_list (XedWindow *window,
|
||||
GList *docs)
|
||||
{
|
||||
GList *l;
|
||||
|
@ -846,7 +871,7 @@ _xed_cmd_file_save_documents_list (XedWindow *window,
|
|||
}
|
||||
else
|
||||
{
|
||||
file_save (t, window);
|
||||
save_tab (t, window);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -898,7 +923,7 @@ _xed_cmd_file_save_documents_list (XedWindow *window,
|
|||
tab = XED_TAB (tabs_to_save_as->data);
|
||||
|
||||
xed_window_set_active_tab (window, tab);
|
||||
file_save_as (tab, window);
|
||||
save_as_tab (tab, window);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -913,7 +938,7 @@ xed_commands_save_all_documents (XedWindow *window)
|
|||
|
||||
docs = xed_window_get_documents (window);
|
||||
|
||||
_xed_cmd_file_save_documents_list (window, docs);
|
||||
save_documents_list (window, docs);
|
||||
|
||||
g_list_free (docs);
|
||||
}
|
||||
|
@ -937,7 +962,7 @@ xed_commands_save_document (XedWindow *window,
|
|||
xed_debug (DEBUG_COMMANDS);
|
||||
|
||||
tab = xed_tab_get_from_document (document);
|
||||
file_save (tab, window);
|
||||
save_tab (tab, window);
|
||||
}
|
||||
|
||||
/* File revert */
|
||||
|
@ -1213,7 +1238,7 @@ save_and_close (XedTab *tab,
|
|||
/* Trace tab state changes */
|
||||
g_signal_connect (tab, "notify::state", G_CALLBACK (tab_state_changed_while_saving), window);
|
||||
|
||||
file_save (tab, window);
|
||||
save_tab (tab, window);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1228,7 +1253,7 @@ save_as_and_close (XedTab *tab,
|
|||
g_signal_connect (tab, "notify::state", G_CALLBACK (tab_state_changed_while_saving), window);
|
||||
|
||||
xed_window_set_active_tab (window, tab);
|
||||
file_save_as (tab, window);
|
||||
save_as_tab (tab, window);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
|
@ -40,24 +40,26 @@
|
|||
|
||||
#include "xed-commands.h"
|
||||
#include "xed-debug.h"
|
||||
#include "xed-help.h"
|
||||
#include "xed-app.h"
|
||||
#include "xed-dirs.h"
|
||||
|
||||
void _xed_cmd_help_contents(GtkAction* action, XedWindow* window)
|
||||
void _xed_cmd_help_contents (GtkAction *action,
|
||||
XedWindow *window)
|
||||
{
|
||||
xed_debug(DEBUG_COMMANDS);
|
||||
|
||||
xed_help_display(GTK_WINDOW(window), NULL, NULL);
|
||||
xed_app_show_help (XED_APP (g_application_get_default ()), GTK_WINDOW (window), NULL, NULL);
|
||||
}
|
||||
|
||||
void _xed_cmd_help_about(GtkAction* action, XedWindow* window)
|
||||
void _xed_cmd_help_about (GtkAction *action,
|
||||
XedWindow *window)
|
||||
{
|
||||
static const gchar comments[] = \
|
||||
N_("A small and lightweight text editor");
|
||||
|
||||
xed_debug (DEBUG_COMMANDS);
|
||||
|
||||
gtk_show_about_dialog(GTK_WINDOW(window),
|
||||
gtk_show_about_dialog (GTK_WINDOW (window),
|
||||
"program-name", "xed",
|
||||
"comments", _(comments),
|
||||
"logo_icon_name", "accessories-text-editor",
|
||||
|
|
|
@ -25,14 +25,14 @@ void
|
|||
_xed_cmd_search_find (GtkAction *action,
|
||||
XedWindow *window)
|
||||
{
|
||||
xed_searchbar_show (XED_SEARCHBAR (xed_window_get_searchbar (window)), SEARCH_MODE_SEARCH);
|
||||
xed_searchbar_show (XED_SEARCHBAR (xed_window_get_searchbar (window)), XED_SEARCH_MODE_SEARCH);
|
||||
}
|
||||
|
||||
void
|
||||
_xed_cmd_search_replace (GtkAction *action,
|
||||
XedWindow *window)
|
||||
{
|
||||
xed_searchbar_show (XED_SEARCHBAR (xed_window_get_searchbar (window)), SEARCH_MODE_REPLACE);
|
||||
xed_searchbar_show (XED_SEARCHBAR (xed_window_get_searchbar (window)), XED_SEARCH_MODE_REPLACE);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -10,7 +10,7 @@ G_BEGIN_DECLS
|
|||
void xed_commands_load_location (XedWindow *window, GFile *location, const GtkSourceEncoding *encoding, gint line_pos);
|
||||
|
||||
/* Ignore non-existing URIs */
|
||||
gint xed_commands_load_locations (XedWindow *window, const GSList *locations, const GtkSourceEncoding *encoding, gint line_pos);
|
||||
GSList *xed_commands_load_locations (XedWindow *window, const GSList *locations, const GtkSourceEncoding *encoding, gint line_pos);
|
||||
void xed_commands_save_document (XedWindow *window, XedDocument *document);
|
||||
void xed_commands_save_all_documents (XedWindow *window);
|
||||
|
||||
|
@ -19,14 +19,13 @@ void xed_commands_save_all_documents (XedWindow *window);
|
|||
*/
|
||||
|
||||
/* Create titled documens for non-existing URIs */
|
||||
gint _xed_cmd_load_files_from_prompt (XedWindow *window, GSList *files, const GtkSourceEncoding *encoding, gint line_pos);
|
||||
GSList *_xed_cmd_load_files_from_prompt (XedWindow *window, GSList *files, const GtkSourceEncoding *encoding, gint line_pos);
|
||||
void _xed_cmd_file_new (GtkAction *action, XedWindow *window);
|
||||
void _xed_cmd_file_open (GtkAction *action, XedWindow *window);
|
||||
void _xed_cmd_file_save (GtkAction *action, XedWindow *window);
|
||||
void _xed_cmd_file_save_as (GtkAction *action, XedWindow *window);
|
||||
void _xed_cmd_file_save_all (GtkAction *action, XedWindow *window);
|
||||
void _xed_cmd_file_revert (GtkAction *action, XedWindow *window);
|
||||
void _xed_cmd_file_open_uri (GtkAction *action, XedWindow *window);
|
||||
void _xed_cmd_file_print_preview (GtkAction *action, XedWindow *window);
|
||||
void _xed_cmd_file_print (GtkAction *action, XedWindow *window);
|
||||
void _xed_cmd_file_close (GtkAction *action, XedWindow *window);
|
||||
|
@ -67,8 +66,6 @@ void _xed_cmd_help_about (GtkAction *action, XedWindow *window);
|
|||
|
||||
void _xed_cmd_file_close_tab (XedTab *tab, XedWindow *window);
|
||||
|
||||
void _xed_cmd_file_save_documents_list (XedWindow *window, GList *docs);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __XED_COMMANDS_H__ */
|
||||
|
|
136
xed/xed-dirs.c
136
xed/xed-dirs.c
|
@ -27,115 +27,115 @@
|
|||
|
||||
#include "xed-dirs.h"
|
||||
|
||||
gchar *
|
||||
static gchar *user_config_dir = NULL;
|
||||
static gchar *user_cache_dir = NULL;
|
||||
static gchar *user_styles_dir = NULL;
|
||||
static gchar *user_plugins_dir = NULL;
|
||||
static gchar *xed_data_dir = NULL;
|
||||
static gchar *xed_locale_dir = NULL;
|
||||
static gchar *xed_lib_dir = NULL;
|
||||
static gchar *xed_plugins_dir = NULL;
|
||||
static gchar *xed_plugins_data_dir = NULL;
|
||||
|
||||
void
|
||||
xed_dirs_init ()
|
||||
{
|
||||
if (xed_data_dir == NULL)
|
||||
{
|
||||
xed_data_dir = g_build_filename (DATADIR, "xed", NULL);
|
||||
xed_locale_dir = g_build_filename (DATADIR, "locale", NULL);
|
||||
xed_lib_dir = g_build_filename (LIBDIR, "xed", NULL);
|
||||
}
|
||||
|
||||
user_cache_dir = g_build_filename (g_get_user_cache_dir (), "xed", NULL);
|
||||
user_config_dir = g_build_filename (g_get_user_config_dir (), "xed", NULL);
|
||||
user_styles_dir = g_build_filename (g_get_user_data_dir (), "xed", "styles", NULL);
|
||||
user_plugins_dir = g_build_filename (g_get_user_data_dir (), "xed", "plugins", NULL);
|
||||
xed_plugins_dir = g_build_filename (xed_lib_dir, "plugins", NULL);
|
||||
xed_plugins_data_dir = g_build_filename (xed_data_dir, "plugins", NULL);
|
||||
}
|
||||
|
||||
void
|
||||
xed_dirs_shutdown ()
|
||||
{
|
||||
g_free (user_config_dir);
|
||||
g_free (user_cache_dir);
|
||||
g_free (user_plugins_dir);
|
||||
g_free (xed_data_dir);
|
||||
g_free (xed_locale_dir);
|
||||
g_free (xed_lib_dir);
|
||||
g_free (xed_plugins_dir);
|
||||
g_free (xed_plugins_data_dir);
|
||||
}
|
||||
|
||||
const gchar *
|
||||
xed_dirs_get_user_config_dir (void)
|
||||
{
|
||||
gchar* config_dir = NULL;
|
||||
|
||||
config_dir = g_build_filename(g_get_user_config_dir(), "xed", NULL);
|
||||
|
||||
return config_dir;
|
||||
return user_config_dir;
|
||||
}
|
||||
|
||||
gchar *
|
||||
const gchar *
|
||||
xed_dirs_get_user_cache_dir (void)
|
||||
{
|
||||
const gchar* cache_dir;
|
||||
|
||||
cache_dir = g_get_user_cache_dir();
|
||||
|
||||
return g_build_filename(cache_dir, "xed", NULL);
|
||||
return user_cache_dir;
|
||||
}
|
||||
|
||||
gchar *
|
||||
const gchar *
|
||||
xed_dirs_get_user_styles_dir (void)
|
||||
{
|
||||
gchar *user_style_dir;
|
||||
|
||||
user_style_dir = g_build_filename (g_get_user_data_dir (), "xed", "styles", NULL);
|
||||
return user_styles_dir;
|
||||
}
|
||||
|
||||
gchar *
|
||||
const gchar *
|
||||
xed_dirs_get_user_plugins_dir (void)
|
||||
{
|
||||
gchar* plugin_dir;
|
||||
|
||||
plugin_dir = g_build_filename(g_get_user_data_dir(), "xed", "plugins", NULL);
|
||||
|
||||
return plugin_dir;
|
||||
return user_plugins_dir;
|
||||
}
|
||||
|
||||
gchar *
|
||||
xed_dirs_get_user_accels_file (void)
|
||||
{
|
||||
gchar* accels = NULL;
|
||||
gchar *config_dir = NULL;
|
||||
|
||||
config_dir = xed_dirs_get_user_config_dir();
|
||||
accels = g_build_filename(config_dir, "accels", NULL);
|
||||
|
||||
g_free(config_dir);
|
||||
|
||||
return accels;
|
||||
}
|
||||
|
||||
gchar *
|
||||
const gchar *
|
||||
xed_dirs_get_xed_data_dir (void)
|
||||
{
|
||||
return g_build_filename(DATADIR, "xed", NULL);
|
||||
return xed_data_dir;
|
||||
}
|
||||
|
||||
gchar *
|
||||
const gchar *
|
||||
xed_dirs_get_xed_locale_dir (void)
|
||||
{
|
||||
return g_build_filename(DATADIR, "locale", NULL);
|
||||
return xed_locale_dir;
|
||||
}
|
||||
|
||||
gchar *
|
||||
const gchar *
|
||||
xed_dirs_get_xed_lib_dir (void)
|
||||
{
|
||||
return g_build_filename(LIBDIR, "xed", NULL);
|
||||
return xed_lib_dir;
|
||||
}
|
||||
|
||||
gchar *
|
||||
const gchar *
|
||||
xed_dirs_get_xed_plugins_dir (void)
|
||||
{
|
||||
gchar* lib_dir;
|
||||
gchar* plugin_dir;
|
||||
|
||||
lib_dir = xed_dirs_get_xed_lib_dir();
|
||||
|
||||
plugin_dir = g_build_filename(lib_dir, "plugins", NULL);
|
||||
g_free(lib_dir);
|
||||
|
||||
return plugin_dir;
|
||||
return xed_plugins_dir;
|
||||
}
|
||||
|
||||
gchar *
|
||||
const gchar *
|
||||
xed_dirs_get_xed_plugins_data_dir (void)
|
||||
{
|
||||
gchar* data_dir;
|
||||
gchar* plugin_data_dir;
|
||||
return xed_plugins_data_dir;
|
||||
}
|
||||
|
||||
data_dir = xed_dirs_get_xed_data_dir ();
|
||||
|
||||
plugin_data_dir = g_build_filename (data_dir, "plugins", NULL);
|
||||
g_free (data_dir);
|
||||
|
||||
return plugin_data_dir;
|
||||
const gchar *
|
||||
xed_dirs_get_binding_modules_dir (void)
|
||||
{
|
||||
return xed_lib_dir;
|
||||
}
|
||||
|
||||
gchar *
|
||||
xed_dirs_get_ui_file (const gchar* file)
|
||||
xed_dirs_get_ui_file (const gchar *file)
|
||||
{
|
||||
gchar* datadir;
|
||||
gchar* ui_file;
|
||||
gchar *ui_file;
|
||||
|
||||
g_return_val_if_fail(file != NULL, NULL);
|
||||
g_return_val_if_fail (file != NULL, NULL);
|
||||
|
||||
datadir = xed_dirs_get_xed_data_dir();
|
||||
ui_file = g_build_filename(datadir, "ui", file, NULL);
|
||||
g_free(datadir);
|
||||
ui_file = g_build_filename (xed_dirs_get_xed_data_dir (), "ui", file, NULL);
|
||||
|
||||
return ui_file;
|
||||
}
|
||||
|
|
|
@ -28,25 +28,30 @@
|
|||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
gchar *xed_dirs_get_user_config_dir (void);
|
||||
/* This function must be called before starting xed */
|
||||
void xed_dirs_init (void);
|
||||
/* This function must be called before exiting xed */
|
||||
void xed_dirs_shutdown (void);
|
||||
|
||||
gchar *xed_dirs_get_user_cache_dir (void);
|
||||
const gchar *xed_dirs_get_user_config_dir (void);
|
||||
|
||||
gchar *xed_dirs_get_user_styles_dir (void);
|
||||
const gchar *xed_dirs_get_user_cache_dir (void);
|
||||
|
||||
gchar *xed_dirs_get_user_plugins_dir (void);
|
||||
const gchar *xed_dirs_get_user_styles_dir (void);
|
||||
|
||||
gchar *xed_dirs_get_user_accels_file (void);
|
||||
const gchar *xed_dirs_get_user_plugins_dir (void);
|
||||
|
||||
gchar *xed_dirs_get_xed_data_dir (void);
|
||||
const gchar *xed_dirs_get_xed_data_dir (void);
|
||||
|
||||
gchar *xed_dirs_get_xed_locale_dir (void);
|
||||
const gchar *xed_dirs_get_xed_locale_dir (void);
|
||||
|
||||
gchar *xed_dirs_get_xed_lib_dir (void);
|
||||
const gchar *xed_dirs_get_xed_lib_dir (void);
|
||||
|
||||
gchar *xed_dirs_get_xed_plugins_dir (void);
|
||||
const gchar *xed_dirs_get_xed_plugins_dir (void);
|
||||
|
||||
gchar *xed_dirs_get_xed_plugins_data_dir (void);
|
||||
const gchar *xed_dirs_get_xed_plugins_data_dir (void);
|
||||
|
||||
const gchar *xed_dirs_get_binding_modules_dir (void);
|
||||
|
||||
gchar *xed_dirs_get_ui_file (const gchar *file);
|
||||
|
||||
|
|
|
@ -510,6 +510,12 @@ save_encoding_metadata (XedDocument *doc)
|
|||
xed_debug (DEBUG_DOCUMENT);
|
||||
|
||||
encoding = gtk_source_file_get_encoding (doc->priv->file);
|
||||
|
||||
if (encoding == NULL)
|
||||
{
|
||||
encoding = gtk_source_encoding_get_utf8 ();
|
||||
}
|
||||
|
||||
charset = gtk_source_encoding_get_charset (encoding);
|
||||
|
||||
xed_document_set_metadata (doc, XED_METADATA_ATTRIBUTE_ENCODING, charset, NULL);
|
||||
|
@ -954,8 +960,6 @@ loaded_query_info_cb (GFile *location,
|
|||
XedDocument *doc)
|
||||
{
|
||||
GFileInfo *info;
|
||||
const gchar *content_type = NULL;
|
||||
gboolean read_only = FALSE;
|
||||
GError *error = NULL;
|
||||
|
||||
info = g_file_query_info_finish (location, result, &error);
|
||||
|
@ -974,18 +978,22 @@ loaded_query_info_cb (GFile *location,
|
|||
error = NULL;
|
||||
}
|
||||
|
||||
doc->priv->mtime_set = FALSE;
|
||||
|
||||
if (info != NULL)
|
||||
{
|
||||
if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE))
|
||||
{
|
||||
const gchar *content_type;
|
||||
|
||||
content_type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
|
||||
xed_document_set_content_type (doc, content_type);
|
||||
}
|
||||
|
||||
if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))
|
||||
{
|
||||
gboolean read_only;
|
||||
|
||||
read_only = !g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE);
|
||||
set_readonly (doc, read_only);
|
||||
}
|
||||
|
||||
if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED))
|
||||
|
@ -993,22 +1001,19 @@ loaded_query_info_cb (GFile *location,
|
|||
g_file_info_get_modification_time (info, &doc->priv->mtime);
|
||||
doc->priv->mtime_set = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
set_readonly (doc, read_only);
|
||||
|
||||
g_get_current_time (&doc->priv->time_of_last_save_or_load);
|
||||
|
||||
doc->priv->externally_modified = FALSE;
|
||||
doc->priv->deleted = FALSE;
|
||||
|
||||
xed_document_set_content_type (doc, content_type);
|
||||
|
||||
if (info != NULL)
|
||||
{
|
||||
g_object_unref (info);
|
||||
}
|
||||
|
||||
/* Async operation finished. */
|
||||
g_object_unref (doc);
|
||||
}
|
||||
|
||||
static void
|
||||
xed_document_loaded_real (XedDocument *doc)
|
||||
{
|
||||
GFile *location;
|
||||
|
||||
if (!doc->priv->language_set_by_user)
|
||||
{
|
||||
GtkSourceLanguage *language = guess_language (doc);
|
||||
|
@ -1019,15 +1024,20 @@ loaded_query_info_cb (GFile *location,
|
|||
set_language (doc, language, FALSE);
|
||||
}
|
||||
|
||||
/* Async operation finished. */
|
||||
g_object_unref (doc);
|
||||
}
|
||||
doc->priv->mtime_set = FALSE;
|
||||
doc->priv->externally_modified = FALSE;
|
||||
doc->priv->deleted = FALSE;
|
||||
|
||||
static void
|
||||
xed_document_loaded_real (XedDocument *doc)
|
||||
{
|
||||
GFile *location = gtk_source_file_get_location (doc->priv->file);
|
||||
g_get_current_time (&doc->priv->time_of_last_save_or_load);
|
||||
|
||||
set_readonly (doc, FALSE);
|
||||
|
||||
xed_document_set_content_type (doc, NULL);
|
||||
|
||||
location = gtk_source_file_get_location (doc->priv->file);
|
||||
|
||||
if (location != NULL)
|
||||
{
|
||||
/* Keep the doc alive during the async operation. */
|
||||
g_object_ref (doc);
|
||||
|
||||
|
@ -1040,6 +1050,7 @@ xed_document_loaded_real (XedDocument *doc)
|
|||
NULL,
|
||||
(GAsyncReadyCallback) loaded_query_info_cb,
|
||||
doc);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1191,9 +1202,11 @@ check_file_on_disk (XedDocument *doc)
|
|||
|
||||
g_file_info_get_modification_time (info, &timeval);
|
||||
|
||||
if (timeval.tv_sec > doc->priv->mtime.tv_sec ||
|
||||
(timeval.tv_sec == doc->priv->mtime.tv_sec &&
|
||||
timeval.tv_usec > doc->priv->mtime.tv_usec))
|
||||
/* Note that mtime can even go backwards if the
|
||||
* user is copying over a file with an old mtime
|
||||
*/
|
||||
if (timeval.tv_sec != doc->priv->mtime.tv_sec ||
|
||||
timeval.tv_usec != doc->priv->mtime.tv_usec)
|
||||
{
|
||||
doc->priv->externally_modified = TRUE;
|
||||
}
|
||||
|
|
|
@ -1,99 +0,0 @@
|
|||
/*
|
||||
* xed-help.c
|
||||
* This file is part of xed
|
||||
*
|
||||
* 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 xed Team, 2005. See the AUTHORS file for a
|
||||
* list of people on the xed Team.
|
||||
* See the ChangeLog files for a list of changes.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "xed-help.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <string.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
gboolean
|
||||
xed_help_display (GtkWindow *parent,
|
||||
const gchar *name, /* "xed" 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 = "xed";
|
||||
else if (strcmp (name, "xed.xml") == 0)
|
||||
{
|
||||
g_warning ("%s: Using \"xed.xml\" for the help name is deprecated, use \"xed\" or simply NULL instead", G_STRFUNC);
|
||||
|
||||
name = "xed";
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
* xed-help.h
|
||||
* This file is part of xed
|
||||
*
|
||||
* 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 xed Team, 2005. See the AUTHORS file for a
|
||||
* list of people on the xed Team.
|
||||
* See the ChangeLog files for a list of changes.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef __XED_HELP_H__
|
||||
#define __XED_HELP_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
gboolean xed_help_display (GtkWindow *parent,
|
||||
const gchar *name, /* "xed" if NULL */
|
||||
const gchar *link_id);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __XED_HELP_H__ */
|
|
@ -27,23 +27,16 @@
|
|||
* 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 "xed-metadata-manager.h"
|
||||
#include "xed-debug.h"
|
||||
#include "xed-dirs.h"
|
||||
|
||||
/*
|
||||
#define XED_METADATA_VERBOSE_DEBUG 1
|
||||
*/
|
||||
|
||||
#define METADATA_FILE "xed-metadata.xml"
|
||||
|
||||
#define MAX_ITEMS 50
|
||||
|
||||
typedef struct _XedMetadataManager XedMetadataManager;
|
||||
|
@ -65,6 +58,8 @@ struct _XedMetadataManager
|
|||
guint timeout_id;
|
||||
|
||||
GHashTable *items;
|
||||
|
||||
gchar *metadata_filename;
|
||||
};
|
||||
|
||||
static gboolean xed_metadata_manager_save (gpointer data);
|
||||
|
@ -105,13 +100,20 @@ xed_metadata_manager_arm_timeout (void)
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
xed_metadata_manager_init (void)
|
||||
/**
|
||||
* xed_metadata_manager_init:
|
||||
* @metadata_filename: the filename where the metadata is.
|
||||
*
|
||||
* This function initializes the metadata manager.
|
||||
* See also xed_metadata_manager_shutdown().
|
||||
*/
|
||||
void
|
||||
xed_metadata_manager_init (const gchar *metadata_filename)
|
||||
{
|
||||
xed_debug (DEBUG_METADATA);
|
||||
|
||||
if (xed_metadata_manager != NULL)
|
||||
return TRUE;
|
||||
return;
|
||||
|
||||
xed_metadata_manager = g_new0 (XedMetadataManager, 1);
|
||||
|
||||
|
@ -123,10 +125,17 @@ xed_metadata_manager_init (void)
|
|||
g_free,
|
||||
item_free);
|
||||
|
||||
return TRUE;
|
||||
xed_metadata_manager->metadata_filename = g_strdup (metadata_filename);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* This function must be called before exiting xed */
|
||||
/**
|
||||
* xed_metadata_manager_shutdown:
|
||||
*
|
||||
* This function frees the internal data of the metadata manager.
|
||||
* See also xed_metadata_manager_init().
|
||||
*/
|
||||
void
|
||||
xed_metadata_manager_shutdown (void)
|
||||
{
|
||||
|
@ -145,6 +154,7 @@ xed_metadata_manager_shutdown (void)
|
|||
if (xed_metadata_manager->items != NULL)
|
||||
g_hash_table_destroy (xed_metadata_manager->items);
|
||||
|
||||
g_free (gedit_metadata_manager->metadata_filename);
|
||||
g_free (xed_metadata_manager);
|
||||
xed_metadata_manager = NULL;
|
||||
}
|
||||
|
@ -218,29 +228,11 @@ parseItem (xmlDocPtr doc, xmlNodePtr cur)
|
|||
xmlFree (atime);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
get_metadata_filename (void)
|
||||
{
|
||||
gchar *cache_dir;
|
||||
gchar *metadata;
|
||||
|
||||
cache_dir = xed_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;
|
||||
|
||||
xed_debug (DEBUG_METADATA);
|
||||
|
||||
|
@ -252,16 +244,13 @@ load_values (void)
|
|||
xmlKeepBlanksDefault (0);
|
||||
|
||||
/* FIXME: file locking - Paolo */
|
||||
file_name = get_metadata_filename ();
|
||||
if ((file_name == NULL) ||
|
||||
(!g_file_test (file_name, G_FILE_TEST_EXISTS)))
|
||||
if ((xed_metadata_manager->metadata_filename == NULL) ||
|
||||
(!g_file_test (xed_metadata_manager->metadata_filename, G_FILE_TEST_EXISTS)))
|
||||
{
|
||||
g_free (file_name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
doc = xmlParseFile (file_name);
|
||||
g_free (file_name);
|
||||
doc = xmlParseFile (xed_metadata_manager->metadata_filename);
|
||||
|
||||
if (doc == NULL)
|
||||
{
|
||||
|
@ -271,7 +260,7 @@ load_values (void)
|
|||
cur = xmlDocGetRootElement (doc);
|
||||
if (cur == NULL)
|
||||
{
|
||||
g_message ("The metadata file '%s' is empty", METADATA_FILE);
|
||||
g_message ("The metadata file '%s' is empty", g_path_get_basename (xed_metadata_manager->metadata_filename));
|
||||
xmlFreeDoc (doc);
|
||||
|
||||
return FALSE;
|
||||
|
@ -279,7 +268,7 @@ load_values (void)
|
|||
|
||||
if (xmlStrcmp (cur->name, (const xmlChar *) "metadata"))
|
||||
{
|
||||
g_message ("File '%s' is of the wrong type", METADATA_FILE);
|
||||
g_message ("File '%s' is of the wrong type", g_path_get_basename (xed_metadata_manager->metadata_filename));
|
||||
xmlFreeDoc (doc);
|
||||
|
||||
return FALSE;
|
||||
|
@ -300,6 +289,13 @@ load_values (void)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* xed_metadata_manager_get:
|
||||
* @location: a #GFile.
|
||||
* @key: a key.
|
||||
*
|
||||
* Gets the value associated with the specified @key for the file @location.
|
||||
*/
|
||||
gchar *
|
||||
xed_metadata_manager_get (GFile *location,
|
||||
const gchar *key)
|
||||
|
@ -315,8 +311,6 @@ xed_metadata_manager_get (GFile *location,
|
|||
|
||||
xed_debug_message (DEBUG_METADATA, "URI: %s --- key: %s", uri, key );
|
||||
|
||||
xed_metadata_manager_init ();
|
||||
|
||||
if (!xed_metadata_manager->values_loaded)
|
||||
{
|
||||
gboolean res;
|
||||
|
@ -348,6 +342,14 @@ xed_metadata_manager_get (GFile *location,
|
|||
return g_strdup (value);
|
||||
}
|
||||
|
||||
/**
|
||||
* xed_metadata_manager_set:
|
||||
* @location: a #GFile.
|
||||
* @key: a key.
|
||||
* @value: the value associated with the @key.
|
||||
*
|
||||
* Sets the @key to contain the given @value for the file @location.
|
||||
*/
|
||||
void
|
||||
xed_metadata_manager_set (GFile *location,
|
||||
const gchar *key,
|
||||
|
@ -363,8 +365,6 @@ xed_metadata_manager_set (GFile *location,
|
|||
|
||||
xed_debug_message (DEBUG_METADATA, "URI: %s --- key: %s --- value: %s", uri, key, value);
|
||||
|
||||
xed_metadata_manager_init ();
|
||||
|
||||
if (!xed_metadata_manager->values_loaded)
|
||||
{
|
||||
gboolean res;
|
||||
|
@ -523,7 +523,6 @@ xed_metadata_manager_save (gpointer data)
|
|||
{
|
||||
xmlDocPtr doc;
|
||||
xmlNodePtr root;
|
||||
gchar *file_name;
|
||||
|
||||
xed_debug (DEBUG_METADATA);
|
||||
|
||||
|
@ -546,22 +545,20 @@ xed_metadata_manager_save (gpointer data)
|
|||
root);
|
||||
|
||||
/* FIXME: lock file - Paolo */
|
||||
file_name = get_metadata_filename ();
|
||||
if (file_name != NULL)
|
||||
if (xed_metadata_manager->metadata_filename != NULL)
|
||||
{
|
||||
gchar *cache_dir;
|
||||
int res;
|
||||
|
||||
/* make sure the cache dir exists */
|
||||
cache_dir = xed_dirs_get_user_cache_dir ();
|
||||
cache_dir = g_path_get_dirname (xed_metadata_manager->metadata_filename);
|
||||
res = g_mkdir_with_parents (cache_dir, 0755);
|
||||
if (res != -1)
|
||||
{
|
||||
xmlSaveFormatFile (file_name, doc, 1);
|
||||
xmlSaveFormatFile (xed_metadata_manager->metadata_filename, doc, 1);
|
||||
}
|
||||
|
||||
g_free (cache_dir);
|
||||
g_free (file_name);
|
||||
}
|
||||
|
||||
xmlFreeDoc (doc);
|
||||
|
|
|
@ -34,13 +34,14 @@
|
|||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void xed_metadata_manager_init (const gchar *metadata_filename);
|
||||
|
||||
/* This function must be called before exiting xed */
|
||||
void xed_metadata_manager_shutdown (void);
|
||||
|
||||
|
||||
gchar *xed_metadata_manager_get (GFile *location,
|
||||
const gchar *key);
|
||||
|
||||
void xed_metadata_manager_set (GFile *location,
|
||||
const gchar *key,
|
||||
const gchar *value);
|
||||
|
|
|
@ -54,7 +54,7 @@ struct _XedSearchbarPrivate
|
|||
GtkWidget *close_button;
|
||||
|
||||
GtkSourceSearchSettings *search_settings;
|
||||
SearchMode search_mode;
|
||||
XedSearchMode search_mode;
|
||||
|
||||
guint update_occurrence_count_id;
|
||||
};
|
||||
|
@ -280,7 +280,7 @@ update_occurrence_count (XedSearchbar *searchbar)
|
|||
gint count;
|
||||
gint pos;
|
||||
|
||||
if (searchbar->priv->search_mode == SEARCH_MODE_REPLACE)
|
||||
if (searchbar->priv->search_mode == XED_SEARCH_MODE_REPLACE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -376,7 +376,7 @@ do_find (XedSearchbar *searchbar,
|
|||
search_settings = xed_searchbar_get_search_settings (searchbar);
|
||||
doc = xed_window_get_active_document (searchbar->window);
|
||||
search_context = xed_document_get_search_context (doc);
|
||||
searchbar->priv->search_mode = SEARCH_MODE_SEARCH;
|
||||
searchbar->priv->search_mode = XED_SEARCH_MODE_SEARCH;
|
||||
|
||||
if (search_context == NULL || search_settings != gtk_source_search_context_get_settings (search_context))
|
||||
{
|
||||
|
@ -487,7 +487,7 @@ do_replace (XedSearchbar *searchbar)
|
|||
|
||||
unescaped_replace_text = gtk_source_utils_unescape_search_text (replace_entry_text);
|
||||
gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (doc), &start, &end);
|
||||
searchbar->priv->search_mode = SEARCH_MODE_REPLACE;
|
||||
searchbar->priv->search_mode = XED_SEARCH_MODE_REPLACE;
|
||||
|
||||
gtk_source_search_context_replace (search_context,
|
||||
&start,
|
||||
|
@ -530,7 +530,7 @@ do_replace_all (XedSearchbar *searchbar)
|
|||
|
||||
unescaped_replace_text = gtk_source_utils_unescape_search_text (replace_entry_text);
|
||||
count = gtk_source_search_context_replace_all (search_context, unescaped_replace_text, -1, NULL);
|
||||
searchbar->priv->search_mode = SEARCH_MODE_REPLACE;
|
||||
searchbar->priv->search_mode = XED_SEARCH_MODE_REPLACE;
|
||||
|
||||
g_free (unescaped_replace_text);
|
||||
|
||||
|
@ -800,7 +800,7 @@ xed_searchbar_new (GtkWindow *parent)
|
|||
|
||||
void
|
||||
xed_searchbar_show (XedSearchbar *searchbar,
|
||||
SearchMode search_mode)
|
||||
XedSearchMode search_mode)
|
||||
{
|
||||
XedDocument *doc;
|
||||
gboolean selection_exists;
|
||||
|
@ -835,7 +835,7 @@ xed_searchbar_show (XedSearchbar *searchbar,
|
|||
gtk_revealer_set_transition_type (GTK_REVEALER (searchbar->priv->revealer), GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP);
|
||||
gtk_revealer_set_reveal_child (GTK_REVEALER (searchbar->priv->revealer), TRUE);
|
||||
|
||||
if (search_mode == SEARCH_MODE_REPLACE)
|
||||
if (search_mode == XED_SEARCH_MODE_REPLACE)
|
||||
{
|
||||
gtk_widget_show (searchbar->priv->replace_label);
|
||||
gtk_widget_show (searchbar->priv->replace_entry);
|
||||
|
|
|
@ -39,16 +39,16 @@ struct _XedSearchbarClass
|
|||
|
||||
typedef enum
|
||||
{
|
||||
SEARCH_MODE_SEARCH,
|
||||
SEARCH_MODE_REPLACE
|
||||
} SearchMode;
|
||||
XED_SEARCH_MODE_SEARCH,
|
||||
XED_SEARCH_MODE_REPLACE
|
||||
} XedSearchMode;
|
||||
|
||||
GType xed_searchbar_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkWidget *xed_searchbar_new (GtkWindow *parent);
|
||||
|
||||
void xed_searchbar_hide (XedSearchbar *searchbar);
|
||||
void xed_searchbar_show (XedSearchbar *searchbar, SearchMode search_mode);
|
||||
void xed_searchbar_show (XedSearchbar *searchbar, XedSearchMode search_mode);
|
||||
void xed_searchbar_find_again (XedSearchbar *searchbar, gboolean backward);
|
||||
|
||||
const gchar *xed_searchbar_get_replace_text (XedSearchbar *searchbar);
|
||||
|
|
|
@ -1,618 +0,0 @@
|
|||
/*
|
||||
* xed-session.c - Basic session management for xed
|
||||
* This file is part of xed
|
||||
*
|
||||
* Copyright (C) 2002 Ximian, Inc.
|
||||
* Copyright (C) 2005 - Paolo Maggi
|
||||
*
|
||||
* Author: Federico Mena-Quintero <federico@ximian.com>
|
||||
*
|
||||
* 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 xed Team, 2002-2005. See the AUTHORS file for a
|
||||
* list of people on the xed Team.
|
||||
* See the ChangeLog files for a list of changes.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libxml/tree.h>
|
||||
#include <libxml/xmlwriter.h>
|
||||
|
||||
#include "xed-session.h"
|
||||
|
||||
#include "xed-debug.h"
|
||||
#include "xed-plugins-engine.h"
|
||||
#include "xed-metadata-manager.h"
|
||||
#include "xed-window.h"
|
||||
#include "xed-app.h"
|
||||
#include "xed-commands.h"
|
||||
#include "dialogs/xed-close-confirmation-dialog.h"
|
||||
#include "smclient/eggsmclient.h"
|
||||
|
||||
/* The master client we use for SM */
|
||||
static EggSMClient *master_client = NULL;
|
||||
|
||||
/* global var used during quit_requested */
|
||||
static GSList *window_dirty_list;
|
||||
|
||||
static void ask_next_confirmation (void);
|
||||
|
||||
#define XED_SESSION_LIST_OF_DOCS_TO_SAVE "xed-session-list-of-docs-to-save-key"
|
||||
|
||||
static void
|
||||
save_window_session (GKeyFile *state_file,
|
||||
const gchar *group_name,
|
||||
XedWindow *window)
|
||||
{
|
||||
const gchar *role;
|
||||
int width, height;
|
||||
XedPanel *panel;
|
||||
GList *docs, *l;
|
||||
GPtrArray *doc_array;
|
||||
XedDocument *active_document;
|
||||
gchar *uri = NULL;
|
||||
|
||||
xed_debug (DEBUG_SESSION);
|
||||
|
||||
role = gtk_window_get_role (GTK_WINDOW (window));
|
||||
g_key_file_set_string (state_file, group_name, "role", role);
|
||||
gtk_window_get_size (GTK_WINDOW (window), &width, &height);
|
||||
g_key_file_set_integer (state_file, group_name, "width", width);
|
||||
g_key_file_set_integer (state_file, group_name, "height", height);
|
||||
|
||||
panel = xed_window_get_side_panel (window);
|
||||
g_key_file_set_boolean (state_file, group_name, "side-panel-visible",
|
||||
gtk_widget_get_visible (GTK_WIDGET (panel)));
|
||||
|
||||
panel = xed_window_get_bottom_panel (window);
|
||||
g_key_file_set_boolean (state_file, group_name, "bottom-panel-visible",
|
||||
gtk_widget_get_visible (GTK_WIDGET (panel)));
|
||||
|
||||
active_document = xed_window_get_active_document (window);
|
||||
if (active_document)
|
||||
{
|
||||
GFile *location;
|
||||
|
||||
location = xed_document_get_location (active_document);
|
||||
if (location)
|
||||
{
|
||||
uri = g_file_get_uri (location);
|
||||
g_object_unref (location);
|
||||
}
|
||||
|
||||
g_key_file_set_string (state_file, group_name, "active-document", uri);
|
||||
g_free (uri);
|
||||
}
|
||||
|
||||
docs = xed_window_get_documents (window);
|
||||
|
||||
doc_array = g_ptr_array_new ();
|
||||
for (l = docs; l != NULL; l = g_list_next (l))
|
||||
{
|
||||
GFile *location;
|
||||
|
||||
location = xed_document_get_location (XED_DOCUMENT (l->data));
|
||||
if (location)
|
||||
{
|
||||
uri = g_file_get_uri (location);
|
||||
g_object_unref (location);
|
||||
}
|
||||
|
||||
if (uri != NULL)
|
||||
{
|
||||
g_ptr_array_add (doc_array, uri);
|
||||
}
|
||||
|
||||
}
|
||||
g_list_free (docs);
|
||||
|
||||
if (doc_array->len)
|
||||
{
|
||||
g_key_file_set_string_list (state_file, group_name,
|
||||
"documents",
|
||||
(const char **)doc_array->pdata,
|
||||
doc_array->len);
|
||||
g_ptr_array_foreach (doc_array, (GFunc) g_free, NULL);
|
||||
}
|
||||
g_ptr_array_free (doc_array, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
client_save_state_cb (EggSMClient *client,
|
||||
GKeyFile *state_file,
|
||||
gpointer user_data)
|
||||
{
|
||||
const GList *windows;
|
||||
gchar *group_name;
|
||||
int n;
|
||||
|
||||
windows = xed_app_get_windows (xed_app_get_default ());
|
||||
n = 1;
|
||||
|
||||
while (windows != NULL)
|
||||
{
|
||||
group_name = g_strdup_printf ("xed window %d", n);
|
||||
save_window_session (state_file,
|
||||
group_name,
|
||||
XED_WINDOW (windows->data));
|
||||
g_free (group_name);
|
||||
|
||||
windows = g_list_next (windows);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
window_handled (XedWindow *window)
|
||||
{
|
||||
window_dirty_list = g_slist_remove (window_dirty_list, window);
|
||||
|
||||
/* whee... we made it! */
|
||||
if (window_dirty_list == NULL)
|
||||
egg_sm_client_will_quit (master_client, TRUE);
|
||||
else
|
||||
ask_next_confirmation ();
|
||||
}
|
||||
|
||||
static void
|
||||
window_state_change (XedWindow *window,
|
||||
GParamSpec *pspec,
|
||||
gpointer data)
|
||||
{
|
||||
XedWindowState state;
|
||||
GList *unsaved_docs;
|
||||
GList *docs_to_save;
|
||||
GList *l;
|
||||
gboolean done = TRUE;
|
||||
|
||||
state = xed_window_get_state (window);
|
||||
|
||||
/* we are still saving */
|
||||
if (state & XED_WINDOW_STATE_SAVING)
|
||||
return;
|
||||
|
||||
unsaved_docs = xed_window_get_unsaved_documents (window);
|
||||
|
||||
docs_to_save = g_object_get_data (G_OBJECT (window),
|
||||
XED_SESSION_LIST_OF_DOCS_TO_SAVE);
|
||||
|
||||
|
||||
for (l = docs_to_save; l != NULL; l = l->next)
|
||||
{
|
||||
if (g_list_find (unsaved_docs, l->data))
|
||||
{
|
||||
done = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (done)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (window, window_state_change, data);
|
||||
g_list_free (docs_to_save);
|
||||
g_object_set_data (G_OBJECT (window),
|
||||
XED_SESSION_LIST_OF_DOCS_TO_SAVE,
|
||||
NULL);
|
||||
|
||||
window_handled (window);
|
||||
}
|
||||
|
||||
g_list_free (unsaved_docs);
|
||||
}
|
||||
|
||||
static void
|
||||
close_confirmation_dialog_response_handler (XedCloseConfirmationDialog *dlg,
|
||||
gint response_id,
|
||||
XedWindow *window)
|
||||
{
|
||||
GList *selected_documents;
|
||||
GSList *l;
|
||||
|
||||
xed_debug (DEBUG_COMMANDS);
|
||||
|
||||
switch (response_id)
|
||||
{
|
||||
case GTK_RESPONSE_YES:
|
||||
/* save selected docs */
|
||||
|
||||
g_signal_connect (window,
|
||||
"notify::state",
|
||||
G_CALLBACK (window_state_change),
|
||||
NULL);
|
||||
|
||||
selected_documents = xed_close_confirmation_dialog_get_selected_documents (dlg);
|
||||
|
||||
g_return_if_fail (g_object_get_data (G_OBJECT (window),
|
||||
XED_SESSION_LIST_OF_DOCS_TO_SAVE) == NULL);
|
||||
|
||||
g_object_set_data (G_OBJECT (window),
|
||||
XED_SESSION_LIST_OF_DOCS_TO_SAVE,
|
||||
selected_documents);
|
||||
|
||||
_xed_cmd_file_save_documents_list (window, selected_documents);
|
||||
|
||||
/* FIXME: also need to lock the window to prevent further changes... */
|
||||
|
||||
break;
|
||||
|
||||
case GTK_RESPONSE_NO:
|
||||
/* dont save */
|
||||
window_handled (window);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* disconnect window_state_changed where needed */
|
||||
for (l = window_dirty_list; l != NULL; l = l->next)
|
||||
g_signal_handlers_disconnect_by_func (window,
|
||||
window_state_change, NULL);
|
||||
g_slist_free (window_dirty_list);
|
||||
window_dirty_list = NULL;
|
||||
|
||||
/* cancel shutdown */
|
||||
egg_sm_client_will_quit (master_client, FALSE);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
gtk_widget_destroy (GTK_WIDGET (dlg));
|
||||
}
|
||||
|
||||
static void
|
||||
show_confirmation_dialog (XedWindow *window)
|
||||
{
|
||||
GList *unsaved_docs;
|
||||
GtkWidget *dlg;
|
||||
|
||||
xed_debug (DEBUG_SESSION);
|
||||
|
||||
unsaved_docs = xed_window_get_unsaved_documents (window);
|
||||
|
||||
g_return_if_fail (unsaved_docs != NULL);
|
||||
|
||||
if (unsaved_docs->next == NULL)
|
||||
{
|
||||
/* There is only one unsaved document */
|
||||
XedTab *tab;
|
||||
XedDocument *doc;
|
||||
|
||||
doc = XED_DOCUMENT (unsaved_docs->data);
|
||||
|
||||
tab = xed_tab_get_from_document (doc);
|
||||
g_return_if_fail (tab != NULL);
|
||||
|
||||
xed_window_set_active_tab (window, tab);
|
||||
|
||||
dlg = xed_close_confirmation_dialog_new_single (
|
||||
GTK_WINDOW (window),
|
||||
doc,
|
||||
TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
dlg = xed_close_confirmation_dialog_new (GTK_WINDOW (window),
|
||||
unsaved_docs,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
g_list_free (unsaved_docs);
|
||||
|
||||
g_signal_connect (dlg,
|
||||
"response",
|
||||
G_CALLBACK (close_confirmation_dialog_response_handler),
|
||||
window);
|
||||
|
||||
gtk_widget_show (dlg);
|
||||
}
|
||||
|
||||
static void
|
||||
ask_next_confirmation (void)
|
||||
{
|
||||
g_return_if_fail (window_dirty_list != NULL);
|
||||
|
||||
/* pop up the confirmation dialog for the first window
|
||||
* in the dirty list. The next confirmation is asked once
|
||||
* this one has been handled.
|
||||
*/
|
||||
show_confirmation_dialog (XED_WINDOW (window_dirty_list->data));
|
||||
}
|
||||
|
||||
/* quit_requested handler for the master client */
|
||||
static void
|
||||
client_quit_requested_cb (EggSMClient *client, gpointer data)
|
||||
{
|
||||
XedApp *app;
|
||||
const GList *l;
|
||||
|
||||
xed_debug (DEBUG_SESSION);
|
||||
|
||||
app = xed_app_get_default ();
|
||||
|
||||
if (window_dirty_list != NULL)
|
||||
{
|
||||
g_critical ("global variable window_dirty_list not NULL");
|
||||
window_dirty_list = NULL;
|
||||
}
|
||||
|
||||
for (l = xed_app_get_windows (app); l != NULL; l = l->next)
|
||||
{
|
||||
if (xed_window_get_unsaved_documents (XED_WINDOW (l->data)) != NULL)
|
||||
{
|
||||
window_dirty_list = g_slist_prepend (window_dirty_list, l->data);
|
||||
}
|
||||
}
|
||||
|
||||
/* no modified docs */
|
||||
if (window_dirty_list == NULL)
|
||||
{
|
||||
egg_sm_client_will_quit (client, TRUE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ask_next_confirmation ();
|
||||
|
||||
xed_debug_message (DEBUG_SESSION, "END");
|
||||
}
|
||||
|
||||
/* quit handler for the master client */
|
||||
static void
|
||||
client_quit_cb (EggSMClient *client, gpointer data)
|
||||
{
|
||||
#if 0
|
||||
xed_debug (DEBUG_SESSION);
|
||||
|
||||
if (!client->save_yourself_emitted)
|
||||
xed_file_close_all ();
|
||||
|
||||
xed_debug_message (DEBUG_FILE, "All files closed.");
|
||||
|
||||
matecomponent_mdi_destroy (MATECOMPONENT_MDI (xed_mdi));
|
||||
|
||||
xed_debug_message (DEBUG_FILE, "Unref xed_mdi.");
|
||||
|
||||
g_object_unref (G_OBJECT (xed_mdi));
|
||||
|
||||
xed_debug_message (DEBUG_FILE, "Unref xed_mdi: DONE");
|
||||
|
||||
xed_debug_message (DEBUG_FILE, "Unref xed_app_server.");
|
||||
|
||||
matecomponent_object_unref (xed_app_server);
|
||||
|
||||
xed_debug_message (DEBUG_FILE, "Unref xed_app_server: DONE");
|
||||
#endif
|
||||
|
||||
gtk_main_quit ();
|
||||
}
|
||||
|
||||
/**
|
||||
* xed_session_init:
|
||||
*
|
||||
* Initializes session management support. This function should be called near
|
||||
* the beginning of the program.
|
||||
**/
|
||||
void
|
||||
xed_session_init (void)
|
||||
{
|
||||
xed_debug (DEBUG_SESSION);
|
||||
|
||||
if (master_client)
|
||||
return;
|
||||
|
||||
master_client = egg_sm_client_get ();
|
||||
g_signal_connect (master_client,
|
||||
"save_state",
|
||||
G_CALLBACK (client_save_state_cb),
|
||||
NULL);
|
||||
g_signal_connect (master_client,
|
||||
"quit_requested",
|
||||
G_CALLBACK (client_quit_requested_cb),
|
||||
NULL);
|
||||
g_signal_connect (master_client,
|
||||
"quit",
|
||||
G_CALLBACK (client_quit_cb),
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* xed_session_is_restored:
|
||||
*
|
||||
* Returns whether this xed is running from a restarted session.
|
||||
*
|
||||
* Return value: TRUE if the session manager restarted us, FALSE otherwise.
|
||||
* This should be used to determine whether to pay attention to command line
|
||||
* arguments in case the session was not restored.
|
||||
**/
|
||||
gboolean
|
||||
xed_session_is_restored (void)
|
||||
{
|
||||
gboolean restored;
|
||||
|
||||
xed_debug (DEBUG_SESSION);
|
||||
|
||||
if (!master_client)
|
||||
return FALSE;
|
||||
|
||||
restored = egg_sm_client_is_resumed (master_client);
|
||||
|
||||
xed_debug_message (DEBUG_SESSION, restored ? "RESTORED" : "NOT RESTORED");
|
||||
|
||||
return restored;
|
||||
}
|
||||
|
||||
static void
|
||||
parse_window (GKeyFile *state_file, const char *group_name)
|
||||
{
|
||||
XedWindow *window;
|
||||
gchar *role, *active_document, **documents;
|
||||
int width, height;
|
||||
gboolean visible;
|
||||
XedPanel *panel;
|
||||
GError *error = NULL;
|
||||
|
||||
role = g_key_file_get_string (state_file, group_name, "role", NULL);
|
||||
|
||||
xed_debug_message (DEBUG_SESSION, "Window role: %s", role);
|
||||
|
||||
window = _xed_app_restore_window (xed_app_get_default (), (gchar *) role);
|
||||
g_free (role);
|
||||
|
||||
if (window == NULL)
|
||||
{
|
||||
g_warning ("Couldn't restore window");
|
||||
return;
|
||||
}
|
||||
|
||||
width = g_key_file_get_integer (state_file, group_name,
|
||||
"width", &error);
|
||||
if (error)
|
||||
{
|
||||
g_clear_error (&error);
|
||||
width = -1;
|
||||
}
|
||||
height = g_key_file_get_integer (state_file, group_name,
|
||||
"height", &error);
|
||||
if (error)
|
||||
{
|
||||
g_clear_error (&error);
|
||||
height = -1;
|
||||
}
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), width, height);
|
||||
|
||||
|
||||
visible = g_key_file_get_boolean (state_file, group_name,
|
||||
"side-panel-visible", &error);
|
||||
if (error)
|
||||
{
|
||||
g_clear_error (&error);
|
||||
visible = FALSE;
|
||||
}
|
||||
|
||||
panel = xed_window_get_side_panel (window);
|
||||
|
||||
if (visible)
|
||||
{
|
||||
xed_debug_message (DEBUG_SESSION, "Side panel visible");
|
||||
gtk_widget_show (GTK_WIDGET (panel));
|
||||
}
|
||||
else
|
||||
{
|
||||
xed_debug_message (DEBUG_SESSION, "Side panel _NOT_ visible");
|
||||
gtk_widget_hide (GTK_WIDGET (panel));
|
||||
}
|
||||
|
||||
visible = g_key_file_get_boolean (state_file, group_name,
|
||||
"bottom-panel-visible", &error);
|
||||
if (error)
|
||||
{
|
||||
g_clear_error (&error);
|
||||
visible = FALSE;
|
||||
}
|
||||
|
||||
panel = xed_window_get_bottom_panel (window);
|
||||
if (visible)
|
||||
{
|
||||
xed_debug_message (DEBUG_SESSION, "Bottom panel visible");
|
||||
gtk_widget_show (GTK_WIDGET (panel));
|
||||
}
|
||||
else
|
||||
{
|
||||
xed_debug_message (DEBUG_SESSION, "Bottom panel _NOT_ visible");
|
||||
gtk_widget_hide (GTK_WIDGET (panel));
|
||||
}
|
||||
|
||||
active_document = g_key_file_get_string (state_file, group_name,
|
||||
"active-document", NULL);
|
||||
documents = g_key_file_get_string_list (state_file, group_name,
|
||||
"documents", NULL, NULL);
|
||||
if (documents)
|
||||
{
|
||||
gint i;
|
||||
gboolean jump_to = FALSE;
|
||||
|
||||
for (i = 0; documents[i]; i++)
|
||||
{
|
||||
GFile *location;
|
||||
|
||||
if (active_document != NULL)
|
||||
{
|
||||
jump_to = strcmp (active_document, documents[i]) == 0;
|
||||
}
|
||||
|
||||
xed_debug_message (DEBUG_SESSION,
|
||||
"URI: %s (%s)",
|
||||
documents[i],
|
||||
jump_to ? "active" : "not active");
|
||||
|
||||
location = g_file_new_for_uri (documents[i]);
|
||||
xed_window_create_tab_from_location (window, location, NULL, 0, FALSE, jump_to);
|
||||
if (location)
|
||||
{
|
||||
g_object_unref (location);
|
||||
}
|
||||
}
|
||||
g_strfreev (documents);
|
||||
}
|
||||
|
||||
g_free (active_document);
|
||||
|
||||
gtk_widget_show (GTK_WIDGET (window));
|
||||
}
|
||||
|
||||
/**
|
||||
* xed_session_load:
|
||||
*
|
||||
* Loads the session by fetching the necessary information from the session
|
||||
* manager and opening files.
|
||||
*
|
||||
* Return value: TRUE if the session was loaded successfully, FALSE otherwise.
|
||||
**/
|
||||
gboolean
|
||||
xed_session_load (void)
|
||||
{
|
||||
GKeyFile *state_file;
|
||||
gchar **groups;
|
||||
int i;
|
||||
|
||||
xed_debug (DEBUG_SESSION);
|
||||
|
||||
state_file = egg_sm_client_get_state_file (master_client);
|
||||
if (state_file == NULL)
|
||||
return FALSE;
|
||||
|
||||
groups = g_key_file_get_groups (state_file, NULL);
|
||||
|
||||
for (i = 0; groups[i] != NULL; i++)
|
||||
{
|
||||
if (g_str_has_prefix (groups[i], "xed window "))
|
||||
parse_window (state_file, groups[i]);
|
||||
}
|
||||
|
||||
g_strfreev (groups);
|
||||
g_key_file_free (state_file);
|
||||
|
||||
return TRUE;
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* xed-session.h - Basic session management for xed
|
||||
* This file is part of xed
|
||||
*
|
||||
* Copyright (C) 2002 Ximian, Inc.
|
||||
* Copyright (C) 2005 - Paolo Maggi
|
||||
*
|
||||
* Author: Federico Mena-Quintero <federico@ximian.com>
|
||||
*
|
||||
* 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 xed Team, 2002-2005. See the AUTHORS file for a
|
||||
* list of people on the xed Team.
|
||||
* See the ChangeLog files for a list of changes.
|
||||
*
|
||||
* $Id
|
||||
*/
|
||||
|
||||
#ifndef __XED_SESSION_H__
|
||||
#define __XED_SESSION_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void xed_session_init (void);
|
||||
gboolean xed_session_is_restored (void);
|
||||
gboolean xed_session_load (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __XED_SESSION_H__ */
|
|
@ -96,7 +96,7 @@ set_font (XedSettings *xs,
|
|||
|
||||
ts = g_settings_get_uint (xs->priv->editor, XED_SETTINGS_TABS_SIZE);
|
||||
|
||||
views = xed_app_get_views (xed_app_get_default ());
|
||||
views = xed_app_get_views (XED_APP (g_application_get_default ()));
|
||||
|
||||
for (l = views; l != NULL; l = g_list_next (l))
|
||||
{
|
||||
|
@ -213,7 +213,7 @@ on_scheme_changed (GSettings *settings,
|
|||
}
|
||||
}
|
||||
|
||||
docs = xed_app_get_documents (xed_app_get_default ());
|
||||
docs = xed_app_get_documents (XED_APP (g_application_get_default ()));
|
||||
for (l = docs; l != NULL; l = g_list_next (l))
|
||||
{
|
||||
g_return_if_fail (GTK_SOURCE_IS_BUFFER (l->data));
|
||||
|
@ -234,7 +234,7 @@ on_auto_save_changed (GSettings *settings,
|
|||
|
||||
auto_save = g_settings_get_boolean (settings, key);
|
||||
|
||||
docs = xed_app_get_documents (xed_app_get_default ());
|
||||
docs = xed_app_get_documents (XED_APP (g_application_get_default ()));
|
||||
|
||||
for (l = docs; l != NULL; l = g_list_next (l))
|
||||
{
|
||||
|
@ -256,7 +256,7 @@ on_auto_save_interval_changed (GSettings *settings,
|
|||
|
||||
g_settings_get (settings, key, "u", &auto_save_interval);
|
||||
|
||||
docs = xed_app_get_documents (xed_app_get_default ());
|
||||
docs = xed_app_get_documents (XED_APP (g_application_get_default ()));
|
||||
|
||||
for (l = docs; l != NULL; l = g_list_next (l))
|
||||
{
|
||||
|
@ -278,7 +278,7 @@ on_wrap_mode_changed (GSettings *settings,
|
|||
|
||||
wrap_mode = g_settings_get_enum (settings, key);
|
||||
|
||||
views = xed_app_get_views (xed_app_get_default ());
|
||||
views = xed_app_get_views (XED_APP (g_application_get_default ()));
|
||||
|
||||
for (l = views; l != NULL; l = g_list_next (l))
|
||||
{
|
||||
|
@ -293,13 +293,12 @@ on_syntax_highlighting_changed (GSettings *settings,
|
|||
const gchar *key,
|
||||
XedSettings *xs)
|
||||
{
|
||||
const GList *windows;
|
||||
GList *docs, *l;
|
||||
GList *docs, *windows, *l;
|
||||
gboolean enable;
|
||||
|
||||
enable = g_settings_get_boolean (settings, key);
|
||||
|
||||
docs = xed_app_get_documents (xed_app_get_default ());
|
||||
docs = xed_app_get_documents (XED_APP (g_application_get_default ()));
|
||||
|
||||
for (l = docs; l != NULL; l = g_list_next (l))
|
||||
{
|
||||
|
@ -309,20 +308,20 @@ on_syntax_highlighting_changed (GSettings *settings,
|
|||
g_list_free (docs);
|
||||
|
||||
/* update the sensitivity of the Higlight Mode menu item */
|
||||
windows = xed_app_get_windows (xed_app_get_default ());
|
||||
while (windows != NULL)
|
||||
windows = xed_app_get_main_windows (XED_APP (g_application_get_default ()));
|
||||
for (l = windows; l != NULL; l = g_list_next (l))
|
||||
{
|
||||
GtkUIManager *ui;
|
||||
GtkAction *a;
|
||||
|
||||
ui = xed_window_get_ui_manager (XED_WINDOW (windows->data));
|
||||
ui = xed_window_get_ui_manager (XED_WINDOW (l->data));
|
||||
|
||||
a = gtk_ui_manager_get_action (ui, "/MenuBar/ViewMenu/ViewHighlightModeMenu");
|
||||
|
||||
gtk_action_set_sensitive (a, enable);
|
||||
|
||||
windows = g_list_next (windows);
|
||||
}
|
||||
|
||||
g_list_free (windows);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -335,7 +334,7 @@ on_enable_tab_scrolling_changed (GSettings *settings,
|
|||
|
||||
enable = g_settings_get_boolean (settings, key);
|
||||
|
||||
windows = xed_app_get_windows (xed_app_get_default ());
|
||||
windows = xed_app_get_main_windows (XED_APP (g_application_get_default ()));
|
||||
while (windows != NULL)
|
||||
{
|
||||
XedNotebook *notebook;
|
||||
|
|
323
xed/xed-tab.c
323
xed/xed-tab.c
|
@ -64,7 +64,7 @@ struct _XedTabPrivate
|
|||
|
||||
XedPrintJob *print_job;
|
||||
|
||||
GtkSourceFileSaver *saver;
|
||||
GTask *task_saver;
|
||||
GtkSourceFileSaverFlags save_flags;
|
||||
|
||||
/* tmp data for loading */
|
||||
|
@ -84,10 +84,20 @@ struct _XedTabPrivate
|
|||
|
||||
gint ask_if_externally_modified : 1;
|
||||
|
||||
/*tmp data for loading */
|
||||
guint user_requested_encoding : 1;
|
||||
};
|
||||
|
||||
typedef struct _SaverData SaverData;
|
||||
|
||||
struct _SaverData
|
||||
{
|
||||
GtkSourceFileSaver *saver;
|
||||
|
||||
/* Notes about the create_backup saver flag:
|
||||
* - At the beginning of a new file saving, force_no_backup is reset to
|
||||
* FALSE. The create_backup flag is set to the saver if it is enabled
|
||||
* in GSettings and if it isn't an auto-save.
|
||||
* - At the beginning of a new file saving, force_no_backup is FALSE.
|
||||
* The create_backup flag is set to the saver if it is enabled in
|
||||
* GSettings and if it isn't an auto-save.
|
||||
* - If creating the backup gives an error, and if the user wants to
|
||||
* save the file without the backup, force_no_backup is set to TRUE
|
||||
* and the create_backup flag is removed from the saver.
|
||||
|
@ -103,9 +113,6 @@ struct _XedTabPrivate
|
|||
* button in the info bar to retry the file saving.
|
||||
*/
|
||||
guint force_no_backup : 1;
|
||||
|
||||
/*tmp data for loading */
|
||||
guint user_requested_encoding : 1;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(XedTab, xed_tab, GTK_TYPE_BOX)
|
||||
|
@ -127,6 +134,26 @@ static void load (XedTab *tab,
|
|||
|
||||
static void save (XedTab *tab);
|
||||
|
||||
static SaverData *
|
||||
saver_data_new (void)
|
||||
{
|
||||
return g_slice_new0 (SaverData);
|
||||
}
|
||||
|
||||
static void
|
||||
saver_data_free (SaverData *data)
|
||||
{
|
||||
if (data != NULL)
|
||||
{
|
||||
if (data->saver != NULL)
|
||||
{
|
||||
g_object_unref (data->saver);
|
||||
}
|
||||
|
||||
g_slice_free (SaverData, data);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
install_auto_save_timeout (XedTab *tab)
|
||||
{
|
||||
|
@ -235,22 +262,15 @@ clear_loading (XedTab *tab)
|
|||
g_clear_object (&tab->priv->cancellable);
|
||||
}
|
||||
|
||||
static void
|
||||
clear_saving (XedTab *tab)
|
||||
{
|
||||
g_clear_object (&tab->priv->saver);
|
||||
tab->priv->force_no_backup = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
xed_tab_dispose (GObject *object)
|
||||
{
|
||||
XedTab *tab = XED_TAB (object);
|
||||
|
||||
g_clear_object (&tab->priv->editor);
|
||||
g_clear_object (&tab->priv->task_saver);
|
||||
|
||||
clear_loading (tab);
|
||||
clear_saving (tab);
|
||||
|
||||
G_OBJECT_CLASS (xed_tab_parent_class)->dispose (object);
|
||||
}
|
||||
|
@ -734,7 +754,7 @@ show_saving_message_area (XedTab *tab)
|
|||
gchar *msg = NULL;
|
||||
gint len;
|
||||
|
||||
g_return_if_fail (tab->priv->saver != NULL);
|
||||
g_return_if_fail (tab->priv->task_saver != NULL);
|
||||
|
||||
if (tab->priv->message_area != NULL)
|
||||
{
|
||||
|
@ -761,7 +781,11 @@ show_saving_message_area (XedTab *tab)
|
|||
else
|
||||
{
|
||||
gchar *str;
|
||||
GFile *location = gtk_source_file_saver_get_location (tab->priv->saver);
|
||||
SaverData *data;
|
||||
GFile *location;
|
||||
|
||||
data = g_task_get_task_data (tab->priv->task_saver);
|
||||
location = gtk_source_file_saver_get_location (data->saver);
|
||||
|
||||
from = short_name;
|
||||
to = g_file_get_parse_name (location);
|
||||
|
@ -858,10 +882,11 @@ unrecoverable_saving_error_message_area_response (GtkWidget *message_area,
|
|||
xed_tab_set_state (tab, XED_TAB_STATE_NORMAL);
|
||||
}
|
||||
|
||||
clear_saving (tab);
|
||||
|
||||
set_message_area (tab, NULL);
|
||||
|
||||
g_return_if_fail (tab->priv->task_saver != NULL);
|
||||
g_task_return_boolean (tab->priv->task_saver, FALSE);
|
||||
|
||||
view = xed_tab_get_view (tab);
|
||||
|
||||
gtk_widget_grab_focus (GTK_WIDGET (view));
|
||||
|
@ -872,8 +897,11 @@ static void
|
|||
response_set_save_flags (XedTab *tab,
|
||||
GtkSourceFileSaverFlags save_flags)
|
||||
{
|
||||
SaverData *data;
|
||||
gboolean create_backup;
|
||||
|
||||
data = g_task_get_task_data (tab->priv->task_saver);
|
||||
|
||||
create_backup = g_settings_get_boolean (tab->priv->editor, XED_SETTINGS_CREATE_BACKUP_COPY);
|
||||
|
||||
/* If we are here, it means that the user expressed his or her willing
|
||||
|
@ -881,7 +909,7 @@ response_set_save_flags (XedTab *tab,
|
|||
* the file saving was initially an auto-save, we set the create_backup
|
||||
* flag (if the conditions are met).
|
||||
*/
|
||||
if (create_backup && !tab->priv->force_no_backup)
|
||||
if (create_backup && !data->force_no_backup)
|
||||
{
|
||||
save_flags |= GTK_SOURCE_FILE_SAVER_FLAGS_CREATE_BACKUP;
|
||||
}
|
||||
|
@ -890,7 +918,7 @@ response_set_save_flags (XedTab *tab,
|
|||
save_flags &= ~GTK_SOURCE_FILE_SAVER_FLAGS_CREATE_BACKUP;
|
||||
}
|
||||
|
||||
gtk_source_file_saver_set_flags (tab->priv->saver, save_flags);
|
||||
gtk_source_file_saver_set_flags (data->saver, save_flags);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -900,16 +928,18 @@ invalid_character_message_area_response (GtkWidget *info_bar,
|
|||
{
|
||||
if (response_id == GTK_RESPONSE_YES)
|
||||
{
|
||||
SaverData *data;
|
||||
GtkSourceFileSaverFlags save_flags;
|
||||
|
||||
set_message_area (tab, NULL);
|
||||
|
||||
g_return_if_fail (tab->priv->saver != NULL);
|
||||
g_return_if_fail (tab->priv->task_saver != NULL);
|
||||
data = g_task_get_task_data (tab->priv->task_saver);
|
||||
|
||||
/* Don't bug the user again with this... */
|
||||
tab->priv->save_flags |= GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_INVALID_CHARS;
|
||||
|
||||
save_flags = gtk_source_file_saver_get_flags (tab->priv->saver);
|
||||
save_flags = gtk_source_file_saver_get_flags (data->saver);
|
||||
save_flags |= GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_INVALID_CHARS;
|
||||
response_set_save_flags (tab, save_flags);
|
||||
|
||||
|
@ -929,14 +959,16 @@ no_backup_error_message_area_response (GtkWidget *message_area,
|
|||
{
|
||||
if (response_id == GTK_RESPONSE_YES)
|
||||
{
|
||||
SaverData *data;
|
||||
GtkSourceFileSaverFlags save_flags;
|
||||
|
||||
set_message_area (tab, NULL);
|
||||
|
||||
g_return_if_fail (tab->priv->saver != NULL);
|
||||
g_return_if_fail (tab->priv->task_saver != NULL);
|
||||
data = g_task_get_task_data (tab->priv->task_saver);
|
||||
|
||||
tab->priv->force_no_backup = TRUE;
|
||||
save_flags = gtk_source_file_saver_get_flags (tab->priv->saver);
|
||||
data->force_no_backup = TRUE;
|
||||
save_flags = gtk_source_file_saver_get_flags (data->saver);
|
||||
response_set_save_flags (tab, save_flags);
|
||||
|
||||
/* Force saving */
|
||||
|
@ -955,17 +987,19 @@ externally_modified_error_message_area_response (GtkWidget *message_area,
|
|||
{
|
||||
if (response_id == GTK_RESPONSE_YES)
|
||||
{
|
||||
SaverData *data;
|
||||
GtkSourceFileSaverFlags save_flags;
|
||||
|
||||
set_message_area (tab, NULL);
|
||||
|
||||
g_return_if_fail (tab->priv->saver != NULL);
|
||||
g_return_if_fail (tab->priv->task_saver != NULL);
|
||||
data = g_task_get_task_data (tab->priv->task_saver);
|
||||
|
||||
/* ignore_modification_time should not be persisted in save
|
||||
* flags across saves (i.e. priv->save_flags is not modified).
|
||||
*/
|
||||
|
||||
save_flags = gtk_source_file_saver_get_flags (tab->priv->saver);
|
||||
save_flags = gtk_source_file_saver_get_flags (data->saver);
|
||||
save_flags |= GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_MODIFICATION_TIME;
|
||||
response_set_save_flags (tab, save_flags);
|
||||
|
||||
|
@ -985,16 +1019,18 @@ recoverable_saving_error_message_area_response (GtkWidget *message_area,
|
|||
{
|
||||
if (response_id == GTK_RESPONSE_OK)
|
||||
{
|
||||
SaverData *data;
|
||||
const GtkSourceEncoding *encoding;
|
||||
|
||||
set_message_area (tab, NULL);
|
||||
|
||||
g_return_if_fail (tab->priv->saver != NULL);
|
||||
g_return_if_fail (tab->priv->task_saver != NULL);
|
||||
data = g_task_get_task_data (tab->priv->task_saver);
|
||||
|
||||
encoding = xed_conversion_error_message_area_get_encoding (GTK_WIDGET (message_area));
|
||||
g_return_if_fail (encoding != NULL);
|
||||
|
||||
gtk_source_file_saver_set_encoding (tab->priv->saver, encoding);
|
||||
gtk_source_file_saver_set_encoding (data->saver, encoding);
|
||||
save (tab);
|
||||
}
|
||||
else
|
||||
|
@ -1175,6 +1211,22 @@ _xed_tab_new_from_location (GFile *location,
|
|||
return GTK_WIDGET (tab);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
_xed_tab_new_from_stream (GInputStream *stream,
|
||||
const GtkSourceEncoding *encoding,
|
||||
gint line_pos)
|
||||
{
|
||||
GtkWidget *tab;
|
||||
|
||||
g_return_val_if_fail (G_IS_INPUT_STREAM (stream), NULL);
|
||||
|
||||
tab = _xed_tab_new ();
|
||||
|
||||
_xed_tab_load_stream (XED_TAB (tab), stream, encoding, line_pos);
|
||||
|
||||
return tab;
|
||||
}
|
||||
|
||||
/**
|
||||
* xed_tab_get_view:
|
||||
* @tab: a #XedTab
|
||||
|
@ -1317,12 +1369,10 @@ _xed_tab_get_tooltips (XedTab *tab)
|
|||
|
||||
if (enc == NULL)
|
||||
{
|
||||
encoding = g_strdup (_("Unicode (UTF-8)"));
|
||||
enc = gtk_source_encoding_get_utf8 ();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
encoding = gtk_source_encoding_to_string (enc);
|
||||
}
|
||||
|
||||
tip = g_markup_printf_escaped ("<b>%s</b> %s\n\n"
|
||||
"<b>%s</b> %s\n"
|
||||
|
@ -1574,6 +1624,7 @@ load_cb (GtkSourceFileLoader *loader,
|
|||
{
|
||||
XedDocument *doc = xed_tab_get_document (tab);
|
||||
GFile *location = gtk_source_file_loader_get_location (loader);
|
||||
gboolean create_named_new_doc;
|
||||
GError *error = NULL;
|
||||
|
||||
g_return_if_fail (tab->priv->state == XED_TAB_STATE_LOADING ||
|
||||
|
@ -1611,10 +1662,13 @@ load_cb (GtkSourceFileLoader *loader,
|
|||
}
|
||||
|
||||
/* Special case creating a named new doc. */
|
||||
else if (_xed_document_get_create (doc) &&
|
||||
create_named_new_doc = (_xed_document_get_create (doc) &&
|
||||
error != NULL &&
|
||||
error->domain == G_IO_ERROR &&
|
||||
error->code == G_IO_ERROR_NOT_FOUND &&
|
||||
g_file_has_uri_scheme (location, "file"))
|
||||
g_file_has_uri_scheme (location, "file"));
|
||||
|
||||
if (create_named_new_doc)
|
||||
{
|
||||
g_error_free (error);
|
||||
error = NULL;
|
||||
|
@ -1676,7 +1730,7 @@ load_cb (GtkSourceFileLoader *loader,
|
|||
goto end;
|
||||
}
|
||||
|
||||
if (location != NULL)
|
||||
if (location != NULL && !create_named_new_doc)
|
||||
{
|
||||
gchar *mime = xed_document_get_mime_type (doc);
|
||||
|
||||
|
@ -1725,7 +1779,7 @@ load_cb (GtkSourceFileLoader *loader,
|
|||
GList *all_documents;
|
||||
GList *l;
|
||||
|
||||
all_documents = xed_app_get_documents (xed_app_get_default ());
|
||||
all_documents = xed_app_get_documents (XED_APP (g_application_get_default ()));
|
||||
|
||||
for (l = all_documents; l != NULL; l = g_list_next (l))
|
||||
{
|
||||
|
@ -1793,6 +1847,8 @@ get_candidate_encodings (XedTab *tab)
|
|||
GSettings *enc_settings;
|
||||
gchar **enc_strv;
|
||||
gchar *metadata_charset;
|
||||
GtkSourceFile *file;
|
||||
const GtkSourceEncoding *file_encoding;
|
||||
GSList *encodings;
|
||||
|
||||
enc_settings = g_settings_new ("org.x.editor.preferences.encodings");
|
||||
|
@ -1814,12 +1870,19 @@ get_candidate_encodings (XedTab *tab)
|
|||
{
|
||||
encodings = g_slist_prepend (encodings, (gpointer)metadata_enc);
|
||||
}
|
||||
|
||||
g_free (metadata_charset);
|
||||
}
|
||||
|
||||
g_strfreev (enc_strv);
|
||||
file = xed_document_get_file (doc);
|
||||
file_encoding = gtk_source_file_get_encoding (file);
|
||||
|
||||
if (file_encoding != NULL)
|
||||
{
|
||||
encodings = g_slist_prepend (encodings, (gpointer)file_encoding);
|
||||
}
|
||||
|
||||
g_object_unref (enc_settings);
|
||||
g_strfreev (enc_strv);
|
||||
g_free (metadata_charset);
|
||||
|
||||
return encodings;
|
||||
}
|
||||
|
@ -1902,6 +1965,39 @@ _xed_tab_load (XedTab *tab,
|
|||
load (tab, encoding, line_pos);
|
||||
}
|
||||
|
||||
void
|
||||
_xed_tab_load_stream (XedTab *tab,
|
||||
GInputStream *stream,
|
||||
const GtkSourceEncoding *encoding,
|
||||
gint line_pos)
|
||||
{
|
||||
XedDocument *doc;
|
||||
GtkSourceFile *file;
|
||||
|
||||
g_return_if_fail (XED_IS_TAB (tab));
|
||||
g_return_if_fail (G_IS_INPUT_STREAM (stream));
|
||||
g_return_if_fail (tab->priv->state == XED_TAB_STATE_NORMAL);
|
||||
|
||||
xed_tab_set_state (tab, XED_TAB_STATE_LOADING);
|
||||
|
||||
doc = xed_tab_get_document (tab);
|
||||
file = xed_document_get_file (doc);
|
||||
|
||||
if (tab->priv->loader != NULL)
|
||||
{
|
||||
g_warning ("XedTab: file loader already exists.");
|
||||
g_object_unref (tab->priv->loader);
|
||||
}
|
||||
|
||||
gtk_source_file_set_location (file, NULL);
|
||||
|
||||
tab->priv->loader = gtk_source_file_loader_new_from_stream (GTK_SOURCE_BUFFER (doc), file, stream);
|
||||
|
||||
_xed_document_set_create (doc, FALSE);
|
||||
|
||||
load (tab, encoding, line_pos);
|
||||
}
|
||||
|
||||
void
|
||||
_xed_tab_revert (XedTab *tab)
|
||||
{
|
||||
|
@ -1977,7 +2073,7 @@ save_cb (GtkSourceFileSaver *saver,
|
|||
GFile *location = gtk_source_file_saver_get_location (saver);
|
||||
GError *error = NULL;
|
||||
|
||||
g_return_if_fail (tab->priv->state == XED_TAB_STATE_SAVING);
|
||||
g_return_if_fail (tab->priv->task_saver != NULL);
|
||||
|
||||
gtk_source_file_saver_save_finish (saver, result, &error);
|
||||
|
||||
|
@ -2084,14 +2180,10 @@ save_cb (GtkSourceFileSaver *saver,
|
|||
|
||||
tab->priv->ask_if_externally_modified = TRUE;
|
||||
|
||||
clear_saving (tab);
|
||||
|
||||
g_signal_emit_by_name (doc, "saved");
|
||||
g_task_return_boolean (tab->priv->task_saver, TRUE);
|
||||
}
|
||||
|
||||
/* Async operation finished. */
|
||||
g_object_unref (tab);
|
||||
|
||||
if (error != NULL)
|
||||
{
|
||||
g_error_free (error);
|
||||
|
@ -2102,20 +2194,20 @@ static void
|
|||
save (XedTab *tab)
|
||||
{
|
||||
XedDocument *doc;
|
||||
SaverData *data;
|
||||
|
||||
g_return_if_fail (GTK_SOURCE_IS_FILE_SAVER (tab->priv->saver));
|
||||
g_return_if_fail (G_IS_TASK (tab->priv->task_saver));
|
||||
|
||||
xed_tab_set_state (tab, XED_TAB_STATE_SAVING);
|
||||
|
||||
doc = xed_tab_get_document (tab);
|
||||
g_signal_emit_by_name (doc, "save");
|
||||
|
||||
/* Keep the tab alive during the async operation. */
|
||||
g_object_ref (tab);
|
||||
data = g_task_get_task_data (tab->priv->task_saver);
|
||||
|
||||
gtk_source_file_saver_save_async (tab->priv->saver,
|
||||
gtk_source_file_saver_save_async (data->saver,
|
||||
G_PRIORITY_DEFAULT,
|
||||
NULL, /* TODO add a cancellable */
|
||||
g_task_get_cancellable (tab->priv->task_saver),
|
||||
(GFileProgressCallback) saver_progress_cb,
|
||||
tab,
|
||||
NULL,
|
||||
|
@ -2133,9 +2225,6 @@ get_initial_save_flags (XedTab *tab,
|
|||
|
||||
save_flags = tab->priv->save_flags;
|
||||
|
||||
/* force_no_backup must have been reset to FALSE for a new file saving. */
|
||||
g_return_val_if_fail (!tab->priv->force_no_backup, save_flags);
|
||||
|
||||
create_backup = g_settings_get_boolean (tab->priv->editor, XED_SETTINGS_CREATE_BACKUP_COPY);
|
||||
|
||||
/* In case of autosaving, we need to preserve the backup that was produced
|
||||
|
@ -2151,8 +2240,12 @@ get_initial_save_flags (XedTab *tab,
|
|||
}
|
||||
|
||||
void
|
||||
_xed_tab_save (XedTab *tab)
|
||||
_xed_tab_save_async (XedTab *tab,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
SaverData *data;
|
||||
XedDocument *doc;
|
||||
GtkSourceFile *file;
|
||||
GtkSourceFileSaverFlags save_flags;
|
||||
|
@ -2162,19 +2255,23 @@ _xed_tab_save (XedTab *tab)
|
|||
(tab->priv->state == XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION) ||
|
||||
(tab->priv->state == XED_TAB_STATE_SHOWING_PRINT_PREVIEW));
|
||||
|
||||
if (tab->priv->saver != NULL)
|
||||
if (tab->priv->task_saver != NULL)
|
||||
{
|
||||
g_warning ("XedTab: file saver already exists.");
|
||||
g_object_unref (tab->priv->saver);
|
||||
tab->priv->saver = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
clear_saving (tab);
|
||||
|
||||
doc = xed_tab_get_document (tab);
|
||||
g_return_if_fail (XED_IS_DOCUMENT (doc));
|
||||
// g_return_if_fail (XED_IS_DOCUMENT (doc));
|
||||
g_return_if_fail (!xed_document_is_untitled (doc));
|
||||
|
||||
tab->priv->task_saver = g_task_new (tab, cancellable, callback, user_data);
|
||||
|
||||
data = saver_data_new ();
|
||||
g_task_set_task_data (tab->priv->task_saver,
|
||||
data,
|
||||
(GDestroyNotify) saver_data_free);
|
||||
|
||||
save_flags = get_initial_save_flags (tab, FALSE);
|
||||
|
||||
if (tab->priv->state == XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION)
|
||||
|
@ -2189,15 +2286,39 @@ _xed_tab_save (XedTab *tab)
|
|||
|
||||
file = xed_document_get_file (doc);
|
||||
|
||||
tab->priv->saver = gtk_source_file_saver_new (GTK_SOURCE_BUFFER (doc), file);
|
||||
gtk_source_file_saver_set_flags (tab->priv->saver, save_flags);
|
||||
data->saver = gtk_source_file_saver_new (GTK_SOURCE_BUFFER (doc), file);
|
||||
gtk_source_file_saver_set_flags (data->saver, save_flags);
|
||||
|
||||
save (tab);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_xed_tab_save_finish (XedTab *tab,
|
||||
GAsyncResult *result)
|
||||
{
|
||||
gboolean success;
|
||||
|
||||
g_return_val_if_fail (g_task_is_valid (result, tab), FALSE);
|
||||
g_return_val_if_fail (tab->priv->task_saver == G_TASK (result), FALSE);
|
||||
|
||||
success = g_task_propagate_boolean (tab->priv->task_saver, NULL);
|
||||
g_clear_object (&tab->priv->task_saver);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static void
|
||||
auto_save_finished_cb (XedTab *tab,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
_xed_tab_save_finish (tab, result);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
xed_tab_auto_save (XedTab *tab)
|
||||
{
|
||||
SaverData *data;
|
||||
XedDocument *doc;
|
||||
GtkSourceFile *file;
|
||||
GtkSourceFileSaverFlags save_flags;
|
||||
|
@ -2205,11 +2326,10 @@ xed_tab_auto_save (XedTab *tab)
|
|||
xed_debug (DEBUG_TAB);
|
||||
|
||||
doc = xed_tab_get_document (tab);
|
||||
g_return_val_if_fail (!xed_document_is_untitled (doc), G_SOURCE_REMOVE);
|
||||
g_return_val_if_fail (!xed_document_get_readonly (doc), G_SOURCE_REMOVE);
|
||||
|
||||
g_return_val_if_fail (!xed_document_is_untitled (doc), FALSE);
|
||||
g_return_val_if_fail (!xed_document_get_readonly (doc), FALSE);
|
||||
|
||||
if (!gtk_text_buffer_get_modified (GTK_TEXT_BUFFER(doc)))
|
||||
if (!gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc)))
|
||||
{
|
||||
xed_debug_message (DEBUG_TAB, "Document not modified");
|
||||
|
||||
|
@ -2229,37 +2349,50 @@ xed_tab_auto_save (XedTab *tab)
|
|||
/* Set auto_save_timeout to 0 since the timeout is going to be destroyed */
|
||||
tab->priv->auto_save_timeout = 0;
|
||||
|
||||
if (tab->priv->saver != NULL)
|
||||
if (tab->priv->task_saver != NULL)
|
||||
{
|
||||
g_warning ("XedTab: file saver already exists.");
|
||||
g_object_unref (tab->priv->saver);
|
||||
tab->priv->saver = NULL;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
clear_saving (tab);
|
||||
tab->priv->task_saver = g_task_new (tab,
|
||||
NULL,
|
||||
(GAsyncReadyCallback) auto_save_finished_cb,
|
||||
NULL);
|
||||
|
||||
data = saver_data_new ();
|
||||
g_task_set_task_data (tab->priv->task_saver,
|
||||
data,
|
||||
(GDestroyNotify) saver_data_free);
|
||||
|
||||
file = xed_document_get_file (doc);
|
||||
|
||||
tab->priv->saver = gtk_source_file_saver_new (GTK_SOURCE_BUFFER (doc), file);
|
||||
data->saver = gtk_source_file_saver_new (GTK_SOURCE_BUFFER (doc), file);
|
||||
|
||||
save_flags = get_initial_save_flags (tab, TRUE);
|
||||
gtk_source_file_saver_set_flags (tab->priv->saver, save_flags);
|
||||
gtk_source_file_saver_set_flags (data->saver, save_flags);
|
||||
|
||||
save (tab);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
/* Call _xed_tab_save_finish() in @callback, there is no
|
||||
* _xed_tab_save_as_finish().
|
||||
*/
|
||||
void
|
||||
_xed_tab_save_as (XedTab *tab,
|
||||
_xed_tab_save_as_async (XedTab *tab,
|
||||
GFile *location,
|
||||
const GtkSourceEncoding *encoding,
|
||||
GtkSourceNewlineType newline_type)
|
||||
GtkSourceNewlineType newline_type,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
SaverData *data;
|
||||
XedDocument *doc;
|
||||
GtkSourceFile *file;
|
||||
GtkSourceFileSaverFlags save_flags;
|
||||
GFile *prev_location;
|
||||
|
||||
g_return_if_fail (XED_IS_TAB (tab));
|
||||
g_return_if_fail ((tab->priv->state == XED_TAB_STATE_NORMAL) ||
|
||||
|
@ -2268,14 +2401,18 @@ _xed_tab_save_as (XedTab *tab,
|
|||
g_return_if_fail (G_IS_FILE (location));
|
||||
g_return_if_fail (encoding != NULL);
|
||||
|
||||
if (tab->priv->saver != NULL)
|
||||
if (tab->priv->task_saver != NULL)
|
||||
{
|
||||
g_warning ("XedTab: file saver already exists.");
|
||||
g_object_unref (tab->priv->saver);
|
||||
tab->priv->saver = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
clear_saving (tab);
|
||||
tab->priv->task_saver = g_task_new (tab, cancellable, callback, user_data);
|
||||
|
||||
data = saver_data_new ();
|
||||
g_task_set_task_data (tab->priv->task_saver,
|
||||
data,
|
||||
(GDestroyNotify) saver_data_free);
|
||||
|
||||
doc = xed_tab_get_document (tab);
|
||||
g_return_if_fail (XED_IS_DOCUMENT (doc));
|
||||
|
@ -2295,20 +2432,12 @@ _xed_tab_save_as (XedTab *tab,
|
|||
}
|
||||
|
||||
file = xed_document_get_file (doc);
|
||||
prev_location = gtk_source_file_get_location (file);
|
||||
|
||||
if (prev_location == NULL || !g_file_equal (prev_location, location))
|
||||
{
|
||||
/* Ignore modification time for a save to another location. */
|
||||
/* TODO do that in GtkSourceFileSaver. */
|
||||
save_flags |= GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_MODIFICATION_TIME;
|
||||
}
|
||||
data->saver = gtk_source_file_saver_new_with_target (GTK_SOURCE_BUFFER (doc), file, location);
|
||||
|
||||
tab->priv->saver = gtk_source_file_saver_new_with_target (GTK_SOURCE_BUFFER (doc), file, location);
|
||||
|
||||
gtk_source_file_saver_set_encoding (tab->priv->saver, encoding);
|
||||
gtk_source_file_saver_set_newline_type (tab->priv->saver, newline_type);
|
||||
gtk_source_file_saver_set_flags (tab->priv->saver, save_flags);
|
||||
gtk_source_file_saver_set_encoding (data->saver, encoding);
|
||||
gtk_source_file_saver_set_newline_type (data->saver, newline_type);
|
||||
gtk_source_file_saver_set_flags (data->saver, save_flags);
|
||||
|
||||
save (tab);
|
||||
}
|
||||
|
@ -2327,7 +2456,7 @@ get_page_setup (XedTab *tab)
|
|||
|
||||
if (data == NULL)
|
||||
{
|
||||
return _xed_app_get_default_page_setup (xed_app_get_default());
|
||||
return _xed_app_get_default_page_setup (XED_APP (g_application_get_default ()));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2349,7 +2478,7 @@ get_print_settings (XedTab *tab)
|
|||
|
||||
if (data == NULL)
|
||||
{
|
||||
settings = _xed_app_get_default_print_settings (xed_app_get_default());
|
||||
settings = _xed_app_get_default_print_settings (XED_APP (g_application_get_default ()));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2407,7 +2536,7 @@ store_print_settings (XedTab *tab,
|
|||
g_object_ref (settings), (GDestroyNotify)g_object_unref);
|
||||
|
||||
/* make them the default */
|
||||
_xed_app_set_default_print_settings (xed_app_get_default (), settings);
|
||||
_xed_app_set_default_print_settings (XED_APP (g_application_get_default ()), settings);
|
||||
|
||||
page_setup = xed_print_job_get_page_setup (job);
|
||||
|
||||
|
@ -2416,7 +2545,7 @@ store_print_settings (XedTab *tab,
|
|||
g_object_ref (page_setup), (GDestroyNotify)g_object_unref);
|
||||
|
||||
/* make it the default */
|
||||
_xed_app_set_default_page_setup (xed_app_get_default (), page_setup);
|
||||
_xed_app_set_default_page_setup (XED_APP (g_application_get_default ()), page_setup);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -112,20 +112,46 @@ GtkWidget *_xed_tab_new_from_location (GFile *location,
|
|||
const GtkSourceEncoding *encoding,
|
||||
gint line_pos,
|
||||
gboolean create);
|
||||
|
||||
GtkWidget *_xed_tab_new_from_stream (GInputStream *stream,
|
||||
const GtkSourceEncoding *encoding,
|
||||
gint line_pos);
|
||||
|
||||
gchar *_xed_tab_get_name (XedTab *tab);
|
||||
|
||||
gchar *_xed_tab_get_tooltips (XedTab *tab);
|
||||
|
||||
GdkPixbuf *_xed_tab_get_icon (XedTab *tab);
|
||||
|
||||
void _xed_tab_load (XedTab *tab,
|
||||
GFile *location,
|
||||
const GtkSourceEncoding *encoding,
|
||||
gint line_pos,
|
||||
gboolean create);
|
||||
|
||||
void _xed_tab_load_stream (XedTab *tab,
|
||||
GInputStream *location,
|
||||
const GtkSourceEncoding *encoding,
|
||||
gint line_pos);
|
||||
|
||||
void _xed_tab_revert (XedTab *tab);
|
||||
void _xed_tab_save (XedTab *tab);
|
||||
void _xed_tab_save_as (XedTab *tab,
|
||||
|
||||
void _xed_tab_save_async (XedTab *tab,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
|
||||
gboolean _xed_tab_save_finish (XedTab *tab,
|
||||
GAsyncResult *result);
|
||||
|
||||
void _xed_tab_save_as_async (XedTab *tab,
|
||||
GFile *location,
|
||||
const GtkSourceEncoding *encoding,
|
||||
GtkSourceNewlineType newline_type);
|
||||
GtkSourceNewlineType newline_type,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
void _xed_tab_print (XedTab *tab);
|
||||
void _xed_tab_print_preview (XedTab *tab);
|
||||
|
|
|
@ -771,7 +771,7 @@ xed_view_set_font (XedView *view,
|
|||
GObject *settings;
|
||||
gchar *font;
|
||||
|
||||
settings = _xed_app_get_settings (xed_app_get_default ());
|
||||
settings = _xed_app_get_settings (XED_APP (g_application_get_default ()));
|
||||
font = xed_settings_get_system_font (XED_SETTINGS (settings));
|
||||
font_desc = pango_font_description_from_string (font);
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ enum
|
|||
TARGET_URI_LIST = 100
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(XedWindow, xed_window, GTK_TYPE_WINDOW)
|
||||
G_DEFINE_TYPE(XedWindow, xed_window, GTK_TYPE_APPLICATION_WINDOW)
|
||||
|
||||
static void recent_manager_changed (GtkRecentManager *manager, XedWindow *window);
|
||||
|
||||
|
@ -583,7 +583,7 @@ set_sensitivity_according_to_tab (XedWindow *window,
|
|||
view = xed_tab_get_view (tab);
|
||||
editable = gtk_text_view_get_editable (GTK_TEXT_VIEW(view));
|
||||
|
||||
doc = XED_DOCUMENT(gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
|
||||
doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
|
||||
|
||||
clipboard = gtk_widget_get_clipboard (GTK_WIDGET(window),
|
||||
GDK_SELECTION_CLIPBOARD);
|
||||
|
@ -983,15 +983,19 @@ open_recent_file (GFile *location,
|
|||
XedWindow *window)
|
||||
{
|
||||
GSList *locations = NULL;
|
||||
GSList *loaded = NULL;
|
||||
|
||||
locations = g_slist_prepend (locations, (gpointer) location);
|
||||
|
||||
if (xed_commands_load_locations (window, locations, NULL, 0) != 1)
|
||||
loaded = xed_commands_load_locations (window, locations, NULL, 0);
|
||||
|
||||
if (!loaded || loaded->next) /* if it doesn't contain just 1 element */
|
||||
{
|
||||
_xed_recent_remove (window, location);
|
||||
}
|
||||
|
||||
g_slist_free (locations);
|
||||
g_slist_free (loaded);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1803,7 +1807,7 @@ clone_window (XedWindow *origin)
|
|||
|
||||
xed_debug (DEBUG_WINDOW);
|
||||
|
||||
app = xed_app_get_default ();
|
||||
app = XED_APP (g_application_get_default ());
|
||||
|
||||
screen = gtk_window_get_screen (GTK_WINDOW(origin));
|
||||
window = xed_app_create_window (app, screen);
|
||||
|
@ -1915,7 +1919,7 @@ static void
|
|||
update_overwrite_mode_statusbar (GtkTextView *view,
|
||||
XedWindow *window)
|
||||
{
|
||||
if (view != GTK_TEXT_VIEW(xed_window_get_active_view (window)))
|
||||
if (view != GTK_TEXT_VIEW (xed_window_get_active_view (window)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -1940,7 +1944,7 @@ set_title (XedWindow *window)
|
|||
|
||||
if (window->priv->active_tab == NULL)
|
||||
{
|
||||
gtk_window_set_title (GTK_WINDOW(window), "Xed");
|
||||
xed_app_set_window_title (XED_APP (g_application_get_default ()), window, "Xed");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2012,7 +2016,7 @@ set_title (XedWindow *window)
|
|||
}
|
||||
}
|
||||
|
||||
gtk_window_set_title (GTK_WINDOW(window), title);
|
||||
xed_app_set_window_title (XED_APP (g_application_get_default ()), window, title);
|
||||
|
||||
g_free (dirname);
|
||||
g_free (name);
|
||||
|
@ -2486,6 +2490,7 @@ load_uris_from_drop (XedWindow *window,
|
|||
{
|
||||
GSList *locations = NULL;
|
||||
gint i;
|
||||
GSList *loaded;
|
||||
|
||||
if (uri_list == NULL)
|
||||
{
|
||||
|
@ -2498,7 +2503,9 @@ load_uris_from_drop (XedWindow *window,
|
|||
}
|
||||
|
||||
locations = g_slist_reverse (locations);
|
||||
xed_commands_load_locations (window, locations, NULL, 0);
|
||||
loaded = xed_commands_load_locations (window, locations, NULL, 0);
|
||||
|
||||
g_slist_free (loaded);
|
||||
|
||||
g_slist_foreach (locations, (GFunc) g_object_unref, NULL);
|
||||
g_slist_free (locations);
|
||||
|
@ -2704,7 +2711,7 @@ fullscreen_controls_build (XedWindow *window)
|
|||
|
||||
priv->fullscreen_controls = gtk_window_new (GTK_WINDOW_POPUP);
|
||||
|
||||
gtk_window_set_transient_for (GTK_WINDOW(priv->fullscreen_controls), &window->window);
|
||||
gtk_window_set_transient_for (GTK_WINDOW (priv->fullscreen_controls), GTK_WINDOW (&window->window));
|
||||
|
||||
window->priv->fullscreen_controls_container = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (window->priv->fullscreen_controls_container), 6);
|
||||
|
@ -3634,7 +3641,7 @@ xed_window_get_active_view (XedWindow *window)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
view = xed_tab_get_view (XED_TAB(window->priv->active_tab));
|
||||
view = xed_tab_get_view (XED_TAB (window->priv->active_tab));
|
||||
|
||||
return view;
|
||||
}
|
||||
|
@ -3663,7 +3670,7 @@ xed_window_get_active_document (XedWindow *window)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return XED_DOCUMENT(gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
|
||||
return XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
|
@ -3693,13 +3700,35 @@ xed_window_create_tab (XedWindow *window,
|
|||
g_return_val_if_fail(XED_IS_WINDOW (window), NULL);
|
||||
|
||||
tab = XED_TAB(_xed_tab_new ());
|
||||
gtk_widget_show (GTK_WIDGET(tab));
|
||||
gtk_widget_show (GTK_WIDGET (tab));
|
||||
|
||||
xed_notebook_add_tab (XED_NOTEBOOK(window->priv->notebook), tab, -1, jump_to);
|
||||
xed_notebook_add_tab (XED_NOTEBOOK (window->priv->notebook), tab, -1, jump_to);
|
||||
|
||||
if (!gtk_widget_get_visible (GTK_WIDGET(window)))
|
||||
if (!gtk_widget_get_visible (GTK_WIDGET (window)))
|
||||
{
|
||||
gtk_window_present (GTK_WINDOW(window));
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
}
|
||||
|
||||
return tab;
|
||||
}
|
||||
|
||||
static XedTab *
|
||||
process_create_tab (XedWindow *window,
|
||||
XedTab *tab,
|
||||
gboolean jump_to)
|
||||
{
|
||||
if (tab == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gtk_widget_show (GTK_WIDGET (tab));
|
||||
|
||||
xed_notebook_add_tab (XED_NOTEBOOK (window->priv->notebook), tab, -1, jump_to);
|
||||
|
||||
if (!gtk_widget_get_visible (GTK_WIDGET (window)))
|
||||
{
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
}
|
||||
|
||||
return tab;
|
||||
|
@ -3735,21 +3764,25 @@ xed_window_create_tab_from_location (XedWindow *window,
|
|||
g_return_val_if_fail(G_IS_FILE (location), NULL);
|
||||
|
||||
tab = _xed_tab_new_from_location (location, encoding, line_pos, create);
|
||||
if (tab == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gtk_widget_show (tab);
|
||||
return process_create_tab (window, XED_TAB (tab), jump_to);
|
||||
}
|
||||
|
||||
xed_notebook_add_tab (XED_NOTEBOOK(window->priv->notebook), XED_TAB(tab), -1, jump_to);
|
||||
XedTab *
|
||||
xed_window_create_tab_from_stream (XedWindow *window,
|
||||
GInputStream *stream,
|
||||
const GtkSourceEncoding *encoding,
|
||||
gint line_pos,
|
||||
gboolean jump_to)
|
||||
{
|
||||
GtkWidget *tab;
|
||||
|
||||
if (!gtk_widget_get_visible (GTK_WIDGET(window)))
|
||||
{
|
||||
gtk_window_present (GTK_WINDOW(window));
|
||||
}
|
||||
g_return_val_if_fail (XED_IS_WINDOW (window), NULL);
|
||||
g_return_val_if_fail (G_IS_INPUT_STREAM (stream), NULL);
|
||||
|
||||
return XED_TAB(tab);
|
||||
tab = _xed_tab_new_from_stream (stream, encoding, line_pos);
|
||||
|
||||
return process_create_tab (window, XED_TAB (tab), jump_to);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3845,12 +3878,12 @@ void
|
|||
xed_window_close_tab (XedWindow *window,
|
||||
XedTab *tab)
|
||||
{
|
||||
g_return_if_fail(XED_IS_WINDOW (window));
|
||||
g_return_if_fail(XED_IS_TAB (tab));
|
||||
g_return_if_fail((xed_tab_get_state (tab) != XED_TAB_STATE_SAVING)
|
||||
g_return_if_fail (XED_IS_WINDOW (window));
|
||||
g_return_if_fail (XED_IS_TAB (tab));
|
||||
g_return_if_fail ((xed_tab_get_state (tab) != XED_TAB_STATE_SAVING)
|
||||
&& (xed_tab_get_state (tab) != XED_TAB_STATE_SHOWING_PRINT_PREVIEW));
|
||||
|
||||
xed_notebook_remove_tab (XED_NOTEBOOK(window->priv->notebook), tab);
|
||||
xed_notebook_remove_tab (XED_NOTEBOOK (window->priv->notebook), tab);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4175,7 +4208,7 @@ _xed_window_fullscreen (XedWindow *window)
|
|||
}
|
||||
|
||||
/* Go to fullscreen mode and hide bars */
|
||||
gtk_window_fullscreen (&window->window);
|
||||
gtk_window_fullscreen (GTK_WINDOW (&window->window));
|
||||
|
||||
gtk_widget_hide (window->priv->menubar);
|
||||
|
||||
|
@ -4203,7 +4236,7 @@ _xed_window_unfullscreen (XedWindow *window)
|
|||
}
|
||||
|
||||
/* Unfullscreen and show bars */
|
||||
gtk_window_unfullscreen (&window->window);
|
||||
gtk_window_unfullscreen (GTK_WINDOW (&window->window));
|
||||
g_signal_handlers_disconnect_by_func (window->priv->notebook, hide_notebook_tabs_on_fullscreen, window);
|
||||
gtk_widget_show (window->priv->menubar);
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ typedef struct _XedWindowClass XedWindowClass;
|
|||
|
||||
struct _XedWindow
|
||||
{
|
||||
GtkWindow window;
|
||||
GtkApplicationWindow window;
|
||||
|
||||
/*< private > */
|
||||
XedWindowPrivate *priv;
|
||||
|
@ -40,7 +40,7 @@ struct _XedWindow
|
|||
|
||||
struct _XedWindowClass
|
||||
{
|
||||
GtkWindowClass parent_class;
|
||||
GtkApplicationWindowClass parent_class;
|
||||
|
||||
/* Signals */
|
||||
void (* tab_added) (XedWindow *window, XedTab *tab);
|
||||
|
@ -50,13 +50,13 @@ struct _XedWindowClass
|
|||
void (* active_tab_state_changed) (XedWindow *window);
|
||||
};
|
||||
|
||||
/*
|
||||
* Public methods
|
||||
*/
|
||||
/* Public methods */
|
||||
GType xed_window_get_type (void) G_GNUC_CONST;
|
||||
XedTab *xed_window_create_tab (XedWindow *window, gboolean jump_to);
|
||||
XedTab *xed_window_create_tab_from_location (XedWindow *window, GFile *location, const GtkSourceEncoding *encoding,
|
||||
gint line_pos, gboolean create, gboolean jump_to);
|
||||
XedTab *xed_window_create_tab_from_stream (XedWindow *window, GInputStream *stream, const GtkSourceEncoding *encoding,
|
||||
gint line_pos, gboolean jump_to);
|
||||
void xed_window_close_tab (XedWindow *window, XedTab *tab);
|
||||
void xed_window_close_all_tabs (XedWindow *window);
|
||||
void xed_window_close_tabs (XedWindow *window, const GList *tabs);
|
||||
|
|
620
xed/xed.c
620
xed/xed.c
|
@ -32,631 +32,25 @@
|
|||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#ifdef HAVE_INTROSPECTION
|
||||
#include <girepository.h>
|
||||
#endif
|
||||
|
||||
#include "xed-app.h"
|
||||
#include "xed-commands.h"
|
||||
#include "xed-debug.h"
|
||||
#include "xed-dirs.h"
|
||||
#include "xed-plugins-engine.h"
|
||||
#include "xed-session.h"
|
||||
#include "xed-utils.h"
|
||||
#include "xed-window.h"
|
||||
|
||||
#include "eggsmclient.h"
|
||||
#include "eggdesktopfile.h"
|
||||
|
||||
#ifndef ENABLE_GVFS_METADATA
|
||||
#include "xed-metadata-manager.h"
|
||||
#endif
|
||||
|
||||
#include "bacon-message-connection.h"
|
||||
|
||||
static guint32 startup_timestamp = 0;
|
||||
|
||||
static BaconMessageConnection *connection;
|
||||
|
||||
/* command line */
|
||||
static gint line_position = 0;
|
||||
// static gchar *encoding_charset = NULL;
|
||||
static gboolean new_window_option = FALSE;
|
||||
static gboolean new_document_option = FALSE;
|
||||
static gchar **remaining_args = NULL;
|
||||
static GSList *file_list = NULL;
|
||||
|
||||
static void
|
||||
show_version_and_quit (void)
|
||||
{
|
||||
g_print ("%s - Version %s\n", g_get_application_name (), VERSION);
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
// static void
|
||||
// list_encodings_and_quit (void)
|
||||
// {
|
||||
// gint i = 0;
|
||||
// const XedEncoding *enc;
|
||||
|
||||
// while ((enc = xed_encoding_get_from_index (i)) != NULL)
|
||||
// {
|
||||
// g_print ("%s\n", xed_encoding_get_charset (enc));
|
||||
|
||||
// ++i;
|
||||
// }
|
||||
|
||||
// exit (0);
|
||||
// }
|
||||
|
||||
static const GOptionEntry options [] =
|
||||
{
|
||||
{ "version", 'V', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
|
||||
show_version_and_quit, N_("Show the application's version"), NULL },
|
||||
|
||||
// { "encoding", '\0', 0, G_OPTION_ARG_STRING, &encoding_charset,
|
||||
// N_("Set the character encoding to be used to open the files listed on the command line"), N_("ENCODING")},
|
||||
|
||||
// { "list-encodings", '\0', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
|
||||
// list_encodings_and_quit, N_("Display list of possible values for the encoding option"), NULL},
|
||||
|
||||
{ "new-window", '\0', 0, G_OPTION_ARG_NONE, &new_window_option,
|
||||
N_("Create a new top-level window in an existing instance of xed"), NULL },
|
||||
|
||||
{ "new-document", '\0', 0, G_OPTION_ARG_NONE, &new_document_option,
|
||||
N_("Create a new document in an existing instance of xed"), NULL },
|
||||
|
||||
{ G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, &remaining_args,
|
||||
NULL, N_("[FILE...]") }, /* collects file arguments */
|
||||
|
||||
{NULL}
|
||||
};
|
||||
|
||||
static void
|
||||
free_command_line_data (void)
|
||||
{
|
||||
g_slist_foreach (file_list, (GFunc) g_object_unref, NULL);
|
||||
g_slist_free (file_list);
|
||||
file_list = NULL;
|
||||
|
||||
g_strfreev (remaining_args);
|
||||
remaining_args = NULL;
|
||||
|
||||
// g_free (encoding_charset);
|
||||
// encoding_charset = NULL;
|
||||
|
||||
new_window_option = FALSE;
|
||||
new_document_option = FALSE;
|
||||
line_position = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
xed_get_command_line_data (void)
|
||||
{
|
||||
if (remaining_args)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; remaining_args[i]; i++)
|
||||
{
|
||||
if (*remaining_args[i] == '+')
|
||||
{
|
||||
if (*(remaining_args[i] + 1) == '\0')
|
||||
/* goto the last line of the document */
|
||||
line_position = G_MAXINT;
|
||||
else
|
||||
line_position = atoi (remaining_args[i] + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
GFile *file;
|
||||
|
||||
file = g_file_new_for_commandline_arg (remaining_args[i]);
|
||||
file_list = g_slist_prepend (file_list, file);
|
||||
}
|
||||
}
|
||||
|
||||
file_list = g_slist_reverse (file_list);
|
||||
}
|
||||
|
||||
// if (encoding_charset &&
|
||||
// (xed_encoding_get_from_charset (encoding_charset) == NULL))
|
||||
// {
|
||||
// g_print (_("%s: invalid encoding.\n"),
|
||||
// encoding_charset);
|
||||
// }
|
||||
}
|
||||
|
||||
static guint32
|
||||
get_startup_timestamp (void)
|
||||
{
|
||||
const gchar *startup_id_env;
|
||||
gchar *startup_id = NULL;
|
||||
gchar *time_str;
|
||||
gchar *end;
|
||||
gulong retval = 0;
|
||||
|
||||
/* we don't unset the env, since startup-notification
|
||||
* may still need it */
|
||||
startup_id_env = g_getenv ("DESKTOP_STARTUP_ID");
|
||||
if (startup_id_env == NULL)
|
||||
goto out;
|
||||
|
||||
startup_id = g_strdup (startup_id_env);
|
||||
|
||||
time_str = g_strrstr (startup_id, "_TIME");
|
||||
if (time_str == NULL)
|
||||
goto out;
|
||||
|
||||
errno = 0;
|
||||
|
||||
/* Skip past the "_TIME" part */
|
||||
time_str += 5;
|
||||
|
||||
retval = strtoul (time_str, &end, 0);
|
||||
if (end == time_str || errno != 0)
|
||||
retval = 0;
|
||||
|
||||
out:
|
||||
g_free (startup_id);
|
||||
|
||||
return (retval > 0) ? retval : 0;
|
||||
}
|
||||
|
||||
static GdkDisplay *
|
||||
display_open_if_needed (const gchar *name)
|
||||
{
|
||||
GSList *displays;
|
||||
GSList *l;
|
||||
GdkDisplay *display = NULL;
|
||||
|
||||
displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
|
||||
|
||||
for (l = displays; l != NULL; l = l->next)
|
||||
{
|
||||
if (strcmp (gdk_display_get_name ((GdkDisplay *) l->data), name) == 0)
|
||||
{
|
||||
display = l->data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_slist_free (displays);
|
||||
|
||||
return display != NULL ? display : gdk_display_open (name);
|
||||
}
|
||||
|
||||
/* serverside */
|
||||
static void
|
||||
on_message_received (const char *message,
|
||||
gpointer data)
|
||||
{
|
||||
// const XedEncoding *encoding = NULL;
|
||||
gchar **commands;
|
||||
gchar **params;
|
||||
gint workspace;
|
||||
gint viewport_x;
|
||||
gint viewport_y;
|
||||
gchar *display_name;
|
||||
gint screen_number;
|
||||
gint i;
|
||||
XedApp *app;
|
||||
XedWindow *window;
|
||||
GdkDisplay *display;
|
||||
GdkScreen *screen;
|
||||
|
||||
g_return_if_fail (message != NULL);
|
||||
|
||||
xed_debug_message (DEBUG_APP, "Received message:\n%s\n", message);
|
||||
|
||||
commands = g_strsplit (message, "\v", -1);
|
||||
|
||||
/* header */
|
||||
params = g_strsplit (commands[0], "\t", 6);
|
||||
startup_timestamp = atoi (params[0]);
|
||||
display_name = params[1];
|
||||
screen_number = atoi (params[2]);
|
||||
workspace = atoi (params[3]);
|
||||
viewport_x = atoi (params[4]);
|
||||
viewport_y = atoi (params[5]);
|
||||
|
||||
display = display_open_if_needed (display_name);
|
||||
if (display == NULL)
|
||||
{
|
||||
g_warning ("Could not open display %s\n", display_name);
|
||||
g_strfreev (params);
|
||||
goto out;
|
||||
}
|
||||
|
||||
screen = gdk_display_get_screen (display, screen_number);
|
||||
|
||||
g_strfreev (params);
|
||||
|
||||
/* body */
|
||||
for (i = 1; commands[i] != NULL; i++)
|
||||
{
|
||||
params = g_strsplit (commands[i], "\t", -1);
|
||||
|
||||
if (strcmp (params[0], "NEW-WINDOW") == 0)
|
||||
{
|
||||
new_window_option = TRUE;
|
||||
}
|
||||
else if (strcmp (params[0], "NEW-DOCUMENT") == 0)
|
||||
{
|
||||
new_document_option = TRUE;
|
||||
}
|
||||
else if (strcmp (params[0], "OPEN-URIS") == 0)
|
||||
{
|
||||
gint n_uris, j;
|
||||
gchar **uris;
|
||||
|
||||
line_position = atoi (params[1]);
|
||||
|
||||
// if (params[2] != '\0')
|
||||
// encoding = xed_encoding_get_from_charset (params[2]);
|
||||
|
||||
n_uris = atoi (params[3]);
|
||||
uris = g_strsplit (params[4], " ", n_uris);
|
||||
|
||||
for (j = 0; j < n_uris; j++)
|
||||
{
|
||||
GFile *file;
|
||||
|
||||
file = g_file_new_for_uri (uris[j]);
|
||||
file_list = g_slist_prepend (file_list, file);
|
||||
}
|
||||
|
||||
file_list = g_slist_reverse (file_list);
|
||||
|
||||
/* the list takes ownerhip of the strings,
|
||||
* only free the array */
|
||||
g_free (uris);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Unexpected bacon command");
|
||||
}
|
||||
|
||||
g_strfreev (params);
|
||||
}
|
||||
|
||||
/* execute the commands */
|
||||
|
||||
app = xed_app_get_default ();
|
||||
|
||||
if (new_window_option)
|
||||
{
|
||||
window = xed_app_create_window (app, screen);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* get a window in the current workspace (if exists) and raise it */
|
||||
window = _xed_app_get_window_in_viewport (app,
|
||||
screen,
|
||||
workspace,
|
||||
viewport_x,
|
||||
viewport_y);
|
||||
}
|
||||
|
||||
if (file_list != NULL)
|
||||
{
|
||||
// _xed_cmd_load_files_from_prompt (window,
|
||||
// file_list,
|
||||
// encoding,
|
||||
// line_position);
|
||||
|
||||
if (new_document_option)
|
||||
xed_window_create_tab (window, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
XedDocument *doc;
|
||||
doc = xed_window_get_active_document (window);
|
||||
|
||||
if (doc == NULL ||
|
||||
!xed_document_is_untouched (doc) ||
|
||||
new_document_option)
|
||||
xed_window_create_tab (window, TRUE);
|
||||
}
|
||||
|
||||
/* set the proper interaction time on the window.
|
||||
* Fall back to roundtripping to the X server when we
|
||||
* don't have the timestamp, e.g. when launched from
|
||||
* terminal. We also need to make sure that the window
|
||||
* has been realized otherwise it will not work. lame.
|
||||
*/
|
||||
if (!gtk_widget_get_realized (GTK_WIDGET (window)))
|
||||
gtk_widget_realize (GTK_WIDGET (window));
|
||||
|
||||
if (startup_timestamp <= 0)
|
||||
startup_timestamp = gdk_x11_get_server_time (gtk_widget_get_window (GTK_WIDGET (window)));
|
||||
|
||||
gdk_x11_window_set_user_time (gtk_widget_get_window (GTK_WIDGET (window)),
|
||||
startup_timestamp);
|
||||
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
|
||||
out:
|
||||
g_strfreev (commands);
|
||||
|
||||
free_command_line_data ();
|
||||
}
|
||||
|
||||
/* clientside */
|
||||
static void
|
||||
send_bacon_message (void)
|
||||
{
|
||||
GdkScreen *screen;
|
||||
GdkDisplay *display;
|
||||
const gchar *display_name;
|
||||
gint screen_number;
|
||||
gint ws;
|
||||
gint viewport_x;
|
||||
gint viewport_y;
|
||||
GString *command;
|
||||
|
||||
/* the messages have the following format:
|
||||
* <--- header ---> <---- body ----->
|
||||
* timestamp \t display_name \t screen_number \t workspace \t viewport_x \t viewport_y \v OP1 \t arg \t arg \v OP2 \t arg \t arg|...
|
||||
*
|
||||
* when the arg is a list of uri, they are separated by a space.
|
||||
* So the delimiters are \v for the commands, \t for the tokens in
|
||||
* a command and ' ' for the uris: note that such delimiters cannot
|
||||
* be part of an uri, this way parsing is easier.
|
||||
*/
|
||||
|
||||
xed_debug (DEBUG_APP);
|
||||
|
||||
screen = gdk_screen_get_default ();
|
||||
display = gdk_screen_get_display (screen);
|
||||
|
||||
display_name = gdk_display_get_name (display);
|
||||
screen_number = gdk_screen_get_number (screen);
|
||||
|
||||
xed_debug_message (DEBUG_APP, "Display: %s", display_name);
|
||||
xed_debug_message (DEBUG_APP, "Screen: %d", screen_number);
|
||||
|
||||
ws = xed_utils_get_current_workspace (screen);
|
||||
xed_utils_get_current_viewport (screen, &viewport_x, &viewport_y);
|
||||
|
||||
command = g_string_new (NULL);
|
||||
|
||||
/* header */
|
||||
g_string_append_printf (command,
|
||||
"%" G_GUINT32_FORMAT "\t%s\t%d\t%d\t%d\t%d",
|
||||
startup_timestamp,
|
||||
display_name,
|
||||
screen_number,
|
||||
ws,
|
||||
viewport_x,
|
||||
viewport_y);
|
||||
|
||||
/* NEW-WINDOW command */
|
||||
if (new_window_option)
|
||||
{
|
||||
command = g_string_append_c (command, '\v');
|
||||
command = g_string_append (command, "NEW-WINDOW");
|
||||
}
|
||||
|
||||
/* NEW-DOCUMENT command */
|
||||
if (new_document_option)
|
||||
{
|
||||
command = g_string_append_c (command, '\v');
|
||||
command = g_string_append (command, "NEW-DOCUMENT");
|
||||
}
|
||||
|
||||
/* OPEN_URIS command, optionally specify line_num and encoding */
|
||||
if (file_list)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
command = g_string_append_c (command, '\v');
|
||||
command = g_string_append (command, "OPEN-URIS");
|
||||
|
||||
// g_string_append_printf (command,
|
||||
// "\t%d\t%s\t%u\t",
|
||||
// line_position,
|
||||
// encoding_charset ? encoding_charset : "",
|
||||
// g_slist_length (file_list));
|
||||
|
||||
for (l = file_list; l != NULL; l = l->next)
|
||||
{
|
||||
gchar *uri;
|
||||
|
||||
uri = g_file_get_uri (G_FILE (l->data));
|
||||
command = g_string_append (command, uri);
|
||||
if (l->next != NULL)
|
||||
command = g_string_append_c (command, ' ');
|
||||
|
||||
g_free (uri);
|
||||
}
|
||||
}
|
||||
|
||||
xed_debug_message (DEBUG_APP, "Bacon Message: %s", command->str);
|
||||
|
||||
bacon_message_connection_send (connection,
|
||||
command->str);
|
||||
|
||||
g_string_free (command, TRUE);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
GOptionContext *context;
|
||||
XedPluginsEngine *engine;
|
||||
XedWindow *window;
|
||||
XedApp *app;
|
||||
gboolean restored = FALSE;
|
||||
GError *error = NULL;
|
||||
gchar *dir;
|
||||
gchar *icon_dir;
|
||||
gint status;
|
||||
|
||||
|
||||
/* Setup debugging */
|
||||
xed_debug_init ();
|
||||
xed_debug_message (DEBUG_APP, "Startup");
|
||||
|
||||
setlocale (LC_ALL, "");
|
||||
|
||||
dir = xed_dirs_get_xed_locale_dir ();
|
||||
bindtextdomain (GETTEXT_PACKAGE, dir);
|
||||
g_free (dir);
|
||||
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
||||
textdomain (GETTEXT_PACKAGE);
|
||||
|
||||
startup_timestamp = get_startup_timestamp();
|
||||
|
||||
/* Setup command line options */
|
||||
context = g_option_context_new (_("- Edit text files"));
|
||||
g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
|
||||
g_option_context_add_group (context, gtk_get_option_group (FALSE));
|
||||
g_option_context_add_group (context, egg_sm_client_get_option_group ());
|
||||
|
||||
#ifdef HAVE_INTROSPECTION
|
||||
g_option_context_add_group (context, g_irepository_get_option_group ());
|
||||
#endif
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
if (!g_option_context_parse (context, &argc, &argv, &error))
|
||||
{
|
||||
g_print(_("%s\nRun '%s --help' to see a full list of available command line options.\n"),
|
||||
error->message, argv[0]);
|
||||
g_error_free (error);
|
||||
g_option_context_free (context);
|
||||
return 1;
|
||||
}
|
||||
|
||||
g_option_context_free (context);
|
||||
|
||||
xed_debug_message (DEBUG_APP, "Create bacon connection");
|
||||
|
||||
connection = bacon_message_connection_new ("xed");
|
||||
|
||||
if (connection != NULL)
|
||||
{
|
||||
if (!bacon_message_connection_get_is_server (connection))
|
||||
{
|
||||
xed_debug_message (DEBUG_APP, "I'm a client");
|
||||
|
||||
xed_get_command_line_data ();
|
||||
|
||||
send_bacon_message ();
|
||||
|
||||
free_command_line_data ();
|
||||
|
||||
/* we never popup a window... tell startup-notification
|
||||
* that we are done.
|
||||
*/
|
||||
gdk_notify_startup_complete ();
|
||||
|
||||
bacon_message_connection_free (connection);
|
||||
|
||||
exit (0);
|
||||
}
|
||||
else
|
||||
{
|
||||
xed_debug_message (DEBUG_APP, "I'm a server");
|
||||
|
||||
bacon_message_connection_set_callback (connection,
|
||||
on_message_received,
|
||||
app = g_object_new (XED_TYPE_APP,
|
||||
"application-id", "org.x.editor",
|
||||
"flags", G_APPLICATION_HANDLES_COMMAND_LINE,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Cannot create the 'xed' connection.");
|
||||
}
|
||||
|
||||
xed_debug_message (DEBUG_APP, "Set icon");
|
||||
status = g_application_run (G_APPLICATION (app), argc, argv);
|
||||
|
||||
dir = xed_dirs_get_xed_data_dir ();
|
||||
icon_dir = g_build_filename (dir,
|
||||
"icons",
|
||||
NULL);
|
||||
g_free (dir);
|
||||
g_object_unref (app);
|
||||
|
||||
gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (),
|
||||
icon_dir);
|
||||
g_free (icon_dir);
|
||||
|
||||
/* Set the associated .desktop file */
|
||||
egg_set_desktop_file (DATADIR "/applications/xed.desktop");
|
||||
|
||||
/* Init plugins engine */
|
||||
xed_debug_message (DEBUG_APP, "Init plugins");
|
||||
engine = xed_plugins_engine_get_default ();
|
||||
|
||||
/* Initialize session management */
|
||||
xed_debug_message (DEBUG_APP, "Init session manager");
|
||||
xed_session_init ();
|
||||
|
||||
if (xed_session_is_restored ())
|
||||
restored = xed_session_load ();
|
||||
|
||||
if (!restored)
|
||||
{
|
||||
xed_debug_message (DEBUG_APP, "Analyze command line data");
|
||||
xed_get_command_line_data ();
|
||||
|
||||
xed_debug_message (DEBUG_APP, "Get default app");
|
||||
app = xed_app_get_default ();
|
||||
|
||||
xed_debug_message (DEBUG_APP, "Create main window");
|
||||
window = xed_app_create_window (app, NULL);
|
||||
|
||||
// if (file_list != NULL)
|
||||
// {
|
||||
// const XedEncoding *encoding = NULL;
|
||||
|
||||
// // if (encoding_charset)
|
||||
// // encoding = xed_encoding_get_from_charset (encoding_charset);
|
||||
|
||||
// xed_debug_message (DEBUG_APP, "Load files");
|
||||
// _xed_cmd_load_files_from_prompt (window,
|
||||
// file_list,
|
||||
// encoding,
|
||||
// line_position);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// xed_debug_message (DEBUG_APP, "Create tab");
|
||||
// xed_window_create_tab (window, TRUE);
|
||||
// }
|
||||
|
||||
xed_debug_message (DEBUG_APP, "Show window");
|
||||
gtk_widget_show (GTK_WIDGET (window));
|
||||
|
||||
free_command_line_data ();
|
||||
}
|
||||
|
||||
xed_debug_message (DEBUG_APP, "Start gtk-main");
|
||||
|
||||
gtk_main();
|
||||
|
||||
bacon_message_connection_free (connection);
|
||||
|
||||
/* We kept the original engine reference here. So let's unref it to
|
||||
* finalize it properly.
|
||||
*/
|
||||
g_object_unref (engine);
|
||||
|
||||
#ifndef ENABLE_GVFS_METADATA
|
||||
xed_metadata_manager_shutdown ();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue