This repository has been archived on 2020-04-11. You can view files and clone it, but cannot push or open issues or pull requests.
gnoemoe/gnoemoe/widgets/gm-external-view.c

139 lines
3.3 KiB
C
Raw Normal View History

2005-11-19 14:02:36 +01:00
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <libgnome/libgnome.h>
#include <stdlib.h>
#include "gm-external-view.h"
#include "../gm-debug.h"
#include "../gm-app.h"
#include "../gm-options.h"
void on_gm_external_view_exited(GPid pid, gint status, GmExternalView *view);
void on_gm_external_view_file_changed(GnomeVFSMonitorHandle *handle,
const gchar *monitor_uri, const gchar *info_uri,
GnomeVFSMonitorEventType event_type, GmExternalView *view);
void
gm_external_view_destroy(GmExternalView *view) {
struct stat buf;
if (view->monitor) {
gnome_vfs_monitor_cancel(view->monitor);
}
g_source_remove(view->child_watch);
g_spawn_close_pid(view->pid);
if (GM_IS_EDITOR(view->editor)) {
if (stat(view->filename, &buf) != -1) {
if (buf.st_mtime > view->last_modified) {
gm_editor_save(view->editor);
}
}
}
if (view->filename) {
unlink(view->filename);
g_free(view->filename);
}
}
void
gm_external_view_update_last_modified(GmExternalView *view) {
struct stat buf;
if (stat(view->filename, &buf) != -1) {
view->last_modified = buf.st_mtime;
}
}
gboolean
gm_external_view_spawn(GmExternalView *view, gchar **argv) {
GError *err = NULL;
g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH |
G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &(view->pid), &err);
if (err) {
gm_debug_msg(DEBUG_DEFAULT, "GmExternalView.Spawn: couldn't spawn "
"editor: %s", err->message);
g_error_free(err);
return FALSE;
} else {
return TRUE;
}
}
GmExternalView *
gm_external_view_new(GmWorld *world, GmEditor *editor) {
GmExternalView *obj = g_new0(GmExternalView, 1);
gchar *spawn_command[4] = {NULL, NULL, NULL, NULL};
gchar **av, *command;
gint an;
GmOptions *options = gm_app_options(gm_app_instance());
obj->world = world;
obj->editor = editor;
obj->filename = gm_editor_write_lines(editor);
gm_external_view_update_last_modified(obj);
gnome_vfs_monitor_add(&(obj->monitor), obj->filename,
GNOME_VFS_MONITOR_FILE,
(GnomeVFSMonitorCallback)on_gm_external_view_file_changed, obj);
command = g_strconcat(gm_options_get(options, "editor_alternative"),
" ", obj->filename, NULL);
if (gm_options_get_int(options, "editor_needs_terminal")) {
spawn_command[0] = getenv("TERM");
if (spawn_command[0] == NULL) {
spawn_command[0] = "xterm";
}
spawn_command[1] = "-e";
spawn_command[2] = command;
gm_external_view_spawn(obj, spawn_command);
} else {
g_shell_parse_argv(command, &an, &av, NULL);
gm_external_view_spawn(obj, av);
}
g_free(command);
obj->child_watch = g_child_watch_add(obj->pid,
(GChildWatchFunc)on_gm_external_view_exited, obj);
return obj;
}
/* Callbacks */
void
on_gm_external_view_exited(GPid pid, gint status, GmExternalView *view) {
gm_editor_close(view->editor);
}
void
on_gm_external_view_file_changed(GnomeVFSMonitorHandle *handle,
const gchar *monitor_uri, const gchar *info_uri,
GnomeVFSMonitorEventType event_type, GmExternalView *view) {
switch (event_type) {
case GNOME_VFS_MONITOR_EVENT_CHANGED:
case GNOME_VFS_MONITOR_EVENT_CREATED:
gm_debug_msg(DEBUG_DEFAULT, "GmExternalView.OnFileChanged: "
"change event detected!");
gm_editor_set_lines_from_file(view->editor,
view->filename);
gm_editor_save(view->editor);
gm_external_view_update_last_modified(view);
break;
default:
break;
}
}