#ifdef HAVE_CONFIG_H # include #endif #ifdef HAVE_RUBY #include #include #include #include #include #include #include #include #include #include #include #include #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\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 GM_SCRIPTS_DIALOG_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; 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); } g_object_unref(G_OBJECT(lm)); gm_register_schemed(view, gm_app_color_table(gm_app_instance()), GM_SCHEMED_FONT | GM_SCHEMED_COLORS); 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(GM_SCRIPTS_DIALOG_XML, "gm_scripts_dialog", NULL); if (scripts_dialog->xml == NULL) { gm_debug_msg(DEBUG_ALWAYS, "Couldn't find glade file %s!", GM_SCRIPTS_DIALOG_XML); return; } 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 (scripts_dialog->current_edit && 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