add binfolder path relative filters, fix gbrp color model, vwdw timebar tweaks, title...
[goodguy/history.git] / cinelerra-5.1 / cinelerra / binfolder.C
index 200f31062cb767ad2b151d2b9988b88e2f024b1e..ffe5a12f9484548a3a2aabcfab901e3236f0dde9 100644 (file)
@@ -27,6 +27,7 @@
 #include "guicast.h"
 #include "indexable.h"
 #include "language.h"
 #include "guicast.h"
 #include "indexable.h"
 #include "language.h"
+#include "localsession.h"
 #include "mainerror.h"
 #include "mainsession.h"
 #include "mutex.h"
 #include "mainerror.h"
 #include "mainsession.h"
 #include "mutex.h"
@@ -57,12 +58,12 @@ const char *BinFolderTarget::types[] = {
 
 const char *BinFolderOp::types[] = {
        N_("Around"),
 
 const char *BinFolderOp::types[] = {
        N_("Around"),
-       N_("Eq"),
-       N_("Ge"),
-       N_("Gt"),
-       N_("Ne"),
-       N_("Le"),
-       N_("Lt"),
+       N_("Eq  =="),
+       N_("Ge  >="),
+       N_("Gt  > "),
+       N_("Ne  !="),
+       N_("Le  <="),
+       N_("Lt  < "),
        N_("Matches"),
 };
 
        N_("Matches"),
 };
 
@@ -238,7 +239,6 @@ static int64_t scan_date(const char *cp, char *&bp)
        struct tm ttm;  memset(&ttm, 0, sizeof(ttm));
        ttm.tm_year = year-1900;  ttm.tm_mon = mon-1;  ttm.tm_mday = day;
        ttm.tm_hour = hour;       ttm.tm_min = min;    ttm.tm_sec = secs;
        struct tm ttm;  memset(&ttm, 0, sizeof(ttm));
        ttm.tm_year = year-1900;  ttm.tm_mon = mon-1;  ttm.tm_mday = day;
        ttm.tm_hour = hour;       ttm.tm_min = min;    ttm.tm_sec = secs;
-       ttm.tm_wday = ttm.tm_yday = 0;  ttm.tm_isdst = daylight; /* tzset in main */
        time_t t = mktime(&ttm);
        return (int64_t)t;
 }
        time_t t = mktime(&ttm);
        return (int64_t)t;
 }
@@ -276,9 +276,10 @@ double BinFolder::matches_indexable(Indexable *idxbl)
 }
 
 
 }
 
 
-BinFolder::BinFolder(int awindow_folder, const char *title)
+BinFolder::BinFolder(int awindow_folder, int is_clips, const char *title)
 {
        this->awindow_folder = awindow_folder;
 {
        this->awindow_folder = awindow_folder;
+       this->is_clips = is_clips;
        char *bp = this->title;
        int len = sizeof(this->title);
        while( --len>0 && *title ) *bp++ = *title++;
        char *bp = this->title;
        int len = sizeof(this->title);
        while( --len>0 && *title ) *bp++ = *title++;
@@ -294,6 +295,7 @@ void BinFolder::copy_from(BinFolder *that)
 {
        strcpy(title, that->title);
        awindow_folder = that->awindow_folder;
 {
        strcpy(title, that->title);
        awindow_folder = that->awindow_folder;
+       is_clips = that->is_clips;
        filters.copy_from(&that->filters);
 }
 
        filters.copy_from(&that->filters);
 }
 
@@ -306,6 +308,7 @@ void BinFolder::save_xml(FileXML *file)
        file->tag.set_title("FOLDER");
        file->tag.set_property("TITLE", title);
        file->tag.set_property("AWINDOW_FOLDER", awindow_folder);
        file->tag.set_title("FOLDER");
        file->tag.set_property("TITLE", title);
        file->tag.set_property("AWINDOW_FOLDER", awindow_folder);
+       file->tag.set_property("IS_CLIPS", is_clips);
        file->append_tag();
        file->append_newline();
        for( int i=0; i<filters.size(); ++i )
        file->append_tag();
        file->append_newline();
        for( int i=0; i<filters.size(); ++i )
@@ -320,6 +323,7 @@ int BinFolder::load_xml(FileXML *file)
        title[0] = 0;
        file->tag.get_property("TITLE", title);
        awindow_folder = file->tag.get_property("AWINDOW_FOLDER", -1);
        title[0] = 0;
        file->tag.get_property("TITLE", title);
        awindow_folder = file->tag.get_property("AWINDOW_FOLDER", -1);
+       is_clips = file->tag.get_property("IS_CLIPS", 0);
        filters.remove_all_objects();
 
        int ret = 0;
        filters.remove_all_objects();
 
        int ret = 0;
@@ -334,39 +338,64 @@ int BinFolder::load_xml(FileXML *file)
        return ret;
 }
 
        return ret;
 }
 
