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