/* * Copyright (C) 2004-2005 Vadim Berezniker * http://www.kryptolus.com * * This Program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This Program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * http://www.gnu.org/copyleft/gpl.html * */ #include "stdafx.h" #include "common.h" #include "sabbu.h" #include "kryArray.h" #include "kryString.h" #include "krySSACommandParser.h" #include "krySSACommandHighlighter.h" #include "gui_text_editor.h" #include "gui_main_event.h" #include "gui_main_karaoke.h" #include "gui_event_list.h" #include "gui_event_tree.h" #include "sound.h" #include "stringutils.h" extern struct sabbu app; void gui_main_menu_event_join(gpointer callback_data, guint callback_action, GtkWidget *menu_item) { GtkTreeModel *model; GtkTreeSelection *selection = gui_event_list_get_selection(app.ui.event_list); GList *sel_items = gtk_tree_selection_get_selected_rows(selection, &model); GList *group = NULL; GList *lines, *ptr; // convert to references because we will be deleting rows which will not work with plain GtkTreePaths for(ptr = sel_items; ptr; ptr = ptr->next) { GtkTreePath *path = (GtkTreePath *) ptr->data; ptr->data = gtk_tree_row_reference_new(model, path); } /* We must break up the selection into groups. Any adjacent selected lines are counted as a group */ for(ptr = sel_items; ptr; ptr = ptr->next) { GtkTreePath *path = gtk_tree_row_reference_get_path((GtkTreeRowReference *) ptr->data); /* If the group is empty, or the next selected item comes right after the last selected item, add it to the group */ if(group == NULL || gtk_tree_path_get_indices(path)[0] == gtk_tree_path_get_indices(gtk_tree_row_reference_get_path((GtkTreeRowReference *) g_list_last(group)->data))[0] + 1) { GtkTreeIter iter; kryEvent *line; GtkTreePath *lPath = gtk_tree_row_reference_get_path((GtkTreeRowReference *) ptr->data); gtk_tree_model_get_iter(model, &iter, lPath); gtk_tree_model_get(model, &iter, PTR_COLUMN, &line, -1); if(line->GetType() != kryEvent::EVENT_BLANK && line->GetType() != kryEvent::EVENT_COMMENT_STRING && line->GetType() != kryEvent::EVENT_COMMENT_BLANK) group = g_list_append(group, ptr->data); if(ptr->next != NULL) continue; } /* We finished gathering the group elements */ if(g_list_length(group) != 1) { GList *list_text = NULL; int lineLen = 0; char *newLine; int offset = 0; long min_start = -1; long max_end = -1; for(lines = group; lines; lines = lines->next) { kryEvent *line; GtkTreeIter iter; GtkTreePath *lPath = gtk_tree_row_reference_get_path((GtkTreeRowReference *) lines->data); gtk_tree_model_get_iter(model, &iter, lPath); gtk_tree_model_get(model, &iter, PTR_COLUMN, &line, -1); list_text = g_list_append(list_text, line->GetText()); lineLen += strlen(line->GetText()) + (app.opts.join_2spaces ? 2 : 1); if(line->GetStart() != 0 && line->GetEnd() != 0) { if(min_start == -1 || line->GetStart() < (unsigned long) min_start) min_start = line->GetStart(); if(max_end == -1 || line->GetEnd() > (unsigned long) max_end) max_end = line->GetEnd(); } } lineLen++; if(min_start == -1 && max_end == -1) { min_start = 0; max_end = 0; } /* Paste all the strings together */ newLine = (char *) kry_malloc(lineLen); for(lines = list_text; lines; lines = lines->next) { char *text = (char *) lines->data; int nCopy = strlen(text); int nIgnore = 0; int i; for(i = nCopy - 1; i >= 0 && text[i] == ' '; i--) nCopy--; for(i = 0; (unsigned int) i < strlen(text) && text[i] == ' '; i++) nIgnore++; if(nCopy == 0) nIgnore = 0; memcpy(newLine + offset, text + nIgnore, nCopy - nIgnore); offset += (nCopy - nIgnore); newLine[offset] = ' '; offset++; if(app.opts.join_2spaces && offset - 2 >= 0) { if( ((newLine[offset - 2] == '.' && (offset - 4 < 0 || newLine[offset - 3] != '.' && newLine[offset - 4] != '.')) || newLine[offset - 2] == '?') || newLine[offset - 2] == '!') { newLine[offset] = ' '; offset++; } } } newLine[offset] = 0; for(lines = group; lines; lines = lines->next) { kryEventDetailed *line; GtkTreeIter iter; GtkTreePath *lPath = gtk_tree_row_reference_get_path((GtkTreeRowReference *) lines->data); // if it's the first line, we put the entire text there, otherwise we delete if(lines == group) { gtk_tree_model_get_iter(model, &iter, lPath); gtk_tree_model_get(model, &iter, PTR_COLUMN, &line, -1); line->SetText(newLine); line->SetTime(min_start, max_end); gui_event_list_update_line(app.ui.event_list, line, &iter); } else { gtk_tree_model_get_iter(model, &iter, lPath); gtk_tree_model_get(model, &iter, PTR_COLUMN, &line, -1); app.script->RemoveEvent(line); gtk_list_store_remove(GTK_LIST_STORE(model), &iter); delete line; } app.script->SetModifiedFlag(TRUE); } g_list_free(list_text); kry_free(newLine); } g_list_free(group); group = NULL; if(ptr->next != NULL) ptr = ptr->prev; } g_list_free(group); for(ptr = sel_items; ptr; ptr = ptr->next) { GtkTreeRowReference *ref = (GtkTreeRowReference *) ptr->data; GtkTreePath *path = gtk_tree_row_reference_get_path(ref); gtk_tree_row_reference_free(ref); gtk_tree_path_free(path); } g_list_free(sel_items); } void gui_main_menu_event_split(gpointer callback_data, enum event_split_type split_type, GtkWidget *menu_item) { GtkTreeModel *model; GtkTreeSelection *selection = gui_event_list_get_selection(app.ui.event_list); GList *sel_items = gtk_tree_selection_get_selected_rows(selection, &model); GList *ptr; gboolean c_split = FALSE; if(split_type == EVENT_SPLIT_CURSOR) c_split = TRUE; for(ptr = sel_items; ptr; ptr = ptr->next) { GtkTreePath *path = (GtkTreePath *) ptr->data; ptr->data = gtk_tree_row_reference_new(model, path); } if(c_split == 1 && !sel_items) return; for(ptr = sel_items; ptr; ptr = ptr->next) { GtkTreePath *path = gtk_tree_row_reference_get_path((GtkTreeRowReference *) ptr->data); kryEventDetailed *line; kryEventDetailed *line2; int split_idx = -1; int space_idx = -1; char *part1, *part2; GtkTreeIter iter, iter_new; int event_length; int len; int i; gtk_tree_model_get_iter(model, &iter, path); gtk_tree_model_get(model, &iter, PTR_COLUMN, &line, -1); if(line->GetType() == kryEvent::EVENT_BLANK || line->GetType() == kryEvent::EVENT_COMMENT_STRING || line->GetType() == kryEvent::EVENT_COMMENT_BLANK) continue; if(c_split == TRUE) { GtkTextIter iter; GtkTextBuffer *buffer = gui_text_editor_get_buffer(app.ui.text_editor); GtkTextMark *mark = gtk_text_buffer_get_mark(buffer, "insert"); gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); split_idx = gtk_text_iter_get_offset(&iter); if(split_idx == 0 || gtk_text_iter_ends_line(&iter)) { for(ptr = sel_items; ptr; ptr = ptr->next) { GtkTreeRowReference *ref = (GtkTreeRowReference *) ptr->data; GtkTreePath *path = gtk_tree_row_reference_get_path(ref); gtk_tree_row_reference_free(ref); gtk_tree_path_free(path); } g_list_free(sel_items); return; } gui_main_event_current_save_text(); char *text = gui_text_editor_get_text(app.ui.text_editor, &split_idx, NULL); split_idx = g_utf8_offset_to_pointer(text, split_idx) - text; kry_free(text); } else { char *line_text = line->GetText(); char *ptr = line_text; for(i = 0; i < (int) g_utf8_strlen(line_text, -1); i++) { gunichar uchar = g_utf8_get_char(ptr); if(uchar == ' ') space_idx = i; if(i != 0 && g_utf8_strlen(line_text, -1) / (i * 2) == 0 && uchar == ' ') { split_idx = i; break; } ptr = g_utf8_next_char(ptr); } if(split_idx != -1) split_idx = g_utf8_offset_to_pointer(line_text, split_idx) - line_text; if(space_idx != -1) space_idx = g_utf8_offset_to_pointer(line_text, space_idx) - line_text; } if(split_idx == -1) split_idx = space_idx; if(split_idx == -1) continue; app.script->SetModifiedFlag(TRUE); part1 = (char *) kry_malloc(split_idx + 1); memcpy(part1, line->GetText(), split_idx); part1[split_idx] = 0; for(i = split_idx - 1; i >= 0 && part1[i] == ' '; i--) // remove spaces at the end part1[i] = 0; part2 = (char *) kry_malloc(strlen(line->GetText()) - split_idx + (c_split == 1 ? 1 : 0)); memcpy(part2, line->GetText() + split_idx + (c_split == 1 ? 0 : 1), strlen(line->GetText()) - split_idx - (c_split == 1 ? 0 : 1)); part2[strlen(line->GetText()) - split_idx + (c_split == 1 ? 1 : 0) - 1] = 0; // remove spaces at the beginning for(i = 0; i < (int) strlen(part2) && part2[i] == ' '; i++); if(i != 0) { char *tmp = (char *) kry_malloc(strlen(part2) - i + 1); memcpy(tmp, part2 + i, strlen(part2) - i); tmp[strlen(part2) - i] = 0; kry_free(part2); part2 = tmp; } if(app.ui.karaoke_mode == KARAOKE_MODE_LINE) { GList *words = g_list_append(NULL, part1); words = g_list_append(words, part2); gui_main_karaoke_split_word_real(words); g_list_free(words); kry_free(part1); kry_free(part2); break; } // first selected line if(ptr == sel_items) gui_text_editor_set_text(app.ui.text_editor, part1); event_length = line->GetEnd() - line->GetStart(); len = strlen(line->GetText()); line->SetTime(line->GetStart(), (long) (line->GetStart() + ((double) split_idx / len) * event_length)); line->SetText(part1); kry_free(part1); gui_event_list_update_line(app.ui.event_list, line, &iter); gtk_list_store_insert_after(GTK_LIST_STORE(model), &iter_new, &iter); line2 = line->Copy(); GtkTreePath *insert_pos = gtk_tree_model_get_path(model, &iter_new); app.script->InsertEvent(line2, gtk_tree_path_get_indices(insert_pos)[0]); gtk_tree_path_free(insert_pos); int start = line->GetEnd() + (event_length > 0 ? 10 : 0); int end = start + (event_length - (line->GetEnd() - line->GetStart())) - (event_length > 0 ? 10 : 0); line2->SetTime(start, end); line2->SetText(part2); kry_free(part2); gui_event_list_update_line(app.ui.event_list, line2, &iter_new); if(split_type == EVENT_SPLIT_CURSOR) break; } for(ptr = sel_items; ptr; ptr = ptr->next) { GtkTreeRowReference *ref = (GtkTreeRowReference *) ptr->data; GtkTreePath *path = gtk_tree_row_reference_get_path(ref); gtk_tree_row_reference_free(ref); gtk_tree_path_free(path); } g_list_free(sel_items); gui_event_list_color_collisions(app.ui.event_list); } void gui_main_menu_event_paste(gpointer callback_data, enum event_action_loc paste_loc, GtkWidget *menu_item) { GtkTreeModel *model; GtkTreeSelection *selection = gui_event_list_get_selection(app.ui.event_list); GList *list_orig = gtk_tree_selection_get_selected_rows(selection, &model); GList *list = list_orig; GtkTreePath *path; GtkTreeIter iter, parent; kryListIterator iter_clipboard; kryEventDetailed *line; kryEventDetailed *ref; int ref_index; app.ui.clipboard_events.GetIterator(&iter_clipboard); if(!list || !app.ui.clipboard_events.GetLength()) { g_list_foreach(list_orig, (GFunc) gtk_tree_path_free, NULL); g_list_free(list_orig); return; } if(paste_loc == EVENT_PASTE_AFTER) while(list && list->next) list = list->next; path = (GtkTreePath *) list->data; ref_index = gtk_tree_path_get_indices(path)[0]; ref = app.script->GetEvent(ref_index); gtk_tree_model_get_iter(model, &parent, path); while((line = iter_clipboard.GetNext())) { line = line->Copy(); if(paste_loc == EVENT_PASTE_AFTER) { app.script->InsertEvent(line, ref_index + 1); ref_index++; gtk_list_store_insert_after(GTK_LIST_STORE(model), &iter, &parent); } else { app.script->InsertEvent(line, ref_index); ref_index++; gtk_list_store_insert_before(GTK_LIST_STORE(model), &iter, &parent); } gui_event_list_update_line(app.ui.event_list, line, &iter); if(paste_loc == EVENT_PASTE_AFTER) parent = iter; } g_list_foreach(list_orig, (GFunc) gtk_tree_path_free, NULL); g_list_free(list_orig); app.script->SetModifiedFlag(TRUE); gui_event_list_update_blank_count(app.ui.event_list); gui_event_list_append_blank_rows(app.ui.event_list, 10 - app.script->GetBlankCount()); } void gui_main_menu_number_events(GtkWidget *menu, void *param) { /*GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file("c:\\stock.png", NULL); int width, height, rowstride, n_channels; guchar *pixels, *p; n_channels = gdk_pixbuf_get_n_channels (pixbuf); width = gdk_pixbuf_get_width (pixbuf); height = gdk_pixbuf_get_height (pixbuf); rowstride = gdk_pixbuf_get_rowstride (pixbuf); pixels = gdk_pixbuf_get_pixels (pixbuf); GList *parts = NULL; int len = 0; app.script->GetEventList().Clear(); for(int y = 0; y < height; y++) { for(int x = width - 1; x >= 0; x--) { char *str; p = pixels + y * rowstride + x * n_channels; if(p[3] == 0) continue; int offsetx = 30; int offsety = 1; int posx = (x) + offsetx; int posy = (y) + offsety; int clipx1 = posx + 4; int clipx2 = posx + 5; int clipy1 = posy + 10; int clipy2 = posy + 11; str = kry_strdup_printf(KRY_LOC "{\\move(%d,%d,%d,%d,0,1000)\\1a&H%02X\\1c&H%02X%02X%02X\\a4\\pos(%d,%d)\\clip(%d,%d,%d,%d)}\xE2\x96\xA0", 0, 0, posx, posy, 255 - p[3], p[2], p[1], p[0], posx, posy, clipx1, clipy1, clipx2, clipy2); //str = kry_strdup_printf(KRY_LOC "{\\pos(%d,%d)\\1c&%02X%02X%02X\\clip(%d,%d,%d,%d)\\p1}m 0 0 l 10 0 10 10 0 10", // x + 50, y + 50, p[2], p[1], p[0], x + 50 - 2, y + 50- 5, x + 50 - 1, y + 50 - 4); //g_warning(str); //str = kry_strdup_printf(KRY_LOC "{\\pos(%d,%d)\\fs1\\3c&%02X%02X%02X}XX", (x * 4) + 50, (y * 4) + 50, p[2], p[1], p[0]); kryEventDetailed *event = new kryEventDetailed(); event->SetStart(0); event->SetEnd(1000000); event->SetText(str); app.script->AddEvent(event); kry_free(str); //p[0] = red; //p[1] = green; //p[2] = blue; //p[3] = alpha; } } gui_event_list_fill_from_list_detailed(app.ui.event_list, &app.script->GetEventList(), TRUE); return;*/ /*int index = 0; kryEventDetailed *event; kryListIterator iter; app.script->GetEventIterator(&iter); while(event = iter.GetNext()) { if(event->GetType() != kryEvent::EVENT_DIALOG) continue; if(!strcmp(event->GetStyle(), "Default") || !strcmp(event->GetStyle(), "Default 2")) { char *text = event->GetText(); char *new_text = kry_strdup_printf(KRY_LOC "(%d) %s", index, text); index++; event->SetText(new_text); kry_free(new_text); } }*/ /*kryEventDetailed *event; kryListIterator iter; app.script->GetEventIterator(&iter); while(event = iter.GetNext()) { if(event->GetType() != kryEvent::EVENT_DIALOG) continue; char *str = event->GetText(); char *val = string_read_token(&str, ')', TRUE); if(!val || strlen(val) > 4) { if(val) kry_free(val); continue; } char *newstr = kry_strdup(string_ignore_whitespce(str + 1)); event->SetText(newstr); kry_free(newstr); } */ } void gui_main_menu_event_clipboard(gpointer callback_data, enum event_action action, GtkWidget *menu_item) { GtkTreeModel *model; GtkTreeSelection *selection = gui_event_list_get_selection(app.ui.event_list); GList *list = gtk_tree_selection_get_selected_rows(selection, &model); GList *list_ref = NULL, *ptr; GtkTreeIter iter; gboolean row_valid = FALSE; kryEventDetailed *line; int index; if(!list) return; /* We must convert the tree paths to references because paths will point to wrong nodes once rows are deleted. */ ptr = list; while(ptr) { GtkTreeRowReference *ref = gtk_tree_row_reference_new(model, (GtkTreePath *) ptr->data); list_ref = g_list_append(list_ref, ref); ptr=ptr->next; } if(action == EVENT_COPY || action == EVENT_CUT) { kryListIterator iter; app.ui.clipboard_events.GetIterator(&iter); while(kryEvent *event = iter.GetNext()) delete event; app.ui.clipboard_events.Clear(); } ptr = list_ref; while(ptr) { GtkTreePath *path = gtk_tree_row_reference_get_path((GtkTreeRowReference *) ptr->data); gtk_tree_model_get_iter(model, &iter, (GtkTreePath *) path); gtk_tree_model_get(model, &iter, PTR_COLUMN, &line, -1); index = gtk_tree_path_get_indices(path)[0]; // allow user to delete, but not copy or paste, blank events if((action == EVENT_DELETE && gtk_tree_path_get_indices(path)[0] < app.script->GetEventCount() - app.script->GetBlankCount()) || line->GetType() != kryEvent::EVENT_BLANK && line->GetType() != kryEvent::EVENT_COMMENT_STRING && line->GetType() != kryEvent::EVENT_COMMENT_BLANK) { if(action != EVENT_COPY) app.script->SetModifiedFlag(TRUE); if(action == EVENT_COPY || action == EVENT_CUT) { kryEventDetailed *event_copy = line->Copy(); app.ui.clipboard_events.Append(event_copy); } if(action == EVENT_CUT || action == EVENT_DELETE) { app.script->RemoveEvent(line); row_valid = gtk_list_store_remove(GTK_LIST_STORE(model), &iter); delete line; } } ptr=ptr->next; } ptr = list_ref; while(ptr) { gtk_tree_row_reference_free((GtkTreeRowReference *) ptr->data); ptr = ptr->next; } g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL); g_list_free(list); if(row_valid) gtk_tree_selection_select_iter(selection, &iter); gui_event_list_update_blank_count(app.ui.event_list); } void gui_main_menu_event_add(gpointer callback_data, enum event_action_loc add_loc, GtkWidget *menu_item) { GtkTreeIter iter; GtkTreeIter iter_new; GtkTreeModel *model; GtkTreeSelection *selection = gui_event_list_get_selection(app.ui.event_list); GList *list_orig = gtk_tree_selection_get_selected_rows(selection, &model); GList *list = list_orig; kryEventDetailed *line; kryEventDetailed *line_orig; GList *ptr; int index; int num_selected; if(!list) return; num_selected = g_list_length(list); ptr = list; if(add_loc == EVENT_ADD_BLANK_AFTER || add_loc == EVENT_ADD_SEPARATOR_AFTER) while(list && list->next) list = list->next; app.script->SetModifiedFlag(TRUE); gtk_tree_model_get_iter(model, &iter, (GtkTreePath *) list->data); if(add_loc == EVENT_ADD_BLANK_AFTER || add_loc == EVENT_ADD_SEPARATOR_AFTER) gtk_list_store_insert_after(GTK_LIST_STORE(model), &iter_new, &iter); else if(add_loc == EVENT_ADD_BLANK_BEFORE || add_loc == EVENT_ADD_SEPARATOR_BEFORE) gtk_list_store_insert_before(GTK_LIST_STORE(model), &iter_new, &iter); line = new kryEventDetailed(); if(add_loc == EVENT_ADD_SEPARATOR_AFTER || add_loc == EVENT_ADD_SEPARATOR_BEFORE) { line->SetType(kryEvent::EVENT_COMMENT_BLANK); line->SetText(""); line->SetStyle(""); line->SetPrefix(""); } else { line->SetType(kryEvent::EVENT_BLANK); } line_orig = line; gtk_list_store_set(GTK_LIST_STORE(model), &iter_new, FLAGS_COLUMN, "", START_COLUMN, "", END_COLUMN, "", DUR_COLUMN, "", STYLE_COLUMN, "", NAME_COLUMN, "", TEXT_COLUMN, "", PTR_COLUMN, line, -1); index = gtk_tree_path_get_indices((GtkTreePath *) list->data)[0]; if(add_loc == EVENT_ADD_BLANK_AFTER || add_loc == EVENT_ADD_SEPARATOR_AFTER) index++; app.script->InsertEvent(line_orig, index); gui_event_list_update_blank_count(app.ui.event_list); if(num_selected == 1 && (add_loc != EVENT_ADD_SEPARATOR_AFTER && add_loc != EVENT_ADD_SEPARATOR_BEFORE)) { gtk_tree_selection_unselect_all(selection); gtk_tree_selection_select_iter(selection, &iter_new); } g_list_foreach (list_orig, (GFunc) gtk_tree_path_free, NULL); g_list_free(list_orig); } void gui_main_menu_event_type(GtkWidget *menu_item, gpointer data) { GtkTreeIter iter; GtkTreeModel *model; GtkTreeSelection *selection = gui_event_list_get_selection(app.ui.event_list); GList *sel_items = gtk_tree_selection_get_selected_rows(selection, &model); kryEventDetailed *line; GList *ptr; if(!sel_items) return; app.script->SetModifiedFlag(TRUE); ptr = sel_items; while(ptr) { gtk_tree_model_get_iter(model, &iter, (GtkTreePath *) ptr->data); gtk_tree_model_get(model, &iter, PTR_COLUMN, &line, -1); if(line->GetType() != kryEvent::EVENT_BLANK && line->GetType() != kryEvent::EVENT_COMMENT_STRING && line->GetType() != kryEvent::EVENT_COMMENT_BLANK) { if(line->GetType() == kryEvent::EVENT_BLANK) line->SetTypeSub((enum kryEvent::event_type) ((long) data)); else line->SetType ((enum kryEvent::event_type) ((long) data)); if((long) data == kryEvent::EVENT_COMMENT_DIALOG) gui_event_tree_remove_event(line); else if((long) data == kryEvent::EVENT_DIALOG) gui_event_tree_add_event(line); gui_event_list_color_collisions(app.ui.event_list); gui_event_list_update_line(app.ui.event_list, line, &iter); } ptr = ptr -> next; } g_list_foreach (sel_items, (GFunc) gtk_tree_path_free, NULL); g_list_free(sel_items); } void gui_main_event_current_save_text() { GtkTreeModel *model; GtkTreeSelection *selection = gui_event_list_get_selection(app.ui.event_list); GList *sel_items = gtk_tree_selection_get_selected_rows(selection, &model); char *text_old, *text; kryEvent *line; if(!sel_items) return; GtkTreeIter iter; gtk_tree_model_get_iter(model, &iter, (GtkTreePath *) sel_items->data); gtk_tree_model_get(model, &iter, TEXT_COLUMN, &text_old, PTR_COLUMN, &line, -1); text_old = KRY_TS(text_old); g_list_foreach (sel_items, (GFunc) gtk_tree_path_free, NULL); g_list_free(sel_items); if(line->GetType() == kryEvent::EVENT_BLANK || line->GetType() == kryEvent::EVENT_COMMENT_BLANK) return; text = gui_text_editor_get_text(app.ui.text_editor); if(!strcmp(text, text_old)) { kry_free(text); return; } app.script->SetModifiedFlag(TRUE); line->SetText(text); gtk_list_store_set(GTK_LIST_STORE(model), &iter, TEXT_COLUMN, text, -1); kry_free(text); } void gui_event_name_list_clear() { app.ui.name_store_rows = 0; gtk_list_store_clear(app.ui.name_store); } void gui_event_name_list_add(char *name) { if(app.ui.name_store_rows == 20) return; if(!strcmp(name, "")) return; GtkTreeIter iter; gtk_list_store_append(app.ui.name_store, &iter); gtk_list_store_set(app.ui.name_store, &iter, 0, name, -1); app.ui.name_store_rows++; } void gui_event_name_list_remove(char *name) { GtkTreeIter iter; if(!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(app.ui.name_store), &iter)) return; do { char *name_row; gtk_tree_model_get(GTK_TREE_MODEL(app.ui.name_store), &iter, 0, &name_row, -1); name_row = KRY_TS(name_row); if(!strcmp(name, name_row)) { gtk_list_store_remove(app.ui.name_store, &iter); app.ui.name_store_rows--; if(app.ui.name_store_rows == 19 && app.script->GetNameCount() > 20) gui_event_name_list_add(app.script->GetNthName(19)); kry_free(name_row); return; } kry_free(name_row); } while(gtk_tree_model_iter_next(GTK_TREE_MODEL(app.ui.name_store), &iter)); }