-void BinFolder::add_patterns(ArrayList<Indexable*> *drag_assets)
-{
-       int n = drag_assets->size();
-       if( n > 0 ) {
-               int len = 1;
-               for( int i=0; i<n; ++i )
-                       len += strlen(drag_assets->get(i)->path) + 1;
-               char *pats = new char[len], *bp = pats;
-               const char *cp = drag_assets->get(0)->path;
-               while( *cp ) *bp++ = *cp++;
-               for( int i=1; i<n; ++i ) {
-                       *bp++ = '\n';
-                       cp = drag_assets->get(i)->path;
-                       while( *cp ) *bp++ = *cp++;
+int BinFolder::add_patterns(ArrayList<Indexable*> *drag_idxbls, int use_basename)
+{
+       int n = drag_idxbls->size();
+       if( !n ) return 1;
+       Indexable *idxbl;
+       int len = 0;
+       for( int i=0; i<n; ++i ) {
+               idxbl = drag_idxbls->get(i);
+               if( !idxbl->is_asset &&
+                   idxbl->awindow_folder == AW_PROXY_FOLDER )
+                       continue;
+
+               const char *tp = idxbl->get_title();
+               if( use_basename && idxbl->is_asset ) {
+                       const char *cp = strrchr(tp, '/');
+                       if( cp ) tp = cp + 1;
+                       len += 2;  // "*/" + fn
                }
                }
-               *bp = 0;
-// new pattern filter
-               BinFolderFilter *filter = new BinFolderFilter();
-               filter->update_enabled(FOLDER_ENABLED_OR);
-               filter->update_target(FOLDER_TARGET_PATTERNS);
-               filter->update_op(FOLDER_OP_MATCHES);
-               BinFolderTargetPatterns *patterns = (BinFolderTargetPatterns *)(filter->target);
-               patterns->update(pats);
-               filters.append(filter);
+               len += strlen(tp) + 1;
        }
        }
+       if( !len ) return 1;
+       char *pats = new char[len+1], *bp = pats;
+       for( int i=0; i<n; ++i ) {
+               idxbl = drag_idxbls->get(i);
+               if( !idxbl->is_asset &&
+                   idxbl->awindow_folder == AW_PROXY_FOLDER )
+                       continue;
+               if( i > 0 ) *bp++ = '\n';
+               const char *tp = idxbl->get_title();
+               if( use_basename && idxbl->is_asset ) {
+                       const char *cp = strrchr(tp, '/');
+                       if( cp ) tp = cp + 1;
+                       *bp++ = '*';  *bp++ = '/';
+               }
+               while( *tp ) *bp++ = *tp++;
+       }
+       *bp = 0;
+// new pattern filter
+       BinFolderFilter *filter = new BinFolderFilter();
+       filter->update_enabled(FOLDER_ENABLED_OR);
+       filter->update_target(FOLDER_TARGET_PATTERNS);
+       filter->update_op(FOLDER_OP_MATCHES);
+       BinFolderTargetPatterns *patterns = (BinFolderTargetPatterns *)(filter->target);
+       patterns->update(pats);
+       filters.append(filter);
+       return 0;
 }
 
 
 double BinFolders::matches_indexable(int folder, Indexable *idxbl)
 {
        int k = size();
 }
 
 
 double BinFolders::matches_indexable(int folder, Indexable *idxbl)
 {
        int k = size();
-       while( --k>=0 && get(k)->awindow_folder!=folder );
-       return k < 0 ? 0 : get(k)->matches_indexable(idxbl);
+       BinFolder *bin_folder = 0;
+       while( --k>=0 && (bin_folder=get(k)) && bin_folder->awindow_folder!=folder );
+       if( k < 0 ) return -1;
+       if( bin_folder->is_clips && idxbl->is_asset ) return -1;
+       if( !bin_folder->is_clips && !idxbl->is_asset ) return -1;
+       return bin_folder->matches_indexable(idxbl);
 }
 
 void BinFolders::save_xml(FileXML *file)
 }
 
 void BinFolders::save_xml(FileXML *file)
