|
@@ -193,6 +193,34 @@ int la_AcceptFileFormat(laFileBrowser* fb, char* format){
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
+
|
|
|
+typedef int (*FileSortCompF)(laFileItem* f1,laFileItem* f2);
|
|
|
+int la_filecompname(laFileItem* f1,laFileItem* f2){ return strverscmp(f2->Name, f1->Name); }
|
|
|
+int la_filecompnamerev(laFileItem* f1,laFileItem* f2){ return strverscmp(f1->Name, f2->Name); }
|
|
|
+int la_filecomptime(laFileItem* f1,laFileItem* f2){ return f1->Timestamp - f2->Timestamp; }
|
|
|
+int la_filecomptimerev(laFileItem* f1,laFileItem* f2){ return f2->Timestamp - f1->Timestamp; }
|
|
|
+int la_filecompsize(laFileItem* f1,laFileItem* f2){ return f1->Size - f2->Size; }
|
|
|
+int la_filecompsizerev(laFileItem* f1,laFileItem* f2){ return f2->Size - f1->Size; }
|
|
|
+void la_SortFiles(laFileBrowser* fb, laListHandle* files){
|
|
|
+ laListHandle tmp={0}; laFileItem* fi;
|
|
|
+ FileSortCompF comp = 0;
|
|
|
+ switch(fb->SortBy){
|
|
|
+ case LA_FILE_SORT_NAME: default: comp=la_filecompname; break;
|
|
|
+ case LA_FILE_SORT_NAME_REV: comp=la_filecompnamerev; break;
|
|
|
+ case LA_FILE_SORT_TIME: comp=la_filecomptime; break;
|
|
|
+ case LA_FILE_SORT_TIME_REV: comp=la_filecomptimerev; break;
|
|
|
+ case LA_FILE_SORT_SIZE: comp=la_filecompsize; break;
|
|
|
+ case LA_FILE_SORT_SIZE_REV: comp=la_filecompsizerev; break;
|
|
|
+ }
|
|
|
+ while(fi=lstPopItem(files)){ int inserted=0;
|
|
|
+ for(laFileItem* fii=tmp.pFirst;fii;fii=fii->Hyper.pNext){
|
|
|
+ int a=comp(fii,fi);
|
|
|
+ if(a<0){ lstInsertItemBefore(&tmp,fi,fii); inserted=1; break; }
|
|
|
+ }
|
|
|
+ if(!inserted){ lstAppendItem(&tmp, fi); }
|
|
|
+ }
|
|
|
+ files->pFirst=tmp.pFirst; files->pLast=tmp.pLast;
|
|
|
+}
|
|
|
void la_FileBrowserRebuildList(laFileBrowser *fb){
|
|
|
laFileItem *fi = 0;
|
|
|
laDiskItem *dl = 0;
|
|
@@ -211,7 +239,7 @@ void la_FileBrowserRebuildList(laFileBrowser *fb){
|
|
|
#ifdef __linux__
|
|
|
if (fb->Path[len - 1] != U'/') strcat(fb->Path, "/");
|
|
|
struct dirent **NameList=0;
|
|
|
- int NumFiles=scandir(fb->Path,&NameList,0,alphasort);
|
|
|
+ int NumFiles=scandir(fb->Path,&NameList,0,versionsort);
|
|
|
|
|
|
while (fi = lstPopItem(&fb->FileList)) memFree(fi);
|
|
|
|
|
@@ -236,6 +264,7 @@ void la_FileBrowserRebuildList(laFileBrowser *fb){
|
|
|
fi->Size = s.st_size;
|
|
|
fi->Type = la_DetectFileItemType(format);
|
|
|
|
|
|
+ fi->Timestamp = s.st_ctime;
|
|
|
struct tm *t = localtime(&s.st_ctime);
|
|
|
fi->TimeModified.Year = t->tm_year+1900;
|
|
|
fi->TimeModified.Month = t->tm_mon+1;;
|
|
@@ -295,6 +324,7 @@ void la_FileBrowserRebuildList(laFileBrowser *fb){
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
+ la_SortFiles(fb, &Files);
|
|
|
lstCombineLists(&fb->FileList, &Files);
|
|
|
|
|
|
while (dl = lstPopItem(&fb->Disks)) memFree(dl);
|
|
@@ -446,6 +476,38 @@ void* laset_FileBrowserExtension(laFileBrowser* fb, laExtensionType* et){
|
|
|
void laset_FileBrowserShowBackups(laFileBrowser* fb, int show){
|
|
|
fb->ShowBackups = show; la_FileBrowserRebuildList(fb); laRecalcCurrentPanel();
|
|
|
}
|
|
|
+void laset_FileBrowserSortName(laFileBrowser* fb, int s){
|
|
|
+ if(fb->SortBy==LA_FILE_SORT_NAME) fb->SortBy=LA_FILE_SORT_NAME_REV;
|
|
|
+ else fb->SortBy=LA_FILE_SORT_NAME; la_FileBrowserRebuildList(fb); laRecalcCurrentPanel();
|
|
|
+}
|
|
|
+int laget_FileBrowserSortName(laFileBrowser*fb){
|
|
|
+ if(fb->SortBy==LA_FILE_SORT_NAME) return 1; if(fb->SortBy==LA_FILE_SORT_NAME_REV) return 2; return 0;
|
|
|
+}
|
|
|
+void laset_FileBrowserSortTime(laFileBrowser* fb, int s){
|
|
|
+ if(fb->SortBy==LA_FILE_SORT_TIME) fb->SortBy=LA_FILE_SORT_TIME_REV;
|
|
|
+ else fb->SortBy=LA_FILE_SORT_TIME; la_FileBrowserRebuildList(fb); laRecalcCurrentPanel();
|
|
|
+}
|
|
|
+int laget_FileBrowserSortTime(laFileBrowser*fb){
|
|
|
+ if(fb->SortBy==LA_FILE_SORT_TIME) return 1; if(fb->SortBy==LA_FILE_SORT_TIME_REV) return 2; return 0;
|
|
|
+}
|
|
|
+void laset_FileBrowserSortSize(laFileBrowser* fb, int s){
|
|
|
+ if(fb->SortBy==LA_FILE_SORT_SIZE) fb->SortBy=LA_FILE_SORT_SIZE_REV;
|
|
|
+ else fb->SortBy=LA_FILE_SORT_SIZE; la_FileBrowserRebuildList(fb); laRecalcCurrentPanel();
|
|
|
+}
|
|
|
+int laget_FileBrowserSortSize(laFileBrowser*fb){
|
|
|
+ if(fb->SortBy==LA_FILE_SORT_SIZE) return 1; if(fb->SortBy==LA_FILE_SORT_SIZE_REV) return 2; return 0;
|
|
|
+}
|
|
|
+void laget_FileBrowserFileSizeString(laFileItem* fi, char* content, char** move){
|
|
|
+ if(fi->Size >= (1<<30)){
|
|
|
+ sprintf(content, "%.3lf GB", (real)fi->Size/(1<<30));
|
|
|
+ }elif(fi->Size >= (1<<20)){
|
|
|
+ sprintf(content, "%.3lf MB", (real)fi->Size/(1<<20));
|
|
|
+ }elif(fi->Size >= (1<<10)){
|
|
|
+ sprintf(content, "%.3lf KB", (real)fi->Size/(1<<10));
|
|
|
+ }else{
|
|
|
+ sprintf(content, "%d %s", fi->Size, transLate("Bytes"));
|
|
|
+ }
|
|
|
+}
|
|
|
void la_FileBrowserUpLevel(laFileBrowser *fb){
|
|
|
char *p = fb->Path;
|
|
|
char *LastP = 0;
|
|
@@ -460,6 +522,22 @@ void la_FileBrowserUpLevel(laFileBrowser *fb){
|
|
|
else if(LastP) *(LastP + 1) = 0;
|
|
|
la_FileBrowserRebuildList(fb); fb->FileName[0] = 0;
|
|
|
}
|
|
|
+void la_FileBrowserNewDirectory(laFileBrowser* fb,char* path){
|
|
|
+ char* p=fb->Path;
|
|
|
+ int len =strlen(p);
|
|
|
+#ifdef __linux__
|
|
|
+ if (p[len - 1] != U'/') strcat(p, "/");
|
|
|
+ char usepath[2048]; sprintf(usepath,"%s%s",p,path);
|
|
|
+ if(!mkdir(usepath,S_IRWXU | S_IRWXG | S_IRWXO)){
|
|
|
+ strcpy(fb->Path,usepath);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+#ifdef _WIN32
|
|
|
+ if (p[len - 1] != U'\\') strcat(p, "\\");
|
|
|
+ //...
|
|
|
+#endif
|
|
|
+ la_FileBrowserRebuildList(fb); laRecalcCurrentPanel();
|
|
|
+}
|
|
|
int OPINV_FileBrowser(laOperator *a, laEvent *e){
|
|
|
a->CustomData = la_FileBrowserInit(a);
|
|
|
laEnableOperatorPanel(a, 0, LA_RH2, LA_RH2, 500, 500, 0, 0, 0, 0, LA_RH2, LA_RH2, LA_RH2, LA_RH2, e);
|
|
@@ -506,6 +584,30 @@ int OPINV_FileBrowserUpLevel(laOperator *a, laEvent *e){
|
|
|
}
|
|
|
return LA_FINISHED_PASS;
|
|
|
}
|
|
|
+int OPINV_FileBrowserRefresh(laOperator *a, laEvent *e){
|
|
|
+ if (a->This){
|
|
|
+ la_FileBrowserRebuildList(a->This->EndInstance); laRecalcCurrentPanel();
|
|
|
+ laNotifyUsersPPPath(a->This, "path");
|
|
|
+ }
|
|
|
+ return LA_FINISHED_PASS;
|
|
|
+}
|
|
|
+int OPINV_FileBrowserNewDirectory(laOperator *a, laEvent *e){
|
|
|
+ if (a->This){
|
|
|
+ laEnableOperatorPanel(a,a->This,e->x,e->y,200,200,400,400,0,0,0,0,0,0,e);
|
|
|
+ return LA_RUNNING;
|
|
|
+ }
|
|
|
+ return LA_FINISHED;
|
|
|
+}
|
|
|
+int OPMOD_FileBrowserNewDirectory(laOperator *a, laEvent *e){
|
|
|
+ laFileBrowser* fb=a->This->EndInstance;
|
|
|
+ if (a->ConfirmData){
|
|
|
+ if (a->ConfirmData->Mode == LA_CONFIRM_OK){
|
|
|
+ la_FileBrowserNewDirectory(fb,fb->TempStr);
|
|
|
+ }
|
|
|
+ return LA_FINISHED;
|
|
|
+ }
|
|
|
+ return LA_RUNNING;
|
|
|
+}
|
|
|
int OPCHK_FileBrowserCanConfirm(laPropPack *This, laStringSplitor *ss){
|
|
|
if(!OPCHK_IsFileBrowser(This,ss)) return 0;
|
|
|
laFileBrowser* fb=This->EndInstance;
|
|
@@ -547,6 +649,15 @@ int OPMOD_FileBrowserConfirm(laOperator *a, laEvent *e){
|
|
|
return LA_RUNNING;
|
|
|
}
|
|
|
|
|
|
+void laui_FileBrowserNewDirectory(laUiList *uil, laPropPack *This, laPropPack *Operator, laColumn *UNUSED, int context){
|
|
|
+ laColumn* c=laFirstColumn(uil);
|
|
|
+ laShowItem(uil,c,This,"temp_str");
|
|
|
+ laUiItem* row=laBeginRow(uil,c,0,0);
|
|
|
+ laShowSeparator(uil,c)->Expand=1;
|
|
|
+ laShowItem(uil,c,0,"LA_confirm")->Flags|=LA_UI_FLAGS_HIGHLIGHT;
|
|
|
+ laEndRow(uil,row);
|
|
|
+}
|
|
|
+
|
|
|
void OPEXT_UDFOperation(laOperator *a, laEvent *e){
|
|
|
laUDFPreviewExtra *upe = a->CustomData;
|
|
|
memFree(upe);
|
|
@@ -2247,6 +2358,9 @@ void la_RegisterBuiltinOperators(){
|
|
|
|
|
|
laCreateOperatorType("LA_view_hyper_data", "View Hyper Data", "Show Properties Of Specific Data Block", OPCHK_IsHyper, 0, 0, OPINV_ViewHyperData, 0, U'🛈', LA_ACTUATOR_SYSTEM);
|
|
|
|
|
|
+ at = laCreateOperatorType("LA_file_dialog_new_directory", "New Directory", "New Directory", OPCHK_IsFileBrowser, 0, 0, OPINV_FileBrowserNewDirectory, OPMOD_FileBrowserNewDirectory, U'📁', LA_ACTUATOR_SYSTEM | LA_ACTUATOR_HIDDEN);
|
|
|
+ at->UiDefine = laui_FileBrowserNewDirectory;
|
|
|
+ laCreateOperatorType("LA_file_dialog_refresh", "Refresh", "Refresh List", OPCHK_IsFileBrowser, 0, 0, OPINV_FileBrowserRefresh, 0, U'🗘', LA_ACTUATOR_SYSTEM | LA_ACTUATOR_HIDDEN);
|
|
|
laCreateOperatorType("LA_file_dialog_up", "Up", "Select Upper Folder Level", OPCHK_IsFileBrowser, 0, 0, OPINV_FileBrowserUpLevel, 0, U'🢰', LA_ACTUATOR_SYSTEM | LA_ACTUATOR_HIDDEN);
|
|
|
laCreateOperatorType("LA_file_dialog_confirm", "Confirm", "Confirm selection", OPCHK_FileBrowserCanConfirm, 0, 0, OPINV_FileBrowserConfirm, OPMOD_FileBrowserConfirm, U'✔', LA_ACTUATOR_SYSTEM | LA_ACTUATOR_HIDDEN);
|
|
|
at = laCreateOperatorType("LA_file_dialog", "File Dialog", "Do File Operations", 0, 0, OPEXT_FileBrowser, OPINV_FileBrowser, OPMOD_FileBrowser, U'🗐', LA_ACTUATOR_SYSTEM);
|
|
@@ -2256,6 +2370,7 @@ void la_RegisterBuiltinOperators(){
|
|
|
|
|
|
laAddStringProperty(pc, "path", "Path", "Directort Path", 0, 0, 0, "/", 0, offsetof(laFileBrowser, Path), 0, 0, laset_FileBrowserPath, 0, LA_UDF_LOCAL);
|
|
|
laAddStringProperty(pc, "file_name", "File Name", "File Name", 0, 0, 0, 0, 0, offsetof(laFileBrowser, FileName), 0, 0, laset_FileBrowserFileName, 0, LA_UDF_LOCAL);
|
|
|
+ laAddStringProperty(pc, "temp_str", "Temp String", "Temp String", 0, 0, 0, "", 0, offsetof(laFileBrowser, TempStr), 0, 0, 0, 0, LA_UDF_LOCAL);
|
|
|
laAddSubGroup(pc, "file_list", "File List", "List Of Files And Directories Under A Specific Path", "file_item",0,0,laui_FileBrowserFileItem, -1, 0, laget_FileBrowserActiveFile, 0, 0, 0, laset_FileBrowserSelectFile, offsetof(laFileBrowser, FileList), 0);
|
|
|
laAddSubGroup(pc, "disk_list", "Disk List", "List Of All Logical Drives (In Windows)", "disk_item",0, 0, 0, -1, 0, 0, 0, 0, 0, laset_FileBrowserActiveDisk, offsetof(laFileBrowser, Disks), 0);
|
|
|
laAddSubGroup(pc, "bookmarks", "Bookmarks", "Bookmarked directories in GTK3", "bookmarked_folder",0, 0, 0, -1, 0, 0, 0, laset_FileBrowserBookmark, 0, 0, offsetof(laFileBrowser, Bookmarks), 0);
|
|
@@ -2265,6 +2380,8 @@ void la_RegisterBuiltinOperators(){
|
|
|
laAddEnumItemAs(ep, "file", "File", "File", LA_FILE_SELECT_FILE, U'📁');
|
|
|
laAddEnumItemAs(ep, "folder", "Folder", "Folder", LA_FILE_SELECT_FOLDER, U'🖹');
|
|
|
}
|
|
|
+ laAddOperatorProperty(pc, "new_directory", "New Directory", "Create a new directory", "LA_file_dialog_new_directory", U'📁', 0);
|
|
|
+ laAddOperatorProperty(pc, "refresh", "Refresh", "Refresh file list", "LA_file_dialog_refresh", U'🗘', 0);
|
|
|
laAddOperatorProperty(pc, "folder_up", "Up", "Select Upper Folder Level In File Browsers", "LA_file_dialog_up", U'🢰', 0);
|
|
|
laAddOperatorProperty(pc, "confirm", "Confirm", "Confirm selection", "LA_file_dialog_confirm", U'✔', 0);
|
|
|
p = laAddPropertyContainer("disk_item", "Disk Item", "A Logical Drive (In Windows)", 0, laui_FileBrowserDiskItem, 0, 0, 0, 1);{
|
|
@@ -2277,6 +2394,7 @@ void la_RegisterBuiltinOperators(){
|
|
|
laAddIntProperty(p, "is_folder", "Is Folder", "File Is A Folder Or Actual File", 0, 0, 0, 1, 0, 0, 0, 0, offsetof(laFileItem, IsFolder), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,LA_READ_ONLY);
|
|
|
laAddSubGroup(p, "time_modified", "Time Last Modified", "The Time When The File Was Last Modified", "time_info",0, 0, 0, offsetof(laFileItem, TimeModified), 0, 0, 0, 0, 0, 0, 0, LA_UDF_LOCAL);
|
|
|
laAddIntProperty(p, "size", "Size", "File Size In Bytes", 0, 0, "Bytes", 0, 0, 0, 0, 0, offsetof(laFileItem, Size), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,LA_READ_ONLY);
|
|
|
+ laAddStringProperty(p, "size_string", "Size String", "File size in convenient string", 0, 0, 0, 0, 0, 0, 0, laget_FileBrowserFileSizeString, 0, 0, LA_READ_ONLY);
|
|
|
ep = laAddEnumProperty(p, "type", "Type", "General Type Of The File", 0, 0, 0, 0, 0, offsetof(laFileItem, Type), 0, 0, 0, 0, 0, 0, 0, 0, 0,LA_READ_ONLY);{
|
|
|
laAddEnumItemAs(ep, "unknown", "Unknown", "Unknown/Uncategorized File Type", LA_FILETYPE_UNKNOWN, U'🖹');
|
|
|
laAddEnumItemAs(ep, "udf", "UDF", "Uniform Data Format", LA_FILETYPE_UDF, U'📦');
|
|
@@ -2305,6 +2423,21 @@ void la_RegisterBuiltinOperators(){
|
|
|
laAddEnumItemAs(ep, "NONE", "None", "Don't show backup files", 0, 0);
|
|
|
laAddEnumItemAs(ep, "SHOWN", "Shown", "Show backup files", 1, U'~');
|
|
|
}
|
|
|
+ ep = laAddEnumProperty(pc, "sort_name", "Name", "Sort by names",LA_WIDGET_ENUM_CYCLE, 0, 0, 0, 0, 0, laget_FileBrowserSortName,laset_FileBrowserSortName, 0, 0, 0, 0, 0, 0, 0,0);{
|
|
|
+ laAddEnumItemAs(ep, "NONE", "None", "Don't sort", 0, 0);
|
|
|
+ laAddEnumItemAs(ep, "SORT", "Sort", "Sort accending", 1, U'🔻');
|
|
|
+ laAddEnumItemAs(ep, "REV", "Reversed", "Sort Descending", 2, U'🔺');
|
|
|
+ }
|
|
|
+ ep = laAddEnumProperty(pc, "sort_time", "Time", "Sort by times",LA_WIDGET_ENUM_CYCLE, 0, 0, 0, 0, 0, laget_FileBrowserSortTime,laset_FileBrowserSortTime, 0, 0, 0, 0, 0, 0, 0,0);{
|
|
|
+ laAddEnumItemAs(ep, "NONE", "None", "Don't sort", 0, 0);
|
|
|
+ laAddEnumItemAs(ep, "SORT", "Sort", "Sort accending", 1, U'🔻');
|
|
|
+ laAddEnumItemAs(ep, "REV", "Reversed", "Sort Descending", 2, U'🔺');
|
|
|
+ }
|
|
|
+ ep = laAddEnumProperty(pc, "sort_size", "Size", "Sort by sizes",LA_WIDGET_ENUM_CYCLE, 0, 0, 0, 0, 0, laget_FileBrowserSortSize,laset_FileBrowserSortSize, 0, 0, 0, 0, 0, 0, 0,0);{
|
|
|
+ laAddEnumItemAs(ep, "NONE", "None", "Don't sort", 0, 0);
|
|
|
+ laAddEnumItemAs(ep, "SORT", "Sort", "Sort accending", 1, U'🔻');
|
|
|
+ laAddEnumItemAs(ep, "REV", "Reversed", "Sort Descending", 2, U'🔺');
|
|
|
+ }
|
|
|
|
|
|
at = laCreateOperatorType("LA_udf_read", "Read", "Read a UDF file", 0, 0, OPEXT_UDFOperation, OPINV_UDFRead, OPMOD_UDFRead, U'📑', LA_ACTUATOR_SYSTEM);
|
|
|
pc = laDefineOperatorProps(at, 0);
|