📄 htapp.cc
字号:
* CLASS ht_log */ht_log::ht_log() : Array(true){ maxlinecount = 128;}void ht_log::deletefirstline(){ del(0);}void ht_log::insertline(LogColor color, char *line){ if (count() >= maxlinecount) deletefirstline(); vcp c; switch (color) { case LOG_NORMAL: c = VCP(VC_WHITE, VC_TRANSPARENT); break; case LOG_WARN: c = VCP(VC_LIGHT(VC_YELLOW), VC_TRANSPARENT); break; case LOG_ERROR: c = VCP(VC_LIGHT(VC_RED), VC_TRANSPARENT); break; default: c = VCP(VC_WHITE, VC_TRANSPARENT); break; } insert(new ht_log_msg(c, line));}void ht_log::log(LogColor c, char *line){ insertline(c, line);}/* * CLASS ht_logviewer */void ht_logviewer::init(Bounds *b, ht_window *w, ht_log *l, bool ol){ ht_viewer::init(b, "log", 0); VIEW_DEBUG_NAME("ht_logviewer"); ofs = 0; xofs = 0; window = w; lines = l; own_lines = ol; update();}void ht_logviewer::done(){ if (own_lines) { delete lines; } ht_viewer::done();}int ht_logviewer::cursor_up(int n){ ofs -= n; if (ofs < 0) ofs = 0; return n;}int ht_logviewer::cursor_down(int n){ int c = lines->count(); if (c >= size.h) { ofs += n; if (ofs > c-size.h) ofs = c-size.h; } return n;}void ht_logviewer::draw(){ clear(getcolor(palidx_generic_body)); int c = lines->count(); for (int i=0; i < size.h; i++) { if (i+ofs >= c) break; ht_log_msg *msg = (ht_log_msg*)(*lines)[i+ofs]; int l = strlen(msg->msg); if (xofs < l) buf->print(0, i, /*getcolor(palidx_generic_body)*/msg->color, msg->msg+xofs); }}bool ht_logviewer::get_vscrollbar_pos(int *pstart, int *psize){ return scrollbar_pos(ofs, size.h, lines->count(), pstart, psize);}void ht_logviewer::handlemsg(htmsg *msg){ switch (msg->msg) { case msg_get_scrollinfo: switch (msg->data1.integer) { case gsi_vscrollbar: { gsi_scrollbar_t *p=(gsi_scrollbar_t*)msg->data2.ptr; if (!get_vscrollbar_pos(&p->pstart, &p->psize)) { p->pstart = 0; p->psize = 100; } clearmsg(msg); return; } } break; case msg_log_changed: { ofs = lines->count()-size.h; if (ofs < 0) ofs = 0; update(); clearmsg(msg); return; } case msg_keypressed: switch (msg->data1.integer) { case K_Up: cursor_up(1); update(); clearmsg(msg); return; case K_Down: cursor_down(1); update(); clearmsg(msg); return; case K_PageUp: cursor_up(size.h); update(); clearmsg(msg); return; case K_PageDown: cursor_down(size.h); update(); clearmsg(msg); return; case K_Right: case K_Control_Right: xofs += 2; update(); clearmsg(msg); return; case K_Left: case K_Control_Left: if (xofs-2 >= 0) xofs -= 2; update(); clearmsg(msg); return; case K_Control_PageUp: ofs = 0; update(); clearmsg(msg); return; case K_Control_PageDown: ofs = lines->count()-size.h; if (ofs < 0) ofs = 0; update(); clearmsg(msg); return; } break; } ht_viewer::handlemsg(msg);}void ht_logviewer::update(){ dirtyview();}/* * CLASS ht_app_window_entry */ht_app_window_entry::ht_app_window_entry(ht_window *w, uint n, uint t, bool m, bool isf, FileLayer *l){ window = w; number = n; type = t; minimized = m; isfile = isf; layer = l;}int ht_app_window_entry::compareTo(const Object *obj) const{ uint a = number; uint b = ((ht_app_window_entry*)obj)->number; if (a > b) return 1; else if (a < b) return -1; return 0;}/* * CLASS ht_app */static bool doFileChecks(File *file){// FIXME: this is notify-user-only. should actually also take the actions it claims to...// (its done in stream.cc in ht_file::set_access_mode_internal() pstat_t s; file->pstat(s); if (s.caps & pstat_mode_type) { switch (s.mode & HT_S_IFMT) { case HT_S_IFREG: return true; default: LOG_EX(LOG_WARN, "file is not regular (but device, fifo or something...)."); LOG_EX(LOG_WARN, "Write-access disabled for safety!"); return true; } } else { LOG_EX(LOG_WARN, "can't determine file type (regular, device, directory...)! assuming non-regular..."); LOG_EX(LOG_WARN, "file is not regular (but device, fifo or something...)."); LOG_EX(LOG_WARN, "Write-access disabled for safety!"); return true; } return false;}/*debug*///#define DRAW_TIMINGS//#define NO_AVG#define AVG_TIMINGS 10int timings[AVG_TIMINGS];int cur_timing=0, max_timing=0;int h0;/**/void ht_app::init(Bounds *pq){ ht_dialog::init(pq, 0, 0); menu = NULL; setframe(NULL); options |= VO_RESIZE; VIEW_DEBUG_NAME("ht_app"); exit_program = false; focused = true; Bounds b; windows = new AVLTree(true); syntax_lexers = new Array(true); ht_c_syntax_lexer *c_lexer = new ht_c_syntax_lexer(); c_lexer->init(); syntax_lexers->insert(c_lexer); ht_html_syntax_lexer *html_lexer = new ht_html_syntax_lexer(); html_lexer->init(); syntax_lexers->insert(html_lexer); /* init timer */ h0=new_timer(); /* create menu */ getbounds(&b); b.x=0; b.y=0; b.h=1; ht_menu *m=new ht_menu(); m->init(&b); ht_static_context_menu *file=new ht_static_context_menu(); file->init("~File"); file->insert_entry("~New...", NULL, cmd_file_new, 0, 1); file->insert_entry("~Open...", "F3", cmd_file_open, 0, 1); file->insert_entry("~Save", NULL, cmd_file_save, 0, 1); file->insert_entry("Save ~As...", NULL, cmd_file_saveas, 0, 1); file->insert_separator(); file->insert_entry("Open/Create ~project...", NULL, cmd_project_open, 0, 1); file->insert_entry("Close p~roject", NULL, cmd_project_close, 0, 1); file->insert_separator();// file->insert_entry("~Execute", "Alt+Z", cmd_file_exec_cmd, K_Meta_Z, 1); file->insert_entry("~Quit", "F10", cmd_quit, 0, 1); m->insert_menu(file); ht_static_context_menu *edit=new ht_static_context_menu(); edit->init("~Edit"); edit->insert_entry("Cu~t", "Shift+Del", cmd_edit_cut, 0, 1); edit->insert_entry("~Delete", "Ctrl+Del", cmd_edit_delete, 0, 1); edit->insert_entry("~Copy", "Ctrl+Ins", cmd_edit_copy, 0, 1); edit->insert_entry("~Paste", "Shift+Ins", cmd_edit_paste, 0, 1); edit->insert_entry("~Show clipboard", 0, cmd_edit_show_clipboard, 0, 1); edit->insert_entry("C~lear clipboard", 0, cmd_edit_clear_clipboard, 0, 1); edit->insert_separator(); edit->insert_entry("Copy ~from file...", 0, cmd_edit_copy_from_file, 0, 1); edit->insert_entry("Paste ~into file...", 0, cmd_edit_paste_into_file, 0, 1); if (sys_get_caps() & SYSCAP_NATIVE_CLIPBOARD) { char s[100]; edit->insert_separator(); ht_snprintf(s, sizeof s, "Copy from %s", sys_native_clipboard_name()); edit->insert_entry(s, 0, cmd_edit_copy_native, 0, 1); ht_snprintf(s, sizeof s, "Paste into %s", sys_native_clipboard_name()); edit->insert_entry(s, 0, cmd_edit_paste_native, 0, 1); } edit->insert_separator(); edit->insert_entry("~Evaluate...", 0, cmd_popup_dialog_eval, 0, 1); m->insert_menu(edit); ht_static_context_menu *windows=new ht_static_context_menu(); windows->init("~Windows"); windows->insert_entry("~Size/Move", "Alt+F5", cmd_window_resizemove, K_Meta_F5, 1); windows->insert_entry("~Close", "Alt+F3", cmd_window_close, K_Meta_F3, 1); windows->insert_entry("~Close (alt)", "Ctrl+W", cmd_window_close, K_Control_W, 1); windows->insert_entry("~List", "Alt+0", cmd_popup_dialog_window_list, K_Meta_0, 1); ht_static_context_menu *tile=new ht_static_context_menu(); tile->init("~Tile"); tile->insert_entry("~Vertically", NULL, cmd_window_tile_vertical, 0, 1); tile->insert_entry("~Horizontally", NULL, cmd_window_tile_horizontal, 0, 1); windows->insert_submenu(tile); windows->insert_separator(); windows->insert_entry("Lo~g window", NULL, cmd_popup_window_log, 0, 1); windows->insert_entry("~Options", NULL, cmd_popup_window_options, 0, 1); windows->insert_entry("~Project", NULL, cmd_popup_window_project, 0, 1); m->insert_menu(windows); ht_static_context_menu *help=new ht_static_context_menu(); help->init("~Help"); help->insert_entry("~About "ht_name, "", cmd_about, 0, 1); help->insert_separator(); help->insert_entry("~Help contents", "F1", cmd_popup_window_help, 0, 1); help->insert_entry("~Open info file...", NULL, cmd_popup_dialog_info_loader, 0, 1); m->insert_menu(help); m->insert_local_menu(); menu = m; insert(menu); /* create status */ /* the status should have the same Bounds as the menu */ ht_status *status = new ht_status(); status->init(&b); status->setpalette(menu->getpalette()); insert(status); /* create desktop */ getbounds(&b); b.x = 0; b.y = 1; b.h -= 2; desktop = new ht_desktop(); desktop->init(&b); insert(desktop); /* create keyline */ getbounds(&b); b.x = 0; b.y = b.h-1; b.h = 1; keyline = new ht_keyline(); keyline->init(&b); insert(keyline); /* create battlefield */ getbounds(&b); b.x = 0; b.y = 1; b.h -= 2; battlefield = new ht_group(); battlefield->init(&b, VO_TRANSPARENT_CHARS | VO_RESIZE, "battlefield"); battlefield->growmode = MK_GM(GMH_FIT, GMV_FIT); insert(battlefield); create_window_log();}void ht_app::done(){ delete_timer(h0); delete syntax_lexers; delete windows; ht_dialog::done();}bool ht_app::accept_close_all_windows(){ foreach(ht_app_window_entry, e, *windows, { htmsg m; m.msg = msg_accept_close; m.type = mt_empty; e->window->sendmsg(&m); if (m.msg != msg_accept_close) return false; }); return true;}ht_window *ht_app::create_window_log(){ ht_window *w = get_window_by_type(AWT_LOG); if (w) { focus(w); } else { Bounds b;/* battlefield->getbounds(&b); b.x = 0; b.y = 0;*/ get_stdbounds_file(&b); ht_window *logwindow=new ht_window(); logwindow->init(&b, "log window", FS_KILLER | FS_TITLE | FS_NUMBER | FS_MOVE | FS_RESIZE, 0); Bounds k=b; k.x=b.w-2; k.y=0; k.w=1; k.h-=2; ht_scrollbar *hs=new ht_scrollbar(); hs->init(&k, &logwindow->pal, true); logwindow->setvscrollbar(hs); b.x=0; b.y=0; b.w-=2; b.h-=2; ht_logviewer *logviewer=new ht_logviewer(); logviewer->init(&b, logwindow, loglines, false); logwindow->insert(logviewer); insert_window(logwindow, AWT_LOG, 0, false, NULL); } return w;}ht_window *ht_app::create_window_term(const char *cmd){ ht_window *w = get_window_by_type(AWT_TERM); if (w) { focus(w); } else { Bounds b; get_stdbounds_file(&b); ht_window *termwindow=new ht_window(); termwindow->init(&b, "terminal", FS_KILLER | FS_TITLE | FS_NUMBER | FS_MOVE | FS_RESIZE, 0); Bounds k=b; k.x=3; k.y=k.h-2; k.w-=7; k.h=1; ht_statictext *ind=new ht_statictext(); ind->init(&k, NULL, align_left, false, true); ind->disable_buffering(); ind->growmode = MK_GM(GMH_FIT, GMV_BOTTOM); termwindow->setpindicator(ind); k=b; k.x=b.w-2; k.y=0; k.w=1; k.h-=2; ht_scrollbar *hs=new ht_scrollbar(); hs->init(&k, &termwindow->pal, true); termwindow->setvscrollbar(hs);/*FIXPORT File *in, *out, *err; int handle; int e; if ((e = sys_ipc_exec(&in, &out, &err, &handle, cmd, 0)) == 0) { Terminal *terminal = new Terminal(); terminal->init(in, out, err, handle); b.x=0; b.y=0; b.w-=2; b.h-=2; TerminalViewer *termviewer=new TerminalViewer(); termviewer->init(&b, terminal, true); termwindow->insert(termviewer); insert_window(termwindow, AWT_LOG, 0, false, NULL); } else { errorbox("couldn't create child-process (%d)", e); return NULL; }*/ } return w;}ht_window *ht_app::create_window_clipboard(){ ht_window *w = get_window_by_type(AWT_CLIPBOARD); if (w) { focus(w); return w; } else { Bounds b; get_stdbounds_file(&b);/* ht_file_window *window=new ht_file_window(); window->init(&b, "clipboard", FS_KILLER | FS_TITLE | FS_NUMBER | FS_MOVE | FS_RESIZE, 0, clipboard);*/ ht_window *window = new ht_window(); window->init(&b, "clipboard", FS_KILLER | FS_TITLE | FS_NUMBER | FS_MOVE | FS_RESIZE, 0); /* Bounds k=b; k.x=b.w-2; k.y=0; k.w=1; k.h-=2; ht_scrollbar *hs=new ht_scrollbar(); hs->init(&k, &window->pal, true); window->setvscrollbar(hs);*/ Bounds k; k = b; k.x=3; k.y=k.h-2; k.w-=7; k.h=1; ht_statictext *ind = new ht_statictext(); ind->init(&k, NULL, align_left, false, true); ind->disable_buffering(); ind->growmode = MK_GM(GMH_FIT, GMV_BOTTOM); window->setpindicator(ind); b.x=0; b.y=0; b.w-=2; b.h-=2; ht_clipboard_viewer *v = new ht_clipboard_viewer(); v->init(&b, "clipboard", VC_EDIT | VC_GOTO | VC_SEARCH, clipboard, 0); window->insert(v); // FIXME: needs wrapper (layer) //insert_window(window, AWT_CLIPBOARD, 0, false, clipboard); insert_window(window, AWT_CLIPBOARD, 0, false, NULL); } return NULL;}ht_window *ht_app::create_window_file(const char *filename, uint mode, bool allow_duplicates){ if (mode == FOM_AUTO) mode = autodetect_file_open_mode(filename); switch (mode) { case FOM_BIN: return create_window_file_bin(filename, allow_duplicates); case FOM_TEXT: return create_window_file_text(filename, allow_duplicates); } return NULL;}ht_window *ht_app::create_window_file_bin(const char *filename, bool allow_duplicates){ Bounds b; get_stdbounds_file(&b); int e; char *fullfilename; if ((e = sys_canonicalize(&fullfilename, filename))) { LOG_EX(LOG_ERROR, "error loading file %s: %s", filename, strerror(e)); return NULL; } String f(fullfilename); free(fullfilename); ht_window *w; if (!allow_duplicates && ((w = get_window_by_filename(f.contentChar())))) { focus(w); return w; } File *emfile = NULL; FileModificator *mfile = NULL; FileLayer *file = NULL; try { emfile = new LocalFile(f, IOAM_READ, FOM_EXISTS); if (!doFileChecks(emfile)) { delete emfile; return NULL; } mfile = new FileModificator(emfile, true); file = new FileLayer(mfile, true); } catch (const IOException &e) { LOG_EX(LOG_ERROR, "error loading file %y: %y", &f, &e); if (file) delete file; else if (mfile) delete mfile; else delete emfile; return NULL; } LOG("loading binary file %y...", &f); return create_window_file_bin(&b, file, f.contentChar(), true);}ht_window *ht_app::create_window_file_bin(Bounds *b, FileLayer *file, const char *title, bool isfile){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -