From 36735bb1906d1084715d21dee2ced0fdd4f9f4f0 Mon Sep 17 00:00:00 2001 From: "Kirill Lipatov (Leency)" Date: Sat, 6 Feb 2021 17:26:52 +0000 Subject: [PATCH] Quark: edit text, ability to make font bigger git-svn-id: svn://kolibrios.org@8584 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/cmm/quark/data.h | 32 ++- programs/cmm/quark/prepare_page.h | 64 +++-- programs/cmm/quark/quark.c | 416 ++++++++++++++++-------------- programs/cmm/quark/search.h | 62 ++--- programs/cmm/quark/textbuf.h | 58 +++++ 5 files changed, 374 insertions(+), 258 deletions(-) create mode 100644 programs/cmm/quark/textbuf.h diff --git a/programs/cmm/quark/data.h b/programs/cmm/quark/data.h index a8ee45753c..5ffc88e87e 100644 --- a/programs/cmm/quark/data.h +++ b/programs/cmm/quark/data.h @@ -8,12 +8,13 @@ char short_app_name[] = "Quark"; #ifdef LANG_RUS -char intro[] = "Это простой просмотрщик текста. +char intro[] = "Это простой просмотрщик и редактор текста. Попробуйте открыть текстовый файл."; -char copied_chars[] = "Скопировано сиволов: %i"; +char copied_chars[] = "%i символов скопировано"; +char chars_selected[] = "%i символов выделено"; -char about[] = "Quark Text v0.9 +char about[] = "Quark Text v0.95 Автор: Кирилл Липатов aka Leency Сайт: http://aspero.pro @@ -34,7 +35,7 @@ char color_scheme_names[] = " ?define FILE_SAVED_WELL "'Файл успешно сохранен'O" ?define FILE_NOT_SAVED "'Ошибка при сохранении файла!'E" -char rmb_menu[] = +char rmb_menu[] = "Вырезать|Ctrl+X Копировать|Ctrl+C Вставить|Ctrl+V @@ -47,13 +48,14 @@ char rmb_menu[] = #else -char intro[] = "Quark is a simple text viewer. +char intro[] = "Quark is a simple text viewer and editor. Try to open some text file."; -char copied_chars[] = "Copied %i chars"; +char copied_chars[] = "%i characters copied"; +char chars_selected[] = "%i characters selected"; -char about[] = "Quark Text v0.91 -Author: Kiril Lipatov aka Leency +char about[] = "Quark Text v0.95 +Author: Kiril Lipatov aka Leency Website: http://aspero.pro Hotkeys: @@ -73,7 +75,7 @@ char color_scheme_names[] = "Dairy\nCosmos "; ?define FILE_SAVED_WELL "'File saved'O" ?define FILE_NOT_SAVED "'Error saving file!'E" -char rmb_menu[] = +char rmb_menu[] = "Cut|Ctrl+X Copy|Ctrl+C Paste|Ctrl+V @@ -104,7 +106,7 @@ struct THEME } theme; char default_dir[] = "/rd/1"; -od_filter filter2 = { 33, "TXT\0ASM\0HTM\0HTML\0C\0H\0C--\0H--\0CPP\0\0" }; +od_filter filter2 = { 37, "TXT\0INI\0ASM\0HTM\0HTML\0C\0H\0C--\0H--\0CPP\0\0" }; CANVAS canvas; @@ -112,6 +114,8 @@ dword cursor_pos=0; collection_int lines = {0}; +#define file_path param + //===================================================// // // // SETTINGS // @@ -123,12 +127,12 @@ _ini ini = { "/sys/settings/app.ini", "Quark" }; void LoadIniSettings() { - font_size = ini.GetInt("FontSize", 'M'); + font_size = ini.GetInt("FontSize", 1); user_encoding = ini.GetInt("Encoding", CH_AUTO); curcol_scheme = ini.GetInt("ColorScheme", 0); - Form.left = ini.GetInt("WinX", 150); - Form.top = ini.GetInt("WinY", 50); - Form.width = ini.GetInt("WinW", 640); + Form.left = ini.GetInt("WinX", 150); + Form.top = ini.GetInt("WinY", 50); + Form.width = ini.GetInt("WinW", 640); Form.height = ini.GetInt("WinH", 563); } diff --git a/programs/cmm/quark/prepare_page.h b/programs/cmm/quark/prepare_page.h index 54ebe7c777..b8886c4ba0 100644 --- a/programs/cmm/quark/prepare_page.h +++ b/programs/cmm/quark/prepare_page.h @@ -1,45 +1,73 @@ void ParseAndPaint() { - list.count=0; - selection.cancel(); - if (list.w != canvas.bufw) canvas.Init(list.x, list.y, list.w, screen.height); Parse(); - DrawPage(); + DrawPage(); } void Parse() { -dword off; +dword ptr; int line_end; -dword line_length=0; -dword line_start = io.buffer_data; -dword buflen = strlen(io.buffer_data) + io.buffer_data; +dword line_length = 0; +dword line_start = textbuf.p; + + list.count=0; + selection.cancel(); + if (list.w != canvas.bufw) canvas.Init(list.x, list.y, list.w, screen.height); lines.drop(); - lines.add(io.buffer_data); + lines.add(textbuf.p); - for (off = io.buffer_data; off < buflen; off++) + for (ptr = textbuf.p; ptr < textbuf.p + textbuf.len; ptr++) { line_length += list.font_w; - if (line_length + 30 >= list.w) || (ESBYTE[off] == 10) + if (line_length + 30 >= list.w) || (ESBYTE[ptr] == '\n') { + //if (ESBYTE[ptr+1] == '\r') ptr++; + //searching a 'white' for a normal word-break - for(line_end = off; line_end != line_start; line_end--) + for(line_end = ptr; line_end != line_start; line_end--) { - if (__isWhite(ESBYTE[line_end])) { off=line_end+1; break; } + if (__isWhite(ESBYTE[line_end])) { ptr=line_end+1; break; } } - line_length = off - line_start * list.font_w; + line_length = ptr - line_start * list.font_w; list.count++; - lines.add(off); - line_start = off; + lines.add(ptr); + line_start = ptr; line_length = 0; } } - lines.add(buflen); + lines.add(ptr); list.count++; } +void DrawPage() +{ + char t[64]; + scroll.max_area = list.count; + scroll.cur_area = list.visible; + scroll.position = list.first; + scroll.all_redraw = 0; + scroll.start_x = list.x + list.w; + scroll.start_y = list.y; + scroll.size_y = list.h; + + if (list.count <= list.visible) { + DrawBar(scroll.start_x, scroll.start_y, scroll.size_x, + scroll.size_y, theme.bg); + } else { + scrollbar_v_draw(#scroll); + } + DrawRectangle(scroll.start_x, scroll.start_y, scroll.size_x, + scroll.size_y-1, scroll.bckg_col); + + PaintVisible(); + + sprintf(#t, #chars_selected, math.abs(selection.end_offset - selection.start_offset)); + if (selection.is_active()) DrawStatusBar(#t); else DrawStatusBar(" "); +} + void PaintVisible() { int i, ff; @@ -78,7 +106,7 @@ void PaintVisible() } } - if (absolute_y= list.column_max) return; - - ESBYTE[cursor_pos] = key_ascii; - list.KeyRight(); - PaintVisible(); } void EventOpenSysfuncs() { - if (io.run("/sys/docpack", "f") <= 0) { + if (RunProgram("/sys/docpack", "f") <= 0) { notify("'Can not open SysFunctions because\n/rd/1/docpack is not found!'E"); } } void EventOpenPipet() { - io.run("/sys/develop/pipet", NULL); + RunProgram("/sys/develop/pipet", NULL); } void EventRbmMenuClick(dword id) @@ -527,9 +527,10 @@ void EventRbmMenuClick(dword id) } } -void EventCut() +void EventSelectAllText() { - //selection.copy(); + selection.select_all(); + DrawPage(); } void EventCopy() @@ -560,31 +561,51 @@ void EventCopy() DrawStatusBar(#copy_status_text); } +void EventCut() +{ + if (!selection.is_active()) { + selection.start_offset = lines.get(list.cur_y); + selection.end_offset = lines.get(list.cur_y+1); + } + EventCopy(); + EventDeleteSelectedText(); + ParseAndPaint(); +} + void EventPaste() { - //selection.copy(); + int i; + dword buf = Clipboard__GetSlotData(Clipboard__GetSlotCount()-1); + if (selection.is_active()) { + EventDeleteSelectedText(); + } + cursor_pos = lines.get(list.cur_y) + list.cur_x; + textbuf.insert_str(cursor_pos, buf+12, ESDWORD[buf]-12); + for (i=0; i5) - || (strstr(io.buffer_data, "\239\240")) real_encoding = CH_CP1251; + if (chrnum(textbuf.p, '\246')>5) + || (strstr(textbuf.p, "\239\240")) real_encoding = CH_CP1251; } } if (real_encoding != CH_CP866) { - ChangeCharset(real_encoding, "CP866", io.buffer_data); + ChangeCharset(real_encoding, "CP866", textbuf.p); } } -void LoadFile(dword f_path) +void LoadFile(dword f_path) { - if (io.buffer_data) free(io.buffer_data); if (ESBYTE[f_path]) { - strcpy(#param, f_path); - if (!io.read(#param)) goto NO_DATA; - sprintf(#title, "%s - %s", #param, #short_app_name); - EncodeToDos(); + strcpy(#file_path, f_path); + if (!io.read(#file_path)) goto NO_DATA; + textbuf.set(io.buffer_data, io.FILES_SIZE); + free(io.buffer_data); + sprintf(#title, "%s - %s", #file_path, #short_app_name); + EncodeToDos(); } else { NO_DATA: - io.buffer_data = malloc(sizeof(intro)); - strcpy(io.buffer_data, #intro); - strcpy(#title, #short_app_name); + textbuf.set(#intro, sizeof(intro)-1); + strcpy(#title, #short_app_name); } list.ClearList(); } -int AddTopBarButton(dword _event, _hotkey, char image_id, int x, pressed) { +int TopBarBt(dword _event, _hotkey, char image_id, int x, pressed) { if (_hotkey) key.add_n(_hotkey, _event); return DrawTopPanelButton(button.add(_event), x, 5, image_id, pressed); } @@ -635,34 +656,32 @@ int AddTopBarButton(dword _event, _hotkey, char image_id, int x, pressed) { void DrawToolbar() { - #define SMALL_GAP 26+5 - #define BIG_GAP 26+18 + #define GAP_S 26+5 + #define GAP_B 26+18 incn x; bool thema = false; bool reopa = false; - bool serha = search.draw(BTN_FIND_NEXT+10, BTN_FIND_CLOSE+10, Form.cheight - SEARCH_H - STATUSBAR_H); if (menu_id == COLOR_SCHEME) thema = true; if (menu_id == REOPEN_IN_APP) reopa = true; DrawBar(0, 0, Form.cwidth, TOOLBAR_H - 1, sc.work); DrawBar(0, TOOLBAR_H - 1, Form.cwidth, 1, sc.work_graph); - - x.set(-SMALL_GAP+8); - if(enable_edit) AddTopBarButton(#EventNewFile, ECTRL+SCAN_CODE_KEY_N, 2, x.inc(SMALL_GAP), false); - AddTopBarButton(#EventOpenDialog, ECTRL+SCAN_CODE_KEY_O, 0, x.inc(SMALL_GAP), false); - if(enable_edit) && (param[0]) AddTopBarButton(#EventSave, ECTRL+SCAN_CODE_KEY_S, 5, x.inc(SMALL_GAP), false); - AddTopBarButton(#EventShowFileInfo, ECTRL+SCAN_CODE_KEY_I, 10, x.inc(SMALL_GAP), false); - AddTopBarButton(#EventMagnifyMinus, ECTRL+SCAN_CODE_MINUS, 33, x.inc(BIG_GAP), false); - AddTopBarButton(#EventMagnifyPlus, ECTRL+SCAN_CODE_PLUS, 32, x.inc(SMALL_GAP), false); - AddTopBarButton(#EventClickSearch, ECTRL+SCAN_CODE_KEY_F, 49, x.inc(BIG_GAP), serha); search_mx = EAX; + + x.set(-GAP_S+8); + TopBarBt(#EventNewFile, ECTRL+SCAN_CODE_KEY_N, 2, x.inc(GAP_S), false); + TopBarBt(#EventOpenDialog, ECTRL+SCAN_CODE_KEY_O, 0, x.inc(GAP_S), false); + TopBarBt(#EventSave, ECTRL+SCAN_CODE_KEY_S, 5, x.inc(GAP_S), false); + TopBarBt(#EventShowFileInfo, ECTRL+SCAN_CODE_KEY_I, 10, x.inc(GAP_S), false); + TopBarBt(#EventMagnifyMinus, ECTRL+SCAN_CODE_MINUS, 33, x.inc(GAP_B), false); + TopBarBt(#EventMagnifyPlus, ECTRL+SCAN_CODE_PLUS, 32, x.inc(GAP_S), false); + TopBarBt(#EventClickSearch, ECTRL+SCAN_CODE_KEY_F, 49, x.inc(GAP_B), search.visible); search_mx = EAX; x.set(Form.cwidth-4); - AddTopBarButton(#EventEnableEdit, NULL, 38, x.inc(-SMALL_GAP), enable_edit); - //if(enable_edit) AddTopBarButton(#EventShowInfo, NULL, -1, x.inc(-SMALL_GAP), false); burger_mx = EAX; - AddTopBarButton(#EventShowThemesList, NULL, 40, x.inc(-BIG_GAP), thema); theme_mx = EAX; - AddTopBarButton(#EventShowReopenMenu, ECTRL+SCAN_CODE_KEY_E, 16, x.inc(-SMALL_GAP), reopa); reopenin_mx = EAX; - if(enable_edit) AddTopBarButton(#EventOpenSysfuncs, NULL, 18, x.inc(-SMALL_GAP), false); - if(enable_edit) AddTopBarButton(#EventOpenPipet, NULL, 39, x.inc(-SMALL_GAP), false); + TopBarBt(#EventShowInfo, NULL, -1, x.inc(-GAP_S), false); burger_mx = EAX; + TopBarBt(#EventShowThemesList, NULL, 40, x.inc(-GAP_B), thema); theme_mx = EAX; + TopBarBt(#EventShowReopenMenu, ECTRL+SCAN_CODE_KEY_E, 16, x.inc(-GAP_S), reopa); reopenin_mx = EAX; + TopBarBt(#EventOpenSysfuncs, NULL, 18, x.inc(-GAP_S), false); + TopBarBt(#EventOpenPipet, NULL, 39, x.inc(-GAP_S), false); } void DrawStatusBar(dword _in_text) @@ -673,7 +692,7 @@ void DrawStatusBar(dword _in_text) DrawBar(0,Form.cheight - STATUSBAR_H, Form.cwidth,1, sc.work_graph); DrawBar(0,Form.cheight - STATUSBAR_H+1, Form.cwidth,STATUSBAR_H-1, sc.work); WriteText(5, Form.cheight - STATUSBAR_H + 4, 0x80, sc.work_text, #status_text); - if (param[0]) { + if (file_path[0]) { WriteTextCenter(Form.cwidth-70, Form.cheight - STATUSBAR_H + 4, 60, sc.work_text, real_encoding*10+#charsets); DefineHiddenButton(Form.cwidth-70, Form.cheight - STATUSBAR_H + 1, @@ -684,53 +703,70 @@ void DrawStatusBar(dword _in_text) void draw_window() { int old_w = list.w; + if (CheckActiveProcess(Form.ID)) EventMenuClick(); DefineAndDrawWindow(Form.left,Form.top,Form.width,Form.height,0x73,0,#title,0); GetProcessInfo(#Form, SelfInfo); sc.get(); if (Form.status_window>2) return; if (Form.width < 450) { MoveSize(OLD,OLD,450,OLD); return; } if (Form.height < 200) { MoveSize(OLD,OLD,OLD,200); return; } - + button.init(40); key.init(40); - SetSizes(font_size); + SetFontSize(font_size); if ((list.w == old_w) && (list.count)) { - DrawPage(); + DrawPage(); } else { ParseAndPaint(); } DrawToolbar(); + DrawSearch(); DrawStatusBar(NULL); } -void DrawPage() +bool DrawSearch() { - scroll.max_area = list.count; - scroll.cur_area = list.visible; - scroll.position = list.first; - scroll.all_redraw = 0; - scroll.start_x = list.x + list.w; - scroll.start_y = list.y; - scroll.size_y = list.h; - scrollbar_v_draw(#scroll); + char matches[30]; + int _y = Form.cheight - SEARCH_H - STATUSBAR_H; + if (!search.visible) return false; + DrawBar(0, _y, Form.cwidth, 1, sc.work_graph); + DrawBar(0, _y+1, Form.cwidth, SEARCH_H-1, sc.work); - DrawRectangle(scroll.start_x, scroll.start_y, scroll.size_x, - scroll.size_y-1, scroll.bckg_col); - PaintVisible(); + search_box.top = _y + 6; + search_box.width = math.min(Form.width - 200, 150); + + DrawRectangle(search_box.left-1, search_box.top-1, search_box.width+2, 23,sc.work_graph); + + edit_box_draw stdcall(#search_box); + + DrawCaptButton(search_box.left+search_box.width+14, search_box.top-1, 30, + TOOLBAR_ICON_HEIGHT+1, BTN_FIND_PREVIOUS+10, sc.work_light, sc.work_text, "<"); + DrawCaptButton(search_box.left+search_box.width+44, search_box.top-1, 30, + TOOLBAR_ICON_HEIGHT+1, BTN_FIND_NEXT+10, sc.work_light, sc.work_text, ">"); + + sprintf(#matches, T_MATCHES, search.found.count); + WriteTextWithBg(search_box.left+search_box.width+14+85, + search_box.top+3, 0xD0, sc.work_text, #matches, sc.work); + + DefineHiddenButton(Form.cwidth-26, search_box.top-1, TOOLBAR_ICON_HEIGHT+1, + TOOLBAR_ICON_HEIGHT+1, BTN_FIND_CLOSE+10); + WriteText(Form.cwidth-26+7, search_box.top+2, 0x81, sc.work_graph, "x"); + return true; } - -void SetSizes(char _size) +void SetFontSize(char _size) { font_size = _size; - if (font_size == 'S') list.SetFont(6, 9, 00001000b); - if (font_size == 'M') list.SetFont(8, 14, 00011000b); + if (font_size == 0) list.SetFont( 6, 9, 00001000b); + if (font_size == 1) list.SetFont( 8, 14, 00011000b); + if (font_size == 2) list.SetFont(2*6, 2*9, 00001001b); + if (font_size == 3) list.SetFont(2*8, 2*14-2, 00011001b); list.item_w = list.font_w; list.horisontal_selelection = true; - list.SetSizes(0, TOOLBAR_H, Form.cwidth-scroll.size_x-1, - Form.cheight - TOOLBAR_H - calc(search.visible * SEARCH_H) - STATUSBAR_H /*- TAB_H*/, + list.SetSizes(0, TOOLBAR_H, Form.cwidth-scroll.size_x-1, + Form.cheight - TOOLBAR_H - calc(search.visible * SEARCH_H) - STATUSBAR_H /*- TAB_H*/, math.round(list.font_h * 1.4)); } \ No newline at end of file diff --git a/programs/cmm/quark/search.h b/programs/cmm/quark/search.h index b32bc066b8..698075f2b2 100644 --- a/programs/cmm/quark/search.h +++ b/programs/cmm/quark/search.h @@ -9,11 +9,11 @@ struct SEARCH collection_int found; void show(); void hide(); - bool draw(); bool edit_key(); bool edit_mouse(); int find_all(); int find_next(); + int find_prior(); } search; char found_text[64]; @@ -39,7 +39,7 @@ void SEARCH::hide() bool SEARCH::edit_key() { if (visible) && (search_box.flags & ed_focus) { - EAX = key_editbox; + EAX = key_editbox; edit_box_key stdcall(#search_box); return true; } @@ -55,36 +55,9 @@ bool SEARCH::edit_mouse() return false; } -bool SEARCH::draw(dword _btn_find, _btn_hide, _y) -{ - char matches[30]; - if (!visible) return false; - DrawBar(0, _y, Form.cwidth, 1, sc.work_graph); - DrawBar(0, _y+1, Form.cwidth, SEARCH_H-1, sc.work); - - search_box.top = _y + 6; - search_box.width = math.min(Form.width - 200, 150); - - DrawRectangle(search_box.left-1, search_box.top-1, search_box.width+2, 23,sc.work_graph); - - edit_box_draw stdcall(#search_box); - - DrawCaptButton(search_box.left+search_box.width+14, search_box.top-1, 100, - TOOLBAR_ICON_HEIGHT+1, _btn_find, sc.work_light, sc.work_text, T_FIND_NEXT); - - sprintf(#matches, T_MATCHES, found.count); - WriteTextWithBg(search_box.left+search_box.width+14+115, - search_box.top+3, 0xD0, sc.work_text, #matches, sc.work); - - DefineHiddenButton(Form.cwidth-26, search_box.top-1, TOOLBAR_ICON_HEIGHT+1, - TOOLBAR_ICON_HEIGHT+1, _btn_hide); - WriteText(Form.cwidth-26+7, search_box.top+2, 0x81, sc.work_graph, "x"); - return true; -} - int SEARCH::find_all() { - dword haystack = io.buffer_data; + dword haystack = textbuf.p; int needle_len = strlen(#found_text); found.drop(); loop() { @@ -94,10 +67,9 @@ int SEARCH::find_all() } } -int SEARCH::find_next(int _cur_pos) +int SEARCH::find_next(int _first) { int i; - dword t1, t2; if (!search_text[0]) return false; if (!streq(#found_text, #search_text)) { @@ -107,12 +79,30 @@ int SEARCH::find_next(int _cur_pos) } for (i=0; i 0) { - t1 = found.get(i); - while(t1 > lines.get(_cur_pos)) _cur_pos++; - return _cur_pos-1; + if (signed found.get(i) - lines.get(_first) > 0) { + while(signed found.get(i) - lines.get(_first) > 0) _first++; + return _first-1; } } return false; } +int SEARCH::find_prior(int _first) +{ + int i; + if (!search_text[0]) return false; + + if (!streq(#found_text, #search_text)) { + strcpy(#found_text, #search_text); + find_all(); + draw_window(); + } + + for (i=0; i 0) { + while(signed lines.get(_first) - found.get(i-1) > 0) _first--; + return _first; + } + } + return false; +} diff --git a/programs/cmm/quark/textbuf.h b/programs/cmm/quark/textbuf.h new file mode 100644 index 0000000000..375e26c1ec --- /dev/null +++ b/programs/cmm/quark/textbuf.h @@ -0,0 +1,58 @@ +struct TEXTBUF +{ + dword p; + unsigned len; + unsigned max; + void drop(); + void extend(); + void set(); + void insert_ch(); + void insert_str(); + void del(); +} textbuf; + +void TEXTBUF::drop() +{ + p = free(p); + len = max = 0; +} + +void TEXTBUF::extend(unsigned _size) +{ + max = _size; + p = realloc(p, max); +} + +void TEXTBUF::set(dword _p, unsigned _size) +{ + len = _size; + extend(len + 4096); + strncpy(p, _p, len); +} + +void TEXTBUF::insert_ch(unsigned _pos, char _ch) +{ + char str[1]; + str[0] = _ch; + insert_str(_pos, #str, 1); +} + +void TEXTBUF::insert_str(unsigned _pos, dword _string, unsigned _sl) +{ + dword i; + if (len + _sl >= max) { + extend(len + _sl + 4096); + } + len += _sl; + for (i=p+len; i>=_pos+_sl; i--) { + ESBYTE[i] = ESBYTE[i-_sl]; + } + memmov(_pos, _string, _sl); +} + +void TEXTBUF::del(unsigned _start, _end) +{ + if (_start > _end) _end >< _start; + strcpy(_start, _end); + len -= _end - _start; +} \ No newline at end of file