Subversion Repositories Kolibri OS

Rev

Rev 9668 | Rev 9674 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
8728 leency 1
(*
9560 akron1 2
    Copyright 2021, 2022 Anton Krotov
8728 leency 3
 
4
    This file is part of CEdit.
5
 
6
    CEdit is free software: you can redistribute it and/or modify
7
    it under the terms of the GNU General Public License as published by
8
    the Free Software Foundation, either version 3 of the License, or
9
    (at your option) any later version.
10
 
11
    CEdit is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
    GNU General Public License for more details.
15
 
16
    You should have received a copy of the GNU General Public License
17
    along with CEdit. If not, see .
18
*)
19
 
20
MODULE CEdit;
21
 
22
IMPORT
9628 akron1 23
    OpenDlg, K := KolibriOS, Args,
8728 leency 24
    U := Utils, Lines, Menu, List,
25
    G := Graph, T := Text, E := Encodings,
26
    CB := Clipboard, Languages,
9182 akron1 27
    ChangeLog, Scroll, CheckBox,
9522 akron1 28
    RW, Ini, EB := EditBox, Tabs, Toolbar, SB := StatusBar;
8728 leency 29
 
30
CONST
9671 akron1 31
    HEADER = "CEdit (26-jan-2022)";
8728 leency 32
 
8762 leency 33
    ShellFilter = "";
9210 akron1 34
    EditFilter = "SH|INC|TXT|ASM|OB07|C|CPP|H|PAS|PP|LUA|INI|JSON";
8728 leency 35
 
36
    fontWidth = K.fontWidth;
37
    fontHeight = K.fontHeight;
38
 
39
    btnClose = 1;
9448 akron1 40
 
8728 leency 41
    btnNew = 20;
42
    btnOpen = 21;
43
    btnSave = 22;
44
    btnSearch = 23;
45
    btnUndo = 24;
46
    btnRedo = 25;
47
    btnUpper = 26;
48
    btnLower = 27;
49
    btnBuild = 28;
50
    btnRun = 29;
9174 akron1 51
 
8728 leency 52
    btnYes = 40;
53
    btnNo = 41;
9210 akron1 54
    btnFindNext = 42;
55
    btnReplace = 43;
56
    btnReplaceAll = 44;
57
    btnGoto = 45;
58
    btnCloseSearch = 46;
59
    btnHideSearch = 47;
8728 leency 60
 
9210 akron1 61
    mainMenuBtn = 60;
8728 leency 62
 
63
    btnHeight = 25;
64
    btnWidth = 75;
65
 
9448 akron1 66
    toolbarTop = Menu.MainMenuHeight + 3;
67
 
68
    TOP = toolbarTop + Toolbar.BtnSize + 10 + Tabs.tabHeight;
8728 leency 69
 
9181 akron1 70
    minWinWidth = 635; minWinHeight = 550;
8728 leency 71
 
72
    SEARCH_PADDING = 10;
9457 akron1 73
    LEFT_PADDING = 1;
74
    RIGHT_PADDING = 1;
75
 
8728 leency 76
    EditBox_Width = 180;
77
    EDITBOX_MAXCHARS = 500;
78
 
79
    menuCut = 1;
80
    menuCopy = 2;
81
    menuPaste = 3;
82
    menuDelete = 4;
83
    menuSelectAll = 5;
84
 
85
    menuUndo = 6;
86
    menuRedo = 7;
87
 
9174 akron1 88
    menuCurLine = 100;
89
    menuIndent = 110;
90
    menuCase = 120;
8728 leency 91
 
92
    menuNew = 10;
93
    menuOpen = 11;
94
    menuSave = 12;
95
    menuSaveAs = 13;
9050 leency 96
    menuSaveAll = 14;
97
    menuFolder = 15;
98
    menuClose = 16;
99
    menuExit = 17;
8728 leency 100
 
9671 akron1 101
    menuFontSmall = 20;
102
    menuFontMedium = menuFontSmall + 1;
103
    menuFontLarge = menuFontMedium + 1;
8728 leency 104
    menuColors = 1000;
105
    menuMaxColors = menuColors + Ini.MAX_SECTIONS - 1;
106
 
9190 akron1 107
    menuText = 30;
8728 leency 108
    menuC = 31;
109
    menuFasm = 32;
110
    menuIni = 33;
9174 akron1 111
    menuJSON = 34;
112
    menuLua = 35;
113
    menuOberon = 36;
114
    menuPascal = 37;
8728 leency 115
 
116
    menuBuild = 50;
117
    menuBuildScript = 51;
118
    menuRun = 52;
119
    menuRunScript = 53;
120
    menuDebug = 54;
121
    menuDebugScript = 55;
122
 
123
    menuUTF8BOM = 60;
124
    menuUTF8 = 61;
125
    menuCP866 = 62;
126
    menuWin1251 = 63;
9190 akron1 127
    menuEOL = 140;
8728 leency 128
 
129
    menuPipet = 70;
9457 akron1 130
    menuMagnify = 71;
131
    menuBoard = 72;
132
    menuSysFunc = 73;
8728 leency 133
 
9174 akron1 134
    menuFind = 80;
135
    menuFindNext = 81;
136
    menuFindPrev = 82;
137
    menuGoto = 83;
138
    menuBookmark = 130;
139
 
9671 akron1 140
    menuLineNumbers  = 90;
141
    menuAutoIndents  = 91;
142
    menuAutoBrackets = 92;
143
    menuTrimSpace    = 93;
144
 
9174 akron1 145
    menuMoveUp = 101;
146
    menuMoveDown = 102;
147
    menuDuplicate = 103;
148
    menuRemove = 104;
149
 
150
    menuIncInd = 111;
151
    menuDecInd = 112;
152
 
153
    menuUpper = 121;
154
    menuLower = 122;
155
 
156
    menuToggleBookmark = 131;
157
    menuNextBookmark = 132;
158
    menuPrevBookmark = 133;
159
 
9190 akron1 160
    menuLF = 141;
161
    menuCRLF = 142;
162
    menuCR = 143;
9180 akron1 163
 
9050 leency 164
    maxTexts = 32;
8762 leency 165
 
9648 akron1 166
	SHIFT = Menu.SHIFT;
167
	CTRL  = Menu.CTRL;
9050 leency 168
 
9648 akron1 169
 
8728 leency 170
VAR
9526 akron1 171
	header: RW.tFileName;
8728 leency 172
    canvas: G.tCanvas;
9668 akron1 173
    font: G.tFont;
9050 leency 174
 
175
    tabs: Tabs.tTabs;
8728 leency 176
    text: T.tText;
9050 leency 177
    texts: ARRAY maxTexts OF T.tText;
178
    textsCount, curText: INTEGER;
179
 
8728 leency 180
    winWidth, winHeight: INTEGER;
9668 akron1 181
    SkinHeight, scrollWidth: INTEGER;
9630 akron1 182
    AppPath, runScript, buildScript, debugScript, CurFolder: RW.tFileName;
8728 leency 183
    OD: OpenDlg.Dialog;
9522 akron1 184
    confirm, notFound, menuFindClicked, search, searchOpened: BOOLEAN;
8728 leency 185
 
9073 leency 186
    switch, closing: BOOLEAN;
9174 akron1 187
    leftButton: BOOLEAN;
9668 akron1 188
    LEFT, RIGHT, BOTTOM: INTEGER;
8728 leency 189
 
9187 akron1 190
    FindEdit, ReplaceEdit, GotoEdit: EB.tEditBox;
9210 akron1 191
    hScroll, vScroll: Scroll.tScroll;
9182 akron1 192
    CS, WH, BKW: CheckBox.tCheckBox;
8728 leency 193
 
194
    new_searchText, searchText, replaceText, gotoText: T.tString;
195
    cs, whole: BOOLEAN;
196
 
197
    replaced: INTEGER;
198
 
9174 akron1 199
    context, menuFile, menuEdit, menuSearch, menuEncoding,
9671 akron1 200
    menuView, menuLanguage, menuProgram, menuTools, menuOptions,
9190 akron1 201
    subCurLine, subIndent, subCase, subBookmark, subEOL: Menu.tMenu;
8728 leency 202
 
9187 akron1 203
    mainMenu: Menu.tMain;
204
 
9175 akron1 205
    menuActive: BOOLEAN;
206
 
9448 akron1 207
    toolbar: Toolbar.tToolbar;
8728 leency 208
 
9448 akron1 209
    CursorTime, CurrentTime: INTEGER;
210
    timerEnabled: BOOLEAN;
8728 leency 211
 
9448 akron1 212
 
9187 akron1 213
PROCEDURE EditBox_Focus (edit: EB.tEditBox): BOOLEAN;
9210 akron1 214
	RETURN 1 IN edit.flags
8728 leency 215
END EditBox_Focus;
216
 
217
 
9174 akron1 218
PROCEDURE resetTimer;
219
BEGIN
220
	IF EditBox_Focus(FindEdit) OR EditBox_Focus(ReplaceEdit) OR EditBox_Focus(GotoEdit) THEN
221
		T.hideCursor;
9448 akron1 222
		timerEnabled := FALSE
9174 akron1 223
	ELSE
224
		T.showCursor;
9448 akron1 225
		timerEnabled := TRUE
226
	END;
227
	CursorTime := CurrentTime
9174 akron1 228
END resetTimer;
229
 
230
 
9210 akron1 231
PROCEDURE EditBox_SetFocus (VAR edit: EB.tEditBox; value: BOOLEAN);
8728 leency 232
BEGIN
233
    IF value THEN
9208 akron1 234
    	INCL(edit.flags, 1)
8728 leency 235
    ELSE
9208 akron1 236
    	EXCL(edit.flags, 1)
8728 leency 237
    END;
9073 leency 238
    IF search & searchOpened THEN
9630 akron1 239
        EB.draw(edit)
8728 leency 240
    END
241
END EditBox_SetFocus;
242
 
243
 
9210 akron1 244
PROCEDURE SetFocus (VAR edit: EB.tEditBox; value: BOOLEAN);
9073 leency 245
BEGIN
246
    EditBox_SetFocus(FindEdit, FALSE);
247
    EditBox_SetFocus(ReplaceEdit, FALSE);
248
    EditBox_SetFocus(GotoEdit, FALSE);
9174 akron1 249
    EditBox_SetFocus(edit, value);
250
  	resetTimer
9073 leency 251
END SetFocus;
252
 
253
 
8728 leency 254
PROCEDURE Rect (left, top, right, bottom, color: INTEGER);
255
BEGIN
256
    K.DrawLine(left, top, right, top, color);
257
    K.DrawLine(left, bottom, right, bottom, color);
258
    K.DrawLine(left, top, left, bottom, color);
259
    K.DrawLine(right, top, right, bottom, color);
260
END Rect;
261
 
262
 
263
PROCEDURE Message (s: ARRAY OF WCHAR);
264
CONST
265
    minWidth = 30;
266
    height = 40;
267
VAR
268
    top, left, right, bottom, x, y, width: INTEGER;
269
BEGIN
9448 akron1 270
	timerEnabled := FALSE;
271
	CursorTime := CurrentTime;
8728 leency 272
    width := minWidth + LENGTH(s)*fontWidth;
273
    left := (canvas.width - width) DIV 2 + LEFT;
274
    top := (canvas.height - height) DIV 2 + TOP;
275
    bottom := top + height - 1;
276
    right := left + width - 1;
277
    x := minWidth DIV 2 + left;
278
    y := (height - fontHeight) DIV 2 + top;
9628 akron1 279
    K.DrawRect(left, top, width, height, K.colors.work);
280
    Rect(left, top, right, bottom, K.colors.line);
281
    K.DrawText(x, y, K.colors.work_text, s);
8728 leency 282
END Message;
283
 
284
 
285
PROCEDURE NotFound;
286
BEGIN
287
    IF notFound THEN
288
        Message("not found");
9175 akron1 289
        IF menuFindClicked THEN
290
        	menuFindClicked := FALSE
291
        ELSE
292
        	notFound := FALSE
293
        END;
9073 leency 294
        SetFocus(FindEdit, TRUE)
8728 leency 295
    END
296
END NotFound;
297
 
298
 
