/* $Id: tablewidget.c,v 1.4 2006/09/15 13:34:06 toad32767 Exp $ */ /** ** 2004, 2005, 2006 by Marco Trillo ** This file is part of UModPlayer, and is released by ** its autors to the Public Domain. ** In case it's not legally possible, its autors grant ** anyone the right to use, redistribute and modify ** this software for any purpose, without any conditions, ** unless such conditions are required by law. ** ** THIS FILE COMES WITHOUT ANY WARRANTY. THE AUTHORS ** SHALL NOT BE LIABLE FOR ANY DAMAGE RESULTING BY THE ** USE OR MISUSE OF THIS SOFTWARE. **/ #include #include #include #include "tablewidget.h" /* Themes */ #define TABLE_SYMBOLS 6 enum { TABLE_UPPER_BOUND = 0, TABLE_LOWER_BOUND = 1, TABLE_BASE = 2, TABLE_EDGE = 3, TABLE_WALL = 4, TABLE_CAPTION_SPACER = 5 }; LOCAL char Classic[TABLE_SYMBOLS] = { '+', '+', '-', '+', '|', ' ' }; LOCAL char Strong[TABLE_SYMBOLS] = { '+', '+', '=', '+', '|', '-' }; LOCAL char Boxed[TABLE_SYMBOLS] = { '/', '\\', '-', '+', '|', ' ' }; /* Public functions */ EXPORT int TableInitCallback(WTable * table, TableCallback callback) { if (!table) return TABLE_ERR_NOTABLE; table->callback = callback; return TABLE_OK; } EXPORT int TableSetOptions(WTable * table, int ID, int rows, int cols, int len, int spacer, int align) { if (!table) return TABLE_ERR_NOTABLE; if (rows < 1 || cols < 1 || len < 2 || spacer < 0) { return TABLE_ERR_INVALID; } table->rows = rows; table->cols = cols; table->len = len; table->align = align; table->id = ID; table->spacer = spacer; table->caption = NULL; table->callback = NULL; table->theme = TABLE_THEME_CLASSIC; table->stream = stdout; return TABLE_OK; } EXPORT int TableSetCaption(WTable * table, char *caption) { if (!table) return TABLE_ERR_NOTABLE; if (caption && *caption != '\0') { table->caption = caption; } else table->caption = NULL; return TABLE_OK; } EXPORT int TableSetOutput(WTable * table, FILE * stream) { if (!table) return TABLE_ERR_NOTABLE; if (stream) table->stream = stream; else { return TABLE_ERR_INVALID; } return TABLE_OK; } EXPORT int TableUseTheme(WTable * table, WTheme theme) { if (!table) { return TABLE_ERR_NOTABLE; } switch (theme) { case TABLE_THEME_CLASSIC: case TABLE_THEME_STRONG: case TABLE_THEME_BOXED: break; default: return TABLE_ERR_INVALID; } table->theme = theme; return TABLE_OK; } EXPORT int DrawTable(WTable table) { register int i, j, e, sp; int k; char *symbols; int rows = table.rows; int cols = table.cols; int len = table.len; int align = table.align; int spacer = table.spacer; FILE *stream = table.stream; char upsymbol, losymbol; char buffer[TABLE_BUFFER_SIZE]; char format[9]; if (!stream || !(table.callback)) { return TABLE_ERR_INVALID; } switch (table.theme) { case TABLE_THEME_CLASSIC: symbols = Classic; break; case TABLE_THEME_STRONG: symbols = Strong; break; case TABLE_THEME_BOXED: symbols = Boxed; break; default: return TABLE_ERR_INVALID; } if (table.caption) { sp = (cols * len) - 1; if ((sp & 1) == (strlen(table.caption) & 1)) { /* x & 1 == x % 2 */ i = strlen(table.caption); strcpy(format, "%s"); } else { i = strlen(table.caption) + 1; sprintf(format, "%%s%c", symbols[TABLE_CAPTION_SPACER]); } i = (sp - i) >> 1; /* x >> 1 == x / 2 */ for (e = 0; e < spacer; ++e) putc(' ', stream); putc(symbols[TABLE_UPPER_BOUND], stream); for (e = 0; e < sp; ++e) putc(symbols[TABLE_BASE], stream); putc(symbols[TABLE_LOWER_BOUND], stream); putc('\n', stream); for (e = 0; e < spacer; ++e) putc(' ', stream); putc(symbols[TABLE_WALL], stream); for (e = 0; e < i; ++e) putc(symbols[TABLE_CAPTION_SPACER], stream); fprintf(stream, format, table.caption); for (e = 0; e < i; ++e) putc(symbols[TABLE_CAPTION_SPACER], stream); putc(symbols[TABLE_WALL], stream); putc('\n', stream); upsymbol = losymbol = symbols[TABLE_EDGE]; } else { /* If table hasn`t a caption we need to draw * the first row using special symbols */ upsymbol = symbols[TABLE_UPPER_BOUND]; losymbol = symbols[TABLE_LOWER_BOUND]; } if (align == TABLE_LEFT_ALIGN) { sprintf(format, "%%-%ds", len - 1); } else { sprintf(format, "%%%ds", len - 1); } cols = (cols * len) + 1; rows++; e = 0; for (sp = 0; sp < spacer; ++sp) putchar(' '); for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { if (j % len == 0) { if (j == 0) { if (i == 0) putc(upsymbol, stream); else if (i == table.rows) /* table.rows = rows-1 */ putc(symbols[TABLE_LOWER_BOUND], stream); else putc(symbols[TABLE_EDGE], stream); } else if (j == (cols - 1)) { if (i == 0) putc(losymbol, stream); else if (i == table.rows) putc(symbols[TABLE_UPPER_BOUND], stream); else putc(symbols[TABLE_EDGE], stream); } else putc(symbols[TABLE_EDGE], stream); } else putc(symbols[TABLE_BASE], stream); } putc('\n', stream); for (sp = 0; sp < spacer; ++sp) putc(' ', stream); if (e < table.rows) { k = 0; for (j = 0; j < cols; j++) { if (j % len == 0) { putc(symbols[TABLE_WALL], stream); if (j != (cols - 1)) { table.callback(table.id, i, k, buffer); fprintf(stream, format, buffer); } ++k; } } putc('\n', stream); for (sp = 0; sp < spacer; ++sp) putc(' ', stream); } e++; } return TABLE_OK; } /* * @EOF@ -- revised February 26 2006 */