void move_curitem(int direction) { list_item tmp; if(curitem < 0 || curitem > last_item()) return; tmp = item_create(); item_copy(tmp, db_item_get(curitem)); switch(direction) { case MOVE_ITEM_UP: if( curitem < 1 ) goto out_move; item_copy(db_item_get(curitem), db_item_get(curitem - 1)); item_copy(db_item_get(curitem-1), tmp); scroll_up(); break; case MOVE_ITEM_DOWN: if(curitem >= last_item()) goto out_move; item_copy(db_item_get(curitem), db_item_get(curitem + 1)); item_copy(db_item_get(curitem + 1), tmp); scroll_down(); break; } out_move: item_free(&tmp); }
void page_down() { if(curitem > db_n_items() - 2) return; if(curitem == LAST_LIST_ITEM) { if((curitem += LIST_LINES) > last_item()) curitem = last_item(); } else { curitem = min(LAST_LIST_ITEM, last_item()); } refresh_list(); }
bool edit_interface_rep::complete_try () { tree st= subtree (et, path_up (tp)); if (is_compound (st)) return false; string s= st->label, ss; int end= last_item (tp); array<string> a; if (inside (LABEL) || inside (REFERENCE) || inside (PAGEREF)) { if (end != N(s)) return false; ss= copy (s); tree t= get_labels (); int i, n= N(t); for (i=0; i<n; i++) if (is_atomic (t[i]) && starts (t[i]->label, s)) a << string (t[i]->label (N(s), N(t[i]->label))); } else { if ((end==0) || (!is_iso_alpha (s[end-1])) || ((end!=N(s)) && is_iso_alpha (s[end]))) return false; int start= end-1; while ((start>0) && is_iso_alpha (s[start-1])) start--; ss= s (start, end); a= find_completions (drd, et, ss); } if (N(a) == 0) return false; complete_start (ss, a); return true; }
bool edit_interface_rep::complete_keypress (string key) { set_message ("", ""); if (key == "space") key= " "; if ((key != "tab") && (key != "S-tab")) { set_input_normal (); return false; } tree st= subtree (et, path_up (tp)); if (is_compound (st)) { set_input_normal (); return false; } string s= st->label; int end= last_item (tp); string old_s= completions [completion_pos]; string test= completion_prefix * old_s; if ((end<N(test)) || (s (end-N(test), end) != test)) { set_input_normal (); return false; } if (key == "tab") completion_pos++; else completion_pos--; if (completion_pos < 0) completion_pos= N(completions)-1; if (completion_pos >= N(completions)) completion_pos= 0; string new_s= completions [completion_pos]; remove (path_up (tp) * (end-N(old_s)), N(old_s)); insert (path_up (tp) * (end-N(old_s)), new_s); complete_message (); return true; }
void edit_interface_rep::complete_start (string prefix, array<string> compls) { // check consistency tree st= subtree (et, path_up (tp)); if (is_compound (st)) return; string s= st->label; int end= last_item (tp); if ((end<N(prefix)) || (s (end-N(prefix), end) != prefix)) return; // perform first completion and switch to completion mode if necessary if (N (compls) == 1) { string s= compls[0]; if (ends (s, "()")) // temporary fix for Pari insert_tree (s, path (N(s)-1)); else insert_tree (s); completions= array<string> (); } else { completion_prefix= prefix; completions = close_completions (compls); completion_pos = 0; insert_tree (completions[0]); complete_message (); beep (); set_input_mode (INPUT_COMPLETE); } }
void goto_end() { if(db_n_items() > 0) curitem = last_item(); refresh_list(); }
void edit_select_rep::select_enlarge_text () { path p= common (start_p, end_p); if (start_p == end_p) p= path_up (p); tree st= subtree (et, p); ASSERT (is_atomic (st), "non textual tree"); string s= st->label; string mode= get_env_string (MODE); int i1= last_item (start_p), j1= i1; int i2= last_item (end_p), j2= i2; path q= path_up (p); if (mode == "text" || mode == "src") { int i, f= 4; if (i1 > 0) { i= i1; tm_char_backwards (s, i); f= min (f, breaking_force (s[i])); } if (i2 < N(s)) f= min (f, breaking_force (s[i2])); while (i1 > 0) { i= i1; tm_char_backwards (s, i); if (breaking_force (s[i]) > f) break; i1= i; } while (i2 < N(s)) { if (breaking_force (s[i2]) > f) break; tm_char_forwards (s, i2); } if (i1 < i2 && (i1 != j1 || i2 != j2)) { if (is_concat (subtree (et, q)) && i1 == 0 && i2 == N(s)) select (q * 0, q * 1); else select (p * i1, p * i2); return; } } if (is_concat (subtree (et, q)) || (i1 == 0 && i2 == N(s))) select (q * 0, q * 1); else select (p * 0, p * N(s)); }
path box_rep::find_box_path (path p, bool& found) { // cout << "Find box path " << box (this) << ", " << p // << "; " << reverse (ip) // << ", " << reverse (find_lip ()) // << " -- " << reverse (find_rip ()) << "\n"; found= (!is_nil(p)) && is_accessible (ip); if (last_item (p) == 0) return path (0); else return path (1); }
void notify_insert_node (typesetter ttt, path p, tree t) { // cout << "Insert node " << p << ", " << t << "\n"; int i, pos= last_item (p), n= N(t); tree r (t, n+1); for (i=0; i<pos; i++) r[i]= t[i]; r[pos]= subtree (ttt->br->st, path_up (p)); for (i=pos; i<n; i++) r[i+1]= t[i]; if (is_nil (path_up (p))) ttt->br= make_bridge (ttt, r, ttt->br->ip); else ttt->br->notify_assign (path_up (p), r); }
bool admissible_selection (gr_selection sel) { if (sel->type != "box" || N(sel->cp) != 1) return true; if (last_item (sel->cp[0]) < 0 || N(sel->cp[0]) <= 2) return true; path p= path_up (sel->cp[0]); if (!has_subtree (the_et, p)) return true; tree st= subtree (the_et, p); if (is_compound (st, "anim-edit")) return false; tree pt= subtree (the_et, path_up (p)); if (is_func (st, WITH) && is_compound (pt, "anim-edit")) return false; return true; }
path text_box_rep::find_box_path (path p, bool& found) { // cout << "Find box path " << box (this) << ", " << p // << "; " << reverse (ip) // << ", " << reverse (find_lip ()) // << " -- " << reverse (find_rip ()) << "\n"; found= (!is_nil(p)) && is_accessible (ip); if (found) { int i= last_item (p) - pos; if (i < 0) return path (0); else if (i > N(str)) return N(str); else return path (i); } else return path (0); }
tree edit_interface_rep::compute_text_footer (tree st) { string r; language lan= get_env_language (); int end = last_item (tp); int start= end; tm_char_backwards (st->label, start); r= st->label (start, end); if (r == "") r= "start"; if (r == " ") r= "space"; if (r == "space" && get_env_string (MODE) == "math") r= "apply"; if (starts (r, "<") && !starts (r, "<#")) if (cork_to_utf8 (r) != r) r= r * " (" * r(1, N(r)-1) * ")"; return r; }
void edit_graphics_rep::back_in_text_at (tree t, path p, bool forward) { (void) forward; int i= last_item (p); if ((i == 0) && is_empty (t[0])) { p= path_up (p); if (is_func (subtree (et, path_up (p)), WITH)) p= path_up (p); tree st= subtree (et, path_up (p)); if (is_func (st, GRAPHICS)) { if (N(st) == 1) assign (p, ""); else { remove (p, 1); go_to_border (path_up (p) * 0, true); } } } }
/* Compress the custkey in orders. */ bool pageManage::compressCustkey() { /* External sort. */ if (!externalSort()) return false; /* Open the relevant files. */ FILE* cfileAfterSort = fopen(PATH_OF_CUSTKEY_AFTER_SORT, "rb"), *cfileAfterCompress = fopen(PATH_OF_CUSTKEY_AFTER_COMPRESS, "wb"); if (!cfileAfterSort || !cfileAfterCompress) return false; int ckeyAfterSort[MAX_ITEM], count = 0, length = 1, pre_ckey = -1; item ckeyAfterCompress[MAX_ITEM]; /* Compress custkey sort. */ while(!feof(cfileAfterSort)) { int num = fread(ckeyAfterSort, sizeof(int), MAX_ITEM, cfileAfterSort); for (int i = 0; i < num; ++i) { if (ckeyAfterSort[i] == pre_ckey) { ++length; } else if (pre_ckey != -1) { if (count == MAX_ITEM) { fwrite(ckeyAfterCompress, sizeof(item), count, cfileAfterCompress); count = 0; } ckeyAfterCompress[count++] = item(pre_ckey, length); length = 1; } pre_ckey = ckeyAfterSort[i]; } } if (count != 0) fwrite(ckeyAfterCompress, sizeof(item), count, cfileAfterCompress); item last_item(pre_ckey, length); fwrite(&last_item, sizeof(item), 1, cfileAfterCompress); /* Close the relevant files and remove the temporary files. */ fclose(cfileAfterSort); fclose(cfileAfterCompress); remove(PATH_OF_CUSTKEY_AFTER_SORT); return true; }
path edit_select_rep::focus_search (path p, bool skip_flag, bool up_flag) { //cout << "Search focus " << p << ", " << skip_flag << ", " << up_flag << "\n"; if (!(rp < p)) return rp; tree st= subtree (et, p); if (!skip_flag) return p; if (none_accessible (st) && p == path_up (tp) && last_item (tp) != 0) return p; if (is_atomic (st) || is_func (st, DOCUMENT) || is_func (st, CONCAT) || is_func (st, TFORMAT) || is_func (st, TABLE) || is_func (st, ROW) || is_func (st, CELL) || is_compound (st, "shown") || is_func (st, HIDDEN) || up_flag) return focus_search (path_up (p), skip_flag, false); return p; }
int duplicate_item() { list_item item; if(curitem < 0) return 1; item = item_create(); item_duplicate(item, db_item_get(curitem)); if(add_item2database(item)) { item_free(&item); return 1; } item_free(&item); curitem = last_item(); refresh_list(); return 0; }
int main(void) { link *t, *head; struct node *d = NULL; int max, not_last = 1; t = new_list(); print_list(t); head = t; max = t->item; t = t->next; while (t != NULL) { if (t->item > max) max = t->item; t = t->next; } t = head; if (max != last_item(t)) { while (t->next != NULL) { if (t->next->item == max) { d = t->next; not_last = 0; t->next = d->next; d->next = NULL; } t = t->next; } t->next = d; } print_list(head); return 0; }
tree edit_interface_rep::compute_compound_footer (tree t, path p) { if (!(rp < p)) return ""; tree up= compute_compound_footer (t, path_up (p)); if (N(focus_get (false))+1 < N(p)) return up; tree st= subtree (t, path_up (p)); int l = last_item (p); switch (L (st)) { case DOCUMENT: case PARA: return up; case SURROUND: if (l == 0) return concat (up, "left surrounding "); if (l == 1) return concat (up, "right surrounding "); return up; case CONCAT: return up; case MOVE: if (l == 0) return concat (up, "move "); else return up; case SHIFT: if (l==0) return concat (up, "shift "); else return up; case RESIZE: if (l==0) return concat (up, "resize "); else return up; case CLIPPED: if (l==0) return concat (up, "clipped "); else return up; case _FLOAT: if (N(st) >= 1 && is_atomic (st[0])) return concat (up, st[0]->label * " "); else return concat (up, "float "); case LONG_ARROW: if (l == 1) return concat (up, "above "); else if (l == 2) return concat (up, "below "); else return up; case BELOW: if (l==0) return concat (up, "body "); else return concat (up, "script below "); case ABOVE: if (l==0) return concat (up, "body "); else return concat (up, "script above "); case FRAC: if (l==0) return concat (up, "numerator "); else return concat (up, "denominator "); case SQRT: if (N(st)==1) return concat (up, "square root "); if (l==0) return concat (up, "root "); else return concat (up, "index "); case WIDE: if (N(st) >= 1) return concat (up, get_accent_type (as_string (st[1])) * " "); else return concat (up, "wide "); case VAR_WIDE: if (N(st) >= 1) return concat (up, "under " * get_accent_type (as_string (st[1])) * " "); else return concat (up, "var-wide "); case TREE: if (l==0) return concat (up, "root "); else return concat (up, "branch(" * as_string (l) * ") "); case TFORMAT: return up; case TABLE: return concat (up, "(" * as_string (l+1) * ","); case ROW: return concat (up, as_string (l+1) * ") "); case CELL: return up; case WITH: return concat (up, get_with_text (st), " "); case DRD_PROPS: if (l == 0) return concat (up, "drd property(variable) "); if ((l&1) == 1) return concat (up, "drd property(" * as_string (l/2+1) * ") "); return concat (up, "value(" * as_string (l/2) * ") "); case COMPOUND: if (N(st) >= 1 && is_atomic (st[0])) return concat (up, as_string (st[0]) * " "); else return concat (up, "compound "); case HLINK: if (N(st) >= 2) return concat (up, "hyperlink(" * as_string (st[1]) * ") "); else return concat (up, "hyperlink "); case TUPLE: return concat (up, "tuple(" * as_string (l+1) * ") "); case ATTR: if ((l&1) == 0) return concat (up, "variable(" * as_string (l/2+1) * ") "); else return concat (up, "value(" * as_string (l/2+1) * ") "); case SPECIFIC: return concat (up, "texmacs "); case ANIM_CONSTANT: if (l == 0) return concat (up, "anim-constant "); else return up; case ANIM_TRANSLATE: if (l == 0) return concat (up, "anim-translate "); else return up; case ANIM_PROGRESSIVE: if (l == 0) return concat (up, "anim-progressive "); else return up; default: return concat (up, drd->get_name (L(st)) * " "); } }
tree edit_interface_rep::compute_operation_footer (tree st) { tree r= ""; if (N(st) >= 2) { switch (L (st)) { case VAR_WIDE: r= concat ("under ", get_accent_type (as_string (st[1]))); break; default: ; } } if (r == "" && N(st) >= 1) { switch (L (st)) { case HSPACE: r= concat ("space"); break; case VAR_VSPACE: r= concat ("vertical space before"); break; case VSPACE: r= concat ("vertical space"); break; case SPACE: r= concat ("space"); break; case _FLOAT: r= (is_atomic (st[0])? st[0]->label: string ("float")); break; case MID: r= concat ("middle ", as_symbol (st[0])); break; case RIGHT: r= concat ("close ", as_symbol (st[0])); break; case BIG: r= concat ("big ", as_symbol (st[0])); break; case LPRIME: r= concat ("left prime ", as_string (st[0])); break; case LONG_ARROW: r= concat ("long arrow ", as_string (st[0])); break; case RPRIME: r= concat ("prime ", as_string (st[0])); break; case SQRT: r= tree ((char*) ((N(st)==1)? "square root": "n-th root")); break; case WIDE: r= tree (get_accent_type (as_string (st[1]))); break; case ASSIGN: r= concat ("assign ", as_string (st[0])); break; case WITH: r= concat ("with ", get_with_text (st)); break; case PROVIDES: r= concat ("provides ", as_string (st[0])); break; case VALUE: r= concat ("value ", as_string (st[0])); break; case QUOTE_VALUE: r= concat ("quoted value ", as_string (st[0])); break; case ARG: r= concat ("argument ", as_string (st[0])); break; case QUOTE_ARG: r= concat ("quoted argument ", as_string (st[0])); break; case COMPOUND: if (is_atomic (st[0])) r= as_string (st[0]); else r= "compound"; break; case VAR_INCLUDE: case INCLUDE: r= concat ("include ", as_string (st[0])); break; case INACTIVE: r= concat ("inactive ", drd->get_name (L(st[0]))); break; case VAR_INACTIVE: r= concat ("inactive ", drd->get_name (L(st[0]))); break; case LABEL: r= concat ("label: ", as_string (st[0])); break; case REFERENCE: r= concat ("reference: ", as_string (st[0])); break; case PAGEREF: r= concat ("page reference: ", as_string (st[0])); break; case GET_ATTACHMENT: r= concat ("get attachment: ", as_string (st[0])); break; case WRITE: r= concat ("write to ", as_string (st[0])); break; case TOC_NOTIFY: r= concat ("toc notify: ", as_string (st[1])); break; case SPECIFIC: r= concat ("specific ", as_string (st[0])); break; case IMAGE: r= concat ("image"); break; default: ; } } if (r == "") { switch (L (st)) { case IMAGE: r= "image"; break; default: r= drd->get_name (L(st)); } } if (last_item (tp) == 0) r= concat ("before ", r); return r; }
static int handle_input(int ch) { switch (ch) { case 'q': quit_mode = quit_mode ? 0 : 1; return 1; case 0x1b: quit_mode = 0; print_help = 0; return 1; case 'y': if (quit_mode) exit(0); break; case 'a': next_attr(); return 1; case 'n': if (quit_mode) quit_mode = 0; else new_graph(); return 1; case 'x': del_graph(); return 1; case 'f': fold(); return 1; case 12: case KEY_CLEAR: #ifdef HAVE_REDRAWWIN redrawwin(stdscr); #endif clear(); return 1; case 'c': c_combined_node_list = c_combined_node_list ? 0 : 1; return 1; case 'S': clear(); set_graph_unit(X_SEC); return 1; case 'M': clear(); set_graph_unit(X_MIN); return 1; case 'H': clear(); set_graph_unit(X_HOUR); return 1; case 'D': clear(); set_graph_unit(X_DAY); return 1; case 'R': clear(); set_graph_unit(X_READ); return 1; case '?': clear(); print_help = print_help ? 0 : 1; return 1; case 'g': c_graphical_in_list = c_graphical_in_list ? 0 : 1; return 1; case 'd': c_detailed_in_list = c_detailed_in_list ? 0 : 1; return 1; case 'l': c_list_in_list = c_list_in_list ? 0 : 1; return 1; case KEY_PPAGE: if (print_help) help_page = help_page ? 0 : 1; else prev_node(); return 1; case KEY_NPAGE: if (print_help) help_page = help_page ? 0 : 1; else next_node(); return 1; case KEY_DOWN: if (next_item() == END_OF_LIST) { if (next_node() != END_OF_LIST) first_item(); } return 1; case KEY_UP: if (prev_item() == END_OF_LIST) { if (prev_node() != END_OF_LIST) last_item(); } return 1; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': goto_item(ch - 48); return 1; case '>': next_graph(); return 1; case '<': prev_graph(); return 1; default: if (get_current_item()) if (handle_bindings(ch, get_current_item()->i_name)) return 1; break; } return 0; }
void edit_select_rep::raw_cut (path p1, path p2) { if (p2 == p1) return; path p = common (p1, p2); tree t = subtree (et, p); int n = N(p); int i1= p1[n]; int i2= p2[n]; if (is_document (t) || is_concat (t)) { path q1= copy (p); q1 << path (i1, end (t[i1])); path q2= copy (p); q2 << path (i2, start (t[i2])); raw_cut (q2, p2); if (i2>i1+1) remove (p * (i1+1), i2-i1-1); raw_cut (p1, q1); if (is_concat (t)) correct_concat (p); else remove_return (p * i1); return; } if (is_func (t, TFORMAT) || is_func (t, TABLE) || is_func (t, ROW)) { path fp= ::table_search_format (et, p); tree st= subtree (et, fp); int row1, col1, row2, col2; table_search_coordinates (st, tail (p1, N(fp)), row1, col1); table_search_coordinates (st, tail (p2, N(fp)), row2, col2); if (row1>row2) { int tmp= row1; row1= row2; row2= tmp; } if (col1>col2) { int tmp= col1; col1= col2; col2= tmp; } int i, j; for (i=row1; i<=row2; i++) for (j=col1; j<=col2; j++) { path cp= fp * ::table_search_cell (st, i, j); if (is_func (subtree (et, cp), CELL, 1)) cp= cp * 0; assign (cp, ""); } path cp= fp * ::table_search_cell (st, row1, col1); go_to (cp * path (0, 0)); if (is_func (st, TFORMAT)) table_del_format (fp, row1+1, col1+1, row2+1, col2+1, ""); return; } if (is_compound (t) && (!is_format (t))) { assign (p, ""); return; } if ((N(p1) != (N(p)+1)) || (N(p2) != (N(p)+1))) { cerr << "t = " << t << "\n"; cerr << "p = " << p << "\n"; cerr << "p1= " << p1 << "\n"; cerr << "p2= " << p2 << "\n"; FAILED ("invalid cut"); } if (is_atomic (t)) { int pos= last_item (p1); int nr = last_item (p2)-pos; if (nr>0) remove (p1, nr); } else { if ((last_item (p1) != 0) || (last_item (p2) != 1)) { cerr << "t = " << t << "\n"; cerr << "p = " << p << "\n"; cerr << "p1= " << p1 << "\n"; cerr << "p2= " << p2 << "\n"; FAILED ("invalid object cut"); } assign (p, ""); } }
/* * This is an alternate interface to 'buildlist' which allows the application * to read the list item states back directly without putting them in the * output buffer. */ int dlg_buildlist(const char *title, const char *cprompt, int height, int width, int list_height, int item_no, DIALOG_LISTITEM * items, const char *states, int order_mode, int *current_item) { /* *INDENT-OFF* */ static DLG_KEYS_BINDING binding[] = { HELPKEY_BINDINGS, ENTERKEY_BINDINGS, DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ), DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ), DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ), DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ), DLG_KEYS_DATA( DLGK_ITEM_FIRST, KEY_HOME ), DLG_KEYS_DATA( DLGK_ITEM_LAST, KEY_END ), DLG_KEYS_DATA( DLGK_ITEM_LAST, KEY_LL ), DLG_KEYS_DATA( DLGK_ITEM_NEXT, '+' ), DLG_KEYS_DATA( DLGK_ITEM_NEXT, KEY_DOWN ), DLG_KEYS_DATA( DLGK_ITEM_NEXT, CHR_NEXT ), DLG_KEYS_DATA( DLGK_ITEM_PREV, '-' ), DLG_KEYS_DATA( DLGK_ITEM_PREV, KEY_UP ), DLG_KEYS_DATA( DLGK_ITEM_PREV, CHR_PREVIOUS ), DLG_KEYS_DATA( DLGK_PAGE_NEXT, KEY_NPAGE ), DLG_KEYS_DATA( DLGK_PAGE_NEXT, DLGK_MOUSE(KEY_NPAGE) ), DLG_KEYS_DATA( DLGK_PAGE_NEXT, DLGK_MOUSE(KEY_NPAGE+KEY_MAX) ), DLG_KEYS_DATA( DLGK_PAGE_PREV, KEY_PPAGE ), DLG_KEYS_DATA( DLGK_PAGE_PREV, DLGK_MOUSE(KEY_PPAGE) ), DLG_KEYS_DATA( DLGK_PAGE_PREV, DLGK_MOUSE(KEY_PPAGE+KEY_MAX) ), DLG_KEYS_DATA( DLGK_GRID_LEFT, KEY_LEFTCOL ), DLG_KEYS_DATA( DLGK_GRID_RIGHT, KEY_RIGHTCOL ), END_KEYS_BINDING }; /* *INDENT-ON* */ #ifdef KEY_RESIZE int old_height = height; int old_width = width; #endif ALL_DATA all; MY_DATA *data = all.list; int i, j, k, key2, found, x, y, cur_x, cur_y; int key = 0, fkey; bool save_visit = dialog_state.visit_items; int button; int cur_item; int was_mouse; int name_width, text_width, full_width, list_width; int result = DLG_EXIT_UNKNOWN; int num_states; bool first = TRUE; WINDOW *dialog; char *prompt = dlg_strclone(cprompt); const char **buttons = dlg_ok_labels(); const char *widget_name = "buildlist"; (void) order_mode; /* * Unlike other uses of --visit-items, we have two windows to visit. */ if (dialog_state.visit_cols) dialog_state.visit_cols = 2; memset(&all, 0, sizeof(all)); all.items = items; all.item_no = item_no; if (dialog_vars.default_item != 0) { cur_item = dlg_default_listitem(items); } else { if ((cur_item = first_item(&all, 0)) < 0) cur_item = first_item(&all, 1); } button = (dialog_state.visit_items ? (items[cur_item].state ? sRIGHT : sLEFT) : dlg_default_button()); dlg_does_output(); dlg_tab_correct_str(prompt); #ifdef KEY_RESIZE retry: #endif all.use_height = list_height; all.use_width = (2 * (dlg_calc_list_width(item_no, items) + 4 + 2 * MARGIN) + 1); all.use_width = MAX(26, all.use_width); if (all.use_height == 0) { /* calculate height without items (4) */ dlg_auto_size(title, prompt, &height, &width, MIN_HIGH, all.use_width); dlg_calc_listh(&height, &all.use_height, item_no); } else { dlg_auto_size(title, prompt, &height, &width, MIN_HIGH + all.use_height, all.use_width); } dlg_button_layout(buttons, &width); dlg_print_size(height, width); dlg_ctl_size(height, width); /* we need at least two states */ if (states == 0 || strlen(states) < 2) states = " *"; num_states = (int) strlen(states); x = dlg_box_x_ordinate(width); y = dlg_box_y_ordinate(height); dialog = dlg_new_window(height, width, y, x); dlg_register_window(dialog, widget_name, binding); dlg_register_buttons(dialog, widget_name, buttons); dlg_mouse_setbase(all.base_x = x, all.base_y = y); dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr); dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr); dlg_draw_title(dialog, title); (void) wattrset(dialog, dialog_attr); dlg_print_autowrap(dialog, prompt, height, width); list_width = (width - 6 * MARGIN - 2) / 2; getyx(dialog, cur_y, cur_x); data[0].box_y = cur_y + 1; data[0].box_x = MARGIN + 1; data[1].box_y = cur_y + 1; data[1].box_x = data[0].box_x + 1 + 2 * MARGIN + list_width; /* * After displaying the prompt, we know how much space we really have. * Limit the list to avoid overwriting the ok-button. */ if (all.use_height + MIN_HIGH > height - cur_y) all.use_height = height - MIN_HIGH - cur_y; if (all.use_height <= 0) all.use_height = 1; for (k = 0; k < 2; ++k) { /* create new window for the list */ data[k].win = dlg_sub_window(dialog, all.use_height, list_width, y + data[k].box_y + 1, x + data[k].box_x + 1); /* draw a box around the list items */ dlg_draw_box(dialog, data[k].box_y, data[k].box_x, all.use_height + 2 * MARGIN, list_width + 2 * MARGIN, menubox_border_attr, menubox_border2_attr); } text_width = 0; name_width = 0; /* Find length of longest item to center buildlist */ for (i = 0; i < item_no; i++) { text_width = MAX(text_width, dlg_count_columns(items[i].text)); name_width = MAX(name_width, dlg_count_columns(items[i].name)); } /* If the name+text is wider than the list is allowed, then truncate * one or both of them. If the name is no wider than 1/4 of the list, * leave it intact. */ all.use_width = (list_width - 6 * MARGIN); if (dialog_vars.no_tags && !dialog_vars.no_items) { full_width = MIN(all.use_width, text_width); } else if (dialog_vars.no_items) { full_width = MIN(all.use_width, name_width); } else { if (text_width >= 0 && name_width >= 0 && all.use_width > 0 && text_width + name_width > all.use_width) { int need = (int) (0.25 * all.use_width); if (name_width > need) { int want = (int) (all.use_width * ((double) name_width) / (text_width + name_width)); name_width = (want > need) ? want : need; } text_width = all.use_width - name_width; } full_width = text_width + name_width; } all.check_x = (all.use_width - full_width) / 2; all.item_x = ((dialog_vars.no_tags ? 0 : (dialog_vars.no_items ? 0 : (name_width + 2))) + all.check_x); /* ensure we are scrolled to show the current choice */ j = MIN(all.use_height, item_no); for (i = 0; i < 2; ++i) { int top_item = 0; if ((items[cur_item].state != 0) == i) { top_item = cur_item - j + 1; if (top_item < 0) top_item = 0; set_top_item(&all, top_item, i); } else { set_top_item(&all, 0, i); } } /* register the new window, along with its borders */ for (i = 0; i < 2; ++i) { dlg_mouse_mkbigregion(data[i].box_y + 1, data[i].box_x, all.use_height, list_width + 2, 2 * KEY_MAX + (i * (1 + all.use_height)), 1, 1, 1 /* by lines */ ); } dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width); while (result == DLG_EXIT_UNKNOWN) { int which = (items[cur_item].state != 0); MY_DATA *moi = data + which; int at_top = index2row(&all, moi->top_index, which); int at_end = index2row(&all, -1, which); int at_bot = skip_rows(&all, at_top, all.use_height, which); dlg_trace_msg("\t** state %d:%d top %d (%d:%d:%d) %d\n", cur_item, item_no - 1, moi->top_index, at_top, at_bot, at_end, which); if (first) { print_both(&all, cur_item); dlg_trace_win(dialog); first = FALSE; } if (button < 0) { /* --visit-items */ int cur_row = index2row(&all, cur_item, which); cur_y = (data[which].box_y + cur_row + 1); if (at_top > 0) cur_y -= at_top; cur_x = (data[which].box_x + all.check_x + 1); dlg_trace_msg("\t...visit row %d (%d,%d)\n", cur_row, cur_y, cur_x); wmove(dialog, cur_y, cur_x); } key = dlg_mouse_wgetch(dialog, &fkey); if (dlg_result_key(key, fkey, &result)) break; was_mouse = (fkey && is_DLGK_MOUSE(key)); if (was_mouse) key -= M_EVENT; if (!was_mouse) { ; } else if (key >= 2 * KEY_MAX) { i = (key - 2 * KEY_MAX) % (1 + all.use_height); j = (key - 2 * KEY_MAX) / (1 + all.use_height); k = row2index(&all, i + at_top, j); dlg_trace_msg("MOUSE column %d, row %d ->item %d\n", j, i, k); if (k >= 0 && j < 2) { if (j != which) { /* * Mouse click was in the other column. */ moi = data + j; fix_top_item(&all, k, j); } which = j; at_top = index2row(&all, moi->top_index, which); at_bot = skip_rows(&all, at_top, all.use_height, which); cur_item = k; print_both(&all, cur_item); key = KEY_TOGGLE; /* force the selected item to toggle */ } else { beep(); continue; } fkey = FALSE; } else if (key >= KEY_MIN) { if (key > KEY_MAX) { if (which == 0) { key = KEY_RIGHTCOL; /* switch to right-column */ fkey = FALSE; } else { key -= KEY_MAX; } } else { if (which == 1) { key = KEY_LEFTCOL; /* switch to left-column */ fkey = FALSE; } } key = dlg_lookup_key(dialog, key, &fkey); } /* * A space toggles the item status. Normally we put the cursor on * the next available item in the same column. But if there are no * more items in the column, move the cursor to the other column. */ if (key == KEY_TOGGLE) { int new_choice; int new_state = items[cur_item].state + 1; if ((new_choice = next_item(&all, cur_item, which)) == cur_item) { new_choice = prev_item(&all, cur_item, which); } dlg_trace_msg("cur_item %d, new_choice:%d\n", cur_item, new_choice); if (new_state >= num_states) new_state = 0; items[cur_item].state = new_state; if (cur_item == moi->top_index) { set_top_item(&all, new_choice, which); } if (new_choice >= 0) { fix_top_item(&all, cur_item, !which); cur_item = new_choice; } print_both(&all, cur_item); dlg_trace_win(dialog); continue; /* wait for another key press */ } /* * Check if key pressed matches first character of any item tag in * list. If there is more than one match, we will cycle through * each one as the same key is pressed repeatedly. */ found = FALSE; if (!fkey) { if (button < 0 || !dialog_state.visit_items) { for (j = cur_item + 1; j < item_no; j++) { if (check_hotkey(items, j, which)) { found = TRUE; i = j; break; } } if (!found) { for (j = 0; j <= cur_item; j++) { if (check_hotkey(items, j, which)) { found = TRUE; i = j; break; } } } if (found) dlg_flush_getc(); } else if ((j = dlg_char_to_button(key, buttons)) >= 0) { button = j; ungetch('\n'); continue; } } /* * A single digit (1-9) positions the selection to that line in the * current screen. */ if (!found && (key <= '9') && (key > '0') && (key - '1' < at_bot)) { found = TRUE; i = key - '1'; } if (!found && fkey) { switch (key) { case DLGK_FIELD_PREV: if ((button == sRIGHT) && dialog_state.visit_items) { key = DLGK_GRID_LEFT; button = sLEFT; } else { button = dlg_prev_button(buttons, button); dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width); if (button == sRIGHT) { key = DLGK_GRID_RIGHT; } else { continue; } } break; case DLGK_FIELD_NEXT: if ((button == sLEFT) && dialog_state.visit_items) { key = DLGK_GRID_RIGHT; button = sRIGHT; } else { button = dlg_next_button(buttons, button); dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width); if (button == sLEFT) { key = DLGK_GRID_LEFT; } else { continue; } } break; } } if (!found && fkey) { i = cur_item; found = TRUE; switch (key) { case DLGK_GRID_LEFT: i = closest_item(&all, cur_item, 0); fix_top_item(&all, i, 0); break; case DLGK_GRID_RIGHT: i = closest_item(&all, cur_item, 1); fix_top_item(&all, i, 1); break; case DLGK_PAGE_PREV: if (cur_item > moi->top_index) { i = moi->top_index; } else if (moi->top_index != 0) { int temp = at_top; if ((temp -= all.use_height) < 0) temp = 0; i = row2index(&all, temp, which); } break; case DLGK_PAGE_NEXT: if ((at_end - at_bot) < all.use_height) { i = next_item(&all, row2index(&all, at_end, which), which); } else { i = next_item(&all, row2index(&all, at_bot, which), which); at_top = at_bot; set_top_item(&all, next_item(&all, row2index(&all, at_top, which), which), which); at_bot = skip_rows(&all, at_top, all.use_height, which); at_bot = MIN(at_bot, at_end); } break; case DLGK_ITEM_FIRST: i = first_item(&all, which); break; case DLGK_ITEM_LAST: i = last_item(&all, which); break; case DLGK_ITEM_PREV: i = prev_item(&all, cur_item, which); if (stop_prev(&all, cur_item, which)) continue; break; case DLGK_ITEM_NEXT: i = next_item(&all, cur_item, which); break; default: found = FALSE; break; } } if (found) { if (i != cur_item) { int now_at = index2row(&all, i, which); int oops = item_no; int old_item; dlg_trace_msg("<--CHOICE %d\n", i); dlg_trace_msg("<--topITM %d\n", moi->top_index); dlg_trace_msg("<--now_at %d\n", now_at); dlg_trace_msg("<--at_top %d\n", at_top); dlg_trace_msg("<--at_bot %d\n", at_bot); if (now_at >= at_bot) { while (now_at >= at_bot) { if ((at_bot - at_top) >= all.use_height) { set_top_item(&all, next_item(&all, moi->top_index, which), which); } at_top = index2row(&all, moi->top_index, which); at_bot = skip_rows(&all, at_top, all.use_height, which); dlg_trace_msg("...at_bot %d (now %d vs %d)\n", at_bot, now_at, at_end); dlg_trace_msg("...topITM %d\n", moi->top_index); dlg_trace_msg("...at_top %d (diff %d)\n", at_top, at_bot - at_top); if (at_bot >= at_end) { /* * If we bumped into the end, move the top-item * down by one line so that we can display the * last item in the list. */ if ((at_bot - at_top) > all.use_height) { set_top_item(&all, next_item(&all, moi->top_index, which), which); } else if (at_top > 0 && (at_bot - at_top) >= all.use_height) { set_top_item(&all, next_item(&all, moi->top_index, which), which); } break; } if (--oops < 0) { dlg_trace_msg("OOPS-forward\n"); break; } } } else if (now_at < at_top) { while (now_at < at_top) { old_item = moi->top_index; set_top_item(&all, prev_item(&all, moi->top_index, which), which); at_top = index2row(&all, moi->top_index, which); dlg_trace_msg("...at_top %d (now %d)\n", at_top, now_at); dlg_trace_msg("...topITM %d\n", moi->top_index); if (moi->top_index >= old_item) break; if (at_top <= now_at) break; if (--oops < 0) { dlg_trace_msg("OOPS-backward\n"); break; } } } dlg_trace_msg("-->now_at %d\n", now_at); cur_item = i; print_both(&all, cur_item); } dlg_trace_win(dialog); continue; /* wait for another key press */ } if (fkey) { switch (key) { case DLGK_ENTER: result = dlg_enter_buttoncode(button); break; #ifdef KEY_RESIZE case KEY_RESIZE: /* reset data */ height = old_height; width = old_width; /* repaint */ dlg_clear(); dlg_del_window(dialog); refresh(); dlg_mouse_free_regions(); goto retry; #endif default: if (was_mouse) { if ((key2 = dlg_ok_buttoncode(key)) >= 0) { result = key2; break; } beep(); } } } else { beep(); } } dialog_state.visit_cols = save_visit; dlg_del_window(dialog); dlg_mouse_free_regions(); free(prompt); *current_item = cur_item; return result; }
tree texmacs_invarianted_merge (tree t, string src, tree org, tree u, hashmap<tree,path> h) { if (is_atomic (t)) return t; else { if (true) { int i, n= N(t); tree r (t, n); for (i=0; i<n; i++) r[i]= texmacs_invarianted_merge (t[i], src, org, u, h); t= r; } if (is_concat (t) || is_document (t)) { int i, n= N(t); tree r (L(t)); for (i=0; i<n; i++) { if (is_document (t) && is_compound (t[i], "ilx", 1)) t[i]= compound ("ilx", texmacs_invarianted_extend (t[i][0], src)); if (N(r) > 0 && is_compound (r[N(r)-1], "ilx", 1) && is_compound (t[i], "ilx", 1)) { int b1, e1, b2, e2; bool ok = get_range (r[N(r)-1][0], b1, e1, src); ok = get_range (t[i][0], b2, e2, src) || ok; if (ok && e1 <= b2) { skip_latex_spaces (src, e1); if (e1 >= b2) { string id= as_string (b1) * ":" * as_string (e2); r[N(r)-1][0]= id; continue; } } } int j= i; while (j<n && !is_compound (t[j], "ilx", 1)) j++; if (j < n && j > i && N(r) > 0 && is_compound (r[N(r)-1], "ilx", 1)) { // NOTE: this special treatment allows for the recognition of // pieces which may be invarianted even in case of missing markers int b1, e1, b2, e2; bool ok1= get_range (r[N(r)-1][0], b1, e1, src); bool ok2= get_range (t[j][0], b2, e2, src); if (ok1 && ok2 && e1 <= b2 && i-1 < N(org)) { path p= h [org[i-1]]; if (p != path (-1)) { tree pt= subtree (u, path_up (p)); int k, k2= last_item (p); for (k=i-1; k<=j && k2<N(pt); k++, k2++) if (org[k] != pt[k2]) { //cout << " <<< " << org[k] << LF // << " >>> " << pt[k2] << LF; break; } if (k > j) { string id= as_string (b1) * ":" * as_string (e2); r[N(r)-1][0]= id; i= j; continue; } } } } r << t[i]; } if (is_concat (r) && N(r) == 1) r= r[0]; return r; } return t; } }