299
PROCEDURE Replaced;
300
VAR
301
    s, s1: ARRAY 32 OF WCHAR;
302
BEGIN
303
    IF replaced # 0 THEN
304
        s := "replaced: ";
305
        U.int2str(replaced, s1);
306
        U.append(s, s1);
307
        Message(s);
308
        replaced := 0;
9073 leency 309
        SetFocus(FindEdit, TRUE)
8728 leency 310
    END
311
END Replaced;
312
 
313
 
9410 akron1 314
PROCEDURE getIdx (text: T.tText): INTEGER;
315
VAR
316
    i: INTEGER;
8728 leency 317
BEGIN
9410 akron1 318
    i := 0;
319
    WHILE texts[i] # text DO
320
        INC(i)
8728 leency 321
    END
9410 akron1 322
    RETURN i
323
END getIdx;
8728 leency 324
 
325
 
9410 akron1 326
PROCEDURE SetCaption (fileName: RW.tFileName);
327
VAR
9526 akron1 328
	newHeader: RW.tFileName;
9410 akron1 329
BEGIN
9526 akron1 330
    newHeader := HEADER;
9410 akron1 331
    IF text.fileName # "" THEN
9526 akron1 332
    	U.append8(newHeader, " - ");
333
    	U.append8(newHeader, text.fileName)
9410 akron1 334
    END;
9526 akron1 335
    IF newHeader # header THEN
336
    	header := newHeader;
337
		K.SetCaption(header)
338
    END
9410 akron1 339
END SetCaption;
340
 
341
 
9522 akron1 342
PROCEDURE Status (text: T.tText; height: INTEGER);
9050 leency 343
VAR
9522 akron1 344
	line, col, chars, lines: INTEGER;
9050 leency 345
BEGIN
9522 akron1 346
	T.getPos(text, col, line);
347
	T.getSelCnt(text, chars, lines);
348
	SB.setWidth(canvas.width + scrollWidth);
349
	SB.setPos(line, col);
350
	SB.setSel(chars, lines);
9659 akron1 351
	SB.setEnc(E.eolNames[T.getEol(text)], E.names[T.getEnc(text)]);
9522 akron1 352
	SB.draw(LEFT, height - BOTTOM + scrollWidth - 1);
353
	Tabs.modify(tabs, getIdx(text), text.modified)
354
END Status;
9050 leency 355
 
356
 
9174 akron1 357
PROCEDURE DrawScroll (VAR scroll: Scroll.tScroll; left, top, value, maxVal: INTEGER);
358
BEGIN
359
	scroll.maxVal := maxVal;
360
    scroll.left := left;
361
    scroll.top := top;
362
    Scroll.setValue(scroll, value);
9630 akron1 363
    Scroll.draw(scroll)
9174 akron1 364
END DrawScroll;
365
 
366
 
9668 akron1 367
PROCEDURE drawText;
368
BEGIN
369
	G.SetColor(canvas, K.colors.line);
370
	G.VLine(canvas, 0, 0, canvas.height - 1);
371
	G.DrawCanvas(canvas, LEFT, TOP)
372
END drawText;
373
 
374
 
8728 leency 375
PROCEDURE repaint;
376
VAR
9462 akron1 377
    width, height, scrollX, scrollY: INTEGER;