@@ -388,7 +417,7 @@ int BinFolders::load_xml(FileXML *file)
        while( !(ret=file->read_tag()) ) {
                if( file->tag.title_is("/FOLDERS") ) break;
                if( file->tag.title_is("FOLDER") ) {
        while( !(ret=file->read_tag()) ) {
                if( file->tag.title_is("/FOLDERS") ) break;
                if( file->tag.title_is("FOLDER") ) {
-                       BinFolder *folder = new BinFolder(-1, "folder");
+                       BinFolder *folder = new BinFolder(-1, -1, "folder");
                        folder->load_xml(file);
                        append(folder);
                }
                        folder->load_xml(file);
                        append(folder);
                }
@@ -521,9 +550,9 @@ void BinFolderFilters::copy_from(BinFolderFilters *that)
 
 double BinFolderOp::around(double v, double a)
 {
 
 double BinFolderOp::around(double v, double a)
 {
-       if( type != FOLDER_OP_AROUND || a <= 0 ) return v;
-       if( (v=fabs(v)) > a ) return -1;
-       return v / a;
+       if( type != FOLDER_OP_AROUND ) return v;
+       v = fabs(v);
+       return a>0 ? v/a : v;
 }
 
 // string theory: Feynman, Einstein and Schrodinger string compare
 }
 
 // string theory: Feynman, Einstein and Schrodinger string compare
@@ -580,8 +609,9 @@ double BinFolderOp::compare(BinFolderTarget *target, Indexable *idxbl)
                                char pattern[BCTEXTLEN], *bp = pattern, ch;
                                while( *cp && (ch=*cp++)!='\n' ) *bp++ = ch;
                                *bp = 0;
                                char pattern[BCTEXTLEN], *bp = pattern, ch;
                                while( *cp && (ch=*cp++)!='\n' ) *bp++ = ch;
                                *bp = 0;
-                               if( bp > pattern &&
-                                   !FileSystem::test_filter(idxbl->path, pattern) )
+                               if( !pattern[0] ) continue;
+                               const char *title = idxbl->get_title();
+                               if( !FileSystem::test_filter(title, pattern) )
                                        v = 1;
                        }
                        break; }
                                        v = 1;
                        }
                        break; }
@@ -1655,9 +1685,10 @@ void NewFolderGUI::create_objects()
        lock_window("NewFolderGUI::create_objects");
        int x = 10, y = 10;
        BC_Title *title;
        lock_window("NewFolderGUI::create_objects");
        int x = 10, y = 10;
        BC_Title *title;
-       add_subwindow(title = new BC_Title(x, y, _("Enter the name of the folder:")));
+       add_subwindow(title = new BC_Title(x, y, _("Folder name:")));
        y += title->get_h() + 5;
        y += title->get_h() + 5;
