add edit length update when open_edl changes media length, replace stack_warn with...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / editpopup.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 "asset.h"
23 #include "assets.h"
24 #include "awindow.h"
25 #include "awindowgui.h"
26 #include "edit.h"
27 #include "edits.h"
28 #include "editpopup.h"
29 #include "edl.h"
30 #include "edlsession.h"
31 #include "file.h"
32 #include "filexml.h"
33 #include "keys.h"
34 #include "language.h"
35 #include "localsession.h"
36 #include "mainerror.h"
37 #include "mainsession.h"
38 #include "mwindow.h"
39 #include "mwindowgui.h"
40 #include "plugindialog.h"
41 #include "resizetrackthread.h"
42 #include "track.h"
43 #include "tracks.h"
44 #include "trackcanvas.h"
45
46 #include <string.h>
47
48 EditPopup::EditPopup(MWindow *mwindow, MWindowGUI *gui)
49  : BC_PopupMenu(0, 0, 0, "", 0)
50 {
51         this->mwindow = mwindow;
52         this->gui = gui;
53
54         track = 0;
55         edit = 0;
56         plugin = 0;
57         pluginset = 0;
58         position = 0;
59         open_edl = 0;
60 }
61
62 EditPopup::~EditPopup()
63 {
64 }
65
66 void EditPopup::create_objects()
67 {
68         add_item(open_edl = new EditPopupOpenEDL(mwindow, this));
69         add_item(new EditPopupClearSelect(mwindow, this));
70         add_item(new EditPopupCopy(mwindow, this));
71         add_item(new EditPopupCut(mwindow, this));
72         add_item(new EditPopupMute(mwindow, this));
73         add_item(new EditPopupCopyPack(mwindow, this));
74         add_item(new EditPopupCutPack(mwindow, this));
75         add_item(new EditPopupMutePack(mwindow, this));
76         add_item(new EditPopupPaste(mwindow, this));
77         add_item(new EditPopupOverwrite(mwindow, this));
78         add_item(new BC_MenuItem("-"));
79         add_item(new EditPopupOverwritePlugins(mwindow, this));
80         add_item(new EditCollectEffects(mwindow, this));
81         add_item(new EditPasteEffects(mwindow, this));
82         add_item(new EditPopupTimecode(mwindow, this));
83 }
84
85 int EditPopup::activate_menu(Track *track, Edit *edit,
86                 PluginSet *pluginset, Plugin *plugin, double position)
87 {
88         this->track = track;
89         this->edit = edit;
90         this->pluginset = pluginset;
91         this->plugin = plugin;
92         this->position = position;
93         int enable = !edit ? 0 :
94                 edit->nested_edl ? 1 :
95                 !edit->asset ? 0 :
96                 edit->asset->format == FILE_REF ? 1 : 0;
97         open_edl->set_enabled(enable);
98         return BC_PopupMenu::activate_menu();
99 }
100
101 EditPopupOpenEDL::EditPopupOpenEDL(MWindow *mwindow, EditPopup *popup)
102  : BC_MenuItem(_("Open EDL"))
103 {
104         this->mwindow = mwindow;
105         this->popup = popup;
106         set_ctrl(1);
107         set_shift(1);
108 }
109
110 int EditPopupOpenEDL::handle_event()
111 {
112         Edit *edit = popup->edit;
113         if( !edit ) return 1;
114         EDL *edl = 0;
115         Indexable *idxbl = 0;
116         if( edit->asset && edit->asset->format == FILE_REF ) {
117                 FileXML xml_file;
118                 const char *filename = edit->asset->path;
119                 if( xml_file.read_from_file(filename, 1) ) {
120                         eprintf(_("Error: unable to open:\n  %s"), filename);
121                         return 1;
122                 }
123                 edl = new EDL;
124                 edl->create_objects();
125                 if( edl->load_xml(&xml_file, LOAD_ALL) ) {
126                         eprintf(_("Error: unable to load:\n  %s"), filename);
127                         edl->remove_user();
128                         return 1;
129                 }
130                 idxbl = edit->asset;
131         }
132         else if( edit->nested_edl ) {
133                 edl = edit->nested_edl;
134                 edl->add_user();
135                 idxbl = edl;
136         }
137         else {
138                 char edit_title[BCTEXTLEN];
139                 edit->get_title(edit_title);
140                 eprintf(_("Edit is not EDL: %s"), edit_title);
141                 return 1;
142         }
143         mwindow->stack_push(edl, idxbl);
144         return 1;
145 }
146
147 EditPopupClearSelect::EditPopupClearSelect(MWindow *mwindow, EditPopup *popup)
148  : BC_MenuItem(_("Clear Select"),_("Ctrl-Shift-A"),'A')
149 {
150         this->mwindow = mwindow;
151         this->popup = popup;
152         set_ctrl(1);
153         set_shift(1);
154 }
155
156 int EditPopupClearSelect::handle_event()
157 {
158         mwindow->clear_select();
159         return 1;
160 }
161
162 EditPopupCopy::EditPopupCopy(MWindow *mwindow, EditPopup *popup)
163  : BC_MenuItem(_("Copy"),_("Ctrl-c"),'c')
164 {
165         this->mwindow = mwindow;
166         this->popup = popup;
167         set_ctrl(1);
168 }
169
170 int EditPopupCopy::handle_event()
171 {
172         mwindow->selected_edits_to_clipboard(0);
173         return 1;
174 }
175
176 EditPopupCopyPack::EditPopupCopyPack(MWindow *mwindow, EditPopup *popup)
177  : BC_MenuItem(_("Copy pack"),_("Ctrl-Shift-C"),'C')
178 {
179         this->mwindow = mwindow;
180         this->popup = popup;
181         set_ctrl(1);
182         set_shift(1);
183 }
184
185 int EditPopupCopyPack::handle_event()
186 {
187         mwindow->selected_edits_to_clipboard(1);
188         return 1;
189 }
190
191 EditPopupCut::EditPopupCut(MWindow *mwindow, EditPopup *popup)
192  : BC_MenuItem(_("Cut"),_("Ctrl-x"),'x')
193 {
194         this->mwindow = mwindow;
195         this->popup = popup;
196         set_ctrl(1);
197 }
198
199 int EditPopupCut::handle_event()
200 {
201         mwindow->cut_selected_edits(1, 0);
202         return 1;
203 }
204
205 EditPopupCutPack::EditPopupCutPack(MWindow *mwindow, EditPopup *popup)
206  : BC_MenuItem(_("Cut pack"),_("Ctrl-z"),'z')
207 {
208         this->mwindow = mwindow;
209         this->popup = popup;
210         set_ctrl(1);
211 }
212
213 int EditPopupCutPack::handle_event()
214 {
215         mwindow->cut_selected_edits(1, 1);
216         return 1;
217 }
218
219 EditPopupMute::EditPopupMute(MWindow *mwindow, EditPopup *popup)
220  : BC_MenuItem(C_("Mute"),_("Ctrl-m"),'m')
221 {
222         this->mwindow = mwindow;
223         this->popup = popup;
224         set_ctrl(1);
225 }
226
227 int EditPopupMute::handle_event()
228 {
229         mwindow->cut_selected_edits(0, 0);
230         return 1;
231 }
232
233 EditPopupMutePack::EditPopupMutePack(MWindow *mwindow, EditPopup *popup)
234  : BC_MenuItem(_("Mute pack"),_("Ctrl-Shift-M"),'M')
235 {
236         this->mwindow = mwindow;
237         this->popup = popup;
238         set_ctrl(1);
239         set_shift(1);
240 }
241
242 int EditPopupMutePack::handle_event()
243 {
244         mwindow->cut_selected_edits(0, 1);
245         return 1;
246 }
247
248 EditPopupPaste::EditPopupPaste(MWindow *mwindow, EditPopup *popup)
249  : BC_MenuItem(_("Paste"),_("Ctrl-v"),'v')
250 {
251         this->mwindow = mwindow;
252         this->popup = popup;
253         set_ctrl(1);
254 }
255
256 int EditPopupPaste::handle_event()
257 {
258         mwindow->paste(popup->position, popup->track, 0, 0);
259         mwindow->edl->tracks->clear_selected_edits();
260         popup->gui->draw_overlays(1);
261         if( mwindow->session->current_operation == DROP_TARGETING ) {
262                 mwindow->session->current_operation = NO_OPERATION;
263                 popup->gui->update_cursor();
264         }
265         return 1;
266 }
267
268 EditPopupOverwrite::EditPopupOverwrite(MWindow *mwindow, EditPopup *popup)
269  : BC_MenuItem(_("Overwrite"),_("Ctrl-b"),'b')
270 {
271         this->mwindow = mwindow;
272         this->popup = popup;
273         set_ctrl(1);
274 }
275
276 int EditPopupOverwrite::handle_event()
277 {
278         mwindow->paste(popup->position, popup->track, 0, -1);
279         mwindow->edl->tracks->clear_selected_edits();
280         popup->gui->draw_overlays(1);
281         if( mwindow->session->current_operation == DROP_TARGETING ) {
282                 mwindow->session->current_operation = NO_OPERATION;
283                 popup->gui->update_cursor();
284         }
285         return 1;
286 }
287
288 EditPopupOverwritePlugins::EditPopupOverwritePlugins(MWindow *mwindow, EditPopup *popup)
289  : BC_MenuItem(_("Overwrite Plugins"),_("Ctrl-Shift-P"),'P')
290 {
291         this->mwindow = mwindow;
292         this->popup = popup;
293         set_ctrl(1);
294         set_shift(1);
295 }
296
297 int EditPopupOverwritePlugins::handle_event()
298 {
299         mwindow->paste_clipboard(popup->track, popup->position, 1, 0,
300                         mwindow->edl->session->labels_follow_edits,
301                         mwindow->edl->session->autos_follow_edits,
302                         mwindow->edl->session->plugins_follow_edits);
303         mwindow->edl->tracks->clear_selected_edits();
304         if( mwindow->session->current_operation == DROP_TARGETING ) {
305                 mwindow->session->current_operation = NO_OPERATION;
306                 popup->gui->update_cursor();
307         }
308         return 1;
309 }
310
311
312 EditCollectEffects::EditCollectEffects(MWindow *mwindow, EditPopup *popup)
313  : BC_MenuItem(_("Collect Effects"))
314 {
315         this->mwindow = mwindow;
316         this->popup = popup;
317         set_ctrl(1);
318 }
319
320 int EditCollectEffects::handle_event()
321 {
322         if( mwindow->session->current_operation == NO_OPERATION )
323                 mwindow->collect_effects();
324         return 1;
325 }
326
327 EditPasteEffects::EditPasteEffects(MWindow *mwindow, EditPopup *popup)
328  : BC_MenuItem(_("Paste Effects"))
329 {
330         this->mwindow = mwindow;
331         this->popup = popup;
332         set_ctrl(1);
333         set_shift(1);
334 }
335
336 int EditPasteEffects::handle_event()
337 {
338         if( mwindow->session->current_operation == NO_OPERATION )
339                 mwindow->paste_effects();
340         return 1;
341 }
342
343 EditPopupTimecode::EditPopupTimecode(MWindow *mwindow, EditPopup *popup)
344  : BC_MenuItem(_("Timecode"),_("Ctrl-!"),'!')
345 {
346         this->mwindow = mwindow;
347         this->popup = popup;
348         set_ctrl(1);
349 }
350
351 int EditPopupTimecode::handle_event()
352 {
353         if( mwindow->session->current_operation != NO_OPERATION ) return 1;
354         Edit *edit = popup->edit;
355         if( !edit || !edit->asset ) return 1;
356         Asset *asset = edit->asset;
357         double timecode = asset->timecode != -2 ? asset->timecode :
358                 FFMPEG::get_timecode(asset->path,
359                         edit->track->data_type, edit->channel,
360                         mwindow->edl->session->frame_rate);
361         asset->timecode = timecode;
362         if( timecode >= 0 ) {
363                 int64_t pos = edit->startproject + edit->startsource;
364                 double position = edit->track->from_units(pos);
365                 mwindow->set_timecode_offset(timecode - position);
366         }
367         else
368                 mwindow->set_timecode_offset(0);
369         return 1;
370 }
371