4 * Copyright (C) 1997-2012 Adam Williams <broadcast at earthling dot net>
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.
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.
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
22 #include "assetedit.h"
23 #include "clippopup.h"
24 #include "assetremove.h"
26 #include "awindowgui.h"
27 #include "bcsignals.h"
31 #include "cwindowgui.h"
35 #include "edlsession.h"
38 #include "localsession.h"
39 #include "mainerror.h"
40 #include "mainindexes.h"
41 #include "mainsession.h"
43 #include "mwindowgui.h"
47 #include "vwindowgui.h"
51 ClipPopup::ClipPopup(MWindow *mwindow, AWindowGUI *gui)
52 : BC_PopupMenu(0, 0, 0, "", 0)
54 this->mwindow = mwindow;
58 ClipPopup::~ClipPopup()
62 void ClipPopup::create_objects()
64 BC_MenuItem *menu_item;
66 add_item(info = new ClipPopupInfo(mwindow, this));
67 add_item(format = new AWindowListFormat(mwindow, gui));
68 add_item(new ClipPopupSort(mwindow, this));
69 add_item(view = new ClipPopupView(mwindow, this));
70 add_item(view_window = new ClipPopupViewWindow(mwindow, this));
71 add_item(new ClipPopupCopy(mwindow, this));
72 add_item(new ClipPopupNest(mwindow, this));
73 add_item(new ClipPopupUnNest(mwindow, this));
74 add_item(new ClipPopupPaste(mwindow, this));
75 add_item(menu_item = new BC_MenuItem(_("Match...")));
76 menu_item->add_submenu(submenu = new BC_SubMenu());
77 submenu->add_submenuitem(new ClipMatchSize(mwindow, this));
78 submenu->add_submenuitem(new ClipMatchRate(mwindow, this));
79 submenu->add_submenuitem(new ClipMatchAll(mwindow, this));
80 add_item(new ClipPopupDelete(mwindow, this));
83 void ClipPopup::paste_assets()
85 // Collect items into the drag vectors for temporary storage
86 gui->lock_window("ClipPopup::paste_assets");
87 mwindow->gui->lock_window("ClipPopup::paste_assets");
88 mwindow->cwindow->gui->lock_window("ClipPopup::paste_assets");
90 gui->collect_assets();
91 mwindow->paste_assets(mwindow->edl->local_session->get_selectionstart(1),
92 mwindow->edl->tracks->first,
93 0); // do not overwrite
96 mwindow->gui->unlock_window();
97 mwindow->cwindow->gui->unlock_window();
100 void ClipPopup::match_size()
102 // Collect items into the drag vectors for temporary storage
103 gui->collect_assets();
104 mwindow->gui->lock_window("ClipPopup::match_size");
105 mwindow->asset_to_size();
106 mwindow->gui->unlock_window();
109 void ClipPopup::match_rate()
111 // Collect items into the drag vectors for temporary storage
112 gui->collect_assets();
113 mwindow->gui->lock_window("ClipPopup::match_rate");
114 mwindow->asset_to_rate();
115 mwindow->gui->unlock_window();
118 void ClipPopup::match_all()
120 // Collect items into the drag vectors for temporary storage
121 gui->collect_assets();
122 mwindow->gui->lock_window("ClipPopup::match_rate");
123 mwindow->asset_to_all();
124 mwindow->gui->unlock_window();
127 int ClipPopup::update()
130 gui->collect_assets();
135 ClipPopupInfo::ClipPopupInfo(MWindow *mwindow, ClipPopup *popup)
136 : BC_MenuItem(_("Info..."))
138 this->mwindow = mwindow;
142 ClipPopupInfo::~ClipPopupInfo()
146 int ClipPopupInfo::handle_event()
149 popup->gui->get_abs_cursor(cur_x, cur_y, 0);
151 if( mwindow->session->drag_assets->total ) {
152 AssetEdit *asset_edit = mwindow->awindow->get_asset_editor();
153 asset_edit->edit_asset(
154 mwindow->session->drag_assets->values[0], cur_x, cur_y);
157 if( mwindow->session->drag_clips->total ) {
158 popup->gui->awindow->clip_edit->edit_clip(
159 mwindow->session->drag_clips->values[0], cur_x, cur_y);
165 ClipPopupSort::ClipPopupSort(MWindow *mwindow, ClipPopup *popup)
166 : BC_MenuItem(_("Sort items"))
168 this->mwindow = mwindow;
172 ClipPopupSort::~ClipPopupSort()
176 int ClipPopupSort::handle_event()
178 mwindow->awindow->gui->sort_assets();
183 ClipPopupView::ClipPopupView(MWindow *mwindow, ClipPopup *popup)
184 : BC_MenuItem(_("View"))
186 this->mwindow = mwindow;
190 ClipPopupView::~ClipPopupView()
194 int ClipPopupView::handle_event()
196 VWindow *vwindow = mwindow->get_viewer(1, DEFAULT_VWINDOW);
198 if( mwindow->session->drag_assets->total )
199 vwindow->change_source(
200 mwindow->session->drag_assets->values[0]);
202 if( mwindow->session->drag_clips->total )
203 vwindow->change_source(
204 mwindow->session->drag_clips->values[0]);
210 ClipPopupViewWindow::ClipPopupViewWindow(MWindow *mwindow, ClipPopup *popup)
211 : BC_MenuItem(_("View in new window"))
213 this->mwindow = mwindow;
217 ClipPopupViewWindow::~ClipPopupViewWindow()
221 int ClipPopupViewWindow::handle_event()
223 for( int i=0; i<mwindow->session->drag_assets->size(); ++i ) {
224 VWindow *vwindow = mwindow->get_viewer(1);
225 vwindow->gui->lock_window("ClipPopupView::handle_event 1");
226 vwindow->change_source(mwindow->session->drag_assets->get(i));
227 vwindow->gui->unlock_window();
229 for( int i=0; i<mwindow->session->drag_clips->size(); ++i ) {
230 VWindow *vwindow = mwindow->get_viewer(1);
231 vwindow->gui->lock_window("ClipPopupView::handle_event 2");
232 vwindow->change_source(mwindow->session->drag_clips->get(i));
233 vwindow->gui->unlock_window();
239 ClipPopupCopy::ClipPopupCopy(MWindow *mwindow, ClipPopup *popup)
240 : BC_MenuItem(_("Copy"))
242 this->mwindow = mwindow;
245 ClipPopupCopy::~ClipPopupCopy()
249 int ClipPopupCopy::handle_event()
251 MWindowGUI *gui = mwindow->gui;
252 gui->lock_window("ClipPopupCopy::handle_event");
253 if( mwindow->session->drag_clips->total > 0 ) {
254 EDL *edl = mwindow->session->drag_clips->values[0];
255 EDL *copy_edl = new EDL; // no parent or assets wont be copied
256 copy_edl->create_objects();
257 copy_edl->copy_all(edl);
259 double start = 0, end = edl->tracks->total_length();
260 copy_edl->copy(start, end, 1, &file, "", 1);
261 copy_edl->remove_user();
262 const char *file_string = file.string();
263 long file_length = strlen(file_string);
264 gui->to_clipboard(file_string, file_length, SECONDARY_SELECTION);
265 gui->to_clipboard(file_string, file_length, BC_PRIMARY_SELECTION);
267 gui->unlock_window();
272 ClipPopupPaste::ClipPopupPaste(MWindow *mwindow, ClipPopup *popup)
273 : BC_MenuItem(_("Paste"))
275 this->mwindow = mwindow;
279 ClipPopupPaste::~ClipPopupPaste()
283 int ClipPopupPaste::handle_event()
285 popup->paste_assets();
290 ClipMatchSize::ClipMatchSize(MWindow *mwindow, ClipPopup *popup)
291 : BC_MenuItem(_("Match project size"))
293 this->mwindow = mwindow;
297 int ClipMatchSize::handle_event()
304 ClipMatchRate::ClipMatchRate(MWindow *mwindow, ClipPopup *popup)
305 : BC_MenuItem(_("Match frame rate"))
307 this->mwindow = mwindow;
311 int ClipMatchRate::handle_event()
318 ClipMatchAll::ClipMatchAll(MWindow *mwindow, ClipPopup *popup)
319 : BC_MenuItem(_("Match all"))
321 this->mwindow = mwindow;
325 int ClipMatchAll::handle_event()
332 ClipPopupDelete::ClipPopupDelete(MWindow *mwindow, ClipPopup *popup)
333 : BC_MenuItem(_("Delete"))
335 this->mwindow = mwindow;
340 ClipPopupDelete::~ClipPopupDelete()
344 int ClipPopupDelete::handle_event()
346 mwindow->remove_assets_from_project(1, 1,
347 mwindow->session->drag_assets,
348 mwindow->session->drag_clips);
353 ClipPasteToFolder::ClipPasteToFolder(MWindow *mwindow)
354 : BC_MenuItem(_("Paste Clip"))
356 this->mwindow = mwindow;
359 int ClipPasteToFolder::handle_event()
361 MWindowGUI *gui = mwindow->gui;
362 gui->lock_window("ClipPasteToFolder::handle_event 1");
363 int64_t len = gui->clipboard_len(BC_PRIMARY_SELECTION);
365 char *string = new char[len];
366 gui->from_clipboard(string, len, BC_PRIMARY_SELECTION);
367 const char *clip_header = "<EDL VERSION=";
368 if( !strncmp(clip_header, string, strlen(clip_header)) ) {
370 file.read_from_string(string);
371 EDL *edl = mwindow->edl;
372 EDL *new_edl = new EDL(mwindow->edl);
373 new_edl->create_objects();
374 new_edl->load_xml(&file, LOAD_ALL);
375 edl->update_assets(new_edl);
376 mwindow->save_clip(new_edl, _("paste clip: "));
379 char *cp = strchr(string, '\n');
380 if( cp-string < 32 ) *cp = 0;
381 else if( len > 32 ) string[32] = 0;
382 eprintf("paste buffer is not EDL:\n%s", string);
387 eprintf("paste buffer empty");
389 gui->unlock_window();
394 ClipListMenu::ClipListMenu(MWindow *mwindow, AWindowGUI *gui)
395 : BC_PopupMenu(0, 0, 0, "", 0)
397 this->mwindow = mwindow;
401 ClipListMenu::~ClipListMenu()
405 void ClipListMenu::create_objects()
407 add_item(format = new AWindowListFormat(mwindow, gui));
408 add_item(new AWindowListSort(mwindow, gui));
409 add_item(new ClipPasteToFolder(mwindow));
413 void ClipListMenu::update()
419 ClipPopupNest::ClipPopupNest(MWindow *mwindow, ClipPopup *popup)
420 : BC_MenuItem(_("Nest"))
422 this->mwindow = mwindow;
425 ClipPopupNest::~ClipPopupNest()
429 int ClipPopupNest::handle_event()
431 MWindowGUI *gui = mwindow->gui;
432 gui->lock_window("ClipPopupNest::handle_event 1");
433 if( mwindow->edl->session->proxy_scale != 1 ) {
434 eprintf("Nesting not allowed when proxy scale != 1");
436 else if( mwindow->session->drag_clips->total > 0 ) {
437 EDL *edl = mwindow->edl;
438 time_t dt; time(&dt);
439 struct tm dtm; localtime_r(&dt, &dtm);
441 sprintf(path, _("Nested_%02d%02d%02d-%02d%02d%02d"),
442 dtm.tm_year+1900, dtm.tm_mon+1, dtm.tm_mday,
443 dtm.tm_hour, dtm.tm_min, dtm.tm_sec);
444 EDL *clip = mwindow->session->drag_clips->values[0];
445 EDL *nested = edl->new_nested(clip, path);
446 EDL *new_clip = edl->create_nested_clip(nested);
447 new_clip->folder_no = AW_CLIP_FOLDER;
448 sprintf(new_clip->local_session->clip_icon,
449 "clip_%02d%02d%02d-%02d%02d%02d.png",
450 dtm.tm_year+1900, dtm.tm_mon+1, dtm.tm_mday,
451 dtm.tm_hour, dtm.tm_min, dtm.tm_sec);
452 snprintf(new_clip->local_session->clip_title,
453 sizeof(new_clip->local_session->clip_title),
454 _("Nested: %s"), clip->local_session->clip_title);
455 strcpy(new_clip->local_session->clip_notes,
456 clip->local_session->clip_notes);
457 int idx = edl->clips.number_of(clip);
459 edl->clips[idx] = new_clip;
463 edl->clips.append(new_clip);
464 mwindow->mainindexes->add_next_asset(0, nested);
465 mwindow->mainindexes->start_build();
466 popup->gui->async_update_assets();
468 gui->unlock_window();
473 ClipPopupUnNest::ClipPopupUnNest(MWindow *mwindow, ClipPopup *popup)
474 : BC_MenuItem(_("UnNest"))
476 this->mwindow = mwindow;
479 ClipPopupUnNest::~ClipPopupUnNest()
483 int ClipPopupUnNest::handle_event()
486 MWindowGUI *gui = mwindow->gui;
487 gui->lock_window("ClipPopupUnNest::handle_event 1");
488 if( mwindow->session->drag_clips->total > 0 ) {
489 EDL *clip = mwindow->session->drag_clips->values[0];
490 Track *track = clip->tracks->first;
491 Edit *edit = track ? track->edits->first : 0;
492 nested_edl = edit && !edit->next && !edit->asset ? edit->nested_edl : 0;
493 while( nested_edl && (track=track->next)!=0 ) {
494 Edit *edit = track->edits->first;
495 if( !edit || edit->next ||
496 ( edit->nested_edl != nested_edl &&
497 strcmp(edit->nested_edl->path, nested_edl->path) ) )
501 EDL *edl = mwindow->edl;
502 EDL *new_clip = new EDL(edl);
503 new_clip->create_objects();
504 new_clip->copy_all(nested_edl);
505 new_clip->folder_no = AW_CLIP_FOLDER;
506 int idx = edl->clips.number_of(clip);
508 edl->clips[idx] = new_clip;
512 edl->clips.append(new_clip);
513 popup->gui->async_update_assets();
516 gui->unlock_window();