add bins/folders, fix listbox bad wdw ref, hide vicons fix, remove sort by time
[goodguy/history.git] / cinelerra-5.1 / cinelerra / awindowgui.C
index 505f32f16cd2c191e3b8d6d19c01dbaedf76fcf1..fceeb04c3459361ecba4e9601fecb74c104ad38e 100644 (file)
@@ -30,6 +30,7 @@
 #include "bccmodels.h"
 #include "bcsignals.h"
 #include "bchash.h"
+#include "binfolder.h"
 #include "cache.h"
 #include "cstrdup.h"
 #include "clip.h"
@@ -54,7 +55,6 @@
 #include "mainsession.h"
 #include "mwindowgui.h"
 #include "mwindow.h"
-#include "newfolder.h"
 #include "preferences.h"
 #include "proxy.h"
 #include "proxypopup.h"
@@ -333,6 +333,17 @@ AssetPicon::AssetPicon(MWindow *mwindow,
        persistent = persist;
 }
 
+AssetPicon::AssetPicon(MWindow *mwindow,
+       AWindowGUI *gui, int folder, const char *title)
+ : BC_ListBoxItem(title, gui->folder_icon)
+{
+       reset();
+       foldernum = folder;
+       this->mwindow = mwindow;
+       this->gui = gui;
+       persistent = 0;
+}
+
 AssetPicon::AssetPicon(MWindow *mwindow,
        AWindowGUI *gui, PluginServer *plugin)
  : BC_ListBoxItem()
@@ -421,11 +432,12 @@ void AssetPicon::reset()
        indexable = 0;
        edl = 0;
        foldernum = AW_NO_FOLDER;
+       sort_key = -1;
        icon = 0;
        icon_vframe = 0;
        vicon = 0;
        in_use = 1;
-       mtime = 0;
+       comments_time = 0;
        id = 0;
        persistent = 0;
 }
@@ -612,7 +624,7 @@ void AssetPicon::create_objects()
 
                }
                struct stat st;
-               mtime = !stat(asset->path, &st) ? st.st_mtime : 0;
+               comments_time = !stat(asset->path, &st) ? st.st_mtime : 0;
        }
        else
        if( indexable && !indexable->is_asset ) {
@@ -838,7 +850,6 @@ AWindowGUI::AWindowGUI(MWindow *mwindow, AWindow *awindow)
        veffect_vframe = 0;             veffect_icon = 0;
 
        plugin_visibility = ((uint64_t)1<<(8*sizeof(uint64_t)-1))-1;
-       newfolder_thread = 0;
        asset_menu = 0;
        effectlist_menu = 0;
        assetlist_menu = 0;
@@ -854,6 +865,8 @@ AWindowGUI::AWindowGUI(MWindow *mwindow, AWindow *awindow)
        vicon_audio = 0;
        vicon_drawing = 1;
        displayed_folder = AW_NO_FOLDER;
+       new_folder_thread = 0;
+       modify_folder_thread = 0;
        folder_lock = new Mutex("AWindowGUI::folder_lock");
 }
 
@@ -868,9 +881,10 @@ AWindowGUI::~AWindowGUI()
        labellist.remove_all_objects();
        displayed_assets[1].remove_all_objects();
 
+       delete new_folder_thread;
+       delete modify_folder_thread;
        delete vicon_thread;
        delete vicon_audio;
-       delete newfolder_thread;
 
        delete search_text;
        delete temp_picon;
@@ -1023,6 +1037,8 @@ void AWindowGUI::create_objects()
 
        mwindow->theme->get_awindow_sizes(this);
        load_defaults(mwindow->defaults);
+       new_folder_thread = new NewFolderThread(this);
+       modify_folder_thread = new ModifyFolderThread(this);
 
        int x1 = mwindow->theme->alist_x, y1 = mwindow->theme->alist_y;
        int w1 = mwindow->theme->alist_w, h1 = mwindow->theme->alist_h;
@@ -1059,9 +1075,6 @@ void AWindowGUI::create_objects()
        //int x = mwindow->theme->abuttons_x;
        //int y = mwindow->theme->abuttons_y;
 
