mirror of
https://github.com/edeproject/ede.git
synced 2023-08-10 21:13:03 +03:00
Show free space on statusbar, attempt to cleanup filesystem functions
(to be continued...), use some of the new edelib stuff (to be continued...)
This commit is contained in:
parent
2d24cd2dc2
commit
ec01a20142
@ -17,6 +17,8 @@
|
|||||||
#include <sys/time.h> // timer
|
#include <sys/time.h> // timer
|
||||||
#include <unistd.h> // edelib/Run needs it :(
|
#include <unistd.h> // edelib/Run needs it :(
|
||||||
#include <sys/resource.h> // for core
|
#include <sys/resource.h> // for core
|
||||||
|
#include <sys/vfs.h> // used for statfs()
|
||||||
|
|
||||||
|
|
||||||
#include <Fl/Fl.H>
|
#include <Fl/Fl.H>
|
||||||
#include <Fl/Fl_Double_Window.H>
|
#include <Fl/Fl_Double_Window.H>
|
||||||
@ -30,7 +32,9 @@
|
|||||||
#include <edelib/Nls.h>
|
#include <edelib/Nls.h>
|
||||||
#include <edelib/MimeType.h>
|
#include <edelib/MimeType.h>
|
||||||
#include <edelib/String.h>
|
#include <edelib/String.h>
|
||||||
|
#include <edelib/StrUtil.h>
|
||||||
#include <edelib/Run.h>
|
#include <edelib/Run.h>
|
||||||
|
#include <edelib/File.h>
|
||||||
|
|
||||||
#include "EDE_FileView.h"
|
#include "EDE_FileView.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
@ -49,10 +53,6 @@ bool semaphore;
|
|||||||
bool dirsfirst;
|
bool dirsfirst;
|
||||||
bool ignorecase;
|
bool ignorecase;
|
||||||
|
|
||||||
// These variables are global to save time on construction/destruction
|
|
||||||
edelib::MimeType mime_resolver;
|
|
||||||
struct stat buf;
|
|
||||||
|
|
||||||
|
|
||||||
// constants
|
// constants
|
||||||
|
|
||||||
@ -63,15 +63,91 @@ const int statusbar_height = 24;
|
|||||||
const int statusbar_width = 400;
|
const int statusbar_width = 400;
|
||||||
|
|
||||||
|
|
||||||
// This is just a temporary fix so that efiler works atm.
|
/*-----------------------------------------------------------------
|
||||||
|
Filesystem functions
|
||||||
|
-------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// Read filesystems - adapted from fltk file chooser
|
||||||
|
char filesystems[50][PATH_MAX]; // must be global
|
||||||
|
int get_filesystems() {
|
||||||
|
FILE *mtab; // /etc/mtab or /etc/mnttab file
|
||||||
|
|
||||||
|
// Results are cached in a static array
|
||||||
|
static int fs_number=0;
|
||||||
|
|
||||||
|
// On first access read filesystems
|
||||||
|
if (fs_number == 0) {
|
||||||
|
mtab = fopen("/etc/mnttab", "r"); // Fairly standard
|
||||||
|
if (mtab == NULL)
|
||||||
|
mtab = fopen("/etc/mtab", "r"); // More standard
|
||||||
|
if (mtab == NULL)
|
||||||
|
mtab = fopen("/etc/fstab", "r"); // Otherwise fallback to full list
|
||||||
|
if (mtab == NULL)
|
||||||
|
mtab = fopen("/etc/vfstab", "r"); // Alternate full list file
|
||||||
|
|
||||||
|
char line[PATH_MAX]; // Input line
|
||||||
|
char device[PATH_MAX], mountpoint[PATH_MAX], fs[PATH_MAX];
|
||||||
|
while (mtab!= NULL && fgets(line, sizeof(line), mtab) != NULL) {
|
||||||
|
if (line[0] == '#' || line[0] == '\n')
|
||||||
|
continue;
|
||||||
|
if (sscanf(line, "%s%s%s", device, mountpoint, fs) != 3)
|
||||||
|
continue;
|
||||||
|
strcpy(filesystems[fs_number],mountpoint);
|
||||||
|
fs_number++;
|
||||||
|
}
|
||||||
|
fclose (mtab);
|
||||||
|
|
||||||
|
if (fs_number == 0) return 0; // error reading mtab/fstab
|
||||||
|
}
|
||||||
|
return fs_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Get mount point of filesystem for given file
|
||||||
|
const char* find_fs_for(const char* file) {
|
||||||
|
int fs_number = get_filesystems();
|
||||||
|
if (fs_number==0) return 0; // error reading mtab/fstab
|
||||||
|
|
||||||
|
// Find filesystem for file (largest mount point match)
|
||||||
|
char *max;
|
||||||
|
int maxlen = 0;
|
||||||
|
for (int i=0; i<fs_number; i++) {
|
||||||
|
int mylen = strlen(filesystems[i]);
|
||||||
|
if ((strncmp(file,filesystems[i],mylen)==0) && (mylen>maxlen)) {
|
||||||
|
maxlen=mylen;
|
||||||
|
max = (char*)filesystems[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (maxlen == 0) return 0; // doesn't match any fs? there should always be root
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Tests if two files are on the same filesystem
|
||||||
|
bool is_on_same_fs(const char* file1, const char* file2) {
|
||||||
|
const char* fs1 = find_fs_for(file1);
|
||||||
|
// See if file2 matches the same filesystem
|
||||||
|
return (strncmp(file1,fs1,strlen(fs1))==0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------
|
||||||
|
"Simple opener" - keep a list of openers in text file
|
||||||
|
This is just a temporary fix so that efiler works atm.
|
||||||
|
-------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// These variables are global to save time on construction/destruction
|
||||||
|
edelib::MimeType mime_resolver;
|
||||||
|
struct stat stat_buffer;
|
||||||
|
|
||||||
struct sopeners {
|
struct sopeners {
|
||||||
char* type;
|
char* type;
|
||||||
char* opener;
|
char* opener;
|
||||||
sopeners* next;
|
sopeners* next;
|
||||||
} *openers=0;
|
} *openers=0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
char *simpleopener(const char* mimetype) {
|
char *simpleopener(const char* mimetype) {
|
||||||
sopeners* p;
|
sopeners* p;
|
||||||
if (!openers) {
|
if (!openers) {
|
||||||
@ -112,17 +188,17 @@ char *simpleopener(const char* mimetype) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------
|
||||||
|
LoadDir()
|
||||||
|
-------------------------------------------------------------------*/
|
||||||
|
|
||||||
// modification of versionsort which ignores case
|
// modification of versionsort which ignores case
|
||||||
void lowercase(char* s) {
|
|
||||||
for (int i=0;i<strlen(s);i++)
|
|
||||||
if (s[i]>='A' && s[i]<='Z') s[i] += 'a'-'A';
|
|
||||||
}
|
|
||||||
int myversionsort(const void *a, const void *b) {
|
int myversionsort(const void *a, const void *b) {
|
||||||
struct dirent** ka = (struct dirent**)a;
|
struct dirent** ka = (struct dirent**)a;
|
||||||
struct dirent** kb = (struct dirent**)b;
|
struct dirent** kb = (struct dirent**)b;
|
||||||
char *ma = strdup((*ka)->d_name);
|
char* ma = strdup((*ka)->d_name);
|
||||||
char *mb = strdup((*kb)->d_name);
|
char* mb = strdup((*kb)->d_name);
|
||||||
lowercase(ma); lowercase(mb);
|
edelib::str_tolower((unsigned char*)ma); edelib::str_tolower((unsigned char*)mb);
|
||||||
int k = strverscmp(ma,mb);
|
int k = strverscmp(ma,mb);
|
||||||
free(ma); free(mb);
|
free(ma); free(mb);
|
||||||
return k;
|
return k;
|
||||||
@ -203,18 +279,18 @@ fprintf (stderr, "loaddir(%s) = (%s)\n",path,current_dir);
|
|||||||
char fullpath[FL_PATH_MAX];
|
char fullpath[FL_PATH_MAX];
|
||||||
snprintf (fullpath,FL_PATH_MAX-1,"%s%s",current_dir,n);
|
snprintf (fullpath,FL_PATH_MAX-1,"%s%s",current_dir,n);
|
||||||
|
|
||||||
if (stat(fullpath,&buf)) continue; // error
|
if (stat(fullpath,&stat_buffer)) continue; // error
|
||||||
|
|
||||||
FileItem *item = new FileItem;
|
FileItem *item = new FileItem;
|
||||||
item->name = n;
|
item->name = n;
|
||||||
item->realpath = fullpath;
|
item->realpath = fullpath;
|
||||||
item->date = nice_time(buf.st_mtime);
|
item->date = nice_time(stat_buffer.st_mtime);
|
||||||
item->permissions = ""; // todo
|
item->permissions = ""; // todo
|
||||||
if (strcmp(n,"..")==0) {
|
if (strcmp(n,"..")==0) {
|
||||||
item->icon = "undo";
|
item->icon = "undo";
|
||||||
item->description = "Go up";
|
item->description = "Go up";
|
||||||
item->size = "";
|
item->size = "";
|
||||||
} else if (S_ISDIR(buf.st_mode)) { // directory
|
} else if (S_ISDIR(stat_buffer.st_mode)) { // directory
|
||||||
item->icon = "folder";
|
item->icon = "folder";
|
||||||
item->description = "Directory";
|
item->description = "Directory";
|
||||||
// item->name += "/";
|
// item->name += "/";
|
||||||
@ -222,7 +298,7 @@ fprintf (stderr, "loaddir(%s) = (%s)\n",path,current_dir);
|
|||||||
} else {
|
} else {
|
||||||
item->icon = "unknown";
|
item->icon = "unknown";
|
||||||
item->description = "Unknown";
|
item->description = "Unknown";
|
||||||
item->size = nice_size(buf.st_size);
|
item->size = nice_size(stat_buffer.st_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
item_list[fsize++] = item;
|
item_list[fsize++] = item;
|
||||||
@ -251,6 +327,8 @@ fprintf (stderr, "loaddir(%s) = (%s)\n",path,current_dir);
|
|||||||
mime_resolver.set(item_list[i]->realpath.c_str());
|
mime_resolver.set(item_list[i]->realpath.c_str());
|
||||||
edelib::String desc,icon;
|
edelib::String desc,icon;
|
||||||
desc = mime_resolver.comment();
|
desc = mime_resolver.comment();
|
||||||
|
// First letter of desc should be upper case:
|
||||||
|
if (desc[0]>='a' && desc[0]<='z') desc[0] = desc[0]-'a'+'A';
|
||||||
icon = mime_resolver.icon_name();
|
icon = mime_resolver.icon_name();
|
||||||
if (desc!="" || icon!="") {
|
if (desc!="" || icon!="") {
|
||||||
if (desc != "") item_list[i]->description = desc;
|
if (desc != "") item_list[i]->description = desc;
|
||||||
@ -267,8 +345,18 @@ fprintf (stderr, "ICON: %s !!!!!\n", icon.c_str());
|
|||||||
delete[] item_list;
|
delete[] item_list;
|
||||||
semaphore=false;
|
semaphore=false;
|
||||||
|
|
||||||
// TODO Get free space for statusbar
|
// TODO Attempt to cache the results in a meaningful way
|
||||||
statusbar->label(_("Ready."));
|
static struct statfs statfs_buffer;
|
||||||
|
if (statfs(current_dir, &statfs_buffer)==0) {
|
||||||
|
double totalsize = double(statfs_buffer.f_bsize) * statfs_buffer.f_blocks;
|
||||||
|
double freesize = double(statfs_buffer.f_bsize) * statfs_buffer.f_bavail; // This is what df returns
|
||||||
|
// f_bfree is size available to root
|
||||||
|
double percent = double(statfs_buffer.f_blocks-statfs_buffer.f_bavail)/statfs_buffer.f_blocks*100;
|
||||||
|
char *tmp = strdup(nice_size(totalsize)); // nice_size() operates on a static char buffer, we can't use two calls at the same time
|
||||||
|
statusbar->label(tasprintf(_("Filesystem %s, Size %s, Free %s (%4.1f%% used)"), find_fs_for(current_dir), tmp, nice_size(freesize), percent));
|
||||||
|
free(tmp);
|
||||||
|
} else
|
||||||
|
statusbar->label(_("Error reading filesystem information!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -285,10 +373,6 @@ char **cut_copy_buffer = 0;
|
|||||||
bool operation_is_copy = false;
|
bool operation_is_copy = false;
|
||||||
|
|
||||||
|
|
||||||
// Yada n'exist cest pas
|
|
||||||
bool fl_filename_exist(const char* file) { return (stat(file,&buf)==0); }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Execute cut or copy operation when List View is active
|
// Execute cut or copy operation when List View is active
|
||||||
void do_cut_copy(bool m_copy) {
|
void do_cut_copy(bool m_copy) {
|
||||||
@ -355,54 +439,6 @@ void do_cut_copy(bool m_copy) {
|
|||||||
|
|
||||||
// Helper functions for paste:
|
// Helper functions for paste:
|
||||||
|
|
||||||
// Tests if two files are on the same filesystem
|
|
||||||
bool is_on_same_fs(const char* file1, const char* file2) {
|
|
||||||
FILE *mtab; // /etc/mtab or /etc/mnttab file
|
|
||||||
static char filesystems[50][PATH_MAX];
|
|
||||||
static int fs_number=0;
|
|
||||||
|
|
||||||
// On first access read filesystems
|
|
||||||
if (fs_number == 0) {
|
|
||||||
mtab = fopen("/etc/mnttab", "r"); // Fairly standard
|
|
||||||
if (mtab == NULL)
|
|
||||||
mtab = fopen("/etc/mtab", "r"); // More standard
|
|
||||||
if (mtab == NULL)
|
|
||||||
mtab = fopen("/etc/fstab", "r"); // Otherwise fallback to full list
|
|
||||||
if (mtab == NULL)
|
|
||||||
mtab = fopen("/etc/vfstab", "r"); // Alternate full list file
|
|
||||||
|
|
||||||
char line[PATH_MAX]; // Input line
|
|
||||||
char device[PATH_MAX], mountpoint[PATH_MAX], fs[PATH_MAX];
|
|
||||||
while (mtab!= NULL && fgets(line, sizeof(line), mtab) != NULL) {
|
|
||||||
if (line[0] == '#' || line[0] == '\n')
|
|
||||||
continue;
|
|
||||||
if (sscanf(line, "%s%s%s", device, mountpoint, fs) != 3)
|
|
||||||
continue;
|
|
||||||
strcpy(filesystems[fs_number],mountpoint);
|
|
||||||
fs_number++;
|
|
||||||
}
|
|
||||||
fclose (mtab);
|
|
||||||
|
|
||||||
if (fs_number == 0) return false; // some kind of error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find filesystem for file1 (largest mount point match)
|
|
||||||
char *max;
|
|
||||||
int maxlen = 0;
|
|
||||||
for (int i=0; i<fs_number; i++) {
|
|
||||||
int mylen = strlen(filesystems[i]);
|
|
||||||
if ((strncmp(file1,filesystems[i],mylen)==0) && (mylen>maxlen)) {
|
|
||||||
maxlen=mylen;
|
|
||||||
max = filesystems[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (maxlen == 0) return false; // some kind of error
|
|
||||||
|
|
||||||
// See if file2 matches the same filesystem
|
|
||||||
return (strncmp(file2,max,maxlen)==0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Copy single file. Returns true if operation should continue
|
// Copy single file. Returns true if operation should continue
|
||||||
bool my_copy(const char* src, const char* dest) {
|
bool my_copy(const char* src, const char* dest) {
|
||||||
FILE *fold, *fnew;
|
FILE *fold, *fnew;
|
||||||
@ -412,7 +448,7 @@ bool my_copy(const char* src, const char* dest) {
|
|||||||
// this shouldn't happen
|
// this shouldn't happen
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (fl_filename_exist(dest)) {
|
if (edelib::file_exists(dest)) {
|
||||||
// if both src and dest are directories, do nothing
|
// if both src and dest are directories, do nothing
|
||||||
if (fl_filename_isdir(src) && fl_filename_isdir(dest))
|
if (fl_filename_isdir(src) && fl_filename_isdir(dest))
|
||||||
return true;
|
return true;
|
||||||
@ -529,7 +565,7 @@ void do_paste() {
|
|||||||
for (int i=0; cut_copy_buffer[i]; i++) {
|
for (int i=0; cut_copy_buffer[i]; i++) {
|
||||||
char *newname;
|
char *newname;
|
||||||
asprintf(&newname, "%s%s", current_dir, fl_filename_name(cut_copy_buffer[i]));
|
asprintf(&newname, "%s%s", current_dir, fl_filename_name(cut_copy_buffer[i]));
|
||||||
if (fl_filename_exist(newname)) {
|
if (edelib::file_exists(newname)) {
|
||||||
int c = -1;
|
int c = -1;
|
||||||
if (!overwrite_all && !skip_all) {
|
if (!overwrite_all && !skip_all) {
|
||||||
// here was choice_alert
|
// here was choice_alert
|
||||||
@ -663,6 +699,8 @@ void open_cb(Fl_Widget*w, void*data) {
|
|||||||
fprintf (stderr,"cb\n");
|
fprintf (stderr,"cb\n");
|
||||||
if (Fl::event_clicks() || Fl::event_key() == FL_Enter || w==main_menu) {
|
if (Fl::event_clicks() || Fl::event_key() == FL_Enter || w==main_menu) {
|
||||||
fprintf (stderr,"enter\n");
|
fprintf (stderr,"enter\n");
|
||||||
|
//if (Fl::event_clicks()) fprintf(stderr, "clicks\n");
|
||||||
|
//if (Fl::event_key()==FL_Enter) fprintf(stderr, "ekey\n");
|
||||||
static timeval tm = {0,0};
|
static timeval tm = {0,0};
|
||||||
timeval newtm;
|
timeval newtm;
|
||||||
gettimeofday(&newtm,0);
|
gettimeofday(&newtm,0);
|
||||||
@ -675,8 +713,8 @@ fprintf (stderr,"enter\n");
|
|||||||
char* path = (char*)view->data(view->value());
|
char* path = (char*)view->data(view->value());
|
||||||
fprintf(stderr, "Path: %s (ev %d)\n",path,Fl::event());
|
fprintf(stderr, "Path: %s (ev %d)\n",path,Fl::event());
|
||||||
|
|
||||||
if (stat(path,&buf)) return; // error
|
if (stat(path,&stat_buffer)) return; // error
|
||||||
if (S_ISDIR(buf.st_mode)) { // directory
|
if (S_ISDIR(stat_buffer.st_mode)) { // directory
|
||||||
loaddir(path);
|
loaddir(path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user