/* ** BRIEF -- Basic Reconfigurable Interactive Editing Facility ** ** ** dlg_btn.cb: ** ** This file contains all BRIEF macros for managing dialog box buttons. */ #include "dialog.h" #include "dlg.h" /* ** _dialog_check_button: ** ** Places or removes a checkmark from the button specified ** by button label. If check is nonzero a check mark will be ** placed in the check box, otherwise a space will be placed in ** the check box. ** ** This is a user-accessible function. */ void _dialog_check_button (string button_label, int check) { int row, col; save_position (); if (_dlg_goto_btn ('C', button_label)) { delete_char (); insert (check ? CHECKMARK : NOCHECKMARK); } restore_position (); } /* ** _dialog_is_checked: ** ** Determines whether the control specified by button_label ** has a checkmark next to it. Returns TRUE if a check mark is ** present, FALSE otherwise. ** ** This is a user-accessible function. */ int _dialog_is_checked (string button_label) { int rval; if (_dlg_goto_btn ('C', button_label)) { if (read (1) == CHECKMARK) rval = TRUE; } returns (rval); } /* ** _dialog_check_radio: ** ** Places a check by the specified radio button and removes the check ** from all other radio buttons within the specified group. The group label ** is not required if the dialog box has only one group of radio buttons. ** ** This is a user-accessible function. */ void _dialog_check_radio (string button, ~string group) { int curr_buf = inq_buffer (); string label; set_buffer (_dialog_radio_buf); save_position (); top_of_buffer (); sprintf (label, FIND_RADIO_GRP, group); if (search_fwd (label, TRUE, TRUE) >= 1) { int offset; string ctrl = read (); offset = index (ctrl, "\"") + 1; label = substr (ctrl, offset, rindex (ctrl, "\"") - offset); /* ** Only do real work when we absolutely have to ... ** ** If the specified button and the current 'ON' button are not the ** same, then turn the current 'ON' button off and the specified ** button 'ON'. Update the radio button control file first, then the ** display buffer. */ if (label != button) { int row_off = atoi (substr (ctrl, rindex (ctrl, "(") + 1)), col_off = atoi (substr (ctrl, rindex (ctrl, ",") + 1)), row_on, col_on; move_rel (0, strlen (ctrl) - 2); delete_char (); insert ("%c", RADIO_OFF); top_of_buffer (); sprintf (label, FIND_RADIO_LBL, group, button, RADIO_OFF); if (search_fwd (label, TRUE, TRUE) >= 1) { ctrl = read (); row_on = atoi (substr (ctrl, rindex (ctrl, "(") + 1)); col_on = atoi (substr (ctrl, rindex (ctrl, ",") + 1)); move_rel (0, strlen (ctrl) - 2); delete_char (); insert ("%c", RADIO_ON); /* ** Update the display buffer. */ set_buffer (_dialog_disp_buf); save_position (); move_abs (row_off, col_off + 1); delete_char (); insert ("%c", RADIO_OFF); move_abs (row_on, col_on + 1); delete_char (); insert ("%c", RADIO_ON); restore_position (); set_buffer (_dialog_radio_buf); } else { error ("Unable to locate 'OFF' Radio button in control file."); beep (); } } } else { error ("Unable to locate 'ON' Radio button in control file."); beep (); } restore_position (); set_buffer (curr_buf); } /* ** _dialog_radio_checked: ** ** Determines which radio button of the specified group is on. Returns ** the label of the 'on' button. The group lable is not required if the ** dialog box has only one group of radio buttons. ** ** This is a user-accessible function. */ string _dialog_radio_checked (~string group) { int curr_buf = inq_buffer (); string label; /* ** Search the radio button control buffer for the specified button. ** If we find it, return its label. Otherwise, return an empty string. */ set_buffer (_dialog_radio_buf); save_position (); top_of_buffer (); sprintf (label, FIND_RADIO_GRP, group); if (search_fwd (label, TRUE, TRUE) >= 1) { int offset; label = read (); offset = index (label, "\"") + 1; label = substr (label, offset, rindex (label, "\"") - offset); } else label = ""; restore_position (); set_buffer (curr_buf); returns (label); } /* ** _dlg_goto_btn: ** ** Positions the cursor at the second character of the control text ** in the display buffer. If the control is a checkbox, the cursor will ** be below the check area. If the control is a push button, the cursor ** will be below the white space before the push button label. This function ** set the current buffer to the display buffer at exit. */ int _dlg_goto_btn (int btn_type, string button_label, ~string group) { string line; int row, col, rval; set_buffer (_dialog_data_buf); save_position (); top_of_buffer (); sprintf (line, BTN_SRCH_STRN, btn_type, button_label, group); if (search_fwd (line, TRUE, FALSE)) { row = atoi (line = read ()); col = atoi (substr (line, index (line, ",") + 1)) + 1; rval = TRUE; } restore_position (); set_buffer (_dialog_disp_buf); if (rval) move_abs (row, col); returns (rval); } /* ** _dlg_check_btn, _dlg_push_btn, _dlg_radio_btn: ** ** Returns the label of the current check, push or radio button. ** Assumes that the current buffer is the display buffer. */ string _dlg_check_btn () { string line; line = read (); line = trim (substr (line, index (line, CHECK_RGT_SRCH) + 2)); line = substr (line, 1, search_string ("[\t\n]", line) - 1); returns (line); } string _dlg_push_btn () { string line; line = read (); line = trim (substr (line, 2, search_string (PUSH_RGT_SRCH, line) - 2)); returns (line); } string _dlg_radio_btn () { int offset; string label; set_buffer (_dialog_radio_buf); top_of_buffer (); sprintf (label, FIND_RADIO_POS, _dialog_row, _dialog_col - 1); if (search_fwd (label, TRUE, TRUE) >= 1) { label = read (); offset = index (label, "\"") + 1; label = substr (label, offset, rindex (label, "\"") - offset); } else { error ("Unable to locate Radiobutton in control file."); beep (); } set_buffer (_dialog_disp_buf); returns (label); } /* ** _dlg_radio_group: ** ** Returns the current radio button's group label. Returns NULL if the ** the current button is not a radio button. */ string _dlg_radio_grp (void) { string group; if (_dialog_type == RADIO) { set_buffer (_dialog_radio_buf); top_of_buffer (); sprintf (group, FIND_RADIO_POS, _dialog_row, _dialog_col - 1); if (search_fwd (group, TRUE, TRUE) >= 1) { group = read (); group = substr (group, 1, index (group, "\"") - 1); } else { error ("Unable to locate current Radiobutton in control file."); beep (); } set_buffer (_dialog_disp_buf); } returns (group); } /* ** _dlg_pick_btn: ** ** Generates the event for a pick button. Passes the row number and ** the button label to the user. */ void _dlg_pick_btn (void) { switch (_dialog_type) { case CHECK: execute_macro (_dialog_action_func, DIALOG_PICK_CHECK, _dialog_row, _dlg_check_btn ()); case PUSH: execute_macro (_dialog_action_func, DIALOG_PICK_PUSH, _dialog_row, _dlg_push_btn ()); case RADIO: execute_macro (_dialog_action_func, DIALOG_PICK_RADIO, _dialog_row, _dlg_radio_btn (), _dlg_radio_grp ()); } } /* ** _dlg_select_push: ** ** Selects or deselects the push button specified by button label. ** If select is nonzero, the push button is selected, otherwise it is ** deselected. */ void _dlg_select_push (string button_label, int select) { int len; if (button_label != "") { if (button_label == _dialog_default_pb) _dialog_pb_state = select; if (_dlg_goto_btn ('P', button_label)) { /* position over the left delimiter of the push button */ move_rel( 0,-1 ); delete_char (len = (strlen (button_label) + 4)); if (select) insert (PUSH_BUTTON_DEF, button_label); else insert (PUSH_BUTTON, button_label); move_rel (0, -(len - 1)); } } } /* ** _dlg_btn_tab_next, _dlg_btn_tab_prev, _dlg_btn_next, _dlg_btn_prev: ** ** Moves the cursor from button control to button control. Check and ** push buttons work just like other controls. Radio buttons are different. ** ** Pressing the Tab or Shift-Tab key when a radio button has the focus ** will move the focus to the next control not in that radio button's group. ** ** The cursor keys also work a little differently for radio buttons. If ** the current control is a radio button, pressing Up/Left or Right/Down ** moves the focus to the next radio button in the same group of radio ** buttons. When the current radio button is the first or last button in ** the group, the cursor will 'wrap-around' to the last or first button in ** the group. */ void _dlg_btn_tab_next (void) { if (_dialog_type == RADIO) { if (_dialog_exit ()) { /* ** Find next radio button group or other control. If the next ** control found is another set of radio buttons, make the first ** button of the group the current control. */ set_buffer (_dialog_data_buf); next_char (); if (search_fwd (FIND_NEXT, TRUE, FALSE)) { if (upper (read (1)) == "G") search_fwd ("<[ \t]@\\cR", TRUE, FALSE); } else prev_char (); _dialog_enter (); } } else _dialog_next (); } void _dlg_btn_tab_prev (void) { if (_dialog_type == RADIO) { if (_dialog_exit ()) { set_buffer (_dialog_data_buf); /* ** Find previous radio button group or other control. If the ** previous control found is another set of radio buttons, make the ** last button of the group the current control. */ if (prev_char ()) { if (search_back (FIND_PREV, TRUE, FALSE)) { if (upper (read (1)) == "E") search_back ("<[ \t]@\\cR", TRUE, FALSE); } else next_char (); } _dialog_enter (); } } else _dialog_prev (); } void _dlg_btn_next (void) { if (_dialog_type == RADIO) { if (_dialog_exit ()) { set_buffer (_dialog_data_buf); search_fwd ("<[ \t]@\\c[RE]", TRUE, FALSE); if (read (1) == "E") { search_back ("<[ \t]@\\cG", TRUE, FALSE); search_fwd ("<[ \t]@\\cR", TRUE, FALSE); } _dialog_enter (); } } else _dialog_next (); } void _dlg_btn_prev (void) { if (_dialog_type == RADIO) { if (_dialog_exit ()) { set_buffer (_dialog_data_buf); up (); search_back ("<[ \t]@\\c[RG]", TRUE, FALSE); if (read (1) == "G") { search_fwd ("<[ \t]@\\cE", TRUE, FALSE); search_back ("<[ \t]@\\cR", TRUE, FALSE); } _dialog_enter (); } } else _dialog_prev (); } /* ** _is_push_button ** ** Search the current line of the dialog display buffer ** and determine if the user clicked on a push button. ** ** Input: ** Current buffer equal _dialog_disp_buf ** col - the column position of the click ** ** Returns ** the position of the left delimiter of the push button ** if a push button was clicked in; otherwise zero. On ** exit the current position in _dialog_disp_buf is the ** position of the click. ** */ int _is_push_button( int col ) { int i, btn_left, btn_right, len; string temp; i = 0; // adjustment for position on original line beginning_of_line(); temp = read(); // get the whole line /* ** Look thru the whole line finding each push button on the line ** and checking if the given column position is inside that button */ btn_left = search_string( PUSH_SRCH, temp, len); // look for a push button while ( btn_left && col > btn_right ) { btn_left = btn_left + i; btn_right = btn_left + len - 1; /* was the click on this push button?? */ if ( btn_left <= col && col <= btn_right ) { break; } else { /* No - check for the next push button */ i = btn_right++; // look for another push button temp = substr( temp, btn_right ); btn_left = search_string( PUSH_SRCH, temp, len); // look for the btn_right delimiter } } move_abs( 0, col ); // return to original position return( btn_left ); }