📄 panel_text.c
字号:
* and place caret before seln_first or after seln_last * depending upon which is nearest to the mouse pointer */ first_offset = (dp->seln_first - dp->first_char) * dp->font->pf_defaultsize.x; last_offset = (dp->seln_last - dp->first_char + 1) * dp->font->pf_defaultsize.x; if (dp->first_char) { first_offset += panel_left_arrow_pr.pr_width; last_offset += panel_left_arrow_pr.pr_width; } if (strlen(dp->value) == 0) caret_offset = 0; else if (ptr_offset < first_offset || last_offset - ptr_offset > ptr_offset - first_offset) { if (holder.rank == SELN_PRIMARY && dp->seln_first < dp->first_char) { /* need to scroll caret into view */ dp->first_char = dp->seln_first; if (strlen(dp->value) <= dp->display_length) dp->last_char = strlen(dp->value) - 1; else { dp->last_char = dp->first_char + dp->display_length - 1; if (dp->first_char) dp->last_char--; if (strlen(dp->value) - dp->first_char + 1 > dp->display_length) dp->last_char--; } paint_caret(ip, PIX_CLR); paint_value(ip, PV_HIGHLIGHT); } caret_offset = (dp->seln_first - dp->first_char) * dp->font->pf_defaultsize.x; } else { if (holder.rank == SELN_PRIMARY && dp->seln_last > dp->last_char) { /* need to scroll caret into view */ dp->last_char = dp->seln_last; dp->first_char = dp->last_char - dp->display_length + 1; if (dp->first_char) dp->first_char++; if (strlen(dp->value) - dp->first_char + 1 > dp->display_length) dp->first_char++; paint_caret(ip, PIX_CLR); paint_value(ip, PV_HIGHLIGHT); } caret_offset = (dp->seln_last - dp->first_char + 1) * dp->font->pf_defaultsize.x; } if (dp->first_char) /* adjust for left arrow */ caret_offset += panel_left_arrow_pr.pr_width; /* Caret offset cannot exceed value offset */ if (caret_offset > strlen(dp->value) * dp->font->pf_defaultsize.x) caret_offset = strlen(dp->value) * dp->font->pf_defaultsize.x; if (holder.rank == SELN_PRIMARY) { dp->caret_offset = caret_offset; primary_ms_clicks = ms_clicks; primary_seln_first = dp->seln_first; primary_seln_last = dp->seln_last; primary_pending_delete = pending_delete; } else { /* SECONDARY SELECTION */ dp->secondary_caret_offset = caret_offset; secondary_ms_clicks = ms_clicks; secondary_seln_first = dp->seln_first; secondary_seln_last = dp->seln_last; secondary_pending_delete = pending_delete; } /* * Make this item the selection (includes highlighting). * Must be done AFTER caret placement since scrolling may occur */ is_null = strlen(dp->value) == 0; panel_seln_acquire(panel, ip, holder.rank, is_null); if (holder.rank == SELN_PRIMARY) { /* * Make sure we have acquired the CARET selection token, too. * Paint caret AFTER painting value */ dp->flags |= SELECTING_ITEM; dp->orig_caret = ip->panel->caret; panel_seln_acquire(panel, ip, SELN_CARET, TRUE); (void) panel_setcaret(panel, ip); /* READ_ONLY text is selectable */ }}/***********************************************************************//* cancel_preview *//***********************************************************************//* ARGSUSED */staticcancel_preview(ip, event) panel_item_handle ip; Event *event;{ register text_data *dp = textdp(ip); register panel_handle panel = ip->panel; if (dp->flags & SELECTING_ITEM) { deselect(panel); panel->caret = dp->orig_caret; textdp(dp->orig_caret)->flags |= HASCARET; dp->orig_caret = (panel_item_handle) NULL; dp->flags &= ~SELECTING_ITEM; } if (ip == panel_seln(panel, SELN_PRIMARY)->ip) panel_seln_cancel(panel, SELN_PRIMARY); if (ip == panel_seln(panel, SELN_SECONDARY)->ip) panel_seln_cancel(panel, SELN_SECONDARY); if (ip == panel_seln(panel, SELN_CARET)->ip) panel_seln_cancel(panel, SELN_CARET);}/***********************************************************************//* accept_preview *//***********************************************************************//* ARGSUSED */staticaccept_preview(ip, event) panel_item_handle ip; Event *event;{ register text_data *dp = textdp(ip); register panel_handle panel = ip->panel; Seln_holder holder; if (!(dp->flags & SELECTING_ITEM)) return; dp->orig_caret = (panel_item_handle) NULL; dp->flags &= ~SELECTING_ITEM; /* Ask for kbd focus if this is a primary selection */ holder = panel_seln_inquire(panel, SELN_UNSPECIFIED); if (holder.rank == SELN_PRIMARY) (void) win_set_kbd_focus(panel->windowfd, win_fdtonumber(panel->windowfd));}staticaccept_menu(ip, event) panel_item_handle ip; Event *event;{ struct menuitem *mi; /* Make sure the menu title reflects the label. */ panel_sync_menu_title(ip); if (mi = panel_menu_display(ip, event)) { if ((panel_item_handle) LINT_CAST(panel_getcaret(ip->panel)) != ip) (void) panel_setcaret(ip->panel, ip); event_id(event) = (short) mi->mi_data; accept_key(ip, event); }}#define CTRL_D_KEY '\004'#define CTRL_G_KEY '\007'/* * Since the keymapping system no longer supports full translation of event * ids, shiftmasks and flags we must revert to the old stuff that directly * recognizes the 3.x accelerators for CUT and PASTE. */static short keyboard_accel_state_cached;static short keyboard_accel_state;/***********************************************************************//* accept_key *//***********************************************************************/staticaccept_key(ip, event) register panel_item_handle ip; register Event *event;{ panel_handle panel = ip->panel; register text_data *dp = textdp(ip); int caret_was_on; int notify_desired = FALSE; Panel_setting notify_rtn_code; int ok_to_insert; panel_selection_handle selection; extern char *index(); short code; Event save_event; int status; int keep_flags; /* * recognize arrow keys * * NOTES: FAKE_ESC is used to handle recursion properly * * Design Goals: ESC by itself should blink immediately and not be inserted * in the field ESC [ DIGITS CHAR should blink immediately and insert [ * DIGITS CHAR in the field ESC [ C should be interpreted as a * RIGHT_CURSOR_KEY ESC [ D should be interpreted as a LEFT_CURSOR_KEY * ESC [ CHAR where CHAR is not C or D should blink and insert [ CHAR in * the field BACKSPACE must be handled correctly in all cases */#define FAKE_ESC 0#define ESC 27 if (event_id(event) == ESC) { save_event = *event; /* set up for non-blocking read */ keep_flags = fcntl(window_fd(ip->panel), F_GETFL, 0); fcntl(window_fd(ip->panel), F_SETFL, keep_flags | FNDELAY); status = window_read_event(ip->panel, event); if (status >= 0) { /* event waiting after ESC */ if (event_id(event) == '[') { status = window_read_event(ip->panel, event); if (status >= 0) { /* event waiting after ESC [ */ save_event = *event; switch (event_id(event)) { case 'A': event_id(event) = UP_CURSOR_KEY; break; case 'B': event_id(event) = DOWN_CURSOR_KEY; break; case 'C': event_id(event) = RIGHT_CURSOR_KEY; break; case 'D': event_id(event) = LEFT_CURSOR_KEY; break; default: event_id(event) = FAKE_ESC; accept_key(ip, event); event_id(event) = '['; accept_key(ip, event); *event = save_event; break; } } else { /* no event waiting after ESC [ */ event_id(event) = FAKE_ESC; accept_key(ip, event); event_id(event) = '['; } } else if (event_is_ascii(event) || event_is_meta(event)) { save_event = *event; event_id(event) = FAKE_ESC; accept_key(ip, event); *event = save_event; } else /* ignore mouse event */ *event = save_event; } else /* no event waiting after ESC */ *event = save_event; /* restore to blocking read */ fcntl(window_fd(ip->panel), F_SETFL, keep_flags); } /* change back to ESCAPE, now that the recursive part is finished */ if (event_id(event) == FAKE_ESC) event_id(event) = ESC; if (event_shift_is_down(event)) { if (event_id(event) == dp->edit_bk_char) event_set_action(event, ACTION_ERASE_CHAR_FORWARD); else if (event_id(event) == dp->edit_bk_word) event_set_action(event, ACTION_ERASE_WORD_FORWARD); else if (event_id(event) == dp->edit_bk_line) event_set_action(event, ACTION_ERASE_LINE_END); } code = event_action(event); if (primary_pending_delete) { /* * If moving the caret to another text item via the keyboard, turn * off the pending delete. If moving the caret within the same * field, make the selection non-pending. */ if (event_is_key_right(event) || (code == '\n') || (code == '\r') || (code == '\t')) { if (ip == panel_seln(panel, SELN_PRIMARY)->ip) panel_seln_dehilite(ip, SELN_PRIMARY); else if (ip == panel_seln(panel, SELN_SECONDARY)->ip) panel_seln_dehilite(ip, SELN_SECONDARY); primary_pending_delete = 0; if ((code == LEFT_CURSOR_KEY) || (code == RIGHT_CURSOR_KEY)) { if (ip == panel_seln(panel, SELN_PRIMARY)->ip) panel_seln_hilite(panel_seln(panel, SELN_PRIMARY)); else if (ip == panel_seln(panel, SELN_SECONDARY)->ip) panel_seln_hilite(panel_seln(panel, SELN_SECONDARY)); } } /* * Turn off pending delete when editing the item with backspace & co. */ else if (panel_event_is_panel_semantic(event) || (code == dp->edit_bk_char) || (code == dp->edit_bk_word) || (code == dp->edit_bk_line)) { if (ip == panel_seln(panel, SELN_PRIMARY)->ip) panel_seln_dehilite(ip, SELN_PRIMARY); else if (ip == panel_seln(panel, SELN_SECONDARY)->ip) panel_seln_dehilite(ip, SELN_SECONDARY); primary_pending_delete = 0; } /* * Carry out pending delete on the selection. */ else if (!panel_event_is_sunview_semantic(event)) { selection = panel_seln(panel, SELN_PRIMARY); if (selection->ip) { /* Copy the selection to the shelf */ panel_seln_shelve(panel, selection, SELN_PRIMARY); /* Delete the selected characters */ panel_seln_delete(selection->ip, SELN_PRIMARY); selection->ip = (panel_item_handle)0; (void) seln_done(panel->seln_client, SELN_PRIMARY); } primary_pending_delete = 0; } } else { /* * No pending-delete. If editting this item or moving to another * one, unhilite in case there was a non-pending selection. */ if ((panel_printable_char(code) || (code == dp->edit_bk_char) || (code == dp->edit_bk_word) || (code == dp->edit_bk_line) || panel_event_is_panel_semantic(event) || (code == '\n') || (code == '\r') || (code == '\t')) && ((code != LEFT_CURSOR_KEY) && (code != RIGHT_CURSOR_KEY))) { if (ip == panel_seln(panel, SELN_PRIMARY)->ip) panel_seln_dehilite(ip, SELN_PRIMARY); else if (ip == panel_seln(panel, SELN_SECONDARY)->ip) panel_seln_dehilite(ip, SELN_SECONDARY); } } /* * If hiliting turned off, set click count to 0. Other routines, like * panel_seln_delete() & panel_seln_hilite will key on this value. */ if ((event_is_euc(event) || event_is_iso(event) || panel_event_is_panel_semantic(event) || (code == dp->edit_bk_char) || (code == dp->edit_bk_word) || (code == dp->edit_bk_line)) && ((code != ACTION_CUT) && (code != LEFT_CURSOR_KEY) && (code != RIGHT_CURSOR_KEY))) { primary_ms_clicks = 0; } /* READ_ONLY text can accept caret to allow scrolling */#ifdef OBSOLETE if (dp->flags & READ_ONLY) return NULL;#endif /* get the caret selection */ selection = panel_seln(panel, SELN_CARET); if (panel->seln_client && !selection->ip) if (event_is_down(event) && (event_is_euc(event) || event_is_iso(event) || event_action(event) == GET_KEY)) panel_seln_acquire(panel, ip, SELN_CARET, TRUE); /* * not interested in function keys, except for acquiring the caret * selection. */ /* * also, never pass ctrl-D or ctrl-G, which have been mapped to the * Delete and Get function keys, to the notify proc */ /* * Cache and check state of 4.0 accelerators; if not enabled then allow * use of 3.x accelerators */ if (!keyboard_accel_state_cached) { keyboard_accel_state = (!strcmp("Enabled", (char *) defaults_get_string( "/Compatibility/New_keyboard_accelerators", "Enabled", 0))) ? 1 : 0; keyboard_accel_state_cached = 1; } if (panel_event_is_sunview_semantic(event) || (keyboard_accel_state && event_id(event) == CTRL_D_KEY) || (keyboard_accel_state && event_id(event) == CTRL_G_KEY)) return; switch (dp->notify_level) { case PANEL_ALL: notify_desired = TRUE; break; case PANEL_SPECIFIED: notify_desired = index(dp->terminators, code) != 0; break; case PANEL_NON_PRINTABLE: notify_desired = !panel_printable_char(code); break; case PANEL_NONE: notify_desired = FALSE; break; } if (notify_desired) { notify_rtn_code = (Panel_setting) (*ip->notify) (ip, event); ok_to_insert = notify_rtn_code == PANEL_INSERT; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -