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"
|
TOOLBAR_STYLE="XED_TOOLBAR_SYSTEM"
|
||||||
AC_SUBST(TOOLBAR_STYLE)
|
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 ===============================================================
|
||||||
dnl Expanded dirs
|
dnl Expanded dirs
|
||||||
dnl ===============================================================
|
dnl ===============================================================
|
||||||
|
@ -151,12 +145,12 @@ dnl ================================================================
|
||||||
PKG_CHECK_MODULES(GMODULE,gmodule-2.0,[GMODULE_ADD="gmodule-2.0"],[GMODULE_ADD=""])
|
PKG_CHECK_MODULES(GMODULE,gmodule-2.0,[GMODULE_ADD="gmodule-2.0"],[GMODULE_ADD=""])
|
||||||
PKG_CHECK_MODULES(XED, [
|
PKG_CHECK_MODULES(XED, [
|
||||||
libxml-2.0 >= 2.5.0
|
libxml-2.0 >= 2.5.0
|
||||||
glib-2.0 >= 2.36.0
|
glib-2.0 >= 2.40.0
|
||||||
$GMODULE_ADD
|
$GMODULE_ADD
|
||||||
gthread-2.0 >= 2.13.0
|
gthread-2.0 >= 2.13.0
|
||||||
gio-2.0 >= 2.26.0
|
gio-2.0 >= 2.40.0
|
||||||
gtk+-3.0 >= 3.10.0
|
gtk+-3.0 >= 3.14.0
|
||||||
gtksourceview-3.0 >= 2.9.7
|
gtksourceview-3.0 >= 3.14.3
|
||||||
libpeas-1.0 >= 1.12.0
|
libpeas-1.0 >= 1.12.0
|
||||||
libpeas-gtk-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_CFLAGS)
|
||||||
AC_SUBST(XED_LIBS)
|
AC_SUBST(XED_LIBS)
|
||||||
|
|
||||||
PKG_CHECK_MODULES(EGG_SMCLIENT, [sm >= 1.0.0])
|
|
||||||
|
|
||||||
AC_SUBST(EGG_SMCLIENT_CFLAGS)
|
|
||||||
AC_SUBST(EGG_SMCLIENT_LIBS)
|
|
||||||
|
|
||||||
# Introspection
|
# Introspection
|
||||||
GOBJECT_INTROSPECTION_CHECK([0.9.3])
|
GOBJECT_INTROSPECTION_CHECK([0.9.3])
|
||||||
|
|
||||||
if test "$found_introspection" = "yes"; then
|
if test "$found_introspection" = "yes"; then
|
||||||
have_introspection=yes
|
enable_introspection=yes
|
||||||
AC_DEFINE([HAVE_INTROSPECTION], [1], [Define to enable GObject Introspection])
|
AC_DEFINE([ENABLE_INTROSPECTION], [1], [Define to enable GObject Introspection])
|
||||||
else
|
else
|
||||||
have_introspection=no
|
enable_introspection=no
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl ================================================================
|
dnl ================================================================
|
||||||
|
@ -235,7 +224,6 @@ data/Makefile
|
||||||
docs/Makefile
|
docs/Makefile
|
||||||
docs/reference/Makefile
|
docs/reference/Makefile
|
||||||
xed/dialogs/Makefile
|
xed/dialogs/Makefile
|
||||||
xed/smclient/Makefile
|
|
||||||
xed/Makefile
|
xed/Makefile
|
||||||
help/Makefile
|
help/Makefile
|
||||||
pixmaps/Makefile
|
pixmaps/Makefile
|
||||||
|
@ -264,5 +252,5 @@ Configuration:
|
||||||
Compiler: ${CC}
|
Compiler: ${CC}
|
||||||
Spell Plugin enabled: $enable_enchant
|
Spell Plugin enabled: $enable_enchant
|
||||||
Gvfs metadata enabled: $enable_gvfs_metadata
|
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@
|
@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
|
man_MANS = xed.1
|
||||||
|
|
||||||
pkgconfigdir = $(libdir)/pkgconfig
|
pkgconfigdir = $(libdir)/pkgconfig
|
||||||
|
@ -24,12 +31,14 @@ bugreport_SCRIPTS = xed-bugreport.sh
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
$(appdata_in_files) \
|
$(appdata_in_files) \
|
||||||
$(desktop_in_files) \
|
$(desktop_in_files) \
|
||||||
|
$(service_in_files) \
|
||||||
$(man_MANS) \
|
$(man_MANS) \
|
||||||
xed.pc.in \
|
xed.pc.in \
|
||||||
xed-bugreport.sh.in
|
xed-bugreport.sh.in
|
||||||
|
|
||||||
CLEANFILES = \
|
CLEANFILES = \
|
||||||
$(desktop_DATA) \
|
$(desktop_DATA) \
|
||||||
|
$(service_DATA) \
|
||||||
$(gsettings_SCHEMAS) \
|
$(gsettings_SCHEMAS) \
|
||||||
$(pkgconfig_DATA) \
|
$(pkgconfig_DATA) \
|
||||||
$(appdata_DATA)
|
$(appdata_DATA)
|
||||||
|
|
|
@ -4,4 +4,5 @@ usr/lib/xed/xed-bugreport.sh
|
||||||
usr/lib/*/xed/plugins/*.plugin
|
usr/lib/*/xed/plugins/*.plugin
|
||||||
usr/lib/*/xed/plugins/*.so
|
usr/lib/*/xed/plugins/*.so
|
||||||
usr/share/applications/xed.desktop
|
usr/share/applications/xed.desktop
|
||||||
|
usr/share/dbus-1/
|
||||||
usr/share/man/
|
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_activatable_get_type
|
||||||
xed_app_get_type
|
xed_app_get_type
|
||||||
xed_close_button_get_type
|
xed_close_button_get_type
|
||||||
|
|
|
@ -761,13 +761,11 @@ on_rename_cb (XedFileBrowserStore *store,
|
||||||
GFile *newfile,
|
GFile *newfile,
|
||||||
XedWindow *window)
|
XedWindow *window)
|
||||||
{
|
{
|
||||||
XedApp *app;
|
|
||||||
GList *documents;
|
GList *documents;
|
||||||
GList *item;
|
GList *item;
|
||||||
|
|
||||||
/* Find all documents and set its uri to newuri where it matches olduri */
|
/* Find all documents and set its uri to newuri where it matches olduri */
|
||||||
app = xed_app_get_default ();
|
documents = xed_app_get_documents (XED_APP (g_application_get_default ()));
|
||||||
documents = xed_app_get_documents (app);
|
|
||||||
|
|
||||||
for (item = documents; item; item = item->next)
|
for (item = documents; item; item = item->next)
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
#include <xed/xed-window-activatable.h>
|
#include <xed/xed-window-activatable.h>
|
||||||
#include <xed/xed-debug.h>
|
#include <xed/xed-debug.h>
|
||||||
#include <xed/xed-utils.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))
|
#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;
|
break;
|
||||||
|
|
||||||
case GTK_RESPONSE_HELP:
|
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;
|
break;
|
||||||
|
|
||||||
case GTK_RESPONSE_CANCEL:
|
case GTK_RESPONSE_CANCEL:
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <xed/xed-utils.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-language-dialog.h"
|
||||||
#include "xed-spell-checker-language.h"
|
#include "xed-spell-checker-language.h"
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ dialog_response_handler (GtkDialog *dlg,
|
||||||
{
|
{
|
||||||
if (res_id == GTK_RESPONSE_HELP)
|
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");
|
g_signal_stop_emission_by_name (dlg, "response");
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "xed-time-plugin.h"
|
#include "xed-time-plugin.h"
|
||||||
#include <xed/xed-help.h>
|
#include <xed/xed-app.h>
|
||||||
|
|
||||||
#include <glib/gi18n-lib.h>
|
#include <glib/gi18n-lib.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
@ -916,7 +916,7 @@ choose_format_dialog_response_cb (GtkWidget *widget,
|
||||||
case GTK_RESPONSE_HELP:
|
case GTK_RESPONSE_HELP:
|
||||||
{
|
{
|
||||||
xed_debug_message (DEBUG_PLUGINS, "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;
|
break;
|
||||||
}
|
}
|
||||||
case GTK_RESPONSE_OK:
|
case GTK_RESPONSE_OK:
|
||||||
|
|
|
@ -17,7 +17,6 @@ xed/xed-commands-search.c
|
||||||
xed/xed-debug.c
|
xed/xed-debug.c
|
||||||
xed/xed-document.c
|
xed/xed-document.c
|
||||||
xed/xed-documents-panel.c
|
xed/xed-documents-panel.c
|
||||||
xed/xed-encodings.c
|
|
||||||
xed/xed-encodings-combo-box.c
|
xed/xed-encodings-combo-box.c
|
||||||
xed/xed-file-chooser-dialog.c
|
xed/xed-file-chooser-dialog.c
|
||||||
xed/xed-gio-document-loader.c
|
xed/xed-gio-document-loader.c
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
## Process this file with automake to produce Makefile.in
|
## Process this file with automake to produce Makefile.in
|
||||||
SUBDIRS = dialogs smclient
|
SUBDIRS = dialogs
|
||||||
|
|
||||||
bin_PROGRAMS = xed
|
bin_PROGRAMS = xed
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ noinst_LTLIBRARIES = libxed.la
|
||||||
AM_CPPFLAGS = \
|
AM_CPPFLAGS = \
|
||||||
-I$(top_srcdir) \
|
-I$(top_srcdir) \
|
||||||
-I$(srcdir) \
|
-I$(srcdir) \
|
||||||
-I$(srcdir)/smclient \
|
|
||||||
$(XED_CFLAGS) \
|
$(XED_CFLAGS) \
|
||||||
$(WARN_CFLAGS) \
|
$(WARN_CFLAGS) \
|
||||||
$(INTROSPECTION_CFLAGS) \
|
$(INTROSPECTION_CFLAGS) \
|
||||||
|
@ -22,7 +21,6 @@ xed_SOURCES = \
|
||||||
xed_LDADD = \
|
xed_LDADD = \
|
||||||
libxed.la \
|
libxed.la \
|
||||||
$(XED_LIBS) \
|
$(XED_LIBS) \
|
||||||
$(EGG_SMCLIENT_LIBS) \
|
|
||||||
$(INTROSPECTION_LIBS)
|
$(INTROSPECTION_LIBS)
|
||||||
|
|
||||||
xed_LDFLAGS = -export-dynamic -no-undefined -export-symbols-regex "^[[^_]].*"
|
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_LDFLAGS = -export-dynamic -no-undefined -export-symbols-regex "^[[^_]].*"
|
||||||
|
|
||||||
libxed_la_LIBADD = \
|
libxed_la_LIBADD = \
|
||||||
dialogs/libdialogs.la \
|
dialogs/libdialogs.la
|
||||||
smclient/libeggsmclient.la
|
|
||||||
|
|
||||||
# XED_LIBS must be the last to ensure correct order on some platforms
|
# XED_LIBS must be the last to ensure correct order on some platforms
|
||||||
libxed_la_LIBADD += $(XED_LIBS) -lICE
|
libxed_la_LIBADD += $(XED_LIBS) -lICE
|
||||||
|
@ -52,7 +49,6 @@ NOINST_H_FILES = \
|
||||||
xed-plugins-engine.h \
|
xed-plugins-engine.h \
|
||||||
xed-print-job.h \
|
xed-print-job.h \
|
||||||
xed-print-preview.h \
|
xed-print-preview.h \
|
||||||
xed-session.h \
|
|
||||||
xed-settings.h \
|
xed-settings.h \
|
||||||
xed-status-combo-box.h \
|
xed-status-combo-box.h \
|
||||||
xed-tab-label.h \
|
xed-tab-label.h \
|
||||||
|
@ -69,7 +65,6 @@ INST_H_FILES = \
|
||||||
xed-document.h \
|
xed-document.h \
|
||||||
xed-encodings-combo-box.h \
|
xed-encodings-combo-box.h \
|
||||||
xed-file-chooser-dialog.h \
|
xed-file-chooser-dialog.h \
|
||||||
xed-help.h \
|
|
||||||
xed-message-bus.h \
|
xed-message-bus.h \
|
||||||
xed-message-type.h \
|
xed-message-type.h \
|
||||||
xed-message.h \
|
xed-message.h \
|
||||||
|
@ -111,7 +106,6 @@ libxed_c_files = \
|
||||||
xed-documents-panel.c \
|
xed-documents-panel.c \
|
||||||
xed-encodings-combo-box.c \
|
xed-encodings-combo-box.c \
|
||||||
xed-file-chooser-dialog.c \
|
xed-file-chooser-dialog.c \
|
||||||
xed-help.c \
|
|
||||||
xed-history-entry.c \
|
xed-history-entry.c \
|
||||||
xed-io-error-message-area.c \
|
xed-io-error-message-area.c \
|
||||||
xed-message-bus.c \
|
xed-message-bus.c \
|
||||||
|
@ -123,7 +117,6 @@ libxed_c_files = \
|
||||||
xed-print-job.c \
|
xed-print-job.c \
|
||||||
xed-print-preview.c \
|
xed-print-preview.c \
|
||||||
xed-progress-message-area.c \
|
xed-progress-message-area.c \
|
||||||
xed-session.c \
|
|
||||||
xed-settings.c \
|
xed-settings.c \
|
||||||
xed-searchbar.c \
|
xed-searchbar.c \
|
||||||
xed-statusbar.c \
|
xed-statusbar.c \
|
||||||
|
@ -140,7 +133,6 @@ libxed_c_files = \
|
||||||
libxed_la_SOURCES = \
|
libxed_la_SOURCES = \
|
||||||
$(BUILT_SOURCES) \
|
$(BUILT_SOURCES) \
|
||||||
$(libxed_c_files) \
|
$(libxed_c_files) \
|
||||||
$(BACON_FILES) \
|
|
||||||
$(POSIXIO_FILES) \
|
$(POSIXIO_FILES) \
|
||||||
$(NOINST_H_FILES) \
|
$(NOINST_H_FILES) \
|
||||||
$(INST_H_FILES)
|
$(INST_H_FILES)
|
||||||
|
@ -205,10 +197,4 @@ endif
|
||||||
dist-hook:
|
dist-hook:
|
||||||
cd $(distdir); rm -f $(BUILT_SOURCES)
|
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
|
-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-encodings-dialog.h"
|
||||||
#include "xed-utils.h"
|
#include "xed-utils.h"
|
||||||
#include "xed-debug.h"
|
#include "xed-debug.h"
|
||||||
#include "xed-help.h"
|
|
||||||
#include "xed-dirs.h"
|
#include "xed-dirs.h"
|
||||||
#include "xed-settings.h"
|
#include "xed-settings.h"
|
||||||
|
|
||||||
|
@ -271,7 +270,7 @@ response_handler (GtkDialog *dialog,
|
||||||
{
|
{
|
||||||
if (response_id == GTK_RESPONSE_HELP)
|
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");
|
g_signal_stop_emission_by_name (dialog, "response");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,6 @@
|
||||||
#include "xed-utils.h"
|
#include "xed-utils.h"
|
||||||
#include "xed-debug.h"
|
#include "xed-debug.h"
|
||||||
#include "xed-document.h"
|
#include "xed-document.h"
|
||||||
#include "xed-help.h"
|
|
||||||
#include "xed-dirs.h"
|
#include "xed-dirs.h"
|
||||||
#include "xed-settings.h"
|
#include "xed-settings.h"
|
||||||
#include "xed-utils.h"
|
#include "xed-utils.h"
|
||||||
|
@ -172,7 +171,7 @@ dialog_response_handler (GtkDialog *dlg,
|
||||||
switch (res_id)
|
switch (res_id)
|
||||||
{
|
{
|
||||||
case GTK_RESPONSE_HELP:
|
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");
|
g_signal_stop_emission_by_name (dlg, "response");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -308,13 +307,11 @@ setup_view_page (XedPreferencesDialog *dlg)
|
||||||
{
|
{
|
||||||
GtkWrapMode wrap_mode;
|
GtkWrapMode wrap_mode;
|
||||||
gboolean display_right_margin;
|
gboolean display_right_margin;
|
||||||
guint right_margin_position;
|
|
||||||
|
|
||||||
xed_debug (DEBUG_PREFS);
|
xed_debug (DEBUG_PREFS);
|
||||||
|
|
||||||
/* Get values */
|
/* Get values */
|
||||||
display_right_margin = g_settings_get_boolean (dlg->priv->editor, XED_SETTINGS_DISPLAY_RIGHT_MARGIN);
|
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 */
|
/* Set initial state */
|
||||||
wrap_mode = g_settings_get_enum (dlg->priv->editor, XED_SETTINGS_WRAP_MODE);
|
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);
|
ATK_RELATION_CONTROLLER_FOR);
|
||||||
|
|
||||||
/* Get values */
|
/* 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));
|
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);
|
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
|
struct _XedApp
|
||||||
{
|
{
|
||||||
GObject object;
|
GtkApplication parent;
|
||||||
|
|
||||||
/*< private > */
|
/*< private > */
|
||||||
XedAppPrivate *priv;
|
XedAppPrivate *priv;
|
||||||
|
@ -58,38 +58,49 @@ struct _XedApp
|
||||||
|
|
||||||
struct _XedAppClass
|
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;
|
GType xed_app_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
XedApp *xed_app_get_default (void);
|
|
||||||
|
|
||||||
XedWindow *xed_app_create_window (XedApp *app,
|
XedWindow *xed_app_create_window (XedApp *app,
|
||||||
GdkScreen *screen);
|
GdkScreen *screen);
|
||||||
|
|
||||||
const GList *xed_app_get_windows (XedApp *app);
|
GList *xed_app_get_main_windows (XedApp *app);
|
||||||
XedWindow *xed_app_get_active_window (XedApp *app);
|
|
||||||
|
|
||||||
/* Returns a newly allocated list with all the documents */
|
|
||||||
GList *xed_app_get_documents (XedApp *app);
|
GList *xed_app_get_documents (XedApp *app);
|
||||||
|
|
||||||
/* Returns a newly allocated list with all the views */
|
/* Returns a newly allocated list with all the views */
|
||||||
GList *xed_app_get_views (XedApp *app);
|
GList *xed_app_get_views (XedApp *app);
|
||||||
|
|
||||||
/*
|
gboolean xed_app_show_help (XedApp *app,
|
||||||
* Non exported functions
|
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,
|
XedWindow *_xed_app_restore_window (XedApp *app,
|
||||||
const gchar *role);
|
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 */
|
/* global print config */
|
||||||
GtkPageSetup *_xed_app_get_default_page_setup (XedApp *app);
|
GtkPageSetup *_xed_app_get_default_page_setup (XedApp *app);
|
||||||
|
|
|
@ -61,6 +61,9 @@ static void tab_state_changed_while_saving (XedTab *tab,
|
||||||
GParamSpec *pspec,
|
GParamSpec *pspec,
|
||||||
XedWindow *window);
|
XedWindow *window);
|
||||||
|
|
||||||
|
static void save_as_tab (XedTab *tab,
|
||||||
|
XedWindow *window);
|
||||||
|
|
||||||
void
|
void
|
||||||
_xed_cmd_file_new (GtkAction *action,
|
_xed_cmd_file_new (GtkAction *action,
|
||||||
XedWindow *window)
|
XedWindow *window)
|
||||||
|
@ -116,7 +119,7 @@ is_duplicated_file (GSList *files,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* File loading */
|
/* File loading */
|
||||||
static gint
|
static GSList *
|
||||||
load_file_list (XedWindow *window,
|
load_file_list (XedWindow *window,
|
||||||
const GSList *files,
|
const GSList *files,
|
||||||
const GtkSourceEncoding *encoding,
|
const GtkSourceEncoding *encoding,
|
||||||
|
@ -124,11 +127,12 @@ load_file_list (XedWindow *window,
|
||||||
gboolean create)
|
gboolean create)
|
||||||
{
|
{
|
||||||
XedTab *tab;
|
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 */
|
gboolean jump_to = TRUE; /* Whether to jump to the new tab */
|
||||||
GList *win_docs;
|
GList *win_docs;
|
||||||
GSList *files_to_load = NULL;
|
GSList *files_to_load = NULL;
|
||||||
const GSList *l;
|
const GSList *l;
|
||||||
|
gint num_loaded_files = 0;
|
||||||
|
|
||||||
xed_debug (DEBUG_COMMANDS);
|
xed_debug (DEBUG_COMMANDS);
|
||||||
|
|
||||||
|
@ -145,29 +149,25 @@ load_file_list (XedWindow *window,
|
||||||
{
|
{
|
||||||
if (l == files)
|
if (l == files)
|
||||||
{
|
{
|
||||||
|
XedDocument *doc;
|
||||||
|
|
||||||
xed_window_set_active_tab (window, tab);
|
xed_window_set_active_tab (window, tab);
|
||||||
jump_to = FALSE;
|
jump_to = FALSE;
|
||||||
|
doc = xed_tab_get_document (tab);
|
||||||
|
|
||||||
if (line_pos > 0)
|
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_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
|
else
|
||||||
{
|
{
|
||||||
files_to_load = g_slist_prepend (files_to_load,
|
files_to_load = g_slist_prepend (files_to_load, l->data);
|
||||||
l->data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,7 @@ load_file_list (XedWindow *window,
|
||||||
|
|
||||||
if (files_to_load == NULL)
|
if (files_to_load == NULL)
|
||||||
{
|
{
|
||||||
return loaded_files;
|
return g_slist_reverse (loaded_files);
|
||||||
}
|
}
|
||||||
|
|
||||||
files_to_load = g_slist_reverse (files_to_load);
|
files_to_load = g_slist_reverse (files_to_load);
|
||||||
|
@ -196,7 +196,8 @@ load_file_list (XedWindow *window,
|
||||||
l = g_slist_next (l);
|
l = g_slist_next (l);
|
||||||
jump_to = FALSE;
|
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)
|
if (tab != NULL)
|
||||||
{
|
{
|
||||||
jump_to = FALSE;
|
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);
|
l = g_slist_next (l);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loaded_files == 1)
|
loaded_files = g_slist_reverse (loaded_files);
|
||||||
|
|
||||||
|
if (num_loaded_files == 1)
|
||||||
{
|
{
|
||||||
XedDocument *doc;
|
XedDocument *doc;
|
||||||
gchar *uri_for_display;
|
gchar *uri_for_display;
|
||||||
|
@ -238,8 +242,8 @@ load_file_list (XedWindow *window,
|
||||||
window->priv->generic_message_cid,
|
window->priv->generic_message_cid,
|
||||||
ngettext("Loading %d file\342\200\246",
|
ngettext("Loading %d file\342\200\246",
|
||||||
"Loading %d files\342\200\246",
|
"Loading %d files\342\200\246",
|
||||||
loaded_files),
|
num_loaded_files),
|
||||||
loaded_files);
|
num_loaded_files);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free uris_to_load. Note that l points to the first element of uris_to_load */
|
/* 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;
|
GSList *locations = NULL;
|
||||||
gchar *uri;
|
gchar *uri;
|
||||||
|
GSList *ret;
|
||||||
|
|
||||||
g_return_if_fail (XED_IS_WINDOW (window));
|
g_return_if_fail (XED_IS_WINDOW (window));
|
||||||
g_return_if_fail (G_IS_FILE (location));
|
g_return_if_fail (G_IS_FILE (location));
|
||||||
|
@ -276,7 +281,8 @@ xed_commands_load_location (XedWindow *window,
|
||||||
|
|
||||||
locations = g_slist_prepend (locations, location);
|
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);
|
g_slist_free (locations);
|
||||||
}
|
}
|
||||||
|
@ -292,7 +298,7 @@ xed_commands_load_location (XedWindow *window,
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
*/
|
*/
|
||||||
gint
|
GSList *
|
||||||
xed_commands_load_locations (XedWindow *window,
|
xed_commands_load_locations (XedWindow *window,
|
||||||
const GSList *locations,
|
const GSList *locations,
|
||||||
const GtkSourceEncoding *encoding,
|
const GtkSourceEncoding *encoding,
|
||||||
|
@ -311,7 +317,7 @@ xed_commands_load_locations (XedWindow *window,
|
||||||
* first doc. Beside specifying a not existing uri creates a
|
* first doc. Beside specifying a not existing uri creates a
|
||||||
* titled document.
|
* titled document.
|
||||||
*/
|
*/
|
||||||
gint
|
GSList *
|
||||||
_xed_cmd_load_files_from_prompt (XedWindow *window,
|
_xed_cmd_load_files_from_prompt (XedWindow *window,
|
||||||
GSList *files,
|
GSList *files,
|
||||||
const GtkSourceEncoding *encoding,
|
const GtkSourceEncoding *encoding,
|
||||||
|
@ -338,6 +344,7 @@ open_dialog_response_cb (XedFileChooserDialog *dialog,
|
||||||
{
|
{
|
||||||
GSList *files;
|
GSList *files;
|
||||||
const GtkSourceEncoding *encoding;
|
const GtkSourceEncoding *encoding;
|
||||||
|
GSList *loaded;
|
||||||
|
|
||||||
xed_debug (DEBUG_COMMANDS);
|
xed_debug (DEBUG_COMMANDS);
|
||||||
|
|
||||||
|
@ -358,7 +365,9 @@ open_dialog_response_cb (XedFileChooserDialog *dialog,
|
||||||
/* Remember the folder we navigated to */
|
/* Remember the folder we navigated to */
|
||||||
_xed_window_set_default_location (window, files->data);
|
_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_foreach (files, (GFunc) g_object_unref, NULL);
|
||||||
g_slist_free (files);
|
g_slist_free (files);
|
||||||
|
@ -433,9 +442,6 @@ _xed_cmd_file_open (GtkAction *action,
|
||||||
gtk_widget_show (open_dialog);
|
gtk_widget_show (open_dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* File saving */
|
|
||||||
static void file_save_as (XedTab *tab, XedWindow *window);
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
is_read_only (GFile *location)
|
is_read_only (GFile *location)
|
||||||
{
|
{
|
||||||
|
@ -511,6 +517,14 @@ replace_read_only_file (GtkWindow *parent,
|
||||||
return (ret == GTK_RESPONSE_YES);
|
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
|
static void
|
||||||
save_dialog_response_cb (XedFileChooserDialog *dialog,
|
save_dialog_response_cb (XedFileChooserDialog *dialog,
|
||||||
gint response_id,
|
gint response_id,
|
||||||
|
@ -535,13 +549,11 @@ save_dialog_response_cb (XedFileChooserDialog *dialog,
|
||||||
{
|
{
|
||||||
GFile *location;
|
GFile *location;
|
||||||
XedDocument *doc;
|
XedDocument *doc;
|
||||||
GtkSourceFile *file;
|
|
||||||
gchar *parse_name;
|
gchar *parse_name;
|
||||||
GtkSourceNewlineType newline_type;
|
GtkSourceNewlineType newline_type;
|
||||||
const GtkSourceEncoding *encoding;
|
const GtkSourceEncoding *encoding;
|
||||||
|
|
||||||
doc = xed_tab_get_document (tab);
|
doc = xed_tab_get_document (tab);
|
||||||
file = xed_document_get_file (doc);
|
|
||||||
|
|
||||||
location = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
|
location = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
|
||||||
g_return_if_fail (location != NULL);
|
g_return_if_fail (location != NULL);
|
||||||
|
@ -567,7 +579,13 @@ save_dialog_response_cb (XedFileChooserDialog *dialog,
|
||||||
* even if the saving fails... */
|
* even if the saving fails... */
|
||||||
_xed_window_set_default_location (window, location);
|
_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);
|
g_object_unref (location);
|
||||||
}
|
}
|
||||||
|
@ -602,7 +620,7 @@ save_next_tab:
|
||||||
}
|
}
|
||||||
|
|
||||||
xed_window_set_active_tab (window, 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
|
static void
|
||||||
file_save_as (XedTab *tab,
|
save_as_tab (XedTab *tab,
|
||||||
XedWindow *window)
|
XedWindow *window)
|
||||||
{
|
{
|
||||||
GtkWidget *save_dialog;
|
GtkWidget *save_dialog;
|
||||||
|
@ -715,7 +733,11 @@ file_save_as (XedTab *tab,
|
||||||
|
|
||||||
/* Set suggested encoding */
|
/* Set suggested encoding */
|
||||||
encoding = gtk_source_file_get_encoding (file);
|
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);
|
newline_type = gtk_source_file_get_newline_type (file);
|
||||||
|
|
||||||
|
@ -731,7 +753,7 @@ file_save_as (XedTab *tab,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
file_save (XedTab *tab,
|
save_tab (XedTab *tab,
|
||||||
XedWindow *window)
|
XedWindow *window)
|
||||||
{
|
{
|
||||||
XedDocument *doc;
|
XedDocument *doc;
|
||||||
|
@ -750,7 +772,7 @@ file_save (XedTab *tab,
|
||||||
{
|
{
|
||||||
xed_debug_message (DEBUG_COMMANDS, "Untitled or Readonly");
|
xed_debug_message (DEBUG_COMMANDS, "Untitled or Readonly");
|
||||||
|
|
||||||
file_save_as (tab, window);
|
save_as_tab (tab, window);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -763,7 +785,10 @@ file_save (XedTab *tab,
|
||||||
|
|
||||||
g_free (uri_for_display);
|
g_free (uri_for_display);
|
||||||
|
|
||||||
_xed_tab_save (tab);
|
_xed_tab_save_async (tab,
|
||||||
|
NULL,
|
||||||
|
(GAsyncReadyCallback) save_finish_cb,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -780,7 +805,7 @@ _xed_cmd_file_save (GtkAction *action,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
file_save (tab, window);
|
save_tab (tab, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -797,14 +822,14 @@ _xed_cmd_file_save_as (GtkAction *action,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
file_save_as (tab, window);
|
save_as_tab (tab, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The docs in the list must belong to the same XedWindow.
|
* The docs in the list must belong to the same XedWindow.
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
_xed_cmd_file_save_documents_list (XedWindow *window,
|
save_documents_list (XedWindow *window,
|
||||||
GList *docs)
|
GList *docs)
|
||||||
{
|
{
|
||||||
GList *l;
|
GList *l;
|
||||||
|
@ -846,7 +871,7 @@ _xed_cmd_file_save_documents_list (XedWindow *window,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
file_save (t, window);
|
save_tab (t, window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -898,7 +923,7 @@ _xed_cmd_file_save_documents_list (XedWindow *window,
|
||||||
tab = XED_TAB (tabs_to_save_as->data);
|
tab = XED_TAB (tabs_to_save_as->data);
|
||||||
|
|
||||||
xed_window_set_active_tab (window, tab);
|
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);
|
docs = xed_window_get_documents (window);
|
||||||
|
|
||||||
_xed_cmd_file_save_documents_list (window, docs);
|
save_documents_list (window, docs);
|
||||||
|
|
||||||
g_list_free (docs);
|
g_list_free (docs);
|
||||||
}
|
}
|
||||||
|
@ -937,7 +962,7 @@ xed_commands_save_document (XedWindow *window,
|
||||||
xed_debug (DEBUG_COMMANDS);
|
xed_debug (DEBUG_COMMANDS);
|
||||||
|
|
||||||
tab = xed_tab_get_from_document (document);
|
tab = xed_tab_get_from_document (document);
|
||||||
file_save (tab, window);
|
save_tab (tab, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* File revert */
|
/* File revert */
|
||||||
|
@ -1213,7 +1238,7 @@ save_and_close (XedTab *tab,
|
||||||
/* Trace tab state changes */
|
/* Trace tab state changes */
|
||||||
g_signal_connect (tab, "notify::state", G_CALLBACK (tab_state_changed_while_saving), window);
|
g_signal_connect (tab, "notify::state", G_CALLBACK (tab_state_changed_while_saving), window);
|
||||||
|
|
||||||
file_save (tab, window);
|
save_tab (tab, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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);
|
g_signal_connect (tab, "notify::state", G_CALLBACK (tab_state_changed_while_saving), window);
|
||||||
|
|
||||||
xed_window_set_active_tab (window, tab);
|
xed_window_set_active_tab (window, tab);
|
||||||
file_save_as (tab, window);
|
save_as_tab (tab, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -40,17 +40,19 @@
|
||||||
|
|
||||||
#include "xed-commands.h"
|
#include "xed-commands.h"
|
||||||
#include "xed-debug.h"
|
#include "xed-debug.h"
|
||||||
#include "xed-help.h"
|
#include "xed-app.h"
|
||||||
#include "xed-dirs.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_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[] = \
|
static const gchar comments[] = \
|
||||||
N_("A small and lightweight text editor");
|
N_("A small and lightweight text editor");
|
||||||
|
|
|
@ -25,14 +25,14 @@ void
|
||||||
_xed_cmd_search_find (GtkAction *action,
|
_xed_cmd_search_find (GtkAction *action,
|
||||||
XedWindow *window)
|
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
|
void
|
||||||
_xed_cmd_search_replace (GtkAction *action,
|
_xed_cmd_search_replace (GtkAction *action,
|
||||||
XedWindow *window)
|
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
|
void
|
||||||
|
|
|
@ -10,7 +10,7 @@ G_BEGIN_DECLS
|
||||||
void xed_commands_load_location (XedWindow *window, GFile *location, const GtkSourceEncoding *encoding, gint line_pos);
|
void xed_commands_load_location (XedWindow *window, GFile *location, const GtkSourceEncoding *encoding, gint line_pos);
|
||||||
|
|
||||||
/* Ignore non-existing URIs */
|
/* 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_document (XedWindow *window, XedDocument *document);
|
||||||
void xed_commands_save_all_documents (XedWindow *window);
|
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 */
|
/* 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_new (GtkAction *action, XedWindow *window);
|
||||||
void _xed_cmd_file_open (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 (GtkAction *action, XedWindow *window);
|
||||||
void _xed_cmd_file_save_as (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_save_all (GtkAction *action, XedWindow *window);
|
||||||
void _xed_cmd_file_revert (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_preview (GtkAction *action, XedWindow *window);
|
||||||
void _xed_cmd_file_print (GtkAction *action, XedWindow *window);
|
void _xed_cmd_file_print (GtkAction *action, XedWindow *window);
|
||||||
void _xed_cmd_file_close (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_close_tab (XedTab *tab, XedWindow *window);
|
||||||
|
|
||||||
void _xed_cmd_file_save_documents_list (XedWindow *window, GList *docs);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __XED_COMMANDS_H__ */
|
#endif /* __XED_COMMANDS_H__ */
|
||||||
|
|
130
xed/xed-dirs.c
130
xed/xed-dirs.c
|
@ -27,115 +27,115 @@
|
||||||
|
|
||||||
#include "xed-dirs.h"
|
#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)
|
xed_dirs_get_user_config_dir (void)
|
||||||
{
|
{
|
||||||
gchar* config_dir = NULL;
|
return user_config_dir;
|
||||||
|
|
||||||
config_dir = g_build_filename(g_get_user_config_dir(), "xed", NULL);
|
|
||||||
|
|
||||||
return config_dir;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gchar *
|
const gchar *
|
||||||
xed_dirs_get_user_cache_dir (void)
|
xed_dirs_get_user_cache_dir (void)
|
||||||
{
|
{
|
||||||
const gchar* cache_dir;
|
return user_cache_dir;
|
||||||
|
|
||||||
cache_dir = g_get_user_cache_dir();
|
|
||||||
|
|
||||||
return g_build_filename(cache_dir, "xed", NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gchar *
|
const gchar *
|
||||||
xed_dirs_get_user_styles_dir (void)
|
xed_dirs_get_user_styles_dir (void)
|
||||||
{
|
{
|
||||||
gchar *user_style_dir;
|
return user_styles_dir;
|
||||||
|
|
||||||
user_style_dir = g_build_filename (g_get_user_data_dir (), "xed", "styles", NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gchar *
|
const gchar *
|
||||||
xed_dirs_get_user_plugins_dir (void)
|
xed_dirs_get_user_plugins_dir (void)
|
||||||
{
|
{
|
||||||
gchar* plugin_dir;
|
return user_plugins_dir;
|
||||||
|
|
||||||
plugin_dir = g_build_filename(g_get_user_data_dir(), "xed", "plugins", NULL);
|
|
||||||
|
|
||||||
return plugin_dir;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gchar *
|
const 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 *
|
|
||||||
xed_dirs_get_xed_data_dir (void)
|
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)
|
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)
|
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)
|
xed_dirs_get_xed_plugins_dir (void)
|
||||||
{
|
{
|
||||||
gchar* lib_dir;
|
return xed_plugins_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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gchar *
|
const gchar *
|
||||||
xed_dirs_get_xed_plugins_data_dir (void)
|
xed_dirs_get_xed_plugins_data_dir (void)
|
||||||
{
|
{
|
||||||
gchar* data_dir;
|
return xed_plugins_data_dir;
|
||||||
gchar* plugin_data_dir;
|
}
|
||||||
|
|
||||||
data_dir = xed_dirs_get_xed_data_dir ();
|
const gchar *
|
||||||
|
xed_dirs_get_binding_modules_dir (void)
|
||||||
plugin_data_dir = g_build_filename (data_dir, "plugins", NULL);
|
{
|
||||||
g_free (data_dir);
|
return xed_lib_dir;
|
||||||
|
|
||||||
return plugin_data_dir;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gchar *
|
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 (xed_dirs_get_xed_data_dir (), "ui", file, NULL);
|
||||||
ui_file = g_build_filename(datadir, "ui", file, NULL);
|
|
||||||
g_free(datadir);
|
|
||||||
|
|
||||||
return ui_file;
|
return ui_file;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,25 +28,30 @@
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
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);
|
gchar *xed_dirs_get_ui_file (const gchar *file);
|
||||||
|
|
||||||
|
|
|
@ -510,6 +510,12 @@ save_encoding_metadata (XedDocument *doc)
|
||||||
xed_debug (DEBUG_DOCUMENT);
|
xed_debug (DEBUG_DOCUMENT);
|
||||||
|
|
||||||
encoding = gtk_source_file_get_encoding (doc->priv->file);
|
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);
|
charset = gtk_source_encoding_get_charset (encoding);
|
||||||
|
|
||||||
xed_document_set_metadata (doc, XED_METADATA_ATTRIBUTE_ENCODING, charset, NULL);
|
xed_document_set_metadata (doc, XED_METADATA_ATTRIBUTE_ENCODING, charset, NULL);
|
||||||
|
@ -954,8 +960,6 @@ loaded_query_info_cb (GFile *location,
|
||||||
XedDocument *doc)
|
XedDocument *doc)
|
||||||
{
|
{
|
||||||
GFileInfo *info;
|
GFileInfo *info;
|
||||||
const gchar *content_type = NULL;
|
|
||||||
gboolean read_only = FALSE;
|
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
info = g_file_query_info_finish (location, result, &error);
|
info = g_file_query_info_finish (location, result, &error);
|
||||||
|
@ -974,18 +978,22 @@ loaded_query_info_cb (GFile *location,
|
||||||
error = NULL;
|
error = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
doc->priv->mtime_set = FALSE;
|
|
||||||
|
|
||||||
if (info != NULL)
|
if (info != NULL)
|
||||||
{
|
{
|
||||||
if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE))
|
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);
|
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))
|
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);
|
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))
|
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);
|
g_file_info_get_modification_time (info, &doc->priv->mtime);
|
||||||
doc->priv->mtime_set = TRUE;
|
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);
|
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)
|
if (!doc->priv->language_set_by_user)
|
||||||
{
|
{
|
||||||
GtkSourceLanguage *language = guess_language (doc);
|
GtkSourceLanguage *language = guess_language (doc);
|
||||||
|
@ -1019,15 +1024,20 @@ loaded_query_info_cb (GFile *location,
|
||||||
set_language (doc, language, FALSE);
|
set_language (doc, language, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Async operation finished. */
|
doc->priv->mtime_set = FALSE;
|
||||||
g_object_unref (doc);
|
doc->priv->externally_modified = FALSE;
|
||||||
}
|
doc->priv->deleted = FALSE;
|
||||||
|
|
||||||
static void
|
g_get_current_time (&doc->priv->time_of_last_save_or_load);
|
||||||
xed_document_loaded_real (XedDocument *doc)
|
|
||||||
|
set_readonly (doc, FALSE);
|
||||||
|
|
||||||
|
xed_document_set_content_type (doc, NULL);
|
||||||
|
|
||||||
|
location = gtk_source_file_get_location (doc->priv->file);
|
||||||
|
|
||||||
|
if (location != NULL)
|
||||||
{
|
{
|
||||||
GFile *location = gtk_source_file_get_location (doc->priv->file);
|
|
||||||
|
|
||||||
/* Keep the doc alive during the async operation. */
|
/* Keep the doc alive during the async operation. */
|
||||||
g_object_ref (doc);
|
g_object_ref (doc);
|
||||||
|
|
||||||
|
@ -1041,6 +1051,7 @@ xed_document_loaded_real (XedDocument *doc)
|
||||||
(GAsyncReadyCallback) loaded_query_info_cb,
|
(GAsyncReadyCallback) loaded_query_info_cb,
|
||||||
doc);
|
doc);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
saved_query_info_cb (GFile *location,
|
saved_query_info_cb (GFile *location,
|
||||||
|
@ -1191,9 +1202,11 @@ check_file_on_disk (XedDocument *doc)
|
||||||
|
|
||||||
g_file_info_get_modification_time (info, &timeval);
|
g_file_info_get_modification_time (info, &timeval);
|
||||||
|
|
||||||
if (timeval.tv_sec > doc->priv->mtime.tv_sec ||
|
/* Note that mtime can even go backwards if the
|
||||||
(timeval.tv_sec == doc->priv->mtime.tv_sec &&
|
* user is copying over a file with an old mtime
|
||||||
timeval.tv_usec > doc->priv->mtime.tv_usec))
|
*/
|
||||||
|
if (timeval.tv_sec != doc->priv->mtime.tv_sec ||
|
||||||
|
timeval.tv_usec != doc->priv->mtime.tv_usec)
|
||||||
{
|
{
|
||||||
doc->priv->externally_modified = TRUE;
|
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.
|
* See the ChangeLog files for a list of changes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <libxml/xmlreader.h>
|
#include <libxml/xmlreader.h>
|
||||||
#include "xed-metadata-manager.h"
|
#include "xed-metadata-manager.h"
|
||||||
#include "xed-debug.h"
|
#include "xed-debug.h"
|
||||||
#include "xed-dirs.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define XED_METADATA_VERBOSE_DEBUG 1
|
#define XED_METADATA_VERBOSE_DEBUG 1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define METADATA_FILE "xed-metadata.xml"
|
|
||||||
|
|
||||||
#define MAX_ITEMS 50
|
#define MAX_ITEMS 50
|
||||||
|
|
||||||
typedef struct _XedMetadataManager XedMetadataManager;
|
typedef struct _XedMetadataManager XedMetadataManager;
|
||||||
|
@ -65,6 +58,8 @@ struct _XedMetadataManager
|
||||||
guint timeout_id;
|
guint timeout_id;
|
||||||
|
|
||||||
GHashTable *items;
|
GHashTable *items;
|
||||||
|
|
||||||
|
gchar *metadata_filename;
|
||||||
};
|
};
|
||||||
|
|
||||||
static gboolean xed_metadata_manager_save (gpointer data);
|
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);
|
xed_debug (DEBUG_METADATA);
|
||||||
|
|
||||||
if (xed_metadata_manager != NULL)
|
if (xed_metadata_manager != NULL)
|
||||||
return TRUE;
|
return;
|
||||||
|
|
||||||
xed_metadata_manager = g_new0 (XedMetadataManager, 1);
|
xed_metadata_manager = g_new0 (XedMetadataManager, 1);
|
||||||
|
|
||||||
|
@ -123,10 +125,17 @@ xed_metadata_manager_init (void)
|
||||||
g_free,
|
g_free,
|
||||||
item_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
|
void
|
||||||
xed_metadata_manager_shutdown (void)
|
xed_metadata_manager_shutdown (void)
|
||||||
{
|
{
|
||||||
|
@ -145,6 +154,7 @@ xed_metadata_manager_shutdown (void)
|
||||||
if (xed_metadata_manager->items != NULL)
|
if (xed_metadata_manager->items != NULL)
|
||||||
g_hash_table_destroy (xed_metadata_manager->items);
|
g_hash_table_destroy (xed_metadata_manager->items);
|
||||||
|
|
||||||
|
g_free (gedit_metadata_manager->metadata_filename);
|
||||||
g_free (xed_metadata_manager);
|
g_free (xed_metadata_manager);
|
||||||
xed_metadata_manager = NULL;
|
xed_metadata_manager = NULL;
|
||||||
}
|
}
|
||||||
|
@ -218,29 +228,11 @@ parseItem (xmlDocPtr doc, xmlNodePtr cur)
|
||||||
xmlFree (atime);
|
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
|
static gboolean
|
||||||
load_values (void)
|
load_values (void)
|
||||||
{
|
{
|
||||||
xmlDocPtr doc;
|
xmlDocPtr doc;
|
||||||
xmlNodePtr cur;
|
xmlNodePtr cur;
|
||||||
gchar *file_name;
|
|
||||||
|
|
||||||
xed_debug (DEBUG_METADATA);
|
xed_debug (DEBUG_METADATA);
|
||||||
|
|
||||||
|
@ -252,16 +244,13 @@ load_values (void)
|
||||||
xmlKeepBlanksDefault (0);
|
xmlKeepBlanksDefault (0);
|
||||||
|
|
||||||
/* FIXME: file locking - Paolo */
|
/* FIXME: file locking - Paolo */
|
||||||
file_name = get_metadata_filename ();
|
if ((xed_metadata_manager->metadata_filename == NULL) ||
|
||||||
if ((file_name == NULL) ||
|
(!g_file_test (xed_metadata_manager->metadata_filename, G_FILE_TEST_EXISTS)))
|
||||||
(!g_file_test (file_name, G_FILE_TEST_EXISTS)))
|
|
||||||
{
|
{
|
||||||
g_free (file_name);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
doc = xmlParseFile (file_name);
|
doc = xmlParseFile (xed_metadata_manager->metadata_filename);
|
||||||
g_free (file_name);
|
|
||||||
|
|
||||||
if (doc == NULL)
|
if (doc == NULL)
|
||||||
{
|
{
|
||||||
|
@ -271,7 +260,7 @@ load_values (void)
|
||||||
cur = xmlDocGetRootElement (doc);
|
cur = xmlDocGetRootElement (doc);
|
||||||
if (cur == NULL)
|
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);
|
xmlFreeDoc (doc);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -279,7 +268,7 @@ load_values (void)
|
||||||
|
|
||||||
if (xmlStrcmp (cur->name, (const xmlChar *) "metadata"))
|
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);
|
xmlFreeDoc (doc);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -300,6 +289,13 @@ load_values (void)
|
||||||
return TRUE;
|
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 *
|
gchar *
|
||||||
xed_metadata_manager_get (GFile *location,
|
xed_metadata_manager_get (GFile *location,
|
||||||
const gchar *key)
|
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_debug_message (DEBUG_METADATA, "URI: %s --- key: %s", uri, key );
|
||||||
|
|
||||||
xed_metadata_manager_init ();
|
|
||||||
|
|
||||||
if (!xed_metadata_manager->values_loaded)
|
if (!xed_metadata_manager->values_loaded)
|
||||||
{
|
{
|
||||||
gboolean res;
|
gboolean res;
|
||||||
|
@ -348,6 +342,14 @@ xed_metadata_manager_get (GFile *location,
|
||||||
return g_strdup (value);
|
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
|
void
|
||||||
xed_metadata_manager_set (GFile *location,
|
xed_metadata_manager_set (GFile *location,
|
||||||
const gchar *key,
|
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_debug_message (DEBUG_METADATA, "URI: %s --- key: %s --- value: %s", uri, key, value);
|
||||||
|
|
||||||
xed_metadata_manager_init ();
|
|
||||||
|
|
||||||
if (!xed_metadata_manager->values_loaded)
|
if (!xed_metadata_manager->values_loaded)
|
||||||
{
|
{
|
||||||
gboolean res;
|
gboolean res;
|
||||||
|
@ -523,7 +523,6 @@ xed_metadata_manager_save (gpointer data)
|
||||||
{
|
{
|
||||||
xmlDocPtr doc;
|
xmlDocPtr doc;
|
||||||
xmlNodePtr root;
|
xmlNodePtr root;
|
||||||
gchar *file_name;
|
|
||||||
|
|
||||||
xed_debug (DEBUG_METADATA);
|
xed_debug (DEBUG_METADATA);
|
||||||
|
|
||||||
|
@ -546,22 +545,20 @@ xed_metadata_manager_save (gpointer data)
|
||||||
root);
|
root);
|
||||||
|
|
||||||
/* FIXME: lock file - Paolo */
|
/* FIXME: lock file - Paolo */
|
||||||
file_name = get_metadata_filename ();
|
if (xed_metadata_manager->metadata_filename != NULL)
|
||||||
if (file_name != NULL)
|
|
||||||
{
|
{
|
||||||
gchar *cache_dir;
|
gchar *cache_dir;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
/* make sure the cache dir exists */
|
/* 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);
|
res = g_mkdir_with_parents (cache_dir, 0755);
|
||||||
if (res != -1)
|
if (res != -1)
|
||||||
{
|
{
|
||||||
xmlSaveFormatFile (file_name, doc, 1);
|
xmlSaveFormatFile (xed_metadata_manager->metadata_filename, doc, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (cache_dir);
|
g_free (cache_dir);
|
||||||
g_free (file_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xmlFreeDoc (doc);
|
xmlFreeDoc (doc);
|
||||||
|
|
|
@ -34,13 +34,14 @@
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
void xed_metadata_manager_init (const gchar *metadata_filename);
|
||||||
|
|
||||||
/* This function must be called before exiting xed */
|
/* This function must be called before exiting xed */
|
||||||
void xed_metadata_manager_shutdown (void);
|
void xed_metadata_manager_shutdown (void);
|
||||||
|
|
||||||
|
|
||||||
gchar *xed_metadata_manager_get (GFile *location,
|
gchar *xed_metadata_manager_get (GFile *location,
|
||||||
const gchar *key);
|
const gchar *key);
|
||||||
|
|
||||||
void xed_metadata_manager_set (GFile *location,
|
void xed_metadata_manager_set (GFile *location,
|
||||||
const gchar *key,
|
const gchar *key,
|
||||||
const gchar *value);
|
const gchar *value);
|
||||||
|
|
|
@ -54,7 +54,7 @@ struct _XedSearchbarPrivate
|
||||||
GtkWidget *close_button;
|
GtkWidget *close_button;
|
||||||
|
|
||||||
GtkSourceSearchSettings *search_settings;
|
GtkSourceSearchSettings *search_settings;
|
||||||
SearchMode search_mode;
|
XedSearchMode search_mode;
|
||||||
|
|
||||||
guint update_occurrence_count_id;
|
guint update_occurrence_count_id;
|
||||||
};
|
};
|
||||||
|
@ -280,7 +280,7 @@ update_occurrence_count (XedSearchbar *searchbar)
|
||||||
gint count;
|
gint count;
|
||||||
gint pos;
|
gint pos;
|
||||||
|
|
||||||
if (searchbar->priv->search_mode == SEARCH_MODE_REPLACE)
|
if (searchbar->priv->search_mode == XED_SEARCH_MODE_REPLACE)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -376,7 +376,7 @@ do_find (XedSearchbar *searchbar,
|
||||||
search_settings = xed_searchbar_get_search_settings (searchbar);
|
search_settings = xed_searchbar_get_search_settings (searchbar);
|
||||||
doc = xed_window_get_active_document (searchbar->window);
|
doc = xed_window_get_active_document (searchbar->window);
|
||||||
search_context = xed_document_get_search_context (doc);
|
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))
|
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);
|
unescaped_replace_text = gtk_source_utils_unescape_search_text (replace_entry_text);
|
||||||
gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (doc), &start, &end);
|
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,
|
gtk_source_search_context_replace (search_context,
|
||||||
&start,
|
&start,
|
||||||
|
@ -530,7 +530,7 @@ do_replace_all (XedSearchbar *searchbar)
|
||||||
|
|
||||||
unescaped_replace_text = gtk_source_utils_unescape_search_text (replace_entry_text);
|
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);
|
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);
|
g_free (unescaped_replace_text);
|
||||||
|
|
||||||
|
@ -800,7 +800,7 @@ xed_searchbar_new (GtkWindow *parent)
|
||||||
|
|
||||||
void
|
void
|
||||||
xed_searchbar_show (XedSearchbar *searchbar,
|
xed_searchbar_show (XedSearchbar *searchbar,
|
||||||
SearchMode search_mode)
|
XedSearchMode search_mode)
|
||||||
{
|
{
|
||||||
XedDocument *doc;
|
XedDocument *doc;
|
||||||
gboolean selection_exists;
|
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_transition_type (GTK_REVEALER (searchbar->priv->revealer), GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP);
|
||||||
gtk_revealer_set_reveal_child (GTK_REVEALER (searchbar->priv->revealer), TRUE);
|
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_label);
|
||||||
gtk_widget_show (searchbar->priv->replace_entry);
|
gtk_widget_show (searchbar->priv->replace_entry);
|
||||||
|
|
|
@ -39,16 +39,16 @@ struct _XedSearchbarClass
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
SEARCH_MODE_SEARCH,
|
XED_SEARCH_MODE_SEARCH,
|
||||||
SEARCH_MODE_REPLACE
|
XED_SEARCH_MODE_REPLACE
|
||||||
} SearchMode;
|
} XedSearchMode;
|
||||||
|
|
||||||
GType xed_searchbar_get_type (void) G_GNUC_CONST;
|
GType xed_searchbar_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
GtkWidget *xed_searchbar_new (GtkWindow *parent);
|
GtkWidget *xed_searchbar_new (GtkWindow *parent);
|
||||||
|
|
||||||
void xed_searchbar_hide (XedSearchbar *searchbar);
|
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);
|
void xed_searchbar_find_again (XedSearchbar *searchbar, gboolean backward);
|
||||||
|
|
||||||
const gchar *xed_searchbar_get_replace_text (XedSearchbar *searchbar);
|
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);
|
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))
|
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))
|
for (l = docs; l != NULL; l = g_list_next (l))
|
||||||
{
|
{
|
||||||
g_return_if_fail (GTK_SOURCE_IS_BUFFER (l->data));
|
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);
|
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))
|
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);
|
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))
|
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);
|
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))
|
for (l = views; l != NULL; l = g_list_next (l))
|
||||||
{
|
{
|
||||||
|
@ -293,13 +293,12 @@ on_syntax_highlighting_changed (GSettings *settings,
|
||||||
const gchar *key,
|
const gchar *key,
|
||||||
XedSettings *xs)
|
XedSettings *xs)
|
||||||
{
|
{
|
||||||
const GList *windows;
|
GList *docs, *windows, *l;
|
||||||
GList *docs, *l;
|
|
||||||
gboolean enable;
|
gboolean enable;
|
||||||
|
|
||||||
enable = g_settings_get_boolean (settings, key);
|
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))
|
for (l = docs; l != NULL; l = g_list_next (l))
|
||||||
{
|
{
|
||||||
|
@ -309,20 +308,20 @@ on_syntax_highlighting_changed (GSettings *settings,
|
||||||
g_list_free (docs);
|
g_list_free (docs);
|
||||||
|
|
||||||
/* update the sensitivity of the Higlight Mode menu item */
|
/* update the sensitivity of the Higlight Mode menu item */
|
||||||
windows = xed_app_get_windows (xed_app_get_default ());
|
windows = xed_app_get_main_windows (XED_APP (g_application_get_default ()));
|
||||||
while (windows != NULL)
|
for (l = windows; l != NULL; l = g_list_next (l))
|
||||||
{
|
{
|
||||||
GtkUIManager *ui;
|
GtkUIManager *ui;
|
||||||
GtkAction *a;
|
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");
|
a = gtk_ui_manager_get_action (ui, "/MenuBar/ViewMenu/ViewHighlightModeMenu");
|
||||||
|
|
||||||
gtk_action_set_sensitive (a, enable);
|
gtk_action_set_sensitive (a, enable);
|
||||||
|
|
||||||
windows = g_list_next (windows);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_list_free (windows);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -335,7 +334,7 @@ on_enable_tab_scrolling_changed (GSettings *settings,
|
||||||
|
|
||||||
enable = g_settings_get_boolean (settings, key);
|
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)
|
while (windows != NULL)
|
||||||
{
|
{
|
||||||
XedNotebook *notebook;
|
XedNotebook *notebook;
|
||||||
|
|
321
xed/xed-tab.c
321
xed/xed-tab.c
|
@ -64,7 +64,7 @@ struct _XedTabPrivate
|
||||||
|
|
||||||
XedPrintJob *print_job;
|
XedPrintJob *print_job;
|
||||||
|
|
||||||
GtkSourceFileSaver *saver;
|
GTask *task_saver;
|
||||||
GtkSourceFileSaverFlags save_flags;
|
GtkSourceFileSaverFlags save_flags;
|
||||||
|
|
||||||
/* tmp data for loading */
|
/* tmp data for loading */
|
||||||
|
@ -84,10 +84,20 @@ struct _XedTabPrivate
|
||||||
|
|
||||||
gint ask_if_externally_modified : 1;
|
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:
|
/* Notes about the create_backup saver flag:
|
||||||
* - At the beginning of a new file saving, force_no_backup is reset to
|
* - At the beginning of a new file saving, force_no_backup is FALSE.
|
||||||
* FALSE. The create_backup flag is set to the saver if it is enabled
|
* The create_backup flag is set to the saver if it is enabled in
|
||||||
* in GSettings and if it isn't an auto-save.
|
* GSettings and if it isn't an auto-save.
|
||||||
* - If creating the backup gives an error, and if the user wants to
|
* - 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
|
* save the file without the backup, force_no_backup is set to TRUE
|
||||||
* and the create_backup flag is removed from the saver.
|
* 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.
|
* button in the info bar to retry the file saving.
|
||||||
*/
|
*/
|
||||||
guint force_no_backup : 1;
|
guint force_no_backup : 1;
|
||||||
|
|
||||||
/*tmp data for loading */
|
|
||||||
guint user_requested_encoding : 1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE(XedTab, xed_tab, GTK_TYPE_BOX)
|
G_DEFINE_TYPE(XedTab, xed_tab, GTK_TYPE_BOX)
|
||||||
|
@ -127,6 +134,26 @@ static void load (XedTab *tab,
|
||||||
|
|
||||||
static void save (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
|
static void
|
||||||
install_auto_save_timeout (XedTab *tab)
|
install_auto_save_timeout (XedTab *tab)
|
||||||
{
|
{
|
||||||
|
@ -235,22 +262,15 @@ clear_loading (XedTab *tab)
|
||||||
g_clear_object (&tab->priv->cancellable);
|
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
|
static void
|
||||||
xed_tab_dispose (GObject *object)
|
xed_tab_dispose (GObject *object)
|
||||||
{
|
{
|
||||||
XedTab *tab = XED_TAB (object);
|
XedTab *tab = XED_TAB (object);
|
||||||
|
|
||||||
g_clear_object (&tab->priv->editor);
|
g_clear_object (&tab->priv->editor);
|
||||||
|
g_clear_object (&tab->priv->task_saver);
|
||||||
|
|
||||||
clear_loading (tab);
|
clear_loading (tab);
|
||||||
clear_saving (tab);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (xed_tab_parent_class)->dispose (object);
|
G_OBJECT_CLASS (xed_tab_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
@ -734,7 +754,7 @@ show_saving_message_area (XedTab *tab)
|
||||||
gchar *msg = NULL;
|
gchar *msg = NULL;
|
||||||
gint len;
|
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)
|
if (tab->priv->message_area != NULL)
|
||||||
{
|
{
|
||||||
|
@ -761,7 +781,11 @@ show_saving_message_area (XedTab *tab)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gchar *str;
|
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;
|
from = short_name;
|
||||||
to = g_file_get_parse_name (location);
|
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);
|
xed_tab_set_state (tab, XED_TAB_STATE_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
clear_saving (tab);
|
|
||||||
|
|
||||||
set_message_area (tab, NULL);
|
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);
|
view = xed_tab_get_view (tab);
|
||||||
|
|
||||||
gtk_widget_grab_focus (GTK_WIDGET (view));
|
gtk_widget_grab_focus (GTK_WIDGET (view));
|
||||||
|
@ -872,8 +897,11 @@ static void
|
||||||
response_set_save_flags (XedTab *tab,
|
response_set_save_flags (XedTab *tab,
|
||||||
GtkSourceFileSaverFlags save_flags)
|
GtkSourceFileSaverFlags save_flags)
|
||||||
{
|
{
|
||||||
|
SaverData *data;
|
||||||
gboolean create_backup;
|
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);
|
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
|
/* 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
|
* the file saving was initially an auto-save, we set the create_backup
|
||||||
* flag (if the conditions are met).
|
* 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;
|
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;
|
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
|
static void
|
||||||
|
@ -900,16 +928,18 @@ invalid_character_message_area_response (GtkWidget *info_bar,
|
||||||
{
|
{
|
||||||
if (response_id == GTK_RESPONSE_YES)
|
if (response_id == GTK_RESPONSE_YES)
|
||||||
{
|
{
|
||||||
|
SaverData *data;
|
||||||
GtkSourceFileSaverFlags save_flags;
|
GtkSourceFileSaverFlags save_flags;
|
||||||
|
|
||||||
set_message_area (tab, NULL);
|
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... */
|
/* Don't bug the user again with this... */
|
||||||
tab->priv->save_flags |= GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_INVALID_CHARS;
|
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;
|
save_flags |= GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_INVALID_CHARS;
|
||||||
response_set_save_flags (tab, save_flags);
|
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)
|
if (response_id == GTK_RESPONSE_YES)
|
||||||
{
|
{
|
||||||
|
SaverData *data;
|
||||||
GtkSourceFileSaverFlags save_flags;
|
GtkSourceFileSaverFlags save_flags;
|
||||||
|
|
||||||
set_message_area (tab, NULL);
|
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;
|
data->force_no_backup = TRUE;
|
||||||
save_flags = gtk_source_file_saver_get_flags (tab->priv->saver);
|
save_flags = gtk_source_file_saver_get_flags (data->saver);
|
||||||
response_set_save_flags (tab, save_flags);
|
response_set_save_flags (tab, save_flags);
|
||||||
|
|
||||||
/* Force saving */
|
/* Force saving */
|
||||||
|
@ -955,17 +987,19 @@ externally_modified_error_message_area_response (GtkWidget *message_area,
|
||||||
{
|
{
|
||||||
if (response_id == GTK_RESPONSE_YES)
|
if (response_id == GTK_RESPONSE_YES)
|
||||||
{
|
{
|
||||||
|
SaverData *data;
|
||||||
GtkSourceFileSaverFlags save_flags;
|
GtkSourceFileSaverFlags save_flags;
|
||||||
|
|
||||||
set_message_area (tab, NULL);
|
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
|
/* ignore_modification_time should not be persisted in save
|
||||||
* flags across saves (i.e. priv->save_flags is not modified).
|
* 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;
|
save_flags |= GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_MODIFICATION_TIME;
|
||||||
response_set_save_flags (tab, save_flags);
|
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)
|
if (response_id == GTK_RESPONSE_OK)
|
||||||
{
|
{
|
||||||
|
SaverData *data;
|
||||||
const GtkSourceEncoding *encoding;
|
const GtkSourceEncoding *encoding;
|
||||||
|
|
||||||
set_message_area (tab, NULL);
|
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));
|
encoding = xed_conversion_error_message_area_get_encoding (GTK_WIDGET (message_area));
|
||||||
g_return_if_fail (encoding != NULL);
|
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);
|
save (tab);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1175,6 +1211,22 @@ _xed_tab_new_from_location (GFile *location,
|
||||||
return GTK_WIDGET (tab);
|
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:
|
* xed_tab_get_view:
|
||||||
* @tab: a #XedTab
|
* @tab: a #XedTab
|
||||||
|
@ -1317,12 +1369,10 @@ _xed_tab_get_tooltips (XedTab *tab)
|
||||||
|
|
||||||
if (enc == NULL)
|
if (enc == NULL)
|
||||||
{
|
{
|
||||||
encoding = g_strdup (_("Unicode (UTF-8)"));
|
enc = gtk_source_encoding_get_utf8 ();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
encoding = gtk_source_encoding_to_string (enc);
|
encoding = gtk_source_encoding_to_string (enc);
|
||||||
}
|
|
||||||
|
|
||||||
tip = g_markup_printf_escaped ("<b>%s</b> %s\n\n"
|
tip = g_markup_printf_escaped ("<b>%s</b> %s\n\n"
|
||||||
"<b>%s</b> %s\n"
|
"<b>%s</b> %s\n"
|
||||||
|
@ -1574,6 +1624,7 @@ load_cb (GtkSourceFileLoader *loader,
|
||||||
{
|
{
|
||||||
XedDocument *doc = xed_tab_get_document (tab);
|
XedDocument *doc = xed_tab_get_document (tab);
|
||||||
GFile *location = gtk_source_file_loader_get_location (loader);
|
GFile *location = gtk_source_file_loader_get_location (loader);
|
||||||
|
gboolean create_named_new_doc;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
g_return_if_fail (tab->priv->state == XED_TAB_STATE_LOADING ||
|
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. */
|
/* 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->domain == G_IO_ERROR &&
|
||||||
error->code == G_IO_ERROR_NOT_FOUND &&
|
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);
|
g_error_free (error);
|
||||||
error = NULL;
|
error = NULL;
|
||||||
|
@ -1676,7 +1730,7 @@ load_cb (GtkSourceFileLoader *loader,
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (location != NULL)
|
if (location != NULL && !create_named_new_doc)
|
||||||
{
|
{
|
||||||
gchar *mime = xed_document_get_mime_type (doc);
|
gchar *mime = xed_document_get_mime_type (doc);
|
||||||
|
|
||||||
|
@ -1725,7 +1779,7 @@ load_cb (GtkSourceFileLoader *loader,
|
||||||
GList *all_documents;
|
GList *all_documents;
|
||||||
GList *l;
|
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))
|
for (l = all_documents; l != NULL; l = g_list_next (l))
|
||||||
{
|
{
|
||||||
|
@ -1793,6 +1847,8 @@ get_candidate_encodings (XedTab *tab)
|
||||||
GSettings *enc_settings;
|
GSettings *enc_settings;
|
||||||
gchar **enc_strv;
|
gchar **enc_strv;
|
||||||
gchar *metadata_charset;
|
gchar *metadata_charset;
|
||||||
|
GtkSourceFile *file;
|
||||||
|
const GtkSourceEncoding *file_encoding;
|
||||||
GSList *encodings;
|
GSList *encodings;
|
||||||
|
|
||||||
enc_settings = g_settings_new ("org.x.editor.preferences.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);
|
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_object_unref (enc_settings);
|
||||||
|
g_strfreev (enc_strv);
|
||||||
|
g_free (metadata_charset);
|
||||||
|
|
||||||
return encodings;
|
return encodings;
|
||||||
}
|
}
|
||||||
|
@ -1902,6 +1965,39 @@ _xed_tab_load (XedTab *tab,
|
||||||
load (tab, encoding, line_pos);
|
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
|
void
|
||||||
_xed_tab_revert (XedTab *tab)
|
_xed_tab_revert (XedTab *tab)
|
||||||
{
|
{
|
||||||
|
@ -1977,7 +2073,7 @@ save_cb (GtkSourceFileSaver *saver,
|
||||||
GFile *location = gtk_source_file_saver_get_location (saver);
|
GFile *location = gtk_source_file_saver_get_location (saver);
|
||||||
GError *error = NULL;
|
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);
|
gtk_source_file_saver_save_finish (saver, result, &error);
|
||||||
|
|
||||||
|
@ -2084,14 +2180,10 @@ save_cb (GtkSourceFileSaver *saver,
|
||||||
|
|
||||||
tab->priv->ask_if_externally_modified = TRUE;
|
tab->priv->ask_if_externally_modified = TRUE;
|
||||||
|
|
||||||
clear_saving (tab);
|
|
||||||
|
|
||||||
g_signal_emit_by_name (doc, "saved");
|
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)
|
if (error != NULL)
|
||||||
{
|
{
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
|
@ -2102,20 +2194,20 @@ static void
|
||||||
save (XedTab *tab)
|
save (XedTab *tab)
|
||||||
{
|
{
|
||||||
XedDocument *doc;
|
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);
|
xed_tab_set_state (tab, XED_TAB_STATE_SAVING);
|
||||||
|
|
||||||
doc = xed_tab_get_document (tab);
|
doc = xed_tab_get_document (tab);
|
||||||
g_signal_emit_by_name (doc, "save");
|
g_signal_emit_by_name (doc, "save");
|
||||||
|
|
||||||
/* Keep the tab alive during the async operation. */
|
data = g_task_get_task_data (tab->priv->task_saver);
|
||||||
g_object_ref (tab);
|
|
||||||
|
|
||||||
gtk_source_file_saver_save_async (tab->priv->saver,
|
gtk_source_file_saver_save_async (data->saver,
|
||||||
G_PRIORITY_DEFAULT,
|
G_PRIORITY_DEFAULT,
|
||||||
NULL, /* TODO add a cancellable */
|
g_task_get_cancellable (tab->priv->task_saver),
|
||||||
(GFileProgressCallback) saver_progress_cb,
|
(GFileProgressCallback) saver_progress_cb,
|
||||||
tab,
|
tab,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -2133,9 +2225,6 @@ get_initial_save_flags (XedTab *tab,
|
||||||
|
|
||||||
save_flags = tab->priv->save_flags;
|
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);
|
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
|
/* In case of autosaving, we need to preserve the backup that was produced
|
||||||
|
@ -2151,8 +2240,12 @@ get_initial_save_flags (XedTab *tab,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_xed_tab_save (XedTab *tab)
|
_xed_tab_save_async (XedTab *tab,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
|
SaverData *data;
|
||||||
XedDocument *doc;
|
XedDocument *doc;
|
||||||
GtkSourceFile *file;
|
GtkSourceFile *file;
|
||||||
GtkSourceFileSaverFlags save_flags;
|
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_EXTERNALLY_MODIFIED_NOTIFICATION) ||
|
||||||
(tab->priv->state == XED_TAB_STATE_SHOWING_PRINT_PREVIEW));
|
(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_warning ("XedTab: file saver already exists.");
|
||||||
g_object_unref (tab->priv->saver);
|
return;
|
||||||
tab->priv->saver = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clear_saving (tab);
|
|
||||||
|
|
||||||
doc = xed_tab_get_document (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));
|
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);
|
save_flags = get_initial_save_flags (tab, FALSE);
|
||||||
|
|
||||||
if (tab->priv->state == XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION)
|
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);
|
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);
|
||||||
gtk_source_file_saver_set_flags (tab->priv->saver, save_flags);
|
gtk_source_file_saver_set_flags (data->saver, save_flags);
|
||||||
|
|
||||||
save (tab);
|
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
|
static gboolean
|
||||||
xed_tab_auto_save (XedTab *tab)
|
xed_tab_auto_save (XedTab *tab)
|
||||||
{
|
{
|
||||||
|
SaverData *data;
|
||||||
XedDocument *doc;
|
XedDocument *doc;
|
||||||
GtkSourceFile *file;
|
GtkSourceFile *file;
|
||||||
GtkSourceFileSaverFlags save_flags;
|
GtkSourceFileSaverFlags save_flags;
|
||||||
|
@ -2205,9 +2326,8 @@ xed_tab_auto_save (XedTab *tab)
|
||||||
xed_debug (DEBUG_TAB);
|
xed_debug (DEBUG_TAB);
|
||||||
|
|
||||||
doc = xed_tab_get_document (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_is_untitled (doc), FALSE);
|
g_return_val_if_fail (!xed_document_get_readonly (doc), G_SOURCE_REMOVE);
|
||||||
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)))
|
||||||
{
|
{
|
||||||
|
@ -2229,37 +2349,50 @@ xed_tab_auto_save (XedTab *tab)
|
||||||
/* Set auto_save_timeout to 0 since the timeout is going to be destroyed */
|
/* Set auto_save_timeout to 0 since the timeout is going to be destroyed */
|
||||||
tab->priv->auto_save_timeout = 0;
|
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_warning ("XedTab: file saver already exists.");
|
||||||
g_object_unref (tab->priv->saver);
|
return G_SOURCE_REMOVE;
|
||||||
tab->priv->saver = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
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);
|
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);
|
save (tab);
|
||||||
|
|
||||||
return G_SOURCE_REMOVE;
|
return G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Call _xed_tab_save_finish() in @callback, there is no
|
||||||
|
* _xed_tab_save_as_finish().
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
_xed_tab_save_as (XedTab *tab,
|
_xed_tab_save_as_async (XedTab *tab,
|
||||||
GFile *location,
|
GFile *location,
|
||||||
const GtkSourceEncoding *encoding,
|
const GtkSourceEncoding *encoding,
|
||||||
GtkSourceNewlineType newline_type)
|
GtkSourceNewlineType newline_type,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
|
SaverData *data;
|
||||||
XedDocument *doc;
|
XedDocument *doc;
|
||||||
GtkSourceFile *file;
|
GtkSourceFile *file;
|
||||||
GtkSourceFileSaverFlags save_flags;
|
GtkSourceFileSaverFlags save_flags;
|
||||||
GFile *prev_location;
|
|
||||||
|
|
||||||
g_return_if_fail (XED_IS_TAB (tab));
|
g_return_if_fail (XED_IS_TAB (tab));
|
||||||
g_return_if_fail ((tab->priv->state == XED_TAB_STATE_NORMAL) ||
|
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 (G_IS_FILE (location));
|
||||||
g_return_if_fail (encoding != NULL);
|
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_warning ("XedTab: file saver already exists.");
|
||||||
g_object_unref (tab->priv->saver);
|
return;
|
||||||
tab->priv->saver = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
doc = xed_tab_get_document (tab);
|
||||||
g_return_if_fail (XED_IS_DOCUMENT (doc));
|
g_return_if_fail (XED_IS_DOCUMENT (doc));
|
||||||
|
@ -2295,20 +2432,12 @@ _xed_tab_save_as (XedTab *tab,
|
||||||
}
|
}
|
||||||
|
|
||||||
file = xed_document_get_file (doc);
|
file = xed_document_get_file (doc);
|
||||||
prev_location = gtk_source_file_get_location (file);
|
|
||||||
|
|
||||||
if (prev_location == NULL || !g_file_equal (prev_location, location))
|
data->saver = gtk_source_file_saver_new_with_target (GTK_SOURCE_BUFFER (doc), file, 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
tab->priv->saver = gtk_source_file_saver_new_with_target (GTK_SOURCE_BUFFER (doc), file, location);
|
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_encoding (tab->priv->saver, encoding);
|
gtk_source_file_saver_set_flags (data->saver, save_flags);
|
||||||
gtk_source_file_saver_set_newline_type (tab->priv->saver, newline_type);
|
|
||||||
gtk_source_file_saver_set_flags (tab->priv->saver, save_flags);
|
|
||||||
|
|
||||||
save (tab);
|
save (tab);
|
||||||
}
|
}
|
||||||
|
@ -2327,7 +2456,7 @@ get_page_setup (XedTab *tab)
|
||||||
|
|
||||||
if (data == NULL)
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -2349,7 +2478,7 @@ get_print_settings (XedTab *tab)
|
||||||
|
|
||||||
if (data == NULL)
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -2407,7 +2536,7 @@ store_print_settings (XedTab *tab,
|
||||||
g_object_ref (settings), (GDestroyNotify)g_object_unref);
|
g_object_ref (settings), (GDestroyNotify)g_object_unref);
|
||||||
|
|
||||||
/* make them the default */
|
/* 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);
|
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);
|
g_object_ref (page_setup), (GDestroyNotify)g_object_unref);
|
||||||
|
|
||||||
/* make it the default */
|
/* 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
|
static void
|
||||||
|
|
|
@ -112,20 +112,46 @@ GtkWidget *_xed_tab_new_from_location (GFile *location,
|
||||||
const GtkSourceEncoding *encoding,
|
const GtkSourceEncoding *encoding,
|
||||||
gint line_pos,
|
gint line_pos,
|
||||||
gboolean create);
|
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_name (XedTab *tab);
|
||||||
|
|
||||||
gchar *_xed_tab_get_tooltips (XedTab *tab);
|
gchar *_xed_tab_get_tooltips (XedTab *tab);
|
||||||
|
|
||||||
GdkPixbuf *_xed_tab_get_icon (XedTab *tab);
|
GdkPixbuf *_xed_tab_get_icon (XedTab *tab);
|
||||||
|
|
||||||
void _xed_tab_load (XedTab *tab,
|
void _xed_tab_load (XedTab *tab,
|
||||||
GFile *location,
|
GFile *location,
|
||||||
const GtkSourceEncoding *encoding,
|
const GtkSourceEncoding *encoding,
|
||||||
gint line_pos,
|
gint line_pos,
|
||||||
gboolean create);
|
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_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,
|
GFile *location,
|
||||||
const GtkSourceEncoding *encoding,
|
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 (XedTab *tab);
|
||||||
void _xed_tab_print_preview (XedTab *tab);
|
void _xed_tab_print_preview (XedTab *tab);
|
||||||
|
|
|
@ -771,7 +771,7 @@ xed_view_set_font (XedView *view,
|
||||||
GObject *settings;
|
GObject *settings;
|
||||||
gchar *font;
|
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 = xed_settings_get_system_font (XED_SETTINGS (settings));
|
||||||
font_desc = pango_font_description_from_string (font);
|
font_desc = pango_font_description_from_string (font);
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ enum
|
||||||
TARGET_URI_LIST = 100
|
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);
|
static void recent_manager_changed (GtkRecentManager *manager, XedWindow *window);
|
||||||
|
|
||||||
|
@ -983,15 +983,19 @@ open_recent_file (GFile *location,
|
||||||
XedWindow *window)
|
XedWindow *window)
|
||||||
{
|
{
|
||||||
GSList *locations = NULL;
|
GSList *locations = NULL;
|
||||||
|
GSList *loaded = NULL;
|
||||||
|
|
||||||
locations = g_slist_prepend (locations, (gpointer) location);
|
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);
|
_xed_recent_remove (window, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_slist_free (locations);
|
g_slist_free (locations);
|
||||||
|
g_slist_free (loaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1803,7 +1807,7 @@ clone_window (XedWindow *origin)
|
||||||
|
|
||||||
xed_debug (DEBUG_WINDOW);
|
xed_debug (DEBUG_WINDOW);
|
||||||
|
|
||||||
app = xed_app_get_default ();
|
app = XED_APP (g_application_get_default ());
|
||||||
|
|
||||||
screen = gtk_window_get_screen (GTK_WINDOW(origin));
|
screen = gtk_window_get_screen (GTK_WINDOW(origin));
|
||||||
window = xed_app_create_window (app, screen);
|
window = xed_app_create_window (app, screen);
|
||||||
|
@ -1940,7 +1944,7 @@ set_title (XedWindow *window)
|
||||||
|
|
||||||
if (window->priv->active_tab == NULL)
|
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;
|
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 (dirname);
|
||||||
g_free (name);
|
g_free (name);
|
||||||
|
@ -2486,6 +2490,7 @@ load_uris_from_drop (XedWindow *window,
|
||||||
{
|
{
|
||||||
GSList *locations = NULL;
|
GSList *locations = NULL;
|
||||||
gint i;
|
gint i;
|
||||||
|
GSList *loaded;
|
||||||
|
|
||||||
if (uri_list == NULL)
|
if (uri_list == NULL)
|
||||||
{
|
{
|
||||||
|
@ -2498,7 +2503,9 @@ load_uris_from_drop (XedWindow *window,
|
||||||
}
|
}
|
||||||
|
|
||||||
locations = g_slist_reverse (locations);
|
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_foreach (locations, (GFunc) g_object_unref, NULL);
|
||||||
g_slist_free (locations);
|
g_slist_free (locations);
|
||||||
|
@ -2704,7 +2711,7 @@ fullscreen_controls_build (XedWindow *window)
|
||||||
|
|
||||||
priv->fullscreen_controls = gtk_window_new (GTK_WINDOW_POPUP);
|
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);
|
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);
|
gtk_container_set_border_width (GTK_CONTAINER (window->priv->fullscreen_controls_container), 6);
|
||||||
|
@ -3705,6 +3712,28 @@ xed_window_create_tab (XedWindow *window,
|
||||||
return tab;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xed_window_create_tab_from_location:
|
* xed_window_create_tab_from_location:
|
||||||
* @window: a #XedWindow
|
* @window: a #XedWindow
|
||||||
|
@ -3735,21 +3764,25 @@ xed_window_create_tab_from_location (XedWindow *window,
|
||||||
g_return_val_if_fail(G_IS_FILE (location), NULL);
|
g_return_val_if_fail(G_IS_FILE (location), NULL);
|
||||||
|
|
||||||
tab = _xed_tab_new_from_location (location, encoding, line_pos, create);
|
tab = _xed_tab_new_from_location (location, encoding, line_pos, create);
|
||||||
if (tab == NULL)
|
|
||||||
{
|
return process_create_tab (window, XED_TAB (tab), jump_to);
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_widget_show (tab);
|
XedTab *
|
||||||
|
xed_window_create_tab_from_stream (XedWindow *window,
|
||||||
xed_notebook_add_tab (XED_NOTEBOOK(window->priv->notebook), XED_TAB(tab), -1, jump_to);
|
GInputStream *stream,
|
||||||
|
const GtkSourceEncoding *encoding,
|
||||||
if (!gtk_widget_get_visible (GTK_WIDGET(window)))
|
gint line_pos,
|
||||||
|
gboolean jump_to)
|
||||||
{
|
{
|
||||||
gtk_window_present (GTK_WINDOW(window));
|
GtkWidget *tab;
|
||||||
}
|
|
||||||
|
|
||||||
return XED_TAB(tab);
|
g_return_val_if_fail (XED_IS_WINDOW (window), NULL);
|
||||||
|
g_return_val_if_fail (G_IS_INPUT_STREAM (stream), NULL);
|
||||||
|
|
||||||
|
tab = _xed_tab_new_from_stream (stream, encoding, line_pos);
|
||||||
|
|
||||||
|
return process_create_tab (window, XED_TAB (tab), jump_to);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4175,7 +4208,7 @@ _xed_window_fullscreen (XedWindow *window)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Go to fullscreen mode and hide bars */
|
/* 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);
|
gtk_widget_hide (window->priv->menubar);
|
||||||
|
|
||||||
|
@ -4203,7 +4236,7 @@ _xed_window_unfullscreen (XedWindow *window)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unfullscreen and show bars */
|
/* 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);
|
g_signal_handlers_disconnect_by_func (window->priv->notebook, hide_notebook_tabs_on_fullscreen, window);
|
||||||
gtk_widget_show (window->priv->menubar);
|
gtk_widget_show (window->priv->menubar);
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ typedef struct _XedWindowClass XedWindowClass;
|
||||||
|
|
||||||
struct _XedWindow
|
struct _XedWindow
|
||||||
{
|
{
|
||||||
GtkWindow window;
|
GtkApplicationWindow window;
|
||||||
|
|
||||||
/*< private > */
|
/*< private > */
|
||||||
XedWindowPrivate *priv;
|
XedWindowPrivate *priv;
|
||||||
|
@ -40,7 +40,7 @@ struct _XedWindow
|
||||||
|
|
||||||
struct _XedWindowClass
|
struct _XedWindowClass
|
||||||
{
|
{
|
||||||
GtkWindowClass parent_class;
|
GtkApplicationWindowClass parent_class;
|
||||||
|
|
||||||
/* Signals */
|
/* Signals */
|
||||||
void (* tab_added) (XedWindow *window, XedTab *tab);
|
void (* tab_added) (XedWindow *window, XedTab *tab);
|
||||||
|
@ -50,13 +50,13 @@ struct _XedWindowClass
|
||||||
void (* active_tab_state_changed) (XedWindow *window);
|
void (* active_tab_state_changed) (XedWindow *window);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/* Public methods */
|
||||||
* Public methods
|
|
||||||
*/
|
|
||||||
GType xed_window_get_type (void) G_GNUC_CONST;
|
GType xed_window_get_type (void) G_GNUC_CONST;
|
||||||
XedTab *xed_window_create_tab (XedWindow *window, gboolean jump_to);
|
XedTab *xed_window_create_tab (XedWindow *window, gboolean jump_to);
|
||||||
XedTab *xed_window_create_tab_from_location (XedWindow *window, GFile *location, const GtkSourceEncoding *encoding,
|
XedTab *xed_window_create_tab_from_location (XedWindow *window, GFile *location, const GtkSourceEncoding *encoding,
|
||||||
gint line_pos, gboolean create, gboolean jump_to);
|
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_tab (XedWindow *window, XedTab *tab);
|
||||||
void xed_window_close_all_tabs (XedWindow *window);
|
void xed_window_close_all_tabs (XedWindow *window);
|
||||||
void xed_window_close_tabs (XedWindow *window, const GList *tabs);
|
void xed_window_close_tabs (XedWindow *window, const GList *tabs);
|
||||||
|
|
626
xed/xed.c
626
xed/xed.c
|
@ -32,631 +32,25 @@
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <locale.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <glib.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-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
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
GOptionContext *context;
|
|
||||||
XedPluginsEngine *engine;
|
|
||||||
XedWindow *window;
|
|
||||||
XedApp *app;
|
XedApp *app;
|
||||||
gboolean restored = FALSE;
|
gint status;
|
||||||
GError *error = NULL;
|
|
||||||
gchar *dir;
|
|
||||||
gchar *icon_dir;
|
|
||||||
|
|
||||||
|
app = g_object_new (XED_TYPE_APP,
|
||||||
/* Setup debugging */
|
"application-id", "org.x.editor",
|
||||||
xed_debug_init ();
|
"flags", G_APPLICATION_HANDLES_COMMAND_LINE,
|
||||||
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,
|
|
||||||
NULL);
|
NULL);
|
||||||
}
|
|
||||||
}
|
status = g_application_run (G_APPLICATION (app), argc, argv);
|
||||||
else
|
|
||||||
{
|
g_object_unref (app);
|
||||||
g_warning ("Cannot create the 'xed' connection.");
|
|
||||||
}
|
return status;
|
||||||
|
|
||||||
xed_debug_message (DEBUG_APP, "Set icon");
|
|
||||||
|
|
||||||
dir = xed_dirs_get_xed_data_dir ();
|
|
||||||
icon_dir = g_build_filename (dir,
|
|
||||||
"icons",
|
|
||||||
NULL);
|
|
||||||
g_free (dir);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue