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/gm-editor.c

267 lines
5.5 KiB
C

#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include "gm-editor.h"
#include "gm-world.h"
#include "gm-support.h"
#include "gm-string.h"
#include "gm-debug.h"
#define GM_EDITOR_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GM_TYPE_EDITOR, GmEditorPrivate))
struct _GmEditorPrivate {
gchar *name;
gchar *upload_cmd;
gchar *mcp_type;
GmEditType type;
gboolean is_code;
GList *lines;
};
/* Signals */
enum {
SAVE,
SAVED,
CLOSE,
NUM_SIGNALS
};
static guint editor_signals[NUM_SIGNALS] = {0};
G_DEFINE_TYPE(GmEditor, gm_editor, G_TYPE_OBJECT)
static void
gm_editor_finalize(GObject *object) {
GmEditor *editor = GM_EDITOR(object);
g_free(editor->priv->name);
g_free(editor->priv->upload_cmd);
g_free(editor->priv->mcp_type);
gm_g_list_free_simple(editor->priv->lines);
G_OBJECT_CLASS(gm_editor_parent_class)->finalize(object);
}
static void
gm_editor_class_init(GmEditorClass *klass) {
GObjectClass *object_class = G_OBJECT_CLASS(klass);
object_class->finalize = gm_editor_finalize;
editor_signals[SAVE] =
g_signal_new("save",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(GmEditorClass, save),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
editor_signals[SAVED] =
g_signal_new("saved",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(GmEditorClass, saved),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
editor_signals[CLOSE] =
g_signal_new("close",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(GmEditorClass, close),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
g_type_class_add_private(object_class, sizeof(GmEditorPrivate));
}
static void
gm_editor_init(GmEditor *view) {
view->priv = GM_EDITOR_GET_PRIVATE(view);
}
GmEditor *
gm_editor_new(gchar *name, gchar *uploadcmd, GList *text) {
GmEditor *editor = GM_EDITOR(g_object_new(GM_TYPE_EDITOR, NULL));
editor->priv->name = g_strdup(name);
editor->priv->upload_cmd = g_strdup(uploadcmd);
editor->priv->mcp_type = NULL;
editor->priv->lines = g_list_copy(text);
editor->priv->type = E_LEGACY;
editor->priv->is_code = (strncmp(uploadcmd, "@program", 7) == 0);
return editor;
}
GmEditor *
gm_editor_new_mcp(gchar *name, gchar *reference, gchar *type,
GList *text) {
GmEditor *editor = GM_EDITOR(g_object_new(GM_TYPE_EDITOR, NULL));
editor->priv->name = g_strdup(name);
editor->priv->upload_cmd = g_strdup(reference);
editor->priv->mcp_type = g_strdup(type);
editor->priv->lines = g_list_copy(text);
editor->priv->type = E_LEGACY;
editor->priv->is_code = (strcmp(type, "moo-code") == 0);
return editor;
}
void
gm_editor_lines_free(GmEditor *editor) {
gm_g_list_free_simple(editor->priv->lines);
editor->priv->lines = NULL;
}
void
gm_editor_set_lines_from_string(GmEditor *editor, gchar const *text) {
editor->priv->lines = gm_string_split(text);
}
void
gm_editor_set_lines_from_file(GmEditor *editor, gchar const *filename) {
gchar *text = gm_read_file(filename);
if (!text) {
// TODO: Couldn't read file... what to do
return;
}
gm_editor_set_lines_from_string(editor, text);
g_free(text);
}
gboolean
gm_editor_is_code(GmEditor *editor) {
return editor->priv->is_code;
}
gchar *
gm_editor_name(GmEditor *editor) {
return editor->priv->name;
}
gchar *
gm_editor_upload_cmd(GmEditor *editor) {
return editor->priv->upload_cmd;
}
gchar *
gm_editor_mcp_type(GmEditor *editor) {
return editor->priv->mcp_type;
}
GList *
gm_editor_lines(GmEditor *editor) {
return editor->priv->lines;
}
GmEditType
gm_editor_type(GmEditor *editor) {
return editor->priv->type;
}
void
gm_editor_save(GmEditor *editor) {
g_signal_emit(editor, editor_signals[SAVE], 0);
}
void
gm_editor_saved(GmEditor *editor) {
g_signal_emit(editor, editor_signals[SAVED], 0);
}
void
gm_editor_close(GmEditor *editor) {
g_signal_emit(editor, editor_signals[CLOSE], 0);
}
gchar *
gm_editor_generate_filename(GmEditor *editor) {
gchar *filename, *ptr, *fptr;
gunichar c;
guint counter;
filename = g_strdup(editor->priv->name);
ptr = filename;
fptr = filename;
// Remove any characters that are not digits or chars
// Replace spaces with underscores
while (*ptr != '\0') {
c = g_utf8_get_char(ptr);
if (c == ' ') {
*fptr++ = '_';
} else if (c == '.' || c == ':' || c == '_' || g_unichar_isalnum(c)) {
fptr += g_unichar_to_utf8(c, fptr);
}
ptr = g_utf8_next_char(ptr);
}
*fptr = '\0';
ptr = NULL;
counter = 0;
while (ptr == NULL || g_file_test(ptr, G_FILE_TEST_EXISTS)) {
g_free(ptr);
if (editor->priv->is_code) {
ptr = g_strdup_printf("%s/gnoemoe-edit.%s.%d.%s", g_get_tmp_dir(),
filename, counter, "moo");
} else {
ptr = g_strdup_printf("%s/gnoemoe-edit.%s.%d.%s",g_get_tmp_dir(),
filename, counter, "txt");
}
++counter;
}
g_free(filename);
return ptr;
}
gchar *
gm_editor_write_lines(GmEditor *editor) {
gchar *tmp = gm_editor_generate_filename(editor);
gint fd = open(tmp, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP);
GList *line;
if (fd == -1) {
gm_debug_msg(DEBUG_ALWAYS, "Couldn't open file: %s, %s", tmp,
strerror(errno));
g_free(tmp);
return NULL;
}
// Write lines
for (line = editor->priv->lines; line; line = line->next) {
if (write(fd, line->data, strlen(line->data)) == -1) {
gm_debug_msg(DEBUG_ALWAYS, "Writing failed");
break;
}
if (write(fd, "\n", 1) == -1) {
gm_debug_msg(DEBUG_ALWAYS, "Writing failed");
break;
}
}
close(fd);
return tmp;
}