Subversion Repositories Kolibri OS

Rev

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