/* * 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_main_event.h" #include "sound.h" #include "gui_status_bar.h" #include "gui_text_editor.h" #include "gui_time_entry.h" #include "gui_main_karaoke.h" #include "gui_event_list.h" #include "stringutils.h" #include "pavl.h" extern struct sabbu app; void gui_event_list_update_blank_count(struct KryEventList *event_list) { struct kryListNode *node = app.script->GetEventList().m_tail; int count = 0; while(node) { kryEvent *line = (kryEvent *) node->data; if(line->GetType() != kryEvent::EVENT_BLANK) break; count++; node = node->prev; } app.script->SetBlankCount(count); } /*void gui_event_list_collision_cb(kryScript *script, int index) { gui_event_list_set_row_color(index, COLOR_COLLISION); }*/ void gui_event_list_set_row_color(struct KryEventList *event_list, int index, enum event_list_color col_color) { char *color = NULL; char *path_str; GtkTreePath *path; GtkTreeIter iter; if(col_color == LIST_COLOR_NONE) color = NULL; else color = (char *) app.ui.list_color_table->GetUserData(col_color); path_str = kry_strdup_printf(KRY_LOC "%d", index); path = gtk_tree_path_new_from_string(path_str); gtk_tree_model_get_iter(GTK_TREE_MODEL(event_list->store), &iter, path); gtk_list_store_set(event_list->store, &iter, COLOR_COLUMN, color, -1); kry_free(path_str); gtk_tree_path_free(path); } void gui_event_list_color_collisions(struct KryEventList *event_list) { GtkTreeModel *model; GtkTreeSelection *selection = gtk_tree_view_get_selection(event_list->view); GList *sel_items = gtk_tree_selection_get_selected_rows(selection, &model); GtkTreePath *path; GtkTreeIter iter; kryEventDetailed *line; if(!sel_items) return; for(GList *ptr = sel_items; ptr; ptr = ptr->next) { path = (GtkTreePath *) ptr->data; 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_DIALOG) { kryListIterator iter_col; app.script->GetCollisionIterator(&iter_col); kryEventDetailed *line_col; while((line_col = iter_col.GetNext())) { if(line_col->GetCollisionHighlighted()) { gui_event_list_set_row_color(event_list, line_col->GetIndex(), LIST_COLOR_COLLISION); line_col->SetCollisionHighlighted(FALSE); } } } if(line->GetType() == kryEvent::EVENT_DIALOG) { kryListIterator iter_col; app.script->GetCollisionIterator(&iter_col); kryEventDetailed *line_col; while((line_col = iter_col.GetNext())) { if(line_col->GetCollisionHighlighted()) { gui_event_list_set_row_color(event_list, line_col->GetIndex(), LIST_COLOR_COLLISION); line_col->SetCollisionHighlighted(FALSE); } if(line->GetCollisionAdded()) { kryEventDetailed *line; for(GList *sel = sel_items; sel; sel=sel->next) { gtk_tree_model_get_iter(model, &iter, (GtkTreePath *) sel->data); gtk_tree_model_get(model, &iter, PTR_COLUMN, &line, -1); if(line_col->GetLayer() == line->GetLayer() && (line_col->GetEnd() > line->GetStart() && line_col->GetStart() < line->GetEnd() || line_col->GetStart() < line->GetEnd() && line_col->GetEnd() > line->GetStart())) { line_col->SetCollisionHighlighted(TRUE); gui_event_list_set_row_color(event_list, line_col->GetIndex(), LIST_COLOR_COLLISION_HIGHLIGHT); } } } } } } g_list_foreach(sel_items, (GFunc) gtk_tree_path_free, NULL); g_list_free(sel_items); } void gui_event_list_selection_changed_cb(GtkTreeSelection *selection, struct KryEventList *event_list) { GtkTreeModel *model; GList *sel_items = gtk_tree_selection_get_selected_rows(selection, &model); GtkTreePath *path; GtkTreeIter iter; kryEventDetailed *line; char *style, *name; if(!app.script) return; if(!sel_items) return; path = (GtkTreePath *) sel_items->data; gtk_tree_model_get_iter(model, &iter, path); gtk_tree_model_get(model, &iter, STYLE_COLUMN, &style, NAME_COLUMN, &name, PTR_COLUMN, &line, -1); style = KRY_TS(style); name = KRY_TS(name); app.ui.tab_video.posx = -1; app.ui.tab_video.posy = -1; gui_text_editor_set_text(app.ui.text_editor, line->GetText() != NULL ? line->GetText() : (char *) ""); if(line->GetType() == kryEvent::EVENT_BLANK || line->GetType() == kryEvent::EVENT_COMMENT_STRING || line->GetType() == kryEvent::EVENT_COMMENT_BLANK) { if(app.ui.karaoke_mode == KARAOKE_MODE_BOX) gui_main_karaoke_off(); gtk_spin_button_set_value(app.ui.spin_layer, 0); gui_combo_box_set_text(app.ui.combo_style, "Default"); gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(app.ui.combo_name))), ""); } else { gboolean is_box_karaoke_mode = (app.ui.karaoke_mode == KARAOKE_MODE_BOX); if(is_box_karaoke_mode) { gui_karaoke_events_empty(); } else if(app.ui.karaoke_mode == KARAOKE_MODE_LINE) { gui_karaoke_set_selected_event(line); } gboolean nojump = app.opts.disable_automatic_wave_jump; if(!app.ui.sound_info) nojump = FALSE; if(((!nojump && app.ui.time_modified == FALSE && line->GetType() != kryEvent::EVENT_BLANK) || is_box_karaoke_mode) && (line->GetStart() != 0 || line->GetEnd() != 0) && app.ui.karaoke_mode == KARAOKE_MODE_OFF) { kry_marker_set_value(app.ui.marker_active_start, line->GetStart()); kry_marker_set_value(app.ui.marker_active_end, line->GetEnd()); kry_marker_set_value(app.ui.tab_video.marker_start, line->GetStart()); gui_main_set_time_modified(FALSE); if(g_object_get_data(G_OBJECT(event_list->view), "disable-auto-focus") == NULL && app.ui.karaoke_mode != KARAOKE_MODE_LINE) kry_waveform_group_focus_selected(app.ui.waveform_group); } if(is_box_karaoke_mode) { gui_main_karaoke_fill_list(); } gtk_widget_queue_draw(GTK_WIDGET(app.ui.video_area)); // changing the layer causes the handler to think the selected lines' layers have changed which // might make the script be marked as modified even if it is not // we set a custom variable which the callback checks to see if the user caused the event or not g_signal_handlers_block_by_func(app.ui.spin_layer, (void *) (gui_main_layer_style_changed_cb), NULL); gtk_spin_button_set_value(app.ui.spin_layer, line->GetLayer()); g_signal_handlers_unblock_by_func(app.ui.spin_layer, (void *) (gui_main_layer_style_changed_cb), NULL); g_signal_handlers_block_by_func(app.ui.combo_name, (void *) (gui_main_entry_name_changed_cb), app.ui.combo_name); g_signal_handlers_block_by_func(app.ui.combo_style, (void *) (gui_main_entry_style_changed_cb), NULL); if(style) gui_combo_box_set_text(app.ui.combo_style, style); g_signal_handlers_unblock_by_func(app.ui.combo_style, (void *) (gui_main_entry_style_changed_cb), NULL); if(name && strcmp(name, "")) gui_combo_box_set_text(app.ui.combo_name, name); else gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(app.ui.combo_name))), ""); g_signal_handlers_unblock_by_func(app.ui.combo_name, (void *) (gui_main_entry_name_changed_cb), app.ui.combo_name); } kry_free(style); if(name) kry_free(name); gui_event_list_color_collisions(event_list); g_list_foreach (sel_items, (GFunc) gtk_tree_path_free, NULL); g_list_free(sel_items); } void gui_event_list_disable_selection_event(struct KryEventList *event_list) { GtkTreeSelection *selection = gtk_tree_view_get_selection(event_list->view); g_signal_handlers_block_by_func(selection, (void *) (gui_event_list_selection_changed_cb), event_list); } void gui_event_list_enable_selection_event(struct KryEventList *event_list) { GtkTreeSelection *selection = gtk_tree_view_get_selection(event_list->view); g_signal_handlers_unblock_by_func(selection, (void *) (gui_event_list_selection_changed_cb), event_list); } void gui_event_list_index_column_data_cb(GtkTreeViewColumn *column, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, struct KryEventList *event_list) { GtkTreePath *path = gtk_tree_model_get_path(model, iter); char *text = kry_strdup_printf(KRY_LOC "%d", gtk_tree_path_get_indices(path)[0] + 1); g_object_set(renderer, "text", text, NULL); kry_free(text); gtk_tree_path_free(path); } GtkTreeSelection *gui_event_list_get_selection(struct KryEventList *event_list) { return gtk_tree_view_get_selection(event_list->view); } gboolean gui_event_list_is_first_selected_row(struct KryEventList *event_list, GtkTreePath *path) { GtkTreeModel *model; GtkTreeSelection *selection = gtk_tree_view_get_selection(event_list->view); GList *sel = gtk_tree_selection_get_selected_rows(selection, &model); if(!sel) { g_warning("checking selection, but selection is empty..."); return false; } int rv = gtk_tree_path_compare(path, (GtkTreePath *) sel->data); g_list_foreach(sel, GFunc(gtk_tree_path_free), NULL); g_list_free(sel); return rv == 0; } void gui_event_list_text_column_editing_started_cb(GtkCellRendererText *renderer, GtkCellEditable *editable, gchar *pathstr, struct KryEventList *event_list) { GtkTreePath *path = gtk_tree_path_new_from_string(pathstr); GtkTreeIter iter; kryEvent *event; gtk_tree_model_get_iter(GTK_TREE_MODEL(event_list->store), &iter, path); gtk_tree_model_get(GTK_TREE_MODEL(event_list->store), &iter, PTR_COLUMN, &event, -1); if(event->GetType() == kryEvent::EVENT_KARAOKE_TEXT && ((kryEventKaraokeTextBox *) event)->GetIsSilence()) { if(GTK_IS_ENTRY(editable)) { GtkEntry *entry = GTK_ENTRY(editable); gtk_entry_set_text(entry, ""); } } gtk_tree_path_free(path); } void gui_event_list_handle_column_edit(struct KryEventList *event_list, int column_id, char *path_string, char *text) { GtkTreeIter iter; GtkTreePath *path = gtk_tree_path_new_from_string(path_string); kryEventDetailed *line; char *old_text; if(!app.script || text == NULL) return; gtk_tree_model_get_iter(GTK_TREE_MODEL(event_list->store), &iter, path); gtk_tree_model_get(GTK_TREE_MODEL(event_list->store), &iter, PTR_COLUMN, &line, column_id, &old_text, -1); old_text = KRY_TS(old_text); if(column_id == TEXT_COLUMN && line->GetType() == kryEvent::EVENT_KARAOKE_TEXT) { kryEventKaraokeText *event = (kryEventKaraokeText *) line; if(event->GetIsSilence() && !strcmp(string_ignore_whitespce(text), "")) return; gui_main_karaoke_split_word(text); return; } if(column_id != TEXT_COLUMN && line->GetType() == kryEvent::EVENT_COMMENT_STRING || line->GetType() == kryEvent::EVENT_COMMENT_BLANK) return; if(line->GetType() == kryEvent::EVENT_BLANK) { if(!strcmp(text, "")) { kry_free(old_text); return; } line->SetType(kryEvent::EVENT_DIALOG); line->SetStyle("Default"); line->SetName(""); line->SetText(""); gui_event_list_update_line(event_list, line, &iter); app.script->SetModifiedFlag(TRUE); gui_event_list_update_blank_count(event_list); gui_event_list_append_blank_rows(event_list, 10 - app.script->GetBlankCount()); } if(strcmp(old_text, text)) app.script->SetModifiedFlag(TRUE); gtk_list_store_set(event_list->store, &iter, column_id, text, -1); kry_free(old_text); if(column_id == TEXT_COLUMN) line->SetText(text); else if(column_id == STYLE_COLUMN) line->SetStyle(text); else if(column_id == NAME_COLUMN) line->SetName(text); if(gui_event_list_is_first_selected_row(event_list, path)) { if(column_id == TEXT_COLUMN) gui_text_editor_set_text(app.ui.text_editor, text); else if(column_id == STYLE_COLUMN) gui_combo_box_set_text(app.ui.combo_style, text); else if(column_id == NAME_COLUMN) gui_combo_box_set_text(app.ui.combo_name, text); } } void gui_event_list_text_column_edited_cb(GtkCellRendererText *renderer, gchar *path_string, gchar *text, KryEventList *event_list) { gui_event_list_handle_column_edit(event_list, TEXT_COLUMN, path_string, text); } void gui_event_list_style_column_edited_cb(GtkCellRendererCombo *renderer, gchar *path_string, gchar *text, KryEventList *event_list) { gui_event_list_handle_column_edit(event_list, STYLE_COLUMN, path_string, text); } void gui_event_list_name_column_edited_cb(GtkCellRendererCombo *renderer, gchar *path_string, gchar *text, KryEventList *event_list) { gui_event_list_handle_column_edit(event_list, NAME_COLUMN, path_string, text); } gboolean gui_event_list_key_press_cb(GtkWidget *widget, GdkEventKey *event, struct KryEventList *event_list) { event->state &= ~GDK_LOCK_MASK; if((event->keyval == GDK_x || event->keyval == GDK_X) && event->state == GDK_CONTROL_MASK) gui_main_menu_event_clipboard(NULL, EVENT_CUT, NULL); else if((event->keyval == GDK_c || event->keyval == GDK_C) && event->state == GDK_CONTROL_MASK) gui_main_menu_event_clipboard(NULL, EVENT_COPY, NULL); else if((event->keyval == GDK_V || event->keyval == GDK_v) && event->state == (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) gui_main_menu_event_paste(NULL, EVENT_PASTE_BEFORE, NULL); else if((event->keyval == GDK_v || event->keyval == GDK_V) && event->state == GDK_CONTROL_MASK) gui_main_menu_event_paste(NULL, EVENT_PASTE_AFTER, NULL); return FALSE; } void gui_event_list_color_change_string(kryColor *color) { if(color->GetUserData()) kry_free(color->GetUserData()); char *str = kry_strdup_printf(KRY_LOC "#%02X%02X%02X", color->GetRed(), color->GetGreen(), color->GetBlue()); color->SetUserData(str); } void gui_event_list_color_changed_cb(kryObject *obj, kryColor *color, struct KryEventList *event_list) { //kryColorTable *table = (kryColorTable*) obj; gui_event_list_color_change_string(color); GtkTreeIter iter; if(!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(event_list->store), &iter)) return; do { kryEventDetailed *event; gtk_tree_model_get(GTK_TREE_MODEL(event_list->store), &iter, PTR_COLUMN, &event, -1); if(color->GetID() == LIST_COLOR_COMMENT && event->GetType() == kryEvent::EVENT_COMMENT_DIALOG || color->GetID() == LIST_COLOR_COLLISION && event->GetCollisionAdded() || color->GetID() == LIST_COLOR_COLLISION_HIGHLIGHT && event->GetCollisionHighlighted()) { gtk_list_store_set(event_list->store, &iter, COLOR_COLUMN, color->GetUserData(), -1); } } while(gtk_tree_model_iter_next(GTK_TREE_MODEL(event_list->store), &iter)); } gboolean gui_event_list_is_separator_cb(GtkTreeModel *model, GtkTreeIter *iter, struct KryEventList *event_list) { kryEvent *event; gtk_tree_model_get(model, iter, PTR_COLUMN, &event, -1); if(event->GetType() == kryEvent::EVENT_COMMENT_BLANK) return TRUE; else return FALSE; } struct KryEventList *gui_event_list_new(gboolean dummy) { GtkTreeSelection *selection; GtkCellRenderer *renderer; GtkCellRenderer *renderer_text; GtkCellRenderer *renderer_name; GtkCellRenderer *renderer_style; GtkTreeViewColumn *column; struct KryEventList *event_list = kry_new0(struct KryEventList); event_list->dummy = dummy; app.ui.list_color_table->ConnectSignal(kryColorTable::SIGNAL_COLOR_CHANGED, (krySignalFunc1) gui_event_list_color_changed_cb, event_list); gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(app.ui.name_store_sorted), 0, GTK_SORT_ASCENDING); event_list->store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_STRING); event_list->view = GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(event_list->store))); gtk_tree_view_set_rules_hint(event_list->view, TRUE); selection = gtk_tree_view_get_selection(event_list->view); if(!dummy) g_signal_connect_after(selection, "changed", G_CALLBACK(gui_event_list_selection_changed_cb), event_list); gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); renderer = gtk_cell_renderer_text_new(); renderer_text = gtk_cell_renderer_text_new(); renderer_name = gtk_cell_renderer_combo_new(); renderer_style = gtk_cell_renderer_combo_new(); if(!app.ui.renderer_text) app.ui.renderer_text = renderer_text; if(!dummy) g_object_set(renderer_text, "editable", TRUE, NULL); if(!dummy) { g_signal_connect(renderer_text, "edited", G_CALLBACK(gui_event_list_text_column_edited_cb), event_list); g_signal_connect(renderer_text, "editing-started", G_CALLBACK(gui_event_list_text_column_editing_started_cb), event_list); g_signal_connect(renderer_name, "edited", G_CALLBACK(gui_event_list_name_column_edited_cb), event_list); g_signal_connect(renderer_style,"edited", G_CALLBACK(gui_event_list_style_column_edited_cb), event_list); g_signal_connect(event_list->view, "key-press-event", G_CALLBACK(gui_event_list_key_press_cb), NULL); } column = gtk_tree_view_column_new_with_attributes (__("EventListColumn|#"), renderer, "background", COLOR_COLUMN, NULL); event_list->columns[INDEX_COLUMN] = column; g_object_ref(column); gtk_tree_view_column_set_resizable(column, TRUE); gtk_tree_view_column_set_cell_data_func(column, renderer, (GtkTreeCellDataFunc) gui_event_list_index_column_data_cb, event_list, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (event_list->view), column); column = gtk_tree_view_column_new_with_attributes (__("EventListColumn|Layer"), renderer, "text", LAYER_COLUMN, "background", COLOR_COLUMN, NULL); event_list->columns[LAYER_COLUMN] = column; g_object_ref(column); gtk_tree_view_column_set_resizable(column, TRUE); gtk_tree_view_append_column (GTK_TREE_VIEW (event_list->view), column); column = gtk_tree_view_column_new_with_attributes ("Flags", renderer, "text", FLAGS_COLUMN, NULL); gtk_tree_view_column_set_resizable(column, TRUE); column = gtk_tree_view_column_new_with_attributes (__("EventListColumn|Start"), renderer, "text", START_COLUMN, "background", COLOR_COLUMN, NULL); event_list->columns[START_COLUMN] = column; g_object_ref(column); gtk_tree_view_column_set_resizable(column, TRUE); gtk_tree_view_append_column (GTK_TREE_VIEW (event_list->view), column); column = gtk_tree_view_column_new_with_attributes (__("EventListColumn|End"), renderer, "text", END_COLUMN, "background", COLOR_COLUMN, NULL); event_list->columns[END_COLUMN] = column; g_object_ref(column); gtk_tree_view_column_set_resizable(column, TRUE); gtk_tree_view_append_column (GTK_TREE_VIEW (event_list->view), column); column = gtk_tree_view_column_new_with_attributes (__("EventListColumn|Duration"), renderer, "text", DUR_COLUMN, "background", COLOR_COLUMN, NULL); event_list->columns[DUR_COLUMN] = column; g_object_ref(column); gtk_tree_view_column_set_resizable(column, TRUE); gtk_tree_view_append_column (GTK_TREE_VIEW (event_list->view), column); g_object_set(renderer_style, "model", app.ui.style_store, "text-column", 0, "editable", !dummy, "has-entry", 0, NULL); GtkHBox *hbox_style_header = GTK_HBOX(gtk_hbox_new(FALSE, 0)); GtkLabel *label_style = GTK_LABEL(gtk_label_new(__("EventListColumn|Style"))); GtkImage *image_indicator = GTK_IMAGE(gtk_image_new_from_pixbuf(app.ui.pixbufs.search_indicator)); GtkEventBox *event_box_image = GTK_EVENT_BOX(gtk_event_box_new()); gtk_widget_set_size_request(GTK_WIDGET(event_box_image), 13, 13); gtk_container_add(GTK_CONTAINER(event_box_image), GTK_WIDGET(image_indicator)); gtk_box_pack_start(GTK_BOX(hbox_style_header), GTK_WIDGET(label_style), TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox_style_header), GTK_WIDGET(event_box_image), FALSE, TRUE, 5); gtk_widget_show_all(GTK_WIDGET(hbox_style_header)); gtk_widget_hide(GTK_WIDGET(image_indicator)); app.ui.search_indicator_style = GTK_WIDGET(image_indicator); column = gtk_tree_view_column_new_with_attributes (__("EventListColumn|Style"), renderer_style, "text", STYLE_COLUMN, "background", COLOR_COLUMN, NULL); event_list->columns[STYLE_COLUMN] = column; gtk_tree_view_column_set_widget(column, GTK_WIDGET(hbox_style_header)); g_object_ref(column); gtk_tree_view_column_set_resizable(column, TRUE); gtk_tree_view_append_column (GTK_TREE_VIEW (event_list->view), column); g_object_set(renderer_name, "has-entry", 1, "model", app.ui.name_store_sorted, "text-column", 0, "editable", !dummy, NULL); GtkHBox *hbox_name_header = GTK_HBOX(gtk_hbox_new(FALSE, 0)); GtkLabel *label_name = GTK_LABEL(gtk_label_new(__("EventListColumn|Name"))); image_indicator = GTK_IMAGE(gtk_image_new_from_pixbuf(app.ui.pixbufs.search_indicator)); event_box_image = GTK_EVENT_BOX(gtk_event_box_new()); gtk_widget_set_size_request(GTK_WIDGET(event_box_image), 13, 13); gtk_container_add(GTK_CONTAINER(event_box_image), GTK_WIDGET(image_indicator)); gtk_box_pack_start(GTK_BOX(hbox_name_header), GTK_WIDGET(label_name), TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox_name_header), GTK_WIDGET(event_box_image), FALSE, TRUE, 5); gtk_widget_show_all(GTK_WIDGET(hbox_name_header)); gtk_widget_hide(GTK_WIDGET(image_indicator)); app.ui.search_indicator_name = GTK_WIDGET(image_indicator); column = gtk_tree_view_column_new_with_attributes (__("EventListColumn|Name"), renderer_name, "text", NAME_COLUMN, "background", COLOR_COLUMN, NULL); event_list->columns[NAME_COLUMN] = column; gtk_tree_view_column_set_widget(column, GTK_WIDGET(hbox_name_header)); g_object_ref(column); gtk_tree_view_column_set_resizable(column, TRUE); gtk_tree_view_append_column (GTK_TREE_VIEW (event_list->view), column); GtkHBox *hbox_text_header = GTK_HBOX(gtk_hbox_new(FALSE, 0)); GtkLabel *label_text = GTK_LABEL(gtk_label_new(__("EventListColumn|Text"))); image_indicator = GTK_IMAGE(gtk_image_new_from_pixbuf(app.ui.pixbufs.search_indicator)); event_box_image = GTK_EVENT_BOX(gtk_event_box_new()); gtk_widget_set_size_request(GTK_WIDGET(event_box_image), 13, 13); gtk_container_add(GTK_CONTAINER(event_box_image), GTK_WIDGET(image_indicator)); gtk_box_pack_start(GTK_BOX(hbox_text_header), GTK_WIDGET(label_text), TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox_text_header), GTK_WIDGET(event_box_image), FALSE, TRUE, 5); gtk_widget_show_all(GTK_WIDGET(hbox_text_header)); gtk_widget_hide(GTK_WIDGET(image_indicator)); app.ui.search_indicator_text = GTK_WIDGET(image_indicator); column = gtk_tree_view_column_new_with_attributes (__("EventListColumn|Text"), renderer_text, "text", TEXT_COLUMN, "background", COLOR_COLUMN, NULL); event_list->columns[TEXT_COLUMN] = column; gtk_tree_view_column_set_widget(column, GTK_WIDGET(hbox_text_header)); g_object_ref(column); gtk_tree_view_column_set_resizable(column, TRUE); gtk_tree_view_append_column (GTK_TREE_VIEW (event_list->view), column); gtk_tree_view_set_enable_search(event_list->view, FALSE); gtk_tree_view_set_search_column(event_list->view, TEXT_COLUMN); gtk_tree_view_set_row_separator_func(event_list->view, (GtkTreeViewRowSeparatorFunc) gui_event_list_is_separator_cb, NULL, NULL); return event_list; } void gui_event_list_append_blank_rows(struct KryEventList *event_list, int count) { int i; GtkTreeIter iter; for(i = 0; i < count; i++) { kryEventDetailed *line = new kryEventDetailed(); line->SetType(kryEvent::EVENT_BLANK); line->SetTypeSub(kryEvent::EVENT_BLANK); gtk_list_store_append(event_list->store, &iter); gtk_list_store_set(event_list->store, &iter, FLAGS_COLUMN, "", START_COLUMN, "", END_COLUMN, "", DUR_COLUMN, "", STYLE_COLUMN, "", NAME_COLUMN, "", TEXT_COLUMN, "", PTR_COLUMN, line, -1); gboolean mod = app.script->GetModifiedFlag(); app.script->AddEvent(line); app.script->SetBlankCount(app.script->GetBlankCount() + 1); if(!mod) app.script->SetModifiedFlag(FALSE); } } void gui_event_list_update_line(struct KryEventList *event_list, kryEvent *line, GtkTreeIter *iter_param) { GtkTreeIter iter_internal; GtkTreeIter *iter = NULL; char *start, *end, *dur, *layer, *style, *color = NULL; if(iter_param) { iter = iter_param; } if(!iter) { char *pathstr = kry_strdup_printf(KRY_LOC "%d", line->GetIndex()); GtkTreePath *path = gtk_tree_path_new_from_string(pathstr); gtk_tree_model_get_iter(GTK_TREE_MODEL(event_list->store), &iter_internal, path); gtk_tree_path_free(path); kry_free(pathstr); iter = &iter_internal; } if(line->GetType() == kryEvent::EVENT_BLANK || line->GetType() == kryEvent::EVENT_COMMENT_STRING || line->GetType() == kryEvent::EVENT_COMMENT_BLANK) { start = kry_strdup(""); end = kry_strdup(""); dur = kry_strdup(""); layer = kry_strdup(""); style = kry_strdup(""); } else { start = time_mili_to_string(line->GetStart(), app.ui.ui_mode == UI_MODE_SRT); end = time_mili_to_string(line->GetEnd(), app.ui.ui_mode == UI_MODE_SRT); dur = time_mili_to_string(line->GetEnd() - line->GetStart(), app.ui.ui_mode == UI_MODE_SRT); if(line->IsDetailed()) { layer = kry_strdup_printf(KRY_LOC "%d", ((kryEventDetailed *) line)->GetLayer()); style = kry_strdup(((kryEventDetailed *) line)->GetStyle()); } else { layer = kry_strdup(""); style = kry_strdup(""); } } if(line->GetType() == kryEvent::EVENT_COMMENT_DIALOG || line->GetType() == kryEvent::EVENT_COMMENT_STRING || line->GetType() == kryEvent::EVENT_COMMENT_BLANK) color = (char *) app.ui.list_color_table->GetUserData(LIST_COLOR_COMMENT); char *text = line->GetText(); if(line->GetType() == kryEvent::EVENT_KARAOKE_TEXT && ((kryEventKaraokeTextBox *) line)->GetIsSilence()) text = "[...]"; gtk_list_store_set(event_list->store, iter, START_COLUMN, start, END_COLUMN, end, DUR_COLUMN, dur, TEXT_COLUMN, text, PTR_COLUMN, line, LAYER_COLUMN, layer, COLOR_COLUMN, color, STYLE_COLUMN, style, -1); if(line->IsDetailed()) { gtk_list_store_set(event_list->store, iter, NAME_COLUMN, ((kryEventDetailed *) line)->GetName(), -1); if(((kryEventDetailed *) line)->GetCollisionAdded()) gui_event_list_set_row_color(event_list, line->GetIndex(), LIST_COLOR_COLLISION); if(((kryEventDetailed *) line)->GetCollisionHighlighted()) gui_event_list_set_row_color(event_list, line->GetIndex(), LIST_COLOR_COLLISION_HIGHLIGHT); } kry_free(layer); kry_free(start); kry_free(end); kry_free(dur); kry_free(style); } void gui_event_list_fill_from_list_karaoke(struct KryEventList *event_list, kryList *list) { int length = list->GetCount(); int index = 0; int prev_pos = 0; GtkTreeIter iter; GtkTreeIter iter_first; kryEvent *line; gui_event_list_clear(event_list); kryListIterator iter_events; list->GetIterator(&iter_events); while((line = iter_events.GetNext())) { if((double) (index - prev_pos) / length > 0.33) { gui_status_bar_set_progress(app.ui.status_bar, ((double) index / length), TRUE); prev_pos = index; } if(line->GetType() != kryEvent::EVENT_KARAOKE_TEXT) continue; if( ((kryEventKaraokeText *)line)->GetIsSilence()) continue; gtk_list_store_append(event_list->store, &iter); gui_event_list_update_line(event_list, line, &iter); if(index == 0) iter_first = iter; index++; } GtkTreeSelection *selection = GTK_TREE_SELECTION(gtk_tree_view_get_selection(event_list->view)); gtk_tree_selection_select_iter(selection, &iter_first); } void gui_event_list_fill_from_list_detailed(struct KryEventList *event_list, kryList *list, gboolean add_blanks) { int length = list->GetCount(); int index = 0; int prev_pos = 0; int blank_count = 0; GtkTreeIter iter; GTimer *timer = g_timer_new(); gui_event_list_clear(event_list); kryListIterator iter_events; list->GetIterator(&iter_events); kryEvent *line; while((line = iter_events.GetNext())) { if(g_timer_elapsed(timer, NULL) > 1.0) { g_timer_start(timer); gui_status_bar_set_progress(app.ui.status_bar, ((double) index / length), TRUE); prev_pos = index; } if(app.ui.ui_mode == UI_MODE_SRT && (line->GetType() == kryEvent::EVENT_COMMENT_STRING || line->GetType() == kryEvent::EVENT_COMMENT_BLANK || line->GetType() == kryEvent::EVENT_COMMENT_DIALOG)) continue; gtk_list_store_append(event_list->store, &iter); gui_event_list_update_line(event_list, line, &iter); if(line->GetType() == kryEvent::EVENT_BLANK) blank_count++; else blank_count = 0; index++; } if(timer) g_timer_destroy(timer); if(add_blanks) gui_event_list_append_blank_rows(event_list, blank_count > 10 ? 0 : 10 - blank_count); if(!event_list->dummy) { kryListIterator iter_col; app.script->GetCollisionIterator(&iter_col); while((line = iter_col.GetNext())) gui_event_list_set_row_color(event_list, line->GetIndex(), LIST_COLOR_COLLISION); } } void gui_event_list_clear(struct KryEventList *event_list) { gtk_list_store_clear(event_list->store); } GtkTreeView *gui_event_list_get_view(struct KryEventList *event_list) { return event_list->view; } GtkListStore *gui_event_list_get_store(struct KryEventList *event_list) { return event_list->store; } void gui_event_list_update_visible_columns(struct KryEventList *event_list, enum ui_mode ui_mode) { if(ui_mode == UI_MODE_SSA) { gtk_tree_view_column_set_visible(event_list->columns[INDEX_COLUMN], TRUE); gtk_tree_view_column_set_visible(event_list->columns[LAYER_COLUMN], FALSE); gtk_tree_view_column_set_visible(event_list->columns[START_COLUMN], TRUE); gtk_tree_view_column_set_visible(event_list->columns[END_COLUMN], TRUE); gtk_tree_view_column_set_visible(event_list->columns[DUR_COLUMN], TRUE); gtk_tree_view_column_set_visible(event_list->columns[STYLE_COLUMN], TRUE); gtk_tree_view_column_set_visible(event_list->columns[NAME_COLUMN], TRUE); gtk_tree_view_column_set_visible(event_list->columns[TEXT_COLUMN], TRUE); } else if(ui_mode == UI_MODE_ASS) { gtk_tree_view_column_set_visible(event_list->columns[INDEX_COLUMN], TRUE); gtk_tree_view_column_set_visible(event_list->columns[LAYER_COLUMN], TRUE); gtk_tree_view_column_set_visible(event_list->columns[START_COLUMN], TRUE); gtk_tree_view_column_set_visible(event_list->columns[END_COLUMN], TRUE); gtk_tree_view_column_set_visible(event_list->columns[DUR_COLUMN], TRUE); gtk_tree_view_column_set_visible(event_list->columns[STYLE_COLUMN], TRUE); gtk_tree_view_column_set_visible(event_list->columns[NAME_COLUMN], TRUE); gtk_tree_view_column_set_visible(event_list->columns[TEXT_COLUMN], TRUE); } else if(ui_mode == UI_MODE_SRT) { gtk_tree_view_column_set_visible(event_list->columns[INDEX_COLUMN], TRUE); gtk_tree_view_column_set_visible(event_list->columns[LAYER_COLUMN], FALSE); gtk_tree_view_column_set_visible(event_list->columns[START_COLUMN], TRUE); gtk_tree_view_column_set_visible(event_list->columns[END_COLUMN], TRUE); gtk_tree_view_column_set_visible(event_list->columns[DUR_COLUMN], TRUE); gtk_tree_view_column_set_visible(event_list->columns[STYLE_COLUMN], FALSE); gtk_tree_view_column_set_visible(event_list->columns[NAME_COLUMN], FALSE); gtk_tree_view_column_set_visible(event_list->columns[TEXT_COLUMN], TRUE); } else if(ui_mode == UI_MODE_KARAOKE) { gtk_tree_view_column_set_visible(event_list->columns[INDEX_COLUMN], TRUE); gtk_tree_view_column_set_visible(event_list->columns[LAYER_COLUMN], FALSE); gtk_tree_view_column_set_visible(event_list->columns[START_COLUMN], TRUE); gtk_tree_view_column_set_visible(event_list->columns[END_COLUMN], TRUE); gtk_tree_view_column_set_visible(event_list->columns[DUR_COLUMN], TRUE); gtk_tree_view_column_set_visible(event_list->columns[STYLE_COLUMN], FALSE); gtk_tree_view_column_set_visible(event_list->columns[NAME_COLUMN], FALSE); gtk_tree_view_column_set_visible(event_list->columns[TEXT_COLUMN], TRUE); } } void gui_event_list_scroll_if_necessary(struct KryEventList *list, GtkTreePath *path, gboolean up) { GdkRectangle rect_view, rect_cell; GtkTreeModel *model; GtkTreeSelection *selection = gui_event_list_get_selection(app.ui.event_list); GList *sel_items = gtk_tree_selection_get_selected_rows(selection, &model); if(!path && !sel_items) return; gtk_tree_view_get_visible_rect(gui_event_list_get_view(app.ui.event_list), &rect_view); if(!path) path = (GtkTreePath *) sel_items->data; gtk_tree_view_get_cell_area(gui_event_list_get_view(app.ui.event_list), path, NULL, &rect_cell); int threshold = rect_cell.height * 3; if((up && rect_cell.y < 0 + threshold) || (!up && rect_cell.y + rect_cell.height > rect_view.height - threshold)) gtk_tree_view_scroll_to_cell(gui_event_list_get_view(app.ui.event_list), path, NULL, TRUE, up ? 0.8f : 0.1f, 0); g_list_foreach(sel_items, (GFunc) gtk_tree_path_free, NULL); g_list_free(sel_items); }