207 lines
5.6 KiB
C
207 lines
5.6 KiB
C
#include <vte/vte.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
#include <libgnomevfs/gnome-vfs.h>
|
|
#include <libgnome/libgnome.h>
|
|
#include "gm-embedded-view.h"
|
|
#include "../gm-app.h"
|
|
#include "../gm-color-table.h"
|
|
#include "../gm-options.h"
|
|
#include "../gm-debug.h"
|
|
|
|
#define GM_EMBEDDED_VIEW_GET_PRIVATE(object)( \
|
|
G_TYPE_INSTANCE_GET_PRIVATE((object), \
|
|
GM_TYPE_EMBEDDED_VIEW, GmEmbeddedViewPrivate))
|
|
|
|
struct _GmEmbeddedViewPrivate {
|
|
GmWorld *world;
|
|
GmEditor *editor;
|
|
|
|
VteTerminal *vte;
|
|
gchar *filename;
|
|
GnomeVFSMonitorHandle *monitor;
|
|
time_t last_modified;
|
|
};
|
|
|
|
/* Signals
|
|
|
|
enum {
|
|
PROTO
|
|
NUM_SIGNALS
|
|
};
|
|
|
|
static guint gm_embedded_view_signals[NUM_SIGNALS] = {0};*/
|
|
|
|
void on_gm_embedded_view_exited(VteTerminal *vte, GmEmbeddedView *embedded);
|
|
void on_gm_embedded_view_file_changed(GnomeVFSMonitorHandle *handle,
|
|
const gchar *monitor_uri, const gchar *info_uri,
|
|
GnomeVFSMonitorEventType event_type, GmEmbeddedView *embedded);
|
|
void on_gm_embedded_view_font_changed(GmColorTable *color_table,
|
|
gchar const *desc, GmEmbeddedView *view);
|
|
|
|
G_DEFINE_TYPE(GmEmbeddedView, gm_embedded_view, GTK_TYPE_HBOX)
|
|
|
|
static void
|
|
gm_embedded_view_finalize(GObject *object) {
|
|
GmEmbeddedView *obj = GM_EMBEDDED_VIEW(object);
|
|
struct stat buf;
|
|
|
|
if (obj->priv->monitor) {
|
|
gnome_vfs_monitor_cancel(obj->priv->monitor);
|
|
}
|
|
|
|
if (GM_IS_EDITOR(obj->priv->editor)) {
|
|
if (stat(obj->priv->filename, &buf) != -1) {
|
|
if (buf.st_mtime > obj->priv->last_modified) {
|
|
gm_editor_save(obj->priv->editor);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (obj->priv->filename) {
|
|
unlink(obj->priv->filename);
|
|
g_free(obj->priv->filename);
|
|
}
|
|
|
|
G_OBJECT_CLASS(gm_embedded_view_parent_class)->finalize(object);
|
|
}
|
|
|
|
static void
|
|
gm_embedded_view_class_init(GmEmbeddedViewClass *klass) {
|
|
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
|
|
|
object_class->finalize = gm_embedded_view_finalize;
|
|
|
|
/*gm_embedded_view_signals[PROTO] =
|
|
g_signal_new("proto",
|
|
G_OBJECT_CLASS_TYPE(object_class),
|
|
G_SIGNAL_RUN_LAST,
|
|
G_STRUCT_OFFSET(GmEmbeddedViewClass, proto),
|
|
NULL, NULL,
|
|
g_cclosure_marshal_VOID__VOID,
|
|
G_TYPE_NONE,
|
|
0);*/
|
|
|
|
g_type_class_add_private(object_class, sizeof(GmEmbeddedViewPrivate));
|
|
}
|
|
|
|
static void
|
|
gm_embedded_view_init(GmEmbeddedView *obj) {
|
|
GtkWidget *vte;
|
|
GtkWidget *vscroll;
|
|
|
|
obj->priv = GM_EMBEDDED_VIEW_GET_PRIVATE(obj);
|
|
|
|
gtk_box_set_homogeneous(GTK_BOX(obj), FALSE);
|
|
gtk_box_set_spacing(GTK_BOX(obj), 6);
|
|
|
|
vte = vte_terminal_new();
|
|
vte_terminal_set_font_from_string(VTE_TERMINAL(vte),
|
|
gm_color_table_font_description(gm_app_color_table(
|
|
gm_app_instance())));
|
|
vte_terminal_set_scroll_on_keystroke(VTE_TERMINAL(vte), TRUE);
|
|
vte_terminal_set_scrollback_lines(VTE_TERMINAL(vte), 500);
|
|
vte_terminal_set_scroll_on_output(VTE_TERMINAL(vte), FALSE);
|
|
vte_terminal_set_word_chars(VTE_TERMINAL(vte), "-A-Za-z0-9,./?%&#:_");
|
|
vte_terminal_set_allow_bold(VTE_TERMINAL(vte), TRUE);
|
|
vte_terminal_set_audible_bell(VTE_TERMINAL(vte), TRUE);
|
|
gtk_widget_show(vte);
|
|
|
|
vscroll = gtk_vscrollbar_new(VTE_TERMINAL(vte)->adjustment);
|
|
gtk_widget_show(vscroll);
|
|
gtk_box_pack_start(GTK_BOX(obj), vte, TRUE, TRUE, 0);
|
|
gtk_box_pack_end(GTK_BOX(obj), vscroll, FALSE, FALSE, 0);
|
|
|
|
g_signal_connect(gm_app_color_table(gm_app_instance()), "font_changed",
|
|
G_CALLBACK(on_gm_embedded_view_font_changed), obj);
|
|
|
|
obj->priv->vte = VTE_TERMINAL(vte);
|
|
}
|
|
|
|
void
|
|
gm_embedded_view_update_last_modified(GmEmbeddedView *embedded) {
|
|
struct stat buf;
|
|
|
|
if (stat(embedded->priv->filename, &buf) != -1) {
|
|
embedded->priv->last_modified = buf.st_mtime;
|
|
}
|
|
}
|
|
|
|
GmEmbeddedView *
|
|
gm_embedded_view_new(GmWorld *world, GmEditor *editor) {
|
|
GmEmbeddedView *obj = GM_EMBEDDED_VIEW(g_object_new(GM_TYPE_EMBEDDED_VIEW,
|
|
NULL));
|
|
gchar *cmd[4] = { NULL, NULL, NULL, NULL };
|
|
GmOptions *options = gm_app_options(gm_app_instance());
|
|
|
|
obj->priv->world = world;
|
|
obj->priv->editor = editor;
|
|
obj->priv->filename = gm_editor_write_lines(editor);
|
|
|
|
gm_embedded_view_update_last_modified(obj);
|
|
|
|
cmd[0] = gnome_util_user_shell();
|
|
|
|
if (!cmd[0]) {
|
|
cmd[0] = g_strdup("/bin/sh");
|
|
}
|
|
|
|
cmd[1] = "-c";
|
|
cmd[2] = g_strconcat(gm_options_get(options, "editor_alternative"), " ",
|
|
obj->priv->filename, NULL);
|
|
|
|
vte_terminal_fork_command(obj->priv->vte, cmd[0], cmd, NULL,
|
|
g_get_home_dir(), FALSE, TRUE, TRUE);
|
|
|
|
g_free(cmd[0]);
|
|
g_free(cmd[2]);
|
|
|
|
gnome_vfs_monitor_add(&(obj->priv->monitor), obj->priv->filename,
|
|
GNOME_VFS_MONITOR_FILE,
|
|
(GnomeVFSMonitorCallback)on_gm_embedded_view_file_changed, obj);
|
|
|
|
g_signal_connect(obj->priv->vte, "child-exited",
|
|
G_CALLBACK(on_gm_embedded_view_exited), obj);
|
|
|
|
return obj;
|
|
}
|
|
|
|
GmEditor *
|
|
gm_embedded_view_editor(GmEmbeddedView *view) {
|
|
return view->priv->editor;
|
|
}
|
|
|
|
/* Callbacks */
|
|
void
|
|
on_gm_embedded_view_file_changed(GnomeVFSMonitorHandle *handle,
|
|
const gchar *monitor_uri, const gchar *info_uri,
|
|
GnomeVFSMonitorEventType event_type, GmEmbeddedView *embedded) {
|
|
switch (event_type) {
|
|
case GNOME_VFS_MONITOR_EVENT_CHANGED:
|
|
case GNOME_VFS_MONITOR_EVENT_CREATED:
|
|
gm_debug_msg(DEBUG_DEFAULT, "GmEmbedded.OnFileChanged: "
|
|
"change event detected!");
|
|
|
|
gm_editor_set_lines_from_file(embedded->priv->editor,
|
|
embedded->priv->filename);
|
|
gm_editor_save(embedded->priv->editor);
|
|
gm_embedded_view_update_last_modified(embedded);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
on_gm_embedded_view_exited(VteTerminal *vte, GmEmbeddedView *embedded) {
|
|
gm_editor_close(embedded->priv->editor);
|
|
}
|
|
|
|
void
|
|
on_gm_embedded_view_font_changed(GmColorTable *color_table, gchar const *desc,
|
|
GmEmbeddedView *view) {
|
|
vte_terminal_set_font_from_string(VTE_TERMINAL(view->priv->vte),
|
|
gm_color_table_font_description(gm_app_color_table(
|
|
gm_app_instance())));
|
|
}
|