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()
51 return context_help_check_and_show();
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;
283 // *** CONTEXT_HELP ***
284 context_help_set_keyword("Subtitles");
287 SWindowGUI::~SWindowGUI()
291 delete script_position;
292 delete [] blank_line;
295 void SWindowGUI::stop(int v)
297 if( !swindow->gui_done ) {
298 swindow->gui_done = 1;
303 int SWindowGUI::translation_event()
305 swindow->mwindow->session->swindow_x = get_x();
306 swindow->mwindow->session->swindow_y = get_y();
310 int SWindowGUI::resize_event(int w, int h)
312 swindow->mwindow->session->swindow_w = w;
313 swindow->mwindow->session->swindow_h = h;
316 ok_y = h - ok_h - yS(10);
317 ok->reposition_window(ok_x, ok_y);
318 cancel_x = w - cancel_w - xS(10);
319 cancel_y = h - cancel_h - yS(10);
320 cancel->reposition_window(cancel_x, cancel_y);
322 int x = script_position->get_x();
323 int y = script_position->get_y();
324 int hh = script_position->get_h();
325 int ww = script_position->get_w();
326 int x1 = x + ww + xpad;
327 int w1 = w - x1 - xpad;
328 script_scroll->reposition_window(x1, y, w1);
330 script_title->reposition_window(x, y);
331 y += script_title->get_h() + ypad;
333 int rows = (ok_y - y - line_title->get_h() - 4*ypad) / text_rowsz - 4;
334 script_entry->reposition_window(x, y, w1, rows);
335 y += script_entry->get_h() + 2*ypad;
336 line_title->reposition_window(x, y);
337 y += line_title->get_h() + ypad;
338 line_entry->reposition_window(x, y, w1, 4);
342 void SWindowGUI::load_defaults()
344 BC_Hash *defaults = swindow->mwindow->defaults;
345 defaults->get("SUBTTL_SCRIPT_PATH", script_path);
346 script_entry_no = defaults->get("SUBTTL_SCRIPT_ENTRY_NO", script_entry_no);
347 script_text_no = defaults->get("SUBTTL_SCRIPT_TEXT_NO", script_text_no);
348 sub_format = defaults->get("SUBTTL_SCRIPT_FORMAT", sub_format);
351 void SWindowGUI::save_defaults()
353 BC_Hash *defaults = swindow->mwindow->defaults;
354 defaults->update("SUBTTL_SCRIPT_PATH", script_path);
355 defaults->update("SUBTTL_SCRIPT_ENTRY_NO", script_entry_no);
356 defaults->update("SUBTTL_SCRIPT_TEXT_NO", script_text_no);
357 defaults->update("SUBTTL_SCRIPT_FORMAT", sub_format);
360 void SWindowGUI::set_script_pos(int64_t entry_no, int text_no)
362 script_entry_no = entry_no<0 ? 0 :
363 entry_no>script.size()-1 ? script.size()-1 : entry_no;
364 script_text_no = text_no-1;
365 load_next_selection();
368 int SWindowGUI::load_selection(int pos, int row)
370 if( pos < 0 || pos >= script.size() ) return 1;
371 ScriptLines *texts = script[pos];
372 char *rp = texts->get_text_row(row);
373 if( !rp || *rp == '=' || *rp == '*' || *rp=='\n' ) return 1;
374 if( pos != script_entry_no || script_text_no < 0 ) {
375 script_entry_no = pos;
376 script_scroll->update_value(script_entry_no);
377 script_position->update(script_entry_no);
378 script_entry->set_text(texts->text);
379 script_entry->set_text_row(0);
381 script_text_no = row;
382 char line[BCTEXTLEN], *bp = line;
383 char *ep = bp+sizeof(line)-1, *cp = rp;
384 while( bp < ep && *cp && *cp!='\n' ) *bp++ = *cp++;
385 *bp = 0; bp = texts->text;
386 int char1 = rp-bp, char2 = cp-bp;
387 script_entry->set_selection(char1, char2, char2);
388 int rows = script_entry->get_rows();
389 int rows2 = rows / 2;
390 int rows1 = texts->lines+1 - rows;
391 if( (row-=rows2) > rows1 ) row = rows1;
392 if( row < 0 ) row = 0;
393 script_entry->set_text_row(row);
394 line_entry->update(line);
395 line_entry->set_text_row(0);
399 int SWindowGUI::load_prev_selection()
401 int pos = script_entry_no, row = script_text_no;
402 if( pos < 0 || pos >= script.size() ) return 1;
405 if( --pos < 0 ) break;
406 row = script[pos]->lines;
409 if( !load_selection(pos, row) )
415 int SWindowGUI::load_next_selection()
417 int pos = script_entry_no, row = script_text_no;
418 if( pos < 0 || pos >= script.size() ) return 1;
420 if( ++row >= script[pos]->lines ) {
421 if( ++pos >= script.size() ) break;
425 if( !load_selection(pos, row) )
431 int SWindowGUI::update_selection()
433 EDL *edl = swindow->mwindow->edl;
434 LocalSession *lsn = edl->local_session;
435 double position = lsn->get_selectionstart();
437 Tracks *tracks = edl->tracks;
438 for( Track *track=tracks->first; track && !edit; track=track->next ) {
439 if( !track->is_armed() ) continue;
440 if( track->data_type != TRACK_SUBTITLE ) continue;
441 int64_t pos = track->to_units(position,0);
442 edit = track->edits->editof(pos, PLAY_FORWARD, 0);
444 if( !edit ) return 1;
445 SEdit *sedit = (SEdit *)edit;
446 line_entry->update(sedit->get_text());
447 line_entry->set_text_row(0);
451 int MWindow::paste_subtitle_text(char *text, double start, double end)
453 gui->lock_window("MWindow::paste_subtitle_text 1");
454 undo->update_undo_before();
456 Tracks *tracks = edl->tracks;
457 for( Track *track=tracks->first; track; track=track->next ) {
458 if( track->data_type != TRACK_SUBTITLE ) continue;
459 if( !track->is_armed() ) continue;
460 int64_t start_i = track->to_units(start, 0);
461 int64_t end_i = track->to_units(end, 1);
462 track->edits->clear(start_i,end_i);
463 SEdit *sedit = (SEdit *)track->edits->create_silence(start_i,end_i);
464 strcpy(sedit->get_text(),text);
465 track->edits->optimize();
469 undo->update_undo_after(_("paste subttl"), LOAD_EDITS | LOAD_PATCHES);
471 sync_parameters(CHANGE_EDL);
473 gui->update(0, NORMAL_DRAW, 1, 0, 0, 0, 0);
474 gui->unlock_window();
479 int SWindowGUI::paste_text(const char *text, double start, double end)
481 char stext[BCTEXTLEN], *cp = stext;
482 if( text ) { // remap charset, reformat if needed
483 for( const char *bp=text; *bp!=0; ++bp,++cp ) {
485 case '\n': *cp = '|'; break;
486 default: *cp = *bp; break;
490 if( cp > stext && *(cp-1) == '|' ) --cp;
492 return swindow->mwindow->paste_subtitle_text(stext, start, end);
495 int SWindowGUI::paste_selection()
497 EDL *edl = swindow->mwindow->edl;
498 LocalSession *lsn = edl->local_session;
499 double start = lsn->get_selectionstart();
500 double end = lsn->get_selectionend();
501 if( start >= end ) return 1;
502 if( lsn->inpoint_valid() && lsn->outpoint_valid() ) {
503 lsn->set_inpoint(lsn->get_outpoint());
504 lsn->unset_outpoint();
506 paste_text(line_entry->get_text(), start, end);
507 load_next_selection();
511 int SWindowGUI::clear_selection()
513 EDL *edl = swindow->mwindow->edl;
514 double start = edl->local_session->get_selectionstart();
515 double end = edl->local_session->get_selectionend();
517 paste_text(0, start, end);
522 ScriptPrev::ScriptPrev(SWindowGUI *gui, int x, int y)
523 : BC_GenericButton(x, y, _("Prev"))
528 ScriptPrev::~ScriptPrev()
532 int ScriptPrev::handle_event()
534 sw_gui->load_prev_selection();
538 ScriptNext::ScriptNext(SWindowGUI *gui, int x, int y)
539 : BC_GenericButton(x, y, _("Next"))
544 ScriptNext::~ScriptNext()
548 int ScriptNext::handle_event()
550 sw_gui->load_next_selection();
554 ScriptPaste::ScriptPaste(SWindowGUI *gui, int x, int y)
555 : BC_GenericButton(x, y, _("Paste"))
560 ScriptPaste::~ScriptPaste()
564 int ScriptPaste::handle_event()
566 sw_gui->paste_selection();
570 ScriptClear::ScriptClear(SWindowGUI *gui, int x, int y)
571 : BC_GenericButton(x, y, _("Clear"))
576 ScriptClear::~ScriptClear()
580 int ScriptClear::handle_event()
582 sw_gui->clear_selection();
587 ScriptLines::ScriptLines()
591 text = new char[allocated = 256];
595 ScriptLines::~ScriptLines()
600 void ScriptLines::append(char *cp)
602 int len = strlen(cp);
603 if( allocated-used < len+1 ) {
604 int isz = allocated + used + len;
605 char *new_text = new char[isz];
607 memcpy(new_text, text, used);
608 delete [] text; text = new_text;
610 memcpy(text+used, cp, len);
611 text[used += len] = 0;
615 int ScriptLines::break_lines()
618 int limit2 = line_limit/2;
619 int limit4 = line_limit/4-2;
620 char *cp = text, *dp = cp+used;
621 int n; char *bp, *ep, *pp, *sp;
622 for( lines=0; cp<dp; ++lines ) {
623 // find end of line/buffer
624 for( ep=cp; ep<dp && *ep!='\n'; ++ep );
625 // delete trailing spaces
626 for( sp=ep; sp>=cp && (!*sp || isspace(*sp)); --sp);
628 if( (n=ep-sp) > 0 ) {
629 memmove(sp,ep,dp+1-ep);
630 used -= n; dp -= n; ep -= n;
633 // skip, if comment or title line
634 if( *cp == '*' || *cp == '=' ) {
637 // delete leading spaces
638 for( sp=cp; sp<ep && isspace(*sp); ++sp);
639 if( (n=sp-cp) > 0 ) {
640 memmove(cp,sp,dp+1-sp);
641 used -= n; dp -= n; ep -= n;
643 // target about half remaining line, constrain line_limit
644 if( (n=(ep-1-cp)/2) < limit2 || n > line_limit )
646 // search for last punct, last space before line_limit
647 for( bp=cp, pp=sp=0; --n>=0 && cp<ep; ++cp ) {
648 if( ispunct(*cp) && isspace(*(cp+1)) ) pp = cp;
649 else if( isspace(*cp) ) sp = cp;
653 // first, after punctuation
654 if( pp && pp-bp >= limit4 )
660 // last, on next space
662 while( cp<dp && !isspace(*cp) ) ++cp;
672 int ScriptLines::get_text_rows()
675 for( char *cp=text; --i>=0; ++cp )
676 if( *cp == '\n' ) ++ret;
680 char *ScriptLines::get_text_row(int n)
684 for( int i=used; --i>=0; ) {
685 if( *cp++ != '\n' ) continue;
686 if( --n <= 0 ) return cp;
691 ScriptScroll::ScriptScroll(SWindowGUI *gui, int x, int y, int w)
692 : BC_ScrollBar(x, y, SCROLL_HORIZ + SCROLL_STRETCH, w, 0, 0, 0)
697 ScriptScroll::~ScriptScroll()
701 int ScriptScroll::handle_event()
703 int64_t pos = get_value();
704 sw_gui->set_script_pos(pos);
705 sw_gui->script_position->update(pos);
710 ScriptPosition::ScriptPosition(SWindowGUI *gui, int x, int y, int w, int v, int mn, int mx)
711 : BC_TumbleTextBox(gui, v, mn, mx, x, y, w-BC_Tumbler::calculate_w())
716 ScriptPosition::~ScriptPosition()
720 int ScriptPosition::handle_event()
722 int64_t pos = atol(get_text());
723 sw_gui->set_script_pos(pos);
724 sw_gui->script_scroll->update_value(pos);
729 ScriptEntry::ScriptEntry(SWindowGUI *gui, int x, int y, int w, int rows, char *text)
730 : BC_ScrollTextBox(gui, x, y, w, rows, text, -strlen(text))
736 ScriptEntry::ScriptEntry(SWindowGUI *gui, int x, int y, int w, int rows)
737 : BC_ScrollTextBox(gui, x, y, w, rows,(char*)0, BCTEXTLEN)
743 ScriptEntry::~ScriptEntry()
747 void ScriptEntry::set_text(char *text, int isz)
749 if( !text || !*text ) return;
750 if( isz < 0 ) isz = strlen(text)+1;
751 BC_ScrollTextBox::set_text(text, isz);
755 int ScriptEntry::handle_event()
757 if( ttext && sw_gui->get_button_down() &&
758 sw_gui->get_buttonpress() == 1 &&
759 sw_gui->get_triple_click() ) {
760 int ibeam = get_ibeam_letter(), row = 0;
761 const char *tp = ttext;
762 while( *tp && tp-ttext < ibeam ) {
763 if( *tp++ == '\n' ) ++row;
765 int pos = sw_gui->script_entry_no;
766 sw_gui->load_selection(pos, row);
771 int SWindowGUI::load_script_line(FILE *fp)
774 for(;;) { // skip blank lines
775 char *cp = fgets(line,sizeof(line),fp);
778 while( *cp && isspace(*cp) ) ++cp;
782 ScriptLines *entry = new ScriptLines();
783 script.append(entry);
785 for(;;) { // load non-blank lines
786 //int len = strlen(line);
787 //if( line[len-1] == '\n' ) line[len-1] = ' ';
789 char *cp = fgets(line,sizeof(line),fp);
792 while( *cp && isspace(*cp) ) ++cp;
795 script_text_lines += entry->break_lines();
799 void SWindowGUI::load_script()
801 FILE *fp = fopen(script_path,"r");
803 char string[BCTEXTLEN];
804 sprintf(string,_("cannot open: \"%s\"\n%s"),script_path,strerror(errno));
805 MainError::show_error(string);
810 load_selection(script_entry_no=0, 0);
813 void SWindowGUI::load_script(FILE *fp)
815 script.remove_all_objects();
817 script_text_lines = 0;
818 while( !load_script_line(fp) );
820 sprintf(value,"%ld",ftell(fp));
821 script_filesz->update(value);
822 sprintf(value,"%jd",script_line_no);
823 script_lines->update(value);
824 sprintf(value,"%d",script.size());
825 script_entries->update(value);
826 sprintf(value,"%jd",script_text_lines);
827 script_texts->update(value);
828 int hw = script_scroll->get_h();
829 script_scroll->update_length(script.size(), script_entry_no, hw, 0);
830 script_position->update(script_entry_no);
831 script_position->set_boundaries((int64_t)0, (int64_t)script.size()-1);
835 void SWindowGUI::save_spumux_data()
837 char filename[BCTEXTLEN], track_title[BCTEXTLEN];
838 snprintf(filename,sizeof(filename),"%s",script_path);
839 filename[sizeof(filename)-1] = 0;
840 char *bp = strrchr(filename,'/');
841 if( !bp ) bp = filename; else ++bp;
842 char *ext = strrchr(bp, '.');
843 if( !ext ) ext = bp + strlen(bp);
844 int len = sizeof(filename)-1 - (ext-filename);
846 Tracks *tracks = swindow->mwindow->edl->tracks;
847 for( Track *track=tracks->first; track; track=track->next ) {
848 if( track->data_type != TRACK_SUBTITLE ) continue;
849 if( !track->is_armed() ) continue;
850 char *cp = track_title, *ep = cp+sizeof(track_title)-6;
851 for( const char *bp=track->title; cp<ep && *bp!=0; ) {
852 int wch = butf8(bp); // iswalnum(wch) broken by MS port
853 if( !( (wch >= 'A' && wch <= 'Z') ||
854 (wch >= 'a' && wch <= 'z') ||
855 (wch >= '0' && wch <= '9') ) ) wch = '_';
858 const char *sfx = "";
859 switch( sub_format ) {
860 case SUB_FORMAT_SRT: sfx = ".srt"; break;
861 case SUB_FORMAT_RIP: sfx = ".sub"; break;
862 case SUB_FORMAT_UDVD: sfx = ".udvd"; break;
865 snprintf(ext,len,"-%s%s",track_title, sfx);
866 FILE *fp = fopen(filename, "w");
868 eprintf(_("Unable to open %s:\n%m"), filename);
871 switch( sub_format ) {
873 fprintf(fp,"[SUBTITLE]\n"
874 "[COLF]&HFFFFFF,[SIZE]12,[FONT]Times New Roman\n");
877 int64_t start = 0; int count = 0;
878 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
879 SEdit *sedit = (SEdit *)edit;
880 if( !sedit->length ) continue;
881 int64_t end = start + sedit->length;
882 double st = sedit->track->from_units(start);
883 int shr = st/3600; st -= shr*3600;
884 int smn = st/60; st -= smn*60;
885 int ssc = st; st -= ssc;
887 double et = sedit->track->from_units(end);
888 int ehr = et/3600; et -= ehr*3600;
889 int emn = et/60; et -= emn*60;
890 int esc = et; et -= esc;
892 char *text = sedit->get_text();
895 switch( sub_format ) {
897 fprintf(fp, "%d\n%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\n%s\n\n",
898 count, shr, smn, ssc, sms, ehr, emn, esc, ems, text);
901 fprintf(fp, "%02d:%02d:%02d.%02d,%02d:%02d:%02d.%02d\n%s\n\n",
902 shr, smn, ssc, sms/10, ehr, emn, esc, ems/10, text);
904 case SUB_FORMAT_UDVD:
905 fprintf(fp, "{%jd}{%jd}%s\n", start, end-1, text);
915 SWindowItemFormat::SWindowItemFormat(SWindowSaveFormat *save_format,
916 const char *text, int id)
919 this->save_format = save_format;
923 int SWindowItemFormat::handle_event()
925 save_format->sw_gui->sub_format = id;
926 save_format->update_toggles();
930 SWindowSaveFormat::SWindowSaveFormat(SWindowGUI *sw_gui, int x, int y)
931 : BC_PopupMenu(x, y, _("Format"))
933 this->sw_gui = sw_gui;
936 void SWindowSaveFormat::create_objects()
938 add_item(srt = new SWindowItemFormat(this, _("SRT"), SUB_FORMAT_SRT));
939 add_item(rip = new SWindowItemFormat(this, _("SUB"), SUB_FORMAT_RIP));
940 add_item(udvd = new SWindowItemFormat(this, _("UDVD"), SUB_FORMAT_UDVD));
944 void SWindowSaveFormat::update_toggles()
946 srt->set_checked(sw_gui->sub_format == SUB_FORMAT_SRT);
947 rip->set_checked(sw_gui->sub_format == SUB_FORMAT_RIP);
948 udvd->set_checked(sw_gui->sub_format == SUB_FORMAT_UDVD);
952 SWindow::SWindow(MWindow *mwindow)
955 this->mwindow = mwindow;
956 window_lock = new Mutex("SWindow::window_lock");
957 swin_lock = new Condition(0,"SWindow::swin_lock");
974 void SWindow::start()
976 if( !Thread::running() ) {
984 if( Thread::running() ) {
987 window_lock->lock("SWindow::stop");
988 if( gui ) gui->stop(1);
989 window_lock->unlock();
997 int root_w = mwindow->gui->get_root_w(1);
998 int root_h = mwindow->gui->get_root_h(1);
1004 int x = mwindow->session->swindow_x;
1005 int y = mwindow->session->swindow_y;
1006 int w = mwindow->session->swindow_w;
1007 int h = mwindow->session->swindow_h;
1008 if( w < xS(600) ) w = xS(600);
1009 if( h < yS(500) ) h = yS(500);
1010 int scr_x = mwindow->gui->get_screen_x(1, -1);
1011 int scr_w = mwindow->gui->get_screen_w(1, -1);
1012 if( x < scr_x ) x = scr_x;
1013 if( x > scr_x+scr_w ) x = scr_x+scr_w;
1014 if( x+w > root_w ) x = root_w - w;
1015 if( x < 0 ) { x = 0; w = scr_w; }
1016 if( y+h > root_h ) y = root_h - h;
1017 if( y < 0 ) { y = 0; h = root_h; }
1018 if( y+h > root_h ) h = root_h-y;
1019 mwindow->session->swindow_x = x;
1020 mwindow->session->swindow_y = y;
1021 mwindow->session->swindow_w = w;
1022 mwindow->session->swindow_h = h;
1025 gui = new SWindowGUI(this, x, y, w, h);
1026 gui->lock_window("ChannelInfo::gui_create_objects");
1027 gui->load_defaults();
1028 gui->create_objects();
1029 gui->set_icon(mwindow->theme->get_image("record_icon"));
1030 gui->reposition_window(x, y);
1031 gui->resize_event(w, h);
1034 gui->unlock_window();
1036 int result = gui->run_window();
1038 gui->save_spumux_data();
1041 window_lock->lock("ChannelInfo::run 1");
1042 gui->save_defaults();
1043 delete gui; gui = 0;
1044 window_lock->unlock();
1051 void SWindow::run_swin()
1053 window_lock->lock("SWindow::run_swin");
1055 gui->lock_window("SWindow::run_swin");
1056 gui->raise_window();
1057 gui->unlock_window();
1060 swin_lock->unlock();
1061 window_lock->unlock();
1064 void SWindow::paste_subttl()
1066 window_lock->lock("SWindow::paste_subttl 1");
1068 gui->lock_window("SWindow::paste_subttl 2");
1069 gui->paste_selection();
1070 gui->unlock_window();
1072 window_lock->unlock();
1075 int SWindow::update_selection()
1077 window_lock->lock("SWindow::update_selection 1");
1079 gui->lock_window("SWindow::update_selection 2");
1080 gui->update_selection();
1081 gui->unlock_window();
1083 window_lock->unlock();
1089 SubttlSWin::SubttlSWin(MWindow *mwindow)
1090 : BC_MenuItem(_("SubTitle..."), _("Alt-y"), 'y')
1093 this->mwindow = mwindow;
1096 SubttlSWin::~SubttlSWin()
1100 int SubttlSWin::handle_event()
1102 mwindow->gui->swindow->run_swin();