📄 view.c
字号:
yyyy: mem_free(ln); } } else fs->state = strlen(fs->value); break; case ACT_COPY_CLIPBOARD: set_clipboard_text(fs->value); break; case ACT_CUT_CLIPBOARD: set_clipboard_text(fs->value); if (!form->ro) fs->value[0] = 0; fs->state = 0; break; case ACT_PASTE_CLIPBOARD: { char *clipboard = get_clipboard_text(); if (!clipboard) break; if (!form->ro && strlen(clipboard) <= (size_t)form->maxlength) { unsigned char *v; v = mem_realloc(fs->value, strlen(clipboard) +1); fs->value = v; memmove(v , clipboard, strlen(clipboard) +1); fs->state = strlen(fs->value); } mem_free(clipboard); break; } case ACT_ENTER: if (form->type == FC_TEXTAREA) { if (!form->ro && strlen(fs->value) < (size_t)form->maxlength) { unsigned char *v; v = mem_realloc(fs->value, strlen(fs->value) + 2); fs->value = v; memmove(v + fs->state + 1, v + fs->state, strlen(v + fs->state) + 1); v[fs->state++] = '\n'; } } else x = 0; break; case ACT_BACKSPACE: if (!form->ro && fs->state) memmove(fs->value + fs->state - 1, fs->value + fs->state, strlen(fs->value + fs->state) + 1), fs->state--; break; case ACT_DELETE: if (!form->ro && (size_t)fs->state < strlen(fs->value)) memmove(fs->value + fs->state, fs->value + fs->state + 1, strlen(fs->value + fs->state)); break; case ACT_KILL_TO_BOL: if (!form->ro) memmove(fs->value, fs->value + fs->state, strlen(fs->value + fs->state) + 1); fs->state = 0; break; case ACT_KILL_TO_EOL: fs->value[fs->state] = 0; break; default: if (!ev->y && (ev->x >= 32 && ev->x < 256 && cp2u(ev->x, ses->term->spec->charset) != -1)) { if (!form->ro && strlen(fs->value) < (size_t)form->maxlength) { unsigned char *v; v = mem_realloc(fs->value, strlen(fs->value) + 2); fs->value = v; memmove(v + fs->state + 1, v + fs->state, strlen(v + fs->state) + 1); v[fs->state++] = ev->x; } } else { b: x = 0; } } } else x = 0; if (x) { if (ev->x != KBD_UP && ev->x != KBD_DOWN && form->type == FC_TEXTAREA) textarea_adjust_viewport(f, l); draw_form_entry(ses->term, f, l); redraw_from_window(ses->win); } return x;}void set_textarea(struct session *ses, struct f_data_c *f, int kbd){ if (f->vs->current_link != -1 && f->f_data->links[f->vs->current_link].type == L_AREA) { struct event ev = { EV_KBD, 0, 0, 0 }; ev.x = kbd; field_op(ses, f, &f->f_data->links[f->vs->current_link], &ev, 1); }}void search_for_back(struct session *ses, unsigned char *str){ struct f_data_c *f = current_frame(ses); if (!f || !str || !str[0]) return; if (ses->search_word) mem_free(ses->search_word); ses->search_word = stracpy(str); charset_upcase_string(&ses->search_word, ses->term->spec->charset); if (ses->last_search_word) mem_free(ses->last_search_word); ses->last_search_word = stracpy(ses->search_word); ses->search_direction = -1; find_next(ses, f, 1);}void search_for(struct session *ses, unsigned char *str){ struct f_data_c *f = current_frame(ses); if (!f || !str || !str[0]) return; if (ses->search_word) mem_free(ses->search_word); ses->search_word = stracpy(str); charset_upcase_string(&ses->search_word, ses->term->spec->charset); if (ses->last_search_word) mem_free(ses->last_search_word); ses->last_search_word = stracpy(ses->search_word); ses->search_direction = 1; find_next(ses, f, 1);}#define HASH_SIZE 4096#define HASH(p) (((p.y << 6) + p.x) & (HASH_SIZE - 1))int point_intersect(struct point *p1, int l1, struct point *p2, int l2){ int i, j; static char hash[HASH_SIZE]; static char init = 0; if (!init) memset(hash, 0, HASH_SIZE), init = 1; for (i = 0; i < l1; i++) hash[HASH(p1[i])] = 1; for (j = 0; j < l2; j++) if (hash[HASH(p2[j])]) { for (i = 0; i < l1; i++) if (p1[i].x == p2[j].x && p1[i].y == p2[j].y) { for (i = 0; i < l1; i++) hash[HASH(p1[i])] = 0; return 1; } } for (i = 0; i < l1; i++) hash[HASH(p1[i])] = 0; return 0;}int find_next_link_in_search(struct f_data_c *f, int d){ struct point *pt; int len; struct link *link; if (d == -2 || d == 2) { d /= 2; find_link(f, d, 0); if (f->vs->current_link == -1) return 1; } else nx:if (f->vs->current_link == -1 || !(next_in_view(f, f->vs->current_link + d, d, in_view, NULL))) { find_link(f, d, 0); return 1; } link = &f->f_data->links[f->vs->current_link]; get_searched(f, &pt, &len); if (point_intersect(pt, len, link->pos, link->n)) { mem_free(pt); return 0; } mem_free(pt); goto nx;}void find_next(struct session *ses, struct f_data_c *f, int a){ int min, max; int c = 0; int p = f->vs->view_pos; if (!a && ses->search_word) { if (!(find_next_link_in_search(f, ses->search_direction))) return; p += ses->search_direction * f->yw; } if (!ses->search_word) { if (!ses->last_search_word) { msg_box(ses->term, NULL, TEXT(T_SEARCH), AL_CENTER, TEXT(T_NO_PREVIOUS_SEARCH), NULL, 1, TEXT(T_CANCEL), NULL, B_ENTER | B_ESC); return; } ses->search_word = stracpy(ses->last_search_word); } get_search_data(f->f_data); do { if (is_in_range(f->f_data, p, f->yw, ses->search_word, &min, &max)) { f->vs->view_pos = p; if (max >= min) { if (max > f->vs->view_posx + f->xw) f->vs->view_posx = max - f->xw; if (min < f->vs->view_posx) f->vs->view_posx = min; } f->vs->orig_view_pos = f->vs->view_pos; f->vs->orig_view_posx = f->vs->view_posx; set_link(f); find_next_link_in_search(f, ses->search_direction * 2); /*draw_doc(ses->term, f, 1); print_screen_status(ses); redraw_from_window(ses->win);*/ return; } if ((p += ses->search_direction * f->yw) > f->f_data->y) p = 0; if (p < 0) { p = 0; while (p < f->f_data->y) p += f->yw ? f->yw : 1; p -= f->yw; } } while ((c += f->yw ? f->yw : 1) < f->f_data->y + f->yw); /*draw_doc(ses->term, f, 1); print_screen_status(ses); redraw_from_window(ses->win);*/ msg_box(ses->term, NULL, TEXT(T_SEARCH), AL_CENTER, TEXT(T_SEARCH_STRING_NOT_FOUND), NULL, 1, TEXT(T_CANCEL), NULL, B_ENTER | B_ESC);}void find_next_back(struct session *ses, struct f_data_c *f, int a){ ses->search_direction = - ses->search_direction; find_next(ses, f, a); ses->search_direction = - ses->search_direction;}void rep_ev(struct session *ses, struct f_data_c *fd, void (*f)(struct session *, struct f_data_c *, int), int a){ int i = ses->kbdprefix.rep ? ses->kbdprefix.rep_num : 1; while (i--) f(ses, fd, a);}struct link *choose_mouse_link(struct f_data_c *f, struct event *ev){ struct link *l1 = f->f_data->links + f->f_data->nlinks; struct link *l2 = f->f_data->links; struct link *l; int i; if (!f->f_data->nlinks) return NULL; if (ev->x < 0 || ev->y < 0 || ev->x >= f->xw || ev->y >= f->yw) return NULL; for (i = f->vs->view_pos; i < f->f_data->y && i < f->vs->view_pos + f->yw; i++) { if (f->f_data->lines1[i] && f->f_data->lines1[i] < l1) l1 = f->f_data->lines1[i]; if (f->f_data->lines2[i] && f->f_data->lines2[i] > l2) l2 = f->f_data->lines2[i]; } for (l = l1; l <= l2; l++) { int i; for (i = 0; i < l->n; i++) if (l->pos[i].x - f->vs->view_posx == ev->x && l->pos[i].y - f->vs->view_pos == ev->y) return l; } return NULL;}void goto_link_number(struct session *ses, unsigned char *num){ int n = atoi(num); struct f_data_c *f = current_frame(ses); struct link *link; if (!f || !f->vs) return; if (n < 0 || n > f->f_data->nlinks) return; f->vs->current_link = n - 1; f->vs->orig_link = f->vs->current_link; link = &f->f_data->links[f->vs->current_link]; check_vs(f); f->vs->orig_view_pos = f->vs->view_pos; f->vs->orig_view_posx = f->vs->view_posx; if (link->type != L_AREA && link->type != L_FIELD) enter(ses, f, 0);}void frm_download(struct session *, struct f_data_c *);void send_image(struct terminal *term, void *xxx, struct session *ses); int frame_ev(struct session *ses, struct f_data_c *fd, struct event *ev){ int x = 1; if (fd->vs->current_link >= 0 && (fd->f_data->links[fd->vs->current_link].type == L_FIELD || fd->f_data->links[fd->vs->current_link].type == L_AREA)) if (field_op(ses, fd, &fd->f_data->links[fd->vs->current_link], ev, 0)) return 1; if (ev->ev == EV_KBD && ev->x >= '0'+!ses->kbdprefix.rep && ev->x <= '9' && (!fd->f_data->opt.num_links || ev->y)) { if (!ses->kbdprefix.rep) ses->kbdprefix.rep_num = 0; if ((ses->kbdprefix.rep_num = ses->kbdprefix.rep_num * 10 + ev->x - '0') > 65536) ses->kbdprefix.rep_num = 65536; ses->kbdprefix.rep = 1; return 1; } if (ev->ev == EV_KBD) { switch (kbd_action(KM_MAIN, ev)) { case ACT_PAGE_DOWN: rep_ev(ses, fd, page_down, 0); break; case ACT_PAGE_UP: rep_ev(ses, fd, page_up, 0); break; case ACT_DOWN: rep_ev(ses, fd, down, 0); break; case ACT_UP: rep_ev(ses, fd, up, 0); break; case ACT_COPY_CLIPBOARD: { char *current_link = print_current_link(ses); if (current_link) { set_clipboard_text( current_link ); mem_free(current_link); } break; } case ACT_SCROLL_UP: rep_ev(ses, fd, scroll, -1 - !ses->kbdprefix.rep); break; case ACT_SCROLL_DOWN: rep_ev(ses, fd, scroll, 1 + !ses->kbdprefix.rep); break; case ACT_SCROLL_LEFT: rep_ev(ses, fd, hscroll, -1 - 7 * !ses->kbdprefix.rep); break; case ACT_SCROLL_RIGHT: rep_ev(ses, fd, hscroll, 1 + 7 * !ses->kbdprefix.rep); break; case ACT_HOME: rep_ev(ses, fd, home, 0); break; case ACT_END: rep_ev(ses, fd, x_end, 0); break; case ACT_ENTER: x = enter(ses, fd, 0); break; case ACT_DOWNLOAD: if (!anonymous) frm_download(ses, fd); break; case ACT_SEARCH: search_dlg(ses, fd, 0); break; case ACT_SEARCH_BACK: search_back_dlg(ses, fd, 0); break; case ACT_FIND_NEXT: find_next(ses, fd, 0); break; case ACT_FIND_NEXT_BACK: find_next_back(ses, fd, 0); break; case ACT_ZOOM_FRAME: set_frame(ses, fd, 0), x = 2; break; case ACT_VIEW_IMAGE: send_image(ses->term, NULL, ses); break; default: if (ev->x >= '1' && ev->x <= '9' && !ev->y) { struct f_data *f_data = fd->f_data; int nl, lnl; unsigned char d[2]; d[0] = ev->x; d[1] = 0; nl = f_data->nlinks, lnl = 1; while (nl) nl /= 10, lnl++; if (lnl > 1) input_field(ses->term, NULL, TEXT(T_GO_TO_LINK), TEXT(T_ENTER_LINK_NUMBER), TEXT(T_OK), TEXT(T_CANCEL), ses, NULL, lnl, d, 1, f_data->nlinks, check_number, (void (*)(void *, unsigned char *)) goto_link_number, NULL); } /*else if (ev->x == 'x') { struct node *node; static int n = -1; int i; fd->xl = -1234; draw_doc(ses->term, fd, 1); clear_link(ses->term, fd); n++; i = n; foreachback(node, fd->f_data->nodes) { if (!i--) { int x, y; for (y = 0; y < node->yw; y++) for (x = 0; x < node->xw && x < 1000; x++) { int rx = x + node->x + fd->xp - fd->vs->view_posx; int ry = y + node->y + fd->yp - fd->vs->view_pos; if (rx >= 0 && ry >= 0 && rx < ses->term->x && ry < ses->term->y) { set_color(ses->term, rx, ry, 0x3800); } } break; } } if (i >= 0) n = -1; x = 0; }*/ else x = 0; } } else if (ev->ev == EV_MOUSE) { struct link *l = choose_mouse_link(fd, ev); if (l) { x = 1; fd->vs->current_link = l - fd->f_data->links; fd->vs->orig_link = fd->vs->current_link; if (l->type == L_LINK || l->type == L_BUTTON || l->type == L_CHECKBOX || l->type == L_SELECT) if ((ev->b & BM_ACT) == B_UP) { draw_doc(ses->term, fd, 1); print_screen_status(ses); redraw_from_window(ses->win); if ((ev->b & BM_BUTT) < B_MIDDLE) x = enter(ses, fd, 0); else link_menu(ses->term, NULL, ses); } } } else x = 0; ses->kbdprefix.rep = 0; return x;}struct f_data_c *current_frame(struct session *ses){ struct f_data_c *fd = NULL; int i; if (ses->history.next == &ses->history) return NULL; i = cur_loc(ses)->vs.current_link; foreach(fd, ses->scrn_frames) { if (fd->f_data && fd->f_data->frame) continue; if (!i--) return fd; } if (!ses->screen || !ses->screen->f_data || ses->screen->f_data->frame) return NULL; return ses->screen;}int send_to_frame(struct session *ses, struct event *ev){ int r; struct f_data_c *fd; fd = current_frame(ses); if (!fd) { /*internal("document not formatted");*/ return 0; } r = frame_ev(ses, fd, ev); if (r == 1) { draw_doc(ses->term, fd, 1); print_screen_status(ses); redraw_from_window(ses->win); } return r;}void next_frame(struct session *ses, int p){ int n; struct view_state *vs; struct f_data_c *fd; if (list_empty(ses->history) || (ses->screen && ses->screen->f_data && !ses->screen->f_data->frame)) return; vs = &cur_loc(ses)->vs; n = 0; foreach(fd, ses->scrn_frames) if (!(fd->f_data && fd->f_data->frame)) n++; vs->current_link += p; if (!n) n = 1; while (vs->current_link < 0) vs->current_link += n; vs->current_link %= n;}void do_for_frame(struct session *ses, void (*f)(struct session *, struct f_data_c *, int), int a){ struct f_data_c *fd = current_frame(ses); if (!fd) { /*internal("document not formatted");*/ return; } f(ses, fd, a); draw_doc(ses->term, fd, 1); print_screen_status(ses); redraw_from_window(ses->win);}void do_mouse_event(struct session *ses, struct event *ev){ struct event evv; struct f_data_c *fdd, *fd = current_frame(ses); /* !!! FXIME: frames */ struct document_options *o; if (!fd) return; o = &fd->f_data->opt; if (ev->x >= o->xp && ev->x < o->xp + o->xw && ev->y >= o->yp && ev->y < o->yp + o->yw) goto ok; r: next_frame(ses, 1); fdd = current_frame(ses); o = &fdd->f_data->opt; if (ev->x >= o->xp && ev->x < o->xp + o->xw && ev->y >= o->yp && ev->y < o->yp + o->yw) { draw_formatted(ses); fd = fdd; goto ok; } if (fdd != fd) goto r; return; ok: memcpy(&evv, ev, sizeof(struct event)); evv.x -= fd->xp; evv.y -= fd->yp; send_to_frame(ses, &evv);}void send_event(struct session *ses, struct event *ev){ if (ev->ev == EV_KBD) { if (send_to_frame(ses, ev)) return; switch (kbd_action(KM_MAIN, ev)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -