Mercurial > ~dholland > hg > ag > index.cgi
view examples/dsl/query.cpp @ 16:f9e4689b837d
Some minor updates for 15 years later.
author | David A. Holland |
---|---|
date | Tue, 31 May 2022 01:45:26 -0400 |
parents | ec2b657edf13 |
children |
line wrap: on
line source
/***** AnaGram Programming Examples A Dos Script Language Query Table Module Copyright 1993 Parsifal Software. All Rights Reserved. This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. *****/ #include "query.h" #include "screen.h" #include "symbol.h" #include "util.h" #include "edit.h" #include <ctype.h> #include <stdlib.h> #if defined(__MSDOS__) || defined(__WINDOWS__) #include <conio.h> #else /* This is only meant to compile, not run. (Unix) */ static int getch(void) { return '?'; } #endif // Editing keystrokes #define BACKSPACE '\b' #define BACKTAB 271 #define LEFT 331 #define DELETE 339 #define ESCAPE 27 #define DOWN 336 #define RIGHT 333 #define TAB '\t' #define UP 328 #define HOME 327 #define END 335 void perform_action(action_pointer); int get_key(void) { int key = getch(); if (key == 0) key = 256 + getch(); if (key == 3) { printf("\n^C"); exit(1); } return key; } void expand_formula(const int *s) { ++sa; while (*s) { switch (st[*s].type) { case value_type: case string_type: { sa << st[*s].data.text; break; } case integer_type: { sa.printf("%d", st[*s].data.integer); break; } default: { sa << sd[*s]; } } s++; } } screen_rect &operator << (screen_rect &r, const int *s) { expand_formula(s); r << (sa--).top(); return r; } // Query Table Class // Constructor query_table::query_table(stack<query_item> &qs, screen_descriptor *scd) { int i = 0; int j; title = scd->title; color = scd->color; entry_color = scd->entry_color; highlight_color = scd->highlight_color; height = scd->height; width = scd-> width; if (scd->pos.x >= 0) window_box = at(scd->pos.x,scd->pos.y).rect(width,height,0); else window_box = at(0,0).rect(width,height,11); height -= 2; width -= 4; window = window_box.rect(width,height); previous = contents(window_box); nq = size(qs); // Number of fields q = new query_item[nq]; // Query items sr = new screen_rect[nq]; // screen position field_color = new unsigned char[nq]; // color j = nq; for (j = nq, i = 0; j--; i++) { unsigned index; q[i] = qs[j]; if (q[i].value == NULL) continue; index = q[i].id; release(st[index]); st[index].type = value_type; expand_formula(q[i].value); st[index].data.text = copy(sa--); } current_field = 0; resize(); } // Destructor query_table::~query_table() { window_box << previous; delete [] previous; delete [] q; delete [] sr; delete [] field_color; } query_table &query_table::resize(void) { int bw; // bar width int i; // index query lines int ln; // line number int blank_lines; int justification_points; int undistributed_blanks; // Vertical justification calculations blank_lines = height - 2 - nq; justification_points = nq + 1; nbl = blank_lines/justification_points; //number of blank lines undistributed_blanks = blank_lines - justification_points*nbl; title_line = undistributed_blanks/4; exp_line = height -1 - title_line; undistributed_blanks -= 2*title_line; first_line = undistributed_blanks/2 + nbl + 1; // first line location // Calculate horizontal spacing pw = 0; // prompt width dw = width/2; // data width for (i = 0; i < nq; i++) { int qw; // width of prompt-this query expand_formula(q[i].prompt); qw = size(sa--); // width if (qw > pw) pw = qw; // max prompt width } pw += 2; // extra space bw = pw + dw; // bar width if (bw > width) bw = width; dw = bw - pw; // maybe reduce data width px = (width - bw)/2; // left position of prompt dx = px + pw; // left position of data // Set up data windows ln = first_line; // ln is line number for (i = 0; i < nq; i++) { int id = q[i].id; // Variable id if (id) sr[i] = window.line(dx, ln, dw); // If data field else { // Otherwise button expand_formula(q[i].prompt); // Expand prompt to get size sr[i] = window.line(px,ln, size(sa--)); } ln += nbl + 1; } return *this; } // Refresh query table display query_table &query_table::refresh(void) { int ln = first_line; int k; // Index queries screen_rect msg_line; // Reset field colors for (k = 0; k < nq; k++) field_color[k] = entry_color; field_color[current_field] = highlight_color; // Display prompts and initial values for (k = 0; k < nq; k++) { int id = q[k].id; sr[k].tint(field_color[k]); msg_line = window.line(px,ln,width); msg_line << q[k].prompt; if (id) { // Data field if (q[k].value) { expand_formula(q[k].value); release(st[id]); st[id].data.text = copy(sa--); } sr[k] << st[q[k].id].data.text; } ln += nbl + 1; } sr[current_field].set_cursor(); // Display explanation line msg_line = window.line(0,exp_line, width, 10); msg_line << q[current_field].explanation; return *this; } int query_table::edit_line(void) { int key; if (current_field >= nq || q[current_field].id == 0) { return get_key(); } line_edit_buffer buf(st[q[current_field].id].data.text,100); while (1) { sr[current_field] << buf; // Update display key = get_key(); switch (key) { case HOME: home(buf); break; case END: end(buf); break; case LEFT: --buf; break; case RIGHT: ++buf; break; case DELETE: ~buf; break; case BACKSPACE: if (buf.index() == 0) break; ~(--buf); break; case TAB: case BACKTAB: case UP: case DOWN: case '\r': { unsigned index = q[current_field].id; if (buf.changes) { st[index].data.text = memdup((char *) buf, 1+strlen(buf)); delete [] q[current_field].value; q[current_field].value = NULL; } } /* FALLTHROUGH */ case ESCAPE: return key; default: if (current_field < nq && key >= ' ' && key < 255) buf << key; break; } } } void display_queries(screen_descriptor *scd) { protect_display save_screen; query_table qt(qs,scd); qt.window_box << char_cell(' ',qt.color); qt.window = box(qt.window_box); screen_rect title_line = qt.window.line(0,qt.title_line,qt.width,10); title_line << qt.title; while (1) { int key; qt.refresh(); key = qt.edit_line(); switch (key) { case BACKTAB: case UP: qt.current_field += qt.nq - 1; qt.current_field %= qt.nq; break; case TAB: case DOWN: qt.current_field++; qt.current_field %= qt.nq; break; case '\r': { int id = qt.q[qt.current_field].id; action_pointer ap = qt.q[qt.current_field].action; if (id) { qt.current_field++; qt.current_field %= qt.nq; break; } if (ap.pointer) perform_action(ap); return; } } } }