-
-       newfolder_thread = new NewFolderThread(mwindow, this);
-
        add_subwindow(asset_menu = new AssetPopup(mwindow, this));
        asset_menu->create_objects();
        add_subwindow(clip_menu = new ClipPopup(mwindow, this));
@@ -1185,15 +1198,17 @@ int AWindowGUI::close_event()
 void AWindowGUI::start_vicon_drawing()
 {
        if( !vicon_drawing ) return;
-       if( mwindow->edl->session->awindow_folder != AW_MEDIA_FOLDER ) return;
-       switch( mwindow->edl->session->assetlist_format ) {
-       case ASSETS_ICONS:
-       case ASSETS_ICONS_PACKED:
-       case ASSETS_ICON_LIST:
-               vicon_thread->start_drawing();
-               break;
-       default:
-               break;
+       if( mwindow->edl->session->awindow_folder == AW_MEDIA_FOLDER ||
+           mwindow->edl->session->awindow_folder >= AWINDOW_USER_FOLDERS ) {
+               switch( mwindow->edl->session->assetlist_format ) {
+               case ASSETS_ICONS:
+               case ASSETS_ICONS_PACKED:
+               case ASSETS_ICON_LIST:
+                       vicon_thread->start_drawing();
+                       break;
+               default:
+                       break;
+               }
        }
 }
 
@@ -1202,6 +1217,39 @@ void AWindowGUI::stop_vicon_drawing()
        vicon_thread->stop_drawing();
 }
 
+int AWindowGUI::cycle_assetlist_format()
+{
+       EDLSession *session = mwindow->edl->session;
+       int format = ASSETS_TEXT;
+       if( allow_iconlisting ) {
+               switch( session->assetlist_format ) {
+               case ASSETS_TEXT:
+                       format = ASSETS_ICONS;
+                       break;
+               case ASSETS_ICONS:
+                       format = ASSETS_ICONS_PACKED;
+                       break;
+               case ASSETS_ICONS_PACKED:
+                       format = ASSETS_ICON_LIST;
+                       break;
+               case ASSETS_ICON_LIST:
+                       format = ASSETS_TEXT;
+                       break;
+               }
+       }
+       stop_vicon_drawing();
+       session->assetlist_format = format;
+       asset_list->update_format(session->assetlist_format, 0);
+       int x0 = 0;
+       int x1 = asset_list->get_w();
+       int y0 = asset_list->get_title_h();
+       int y1 = asset_list->get_h();
+       vicon_thread->set_drawing_area(x0,y0, x1,y1);
+       async_update_assets();
+       start_vicon_drawing();
+       return 1;
+}
+
 AWindowRemovePluginGUI::
 AWindowRemovePluginGUI(AWindow *awindow, AWindowRemovePlugin *thread,
        int x, int y, PluginServer *plugin)
@@ -1337,6 +1385,8 @@ int AWindowGUI::keypress_event()
                        return 1;
                }
                break;
+       case 'v':
+               return cycle_assetlist_format();
        case DELETE:
                if( shift_down() ) {
                        PluginServer* plugin = selected_plugin();
@@ -1357,7 +1407,7 @@ int AWindowGUI::create_custom_xatoms()
        UpdateAssetsXAtom = create_xatom("CWINDOWGUI_UPDATE_ASSETS");
        return 0;
 }
