📄 filemgr.c
字号:
/* filemgr.c -- File manager Copyright (C) 1996 Nadav Cohen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "filemgr.h"#include "screen.h"#include "window.h"#include "list.h"#include "config.h"#include "error.h"#include <stdio.h>#include <stdlib.h>#include <dirent.h>#include <errno.h>#include <time.h>#include <sys/stat.h>#include <unistd.h>#include <string.h>class tName : public tListObj { public: char Directory; char *Name; long Time; int Size; char Tag; ~tName();};int CurrentNumber, BarY, LastY;long int UploadSize;tName *CurrentName;tList Files;char PWD[256];struct stat Stat;tName::~tName(){// free(Name);}void DestroyList(){ tName *Tmp, *Temp; int i; Tmp = (tName *)Files.Base; for (i=0;i<Files.Total;i++) { Temp = (tName *)Tmp->Next; free(Tmp->Name);// delete Tmp; Tmp = Temp; } Files.Total = 0; Files.Base = NULL; Files.Last = NULL;}int isdir(tName *Name){ stat(Name->Name, &Stat); Name->Time = Stat.st_ctime; Name->Size = Stat.st_size; Name->Tag = 0; Name->Directory = 0; if (S_ISDIR(Stat.st_mode)){ Name->Directory = 1; return 0; } return -1;}int Scandir(char *Name){ tName *Tmp; DIR *dir; struct dirent *Entry; if ((dir = opendir(Name)) != NULL){ chdir(Name); rewinddir(dir); while((Entry = readdir(dir)) != NULL){ if (strcmp(Entry->d_name, ".") != 0){ Tmp = new tName; Tmp->Name = (char *)malloc(strlen(Entry->d_name)+1); strcpy(Tmp->Name, Entry->d_name); isdir(Tmp); Files.Add(Tmp); } } closedir(dir); } else { WindowError(FileScreen, "Unable to opendir"); return -1; } return 0;};void ShowFile(tName *Name, int Y){ char Temp[256]; tm *Time; int i; for (i=1;i<COLS-1;i++) mvwaddch(FileScreen, Y, i, ' '); wnoutrefresh(FileScreen); wmove(FileScreen, Y, 2); Time = localtime(&Name->Time); sprintf(Temp, "%02d-%02d-%04d %02d:%02d", Time->tm_mday, Time->tm_mon, Time->tm_year+1900, Time->tm_hour, Time->tm_min); waddstr(FileScreen, Temp); sprintf(Temp, "%d", Name->Size); wmove(FileScreen, Y, 29-strlen(Temp)); waddstr(FileScreen, Temp); wnoutrefresh(FileScreen); if (strlen(Name->Name)<40) strcpy(Temp, Name->Name); else { strncpy(Temp, Name->Name, 40); Temp[40]=0; } wmove(FileScreen, Y, 30); if (Name->Tag) waddch(FileScreen, Integers[TagChar]); else waddch(FileScreen, ' '); wnoutrefresh(FileScreen); wmove(FileScreen, Y, 31); waddstr(FileScreen, Temp); if (Name->Directory) waddch(FileScreen,'/');}void PaintMgrBar(){ int i; tName *Tmp; Tmp = CurrentName; for (i=0;i<LastY-1;i++) Tmp = (tName *)Tmp->Next; textAttr(FileScreen, Integers[cMenuText]); ShowFile(Tmp, LastY); Tmp = CurrentName; for (i=0;i<BarY-1;i++) Tmp = (tName *)Tmp->Next; textAttr(FileScreen, Integers[cMenuBar]); ShowFile(Tmp, BarY); LastY = BarY; wrefresh(FileScreen);}void ShowMgr(){ int i, j; tName *Tmp; textAttr(FileScreen, Integers[cMenu]); for (i=2;i<24;i++) for (j=0;j<COLS;j++) mvwaddch(FileScreen, i, j, ' '); wnoutrefresh(FileScreen); box(FileScreen, SVLINE, SHLINE); textAttr(FileScreen, Integers[cMenuText]); wmove(FileScreen, LINES-2, 2); waddstr(FileScreen, " +-* Time in cps "); wmove(FileScreen, 0, COLS-8); wnoutrefresh(FileScreen);// wrefresh(FileScreen); switch(Integers[FileMgrSort]){ case 0: waddstr(FileScreen, "Name"); break; case 1: waddstr(FileScreen, "Size"); break; case 2: waddstr(FileScreen, "Date"); break; default:break; } Tmp = CurrentName; for (i=0;i<22 && i+CurrentNumber<Files.Total;i++) { ShowFile(Tmp, i+1); wnoutrefresh(FileScreen); Tmp = (tName *)Tmp->Next; } PaintMgrBar(); textAttr(FileScreen, Integers[cMenuTitle]); wmove(FileScreen, 0, 2); waddstr(FileScreen, PWD); wrefresh(FileScreen);}int CompareNames(tName *I, tName *J){ if (strcmp(I->Name, "..") == 0) return -1; if (strcmp(J->Name, "..") == 0) return 1; if (I->Directory && !J->Directory) return -1; if (!I->Directory && J->Directory) return 1; return(strcasecmp(I->Name, J->Name));}int CompareSizes(tName *I, tName *J){ if (strcmp(I->Name, "..") == 0) return -1; if (strcmp(J->Name, "..") == 0) return 1; if (I->Directory && !J->Directory) return -1; if (!I->Directory && J->Directory) return 1; if (I->Size > J->Size) return 1; if (I->Size == J->Size) return 0; if (I->Size < J->Size) return -1; return 0;}int CompareDates(tName *I, tName *J){ if (strcmp(I->Name, "..") == 0) return -1; if (strcmp(J->Name, "..") == 0) return 1; if (I->Directory && !J->Directory) return -1; if (!I->Directory && J->Directory) return 1; if (I->Time > J->Time) return 1; if (I->Time == J->Time) return 0; if (I->Time < J->Time) return -1; return 0;}void Swap(tName *First, tName *Second){ tName *Next, *Prev; /* memmove(&Tmp, First, sizeof(tName)); memmove(First, Second, sizeof(tName)); memmove(Second, &Tmp, sizeof(tName)); Second->Prev = First->Prev; Second->Next = First->Next; First->Prev = Tmp.Prev; First->Next = Tmp.Next;*/ if (First->Next == Second){ Next = (tName *)Second->Next; Second->Next = First; Second->Prev = First->Prev; First->Next = Next; First->Prev = Second; } else if (Second->Next == First){ Next = (tName *)First->Next; First->Next = Second; First->Prev = Second->Prev; Second->Next = Next; Second->Prev = First; } else{ Prev = (tName *)First->Prev; Next = (tName *)First->Next; First->Next = Second->Next; First->Prev = Second->Prev; Second->Next = Next; Second->Prev = Prev; } if (First->Prev != NULL) First->Prev->Next = First; if (First->Next != NULL) First->Next->Prev = First; if (Second->Prev != NULL) Second->Prev->Next = Second; if (Second->Next != NULL) Second->Next->Prev = Second; if (Files.Base == First) Files.Base = Second; else if (Files.Base == Second) Files.Base = First; if (Files.Last == First) Files.Last = Second; else if (Files.Last == Second) Files.Last = First;}void SortAscending(int Low, int High, int cmp(tName *I, tName *J)){ tName *CurrentI, *CurrentJ, *Middle; tListObj *SaveI, *SaveJ; int i,j; CurrentI = (tName *)Files.Base; for (i=1;i<Low;i++) CurrentI = (tName *)CurrentI->Next; Middle = (tName *)Files.Base; for (i=1;i<(High+Low)/2;i++) Middle = (tName *)Middle->Next; CurrentJ = (tName *)Files.Base; for (i=1;i<High;i++) CurrentJ = (tName *)CurrentJ->Next; i = Low; j = High; do { while (cmp(CurrentI, Middle)<0) { i++; CurrentI = (tName *)CurrentI->Next; } while (cmp(CurrentJ, Middle)>0) { j--; CurrentJ = (tName *)CurrentJ->Prev; } if (i<=j) { SaveI = CurrentI->Next; SaveJ = CurrentJ->Prev; Swap(CurrentI, CurrentJ); i++; j--; // This is reversed for a reason, do NOT change CurrentI = (tName *)SaveI; CurrentJ = (tName *)SaveJ; } }while(i<=j); if (Low<j) SortAscending(Low, j, cmp); if (i<High) SortAscending(i, High, cmp);}void SortFiles(){ if (Files.Total > 1) switch(Integers[FileMgrSort]){ case 0: SortAscending(1,Files.Total,CompareNames); break; case 1: SortAscending(1,Files.Total,CompareSizes); break; case 2: SortAscending(1,Files.Total,CompareDates); break; default:break; }}void EnterCPS(char *Putin){ tWindow *Win; int Center, Exit, i; char Temp[20]; Center = findCenter(1,COLS,5); Win = new tWindow(FileScreen, Center, (LINES/2)-1, Center+10, (LINES/2)+1, Integers[cInfoBold] >> 4,Integers[cInfoBold] % 16); Win->Frame(2, Integers[cInfoBold]); Win->Headline("CPS", Integers[cInfoBold]); wrefresh(FileScreen); textAttr(FileScreen, Integers[cInfoBold]); Exit = 0; i = 0; Temp[0]=0; switch(getstring(FileScreen, LINES/2,Center+1,Temp,NumberEdit,"\n\e\t",5,-1,Temp)){ case '\e': Exit = 1; break; case '\n': Exit = 2; break; default:break; } if (Exit == 2) strcpy(Putin, Temp); delete Win;}void FileMgr(char **Filename, char *Name, char SpaceTag){ int i,j, Key, Refresh; char Temp[256]; tName *Tmp; // Files.~tList(); nl(); if (Scandir(Name) == 0){ CurrentName = (tName *)Files.Base; CurrentNumber = 0; BarY = 1; LastY = 1; getcwd(PWD, 255); SortFiles(); clearok(FileScreen, TRUE); ShowMgr(); curs_set(1); wrefresh(FileScreen); Key = 0; Refresh = 0; curs_set(0); while (Key != '\e'){ Key = getEscChar(); switch(Key){ case KEY_DOWN: DOWN: if (CurrentNumber+BarY<Files.Total){ if (BarY<LINES-3){ BarY++; Refresh = 1; } else { CurrentName = (tName *)CurrentName->Next; CurrentNumber++; Refresh = 2; } } break; case KEY_UP: if (CurrentNumber+BarY-1>0){ if (BarY>1){ BarY--; Refresh = 1; } else { CurrentName = (tName *)CurrentName->Prev; CurrentNumber--; Refresh = 2; } } break; case KEY_HOME: HOME: CurrentNumber = 0; CurrentName = (tName *)Files.Base; BarY = 1; Refresh = 2; break; case KEY_END: END: if (Files.Total > 21){ CurrentNumber = Files.Total-22; CurrentName =(tName *)Files.Last; BarY = 22; for (i=0;i<21;i++) CurrentName = (tName *)CurrentName->Prev; } else { CurrentNumber = 0; CurrentName = (tName *)Files.Base; BarY = Files.Total; } Refresh = 2; break; case KEY_PPAGE: if (CurrentNumber-22>0){ CurrentNumber-=22; for (i=0;i<22;i++) CurrentName = (tName *)CurrentName->Prev; } else goto HOME; Refresh = 2; break; case KEY_NPAGE: if (CurrentNumber+BarY+22<Files.Total){ CurrentNumber+=22; for (i=0;i<22;i++) CurrentName = (tName *)CurrentName->Next; } else goto END; Refresh = 2; break; case ' ': if (SpaceTag){ Refresh = 1; Tmp = CurrentName; for (i=0;i<BarY-1;i++) Tmp = (tName *)Tmp->Next; if (!Tmp->Directory){ Tmp->Tag = Tmp->Tag ^ 1; if (Integers[TagAdvance]) goto DOWN; } } break; case '+': if (SpaceTag){ Tmp = (tName *)Files.Base; for (i=0;i<Files.Total;i++) { if (!Tmp->Directory) Tmp->Tag = 1; Tmp = (tName *)Tmp->Next; } Refresh = 2; } break; case '-': if (SpaceTag){ Tmp = (tName *)Files.Base; for (i=0;i<Files.Total;i++) { Tmp->Tag = 0; Tmp = (tName *)Tmp->Next; } Refresh = 2; } break; case '*': if (SpaceTag){ Tmp = (tName *)Files.Base; for (i=0;i<Files.Total;i++) { if (!Tmp->Directory) Tmp->Tag = Tmp->Tag ^ 1; Tmp = (tName *)Tmp->Next; } Refresh = 2; } break; case '\n': Tmp = CurrentName; for (i=0;i<BarY-1;i++) Tmp = (tName *)Tmp->Next; if (Tmp->Directory){ chdir(Tmp->Name); getcwd(PWD,255); DestroyList(); Scandir(PWD); SortFiles(); CurrentName = (tName *)Files.Base; CurrentNumber = 0; BarY = 1; LastY = 1; Refresh = 2; } else if (!SpaceTag){ Tmp->Tag = 1; Key = '\e'; } break; case 't': case 'T': if (SpaceTag){ EnterCPS(Temp); textAttr(FileScreen, Integers[cMenuText]); Tmp = (tName *)Files.Base; j = 0; for (i=0;i<Files.Total;i++) { if (Tmp->Tag) j+=Tmp->Size; Tmp = (tName *)Tmp->Next; } wmove(FileScreen, LINES-2, 30); waddstr(FileScreen, "Total size: "); i = atoi(Temp); if (i == 0) i = 1; sprintf(Temp, "%d ", j); waddstr(FileScreen, Temp); waddstr(FileScreen, "Total time: "); j /= i; sprintf(Temp, "%02d:%02d:%02d", j / 3600, j / 60, j % 60); waddstr(FileScreen, Temp); wrefresh(FileScreen); getEscChar(); Refresh = 2; } break; case 's': case 'S': Integers[FileMgrSort]++; if (Integers[FileMgrSort] == 3) Integers[FileMgrSort] = 0; SortFiles(); CurrentName = (tName *)Files.Base; CurrentNumber = 0; BarY = 1; LastY = 1; Refresh = 2; break; default:break; } if (Refresh == 1) PaintMgrBar(); if (Refresh == 2) ShowMgr(); if (Refresh != 0) wrefresh(FileScreen); Refresh = 0; } curs_set(1); Tmp = (tName *)Files.Base; j = 0; UploadSize = 0; for (i = 0; i < Files.Total; i++){ if (Tmp->Tag){ j += strlen(Tmp->Name); UploadSize += Tmp->Size; } Tmp = (tName *)Tmp->Next; } Tmp = (tName *)Files.Base; *Filename = (char *)malloc(j+1); **Filename = '\0'; strcpy(*Filename, ""); for (i=0;i<Files.Total;i++){ if ((Tmp->Tag) && (strlen(*Filename)+strlen(Tmp->Name) < 255)){ strcat(*Filename, Tmp->Name); strcat(*Filename, " "); } Tmp = (tName *)Tmp->Next; } if (!SpaceTag) *(*Filename+strlen(*Filename)-1) = '\0'; DestroyList(); } nonl();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -