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/dialogs/gm-scripts-dialog.c

921 lines
26 KiB
C

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef HAVE_RUBY
#include <gtk/gtk.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <gtksourceview/gtksourceview.h>
#include <gtksourceview/gtksourcelanguage.h>
#include <gtksourceview/gtksourcelanguagesmanager.h>
#include <gtksourceview/gtksourcetag.h>
#include <libgnomevfs/gnome-vfs.h>
#include <glade/glade.h>
#include "../gm-scripts.h"
#include "../gm-world.h"
#include "../gm-debug.h"
#include "../gm-app.h"
#include "../gm-support.h"
#include "../widgets/gm-app-view.h"
#include "../widgets/gm-text-scroller.h"
#define SCRIPT_TEMPLATE \
_("=begin\n" \
"\t<title>\n" \
"\t<copyright>\n" \
"\n\tRegister functions in the register_functions method defined below.\n" \
"\tRegister functions with " \
"$scripts.register(<name>, <description>[, <alias>])\n=end" \
"\n\ndef register_functions\n" \
"\t$scripts.register(\"myscript\", \"use /myscript\")\nend\n\n" \
"def myscript(argstr)\n\t# Insert code here\nend\n")
void on_gm_scripts_dialog_script_added(GmScripts *scripts, GmScript *script,
gpointer user_data);
void on_gm_scripts_dialog_script_changed(GmScripts *scripts, GmScript *script,
gpointer user_data);
void on_gm_scripts_dialog_script_removed(GmScripts *scripts, GmScript *script,
gpointer user_data);
void on_gm_scripts_dialog_message(GmScripts *scripts, gchar *message,
gpointer user_data);
void on_gm_scripts_dialog_error(GmScripts *scripts, gchar *message,
gpointer user_data);
void on_gm_scripts_dialog_run(GmScripts *scripts, gchar *message,
gpointer user_data);
typedef enum _MessageType {
SCRIPT_MESSAGE,
SCRIPT_ERROR,
SCRIPT_RUN
} MessageType;
typedef enum _scripts_columns {
SCRIPTS_NAME,
SCRIPTS_OBJECT,
SCRIPTS_N
} scripts_columns;
typedef struct _SelectionInfo {
GtkTreeView *view;
GtkTreeModel *model;
GtkTreeIter seliter;
GtkTreeIter parent;
gboolean has_parent;
gboolean can_save;
gchar *filename;
} SelectionInfo;
typedef struct _GmScriptsDialog {
GtkTextTagTable *tag_table;
GladeXML *xml;
GtkTextBuffer *text_buffer_console;
gchar *current_edit;
GtkTextBuffer *text_buffer_editor;
GtkWidget *dialog;
GtkWidget *text_view_console;
GtkWidget *statusbar_editor;
GtkWidget *button_save;
GtkWidget *tree_view_scripts;
GtkWidget *tree_view_files;
GtkWidget *button_delete;
GmTextScroller *text_scroller;
SelectionInfo info;
} GmScriptsDialog;
static GmScriptsDialog *scripts_dialog = NULL;
#define G_SCRIPTS_XML PACKAGE_DATA_DIR "/" PACKAGE "/ui/gm-scripts.glade"
gboolean on_gm_scripts_dialog_delete(GtkWidget *widget, GdkEvent *event,
gpointer user_data);
void on_files_changed(GtkTreeSelection *treeselection, gpointer user_data);
void on_tree_view_files_row_activated(GtkTreeView *treeview, GtkTreePath *arg1,
GtkTreeViewColumn *arg2, gpointer user_data);
void on_text_buffer_editor_modified_changed(GtkTextBuffer *buffer,
gpointer user_data);
void on_tool_button_new_clicked(GtkToolButton *button, gpointer user_data);
void on_tool_button_save_clicked(GtkToolButton *button, gpointer user_data);
void on_tool_button_save_as_clicked(GtkToolButton *button, gpointer user_data);
void on_tool_button_delete_clicked(GtkToolButton *button, gpointer user_data);
gboolean
gm_scripts_dialog_can_write(gchar *filename) {
return (access(filename, W_OK) == 0);
}
void
gm_scripts_dialog_set_status(gchar *msg) {
gtk_statusbar_pop(GTK_STATUSBAR(scripts_dialog->statusbar_editor),
0);
gtk_statusbar_push(GTK_STATUSBAR(scripts_dialog->statusbar_editor),
0, msg);
}
gboolean
gm_scripts_dialog_editor_save(gchar *filename) {
FILE *f;
gchar *msg, *text;
GtkTextIter start, end;
if (!filename) {
return FALSE;
}
f = fopen(filename, "w");
if (f) {
gtk_text_buffer_get_start_iter(scripts_dialog->text_buffer_editor,
&start);
gtk_text_buffer_get_end_iter(scripts_dialog->text_buffer_editor, &end);
text = gtk_text_buffer_get_text(scripts_dialog->text_buffer_editor,
&start, &end, TRUE);
fputs(text, f);
msg = g_strconcat(_("Saved "), filename, NULL);
gm_scripts_dialog_set_status(msg);
g_free(msg);
if (scripts_dialog->current_edit != filename) {
g_free(scripts_dialog->current_edit);
scripts_dialog->current_edit = g_strdup(filename);
}
gtk_text_buffer_set_modified(scripts_dialog->text_buffer_editor,
FALSE);
fclose(f);
return TRUE;
} else {
text = g_filename_to_utf8(filename, -1, NULL, NULL, NULL);
msg = g_strconcat(_("Saving failed: "), strerror(errno), " (",
text, ")", NULL);
gm_error_dialog(msg, GTK_WINDOW(scripts_dialog->dialog));
g_free(text);
g_free(msg);
return FALSE;
}
}
void
gm_scripts_dialog_editor_load(SelectionInfo *info) {
FILE *f;
gchar line[1024];
GtkTextIter end;
gchar *lline, *msg;
if (info) {
gtk_text_buffer_set_text(scripts_dialog->text_buffer_editor, "", 0);
gtk_text_buffer_get_end_iter(scripts_dialog->text_buffer_editor, &end);
f = fopen(info->filename, "r");
if (f) {
while (fgets((char *) &line, 1024 - 1, f) != NULL) {
lline = g_locale_to_utf8((gchar *)&line, strlen((char *)&line),
NULL, NULL, NULL);
if (lline) {
gtk_text_buffer_insert(scripts_dialog->text_buffer_editor,
&end, lline, strlen(lline));
g_free(lline);
} else {
gtk_text_buffer_insert(scripts_dialog->text_buffer_editor,
&end, (gchar *)&line, strlen((char *)&line));
}
}
fclose(f);
gtk_widget_set_sensitive(scripts_dialog->button_save,
info->can_save);
g_free(scripts_dialog->current_edit);
scripts_dialog->current_edit = g_strdup(info->filename);
g_free(scripts_dialog->current_edit);
scripts_dialog->current_edit = g_strdup(info->filename);
msg = g_strconcat(_("Loaded "), info->filename, NULL);
gm_scripts_dialog_set_status(msg);
g_free(msg);
} else {
gm_debug_msg(DEBUG_DEFAULT, "GmScript.EditorLoad: file (%s) could not be read: %s",
scripts_dialog->current_edit, strerror(errno));
}
} else {
gtk_text_buffer_set_text(scripts_dialog->text_buffer_editor,
SCRIPT_TEMPLATE, -1);
g_free(scripts_dialog->current_edit);
scripts_dialog->current_edit = NULL;
gm_scripts_dialog_set_status(_("New <untitled>"));
}
}
void
gm_scripts_dialog_init_console() {
GtkTextView *txt = GTK_TEXT_VIEW(scripts_dialog->text_view_console);
PangoFontDescription *f;
gtk_text_view_set_buffer(txt, scripts_dialog->text_buffer_console);
gtk_text_view_set_editable(txt, FALSE);
f =
pango_font_description_from_string("monospace 8");
if (f) {
gtk_widget_modify_font(GTK_WIDGET(txt), f);
pango_font_description_free(f);
}
}
void
gm_scripts_dialog_tree_add_function(GtkTreeStore *model, GtkTreeIter *parent,
GmScriptFunction *fi) {
GtkTreeIter item;
gchar *name, *description, *all, *markup;
gtk_tree_store_append(model, &item, parent);
name = g_filename_to_utf8(fi->name, strlen(fi->name), NULL,
NULL, NULL);
description = g_locale_to_utf8(fi->description, strlen(fi->description),
NULL, NULL, NULL);
markup = g_markup_escape_text(description, g_utf8_strlen(description, -1));
all = g_strconcat("<b>", name, "</b>\n", markup, NULL);
gtk_tree_store_set(model, &item, SCRIPTS_NAME, all, -1);
g_free(all);
g_free(markup);
g_free(description);
g_free(name);
}
void
gm_scripts_dialog_tree_update_script_item(GmScript *script, GtkTreeIter *iter) {
GList *list;
GtkTreeStore *model = GTK_TREE_STORE(gtk_tree_view_get_model(
GTK_TREE_VIEW(scripts_dialog->tree_view_scripts)));
GtkTreeIter item;
if (gtk_tree_model_iter_children(GTK_TREE_MODEL(model), &item, iter)) {
while (gtk_tree_store_remove(model, &item));
}
for (list = script->functions; list; list = list->next) {
gm_scripts_dialog_tree_add_function(model, iter,
(GmScriptFunction *)(list->data));
}
}
gboolean
gm_scripts_dialog_model_find_script(GtkTreeModel *model,
GmScript *script, GtkTreeIter *item, GtkTreeIter *parent) {
GmScript *obj;
if (gtk_tree_model_iter_children(model, item, parent)) {
do {
gtk_tree_model_get(model, item, SCRIPTS_OBJECT,
&obj, -1);
if (obj == script) {
return TRUE;
}
} while (gtk_tree_model_iter_next(model, item));
}
return FALSE;
}
void
gm_scripts_dialog_tree_update_script(GmScript *script) {
GtkTreeModel *model = gtk_tree_view_get_model(
GTK_TREE_VIEW(scripts_dialog->tree_view_scripts));
GtkTreeIter item;
if (gm_scripts_dialog_model_find_script(model, script, &item, NULL)) {
gm_scripts_dialog_tree_update_script_item(script, &item);
}
}
void
gm_scripts_dialog_tree_remove_script(GmScript *script) {
GtkTreeModel *model = gtk_tree_view_get_model(
GTK_TREE_VIEW(scripts_dialog->tree_view_scripts));
GtkTreeIter item;
if (gm_scripts_dialog_model_find_script(model, script, &item, NULL)) {
gtk_tree_store_remove(GTK_TREE_STORE(model), &item);
}
}
void
gm_scripts_dialog_tree_add_script(GmScript *script) {
GtkTreeStore *model = GTK_TREE_STORE(gtk_tree_view_get_model(
GTK_TREE_VIEW(scripts_dialog->tree_view_scripts)));
GtkTreeIter item;
gchar *name, *base;
gtk_tree_store_append(model, &item, NULL);
name = g_filename_to_utf8(script->filename, strlen(script->filename), NULL,
NULL, NULL);
base = g_path_get_basename(name);
g_free(name);
if (script->type == GM_SCRIPT_TYPE_USER) {
name = g_strconcat(_("<b>User:</b> "), base, NULL);
} else {
name = g_strconcat(_("<b>Share:</b> "), base, NULL);
}
g_free(base);
gtk_tree_store_set(model, &item, SCRIPTS_NAME, name, SCRIPTS_OBJECT,
script, -1);
g_free(name);
gm_scripts_dialog_tree_update_script_item(script, &item);
}
void
gm_scripts_dialog_fill_tree() {
GtkTreeView *view = GTK_TREE_VIEW(scripts_dialog->tree_view_scripts);
GtkTreeStore *model = GTK_TREE_STORE(gtk_tree_view_get_model(view));
GList *scripts;
gtk_tree_store_clear(model);
for (scripts = gm_scripts_scripts(gm_app_scripts(gm_app_instance()));
scripts; scripts = scripts->next) {
gm_scripts_dialog_tree_add_script((GmScript *)(scripts->data));
}
}
void
gm_scripts_dialog_init_tree() {
GtkTreeView *view = GTK_TREE_VIEW(scripts_dialog->tree_view_scripts);
GtkTreeStore *model = gtk_tree_store_new(SCRIPTS_N, G_TYPE_STRING,
G_TYPE_POINTER);
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes(_("Scripts"), renderer,
"markup", SCRIPTS_NAME, NULL);
gtk_tree_view_append_column(view, column);
gtk_tree_view_set_model(view, GTK_TREE_MODEL(model));
gm_scripts_dialog_fill_tree();
}
void
gm_scripts_dialog_remove_file(GmScript *script) {
GtkTreeView *view = GTK_TREE_VIEW(scripts_dialog->tree_view_files);
GtkTreeStore *model = GTK_TREE_STORE(gtk_tree_view_get_model(view));
const gchar *sharedir = PACKAGE_DATA_DIR "/" PACKAGE "/scripts";
GtkTreeIter parent;
GtkTreeIter item;
gchar *name = g_filename_to_utf8(script->filename,
strlen(script->filename), NULL, NULL, NULL);
if (strncmp(sharedir, name, strlen(sharedir)) == 0) {
gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(model), &parent, "0");
} else {
gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(model), &parent, "1");
}
g_free(name);
if (gm_scripts_dialog_model_find_script(GTK_TREE_MODEL(model), script,
&item, &parent)) {
gtk_tree_store_remove(model, &item);
}
}
gboolean
gm_scripts_dialog_add_file(GmScript *script) {
GtkTreeView *view = GTK_TREE_VIEW(scripts_dialog->tree_view_files);
GtkTreeStore *model = GTK_TREE_STORE(gtk_tree_view_get_model(view));
GtkTreeIter share, home, parent, item;
gchar *sharedir = g_strdup(PACKAGE_DATA_DIR "/" PACKAGE "/scripts");
gchar *homedir = g_strconcat(gm_app_path(gm_app_instance()), "/scripts",
NULL);
gchar *name;
gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(model), &share, "0");
gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(model), &home, "1");
name = g_filename_to_utf8(script->filename, strlen(script->filename), NULL,
NULL, NULL);
if (strncmp(sharedir, name, strlen(sharedir)) == 0) {
parent = share;
} else if (strncmp(homedir, name, strlen(homedir)) == 0) {
parent = home;
} else {
g_free(sharedir);
g_free(homedir);
g_free(name);
return FALSE;
}
gtk_tree_store_append(model, &item, &parent);
gtk_tree_store_set(model, &item, SCRIPTS_NAME, g_strrstr(name, "/") + 1,
SCRIPTS_OBJECT, script, -1);
g_free(name);
g_free(sharedir);
g_free(homedir);
return TRUE;
}
void
gm_scripts_dialog_fill_files() {
GtkTreeView *view = GTK_TREE_VIEW(scripts_dialog->tree_view_files);
GtkTreeStore *model = GTK_TREE_STORE(gtk_tree_view_get_model(view));
GtkTreeIter share, home;
GtkTreePath *path;
GList *scripts;
GmScript *script;
gtk_tree_store_clear(model);
gtk_tree_store_append(model, &share, NULL);
gtk_tree_store_set(model, &share, SCRIPTS_NAME, _("Share"), -1);
gtk_tree_store_append(model, &home, NULL);
gtk_tree_store_set(model, &home, SCRIPTS_NAME, _("User"), -1);
for (scripts = gm_scripts_scripts(gm_app_scripts(gm_app_instance()));
scripts; scripts = scripts->next) {
script = (GmScript *)(scripts->data);
gm_scripts_dialog_add_file(script);
}
path = gtk_tree_model_get_path(GTK_TREE_MODEL(model), &home);
gtk_tree_view_expand_to_path(view, path);
gtk_tree_path_free(path);
path = gtk_tree_model_get_path(GTK_TREE_MODEL(model), &share);
gtk_tree_view_expand_to_path(view, path);
gtk_tree_path_free(path);
}
void
gm_scripts_dialog_init_files() {
GtkTreeView *view = GTK_TREE_VIEW(scripts_dialog->tree_view_files);
GtkTreeStore *model = gtk_tree_store_new(SCRIPTS_N, G_TYPE_STRING,
G_TYPE_POINTER);
GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
GtkTreeSelection *selection;
GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes(
_("Filename"), renderer, "text", SCRIPTS_NAME, NULL);
gtk_tree_view_append_column(view, column);
gtk_tree_view_set_model(view, GTK_TREE_MODEL(model));
selection = gtk_tree_view_get_selection(view);
g_signal_connect((gpointer)selection, "changed",
G_CALLBACK(on_files_changed), NULL);
gm_scripts_dialog_fill_files();
}
GtkWidget *
gm_scripts_dialog_init_editor() {
GtkSourceLanguagesManager *lm = gtk_source_languages_manager_new();
GtkSourceLanguage *lang;
GtkWidget *view;
PangoFontDescription *f;
lang = gtk_source_languages_manager_get_language_from_mime_type(lm,
"application/x-ruby");
view = gtk_source_view_new();
scripts_dialog->text_buffer_editor = gtk_text_view_get_buffer(
GTK_TEXT_VIEW(view));
g_signal_connect((gpointer)scripts_dialog->text_buffer_editor,
"modified-changed",
G_CALLBACK(on_text_buffer_editor_modified_changed), NULL);
if (lang) {
gtk_source_buffer_set_language(
GTK_SOURCE_BUFFER(scripts_dialog->text_buffer_editor), lang);
}
f = pango_font_description_from_string(gm_options_get(gm_app_options(
gm_app_instance()), "font-family"));
gtk_widget_modify_font(view, f);
gtk_source_view_set_insert_spaces_instead_of_tabs(GTK_SOURCE_VIEW(view),
FALSE);
gtk_source_view_set_auto_indent(GTK_SOURCE_VIEW(view), TRUE);
gtk_source_view_set_show_line_numbers(GTK_SOURCE_VIEW(view), TRUE);
gtk_source_view_set_smart_home_end(GTK_SOURCE_VIEW(view), TRUE);
gtk_source_view_set_tabs_width(GTK_SOURCE_VIEW(view), 4);
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(view), GTK_WRAP_WORD_CHAR);
gtk_text_view_set_left_margin(GTK_TEXT_VIEW(view), 6);
gtk_text_view_set_right_margin(GTK_TEXT_VIEW(view), 6);
gtk_source_buffer_set_highlight(GTK_SOURCE_BUFFER(
scripts_dialog->text_buffer_editor), TRUE);
// Load default template
gtk_text_buffer_set_text(scripts_dialog->text_buffer_editor,
SCRIPT_TEMPLATE, -1);
gtk_widget_show(view);
return view;
}
GtkTextTag *
gm_scripts_dialog_create_tag(gchar *name, gchar *fg) {
GtkTextTag *tag;
GdkColor col;
gdk_color_parse(fg, &col);
tag = gtk_text_tag_new(name);
g_object_set(G_OBJECT(tag), "foreground-gdk", &col, NULL);
return tag;
}
void
gm_scripts_dialog_init() {
GmScripts *scripts = gm_app_scripts(gm_app_instance());
scripts_dialog = g_new0(GmScriptsDialog, 1);
scripts_dialog->tag_table = g_object_ref(gtk_text_tag_table_new());
scripts_dialog->dialog = NULL;
gtk_text_tag_table_add(scripts_dialog->tag_table,
gm_scripts_dialog_create_tag("scripts-run", "#445632"));
gtk_text_tag_table_add(scripts_dialog->tag_table,
gm_scripts_dialog_create_tag("scripts-msg", "#314E6C"));
gtk_text_tag_table_add(scripts_dialog->tag_table,
gm_scripts_dialog_create_tag("scripts-error", "#663822"));
scripts_dialog->text_buffer_console =
g_object_ref(gtk_text_buffer_new(scripts_dialog->tag_table));
// Attach signals to GmScripts object to know about changes
g_signal_connect(scripts, "script_added",
G_CALLBACK(on_gm_scripts_dialog_script_added), NULL);
g_signal_connect(scripts, "script_changed",
G_CALLBACK(on_gm_scripts_dialog_script_changed), NULL);
g_signal_connect(scripts, "script_removed",
G_CALLBACK(on_gm_scripts_dialog_script_removed), NULL);
g_signal_connect(scripts, "message",
G_CALLBACK(on_gm_scripts_dialog_message), NULL);
g_signal_connect(scripts, "error",
G_CALLBACK(on_gm_scripts_dialog_error), NULL);
g_signal_connect(scripts, "run",
G_CALLBACK(on_gm_scripts_dialog_run), NULL);
}
void
gm_scripts_dialog_fini() {
g_object_unref(scripts_dialog->tag_table);
g_object_unref(scripts_dialog->text_buffer_console);
g_free(scripts_dialog);
}
gboolean
gm_scripts_scroll_end_idle(gpointer user_data) {
//gm_text_scroller_scroll_end(scripts_dialog->text_scroller);
return FALSE;
}
void
gm_scripts_dialog_run(GmAppView *view) {
GtkWidget *editor;
if (scripts_dialog->dialog != NULL) {
gtk_window_present(GTK_WINDOW(scripts_dialog->dialog));
return;
}
scripts_dialog->xml = glade_xml_new(G_SCRIPTS_XML, "gm_scripts_dialog", NULL);
scripts_dialog->dialog = glade_xml_get_widget(scripts_dialog->xml,
"gm_scripts_dialog");
scripts_dialog->text_view_console = glade_xml_get_widget(scripts_dialog->xml,
"text_view_console");
scripts_dialog->statusbar_editor = glade_xml_get_widget(scripts_dialog->xml,
"statusbar_editor");
scripts_dialog->button_save = glade_xml_get_widget(scripts_dialog->xml,
"tool_button_save");
scripts_dialog->tree_view_scripts = glade_xml_get_widget(scripts_dialog->xml,
"tree_view_scripts");
scripts_dialog->tree_view_files = glade_xml_get_widget(scripts_dialog->xml,
"tree_view_files");
scripts_dialog->button_delete = glade_xml_get_widget(scripts_dialog->xml,
"tool_button_delete");
// Create new text scroller, this object will take care of itself and will
// destroy itself when the view dies, neat!
scripts_dialog->text_scroller = gm_text_scroller_new(GTK_TEXT_VIEW(
scripts_dialog->text_view_console));
gm_scripts_dialog_init_console();
gm_scripts_dialog_init_tree();
gm_scripts_dialog_init_files();
editor = gm_scripts_dialog_init_editor();
gtk_container_add(GTK_CONTAINER(glade_xml_get_widget(scripts_dialog->xml,
"scrolled_window_editor")), editor);
glade_xml_signal_connect(scripts_dialog->xml, "on_gm_scripts_dialog_delete",
G_CALLBACK(on_gm_scripts_dialog_delete));
glade_xml_signal_connect(scripts_dialog->xml,
"on_tree_view_files_row_activated",
G_CALLBACK(on_tree_view_files_row_activated));
glade_xml_signal_connect(scripts_dialog->xml,
"on_tool_button_new_clicked",
G_CALLBACK(on_tool_button_new_clicked));
glade_xml_signal_connect(scripts_dialog->xml,
"on_tool_button_save_clicked",
G_CALLBACK(on_tool_button_save_clicked));
glade_xml_signal_connect(scripts_dialog->xml,
"on_tool_button_save_as_clicked",
G_CALLBACK(on_tool_button_save_as_clicked));
glade_xml_signal_connect(scripts_dialog->xml,
"on_tool_button_delete_clicked",
G_CALLBACK(on_tool_button_delete_clicked));
gtk_window_set_transient_for(GTK_WINDOW(scripts_dialog->dialog),
GTK_WINDOW(view));
gm_scripts_dialog_set_status(_("New <untitled>"));
g_object_unref(scripts_dialog->xml);
g_idle_add((GSourceFunc)(gm_scripts_scroll_end_idle), NULL);
}
void
gm_scripts_dialog_add(MessageType mtype, gchar *msg) {
gchar *m, *tagName = NULL, *newLine;
gchar p[3] = {' ', ' ', '\0'};
GtkTextIter end;
switch (mtype) {
case SCRIPT_RUN:
p[0] = ':';
tagName = g_strdup("scripts-run");
break;
case SCRIPT_MESSAGE:
p[0] = '#';
tagName = g_strdup("scripts-msg");
break;
case SCRIPT_ERROR:
p[0] = '!';
tagName = g_strdup("scripts-error");
break;
}
m = g_strconcat(p, msg, "\n", NULL);
gtk_text_buffer_get_end_iter(scripts_dialog->text_buffer_console, &end);
// convert to UTF-8
newLine = g_locale_to_utf8(m, strlen(m), NULL, NULL, NULL);
if (newLine == NULL) {
gtk_text_buffer_insert_with_tags_by_name(
scripts_dialog->text_buffer_console, &end, m, strlen(m),
tagName, NULL);
} else {
gtk_text_buffer_insert_with_tags_by_name(
scripts_dialog->text_buffer_console, &end, newLine,
strlen(newLine), tagName, NULL);
g_free(newLine);
}
g_free(m);
g_free(tagName);
}
gboolean
gm_scripts_dialog_selection_info(SelectionInfo *info) {
GtkTreeView *view = GTK_TREE_VIEW(scripts_dialog->tree_view_files);
GtkTreeModel *model = gtk_tree_view_get_model(view);
GtkTreeSelection *selection = gtk_tree_view_get_selection(view);
gchar *parentName, *name, *filename;
info->view = view;
info->model = model;
if (gtk_tree_selection_get_selected(selection, &model, &(info->seliter))) {
info->has_parent = gtk_tree_model_iter_parent(model,
&(info->parent), &(info->seliter));
if (info->has_parent) {
gtk_tree_model_get(model, &(info->parent), SCRIPTS_NAME,
&parentName, -1);
gtk_tree_model_get(model, &(info->seliter), SCRIPTS_NAME,
&name, -1);
if (strcmp(parentName, _("Share")) == 0) {
filename = g_strconcat(
PACKAGE_DATA_DIR "/" PACKAGE "/scripts/", name, NULL);
} else {
filename = g_strconcat(gm_app_path(gm_app_instance()),
"/scripts/", name, NULL);
}
info->filename = g_filename_from_utf8(filename, -1,
NULL, NULL, NULL);
g_free(name);
g_free(parentName);
g_free(filename);
info->can_save = gm_scripts_dialog_can_write(info->filename);
} else {
info->filename = NULL;
}
return TRUE;
} else {
return FALSE;
}
}
/* CALLBACKS */
gboolean
on_gm_scripts_dialog_delete(GtkWidget *widget, GdkEvent *event,
gpointer user_data) {
g_free(scripts_dialog->current_edit);
scripts_dialog->current_edit = NULL;
scripts_dialog->dialog = NULL;
return FALSE;
}
void
on_files_changed(GtkTreeSelection *treeselection, gpointer user_data) {
SelectionInfo info;
if (gm_scripts_dialog_selection_info(&info)) {
gtk_widget_set_sensitive(scripts_dialog->button_delete,
info.has_parent && info.can_save);
if (info.filename) {
g_free(info.filename);
}
}
}
void
on_tree_view_files_row_activated(GtkTreeView *treeview, GtkTreePath *arg1,
GtkTreeViewColumn *arg2, gpointer user_data) {
SelectionInfo si;
if (gm_scripts_dialog_selection_info(&si) && si.filename) {
gm_scripts_dialog_editor_load(&si);
g_free(si.filename);
}
}
void
on_text_buffer_editor_modified_changed(GtkTextBuffer *buffer,
gpointer user_data) {
gchar *msg;
gboolean modified = gtk_text_buffer_get_modified(buffer);
if (modified) {
if (scripts_dialog->current_edit) {
msg = g_strconcat(_("Changed "), scripts_dialog->current_edit, NULL);
} else {
msg = g_strdup(_("Changed <untitled>"));
}
gm_scripts_dialog_set_status(msg);
g_free(msg);
}
}
void
on_tool_button_new_clicked(GtkToolButton *button, gpointer user_data) {
gm_scripts_dialog_editor_load(NULL);
}
void
on_tool_button_save_clicked(GtkToolButton *button, gpointer user_data) {
if (scripts_dialog->current_edit) {
gm_scripts_dialog_editor_save(scripts_dialog->current_edit);
} else {
on_tool_button_save_as_clicked(button, user_data);
}
}
void
on_tool_button_save_as_clicked(GtkToolButton *button, gpointer user_data) {
GtkWidget *dlg;
gchar *filename, *di;
dlg = gtk_file_chooser_dialog_new(_("Save file"),
GTK_WINDOW(scripts_dialog->dialog),
GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
NULL);
if (scripts_dialog->current_edit) {
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dlg),
scripts_dialog->current_edit);
} else {
di = g_strconcat(gm_app_path(gm_app_instance()),
"/scripts/untitled.rb", NULL);
gtk_file_chooser_select_filename(GTK_FILE_CHOOSER(dlg), di);
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dlg), "untitled.rb");
g_free(di);
}
if (gtk_dialog_run(GTK_DIALOG(dlg)) == GTK_RESPONSE_ACCEPT) {
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dlg));
gm_scripts_dialog_editor_save(filename);
g_free(filename);
}
gtk_widget_destroy(dlg);
}
void
on_tool_button_delete_clicked(GtkToolButton *button, gpointer user_data) {
SelectionInfo info;
if (gm_scripts_dialog_selection_info(&info)) {
if (info.has_parent && info.can_save) {
remove(info.filename);
}
g_free(info.filename);
}
}
void
on_gm_scripts_dialog_script_added(GmScripts *scripts, GmScript *script,
gpointer user_data) {
if (scripts_dialog->dialog != NULL) {
gm_scripts_dialog_tree_add_script(script);
gm_scripts_dialog_add_file(script);
}
}
void
on_gm_scripts_dialog_script_changed(GmScripts *scripts, GmScript *script,
gpointer user_data) {
if (scripts_dialog->dialog != NULL) {
gm_scripts_dialog_tree_update_script(script);
}
}
void
on_gm_scripts_dialog_script_removed(GmScripts *scripts, GmScript *script,
gpointer user_data) {
if (scripts_dialog->dialog != NULL) {
gm_scripts_dialog_tree_remove_script(script);
gm_scripts_dialog_remove_file(script);
if (strcmp(script->filename, scripts_dialog->current_edit) == 0) {
gm_scripts_dialog_editor_load(NULL);
}
}
}
void on_gm_scripts_dialog_message(GmScripts *scripts, gchar *message,
gpointer user_data) {
gm_scripts_dialog_add(SCRIPT_MESSAGE, message);
}
void on_gm_scripts_dialog_error(GmScripts *scripts, gchar *message,
gpointer user_data) {
gm_scripts_dialog_add(SCRIPT_ERROR, message);
}
void on_gm_scripts_dialog_run(GmScripts *scripts, gchar *message,
gpointer user_data) {
gm_scripts_dialog_add(SCRIPT_RUN, message);
}
#endif