?? vfsview.cc
字號:
/* * HT Editor * vfsview.cc * * Copyright (C) 1999-2003 Stefan Weyergraf * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * 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 <errno.h>#include <string.h>#include <stdlib.h>#include "strtools.h"#include "snprintf.h"#include "vfsview.h"static vfs_extra *make_vfs_extra(const char *name, pstat_t s){ vfs_extra *e = ht_malloc(sizeof *e); e->stat = s; e->name = strdup(name); return e;}static void free_vfs_extra(vfs_extra *e){ free(e->name); free(e);}static Vfs *vfslistbox_vfs;static int vfslistbox_fncmp(const char *a, const char *b){ if (strchr("/ *@=#+", *a) && (*b != *a)) { if (*a == '/') return -1; if (*b == '/') return 1; return *b-*a; } return vfslistbox_vfs->compareFilenames(a,b);}/* * class VfsListbox */#define VFSV_FORMAT_NAME 0#define VFSV_FORMAT_SIZE 1#define VFSV_FORMAT_BSIZE 2#define VFSV_FORMAT_TYPE 3#define VFSV_FORMAT_MTIME 4#define VFSV_FORMAT_ATIME 5#define VFSV_FORMAT_CTIME 6#define VFSV_FORMAT_PERM 7#define VFSV_FORMAT_MODE 8#define VFSV_FORMAT_NLINK 9#define VFSV_FORMAT_NGID 10#define VFSV_FORMAT_NUID 11#define VFSV_FORMAT_OWNER 12#define VFSV_FORMAT_GROUP 13#define VFSV_FORMAT_INODE 14#define VFSV_FORMAT_SPACE 15#define VFSV_FORMAT_MARK 16#define VFSV_FORMAT_SEPARATOR 17#define VFSV_FORMAT_DESC 18#define VFSV_FORMAT_RMTIME 19#define VFSV_FORMAT_RATIME 20#define VFSV_FORMAT_RCTIME 21static const char *format_property[VFSV_FORMAT_PROPERTIES]={ "name", "size", "bsize", "type", "mtime", "atime", "ctime", "perm", "mode", "nlink", "ngid", "nuid", "owner", "group", "inode", "space", "mark", "|", "desc", "rmtime", "ratime", "rctime"};#define MAKE_DISPLAY_FORMAT(type) MAKE_DISPLAY_FORMAT_MIN_WIDTH(type, 0)#define MAKE_DISPLAY_FORMAT_MIN_WIDTH(type, width) (((width) << 16) | (type))#define MAKE_DISPLAY_FORMAT_FIXED_WIDTH(type, width) ((((width) | 0x8000) << 16) | (type))#define GET_DISPLAY_FORMAT_TYPE(dfmt) ((dfmt) & 0xffff)#define GET_DISPLAY_FORMAT_SIZE(dfmt) (((dfmt)>>16) & 0x7fff)#define GET_DISPLAY_FORMAT_IS_FIXED_SIZE(dfmt) ((dfmt) & 0x80000000)#define GET_DISPLAY_FORMAT_IS_MIN_SIZE(dfmt) (!GET_DISPLAY_FORMAT_IS_FIXED_SIZE(dfmt))void VfsListbox::init(Bounds *b, Container *vl, ht_text *sp){ cvfs = NULL; show_pos = sp; cdir[0] = 0; cproto[0] = 0; vfs_list = vl; ht_itext_listbox::init(b); config_changed();}void VfsListbox::done(){ ht_itext_listbox::done();}int VfsListbox::changeDir(const char *dir){ char url[VFS_URL_MAX]; ht_snprintf(url, sizeof url, "%s:%s", cproto, dir); return changeURL(url);}int VfsListbox::changeURL(const char *url){ int c = vfs_list->count(); const char *pend = strchr(url, ':'); Vfs *newVfs = NULL; const char *pathptr = url; if (pend) { /* find matching protocol */ char protoname[VFS_PROTO_MAX+1]; if (pend-url > VFS_PROTO_MAX) return EINVAL; ht_strlcpy(protoname, url, pend-url+1); for (int i = 0; i < c; i++) { Vfs *v = (Vfs*)(*vfs_list)[i]; if (strcmp(protoname, v->getProtoName()) == 0) { newVfs = v; break; } } if (!newVfs) return EINVAL; pathptr = pend+1; } else { /* no proto mentioned, default to first in list */ if (!c) return EINVAL; newVfs = (Vfs*)vfs_list->get(0); } char path[VFS_DIR_MAX+1]; if (sys_common_canonicalize(path, pathptr, NULL, newVfs->isPathDelim()) !=0) return EINVAL; /* add trailing path delimiter if needed */ int l = strlen(path)-1; if ((l==-1) || !newVfs->isPathDelim()(path[l])) { char delim = newVfs->isPathDelim()('/') ? '/' : '\\'; if (l+2 >= (int)sizeof path) return EINVAL; path[l+1] = delim; path[l+2] = 0; } /* stat and find out if its a dir*/ pstat_t s; int e; if ((e = newVfs->pstat(&s, path)) != 0) return e; if (!(s.caps & pstat_mode_type) || !(HT_S_ISDIR(s.mode))) return ENOTDIR; /* code to position cursor when doing "cd .." */ char spath[VFS_DIR_MAX+1]; char spath2[VFS_DIR_MAX+1]; strcpy(spath, cdir); char *p = ht_strend(spath)-2; bool cdpp = false; while (p >= spath) { if (newVfs->isPathDelim()(*p)) { strcpy(spath2, p+1); *(ht_strend(spath2)-1) = 0; *(p+1) = 0; if (newVfs->compareFilenames(path, spath) == 0) { cdpp = true; } break; } p--; } /* everything ok, set current to this */ ht_strlcpy(cproto, newVfs->getProtoName(), sizeof cproto); ht_strlcpy(cdir, path, sizeof cdir); cvfs = newVfs; reread(); /**/ update(); if (dfmt_quickfind != -1) { ht_text_listbox_sort_order so[1]; vfslistbox_vfs = cvfs; so[0].col = dfmt_quickfind; so[0].compare_func = vfslistbox_fncmp; sort(1, so); } /*else update();*/ gotoItemByPosition(0); /* code to position cursor when doing "cd .." (part II) */ if (cdpp) { ht_text_listbox_item *i = (ht_text_listbox_item*)getFirst(); while (i) { vfs_extra *x = (vfs_extra*)i->extra_data; if (newVfs->compareFilenames(x->name, spath2) == 0) { gotoItemByEntry(i); break; } i = (ht_text_listbox_item*)getNext(i); } } rearrangeColumns(); return 0;}void VfsListbox::config_changed(){ ht_text_listbox::config_changed(); char *dfmt = get_config_string("misc/vfs display format"); setDisplayFormat(dfmt ? dfmt : (char*)"name"); free(dfmt);}int VfsListbox::cursorAdjust(){ return 1;}void VfsListbox::freeExtraData(void *extra_data){ if (extra_data) { free_vfs_extra((vfs_extra*)extra_data); }}const char *VfsListbox::getCurDir(){ return cdir;}const char *VfsListbox::getCurProto(){ return cproto;}Vfs *VfsListbox::getCurVfs(){ return cvfs;}void VfsListbox::handlemsg(htmsg *msg){ switch (msg->msg) { case msg_keypressed: switch (msg->data1.integer) { case K_Return: if (count && selectEntry(e_cursor)) { clearmsg(msg); return; } break; } break; } return ht_text_listbox::handlemsg(msg);}void VfsListbox::setDisplayFormat(char *fmt){/* int dfmt_cols; int dfmt_props; int dfmt_prop2colidx[VFSV_FORMAT_MAX_COLS]; int dfmt_prop[VFSV_FORMAT_MAX_COLS];*/ int type; dfmt_cols = 0; dfmt_props = 0; dfmt_quickfind = -1; while ((fmt = translateProp(fmt, &type))) { if (type == VFSV_FORMAT_SEPARATOR) { if (++dfmt_cols == VFSV_FORMAT_MAX_COLS) break; } else { if (*fmt == ':') { fmt++; unsigned int width = strtoul(fmt, &fmt, 10); if (*fmt == '+') { fmt++; dfmt_prop[dfmt_props] = MAKE_DISPLAY_FORMAT_MIN_WIDTH(type, width); } else { dfmt_prop[dfmt_props] = MAKE_DISPLAY_FORMAT_FIXED_WIDTH(type, width); } } else { dfmt_prop[dfmt_props] = MAKE_DISPLAY_FORMAT(type); } dfmt_prop2colidx[dfmt_props] = dfmt_cols; if (++dfmt_props == VFSV_FORMAT_MAX_COLS) break; } while ((*fmt == ',') || (*fmt == ' ')) fmt++; if ((type == VFSV_FORMAT_NAME) && (dfmt_quickfind == -1)) { dfmt_quickfind = dfmt_cols; } } ++dfmt_cols; cols = dfmt_cols; if (dfmt_quickfind != -1) keycol = dfmt_quickfind; else keycol = 0; rearrangeColumns();}bool VfsListbox::selectEntry(void *entry){ ht_text_listbox_item *i = (ht_text_listbox_item*)entry; if (i->extra_data) { vfs_extra *e = (vfs_extra*)i->extra_data; if (e->stat.caps & pstat_mode_type) { if (HT_S_ISDIR(e->stat.mode)) { char d[VFS_DIR_MAX]; ht_snprintf(d, sizeof d, "%s%s", cdir, e->name); changeDir(d); update(); return true; }
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -