Subversion Repositories Kolibri OS

Rev

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

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