-int AWindowGUI::recieve_custom_xatoms(xatom_event *event)
+int AWindowGUI::receive_custom_xatoms(xatom_event *event)
 {
        if( event->message_type == UpdateAssetsXAtom ) {
                update_assets();
@@ -1383,12 +1433,12 @@ void AWindowGUI::update_folder_list()
 
 // Search assets for folders
        for( int i = 0; i < mwindow->edl->folders.total; i++ ) {
-               const char *folder = mwindow->edl->folders.values[i];
+               BinFolder *bin_folder = mwindow->edl->folders[i];
                int exists = 0;
 
                for( int j = 0; j < folders.total; j++ ) {
-                       AssetPicon *picon = (AssetPicon*)folders.values[j];
-                       if( !strcasecmp(picon->get_text(), folder) ) {
+                       AssetPicon *picon = (AssetPicon*)folders[j];
+                       if( !strcasecmp(picon->get_text(), bin_folder->title) ) {
                                exists = 1;
                                picon->in_use = 1;
                                break;
@@ -1396,12 +1446,11 @@ void AWindowGUI::update_folder_list()
                }
 
                if( !exists ) {
-                       int aw_folder = folder_number(folder);
-                       if( aw_folder >= 0 ) {
-                               AssetPicon *picon = new AssetPicon(mwindow, this, aw_folder, 1);
-                               picon->create_objects();
-                               folders.append(picon);
-                       }
+                       const char *title = bin_folder->title;
+                       int folder = bin_folder->awindow_folder;
+                       AssetPicon *picon = new AssetPicon(mwindow, this, folder, title);
+                       picon->create_objects();
+                       folders.append(picon);
                }
        }
 
@@ -1543,9 +1592,11 @@ void AWindowGUI::update_asset_list()
                        assets.remove_number(i);
                        continue;
                }
-               if( !picon->indexable || !picon->indexable->is_asset ) continue;
-               struct stat st;
-               picon->mtime = !stat(picon->indexable->path, &st) ? st.st_mtime : 0;
+               if( picon->indexable && picon->indexable->is_asset ) {
+                       struct stat st;
+                       picon->comments_time = !stat(picon->indexable->path, &st) ?
+                               st.st_mtime : 0;
+               }
        }
 }
 
@@ -1572,7 +1623,7 @@ void AWindowGUI::update_picon(Indexable *indexable)
        }
 }
 
-void AWindowGUI::sort_assets(int use_mtime)
+void AWindowGUI::sort_assets()
 {
        folder_lock->lock("AWindowGUI::sort_assets");
        switch( mwindow->edl->session->awindow_folder ) {
@@ -1592,7 +1643,7 @@ void AWindowGUI::sort_assets(int use_mtime)
                sort_picons(&labellist);
                break;
        default:
-               sort_picons(&assets, use_mtime);
+               sort_picons(&assets);
                break;
        }
 // reset xyposition
@@ -1642,6 +1693,7 @@ EDL *AWindowGUI::collect_proxy(Indexable *indexable)
                if( current->data_type != TRACK_AUDIO ) continue;
                current->insert_asset(unproxy_asset, 0, length, 0, atrack++);
        }
+       proxy_edl->awindow_folder = AW_PROXY_FOLDER;
        return proxy_edl;
 }
 
