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"
37 #include "localsession.h"
38 #include "mainerror.h"
39 #include "mainindexes.h"
40 #include "mainsession.h"
42 #include "mwindowgui.h"
46 #include "vwindowgui.h"
50 ClipPopup::ClipPopup(MWindow *mwindow, AWindowGUI *gui)
51 : BC_PopupMenu(0, 0, 0, "", 0)
53 this->mwindow = mwindow;
57 ClipPopup::~ClipPopup()
61 void ClipPopup::create_objects()
63 BC_MenuItem *menu_item;
65 add_item(info = new ClipPopupInfo(mwindow, this));
66 add_item(format = new AWindowListFormat(mwindow, gui));
67 add_item(new ClipPopupSort(mwindow, this));
68 add_item(view = new ClipPopupView(mwindow, this));
69 add_item(view_window = new ClipPopupViewWindow(mwindow, this));
70 add_item(new ClipPopupCopy(mwindow, this));
71 add_item(new ClipPopupNest(mwindow, this));
72 add_item(new ClipPopupUnNest(mwindow, this));
73 add_item(new ClipPopupPaste(mwindow, this));
74 add_item(menu_item = new BC_MenuItem(_("Match...")));
75 menu_item->add_submenu(submenu = new BC_SubMenu());
76 submenu->add_submenuitem(new ClipMatchSize(mwindow, this));
77 submenu->add_submenuitem(new ClipMatchRate(mwindow, this));
78 submenu->add_submenuitem(new ClipMatchAll(mwindow, this));
79 add_item(new ClipPopupDelete(mwindow, this));
82 void ClipPopup::paste_assets()
84 // Collect items into the drag vectors for temporary storage
85 gui->lock_window("ClipPopup::paste_assets");
86 mwindow->gui->lock_window("ClipPopup::paste_assets");
87 mwindow->cwindow->gui->lock_window("ClipPopup::paste_assets");
89 gui->collect_assets();
90 mwindow->paste_assets(mwindow->edl->local_session->get_selectionstart(1),
91 mwindow->edl->tracks->first,
92 0); // do not overwrite
95 mwindow->gui->unlock_window();
96 mwindow->cwindow->gui->unlock_window();
99 void ClipPopup::match_size()
101 // Collect items into the drag vectors for temporary storage
102 gui->collect_assets();
103 mwindow->gui->lock_window("ClipPopup::match_size");
104 mwindow->asset_to_size();
105 mwindow->gui->unlock_window();
108 void ClipPopup::match_rate()
110 // Collect items into the drag vectors for temporary storage
111 gui->collect_assets();
112 mwindow->gui->lock_window("ClipPopup::match_rate");
113 mwindow->asset_to_rate();
114 mwindow->gui->unlock_window();
117 void ClipPopup::match_all()
119 // Collect items into the drag vectors for temporary storage
120 gui->collect_assets();
121 mwindow->gui->lock_window("ClipPopup::match_rate");
122 mwindow->asset_to_all();
123 mwindow->gui->unlock_window();
126 int ClipPopup::update()
129 gui->collect_assets();
134 ClipPopupInfo::ClipPopupInfo(MWindow *mwindow, ClipPopup *popup)
135 : BC_MenuItem(_("Info..."))
137 this->mwindow = mwindow;
141 ClipPopupInfo::~ClipPopupInfo()
145 int ClipPopupInfo::handle_event()
148 popup->gui->get_abs_cursor(cur_x, cur_y, 0);
150 if( mwindow->session->drag_assets->total ) {
151 AssetEdit *asset_edit = mwindow->awindow->get_asset_editor();
152 asset_edit->edit_asset(
153 mwindow->session->drag_assets->values[0], cur_x, cur_y);
156 if( mwindow->session->drag_clips->total ) {
157 popup->gui->awindow->clip_edit->edit_clip(
158 mwindow->session->drag_clips->values[0], cur_x, cur_y);
164 ClipPopupSort::ClipPopupSort(MWindow *mwindow, ClipPopup *popup)
165 : BC_MenuItem(_("Sort items"))
167 this->mwindow = mwindow;
171 ClipPopupSort::~ClipPopupSort()
175 int ClipPopupSort::handle_event()
177 mwindow->awindow->gui->sort_assets(0);
182 ClipPopupView::ClipPopupView(MWindow *mwindow, ClipPopup *popup)
183 : BC_MenuItem(_("View"))
185 this->mwindow = mwindow;
189 ClipPopupView::~ClipPopupView()
193 int ClipPopupView::handle_event()
195 VWindow *vwindow = mwindow->get_viewer(1, DEFAULT_VWINDOW);
197 if( mwindow->session->drag_assets->total )
198 vwindow->change_source(
199 mwindow->session->drag_assets->values[0]);
201 if( mwindow->session->drag_clips->total )
202 vwindow->change_source(
203 mwindow->session->drag_clips->values[0]);
209 ClipPopupViewWindow::ClipPopupViewWindow(MWindow *mwindow, ClipPopup *popup)
210 : BC_MenuItem(_("View in new window"))
212 this->mwindow = mwindow;
216 ClipPopupViewWindow::~ClipPopupViewWindow()
220 int ClipPopupViewWindow::handle_event()
222 // Find window with nothing
223 VWindow *vwindow = mwindow->get_viewer(1);
225 // TODO: create new vwindow or change current vwindow
226 vwindow->gui->lock_window("ClipPopupView::handle_event");
228 if( mwindow->session->drag_assets->total )
229 vwindow->change_source(
230 mwindow->session->drag_assets->values[0]);
232 if( mwindow->session->drag_clips->total )
233 vwindow->change_source(
234 mwindow->session->drag_clips->values[0]);
236 vwindow->gui->unlock_window();
241 ClipPopupCopy::ClipPopupCopy(MWindow *mwindow, ClipPopup *popup)
242 : BC_MenuItem(_("Copy"))
244 this->mwindow = mwindow;
247 ClipPopupCopy::~ClipPopupCopy()
251 int ClipPopupCopy::handle_event()
253 MWindowGUI *gui = mwindow->gui;
254 gui->lock_window("ClipPopupCopy::handle_event");
255 if( mwindow->session->drag_clips->total > 0 ) {
256 EDL *edl = mwindow->session->drag_clips->values[0];
257 EDL *copy_edl = new EDL; // no parent or assets wont be copied
258 copy_edl->create_objects();
259 copy_edl->copy_all(edl);
261 double start = 0, end = edl->tracks->total_length();
262 copy_edl->copy(start, end, 1, &file, "", 1);
263 copy_edl->remove_user();
264 const char *file_string = file.string();
265 long file_length = strlen(file_string);
266 gui->to_clipboard(file_string, file_length, SECONDARY_SELECTION);
267 gui->to_clipboard(file_string, file_length, BC_PRIMARY_SELECTION);
269 gui->unlock_window();
274 ClipPopupPaste::ClipPopupPaste(MWindow *mwindow, ClipPopup *popup)
275 : BC_MenuItem(_("Paste"))
277 this->mwindow = mwindow;
281 ClipPopupPaste::~ClipPopupPaste()
285 int ClipPopupPaste::handle_event()
287 popup->paste_assets();
292 ClipMatchSize::ClipMatchSize(MWindow *mwindow, ClipPopup *popup)
293 : BC_MenuItem(_("Match project size"))
295 this->mwindow = mwindow;
299 int ClipMatchSize::handle_event()
306 ClipMatchRate::ClipMatchRate(MWindow *mwindow, ClipPopup *popup)
307 : BC_MenuItem(_("Match frame rate"))
309 this->mwindow = mwindow;
313 int ClipMatchRate::handle_event()
320 ClipMatchAll::ClipMatchAll(MWindow *mwindow, ClipPopup *popup)
321 : BC_MenuItem(_("Match all"))
323 this->mwindow = mwindow;
327 int ClipMatchAll::handle_event()
334 ClipPopupDelete::ClipPopupDelete(MWindow *mwindow, ClipPopup *popup)
335 : BC_MenuItem(_("Delete"))
337 this->mwindow = mwindow;
342 ClipPopupDelete::~ClipPopupDelete()
346 int ClipPopupDelete::handle_event()
348 mwindow->remove_assets_from_project(1, 1,
349 mwindow->session->drag_assets,
350 mwindow->session->drag_clips);
355 ClipPasteToFolder::ClipPasteToFolder(MWindow *mwindow)
356 : BC_MenuItem(_("Paste Clip"))
358 this->mwindow = mwindow;
361 int ClipPasteToFolder::handle_event()
363 MWindowGUI *gui = mwindow->gui;
364 gui->lock_window("ClipPasteToFolder::handle_event 1");
365 int64_t len = gui->clipboard_len(BC_PRIMARY_SELECTION);
367 char *string = new char[len];
368 gui->from_clipboard(string, len, BC_PRIMARY_SELECTION);
369 const char *clip_header = "<EDL VERSION=";
370 if( !strncmp(clip_header, string, strlen(clip_header)) ) {
372 file.read_from_string(string);
373 EDL *edl = mwindow->edl;
374 EDL *new_edl = new EDL(mwindow->edl);
375 new_edl->create_objects();
376 new_edl->load_xml(&file, LOAD_ALL);
377 edl->update_assets(new_edl);
378 mwindow->save_clip(new_edl, _("paste clip: "));
381 char *cp = strchr(string, '\n');
382 if( cp-string < 32 ) *cp = 0;
383 else if( len > 32 ) string[32] = 0;
384 eprintf("paste buffer is not EDL:\n%s", string);
389 eprintf("paste buffer empty");
391 gui->unlock_window();
396 ClipListMenu::ClipListMenu(MWindow *mwindow, AWindowGUI *gui)
397 : BC_PopupMenu(0, 0, 0, "", 0)
399 this->mwindow = mwindow;
403 ClipListMenu::~ClipListMenu()
407 void ClipListMenu::create_objects()
409 add_item(format = new AWindowListFormat(mwindow, gui));
410 add_item(new AWindowListSort(mwindow, gui));
411 add_item(new ClipPasteToFolder(mwindow));
415 void ClipListMenu::update()
421 ClipPopupNest::ClipPopupNest(MWindow *mwindow, ClipPopup *popup)
422 : BC_MenuItem(_("Nest"))
424 this->mwindow = mwindow;
427 ClipPopupNest::~ClipPopupNest()
431 int ClipPopupNest::handle_event()
433 MWindowGUI *gui = mwindow->gui;
434 gui->lock_window("ClipPopupNest::handle_event 1");
435 if( mwindow->session->drag_clips->total > 0 ) {
436 EDL *edl = mwindow->edl;
437 EDL *clip = mwindow->session->drag_clips->values[0];
438 EDL *clip_edl = new EDL; // no parent for nested clip
439 clip_edl->create_objects();
440 clip_edl->copy_all(clip);
441 EDL *new_clip = new EDL(edl);
442 new_clip->create_objects();
443 new_clip->awindow_folder = AW_CLIP_FOLDER;
444 snprintf(new_clip->local_session->clip_title,
445 sizeof(new_clip->local_session->clip_title),
446 _("Nested: %s"), clip->local_session->clip_title);
447 strcpy(new_clip->local_session->clip_notes,
448 clip->local_session->clip_notes);
449 time_t dt; time(&dt);
450 struct tm dtm; localtime_r(&dt, &dtm);
452 sprintf(path, _("Nested_%02d%02d%02d-%02d%02d%02d"),
453 dtm.tm_year+1900, dtm.tm_mon+1, dtm.tm_mday,
454 dtm.tm_hour, dtm.tm_min, dtm.tm_sec);
455 clip_edl->set_path(path);
456 sprintf(new_clip->local_session->clip_icon,
457 "clip_%02d%02d%02d-%02d%02d%02d.png",
458 dtm.tm_year+1900, dtm.tm_mon+1, dtm.tm_mday,
459 dtm.tm_hour, dtm.tm_min, dtm.tm_sec);
460 new_clip->set_path(path);
461 new_clip->to_nested(clip_edl);
462 int idx = edl->clips.number_of(clip);
464 edl->clips[idx] = new_clip;
468 edl->clips.append(new_clip);
469 mwindow->mainindexes->add_next_asset(0, clip_edl);
470 mwindow->mainindexes->start_build();
471 clip_edl->remove_user();
472 popup->gui->async_update_assets();
474 gui->unlock_window();
479 ClipPopupUnNest::ClipPopupUnNest(MWindow *mwindow, ClipPopup *popup)
480 : BC_MenuItem(_("UnNest"))
482 this->mwindow = mwindow;
485 ClipPopupUnNest::~ClipPopupUnNest()
489 int ClipPopupUnNest::handle_event()
492 MWindowGUI *gui = mwindow->gui;
493 gui->lock_window("ClipPopupUnNest::handle_event 1");
494 if( mwindow->session->drag_clips->total > 0 ) {
495 EDL *clip = mwindow->session->drag_clips->values[0];
496 Track *track = clip->tracks->first;
497 Edit *edit = track ? track->edits->first : 0;
498 nested_edl = edit && !edit->next && !edit->asset ? edit->nested_edl : 0;
499 while( nested_edl && (track=track->next)!=0 ) {
500 Edit *edit = track->edits->first;
501 if( !edit || edit->next || edit->nested_edl != nested_edl )
505 EDL *edl = mwindow->edl;
506 EDL *new_clip = new EDL(edl);
507 new_clip->create_objects();
508 new_clip->copy_all(nested_edl);
509 new_clip->awindow_folder = AW_CLIP_FOLDER;
510 int idx = edl->clips.number_of(clip);
512 edl->clips[idx] = new_clip;
516 edl->clips.append(new_clip);
517 popup->gui->async_update_assets();
520 gui->unlock_window();