-       add_subwindow(text_box = new BC_TextBox(x, y, 300, 1, _("Untitled")));
+       const char *text = !thread->is_clips ? _("media bin") : _("clip bin");
+       add_subwindow(text_box = new BC_TextBox(x, y, 300, 1, text));
        add_subwindow(new BC_OKButton(this));
        add_subwindow(new BC_CancelButton(this));
        show_window();
        add_subwindow(new BC_OKButton(this));
        add_subwindow(new BC_CancelButton(this));
        show_window();
@@ -1674,6 +1705,7 @@ NewFolderThread::NewFolderThread(AWindowGUI *agui)
  : BC_DialogThread()
 {
        this->agui = agui;
  : BC_DialogThread()
 {
        this->agui = agui;
+       is_clips = -1;
 }
 
 NewFolderThread::~NewFolderThread()
 }
 
 NewFolderThread::~NewFolderThread()
@@ -1681,11 +1713,12 @@ NewFolderThread::~NewFolderThread()
        close_window();
 }
 
        close_window();
 }
 
-void NewFolderThread::start(int x, int y, int w, int h)
+void NewFolderThread::start(int x, int y, int w, int h, int is_clips)
 {
        close_window();
 {
        close_window();
-       wx = x;  wy = y;
-       ww = w;  wh = h;
+       this->is_clips = is_clips;
+       this->wx = x;  this->wy = y;
+       this->ww = w;  this->wh = h;
        Thread::start();
 }
 
        Thread::start();
 }
 
@@ -1700,12 +1733,13 @@ void NewFolderThread::handle_done_event(int result)
 {
        if( !result ) {
                const char *text = window->get_text();
 {
        if( !result ) {
                const char *text = window->get_text();
-               agui->mwindow->new_folder(text);
+               agui->mwindow->new_folder(text, is_clips);
        }
 }
 
 void NewFolderThread::handle_close_event(int result)
 {
        }
 }
 
 void NewFolderThread::handle_close_event(int result)
 {
+       is_clips = -1;
 }
 
 ModifyFolderGUI::ModifyFolderGUI(ModifyFolderThread *thread, int x, int y, int w, int h)
 }
 
 ModifyFolderGUI::ModifyFolderGUI(ModifyFolderThread *thread, int x, int y, int w, int h)
@@ -1740,12 +1774,17 @@ void ModifyFolderGUI::create_objects()
        lock_window("ModifyFolderGUI::create_objects");
        modify_folder_xatom = create_xatom("CWINDOWGUI_UPDATE_FILTERS");
        int x = 10, y = 10;
        lock_window("ModifyFolderGUI::create_objects");
        modify_folder_xatom = create_xatom("CWINDOWGUI_UPDATE_FILTERS");
        int x = 10, y = 10;
-       add_tool(new BC_Title(x, y, _("Enter the name of the folder:")));
-       y += 20;
+       BC_Title *title;
+       add_subwindow(title = new BC_Title(x, y, _("Enter the name of the folder:")));
+       const char *text = !thread->folder->is_clips ? _("Media") : _("Clips");
+       int tw = BC_Title::calculate_w(this, text, LARGEFONT);
+       int x0 = get_w() - 50 - tw;
+       add_subwindow(text_title = new BC_Title(x0, y, text, LARGEFONT, YELLOW));
+       y += title->get_h() + 10;
        add_subwindow(text_box = new BC_TextBox(x, y, 300, 1, thread->folder->title));
        add_subwindow(text_box = new BC_TextBox(x, y, 300, 1, thread->folder->title));
-       y += 30;
+       y += text_box->get_h() + 10;
        int lh = get_h() - y - BC_OKButton::calculate_h() - 30;
        int lh = get_h() - y - BC_OKButton::calculate_h() - 30;
