123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825 |
- /*
- * sfnedit/m_fileops.c
- *
- * Copyright (C) 2020 bzt (bztsrc@gitlab)
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * @brief Main window file operation tools
- *
- */
- #include <stdint.h>
- #include <stdio.h>
- #include <string.h>
- #include <unistd.h>
- #include <dirent.h>
- #include <time.h>
- #include <sys/stat.h>
- #include <inttypes.h>
- #include <stdlib.h>
- #include <limits.h>
- #include "libsfn.h"
- #include "ui.h"
- #include "lang.h"
- #ifdef __WIN32__
- #include <windows.h>
- #include <winnls.h>
- #include <shlobj.h>
- #else
- #ifndef __wur
- #define __wur
- #endif
- extern char *realpath (const char *__restrict __name, char *__restrict __resolved) __THROW __wur;
- #endif
- #ifndef PRIu64
- #if __WORDSIZE == 64
- #define PRIu64 "lu"
- #define PRId64 "ld"
- #else
- #define PRIu64 "llu"
- #define PRId64 "lld"
- #endif
- #endif
- #ifndef PATH_MAX
- # ifdef MAX_PATH
- # define PATH_MAX MAX_PATH
- # else
- # define PATH_MAX 65536
- # endif
- #endif
- #ifndef FILENAME_MAX
- # define FILENAME_MAX 256
- #endif
- typedef struct {
- char *name;
- char type;
- uint64_t size;
- time_t time;
- } filelist_t;
- filelist_t *files = NULL;
- int numfiles = 0, scrollfiles = 0, pagefiles = 0, selfiles = -1, ordering = 0, pathX[PATH_MAX/FILENAME_MAX+64] = { 0 }, pathlen;
- int lastsave = -1, clkfiles = 0, question_y = 0, numdrives = 0, seldrive = 0;
- char fn[PATH_MAX+64] = {0}, filename[FILENAME_MAX+64] = {0}, path[PATH_MAX/FILENAME_MAX+64][FILENAME_MAX], fsearch[256] = { 0 };
- char strrs[16] = { 0 }, strre[16] = { 0 }, fstatus[256], drives[128];
- unsigned char peekbuf[256];
- /**
- * Sort file names
- */
- static int fncmp(const void *a, const void *b)
- {
- filelist_t *A = (filelist_t*)a, *B = (filelist_t*)b;
- if(ordering < 4) {
- if(A->type && !B->type) return 1;
- if(!A->type && B->type) return -1;
- }
- switch(ordering) {
- case 0: return strcmp(A->name, B->name);
- case 1: return strcmp(B->name, A->name);
- case 2: return A->size > B->size;
- case 3: return B->size > A->size;
- case 4: return (int)(A->time - B->time);
- case 5: return (int)(B->time - A->time);
- }
- return 0;
- }
- /**
- * Read directory contents
- */
- void fileops_readdir(int save)
- {
- char tmp[PATH_MAX+64];
- DIR *dir;
- struct dirent *de;
- struct stat st;
- int i, j, k, l = strlen(fsearch);
- if(files) {
- for(i = 0; i < numfiles; i++)
- if(files[i].name)
- free(files[i].name);
- free(files);
- files = NULL;
- }
- numfiles = scrollfiles = 0; selfiles = clkfiles = -1;
- for(tmp[0] = 0, i = 0; i < pathlen; i++)
- strcat(tmp, path[i]);
- j = strlen(tmp);
- dir = opendir(tmp);
- if(dir) {
- while((de = readdir(dir))) {
- if(de->d_name[0] == '.') continue;
- strcpy(tmp + j, de->d_name);
- if(stat(tmp, &st)) continue;
- if(!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) continue;
- k = strlen(de->d_name);
- if(!S_ISDIR(st.st_mode)) {
- if(k < 3) continue;
- if(!memcmp(de->d_name + k - 3, ".gz", 3)) k -= 3;
- if(k < 5) continue;
- if( memcmp(de->d_name + k - 4, ".sfn", 4) && memcmp(de->d_name + k - 4, ".asc", 4)
- #ifndef USE_NOFOREIGN
- && (save || (memcmp(de->d_name + k - 4, ".pf2", 4) &&
- memcmp(de->d_name + k - 4, ".pfa", 4) && memcmp(de->d_name + k - 4, ".pfb", 4) &&
- memcmp(de->d_name + k - 5, ".woff",5) && memcmp(de->d_name + k - 5, "woff2",5) &&
- memcmp(de->d_name + k - 4, ".ttf", 4) && memcmp(de->d_name + k - 4, ".ttc", 4) &&
- memcmp(de->d_name + k - 4, ".otf", 4) && memcmp(de->d_name + k - 4, ".pcf", 4) &&
- memcmp(de->d_name + k - 4, ".sfd", 4) && memcmp(de->d_name + k - 4, ".svg", 4) &&
- memcmp(de->d_name + k - 4, ".fnt", 4) && memcmp(de->d_name + k - 4, ".fon", 4) &&
- memcmp(de->d_name + k - 4, ".psf", 4) && memcmp(de->d_name + k - 5, ".psfu",5) &&
- memcmp(de->d_name + k - 4, ".bdf", 4) && memcmp(de->d_name + k - 4, ".hex", 4) &&
- memcmp(de->d_name + k - 4, ".bmf", 4) && memcmp(de->d_name + k - 5, ".yaff", 5) &&
- memcmp(de->d_name + k - 6, ".kbits", 6) && memcmp(de->d_name + k - 6, ".kbitx", 6) &&
- memcmp(de->d_name + k - 4, ".tga", 4) && memcmp(de->d_name + k - 4, ".png", 4)))
- #endif
- ) continue;
- }
- if(l) {
- if(k < l) continue;
- k -= l;
- for(i = 0; i <= k && ui_casecmp(de->d_name + i, fsearch, l); i++);
- if(i > k) continue;
- }
- i = numfiles++;
- files = (filelist_t*)realloc(files, numfiles * sizeof(filelist_t));
- if(!files) { numfiles = 0; break; }
- files[i].name = (char*)malloc(strlen(de->d_name)+1);
- if(!files[i].name) { numfiles--; continue; }
- strcpy(files[i].name, de->d_name);
- files[i].type = S_ISDIR(st.st_mode) ? 0 : 1;
- files[i].size = st.st_size;
- files[i].time = st.st_mtime;
- }
- closedir(dir);
- }
- qsort(files, numfiles, sizeof(filelist_t), fncmp);
- memset(peekbuf, 0, sizeof(peekbuf));
- px = py = 0;
- }
- /**
- * Peek into selected file to see if it's an image
- */
- void fileops_peek(int sel)
- {
- FILE *f;
- char tmp[PATH_MAX+64];
- int i, w, h;
- memset(peekbuf, 0, sizeof(peekbuf));
- px = py = 0;
- if(sel >= 0 && sel < numfiles) {
- for(tmp[0] = 0, i = 0; i < pathlen; i++)
- strcat(tmp, path[i]);
- strcat(tmp, files[sel].name);
- if((f = fopen(tmp, "rb"))) {
- i = fread(peekbuf, 1, sizeof(peekbuf), f);
- fclose(f);
- w = h = 0;
- if(peekbuf[0]==0 && (peekbuf[1]==0 || peekbuf[1]==1) && (peekbuf[2]==1 || peekbuf[2]==2 || peekbuf[2]==9 ||
- peekbuf[2]==10) && (peekbuf[16]==8 || peekbuf[16]==24 || peekbuf[16]==32)) {
- w = (peekbuf[13] << 8) + peekbuf[12];
- h = (peekbuf[15] << 8) + peekbuf[14];
- } else
- if(peekbuf[0]==0x89 && peekbuf[1]=='P' && peekbuf[2]=='N' && peekbuf[3]=='G' && peekbuf[12] == 'I' && peekbuf[13] == 'H') {
- w = (peekbuf[18] << 8) + peekbuf[19];
- h = (peekbuf[22] << 8) + peekbuf[23];
- }
- if(w >= 128 && h >= 128 && !(w & 0xf) && !(h & 0xf) && (w < h ? h / w : w / h) < 3) { px = w / 16; py = h / 16; }
- }
- }
- }
- /**
- * File operations windows, load / save
- */
- void view_fileops(int save)
- {
- struct tm *lt;
- char *s, tmp[32];
- int i, j, k;
- ui_win_t *win = &wins[0];
- time_t now = time(NULL), diff;
- #ifdef __WIN32__
- wchar_t home[MAX_PATH];
- #endif
- if(!fn[0]) {
- if(ctx.filename)
- #ifdef __WIN32__
- strcpy(fn, ctx.filename);
- #else
- s = realpath(ctx.filename, fn);
- #endif
- else {
- #ifdef __WIN32__
- if(SHGetFolderPathW(HWND_DESKTOP, CSIDL_DESKTOPDIRECTORY, NULL, 0, home))
- wsprintfW(home, L".\\");
- for(i = 0, s = fn; home[i]; i++) {
- if(home[i] < 0x80) {
- *s++ = home[i];
- } else if(home[i] < 0x800) {
- *s++ = ((home[i]>>6)&0x1F)|0xC0;
- *s++ = (home[i]&0x3F)|0x80;
- } else {
- *s++ = ((home[i]>>12)&0x0F)|0xE0;
- *s++ = ((home[i]>>6)&0x3F)|0x80;
- *s++ = (home[i]&0x3F)|0x80;
- }
- }
- *s++ = DIRSEP;
- *s = 0;
- #else
- if((!getcwd(fn, sizeof(fn) - 3) || !fn[0] || !memcmp(fn, "/usr", 4)) && (s = getenv("HOME")) != NULL) strcpy(fn, s);
- strcat(fn, "/");
- #endif
- strcpy(filename, "noname.sfn");
- }
- }
- ssfn_dst.fg = theme[THEME_FG];
- ssfn_dst.bg = theme[THEME_BG];
- ssfn_dst.w = win->w;
- ssfn_dst.h = win->h;
- ui_box(win, 10, 29, win->w - 168, 20, theme[THEME_BG], theme[THEME_BG], theme[THEME_BG]);
- memset(path, 0, sizeof(path));
- for(i = pathlen = 0, s = fn; *s; s++) {
- if(i < FILENAME_MAX-1) path[pathlen][i++] = *s;
- if(*s == DIRSEP) { i = 0; pathlen++; }
- }
- memset(pathX, 0, sizeof(pathX));
- if(wins[0].field == 7) j = k = THEME_CURSOR; else { j = THEME_LIGHT; k = THEME_DARK; }
- ssfn_dst.w = win->w - 158; if(ssfn_dst.w < 1) ssfn_dst.w = 1;
- for(i = 0, ssfn_dst.x = 10; i < pathlen && ssfn_dst.x < win->w - 158; i++) {
- pathX[i] = ssfn_dst.x;
- ui_text(win, ssfn_dst.x, 30, path[i]);
- ui_rect(win, pathX[i] - 3, 29, ssfn_dst.x - pathX[i] + 6, 20, theme[selfield == i + 7 ? k : j],
- theme[selfield == i + 7 ? j : k]);
- ssfn_dst.x += 8;
- }
- pathX[i] = ssfn_dst.x - 8;
- ssfn_dst.w = win->w;
- if(!files || lastsave != save || input_refresh) fileops_readdir(save);
- lastsave = save;
- if(wins[0].field == 9 && selfiles == -1 && numfiles > 0)
- selfiles = 0;
- pagefiles = (win->h - 51 - 72) / 16; if(pagefiles < 2) pagefiles = 2;
- if(selfiles + 1 > scrollfiles + pagefiles - 1) scrollfiles = selfiles - pagefiles + 1;
- if(selfiles >= 0 && selfiles < scrollfiles) scrollfiles = selfiles;
- if(wins[0].tool == MAIN_TOOL_LOAD || wins[0].tool == MAIN_TOOL_SAVE) {
- ssfn_dst.w = win->w - 8; if(ssfn_dst.w < 1) ssfn_dst.w = 1;
- ssfn_dst.h = win->h;
- ui_icon(win, win->w - 134 - 16, 30, ICON_SEARCH, 0);
- ui_input(win, win->w - 132, 29, 120, fsearch, wins[0].field == 8, 255, 0);
- ui_rect(win, 7, 51, win->w - 14, win->h - 102, theme[THEME_DARKER], theme[THEME_LIGHT]);
- ui_box(win, 8, 52, 18, 20, theme[THEME_LIGHT], theme[THEME_BG], theme[THEME_DARKER]);
- ssfn_dst.w = win->w - 284; if(ssfn_dst.w < 1) ssfn_dst.w = 1;
- ui_box(win, 26, 52, win->w - 314, 20, theme[selfield == 1 ? THEME_DARKER : THEME_LIGHT], theme[THEME_BG],
- theme[selfield == 1 ? THEME_LIGHT : THEME_DARKER]);
- ssfn_dst.fg = theme[THEME_LIGHTER];
- ui_text(win, 34, 53, lang[FILEOP_NAME]);
- ssfn_dst.fg = theme[THEME_DARKER];
- ui_text(win, 33, 52, lang[FILEOP_NAME]);
- ssfn_dst.w = win->w - 168; if(ssfn_dst.w < 1) ssfn_dst.w = 1;
- ui_box(win, win->w - 288, 52, 120, 20, theme[selfield == 2 ? THEME_DARKER : THEME_LIGHT], theme[THEME_BG],
- theme[selfield == 2 ? THEME_LIGHT : THEME_DARKER]);
- ssfn_dst.fg = theme[THEME_LIGHTER];
- ui_text(win, win->w - 280, 53, lang[FILEOP_SIZE]);
- ssfn_dst.fg = theme[THEME_DARKER];
- ui_text(win, win->w - 281, 52, lang[FILEOP_SIZE]);
- ssfn_dst.w = win->w - 9; if(ssfn_dst.w < 1) ssfn_dst.w = 1;
- ui_box(win, win->w - 168, 52, 159, 20, theme[selfield == 3 ? THEME_DARKER : THEME_LIGHT], theme[THEME_BG],
- theme[selfield == 3 ? THEME_LIGHT : THEME_DARKER]);
- ssfn_dst.fg = theme[THEME_LIGHTER];
- ui_text(win, win->w - 160, 53, lang[FILEOP_TIME]);
- ssfn_dst.fg = theme[THEME_DARKER];
- ui_text(win, win->w - 161, 52, lang[FILEOP_TIME]);
- ssfn_dst.w = win->w;
- ssfn_dst.fg = theme[THEME_FG];
- j = win->w * 60;
- switch(ordering >> 1) {
- case 0: ui_tri(win, win->w - 300, 60, ordering & 1); break;
- case 1: ui_tri(win, win->w - 180, 60, ordering & 1); break;
- case 2: ui_tri(win, win->w - 20, 60, ordering & 1); break;
- }
- ssfn_dst.y = 72;
- ssfn_dst.h = win->h - 63;
- for(i = scrollfiles; i < numfiles && ssfn_dst.y < ssfn_dst.h; i++, ssfn_dst.y += 16) {
- if(i == selfiles) {
- ui_box(win, 9, ssfn_dst.y, win->w - 30, 16, theme[THEME_SELBG], theme[THEME_SELBG], theme[THEME_SELBG]);
- ssfn_dst.fg = theme[THEME_SELFG];
- } else
- ssfn_dst.fg = theme[THEME_FG];
- ui_icon(win, 9, ssfn_dst.y, files[i].type ? ICON_FILE : ICON_FOLDER, 0);
- ssfn_dst.w = win->w - 284; if(ssfn_dst.w < 1) ssfn_dst.w = 1;
- ui_text(win, 30, ssfn_dst.y, files[i].name);
- sprintf(tmp,"%13" PRIu64,files[i].size);
- ssfn_dst.w = win->w - 168; if(ssfn_dst.w < 1) ssfn_dst.w = 1;
- ui_text(win, win->w - 288, ssfn_dst.y, tmp);
- ssfn_dst.w = win->w - 9; if(ssfn_dst.w < 1) ssfn_dst.w = 1;
- diff = now - files[i].time;
- if(diff < 120) strcpy(tmp, lang[FILEOP_NOW]); else
- if(diff < 3600) sprintf(tmp, lang[FILEOP_MSAGO], (int)(diff/60)); else
- if(diff < 7200) sprintf(tmp, lang[FILEOP_HAGO], (int)(diff/60)); else
- if(diff < 24*3600) sprintf(tmp, lang[FILEOP_HSAGO], (int)(diff/3600)); else
- if(diff < 48*3600) strcpy(tmp, lang[FILEOP_YESTERDAY]); else {
- lt = localtime(&files[i].time);
- if(files[i].time < 7*24*3600) strcpy(tmp, lang[FILEOP_WDAY0 + lt->tm_wday]); else
- sprintf(tmp, "%04d-%02d-%02d", lt->tm_year+1900, lt->tm_mon+1, lt->tm_mday);
- }
- ui_text(win, win->w - 160, ssfn_dst.y, tmp);
- }
- ssfn_dst.fg = theme[THEME_FG];
- ssfn_dst.w = win->w;
- ssfn_dst.h = win->h;
- ui_hscrbar(win, win->w - 20, 72, 12, win->h - 124, scrollfiles, pagefiles, numfiles, selfield == 5);
- j = win->w / 4;
- if(!save) {
- if(!strrs[0]) sprintf(strrs, "U+%X", rs);
- if(!strre[0]) sprintf(strre, "U+%X", re);
- ui_text(win, 8, win->h - 44, lang[FILEOP_RANGE]);
- ui_input(win, 80, win->h - 44, 72, strrs, wins[0].field == 10, 15, 1);
- ui_input(win, 164, win->h - 44, 72, strre, wins[0].field == 11, 15, 2);
- ui_bool(win, 250, win->h - 44, lang[FILEOP_REPLACE], replace, wins[0].field == 12);
- if(px || py) {
- ui_num(win, 440, win->h - 44, px, wins[0].field == 14, selfield - 14);
- ui_num(win, 496, win->h - 44, py, wins[0].field == 15, selfield - 16);
- }
- ui_button(win, win->w - 12 - j, win->h - 44, j, lang[FILEOP_IMPORT], selfield == 4 ? 1 : 0, wins[0].field == 13);
- } else {
- ui_bool(win, 8, win->h - 44, "ASC", ascii, wins[0].field == 10);
- ui_bool(win, 64, win->h - 44, "gzip", zip, wins[0].field == 11);
- s = strrchr(filename, '.');
- if(s && !strcmp(s, ".gz")) { *s = 0; s = strrchr(filename, '.'); }
- if(!s) s = filename + strlen(filename);
- if(s != filename) memcpy(s, ascii ? ".asc" : ".sfn", 5);
- ui_input(win, 128, win->h - 44, win->w - j - 12 - 128 - 12, filename, wins[0].field == 12, 255, 0);
- ui_button(win, win->w - 12 - j, win->h - 44, j, lang[FILEOP_SAVE], selfield == 4 ? 3 : 2, wins[0].field == 13);
- }
- }
- #ifdef __WIN32__
- if(selfield == 7) {
- memset(drives, 0, sizeof(drives)); numdrives = 0;
- k = (int)GetLogicalDrives();
- for(i = 0, j = 1; i < 32; i++, j <<= 1)
- if(k & j) {
- drives[numdrives * 4] = 'A' + i;
- drives[numdrives * 4 + 1] = ':';
- drives[numdrives * 4 + 2] = DIRSEP;
- numdrives++;
- }
- ui_box(win, 10, 52, 32, 4 + numdrives * 16, theme[THEME_DARK], theme[THEME_BG], theme[THEME_LIGHT]);
- for(i = 0; i < numdrives; i++) {
- if(i == seldrive) {
- ui_box(win, 11, 52 + i * 16, 30, 16, theme[THEME_SELBG], theme[THEME_SELBG], theme[THEME_SELBG]);
- ssfn_dst.fg = theme[THEME_SELFG];
- } else
- ssfn_dst.fg = theme[THEME_FG];
- ui_text(win, 12, 52 + i * 16, drives + i * 4);
- }
- }
- #endif
- }
- /**
- * On enter handler
- */
- void ctrl_fileops_onenter(int save)
- {
- int i, j = wins[0].w / 4;
- char *s;
- clkfiles = -1;
- if(wins[0].field == 7) {
- if(pathlen > 0) pathlen--;
- for(fn[0] = 0, i = 0; i < pathlen; i++)
- strcat(fn, path[i]);
- fileops_readdir(save);
- path[pathlen][strlen(path[pathlen]) - 1] = 0;
- for(selfiles = 0; selfiles < numfiles && strcmp(files[selfiles].name, path[pathlen]); selfiles++);
- }
- if(!save) {
- if(wins[0].field == 12) replace ^= 1;
- if(wins[0].field == 9 || wins[0].field == 13) {
- if(selfiles >= 0 && selfiles < numfiles) {
- for(fn[0] = 0, i = 0; i < pathlen; i++)
- strcat(fn, path[i]);
- strcat(fn, files[selfiles].name);
- if(files[selfiles].type) {
- ui_cursorwin(&wins[0], CURSOR_LOADING);
- ui_button(&wins[0], wins[0].w - 12 - j, wins[0].h - 44, j, lang[FILEOP_IMPORT], 0, -1);
- ui_flushwin(&wins[0], wins[0].w - 12 - j, wins[0].h - 44, j, 32);
- if(sfn_load(fn, 0)) {
- sfn_sanitize(-1);
- strcpy(filename, files[selfiles].name);
- wins[0].tool = MAIN_TOOL_GLYPHS;
- wins[0].field = selfield = -1;
- ui_updatetitle(0);
- } else {
- sprintf(fstatus, "libsfn: %s", lang[ERR_LOAD]);
- errstatus = fstatus;
- }
- ui_cursorwin(&wins[0], CURSOR_PTR);
- } else {
- strcat(path[pathlen++], files[selfiles].name);
- strcat(fn, DIRSEPS);
- fileops_readdir(save);
- selfiles = 0;
- wins[0].field = 9;
- }
- }
- }
- } else {
- if(wins[0].field == 10) { ascii ^= 1; if(ascii) zip = 0; }
- if(wins[0].field == 11) { zip ^= 1; if(zip) ascii = 0; }
- if(wins[0].field == 9 || wins[0].field == 13) {
- for(fn[0] = 0, i = 0; i < pathlen; i++)
- strcat(fn, path[i]);
- if(wins[0].field == 13 || (selfiles >= 0 && selfiles < numfiles && files[selfiles].type)) {
- if(wins[0].field == 9) strcpy(filename, files[selfiles].name);
- s = strrchr(filename, '.');
- if(s && !strcmp(s, ".gz")) { *s = 0; s = strrchr(filename, '.'); }
- if(!s) s = filename + strlen(filename);
- if(s != filename) memcpy(s, ascii ? ".asc" : ".sfn", 5);
- strcat(fn, filename);
- ui_cursorwin(&wins[0], CURSOR_LOADING);
- if(wins[0].tool == MAIN_TOOL_SAVE) {
- ui_input(&wins[0], 128, wins[0].h - 44, wins[0].w - j - 12 - 128 - 12, filename, 0, 255, 0);
- ui_button(&wins[0], wins[0].w - 12 - j, wins[0].h - 44, j, lang[FILEOP_SAVE], 2, -1);
- ui_flushwin(&wins[0], 0, wins[0].h - 44, wins[0].w, 32);
- }
- sfn_sanitize(-1);
- if(sfn_save(fn, ascii, zip)) ui_updatetitle(0); else
- {
- sprintf(fstatus, "libsfn: %s", lang[ERR_SAVE]);
- errstatus = fstatus;
- }
- fileops_readdir(save);
- ui_cursorwin(&wins[0], CURSOR_PTR);
- } else {
- strcat(path[pathlen++], files[selfiles].name);
- strcat(fn, files[selfiles].name);
- strcat(fn, DIRSEPS);
- fileops_readdir(save);
- selfiles = 0;
- wins[0].field = 9;
- }
- }
- }
- ui_resizewin(&wins[0], wins[0].w, wins[0].h);
- ui_refreshwin(0, 0, 0, wins[0].w, wins[0].h);
- selfield = -1;
- }
- /**
- * On key handler
- */
- void ctrl_fileops_onkey()
- {
- int i, j;
- if(wins[0].field == 9) {
- switch(event.x) {
- case K_LEFT:
- case K_BACKSPC:
- wins[0].field = 7;
- ctrl_fileops_onenter(wins[0].tool == MTOOL_SAVE);
- wins[0].field = 9;
- break;
- case K_RIGHT: ctrl_fileops_onenter(wins[0].tool == MTOOL_SAVE); break;
- case K_UP:
- if(event.h & 1) { if(ordering > 0) ordering--; else ordering = 5; }
- else { if(selfiles > 0) selfiles--; }
- break;
- case K_DOWN:
- if(event.h & 1) { if(ordering < 5) ordering++; else ordering = 0; }
- else { if(selfiles + 1 < numfiles) selfiles++; }
- break;
- case K_PGUP:
- selfiles -= pagefiles - 1;
- if(selfiles < 0) selfiles = 0;
- break;
- case K_PGDN:
- selfiles += pagefiles - 1;
- if(selfiles >= numfiles) selfiles = numfiles - 1;
- break;
- case K_HOME: selfiles = 0; break;
- case K_END: selfiles = numfiles - 1; break;
- default:
- j = strlen((char*)&event.x);
- for(i = selfiles + 1; i < numfiles && memcmp(files[i].name, (char*)&event.x, j); i++);
- if(i < numfiles) selfiles = i;
- else {
- for(i = 0; i < selfiles && memcmp(files[i].name, (char*)&event.x, j); i++);
- if(i < selfiles) selfiles = i;
- }
- break;
- }
- ui_resizewin(&wins[0], wins[0].w, wins[0].h);
- ui_refreshwin(0, 0, 0, wins[0].w, wins[0].h);
- } else if(event.x == K_DOWN) {
- wins[0].field = 9;
- selfiles = 0;
- ui_resizewin(&wins[0], wins[0].w, wins[0].h);
- ui_refreshwin(0, 0, 0, wins[0].w, wins[0].h);
- }
- fileops_peek(selfiles);
- selfield = 0;
- }
- /**
- * On button press handler
- */
- void ctrl_fileops_onbtnpress(int save)
- {
- int i, j = wins[0].w / 4;
- selfield = 0; wins[0].field = -1;
- if(event.y >= 29 && event.y <= 49) {
- if(event.x >= wins[0].w - 132 && event.x <= wins[0].w - 8) wins[0].field = 8;
- else {
- for(i = 0; i < pathlen; i++)
- if(event.x >= pathX[i] - 3 && event.x <= pathX[i + 1] - 5) {
- selfield = 7 + i; break;
- }
- }
- } else
- if(event.y > 51 && event.y < 73) {
- if(event.x >= 26 && event.x <= wins[0].w - 287) selfield = 1; else
- if(event.x >= wins[0].w - 288 && event.x <= wins[0].w - 167) selfield = 2; else
- if(event.x >= wins[0].w - 168 && event.x <= wins[0].w - 10) selfield = 3;
- } else
- if(event.y > 73 && event.y <= wins[0].h - 51) {
- wins[0].field = 9;
- if(event.x >= wins[0].w - 20 && numfiles) {
- i = 72 + (wins[0].h - 144) * scrollfiles / numfiles; j = 20 + (wins[0].h - 144) * pagefiles / numfiles;
- if(event.y >= i && event.y < i + j) { selfield = 5; scrolly = event.y - i; }
- } else {
- if(event.w & 1) {
- selfiles = (event.y - 73) / 16 + scrollfiles;
- if(selfiles >= numfiles) selfiles = numfiles - 1;
- if(selfiles != clkfiles) clkfiles = selfiles;
- else ctrl_fileops_onenter(save);
- } else
- if(event.w & (1 << 3)) {
- if(scrollfiles > 0) scrollfiles--;
- if(selfiles > scrollfiles + pagefiles - 1) selfiles = scrollfiles + pagefiles - 1;
- } else
- if(event.w & (1 << 4)) {
- if(scrollfiles + pagefiles < numfiles) scrollfiles++;
- if(selfiles < scrollfiles) selfiles = scrollfiles;
- }
- fileops_peek(selfiles);
- }
- ui_resizewin(&wins[0], wins[0].w, wins[0].h);
- } else
- if(event.y >= wins[0].h - 44 && event.y <= wins[0].h - 18) {
- if(!save) {
- if(event.x >= 80 && event.x <= 160) wins[0].field = 10; else
- if(event.x >= 164 && event.x <= 240) wins[0].field = 11; else
- if(event.x >= 250 && event.x <= 440 && event.x <= wins[0].w - 16 - j) replace ^= 1;
- if(wins[0].w - 16 - j > 548) {
- if(event.x >= 440 && event.x < 492) {
- if(event.w & (1 << 3)) { if(px < 128) px++; } else
- if(event.w & (1 << 4)) { if(px > 8) px--; } else
- if(event.x >= 480) selfield = 14 + (event.y - (wins[0].h - 44) > 12 ? 1 : 0); else wins[0].field = 14;
- } else
- if(event.x >= 496 && event.x < 548) {
- if(event.w & (1 << 3)) { if(py < 128) py++; } else
- if(event.w & (1 << 4)) { if(py > 8) py--; } else
- if(event.x >= 536) selfield = 16 + (event.y - (wins[0].h - 44) > 12 ? 1 : 0); else wins[0].field = 15;
- }
- }
- } else {
- if(event.x >= 8 && event.x <= 60) { ascii ^= 1; if(ascii) zip = 0; } else
- if(event.x >= 64 && event.x <= 124) { zip ^= 1; if(zip) ascii = 0; } else
- if(event.x >= 128 && event.x <= wins[0].w - 16 - j) wins[0].field = 12;
- }
- if(event.x >= wins[0].w - 12 - j && event.x <= wins[0].w - 12) selfield = 4;
- }
- }
- /**
- * On click (button release) handler
- */
- void ctrl_fileops_onclick(int save)
- {
- int i, j = wins[0].w / 4;
- #ifdef __WIN32__
- if(selfield == 7 && event.y > 54 && event.y < 54 + numdrives * 16 && event.x >= 10 && event.x < 42) {
- strcpy(path[0], &drives[((event.y - 54) / 16) * 4]);
- strcpy(fn, path[0]);
- pathlen = 1;
- fileops_readdir(save);
- path[pathlen][strlen(path[pathlen]) - 1] = 0;
- } else
- #endif
- if(event.y >= 29 && event.y <= 49) {
- if(event.x < wins[0].w - 132 && selfield >= 7 && event.x >= pathX[selfield-7] - 3 && event.x <= pathX[selfield-6] - 5) {
- pathlen = selfield - 6;
- for(fn[0] = 0, i = 0; i < pathlen; i++)
- strcat(fn, path[i]);
- fileops_readdir(save);
- path[pathlen][strlen(path[pathlen]) - 1] = 0;
- }
- } else
- if(event.y > 51 && event.y < 73) {
- if(event.x >= 26 && event.x <= wins[0].w - 287 && selfield == 1) {
- if(ordering == 0) ordering = 1; else ordering = 0;
- } else
- if(event.x >= wins[0].w - 288 && event.x <= wins[0].w - 167 && selfield == 2) {
- if(ordering == 2) ordering = 3; else ordering = 2;
- } else
- if(event.x >= wins[0].w - 168 && event.x <= wins[0].w - 10 && selfield == 3) {
- if(ordering == 4) ordering = 5; else ordering = 4;
- }
- fileops_readdir(save);
- } else
- if(event.y >= wins[0].h - 44 && event.y <= wins[0].h - 18) {
- if(wins[0].w - 16 - j > 548) {
- if(event.x >= 480 && event.x < 492) {
- if(selfield == 14) { if(px < 128) px++; } else
- if(selfield == 15) { if(px > 8) px--; }
- } else
- if(event.x >= 536 && event.x < 548) {
- if(selfield == 16) { if(py < 128) py++; } else
- if(selfield == 17) { if(py > 8) py--; }
- }
- }
- if(event.x >= wins[0].w - 12 - j && event.x <= wins[0].w - 12 && selfield == 4) {
- wins[0].field = 13;
- ctrl_fileops_onenter(save);
- wins[0].field = 9;
- }
- }
- selfield = scrolly = 0;
- }
- /**
- * On mouse move handler
- */
- void ctrl_fileops_onmove()
- {
- int i;
- if(selfield == 5 && event.y > 73 && event.y < wins[0].h - 72) {
- i = scrollfiles;
- scrollfiles = (event.y - scrolly - 73) * numfiles / (wins[0].h - 144);
- if(scrollfiles > numfiles - pagefiles) scrollfiles = numfiles - pagefiles;
- if(scrollfiles < 0) scrollfiles = 0;
- if(selfiles < scrollfiles) selfiles = scrollfiles;
- if(selfiles > scrollfiles + pagefiles - 1) selfiles = scrollfiles + pagefiles - 1;
- if(i != scrollfiles) {
- ui_resizewin(&wins[0], wins[0].w, wins[0].h);
- ui_refreshwin(0, 0, 0, wins[0].w, wins[0].h);
- }
- }
- if(px && event.y >= wins[0].h - 44 && event.y <= wins[0].h - 18 && event.x >= 440 && event.x < wins[0].w - 16 - wins[0].w / 4)
- status = lang[FILEOP_GDIM];
- #ifdef __WIN32__
- if(selfield == 7 && event.y > 54 && event.y < 54 + numdrives * 16 && event.x >= 10 && event.x < 42) {
- i = (event.y - 54) / 16;
- if(i != seldrive) {
- seldrive = i;
- ui_resizewin(&wins[0], wins[0].w, wins[0].h);
- ui_refreshwin(0, 0, 0, wins[0].w, wins[0].h);
- }
- } else
- seldrive = -1;
- #endif
- }
- /**
- * Save modified font question window
- */
- void view_dosave()
- {
- ui_win_t *win = &wins[0];
- question_y = (win->h / 2) + 16;
- ssfn_dst.bg = 0;
- ui_text(win, (win->w - ui_textwidth(lang[FILEOP_DOSAVE])) / 2, question_y - 48, lang[FILEOP_DOSAVE]);
- ui_button(win, 20, question_y, (win->w - 80) / 2, lang[FILEOP_YES], selfield == 1, win->field == 7);
- ui_button(win, win->w / 2 + 20, question_y, (win->w - 80) / 2, lang[FILEOP_NO], selfield == 2 ? 3 : 2, win->field == 8);
- }
- /**
- * On enter handler
- */
- void ctrl_dosave_onenter()
- {
- if(wins[0].field != 8) {
- wins[0].tool = MAIN_TOOL_SAVE;
- wins[0].field = 12; selfield = -1;
- ui_resizewin(&wins[0], wins[0].w, wins[0].h);
- ui_refreshwin(0, 0, 0, wins[0].w, wins[0].h);
- ctrl_fileops_onenter(1);
- }
- modified = 0;
- }
- /**
- * On button press handler
- */
- void ctrl_dosave_onbtnpress()
- {
- selfield = 0;
- if(question_y && event.y >= question_y && event.y < question_y + 20)
- selfield = (event.x < wins[0].w / 2) ? 1 : 2;
- }
- /**
- * On click (button release) handler
- */
- void ctrl_dosave_onclick()
- {
- int x = wins[0].w / 2;
- if(question_y && event.y >= question_y && event.y < question_y + 20) {
- if(event.x < x && selfield == 1) { wins[0].field = 7; ctrl_dosave_onenter(); }
- if(event.x > x && selfield == 2) { wins[0].field = 8; ctrl_dosave_onenter(); }
- }
- }
- /**
- * Start new font question window
- */
- void view_new()
- {
- ui_win_t *win = &wins[0];
- question_y = (win->h / 2) + 16;
- ssfn_dst.bg = 0;
- ui_text(win, (win->w - ui_textwidth(lang[FILEOP_NEW])) / 2, question_y - 48, lang[FILEOP_NEW]);
- ui_button(win, 20, question_y, (win->w - 80) / 2, lang[FILEOP_YES], selfield == 1 ? 3 : 2, win->field == 7);
- ui_button(win, win->w / 2 + 20, question_y, (win->w - 80) / 2, lang[FILEOP_NO], selfield == 2, win->field == 8);
- }
- /**
- * On enter handler
- */
- void ctrl_new_onenter()
- {
- int i;
- if(wins[0].field != 8) {
- for(i=1; i < numwin; i++)
- if(wins[i].winid)
- ui_closewin(i);
- numwin = 1;
- sfn_free(); sfn_init(ui_pb);
- }
- wins[0].tool = MAIN_TOOL_GLYPHS;
- wins[0].field = selfield = -1;
- }
- /**
- * On key handler
- */
- void ctrl_new_onkey()
- {
- if(event.x == K_BACKSPC) {
- wins[0].tool = MAIN_TOOL_GLYPHS;
- wins[0].field = selfield = -1;
- }
- }
- /**
- * On button press handler
- */
- void ctrl_new_onbtnpress()
- {
- selfield = 0;
- if(question_y && event.y >= question_y && event.y < question_y + 20)
- selfield = (event.x < wins[0].w / 2) ? 1 : 2;
- }
- /**
- * On click (button release) handler
- */
- void ctrl_new_onclick()
- {
- int x = wins[0].w / 2;
- if(question_y && event.y >= question_y && event.y < question_y + 20) {
- if(event.x < x && selfield == 1) { wins[0].field = 7; ctrl_new_onenter(); }
- if(event.x > x && selfield == 2) { wins[0].field = 8; ctrl_new_onenter(); }
- }
- }
|