/* * 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 "gui_main_script.h" #include "gui_main_style.h" #include "gui_main_style_manager.h" #include "sub_preview.h" #include "kryTextFileReader.h" #include "krySubSSA.h" #include "krySubReader.h" #include "krySubReaderSSA.h" #include "krySubWriter.h" #include "krySubWriterSSA.h" extern struct sabbu app; struct store_pair { GtkTreeView *src; GtkTreeView *dest; }; static kryStyle *cur_style = NULL; GtkTreeView *view_global = NULL; GtkTreeView *view_import= NULL; GtkTreeView *view_script = NULL; GtkDrawingArea *preview_area = NULL; GtkToggleButton *toggle_preview = NULL; GtkWindow *window = NULL; void gui_main_style_manager_delete_style(GtkWidget *widget, GtkTreeView *view) { GtkTreeModel *model; GtkTreeSelection *selection = gtk_tree_view_get_selection(view); GList *sel_items = gtk_tree_selection_get_selected_rows(selection, &model); if(!sel_items) { gui_error(__("StyleManager|Please select a style to delete")); return; } char *style_name; GtkTreeIter iter; gtk_tree_model_get_iter(model, &iter, (GtkTreePath*) sel_items->data); gtk_tree_model_get(model, &iter, 0, &style_name, -1); g_object_set_data(G_OBJECT(model), "script-modified", (gpointer) 1); kryScript *script = (kryScript *) g_object_get_data(G_OBJECT(model), "script"); script->RemoveStyle(style_name); gui_main_style_manager_fill_store(GTK_LIST_STORE(model), script); g_list_foreach (sel_items, (GFunc) gtk_tree_path_free, NULL); g_list_free(sel_items); } void gui_main_style_manager_copy_style(GtkWidget *widget, struct store_pair *pair) { GtkTreeModel *dest_model = gtk_tree_view_get_model(pair->dest); GtkTreeModel *src_model = gtk_tree_view_get_model(pair->src); GtkTreeSelection *selection = gtk_tree_view_get_selection(pair->src); GList *sel_items = gtk_tree_selection_get_selected_rows(selection, NULL); if(!sel_items) { gui_error(__("StyleManager|Please select a style to copy")); return; } kryScript *dest_script = (kryScript *) g_object_get_data(G_OBJECT(dest_model), "script"); if(!dest_script) { g_list_foreach (sel_items, (GFunc) gtk_tree_path_free, NULL); g_list_free(sel_items); gui_error(__("StyleManager|The destination file is not open")); return; } char *style_name; GtkTreeIter iter; gtk_tree_model_get_iter(src_model, &iter, (GtkTreePath*) sel_items->data); gtk_tree_model_get(src_model, &iter, 0, &style_name, -1); if(dest_script->GetStyle(style_name) != NULL) { int rv = gui_warning_yes_no(__("StyleManager|Overwrite the existing style?")); if(!rv) return; dest_script->RemoveStyle(style_name); } g_object_set_data(G_OBJECT(dest_model), "script-modified", (gpointer) 1); kryScript *src_script = (kryScript *) g_object_get_data(G_OBJECT(src_model), "script"); kryStyle *src_style = src_script->GetStyle(style_name); dest_script->AddStyle(src_style->Copy()); gui_main_style_manager_fill_store(GTK_LIST_STORE(gtk_tree_view_get_model(pair->dest)), dest_script); g_list_foreach (sel_items, (GFunc) gtk_tree_path_free, NULL); g_list_free(sel_items); } gboolean gui_main_style_manager_delete_cb(GtkWidget *widget, gpointer data) { GtkTreeModel *model_global = gtk_tree_view_get_model(view_global); GtkTreeModel *model_import = gtk_tree_view_get_model(view_import); kryScript *script_global = (kryScript *) g_object_get_data(G_OBJECT(model_global), "script"); kryScript *script_import = (kryScript *) g_object_get_data(G_OBJECT(model_import), "script"); if(script_global && g_object_get_data(G_OBJECT(model_global), "script-modified")) { krySubWriterSSA *writer = new krySubWriterSSA(script_global); if(app.opts.format_script) writer->EnableFormatScript(); writer->WriteScript(); delete writer; } if(script_import&& g_object_get_data(G_OBJECT(model_import), "script-modified")) { krySubWriterSSA *writer = new krySubWriterSSA(script_import); if(app.opts.format_script) writer->EnableFormatScript(); writer->WriteScript(); delete writer; } if(script_global) { delete script_global; script_global = NULL; } if(script_import) { delete script_import; script_global = NULL; } cur_style = NULL; gui_main_style_list_fill(); gui_main_enable(); gui_main_focus(); gtk_widget_destroy(GTK_WIDGET(window)); app.ui.window_focus = app.ui.window; return FALSE; } void gui_main_style_manager_fill_store(GtkListStore *store, kryScript *script) { gtk_list_store_clear(store); GtkTreeIter tree_iter; kryListIterator iter; script->GetStyleNameIterator(&iter); while(char *name = iter.GetNext()) { kryStyle *style = script->GetStyle(name); if(style->GetType() == KRY_STYLE_COMMENT) continue; gtk_list_store_append(store, &tree_iter); gtk_list_store_set(store, &tree_iter, 0, name, -1); } } void gui_main_style_manager_read_global_store(GtkListStore *store) { kryScript *script_global = new kryScript(); struct _stat stat_file; char *dir = sabbu_get_config_dir(); char *filename = kry_strdup_printf(KRY_LOC "%s\\styles.ssa", dir); if(stat(filename, &stat_file) == -1) { script_global->SetFilename(filename); kry_free(filename); } else { krySubReaderSSA *reader = new krySubReaderSSA(filename); int rv = reader->ReadScript(script_global, NULL); delete reader; kry_free(filename); if(rv != krySubReader::SCRIPT_OK) { delete script_global; gui_error(__("StyleManager|There was a problem reading the global style store")); return; } gui_main_style_manager_fill_store(store, script_global); } g_object_set_data(G_OBJECT(store), "script", script_global); } void gui_main_style_manager_preview_expose_cb(GtkWidget *widget, gpointer userdata) { int orig_alignment = 0; int width = widget->allocation.width; int height = widget->allocation.height; char *data = (char *) kry_malloc0(4 * width * height); GdkPixbuf *pixbuf; int i; for(i = 0; i < 4 * width * height; i++) data[i] = (char) 255; if(cur_style != NULL) { orig_alignment = cur_style->GetAlignment(); cur_style->SetAlignment(7); } if(cur_style != NULL && gtk_toggle_button_get_active(toggle_preview)) { #ifdef _WINDOWS subtest_init(width, height, width, height); subtest_set("{\\pos(4,4)}abc def ghi jkl ABC DEF GHI JKL", cur_style, 0, 1000, 1); subtest_do(data, width, height, 500); subtest_uninit(); #endif } for(i = 0; i + 2 < 4 * width * height; i+= 4) { char temp = data[i]; data[i] = data[i+2]; data[i+2] = temp; } for(i = 0; i + 3 < 4 * width * height; i+= 4) data[i+3] = (char) 255; pixbuf = gdk_pixbuf_new_from_data((const guchar *) data, GDK_COLORSPACE_RGB, TRUE, 8, width, height, width * 4, NULL, NULL); gdk_draw_pixbuf(widget->window, NULL, pixbuf, 0, 0, 0, 0, width, height, GDK_RGB_DITHER_NORMAL, 0, 0); g_object_unref(pixbuf); kry_free(data); if(cur_style != NULL) cur_style->SetAlignment(orig_alignment); } void gui_main_styke_manager_open_cb(GtkWidget *widget, GtkListStore *import_store) { kryScript *script = gui_main_script_open(); if(!script) return; kryScript *script_old = (kryScript *) g_object_get_data(G_OBJECT(import_store), "script"); if(script_old) delete script_old; gui_main_style_manager_fill_store(import_store, script); g_object_set_data(G_OBJECT(import_store), "script", script); } void gui_main_style_manager_selection_cb(GtkTreeSelection *selection, GtkTreeView *view) { if(gtk_tree_selection_count_selected_rows(selection) == 0) { cur_style = NULL; gtk_widget_queue_draw(GTK_WIDGET(preview_area)); return; } if(view != view_global) { GtkTreeSelection *selection = gtk_tree_view_get_selection(view_global); gtk_tree_selection_unselect_all(selection); } if(view != view_script) { GtkTreeSelection *selection = gtk_tree_view_get_selection(view_script); gtk_tree_selection_unselect_all(selection); } if(view != view_import) { GtkTreeSelection *selection = gtk_tree_view_get_selection(view_import); gtk_tree_selection_unselect_all(selection); } kryScript *script = (kryScript *) g_object_get_data(G_OBJECT(gtk_tree_view_get_model(view)), "script"); GtkTreeModel *model; GList *sel_items = gtk_tree_selection_get_selected_rows(selection, &model); GtkTreePath *path = (GtkTreePath *) sel_items->data; GtkTreeIter iter; char *style_name; gtk_tree_model_get_iter(model, &iter, path); gtk_tree_model_get(model, &iter, 0, &style_name, -1); cur_style=script->GetStyle(style_name); gtk_widget_queue_draw(GTK_WIDGET(preview_area)); g_list_foreach (sel_items, (GFunc) gtk_tree_path_free, NULL); g_list_free(sel_items); } void gui_main_style_manager_preview_toggle_cb(GtkWidget *widget, gpointer data) { gtk_widget_queue_draw(GTK_WIDGET(preview_area)); } GtkWindow *gui_main_style_manager_create() { window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); app.ui.window_focus = window; gtk_window_set_title(window, _("Style Manager")); GtkHBox *hbox_frames = GTK_HBOX(gtk_hbox_new(FALSE, 0)); GtkVBox *vbox_frames = GTK_VBOX(gtk_vbox_new(FALSE, 0)); GtkVBox *vbox_preview = GTK_VBOX(gtk_vbox_new(FALSE, 0)); GtkFrame *frame_preview = GTK_FRAME(gtk_frame_new(__("StyleManagerFontPreview|Preview"))); GtkScrolledWindow *sw_global = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL)); GtkHBox *hbox_global = GTK_HBOX(gtk_hbox_new(FALSE, 0)); GtkVBox *vbox_global_buttons = GTK_VBOX(gtk_vbox_new(FALSE, 0)); GtkFrame *frame_global = GTK_FRAME(gtk_frame_new(_("Global Store"))); GtkListStore *store_global = gtk_list_store_new(1, G_TYPE_STRING); view_global = GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(store_global))); gtk_scrolled_window_set_policy(sw_global, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_tree_view_set_headers_visible(view_global, FALSE); GtkScrolledWindow *sw_import = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL)); GtkHBox *hbox_import = GTK_HBOX(gtk_hbox_new(FALSE, 0)); GtkVBox *vbox_import_buttons = GTK_VBOX(gtk_vbox_new(FALSE, 0)); GtkFrame *frame_import = GTK_FRAME(gtk_frame_new(_("From Script"))); GtkListStore *store_import = gtk_list_store_new(1, G_TYPE_STRING); view_import = GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(store_import))); gtk_scrolled_window_set_policy(sw_import, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_tree_view_set_headers_visible(view_import, FALSE); GtkScrolledWindow *sw_script = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL)); GtkCellRenderer *renderer = GTK_CELL_RENDERER(gtk_cell_renderer_text_new()); GtkTreeViewColumn *column_global, *column_import, *column_script; GtkFrame *frame_script = GTK_FRAME(gtk_frame_new(_("Current Script"))); GtkListStore *store_script = gtk_list_store_new(1, G_TYPE_STRING); view_script = GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(store_script))); gtk_scrolled_window_set_policy(sw_script, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_tree_view_set_headers_visible(view_script, FALSE); GtkVBox *vbox_window_buttons = GTK_VBOX(gtk_vbox_new(FALSE, 0)); GtkButton *button_close = GTK_BUTTON(gtk_button_new_with_label(_("Close"))); gtk_box_pack_start(GTK_BOX(vbox_window_buttons), GTK_WIDGET(button_close), FALSE, TRUE, 10); column_global = gtk_tree_view_column_new_with_attributes ("Style", renderer, "text", 0, NULL); column_import = gtk_tree_view_column_new_with_attributes ("Style", renderer, "text", 0, NULL); column_script = gtk_tree_view_column_new_with_attributes ("Style", renderer, "text", 0, NULL); // setup global part { #ifndef DISABLE_GETTEXT textdomain("notsabbu"); #endif GtkButton *button_left = GTK_BUTTON(gtk_button_new_from_stock("sabbu-left")); GtkButton *button_delete = GTK_BUTTON(gtk_button_new_from_stock("sabbu-delete")); GtkButton *button_right = GTK_BUTTON(gtk_button_new_from_stock("sabbu-play-current")); #ifndef DISABLE_GETTEXT textdomain("sabbu"); #endif g_signal_connect(G_OBJECT(button_delete), "clicked", G_CALLBACK(gui_main_style_manager_delete_style), view_global); struct store_pair *script_to_global = kry_new(struct store_pair, 1); script_to_global->src = view_script; script_to_global->dest = view_global; g_signal_connect(G_OBJECT(button_left), "clicked", G_CALLBACK(gui_main_style_manager_copy_style), script_to_global); struct store_pair *global_to_script = kry_new(struct store_pair, 1); global_to_script->src = view_global; global_to_script->dest = view_script; g_signal_connect(G_OBJECT(button_right), "clicked", G_CALLBACK(gui_main_style_manager_copy_style), global_to_script); gtk_container_add(GTK_CONTAINER(sw_global), GTK_WIDGET(view_global)); gtk_tree_view_append_column(view_global, column_global); gtk_container_add(GTK_CONTAINER(frame_global), GTK_WIDGET(sw_global)); gtk_box_pack_start(GTK_BOX(hbox_global), GTK_WIDGET(frame_global), TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox_global), GTK_WIDGET(vbox_global_buttons), FALSE, TRUE, 5); gtk_box_pack_start(GTK_BOX(vbox_global_buttons), GTK_WIDGET(button_left), TRUE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox_global_buttons), GTK_WIDGET(button_delete), TRUE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox_global_buttons), GTK_WIDGET(button_right), TRUE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox_frames), GTK_WIDGET(hbox_global), TRUE, TRUE, 5); } // setup buttons between global and import { #ifndef DISABLE_GETTEXT textdomain("notsabbu"); #endif GtkHBox *hbox_buttons = GTK_HBOX(gtk_hbox_new(FALSE, 0)); GtkButton *button_up = GTK_BUTTON(gtk_button_new_from_stock("sabbu-play-previous")); GtkButton *button_down = GTK_BUTTON(gtk_button_new_from_stock("sabbu-play-next")); #ifndef DISABLE_GETTEXT textdomain("sabbu"); #endif struct store_pair *global_to_import = kry_new(struct store_pair, 1); global_to_import->src = view_global; global_to_import->dest = view_import; g_signal_connect(G_OBJECT(button_down), "clicked", G_CALLBACK(gui_main_style_manager_copy_style), global_to_import); struct store_pair *import_to_global = kry_new(struct store_pair, 1); import_to_global->src = view_import; import_to_global->dest = view_global; g_signal_connect(G_OBJECT(button_up), "clicked", G_CALLBACK(gui_main_style_manager_copy_style), import_to_global); gtk_box_pack_start(GTK_BOX(hbox_buttons), GTK_WIDGET(button_up), TRUE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox_buttons), GTK_WIDGET(button_down), TRUE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox_frames), GTK_WIDGET(hbox_buttons), FALSE, TRUE, 0); } // setup import part { #ifndef DISABLE_GETTEXT textdomain("notsabbu"); #endif GtkButton *button_left = GTK_BUTTON(gtk_button_new_from_stock("sabbu-left")); GtkButton *button_delete = GTK_BUTTON(gtk_button_new_from_stock("sabbu-delete")); GtkButton *button_right = GTK_BUTTON(gtk_button_new_from_stock("sabbu-play-current")); #ifndef DISABLE_GETTEXT textdomain("sabbu"); #endif GtkButton *button_open = GTK_BUTTON(gtk_button_new_with_label(_("Open Script"))); g_signal_connect(G_OBJECT(button_delete), "clicked", G_CALLBACK(gui_main_style_manager_delete_style), view_import); struct store_pair *script_to_import = kry_new(struct store_pair, 1); script_to_import->src = view_script; script_to_import->dest = view_import; g_signal_connect(G_OBJECT(button_left), "clicked", G_CALLBACK(gui_main_style_manager_copy_style), script_to_import); struct store_pair *import_to_script = kry_new(struct store_pair, 1); import_to_script->src = view_import; import_to_script->dest = view_script; g_signal_connect(G_OBJECT(button_right), "clicked", G_CALLBACK(gui_main_style_manager_copy_style), import_to_script); g_signal_connect(G_OBJECT(button_open), "clicked", G_CALLBACK(gui_main_styke_manager_open_cb), store_import); gtk_container_add(GTK_CONTAINER(sw_import), GTK_WIDGET(view_import)); GtkVBox *vbox_view = GTK_VBOX(gtk_vbox_new(FALSE, 0)); gtk_box_pack_start(GTK_BOX(vbox_view), GTK_WIDGET(sw_import), TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox_view), GTK_WIDGET(button_open), FALSE, TRUE, 0); gtk_tree_view_append_column(view_import, column_import); gtk_container_add(GTK_CONTAINER(frame_import), GTK_WIDGET(vbox_view)); gtk_box_pack_start(GTK_BOX(hbox_import), GTK_WIDGET(frame_import), TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox_import), GTK_WIDGET(vbox_import_buttons), FALSE, TRUE, 5); gtk_box_pack_start(GTK_BOX(vbox_import_buttons), GTK_WIDGET(button_left), TRUE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox_import_buttons), GTK_WIDGET(button_delete), TRUE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox_import_buttons), GTK_WIDGET(button_right), TRUE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox_frames), GTK_WIDGET(hbox_import), TRUE, TRUE, 5); } //setup script part { gtk_tree_view_append_column(view_script, column_script); gtk_container_add(GTK_CONTAINER(sw_script), GTK_WIDGET(view_script)); gtk_container_add(GTK_CONTAINER(frame_script), GTK_WIDGET(sw_script)); } // setup preview frame { GtkVBox *vbox_preview = GTK_VBOX(gtk_vbox_new(FALSE, 0)); toggle_preview = GTK_TOGGLE_BUTTON(gtk_check_button_new_with_label(__("StyleManagerFontPreviewToggle|Preview"))); preview_area = GTK_DRAWING_AREA(gtk_drawing_area_new()); gtk_toggle_button_set_active(toggle_preview, TRUE); g_signal_connect(G_OBJECT(preview_area), "expose-event", G_CALLBACK(gui_main_style_manager_preview_expose_cb), NULL); g_signal_connect(G_OBJECT(toggle_preview), "toggled", G_CALLBACK(gui_main_style_manager_preview_toggle_cb), NULL); gtk_box_pack_start(GTK_BOX(vbox_preview), GTK_WIDGET(toggle_preview), FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox_preview), GTK_WIDGET(preview_area), FALSE, TRUE, 0); gtk_container_add(GTK_CONTAINER(frame_preview), GTK_WIDGET(vbox_preview)); gtk_widget_set_size_request(GTK_WIDGET(preview_area), -1, 70); } gtk_box_pack_start(GTK_BOX(hbox_frames), GTK_WIDGET(vbox_frames), TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox_frames), GTK_WIDGET(frame_script), TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox_frames), GTK_WIDGET(vbox_window_buttons), FALSE, TRUE, 5); gtk_box_pack_start(GTK_BOX(vbox_preview), GTK_WIDGET(hbox_frames), TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox_preview), GTK_WIDGET(frame_preview), FALSE, TRUE, 0); gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(vbox_preview)); gtk_widget_set_size_request(GTK_WIDGET(window), 500, 400); g_signal_connect(G_OBJECT(window), "delete-event", G_CALLBACK(gui_main_style_manager_delete_cb), NULL); g_signal_connect(G_OBJECT(button_close), "clicked", G_CALLBACK(gui_main_style_manager_delete_cb), NULL); g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(view_global)), "changed", G_CALLBACK(gui_main_style_manager_selection_cb), view_global); g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(view_script)), "changed", G_CALLBACK(gui_main_style_manager_selection_cb), view_script); g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(view_import)), "changed", G_CALLBACK(gui_main_style_manager_selection_cb), view_import); gtk_window_set_transient_for(window, app.ui.window); gtk_window_set_position(window, GTK_WIN_POS_CENTER_ON_PARENT); gtk_widget_show_all(GTK_WIDGET(window)); gui_main_style_manager_read_global_store(store_global); gui_main_style_manager_fill_store(store_script, app.script); g_object_set_data(G_OBJECT(store_script), "script", app.script); return window; }