-       int lw = get_w() - x - 120;
+       int lw = get_w() - x - 160;
        add_subwindow(folder_list =
                new BinFolderList(thread->folder, thread->agui->mwindow, this, x, y, lw, lh));
        folder_list->create_objects();
        add_subwindow(folder_list =
                new BinFolderList(thread->folder, thread->agui->mwindow, this, x, y, lw, lh));
        folder_list->create_objects();
@@ -1766,14 +1805,18 @@ int ModifyFolderGUI::resize_event(int w, int h)
        MWindow *mwindow = thread->agui->mwindow;
        mwindow->session->bwindow_w = w;
        mwindow->session->bwindow_h = h;
        MWindow *mwindow = thread->agui->mwindow;
        mwindow->session->bwindow_w = w;
        mwindow->session->bwindow_h = h;
+       int tx = text_title->get_x() + w - get_w();
+       int ty = text_title->get_y();
+       text_title->reposition_window(tx, ty);
        int lx = folder_list->get_x();
        int ly = folder_list->get_y();
        int lh = h - ly - BC_OKButton::calculate_h() - 30;
        int lx = folder_list->get_x();
        int ly = folder_list->get_y();
        int lh = h - ly - BC_OKButton::calculate_h() - 30;
-       int lw = w - lx - 120;
+       int lw = w - lx - 160;
        folder_list->reposition_window(lx, ly, lw, lh);
        int x1 = lx + lw + 15;
        add_filter->reposition_window(x1, add_filter->get_y());
        del_filter->reposition_window(x1, del_filter->get_y());
        folder_list->reposition_window(lx, ly, lw, lh);
        int x1 = lx + lw + 15;
        add_filter->reposition_window(x1, add_filter->get_y());
        del_filter->reposition_window(x1, del_filter->get_y());
+       apply_filter->reposition_window(x1,apply_filter->get_y());
        ok_button->resize_event(w, h);
        cancel_button->resize_event(w, h);
        return 1;
        ok_button->resize_event(w, h);
        cancel_button->resize_event(w, h);
        return 1;
@@ -1795,6 +1838,7 @@ ModifyFolderThread::ModifyFolderThread(AWindowGUI *agui)
 {
        this->agui = agui;
        original = 0;
 {
        this->agui = agui;
        original = 0;
+       modify_edl = 0;
        folder = 0;
 }
 
        folder = 0;
 }
 
@@ -1808,10 +1852,11 @@ void ModifyFolderThread::start(BinFolder *folder, int x, int y, int w, int h)
 {
        close_window();
        this->original = folder;
 {
        close_window();
        this->original = folder;
-       agui->mwindow->edl->add_user();
+       this->modify_edl = agui->mwindow->edl;
+       this->modify_edl->add_user();
        this->folder = new BinFolder(*folder);
        this->folder = new BinFolder(*folder);
-       wx = x;  wy = y;
-       ww = w;  wh = h;
+       this->wx = x;  this->wy = y;
+       this->ww = w;  this->wh = h;
        Thread::start();
 }
 
        Thread::start();
 }
 
@@ -1841,7 +1886,7 @@ void ModifyFolderThread::handle_done_event(int result)
        }
        delete folder;  folder = 0;
        original = 0;
        }
        delete folder;  folder = 0;
        original = 0;
-       agui->mwindow->edl->remove_user();
+       modify_edl->remove_user();
 }
 
 void ModifyFolderThread::handle_close_event(int result)
 }
 
 void ModifyFolderThread::handle_close_event(int result)
@@ -1889,10 +1934,10 @@ void ModifyTargetThread::handle_close_event(int result)
        target = 0;
 }
 
        target = 0;
 }
 
