#include #include #include #include #include #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; }