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, 200, 1, path)
80 file_entries = new ArrayList<BC_ListBoxItem*>;
81 FileSystem fs; char string[BCTEXTLEN];
82 // Load current directory
83 fs.update(getcwd(string, BCTEXTLEN));
84 int total_files = fs.total_files();
85 for(int i = 0; i < total_files; i++) {
86 const char *name = fs.get_entry(i)->get_name();
87 file_entries->append(new BC_ListBoxItem(name));
91 SWindowLoadPath::~SWindowLoadPath()
93 file_entries->remove_all_objects();
97 int SWindowLoadPath::handle_event()
99 calculate_suggestions(file_entries);
100 strcpy(sw_gui->script_path, get_text());
105 SWindowLoadFile::SWindowLoadFile(SWindowGUI *gui, int x, int y)
106 : BC_GenericButton(x, y, _("Load"))
111 SWindowLoadFile::~SWindowLoadFile()
115 int SWindowLoadFile::handle_event()
117 sw_gui->load_path->set_suggestions(0,0);
118 sw_gui->load_script();
119 sw_gui->set_script_pos(0);
123 SWindowSaveFile::SWindowSaveFile(SWindowGUI *gui, int x, int y)
124 : BC_GenericButton(x, y, _("Save"))
129 SWindowSaveFile::~SWindowSaveFile()
133 int SWindowSaveFile::handle_event()
135 sw_gui->save_spumux_data();
142 void SWindowGUI::create_objects()
145 BC_Title *title = new BC_Title(x, y, _("Path:"));
146 add_subwindow(title);
147 int x1 = x + title->get_w() + pad, y1 = y;
148 load_path = new SWindowLoadPath(this, x1, y1, script_path);
149 add_subwindow(load_path);
150 x1 += load_path->get_w() + 2*pad;
151 add_subwindow(load_file = new SWindowLoadFile(this, x1, y1));
152 x1 += load_file->get_w() + 2*pad;
153 add_subwindow(save_file = new SWindowSaveFile(this, x1, y1));
154 y += max(load_path->get_h(), load_file->get_h()) + pad;
155 x1 = x + pad, y1 = y;
156 BC_Title *title1, *title2;
157 add_subwindow(title1 = new BC_Title(x1, y1, _("File Size:")));
158 y += title1->get_h() + pad;
160 add_subwindow(title2 = new BC_Title(x1, y2, _("Entries:")));
161 int x2 = x1 + max(title1->get_w(), title2->get_w()) + pad;
162 add_subwindow(script_filesz = new BC_Title(x2, y1, "0", MEDIUMFONT, YELLOW));
163 add_subwindow(script_entries = new BC_Title(x2, y2, "0", MEDIUMFONT, YELLOW));
164 int x3 = x2 + max(script_entries->get_w()*8, script_filesz->get_w()*8) + pad;
165 add_subwindow(title1 = new BC_Title(x3, y1, _("Lines:")));
166 add_subwindow(title2 = new BC_Title(x3, y2, _("Texts:")));
167 int x4 = x3 + max(title1->get_w(), title2->get_w()) + pad;
168 add_subwindow(script_lines = new BC_Title(x4, y1, "0", MEDIUMFONT, YELLOW));
169 add_subwindow(script_texts = new BC_Title(x4, y2, "0", MEDIUMFONT, YELLOW));
170 int x5 = x4 + max(script_lines->get_w()*8, script_texts->get_w()*8) + 2*pad;
171 add_subwindow(prev_script = new ScriptPrev(this, x5, y1));
172 add_subwindow(next_script = new ScriptNext(this, x5, y2));
173 int x6 = x5 + max(prev_script->get_w(), next_script->get_w()) + 2*pad;
174 add_subwindow(paste_script = new ScriptPaste(this, x6, y1));
175 add_subwindow(clear_script = new ScriptClear(this, x6, y2));
176 y += max(title1->get_h(), title2->get_h()) + 2*pad;
178 script_position = new ScriptPosition(this, x, y, 100);
179 script_position->create_objects();
180 x1 = x + script_position->get_w() + pad;
181 add_subwindow(script_scroll = new ScriptScroll(this, x1, y, get_w()-x1-pad));
182 y += script_scroll->get_h() + 2*pad;
184 blank_line = new char[2];
185 blank_line[0] = ' '; blank_line[1] = 0;
186 int rows = (ok_y - y - 4*pad) / text_rowsz - 3;
187 int w1 = get_w()-x1-pad;
188 script_entry = new ScriptEntry(this, x1, y, w1, rows, blank_line);
189 script_entry->create_objects();
190 y += script_entry->get_h() + pad;
191 line_entry = new ScriptEntry(this, x1, y, w1, 3);
192 line_entry->create_objects();
193 ok = new SWindowOK(this, ok_x, ok_y);
195 cancel = new SWindowCancel(this, cancel_x, cancel_y);
196 add_subwindow(cancel);
199 void SWindowGUI::load()
201 const char *script_text =
202 _("Adding Subtitles: quick \"How To\" (= or * indicates comment)\n"
203 "*2345678901234567890123456789012345678901234567890123456789\n"
204 "For regular DVD subtitles, put script in a text file. "
205 "Lines can be any length but they will be broken up "
206 "to fit according to some criteria below.\n"
207 "Running text used as script lines will be broken into multilple lines.\n"
208 "The target line length is 60 characters.\n"
209 "Punctuation may be flagged to create an early line break.\n"
210 "Single carriage return ends an individual script line.\n"
211 "Double carriage return indicates the end of an entry.\n"
212 "Whitespace at beginning or end of line is removed.\n"
213 "You can edit the active line in the Line Text box.\n"
215 "== A new entry is here for illustration purposes.\n"
217 "This is the second entry.\n");
219 if( script_path[0] && !access(script_path,R_OK) ) {
224 load_path->update(script_path);
225 FILE *fp = fmemopen((void *)script_text, strlen(script_text), "r");
228 int text_no = script_text_no;
230 load_selection(script_entry_no, text_no);
233 SWindowGUI::SWindowGUI(SWindow *swindow, int x, int y, int w, int h)
234 : BC_Window(_(PROGRAM_NAME ": Subtitle"), x, y, w, h, 600, 500,
235 1, 0, 0 , -1, swindow->mwindow->get_cwindow_display())
237 this->swindow = swindow;
241 ok_w = BC_OKButton::calculate_w();
242 ok_h = BC_OKButton::calculate_h();
244 ok_y = h - ok_h - 10;
246 cancel_w = BC_CancelButton::calculate_w();
247 cancel_h = BC_CancelButton::calculate_h();
248 cancel_x = w - cancel_w - 10,
249 cancel_y = h - cancel_h - 10;
261 script_text_lines = 0;
271 text_font = MEDIUMFONT;
272 text_rowsz = get_text_ascent(text_font)+1 + get_text_descent(text_font)+1;
275 SWindowGUI::~SWindowGUI()
279 delete script_position;
280 delete [] blank_line;
283 void SWindowGUI::stop(int v)
285 if( !swindow->gui_done ) {
286 swindow->gui_done = 1;
291 int SWindowGUI::translation_event()
293 swindow->mwindow->session->swindow_x = get_x();
294 swindow->mwindow->session->swindow_y = get_y();
298 int SWindowGUI::resize_event(int w, int h)
300 swindow->mwindow->session->swindow_w = w;
301 swindow->mwindow->session->swindow_h = h;
304 ok_y = h - ok_h - 10;
305 ok->reposition_window(ok_x, ok_y);
306 cancel_x = w - cancel_w - 10,
307 cancel_y = h - cancel_h - 10;
308 cancel->reposition_window(cancel_x, cancel_y);
310 int x = script_position->get_x();
311 int y = script_position->get_y();
312 int hh = script_position->get_h();
313 int ww = script_position->get_w();
314 int x1 = x + ww + pad;
315 int w1 = w - x1 - pad;
316 script_scroll->reposition_window(x1, y, w1);
319 int rows = (ok_y - y - 4*pad) / text_rowsz - 3;
320 script_entry->reposition_window(x, y, w1, rows);
321 y += script_entry->get_h() + pad;
322 line_entry->reposition_window(x, y, w1, 3);
326 void SWindowGUI::load_defaults()
328 BC_Hash *defaults = swindow->mwindow->defaults;
329 defaults->get("SUBTTL_SCRIPT_PATH", script_path);
330 script_entry_no = defaults->get("SUBTTL_SCRIPT_ENTRY_NO", script_entry_no);
331 script_text_no = defaults->get("SUBTTL_SCRIPT_TEXT_NO", script_text_no);
334 void SWindowGUI::save_defaults()
336 BC_Hash *defaults = swindow->mwindow->defaults;
337 defaults->update("SUBTTL_SCRIPT_PATH", script_path);
338 defaults->update("SUBTTL_SCRIPT_ENTRY_NO", script_entry_no);
339 defaults->update("SUBTTL_SCRIPT_TEXT_NO", script_text_no);
342 void SWindowGUI::set_script_pos(int64_t entry_no, int text_no)
344 script_entry_no = entry_no<0 ? 0 :
345 entry_no>script.size()-1 ? script.size()-1 : entry_no;
346 script_text_no = text_no-1;
347 load_next_selection();
350 int SWindowGUI::load_selection(int pos, int row)
352 ScriptLines *texts = script[pos];
353 char *rp = texts->get_text_row(row);
354 if( !rp || *rp == '=' || *rp == '*' || *rp=='\n' ) return 1;
355 if( pos != script_entry_no || script_text_no < 0 ) {
356 script_entry_no = pos;
357 script_scroll->update_value(script_entry_no);
358 script_position->update(script_entry_no);
359 script_entry->set_text(texts->text);
360 script_entry->set_text_row(0);
362 script_text_no = row;
363 char line[BCTEXTLEN], *bp = line;
364 char *ep = bp+sizeof(line)-1, *cp = rp;
365 while( bp < ep && *cp && *cp!='\n' ) *bp++ = *cp++;
366 *bp = 0; bp = texts->text;
367 int char1 = rp-bp, char2 = cp-bp;
368 script_entry->set_selection(char1, char2, char2);
369 int rows = script_entry->get_rows();
370 int rows2 = rows / 2;
371 int rows1 = texts->lines+1 - rows;
372 if( (row-=rows2) > rows1 ) row = rows1;
373 if( row < 0 ) row = 0;
374 script_entry->set_text_row(row);
375 line_entry->update(line);
376 line_entry->set_text_row(0);
380 int SWindowGUI::load_prev_selection()
382 int pos = script_entry_no, row = script_text_no;
383 if( pos < 0 || pos >= script.size() ) return 1;
386 if( --pos < 0 ) break;
387 row = script[pos]->lines;
390 if( !load_selection(pos, row) )
396 int SWindowGUI::load_next_selection()
398 int pos = script_entry_no, row = script_text_no;
399 if( pos < 0 || pos >= script.size() ) return 1;
401 if( ++row >= script[pos]->lines ) {
402 if( ++pos >= script.size() ) break;
406 if( !load_selection(pos, row) )
412 int SWindowGUI::update_selection()
414 EDL *edl = swindow->mwindow->edl;
415 LocalSession *lsn = edl->local_session;
416 double position = lsn->get_selectionstart();
418 Tracks *tracks = edl->tracks;
419 for( Track *track=tracks->first; track && !edit; track=track->next ) {
420 if( !track->record ) continue;
421 if( track->data_type != TRACK_SUBTITLE ) continue;
422 int64_t pos = track->to_units(position,0);
423 edit = track->edits->editof(pos, PLAY_FORWARD, 0);
425 if( !edit ) return 1;
426 SEdit *sedit = (SEdit *)edit;
427 line_entry->update(sedit->get_text());
428 line_entry->set_text_row(0);
432 int MWindow::paste_subtitle_text(char *text, double start, double end)
434 gui->lock_window("MWindow::paste_subtitle_text 1");
435 undo->update_undo_before();
437 Tracks *tracks = edl->tracks;
438 for( Track *track=tracks->first; track; track=track->next ) {
439 if( track->data_type != TRACK_SUBTITLE ) continue;
440 if( !track->record ) continue;
441 int64_t start_i = track->to_units(start, 0);
442 int64_t end_i = track->to_units(end, 1);
443 track->edits->clear(start_i,end_i);
444 SEdit *sedit = (SEdit *)track->edits->create_silence(start_i,end_i);
445 strcpy(sedit->get_text(),text);
446 track->edits->optimize();
450 undo->update_undo_after(_("paste subttl"), LOAD_EDITS | LOAD_PATCHES);
452 sync_parameters(CHANGE_EDL);
454 gui->update(0, 1, 1, 0, 0, 0, 0);
455 gui->unlock_window();
460 int SWindowGUI::paste_text(const char *text, double start, double end)
462 char stext[BCTEXTLEN], *cp = stext;
463 if( text ) { // remap charset, reformat if needed
464 for( const char *bp=text; *bp!=0; ++bp,++cp ) {
466 case '\n': *cp = '|'; break;
467 default: *cp = *bp; break;
471 if( cp > stext && *(cp-1) == '|' ) --cp;
473 return swindow->mwindow->paste_subtitle_text(stext, start, end);
476 int SWindowGUI::paste_selection()
478 EDL *edl = swindow->mwindow->edl;
479 LocalSession *lsn = edl->local_session;
480 double start = lsn->get_selectionstart();
481 double end = lsn->get_selectionend();
482 if( start >= end ) return 1;
483 if( lsn->inpoint_valid() && lsn->outpoint_valid() ) {
484 lsn->set_inpoint(lsn->get_outpoint());
485 lsn->unset_outpoint();
487 paste_text(line_entry->get_text(), start, end);
488 load_next_selection();
492 int SWindowGUI::clear_selection()
494 EDL *edl = swindow->mwindow->edl;
495 double start = edl->local_session->get_selectionstart();
496 double end = edl->local_session->get_selectionend();
498 paste_text(0, start, end);
503 ScriptPrev::ScriptPrev(SWindowGUI *gui, int x, int y)
504 : BC_GenericButton(x, y, _("Prev"))
509 ScriptPrev::~ScriptPrev()
513 int ScriptPrev::handle_event()
515 sw_gui->load_prev_selection();
519 ScriptNext::ScriptNext(SWindowGUI *gui, int x, int y)
520 : BC_GenericButton(x, y, _("Next"))
525 ScriptNext::~ScriptNext()
529 int ScriptNext::handle_event()
531 sw_gui->load_next_selection();
535 ScriptPaste::ScriptPaste(SWindowGUI *gui, int x, int y)
536 : BC_GenericButton(x, y, _("Paste"))
541 ScriptPaste::~ScriptPaste()
545 int ScriptPaste::handle_event()
547 sw_gui->paste_selection();
551 ScriptClear::ScriptClear(SWindowGUI *gui, int x, int y)
552 : BC_GenericButton(x, y, _("Clear"))
557 ScriptClear::~ScriptClear()
561 int ScriptClear::handle_event()
563 sw_gui->clear_selection();
568 ScriptLines::ScriptLines()
572 text = new char[allocated = 256];
576 ScriptLines::~ScriptLines()
581 void ScriptLines::append(char *cp)
583 int len = strlen(cp);
584 if( allocated-used < len+1 ) {
585 int isz = allocated + used + len;
586 char *new_text = new char[isz];
588 memcpy(new_text, text, used);
589 delete [] text; text = new_text;
591 memcpy(text+used, cp, len);
592 text[used += len] = 0;
596 int ScriptLines::break_lines()
599 int limit2 = line_limit/2;
600 int limit4 = line_limit/4-2;
601 char *cp = text, *dp = cp+used;
602 int n; char *bp, *ep, *pp, *sp;
603 for( lines=0; cp<dp; ++lines ) {
604 // find end of line/buffer
605 for( ep=cp; ep<dp && *ep!='\n'; ++ep );
606 // delete trailing spaces
607 for( sp=ep; sp>=cp && (!*sp || isspace(*sp)); --sp);
609 if( (n=ep-sp) > 0 ) {
610 memmove(sp,ep,dp+1-ep);
611 used -= n; dp -= n; ep -= n;
614 // skip, if comment or title line
615 if( *cp == '*' || *cp == '=' ) {
618 // delete leading spaces
619 for( sp=cp; sp<ep && isspace(*sp); ++sp);
620 if( (n=sp-cp) > 0 ) {
621 memmove(cp,sp,dp+1-sp);
622 used -= n; dp -= n; ep -= n;
624 // target about half remaining line, constrain line_limit
625 if( (n=(ep-1-cp)/2) < limit2 || n > line_limit )
627 // search for last punct, last space before line_limit
628 for( bp=cp, pp=sp=0; --n>=0 && cp<ep; ++cp ) {
629 if( ispunct(*cp) && isspace(*(cp+1)) ) pp = cp;
630 else if( isspace(*cp) ) sp = cp;
634 // first, after punctuation
635 if( pp && pp-bp >= limit4 )
641 // last, on next space
643 while( cp<dp && !isspace(*cp) ) ++cp;
653 int ScriptLines::get_text_rows()
656 for( char *cp=text; --i>=0; ++cp )
657 if( *cp == '\n' ) ++ret;
661 char *ScriptLines::get_text_row(int n)
665 for( int i=used; --i>=0; ) {
666 if( *cp++ != '\n' ) continue;
667 if( --n <= 0 ) return cp;
672 ScriptScroll::ScriptScroll(SWindowGUI *gui, int x, int y, int w)
673 : BC_ScrollBar(x, y, SCROLL_HORIZ, w, 0, 0, 0)
678 ScriptScroll::~ScriptScroll()
682 int ScriptScroll::handle_event()
684 int64_t pos = get_value();
685 sw_gui->set_script_pos(pos);
686 sw_gui->script_position->update(pos);
691 ScriptPosition::ScriptPosition(SWindowGUI *gui, int x, int y, int w, int v, int mn, int mx)
692 : BC_TumbleTextBox(gui, v, mn, mx, x, y, w-BC_Tumbler::calculate_w())
697 ScriptPosition::~ScriptPosition()
701 int ScriptPosition::handle_event()
703 int64_t pos = atol(get_text());
704 sw_gui->set_script_pos(pos);
705 sw_gui->script_scroll->update_value(pos);
710 ScriptEntry::ScriptEntry(SWindowGUI *gui, int x, int y, int w, int rows, char *text)
711 : BC_ScrollTextBox(gui, x, y, w, rows, text, -strlen(text))
717 ScriptEntry::ScriptEntry(SWindowGUI *gui, int x, int y, int w, int rows)
718 : BC_ScrollTextBox(gui, x, y, w, rows,(char*)0, BCTEXTLEN)
724 ScriptEntry::~ScriptEntry()
728 void ScriptEntry::set_text(char *text, int isz)
730 if( !text || !*text ) return;
731 if( isz < 0 ) isz = strlen(text);
732 BC_ScrollTextBox::set_text(text, isz);
737 int SWindowGUI::load_script_line(FILE *fp)
740 for(;;) { // skip blank lines
741 char *cp = fgets(line,sizeof(line),fp);
744 while( *cp && isspace(*cp) ) ++cp;
748 ScriptLines *entry = new ScriptLines();
749 script.append(entry);
751 for(;;) { // load non-blank lines
752 //int len = strlen(line);
753 //if( line[len-1] == '\n' ) line[len-1] = ' ';
755 char *cp = fgets(line,sizeof(line),fp);
758 while( *cp && isspace(*cp) ) ++cp;
761 script_text_lines += entry->break_lines();
765 void SWindowGUI::load_script()
767 FILE *fp = fopen(script_path,"r");
769 char string[BCTEXTLEN];
770 sprintf(string,_("cannot open: \"%s\"\n%s"),script_path,strerror(errno));
771 MainError::show_error(string);
777 void SWindowGUI::load_script(FILE *fp)
779 script.remove_all_objects();
781 script_text_lines = 0;
782 while( !load_script_line(fp) );
784 sprintf(value,"%ld",ftell(fp));
785 script_filesz->update(value);
786 sprintf(value,"%ld",script_line_no);
787 script_lines->update(value);
788 sprintf(value,"%d",script.size());
789 script_entries->update(value);
790 sprintf(value,"%ld",script_text_lines);
791 script_texts->update(value);
792 int hw = 2*script_scroll->get_h();
793 script_scroll->update_length(script.size(), script_entry_no, hw, 0);
794 script_position->update(script_entry_no);
795 script_position->set_boundaries((int64_t)0, (int64_t)script.size()-1);
800 void SWindowGUI::save_spumux_data()
802 char filename[BCTEXTLEN], track_title[BCTEXTLEN];
803 snprintf(filename,sizeof(filename),"%s",script_path);
804 filename[sizeof(filename)-1] = 0;
805 char *bp = strrchr(filename,'/');
806 if( !bp ) bp = filename; else ++bp;
807 char *ext = strrchr(bp, '.');
808 if( !ext ) ext = bp + strlen(bp);
809 int len = sizeof(filename)-1 - (ext-filename);
811 Tracks *tracks = swindow->mwindow->edl->tracks;
812 for( Track *track=tracks->first; track; track=track->next ) {
813 if( track->data_type != TRACK_SUBTITLE ) continue;
814 if( !track->record ) continue;
815 char *cp = track_title;
816 for( char *bp=track->title; *bp; ++bp,++cp )
817 *cp = !isalnum(*bp) ? '_' : *bp;
819 snprintf(ext,len,"-%s.udvd",track_title);
820 FILE *fp = fopen(filename, "w");
822 eprintf(_("Unable to open %s:\n%m"), filename);
826 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
827 SEdit *sedit = (SEdit *)edit;
828 if( sedit->length > 0 ) {
829 int64_t end = start + sedit->length;
830 char *text = sedit->get_text();
832 fprintf(fp, "{%ld}{%ld}%s\n", start, end-1, text);
843 SWindow::SWindow(MWindow *mwindow)
846 this->mwindow = mwindow;
847 window_lock = new Mutex("SWindow::window_lock");
848 swin_lock = new Condition(0,"SWindow::swin_lock");
865 void SWindow::start()
867 if( !Thread::running() ) {
875 if( Thread::running() ) {
878 window_lock->lock("SWindow::stop");
879 if( gui ) gui->stop(1);
880 window_lock->unlock();
888 int root_w = mwindow->gui->get_root_w(1);
889 int root_h = mwindow->gui->get_root_h(1);
895 int x = mwindow->session->swindow_x;
896 int y = mwindow->session->swindow_y;
897 int w = mwindow->session->swindow_w;
898 int h = mwindow->session->swindow_h;
899 if( w < 600 ) w = 600;
900 if( h < 500 ) h = 500;
901 int scr_x = mwindow->gui->get_screen_x(1, -1);
902 int scr_w = mwindow->gui->get_screen_w(1, -1);
903 if( x < scr_x ) x = scr_x;
904 if( x > scr_x+scr_w ) x = scr_x+scr_w;
905 if( x+w > root_w ) x = root_w - w;
906 if( x < 0 ) { x = 0; w = scr_w; }
907 if( y+h > root_h ) y = root_h - h;
908 if( y < 0 ) { y = 0; h = root_h; }
909 if( y+h > root_h ) h = root_h-y;
910 mwindow->session->swindow_x = x;
911 mwindow->session->swindow_y = y;
912 mwindow->session->swindow_w = w;
913 mwindow->session->swindow_h = h;
916 gui = new SWindowGUI(this, x, y, w, h);
917 gui->lock_window("ChannelInfo::gui_create_objects");
918 gui->load_defaults();
919 gui->create_objects();
920 gui->set_icon(mwindow->theme->get_image("record_icon"));
921 gui->reposition_window(x, y);
922 gui->resize_event(w, h);
925 gui->unlock_window();
927 int result = gui->run_window();
929 gui->save_spumux_data();
932 window_lock->lock("ChannelInfo::run 1");
933 gui->save_defaults();
935 window_lock->unlock();
942 void SWindow::run_swin()
944 window_lock->lock("SWindow::run_swin");
946 gui->lock_window("SWindow::run_swin");
948 gui->unlock_window();
952 window_lock->unlock();
955 void SWindow::paste_subttl()
957 window_lock->lock("SWindow::paste_subttl 1");
959 gui->lock_window("SWindow::paste_subttl 2");
960 gui->paste_selection();
961 gui->unlock_window();
963 window_lock->unlock();
966 int SWindow::update_selection()
968 window_lock->lock("SWindow::update_selection 1");
970 gui->lock_window("SWindow::update_selection 2");
971 gui->update_selection();
972 gui->unlock_window();
974 window_lock->unlock();
980 SubttlSWin::SubttlSWin(MWindow *mwindow)
981 : BC_MenuItem(_("SubTitle..."), _("Alt-y"), 'y')
984 this->mwindow = mwindow;
987 SubttlSWin::~SubttlSWin()
991 int SubttlSWin::handle_event()
993 mwindow->gui->swindow->run_swin();