-ModifyTargetGUI::ModifyTargetGUI(ModifyTargetThread *thread)
+ModifyTargetGUI::ModifyTargetGUI(ModifyTargetThread *thread, int allow_resize)
  : BC_Window(_(PROGRAM_NAME ": Modify target"),
                thread->wx, thread->wy, thread->ww, thread->wh,
  : BC_Window(_(PROGRAM_NAME ": Modify target"),
                thread->wx, thread->wy, thread->ww, thread->wh,
-               -1, -1, 0, 0, 1)
+               -1, -1, allow_resize, 0, 1)
 {
        this->thread = thread;
 }
 {
        this->thread = thread;
 }
@@ -1913,11 +1958,17 @@ void ModifyTargetGUI::create_objects(BC_TextBox *&text_box)
        unlock_window();
 }
 
        unlock_window();
 }
 
+int ModifyTargetGUI::resize_event(int w, int h)
+{
+       return BC_WindowBase::resize_event(w, h);
+}
+
 ModifyTargetPatternsGUI::ModifyTargetPatternsGUI(ModifyTargetThread *thread)
 ModifyTargetPatternsGUI::ModifyTargetPatternsGUI(ModifyTargetThread *thread)
- : ModifyTargetGUI(thread)
+ : ModifyTargetGUI(thread, 1)
 {
        this->thread = thread;
        scroll_text_box = 0;
 {
        this->thread = thread;
        scroll_text_box = 0;
+       text_rowsz = 0;
 }
 
 ModifyTargetPatternsGUI::~ModifyTargetPatternsGUI()
 }
 
 ModifyTargetPatternsGUI::~ModifyTargetPatternsGUI()
@@ -1931,17 +1982,33 @@ void ModifyTargetPatternsGUI::create_objects()
        BinFolderTargetPatterns *target = (BinFolderTargetPatterns *)thread->target;
        int x = 10, y = 10;
        int text_font = MEDIUMFONT;
        BinFolderTargetPatterns *target = (BinFolderTargetPatterns *)thread->target;
        int x = 10, y = 10;
        int text_font = MEDIUMFONT;
-       int text_rowsz = get_text_ascent(text_font)+1 + get_text_descent(text_font)+1;
-       int th = get_h() - BC_OKButton::calculate_h() - y - 10;
+       text_rowsz = get_text_ascent(text_font)+1 + get_text_descent(text_font)+1;
+       int th = get_h() - y - BC_OKButton::calculate_h() - 20;
        int rows = th / text_rowsz;
        int rows = th / text_rowsz;
-       scroll_text_box = new BC_ScrollTextBox(this, x, y, get_w()-20, rows, target->text);
+       int text_len = strlen(target->text);
+       if( text_len < BCTEXTLEN ) text_len = BCTEXTLEN;
+       scroll_text_box = new BC_ScrollTextBox(this, x, y, get_w()-20, rows,
+               target->text, 2*text_len);
        scroll_text_box->create_objects();
        scroll_text_box->create_objects();
-       add_subwindow(new BC_OKButton(this));
-       add_subwindow(new BC_CancelButton(this));
+       add_subwindow(ok_button = new BC_OKButton(this));
+       add_subwindow(cancel_button = new BC_CancelButton(this));
        show_window();
        unlock_window();
 }
 
        show_window();
        unlock_window();
 }
 
+int ModifyTargetPatternsGUI::resize_event(int w, int h)
+{
+       int tx = scroll_text_box->get_x();
+       int ty = scroll_text_box->get_y();
+       int th = h - ty - BC_OKButton::calculate_h() - 20;
+       int tw = w - 20;
+       int rows = th / text_rowsz;
+       scroll_text_box->reposition_window(tx, ty, tw, rows);
+       ok_button->resize_event(w, h);
+       cancel_button->resize_event(w, h);
+       return 1;
+}
+
 void ModifyTargetPatternsGUI::update()
 {
        BinFolderTargetPatterns *target = (BinFolderTargetPatterns *)thread->target;
 void ModifyTargetPatternsGUI::update()
 {
        BinFolderTargetPatterns *target = (BinFolderTargetPatterns *)thread->target;