void editcell(CELLPTR ecell) /* Edits a selected cell */ { char s[MAXINPUT + 1]; if (ecell == NULL) return; switch(ecell->attrib) { case TEXT : strcpy(s, ecell->v.text); break; case VALUE : if (ecell->v.value == HUGE_VAL) strcpy(s, "0"); else sprintf(s, "%.*f", MAXPLACES, ecell->v.value); break; case FORMULA : strcpy(s, ecell->v.f.formula); break; } /* switch */ if (!editstring(s, "", MAXINPUT) || (s[0] == 0)) return; act(s); changed = TRUE; } /* editcell */
char *getstring (int w, char *str, char *head, char *mesg) { register r, c, h; int len; BOX *box; static char buf [81]; len = strlen (mesg); if (len > w) w = len; len = strlen (head); if (len > w) w = len; h = 4; w += 4; r = LINES/4; c = (78 - w) / 2; box = VGetBox (r-1, c-2, h+2, w+4); /* save box */ VStandOut (); VSetDim (); VFillBox (r-1, c-2, h+2, w+4, ' '); /* clear */ VDrawBox (r, c, h, w); /* draw margins */ VMPutString (r, c + (w-strlen(head)) / 2, head); /* head */ VMPutString (r+1, c+2, mesg); /* message */ VStandEnd (); VSetNormal (); strncpy (buf, str ? str : "", 80); str = editstring (r+2, c+2, w-4, buf, 0); VUngetBox (box); VFreeBox (box); return (str); }
/* Reads and acts on an input string from the keyboard that started with c. */ void getinput(int c) { char s[MAXINPUT+1]; s[0]=c; s[1]=0; if (!editstring(s,"",MAXINPUT)||(s[0]==0)) return; act(s); changed=TRUE; } /* getinput */
/* Reads in a positive integer from low to high */ int getint(int *number, int low, int high) { int i, good = FALSE; char s[5], message[81]; s[0] = 0; sprintf(message, MSGBADNUMBER, low, high); do { if (!editstring(s, "1234567890", 4)) return(FALSE); i = atoi(s); if ((good = ((i >= low) && (i <= high))) == 0) errormsg(message); } while (!good); *number = i; return(TRUE); } /* getint */
/* Reads in a cell name that was typed in - Returns FALSE if ESC was pressed */ int getcell(int *col, int *row) { int first = TRUE, good = FALSE, len, numlen = rowwidth(MAXROWS), oldcol = *col, oldrow = *row; char data[10], *input, *start, numstring[6]; data[0] = 0; do { if (!first) errormsg(MSGBADCELL); first = FALSE; input = data; if (!editstring(data, "", numlen + 2)) { *col = oldcol; *row = oldrow; return(FALSE); } *col = toupper(*(input++)) - 'A'; if (isalpha(*input)) { *col *= 26; *col += toupper(*(input++)) - 'A' + 26; } if (*col >= MAXCOLS) continue; start = input; for (len = 0; len < numlen; len++) { if (!isdigit(*(input++))) { input--; break; } } if (len == 0) continue; strncpy(numstring, start, len); numstring[len] = 0; *row = atoi(numstring) - 1; if ((*row >= MAXROWS) || (*row == -1) || (*input != 0)) continue; good = TRUE; } while (!good); return(TRUE); } /* getcell */
int fileselector(char *name, char *path, char *filter, char *title, int filemode) { int c, d, scrrep; int color; int files; int filepos = 0; int fileview = 0; int lastclick = 0; int lastfile = 0; int lowest; int exitfilesel; DIR *dir; struct dirent *de; struct stat st; #ifdef __WIN32__ char drivestr[] = "A:\\"; char driveexists[26]; #endif char cmpbuf[MAX_PATHNAME]; char tempname[MAX_PATHNAME]; // Set initial path (if any) if (strlen(path)) chdir(path); // Scan for all existing drives #ifdef __WIN32__ for (c = 0; c < 26; c++) { drivestr[0] = 'A'+c; if (GetDriveType(drivestr) > 1) driveexists[c] = 1; else driveexists[c] = 0; } #endif // Read new directory NEWPATH: getcwd(path, MAX_PATHNAME); files = 0; // Deallocate old names for (c = 0; c < MAX_DIRFILES; c++) { if (direntry[c].name) { free(direntry[c].name); direntry[c].name = NULL; } } #ifdef __WIN32__ // Create drive letters for (c = 0; c < 26; c++) { if (driveexists[c]) { drivestr[0] = 'A'+c; direntry[files].name = strdup(drivestr); direntry[files].attribute = 2; files++; } } #endif // Process directory #ifdef __amigaos__ dir = opendir(""); #else dir = opendir("."); #endif if (dir) { char *filtptr = strstr(filter, "*"); if (!filtptr) filtptr = filter; else filtptr++; for (c = 0; c < strlen(filter); c++) filter[c] = tolower(filter[c]); while ((de = readdir(dir))) { if ((files < MAX_DIRFILES) && (strlen(de->d_name) < MAX_FILENAME)) { direntry[files].name = strdup(de->d_name); direntry[files].attribute = 0; stat(de->d_name, &st); if (st.st_mode & S_IFDIR) { direntry[files].attribute = 1; files++; } else { int c; // If a file, must match filter strcpy(cmpbuf, de->d_name); if ((!strcmp(filtptr, "*")) || (!strcmp(filtptr, ".*"))) files++; else { for (c = 0; c < strlen(cmpbuf); c++) cmpbuf[c] = tolower(cmpbuf[c]); if (strstr(cmpbuf, filtptr)) files++; else { free(direntry[files].name); direntry[files].name = NULL; } } } } } closedir(dir); } // Sort the filelist in a most horrible fashion for (c = 0; c < files; c++) { lowest = c; for (d = c+1; d < files; d++) { if (direntry[d].attribute < direntry[lowest].attribute) { lowest = d; } else { if (direntry[d].attribute == direntry[lowest].attribute) { if (cmpname(direntry[d].name, direntry[lowest].name) < 0) { lowest = d; } } } } if (lowest != c) { DIRENTRY swaptemp = direntry[c]; direntry[c] = direntry[lowest]; direntry[lowest] = swaptemp; } } // Search for the current filename fileview = 0; filepos = 0; for (c = 0; c < files; c++) { if ((!direntry[c].attribute) && (!cmpname(name, direntry[c].name))) { filepos = c; } } exitfilesel = -1; while (exitfilesel < 0) { int cc = cursorcolortable[cursorflash]; if (cursorflashdelay >= 6) { cursorflashdelay %= 6; cursorflash++; cursorflash &= 3; } fliptoscreen(); getkey(); if (lastclick) lastclick--; if (win_quitted) { exitprogram = 1; for (c = 0; c < MAX_DIRFILES; c++) { if (direntry[c].name) { free(direntry[c].name); direntry[c].name = NULL; } } return 0; } if (mouseb) { // Cancel (click outside) if ((mousey < 3) || (mousey > 3+VISIBLEFILES+6) || (mousex <= 4+10) || (mousex >= 75+10)) { if ((!prevmouseb) && (lastclick)) exitfilesel = 0; } // Select dir,name,filter if ((mousey >= 3+VISIBLEFILES+3) && (mousey <= 3+VISIBLEFILES+5) && (mousex >= 14+10) && (mousex <= 73+10)) { filemode = mousey - (3+VISIBLEFILES+3) + 1; if ((filemode == 3) && (!prevmouseb) && (lastclick)) goto ENTERFILE; } // Select file from list if ((mousey >= 3) && (mousey <= 3+VISIBLEFILES+2) && (mousex >= 6+10) && (mousex <= 73+10)) { filemode = 0; filepos = mousey - 4 - 1 + fileview; if (filepos < 0) filepos = 0; if (filepos > files-1) filepos = files - 1; if (!direntry[filepos].attribute) strcpy(name, direntry[filepos].name); if ((!prevmouseb) && (lastclick) && (lastfile == filepos)) goto ENTERFILE; } } if (!filemode) { if (((key >= '0') && (key <= '0')) || ((key >= 'a') && (key <= 'z')) || ((key >= 'A') && (key <= 'Z'))) { char k = tolower(key); int oldfilepos = filepos; for (filepos = oldfilepos + 1; filepos < files; filepos++) if (tolower(direntry[filepos].name[0]) == k) break; if (filepos >= files) { for (filepos = 0; filepos < oldfilepos; filepos++) if (tolower(direntry[filepos].name[0]) == k) break; } if (!direntry[filepos].attribute) strcpy(name, direntry[filepos].name); } } switch(rawkey) { case KEY_ESC: exitfilesel = 0; break; case KEY_BACKSPACE: if (!filemode) { #ifdef __amigaos__ chdir("/"); #else chdir(".."); #endif goto NEWPATH; } break; case KEY_HOME: if (!filemode) { filepos = 0; if (!direntry[filepos].attribute) strcpy(name, direntry[filepos].name); } break; case KEY_END: if (!filemode) { filepos = files-1; if (!direntry[filepos].attribute) strcpy(name, direntry[filepos].name); } break; case KEY_PGUP: for (scrrep = PGUPDNREPEAT; scrrep; scrrep--) { if ((!filemode) && (filepos > 0)) { filepos--; if (!direntry[filepos].attribute) strcpy(name, direntry[filepos].name); } } break; case KEY_UP: if ((!filemode) && (filepos > 0)) { filepos--; if (!direntry[filepos].attribute) strcpy(name, direntry[filepos].name); } break; case KEY_PGDN: for (scrrep = PGUPDNREPEAT; scrrep; scrrep--) { if ((!filemode) && (filepos < files-1)) { filepos++; if (!direntry[filepos].attribute) strcpy(name, direntry[filepos].name); } } break; case KEY_DOWN: if ((!filemode) && (filepos < files-1)) { filepos++; if (!direntry[filepos].attribute) strcpy(name, direntry[filepos].name); } break; case KEY_TAB: if (!shiftpressed) { filemode++; if (filemode > 3) filemode = 0; } else { filemode--; if (filemode < 0) filemode = 3; } break; case KEY_ENTER: ENTERFILE: switch(filemode) { case 0: switch (direntry[filepos].attribute) { case 0: strcpy(name, direntry[filepos].name); exitfilesel = 1; break; case 1: chdir(direntry[filepos].name); goto NEWPATH; case 2: strcpy(tempname, direntry[filepos].name); if (strlen(tempname)) { if (tempname[strlen(tempname)-1] != '\\') strcat(tempname, "\\"); } chdir(tempname); goto NEWPATH; } break; case 1: chdir(path); case 2: filemode = 0; goto NEWPATH; case 3: exitfilesel = 1; break; } break; } switch(filemode) { case 1: editstring(path, MAX_PATHNAME); break; case 2: editstring(filter, MAX_FILENAME); break; case 3: editstring(name, MAX_FILENAME); break; } // Validate filelist view if (filepos < fileview) fileview = filepos; if (filepos - fileview >= VISIBLEFILES) fileview = filepos - VISIBLEFILES + 1; // Refresh fileselector display if (isplaying()) printstatus(); for (c = 0; c < VISIBLEFILES+7; c++) { printblank(50-(MAX_FILENAME+10)/2, 3+c, MAX_FILENAME+10); } drawbox(50-(MAX_FILENAME+10)/2, 3, 15, MAX_FILENAME+10, VISIBLEFILES+7); printblankc(50-(MAX_FILENAME+10)/2+1, 4, 15+16,MAX_FILENAME+8); printtext(50-(MAX_FILENAME+10)/2+1, 4, 15+16, title); for (c = 0; c < VISIBLEFILES; c++) { if ((fileview+c >= 0) && (fileview+c < files)) { switch (direntry[fileview+c].attribute) { case 0: sprintf(textbuffer, "%-60s ", direntry[fileview+c].name); break; case 1: sprintf(textbuffer, "%-60s <DIR>", direntry[fileview+c].name); break; case 2: sprintf(textbuffer, "%-60s <DRV>", direntry[fileview+c].name); break; } } else { sprintf(textbuffer, " "); } color = CNORMAL; if ((fileview+c) == filepos) color = CEDIT; textbuffer[68] = 0; printtext(50-(MAX_FILENAME+10)/2+1, 5+c, color, textbuffer); if ((!filemode) && ((fileview+c) == filepos)) printbg(50-(MAX_FILENAME+10)/2+1, 5+c, cc, 68); } printtext(50-(MAX_FILENAME+10)/2+1, 6+VISIBLEFILES, 15, "PATH: "); sprintf(textbuffer, "%-60s", path); textbuffer[MAX_FILENAME] = 0; color = CNORMAL; if (filemode == 1) color = CEDIT; printtext(50-(MAX_FILENAME+10)/2+9, 6+VISIBLEFILES, color, textbuffer); if ((filemode == 1) && (strlen(path) < MAX_FILENAME)) printbg(50-(MAX_FILENAME+10)/2+9+strlen(path), 6+VISIBLEFILES, cc, 1); printtext(50-(MAX_FILENAME+10)/2+1, 7+VISIBLEFILES, 15, "FILTER: "); sprintf(textbuffer, "%-60s", filter); textbuffer[MAX_FILENAME] = 0; color = CNORMAL; if (filemode == 2) color = CEDIT; printtext(50-(MAX_FILENAME+10)/2+9, 7+VISIBLEFILES, color, textbuffer); if (filemode == 2) printbg(50-(MAX_FILENAME+10)/2+9+strlen(filter), 7+VISIBLEFILES, cc, 1); printtext(50-(MAX_FILENAME+10)/2+1, 8+VISIBLEFILES, 15, "NAME: "); sprintf(textbuffer, "%-60s", name); textbuffer[MAX_FILENAME] = 0; color = CNORMAL; if (filemode == 3) color = CEDIT; printtext(50-(MAX_FILENAME+10)/2+9, 8+VISIBLEFILES, color, textbuffer); if (filemode == 3) printbg(50-(MAX_FILENAME+10)/2+9+strlen(name), 8+VISIBLEFILES, cc, 1); if (win_quitted) exitfilesel = 0; if ((mouseb) && (!prevmouseb)) { lastclick = DOUBLECLICKDELAY; lastfile = filepos; } } // Deallocate all used names for (c = 0; c < MAX_DIRFILES; c++) { if (direntry[c].name) { free(direntry[c].name); direntry[c].name = NULL; } } // Restore screen & exit printmainscreen(); return exitfilesel; }
static void mainloop(struct gopherus *g) { int exitflag; int bufferlen; for (;;) { struct url *url = &(g->history->url); /* a shortcut */ if ((url->itemtype == GOPHER_ITEM_FILE) || (url->itemtype == GOPHER_ITEM_DIR) || (url->itemtype == GOPHER_ITEM_INDEX_SEARCH_SERVER) || (url->itemtype == GOPHER_ITEM_HTML)) { /* if it's a displayable item type... */ draw_urlbar(url, &g->cfg); if (g->history->cache == NULL) { /* reload the resource if not in cache already */ bufferlen = loadfile_buff(url, g->buf, buffersize, g->statusbar, NULL, &g->cfg); if (bufferlen < 0) { history_back(&g->history); continue; } else { history_cleanupcache(g->history); g->history->cache = malloc(bufferlen); if (g->history->cache == NULL) { sprintf(g->statusbar, "Out of memory!"); exitflag = 1; break; } if (bufferlen > 0) memcpy(g->history->cache, g->buf, bufferlen); g->history->cachesize = bufferlen; } } switch (url->itemtype) { case GOPHER_ITEM_FILE: /* text file */ exitflag = display_text(g, TXT_FORMAT_RAW); break; case GOPHER_ITEM_HTML: /* html file */ exitflag = display_text(g, TXT_FORMAT_HTM); break; case GOPHER_ITEM_DIR: /* menu */ case GOPHER_ITEM_INDEX_SEARCH_SERVER: /* query result (also a menu) */ exitflag = display_menu(g); break; default: set_statusbar(g->statusbar, "Fatal error: got an unhandled itemtype!"); exitflag = DISPLAY_ORDER_QUIT; break; } if (exitflag == DISPLAY_ORDER_BACK) { history_back(&(g->history)); } else if (exitflag == DISPLAY_ORDER_REFR) { free(g->history->cache); g->history->cache = NULL; g->history->cachesize = 0; g->history->displaymemory[0] = -1; g->history->displaymemory[1] = -1; } else if (exitflag == DISPLAY_ORDER_QUIT) { break; } } else { /* the itemtype is not one of the internally displayable types -> ask to download it */ char filename[64] = {0}; static const char prompt[] = "Download as: "; char *lastslash = strrchr(url->selector, '/'); set_statusbar(filename, ""); /* make sure to clear out the status bar */ draw_statusbar(filename, &g->cfg); ui_cputs(prompt, 0x70, 0, ui_rows - 1); if (lastslash) strncpy(filename, lastslash + 1, sizeof filename - 1); if (editstring(filename, 63, ui_cols - (sizeof prompt - 1), sizeof prompt - 1, ui_rows - 1, 0x70, NULL) != 0) { loadfile_buff(url, g->buf, buffersize, g->statusbar, filename, &g->cfg); } history_back(&(g->history)); } } }
void printsheet(void) /* Prints a copy of the spreadsheet to a file or to the printer */ { char filename[MAXINPUT + 1], s[133], colstr[MAXCOLWIDTH + 1]; FILE *file; int columns, counter1, counter2, counter3, col = 0, row, border, toppage, lcol, lrow, dummy, printed, oldlastcol; filename[0] = 0; writeprompt(MSGPRINT); if (!editstring(filename, "", MAXINPUT)) return; if (filename[0] == 0) strcpy(filename, "PRN"); if ((file = fopen(filename, "wt")) == NULL) { errormsg(MSGNOOPEN); return; } oldlastcol = lastcol; for (counter1 = 0; counter1 <= lastrow; counter1++) { for (counter2 = lastcol; counter2 < MAXCOLS; counter2++) { if (format[counter2][counter1] >= OVERWRITE) lastcol = counter2; } } if (!getyesno(&columns, MSGCOLUMNS)) return; columns = (columns == 'Y') ? 131 : 79; if (!getyesno(&border, MSGBORDER)) return; border = (border == 'Y'); while (col <= lastcol) { row = 0; toppage = TRUE; lcol = pagecols(col, border, columns) + col; while (row <= lastrow) { lrow = pagerows(row, toppage, border) + row; printed = 0; if (toppage) { for (counter1 = 0; counter1 < TOPMARGIN; counter1++) { fprintf(file, "\n"); printed++; } } for (counter1 = row; counter1 < lrow; counter1++) { if ((border) && (counter1 == row) && (toppage)) { if ((col == 0) && (border)) sprintf(s, "%*s", LEFTMARGIN, ""); else s[0] = 0; for (counter3 = col; counter3 < lcol; counter3++) { centercolstring(counter3, colstr); strcat(s, colstr); } fprintf(file, "%s\n", s); printed++; } if ((col == 0) && (border)) sprintf(s, "%-*d", LEFTMARGIN, counter1 + 1); else s[0] = 0; for (counter2 = col; counter2 < lcol; counter2++) strcat(s, cellstring(counter2, counter1, &dummy, FORMAT)); fprintf(file, "%s\n", s); printed++; } row = lrow; toppage = FALSE; if (printed < 66) fprintf(file, "%c", FORMFEED); } col = lcol; } fclose(file); lastcol = oldlastcol; } /* printsheet */
void savesheet(void) /* Saves the current spreadsheet */ { char filename[MAXINPUT+1], eof = 26; int size, col, row, overwrite, file; CELLPTR cellptr; filename[0] = 0; writeprompt(MSGFILENAME); if (!editstring(filename, "", MAXINPUT)) return; if (!access(filename, 0)) { if (!getyesno(&overwrite, MSGOVERWRITE) || (overwrite == 'N')) return; } if ((file = open(filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, S_IREAD | S_IWRITE)) == -1) { errormsg(MSGNOOPEN); return; } writef(1, 25, PROMPTCOLOR, 79, MSGSAVING); gotoxy(strlen(MSGSAVING) + 1, 25); write(file, name, strlen(name) + 1); write(file, &eof, 1); write(file, (char *)&lastcol, 2); write(file, (char *)&lastrow, 2); size = MAXCOLS; write(file, (char *)&size, 2); write(file, colwidth, sizeof(colwidth)); for (row = 0; row <= lastrow; row++) { for (col = lastcol; col >= 0; col--) { if (cell[col][row] != NULL) { cellptr = cell[col][row]; switch(cellptr->attrib) { case TEXT : size = strlen(cellptr->v.text) + 2; break; case VALUE : size = sizeof(double) + 1; break; case FORMULA : size = strlen(cellptr->v.f.formula) + 2 + sizeof(double); break; } /* switch */ write(file, (char *)&col, 2); write(file, (char *)&row, 2); write(file, (char *)&format[col][row], 1); write(file, (char *)&size, 2); write(file, (char *)cellptr, size); } } } close(file); writef(1, 25, WHITE, strlen(MSGSAVING), ""); gotoxy(1, 25); changed = FALSE; } /* savesheet */
void loadsheet(char *filename) /* Loads a new spreadsheet */ { int size, allocated, reallastcol = 0, reallastrow = 0, file; char check[81]; if (filename[0] == 0) { writeprompt(MSGFILENAME); if (!editstring(filename, "", MAXINPUT)) return; } if (access(filename, 0)) { errormsg(MSGNOEXIST); return; } if ((file = open(filename, O_RDWR | O_BINARY)) == -1) { errormsg(MSGNOOPEN); return; } read(file, check, strlen(name) + 1); if (strcmp(check, name) != 0) { errormsg(MSGNOTURBOCALC); close(file); return; } writef(1, 25, PROMPTCOLOR, 79, MSGLOADING); gotoxy(strlen(MSGLOADING) + 1, 25); clearsheet(); read(file, (char *)&size, 1); read(file, (char *)&lastcol, 2); read(file, (char *)&lastrow, 2); read(file, (char *)&size, 2); read(file, colwidth, sizeof(colwidth)); do { if (read(file, (char *)&curcol, 2) <= 0) break; read(file, (char *)&currow, 2); read(file, &format[curcol][currow], 1); read(file, (char *)&size, 2); read(file, (char *)&rec, size); switch (rec.attrib) { case TEXT : if ((allocated = alloctext(curcol, currow, rec.v.text)) == TRUE) setoflags(curcol, currow, NOUPDATE); break; case VALUE : allocated = allocvalue(curcol, currow, rec.v.value); break; case FORMULA : allocated = allocformula(curcol, currow, rec.v.f.formula, rec.v.f.fvalue); break; } /* switch */ if (!allocated) { errormsg(MSGFILELOMEM); lastrow = reallastrow; lastcol = reallastcol; format[curcol][currow] = DEFAULTFORMAT; break; } else { if (curcol > reallastcol) reallastcol = curcol; if (currow > reallastrow) reallastrow = currow; } } while (TRUE); writef(1, 25, WHITE, strlen(MSGLOADING), ""); gotoxy(1, 25); printfreemem(); close(file); curcol = currow = 0; setrightcol(); displayscreen(NOUPDATE); changed = FALSE; } /* loadsheet */