fix awdw solo vicon crash, fix nested clip for binfolders, open edit edl
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / clippopup.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 1997-2012 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 "assetedit.h"
23 #include "clippopup.h"
24 #include "assetremove.h"
25 #include "awindow.h"
26 #include "awindowgui.h"
27 #include "bcsignals.h"
28 #include "clipedit.h"
29 #include "clipedls.h"
30 #include "cwindow.h"
31 #include "cwindowgui.h"
32 #include "edit.h"
33 #include "edits.h"
34 #include "edl.h"
35 #include "edlsession.h"
36 #include "filexml.h"
37 #include "language.h"
38 #include "localsession.h"
39 #include "mainerror.h"
40 #include "mainindexes.h"
41 #include "mainsession.h"
42 #include "mwindow.h"
43 #include "mwindowgui.h"
44 #include "track.h"
45 #include "tracks.h"
46 #include "vwindow.h"
47 #include "vwindowgui.h"
48
49
50
51 ClipPopup::ClipPopup(MWindow *mwindow, AWindowGUI *gui)
52  : BC_PopupMenu(0, 0, 0, "", 0)
53 {
54         this->mwindow = mwindow;
55         this->gui = gui;
56 }
57
58 ClipPopup::~ClipPopup()
59 {
60 }
61
62 void ClipPopup::create_objects()
63 {
64         BC_MenuItem *menu_item;
65         BC_SubMenu *submenu;
66         add_item(info = new ClipPopupInfo(mwindow, this));
67         add_item(format = new AWindowListFormat(mwindow, gui));
68         add_item(sort = new ClipPopupSort(mwindow, this));
69         add_item(open_edl = new ClipPopupOpenEDL(mwindow, this));
70         add_item(close_edl = new ClipPopupCloseEDL(mwindow, gui));
71         add_item(to_media = new ClipPopupToMedia(mwindow, this));
72         add_item(view = new ClipPopupView(mwindow, this));
73         add_item(view_window = new ClipPopupViewWindow(mwindow, this));
74         add_item(copy = new ClipPopupCopy(mwindow, this));
75         add_item(paste = new ClipPopupPaste(mwindow, this));
76         add_item(menu_item = new BC_MenuItem(_("Match...")));
77         menu_item->add_submenu(submenu = new BC_SubMenu());
78         submenu->add_submenuitem(new ClipMatchSize(mwindow, this));
79         submenu->add_submenuitem(new ClipMatchRate(mwindow, this));
80         submenu->add_submenuitem(new ClipMatchAll(mwindow, this));
81         add_item(new ClipPopupDelete(mwindow, this));
82 }
83
84 void ClipPopup::paste_assets()
85 {
86 // Collect items into the drag vectors for temporary storage
87         gui->lock_window("ClipPopup::paste_assets");
88         mwindow->gui->lock_window("ClipPopup::paste_assets");
89         mwindow->cwindow->gui->lock_window("ClipPopup::paste_assets");
90
91         gui->collect_assets();
92         mwindow->paste_assets(mwindow->edl->local_session->get_selectionstart(1),
93                 mwindow->edl->tracks->first,
94                 0);   // do not overwrite
95
96         gui->unlock_window();
97         mwindow->gui->unlock_window();
98         mwindow->cwindow->gui->unlock_window();
99 }
100
101 void ClipPopup::match_size()
102 {
103 // Collect items into the drag vectors for temporary storage
104         gui->collect_assets();
105         mwindow->gui->lock_window("ClipPopup::match_size");
106         mwindow->asset_to_size();
107         mwindow->gui->unlock_window();
108 }
109
110 void ClipPopup::match_rate()
111 {
112 // Collect items into the drag vectors for temporary storage
113         gui->collect_assets();
114         mwindow->gui->lock_window("ClipPopup::match_rate");
115         mwindow->asset_to_rate();
116         mwindow->gui->unlock_window();
117 }
118
119 void ClipPopup::match_all()
120 {
121 // Collect items into the drag vectors for temporary storage
122         gui->collect_assets();
123         mwindow->gui->lock_window("ClipPopup::match_rate");
124         mwindow->asset_to_all();
125         mwindow->gui->unlock_window();
126 }
127
128 int ClipPopup::update()
129 {
130         format->update();
131         gui->collect_assets();
132         EDL *clip = !mwindow->session->drag_clips->size() ? 0 :
133                 mwindow->session->drag_clips->get(0);
134         int enable_open = clip ? 1 : 0;
135         open_edl->set_enabled(enable_open);
136         int enable_close = mwindow->stack.size() > 0 ? 1 : 0;
137         close_edl->set_enabled(enable_close);
138         return 0;
139 }
140
141
142 ClipPopupInfo::ClipPopupInfo(MWindow *mwindow, ClipPopup *popup)
143  : BC_MenuItem(_("Info..."))
144 {
145         this->mwindow = mwindow;
146         this->popup = popup;
147 }
148
149 ClipPopupInfo::~ClipPopupInfo()
150 {
151 }
152
153 int ClipPopupInfo::handle_event()
154 {
155         int cur_x, cur_y;
156         popup->gui->get_abs_cursor(cur_x, cur_y, 0);
157
158         if( mwindow->session->drag_assets->total ) {
159                 AssetEdit *asset_edit = mwindow->awindow->get_asset_editor();
160                 asset_edit->edit_asset(
161                         mwindow->session->drag_assets->values[0], cur_x, cur_y);
162         }
163         else
164         if( mwindow->session->drag_clips->total ) {
165                 popup->gui->awindow->clip_edit->edit_clip(
166                         mwindow->session->drag_clips->values[0], cur_x, cur_y);
167         }
168         return 1;
169 }
170
171
172 ClipPopupSort::ClipPopupSort(MWindow *mwindow, ClipPopup *popup)
173  : BC_MenuItem(_("Sort items"))
174 {
175         this->mwindow = mwindow;
176         this->popup = popup;
177 }
178
179 ClipPopupSort::~ClipPopupSort()
180 {
181 }
182
183 int ClipPopupSort::handle_event()
184 {
185         mwindow->awindow->gui->sort_assets();
186         return 1;
187 }
188
189
190 ClipPopupView::ClipPopupView(MWindow *mwindow, ClipPopup *popup)
191  : BC_MenuItem(_("View"))
192 {
193         this->mwindow = mwindow;
194         this->popup = popup;
195 }
196
197 ClipPopupView::~ClipPopupView()
198 {
199 }
200
201 int ClipPopupView::handle_event()
202 {
203         VWindow *vwindow = mwindow->get_viewer(1, DEFAULT_VWINDOW);
204
205         if( mwindow->session->drag_assets->total )
206                 vwindow->change_source(
207                         mwindow->session->drag_assets->values[0]);
208         else
209         if( mwindow->session->drag_clips->total )
210                 vwindow->change_source(
211                         mwindow->session->drag_clips->values[0]);
212
213         return 1;
214 }
215
216
217 ClipPopupViewWindow::ClipPopupViewWindow(MWindow *mwindow, ClipPopup *popup)
218  : BC_MenuItem(_("View in new window"))
219 {
220         this->mwindow = mwindow;
221         this->popup = popup;
222 }
223
224 ClipPopupViewWindow::~ClipPopupViewWindow()
225 {
226 }
227
228 int ClipPopupViewWindow::handle_event()
229 {
230         for( int i=0; i<mwindow->session->drag_assets->size(); ++i ) {
231                 VWindow *vwindow = mwindow->get_viewer(1);
232                 vwindow->gui->lock_window("ClipPopupView::handle_event 1");
233                 vwindow->change_source(mwindow->session->drag_assets->get(i));
234                 vwindow->gui->unlock_window();
235         }
236         for( int i=0; i<mwindow->session->drag_clips->size(); ++i ) {
237                 VWindow *vwindow = mwindow->get_viewer(1);
238                 vwindow->gui->lock_window("ClipPopupView::handle_event 2");
239                 vwindow->change_source(mwindow->session->drag_clips->get(i));
240                 vwindow->gui->unlock_window();
241         }
242         return 1;
243 }
244
245
246 ClipPopupCopy::ClipPopupCopy(MWindow *mwindow, ClipPopup *popup)
247  : BC_MenuItem(_("Copy"))
248 {
249         this->mwindow = mwindow;
250         this->popup = popup;
251 }
252 ClipPopupCopy::~ClipPopupCopy()
253 {
254 }
255
256 int ClipPopupCopy::handle_event()
257 {
258         MWindowGUI *gui = mwindow->gui;
259         gui->lock_window("ClipPopupCopy::handle_event");
260         if( mwindow->session->drag_clips->total > 0 ) {
261                 EDL *edl = mwindow->session->drag_clips->values[0];
262                 EDL *copy_edl = new EDL; // no parent or assets wont be copied
263                 copy_edl->create_objects();
264                 copy_edl->copy_all(edl);
265                 FileXML file;
266                 double start = 0, end = edl->tracks->total_length();
267                 copy_edl->copy(COPY_EDL, start, end, &file, "", 1);
268                 copy_edl->remove_user();
269                 const char *file_string = file.string();
270                 long file_length = strlen(file_string);
271                 gui->to_clipboard(file_string, file_length, SECONDARY_SELECTION);
272                 gui->to_clipboard(file_string, file_length, BC_PRIMARY_SELECTION);
273         }
274         gui->unlock_window(); 
275         return 1;
276 }
277
278
279 ClipPopupPaste::ClipPopupPaste(MWindow *mwindow, ClipPopup *popup)
280  : BC_MenuItem(_("Paste"))
281 {
282         this->mwindow = mwindow;
283         this->popup = popup;
284 }
285
286 ClipPopupPaste::~ClipPopupPaste()
287 {
288 }
289
290 int ClipPopupPaste::handle_event()
291 {
292         popup->paste_assets();
293         return 1;
294 }
295
296
297 ClipMatchSize::ClipMatchSize(MWindow *mwindow, ClipPopup *popup)
298  : BC_MenuItem(_("Match project size"))
299 {
300         this->mwindow = mwindow;
301         this->popup = popup;
302 }
303
304 int ClipMatchSize::handle_event()
305 {
306         popup->match_size();
307         return 1;
308 }
309
310
311 ClipMatchRate::ClipMatchRate(MWindow *mwindow, ClipPopup *popup)
312  : BC_MenuItem(_("Match frame rate"))
313 {
314         this->mwindow = mwindow;
315         this->popup = popup;
316 }
317
318 int ClipMatchRate::handle_event()
319 {
320         popup->match_rate();
321         return 1;
322 }
323
324
325 ClipMatchAll::ClipMatchAll(MWindow *mwindow, ClipPopup *popup)
326  : BC_MenuItem(_("Match all"))
327 {
328         this->mwindow = mwindow;
329         this->popup = popup;
330 }
331
332 int ClipMatchAll::handle_event()
333 {
334         popup->match_all();
335         return 1;
336 }
337
338
339 ClipPopupDelete::ClipPopupDelete(MWindow *mwindow, ClipPopup *popup)
340  : BC_MenuItem(_("Delete"))
341 {
342         this->mwindow = mwindow;
343         this->popup = popup;
344 }
345
346
347 ClipPopupDelete::~ClipPopupDelete()
348 {
349 }
350
351 int ClipPopupDelete::handle_event()
352 {
353         popup->gui->unlock_window();
354         mwindow->remove_assets_from_project(1, 1, 0, 0,
355                 mwindow->session->drag_clips);
356         popup->gui->lock_window("ClipPopupDelete::handle_event");
357         return 1;
358 }
359
360
361 ClipPasteToFolder::ClipPasteToFolder(MWindow *mwindow)
362  : BC_MenuItem(_("Paste Clip"))
363 {
364         this->mwindow = mwindow;
365 }
366
367 int ClipPasteToFolder::handle_event()
368 {
369         MWindowGUI *gui = mwindow->gui;
370         gui->lock_window("ClipPasteToFolder::handle_event 1");
371         int64_t len = gui->clipboard_len(BC_PRIMARY_SELECTION);
372         if( len ) {
373                 char *string = new char[len];
374                 gui->from_clipboard(string, len, BC_PRIMARY_SELECTION);
375                 const char *clip_header = "<EDL VERSION=";
376                 if( !strncmp(clip_header, string, strlen(clip_header)) ) {
377                         FileXML file;
378                         file.read_from_string(string);
379                         EDL *edl = mwindow->edl;
380                         EDL *new_edl = new EDL(mwindow->edl);
381                         new_edl->create_objects();
382                         new_edl->load_xml(&file, LOAD_ALL);
383                         edl->update_assets(new_edl);
384                         mwindow->save_clip(new_edl, _("paste clip: "));
385                 }
386                 else {
387                         char *cp = strchr(string, '\n');
388                         if( cp && cp-string < 32 ) *cp = 0;
389                         else if( len > 32 ) string[32] = 0;
390                         eprintf("paste buffer is not EDL:\n%s", string);
391                 }
392                 delete [] string;
393         }
394         else {
395                 eprintf("paste buffer empty");
396         }
397         gui->unlock_window();
398         return 1;
399 }
400
401
402 ClipListMenu::ClipListMenu(MWindow *mwindow, AWindowGUI *gui)
403  : BC_PopupMenu(0, 0, 0, "", 0)
404 {
405         this->mwindow = mwindow;
406         this->gui = gui;
407 }
408
409 ClipListMenu::~ClipListMenu()
410 {
411 }
412
413 void ClipListMenu::create_objects()
414 {
415         add_item(format = new AWindowListFormat(mwindow, gui));
416         add_item(close_edl = new ClipPopupCloseEDL(mwindow, gui));
417         add_item(new AWindowListSort(mwindow, gui));
418         add_item(new ClipPasteToFolder(mwindow));
419         update();
420 }
421
422 void ClipListMenu::update()
423 {
424         format->update();
425         int enable_close = mwindow->stack.size() > 0 ? 1 : 0;
426         close_edl->set_enabled(enable_close);
427 }
428
429
430 ClipPopupToMedia::ClipPopupToMedia(MWindow *mwindow, ClipPopup *popup)
431  : BC_MenuItem(_("Nest to Media"))
432 {
433         this->mwindow = mwindow;
434         this->popup = popup;
435 }
436 ClipPopupToMedia::~ClipPopupToMedia()
437 {
438 }
439
440 int ClipPopupToMedia::handle_event()
441 {
442         if( mwindow->edl->session->proxy_scale == 1 )
443                 mwindow->clip_to_media();
444         else
445                 eprintf("Nesting not allowed when proxy scale != 1");
446         return 1;
447 }
448
449
450 ClipPopupOpenEDL::ClipPopupOpenEDL(MWindow *mwindow, ClipPopup *popup)
451  : BC_MenuItem(_("Open EDL"))
452 {
453         this->mwindow = mwindow;
454         this->popup = popup;
455 }
456
457 ClipPopupOpenEDL::~ClipPopupOpenEDL()
458 {
459 }
460
461 int ClipPopupOpenEDL::handle_event()
462 {
463         int clips_total = mwindow->session->drag_clips->total;
464         if( clips_total ) {
465                 popup->unlock_window();
466                 EDL *clip = mwindow->session->drag_clips->values[0];
467                 mwindow->stack_push(clip, 0);
468                 popup->lock_window("ClipPopupOpenEDL::handle_event");
469         }
470         return 1;
471 }
472
473 ClipPopupCloseEDL::ClipPopupCloseEDL(MWindow *mwindow, AWindowGUI *gui)
474  : BC_MenuItem(_("Close EDL"))
475 {
476         this->mwindow = mwindow;
477         this->gui = gui;
478 }
479 ClipPopupCloseEDL::~ClipPopupCloseEDL()
480 {
481 }
482
483 int ClipPopupCloseEDL::handle_event()
484 {
485         gui->unlock_window();
486         mwindow->gui->lock_window("ClipPopupCloseEDL::handle_event");
487         mwindow->stack_pop();
488         mwindow->gui->unlock_window();
489         gui->lock_window("ClipPopupCloseEDL::handle_event");
490         return 1;
491 }
492