845 lines
24 KiB
C
845 lines
24 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 "debug.h"
|
||
|
#include "gm-app.h"
|
||
|
#include "gm-support.h"
|
||
|
#include "gm-app-view.h"
|
||
|
|
||
|
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;
|
||
|
|
||
|
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 != scripts_dialog->current_edit) {
|
||
|
g_free(scripts_dialog->current_edit);
|
||
|
scripts_dialog->current_edit = g_strdup(filename);
|
||
|
}
|
||
|
|
||
|
fclose(f);
|
||
|
return TRUE;
|
||
|
} else {
|
||
|
msg = g_strconcat(_("Saving failed: "), strerror(errno), NULL);
|
||
|
gm_error_dialog(msg, GTK_WINDOW(scripts_dialog->dialog));
|
||
|
g_free(msg);
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
gm_scripts_dialog_editor_load(SelectionInfo *info) {
|
||
|
FILE *f;
|
||
|
gchar line[1024];
|
||
|
GtkTextIter end;
|
||
|
gchar *lline, *msg;
|
||
|
|
||
|
gtk_text_buffer_set_text(scripts_dialog->text_buffer_editor, "", 0);
|
||
|
gtk_text_buffer_get_end_iter(scripts_dialog->text_buffer_editor, &end);
|
||
|
|
||
|
if (info) {
|
||
|
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);
|
||
|
|
||
|
msg = g_strconcat(_("Loaded "), info->filename, NULL);
|
||
|
gm_scripts_dialog_set_status(msg);
|
||
|
g_free(msg);
|
||
|
} else {
|
||
|
debug_msg(1, "GmScript.EditorLoad: file (%s) could not be read: %s",
|
||
|
scripts_dialog->current_edit, strerror(errno));
|
||
|
}
|
||
|
} else {
|
||
|
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));
|
||
|
}
|
||
|
}
|
||
|
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;
|
||
|
GmScript *obj;
|
||
|
|
||
|
if (gtk_tree_model_iter_children(model, &item, NULL)) {
|
||
|
do {
|
||
|
gtk_tree_model_get(model, &item, SCRIPTS_OBJECT,
|
||
|
&obj, -1);
|
||
|
|
||
|
if (obj == script) {
|
||
|
gm_scripts_dialog_tree_update_script_item(script, &item);
|
||
|
break;
|
||
|
}
|
||
|
} while (gtk_tree_model_iter_next(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();
|
||
|
}
|
||
|
|
||
|
gboolean
|
||
|
gm_scripts_dialog_add_file(gchar *filename) {
|
||
|
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(filename, strlen(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,
|
||
|
-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 item, share, home, parent;
|
||
|
GtkTreePath *path;
|
||
|
gchar *sharedir;
|
||
|
gchar *name;
|
||
|
GList *scripts;
|
||
|
GmScript *script;
|
||
|
|
||
|
sharedir = g_strdup(PACKAGE_DATA_DIR "/" PACKAGE "/scripts");
|
||
|
|
||
|
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);
|
||
|
|
||
|
name = g_filename_to_utf8(script->filename, strlen(script->filename),
|
||
|
NULL, NULL, NULL);
|
||
|
|
||
|
if (strncmp(sharedir, name, strlen(sharedir)) == 0) {
|
||
|
parent = share;
|
||
|
} else {
|
||
|
parent = home;
|
||
|
}
|
||
|
|
||
|
gtk_tree_store_append(model, &item, &parent);
|
||
|
gtk_tree_store_set(model, &item, SCRIPTS_NAME,
|
||
|
g_strrstr(name, "/") + 1, -1);
|
||
|
|
||
|
g_free(name);
|
||
|
}
|
||
|
|
||
|
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);
|
||
|
|
||
|
g_free(sharedir);
|
||
|
}
|
||
|
|
||
|
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),
|
||
|
TRUE);
|
||
|
gtk_source_view_set_auto_indent(GTK_SOURCE_VIEW(view), TRUE);
|
||
|
gtk_source_view_set_show_line_numbers(GTK_SOURCE_VIEW(view), TRUE);
|
||
|
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);
|
||
|
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);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
gm_scripts_dialog_run(GmAppView *view) {
|
||
|
GtkWidget *editor;
|
||
|
|
||
|
if (scripts_dialog->dialog != NULL) {
|
||
|
gtk_widget_show(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");
|
||
|
|
||
|
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);
|
||
|
}
|
||
|
|
||
|
|
||
|
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;
|
||
|
|
||
|
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) {
|
||
|
info->filename = g_strconcat(
|
||
|
PACKAGE_DATA_DIR "/" PACKAGE "/scripts/", name, NULL);
|
||
|
} else {
|
||
|
info->filename = g_strconcat(gm_app_path(gm_app_instance()),
|
||
|
"/scripts/", name, NULL);
|
||
|
}
|
||
|
|
||
|
g_free(name);
|
||
|
g_free(parentName);
|
||
|
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;
|
||
|
|
||
|
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);
|
||
|
gtk_text_buffer_set_modified(scripts_dialog->text_buffer_editor, FALSE);
|
||
|
} 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));
|
||
|
|
||
|
if (gm_scripts_dialog_editor_save(filename)) {
|
||
|
gtk_text_buffer_set_modified(scripts_dialog->text_buffer_editor,
|
||
|
FALSE);
|
||
|
}
|
||
|
|
||
|
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);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Callbacks
|
||
|
|
||
|
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->filename);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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) {
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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
|