📄 editwidget.c
字号:
w->editor = edit_init (e, height / FONT_PIX_PER_LINE, width / FONT_MEAN_WIDTH, filename, text, starting_directory, text_size); w->funcs->data = (void *) w->editor; if (!w->editor) { free (e); CDestroyWidget (w->ident); CPopFont (); return 0; } e->macro_i = -1; e->widget = w; if (!(options & EDITOR_NO_SCROLL)) { w->vert_scrollbar = CDrawVerticalScrollbar (catstrs (identifier, ".vsc", 0), parent, x + width + EDIT_FRAME_W + WIDGET_SPACING, y, height + EDIT_FRAME_H, AUTO_WIDTH, 0, 0); CSetScrollbarCallback (w->vert_scrollbar->ident, w->ident, link_scrollbar_to_editor); w->vert_scrollbar->scroll_bar_extra_render = render_book_marks; CGetHintPos (&max_x, 0); } set_hint_pos (x + width + EDIT_FRAME_W + WIDGET_SPACING, y + height + EDIT_FRAME_H + WIDGET_SPACING + extra_space_for_hscroll); if (extra_space_for_hscroll) { w->hori_scrollbar = CDrawHorizontalScrollbar (catstrs (identifier, ".hsc", 0), parent, x, y + height + EDIT_FRAME_H, width + EDIT_FRAME_W, AUTO_HEIGHT, 0, 0); CSetScrollbarCallback (w->hori_scrollbar->ident, w->ident, link_hscrollbar_to_editor); } CGetHintPos (0, &y); if (!(options & EDITOR_NO_TEXT)) { CPushFont ("widget", 0); CDrawStatus (catstrs (identifier, ".text", 0), parent, x, y, width + EDIT_FRAME_W, e->filename); CPopFont (); } CGetHintPos (0, &y); if (!max_x) CGetHintPos (&max_x, 0); set_hint_pos (max_x, y); CPopFont (); return w;}static void render_book_marks (CWidget * w){ struct _book_mark *p; WEdit *edit; int l; char i[32]; if (!w) return; strcpy (i, CIdentOf (w)); *(strstr (i, ".vsc")) = '\0'; edit = (CIdent (i))->editor; if (!edit->book_mark) return; l = CHeightOf (w) - 10 * CWidthOf (w) / 3 - 10; for (p = edit->book_mark; p->next; p = p->next); for (; p->prev; p = p->prev) { int y = (CWidthOf (w) + 2 * CWidthOf (w) / 3 + 4) + (int) ((double) l * p->line / edit->total_lines); CSetColor (color_palette (((p->c & 0xFF00) >> 8) ? ((p->c & 0xFF00) >> 8) : (p->c & 0xFF))); CLine (CWindowOf (w), 5, y, CWidthOf (w) - 6, y); }}void update_scroll_bars (WEdit * e){ int i, x1, x2; CWidget *scroll; CPushFont ("editor", 0); scroll = e->widget->vert_scrollbar; if (scroll) { i = e->total_lines - e->start_line + 1; if (i > e->num_widget_lines) i = e->num_widget_lines; if (e->total_lines) { x1 = (double) 65535.0 *e->start_line / (e->total_lines + 1); x2 = (double) 65535.0 *i / (e->total_lines + 1); } else { x1 = 0; x2 = 65535; } if (x1 != scroll->firstline || x2 != scroll->numlines) { scroll->firstline = x1; scroll->numlines = x2; EditExposeRedraw = 1; render_scrollbar (scroll); EditExposeRedraw = 0; } } scroll = e->widget->hori_scrollbar; if (scroll) { i = e->max_column - (-e->start_col) + 1; if (i > e->num_widget_columns * FONT_MEAN_WIDTH) i = e->num_widget_columns * FONT_MEAN_WIDTH; x1 = (double) 65535.0 *(-e->start_col) / (e->max_column + 1); x2 = (double) 65535.0 *i / (e->max_column + 1); if (x1 != scroll->firstline || x2 != scroll->numlines) { scroll->firstline = x1; scroll->numlines = x2; EditExposeRedraw = 1; render_scrollbar (scroll); EditExposeRedraw = 0; } } CPopFont ();}void edit_mouse_mark (WEdit * edit, XEvent * event, int double_click){ CPushFont ("editor", 0); edit_update_curs_row (edit); edit_update_curs_col (edit); if (event->type != MotionNotify) { edit_push_action (edit, KEY_PRESS + edit->start_display); if (edit->mark2 == -1) edit_push_action (edit, MARK_1 + edit->mark1); /* mark1 must be following the cursor */ } if (event->type == ButtonPress) { edit->highlight = 0; edit->found_len = 0; } mouse_mark ( event, double_click, edit->widget->funcs ); CPopFont ();}void link_scrollbar_to_editor (CWidget * scrollbar, CWidget * editor, XEvent * xevent, CEvent * cwevent, int whichscrbutton){ int i, start_line; WEdit *e; e = editor->editor; if (!e) return; if (!e->widget->vert_scrollbar) return; CPushFont ("editor", 0); start_line = e->start_line; if ((xevent->type == ButtonRelease || xevent->type == MotionNotify) && whichscrbutton == 3) { edit_move_display (e, (double) scrollbar->firstline * e->total_lines / 65535.0 + 1); } else if (xevent->type == ButtonPress && (cwevent->button == Button1 || cwevent->button == Button2)) { switch (whichscrbutton) { case 1: edit_move_display (e, e->start_line - e->num_widget_lines + 1); break; case 2: edit_move_display (e, e->start_line - 1); break; case 5: edit_move_display (e, e->start_line + 1); break; case 4: edit_move_display (e, e->start_line + e->num_widget_lines - 1); break; } } if (e->total_lines) scrollbar->firstline = (double) 65535.0 *e->start_line / (e->total_lines + 1); else scrollbar->firstline = 0; i = e->total_lines - e->start_line + 1; if (i > e->num_widget_lines) i = e->num_widget_lines; if (e->total_lines) scrollbar->numlines = (double) 65535.0 *i / (e->total_lines + 1); else scrollbar->numlines = 65535; if (start_line != e->start_line) { e->force |= REDRAW_PAGE | REDRAW_LINE; set_cursor_position (0, 0, 0, 0, 0, 0, 0, 0, 0, 0); if (CCheckWindowEvent (xevent->xany.window, ButtonReleaseMask | ButtonMotionMask, 0)) { CPopFont (); return; } } if (e->force) { edit_render_keypress (e); edit_status (e); } CPopFont ();}void link_hscrollbar_to_editor (CWidget * scrollbar, CWidget * editor, XEvent * xevent, CEvent * cwevent, int whichscrbutton){ int i, start_col; WEdit *e; e = editor->editor; if (!e) return; if (!e->widget->hori_scrollbar) return; CPushFont ("editor", 0); start_col = (-e->start_col); if ((xevent->type == ButtonRelease || xevent->type == MotionNotify) && whichscrbutton == 3) { e->start_col = (double) scrollbar->firstline * e->max_column / 65535.0 + 1; e->start_col -= e->start_col % FONT_MEAN_WIDTH; if (e->start_col < 0) e->start_col = 0; e->start_col = (-e->start_col); } else if (xevent->type == ButtonPress && (cwevent->button == Button1 || cwevent->button == Button2)) { switch (whichscrbutton) { case 1: edit_scroll_left (e, (e->num_widget_columns - 1) * FONT_MEAN_WIDTH); break; case 2: edit_scroll_left (e, FONT_MEAN_WIDTH); break; case 5: edit_scroll_right (e, FONT_MEAN_WIDTH); break; case 4: edit_scroll_right (e, (e->num_widget_columns - 1) * FONT_MEAN_WIDTH); break; } } scrollbar->firstline = (double) 65535.0 *(-e->start_col) / (e->max_column + 1); i = e->max_column - (-e->start_col) + 1; if (i > e->num_widget_columns * FONT_MEAN_WIDTH) i = e->num_widget_columns * FONT_MEAN_WIDTH; scrollbar->numlines = (double) 65535.0 *i / (e->max_column + 1); if (start_col != (-e->start_col)) { e->force |= REDRAW_PAGE | REDRAW_LINE; set_cursor_position (0, 0, 0, 0, 0, 0, 0, 0, 0, 0); if (CCheckWindowEvent (xevent->xany.window, ButtonReleaseMask | ButtonMotionMask, 0)) { CPopFont (); return; } } if (e->force) { edit_render_keypress (e); edit_status (e); } CPopFont ();}/* This section comes from rxvt-2.21b1/src/screen.c by Robert Nation <nation@rocket.sanders.lockheed.com> & mods by mj olesen <olesen@me.QueensU.CA> Changes made for cooledit */void selection_send (XSelectionRequestEvent * rq){ XEvent ev; static Atom xa_targets = None; if (xa_targets == None) xa_targets = XInternAtom (CDisplay, "TARGETS", False); ev.xselection.type = SelectionNotify; ev.xselection.property = None; ev.xselection.display = rq->display; ev.xselection.requestor = rq->requestor; ev.xselection.selection = rq->selection; ev.xselection.target = rq->target; ev.xselection.time = rq->time; if (rq->target == xa_targets) { /* * On some systems, the Atom typedef is 64 bits wide. * We need to have a typedef that is exactly 32 bits wide, * because a format of 64 is not allowed by the X11 protocol. * * XXX: yes, but Xlib requires that you pass it 64 bits for 32bit * quantities on 64 bit archs. */ /* typedef CARD32 Atom32; */ Atom target_list[2]; target_list[0] = xa_targets; target_list[1] = XA_STRING; XChangeProperty (CDisplay, rq->requestor, rq->property, xa_targets, 8 * sizeof (target_list[0]), PropModeReplace, (unsigned char *) target_list, sizeof (target_list) / sizeof (target_list[0])); ev.xselection.property = rq->property; } else if (rq->target == XA_STRING) { XChangeProperty (CDisplay, rq->requestor, rq->property, XA_STRING, 8, PropModeReplace, selection.text, selection.len); ev.xselection.property = rq->property; } XSendEvent (CDisplay, rq->requestor, False, 0, &ev);}/*{{{ paste selection *//* repeated in xdnd.c and rxvt */static int paste_prop_internal (void *data, void (*insert) (void *, int), Window win, unsigned long prop, int delete_prop){ long nread = 0; unsigned long nitems; unsigned long bytes_after; do { Atom actual_type; int actual_fmt, i; unsigned char *s = 0; if (XGetWindowProperty (CDisplay, win, prop, nread / 4, 65536, delete_prop, AnyPropertyType, &actual_type, &actual_fmt, &nitems, &bytes_after, &s) != Success) { XFree (s); return 1; } nread += nitems; for (i = 0; i < nitems; i++) (*insert) (data, s[i]); XFree (s); } while (bytes_after); if (!nread) return 1; return 0;}/* * Respond to a notification that a primary selection has been sent */void paste_prop (void *data, void (*insert) (void *, int), Window win, unsigned long prop, int delete_prop){ struct timeval tv, tv_start; long nread; unsigned long bytes_after; Atom actual_type; int actual_fmt; unsigned long nitems; unsigned char *s = 0; if (prop == None) return; nread = 0; if (XGetWindowProperty (CDisplay, win, prop, 0, 8, False, AnyPropertyType, &actual_type, &actual_fmt, &nitems, &bytes_after, &s) != Success) { XFree (s); return; } XFree (s); if (actual_type != XInternAtom (CDisplay, "INCR", False)) { paste_prop_internal (data, insert, win, prop, delete_prop); return; } XDeleteProperty (CDisplay, win, prop); gettimeofday (&tv_start, 0); for (;;) { long t; fd_set r; XEvent xe; if (XCheckMaskEvent (CDisplay, PropertyChangeMask, &xe)) { if (xe.type == PropertyNotify && xe.xproperty.state == PropertyNewValue) {/* time between arrivals of data */ gettimeofday (&tv_start, 0); if (paste_prop_internal (data, insert, win, prop, True)) break; } } else { tv.tv_sec = 0; tv.tv_usec = 10000; FD_ZERO (&r); FD_SET (ConnectionNumber (CDisplay), &r); select (ConnectionNumber (CDisplay) + 1, &r, 0, 0, &tv); if (FD_ISSET (ConnectionNumber (CDisplay), &r)) continue; } gettimeofday (&tv, 0); t = (tv.tv_sec - tv_start.tv_sec) * 1000000L + (tv.tv_usec - tv_start.tv_usec);/* no data for five seconds, so quit */ if (t > 5000000L) break; }}void selection_paste (WEdit * edit, Window win, unsigned prop, int delete_prop){ long c; c = edit->curs1; paste_prop ((void *) edit, (void (*)(void *, int)) edit_insert, win, prop, delete_prop); edit_cursor_move (edit, c - edit->curs1); edit->force |= REDRAW_COMPLETELY | REDRAW_LINE;}/*}}} */void (*user_selection_clear) (void) = 0;void selection_clear (void){ selection.text = 0; selection.len = 0; if (user_selection_clear) (*user_selection_clear) ();}void edit_update_screen (WEdit * e){ if (!e) return; if (!e->force) return; CPushFont ("editor", 0); edit_scroll_screen_over_cursor (e); edit_update_curs_row (e); edit_update_curs_col (e); update_scroll_bars (e); edit_status (e); if (e->force & REDRAW_COMPLETELY) e->force |= REDRAW_PAGE;/* pop all events for this window for internal handling */ if (e->force & (REDRAW_CHAR_ONLY | REDRAW_COMPLETELY)) { edit_render_keypress (e); } else if (CCheckWindowEvent (e->widget->winid, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, 0) || CKeyPending ()) { e->force |= REDRAW_PAGE; CPopFont (); return; } else { edit_render_keypress (e); } CPopFont ();}extern int space_width;#ifdef HAVE_DND#define free_data if (data) {free(data);data=0;}/* handles drag and drop */void handle_client_message (CWidget * w, XEvent * xevent){ int data_type; unsigned char *data = 0; unsigned long size; int xs, ys; long start_line; int x, y, r, deleted = 0; long click; unsigned int state; long start_mark = 0, end_mark = 0; WEdit *e = w->editor;/* see just below for a comment on what this is for: */ if (CIsDropAcknowledge (xevent, &state) != DndNotDnd) { if (!(state & Button1Mask) && just_dropped_something) { edit_push_action (e, KEY_PRESS + e->start_display); edit_block_delete_cmd (e); } return; } data_type = CGetDrop (xevent, &data, &size, &xs, &ys); if (data_type == DndNotDnd || xs < 0 || ys < 0 || xs >= CWidthOf (w) || ys >= CHeightOf (w)) { free_data; return; } edit_translate_xy (xs, ys, &x, &y); click = edit_get_click_pos (e, x, y); r = eval_marks (e, &start_mark, &end_mark);/* musn't be able to drop into a block, otherwise a single click will copy a block: */ if (r) goto fine; if (start_mark > click || click >= end_mark) goto fine; if (column_highlighting) { if (!((x >= e->column1 && x < e->column2)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -