// Copyright (c) 2003,2004,2005 Juraj Kolesár #include "tt.h" /* table input {{{ ************************************************************/ int tt_table_input(POS point, T_CELL *cell, T_TABLE *table) { bool End = false; bool FromList = false; int Pos = 0; int MaxX, MaxY; int BegX, BegY; int Status = __TT_ERR; int Length; WINDOW *win = NULL; TT_TABLE *v_table = NULL; T_TABLE *f_table = NULL; //Filtered table T_COLS *cols = NULL; T_CELL a_cell[]={{"","",0,0},{"","",cell->width,0}}; cols = g_slist_append(cols, &(a_cell[0])); cols = g_slist_append(cols, &(a_cell[1])); getmaxyx(point.win, MaxY, MaxX); getbegyx(point.win, BegY, BegX); wmove(GET_POS(point) + 1); wrefresh(point.win); Status = tt_input(); OFFSET_POS(point,0,2); if (Status == __TT_ENTER) { Length = tt_table_input_init(MaxY - (point.y + 1), cell->name, table, &f_table); tt_table_init(Length, f_table, &v_table); } else return(Status); //TEMP while (!End) { if (Length > 0) { win = newwin(Length + 2, cell->width + 2, BegY + point.y, BegX + point.x - 1); box(win,0,0); if (FromList) tt_table_draw_list(win, cols, f_table, v_table); else tt_table_draw_list(win, cols, NULL, v_table); } mvwprintw(GET_POS(point) - 1, ">"); tt_str_draw(point, cell->width, Pos, '_', cell->name); Status = tt_str_input(tt_input(), cell->width, &Pos, cell->name); switch (Status) { case(__TT_ENTER): if (FromList) { g_slist_free(cols); cols = f_table->data; //cols USED AS T_ROW strcpy(cell->value, cols->data); strcpy(cell->name, (cols->next)->data); } else if (tt_table_input_inlist(table, cell)) Status = __TT_TAB; else Status = __TT_INS; End = true; break; case(__TT_DOWN): if (FromList) tt_table_next(&f_table, &v_table); else FromList = true; break; case(__TT_UP): if (FromList) tt_table_previous(&f_table, &v_table); else FromList = true; break; default: Length = tt_table_input_init(MaxY - (point.y + 1), cell->name, table, &f_table); tt_table_init(Length, f_table, &v_table); FromList = false; break; } if (win != NULL) { werase(win);wrefresh(win);delwin(win);win = NULL; } } mvwprintw(GET_POS(point) - 1, ".]"); OFFSET_POS(point, 0, 1); tt_str_draw(point, cell->width, Pos, ' ', cell->name); touchwin(point.win); wrefresh(point.win); return(Status); } /* }}} */ /* table {{{ ******************************************************************/ int tt_table (POS point, T_TABLE **table, T_COLS *cols) { bool End = false; int MaxX, MaxY; int BegX, BegY; int Status = __TT_ERR; int win_height; TT_TABLE *v_table = NULL; //single list of visible values T_TABLE *start = *table; WINDOW *win; POS m_point; if (*table == NULL) return(__TT_OK); getmaxyx(point.win, MaxY, MaxX); getbegyx(point.win, BegY, BegX); win_height = MIN(g_list_length_full(*table) + 2, (MaxY - point.y) + 1); win = newwin(win_height, MIN(t_cols_width_sum(cols) + g_slist_length(cols), (MaxX - point.x)), BegY + point.y - 1, BegX + point.x); box(win,0,0); SET_POS(m_point, win, 0, 0); tt_table_draw_cols(m_point, cols); wrefresh(win); tt_table_init(win_height - 2, *table, &v_table); //4= up+down border while (!(End)) { //MAIN OBJECT CYCLE tt_table_draw_list(win, cols, *table, v_table); Status = tt_input(); switch (Status) { case __TT_DOWN: tt_table_next(table, &v_table);break; case __TT_UP: tt_table_previous(table, &v_table);break; case __TT_ESC: End = true; *table = start; break; case __TT_INS: End = true; break; case __TT_TAB: End = true; break; case __TT_DEL: End = true; break; case __TT_ENTER: tt_table_store(*table, cols); End = true; break; } } werase(win);wrefresh(win);delwin(win);touchwin(point.win); return(Status); } /* }}} */ /* table qs {{{ ***************************************************************/ int tt_table_qs (WINDOW * win, T_DB *tdb, T_QS *qs, T_COLS *cols) { bool End = FALSE; int Status; TT_TABLE *v_table = NULL; //single list of visible values //ACTUAL COLUMN char Search[__TT_STR_MAX] = {'\0'}; //search string int Col_width; //culumn width int Column = 0; //column number int Pos = 0; //actual cursor position //CURSES int win_height; int win_width; WINDOW *swin_List; POS point; //DATA CONTAINING T_MATRIX matrix; char SQL_cmd[__T_QS_PARAM_LENGTH * 8] = {'\0'}; //CURSES UI INIT getmaxyx(win, win_height, win_width); getbegyx(win, point.y, point.x); swin_List = subwin(win, win_height - 2, win_width, point.y + 2, point.x); SET_POS(point, win, 1, 1); box(swin_List,0,0); box(win,0,0); wrefresh(win); //TABLE INIT t_cols_next(cols, &Column); t_cols_get_values(cols, Column, &point.x, &Col_width, Search); tdb_qs_set_filter_dynamic(qs, cols, Column); tdb_qs_set_order(qs, cols, Column); if (tdb_table_fill(tdb, &matrix, tdb_qs(SQL_cmd, qs)) == 0) return(__TT_NULL); tt_table_init(win_height - 4, matrix.table, &v_table); //4= up+down border, search line, divide line while (!(End)) { //MAIN OBJECT CYCLE tt_table_draw_list(swin_List, cols, matrix.table, v_table); tt_table_draw_filter(win, cols); tt_str_draw(point, Col_width, Pos, '_', Search); Status = tt_str_input(getch(), Col_width, &Pos, Search); switch (Status) { case __TT_DOWN: tt_table_next(&matrix.table, &v_table);break; case __TT_UP: tt_table_previous(&matrix.table, &v_table);break; case __TT_ESC: End = TRUE; break; case __TT_INS: End = TRUE; break; case __TT_ENTER: tt_table_store(matrix.table, cols); End = TRUE; break; case __TT_TAB: t_cols_set_value(cols, Column, Col_width, Search); t_cols_next(cols, &Column); t_cols_get_values(cols, Column, &point.x, &Col_width, Search); tdb_qs_set_filter_dynamic(qs, cols, Column); tdb_qs_set_order(qs, cols, Column); tdb_table_fill(tdb, &matrix, tdb_qs(SQL_cmd, qs)); tt_table_init(win_height - 4, matrix.table, &v_table); tt_table_search(Search, Column, &matrix.table, &v_table); werase(swin_List); box(swin_List,0,0); box(win,0,0); Pos = 0; break; default: tt_table_find(Search, Column, &matrix.table, &v_table); } } tdb_table_free(&matrix); return(Status); } /* }}} */ /* table combo {{{ ************************************************************/ int tt_table_combo(POS point, T_TABLE **table, T_COLS *cols) { int Status = __TT_ERR; wmove(GET_POS(point) + 1); wrefresh(point.win); Status = tt_input(); if (Status == __TT_ENTER) { Status = tt_table(point, table, cols); tt_table_draw_combo(point, cols, *table); } return(Status); } /* }}} */ /* draw {{{ ***************************************************************/ int tt_table_draw (WINDOW *win, T_COLS *cols, T_TABLE *table) { int MaxX, MaxY; TT_TABLE *v_table = NULL; //single list of visible values T_CELL *cell; POS point; SET_POS(point,win,0,0); if (table == NULL) return(__TT_ERR); getmaxyx(win, MaxY, MaxX); box(win,0,0); tt_table_init(MaxY - 2, table, &v_table); tt_table_draw_list(win, cols, table, v_table); tt_table_draw_cols(point, cols); return(__TT_OK); } /* }}} */ /* draw columns {{{ ***********************************************************/ int tt_table_draw_cols (POS point, T_COLS *cols) { T_CELL *cell; while (cols != NULL) { //go through row values cell = cols->data; if (cell->width != 0) { OFFSET_POS(point, 0, 1); tt_str_draw(point, strlen(cell->name), 0, ' ', cell->name); point.x += cell->width; } cols = g_slist_next(cols); } return(__TT_OK); } /* }}} */ /* draw row {{{ ***************************************************************/ int tt_table_draw_row (POS point, char separator, T_COLS *cols, T_ROW *row) { T_CELL *cell; if (cols == NULL) return(__LT_ERR); while (row != NULL) { //go through row values cell = cols->data; if (cell->width != 0) { wmove(GET_POS(point)); if (separator != 0) waddch(point.win, separator); //draws separator symbol(e.g.cursor) else wvline(point.win,0,1); OFFSET_POS(point, 0, 1); switch (cell->type) { case (T_CELL_STR): tt_str_draw(point, cell->width, 0, ' ', row->data); break; case (T_CELL_DATE): tt_datum_draw(point, row->data); break; } point.x += cell->width; } row = g_slist_next(row); if (cols->next != NULL) cols = g_slist_next(cols); } return(__TT_OK); } /* }}} */ /* draw list {{{ **************************************************************/ int tt_table_draw_list ( WINDOW * win, T_COLS *cols, T_TABLE *table, TT_TABLE *v_table) { POS point = {win, 1, 0}; //first window row is a border int cursor = point.y; while (v_table != NULL) { if (table != NULL) if (v_table->data == table->data) { tt_table_draw_row(point, '>', cols, v_table->data); cursor = point.y; } else tt_table_draw_row(point, 0, cols, v_table->data); else tt_table_draw_row(point, 0, cols, v_table->data); point.y++; v_table = g_slist_next(v_table); } point.y = cursor; wmove(GET_POS(point)); wrefresh(win); return(__TT_OK); } /* }}} */ /* draw combo {{{ *************************************************************/ int tt_table_draw_combo(POS point, T_COLS *cols, T_TABLE *table) { if (table != NULL) { OFFSET_POS(point,0,2); tt_table_draw_row(point, ',', cols, table->data); OFFSET_POS(point,0,-2); mvwprintw(GET_POS(point), "[v]"); } else mvwprintw(GET_POS(point), "[ ]"); return(__TT_OK); } /* }}} */ /* draw input {{{ ************************************************************* int tt_table_draw_input(POS point, T_CELL *cell) { if (strlen(cell->value) > 0) mvwprintw(GET_POS(point), "[.]"); else mvwprintw(GET_POS(point), "[ ]"); return(__TT_OK); } /* }}} */ /* draw filter {{{ ************************************************************/ int tt_table_draw_filter (WINDOW *win, GSList *cols) { POS point = {win, 1, 0}; T_CELL *cell; while (cols != NULL) { cell = cols->data; if (cell->width > 0) { wmove(win, 1, point.x); wvline(win, 0, 1); point.x++; tt_str_draw(point, cell->width, 0, ' ', cell->value); point.x += cell->width; } cols = g_slist_next(cols); } return(__TT_OK); } /* }}} */ /* init {{{ *******************************************************************/ int tt_table_init(int rows, T_TABLE *table, TT_TABLE **v_table) { register int count = 0; int length; if (table != NULL) length = g_list_length(table); else return(count); g_slist_free(*v_table); *v_table = NULL; if (length < rows) if (g_list_length(g_list_first(table)) > rows) for (count = 0; count < (rows - length); count++) table = g_list_previous(table); else table = g_list_first(table); for (count=0; count < rows; count++) { if (table != NULL) *v_table = g_slist_append(*v_table, table->data); else break; if (table->next != NULL) table = g_list_next(table); else break; } return(count); } /* }}} */ /* input init{{{ *************************************************************/ int tt_table_input_init( int rows, char *filter, T_TABLE *table, T_TABLE **f_table) { register int i= 0; int length; int count = 0; T_ROW *row; if (table != NULL) { table = g_list_first(table); length = g_list_length(table); } else return(__TT_ERR); g_list_free(*f_table); *f_table = NULL; for (i=0; i < rows; i++) { if (table != NULL) { row = g_slist_next(table->data); if (strncasecmp(filter, row->data, strlen(filter)) == 0) { *f_table = g_list_append(*f_table, table->data); count++; } } else break; if (table->next != NULL) table = g_list_next(table); else break; } return(count); } /* }}} */ /* input inlist {{{ ***********************************************************/ int tt_table_input_inlist( T_TABLE *table, T_CELL *cell) { char *pk; T_ROW *row; if (table != NULL) { table = g_list_first(table); } else return(false); while (table != NULL) { row = table->data; pk = row->data; row = g_slist_next(row); if (strcasecmp(row->data, cell->name) == 0) { strcpy(cell->value, pk); strcpy(cell->name, row->data); return(true); } table = g_list_next(table); } return(false); } /* }}} */ /* store {{{ ******************************************************************/ int tt_table_store(T_TABLE *table, T_COLS *cols) { T_ROW *row; T_CELL *cell; if (table != NULL) { row = table->data; while (row != NULL) { cell = cols->data; strcpy(cell->value, row->data); row = g_slist_next(row); if ((cols)->next != NULL) cols = g_slist_next(cols); else return(__LT_ERR); } } else { while (cols != NULL) { cell = cols->data; strcpy(cell->value, ""); cols = g_slist_next(cols); } } return(__TT_OK); } /* }}} */ /* cursor position {{{ ********************************************************/ int tt_table_cursor(T_TABLE *table, TT_TABLE *v_table) { int cursor = 1; if (table != NULL) while (v_table->data != table->data) { cursor++; if (v_table->next != NULL) v_table = g_slist_next(v_table); else return(__LT_ERR); } else return(0); return(cursor); } /* }}} */ /* next {{{ *******************************************************************/ int tt_table_next(T_TABLE **table, TT_TABLE **v_table) { if (*table != NULL) //if next row is within v_table then just move to next table item if (tt_table_cursor(*table, *v_table) < g_slist_length(*v_table)) *table = g_list_next(*table); else if ((*table)->next != NULL) { *table = g_list_next(*table); *v_table = g_slist_append(*v_table, (*table)->data); *v_table = g_slist_next(*v_table); /* ??? just sets the start pointer to second item in list does anybody remove the old(first) item from memory ??? */ } return(__LT_OK); } /* }}} */ /* previous {{{ ***************************************************************/ int tt_table_previous(T_TABLE **table, TT_TABLE **v_table) { if (*table != NULL) if (tt_table_cursor(*table, *v_table) > 1) *table = g_list_previous(*table); else if ((*table)->prev != NULL) { *table = g_list_previous(*table); *v_table = g_slist_prepend(*v_table, (*table)->data); *v_table = g_slist_remove_last(*v_table); } return(__LT_OK); } /* }}} */ /* search {{{ *****************************************************************/ int tt_table_search( char *search, int column, T_TABLE **table, TT_TABLE **v_table) { register int i; const int length = g_slist_length(*v_table); T_ROW * row; T_TABLE * m_table = g_list_first(*table); if (*table == NULL) return(__LT_OK); while (m_table->next != NULL) { row = m_table->data; for (i=0; i < column; i++) { if (row->next != NULL) row = g_slist_next(row); else return(__LT_ERR); } if (strcasecmp(row->data,search) < 0) m_table = g_list_next(m_table); else break; } *table = m_table; //sets new table cursor position while ((length - 1) > tt_table_init(length, m_table, v_table)) m_table = g_list_previous(m_table); // adds missing number of rows and shifts cursor to actual position return(__TT_OK); } /* }}} */ /* find {{{ *******************************************************************/ int tt_table_find( char *search, int column, T_TABLE **table, TT_TABLE **v_table) { register int i; int n = strlen(search); const int length = g_slist_length(*v_table); T_ROW * row; T_ROW * next_row; T_TABLE * m_table = g_list_first(*table); if (*table == NULL) return(__LT_OK); while (m_table->next != NULL) { row = m_table->data; next_row = (m_table->next)->data; for (i=0; i < column; i++) { if (row->next != NULL) row = g_slist_next(row); if (next_row->next != NULL) next_row = g_slist_next(next_row); else return(__LT_ERR); } if (strcasecmp(row->data,search) < 0) m_table = g_list_next(m_table); else break; } if ((strncasecmp(next_row->data,search, n) > 0) && (strncasecmp(row->data, search, n) == 0)) strcpy(search,row->data); *table = m_table; //sets new table cursor position while ((length - 1) > tt_table_init(length, m_table, v_table)) m_table = g_list_previous(m_table); // adds missing number of rows and shifts cursor to actual position return(__TT_OK); } /* }}} */ /* {{{ edit cell **************************************************************/ int tt_table_edit_cell ( WINDOW *win, T_TABLE *table, T_COLS *cols, int column) { bool End = false; int X,Y; int Status = __TT_ERR; int Width; int Pos; char String[T_CELL_VALUE_WIDTH] = {'\0'}; POS point; T_ROW *row = table->data; TT_TABLE *v_table = NULL; getmaxyx(win, Y, X); tt_table_init(Y-2, table, &v_table); t_cols_get_values(cols, column, &X, &Width, String); Y = tt_table_cursor(table, v_table); SET_POS(point, win, Y, X); for (Pos = 0; Pos < column; Pos++) if (row->next != NULL) row = g_slist_next(row); else return(__TT_ERR); return(tt_str_get(point, Width, row->data)); } /* }}} */