@@ -1679,14 +1731,25 @@ void AWindowGUI::copy_picons(ArrayList<BC_ListBoxItem*> *dst,
 
 // Create new pointers
        for( int i = 0; i < src->total; i++ ) {
+               int visible = folder < 0 ? 1 : 0;
                AssetPicon *picon = (AssetPicon*)src->values[i];
-               if( folder < 0 ||
-                   (picon->indexable && picon->indexable->awindow_folder == folder) ||
-                   (picon->edl && picon->edl->local_session->awindow_folder == folder) ) {
+               picon->sort_key = -1;
+               if( !visible && folder >= AWINDOW_USER_FOLDERS && picon->indexable ) {
+                       picon->sort_key = mwindow->edl->folders.matches_indexable(folder, picon->indexable);
+                       if( picon->sort_key >= 0 ) visible = 1;
+               }
+               if( !visible && picon->indexable && picon->indexable->awindow_folder == folder )
+                       visible = 1;
+               if( !visible && picon->edl && picon->edl->awindow_folder == folder )
+                       visible = 1;
+               if( visible ) {
                        const char *text = search_text->get_text();
-                       int hidden = text && text[0] && !bstrcasestr(picon->get_text(), text);
-                       if( picon->vicon ) picon->vicon->hidden = hidden;
-                       if( hidden ) continue;
+                       if( text && text[0] )
+                               visible = bstrcasestr(picon->get_text(), text) ? 1 : 0;
+               }
+               if( picon->vicon )
+                       picon->vicon->hidden = !visible ? 1 : 0;
+               if( visible ) {
                        BC_ListBoxItem *item2, *item1;
                        dst[0].append(item1 = picon);
                        if( picon->edl )
@@ -1694,9 +1757,9 @@ void AWindowGUI::copy_picons(ArrayList<BC_ListBoxItem*> *dst,
                        else
                        if( picon->label )
                                dst[1].append(item2 = new BC_ListBoxItem(picon->label->textstr));
-                       else if( picon->mtime ) {
+                       else if( picon->comments_time ) {
                                char date_time[BCSTRLEN];
-                               struct tm stm;  localtime_r(&picon->mtime, &stm);
+                               struct tm stm;  localtime_r(&picon->comments_time, &stm);
                                sprintf(date_time,"%04d.%02d.%02d %02d:%02d:%02d",
                                         stm.tm_year+1900, stm.tm_mon+1, stm.tm_mday,
                                         stm.tm_hour, stm.tm_min, stm.tm_sec);
@@ -1710,7 +1773,7 @@ void AWindowGUI::copy_picons(ArrayList<BC_ListBoxItem*> *dst,
        }
 }
 
-void AWindowGUI::sort_picons(ArrayList<BC_ListBoxItem*> *src, int use_mtime)
+void AWindowGUI::sort_picons(ArrayList<BC_ListBoxItem*> *src)
 {
        int done = 0, changed = 0;
        while( !done ) {
@@ -1718,12 +1781,20 @@ void AWindowGUI::sort_picons(ArrayList<BC_ListBoxItem*> *src, int use_mtime)
                for( int i=0; i<src->total-1; ++i ) {
                        AssetPicon *item1 = (AssetPicon *)src->values[i];
                        AssetPicon *item2 = (AssetPicon *)src->values[i + 1];
-                       if( use_mtime ? item1->mtime > item2->mtime :
-                           strcmp(item1->get_text(), item2->get_text()) > 0 ) {
-                               src->values[i + 1] = item1;
-                               src->values[i] = item2;
-                               done = 0;  changed = 1;
+                       double v = item2->sort_key - item1->sort_key;
+                       if( v > 0 ) continue;
+                       if( v == 0 ) {
+                               const char *cp1 = item1->get_text();
+                               const char *bp1 = strrchr(cp1, '/');
+                               if( bp1 ) cp1 = bp1 + 1;
+                               const char *cp2 = item2->get_text();
+                               const char *bp2 = strrchr(cp2, '/');
+                               if( bp2 ) cp2 = bp2 + 1;
+                               if( strcmp(cp2, cp1) >= 0 ) continue;
                        }
+                       src->values[i + 1] = item1;
+                       src->values[i] = item2;
+                       done = 0;  changed = 1;
                }
        }
        if( changed ) {
@@ -1735,7 +1806,6 @@ void AWindowGUI::sort_picons(ArrayList<BC_ListBoxItem*> *src, int use_mtime)
        }
 }
 
-
 void AWindowGUI::filter_displayed_assets()
 {
        //allow_iconlisting = 1;
@@ -1787,6 +1857,7 @@ void AWindowGUI::update_assets()
 
        if( displayed_folder != mwindow->edl->session->awindow_folder )
                search_text->clear();
+       vicon_thread->hide_vicons();
        filter_displayed_assets();
        folder_lock->unlock();
 
@@ -1833,14 +1904,6 @@ void AWindowGUI::update_effects()
        create_persistent_folder(&vtransitions, 0, 1, 0, 1);
 }
 
-int AWindowGUI::folder_number(const char *name)
-{
-       for( int i = 0; i < AWINDOW_FOLDERS; i++ ) {
-               if( !strcasecmp(name, folder_names[i]) ) return i;
-       }
-       return AW_NO_FOLDER;
-}
-
 int AWindowGUI::drag_motion()
 {
        if( get_hidden() ) return 0;
@@ -1990,10 +2053,25 @@ int AWindowFolders::button_press_event()
        return result;
 }
 
-
-
-
-
+int AWindowFolders::drag_stop()
+{
+       int result = 0;
+       if( get_hidden() ) return 0;
+       if( mwindow->session->current_operation == DRAG_ASSET &&
+           gui->folder_list->cursor_above() ) { // check user folder
+               int item_no = gui->folder_list->get_cursor_item();
+               AssetPicon *picon = (AssetPicon *)(item_no < 0 ? 0 : gui->folders[item_no]);
+               if( picon && picon->foldernum >= AWINDOW_USER_FOLDERS ) {
+                       BinFolder *folder = mwindow->edl->get_folder(picon->foldernum);
+                       ArrayList<Indexable *> *drags = mwindow->session->drag_assets;
+                       if( folder && drags ) folder->add_patterns(drags);
+                       mwindow->session->current_operation = ::NO_OPERATION;
+                       flicker(1,30);
+                       result = 1;
+               }
+       }
+       return result;
+}
 
 
 AWindowAssets::AWindowAssets(MWindow *mwindow, AWindowGUI *gui, int x, int y, int w, int h)
@@ -2051,10 +2129,12 @@ int AWindowAssets::button_press_event()
                        gui->proxylist_menu->update();
                        gui->proxylist_menu->activate_menu();
                        break;
-               case AW_MEDIA_FOLDER:
-                       gui->assetlist_menu->update_titles(folder==AW_MEDIA_FOLDER);
+               default:
+               case AW_MEDIA_FOLDER: {
+                       int shots =  folder==AW_MEDIA_FOLDER || folder>=AWINDOW_USER_FOLDERS;
+                       gui->assetlist_menu->update_titles(shots);
                        gui->assetlist_menu->activate_menu();
-                       break;
+                       break; }
                }
                result = 1;
        }
@@ -2151,11 +2231,10 @@ void AWindowAssets::draw_background()
        clear_box(0,0,get_w(),get_h(),get_bg_surface());
        set_color(BC_WindowBase::get_resources()->audiovideo_color);
        set_font(LARGEFONT);
-       int aw_folder = mwindow->edl->session->awindow_folder;
-       if( aw_folder < 0 ) return;
-       const char *aw_name = _(AWindowGUI::folder_names[aw_folder]);
-       draw_text(get_w() - get_text_width(LARGEFONT, aw_name) - 4, 30,
-               aw_name, -1, get_bg_surface());
+       int folder = mwindow->edl->session->awindow_folder;
+       const char *title = mwindow->edl->get_folder_name(folder);
+       draw_text(get_w() - get_text_width(LARGEFONT, title) - 4, 30,
+               title, -1, get_bg_surface());
 }
 
 int AWindowAssets::drag_start_event()
@@ -2237,6 +2316,18 @@ int AWindowAssets::drag_motion_event()
        mwindow->cwindow->gui->unlock_window();
 
        lock_window("AWindowAssets::drag_motion_event");
+       if( mwindow->session->current_operation == DRAG_ASSET &&
+           gui->folder_list->cursor_above() ) { // highlight user folder
+               int item_no = gui->folder_list->get_cursor_item();
+               if( item_no >= 0 ) {
+                       AssetPicon *folder = (AssetPicon *)gui->folders[item_no];
+                       if( folder->foldernum < AWINDOW_USER_FOLDERS ) item_no = -1;
+               }
+               int folder_xposition = gui->folder_list->get_xposition();
+               int folder_yposition = gui->folder_list->get_yposition();
+               gui->folder_list->update(&gui->folders, 0, 0, 1,
+                       folder_xposition, folder_yposition, item_no, 0, 1);
+       }
        return 0;
 }
 
@@ -2276,6 +2367,10 @@ int AWindowAssets::drag_stop_event()
        }
 
        lock_window("AWindowAssets::drag_stop_event");
+       if( !result ) {
+               result = gui->folder_list->drag_stop();
+       }
+
 
        if( result )
                get_drag_popup()->set_animation(0);
@@ -2370,50 +2465,6 @@ void AWindowSearchText::clear()
        text_box->update("");
 }
 
-AWindowNewFolder::AWindowNewFolder(MWindow *mwindow, AWindowGUI *gui, int x, int y)
- : BC_Button(x, y, mwindow->theme->newbin_data)
-{
-       this->mwindow = mwindow;
-       this->gui = gui;
-       set_tooltip(_("New bin"));
-}
-
-int AWindowNewFolder::handle_event()
-{
-       gui->newfolder_thread->start_new_folder();
-       return 1;
-}
-
-AWindowDeleteFolder::AWindowDeleteFolder(MWindow *mwindow, AWindowGUI *gui, int x, int y)
- : BC_Button(x, y, mwindow->theme->deletebin_data)
-{
-       this->mwindow = mwindow;
-       this->gui = gui;
-       set_tooltip(_("Delete bin"));
-}
-
-int AWindowDeleteFolder::handle_event()
-{
-       if( gui->folder_list->get_selection(0, 0) ) {
-               BC_ListBoxItem *folder = gui->folder_list->get_selection(0, 0);
-               mwindow->delete_folder(folder->get_text());
-       }
-       return 1;
-}
-
-AWindowRenameFolder::AWindowRenameFolder(MWindow *mwindow, AWindowGUI *gui, int x, int y)
- : BC_Button(x, y, mwindow->theme->renamebin_data)
-{
-       this->mwindow = mwindow;
-       this->gui = gui;
-       set_tooltip(_("Rename bin"));
-}
-
-int AWindowRenameFolder::handle_event()
-{
-       return 1;
-}
-
 AWindowDeleteDisk::AWindowDeleteDisk(MWindow *mwindow, AWindowGUI *gui, int x, int y)
  : BC_Button(x, y, mwindow->theme->deletedisk_data)
 {
@@ -2612,7 +2663,7 @@ int AVIconDrawing::handle_event()
 
 
 AWindowListFormat::AWindowListFormat(MWindow *mwindow, AWindowGUI *gui)
- : BC_MenuItem("")
+ : BC_MenuItem("","v",'v')
 {
        this->mwindow = mwindow;
        this->gui = gui;
@@ -2620,37 +2671,7 @@ AWindowListFormat::AWindowListFormat(MWindow *mwindow, AWindowGUI *gui)
 
 int AWindowListFormat::handle_event()
 {
-       gui->stop_vicon_drawing();
-
-       EDLSession *session = mwindow->edl->session;
-       if( mwindow->awindow->gui->allow_iconlisting ) {
-               switch( session->assetlist_format ) {
-               case ASSETS_TEXT:
-                       session->assetlist_format = ASSETS_ICONS;
-                       break;
-               case ASSETS_ICONS:
-                       session->assetlist_format = ASSETS_ICONS_PACKED;
-                       break;
-               case ASSETS_ICONS_PACKED:
-                       session->assetlist_format = ASSETS_ICON_LIST;
-                       break;
-               case ASSETS_ICON_LIST:
-                       session->assetlist_format = ASSETS_TEXT;
-                       break;
-               }
-       }
-       else
-               mwindow->edl->session->assetlist_format = ASSETS_TEXT;
-       gui->asset_list->update_format(session->assetlist_format, 0);
-       int x0 = 0;
-       int x1 = gui->asset_list->get_w();
-       int y0 = gui->asset_list->get_title_h();
-       int y1 = gui->asset_list->get_h();
-       gui->vicon_thread->set_drawing_area(x0,y0, x1,y1);
-
-       gui->async_update_assets();
-       gui->start_vicon_drawing();
-       return 1;
+       return gui->cycle_assetlist_format();
 }
 
 void AWindowListFormat::update()
@@ -2683,7 +2704,7 @@ AWindowListSort::AWindowListSort(MWindow *mwindow, AWindowGUI *gui)
 
 int AWindowListSort::handle_event()
 {
-       gui->sort_assets(0);
+       gui->sort_assets();
        return 1;
 }