fix awdw solo vicon crash, fix nested clip for binfolders, open edit edl
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / editpanel.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "awindow.h"
23 #include "awindowgui.h"
24 #include "bcsignals.h"
25 #include "clipedit.h"
26 #include "cplayback.h"
27 #include "cwindow.h"
28 #include "cwindowgui.h"
29 #include "editpanel.h"
30 #include "edl.h"
31 #include "edlsession.h"
32 #include "filexml.h"
33 #include "keys.h"
34 #include "language.h"
35 #include "localsession.h"
36 #include "mainclock.h"
37 #include "mainsession.h"
38 #include "mainundo.h"
39 #include "manualgoto.h"
40 #include "mbuttons.h"
41 #include "meterpanel.h"
42 #include "mwindow.h"
43 #include "mwindowgui.h"
44 #include "playbackengine.h"
45 #include "preferences.h"
46 #include "scopewindow.h"
47 #include "theme.h"
48 #include "timebar.h"
49 #include "trackcanvas.h"
50 #include "transportque.h"
51 #include "vwindowgui.h"
52 #include "zoombar.h"
53
54
55
56 EditPanel::EditPanel(MWindow *mwindow,
57         BC_WindowBase *subwindow,
58         int window_id,
59         int x,
60         int y,
61         int editing_mode,
62         int use_editing_mode,
63         int use_keyframe,
64         int use_splice,   // Extra buttons
65         int use_overwrite,
66         int use_copy,
67         int use_paste,
68         int use_undo,
69         int use_fit,
70         int use_locklabels,
71         int use_labels,
72         int use_toclip,
73         int use_meters,
74         int use_cut,
75         int use_commercial,
76         int use_goto,
77         int use_clk2play,
78         int use_scope)
79 {
80         this->window_id = window_id;
81         this->editing_mode = editing_mode;
82         this->use_editing_mode = use_editing_mode;
83         this->use_keyframe = use_keyframe;
84         this->use_splice = use_splice;
85         this->use_overwrite = use_overwrite;
86         this->use_copy = use_copy;
87         this->use_paste = use_paste;
88         this->use_undo = use_undo;
89         this->mwindow = mwindow;
90         this->subwindow = subwindow;
91         this->use_fit = use_fit;
92         this->use_labels = use_labels;
93         this->use_locklabels = use_locklabels;
94         this->use_toclip = use_toclip;
95         this->use_meters = use_meters;
96         this->use_cut = use_cut;
97         this->use_commercial = use_commercial;
98         this->use_goto = use_goto;
99         this->use_clk2play = use_clk2play;
100         this->use_scope = use_scope;
101
102         this->x = x;
103         this->y = y;
104         this->fit = 0;
105         this->fit_autos = 0;
106         this->inpoint = 0;
107         this->outpoint = 0;
108         this->splice = 0;
109         this->overwrite = 0;
110         this->clip = 0;
111         this->cut = 0;
112         this->commercial = 0;
113         this->copy = 0;
114         this->paste = 0;
115         this->labelbutton = 0;
116         this->prevlabel = 0;
117         this->nextlabel = 0;
118         this->prevedit = 0;
119         this->nextedit = 0;
120         this->undo = 0;
121         this->redo = 0;
122         this->meter_panel = 0;
123         this->meters = 0;
124         this->arrow = 0;
125         this->ibeam = 0;
126         this->keyframe = 0;
127         this->span_keyframe = 0;
128         this->mangoto = 0;
129         this->click2play = 0;
130         this->scope = 0;
131         this->scope_dialog = 0;
132         locklabels = 0;
133 }
134
135 EditPanel::~EditPanel()
136 {
137         delete scope_dialog;
138 }
139
140 void EditPanel::set_meters(MeterPanel *meter_panel)
141 {
142         this->meter_panel = meter_panel;
143 }
144
145
146 void EditPanel::update()
147 {
148         int new_editing_mode = mwindow->edl->session->editing_mode;
149         if( arrow ) arrow->update(new_editing_mode == EDITING_ARROW);
150         if( ibeam ) ibeam->update(new_editing_mode == EDITING_IBEAM);
151         if( keyframe ) keyframe->update(mwindow->edl->session->auto_keyframes);
152         if( span_keyframe ) span_keyframe->update(mwindow->edl->session->span_keyframes);
153         if( locklabels ) locklabels->set_value(mwindow->edl->session->labels_follow_edits);
154         if( click2play ) {
155                 int value = !is_vwindow() ?
156                         mwindow->edl->session->cwindow_click2play :
157                         mwindow->edl->session->vwindow_click2play ;
158                 click2play->set_value(value);
159         }
160         if( meters ) {
161                 if( is_cwindow() ) {
162                         meters->update(mwindow->edl->session->cwindow_meter);
163                         mwindow->cwindow->gui->update_meters();
164                 }
165                 else {
166                         meters->update(mwindow->edl->session->vwindow_meter);
167                 }
168         }
169         subwindow->flush();
170 }
171
172 int EditPanel::calculate_w(MWindow *mwindow, int use_keyframe, int total_buttons)
173 {
174         int button_w = xS(24); // mwindow->theme->get_image_set("meters")[0]->get_w();
175         int result = button_w * total_buttons;
176         if( use_keyframe )
177                 result += 2*(button_w + mwindow->theme->toggle_margin);
178         return result;
179 }
180
181 int EditPanel::calculate_h(MWindow *mwindow)
182 {
183         return mwindow->theme->get_image_set("meters")[0]->get_h();
184 }
185
186 void EditPanel::create_buttons()
187 {
188         x1 = x, y1 = y;
189
190         if( use_editing_mode ) {
191                 arrow = new ArrowButton(mwindow, this, x1, y1);
192                 subwindow->add_subwindow(arrow);
193                 x1 += arrow->get_w();
194                 ibeam = new IBeamButton(mwindow, this, x1, y1);
195                 subwindow->add_subwindow(ibeam);
196                 x1 += ibeam->get_w();
197                 x1 += mwindow->theme->toggle_margin;
198         }
199
200         if( use_keyframe ) {
201                 keyframe = new KeyFrameButton(mwindow, this, x1, y1);
202                 subwindow->add_subwindow(keyframe);
203                 x1 += keyframe->get_w();
204                 span_keyframe = new SpanKeyFrameButton(mwindow, this, x1, y1);
205                 subwindow->add_subwindow(span_keyframe);
206                 x1 += span_keyframe->get_w();
207         }
208
209         if( use_locklabels ) {
210                 locklabels = new LockLabelsButton(mwindow, this, x1, y1);
211                 subwindow->add_subwindow(locklabels);
212                 x1 += locklabels->get_w();
213         }
214
215         if( use_keyframe || use_locklabels )
216                 x1 += mwindow->theme->toggle_margin;
217
218 // Mandatory
219         inpoint = new EditInPoint(mwindow, this, x1, y1);
220         subwindow->add_subwindow(inpoint);
221         x1 += inpoint->get_w();
222         outpoint = new EditOutPoint(mwindow, this, x1, y1);
223         subwindow->add_subwindow(outpoint);
224         x1 += outpoint->get_w();
225
226         if( use_splice ) {
227                 splice = new EditSplice(mwindow, this, x1, y1);
228                 subwindow->add_subwindow(splice);
229                 x1 += splice->get_w();
230         }
231
232         if( use_overwrite ) {
233                 overwrite = new EditOverwrite(mwindow, this, x1, y1);
234                 subwindow->add_subwindow(overwrite);
235                 x1 += overwrite->get_w();
236         }
237
238         if( use_toclip ) {
239                 clip = new EditToClip(mwindow, this, x1, y1);
240                 subwindow->add_subwindow(clip);
241                 x1 += clip->get_w();
242         }
243
244         if( use_cut ) {
245                 cut = new EditCut(mwindow, this, x1, y1);
246                 subwindow->add_subwindow(cut);
247                 x1 += cut->get_w();
248         }
249
250         if( use_copy ) {
251                 copy = new EditCopy(mwindow, this, x1, y1);
252                 subwindow->add_subwindow(copy);
253                 x1 += copy->get_w();
254         }
255
256         if( use_paste ) {
257                 paste = new EditPaste(mwindow, this, x1, y1);
258                 subwindow->add_subwindow(paste);
259                 x1 += paste->get_w();
260         }
261
262         if( use_labels ) {
263                 labelbutton = new EditLabelbutton(mwindow, this, x1, y1);
264                 subwindow->add_subwindow(labelbutton);
265                 x1 += labelbutton->get_w();
266                 prevlabel = new EditPrevLabel(mwindow, this, x1, y1);
267                 subwindow->add_subwindow(prevlabel);
268                 x1 += prevlabel->get_w();
269                 nextlabel = new EditNextLabel(mwindow, this, x1, y1);
270                 subwindow->add_subwindow(nextlabel);
271                 x1 += nextlabel->get_w();
272         }
273
274 // all windows except VWindow since it's only implemented in MWindow.
275         if( use_cut ) {
276                 prevedit = new EditPrevEdit(mwindow, this, x1, y1);
277                 subwindow->add_subwindow(prevedit);
278                 x1 += prevedit->get_w();
279                 nextedit = new EditNextEdit(mwindow, this, x1, y1);
280                 subwindow->add_subwindow(nextedit);
281                 x1 += nextedit->get_w();
282         }
283
284         if( use_fit ) {
285                 fit = new EditFit(mwindow, this, x1, y1);
286                 subwindow->add_subwindow(fit);
287                 x1 += fit->get_w();
288                 fit_autos = new EditFitAutos(mwindow, this, x1, y1);
289                 subwindow->add_subwindow(fit_autos);
290                 x1 += fit_autos->get_w();
291         }
292
293         if( use_undo ) {
294                 undo = new EditUndo(mwindow, this, x1, y1);
295                 subwindow->add_subwindow(undo);
296                 x1 += undo->get_w();
297                 redo = new EditRedo(mwindow, this, x1, y1);
298                 subwindow->add_subwindow(redo);
299                 x1 += redo->get_w();
300         }
301
302         if( use_goto ) {
303                 mangoto = new EditManualGoto(mwindow, this, x1, y1);
304                 subwindow->add_subwindow(mangoto);
305                 x1 += mangoto->get_w();
306         }
307
308         if( use_clk2play ) {
309                 click2play = new EditClick2Play(mwindow, this, x1, y1+yS(3));
310                 subwindow->add_subwindow(click2play);
311                 x1 += click2play->get_w();
312         }
313
314         if( use_scope ) {
315                 scope = new EditPanelScope(mwindow, this, x1, y1-yS(1));
316                 subwindow->add_subwindow(scope);
317                 x1 += scope->get_w();
318                 scope_dialog = new EditPanelScopeDialog(mwindow, this);
319         }
320
321         if( use_meters ) {
322                 if( meter_panel ) {
323                         meters = new MeterShow(mwindow, meter_panel, x1, y1);
324                         subwindow->add_subwindow(meters);
325                         x1 += meters->get_w();
326                 }
327                 else
328                         printf("EditPanel::create_objects: meter_panel == 0\n");
329         }
330
331         if( use_commercial ) {
332                 commercial = new EditCommercial(mwindow, this, x1, y1);
333                 subwindow->add_subwindow(commercial);
334                 x1 += commercial->get_w();
335         }
336 }
337
338 void EditPanel::reposition_buttons(int x, int y)
339 {
340         this->x = x;
341         this->y = y;
342         x1 = x, y1 = y;
343
344         if( use_editing_mode ) {
345                 arrow->reposition_window(x1, y1);
346                 x1 += arrow->get_w();
347                 ibeam->reposition_window(x1, y1);
348                 x1 += ibeam->get_w();
349                 x1 += mwindow->theme->toggle_margin;
350         }
351
352         if( use_keyframe ) {
353                 keyframe->reposition_window(x1, y1);
354                 x1 += keyframe->get_w();
355                 span_keyframe->reposition_window(x1, y1);
356                 x1 += span_keyframe->get_w();
357         }
358
359         if( use_locklabels ) {
360                 locklabels->reposition_window(x1,y1);
361                 x1 += locklabels->get_w();
362         }
363
364         if( use_keyframe || use_locklabels )
365                 x1 += mwindow->theme->toggle_margin;
366
367         inpoint->reposition_window(x1, y1);
368         x1 += inpoint->get_w();
369         outpoint->reposition_window(x1, y1);
370         x1 += outpoint->get_w();
371         if( use_splice ) {
372                 splice->reposition_window(x1, y1);
373                 x1 += splice->get_w();
374         }
375         if( use_overwrite ) {
376                 overwrite->reposition_window(x1, y1);
377                 x1 += overwrite->get_w();
378         }
379         if( use_toclip ) {
380                 clip->reposition_window(x1, y1);
381                 x1 += clip->get_w();
382         }
383         if( use_cut ) {
384                 cut->reposition_window(x1, y1);
385                 x1 += cut->get_w();
386         }
387         if( use_copy ) {
388                 copy->reposition_window(x1, y1);
389                 x1 += copy->get_w();
390         }
391         if( use_paste ) {
392                 paste->reposition_window(x1, y1);
393                 x1 += paste->get_w();
394         }
395
396         if( use_labels ) {
397                 labelbutton->reposition_window(x1, y1);
398                 x1 += labelbutton->get_w();
399                 prevlabel->reposition_window(x1, y1);
400                 x1 += prevlabel->get_w();
401                 nextlabel->reposition_window(x1, y1);
402                 x1 += nextlabel->get_w();
403         }
404
405         if( prevedit ) {
406                 prevedit->reposition_window(x1, y1);
407                 x1 += prevedit->get_w();
408         }
409
410         if( nextedit ) {
411                 nextedit->reposition_window(x1, y1);
412                 x1 += nextedit->get_w();
413         }
414
415         if( use_fit ) {
416                 fit->reposition_window(x1, y1);
417                 x1 += fit->get_w();
418                 fit_autos->reposition_window(x1, y1);
419                 x1 += fit_autos->get_w();
420         }
421
422         if( use_undo ) {
423                 undo->reposition_window(x1, y1);
424                 x1 += undo->get_w();
425                 redo->reposition_window(x1, y1);
426                 x1 += redo->get_w();
427         }
428
429         if( use_goto ) {
430                 mangoto->reposition_window(x1, y1);
431                 x1 += mangoto->get_w();
432         }
433         if( use_clk2play ) {
434                 click2play->reposition_window(x1, y1+yS(3));
435                 x1 += click2play->get_w();
436         }
437         if( use_scope ) {
438                 scope->reposition_window(x1, y1-yS(1));
439                 x1 += scope->get_w();
440         }
441
442         if( use_meters ) {
443                 meters->reposition_window(x1, y1);
444                 x1 += meters->get_w();
445         }
446 }
447
448 void EditPanel::create_objects()
449 {
450         create_buttons();
451 }
452
453 int EditPanel::get_w()
454 {
455         return x1 - x;
456 }
457
458 // toggle_label
459 EditLabelbutton::EditLabelbutton(MWindow *mwindow, EditPanel *panel, int x, int y)
460  : BC_Button(x, y, mwindow->theme->get_image_set("labelbutton"))
461 {
462         this->mwindow = mwindow;
463         this->panel = panel;
464         set_tooltip(_("Toggle label at current position ( l )"));
465 }
466
467 EditLabelbutton::~EditLabelbutton()
468 {
469 }
470 int EditLabelbutton::keypress_event()
471 {
472         if( get_keypress() == 'l' && !alt_down() )
473                 return handle_event();
474         return 0;
475 }
476 int EditLabelbutton::handle_event()
477 {
478         panel->panel_toggle_label();
479         return 1;
480 }
481
482 //next_label
483 EditNextLabel::EditNextLabel(MWindow *mwindow,
484         EditPanel *panel, int x, int y)
485  : BC_Button(x, y, mwindow->theme->get_image_set("nextlabel"))
486 {
487         this->mwindow = mwindow;
488         this->panel = panel;
489         set_tooltip(_("Next label ( ctrl -> )"));
490 }
491 EditNextLabel::~EditNextLabel()
492 {
493 }
494 int EditNextLabel::keypress_event()
495 {
496         if( ctrl_down() ) {
497                 int key = get_keypress();
498                 if( (key == RIGHT || key == '.') && !alt_down() ) {
499                         panel->panel_next_label(0);
500                         return 1;
501                 }
502                 if( key == '>' && alt_down() ) {
503                         panel->panel_next_label(1);
504                         return 1;
505                 }
506         }
507         return 0;
508 }
509 int EditNextLabel::handle_event()
510 {
511         int cut = ctrl_down() && alt_down();
512         panel->panel_next_label(cut);
513         return 1;
514 }
515
516 //prev_label
517 EditPrevLabel::EditPrevLabel(MWindow *mwindow,
518         EditPanel *panel, int x, int y)
519  : BC_Button(x, y, mwindow->theme->get_image_set("prevlabel"))
520 {
521         this->mwindow = mwindow;
522         this->panel = panel;
523         set_tooltip(_("Previous label ( ctrl <- )"));
524 }
525 EditPrevLabel::~EditPrevLabel()
526 {
527 }
528 int EditPrevLabel::keypress_event()
529 {
530         if( ctrl_down() ) {
531                 int key = get_keypress();
532                 if( (key == LEFT || key == ',') && !alt_down() ) {
533                         panel->panel_prev_label(0);
534                         return 1;
535                 }
536                 if( key == '<' && alt_down() ) {
537                         panel->panel_prev_label(1);
538                         return 1;
539                 }
540         }
541         return 0;
542 }
543 int EditPrevLabel::handle_event()
544 {
545         int cut = ctrl_down() && alt_down();
546         panel->panel_prev_label(cut);
547         return 1;
548 }
549
550 //prev_edit
551 EditPrevEdit::EditPrevEdit(MWindow *mwindow,
552         EditPanel *panel, int x, int y)
553  : BC_Button(x, y, mwindow->theme->get_image_set("prevedit"))
554 {
555         this->mwindow = mwindow;
556         this->panel = panel;
557         set_tooltip(_("Previous edit (alt <- )"));
558 }
559 EditPrevEdit::~EditPrevEdit()
560 {
561 }
562 int EditPrevEdit::keypress_event()
563 {
564         if( alt_down() ) {
565                 int key = get_keypress();
566                 if( (key == LEFT || key == ',') && !ctrl_down() ) {
567                         panel->panel_prev_edit(0);
568                         return 1;
569                 }
570                 if( key == ',' && ctrl_down() ) {
571                         panel->panel_prev_edit(1);
572                         return 1;
573                 }
574         }
575         return 0;
576 }
577 int EditPrevEdit::handle_event()
578 {
579         int cut = ctrl_down() && alt_down();
580         panel->panel_prev_edit(cut);
581         return 1;
582 }
583
584 //next_edit
585 EditNextEdit::EditNextEdit(MWindow *mwindow,
586         EditPanel *panel, int x, int y)
587  : BC_Button(x, y, mwindow->theme->get_image_set("nextedit"))
588 {
589         this->mwindow = mwindow;
590         this->panel = panel;
591         set_tooltip(_("Next edit ( alt -> )"));
592 }
593 EditNextEdit::~EditNextEdit()
594 {
595 }
596 int EditNextEdit::keypress_event()
597 {
598         if( alt_down() ) {
599                 int key = get_keypress();
600                 if( (key == RIGHT || key == '.') && !ctrl_down() ) {
601                         panel->panel_next_edit(0);
602                         return 1;
603                 }
604                 if( key == '.' && ctrl_down() ) {
605                         panel->panel_next_edit(1);
606                         return 1;
607                 }
608         }
609         return 0;
610 }
611 int EditNextEdit::handle_event()
612 {
613         int cut = ctrl_down() && alt_down();
614         panel->panel_next_edit(cut);
615         return 1;
616 }
617
618 //copy_selection
619 EditCopy::EditCopy(MWindow *mwindow, EditPanel *panel, int x, int y)
620  : BC_Button(x, y, mwindow->theme->get_image_set("copy"))
621 {
622         this->mwindow = mwindow;
623         this->panel = panel;
624         set_tooltip(_("Copy ( c )"));
625 }
626 EditCopy::~EditCopy()
627 {
628 }
629
630 int EditCopy::keypress_event()
631 {
632         if( alt_down() ) return 0;
633         if( (get_keypress() == 'c' && !ctrl_down()) ||
634             (panel->is_vwindow() && get_keypress() == 'C') ) {
635                 return handle_event();
636         }
637         return 0;
638 }
639 int EditCopy::handle_event()
640 {
641         panel->panel_copy_selection();
642         return 1;
643 }
644
645 //overwrite_selection
646 EditOverwrite::EditOverwrite(MWindow *mwindow, EditPanel *panel, int x, int y)
647  : BC_Button(x, y, mwindow->theme->overwrite_data)
648 {
649         this->mwindow = mwindow;
650         this->panel = panel;
651         set_tooltip(_("Overwrite ( b )"));
652 }
653 EditOverwrite::~EditOverwrite()
654 {
655 }
656 int EditOverwrite::handle_event()
657 {
658         panel->panel_overwrite_selection();
659         return 1;
660 }
661 int EditOverwrite::keypress_event()
662 {
663         if( alt_down() ) return 0;
664         if( get_keypress() == 'b' ||
665             (panel->is_vwindow() && get_keypress() == 'B') ) {
666                 handle_event();
667                 return 1;
668         }
669         return 0;
670 }
671
672 //set_inpoint
673 //unset_inoutpoint
674 EditInPoint::EditInPoint(MWindow *mwindow, EditPanel *panel, int x, int y)
675  : BC_Button(x, y, mwindow->theme->get_image_set("inbutton"))
676 {
677         this->mwindow = mwindow;
678         this->panel = panel;
679         set_tooltip(_("In point ( [ or < )"));
680 }
681 EditInPoint::~EditInPoint()
682 {
683 }
684 int EditInPoint::handle_event()
685 {
686         panel->panel_set_inpoint();
687         return 1;
688 }
689 int EditInPoint::keypress_event()
690 {
691         int key = get_keypress();
692         if( ctrl_down() ) {
693                 if( key == 't' ) {
694                         panel->panel_unset_inoutpoint();
695                         return 1;
696                 }
697         }
698         else if( !alt_down() ) {
699                 if( key == '[' || key == '<' ) {
700                         panel->panel_set_inpoint();
701                         return 1;
702                 }
703         }
704         return 0;
705 }
706
707 //set_outpoint
708 //unset_inoutpoint
709 EditOutPoint::EditOutPoint(MWindow *mwindow, EditPanel *panel, int x, int y)
710  : BC_Button(x, y, mwindow->theme->get_image_set("outbutton"))
711 {
712         this->mwindow = mwindow;
713         this->panel = panel;
714         set_tooltip(_("Out point ( ] or > )"));
715 }
716 EditOutPoint::~EditOutPoint()
717 {
718 }
719 int EditOutPoint::handle_event()
720 {
721         panel->panel_set_outpoint();
722         return 1;
723 }
724 int EditOutPoint::keypress_event()
725 {
726         int key = get_keypress();
727         if( ctrl_down() ) {
728                 if(  key == 't' ) {
729                         panel->panel_unset_inoutpoint();
730                         return 1;
731                 }
732         }
733         else if( !alt_down() ) {
734                 if( key == ']' || key == '>' ) {
735                         panel->panel_set_outpoint();
736                         return 1;
737                 }
738         }
739         return 0;
740 }
741
742 //splice_selection
743 EditSplice::EditSplice(MWindow *mwindow, EditPanel *panel, int x, int y)
744  : BC_Button(x, y, mwindow->theme->splice_data)
745 {
746         this->mwindow = mwindow;
747         this->panel = panel;
748         set_tooltip(_("Splice ( v )"));
749 }
750 EditSplice::~EditSplice()
751 {
752 }
753 int EditSplice::handle_event()
754 {
755         panel->panel_splice_selection();
756         return 1;
757 }
758 int EditSplice::keypress_event()
759 {
760         if( alt_down() ) return 0;
761         if( (get_keypress() == 'v' && !ctrl_down()) ||
762             (panel->is_vwindow() && get_keypress() == 'V') ) {
763                 handle_event();
764                 return 1;
765         }
766         return 0;
767 }
768
769 //to_clip
770 EditToClip::EditToClip(MWindow *mwindow, EditPanel *panel, int x, int y)
771  : BC_Button(x, y, mwindow->theme->get_image_set("toclip"))
772 {
773         this->mwindow = mwindow;
774         this->panel = panel;
775         set_tooltip(_("To clip ( i )"));
776 }
777 EditToClip::~EditToClip()
778 {
779 }
780 int EditToClip::handle_event()
781 {
782         panel->panel_to_clip();
783         return 1;
784 }
785
786 int EditToClip::keypress_event()
787 {
788         if( alt_down() ) return 0;
789         if( get_keypress() == 'i' ||
790             (panel->is_vwindow() && get_keypress() == 'I') ) {
791                 handle_event();
792                 return 1;
793         }
794         return 0;
795 }
796
797 //cut
798 EditCut::EditCut(MWindow *mwindow, EditPanel *panel, int x, int y)
799  : BC_Button(x, y, mwindow->theme->get_image_set("cut"))
800 {
801         this->mwindow = mwindow;
802         this->panel = panel;
803         set_tooltip(_("Split | Cut ( x )"));
804 }
805 EditCut::~EditCut()
806 {
807 }
808 int EditCut::keypress_event()
809 {
810         if( ctrl_down() || shift_down() || alt_down() )
811                 return 0;
812         if( get_keypress() == 'x' )
813                 return handle_event();
814         return 0;
815 }
816
817 int EditCut::handle_event()
818 {
819         panel->panel_cut();
820         return 1;
821 }
822
823 //paste
824 EditPaste::EditPaste(MWindow *mwindow, EditPanel *panel, int x, int y)
825  : BC_Button(x, y, mwindow->theme->get_image_set("paste"))
826 {
827         this->mwindow = mwindow;
828         this->panel = panel;
829         set_tooltip(_("Paste ( v )"));
830 }
831 EditPaste::~EditPaste()
832 {
833 }
834
835 int EditPaste::keypress_event()
836 {
837         if( get_keypress() == 'v' && !ctrl_down() )
838                 return handle_event();
839         return 0;
840 }
841 int EditPaste::handle_event()
842 {
843         panel->panel_paste();
844         return 1;
845 }
846
847 //fit_selection
848 EditFit::EditFit(MWindow *mwindow, EditPanel *panel, int x, int y)
849  : BC_Button(x, y, mwindow->theme->get_image_set("fit"))
850 {
851         this->mwindow = mwindow;
852         this->panel = panel;
853         set_tooltip(_("Fit selection to display ( f )"));
854 }
855 EditFit::~EditFit()
856 {
857 }
858 int EditFit::keypress_event()
859 {
860         if( !alt_down() && get_keypress() == 'f' ) {
861                 handle_event();
862                 return 1;
863         }
864         return 0;
865 }
866 int EditFit::handle_event()
867 {
868         panel->panel_fit_selection();
869         return 1;
870 }
871
872 //fit_autos
873 EditFitAutos::EditFitAutos(MWindow *mwindow, EditPanel *panel, int x, int y)
874  : BC_Button(x, y, mwindow->theme->get_image_set("fitautos"))
875 {
876         this->mwindow = mwindow;
877         this->panel = panel;
878         set_tooltip(_("Fit all autos to display ( Alt + f )"));
879 }
880 EditFitAutos::~EditFitAutos()
881 {
882 }
883 int EditFitAutos::keypress_event()
884 {
885         if( get_keypress() == 'f' && alt_down() ) {
886                 panel->panel_fit_autos(!ctrl_down() ? 1 : 0);
887                 return 1;
888         }
889         return 0;
890 }
891 int EditFitAutos::handle_event()
892 {
893         panel->panel_fit_autos(1);
894         return 1;
895 }
896
897 //set_editing_mode
898 ArrowButton::ArrowButton(MWindow *mwindow, EditPanel *panel, int x, int y)
899  : BC_Toggle(x, y,
900         mwindow->theme->get_image_set("arrow"),
901         mwindow->edl->session->editing_mode == EDITING_ARROW,
902         "", 0, 0, 0)
903 {
904         this->mwindow = mwindow;
905         this->panel = panel;
906         set_tooltip(_("Drag and drop editing mode"));
907 }
908
909 int ArrowButton::handle_event()
910 {
911         update(1);
912         panel->ibeam->update(0);
913         panel->panel_set_editing_mode(EDITING_ARROW);
914 // Nothing after this
915         return 1;
916 }
917
918 IBeamButton::IBeamButton(MWindow *mwindow, EditPanel *panel, int x, int y)
919  : BC_Toggle(x, y,
920         mwindow->theme->get_image_set("ibeam"),
921         mwindow->edl->session->editing_mode == EDITING_IBEAM,
922         "", 0, 0, 0)
923 {
924         this->mwindow = mwindow;
925         this->panel = panel;
926         set_tooltip(_("Cut and paste editing mode"));
927 }
928
929 int IBeamButton::handle_event()
930 {
931         update(1);
932         panel->arrow->update(0);
933         panel->panel_set_editing_mode(EDITING_IBEAM);
934 // Nothing after this
935         return 1;
936 }
937
938 //set_auto_keyframes
939 KeyFrameButton::KeyFrameButton(MWindow *mwindow, EditPanel *panel, int x, int y)
940  : BC_Toggle(x, y,
941         mwindow->theme->get_image_set("autokeyframe"),
942         mwindow->edl->session->auto_keyframes,
943         "", 0, 0, 0)
944 {
945         this->mwindow = mwindow;
946         this->panel = panel;
947         set_tooltip(_("Generate keyframes while tweeking (j)"));
948 }
949
950 int KeyFrameButton::handle_event()
951 {
952         panel->panel_set_auto_keyframes(get_value());
953         return 1;
954 }
955
956 int KeyFrameButton::keypress_event()
957 {
958         int key = get_keypress();
959         if( key == 'j' && !ctrl_down() && !shift_down() && !alt_down() ) {
960                 int value = get_value() ? 0 : 1;
961                 update(value);
962                 panel->panel_set_auto_keyframes(value);
963                 return 1;
964         }
965         return 0;
966 }
967
968 //set_span_keyframes
969 SpanKeyFrameButton::SpanKeyFrameButton(MWindow *mwindow, EditPanel *panel, int x, int y)
970  : BC_Toggle(x, y,
971         mwindow->theme->get_image_set("spankeyframe"),
972         mwindow->edl->session->span_keyframes,
973         "", 0, 0, 0)
974 {
975         this->mwindow = mwindow;
976         this->panel = panel;
977         set_tooltip(_("Allow keyframe spanning"));
978 }
979
980 int SpanKeyFrameButton::handle_event()
981 {
982         panel->panel_set_span_keyframes(get_value());
983         return 1;
984 }
985
986 //set_labels_follow_edits
987 LockLabelsButton::LockLabelsButton(MWindow *mwindow, EditPanel *panel, int x, int y)
988  : BC_Toggle(x, y,
989         mwindow->theme->get_image_set("locklabels"),
990         mwindow->edl->session->labels_follow_edits,
991         "", 0, 0, 0)
992 {
993         this->mwindow = mwindow;
994         this->panel = panel;
995         set_tooltip(_("Lock labels from moving with edits"));
996 }
997
998 int LockLabelsButton::handle_event()
999 {
1000         panel->panel_set_labels_follow_edits(get_value());
1001         return 1;
1002 }
1003
1004
1005
1006 EditManualGoto::EditManualGoto(MWindow *mwindow, EditPanel *panel, int x, int y)
1007  : BC_Button(x, y, mwindow->theme->get_image_set("goto"))
1008 {
1009         this->mwindow = mwindow;
1010         this->panel = panel;
1011         mangoto = new ManualGoto(mwindow, panel);
1012         set_tooltip(_("Manual goto ( g )"));
1013 }
1014 EditManualGoto::~EditManualGoto()
1015 {
1016         delete mangoto;
1017 }
1018 int EditManualGoto::handle_event()
1019 {
1020         mangoto->start();
1021         return 1;
1022 }
1023
1024 int EditManualGoto::keypress_event()
1025 {
1026         if( get_keypress() == 'g' ) {
1027                 handle_event();
1028                 return 1;
1029         }
1030         return 0;
1031 }
1032
1033
1034 EditClick2Play::EditClick2Play(MWindow *mwindow, EditPanel *panel, int x, int y)
1035  : BC_Toggle(x, y, mwindow->theme->get_image_set("playpatch_data"),
1036     !panel->is_vwindow() ?
1037         mwindow->edl->session->cwindow_click2play :
1038         mwindow->edl->session->vwindow_click2play)
1039 {
1040         this->mwindow = mwindow;
1041         this->panel = panel;
1042         set_tooltip(_("Click to play (p)"));
1043 }
1044 int EditClick2Play::handle_event()
1045 {
1046         int value = get_value();
1047         panel->set_click_to_play(value);
1048         return 1;
1049 }
1050 int EditClick2Play::keypress_event()
1051 {
1052         int key = get_keypress();
1053         if( key == 'p' && !ctrl_down() && !shift_down() && !alt_down() ) {
1054                 int value = get_value() ? 0 : 1;
1055                 update(value);
1056                 panel->set_click_to_play(value);
1057                 return 1;
1058         }
1059         return 0;
1060 }
1061
1062
1063 EditCommercial::EditCommercial(MWindow *mwindow, EditPanel *panel, int x, int y)
1064  : BC_Button(x, y, mwindow->theme->get_image_set("commercial"))
1065 {
1066         this->mwindow = mwindow;
1067         this->panel = panel;
1068         set_tooltip(_("Commercial ( shift A )"));
1069 }
1070 EditCommercial::~EditCommercial()
1071 {
1072 }
1073 int EditCommercial::keypress_event()
1074 {
1075         if( ctrl_down() || !shift_down() || alt_down() )
1076                 return 0;
1077         if( get_keypress() == 'A' )
1078                 return handle_event();
1079         return 0;
1080 }
1081
1082 int EditCommercial::handle_event()
1083 {
1084         int have_mwindow_lock = mwindow->gui->get_window_lock();
1085         if( have_mwindow_lock )
1086                 mwindow->gui->unlock_window();
1087         mwindow->commit_commercial();
1088         if( !mwindow->put_commercial() ) {
1089                 mwindow->gui->lock_window("EditCommercial::handle_event 1");
1090                 mwindow->cut();
1091                 if( !have_mwindow_lock )
1092                         mwindow->gui->unlock_window();
1093                 mwindow->activate_commercial();
1094                 return 1;
1095         }
1096         mwindow->undo_commercial();
1097         if( have_mwindow_lock )
1098                 mwindow->gui->lock_window("EditCommercial::handle_event 2");
1099         return 1;
1100 }
1101
1102
1103 EditUndo::EditUndo(MWindow *mwindow, EditPanel *panel, int x, int y)
1104  : BC_Button(x, y, mwindow->theme->get_image_set("undo"))
1105 {
1106         this->mwindow = mwindow;
1107         this->panel = panel;
1108         set_tooltip(_("Undo ( z )"));
1109 }
1110 EditUndo::~EditUndo()
1111 {
1112 }
1113 int EditUndo::keypress_event()
1114 {
1115         if( ctrl_down() || shift_down() || alt_down() )
1116                 return 0;
1117         if( get_keypress() == 'z' )
1118                 return handle_event();
1119         return 0;
1120 }
1121 int EditUndo::handle_event()
1122 {
1123         mwindow->undo_entry(panel->subwindow);
1124         return 1;
1125 }
1126
1127 EditRedo::EditRedo(MWindow *mwindow, EditPanel *panel, int x, int y)
1128  : BC_Button(x, y, mwindow->theme->get_image_set("redo"))
1129 {
1130         this->mwindow = mwindow;
1131         this->panel = panel;
1132         set_tooltip(_("Redo ( shift Z )"));
1133 }
1134 EditRedo::~EditRedo()
1135 {
1136 }
1137 int EditRedo::keypress_event()
1138 {
1139         if( ctrl_down() || !shift_down() || alt_down() )
1140                 return 0;
1141         if( get_keypress() == 'Z' )
1142                 return handle_event();
1143         return 0;
1144 }
1145 int EditRedo::handle_event()
1146 {
1147         mwindow->redo_entry(panel->subwindow);
1148         return 1;
1149 }
1150
1151
1152 EditPanelScopeDialog::EditPanelScopeDialog(MWindow *mwindow, EditPanel *panel)
1153  : BC_DialogThread()
1154 {
1155         this->mwindow = mwindow;
1156         this->panel = panel;
1157         scope_gui = 0;
1158         gui_lock = new Mutex("EditPanelScopeDialog::gui_lock");
1159 }
1160
1161 EditPanelScopeDialog::~EditPanelScopeDialog()
1162 {
1163         close_window();
1164         delete gui_lock;
1165 }
1166
1167 void EditPanelScopeDialog::handle_close_event(int result)
1168 {
1169         scope_gui = 0;
1170 }
1171 void EditPanelScopeDialog::handle_done_event(int result)
1172 {
1173         gui_lock->lock("EditPanelScopeDialog::handle_done_event");
1174         scope_gui = 0;
1175         gui_lock->unlock();
1176
1177         panel->subwindow->lock_window("EditPanelScopeDialog::handle_done_event");
1178         panel->scope->update(0);
1179         panel->subwindow->unlock_window();
1180 }
1181
1182 BC_Window* EditPanelScopeDialog::new_gui()
1183 {
1184         EditPanelScopeGUI *gui = new EditPanelScopeGUI(mwindow, this);
1185         gui->create_objects();
1186         scope_gui = gui;
1187         return gui;
1188 }
1189
1190 void EditPanelScopeDialog::process(VFrame *output_frame)
1191 {
1192         if( panel->scope_dialog ) {
1193                 panel->scope_dialog->gui_lock->lock("EditPanelScopeDialog::process");
1194                 if( panel->scope_dialog->scope_gui ) {
1195                         EditPanelScopeGUI *gui = panel->scope_dialog->scope_gui;
1196                         gui->process(output_frame);
1197                 }
1198                 panel->scope_dialog->gui_lock->unlock();
1199         }
1200 }
1201
1202 EditPanelScopeGUI::EditPanelScopeGUI(MWindow *mwindow, EditPanelScopeDialog *dialog)
1203  : ScopeGUI(mwindow->theme,
1204         mwindow->session->scope_x, mwindow->session->scope_y,
1205         mwindow->session->scope_w, mwindow->session->scope_h,
1206         mwindow->get_cpus())
1207 {
1208         this->mwindow = mwindow;
1209         this->dialog = dialog;
1210 }
1211
1212 EditPanelScopeGUI::~EditPanelScopeGUI()
1213 {
1214 }
1215
1216 void EditPanelScopeGUI::create_objects()
1217 {
1218         MainSession *session = mwindow->session;
1219         use_hist = session->use_hist;
1220         use_wave = session->use_wave;
1221         use_vector = session->use_vector;
1222         use_hist_parade = session->use_hist_parade;
1223         use_wave_parade = session->use_wave_parade;
1224         use_wave_gain = session->use_wave_gain;
1225         use_vect_gain = session->use_vect_gain;
1226         use_smooth = session->use_smooth;
1227         use_refresh = session->use_refresh;
1228         use_release = session->use_release;
1229         use_graticule = session->use_graticule;
1230         ScopeGUI::create_objects();
1231 }
1232
1233 void EditPanelScopeGUI::toggle_event()
1234 {
1235         MainSession *session = mwindow->session;
1236         session->use_hist = use_hist;
1237         session->use_wave = use_wave;
1238         session->use_vector = use_vector;
1239         session->use_hist_parade = use_hist_parade;
1240         session->use_wave_parade = use_wave_parade;
1241         session->use_wave_gain = use_wave_gain;
1242         session->use_vect_gain = use_vect_gain;
1243         session->use_smooth = use_smooth;
1244         session->use_refresh = use_refresh;
1245         session->use_release = use_release;
1246         session->use_graticule = use_graticule;
1247 }
1248
1249 int EditPanelScopeGUI::translation_event()
1250 {
1251         ScopeGUI::translation_event();
1252         MainSession *session = mwindow->session;
1253         session->scope_x = get_x();
1254         session->scope_y = get_y();
1255         return 0;
1256 }
1257
1258 int EditPanelScopeGUI::resize_event(int w, int h)
1259 {
1260         ScopeGUI::resize_event(w, h);
1261         MainSession *session = mwindow->session;
1262         session->scope_w = w;
1263         session->scope_h = h;
1264         return 0;
1265 }
1266
1267 EditPanelScope::EditPanelScope(MWindow *mwindow, EditPanel *panel, int x, int y)
1268  : BC_Toggle(x, y, mwindow->theme ?
1269                 mwindow->theme->get_image_set("scope_toggle") : 0, 0)
1270 {
1271         this->mwindow = mwindow;
1272         this->panel = panel;
1273         set_tooltip(_("View scope"));
1274 }
1275
1276 EditPanelScope::~EditPanelScope()
1277 {
1278 }
1279
1280 void EditPanelScopeGUI::update_scope()
1281 {
1282         Canvas *canvas = 0;
1283         if( dialog->panel->is_cwindow() ) {
1284                 CWindowGUI *cgui = (CWindowGUI *)dialog->panel->subwindow;
1285                 canvas = cgui->canvas;
1286         }
1287         else if( dialog->panel->is_vwindow() ) {
1288                 VWindowGUI *vgui = (VWindowGUI *)dialog->panel->subwindow;
1289                 canvas = vgui->canvas;
1290         }
1291         if( canvas && canvas->refresh_frame )
1292                 process(canvas->refresh_frame);
1293 }
1294
1295 int EditPanelScope::handle_event()
1296 {
1297         unlock_window();
1298         int v = get_value();
1299         if( v )
1300                 panel->scope_dialog->start();
1301         else
1302                 panel->scope_dialog->close_window();
1303         lock_window("EditPanelScope::handle_event");
1304         return 1;
1305 }
1306