file-browser: open files; more icons; symlinks

This commit is contained in:
K. Lange 2018-11-19 19:26:40 +09:00
parent 9514c017ee
commit 212adc0cdc

View File

@ -18,6 +18,7 @@
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <toaru/yutani.h>
#include <toaru/graphics.h>
@ -53,7 +54,7 @@ static yutani_t * yctx;
static yutani_window_t * main_window;
static gfx_context_t * ctx;
#define SCROLL_AMOUNT 20
#define SCROLL_AMOUNT 120
static int application_running = 1;
static int show_hidden = 1;
static int scroll_offset = 0;
@ -76,7 +77,9 @@ static void _menu_action_exit(struct MenuEntry * entry) {
struct File {
char name[256];
char icon[256];
char date[256];
//char date[256];
char link[256]; /* why so big */
char * launcher;
int type;
int selected;
};
@ -138,6 +141,11 @@ static void draw_file(struct File * f, int offset) {
draw_sprite_alpha_paint(contents, icon, center_x_icon + x, y + 2, 0.3, rgb(255,255,255));
}
if (f->link[0]) {
sprite_t * arrow = icon_get_16("forward");
draw_sprite(contents, arrow, center_x_icon + 32 + x, y + 32);
}
free(name);
}
@ -171,6 +179,20 @@ static void set_title(char * directory) {
yutani_window_advertise_icon(yctx, main_window, title, "folder");
}
static int has_extension(struct File * f, char * extension) {
int i = strlen(f->name);
int j = strlen(extension);
do {
if (f->name[i] != (extension)[j]) break;
if (j == 0) return 1;
if (i == 0) break;
i--;
j--;
} while (1);
return 0;
}
static void load_directory(const char * path) {
if (file_pointers) {
for (int i = 0; i < file_pointers_len; ++i) {
@ -230,25 +252,40 @@ static void load_directory(const char * path) {
sprintf(f->name, "%s", ent->d_name); /* snprintf? copy min()? */
struct stat statbuf;
//struct stat statbufl;
//char * link;
struct stat statbufl;
char tmp[strlen(path)+strlen(ent->d_name)+2];
sprintf(tmp, "%s/%s", path, ent->d_name);
lstat(tmp, &statbuf);
#if 0
if (S_ISLNK(statbuf.st_mode)) {
stat(tmp, &statbufl);
f->link = malloc(4096);
readlink(tmp, f->link, 4096);
memcpy(&statbufl, &statbuf, sizeof(struct stat));
stat(tmp, &statbuf);
readlink(tmp, f->link, 256);
} else {
f->link[0] = '\0';
}
#endif
f->launcher = NULL;
if (S_ISDIR(statbuf.st_mode)) {
sprintf(f->icon, "folder");
f->type = 1;
} else {
sprintf(f->icon, "file");
f->launcher = "terminal bim";
if (has_extension(f, ".c")) {
sprintf(f->icon, "c");
} else if (has_extension(f, ".h")) {
sprintf(f->icon, "h");
} else if (has_extension(f, ".bmp")) {
sprintf(f->icon, "image");
f->launcher = "imgviewer";
} else if (statbuf.st_mode & 0111) {
sprintf(f->icon, "%s", f->name);
f->launcher = "SELF";
} else {
sprintf(f->icon, "file");
}
f->type = 0;
}
@ -437,6 +474,66 @@ static void _menu_action_about(struct MenuEntry * entry) {
redraw_window();
}
static void launch_application(char * app) {
if (!fork()) {
chdir(last_directory);
char * tmp = malloc(strlen(app) + 10);
sprintf(tmp, "exec %s", app);
char * args[] = {"/bin/sh", "-c", tmp, NULL};
execvp(args[0], args);
exit(1);
}
}
static void launch_application_menu(struct MenuEntry * self) {
struct MenuEntry_Normal * _self = (void *)self;
launch_application((char *)_self->action);
}
static void open_file(struct File * f) {
if (f->type == 1) {
char tmp[1024];
sprintf(tmp,"%s/%s", last_directory, f->name);
load_directory(tmp);
reinitialize_contents();
redraw_window();
} else if (f->launcher) {
char tmp[4096];
if (!strcmp(f->launcher, "SELF")) {
sprintf(tmp, "./%s", f->name);
} else {
sprintf(tmp, "%s \"%s\"", f->launcher, f->name);
}
launch_application(tmp);
}
}
static void _menu_action_open(struct MenuEntry * self) {
for (int i = 0; i < file_pointers_len; ++i) {
if (file_pointers[i]->selected) {
open_file(file_pointers[i]);
}
}
}
static void toggle_selected(int hilighted_offset, int modifiers) {
struct File * f = get_file_at_offset(hilighted_offset);
if (!f) return;
f->selected = !f->selected;
if (!(modifiers & KEY_MOD_LEFT_CTRL)) {
for (int i = 0; i < file_pointers_len; ++i) {
if (file_pointers[i] != f && file_pointers[i]->selected) {
file_pointers[i]->selected = 0;
clear_offset(i);
draw_file(file_pointers[i], i);
}
}
}
clear_offset(hilighted_offset);
draw_file(f, hilighted_offset);
redraw_window();
}
int main(int argc, char * argv[]) {
yctx = yutani_init();
@ -479,11 +576,16 @@ int main(int argc, char * argv[]) {
available_height = ctx->height - MENU_BAR_HEIGHT - bounds.height;
context_menu = menu_create(); /* Right-click menu */
menu_insert(context_menu, menu_create_normal("up",NULL,"Up",_menu_action_up));
menu_insert(context_menu, menu_create_normal(NULL,NULL,"Open",_menu_action_open));
menu_insert(context_menu, menu_create_separator());
menu_insert(context_menu, menu_create_normal(NULL,NULL,"Copy",_menu_action_copy));
menu_insert(context_menu, menu_create_separator());
menu_insert(context_menu, menu_create_normal("up",NULL,"Up",_menu_action_up));
menu_insert(context_menu, menu_create_normal("utilities-terminal","terminal","Open Terminal",launch_application_menu));
load_directory("/usr/share");
char tmp[1024];
getcwd(tmp, 1024);
load_directory(tmp);
reinitialize_contents();
redraw_window();
@ -492,6 +594,7 @@ int main(int argc, char * argv[]) {
int modifiers = 0; /* For ctrl-click */
while (application_running) {
waitpid(-1, NULL, WNOHANG);
yutani_msg_t * m = yutani_poll(yctx);
while (m) {
if (menu_process_event(yctx, m)) {
@ -603,30 +706,12 @@ int main(int argc, char * argv[]) {
struct File * f = get_file_at_offset(hilighted_offset);
if (f) {
if (last_click_offset == hilighted_offset && precise_time_since(last_click) < 400) {
if (f->type == 1) {
char tmp[1024];
sprintf(tmp,"%s/%s", last_directory, f->name);
load_directory(tmp);
reinitialize_contents();
redraw_window();
}
open_file(f);
last_click = 0;
} else {
last_click = precise_current_time();
last_click_offset = hilighted_offset;
f->selected = !f->selected;
if (!(modifiers & KEY_MOD_LEFT_CTRL)) {
for (int i = 0; i < file_pointers_len; ++i) {
if (file_pointers[i] != f && file_pointers[i]->selected) {
file_pointers[i]->selected = 0;
clear_offset(i);
draw_file(file_pointers[i], i);
}
}
}
clear_offset(hilighted_offset);
draw_file(f, hilighted_offset);
redraw_window();
toggle_selected(hilighted_offset, modifiers);
}
} else {
if (!(modifiers & KEY_MOD_LEFT_CTRL)) {
@ -642,6 +727,10 @@ int main(int argc, char * argv[]) {
}
} else if (me->buttons & YUTANI_MOUSE_BUTTON_RIGHT) {
if (!context_menu->window) {
struct File * f = get_file_at_offset(hilighted_offset);
if (f && !f->selected) {
toggle_selected(hilighted_offset, modifiers);
}
menu_show(context_menu, main_window->ctx);
yutani_window_move(main_window->ctx, context_menu->window, me->new_x + main_window->x, me->new_y + main_window->y);
}