rework undo compression, add shift viewer overwr/copy/clip/splice, fix paste edl...
[goodguy/history.git] / cinelerra-5.1 / cinelerra / clippopup.C
index e3cc1a533f0492a821dfe467a5b96ae66d2933c0..dd73896330963ebdd431aaf67b58155b3a704fd0 100644 (file)
 #include "awindowgui.h"
 #include "bcsignals.h"
 #include "clipedit.h"
+#include "clipedls.h"
 #include "cwindow.h"
 #include "cwindowgui.h"
+#include "edit.h"
+#include "edits.h"
 #include "edl.h"
 #include "filexml.h"
 #include "language.h"
 #include "localsession.h"
 #include "mainerror.h"
+#include "mainindexes.h"
 #include "mainsession.h"
 #include "mwindow.h"
 #include "mwindowgui.h"
+#include "track.h"
 #include "tracks.h"
 #include "vwindow.h"
 #include "vwindowgui.h"
@@ -58,21 +63,20 @@ void ClipPopup::create_objects()
        BC_MenuItem *menu_item;
        BC_SubMenu *submenu;
        add_item(info = new ClipPopupInfo(mwindow, this));
-       add_item(format = new AWindowListFormat(mwindow));
+       add_item(format = new AWindowListFormat(mwindow, gui));
        add_item(new ClipPopupSort(mwindow, this));
        add_item(view = new ClipPopupView(mwindow, this));
        add_item(view_window = new ClipPopupViewWindow(mwindow, this));
        add_item(new ClipPopupCopy(mwindow, this));
+       add_item(new ClipPopupNest(mwindow, this));
+       add_item(new ClipPopupUnNest(mwindow, this));
        add_item(new ClipPopupPaste(mwindow, this));
        add_item(menu_item = new BC_MenuItem(_("Match...")));
        menu_item->add_submenu(submenu = new BC_SubMenu());
        submenu->add_submenuitem(new ClipMatchSize(mwindow, this));
        submenu->add_submenuitem(new ClipMatchRate(mwindow, this));
        submenu->add_submenuitem(new ClipMatchAll(mwindow, this));
-       add_item(menu_item = new BC_MenuItem(_("Remove...")));
-       menu_item->add_submenu(submenu = new BC_SubMenu());
-       submenu->add_submenuitem(new ClipPopupProjectRemove(mwindow, this));
-       submenu->add_submenuitem(new ClipPopupDiskRemove(mwindow, this));
+       add_item(new ClipPopupDelete(mwindow, this));
 }
 
 void ClipPopup::paste_assets()
@@ -140,16 +144,18 @@ ClipPopupInfo::~ClipPopupInfo()
 
 int ClipPopupInfo::handle_event()
 {
-       if(mwindow->session->drag_assets->total)
-       {
-               mwindow->awindow->asset_edit->edit_asset(
-                       mwindow->session->drag_assets->values[0]);
+       int cur_x, cur_y;
+       popup->gui->get_abs_cursor(cur_x, cur_y, 0);
+
+       if( mwindow->session->drag_assets->total ) {
+               AssetEdit *asset_edit = mwindow->awindow->get_asset_editor();
+               asset_edit->edit_asset(
+                       mwindow->session->drag_assets->values[0], cur_x, cur_y);
        }
        else
-       if(mwindow->session->drag_clips->total)
-       {
+       if( mwindow->session->drag_clips->total ) {
                popup->gui->awindow->clip_edit->edit_clip(
-                       mwindow->session->drag_clips->values[0]);
+                       mwindow->session->drag_clips->values[0], cur_x, cur_y);
        }
        return 1;
 }
@@ -168,7 +174,7 @@ ClipPopupSort::~ClipPopupSort()
 
 int ClipPopupSort::handle_event()
 {
-       mwindow->awindow->gui->sort_assets();
+       mwindow->awindow->gui->sort_assets(0);
        return 1;
 }
 
@@ -187,17 +193,15 @@ ClipPopupView::~ClipPopupView()
 int ClipPopupView::handle_event()
 {
        VWindow *vwindow = mwindow->get_viewer(1, DEFAULT_VWINDOW);
-       vwindow->gui->lock_window("ClipPopupView::handle_event");
 
-       if(mwindow->session->drag_assets->total)
+       if( mwindow->session->drag_assets->total )
                vwindow->change_source(
                        mwindow->session->drag_assets->values[0]);
        else
-       if(mwindow->session->drag_clips->total)
+       if( mwindow->session->drag_clips->total )
                vwindow->change_source(
                        mwindow->session->drag_clips->values[0]);
 
-       vwindow->gui->unlock_window();
        return 1;
 }
 
@@ -221,11 +225,11 @@ int ClipPopupViewWindow::handle_event()
 // TODO: create new vwindow or change current vwindow
        vwindow->gui->lock_window("ClipPopupView::handle_event");
 
-       if(mwindow->session->drag_assets->total)
+       if( mwindow->session->drag_assets->total )
                vwindow->change_source(
                        mwindow->session->drag_assets->values[0]);
        else
-       if(mwindow->session->drag_clips->total)
+       if( mwindow->session->drag_clips->total )
                vwindow->change_source(
                        mwindow->session->drag_clips->values[0]);
 
@@ -249,16 +253,18 @@ int ClipPopupCopy::handle_event()
        MWindowGUI *gui = mwindow->gui;
        gui->lock_window("ClipPopupCopy::handle_event");
        if( mwindow->session->drag_clips->total > 0 ) {
-               FileXML file;
                EDL *edl = mwindow->session->drag_clips->values[0];
+               EDL *copy_edl = new EDL; // no parent or assets wont be copied
+               copy_edl->create_objects();
+               copy_edl->copy_all(edl);
+               FileXML file;
                double start = 0, end = edl->tracks->total_length();
-               edl->copy(start, end, 1, 0, 0, &file, "", 1);
+               copy_edl->copy(start, end, 1, &file, "", 1);
+               copy_edl->remove_user();
                const char *file_string = file.string();
                long file_length = strlen(file_string);
-               gui->get_clipboard()->to_clipboard(file_string, file_length,
-                       SECONDARY_SELECTION);
-               gui->get_clipboard()->to_clipboard(file_string, file_length,
-                       BC_PRIMARY_SELECTION);
+               gui->to_clipboard(file_string, file_length, SECONDARY_SELECTION);
+               gui->to_clipboard(file_string, file_length, BC_PRIMARY_SELECTION);
        }
        gui->unlock_window(); 
        return 1;
@@ -325,46 +331,27 @@ int ClipMatchAll::handle_event()
 }
 
 