8728 leency 378
BEGIN
9457 akron1 379
    IF (text # NIL) & ~K.RolledUp() THEN
8728 leency 380
        IF confirm THEN
381
            K.DeleteButton(btnYes);
382
            K.DeleteButton(btnNo);
9073 leency 383
            confirm := FALSE;
9174 akron1 384
            resetTimer;
9073 leency 385
            closing := FALSE
8728 leency 386
        END;
9073 leency 387
        IF ~search OR (searchText = "") THEN
9010 leency 388
            T.wordSel(text)
389
        END;
9050 leency 390
        K.ClientSize(width, height);
391
        IF switch THEN
9522 akron1 392
            Status(text, height);
9050 leency 393
            Tabs.draw(tabs);
394
            IF search & T.search(text, searchText, cs, whole) THEN END;
395
            switch := FALSE
396
        END;
8728 leency 397
        T.draw(text);
9522 akron1 398
        Status(text, height);
8728 leency 399
 
400
        T.getScroll(text, scrollX, scrollY);
9181 akron1 401
        DrawScroll(vScroll, LEFT + canvas.width, TOP - 1, scrollY, text.count - 1);
402
        DrawScroll(hScroll, LEFT, TOP + canvas.height, scrollX, text.maxLength);
9182 akron1 403
        IF search & searchOpened THEN
9630 akron1 404
	        CheckBox.draw(BKW);
405
	        CheckBox.draw(CS);
406
	        CheckBox.draw(WH);
9182 akron1 407
        END;
9668 akron1 408
        drawText;
8728 leency 409
        NotFound;
410
        Replaced;
9448 akron1 411
        Toolbar.enable(toolbar, btnSave,  text.modified);
412
        Toolbar.enable(toolbar, btnUndo,  ~ChangeLog.isFirstGuard(text.edition));
413
        Toolbar.enable(toolbar, btnRedo,  ~ChangeLog.isLastGuard(text.edition));
414
        Toolbar.enable(toolbar, btnUpper, T.selected(text));
415
        Toolbar.enable(toolbar, btnLower, T.selected(text));
416
        Toolbar.enable(toolbar, btnBuild, buildScript # "");
417
        Toolbar.enable(toolbar, btnRun,   runScript # "");
418
        Toolbar.drawIcons(toolbar)
8728 leency 419
    END
420
END repaint;
421
 
422
 
423
PROCEDURE resize;
424
VAR
425
    cliWidth, cliHeight: INTEGER;
426
BEGIN
427
    K.WinSize(winWidth, winHeight);
428
    IF winWidth < minWinWidth THEN
429
        winWidth := minWinWidth
430
    END;
431
    IF winHeight < minWinHeight THEN
432
        winHeight := minWinHeight
433
    END;
434
    K.SetWinSize(winWidth, winHeight);
435
    K.WinSize(winWidth, winHeight);
436
    K.ClientSize(cliWidth, cliHeight);
9671 akron1 437
    IF font # G.fonts[2] THEN
9668 akron1 438
    	SB.SetFont(font)
439
    ELSE
9671 akron1 440
    	SB.SetFont(G.fonts[1])
9668 akron1 441
    END;
442
    BOTTOM := SB.height() + scrollWidth - 1;
8728 leency 443
    G.destroy(canvas);
9457 akron1 444
    canvas := G.CreateCanvas(cliWidth - (LEFT + RIGHT + 2 + RIGHT_PADDING), cliHeight - (TOP + BOTTOM + 1));
445
    Tabs.setArea(tabs, LEFT, TOP - Tabs.tabHeight, cliWidth - (LEFT + RIGHT + 2 + RIGHT_PADDING), Tabs.tabHeight);
8728 leency 446
    G.SetFont(canvas, font);
447
    T.setCanvas(canvas);
448
    T.resize(canvas.width, canvas.height);
9181 akron1 449
    Scroll.resize(vScroll, vScroll.width, canvas.height + 2);
450
    Scroll.resize(hScroll, canvas.width + 1, hScroll.height);
8728 leency 451
END resize;
452
 
453
 
454
PROCEDURE SearchPanel (left, top: INTEGER);
455
VAR
9522 akron1 456
    y, right, bottom: INTEGER;
8728 leency 457
BEGIN
9060 leency 458
    DEC(top, Tabs.tabHeight);
8728 leency 459
    right := left + EditBox_Width + SEARCH_PADDING*2;
460
    bottom := top + 395 + btnHeight + SEARCH_PADDING;
9628 akron1 461
    Rect(left, top, right, bottom, K.colors.line);
9522 akron1 462
 
9190 akron1 463
    K.CreateButton(btnCloseSearch, right - 20, top, 20, 20, 0EF999FH, "");
8728 leency 464
    K.DrawLine(right - 14, top + 5, right - 5, top + 14, 0FFFFFFH);
465
    K.DrawLine(right - 15, top + 5, right - 5, top + 15, 0FFFFFFH);
466
    K.DrawLine(right - 15, top + 6, right - 6, top + 15, 0FFFFFFH);
467
    K.DrawLine(right - 15, top + 14, right - 6, top + 5, 0FFFFFFH);
468
    K.DrawLine(right - 15, top + 15, right - 5, top + 5, 0FFFFFFH);
469
    K.DrawLine(right - 14, top + 15, right - 5, top + 6, 0FFFFFFH);
470
 
9628 akron1 471
    K.CreateButton(btnHideSearch, right - 40, top, 20, 20, K.colors.button, "");
472
    K.DrawLine(right - 34, top + 14, right - 26, top + 14, K.colors.button_text);
473
    K.DrawLine(right - 34, top + 15, right - 26, top + 15, K.colors.button_text);
9073 leency 474
 
8728 leency 475
    INC(top, 15);
476
    INC(left, SEARCH_PADDING);
9628 akron1 477
    K.DrawText866(left, top, K.colors.work_text, "find");
478
    K.DrawText866(left, top + 55, K.colors.work_text, "replace with");
479
    K.DrawText866(left, top + 330, K.colors.work_text, "go to line");
9182 akron1 480
    BKW.top := top + 110;
481
    BKW.left := left;
482
    CS.top := top + 140;
483
    CS.left := left;
484
    WH.top := top + 170;
485
    WH.left := left;
8728 leency 486
    FindEdit.top := top + 20;
487
    ReplaceEdit.top := top + 75;
488
    GotoEdit.top := top + 350;
489
    FindEdit.left := left;
490
    ReplaceEdit.left := left;
491
    GotoEdit.left := left;
9630 akron1 492
    EB.draw(FindEdit);
493
    EB.draw(ReplaceEdit);
494
    EB.draw(GotoEdit);
8728 leency 495
    y := top + 200;
9628 akron1 496
    K.CreateButton(btnFindNext, left, y, btnWidth, btnHeight, K.colors.button, "next"); INC(y, btnHeight + 10);
497
    K.CreateButton(btnReplace, left, y, btnWidth, btnHeight, K.colors.button, "replace"); INC(y, btnHeight + 10);
498
    K.CreateButton(btnReplaceAll, left, y, btnWidth + 5*fontWidth - 2, btnHeight, K.colors.button, "replace all");
499
    K.CreateButton(btnGoto, left, top + 380, btnWidth, btnHeight, K.colors.button, "go");
8728 leency 500
END SearchPanel;
501
 
502
 
503
PROCEDURE draw_window;
504
VAR
9448 akron1 505
    width, height: INTEGER;
8728 leency 506
BEGIN
507
    K.BeginDraw;
9628 akron1 508
    K.CreateWindow(30 + K.GetTickCount() MOD 128, 30 + K.GetTickCount() MOD 128, winWidth, winHeight, K.colors.work, 73H, 0, 0, "");
8728 leency 509
    IF (text # NIL) & ~K.RolledUp() THEN
9174 akron1 510
    	IF confirm THEN
511
    		resetTimer
512
    	END;
8728 leency 513
        confirm := FALSE;
514
        K.ClientSize(width, height);
515
 
9628 akron1 516
        K.DrawRect(0, 0, width, TOP - 1, K.colors.work);
517
        K.DrawRect(0, 0, LEFT, height, K.colors.work);
518
        K.DrawRect(width - RIGHT_PADDING, 0, RIGHT_PADDING, height, K.colors.work);
519
        K.DrawRect(LEFT + canvas.width + 1, TOP + canvas.height + 1, scrollWidth - 1, scrollWidth - 1, K.colors.work);
9187 akron1 520
        Menu.DrawMain(mainMenu);
8728 leency 521
 
9448 akron1 522
        Toolbar.draw(toolbar);
9522 akron1 523
		SetCaption(text.fileName);
524
        Status(text, height);
9073 leency 525
        IF search & searchOpened THEN
9457 akron1 526
            SearchPanel(LEFT_PADDING, TOP)
8728 leency 527
        END;
9050 leency 528
        Tabs.draw(tabs);
8728 leency 529
        repaint
530
    END;
531
    K.EndDraw
532
END draw_window;
533
 
534
 
535
PROCEDURE mouse (VAR x, y: INTEGER);
536
VAR
9208 akron1 537
    msState: SET;
8728 leency 538
BEGIN
9208 akron1 539
	K.mouse(msState, x, y);
540
	DEC(x, LEFT);
541
	DEC(y, TOP)
8728 leency 542
END mouse;
543
 
544
 
9174 akron1 545
PROCEDURE stopTimer;
546
BEGIN
547
	T.hideCursor;
9448 akron1 548
    timerEnabled := FALSE;
549
    CursorTime := CurrentTime;
9181 akron1 550
    repaint
9174 akron1 551
END stopTimer;
552
 
553
 
8728 leency 554
PROCEDURE OpenFile (VAR FileName: RW.tFileName; filter: ARRAY OF CHAR);
555
BEGIN
9174 akron1 556
    stopTimer;
8728 leency 557
    OpenDlg.SetFilter(OD, filter);
558
    OpenDlg.Show(OD, 500, 400);
559
    WHILE OD.status = 2 DO
560
        K.Pause(30)
561
    END;
562
    IF OD.status = 1 THEN
563
        COPY(OD.FilePath, FileName)
564
    ELSE
565
        FileName := ""
9174 akron1 566
    END;
567
    resetTimer
8728 leency 568
END OpenFile;
569
 
570
 
571
PROCEDURE error (s: RW.tFileName);
9410 akron1 572
VAR
573
    temp: RW.tFileName;
8728 leency 574
BEGIN
9410 akron1 575
	temp := "'CEdit: ";
576
	U.append8(temp, s);
577
	U.append8(temp, "' -E");
9577 akron1 578
    K.Run("/sys/@notify", temp)
8728 leency 579
END error;
580
 
581
 
9050 leency 582
PROCEDURE saveError (name: RW.tFileName);
8728 leency 583
VAR
9050 leency 584
    s: RW.tFileName;
585
BEGIN
9410 akron1 586
    s := "error saving file ";
9050 leency 587
    U.append8(s, name);
588
    error(s)
589
END saveError;
590
 
591
 
592
PROCEDURE saveAs (text: T.tText);
593
VAR
594
    fileName, name: RW.tFileName;
8728 leency 595
    ext: ARRAY 8 OF CHAR;
596
BEGIN
597
    OD._type := OpenDlg.tsave;
598
    U.getFileName(text.fileName, OD.FileName, U.SLASH);
599
    IF OD.FileName = "" THEN
600
        OD.FileName := "NewFile.";
9210 akron1 601
        Languages.getExt(text.lang, ext);
8728 leency 602
        U.append8(OD.FileName, ext)
603
    END;
604
    OpenFile(fileName, EditFilter);
605
    IF fileName # "" THEN
9180 akron1 606
        IF T.save(text, fileName) THEN
9050 leency 607
            T.setName(text, fileName);
608
            U.getFileName(fileName, name, U.SLASH);
609
            Tabs.rename(tabs, curText, name)
8728 leency 610
        ELSE
9050 leency 611
            saveError(fileName)
8728 leency 612
        END
613
    END
614
END saveAs;
615
 
616
 
9050 leency 617
PROCEDURE Switch (txt: T.tText);
618
BEGIN
619
    Tabs.switch(tabs, curText);
620
    text := txt;
621
    T.switch(txt);
622
    switch := TRUE
623
END Switch;
624
 
625
 
626
PROCEDURE save (text: T.tText);
627
BEGIN
8728 leency 628
    IF text.modified THEN
629
        IF text.fileName # "" THEN
9180 akron1 630
            IF ~T.save(text, text.fileName) THEN
9050 leency 631
                saveError(text.fileName)
8728 leency 632
            END
633
        ELSE
9050 leency 634
            curText := getIdx(text);
635
            Switch(text);
636
            saveAs(text)
9410 akron1 637
        END;
638
   		Tabs.modify(tabs, getIdx(text), text.modified)
8728 leency 639
    END
640
END save;
641
 
642
 
9050 leency 643
PROCEDURE saveAll;
644
VAR
645
    i: INTEGER;
9410 akron1 646
    txt: T.tText;
8728 leency 647
BEGIN
9050 leency 648
    i := textsCount - 1;
649
    WHILE i >= 0 DO
9410 akron1 650
    	txt := texts[i];
651
        IF txt.modified THEN
652
        	T.switch(txt);
653
            save(txt)
9050 leency 654
        END;
655
        DEC(i)
656
    END;
9410 akron1 657
    T.switch(text)
9050 leency 658
END saveAll;
8728 leency 659
 
660
 
9050 leency 661
PROCEDURE insert (pos: INTEGER; txt: T.tText);
8728 leency 662
VAR
9050 leency 663
    i: INTEGER;
664
    name: RW.tFileName;
8728 leency 665
BEGIN
9050 leency 666
    FOR i := textsCount - 1 TO pos BY -1 DO
667
        texts[i + 1] := texts[i]
668
    END;
669
    texts[pos] := txt;
670
    INC(textsCount);
671
    curText := pos;
672
    IF txt.fileName = "" THEN
673
        name := "new"
674
    ELSE
675
        U.getFileName(txt.fileName, name, U.SLASH)
676
    END;
677
    Tabs.add(tabs, name);
678
    Switch(txt)
679
END insert;
8728 leency 680
 
681
 
682
PROCEDURE Confirm;
683
CONST
684
    width  = btnWidth*2 + 30;
685
    height = btnHeight*2 + 20;
686
VAR
687
    left, top, right, bottom: INTEGER;
688
BEGIN
9174 akron1 689
	stopTimer;
8728 leency 690
    draw_window;
691
    confirm := TRUE;
692
    left := (canvas.width - width) DIV 2 + LEFT;
693
    top := (canvas.height - height) DIV 2 + TOP;
694
    right := left + width - 1;
695
    bottom := top + height - 1;
9628 akron1 696
    K.DrawRect(left, top, width, height, K.colors.work);
697
    Rect(left, top, right, bottom, K.colors.line);
698
    K.DrawText866(left + (width - 10*fontWidth) DIV 2, top + 10, K.colors.work_text, "save file?");
699
    K.CreateButton(btnYes, left + 10, top + 35, btnWidth, btnHeight, K.colors.button, "yes");
700
    K.CreateButton(btnNo, left + 20 + btnWidth, top + 35, btnWidth, btnHeight, K.colors.button, "no");
8728 leency 701
END Confirm;
702
 
703
 
9060 leency 704
PROCEDURE closeFile (conf: BOOLEAN; n: INTEGER);
9050 leency 705
VAR
706
    i: INTEGER;
707
BEGIN
9073 leency 708
    IF texts[n].modified & conf THEN
9050 leency 709
        Confirm
710
    ELSE
9060 leency 711
        Tabs.delete(tabs, n);
9448 akron1 712
        T.destroy(texts[n]);
9060 leency 713
        FOR i := n + 1 TO textsCount - 1 DO
9050 leency 714
            texts[i - 1] := texts[i]
715
        END;
716
        DEC(textsCount);
9060 leency 717
        IF (curText = textsCount) OR (n < curText) THEN
9050 leency 718
            DEC(curText)
719
        END;
720
        IF curText >= 0 THEN
721
            Switch(texts[curText])
722
        ELSE
9181 akron1 723
            K.Exit
9050 leency 724
        END;
725
        draw_window
726
    END
727
END closeFile;
728
 
729
 
730
PROCEDURE NewFile;
731
VAR
732
    nov: T.tText;
733
BEGIN
734
    IF textsCount < maxTexts THEN
735
        nov := T.New();
736
        T.SetPos(nov, 0, 0);
737
        insert(textsCount, nov)
738
    ELSE
9410 akron1 739
        error("too many files")
9050 leency 740
    END
741
END NewFile;
742
 
743
 
744
PROCEDURE getFileNum (fileName: RW.tFileName): INTEGER;
745
VAR
746
    i: INTEGER;
747
 
748
    PROCEDURE nameEq (name1, name2: RW.tFileName): BOOLEAN;
749
    VAR
750
        n1, n2: RW.tFileName;
751
    BEGIN
752
        n1 := name1;
753
        n2 := name2;
754
        U.upcase(n1);
755
        U.upcase(n2)
756
        RETURN n1 = n2
757
    END nameEq;
758
 
759
BEGIN
760
    i := 0;
761
    WHILE (i < textsCount) & ~nameEq(texts[i].fileName, fileName) DO
762
        INC(i)
763
    END;
764
    IF i = textsCount THEN
765
        i := -1
766
    END
767
    RETURN i
768
END getFileNum;
769
 
770
 
9073 leency 771
PROCEDURE SwitchTab (n: INTEGER);
772
BEGIN
773
    curText := n;
774
    Tabs.switch(tabs, n);
775
    Switch(texts[n]);
9174 akron1 776
    resetTimer;
9073 leency 777
    draw_window
778
END SwitchTab;
779
 
780
 
9628 akron1 781
PROCEDURE open (_fileName: RW.tFileName): BOOLEAN;
9050 leency 782
VAR
9628 akron1 783
	fileName: RW.tFileName;
9050 leency 784
    nov: T.tText;
785
    err, n: INTEGER;
9628 akron1 786
    res: BOOLEAN;
9050 leency 787
BEGIN
9628 akron1 788
	res := TRUE;
9050 leency 789
    IF textsCount < maxTexts THEN
9628 akron1 790
    	fileName := _fileName;
791
    	IF fileName = "" THEN
792
        	OD._type := OpenDlg.topen;
793
        	OpenFile(fileName, EditFilter)
794
        END;
9050 leency 795
        IF fileName # "" THEN
796
            n := getFileNum(fileName);
797
            IF n = -1 THEN
798
                nov := T.open(fileName, err);
799
                IF nov = NIL THEN
9628 akron1 800
                    error("error opening file");
801
                    SwitchTab(curText);
802
                    res := FALSE
9050 leency 803
                ELSE
9431 akron1 804
                	T.SetPos(nov, 0, 0);
9050 leency 805
                    insert(textsCount, nov);
9431 akron1 806
                    Scroll.setValue(hScroll, 0);
807
                    Scroll.setValue(vScroll, 0)
9050 leency 808
                END
809
            ELSE
9073 leency 810
                SwitchTab(n)
9050 leency 811
            END
812
        END
813
    ELSE
9628 akron1 814
        error("too many files");
815
        res := FALSE
9050 leency 816
    END
9628 akron1 817
    RETURN res
9050 leency 818
END open;
819
 
820
 
9628 akron1 821
PROCEDURE OpenDial;
822
VAR
823
	res: BOOLEAN;
824
BEGIN
825
	res := open("")
826
END OpenDial;
827
 
828
 
8728 leency 829
PROCEDURE createSearchForm;
830
BEGIN
9457 akron1 831
	EB.create(LEFT_PADDING, TOP + 20, EditBox_Width, EDITBOX_MAXCHARS, FindEdit);
832
	EB.create(LEFT_PADDING, TOP + 20 + 55, EditBox_Width, EDITBOX_MAXCHARS, ReplaceEdit);
833
    EB.create(LEFT_PADDING, TOP + 20 + 330, EditBox_Width, EDITBOX_MAXCHARS, GotoEdit);
9208 akron1 834
    INCL(GotoEdit.flags, 15);
9187 akron1 835
    CheckBox.create("backward", BKW);
836
    CheckBox.create("match case", CS);
837
    CheckBox.create("whole word", WH);
8728 leency 838
END createSearchForm;
839
 
840
 
9659 akron1 841
PROCEDURE EditBox_Get (edit: EB.tEditBox; VAR s: ARRAY OF WCHAR);
8728 leency 842
VAR
843
    str: ARRAY EDITBOX_MAXCHARS + 1 OF CHAR;
844
    i: INTEGER;
845
BEGIN
9659 akron1 846
    EB.get(edit, str);
8728 leency 847
    i := 0;
848
    WHILE str[i] # 0X DO
849
        s[i] := WCHR(E.cp866[ORD(str[i])]);
850
        INC(i)
851
    END;
852
    s[i] := 0X
9659 akron1 853
END EditBox_Get;
8728 leency 854
 
855
 
856
PROCEDURE Search;
857
BEGIN
858
    search := ~search;
9457 akron1 859
    LEFT := LEFT_PADDING;
8728 leency 860
    IF search THEN
9073 leency 861
        searchOpened := TRUE;
9457 akron1 862
        INC(LEFT, EditBox_Width + SEARCH_PADDING*2 + 4);
8728 leency 863
        IF T.search(text, searchText, cs, whole) THEN END
864
    ELSE
865
        IF T.search(text, "", FALSE, FALSE) THEN END
866
    END;
9073 leency 867
    SetFocus(FindEdit, search);
8728 leency 868
    resize;
869
    draw_window
870
END Search;
871
 
872
 
873
PROCEDURE click (x, y: INTEGER): INTEGER;
874
VAR
875
    scrollX, scrollY: INTEGER;
9073 leency 876
    shift, ctrl: BOOLEAN;
8728 leency 877
BEGIN
9187 akron1 878
    K.getKBState(shift, ctrl);
879
    T.getScroll(text, scrollX, scrollY);
880
    T.scroll(text, hScroll.value - scrollX, vScroll.value - scrollY);
9208 akron1 881
    IF U.between(0, x, canvas.width - 1) & U.between(0, y, canvas.height - 1) THEN
8728 leency 882
        leftButton := TRUE;
9073 leency 883
        SetFocus(FindEdit, FALSE);
884
        IF ~shift THEN
8728 leency 885
            T.resetSelect(text)
886
        END;
9187 akron1 887
        T.mouse(text, x, y)
888
    END;
889
    repaint
8728 leency 890
    RETURN K.GetTickCount()
891
END click;
892
 
893
 
9073 leency 894
PROCEDURE Close;
9050 leency 895
VAR
896
    cont: BOOLEAN;
8728 leency 897
BEGIN
9073 leency 898
    closing := TRUE;
9050 leency 899
    cont := TRUE;
900
    WHILE (textsCount > 0) & cont DO
901
        IF text.modified THEN
902
            Confirm;
903
            cont := FALSE
904
        ELSE
9060 leency 905
            closeFile(FALSE, curText);
9050 leency 906
            repaint
907
        END
8728 leency 908
    END
9073 leency 909
END Close;
8728 leency 910
 
911
 
9174 akron1 912
PROCEDURE CloseMenu;
913
BEGIN
9190 akron1 914
    Menu.close(subEOL);
915
    Menu.close(subCurLine);
916
    Menu.close(subIndent);
917
    Menu.close(subCase);
918
    Menu.close(subBookmark);
9174 akron1 919
    Menu.close(menuFile);
920
    Menu.close(menuEdit);
921
    Menu.close(menuSearch);
922
    Menu.close(menuEncoding);
923
    Menu.close(menuView);
9190 akron1 924
    Menu.close(menuLanguage);
9174 akron1 925
    Menu.close(menuProgram);
926
    Menu.close(menuTools);
9671 akron1 927
    Menu.close(menuOptions);
9187 akron1 928
    Menu.close(context)
9174 akron1 929
END CloseMenu;
930
 
931
 
8728 leency 932
PROCEDURE goto;
933
VAR
934
    gotoVal: INTEGER;
935
BEGIN
9659 akron1 936
    EditBox_Get(GotoEdit, gotoText);
9174 akron1 937
    IF U.str2int(gotoText, gotoVal) & T.goto(text, gotoVal) THEN
938
    	SetFocus(GotoEdit, FALSE)
939
    END
8728 leency 940
END goto;
941
 
942
 
943
PROCEDURE Script (script: ARRAY OF CHAR);
944
BEGIN
945
    IF script # "" THEN
9630 akron1 946
    	U.getPath(script, CurFolder);
947
    	K.SetCurFolder(CurFolder);
9577 akron1 948
        K.Run("/sys/@open", script)
8728 leency 949
    END
950
END Script;
951
 
952
 
9197 akron1 953
PROCEDURE ShowSearchPanel (goto: BOOLEAN);
954
VAR
955
	i: INTEGER;
9073 leency 956
BEGIN
9197 akron1 957
	IF T.selected(text) & ~goto THEN
958
		T.getSelectedText(text, new_searchText);
959
		IF new_searchText # "" THEN
960
			i := 0;
961
			WHILE (new_searchText[i] # 0X) & (new_searchText[i] # Lines.TAB) DO
962
				INC(i)
963
			END;
964
			IF new_searchText[i] = 0X THEN
965
				searchText := new_searchText;
9659 akron1 966
				EB.set(FindEdit, searchText);
9197 akron1 967
				notFound := ~T.search(text, searchText, cs, whole);
968
			END
969
		END
970
	END;
9073 leency 971
    IF ~search THEN
972
        Search
973
    ELSIF ~searchOpened THEN
974
        search := FALSE;
975
        Search
9197 akron1 976
    END;
9410 akron1 977
    IF goto THEN
978
    	SetFocus(GotoEdit, TRUE)
9197 akron1 979
    ELSE
9448 akron1 980
    	SetFocus(FindEdit, TRUE)
9073 leency 981
    END
982
END ShowSearchPanel;
983
 
984
 
9174 akron1 985
PROCEDURE CanvasToScreen (VAR x, y: INTEGER);
986
VAR
987
    cliX, cliY,
988
    winX, winY: INTEGER;
989
BEGIN
990
    K.WinPos(winX, winY);
991
    K.ClientPos(cliX, cliY);
992
    x := x + winX + cliX + LEFT;
993
    y := y + winY + cliY + TOP;
994
END CanvasToScreen;
995
 
996
 
997
PROCEDURE ShowMenu (menu: Menu.tMenu);
998
VAR
999
    winX, winY, cliX, cliY, x, y, i: INTEGER;
1000
    selected, enabled: BOOLEAN;
1001
BEGIN
1002
    IF menu = context THEN
1003
        mouse(x, y);
9208 akron1 1004
        IF ~(U.between(0, x, canvas.width - 1) & U.between(0, y, canvas.height - 1)) THEN
9174 akron1 1005
            menu := NIL
1006
        END
1007
    ELSE
1008
        K.WinPos(winX, winY);
1009
        K.ClientPos(cliX, cliY);
1010
        x := winX + cliX;
9187 akron1 1011
        y := Menu.MainMenuHeight + winY + cliY
9174 akron1 1012
    END;
1013
    selected := T.selected(text);
1014
 
1015
    IF menu = menuFile THEN
1016
        Menu.setEnabled(menu, menuSave, text.modified);
1017
        Menu.setEnabled(menu, menuFolder, text.fileName # "");
1018
        i := 0;
1019
        WHILE (i < textsCount) & ~texts[i].modified DO
1020
            INC(i)
1021
        END;
9671 akron1 1022
        Menu.setEnabled(menu, menuSaveAll, i < textsCount)
9174 akron1 1023
    ELSIF (menu = menuEdit) OR (menu = context) THEN
1024
        Menu.setEnabled(menu, menuUndo, ~ChangeLog.isFirstGuard(text.edition));
1025
        Menu.setEnabled(menu, menuRedo, ~ChangeLog.isLastGuard(text.edition));
1026
        Menu.setEnabled(menu, menuCut, selected);
1027
        Menu.setEnabled(menu, menuCopy, selected);
1028
        Menu.setEnabled(menu, menuDelete, selected);
1029
        Menu.setEnabled(menu, menuPaste, CB.available());
9671 akron1 1030
        IF menu = context THEN
9174 akron1 1031
            IF y + menu.height >= canvas.height THEN
1032
                DEC(y, menu.height)
1033
            END;
1034
            IF x + menu.width >= canvas.width THEN
1035
                DEC(x, menu.width)
1036
            END;
9671 akron1 1037
            CanvasToScreen(x, y);
1038
            menu.x := x;
1039
            x := 0
9174 akron1 1040
        END
1041
    ELSIF menu = menuEncoding THEN
9336 akron1 1042
        Menu.option(menu, menuUTF8BOM, T.getEnc(text) = E.UTF8BOM);
1043
        Menu.option(menu, menuUTF8,    T.getEnc(text) = E.UTF8);
1044
        Menu.option(menu, menuCP866,   T.getEnc(text) = E.CP866);
9671 akron1 1045
        Menu.option(menu, menuWin1251, T.getEnc(text) = E.W1251)
9174 akron1 1046
    ELSIF menu = menuView THEN
9671 akron1 1047
        Menu.option(menu, menuFontSmall,  font = G.fonts[0]);
1048
        Menu.option(menu, menuFontMedium, font = G.fonts[1]);
1049
        Menu.option(menu, menuFontLarge,  font = G.fonts[2]);
9174 akron1 1050
        FOR i := 0 TO Ini.sections.count - 1 DO
9182 akron1 1051
            Menu.option(menu, menuColors + i, Ini.curSectionNum = i)
9671 akron1 1052
        END
9190 akron1 1053
    ELSIF menu = menuLanguage THEN
1054
        Menu.option(menu, menuText,   text.lang = Languages.langText);
9182 akron1 1055
        Menu.option(menu, menuC,      text.lang = Languages.langC);
1056
        Menu.option(menu, menuFasm,   text.lang = Languages.langFasm);
1057
        Menu.option(menu, menuIni,    text.lang = Languages.langIni);
1058
        Menu.option(menu, menuJSON,   text.lang = Languages.langJSON);
1059
        Menu.option(menu, menuLua,    text.lang = Languages.langLua);
1060
        Menu.option(menu, menuOberon, text.lang = Languages.langOberon);
1061
        Menu.option(menu, menuPascal, text.lang = Languages.langPascal);
9174 akron1 1062
    ELSIF menu = menuProgram THEN
1063
        Menu.setEnabled(menu, menuBuild, buildScript # "");
1064
        Menu.setEnabled(menu, menuDebug, debugScript # "");
9671 akron1 1065
        Menu.setEnabled(menu, menuRun,   runScript # "")
1066
    ELSIF menu = menuOptions THEN
1067
    	Menu.check(menu, menuLineNumbers,  T.lineNumbers);
1068
    	Menu.check(menu, menuAutoIndents,  T.autoIndents);
1069
    	Menu.check(menu, menuAutoBrackets, T.autoBrackets);
1070
    	Menu.check(menu, menuTrimSpace,    T.trimSpace)
9174 akron1 1071
    END;
1072
 
1073
    enabled := search & (searchText # "");
1074
    Menu.setEnabled(menuSearch, menuFindNext, enabled);
1075
    Menu.setEnabled(menuSearch, menuFindPrev, enabled);
1076
 
1077
    Menu.setEnabled(subIndent, menuIncInd, selected);
1078
    Menu.setEnabled(subIndent, menuDecInd, selected);
1079
 
1080
    Menu.setEnabled(subCase, menuUpper, selected);
1081
    Menu.setEnabled(subCase, menuLower, selected);
1082
 
9659 akron1 1083
	Menu.option(subEOL, menuCRLF, T.getEol(text) = E.EOL_CRLF);
1084
	Menu.option(subEOL, menuLF,   T.getEol(text) = E.EOL_LF);
1085
	Menu.option(subEOL, menuCR,   T.getEol(text) = E.EOL_CR);
9190 akron1 1086
 
9174 akron1 1087
    IF menu # NIL THEN
9448 akron1 1088
    	timerEnabled := FALSE;
9174 akron1 1089
        IF Menu.opened(menu) THEN
1090
            Menu.close(menu)
1091
        END;
9671 akron1 1092
        Menu.open(menu, menu.x + x, y);
9175 akron1 1093
        menuActive := TRUE
1094
    END
9174 akron1 1095
END ShowMenu;
1096
 
1097
 
9208 akron1 1098
PROCEDURE setScript (VAR script: RW.tFileName);
1099
VAR
1100
	temp: RW.tFileName;
1101
BEGIN
1102
	OpenFile(temp, ShellFilter);
1103
	IF temp # "" THEN
1104
		script := temp
1105
	END
1106
END setScript;
1107
 
1108
 
9648 akron1 1109
PROCEDURE ClickMenu;
9174 akron1 1110
VAR
9187 akron1 1111
	item: List.tItem;
8728 leency 1112
BEGIN
9648 akron1 1113
	IF Menu.MenuItem < 0 THEN
1114
		item := List.getItem(mainMenu, (-Menu.MenuItem - mainMenuBtn) MOD mainMenu.count);
1115
		IF item # NIL THEN
1116
			ShowMenu(item(Menu.tMainItem).menu)
1117
		END;
1118
		Menu.SetItem(0)
1119
	END;
1120
    CASE Menu.MenuItem OF
1121
    |0:
1122
    |menuCut:       T.key(text, ORD("X"), FALSE, TRUE)
1123
    |menuCopy:      T.key(text, ORD("C"), FALSE, TRUE)
1124
    |menuPaste:     T.key(text, ORD("V"), FALSE, TRUE)
1125
    |menuDelete:    T.key(text,       46, FALSE, FALSE)
1126
    |menuSelectAll: T.key(text, ORD("A"), FALSE, TRUE)
8728 leency 1127
 
9648 akron1 1128
    |menuNew:
1129
        NewFile
1130
    |menuOpen:
1131
        OpenDial
1132
    |menuSave:
1133
        save(text);
1134
        repaint
1135
    |menuSaveAs:
1136
        saveAs(text);
1137
        repaint
1138
    |menuSaveAll:
1139
        saveAll;
1140
        repaint
1141
    |menuClose:
1142
        closeFile(TRUE, curText)
1143
    |menuFolder:
1144
        K.Run("/sys/File Managers/Eolite", text.fileName)
1145
    |menuExit:
1146
        Close
1147
    |menuUndo:
1148
        T.undo(text);
1149
        repaint
1150
    |menuRedo:
1151
        T.redo(text);
1152
        repaint
1153
    |menuFind:
1154
        ShowSearchPanel(FALSE)
1155
    |menuFindNext:
1156
        notFound := ~T.findNext(text, BKW.value);
1157
        menuFindClicked := TRUE
1158
    |menuFindPrev:
1159
        notFound := ~T.findNext(text, ~BKW.value);
1160
        menuFindClicked := TRUE
1161
    |menuGoto:
1162
        ShowSearchPanel(TRUE)
1163
    |menuToggleBookmark:
1164
    	T.toggleLabel(text)
1165
    |menuNextBookmark:
1166
    	T.gotoLabel(text, TRUE)
1167
    |menuPrevBookmark:
1168
    	T.gotoLabel(text, FALSE)
9671 akron1 1169
    |menuFontSmall..menuFontLarge:
1170
    	font := G.fonts[Menu.MenuItem - menuFontSmall];
1171
    	Ini.setInt("settings", "font", Menu.MenuItem - menuFontSmall);
9668 akron1 1172
    	resize
9648 akron1 1173
    |menuText:
1174
        T.setLang(text, Languages.langText)
1175
    |menuC:
1176
        T.setLang(text, Languages.langC)
1177
    |menuFasm:
1178
        T.setLang(text, Languages.langFasm)
1179
    |menuIni:
1180
        T.setLang(text, Languages.langIni)
1181
    |menuJSON:
1182
        T.setLang(text, Languages.langJSON)
1183
    |menuLua:
1184
        T.setLang(text, Languages.langLua)
1185
    |menuOberon:
1186
        T.setLang(text, Languages.langOberon)
1187
    |menuPascal:
1188
        T.setLang(text, Languages.langPascal)
1189
    |menuBuild:
1190
        Script(buildScript)
1191
    |menuBuildScript:
1192
    	setScript(buildScript)
1193
    |menuRun:
1194
        Script(runScript)
1195
    |menuRunScript:
1196
    	setScript(runScript)
1197
    |menuDebug:
1198
        Script(debugScript)
1199
    |menuDebugScript:
1200
    	setScript(debugScript)
1201
    |menuUTF8BOM:
1202
    	T.setEnc(text, E.UTF8BOM)
1203
    |menuUTF8:
1204
    	T.setEnc(text, E.UTF8)
1205
    |menuCP866:
1206
    	T.setEnc(text, E.CP866)
1207
    |menuWin1251:
1208
    	T.setEnc(text, E.W1251)
1209
    |menuLF:
9659 akron1 1210
    	T.setEol(text, E.EOL_LF)
9648 akron1 1211
    |menuCRLF:
9659 akron1 1212
    	T.setEol(text, E.EOL_CRLF)
9648 akron1 1213
    |menuCR:
9659 akron1 1214
    	T.setEol(text, E.EOL_CR)
9648 akron1 1215
    |menuPipet:
1216
        K.Run("/sys/develop/pipet", "")
1217
    |menuMagnify:
1218
        K.Run("/sys/magnify", "")
1219
    |menuBoard:
1220
        K.Run("/sys/develop/board", "")
1221
    |menuSysFunc:
1222
        K.Run("/sys/docpack", "f")
9671 akron1 1223
    |menuLineNumbers:
1224
        T.toggleNumbers;
1225
        Ini.setInt("settings", "line_numbers", ORD(T.lineNumbers))
1226
    |menuAutoIndents:
1227
        T.toggleIndents;
1228
        Ini.setInt("settings", "auto_indents", ORD(T.autoIndents))
1229
    |menuAutoBrackets:
1230
        T.toggleBrackets;
1231
        Ini.setInt("settings", "auto_brackets", ORD(T.autoBrackets))
1232
    |menuTrimSpace:
1233
        T.toggleTrimSpace;
1234
        Ini.setInt("settings", "trim_space", ORD(T.trimSpace))
9648 akron1 1235
    |menuColors..menuMaxColors:
9671 akron1 1236
        Ini.selectSection(Menu.MenuItem - menuColors);
1237
        Ini.setInt("settings", "theme", Menu.MenuItem - menuColors)
9648 akron1 1238
    |menuMoveUp:
1239
    	T.MoveLines(text, FALSE)
1240
    |menuMoveDown:
1241
		T.MoveLines(text, TRUE)
1242
    |menuDuplicate:
1243
    	T.dupLine(text)
1244
    |menuRemove:
1245
    	T.delLine(text)
1246
    |menuIncInd:
1247
    	T.Indent(text, TRUE)
1248
	|menuDecInd:
1249
		T.Indent(text, FALSE)
1250
	|menuUpper:
1251
		T.chCase(text, TRUE)
1252
	|menuLower:
1253
		T.chCase(text, FALSE)
8728 leency 1254
    END;
9648 akron1 1255
    Menu.SetItem(0)
1256
END ClickMenu;
8728 leency 1257
 
1258
 
1259
PROCEDURE CreateContextMenu (): Menu.tMenu;
1260
VAR
1261
    menu: List.tList;
1262
BEGIN
1263
    menu := List.create(NIL);
1264
    Menu.AddMenuItem(menu, menuUndo,      "undo         ctrl-Z");
1265
    Menu.AddMenuItem(menu, menuRedo,      "redo         ctrl-Y");
1266
    Menu.delimiter(menu);
1267
    Menu.AddMenuItem(menu, menuCut,       "cut          ctrl-X");
1268
    Menu.AddMenuItem(menu, menuCopy,      "copy         ctrl-C");
1269
    Menu.AddMenuItem(menu, menuPaste,     "paste        ctrl-V");
1270
    Menu.AddMenuItem(menu, menuDelete,    "delete");
1271
    Menu.delimiter(menu);
1272
    Menu.AddMenuItem(menu, menuSelectAll, "select all   ctrl-A");
9648 akron1 1273
    RETURN Menu.create(menu)
8728 leency 1274
END CreateContextMenu;
1275
 
1276
 
1277
PROCEDURE CreateMenuFile (): Menu.tMenu;
1278
VAR
1279
    menu: List.tList;
1280
BEGIN
1281
    menu := List.create(NIL);
9050 leency 1282
    Menu.AddMenuItem(menu, menuNew,     "new         ctrl-N");
1283
    Menu.AddMenuItem(menu, menuOpen,    "open        ctrl-O");
1284
    Menu.AddMenuItem(menu, menuSave,    "save        ctrl-S");
1285
    Menu.AddMenuItem(menu, menuSaveAs,  "save as");
1286
    Menu.AddMenuItem(menu, menuSaveAll, "save all");
1287
    Menu.AddMenuItem(menu, menuFolder,  "folder");
8728 leency 1288
    Menu.delimiter(menu);
9060 leency 1289
    Menu.AddMenuItem(menu, menuClose,   "close       ctrl-W");
9050 leency 1290
    Menu.delimiter(menu);
1291
    Menu.AddMenuItem(menu, menuExit,    "exit");
9648 akron1 1292
    RETURN Menu.create(menu)
8728 leency 1293
END CreateMenuFile;
1294
 
1295
 
1296
PROCEDURE CreateMenuEdit (): Menu.tMenu;
1297
VAR
1298
    menu: List.tList;
1299
BEGIN
1300
    menu := List.create(NIL);
9174 akron1 1301
    Menu.AddMenuItem(menu, menuUndo,      "undo            ctrl-Z");
1302
    Menu.AddMenuItem(menu, menuRedo,      "redo            ctrl-Y");
8728 leency 1303
    Menu.delimiter(menu);
9174 akron1 1304
    Menu.AddMenuItem(menu, menuCut,       "cut             ctrl-X");
1305
    Menu.AddMenuItem(menu, menuCopy,      "copy            ctrl-C");
1306
    Menu.AddMenuItem(menu, menuPaste,     "paste           ctrl-V");
8728 leency 1307
    Menu.AddMenuItem(menu, menuDelete,    "delete");
1308
    Menu.delimiter(menu);
9174 akron1 1309
    Menu.AddMenuItem(menu, menuSelectAll, "select all      ctrl-A");
1310
    Menu.delimiter(menu);
1311
    Menu.AddMenuItem(menu, menuCurLine,   "current line");
1312
    Menu.child(menu, subCurLine);
1313
    Menu.AddMenuItem(menu, menuIndent,    "indent");
1314
    Menu.child(menu, subIndent);
1315
    Menu.AddMenuItem(menu, menuCase,      "case");
1316
    Menu.child(menu, subCase);
9648 akron1 1317
    RETURN Menu.create(menu)
8728 leency 1318
END CreateMenuEdit;
1319
 
1320
 
9174 akron1 1321
PROCEDURE CreateMenuSearch (): Menu.tMenu;
1322
VAR
1323
    menu: List.tList;
1324
BEGIN
1325
    menu := List.create(NIL);
1326
    Menu.AddMenuItem(menu, menuFind,     "search           ctrl-F");
1327
    Menu.AddMenuItem(menu, menuFindNext, "find next        F3");
1328
    Menu.AddMenuItem(menu, menuFindPrev, "find previous    shift-F3");
1329
    Menu.AddMenuItem(menu, menuGoto,     "go to line       ctrl-G");
1330
    Menu.delimiter(menu);
1331
    Menu.AddMenuItem(menu, menuBookmark, "bookmark");
1332
    Menu.child(menu, subBookmark);
9648 akron1 1333
    RETURN Menu.create(menu)
9174 akron1 1334
END CreateMenuSearch;
1335
 
1336
 
8728 leency 1337
PROCEDURE CreateMenuEncoding (): Menu.tMenu;
1338
VAR
1339
    menu: List.tList;
1340
BEGIN
1341
    menu := List.create(NIL);
9073 leency 1342
    Menu.AddMenuItem(menu, menuUTF8BOM, E.names[E.UTF8BOM]);
1343
    Menu.AddMenuItem(menu, menuUTF8,    E.names[E.UTF8]);
1344
    Menu.AddMenuItem(menu, menuCP866,   E.names[E.CP866]);
1345
    Menu.AddMenuItem(menu, menuWin1251, E.names[E.W1251]);
9190 akron1 1346
    Menu.delimiter(menu);
1347
    Menu.AddMenuItem(menu, menuEOL,     "EOL");
1348
    Menu.child(menu, subEOL);
9648 akron1 1349
    RETURN Menu.create(menu)
8728 leency 1350
END CreateMenuEncoding;
1351
 
1352
 
9180 akron1 1353
PROCEDURE CreateMenuEOL (): Menu.tMenu;
1354
VAR
1355
    menu: List.tList;
1356
BEGIN
1357
    menu := List.create(NIL);
9659 akron1 1358
    Menu.AddMenuItem(menu, menuCRLF, E.eolNames[E.EOL_CRLF]);
1359
    Menu.AddMenuItem(menu, menuLF,   E.eolNames[E.EOL_LF]);
1360
    Menu.AddMenuItem(menu, menuCR,   E.eolNames[E.EOL_CR]);
9648 akron1 1361
    RETURN Menu.create(menu)
9180 akron1 1362
END CreateMenuEOL;
1363
 
1364
 
8728 leency 1365
PROCEDURE CreateMenuView (): Menu.tMenu;
1366
VAR
1367
    menu: List.tList;
1368
    colors: Ini.tSection;
1369
    idx: INTEGER;
1370
BEGIN
1371
    menu := List.create(NIL);
9668 akron1 1372
    Menu.AddMenuItem(menu, menuFontSmall,  "small");
1373
    Menu.AddMenuItem(menu, menuFontMedium, "medium");
9671 akron1 1374
    Menu.AddMenuItem(menu, menuFontLarge,  "large");
9668 akron1 1375
    Menu.delimiter(menu);
8728 leency 1376
 
1377
    colors := Ini.sections.first(Ini.tSection);
1378
    idx := menuColors;
1379
    WHILE colors # NIL DO
1380
        Menu.AddMenuItem(menu, idx, colors.name);
1381
        INC(idx);
1382
        colors := colors.next(Ini.tSection)
1383
    END;
1384
 
9648 akron1 1385
    RETURN Menu.create(menu)
8728 leency 1386
END CreateMenuView;
1387
 
1388
 
9190 akron1 1389
PROCEDURE CreateMenuLanguage (): Menu.tMenu;
8728 leency 1390
VAR
1391
    menu: List.tList;
1392
BEGIN
1393
    menu := List.create(NIL);
1394
    Menu.AddMenuItem(menu, menuC,      "C");
1395
    Menu.AddMenuItem(menu, menuFasm,   "Fasm");
1396
    Menu.AddMenuItem(menu, menuIni,    "Ini");
9174 akron1 1397
    Menu.AddMenuItem(menu, menuJSON,   "JSON");
8728 leency 1398
    Menu.AddMenuItem(menu, menuLua,    "Lua");
1399
    Menu.AddMenuItem(menu, menuOberon, "Oberon");
1400
    Menu.AddMenuItem(menu, menuPascal, "Pascal");
1401
    Menu.delimiter(menu);
9190 akron1 1402
    Menu.AddMenuItem(menu, menuText,   "Text");
9648 akron1 1403
    RETURN Menu.create(menu)
9190 akron1 1404
END CreateMenuLanguage;
8728 leency 1405
 
1406
 
1407
PROCEDURE CreateMenuProgram (): Menu.tMenu;
1408
VAR
1409
    menu: List.tList;
1410
BEGIN
1411
    menu := List.create(NIL);
9174 akron1 1412
    Menu.AddMenuItem(menu, menuBuild,       "build    ctrl-F9");
8728 leency 1413
    Menu.AddMenuItem(menu, menuBuildScript, "script");
1414
    Menu.delimiter(menu);
1415
    Menu.AddMenuItem(menu, menuRun,         "run           F9");
1416
    Menu.AddMenuItem(menu, menuRunScript,   "script");
1417
    Menu.delimiter(menu);
1418
    Menu.AddMenuItem(menu, menuDebug,       "debug");
1419
    Menu.AddMenuItem(menu, menuDebugScript, "script");
9648 akron1 1420
    RETURN Menu.create(menu)
8728 leency 1421
END CreateMenuProgram;
1422
 
1423
 
1424
PROCEDURE CreateMenuTools (): Menu.tMenu;
1425
VAR
1426
    menu: List.tList;
1427
BEGIN
1428
    menu := List.create(NIL);
1429
    Menu.AddMenuItem(menu, menuPipet,   "pipet");
9457 akron1 1430
    Menu.AddMenuItem(menu, menuMagnify, "magnify");
9073 leency 1431
    Menu.AddMenuItem(menu, menuBoard,   "board");
8728 leency 1432
    Menu.AddMenuItem(menu, menuSysFunc, "system functions");
9648 akron1 1433
    RETURN Menu.create(menu)
8728 leency 1434
END CreateMenuTools;
1435
 
1436
 
9671 akron1 1437
PROCEDURE CreateMenuOptions (): Menu.tMenu;
1438
VAR
1439
    menu: List.tList;
1440
BEGIN
1441
    menu := List.create(NIL);
1442
    Menu.AddMenuItem(menu, menuLineNumbers,  "line numbers");
1443
    Menu.AddMenuItem(menu, menuAutoIndents,  "automatic indents");
1444
    Menu.AddMenuItem(menu, menuAutoBrackets, "automatic brackets");
1445
    Menu.AddMenuItem(menu, menuTrimSpace,    "trim trailing space");
1446
    RETURN Menu.create(menu)
1447
END CreateMenuOptions;
1448
 
1449
 
9174 akron1 1450
PROCEDURE CreateMenuCurLine(): Menu.tMenu;
8728 leency 1451
VAR
9174 akron1 1452
    menu: List.tList;
8728 leency 1453
BEGIN
9174 akron1 1454
    menu := List.create(NIL);
1455
    Menu.AddMenuItem(menu, menuMoveUp,    "move up     ctrl-Up");
1456
    Menu.AddMenuItem(menu, menuMoveDown,  "move down   ctrl-Down");
1457
    Menu.AddMenuItem(menu, menuDuplicate, "duplicate   ctrl-D");
1458
    Menu.AddMenuItem(menu, menuRemove,    "remove      ctrl-Del");
9648 akron1 1459
    RETURN Menu.create(menu)
9174 akron1 1460
END CreateMenuCurLine;
8728 leency 1461
 
1462
 
9174 akron1 1463
PROCEDURE CreateMenuIndent(): Menu.tMenu;
8728 leency 1464
VAR
9174 akron1 1465
    menu: List.tList;
8728 leency 1466
BEGIN
9174 akron1 1467
    menu := List.create(NIL);
1468
    Menu.AddMenuItem(menu, menuIncInd, "increase    Tab");
1469
    Menu.AddMenuItem(menu, menuDecInd, "decrease    shift-Bksp");
9648 akron1 1470
    RETURN Menu.create(menu)
9174 akron1 1471
END CreateMenuIndent;
8728 leency 1472
 
1473
 
9174 akron1 1474
PROCEDURE CreateMenuCase(): Menu.tMenu;
1475
VAR
1476
    menu: List.tList;
1477
BEGIN
1478
    menu := List.create(NIL);
1479
    Menu.AddMenuItem(menu, menuUpper, "UPPER    ctrl-U");
1480
    Menu.AddMenuItem(menu, menuLower, "lower    ctrl-L");
9648 akron1 1481
    RETURN Menu.create(menu)
9174 akron1 1482
END CreateMenuCase;
8728 leency 1483
 
1484
 
9174 akron1 1485
PROCEDURE CreateMenuBookmark(): Menu.tMenu;
1486
VAR
1487
    menu: List.tList;
1488
BEGIN
1489
    menu := List.create(NIL);
1490
    Menu.AddMenuItem(menu, menuToggleBookmark, "toggle      ctrl-F2");
1491
    Menu.AddMenuItem(menu, menuNextBookmark,   "next        F2");
1492
    Menu.AddMenuItem(menu, menuPrevBookmark,   "previous    shift-F2");
9648 akron1 1493
    RETURN Menu.create(menu)
9174 akron1 1494
END CreateMenuBookmark;
1495
 
1496
 
9648 akron1 1497
PROCEDURE Shortcuts;
1498
BEGIN
1499
    Menu.AddShortcut(17 + CTRL,  menuClose);
1500
    Menu.AddShortcut(21 + CTRL,  menuRedo);
1501
    Menu.AddShortcut(30 + CTRL,  menuSelectAll);
1502
    Menu.AddShortcut(32 + CTRL,  menuDuplicate);
1503
    Menu.AddShortcut(33 + CTRL,  menuFind);
1504
    Menu.AddShortcut(35 + CTRL,  menuFind);
1505
    Menu.AddShortcut(34 + CTRL,  menuGoto);
1506
    Menu.AddShortcut(44 + CTRL,  menuUndo);
1507
    Menu.AddShortcut(45 + CTRL,  menuCut);
1508
    Menu.AddShortcut(46 + CTRL,  menuCopy);
1509
    Menu.AddShortcut(47 + CTRL,  menuPaste);
1510
    Menu.AddShortcut(24 + CTRL,  menuOpen);
1511
    Menu.AddShortcut(31 + CTRL,  menuSave);
1512
    Menu.AddShortcut(49 + CTRL,  menuNew);
1513
    Menu.AddShortcut(67 + CTRL,  menuBuild);
1514
    Menu.AddShortcut(83 + CTRL,  menuRemove);
1515
    Menu.AddShortcut(22 + CTRL,  menuUpper);
1516
    Menu.AddShortcut(38 + CTRL,  menuLower);
1517
    Menu.AddShortcut(60 + CTRL,  menuToggleBookmark);
1518
    Menu.AddShortcut(72 + CTRL,  menuMoveUp);
1519
    Menu.AddShortcut(80 + CTRL,  menuMoveDown);
1520
    Menu.AddShortcut(83,         menuDelete);
1521
    Menu.AddShortcut(67,         menuRun);
1522
    Menu.AddShortcut(15,         menuIncInd);
1523
    Menu.AddShortcut(14 + SHIFT, menuDecInd);
1524
    Menu.AddShortcut(60 + SHIFT, menuPrevBookmark);
1525
    Menu.AddShortcut(60,         menuNextBookmark);
1526
    Menu.AddShortcut(61 + SHIFT, menuFindPrev);
1527
    Menu.AddShortcut(61,         menuFindNext);
1528
END Shortcuts;
1529
 
1530
 
9190 akron1 1531
PROCEDURE HideSearch;
1532
BEGIN
1533
    SetFocus(FindEdit, FALSE);
1534
    searchOpened := FALSE;
9457 akron1 1535
    LEFT := LEFT_PADDING;
9190 akron1 1536
    resize;
1537
    draw_window
1538
END HideSearch;
1539
 
1540
 
9073 leency 1541
PROCEDURE KeyDown (key: INTEGER);
1542
VAR
1543
    keyCode: INTEGER;
1544
    shift, ctrl: BOOLEAN;
1545
BEGIN
9187 akron1 1546
	K.getKBState(shift, ctrl);
9073 leency 1547
    keyCode := key DIV 65536;
1548
    IF confirm THEN
1549
        IF keyCode = 28 THEN (* Enter *)
1550
            save(text);
1551
            IF ~text.modified THEN
1552
                closeFile(FALSE, curText)
1553
            END
1554
        END;
1555
        key := -1
1556
    ELSE
1557
        IF keyCode = 61 THEN (* F3 *)
1558
            key := -1;
1559
            IF search & (searchText # "") THEN
1560
                IF shift THEN
9182 akron1 1561
                    notFound := ~T.findNext(text, ~BKW.value)
9073 leency 1562
                ELSE
9182 akron1 1563
                    notFound := ~T.findNext(text, BKW.value)
9073 leency 1564
                END
1565
            END
1566
        ELSIF keyCode = 60 THEN (* F2 *)
1567
            key := -1;
1568
            IF ctrl THEN
1569
                T.toggleLabel(text)
1570
            ELSE
1571
                T.gotoLabel(text, ~shift)
1572
            END
1573
        ELSIF keyCode = 67 THEN (* F9 *)
1574
            key := -1;
1575
            IF ctrl THEN
1576
                Script(buildScript)
1577
            ELSE
1578
                Script(runScript)
1579
            END
9187 akron1 1580
        ELSIF keyCode = 68 THEN (* F10 *)
9190 akron1 1581
        	IF shift THEN
1582
        		ShowMenu(context)
1583
        	ELSE
1584
        		ShowMenu(menuFile)
1585
        	END;
1586
            key := -1
9073 leency 1587
        ELSIF keyCode = 1 THEN (* Esc *)
1588
            IF search THEN
9190 akron1 1589
            	IF shift THEN
1590
            		HideSearch
1591
            	ELSE
1592
                	Search
1593
                END
1594
            END;
1595
            key := -1
9073 leency 1596
        ELSIF (keyCode = 55) & (key DIV 256 MOD 256 = 52) THEN (* PrtScn *)
1597
            key := -1
9174 akron1 1598
        ELSIF (keyCode = 14) & shift THEN (* shift+Backspace *)
1599
            key := -1;
1600
            T.input(text, -8)
9073 leency 1601
        ELSIF (keyCode = 15) & ctrl THEN (* ctrl+Tab *)
1602
            key := -1;
1603
            SwitchTab((curText + 1) MOD textsCount)
9336 akron1 1604
        ELSIF ((keyCode = 33) OR (keyCode = 35)) & ctrl THEN (* ctrl+F, ctrl+H*)
9073 leency 1605
            key := -1;
9197 akron1 1606
            ShowSearchPanel(FALSE)
9336 akron1 1607
        ELSIF (keyCode = 34) & ctrl THEN (* ctrl+G *)
9073 leency 1608
            key := -1;
9197 akron1 1609
            ShowSearchPanel(TRUE)
9410 akron1 1610
        ELSIF (keyCode = 18) & ctrl THEN (* ctrl+E *)
1611
            key := -1;
1612
            T.selectWord(text)
9073 leency 1613
        ELSE
1614
            IF EditBox_Focus(FindEdit) THEN
9336 akron1 1615
            	IF keyCode = 15 THEN (* Tab *)
1616
            		SetFocus(ReplaceEdit, TRUE)
1617
            	ELSE
1618
	                EB.key(FindEdit, key);
9659 akron1 1619
	                EditBox_Get(FindEdit, new_searchText);
9336 akron1 1620
	                IF new_searchText # searchText THEN
1621
	                    searchText := new_searchText;
1622
	                    notFound := ~T.search(text, searchText, cs, whole)
1623
	                END
9073 leency 1624
                END
1625
            ELSIF EditBox_Focus(ReplaceEdit) THEN
9336 akron1 1626
            	IF keyCode = 15 THEN (* Tab *)
1627
            		SetFocus(GotoEdit, TRUE)
1628
            	ELSE
1629
                	EB.key(ReplaceEdit, key);
9659 akron1 1630
                	EditBox_Get(ReplaceEdit, replaceText)
9336 akron1 1631
                END
9073 leency 1632
            ELSIF EditBox_Focus(GotoEdit) THEN
9336 akron1 1633
            	IF keyCode = 15 THEN (* Tab *)
1634
            		SetFocus(FindEdit, TRUE)
1635
            	ELSE
1636
	                IF (key DIV 256) MOD 256 = 13 THEN
1637
	                    goto
1638
	                ELSE
1639
	                    EB.key(GotoEdit, key)
1640
	                END
9073 leency 1641
                END
1642
            ELSE
1643
                CASE keyCode OF
1644
                |73: key := 33
1645
                |81: key := 34
1646
                |71: key := 36
1647
                |79: key := 35
1648
                |72: key := 38
1649
                |80: key := 40
1650
                |75: key := 37
1651
                |77: key := 39
9174 akron1 1652
                |82, 91, 219, 92, 220: key := -1 (* insert, windows *)
1653
                |93: ShowMenu(context); key := -1
9073 leency 1654
                |83: key := 46
9208 akron1 1655
                |59, 62..66, 87, 88: key := -1 (* F1, F4..F8, F11, F12 *)
9073 leency 1656
                ELSE
1657
                    IF ctrl THEN
1658
                        CASE keyCode OF
1659
                        |17: closeFile(TRUE, curText);
1660
                             key := -2
1661
                        |21: T.redo(text);
1662
                             key := -1
1663
                        |22: key := ORD("U")
1664
                        |24: key := -1;
9628 akron1 1665
                             OpenDial
9073 leency 1666
                        |30: key := ORD("A")
1667
                        |31: key := -1;
1668
                             save(text)
1669
                        |32: key := ORD("D")
1670
                        |38: key := ORD("L")
1671
                        |44: T.undo(text);
1672
                             key := -1
1673
                        |45: key := ORD("X")
1674
                        |46: key := ORD("C")
1675
                        |47: key := ORD("V")
9431 akron1 1676
                        |49,
1677
                         20: key := -1;
9073 leency 1678
                             NewFile
1679
                        ELSE
1680
                            key := -1
1681
                        END
1682
                    ELSE
1683
                        T.input(text, E.cp866[key DIV 256 MOD 256]);
1684
                        key := -1
1685
                    END
1686
                END;
1687
                IF key >= 0 THEN
1688
                    T.key(text, key, shift, ctrl)
1689
                END
1690
            END
1691
        END
1692
    END;
1693
    IF key # -2 THEN
1694
        repaint
1695
    END
1696
END KeyDown;
1697
 
1698
 
1699
PROCEDURE BtnClick;
1700
VAR
1701
    btn: INTEGER;
1702
    middle, exit: BOOLEAN;
9187 akron1 1703
    menu: Menu.tMenu;
9073 leency 1704
BEGIN
9648 akron1 1705
	exit := FALSE;
9073 leency 1706
    btn := K.ButtonCode(middle);
9187 akron1 1707
    IF U.between(Tabs.btnID, btn, Tabs.btnID + maxTexts - 1) THEN
9073 leency 1708
        DEC(btn, Tabs.btnID);
1709
        IF middle THEN
1710
            IF texts[btn].modified THEN
1711
                SwitchTab(btn)
1712
            END;
1713
            closeFile(TRUE, btn)
1714
        ELSE
1715
            SwitchTab(btn)
1716
        END;
1717
        btn := 0
1718
    ELSE
1719
        IF middle THEN
1720
            btn := 0
1721
        END
1722
    END;
9187 akron1 1723
    IF btn # 0 THEN
1724
    	menu := Menu.ClickMain(mainMenu, btn);
1725
    	IF menu # NIL THEN
1726
    		ShowMenu(menu);
1727
    		btn := 0
1728
    	END
1729
    END;
9648 akron1 1730
 
9073 leency 1731
    CASE btn OF
1732
    |0:
9648 akron1 1733
    |Tabs.btnLeft, Tabs.btnRight:
1734
    	Tabs.scroll(tabs, btn);
1735
    	switch := TRUE
9073 leency 1736
    |btnNo:
1737
        exit := closing;
1738
        closeFile(FALSE, curText);
9648 akron1 1739
        repaint
9073 leency 1740
    |btnYes:
1741
        exit := closing;
1742
        save(text);
1743
        IF ~text.modified THEN
1744
            closeFile(FALSE, curText)
1745
        END;
9648 akron1 1746
        repaint
9073 leency 1747
    |btnClose:
9648 akron1 1748
    	exit := TRUE
9073 leency 1749
    |btnNew:
9648 akron1 1750
        NewFile
9073 leency 1751
    |btnOpen:
9628 akron1 1752
        OpenDial
9073 leency 1753
    |btnSave:
9648 akron1 1754
        save(text)
9073 leency 1755
    |btnSearch:
9648 akron1 1756
        ShowSearchPanel(FALSE)
9190 akron1 1757
    |btnCloseSearch:
9073 leency 1758
        Search
9190 akron1 1759
    |btnHideSearch:
1760
        HideSearch
9073 leency 1761
    |btnUndo:
9648 akron1 1762
        T.undo(text)
9073 leency 1763
    |btnRedo:
9648 akron1 1764
        T.redo(text)
9073 leency 1765
    |btnUpper:
9648 akron1 1766
        T.chCase(text, TRUE)
9073 leency 1767
    |btnLower:
9648 akron1 1768
        T.chCase(text, FALSE)
9073 leency 1769
    |btnBuild:
1770
        Script(buildScript)
1771
    |btnRun:
1772
        Script(runScript)
1773
    |btnFindNext:
1774
        IF searchText # "" THEN
9182 akron1 1775
            notFound := ~T.findNext(text, BKW.value);
9648 akron1 1776
            SetFocus(FindEdit, FALSE)
9073 leency 1777
        END
1778
    |btnReplace:
1779
        T.replace(text, replaceText, LENGTH(searchText));
9648 akron1 1780
        SetFocus(FindEdit, FALSE)
9073 leency 1781
    |btnReplaceAll:
1782
        notFound := ~T.search(text, searchText, cs, whole);
1783
        IF ~notFound THEN
1784
            replaced := T.replaceAll(text, replaceText, LENGTH(searchText));
1785
        END;
9648 akron1 1786
        SetFocus(FindEdit, FALSE)
9073 leency 1787
    |btnGoto:
9648 akron1 1788
        goto
1789
    END;
1790
 
9668 akron1 1791
    IF ~middle THEN
1792
		IF exit THEN
1793
			Close
1794
		ELSE
1795
			repaint
1796
		END
9648 akron1 1797
	END
9073 leency 1798
END BtnClick;
1799
 
1800
 
1801
PROCEDURE MouseEvent (VAR resized: BOOLEAN; VAR firstClickX, firstClickY, time: INTEGER);
1802
CONST
1803
    DELAY = 10;
1804
VAR
1805
    msState: SET;
1806
    scroll, x, y, scrollX, scrollY: INTEGER;
9210 akron1 1807
    pos1, pos2: T.tPoint;
9073 leency 1808
 
1809
 
9210 akron1 1810
    PROCEDURE EditBox (VAR eb: EB.tEditBox);
9073 leency 1811
    VAR
1812
        focus: BOOLEAN;
1813
    BEGIN
1814
        focus := EditBox_Focus(eb);
9187 akron1 1815
        EB.mouse(eb);
9073 leency 1816
        IF focus # EditBox_Focus(eb) THEN
9174 akron1 1817
            SetFocus(eb, TRUE);
1818
            repaint
9073 leency 1819
        END
1820
    END EditBox;
1821
 
1822
 
1823
BEGIN
9174 akron1 1824
	CloseMenu;
9073 leency 1825
    IF ~resized THEN
1826
        msState := K.MouseState();
1827
        IF ~(0 IN msState) OR (16 IN msState) THEN
9208 akron1 1828
        	leftButton := FALSE
9073 leency 1829
        END;
1830
        scroll := K.Scroll();
1831
        IF scroll # 0 THEN
1832
            T.scroll(text, 0, scroll*3);
1833
            repaint
1834
        END;
1835
        IF leftButton THEN
1836
            IF K.GetTickCount() - time >= DELAY THEN
9210 akron1 1837
            	T.getPos(text, pos1.Y, pos1.X);
9073 leency 1838
                mouse(x, y);
1839
                T.mouse(text, x, y);
9210 akron1 1840
                T.getPos(text, pos2.Y, pos2.X);
1841
                IF (pos1.X # pos2.X) OR (pos1.Y # pos2.Y) THEN
1842
                	repaint
1843
                END
9073 leency 1844
            END
1845
        END;
9208 akron1 1846
 
1847
		Scroll.mouse(hScroll);
1848
		Scroll.mouse(vScroll);
9648 akron1 1849
		msState := K.MouseState();
9208 akron1 1850
        T.getScroll(text, scrollX, scrollY);
1851
        IF (hScroll.value # scrollX) OR (vScroll.value # scrollY) THEN
1852
			T.scroll(text, hScroll.value - scrollX, vScroll.value - scrollY);
1853
        	repaint
1854
        END;
1855
 
9073 leency 1856
        IF (8 IN msState) & ~(24 IN msState) THEN
1857
            mouse(firstClickX, firstClickY);
1858
            time := click(firstClickX, firstClickY)
1859
        END;
1860
        IF 9 IN msState THEN
1861
            ShowMenu(context)
1862
        END;
1863
        IF 24 IN msState THEN
1864
            mouse(x, y);
9208 akron1 1865
            IF U.between(-4, x - firstClickX, 4) & U.between(-4, y - firstClickY, 4) THEN
1866
                IF U.between(0, x, canvas.width - 1) & U.between(0, y, canvas.height - 1) THEN
9073 leency 1867
                    leftButton := FALSE;
1868
                    T.selectWord(text);
1869
                    repaint
9431 akron1 1870
                ELSIF Tabs.DblClicked(tabs, x + LEFT, y + TOP) THEN
1871
                	leftButton := FALSE;
1872
                	NewFile;
1873
                	repaint
9073 leency 1874
                END
1875
            ELSE
1876
                firstClickX := x;
1877
                firstClickY := y;
1878
                time := click(firstClickX, firstClickY)
1879
            END
1880
        END
1881
    END;
1882
    IF search & searchOpened THEN
9208 akron1 1883
	    CheckBox.mouse(BKW);
1884
    	CheckBox.mouse(CS);
1885
    	CheckBox.mouse(WH);
9073 leency 1886
        EditBox(FindEdit);
1887
        EditBox(ReplaceEdit);
1888
        EditBox(GotoEdit);
9208 akron1 1889
        IF (CS.value # cs) OR (WH.value # whole) THEN
1890
            cs := CS.value;
1891
            whole := WH.value;
9073 leency 1892
            notFound := ~T.search(text, searchText, cs, whole);
1893
            repaint
1894
        END
1895
    END;
1896
    resized := FALSE
1897
END MouseEvent;
1898
 
1899
 
1900
PROCEDURE Redraw (VAR resized: BOOLEAN; VAR width, height, cliWidth, cliHeight: INTEGER);
9648 akron1 1901
VAR
1902
	onClose: BOOLEAN;
9073 leency 1903
BEGIN
9648 akron1 1904
	onClose := (Menu.MenuItem = menuClose) OR (Menu.MenuItem = menuExit);
1905
	IF ~onClose THEN
1906
		ClickMenu
1907
	END;
9628 akron1 1908
	K.GetSystemColors;
1909
	IF ~K.RolledUp() THEN
1910
		K.ClientSize(width, height);
1911
		IF (width # cliWidth) OR (height # cliHeight) THEN
1912
			cliWidth := width;
1913
			cliHeight := height;
1914
			resize;
1915
			resized := TRUE
9659 akron1 1916
		END
9628 akron1 1917
	ELSE
9659 akron1 1918
		SetCaption(text.fileName)
9628 akron1 1919
	END;
1920
	draw_window;
1921
	IF SkinHeight # K.SkinHeight() THEN
1922
		SkinHeight := K.SkinHeight();
1923
		Redraw(resized, width, height, cliWidth, cliHeight)
9648 akron1 1924
	END;
1925
	IF onClose THEN
1926
		ClickMenu
9628 akron1 1927
	END
9073 leency 1928
END Redraw;
1929
 
1930
 
9208 akron1 1931
PROCEDURE ScrollChange;
1932
BEGIN
9648 akron1 1933
	T.scroll(text, hScroll.btn, vScroll.btn);
9208 akron1 1934
	IF menuActive THEN
1935
		draw_window;
1936
		menuActive := FALSE
1937
	ELSE
1938
		repaint
1939
	END
1940
END ScrollChange;
1941
 
1942
 
8728 leency 1943
PROCEDURE main;
1944
VAR
1945
    fileName, filePath: RW.tFileName;
9073 leency 1946
    width, height, cliWidth, cliHeight: INTEGER;
1947
    resized: BOOLEAN;
9628 akron1 1948
    firstClickX, firstClickY, time, blink, i: INTEGER;
9659 akron1 1949
    key, scr: INTEGER;
8728 leency 1950
BEGIN
9526 akron1 1951
	header := "";
8762 leency 1952
    K.GetSystemColors;
9050 leency 1953
    switch := FALSE;
9073 leency 1954
    closing := FALSE;
9050 leency 1955
    textsCount := 0;
1956
    curText := 0;
9628 akron1 1957
    Args.GetArg(0, AppPath);
8728 leency 1958
    Ini.load(AppPath);
9671 akron1 1959
    Ini.getSettings;
1960
    runScript := Ini.runScript;
1961
    buildScript := Ini.buildScript;
1962
    debugScript := Ini.debugScript;
9208 akron1 1963
    leftButton := FALSE;
8728 leency 1964
    resized := FALSE;
8772 leency 1965
    K.ScreenSize(winWidth, winHeight);
9668 akron1 1966
    scrollWidth := winHeight DIV 35;
9050 leency 1967
    winWidth := (winWidth*80) DIV 100 - (128 + 30);
8772 leency 1968
    winHeight := winHeight - (128 + 30);
1969
    winWidth := MAX(winWidth, minWinWidth);
1970
    winHeight := MAX(winHeight, minWinHeight);
8762 leency 1971
    cliWidth := winWidth;
1972
    cliHeight := winHeight;
9668 akron1 1973
 
9457 akron1 1974
    LEFT := LEFT_PADDING;
9668 akron1 1975
    RIGHT := scrollWidth - 2;
1976
    BOTTOM := SB.height() + scrollWidth - 1;
9628 akron1 1977
    SkinHeight := K.SkinHeight();
1978
    canvas := G.CreateCanvas(winWidth - (LEFT + RIGHT + 11 + RIGHT_PADDING), winHeight - (TOP + BOTTOM + 5) - SkinHeight);
9050 leency 1979
    tabs := Tabs.create();
1980
    Tabs.setArea(tabs, LEFT, TOP - Tabs.tabHeight, canvas.width, Tabs.tabHeight);
9671 akron1 1981
    font := G.fonts[Ini.font];
8728 leency 1982
    G.SetFont(canvas, font);
9671 akron1 1983
    T.init(resetTimer, Ini.lineNumbers, Ini.autoIndents, Ini.autoBrackets, Ini.trimSpace);
1984
    Ini.selectSection(Ini.theme);
8728 leency 1985
    T.setCanvas(canvas);
9180 akron1 1986
 
9648 akron1 1987
    Menu.init(resetTimer);
8728 leency 1988
    context := CreateContextMenu();
1989
    menuFile := CreateMenuFile();
9174 akron1 1990
    subCurLine := CreateMenuCurLine();
1991
    subIndent := CreateMenuIndent();
1992
    subCase := CreateMenuCase();
8728 leency 1993
    menuEdit := CreateMenuEdit();
9174 akron1 1994
    subCurLine.parent := menuEdit;
1995
    subIndent.parent := menuEdit;
1996
    subCase.parent := menuEdit;
1997
    subBookmark := CreateMenuBookmark();
1998
    menuSearch := CreateMenuSearch();
1999
    subBookmark.parent := menuSearch;
9190 akron1 2000
    subEOL := CreateMenuEOL();
8728 leency 2001
    menuEncoding := CreateMenuEncoding();
9190 akron1 2002
    subEOL.parent := menuEncoding;
8728 leency 2003
    menuView := CreateMenuView();
9190 akron1 2004
    menuLanguage := CreateMenuLanguage();
8728 leency 2005
    menuProgram := CreateMenuProgram();
2006
    menuTools := CreateMenuTools();
9671 akron1 2007
    menuOptions := CreateMenuOptions();
9174 akron1 2008
 
9187 akron1 2009
    mainMenu := Menu.CreateMain(mainMenuBtn);
2010
    Menu.AddMainItem(mainMenu, "file", menuFile);
2011
    Menu.AddMainItem(mainMenu, "edit", menuEdit);
2012
    Menu.AddMainItem(mainMenu, "search", menuSearch);
2013
    Menu.AddMainItem(mainMenu, "encoding", menuEncoding);
2014
    Menu.AddMainItem(mainMenu, "view", menuView);
9190 akron1 2015
    Menu.AddMainItem(mainMenu, "language", menuLanguage);
9187 akron1 2016
    Menu.AddMainItem(mainMenu, "program", menuProgram);
2017
    Menu.AddMainItem(mainMenu, "tools", menuTools);
9671 akron1 2018
    Menu.AddMainItem(mainMenu, "options", menuOptions);
9648 akron1 2019
    Shortcuts;
9187 akron1 2020
 
9522 akron1 2021
    Toolbar.create(toolbar, LEFT_PADDING + 5, toolbarTop);
9448 akron1 2022
    Toolbar.add(toolbar, btnNew,     2, "");
2023
    Toolbar.add(toolbar, btnOpen,    0, "");
2024
    Toolbar.add(toolbar, btnSave,    5, "");
2025
    Toolbar.delimiter(toolbar);
2026
    Toolbar.add(toolbar, btnSearch, 49, "");
2027
    Toolbar.delimiter(toolbar);
2028
    Toolbar.add(toolbar, btnUndo,   37, "");
2029
    Toolbar.add(toolbar, btnRedo,   36, "");
2030
    Toolbar.delimiter(toolbar);
2031
    Toolbar.add(toolbar, btnUpper,  -1, "AB");
2032
    Toolbar.add(toolbar, btnLower,  -1, "ab");
2033
    Toolbar.delimiter(toolbar);
2034
    Toolbar.add(toolbar, btnBuild,  54, "");
2035
    Toolbar.add(toolbar, btnRun,    53, "");
2036
 
9628 akron1 2037
    filePath := "/sys";
2038
    IF Args.argc = 1 THEN
8728 leency 2039
        text := T.New();
9628 akron1 2040
        insert(0, text);
2041
        T.SetPos(text, 0, 0)
8728 leency 2042
    END;
9628 akron1 2043
	FOR i := 1 TO Args.argc - 1 DO
2044
		Args.GetArg(i, fileName);
2045
		IF open(fileName) THEN
2046
			U.getPath(fileName, filePath)
2047
		END
2048
	END;
2049
	IF textsCount = 0 THEN
2050
		K.Exit
2051
	END;
2052
	SwitchTab(textsCount - 1);
2053
 
9648 akron1 2054
    Scroll.create(FALSE, canvas.width + 1, scrollWidth, scrollWidth, scrollWidth*3 DIV 2, ScrollChange, hScroll);
2055
    Scroll.create(TRUE, scrollWidth, canvas.height + 2, scrollWidth, scrollWidth*3 DIV 2, ScrollChange, vScroll);
8728 leency 2056
    T.resize(canvas.width, canvas.height);
2057
    confirm := FALSE;
2058
    notFound := FALSE;
9175 akron1 2059
    menuFindClicked := FALSE;
2060
    menuActive := FALSE;
8728 leency 2061
    search := FALSE;
9073 leency 2062
    searchOpened := FALSE;
8728 leency 2063
    createSearchForm;
2064
    new_searchText := "";
2065
    searchText := "";
2066
    cs := FALSE;
2067
    whole := FALSE;
2068
    replaced := 0;
9628 akron1 2069
 
2070
	OD := OpenDlg.Create(draw_window, OpenDlg.topen, filePath, "");
2071
 
9648 akron1 2072
    K.SetEventsMask({0, 1, 2, 5, 31});
8728 leency 2073
    draw_window;
9599 akron1 2074
    blink := Ini.blink;
2075
	IF blink <= 0 THEN
2076
		blink := 0
2077
	ELSIF blink < 30 THEN
2078
		blink := 30
2079
	END;
9448 akron1 2080
    timerEnabled := TRUE;
2081
    CursorTime := K.GetTickCount();
8728 leency 2082
    WHILE TRUE DO
9659 akron1 2083
 
9448 akron1 2084
    	CurrentTime := K.GetTickCount();
9659 akron1 2085
    	IF (CurrentTime - CursorTime > blink) & (blink > 0) & timerEnabled & ~K.RolledUp() THEN
9448 akron1 2086
    		CursorTime := CurrentTime;
9668 akron1 2087
    		T.cursor(text);
2088
    		drawText
9448 akron1 2089
    	END;
9648 akron1 2090
 
9448 akron1 2091
        CASE K.EventTimeout(10) OF
2092
        |0:
9190 akron1 2093
        |1:	Redraw(resized, width, height, cliWidth, cliHeight)
9659 akron1 2094
        |2:
2095
        	key := K.GetKey();
2096
        	IF ~K.RolledUp() THEN
2097
        		KeyDown(key)
2098
        	END
9073 leency 2099
        |3: BtnClick
9659 akron1 2100
        |6:
2101
        	IF ~K.RolledUp() THEN
2102
        		MouseEvent(resized, firstClickX, firstClickY, time)
2103
        	ELSE
2104
        		scr := K.Scroll()
2105
        	END
8728 leency 2106
        END
2107
    END
2108
END main;
2109
 
2110
 
2111
BEGIN
2112
    main
2113
END CEdit.