#include "main.h" /* Called from the ok-button of a fileselector if action is to open a file */ void gse_cb_open_subtitle (GtkWidget *wgt, GtkWidget *selector) { gint filetype = 0, ret_status; gchar *filename, msg[BUF_LEN] = ""; filename = g_strdup (gtk_file_selection_get_filename (GTK_FILE_SELECTION(selector))); if (*(g_basename (filename)) == '\0') return; g_free (cfg.last_open_dir); cfg.last_open_dir = g_strdup (filename); *(strrchr (cfg.last_open_dir, '/') + 1) = '\0'; /* Remove the filename from the path */ /* Allow user to specify type of subtitle if automatic detection fails! */ if ((filetype = gse_fl_get_subtitle_format (filename, 0)) < 1) { /* Ok, automatic detection failed.. ask the user */ if ((filetype = gse_get_file_format_from_user (filename)) == GSE_SUBT_UNKNOWN) { /* User clicked cancel... */ g_free (filename); return; } } /* Open the file */ ret_status = gse_fl_open_file (filename, filetype, FALSE); switch (ret_status) { case GSE_FILE_NO_ERRORS: gnome_appbar_push (GNOME_APPBAR (mwin_statusbar), (_("File opened successfully"))); break; case GSE_FILE_ERROR_OPEN_R: gtk_widget_hide (selector); g_snprintf (msg, BUF_LEN, _("Error opening file '%s'.\n" "Check if you have read permission to it!"), filename); gnome_dialog_run_and_close (GNOME_DIALOG (gnome_message_box_new (msg, GNOME_MESSAGE_BOX_WARNING, GNOME_STOCK_BUTTON_OK, NULL))); gnome_appbar_push (GNOME_APPBAR (mwin_statusbar), (_("Unable to open file"))); case GSE_FILE_CORRECTED_VALUES: gtk_widget_hide (selector); g_snprintf (msg, BUF_LEN, _("Errors were found in file.\n" "Please check the result!")); gnome_dialog_run_and_close (GNOME_DIALOG (gnome_message_box_new (msg, GNOME_MESSAGE_BOX_INFO, GNOME_STOCK_BUTTON_OK, NULL))); gnome_appbar_push (GNOME_APPBAR (mwin_statusbar), (_("File opened with errors"))); break; } g_free (filename); } /* Invoked from the menu "File->save" */ void gse_cb_save_subtitle_same_file (GtkWidget *wgt, gpointer data) { GtkWidget *msgbox; if (cur_open_file.filename == NULL) { msgbox = gnome_message_box_new (GSE_INFOBOX_NO_FILE_OPEN, GNOME_MESSAGE_BOX_INFO, GNOME_STOCK_BUTTON_OK, NULL); gnome_dialog_run_and_close (GNOME_DIALOG (msgbox)); return; } /* If file is "Untitled" then we ask for a filename */ if (!strcasecmp (cur_open_file.filename, _(GSE_UNTITLED_FILE))) { gse_cb_get_filename_from_user (NULL, GINT_TO_POINTER (GSE_ACTION_SAVE_SUB)); } else if (gse_fl_write_file (cur_open_file.filename, cur_open_file.filetype, GSE_NO_SPLIT) == 1) gnome_appbar_push (GNOME_APPBAR (mwin_statusbar), _("File saved successfully")); } /* Called from the fileselector if the action was to save a file */ void gse_cb_save_subtitle (GtkWidget *wgt, GtkWidget *selector) { GtkWidget *msgbox; gint filetype = 0; gchar *filename; if (cur_open_file.filename == NULL) { gtk_widget_hide (selector); msgbox = gnome_message_box_new (GSE_INFOBOX_NO_FILE_OPEN, GNOME_MESSAGE_BOX_INFO, GNOME_STOCK_BUTTON_OK, NULL); gnome_dialog_run_and_close (GNOME_DIALOG (msgbox)); return; } filename = g_strdup (gtk_file_selection_get_filename (GTK_FILE_SELECTION(selector))); if (*(g_basename (filename)) == '\0') return; g_free (cfg.last_save_dir); cfg.last_save_dir = g_strdup (filename); *(strrchr (cfg.last_save_dir, '/') + 1) = '\0'; /* Remove the filename from the path */ /* Try to determine subtitle format by extension */ if ((filetype = gse_fl_get_subtitle_format (filename, CFG_DETECT_BY_EXT)) < 1) { /* Ok, automatic detection failed.. ask the user */ if ((filetype = gse_get_file_format_from_user (filename)) == GSE_SUBT_UNKNOWN) { g_free (filename); return; } } if (gse_fl_write_file (filename, filetype, GSE_NO_SPLIT) < 0) { msgbox = gnome_message_box_new (_("Unable to save to file '%s'"), GNOME_MESSAGE_BOX_ERROR, GNOME_STOCK_BUTTON_OK, NULL); gnome_dialog_run_and_close (GNOME_DIALOG (msgbox)); } else { gse_fl_open_file (filename, filetype, FALSE); } g_free (filename); } gint gse_get_file_format_from_user (gchar *filename) { gchar msg[100]; gint btn; GtkWidget *msgbox; g_snprintf (msg, 100, _("What kind of format should be used for\n'%s'?"), filename); msgbox = gnome_message_box_new (msg, GNOME_MESSAGE_BOX_QUESTION, "MicroDVD (.sub)", "SubRip (.srt)", GNOME_STOCK_BUTTON_CANCEL, NULL); btn = gnome_dialog_run_and_close (GNOME_DIALOG (msgbox)); switch (btn) { case 0: return GSE_SUBT_MICRODVD; break; case 1: return GSE_SUBT_SUBRIPPER; break; default: return GSE_SUBT_UNKNOWN; break; } } /* Asks the user if he he wishes to save the changes made to file */ gint gse_ask_user_save_changes (gchar *filename) { gchar msg[100]; GtkWidget *msgbox; g_snprintf (msg, 100, _("Do you wish to save the file '%s' first?"), filename); msgbox = gnome_message_box_new (msg, GNOME_MESSAGE_BOX_QUESTION, GNOME_STOCK_BUTTON_YES, GNOME_STOCK_BUTTON_NO, GNOME_STOCK_BUTTON_CANCEL, NULL); if (main_window) gnome_dialog_set_parent (GNOME_DIALOG (msgbox), GTK_WINDOW (main_window)); return gnome_dialog_run_and_close (GNOME_DIALOG (msgbox)); } void gse_cb_combolang_changed (GtkWidget *entry, gpointer data) { gchar *str, **ptr; gint i = 0; str = gtk_entry_get_text (GTK_ENTRY (entry)); if (cur_open_file.lang) g_free (cur_open_file.lang); /* We want the langcode, not the description! */ ptr = cfg.lang_list; while (ptr[i + 1] && !strstr(str, ptr[i])) i++; cur_open_file.lang = g_strdup (ptr[i + 1]); } void gse_cb_mwin_drop_recieved (GtkWidget *wgt, GdkDragContext *context, gint x, gint y, GtkSelectionData *data, guint info, guint tm, gpointer user_data) { gchar *filename; gint filetype; GtkWidget *msgbox; if ((cur_open_file.filename != NULL) && cur_open_file.changed) { switch (gse_ask_user_save_changes (cur_open_file.filename)) { case 2: return; break; case 1: break; case 0: gse_fl_write_file (cur_open_file.filename, cur_open_file.filetype, GSE_NO_SPLIT); break; } } switch (info) { case GSE_DROP_URL: filename = g_strdup (strchr (data->data, '/')); g_strchomp (filename); filetype = gse_fl_get_subtitle_format (filename, 0); break; case GSE_DROP_STRING: filename = g_strdup (data->data); g_strchomp (filename); if (access (filename, R_OK) != 0) { msgbox = gnome_message_box_new (_("Unable to find file '%s'\n" "Make sure the file exists and you have read permission to it!"), GNOME_MESSAGE_BOX_WARNING, GNOME_STOCK_BUTTON_OK, NULL); gnome_dialog_run_and_close (GNOME_DIALOG (msgbox)); return; } default: filename = NULL; } if ((filetype = gse_fl_get_subtitle_format (filename, 0)) == GSE_SUBT_UNKNOWN) { if ((filetype = gse_get_file_format_from_user (filename)) == GSE_SUBT_UNKNOWN) { g_free (filename); return; } } gse_fl_open_file (filename, filetype, FALSE); g_free (filename); } /* Opens a filerequester and performs action according to the 'data' variable */ /* FIXME: remove the annoying bug when dblclick on file-list */ void gse_cb_get_filename_from_user (GtkWidget *wgt, gpointer data) { static GtkWidget *file_selector; if (file_selector != NULL) return; file_selector = gtk_file_selection_new(_("Please select a file")); if (GPOINTER_TO_INT (data) == GSE_ACTION_SAVE_SUB) { gtk_file_selection_set_filename (GTK_FILE_SELECTION (file_selector), cfg.last_save_dir); gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(file_selector)->ok_button), "clicked", GTK_SIGNAL_FUNC (gse_cb_save_subtitle), file_selector); } else if (GPOINTER_TO_INT (data) == GSE_ACTION_OPEN_SUB) { /* Ask if user want to save file first */ if (cur_open_file.changed) { switch (gse_ask_user_save_changes (cur_open_file.filename)) { case 2: gtk_widget_destroy (file_selector); file_selector = NULL; return; case 1: break; case 0: gse_fl_write_file (cur_open_file.filename, cur_open_file.filetype, GSE_NO_SPLIT); break; } } gtk_file_selection_set_filename (GTK_FILE_SELECTION (file_selector), cfg.last_open_dir); gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(file_selector)->ok_button), "clicked", GTK_SIGNAL_FUNC (gse_cb_open_subtitle), file_selector); } gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION(file_selector)->ok_button), "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy), (gpointer) file_selector); gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION(file_selector)->cancel_button), "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy), (gpointer) file_selector); gtk_signal_connect (GTK_OBJECT (file_selector), "destroy", GTK_SIGNAL_FUNC (gtk_widget_destroyed), &file_selector); gtk_widget_show (file_selector); } /* Called if one of the buttons in the main window is pressed */ void gse_cb_btn_clicked (GtkWidget *btn, gpointer data) { GtkWidget *dialog; switch (GPOINTER_TO_INT (data)) { case GSE_ACTION_REOPEN: if (cur_open_file.filename == NULL) return; if (cur_open_file.changed) { dialog = gnome_message_box_new (_("This will abort all changes made\n" "to this file and revert to the original!"), GNOME_MESSAGE_BOX_WARNING, GNOME_STOCK_BUTTON_OK, GNOME_STOCK_BUTTON_CANCEL, NULL); if (gnome_dialog_run_and_close (GNOME_DIALOG (dialog)) != 0) break; } gse_fl_open_file (cur_open_file.filename, cur_open_file.filetype, FALSE); break; case GSE_ACTION_QUIT: gse_delete_main_window (NULL, NULL); break; case GSE_ACTION_SAVE_SUB: gse_cb_get_filename_from_user (NULL, data); } } /* "Closes" the file by clearing the clist and setting cur_open_file.filename to NULL */ void gse_cb_close_file (GtkWidget *wgt, gpointer data) { if (cur_open_file.filename == NULL) return; if (cur_open_file.changed) { switch (gse_ask_user_save_changes (cur_open_file.filename)) { case 2: return; case 1: break; case 0: gse_fl_write_file (cur_open_file.filename, cur_open_file.filetype, GSE_NO_SPLIT); break; } } /* Clean up after the file has been closed */ g_free (cur_open_file.filename); cur_open_file.filename = NULL; gtk_clist_clear (GTK_CLIST (mwin_clist)); gtk_entry_set_text (GTK_ENTRY (mwin_entry_start), ""); gtk_entry_set_text (GTK_ENTRY (mwin_entry_end), ""); gtk_editable_delete_text (GTK_EDITABLE (mwin_text_sub), 0, -1); gse_set_title_changed (FALSE); gse_set_menu_toolbar_state (GSE_NO_FILE_OPEN); gnome_appbar_clear_stack (GNOME_APPBAR (mwin_statusbar)); gnome_appbar_push (GNOME_APPBAR (mwin_statusbar), "Gnome Subtitle Editor version " VERSION); } void gse_cb_toolbar_open_file (GtkWidget *wgt) { gse_cb_get_filename_from_user (NULL, GINT_TO_POINTER (GSE_ACTION_OPEN_SUB)); } /* Called from the convert_framerate dialog so that we remember the state of the checkbutton the next time */ void gse_cb_chk_save_after_conv_clicked (GtkWidget *wgt, gpointer data) { cfg.save_after_conversion = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (wgt)); } /* Converts the currently open subtitle from one framerate to another * A dialog is shown where the user may select src and dest. fps */ void gse_cb_convert_framrate (GtkWidget *wgt, gpointer data) { GtkWidget *dialog, *lbl, *combo_s, *combo_d, *f_hbox, *chk; gint btn, i, col; gint hr, min, sec, msec; gchar *txt, converted[BUF_LEN]; gdouble src_fps, dest_fps, fr, tot_sec; GList *combo_framerates; if (cur_open_file.filename == NULL || gse_clist_is_empty (mwin_clist)) return; dialog = gnome_dialog_new (_("FPS Convert"), _("Convert"), GNOME_STOCK_BUTTON_CANCEL, NULL); gnome_dialog_set_parent (GNOME_DIALOG (dialog), GTK_WINDOW (main_window)); lbl = gtk_label_new (_("What framerates should be used in conversion?")); gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), lbl, FALSE, FALSE, 0); gtk_widget_show (lbl); combo_framerates = cfg_get_predefined_framerates (); f_hbox = gtk_hbox_new (FALSE, 5); lbl = gtk_label_new (_("Source fps:")); combo_s = gtk_combo_new (); gtk_combo_set_popdown_strings (GTK_COMBO (combo_s), combo_framerates); gtk_widget_set_usize (combo_s, 100, 22); gtk_widget_show (lbl); gtk_widget_show (combo_s); g_snprintf (converted, BUF_LEN, "%.3f", cur_open_file.fps); gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (combo_s)->entry), converted); gtk_box_pack_start (GTK_BOX (f_hbox), lbl, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (f_hbox), combo_s, FALSE, FALSE, 0); lbl = gtk_label_new (_("Dest. fps:")); combo_d = gtk_combo_new (); gtk_combo_set_popdown_strings (GTK_COMBO (combo_d), combo_framerates); gtk_widget_set_usize (combo_d, 100, 22); gtk_widget_show (lbl); gtk_widget_show (combo_d); gtk_box_pack_start (GTK_BOX (f_hbox), lbl, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (f_hbox), combo_d, FALSE, FALSE, 0); /* Shall we save the file automaticly? */ chk = gtk_check_button_new_with_label (_("Save file after conversion")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (chk), cfg.save_after_conversion); gtk_signal_connect (GTK_OBJECT (chk), "clicked", GTK_SIGNAL_FUNC (gse_cb_chk_save_after_conv_clicked), NULL); gtk_widget_show (chk); gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), f_hbox, TRUE, TRUE, 5); gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), chk, FALSE, FALSE, 5); gtk_widget_show (f_hbox); btn = gnome_dialog_run (GNOME_DIALOG (dialog)); if (btn == 0) { src_fps = g_strtod (gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (combo_s)->entry)), NULL); dest_fps = g_strtod (gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (combo_d)->entry)), NULL); if (src_fps == 0 || dest_fps == 0) { gnome_dialog_close (GNOME_DIALOG (dialog)); return; } glob_fps = dest_fps; for (i = 0; i < GTK_CLIST (mwin_clist)->rows; i++) { for (col = 1; col < 3; col++) { gtk_clist_get_text (GTK_CLIST (mwin_clist), i, col, &txt); if (cur_open_file.filetype == GSE_SUBT_SUBRIPPER) { /* Convert time to frame and back again with dest_fps */ gse_str_to_time (txt, &hr, &min, &sec, &msec); fr = gse_time_to_frame (src_fps, hr, min, sec, msec); tot_sec = gse_frame_to_time (dest_fps, fr); gse_parse_time (tot_sec, &hr, &min, &sec, &msec); g_snprintf (converted, BUF_LEN, "%.2d:%.2d:%.2d,%.3d", hr, min, sec, msec); } else { g_snprintf (converted, BUF_LEN, "%ld", gse_frame_rate_convert (atoi (txt), src_fps, dest_fps)); } gtk_clist_set_text (GTK_CLIST (mwin_clist), i, col, converted); } } if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (chk))) { if (gse_fl_write_file (cur_open_file.filename, cur_open_file.filetype, GSE_NO_SPLIT) == 1) gnome_appbar_push (GNOME_APPBAR (mwin_statusbar), _("Conversion done, file saved successfully")); } else { gnome_appbar_push (GNOME_APPBAR (mwin_statusbar), _("Conversion done")); cur_open_file.changed = TRUE; gse_set_title_changed (TRUE); } } gnome_dialog_close (GNOME_DIALOG (dialog)); } /* Adds an offset to all frames. Usefull if the framerate is correct, * but the subs appear to late/early * * If 'data' is _not_ NULL, then the dialog will be skipped and * the offset will be taken from 'data' (used by gse_cb_split_file) */ void gse_cb_displace_frames (GtkWidget *wgt, gdouble *data) { GtkWidget *dialog, *chk, *entry, *lbl; gint btn, i, fr, start, col; gint hr, min, sec, msec; gdouble fr_displ; gchar *txt, n_txt[10]; if (cur_open_file.filename == NULL || gse_clist_is_empty (mwin_clist)) return; /* To avoid some warnings from gcc */ dialog = chk = entry = NULL; start = fr_displ = 0; if (data == NULL) { if (cur_open_file.filetype == GSE_SUBT_SUBRIPPER) { dialog = gnome_dialog_new (_("Enter seconds"), _("Displace"), GNOME_STOCK_BUTTON_CANCEL, NULL); lbl = gtk_label_new (_("How many seconds should be added?\n" "'Seconds' can be negative and contain decimals (ie 1.234)")); } else { dialog = gnome_dialog_new (_("Enter frames"), _("Displace"), GNOME_STOCK_BUTTON_CANCEL, NULL); lbl = gtk_label_new (_("How many frames should be added?\n" "'Frame' can be negative")); } gnome_dialog_set_parent (GNOME_DIALOG (dialog), GTK_WINDOW (main_window)); entry = gtk_entry_new (); gtk_widget_show (lbl); gtk_widget_show (entry); chk = gtk_check_button_new_with_label (_("From current line (otherwise entire file)")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (chk), FALSE); gtk_widget_show (chk); gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), lbl, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), entry, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), chk, FALSE, FALSE, 5); gtk_widget_grab_focus (entry); gnome_dialog_set_default (GNOME_DIALOG (dialog), 0); gnome_dialog_editable_enters (GNOME_DIALOG (dialog), GTK_EDITABLE (entry)); btn = gnome_dialog_run (GNOME_DIALOG (dialog)); } else btn = 0; switch (btn) { case 0: /* Start displacing frames */ if (data == NULL) { if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (chk))) start = (int) GTK_CLIST (mwin_clist)->selection->data; fr_displ = g_strtod (gtk_entry_get_text (GTK_ENTRY (entry)), NULL); if (fr_displ == 0) /* Optimization ;-) */ { g_warning ("GSubEdit: Illegal displace value!"); gnome_dialog_close (GNOME_DIALOG (dialog)); return; } } else fr_displ = *data; for (i = start; i < GTK_CLIST (mwin_clist)->rows; i++) { for (col = 1; col < 3; col++) { gtk_clist_get_text (GTK_CLIST (mwin_clist), i, col, &txt); if (cur_open_file.filetype == GSE_SUBT_SUBRIPPER) { /* Do some conversion first.. */ gse_str_to_time (txt, &hr, &min, &sec, &msec); gse_add_to_time (fr_displ, &hr, &min, &sec, &msec); g_snprintf (n_txt, BUF_LEN, "%.2d:%.2d:%.2d,%.3d", hr, min, sec, msec); } else { fr = atoi (txt); fr += fr_displ; if (fr < 0) /* We don't want negative frame values */ fr = 0; g_snprintf (n_txt, BUF_LEN, "%d", fr); } gtk_clist_set_text (GTK_CLIST (mwin_clist), i, col, n_txt); } } cur_open_file.changed = TRUE; gse_set_title_changed (TRUE); break; } if (data == NULL) gnome_dialog_close (GNOME_DIALOG (dialog)); } void gse_cb_clist_insert_line (GtkWidget *wgt, gpointer data) { gint row; gchar *new_txt[4]; if (gse_clist_is_empty (mwin_clist)) return; row = (gint) GTK_CLIST (mwin_clist)->selection->data; gtk_clist_freeze (GTK_CLIST (mwin_clist)); gtk_clist_get_text (GTK_CLIST (mwin_clist), row - 1, 2, &(new_txt[1])); gtk_clist_get_text (GTK_CLIST (mwin_clist), row, 1, &(new_txt[2])); new_txt[0] = g_strdup (""); new_txt[3] = g_strdup (""); gtk_clist_insert (GTK_CLIST (mwin_clist), row, (gchar **) new_txt); gse_mwin_clist_update_index (); gtk_clist_thaw (GTK_CLIST (mwin_clist)); g_free (new_txt[0]); g_free (new_txt[3]); cur_open_file.changed = TRUE; gse_set_title_changed (TRUE); } /* FIXME: Can this be done w/o ougly hack?!? */ /*void gse_cb_copy_line (GtkWidget *wgt, gpointer data) { gchar *text; gchar cp_txt[BUF_LEN]; gint row, col; if (gse_clist_is_empty (mwin_clist)) return; row = (gint) GTK_CLIST (mwin_clist)->selection->data; *cp_txt = '\0'; for (col = 1, col < 4; col++) { gtk_clist_get_text (GTK_CLIST (mwin_clist), row, 1, &text); g_snprintf (cp_txt, BUF_LEN, "%s %s", cp_txt, text); } }*/ void gse_clist_move_line (gint direction) { gint row; gchar buf[15]; if (gse_clist_is_empty (mwin_clist)) return; row = (gint) GTK_CLIST (mwin_clist)->selection->data; if (direction == GSE_DIRECTION_UP) { if (row == 0) return; gtk_clist_swap_rows (GTK_CLIST (mwin_clist), row - 1, row); g_snprintf (buf, 15, "%d", row); gtk_clist_set_text (GTK_CLIST (mwin_clist), row - 1, 0, buf); g_snprintf (buf, 15, "%d", row + 1); gtk_clist_set_text (GTK_CLIST (mwin_clist), row, 0, buf); } else if (direction == GSE_DIRECTION_DOWN) { if (row == GTK_CLIST (mwin_clist)->rows) return; gtk_clist_swap_rows (GTK_CLIST (mwin_clist), row + 1, row); g_snprintf (buf, 15, "%d", row + 1); gtk_clist_set_text (GTK_CLIST (mwin_clist), row, 0, buf); g_snprintf (buf, 15, "%d", row + 2); gtk_clist_set_text (GTK_CLIST (mwin_clist), row + 1, 0, buf); } cur_open_file.changed = TRUE; gse_set_title_changed (TRUE); } void gse_cb_clist_move_up (GtkWidget *wgt, gpointer data) { gse_clist_move_line (GSE_DIRECTION_UP); } void gse_cb_clist_move_down (GtkWidget *wgt, gpointer data) { gse_clist_move_line (GSE_DIRECTION_DOWN); } void gse_cb_clist_delete_line (GtkWidget *wgt, gpointer data) { gint row; if (gse_clist_is_empty (mwin_clist)) return; row = (gint) GTK_CLIST (mwin_clist)->selection->data; gtk_clist_freeze (GTK_CLIST (mwin_clist)); gtk_clist_remove (GTK_CLIST (mwin_clist), row); gse_mwin_clist_update_index (); gtk_clist_thaw (GTK_CLIST (mwin_clist)); cur_open_file.changed = TRUE; gse_set_title_changed (TRUE); } void gse_cb_clist_reindex (GtkWidget *wgt, gpointer data) { gtk_clist_freeze (GTK_CLIST (mwin_clist)); gse_mwin_clist_update_index (); gtk_clist_thaw (GTK_CLIST (mwin_clist)); cur_open_file.changed = TRUE; gse_set_title_changed (TRUE); } void gse_cb_clist_jump_to_line (GtkWidget *wgt, gpointer data) { GtkWidget *dialog, *entry, *lbl; gint btn, row; if (gse_clist_is_empty (mwin_clist)) return; dialog = gnome_dialog_new (_("Enter line"), GNOME_STOCK_PIXMAP_JUMP_TO, GNOME_STOCK_BUTTON_CANCEL, NULL); if (main_window) gnome_dialog_set_parent (GNOME_DIALOG (dialog), GTK_WINDOW (main_window)); lbl = gtk_label_new (_("Enter the line number you want to jump to:")); gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), lbl, FALSE, FALSE, 2); gtk_widget_show (lbl); entry = gtk_entry_new (); gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), entry, FALSE, FALSE, 2); gnome_dialog_editable_enters (GNOME_DIALOG (dialog), GTK_EDITABLE (entry)); gnome_dialog_set_default (GNOME_DIALOG (dialog), 0); gtk_widget_show (entry); gtk_widget_grab_focus (entry); btn = gnome_dialog_run (GNOME_DIALOG (dialog)); if (btn == 0) { row = atoi (gtk_entry_get_text (GTK_ENTRY (entry))) - 1; gtk_clist_moveto (GTK_CLIST (mwin_clist), row, 0, 0.5, 0); gtk_clist_select_row (GTK_CLIST (mwin_clist), row, 0); } gnome_dialog_close (GNOME_DIALOG (dialog)); } void gse_cb_calc_fps (GtkWidget *wgt, gpointer data) { GtkWidget *dialog, *lbl, *hbox, *entry[2], *entry_time; gdouble sec, fps; gint start, end, diff, i; gchar *tmp; if (cur_open_file.filename == NULL || gse_clist_is_empty (mwin_clist)) return; dialog = gnome_dialog_new (_("Calculate Framerate"), "Calculate", GNOME_STOCK_BUTTON_CANCEL, NULL); gnome_dialog_set_default (GNOME_DIALOG (dialog), 0); lbl = gtk_label_new (_("How long time is it between the")); gtk_widget_show (lbl); gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), lbl, FALSE, FALSE, 0); for (i = 0; i < 2; i++) { hbox = gtk_hbox_new (FALSE, 0); lbl = gtk_label_new (_("start of the line")); entry[i] = gtk_entry_new (); gtk_box_pack_start (GTK_BOX (hbox), lbl, FALSE, FALSE, 3); gtk_box_pack_start (GTK_BOX (hbox), entry[i], FALSE, FALSE, 0); gtk_widget_show (lbl); gtk_widget_show (entry[i]); gtk_widget_set_usize (entry[i], 50, 22); if (i == 0) { lbl = gtk_label_new (_("and")); gtk_box_pack_start (GTK_BOX (hbox), lbl, FALSE, FALSE, 3); } else { lbl = gtk_label_new ("?"); gtk_box_pack_start (GTK_BOX (hbox), lbl, FALSE, FALSE, 3); } gtk_widget_show (lbl); gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), hbox, FALSE, FALSE, 0); gtk_widget_show (hbox); } hbox = gtk_hbox_new (FALSE, 0); gtk_clist_get_text (GTK_CLIST (mwin_clist), (gint) GTK_CLIST (mwin_clist)->selection->data, 0, &tmp); gtk_entry_set_text (GTK_ENTRY (entry[0]), tmp); entry_time = gtk_entry_new (); gtk_widget_set_usize (entry_time, 50, 22); lbl = gtk_label_new (_("Seconds.")); gtk_box_pack_start (GTK_BOX (hbox), entry_time, FALSE, FALSE, 3); gtk_box_pack_start (GTK_BOX (hbox), lbl, FALSE, FALSE, 0); gtk_widget_show (lbl); gtk_widget_show (entry_time); gnome_dialog_editable_enters (GNOME_DIALOG (dialog), GTK_EDITABLE (entry_time)); gtk_widget_show (hbox); gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), hbox, FALSE, FALSE, 0); gtk_widget_grab_focus (entry[0]); if (gnome_dialog_run (GNOME_DIALOG (dialog)) != 1) { sec = g_strtod (gtk_entry_get_text (GTK_ENTRY (entry_time)), NULL); if (sec <= 0) { g_warning ("GSubEdit: Illegal num '%.3lf'\n", sec); gnome_dialog_close (GNOME_DIALOG (dialog)); return; } start = atoi (gtk_entry_get_text (GTK_ENTRY (entry[0]))); gtk_clist_get_text (GTK_CLIST (mwin_clist), start, 1, &tmp); start = atoi (tmp); end = atoi (gtk_entry_get_text (GTK_ENTRY (entry[1]))); gtk_clist_get_text (GTK_CLIST (mwin_clist), end, 1, &tmp); end = atoi (tmp); diff = abs (end - start); fps = diff / sec; gnome_dialog_close (GNOME_DIALOG (dialog)); tmp = g_strdup_printf (_("A Frame diff of %d frames lasting %.3lf seconds means\n" "that the framerate is: %.3lf FPS."), diff, sec, fps); gnome_dialog_run_and_close (GNOME_DIALOG (gnome_message_box_new (tmp, GNOME_MESSAGE_BOX_INFO, GNOME_STOCK_BUTTON_OK, NULL))); cur_open_file.fps = fps; gse_gui_set_infobox_values (); } else gnome_dialog_close (GNOME_DIALOG (dialog)); } void gse_cb_clist_mouse_press_event (GtkWidget *clist, GdkEventButton *event, gpointer data) { gint row, col; if (event->button == 3) { if (gtk_clist_get_selection_info (GTK_CLIST (clist), event->x, event->y, &row, &col)) gtk_clist_select_row (GTK_CLIST (clist), row, col); } } /* Updates the text entries when a new row is selected in the clist */ void gse_cb_clist_select_row (GtkWidget *clist, gpointer data) { gchar *txt, *tmp; gint row, start_frame; gboolean update; /* Prevent the clist from being updated when new text is pasted into the entries */ update = cfg.auto_update_clist; cfg.auto_update_clist = FALSE; row = (int) GTK_CLIST (mwin_clist)->selection->data; gtk_clist_get_text (GTK_CLIST (mwin_clist), row, 1, &txt); start_frame = atoi (txt); gtk_entry_set_text (GTK_ENTRY (mwin_entry_start), txt); gtk_clist_get_text (GTK_CLIST (mwin_clist), row, 2, &txt); gtk_entry_set_text (GTK_ENTRY (mwin_entry_end), txt); gtk_clist_get_text (GTK_CLIST (mwin_clist), row, 3, &tmp); txt = g_strdup (tmp); txt = g_strdelimit (txt, "|", '\n'); gtk_text_freeze (GTK_TEXT (mwin_text_sub)); gtk_editable_select_region (GTK_EDITABLE (mwin_text_sub), 0, -1); gtk_editable_delete_selection (GTK_EDITABLE (mwin_text_sub)); gtk_text_insert(GTK_TEXT (mwin_text_sub), NULL, NULL, NULL, txt, -1); gtk_text_thaw (GTK_TEXT (mwin_text_sub)); /* Restore the cfg value */ cfg.auto_update_clist = update; /* Clear statusbar and insert standard message */ gnome_appbar_clear_stack (GNOME_APPBAR (mwin_statusbar)); gnome_appbar_push (GNOME_APPBAR (mwin_statusbar), "Gnome Subtitle Editor version " VERSION); g_free (txt); } /* Checks and fixes errors to the start- and endtag entered by the user * before updating to the clist */ gchar *gse_check_entry_for_errors (gchar *str) { gint hr, min, sec, msec; gchar *buf; buf = NULL; if (cur_open_file.filetype == GSE_SUBT_SUBRIPPER) { hr = min = sec = msec = 0; gse_str_to_time (str, &hr, &min, &sec, &msec); buf = g_strdup_printf ("%.2d:%.2d:%.2d,%.3d", hr, min, sec, msec); } else if (cur_open_file.filetype == GSE_SUBT_MICRODVD) { msec = atoi (str); buf = g_strdup_printf ("%d", msec); } return buf; } /* Updates the clist with the changes made in the edit-entries * if 'data' = 1, then an update will be performed, otherwise it will * only be performed if user has selected "auto update clist" from the * properties */ void gse_cb_update_edit_changes (GtkWidget *btn, gpointer data) { gchar *txt; gint row; if (gse_clist_is_empty (mwin_clist)) return; if ((GPOINTER_TO_INT (data) != 1) && cfg.auto_update_clist == FALSE) return; row = (int) GTK_CLIST (mwin_clist)->selection->data; txt = gse_check_entry_for_errors (gtk_entry_get_text (GTK_ENTRY (mwin_entry_start))); gtk_clist_set_text (GTK_CLIST (mwin_clist), row, 1, txt); g_free (txt); txt = gse_check_entry_for_errors (gtk_entry_get_text (GTK_ENTRY (mwin_entry_end))); gtk_clist_set_text (GTK_CLIST (mwin_clist), row, 2, txt); g_free (txt); txt = gtk_editable_get_chars (GTK_EDITABLE (mwin_text_sub), 0, -1); txt = g_strdelimit (txt, "\n", '|'); gtk_clist_set_text (GTK_CLIST (mwin_clist), row, 3, txt); cur_open_file.changed = TRUE; gse_set_title_changed (TRUE); gtk_clist_set_background (GTK_CLIST (mwin_clist), row, &white); g_free (txt); } void gse_cb_chk_hearing_impaired_click (GtkWidget *wgt, gpointer data) { switch (GPOINTER_TO_INT (data)) { case 1: cfg.hi_rm_bracket = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (wgt)); break; case 2: cfg.hi_rm_at = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (wgt)); break; case 3: cfg.hi_rm_custom = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (wgt)); break; } } /* Removes any text between '[' and ']' and removes any empty rows from the clist */ void gse_cb_rm_hearing_impaired (GtkWidget *wgt, gpointer data) { GtkWidget *dialog, *chk, *lbl, *chr_start, *chr_end, *custom_hbox; gint btn, row, i, count = 0; gchar *txt, *n_txt; gint custom_start, custom_end; if (gse_clist_is_empty (mwin_clist)) return; dialog = gnome_dialog_new (_("Clean up subtitle"), _("Start cleaning") , GNOME_STOCK_BUTTON_CANCEL, NULL); lbl = gtk_label_new (_("Select what to remove:")); gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), lbl, FALSE, FALSE, 0); gtk_widget_show (lbl); chk = gtk_check_button_new_with_label (_("Remove anything between '[' and ']' (Sounds/Speaker)")); gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), chk, FALSE, FALSE, 0); gtk_signal_connect (GTK_OBJECT (chk), "clicked", GTK_SIGNAL_FUNC (gse_cb_chk_hearing_impaired_click), GINT_TO_POINTER (1)); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (chk), cfg.hi_rm_bracket); gtk_widget_show (chk); chk = gtk_check_button_new_with_label (_("Remove anything between '@' and '@' (Singing)")); gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), chk, FALSE, FALSE, 0); gtk_signal_connect (GTK_OBJECT (chk), "clicked", GTK_SIGNAL_FUNC (gse_cb_chk_hearing_impaired_click), GINT_TO_POINTER (2)); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (chk), cfg.hi_rm_at); gtk_widget_show (chk); chk = gtk_check_button_new_with_label (_("Use custom remove:")); gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), chk, FALSE, FALSE, 0); gtk_signal_connect (GTK_OBJECT (chk), "clicked", GTK_SIGNAL_FUNC (gse_cb_chk_hearing_impaired_click), GINT_TO_POINTER (3)); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (chk), cfg.hi_rm_custom); gtk_widget_show (chk); /* Create the "custom" hbox */ custom_hbox = gtk_hbox_new (FALSE, 2); lbl = gtk_label_new (_("Remove anything between")); gtk_box_pack_start (GTK_BOX (custom_hbox), lbl, FALSE, FALSE, 0); gtk_widget_show (lbl); chr_start = gtk_entry_new_with_max_length (1); gtk_box_pack_start (GTK_BOX (custom_hbox), chr_start, FALSE, FALSE, 0); gtk_widget_set_usize (chr_start, 30, 22); gtk_widget_show (chr_start); lbl = gtk_label_new (_("and")); gtk_box_pack_start (GTK_BOX (custom_hbox), lbl, FALSE, FALSE, 0); gtk_widget_show (lbl); chr_end = gtk_entry_new_with_max_length (1); gtk_box_pack_start (GTK_BOX (custom_hbox), chr_end, FALSE, FALSE, 0); gtk_widget_set_usize (chr_end, 30, 22); gtk_widget_show (chr_end); gtk_widget_show (custom_hbox); gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), custom_hbox, FALSE, FALSE, 0); btn = gnome_dialog_run (GNOME_DIALOG (dialog)); if (btn == 1 || !(cfg.hi_rm_bracket || cfg.hi_rm_at || cfg.hi_rm_custom)) /* abort if cancel click or if nothing is to be removed */ { gnome_dialog_close (GNOME_DIALOG (dialog)); return; } /* get the custom start/end chars, and check them for errors! */ custom_start = *(gtk_entry_get_text (GTK_ENTRY (chr_start))); custom_end = *(gtk_entry_get_text (GTK_ENTRY (chr_end))); gnome_dialog_close (GNOME_DIALOG (dialog)); if (cfg.hi_rm_custom) { if (custom_start == '\0') { if (custom_end == '\0') cfg.hi_rm_custom = FALSE; else custom_start = custom_end; } else if (custom_end == '\0') custom_end = custom_start; } gtk_clist_freeze (GTK_CLIST (mwin_clist)); for (row = 0; row < GTK_CLIST (mwin_clist)->rows; row++) { gtk_clist_get_text (GTK_CLIST (mwin_clist), row, 3, &txt); n_txt = g_malloc0 (strlen(txt) + 1); i = 0; for (; *txt != '\0'; txt++) { switch (*txt) { case '[': if (cfg.hi_rm_bracket) { if (strchr (txt, ']') != NULL) { txt = strchr (txt, ']'); count++; } } else { n_txt[i] = *txt; i++; } break; case '@': if (cfg.hi_rm_at) { if (strchr (txt + 1, '@') != NULL) { txt = strchr (txt + 1, '@'); count++; } } else { n_txt[i] = *txt; i++; } break; default: if (cfg.hi_rm_custom && *txt == custom_start) { if (strchr (txt + 1, custom_end) != NULL) { txt = strchr (txt + 1, custom_end); count++; } } else { n_txt[i] = *txt; i++; } break; } } gse_str_remove_empty_lines (&n_txt); if (*n_txt == '\0') { gtk_clist_remove (GTK_CLIST (mwin_clist), row); row--; /* We deleted one row, wich means that 'row' must be decreased.. */ } else { txt = g_strdup_printf ("%d", row + 1); /* Save the index.. */ gtk_clist_set_text (GTK_CLIST (mwin_clist), row, 3, n_txt); gtk_clist_set_text (GTK_CLIST (mwin_clist), row, 0, txt); g_free (txt); } g_free (n_txt); } gtk_clist_thaw (GTK_CLIST (mwin_clist)); if (count) { gse_set_title_changed (TRUE); cur_open_file.changed = TRUE; } txt = g_strdup_printf (_("Action complete, %d entries removed!"), count); gnome_appbar_push (GNOME_APPBAR (mwin_statusbar), txt); g_free (txt); } void gse_cb_join_radio_clicked_1 (GtkWidget *rdo, GtkWidget *entry[2]) { // gtk_widget_set_sensitive (entry[0].lbl, FALSE); gtk_widget_set_sensitive (entry[0], FALSE); gtk_widget_grab_focus (gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (entry[1]))); } void gse_cb_join_radio_clicked_2 (GtkWidget *rdo, GtkWidget *entry[2]) { // gtk_widget_set_sensitive (entry[0].lbl, TRUE); gtk_widget_set_sensitive (entry[0], TRUE); } /* Either joins two files into one new or appends a file to the one currently open */ void gse_cb_join_files (GtkWidget *wgt, gpointer data) { GtkWidget *gnome_f_entry[2], *entry_fl[2]; GtkWidget *dialog, *rdo1, *rdo2; gchar *cur_dir, *tmp_name, *lbltxt, *fname[2], msg[BUF_LEN], *orig_name = NULL; gint i, join_mode = 0, ret_val[2]; gboolean error[2] = { TRUE, TRUE }; dialog = gnome_dialog_new (_("Join files"), _("Join"), GNOME_STOCK_BUTTON_CANCEL, NULL); gnome_dialog_set_parent (GNOME_DIALOG (dialog), GTK_WINDOW (main_window)); rdo1 = gtk_radio_button_new_with_label (NULL, _("Append to current open file")); gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), rdo1, FALSE, FALSE, 0); gtk_widget_show (rdo1); gtk_signal_connect (GTK_OBJECT (rdo1), "clicked", GTK_SIGNAL_FUNC (gse_cb_join_radio_clicked_1), gnome_f_entry); rdo2 = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (rdo1), _("Join two files into one new")); gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), rdo2, FALSE, FALSE, 0); gtk_widget_show (rdo2); gtk_signal_connect (GTK_OBJECT (rdo2), "clicked", GTK_SIGNAL_FUNC (gse_cb_join_radio_clicked_2), gnome_f_entry); fname[0] = fname[1] = NULL; for (i = 0; i < 2; i++) { lbltxt = g_strdup_printf (_("File %d:"), i + 1); gnome_f_entry[i] = gnome_file_entry_new (NULL, lbltxt); g_free (lbltxt); gnome_file_entry_set_default_path (GNOME_FILE_ENTRY (gnome_f_entry[i]), cfg.last_open_dir); entry_fl[i] = gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (gnome_f_entry[i])); gtk_widget_show (gnome_f_entry[i]); gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), gnome_f_entry[i], TRUE, TRUE, 0); } if (cur_open_file.filename == NULL) { gtk_widget_set_sensitive (rdo1, FALSE); gtk_button_clicked (GTK_BUTTON (rdo2)); gtk_widget_grab_focus (entry_fl[0]); } else { orig_name = g_strdup (cur_open_file.filename); gtk_button_clicked (GTK_BUTTON (rdo1)); gtk_widget_grab_focus (entry_fl[1]); } if (gnome_dialog_run (GNOME_DIALOG (dialog)) == 0) { if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rdo1))) join_mode = 1; /* Appending - One filenames required */ else join_mode = 2; /* Joining - Two filenames required */ cur_dir = g_get_current_dir (); for (i = 1; i > (1 - join_mode); i--) { tmp_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry_fl[i]))); /* Check for empty filenames. If we're appending a file, no filename is required for file #1 */ if (*tmp_name == '\0') { g_free (tmp_name); g_warning ("GSubEdit: No filename specified (file %d)", i); gnome_dialog_close (GNOME_DIALOG (dialog)); return; } if (g_path_is_absolute (tmp_name)) fname[i] = g_strdup(tmp_name); else fname[i] = g_strdup_printf ("%s/%s", cur_dir, tmp_name); g_free (tmp_name); } g_free (cur_dir); /* Open/append files */ ret_val[0] = ret_val[1] = GSE_FILE_NO_ERRORS; if (join_mode == 2) ret_val[0] = gse_fl_open_file (fname[0], gse_fl_get_subtitle_format (fname[0], FALSE), FALSE); if (ret_val[0] != GSE_FILE_ERROR_OPEN_R && ret_val[0] != GSE_FILE_UNKNOWN_TYPE) ret_val[1] = gse_fl_open_file (fname[1], gse_fl_get_subtitle_format (fname[1], FALSE), TRUE); /* FIXME: Perhaps this should be an external function.. */ for (i = 0; i < 2; i++) { switch (ret_val[i]) { case GSE_FILE_NO_ERRORS: error[i] = FALSE; break; case GSE_FILE_ERROR_OPEN_R: g_snprintf (msg, BUF_LEN, _("Error opening file '%s'.\n" "Check if you have read permission to it!"), fname[i]); gnome_dialog_run_and_close (GNOME_DIALOG (gnome_message_box_new (msg, GNOME_MESSAGE_BOX_WARNING, GNOME_STOCK_BUTTON_OK, NULL))); break; case GSE_FILE_CORRECTED_VALUES: g_snprintf (msg, BUF_LEN, _("Errors were found in file #%d\n" "Please check the result!"), i + 1); gnome_dialog_run_and_close (GNOME_DIALOG (gnome_message_box_new (msg, GNOME_MESSAGE_BOX_INFO, GNOME_STOCK_BUTTON_OK, NULL))); break; case GSE_FILE_UNKNOWN_TYPE: g_snprintf (msg, BUF_LEN, _("Unable to determine file format of '%s'.\n"), fname[i]); gnome_dialog_run_and_close (GNOME_DIALOG (gnome_message_box_new (msg, GNOME_MESSAGE_BOX_WARNING, GNOME_STOCK_BUTTON_OK, NULL))); break; case GSE_FILE_ERROR_APPEND_FTYPE: g_snprintf (msg, BUF_LEN, _("Unable to append file '%s'.\n" "The fileformat is not the same as the first file"), fname[i]); gnome_dialog_run_and_close (GNOME_DIALOG (gnome_message_box_new (msg, GNOME_MESSAGE_BOX_WARNING, GNOME_STOCK_BUTTON_OK, NULL))); break; } } } gnome_dialog_close (GNOME_DIALOG (dialog)); if (join_mode == 1 && (!error[0]) && (!error[1])) { g_free (cur_open_file.filename); cur_open_file.filename = g_strdup (_(GSE_UNTITLED_FILE)); } if (!error[0] && !error[1]) { g_free (cur_open_file.filename); cur_open_file.filename = orig_name; cur_open_file.changed = TRUE; gse_set_title_changed (TRUE); } for (i = 0; i < 2; i++) g_free (fname[i]); } /* Splits a file into two parts */ void gse_cb_split_file (GtkWidget *wgt, gpointer data) { GtkWidget *dialog, *entry_fl[2], *entry_split, *lbl, *hbox, *gnome_f_entry; gint btn, split, filetype, i; gint hr, min, sec, msec; gdouble tot_sec, diff; gchar *fname[2], *ext, *tmp_name, *lbltxt, *cur_dir; if (cur_open_file.filename == NULL) return; dialog = gnome_dialog_new (_("Split file"), _("Split"), GNOME_STOCK_BUTTON_CANCEL, NULL); gnome_dialog_set_parent (GNOME_DIALOG (dialog), GTK_WINDOW (main_window)); lbl = gtk_label_new (_("Split current file into:\n" "(If first char is a '/' then absoulut path will be used\n" "otherwise from current dir)")); gtk_widget_show (lbl); gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), lbl, FALSE, FALSE, 0); tmp_name = g_strdup (cur_open_file.filename); ext = g_strdup (strrchr (tmp_name, '.')); *(strrchr (tmp_name, '.')) = '\0'; for (i = 0; i < 2; i++) { lbltxt = g_strdup_printf (_("File %d:"), i + 1); gnome_f_entry = gnome_file_entry_new (NULL, lbltxt); g_free (lbltxt); gnome_file_entry_set_default_path (GNOME_FILE_ENTRY (gnome_f_entry), cfg.last_save_dir); entry_fl[i] = gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (gnome_f_entry)); fname[i] = g_strdup_printf ("%s (%d of 2)%s", tmp_name, i + 1, ext); gtk_entry_set_text (GTK_ENTRY (entry_fl[i]), fname[i]); gtk_widget_show (gnome_f_entry); gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), gnome_f_entry, TRUE, TRUE, 0); } g_free (ext); g_free (tmp_name); hbox = gtk_hbox_new (FALSE, 5); lbl = gtk_label_new (_("Row to split:")); gtk_widget_show (lbl); gtk_box_pack_start (GTK_BOX (hbox), lbl, FALSE, FALSE, 0); entry_split = gtk_entry_new_with_max_length (14); gtk_clist_get_text (GTK_CLIST (mwin_clist), (int) GTK_CLIST (mwin_clist)->selection->data, 0, &tmp_name); gtk_entry_set_text (GTK_ENTRY (entry_split), tmp_name); gtk_widget_set_usize (entry_split, 60, 22); gtk_widget_show (entry_split); gtk_box_pack_start (GTK_BOX (hbox), entry_split, FALSE, FALSE, 0); gtk_widget_show (hbox); gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), hbox, FALSE, FALSE, 0); gtk_widget_grab_focus (entry_fl[0]); if ((btn = gnome_dialog_run (GNOME_DIALOG (dialog))) == 0) { cur_dir = g_get_current_dir (); for (i = 0; i < 2; i++) { tmp_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry_fl[i]))); if (*tmp_name == '\0') { g_free (tmp_name); g_warning ("GSubEdit: No filename specified (file %d)", i); gnome_dialog_close (GNOME_DIALOG (dialog)); return; } if (g_path_is_absolute (tmp_name)) fname[i] = g_strdup(tmp_name); else fname[i] = g_strdup_printf ("%s/%s", cur_dir, tmp_name); g_free (tmp_name); } g_free (cur_dir); split = atoi (gtk_entry_get_text (GTK_ENTRY (entry_split))); if (split == 0 || split > GTK_CLIST (mwin_clist)->rows) { g_warning ("GSubEdit: Illegal value to split!\n"); gnome_dialog_close (GNOME_DIALOG (dialog)); g_free (fname[0]); g_free (fname[1]); return; } filetype = gse_fl_get_subtitle_format (fname[0], CFG_DETECT_BY_EXT); gse_fl_write_file (fname[0], filetype, split); /* Remove all lines up to 'split' */ gtk_clist_freeze (GTK_CLIST (mwin_clist)); for (i = 0; i < split; i++) gtk_clist_remove (GTK_CLIST (mwin_clist), 0); gtk_clist_get_text (GTK_CLIST (mwin_clist), 0, 1, &tmp_name); if (cur_open_file.filetype == GSE_SUBT_SUBRIPPER) { gse_str_to_time (tmp_name, &hr, &min, &sec, &msec); tot_sec = (hr * 3600) + (min * 60) + (sec); tot_sec += (gdouble) msec / 1000; diff = tot_sec * -1; } else diff = atoi (tmp_name) * -1; /* Call displace frames with argument 'diff' to indicate that no dialog should be shown */ gse_cb_displace_frames (NULL, (gpointer) &diff); gse_mwin_clist_update_index (); gse_fl_write_file (fname[1], filetype, GSE_NO_SPLIT); g_free (fname[0]); g_free (fname[1]); gtk_clist_thaw (GTK_CLIST (mwin_clist)); } gnome_dialog_close (GNOME_DIALOG (dialog)); } /* Trap the keypresses from the CList */ void gse_cb_clist_key_press_event (GtkWidget *clist, GdkEventKey *event, gpointer data) { gboolean stop = FALSE; switch (event->keyval) { case GDK_J: case GDK_j: case GDK_G: case GDK_g: gse_cb_clist_jump_to_line (NULL, NULL); break; case GDK_F: case GDK_f: gse_srch_show_find_dialog (NULL, NULL); break; case GDK_I: case GDK_i: gse_cb_clist_insert_line (NULL, NULL); break; case GDK_Delete: gse_cb_clist_delete_line (NULL, NULL); break; case GDK_Return: case GDK_KP_Enter: gtk_clist_select_row (GTK_CLIST (clist), (gint) GTK_CLIST (clist)->selection->data, 0); break; case GDK_Up: if ((event->state) & GDK_CONTROL_MASK) { gse_clist_move_line (GSE_DIRECTION_UP); stop = TRUE; } break; case GDK_Down: if ((event->state) & GDK_CONTROL_MASK) { gse_clist_move_line (GSE_DIRECTION_DOWN); stop = TRUE; } break; } /* Keep the focus in the clist by removing the control mask */ if (stop) { if ((event->keyval) == GDK_Up) gtk_signal_emit_stop_by_name (GTK_OBJECT (clist), "key_press_event"); else event->state = event->state ^ 0x04; } } void gse_cb_text_edit_key_press_event (GtkWidget *txt_entry, GdkEventKey *event, gpointer data) { switch (event->keyval) { case GDK_Return: if ((event->state) & GDK_CONTROL_MASK) { if (!cfg.auto_update_clist) gse_cb_update_edit_changes (NULL, GINT_TO_POINTER (TRUE)); gtk_clist_select_row (GTK_CLIST (mwin_clist), (gint) GTK_CLIST (mwin_clist)->selection->data + 1, 0); gtk_clist_moveto (GTK_CLIST (mwin_clist), (gint) GTK_CLIST (mwin_clist)->selection->data, 0, 0.5, 0); } break; } }