-ClipPopupProjectRemove::ClipPopupProjectRemove(MWindow *mwindow, ClipPopup *popup)
- : BC_MenuItem(_("Remove from project"))
+ClipPopupDelete::ClipPopupDelete(MWindow *mwindow, ClipPopup *popup)
+ : BC_MenuItem(_("Delete"))
 {
        this->mwindow = mwindow;
        this->popup = popup;
 }
 
 
-ClipPopupProjectRemove::~ClipPopupProjectRemove()
+ClipPopupDelete::~ClipPopupDelete()
 {
 }
 
-int ClipPopupProjectRemove::handle_event()
+int ClipPopupDelete::handle_event()
 {
-       mwindow->remove_assets_from_project(1,
-               1,
+       mwindow->remove_assets_from_project(1, 1,
                mwindow->session->drag_assets,
                mwindow->session->drag_clips);
        return 1;
 }
 
 
-ClipPopupDiskRemove::ClipPopupDiskRemove(MWindow *mwindow, ClipPopup *popup)
- : BC_MenuItem(_("Remove from disk"))
-{
-       this->mwindow = mwindow;
-       this->popup = popup;
-}
-
-ClipPopupDiskRemove::~ClipPopupDiskRemove()
-{
-}
-
-int ClipPopupDiskRemove::handle_event()
-{
-       mwindow->awindow->asset_remove->start();
-       return 1;
-}
-
-
 ClipPasteToFolder::ClipPasteToFolder(MWindow *mwindow)
  : BC_MenuItem(_("Paste Clip"))
 {
@@ -375,10 +362,10 @@ int ClipPasteToFolder::handle_event()
 {
        MWindowGUI *gui = mwindow->gui;
        gui->lock_window("ClipPasteToFolder::handle_event 1");
-       int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION);
+       int64_t len = gui->clipboard_len(BC_PRIMARY_SELECTION);
        if( len ) {
-               char *string = new char[len + 1];
-               gui->get_clipboard()->from_clipboard(string, len, BC_PRIMARY_SELECTION);
+               char *string = new char[len];
+               gui->from_clipboard(string, len, BC_PRIMARY_SELECTION);
                const char *clip_header = "<EDL VERSION=";
                if( !strncmp(clip_header, string, strlen(clip_header)) ) {
                        FileXML file;
@@ -419,8 +406,8 @@ ClipListMenu::~ClipListMenu()
 
 void ClipListMenu::create_objects()
 {
-       add_item(format = new AWindowListFormat(mwindow));
-       add_item(new AWindowListSort(mwindow));
+       add_item(format = new AWindowListFormat(mwindow, gui));
+       add_item(new AWindowListSort(mwindow, gui));
        add_item(new ClipPasteToFolder(mwindow));
        update();
 }
@@ -430,3 +417,107 @@ void ClipListMenu::update()
        format->update();
 }
 
+
+ClipPopupNest::ClipPopupNest(MWindow *mwindow, ClipPopup *popup)
+ : BC_MenuItem(_("Nest"))
+{
+       this->mwindow = mwindow;
+       this->popup = popup;
+}
+ClipPopupNest::~ClipPopupNest()
+{
+}
+
+int ClipPopupNest::handle_event()
+{
+       MWindowGUI *gui = mwindow->gui;
+       gui->lock_window("ClipPopupNest::handle_event 1");
+       if( mwindow->session->drag_clips->total > 0 ) {
+               EDL *edl = mwindow->edl;
+               EDL *clip = mwindow->session->drag_clips->values[0];
+               EDL *clip_edl = new EDL;  // no parent for nested clip
+               clip_edl->create_objects();
+               clip_edl->copy_all(clip);
+               EDL *new_clip = new EDL(edl);
+               new_clip->create_objects();
+               new_clip->awindow_folder = AW_CLIP_FOLDER;
+               snprintf(new_clip->local_session->clip_title,
+                       sizeof(new_clip->local_session->clip_title),
+                       _("Nested: %s"), clip->local_session->clip_title);
+               strcpy(new_clip->local_session->clip_notes,
+                       clip->local_session->clip_notes);
+               time_t dt;      time(&dt);
+               struct tm dtm;  localtime_r(&dt, &dtm);
+               char path[BCSTRLEN];
+               sprintf(path, _("Nested_%02d%02d%02d-%02d%02d%02d"),
+                       dtm.tm_year+1900, dtm.tm_mon+1, dtm.tm_mday,
+                       dtm.tm_hour, dtm.tm_min, dtm.tm_sec);
+               clip_edl->set_path(path);
+               sprintf(new_clip->local_session->clip_icon,
+                       "clip_%02d%02d%02d-%02d%02d%02d.png",
+                       dtm.tm_year+1900, dtm.tm_mon+1, dtm.tm_mday,
+                       dtm.tm_hour, dtm.tm_min, dtm.tm_sec);
+               new_clip->set_path(path);
+               new_clip->to_nested(clip_edl);
+               int idx = edl->clips.number_of(clip);
+               if( idx >= 0 ) {
+                       edl->clips[idx] = new_clip;
+                       clip->remove_user();
+               }
+               else
+                       edl->clips.append(new_clip);
+               mwindow->mainindexes->add_next_asset(0, clip_edl);
+               mwindow->mainindexes->start_build();
+               clip_edl->remove_user();
+               popup->gui->async_update_assets();
+       }
+       gui->unlock_window();
+       return 1;
+}
+
+
+ClipPopupUnNest::ClipPopupUnNest(MWindow *mwindow, ClipPopup *popup)
+ : BC_MenuItem(_("UnNest"))
+{
+       this->mwindow = mwindow;
+       this->popup = popup;
+}
+ClipPopupUnNest::~ClipPopupUnNest()
+{
+}
+
+int ClipPopupUnNest::handle_event()
+{
+       EDL *nested_edl = 0;
+       MWindowGUI *gui = mwindow->gui;
+       gui->lock_window("ClipPopupUnNest::handle_event 1");
+       if( mwindow->session->drag_clips->total > 0 ) {
+               EDL *clip = mwindow->session->drag_clips->values[0];
+               Track *track = clip->tracks->first;
+               Edit *edit = track ? track->edits->first : 0;
+               nested_edl = edit && !edit->next && !edit->asset ? edit->nested_edl : 0;
+               while( nested_edl && (track=track->next)!=0 ) {
+                       Edit *edit = track->edits->first;
+                       if( !edit || edit->next || edit->nested_edl != nested_edl )
+                               nested_edl = 0;
+               }
+               if( nested_edl ) {
+                       EDL *edl = mwindow->edl;
+                       EDL *new_clip = new EDL(edl);
+                       new_clip->create_objects();
+                       new_clip->copy_all(nested_edl);
+                       new_clip->awindow_folder = AW_CLIP_FOLDER;
+                       int idx = edl->clips.number_of(clip);
+                       if( idx >= 0 ) {
+                               edl->clips[idx] = new_clip;
+                               clip->remove_user();
+                       }
+                       else
+                               edl->clips.append(new_clip);
+                       popup->gui->async_update_assets();
+               }
+       }
+       gui->unlock_window();
+       return 1;
+}
+