7 #include "filesystem.h"
9 #include "localsession.h"
10 #include "mainerror.h"
12 #include "mainsession.h"
15 #include "mwindowgui.h"
30 SWindowOK::SWindowOK(SWindowGUI *gui, int x, int y)
36 SWindowOK::~SWindowOK()
40 int SWindowOK::button_press_event()
42 if(get_buttonpress() == 1 && is_event_win() && cursor_inside()) {
49 int SWindowOK::keypress_event()
55 SWindowCancel::SWindowCancel(SWindowGUI *gui, int x, int y)
56 : BC_CancelButton(x, y)
61 SWindowCancel::~SWindowCancel()
65 int SWindowCancel::button_press_event()
67 if(get_buttonpress() == 1 && is_event_win() && cursor_inside()) {
75 SWindowLoadPath::SWindowLoadPath(SWindowGUI *gui, int x, int y, char *path)
76 : BC_TextBox(x, y, xS(200), 1, path)
81 SWindowLoadPath::~SWindowLoadPath()
85 int SWindowLoadPath::handle_event()
87 calculate_suggestions();
88 strcpy(sw_gui->script_path, get_text());
93 SWindowLoadFile::SWindowLoadFile(SWindowGUI *gui, int x, int y)
94 : BC_GenericButton(x, y, _("Load"))
99 SWindowLoadFile::~SWindowLoadFile()
103 int SWindowLoadFile::handle_event()
105 if( sw_gui->script_path[0] ) {
106 sw_gui->load_path->set_suggestions(0,0);
107 sw_gui->load_script();
108 sw_gui->set_script_pos(0);
111 eprintf(_("script text file path required"));
116 SWindowSaveFile::SWindowSaveFile(SWindowGUI *gui, int x, int y)
117 : BC_GenericButton(x, y, _("Save"))
122 SWindowSaveFile::~SWindowSaveFile()
126 int SWindowSaveFile::handle_event()
128 if( sw_gui->script_path[0] ) {
129 sw_gui->save_spumux_data();
132 eprintf(_("script file path required"));
140 void SWindowGUI::create_objects()
142 lock_window("SWindowGUI::create_objects");
143 int x = xS(10), y = yS(10);
144 BC_Title *title = new BC_Title(x, y, _("Path:"));
145 add_subwindow(title);
146 int x1 = x + title->get_w() + xpad, y1 = y;
147 load_path = new SWindowLoadPath(this, x1, y1, script_path);
148 add_subwindow(load_path);
149 x1 += load_path->get_w() + 2*xpad;
150 add_subwindow(load_file = new SWindowLoadFile(this, x1, y1));
151 x1 += load_file->get_w() + 2*xpad;
152 add_subwindow(save_file = new SWindowSaveFile(this, x1, y1));
153 x1 += save_file->get_w() + 2*xpad;
154 add_subwindow(save_format = new SWindowSaveFormat(this, x1, y1));
155 save_format->create_objects();
156 y += max(load_path->get_h(), load_file->get_h()) + ypad;
157 x1 = x + ypad, y1 = y;
158 BC_Title *title1, *title2;
159 add_subwindow(title1 = new BC_Title(x1, y1, _("File Size:")));
160 y += title1->get_h() + ypad;
162 add_subwindow(title2 = new BC_Title(x1, y2, _("Entries:")));
163 int x2 = x1 + max(title1->get_w(), title2->get_w()) + xpad;
164 add_subwindow(script_filesz = new BC_Title(x2, y1, "0", MEDIUMFONT, YELLOW));
165 add_subwindow(script_entries = new BC_Title(x2, y2, "0", MEDIUMFONT, YELLOW));
166 int x3 = x2 + max(script_entries->get_w()*8, script_filesz->get_w()*8) + xpad;
167 add_subwindow(title1 = new BC_Title(x3, y1, _("Lines:")));
168 add_subwindow(title2 = new BC_Title(x3, y2, _("Texts:")));
169 int x4 = x3 + max(title1->get_w(), title2->get_w()) + xpad;
170 add_subwindow(script_lines = new BC_Title(x4, y1, "0", MEDIUMFONT, YELLOW));
171 add_subwindow(script_texts = new BC_Title(x4, y2, "0", MEDIUMFONT, YELLOW));
172 int x5 = x4 + max(script_lines->get_w()*8, script_texts->get_w()*8) + 2*xpad;
173 add_subwindow(prev_script = new ScriptPrev(this, x5, y1));
174 add_subwindow(next_script = new ScriptNext(this, x5, y2));
175 int x6 = x5 + max(prev_script->get_w(), next_script->get_w()) + 2*xpad;
176 add_subwindow(paste_script = new ScriptPaste(this, x6, y1));
177 add_subwindow(clear_script = new ScriptClear(this, x6, y2));
178 y += max(title1->get_h(), title2->get_h()) + 2*ypad;
180 script_position = new ScriptPosition(this, x, y, xS(100));
181 script_position->create_objects();
182 x1 = x + script_position->get_w() + xpad;
183 add_subwindow(script_scroll = new ScriptScroll(this, x1, y, get_w()-x1-xpad));
184 y += script_scroll->get_h() + 2*ypad;
186 blank_line = new char[2];
187 blank_line[0] = ' '; blank_line[1] = 0;
188 add_subwindow(script_title = new BC_Title(x1, y, _("Script Text:")));
189 y += script_title->get_h() + ypad;
190 int rows = (ok_y - y - BC_Title::calculate_h(this,_("Line Text:")) -
191 4*ypad) / text_rowsz - 4;
192 int w1 = get_w() - x1 - xpad;
193 script_entry = new ScriptEntry(this, x1, y, w1, rows, blank_line);
194 script_entry->create_objects();
195 y += script_entry->get_h() + ypad;
196 add_subwindow(line_title = new BC_Title(x1, y, _("Line Text:")));
197 y += line_title->get_h() + ypad;
198 line_entry = new ScriptEntry(this, x1, y, w1, 4);
199 line_entry->create_objects();
200 ok = new SWindowOK(this, ok_x, ok_y);
202 cancel = new SWindowCancel(this, cancel_x, cancel_y);
203 add_subwindow(cancel);
207 void SWindowGUI::load()
209 const char *script_text =
210 _("Adding Subtitles: quick \"How To\" (= or * indicates comment)\n"
211 "*2345678901234567890123456789012345678901234567890123456789\n"
212 "For regular DVD subtitles, put script in a text file. "
213 "Lines can be any length but they will be broken up "
214 "to fit according to some criteria below.\n"
215 "Running text used as script lines will be broken into multilple lines.\n"
216 "The target line length is 60 characters.\n"
217 "Punctuation may be flagged to create an early line break.\n"
218 "Single carriage return ends an individual script line.\n"
219 "Double carriage return indicates the end of an entry.\n"
220 "Whitespace at beginning or end of line is removed.\n"
221 "You can edit the active line in the Line Text box.\n"
223 "== A new entry is here for illustration purposes.\n"
225 "This is the second entry.\n");
227 if( script_path[0] && !access(script_path,R_OK) ) {
232 load_path->update(script_path);
233 FILE *fp = fmemopen((void *)script_text, strlen(script_text), "r");
236 int text_no = script_text_no;
238 load_selection(script_entry_no, text_no);
241 SWindowGUI::SWindowGUI(SWindow *swindow, int x, int y, int w, int h)
242 : BC_Window(_(PROGRAM_NAME ": Subtitle"), x, y, w, h, xS(600), yS(500),
243 1, 0, 0 , -1, swindow->mwindow->get_cwindow_display())
245 this->swindow = swindow;
250 ok_w = BC_OKButton::calculate_w();
251 ok_h = BC_OKButton::calculate_h();
253 ok_y = h - ok_h - yS(10);
255 cancel_w = BC_CancelButton::calculate_w();
256 cancel_h = BC_CancelButton::calculate_h();
257 cancel_x = w - cancel_w - xS(10);
258 cancel_y = h - cancel_h - yS(10);
270 script_text_lines = 0;
280 text_font = MEDIUMFONT;
281 text_rowsz = get_text_ascent(text_font)+1 + get_text_descent(text_font)+1;
282 sub_format = SUB_FORMAT_SRT;
285 SWindowGUI::~SWindowGUI()
289 delete script_position;
290 delete [] blank_line;
293 void SWindowGUI::stop(int v)
295 if( !swindow->gui_done ) {
296 swindow->gui_done = 1;
301 int SWindowGUI::translation_event()
303 swindow->mwindow->session->swindow_x = get_x();
304 swindow->mwindow->session->swindow_y = get_y();
308 int SWindowGUI::resize_event(int w, int h)
310 swindow->mwindow->session->swindow_w = w;
311 swindow->mwindow->session->swindow_h = h;
314 ok_y = h - ok_h - yS(10);
315 ok->reposition_window(ok_x, ok_y);
316 cancel_x = w - cancel_w - xS(10);
317 cancel_y = h - cancel_h - yS(10);
318 cancel->reposition_window(cancel_x, cancel_y);
320 int x = script_position->get_x();
321 int y = script_position->get_y();
322 int hh = script_position->get_h();
323 int ww = script_position->get_w();
324 int x1 = x + ww + xpad;
325 int w1 = w - x1 - xpad;
326 script_scroll->reposition_window(x1, y, w1);
328 script_title->reposition_window(x, y);
329 y += script_title->get_h() + ypad;
331 int rows = (ok_y - y - line_title->get_h() - 4*ypad) / text_rowsz - 4;
332 script_entry->reposition_window(x, y, w1, rows);
333 y += script_entry->get_h() + 2*ypad;
334 line_title->reposition_window(x, y);
335 y += line_title->get_h() + ypad;
336 line_entry->reposition_window(x, y, w1, 4);
340 void SWindowGUI::load_defaults()
342 BC_Hash *defaults = swindow->mwindow->defaults;
343 defaults->get("SUBTTL_SCRIPT_PATH", script_path);
344 script_entry_no = defaults->get("SUBTTL_SCRIPT_ENTRY_NO", script_entry_no);
345 script_text_no = defaults->get("SUBTTL_SCRIPT_TEXT_NO", script_text_no);
346 sub_format = defaults->get("SUBTTL_SCRIPT_FORMAT", sub_format);
349 void SWindowGUI::save_defaults()
351 BC_Hash *defaults = swindow->mwindow->defaults;
352 defaults->update("SUBTTL_SCRIPT_PATH", script_path);
353 defaults->update("SUBTTL_SCRIPT_ENTRY_NO", script_entry_no);
354 defaults->update("SUBTTL_SCRIPT_TEXT_NO", script_text_no);
355 defaults->update("SUBTTL_SCRIPT_FORMAT", sub_format);
358 void SWindowGUI::set_script_pos(int64_t entry_no, int text_no)
360 script_entry_no = entry_no<0 ? 0 :
361 entry_no>script.size()-1 ? script.size()-1 : entry_no;
362 script_text_no = text_no-1;
363 load_next_selection();
366 int SWindowGUI::load_selection(int pos, int row)
368 if( pos < 0 || pos >= script.size() ) return 1;
369 ScriptLines *texts = script[pos];
370 char *rp = texts->get_text_row(row);
371 if( !rp || *rp == '=' || *rp == '*' || *rp=='\n' ) return 1;
372 if( pos != script_entry_no || script_text_no < 0 ) {
373 script_entry_no = pos;
374 script_scroll->update_value(script_entry_no);
375 script_position->update(script_entry_no);
376 script_entry->set_text(texts->text);
377 script_entry->set_text_row(0);
379 script_text_no = row;
380 char line[BCTEXTLEN], *bp = line;
381 char *ep = bp+sizeof(line)-1, *cp = rp;
382 while( bp < ep && *cp && *cp!='\n' ) *bp++ = *cp++;
383 *bp = 0; bp = texts->text;
384 int char1 = rp-bp, char2 = cp-bp;
385 script_entry->set_selection(char1, char2, char2);
386 int rows = script_entry->get_rows();
387 int rows2 = rows / 2;
388 int rows1 = texts->lines+1 - rows;
389 if( (row-=rows2) > rows1 ) row = rows1;
390 if( row < 0 ) row = 0;
391 script_entry->set_text_row(row);
392 line_entry->update(line);
393 line_entry->set_text_row(0);
397 int SWindowGUI::load_prev_selection()
399 int pos = script_entry_no, row = script_text_no;
400 if( pos < 0 || pos >= script.size() ) return 1;
403 if( --pos < 0 ) break;
404 row = script[pos]->lines;
407 if( !load_selection(pos, row) )
413 int SWindowGUI::load_next_selection()
415 int pos = script_entry_no, row = script_text_no;
416 if( pos < 0 || pos >= script.size() ) return 1;
418 if( ++row >= script[pos]->lines ) {
419 if( ++pos >= script.size() ) break;
423 if( !load_selection(pos, row) )
429 int SWindowGUI::update_selection()
431 EDL *edl = swindow->mwindow->edl;
432 LocalSession *lsn = edl->local_session;
433 double position = lsn->get_selectionstart();
435 Tracks *tracks = edl->tracks;
436 for( Track *track=tracks->first; track && !edit; track=track->next ) {
437 if( !track->is_armed() ) continue;
438 if( track->data_type != TRACK_SUBTITLE ) continue;
439 int64_t pos = track->to_units(position,0);
440 edit = track->edits->editof(pos, PLAY_FORWARD, 0);
442 if( !edit ) return 1;
443 SEdit *sedit = (SEdit *)edit;
444 line_entry->update(sedit->get_text());
445 line_entry->set_text_row(0);
449 int MWindow::paste_subtitle_text(char *text, double start, double end)
451 gui->lock_window("MWindow::paste_subtitle_text 1");
452 undo->update_undo_before();
454 Tracks *tracks = edl->tracks;
455 for( Track *track=tracks->first; track; track=track->next ) {
456 if( track->data_type != TRACK_SUBTITLE ) continue;
457 if( !track->is_armed() ) continue;
458 int64_t start_i = track->to_units(start, 0);
459 int64_t end_i = track->to_units(end, 1);
460 track->edits->clear(start_i,end_i);
461 SEdit *sedit = (SEdit *)track->edits->create_silence(start_i,end_i);
462 strcpy(sedit->get_text(),text);
463 track->edits->optimize();
467 undo->update_undo_after(_("paste subttl"), LOAD_EDITS | LOAD_PATCHES);
469 sync_parameters(CHANGE_EDL);
471 gui->update(0, NORMAL_DRAW, 1, 0, 0, 0, 0);
472 gui->unlock_window();
477 int SWindowGUI::paste_text(const char *text, double start, double end)
479 char stext[BCTEXTLEN], *cp = stext;
480 if( text ) { // remap charset, reformat if needed
481 for( const char *bp=text; *bp!=0; ++bp,++cp ) {
483 case '\n': *cp = '|'; break;
484 default: *cp = *bp; break;
488 if( cp > stext && *(cp-1) == '|' ) --cp;
490 return swindow->mwindow->paste_subtitle_text(stext, start, end);
493 int SWindowGUI::paste_selection()
495 EDL *edl = swindow->mwindow->edl;
496 LocalSession *lsn = edl->local_session;
497 double start = lsn->get_selectionstart();
498 double end = lsn->get_selectionend();
499 if( start >= end ) return 1;
500 if( lsn->inpoint_valid() && lsn->outpoint_valid() ) {
501 lsn->set_inpoint(lsn->get_outpoint());
502 lsn->unset_outpoint();
504 paste_text(line_entry->get_text(), start, end);
505 load_next_selection();
509 int SWindowGUI::clear_selection()
511 EDL *edl = swindow->mwindow->edl;
512 double start = edl->local_session->get_selectionstart();
513 double end = edl->local_session->get_selectionend();
515 paste_text(0, start, end);
520 ScriptPrev::ScriptPrev(SWindowGUI *gui, int x, int y)
521 : BC_GenericButton(x, y, _("Prev"))
526 ScriptPrev::~ScriptPrev()
530 int ScriptPrev::handle_event()
532 sw_gui->load_prev_selection();
536 ScriptNext::ScriptNext(SWindowGUI *gui, int x, int y)
537 : BC_GenericButton(x, y, _("Next"))
542 ScriptNext::~ScriptNext()
546 int ScriptNext::handle_event()
548 sw_gui->load_next_selection();
552 ScriptPaste::ScriptPaste(SWindowGUI *gui, int x, int y)
553 : BC_GenericButton(x, y, _("Paste"))
558 ScriptPaste::~ScriptPaste()
562 int ScriptPaste::handle_event()
564 sw_gui->paste_selection();
568 ScriptClear::ScriptClear(SWindowGUI *gui, int x, int y)
569 : BC_GenericButton(x, y, _("Clear"))
574 ScriptClear::~ScriptClear()
578 int ScriptClear::handle_event()
580 sw_gui->clear_selection();
585 ScriptLines::ScriptLines()
589 text = new char[allocated = 256];
593 ScriptLines::~ScriptLines()
598 void ScriptLines::append(char *cp)
600 int len = strlen(cp);
601 if( allocated-used < len+1 ) {
602 int isz = allocated + used + len;
603 char *new_text = new char[isz];
605 memcpy(new_text, text, used);
606 delete [] text; text = new_text;
608 memcpy(text+used, cp, len);
609 text[used += len] = 0;
613 int ScriptLines::break_lines()
616 int limit2 = line_limit/2;
617 int limit4 = line_limit/4-2;
618 char *cp = text, *dp = cp+used;
619 int n; char *bp, *ep, *pp, *sp;
620 for( lines=0; cp<dp; ++lines ) {
621 // find end of line/buffer
622 for( ep=cp; ep<dp && *ep!='\n'; ++ep );
623 // delete trailing spaces
624 for( sp=ep; sp>=cp && (!*sp || isspace(*sp)); --sp);
626 if( (n=ep-sp) > 0 ) {
627 memmove(sp,ep,dp+1-ep);
628 used -= n; dp -= n; ep -= n;
631 // skip, if comment or title line
632 if( *cp == '*' || *cp == '=' ) {
635 // delete leading spaces
636 for( sp=cp; sp<ep && isspace(*sp); ++sp);
637 if( (n=sp-cp) > 0 ) {
638 memmove(cp,sp,dp+1-sp);
639 used -= n; dp -= n; ep -= n;
641 // target about half remaining line, constrain line_limit
642 if( (n=(ep-1-cp)/2) < limit2 || n > line_limit )
644 // search for last punct, last space before line_limit
645 for( bp=cp, pp=sp=0; --n>=0 && cp<ep; ++cp ) {
646 if( ispunct(*cp) && isspace(*(cp+1)) ) pp = cp;
647 else if( isspace(*cp) ) sp = cp;
651 // first, after punctuation
652 if( pp && pp-bp >= limit4 )
658 // last, on next space
660 while( cp<dp && !isspace(*cp) ) ++cp;
670 int ScriptLines::get_text_rows()
673 for( char *cp=text; --i>=0; ++cp )
674 if( *cp == '\n' ) ++ret;
678 char *ScriptLines::get_text_row(int n)
682 for( int i=used; --i>=0; ) {
683 if( *cp++ != '\n' ) continue;
684 if( --n <= 0 ) return cp;
689 ScriptScroll::ScriptScroll(SWindowGUI *gui, int x, int y, int w)
690 : BC_ScrollBar(x, y, SCROLL_HORIZ + SCROLL_STRETCH, w, 0, 0, 0)
695 ScriptScroll::~ScriptScroll()
699 int ScriptScroll::handle_event()
701 int64_t pos = get_value();
702 sw_gui->set_script_pos(pos);
703 sw_gui->script_position->update(pos);
708 ScriptPosition::ScriptPosition(SWindowGUI *gui, int x, int y, int w, int v, int mn, int mx)
709 : BC_TumbleTextBox(gui, v, mn, mx, x, y, w-BC_Tumbler::calculate_w())
714 ScriptPosition::~ScriptPosition()
718 int ScriptPosition::handle_event()
720 int64_t pos = atol(get_text());
721 sw_gui->set_script_pos(pos);
722 sw_gui->script_scroll->update_value(pos);
727 ScriptEntry::ScriptEntry(SWindowGUI *gui, int x, int y, int w, int rows, char *text)
728 : BC_ScrollTextBox(gui, x, y, w, rows, text, -strlen(text))
734 ScriptEntry::ScriptEntry(SWindowGUI *gui, int x, int y, int w, int rows)
735 : BC_ScrollTextBox(gui, x, y, w, rows,(char*)0, BCTEXTLEN)
741 ScriptEntry::~ScriptEntry()
745 void ScriptEntry::set_text(char *text, int isz)
747 if( !text || !*text ) return;
748 if( isz < 0 ) isz = strlen(text)+1;
749 BC_ScrollTextBox::set_text(text, isz);
753 int ScriptEntry::handle_event()
755 if( ttext && sw_gui->get_button_down() &&
756 sw_gui->get_buttonpress() == 1 &&
757 sw_gui->get_triple_click() ) {
758 int ibeam = get_ibeam_letter(), row = 0;
759 const char *tp = ttext;
760 while( *tp && tp-ttext < ibeam ) {
761 if( *tp++ == '\n' ) ++row;
763 int pos = sw_gui->script_entry_no;
764 sw_gui->load_selection(pos, row);
769 int SWindowGUI::load_script_line(FILE *fp)
772 for(;;) { // skip blank lines
773 char *cp = fgets(line,sizeof(line),fp);
776 while( *cp && isspace(*cp) ) ++cp;
780 ScriptLines *entry = new ScriptLines();
781 script.append(entry);
783 for(;;) { // load non-blank lines
784 //int len = strlen(line);
785 //if( line[len-1] == '\n' ) line[len-1] = ' ';
787 char *cp = fgets(line,sizeof(line),fp);
790 while( *cp && isspace(*cp) ) ++cp;
793 script_text_lines += entry->break_lines();
797 void SWindowGUI::load_script()
799 FILE *fp = fopen(script_path,"r");
801 char string[BCTEXTLEN];
802 sprintf(string,_("cannot open: \"%s\"\n%s"),script_path,strerror(errno));
803 MainError::show_error(string);
808 load_selection(script_entry_no=0, 0);
811 void SWindowGUI::load_script(FILE *fp)
813 script.remove_all_objects();
815 script_text_lines = 0;
816 while( !load_script_line(fp) );
818 sprintf(value,"%ld",ftell(fp));
819 script_filesz->update(value);
820 sprintf(value,"%jd",script_line_no);
821 script_lines->update(value);
822 sprintf(value,"%d",script.size());
823 script_entries->update(value);
824 sprintf(value,"%jd",script_text_lines);
825 script_texts->update(value);
826 int hw = script_scroll->get_h();
827 script_scroll->update_length(script.size(), script_entry_no, hw, 0);
828 script_position->update(script_entry_no);
829 script_position->set_boundaries((int64_t)0, (int64_t)script.size()-1);
833 void SWindowGUI::save_spumux_data()
835 char filename[BCTEXTLEN], track_title[BCTEXTLEN];
836 snprintf(filename,sizeof(filename),"%s",script_path);
837 filename[sizeof(filename)-1] = 0;
838 char *bp = strrchr(filename,'/');
839 if( !bp ) bp = filename; else ++bp;
840 char *ext = strrchr(bp, '.');
841 if( !ext ) ext = bp + strlen(bp);
842 int len = sizeof(filename)-1 - (ext-filename);
844 Tracks *tracks = swindow->mwindow->edl->tracks;
845 for( Track *track=tracks->first; track; track=track->next ) {
846 if( track->data_type != TRACK_SUBTITLE ) continue;
847 if( !track->is_armed() ) continue;
848 char *cp = track_title, *ep = cp+sizeof(track_title)-6;
849 for( const char *bp=track->title; cp<ep && *bp!=0; ) {
850 int wch = butf8(bp); // iswalnum(wch) broken by MS port
851 if( !( (wch >= 'A' && wch <= 'Z') ||
852 (wch >= 'a' && wch <= 'z') ||
853 (wch >= '0' && wch <= '9') ) ) wch = '_';
856 const char *sfx = "";
857 switch( sub_format ) {
858 case SUB_FORMAT_SRT: sfx = ".srt"; break;
859 case SUB_FORMAT_RIP: sfx = ".sub"; break;
860 case SUB_FORMAT_UDVD: sfx = ".udvd"; break;
863 snprintf(ext,len,"-%s%s",track_title, sfx);
864 FILE *fp = fopen(filename, "w");
866 eprintf(_("Unable to open %s:\n%m"), filename);
869 switch( sub_format ) {
871 fprintf(fp,"[SUBTITLE]\n"
872 "[COLF]&HFFFFFF,[SIZE]12,[FONT]Times New Roman\n");
875 int64_t start = 0; int count = 0;
876 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
877 SEdit *sedit = (SEdit *)edit;
878 if( !sedit->length ) continue;
879 int64_t end = start + sedit->length;
880 double st = sedit->track->from_units(start);
881 int shr = st/3600; st -= shr*3600;
882 int smn = st/60; st -= smn*60;
883 int ssc = st; st -= ssc;
885 double et = sedit->track->from_units(end);
886 int ehr = et/3600; et -= ehr*3600;
887 int emn = et/60; et -= emn*60;
888 int esc = et; et -= esc;
890 char *text = sedit->get_text();
893 switch( sub_format ) {
895 fprintf(fp, "%d\n%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\n%s\n\n",
896 count, shr, smn, ssc, sms, ehr, emn, esc, ems, text);
899 fprintf(fp, "%02d:%02d:%02d.%02d,%02d:%02d:%02d.%02d\n%s\n\n",
900 shr, smn, ssc, sms/10, ehr, emn, esc, ems/10, text);
902 case SUB_FORMAT_UDVD:
903 fprintf(fp, "{%jd}{%jd}%s\n", start, end-1, text);
913 SWindowItemFormat::SWindowItemFormat(SWindowSaveFormat *save_format,
914 const char *text, int id)
917 this->save_format = save_format;
921 int SWindowItemFormat::handle_event()
923 save_format->sw_gui->sub_format = id;
924 save_format->update_toggles();
928 SWindowSaveFormat::SWindowSaveFormat(SWindowGUI *sw_gui, int x, int y)
929 : BC_PopupMenu(x, y, _("Format"))
931 this->sw_gui = sw_gui;
934 void SWindowSaveFormat::create_objects()
936 add_item(srt = new SWindowItemFormat(this, _("SRT"), SUB_FORMAT_SRT));
937 add_item(rip = new SWindowItemFormat(this, _("SUB"), SUB_FORMAT_RIP));
938 add_item(udvd = new SWindowItemFormat(this, _("UDVD"), SUB_FORMAT_UDVD));
942 void SWindowSaveFormat::update_toggles()
944 srt->set_checked(sw_gui->sub_format == SUB_FORMAT_SRT);
945 rip->set_checked(sw_gui->sub_format == SUB_FORMAT_RIP);
946 udvd->set_checked(sw_gui->sub_format == SUB_FORMAT_UDVD);
950 SWindow::SWindow(MWindow *mwindow)
953 this->mwindow = mwindow;
954 window_lock = new Mutex("SWindow::window_lock");
955 swin_lock = new Condition(0,"SWindow::swin_lock");
972 void SWindow::start()
974 if( !Thread::running() ) {
982 if( Thread::running() ) {
985 window_lock->lock("SWindow::stop");
986 if( gui ) gui->stop(1);
987 window_lock->unlock();
995 int root_w = mwindow->gui->get_root_w(1);
996 int root_h = mwindow->gui->get_root_h(1);
1002 int x = mwindow->session->swindow_x;
1003 int y = mwindow->session->swindow_y;
1004 int w = mwindow->session->swindow_w;
1005 int h = mwindow->session->swindow_h;
1006 if( w < xS(600) ) w = xS(600);
1007 if( h < yS(500) ) h = yS(500);
1008 int scr_x = mwindow->gui->get_screen_x(1, -1);
1009 int scr_w = mwindow->gui->get_screen_w(1, -1);
1010 if( x < scr_x ) x = scr_x;
1011 if( x > scr_x+scr_w ) x = scr_x+scr_w;
1012 if( x+w > root_w ) x = root_w - w;
1013 if( x < 0 ) { x = 0; w = scr_w; }
1014 if( y+h > root_h ) y = root_h - h;
1015 if( y < 0 ) { y = 0; h = root_h; }
1016 if( y+h > root_h ) h = root_h-y;
1017 mwindow->session->swindow_x = x;
1018 mwindow->session->swindow_y = y;
1019 mwindow->session->swindow_w = w;
1020 mwindow->session->swindow_h = h;
1023 gui = new SWindowGUI(this, x, y, w, h);
1024 gui->lock_window("ChannelInfo::gui_create_objects");
1025 gui->load_defaults();
1026 gui->create_objects();
1027 gui->set_icon(mwindow->theme->get_image("record_icon"));
1028 gui->reposition_window(x, y);
1029 gui->resize_event(w, h);
1032 gui->unlock_window();
1034 int result = gui->run_window();
1036 gui->save_spumux_data();
1039 window_lock->lock("ChannelInfo::run 1");
1040 gui->save_defaults();
1041 delete gui; gui = 0;
1042 window_lock->unlock();
1049 void SWindow::run_swin()
1051 window_lock->lock("SWindow::run_swin");
1053 gui->lock_window("SWindow::run_swin");
1054 gui->raise_window();
1055 gui->unlock_window();
1058 swin_lock->unlock();
1059 window_lock->unlock();
1062 void SWindow::paste_subttl()
1064 window_lock->lock("SWindow::paste_subttl 1");
1066 gui->lock_window("SWindow::paste_subttl 2");
1067 gui->paste_selection();
1068 gui->unlock_window();
1070 window_lock->unlock();
1073 int SWindow::update_selection()
1075 window_lock->lock("SWindow::update_selection 1");
1077 gui->lock_window("SWindow::update_selection 2");
1078 gui->update_selection();
1079 gui->unlock_window();
1081 window_lock->unlock();
1087 SubttlSWin::SubttlSWin(MWindow *mwindow)
1088 : BC_MenuItem(_("SubTitle..."), _("Alt-y"), 'y')
1091 this->mwindow = mwindow;
1094 SubttlSWin::~SubttlSWin()
1098 int SubttlSWin::handle_event()
1100 mwindow->gui->swindow->run_swin();