Subversion Repositories Kolibri OS

Rev

Rev 9180 | Rev 9182 | 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
9181 akron1 31
    header = "CEdit (07-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
 
9181 akron1 84
    minWinWidth = 635; minWinHeight = 550;
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;
9181 akron1 253
		Timer.kill
9174 akron1 254
	ELSE
255
		T.showCursor;
9181 akron1 256
		Timer.create(mainTID)
9174 akron1 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
9181 akron1 301
	Timer.kill;
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;
9181 akron1 414
    K.DrawRect(x, TOP + canvas.height + scrollWidth, 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;
9181 akron1 434
    K.DrawRect(LEFT + 16*fontWidth, TOP + canvas.height + scrollWidth, width - LEFT - 24*fontWidth, BOTTOM - scrollWidth + 1, K.winColor);
9050 leency 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;
9181 akron1 474
        K.DrawRect(LEFT, TOP + canvas.height + scrollWidth, 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);
9181 akron1 482
        DrawScroll(vScroll, LEFT + canvas.width, TOP - 1, scrollY, text.count - 1);
483
        DrawScroll(hScroll, LEFT, TOP + canvas.height, 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);
9181 akron1 508
    canvas := G.CreateCanvas(cliWidth - (LEFT + RIGHT + 2), cliHeight - (TOP + BOTTOM + 1));
509
    Tabs.setArea(tabs, LEFT, TOP - Tabs.tabHeight, cliWidth - (LEFT + RIGHT + 2), Tabs.tabHeight);
8728 leency 510
    G.SetFont(canvas, font);
511
    T.setCanvas(canvas);
512
    T.resize(canvas.width, canvas.height);
9181 akron1 513
    Scroll.resize(vScroll, vScroll.width, canvas.height + 2);
514
    Scroll.resize(hScroll, canvas.width + 1, 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);
9181 akron1 614
        K.DrawRect(LEFT + canvas.width + 1, TOP + canvas.height, scrollWidth - 1, 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;
9181 akron1 701
    Timer.kill;
702
    repaint
9174 akron1 703
END stopTimer;
704
 
705
 
8728 leency 706
PROCEDURE OpenFile (VAR FileName: RW.tFileName; filter: ARRAY OF CHAR);
707
BEGIN
9174 akron1 708
    stopTimer;
8728 leency 709
    OpenDlg.SetFilter(OD, filter);
710
    OpenDlg.Show(OD, 500, 400);
711
    WHILE OD.status = 2 DO
712
        K.Pause(30)
713
    END;
714
    IF OD.status = 1 THEN
715
        COPY(OD.FilePath, FileName)
716
    ELSE
717
        FileName := ""
9174 akron1 718
    END;
719
    resetTimer
8728 leency 720
END OpenFile;
721
 
722
 
723
PROCEDURE error (s: RW.tFileName);
724
BEGIN
725
    K.Run("/rd/1/@notify", s)
726
END error;
727
 
728
 
9050 leency 729
PROCEDURE saveError (name: RW.tFileName);
8728 leency 730
VAR
9050 leency 731
    s: RW.tFileName;
732
BEGIN
733
    s := "'cedit: error saving file ";
734
    U.append8(s, name);
735
    U.append8(s, "' -E");
736
    error(s)
737
END saveError;
738
 
739
 
740
PROCEDURE saveAs (text: T.tText);
741
VAR
742
    fileName, name: RW.tFileName;
8728 leency 743
    ext: ARRAY 8 OF CHAR;
744
BEGIN
745
    OD._type := OpenDlg.tsave;
746
    U.getFileName(text.fileName, OD.FileName, U.SLASH);
747
    IF OD.FileName = "" THEN
748
        OD.FileName := "NewFile.";
749
        CASE text.lang OF
750
        |Languages.langNone:   ext := "txt"
751
        |Languages.langC:      ext := "c"
752
        |Languages.langFasm:   ext := "asm"
753
        |Languages.langIni:    ext := "ini"
9174 akron1 754
        |Languages.langJSON:   ext := "json"
8728 leency 755
        |Languages.langLua:    ext := "lua"
756
        |Languages.langOberon: ext := "ob07"
757
        |Languages.langPascal: ext := "pas"
758
        END;
759
        U.append8(OD.FileName, ext)
760
    END;
761
    OpenFile(fileName, EditFilter);
762
    IF fileName # "" THEN
9180 akron1 763
        IF T.save(text, fileName) THEN
9050 leency 764
            T.setName(text, fileName);
765
            U.getFileName(fileName, name, U.SLASH);
766
            Tabs.rename(tabs, curText, name)
8728 leency 767
        ELSE
9050 leency 768
            saveError(fileName)
8728 leency 769
        END
770
    END
771
END saveAs;
772
 
773
 
9050 leency 774
PROCEDURE getIdx (text: T.tText): INTEGER;
775
VAR
776
    i: INTEGER;
8728 leency 777
BEGIN
9050 leency 778
    i := 0;
779
    WHILE texts[i] # text DO
780
        INC(i)
781
    END
782
    RETURN i
783
END getIdx;
784
 
785
 
786
PROCEDURE Switch (txt: T.tText);
787
BEGIN
788
    Tabs.switch(tabs, curText);
789
    text := txt;
790
    T.switch(txt);
791
    switch := TRUE
792
END Switch;
793
 
794
 
795
PROCEDURE save (text: T.tText);
796
BEGIN
8728 leency 797
    IF text.modified THEN
798
        IF text.fileName # "" THEN
9180 akron1 799
            IF ~T.save(text, text.fileName) THEN
9050 leency 800
                saveError(text.fileName)
8728 leency 801
            END
802
        ELSE
9050 leency 803
            curText := getIdx(text);
804
            Switch(text);
805
            saveAs(text)
8728 leency 806
        END
807
    END
808
END save;
809
 
810
 
9050 leency 811
PROCEDURE saveAll;
812
VAR
813
    i: INTEGER;
8728 leency 814
BEGIN
9050 leency 815
    i := textsCount - 1;
816
    WHILE i >= 0 DO
817
        IF texts[i].modified THEN
818
            save(texts[i])
819
        END;
820
        DEC(i)
821
    END;
822
END saveAll;
8728 leency 823
 
824
 
9050 leency 825
PROCEDURE insert (pos: INTEGER; txt: T.tText);
8728 leency 826
VAR
9050 leency 827
    i: INTEGER;
828
    name: RW.tFileName;
8728 leency 829
BEGIN
9050 leency 830
    FOR i := textsCount - 1 TO pos BY -1 DO
831
        texts[i + 1] := texts[i]
832
    END;
833
    texts[pos] := txt;
834
    INC(textsCount);
835
    curText := pos;
836
    IF txt.fileName = "" THEN
837
        name := "new"
838
    ELSE
839
        U.getFileName(txt.fileName, name, U.SLASH)
840
    END;
841
    Tabs.add(tabs, name);
842
    Switch(txt)
843
END insert;
8728 leency 844
 
845
 
846
PROCEDURE Confirm;
847
CONST
848
    width  = btnWidth*2 + 30;
849
    height = btnHeight*2 + 20;
850
    lineColor = 808080H;
851
VAR
852
    left, top, right, bottom: INTEGER;
853
BEGIN
9174 akron1 854
	stopTimer;
8728 leency 855
    draw_window;
856
    confirm := TRUE;
857
    left := (canvas.width - width) DIV 2 + LEFT;
858
    top := (canvas.height - height) DIV 2 + TOP;
859
    right := left + width - 1;
860
    bottom := top + height - 1;
8762 leency 861
    K.DrawRect(left, top, width, height, K.winColor);
8728 leency 862
    Rect(left, top, right, bottom, lineColor);
8762 leency 863
    K.DrawText866(left + (width - 10*fontWidth) DIV 2, top + 10, K.textColor, "save file?");
864
    K.CreateButton(btnYes, left + 10, top + 35, btnWidth, btnHeight, K.btnColor, "yes");
865
    K.CreateButton(btnNo, left + 20 + btnWidth, top + 35, btnWidth, btnHeight, K.btnColor, "no");
8728 leency 866
END Confirm;
867
 
868
 
9060 leency 869
PROCEDURE closeFile (conf: BOOLEAN; n: INTEGER);
9050 leency 870
VAR
871
    i: INTEGER;
872
BEGIN
9073 leency 873
    IF texts[n].modified & conf THEN
9050 leency 874
        Confirm
875
    ELSE
9060 leency 876
        Tabs.delete(tabs, n);
877
        FOR i := n + 1 TO textsCount - 1 DO
9050 leency 878
            texts[i - 1] := texts[i]
879
        END;
880
        DEC(textsCount);
9060 leency 881
        IF (curText = textsCount) OR (n < curText) THEN
9050 leency 882
            DEC(curText)
883
        END;
884
        IF curText >= 0 THEN
885
            Switch(texts[curText])
886
        ELSE
9181 akron1 887
            K.Exit
9050 leency 888
        END;
889
        draw_window
890
    END
891
END closeFile;
892
 
893
 
894
PROCEDURE NewFile;
895
VAR
896
    nov: T.tText;
897
BEGIN
898
    IF textsCount < maxTexts THEN
899
        nov := T.New();
900
        T.SetPos(nov, 0, 0);
901
        insert(textsCount, nov)
902
    ELSE
903
        error("'cedit: too many files' -E")
904
    END
905
END NewFile;
906
 
907
 
908
PROCEDURE getFileNum (fileName: RW.tFileName): INTEGER;
909
VAR
910
    i: INTEGER;
911
 
912
    PROCEDURE nameEq (name1, name2: RW.tFileName): BOOLEAN;
913
    VAR
914
        n1, n2: RW.tFileName;
915
    BEGIN
916
        n1 := name1;
917
        n2 := name2;
918
        U.upcase(n1);
919
        U.upcase(n2)
920
        RETURN n1 = n2
921
    END nameEq;
922
 
923
BEGIN
924
    i := 0;
925
    WHILE (i < textsCount) & ~nameEq(texts[i].fileName, fileName) DO
926
        INC(i)
927
    END;
928
    IF i = textsCount THEN
929
        i := -1
930
    END
931
    RETURN i
932
END getFileNum;
933
 
934
 
9073 leency 935
PROCEDURE SwitchTab (n: INTEGER);
936
BEGIN
937
    curText := n;
938
    Tabs.switch(tabs, n);
939
    Switch(texts[n]);
9174 akron1 940
    resetTimer;
9073 leency 941
    draw_window
942
END SwitchTab;
943
 
944
 
9050 leency 945
PROCEDURE open;
946
VAR
947
    fileName: RW.tFileName;
948
    nov: T.tText;
949
    err, n: INTEGER;
950
BEGIN
951
    IF textsCount < maxTexts THEN
952
        OD._type := OpenDlg.topen;
953
        OpenFile(fileName, EditFilter);
954
        IF fileName # "" THEN
955
            n := getFileNum(fileName);
956
            IF n = -1 THEN
957
                nov := T.open(fileName, err);
958
                IF nov = NIL THEN
959
                    error("'cedit: error opening file' -E")
960
                ELSE
961
                    insert(textsCount, nov);
962
                    T.SetPos(nov, 0, 0)
963
                END
964
            ELSE
9073 leency 965
                SwitchTab(n)
9050 leency 966
            END
967
        END
968
    ELSE
969
        error("'cedit: too many files' -E")
970
    END
971
END open;
972
 
973
 
8728 leency 974
PROCEDURE createEdit (left, top: INTEGER): box_lib.edit_box;
975
VAR
976
    edit, EditBox0: box_lib.edit_box;
977
BEGIN
978
    NEW(EditBox0);
979
    EditBox0.text := K.malloc(EDITBOX_MAXCHARS + 2);
980
    ASSERT(EditBox0.text # 0);
981
    edit := box_lib.kolibri_new_edit_box(left, top, EditBox_Width, EDITBOX_MAXCHARS, EditBox0);
982
    edit.flags := 4002H;
983
    edit.text_color := 30000000H;
984
    EditBox_SetFocus(edit, FALSE)
985
    RETURN edit
986
END createEdit;
987
 
988
 
989
PROCEDURE createSearchForm;
990
BEGIN
991
    FindEdit := createEdit(searchLeft, TOP + 20);
992
    ReplaceEdit := createEdit(searchLeft, TOP + 20 + 55);
993
    GotoEdit := createEdit(searchLeft, TOP + 20 + 330);
994
    GotoEdit.flags := ORD(BITS(GotoEdit.flags) + BITS(8000H));
995
    BKW := box_lib.kolibri_new_check_box(searchLeft, TOP + 90 + 20, 16, 16, "", 8*fontWidth + 4);
996
    CS := box_lib.kolibri_new_check_box(searchLeft, TOP + 120 + 20, 16, 16, "", 10*fontWidth + 4);
997
    WH := box_lib.kolibri_new_check_box(searchLeft, TOP + 150 + 20, 16, 16, "", 10*fontWidth + 4);
998
END createSearchForm;
999
 
1000
 
1001
PROCEDURE EditBox_GetValue (edit: box_lib.edit_box; VAR s: ARRAY OF WCHAR);
1002
VAR
1003
    str: ARRAY EDITBOX_MAXCHARS + 1 OF CHAR;
1004
    i: INTEGER;
1005
BEGIN
1006
    box_lib.edit_box_get_value(edit, str);
1007
    i := 0;
1008
    WHILE str[i] # 0X DO
1009
        s[i] := WCHR(E.cp866[ORD(str[i])]);
1010
        INC(i)
1011
    END;
1012
    s[i] := 0X
1013
END EditBox_GetValue;
1014
 
1015
 
1016
PROCEDURE Search;
1017
BEGIN
1018
    search := ~search;
9073 leency 1019
    LEFT := searchLeft;
8728 leency 1020
    IF search THEN
9073 leency 1021
        searchOpened := TRUE;
1022
        INC(LEFT, EditBox_Width + SEARCH_PADDING*2 + 5);
8728 leency 1023
        IF T.search(text, searchText, cs, whole) THEN END
1024
    ELSE
1025
        IF T.search(text, "", FALSE, FALSE) THEN END
1026
    END;
9073 leency 1027
    SetFocus(FindEdit, search);
8728 leency 1028
    resize;
1029
    draw_window
1030
END Search;
1031
 
1032
 
1033
PROCEDURE click (x, y: INTEGER): INTEGER;
1034
VAR
1035
    scrollX, scrollY: INTEGER;
9073 leency 1036
    shift, ctrl: BOOLEAN;
8728 leency 1037
BEGIN
9073 leency 1038
    getKBState(shift, ctrl);
9174 akron1 1039
    IF ~hScroll.mouse THEN
1040
    	Scroll.MouseDown(hScroll, x + LEFT, y + TOP);
1041
        T.getScroll(text, scrollX, scrollY);
1042
        T.scroll(text, hScroll.value - scrollX, 0);
1043
        repaint
1044
    END;
1045
    IF ~vScroll.mouse THEN
1046
    	Scroll.MouseDown(vScroll, x + LEFT, y + TOP);
1047
        T.getScroll(text, scrollX, scrollY);
1048
        T.scroll(text, 0, vScroll.value - scrollY);
1049
        repaint
1050
    END;
8728 leency 1051
    IF (0 <= x) & (x < canvas.width) & (0 <= y) & (y < canvas.height) THEN
1052
        leftButton := TRUE;
9073 leency 1053
        SetFocus(FindEdit, FALSE);
1054
        IF ~shift THEN
8728 leency 1055
            T.resetSelect(text)
1056
        END;
1057
        T.mouse(text, x, y);
1058
        repaint
1059
    END
1060
    RETURN K.GetTickCount()
1061
END click;
1062
 
1063
 
1064
PROCEDURE LeftButtonUp;
1065
BEGIN
1066
    leftButton := FALSE;
1067
    Scroll.MouseUp(hScroll);
9174 akron1 1068
    Scroll.MouseUp(vScroll)
8728 leency 1069
END LeftButtonUp;
1070
 
1071
 
9073 leency 1072
PROCEDURE Close;
9050 leency 1073
VAR
1074
    cont: BOOLEAN;
8728 leency 1075
BEGIN
9073 leency 1076
    closing := TRUE;
9050 leency 1077
    cont := TRUE;
1078
    WHILE (textsCount > 0) & cont DO
1079
        IF text.modified THEN
1080
            Confirm;
1081
            cont := FALSE
1082
        ELSE
9060 leency 1083
            closeFile(FALSE, curText);
9050 leency 1084
            repaint
1085
        END
8728 leency 1086
    END
9073 leency 1087
END Close;
8728 leency 1088
 
1089
 
9174 akron1 1090
PROCEDURE CloseMenu;
1091
BEGIN
1092
    Menu.close(menuFile);
1093
    Menu.close(menuEdit);
1094
    Menu.close(menuSearch);
1095
    Menu.close(menuEncoding);
9180 akron1 1096
    Menu.close(menuEOL);
9174 akron1 1097
    Menu.close(menuView);
1098
    Menu.close(menuSyntax);
1099
    Menu.close(menuProgram);
1100
    Menu.close(menuTools);
1101
    Menu.close(subCurLine);
1102
    Menu.close(subIndent);
1103
    Menu.close(subCase);
1104
    Menu.close(subBookmark);
1105
    Menu.close(context);
1106
END CloseMenu;
1107
 
1108
 
8728 leency 1109
PROCEDURE MenuItemClick (menu: Menu.tMenu; id: INTEGER);
1110
BEGIN
1111
    K.SendIPC(mainTID, id)
1112
END MenuItemClick;
1113
 
1114
 
1115
PROCEDURE goto;
1116
VAR
1117
    gotoVal: INTEGER;
1118
BEGIN
1119
    EditBox_GetValue(GotoEdit, gotoText);
9174 akron1 1120
    IF U.str2int(gotoText, gotoVal) & T.goto(text, gotoVal) THEN
1121
    	SetFocus(GotoEdit, FALSE)
1122
    END
8728 leency 1123
END goto;
1124
 
1125
 
1126
PROCEDURE Script (script: ARRAY OF CHAR);
1127
BEGIN
1128
    IF script # "" THEN
1129
        K.Run("/rd/1/@open", script)
1130
    END
1131
END Script;
1132
 
1133
 
9073 leency 1134
PROCEDURE ShowSearchPanel;
1135
BEGIN
1136
    IF ~search THEN
1137
        Search
1138
    ELSIF ~searchOpened THEN
1139
        search := FALSE;
1140
        Search
1141
    END
1142
END ShowSearchPanel;
1143
 
1144
 
9174 akron1 1145
PROCEDURE CanvasToScreen (VAR x, y: INTEGER);
1146
VAR
1147
    cliX, cliY,
1148
    winX, winY: INTEGER;
1149
BEGIN
1150
    K.WinPos(winX, winY);
1151
    K.ClientPos(cliX, cliY);
1152
    x := x + winX + cliX + LEFT;
1153
    y := y + winY + cliY + TOP;
1154
END CanvasToScreen;
1155
 
1156
 
1157
PROCEDURE ShowMenu (menu: Menu.tMenu);
1158
VAR
1159
    winX, winY, cliX, cliY, x, y, i: INTEGER;
1160
    selected, enabled: BOOLEAN;
1161
BEGIN
1162
    IF menu = context THEN
1163
        mouse(x, y);
1164
        IF ~((0 <= x) & (x < canvas.width) & (0 <= y) & (y < canvas.height)) THEN
1165
            menu := NIL
1166
        END
1167
    ELSE
1168
        K.WinPos(winX, winY);
1169
        K.ClientPos(cliX, cliY);
1170
        x := winX + cliX;
1171
        y := MainMenuHeight + winY + cliY
1172
    END;
1173
 
1174
    selected := T.selected(text);
1175
 
1176
    IF menu = menuFile THEN
1177
        Menu.setEnabled(menu, menuSave, text.modified);
1178
        Menu.setEnabled(menu, menuFolder, text.fileName # "");
1179
        i := 0;
1180
        WHILE (i < textsCount) & ~texts[i].modified DO
1181
            INC(i)
1182
        END;
1183
        Menu.setEnabled(menu, menuSaveAll, i < textsCount);
1184
        INC(x, menuFileX)
1185
    ELSIF (menu = menuEdit) OR (menu = context) THEN
1186
        Menu.setEnabled(menu, menuUndo, ~ChangeLog.isFirstGuard(text.edition));
1187
        Menu.setEnabled(menu, menuRedo, ~ChangeLog.isLastGuard(text.edition));
1188
        Menu.setEnabled(menu, menuCut, selected);
1189
        Menu.setEnabled(menu, menuCopy, selected);
1190
        Menu.setEnabled(menu, menuDelete, selected);
1191
        Menu.setEnabled(menu, menuPaste, CB.available());
1192
        IF menu = menuEdit THEN
1193
            INC(x, menuEditX)
1194
        ELSE
1195
            IF y + menu.height >= canvas.height THEN
1196
                DEC(y, menu.height)
1197
            END;
1198
            IF x + menu.width >= canvas.width THEN
1199
                DEC(x, menu.width)
1200
            END;
1201
            CanvasToScreen(x, y)
1202
        END
1203
    ELSIF menu = menuEncoding THEN
1204
        Menu.setCheck(menu, menuUTF8BOM, ORD(text.enc = E.UTF8BOM)*2);
1205
        Menu.setCheck(menu, menuUTF8,    ORD(text.enc = E.UTF8)*2);
1206
        Menu.setCheck(menu, menuCP866,   ORD(text.enc = E.CP866)*2);
1207
        Menu.setCheck(menu, menuWin1251, ORD(text.enc = E.W1251)*2);
1208
        INC(x, menuEncodingX)
9180 akron1 1209
    ELSIF menu = menuEOL THEN
1210
		Menu.setCheck(menu, menuCRLF, ORD(text.eol = RW.EOL_CRLF)*2);
1211
		Menu.setCheck(menu, menuLF,   ORD(text.eol = RW.EOL_LF)*2);
1212
		Menu.setCheck(menu, menuCR,   ORD(text.eol = RW.EOL_CR)*2);
1213
		INC(x, menuEOLX)
9174 akron1 1214
    ELSIF menu = menuView THEN
1215
        Menu.setCheck(menu, menuNumbers,  ORD(text.numbers));
1216
        Menu.setCheck(menu, menuFontSize, ORD(font = font2));
1217
        FOR i := 0 TO Ini.sections.count - 1 DO
1218
            Menu.setCheck(menu, menuColors + i, ORD(Ini.curSectionNum = i)*2)
1219
        END;
1220
        INC(x, menuViewX)
1221
    ELSIF menu = menuSyntax THEN
1222
        Menu.setCheck(menu, menuNone,   ORD(text.lang = Languages.langNone)*2);
1223
        Menu.setCheck(menu, menuC,      ORD(text.lang = Languages.langC)*2);
1224
        Menu.setCheck(menu, menuFasm,   ORD(text.lang = Languages.langFasm)*2);
1225
        Menu.setCheck(menu, menuIni,    ORD(text.lang = Languages.langIni)*2);
1226
        Menu.setCheck(menu, menuJSON,   ORD(text.lang = Languages.langJSON)*2);
1227
        Menu.setCheck(menu, menuLua,    ORD(text.lang = Languages.langLua)*2);
1228
        Menu.setCheck(menu, menuOberon, ORD(text.lang = Languages.langOberon)*2);
1229
        Menu.setCheck(menu, menuPascal, ORD(text.lang = Languages.langPascal)*2);
1230
        INC(x, menuSyntaxX)
1231
    ELSIF menu = menuProgram THEN
1232
        Menu.setEnabled(menu, menuBuild, buildScript # "");
1233
        Menu.setEnabled(menu, menuDebug, debugScript # "");
1234
        Menu.setEnabled(menu, menuRun, runScript # "");
1235
        INC(x, menuProgramX)
1236
    ELSIF menu = menuTools THEN
1237
        INC(x, menuToolsX)
1238
    ELSIF menu = menuSearch THEN
1239
        INC(x, menuSearchX)
1240
    END;
1241
 
1242
    enabled := search & (searchText # "");
1243
    Menu.setEnabled(menuSearch, menuFindNext, enabled);
1244
    Menu.setEnabled(menuSearch, menuFindPrev, enabled);
1245
 
1246
    Menu.setEnabled(subIndent, menuIncInd, selected);
1247
    Menu.setEnabled(subIndent, menuDecInd, selected);
1248
 
1249
    Menu.setEnabled(subCase, menuUpper, selected);
1250
    Menu.setEnabled(subCase, menuLower, selected);
1251
 
1252
    IF menu # NIL THEN
9181 akron1 1253
    	Timer.kill;
9174 akron1 1254
        IF Menu.opened(menu) THEN
1255
            Menu.close(menu)
1256
        END;
9175 akron1 1257
        Menu.open(menu, x, y);
1258
        menuActive := TRUE
1259
    END
9174 akron1 1260
END ShowMenu;
1261
 
1262
 
8728 leency 1263
PROCEDURE receiveIPC;
9174 akron1 1264
VAR
1265
	scrollIPC: BOOLEAN;
8728 leency 1266
BEGIN
9174 akron1 1267
	scrollIPC := FALSE;
1268
    IF IPC[0] = Timer.ID THEN
9181 akron1 1269
    	IF IPC[4] = Timer.n THEN
1270
			T.toggleCursor;
1271
			repaint
1272
		END;
9174 akron1 1273
    	IPC[2] := 0
1274
    ELSIF IPC[0] = mainTID THEN
1275
    	IF IPC[2] = Scroll.ScrollIPC THEN
1276
	    	Scroll.change(hScroll);
1277
	    	IF hScroll.Dec THEN
1278
	    		T.scroll(text, -1, 0)
1279
	    	ELSIF hScroll.Inc THEN
1280
				T.scroll(text, 1, 0)
1281
	    	END;
1282
	    	Scroll.change(vScroll);
1283
	    	IF vScroll.Dec THEN
1284
	    		T.scroll(text, 0, -1)
1285
	    	ELSIF vScroll.Inc THEN
1286
				T.scroll(text, 0, 1)
1287
	    	END;
1288
 
9175 akron1 1289
    		IF menuActive THEN
1290
    			draw_window;
1291
    			menuActive := FALSE
1292
    		ELSE
1293
    			repaint
1294
    		END;
1295
 
9174 akron1 1296
    		IF (0 IN K.MouseState()) THEN
1297
    			WHILE (0 IN K.MouseState()) & (delay > 0) DO
1298
        			K.Pause(1);
1299
    	    		DEC(delay)
1300
        		END;
1301
        		IF delay = 0 THEN
1302
    				IPC[0] := 0;
1303
					IPC[1] := 0;
1304
					scrollIPC := TRUE;
1305
	        		Scroll.SendIPC;
1306
    	    		delay := 2
1307
        		ELSE
1308
        			delay := scrollDelay
1309
        		END
1310
        	ELSE
1311
        		delay := scrollDelay
1312
			END
1313
    	END;
1314
    	IPC[2] := 0
1315
    ELSIF ~Menu.isSender(IPC[0]) THEN
1316
   		IPC[2] := 0
8728 leency 1317
    END;
1318
    CASE IPC[2] OF
1319
    |0:
9073 leency 1320
    |menuCut:       T.key(text, ORD("X"), FALSE, TRUE)
1321
    |menuCopy:      T.key(text, ORD("C"), FALSE, TRUE)
1322
    |menuPaste:     T.key(text, ORD("V"), FALSE, TRUE)
1323
    |menuDelete:    T.key(text,       46, FALSE, FALSE)
1324
    |menuSelectAll: T.key(text, ORD("A"), FALSE, TRUE)
8728 leency 1325
 
1326
    |menuNew:
9050 leency 1327
        NewFile
8728 leency 1328
    |menuOpen:
1329
        open
1330
    |menuSave:
9050 leency 1331
        save(text);
8728 leency 1332
        repaint
1333
    |menuSaveAs:
9050 leency 1334
        saveAs(text);
8728 leency 1335
        repaint
9050 leency 1336
    |menuSaveAll:
1337
        saveAll;
1338
        repaint
1339
    |menuClose:
9060 leency 1340
        closeFile(TRUE, curText)
8728 leency 1341
    |menuFolder:
1342
        K.Run("/rd/1/File Managers/Eolite", text.fileName)
1343
    |menuExit:
9073 leency 1344
        Close
8728 leency 1345
    |menuUndo:
1346
        T.undo(text);
1347
        repaint
1348
    |menuRedo:
1349
        T.redo(text);
1350
        repaint
9174 akron1 1351
    |menuFind:
9073 leency 1352
        ShowSearchPanel;
1353
        SetFocus(FindEdit, TRUE)
9174 akron1 1354
    |menuFindNext:
9175 akron1 1355
        notFound := ~T.findNext(text, box_lib.check_box_get_value(BKW));
1356
        menuFindClicked := TRUE
9174 akron1 1357
    |menuFindPrev:
9175 akron1 1358
        notFound := ~T.findNext(text, ~box_lib.check_box_get_value(BKW));
1359
        menuFindClicked := TRUE
8728 leency 1360
    |menuGoto:
9073 leency 1361
        ShowSearchPanel;
1362
        SetFocus(GotoEdit, TRUE)
9174 akron1 1363
    |menuToggleBookmark:
1364
    	T.toggleLabel(text)
1365
    |menuNextBookmark:
1366
    	T.gotoLabel(text, TRUE)
1367
    |menuPrevBookmark:
1368
    	T.gotoLabel(text, FALSE)
8728 leency 1369
    |menuNumbers:
1370
        T.toggleNumbers(text)
8772 leency 1371
    |menuFontSize:
1372
        IF font = font1 THEN
1373
            font := font2
1374
        ELSE
1375
            font := font1
1376
        END;
1377
        resize
8728 leency 1378
    |menuNone:
1379
        T.setLang(text, Languages.langNone)
1380
    |menuC:
1381
        T.setLang(text, Languages.langC)
1382
    |menuFasm:
1383
        T.setLang(text, Languages.langFasm)
1384
    |menuIni:
1385
        T.setLang(text, Languages.langIni)
9174 akron1 1386
    |menuJSON:
1387
        T.setLang(text, Languages.langJSON)
8728 leency 1388
    |menuLua:
1389
        T.setLang(text, Languages.langLua)
1390
    |menuOberon:
1391
        T.setLang(text, Languages.langOberon)
1392
    |menuPascal:
1393
        T.setLang(text, Languages.langPascal)
1394
    |menuBuild:
1395
        Script(buildScript)
1396
    |menuBuildScript:
1397
        OpenFile(buildScript, ShellFilter)
1398
    |menuRun:
1399
        Script(runScript)
1400
    |menuRunScript:
1401
        OpenFile(runScript, ShellFilter)
1402
    |menuDebug:
1403
        Script(debugScript)
1404
    |menuDebugScript:
1405
        OpenFile(debugScript, ShellFilter)
1406
    |menuUTF8BOM:
1407
        text.enc := E.UTF8BOM
1408
    |menuUTF8:
1409
        text.enc := E.UTF8
1410
    |menuCP866:
1411
        text.enc := E.CP866
1412
    |menuWin1251:
1413
        text.enc := E.W1251
9180 akron1 1414
    |menuLF:
1415
        text.eol := RW.EOL_LF
1416
    |menuCRLF:
1417
        text.eol := RW.EOL_CRLF
1418
    |menuCR:
1419
        text.eol := RW.EOL_CR
8728 leency 1420
    |menuPipet:
1421
        K.Run("/rd/1/develop/pipet", "")
9073 leency 1422
    |menuBoard:
1423
        K.Run("/rd/1/develop/board", "")
8728 leency 1424
    |menuSysFunc:
1425
        K.Run("/rd/1/docpack", "f")
1426
    |menuColors..menuMaxColors:
1427
        Ini.selectSection(IPC[2] - menuColors)
9174 akron1 1428
    |menuMoveUp:
1429
    	T.upLine(text)
1430
    |menuMoveDown:
1431
    	T.downLine(text)
1432
    |menuDuplicate:
1433
    	T.dupLine(text)
1434
    |menuRemove:
1435
    	T.delLine(text)
1436
    |menuIncInd:
1437
    	T.Indent(text, TRUE)
1438
	|menuDecInd:
1439
		T.Indent(text, FALSE)
1440
	|menuUpper:
1441
		T.chCase(text, TRUE)
1442
	|menuLower:
1443
		T.chCase(text, FALSE)
8728 leency 1444
    END;
9174 akron1 1445
    IF ~scrollIPC THEN
1446
    	IPC[0] := 0;
1447
    	IPC[1] := 0
1448
    END
8728 leency 1449
END receiveIPC;
1450
 
1451
 
1452
PROCEDURE MenuKeyDown (menu: Menu.tMenu; key: INTEGER): BOOLEAN;
1453
VAR
1454
    menuItem: INTEGER;
9073 leency 1455
    shift, ctrl: BOOLEAN;
8728 leency 1456
BEGIN
1457
    menuItem := -1;
9073 leency 1458
    getKBState(shift, ctrl);
1459
    IF ctrl THEN
8728 leency 1460
        CASE key DIV 65536 OF
9060 leency 1461
        |17: menuItem := menuClose
8728 leency 1462
        |21: menuItem := menuRedo
1463
        |30: menuItem := menuSelectAll
9174 akron1 1464
        |33: menuItem := menuFind
8728 leency 1465
        |34: menuItem := menuGoto
1466
        |44: menuItem := menuUndo
1467
        |45: menuItem := menuCut
1468
        |46: menuItem := menuCopy
1469
        |47: menuItem := menuPaste
1470
        |24: menuItem := menuOpen
1471
        |31: menuItem := menuSave
1472
        |49: menuItem := menuNew
1473
        |67: menuItem := menuBuild
1474
        ELSE
1475
        END
1476
    ELSE
1477
        IF key DIV 65536 = 83 THEN
1478
            menuItem := menuDelete
1479
        ELSIF key DIV 65536 = 67 THEN
1480
            menuItem := menuRun
1481
        END
1482
    END;
1483
    IF menuItem # -1 THEN
1484
        IF Menu.isEnabled(menu, menuItem) THEN
1485
            MenuItemClick(menu, menuItem)
1486
        ELSE
1487
            menuItem := -1
1488
        END
1489
    END
1490
    RETURN menuItem # -1
1491
END MenuKeyDown;
1492
 
1493
 
1494
PROCEDURE CreateContextMenu (): Menu.tMenu;
1495
VAR
1496
    menu: List.tList;
1497
BEGIN
1498
    menu := List.create(NIL);
1499
    Menu.AddMenuItem(menu, menuUndo,      "undo         ctrl-Z");
1500
    Menu.AddMenuItem(menu, menuRedo,      "redo         ctrl-Y");
1501
    Menu.delimiter(menu);
1502
    Menu.AddMenuItem(menu, menuCut,       "cut          ctrl-X");
1503
    Menu.AddMenuItem(menu, menuCopy,      "copy         ctrl-C");
1504
    Menu.AddMenuItem(menu, menuPaste,     "paste        ctrl-V");
1505
    Menu.AddMenuItem(menu, menuDelete,    "delete");
1506
    Menu.delimiter(menu);
1507
    Menu.AddMenuItem(menu, menuSelectAll, "select all   ctrl-A");
1508
    RETURN Menu.create(menu, MenuItemClick, MenuKeyDown)
1509
END CreateContextMenu;
1510
 
1511
 
1512
PROCEDURE CreateMenuFile (): Menu.tMenu;
1513
VAR
1514
    menu: List.tList;
1515
BEGIN
1516
    menu := List.create(NIL);
9050 leency 1517
    Menu.AddMenuItem(menu, menuNew,     "new         ctrl-N");
1518
    Menu.AddMenuItem(menu, menuOpen,    "open        ctrl-O");
1519
    Menu.AddMenuItem(menu, menuSave,    "save        ctrl-S");
1520
    Menu.AddMenuItem(menu, menuSaveAs,  "save as");
1521
    Menu.AddMenuItem(menu, menuSaveAll, "save all");
1522
    Menu.AddMenuItem(menu, menuFolder,  "folder");
8728 leency 1523
    Menu.delimiter(menu);
9060 leency 1524
    Menu.AddMenuItem(menu, menuClose,   "close       ctrl-W");
9050 leency 1525
    Menu.delimiter(menu);
1526
    Menu.AddMenuItem(menu, menuExit,    "exit");
8728 leency 1527
    RETURN Menu.create(menu, MenuItemClick, MenuKeyDown)
1528
END CreateMenuFile;
1529
 
1530
 
1531
PROCEDURE CreateMenuEdit (): Menu.tMenu;
1532
VAR
1533
    menu: List.tList;
1534
BEGIN
1535
    menu := List.create(NIL);
9174 akron1 1536
    Menu.AddMenuItem(menu, menuUndo,      "undo            ctrl-Z");
1537
    Menu.AddMenuItem(menu, menuRedo,      "redo            ctrl-Y");
8728 leency 1538
    Menu.delimiter(menu);
9174 akron1 1539
    Menu.AddMenuItem(menu, menuCut,       "cut             ctrl-X");
1540
    Menu.AddMenuItem(menu, menuCopy,      "copy            ctrl-C");
1541
    Menu.AddMenuItem(menu, menuPaste,     "paste           ctrl-V");
8728 leency 1542
    Menu.AddMenuItem(menu, menuDelete,    "delete");
1543
    Menu.delimiter(menu);
9174 akron1 1544
    Menu.AddMenuItem(menu, menuSelectAll, "select all      ctrl-A");
1545
    Menu.delimiter(menu);
1546
    Menu.AddMenuItem(menu, menuCurLine,   "current line");
1547
    Menu.child(menu, subCurLine);
1548
    Menu.AddMenuItem(menu, menuIndent,    "indent");
1549
    Menu.child(menu, subIndent);
1550
    Menu.AddMenuItem(menu, menuCase,      "case");
1551
    Menu.child(menu, subCase);
8728 leency 1552
    RETURN Menu.create(menu, MenuItemClick, MenuKeyDown)
1553
END CreateMenuEdit;
1554
 
1555
 
9174 akron1 1556
PROCEDURE CreateMenuSearch (): Menu.tMenu;
1557
VAR
1558
    menu: List.tList;
1559
BEGIN
1560
    menu := List.create(NIL);
1561
    Menu.AddMenuItem(menu, menuFind,     "search           ctrl-F");
1562
    Menu.AddMenuItem(menu, menuFindNext, "find next        F3");
1563
    Menu.AddMenuItem(menu, menuFindPrev, "find previous    shift-F3");
1564
    Menu.AddMenuItem(menu, menuGoto,     "go to line       ctrl-G");
1565
    Menu.delimiter(menu);
1566
    Menu.AddMenuItem(menu, menuBookmark, "bookmark");
1567
    Menu.child(menu, subBookmark);
1568
    RETURN Menu.create(menu, MenuItemClick, MenuKeyDown)
1569
END CreateMenuSearch;
1570
 
1571
 
8728 leency 1572
PROCEDURE CreateMenuEncoding (): Menu.tMenu;
1573
VAR
1574
    menu: List.tList;
1575
BEGIN
1576
    menu := List.create(NIL);
9073 leency 1577
    Menu.AddMenuItem(menu, menuUTF8BOM, E.names[E.UTF8BOM]);
1578
    Menu.AddMenuItem(menu, menuUTF8,    E.names[E.UTF8]);
1579
    Menu.AddMenuItem(menu, menuCP866,   E.names[E.CP866]);
1580
    Menu.AddMenuItem(menu, menuWin1251, E.names[E.W1251]);
8728 leency 1581
    RETURN Menu.create(menu, MenuItemClick, MenuKeyDown)
1582
END CreateMenuEncoding;
1583
 
1584
 
9180 akron1 1585
PROCEDURE CreateMenuEOL (): Menu.tMenu;
1586
VAR
1587
    menu: List.tList;
1588
BEGIN
1589
    menu := List.create(NIL);
1590
    Menu.AddMenuItem(menu, menuCRLF, RW.eolNames[RW.EOL_CRLF]);
1591
    Menu.AddMenuItem(menu, menuLF,   RW.eolNames[RW.EOL_LF]);
1592
    Menu.AddMenuItem(menu, menuCR,   RW.eolNames[RW.EOL_CR]);
1593
    RETURN Menu.create(menu, MenuItemClick, MenuKeyDown)
1594
END CreateMenuEOL;
1595
 
1596
 
8728 leency 1597
PROCEDURE CreateMenuView (): Menu.tMenu;
1598
VAR
1599
    menu: List.tList;
1600
    colors: Ini.tSection;
1601
    idx: INTEGER;
1602
BEGIN
1603
    menu := List.create(NIL);
8762 leency 1604
    Menu.AddMenuItem(menu, menuNumbers, "line numbers");
8772 leency 1605
    Menu.AddMenuItem(menu, menuFontSize, "x2");
8728 leency 1606
    Menu.delimiter(menu);
1607
 
1608
    colors := Ini.sections.first(Ini.tSection);
1609
    idx := menuColors;
1610
    WHILE colors # NIL DO
1611
        Menu.AddMenuItem(menu, idx, colors.name);
1612
        INC(idx);
1613
        colors := colors.next(Ini.tSection)
1614
    END;
1615
 
1616
    RETURN Menu.create(menu, MenuItemClick, MenuKeyDown)
1617
END CreateMenuView;
1618
 
1619
 
1620
PROCEDURE CreateMenuSyntax (): Menu.tMenu;
1621
VAR
1622
    menu: List.tList;
1623
BEGIN
1624
    menu := List.create(NIL);
1625
    Menu.AddMenuItem(menu, menuC,      "C");
1626
    Menu.AddMenuItem(menu, menuFasm,   "Fasm");
1627
    Menu.AddMenuItem(menu, menuIni,    "Ini");
9174 akron1 1628
    Menu.AddMenuItem(menu, menuJSON,   "JSON");
8728 leency 1629
    Menu.AddMenuItem(menu, menuLua,    "Lua");
1630
    Menu.AddMenuItem(menu, menuOberon, "Oberon");
1631
    Menu.AddMenuItem(menu, menuPascal, "Pascal");
1632
    Menu.delimiter(menu);
1633
    Menu.AddMenuItem(menu, menuNone,   "none");
1634
    RETURN Menu.create(menu, MenuItemClick, MenuKeyDown)
1635
END CreateMenuSyntax;
1636
 
1637
 
1638
PROCEDURE CreateMenuProgram (): Menu.tMenu;
1639
VAR
1640
    menu: List.tList;
1641
BEGIN
1642
    menu := List.create(NIL);
9174 akron1 1643
    Menu.AddMenuItem(menu, menuBuild,       "build    ctrl-F9");
8728 leency 1644
    Menu.AddMenuItem(menu, menuBuildScript, "script");
1645
    Menu.delimiter(menu);
1646
    Menu.AddMenuItem(menu, menuRun,         "run           F9");
1647
    Menu.AddMenuItem(menu, menuRunScript,   "script");
1648
    Menu.delimiter(menu);
1649
    Menu.AddMenuItem(menu, menuDebug,       "debug");
1650
    Menu.AddMenuItem(menu, menuDebugScript, "script");
1651
    RETURN Menu.create(menu, MenuItemClick, MenuKeyDown)
1652
END CreateMenuProgram;
1653
 
1654
 
1655
PROCEDURE CreateMenuTools (): Menu.tMenu;
1656
VAR
1657
    menu: List.tList;
1658
BEGIN
1659
    menu := List.create(NIL);
1660
    Menu.AddMenuItem(menu, menuPipet,   "pipet");
9073 leency 1661
    Menu.AddMenuItem(menu, menuBoard,   "board");
8728 leency 1662
    Menu.AddMenuItem(menu, menuSysFunc, "system functions");
1663
    RETURN Menu.create(menu, MenuItemClick, MenuKeyDown)
1664
END CreateMenuTools;
1665
 
1666
 
9174 akron1 1667
PROCEDURE CreateMenuCurLine(): Menu.tMenu;
8728 leency 1668
VAR
9174 akron1 1669
    menu: List.tList;
8728 leency 1670
BEGIN
9174 akron1 1671
    menu := List.create(NIL);
1672
    Menu.AddMenuItem(menu, menuMoveUp,    "move up     ctrl-Up");
1673
    Menu.AddMenuItem(menu, menuMoveDown,  "move down   ctrl-Down");
1674
    Menu.AddMenuItem(menu, menuDuplicate, "duplicate   ctrl-D");
1675
    Menu.AddMenuItem(menu, menuRemove,    "remove      ctrl-Del");
1676
    RETURN Menu.create(menu, MenuItemClick, MenuKeyDown)
1677
END CreateMenuCurLine;
8728 leency 1678
 
1679
 
9174 akron1 1680
PROCEDURE CreateMenuIndent(): Menu.tMenu;
8728 leency 1681
VAR
9174 akron1 1682
    menu: List.tList;
8728 leency 1683
BEGIN
9174 akron1 1684
    menu := List.create(NIL);
1685
    Menu.AddMenuItem(menu, menuIncInd, "increase    Tab");
1686
    Menu.AddMenuItem(menu, menuDecInd, "decrease    shift-Bksp");
1687
    RETURN Menu.create(menu, MenuItemClick, MenuKeyDown)
1688
END CreateMenuIndent;
8728 leency 1689
 
1690
 
9174 akron1 1691
PROCEDURE CreateMenuCase(): Menu.tMenu;
1692
VAR
1693
    menu: List.tList;
1694
BEGIN
1695
    menu := List.create(NIL);
1696
    Menu.AddMenuItem(menu, menuUpper, "UPPER    ctrl-U");
1697
    Menu.AddMenuItem(menu, menuLower, "lower    ctrl-L");
1698
    RETURN Menu.create(menu, MenuItemClick, MenuKeyDown)
1699
END CreateMenuCase;
8728 leency 1700
 
1701
 
9174 akron1 1702
PROCEDURE CreateMenuBookmark(): Menu.tMenu;
1703
VAR
1704
    menu: List.tList;
1705
BEGIN
1706
    menu := List.create(NIL);
1707
    Menu.AddMenuItem(menu, menuToggleBookmark, "toggle      ctrl-F2");
1708
    Menu.AddMenuItem(menu, menuNextBookmark,   "next        F2");
1709
    Menu.AddMenuItem(menu, menuPrevBookmark,   "previous    shift-F2");
1710
    RETURN Menu.create(menu, MenuItemClick, MenuKeyDown)
1711
END CreateMenuBookmark;
1712
 
1713
 
9073 leency 1714
PROCEDURE KeyDown (key: INTEGER);
1715
VAR
1716
    keyCode: INTEGER;
1717
    shift, ctrl: BOOLEAN;
1718
BEGIN
1719
    keyCode := key DIV 65536;
1720
    getKBState(shift, ctrl);
1721
    IF confirm THEN
1722
        IF keyCode = 28 THEN (* Enter *)
1723
            save(text);
1724
            IF ~text.modified THEN
1725
                closeFile(FALSE, curText)
1726
            END
1727
        END;
1728
        key := -1
1729
    ELSE
1730
        IF keyCode = 61 THEN (* F3 *)
1731
            key := -1;
1732
            IF search & (searchText # "") THEN
1733
                IF shift THEN
1734
                    notFound := ~T.findNext(text, ~box_lib.check_box_get_value(BKW))
1735
                ELSE
1736
                    notFound := ~T.findNext(text, box_lib.check_box_get_value(BKW))
1737
                END
1738
            END
1739
        ELSIF keyCode = 60 THEN (* F2 *)
1740
            key := -1;
1741
            IF ctrl THEN
1742
                T.toggleLabel(text)
1743
            ELSE
1744
                T.gotoLabel(text, ~shift)
1745
            END
1746
        ELSIF keyCode = 67 THEN (* F9 *)
1747
            key := -1;
1748
            IF ctrl THEN
1749
                Script(buildScript)
1750
            ELSE
1751
                Script(runScript)
1752
            END
1753
        ELSIF keyCode = 1 THEN (* Esc *)
1754
            key := -1;
1755
            IF search THEN
1756
                Search
1757
            END
1758
        ELSIF (keyCode = 55) & (key DIV 256 MOD 256 = 52) THEN (* PrtScn *)
1759
            key := -1
9174 akron1 1760
        ELSIF (keyCode = 14) & shift THEN (* shift+Backspace *)
1761
            key := -1;
1762
            T.input(text, -8)
9073 leency 1763
        ELSIF (keyCode = 15) & ctrl THEN (* ctrl+Tab *)
1764
            key := -1;
1765
            SwitchTab((curText + 1) MOD textsCount)
1766
        ELSIF (keyCode = 33) & ctrl THEN
1767
            key := -1;
1768
            ShowSearchPanel;
1769
            SetFocus(FindEdit, TRUE)
1770
        ELSIF (keyCode = 34) & ctrl THEN
1771
            key := -1;
1772
            ShowSearchPanel;
1773
            SetFocus(GotoEdit, TRUE)
1774
        ELSE
1775
            IF EditBox_Focus(FindEdit) THEN
1776
                box_lib.edit_box_key(FindEdit, key);
1777
                EditBox_GetValue(FindEdit, new_searchText);
1778
                IF new_searchText # searchText THEN
1779
                    searchText := new_searchText;
1780
                    notFound := ~T.search(text, searchText, cs, whole)
1781
                END
1782
            ELSIF EditBox_Focus(ReplaceEdit) THEN
1783
                box_lib.edit_box_key(ReplaceEdit, key);
1784
                EditBox_GetValue(ReplaceEdit, replaceText)
1785
            ELSIF EditBox_Focus(GotoEdit) THEN
1786
                IF (key DIV 256) MOD 256 = 13 THEN
1787
                    goto
1788
                ELSE
1789
                    box_lib.edit_box_key(GotoEdit, key)
1790
                END
1791
            ELSE
1792
                CASE keyCode OF
1793
                |73: key := 33
1794
                |81: key := 34
1795
                |71: key := 36
1796
                |79: key := 35
1797
                |72: key := 38
1798
                |80: key := 40
1799
                |75: key := 37
1800
                |77: key := 39
9174 akron1 1801
                |82, 91, 219, 92, 220: key := -1 (* insert, windows *)
1802
                |93: ShowMenu(context); key := -1
9073 leency 1803
                |83: key := 46
1804
                |59, 62..66, 68, 87, 88: key := -1 (* F1, F4..F8, F10, F11, F12 *)
1805
                ELSE
1806
                    IF ctrl THEN
1807
                        CASE keyCode OF
1808
                        |17: closeFile(TRUE, curText);
1809
                             key := -2
1810
                        |21: T.redo(text);
1811
                             key := -1
1812
                        |22: key := ORD("U")
1813
                        |24: key := -1;
1814
                             open
1815
                        |30: key := ORD("A")
1816
                        |31: key := -1;
1817
                             save(text)
1818
                        |32: key := ORD("D")
1819
                        |38: key := ORD("L")
1820
                        |44: T.undo(text);
1821
                             key := -1
1822
                        |45: key := ORD("X")
1823
                        |46: key := ORD("C")
1824
                        |47: key := ORD("V")
1825
                        |49: key := -1;
1826
                             NewFile
1827
                        ELSE
1828
                            key := -1
1829
                        END
1830
                    ELSE
1831
                        T.input(text, E.cp866[key DIV 256 MOD 256]);
1832
                        key := -1
1833
                    END
1834
                END;
1835
                IF key >= 0 THEN
1836
                    T.key(text, key, shift, ctrl)
1837
                END
1838
            END
1839
        END
1840
    END;
1841
    IF key # -2 THEN
1842
        repaint
1843
    END
1844
END KeyDown;
1845
 
1846
 
1847
PROCEDURE BtnClick;
1848
VAR
1849
    btn: INTEGER;
1850
    middle, exit: BOOLEAN;
1851
BEGIN
1852
    btn := K.ButtonCode(middle);
1853
    IF (Tabs.btnID <= btn) & (btn <= Tabs.btnID + maxTexts - 1) THEN
1854
        DEC(btn, Tabs.btnID);
1855
        IF middle THEN
1856
            IF texts[btn].modified THEN
1857
                SwitchTab(btn)
1858
            END;
1859
            closeFile(TRUE, btn)
1860
        ELSE
1861
            SwitchTab(btn)
1862
        END;
1863
        btn := 0
1864
    ELSE
1865
        IF middle THEN
1866
            btn := 0
1867
        END
1868
    END;
1869
    CASE btn OF
1870
    |Tabs.btnID - 1: Tabs.scroll(tabs, -1); switch := TRUE; repaint
1871
    |Tabs.btnID - 2: Tabs.scroll(tabs, +1); switch := TRUE; repaint
1872
 
1873
    |0:
1874
 
1875
    |btnFile:
1876
        ShowMenu(menuFile)
1877
    |btnEdit:
1878
        ShowMenu(menuEdit)
9174 akron1 1879
    |btnMenuSearch:
1880
        ShowMenu(menuSearch)
9073 leency 1881
    |btnEncoding:
1882
        ShowMenu(menuEncoding)
9180 akron1 1883
    |btnEOL:
1884
        ShowMenu(menuEOL)
9073 leency 1885
    |btnView:
1886
        ShowMenu(menuView)
1887
    |btnSyntax:
1888
        ShowMenu(menuSyntax)
1889
    |btnProgram:
1890
        ShowMenu(menuProgram)
1891
    |btnTools:
1892
        ShowMenu(menuTools)
1893
    |btnNo:
1894
        exit := closing;
1895
        closeFile(FALSE, curText);
1896
        repaint;
1897
        IF exit THEN
1898
            Close
1899
        END
1900
    |btnYes:
1901
        exit := closing;
1902
        save(text);
1903
        IF ~text.modified THEN
1904
            closeFile(FALSE, curText)
1905
        END;
1906
        repaint;
1907
        IF exit THEN
1908
            Close
1909
        END
1910
    |btnClose:
1911
        Close
1912
    |btnNew:
1913
        NewFile;
1914
        repaint
1915
    |btnOpen:
1916
        open
1917
    |btnSave:
1918
        save(text);
1919
        repaint
1920
    |btnSearch:
1921
        ShowSearchPanel
1922
    |btnCloseFind:
1923
        Search
1924
    |btnHideFind:
1925
        SetFocus(FindEdit, FALSE);
1926
        searchOpened := FALSE;
1927
        LEFT := searchLeft;
1928
        resize;
1929
        draw_window
1930
    |btnUndo:
1931
        T.undo(text);
1932
        repaint
1933
    |btnRedo:
1934
        T.redo(text);
1935
        repaint
1936
    |btnUpper:
1937
        T.chCase(text, TRUE);
1938
        repaint
1939
    |btnLower:
1940
        T.chCase(text, FALSE);
1941
        repaint
1942
    |btnBuild:
1943
        Script(buildScript)
1944
    |btnRun:
1945
        Script(runScript)
1946
    |btnFindNext:
1947
        IF searchText # "" THEN
1948
            notFound := ~T.findNext(text, box_lib.check_box_get_value(BKW));
1949
            repaint
1950
        END
1951
    |btnReplace:
1952
        T.replace(text, replaceText, LENGTH(searchText));
1953
        repaint
1954
    |btnReplaceAll:
1955
        notFound := ~T.search(text, searchText, cs, whole);
1956
        IF ~notFound THEN
1957
            replaced := T.replaceAll(text, replaceText, LENGTH(searchText));
1958
        END;
1959
        repaint
1960
    |btnGoto:
1961
        goto;
1962
        repaint
1963
    END
1964
END BtnClick;
1965
 
1966
 
1967
PROCEDURE MouseEvent (VAR resized: BOOLEAN; VAR firstClickX, firstClickY, time: INTEGER);
1968
CONST
1969
    DELAY = 10;
1970
VAR
1971
    msState: SET;
1972
    scroll, x, y, scrollX, scrollY: INTEGER;
1973
 
1974
 
1975
    PROCEDURE EditBox (eb: box_lib.edit_box);
1976
    VAR
1977
        focus: BOOLEAN;
1978
    BEGIN
1979
        focus := EditBox_Focus(eb);
1980
        box_lib.edit_box_mouse(eb);
1981
        IF focus # EditBox_Focus(eb) THEN
9174 akron1 1982
            SetFocus(eb, TRUE);
1983
            repaint
9073 leency 1984
        END
1985
    END EditBox;
1986
 
1987
 
1988
BEGIN
9174 akron1 1989
	CloseMenu;
9073 leency 1990
    IF ~resized THEN
1991
        msState := K.MouseState();
1992
        IF ~(0 IN msState) OR (16 IN msState) THEN
1993
            LeftButtonUp
1994
        END;
1995
        scroll := K.Scroll();
1996
        IF scroll # 0 THEN
1997
            T.scroll(text, 0, scroll*3);
1998
            repaint
1999
        END;
2000
        IF leftButton THEN
2001
            IF K.GetTickCount() - time >= DELAY THEN
2002
                mouse(x, y);
2003
                T.mouse(text, x, y);
2004
                repaint
2005
            END
2006
        END;
9174 akron1 2007
		IF Scroll.isActive(hScroll) THEN
2008
			mouse(x, y);
2009
			Scroll.MouseMove(hScroll, x + LEFT, y + TOP);
9073 leency 2010
            T.getScroll(text, scrollX, scrollY);
9174 akron1 2011
            T.scroll(text, hScroll.value - scrollX, 0);
2012
			repaint
2013
		END;
2014
		IF Scroll.isActive(vScroll) THEN
2015
			mouse(x, y);
2016
			Scroll.MouseMove(vScroll, x + LEFT, y + TOP);
2017
            T.getScroll(text, scrollX, scrollY);
9073 leency 2018
            T.scroll(text, 0, vScroll.value - scrollY);
9174 akron1 2019
			repaint
2020
		END;
9073 leency 2021
        IF (8 IN msState) & ~(24 IN msState) THEN
2022
            mouse(firstClickX, firstClickY);
2023
            time := click(firstClickX, firstClickY)
2024
        END;
2025
        IF 9 IN msState THEN
2026
            ShowMenu(context)
2027
        END;
2028
        IF 24 IN msState THEN
2029
            mouse(x, y);
9174 akron1 2030
    		IF ~hScroll.mouse THEN
2031
    			Scroll.MouseDown(hScroll, x + LEFT, y + TOP)
2032
    		END;
2033
    		IF ~vScroll.mouse THEN
2034
    			Scroll.MouseDown(vScroll, x + LEFT, y + TOP)
2035
    		END;
9073 leency 2036
            IF (ABS(x - firstClickX) < 5) & (ABS(y - firstClickY) < 5) THEN
2037
                IF (0 <= x) & (x < canvas.width) & (0 <= y) & (y < canvas.height) THEN
2038
                    leftButton := FALSE;
2039
                    T.selectWord(text);
2040
                    repaint
2041
                END
2042
            ELSE
2043
                firstClickX := x;
2044
                firstClickY := y;
2045
                time := click(firstClickX, firstClickY)
2046
            END
2047
        END
2048
    END;
2049
    IF search & searchOpened THEN
2050
        EditBox(FindEdit);
2051
        EditBox(ReplaceEdit);
2052
        EditBox(GotoEdit);
2053
        box_lib.check_box_mouse2(CS);
2054
        box_lib.check_box_mouse2(WH);
2055
        box_lib.check_box_mouse2(BKW);
2056
        IF box_lib.check_box_get_value(CS) # cs THEN
2057
            cs := ~cs;
2058
            notFound := ~T.search(text, searchText, cs, whole);
2059
            repaint
2060
        END;
2061
        IF box_lib.check_box_get_value(WH) # whole THEN
2062
            whole := ~whole;
2063
            notFound := ~T.search(text, searchText, cs, whole);
2064
            repaint
2065
        END
2066
    END;
2067
    resized := FALSE
2068
END MouseEvent;
2069
 
2070
 
2071
PROCEDURE Redraw (VAR resized: BOOLEAN; VAR width, height, cliWidth, cliHeight: INTEGER);
2072
VAR
2073
    i: INTEGER;
2074
BEGIN
2075
    K.GetSystemColors;
2076
    FOR i := 0 TO 1 DO
2077
        IF ~K.RolledUp() THEN
2078
            K.ClientSize(width, height);
2079
            IF (width # cliWidth) OR (height # cliHeight) THEN
2080
                cliWidth := width;
2081
                cliHeight := height;
2082
                resize;
2083
                resized := TRUE
2084
            END;
2085
            K.SetEventsMask({0, 1, 2, 5, 6, 31})
2086
        ELSE
2087
            K.SetEventsMask({0, 30, 31})
2088
        END;
2089
        draw_window
2090
    END
2091
END Redraw;
2092
 
2093
 
8728 leency 2094
PROCEDURE main;
2095
VAR
2096
    err: INTEGER;
2097
    fileName, filePath: RW.tFileName;
9073 leency 2098
    width, height, cliWidth, cliHeight: INTEGER;
2099
    resized: BOOLEAN;
8728 leency 2100
    firstClickX, firstClickY, time: INTEGER;
2101
BEGIN
9174 akron1 2102
	delay := scrollDelay;
8762 leency 2103
    K.GetSystemColors;
2104
    Icons.get(icons, grayIcons);
8728 leency 2105
    modified := FALSE;
9050 leency 2106
    switch := FALSE;
9073 leency 2107
    closing := FALSE;
9050 leency 2108
    textsCount := 0;
2109
    curText := 0;
8728 leency 2110
    mainTID := K.ThreadID();
2111
    K.SetIPC(IPC);
2112
    U.ptr2str(K.GetName(), AppPath);
2113
    Ini.load(AppPath);
2114
    LeftButtonUp;
2115
    resized := FALSE;
8772 leency 2116
    K.ScreenSize(winWidth, winHeight);
9050 leency 2117
    winWidth := (winWidth*80) DIV 100 - (128 + 30);
8772 leency 2118
    winHeight := winHeight - (128 + 30);
2119
    winWidth := MAX(winWidth, minWinWidth);
2120
    winHeight := MAX(winHeight, minWinHeight);
8762 leency 2121
    cliWidth := winWidth;
2122
    cliHeight := winHeight;
8859 leency 2123
    LEFT := searchLeft;
9181 akron1 2124
    canvas := G.CreateCanvas(winWidth - (LEFT + RIGHT + 11), winHeight - (TOP + BOTTOM + 5) - K.SkinHeight());
9050 leency 2125
    tabs := Tabs.create();
2126
    Tabs.setArea(tabs, LEFT, TOP - Tabs.tabHeight, canvas.width, Tabs.tabHeight);
8772 leency 2127
    font1 := G.CreateFont(1, "", {});
2128
    font2 := G.CreateFont(2, "", {});
2129
    font := font1;
8728 leency 2130
    G.SetFont(canvas, font);
9174 akron1 2131
    T.init(resetTimer);
8728 leency 2132
    T.setCanvas(canvas);
2133
    U.ptr2str(K.GetCommandLine(), fileName);
9180 akron1 2134
 
8728 leency 2135
    context := CreateContextMenu();
2136
    menuFile := CreateMenuFile();
9174 akron1 2137
    subCurLine := CreateMenuCurLine();
2138
    subIndent := CreateMenuIndent();
2139
    subCase := CreateMenuCase();
8728 leency 2140
    menuEdit := CreateMenuEdit();
9174 akron1 2141
    subCurLine.parent := menuEdit;
2142
    subIndent.parent := menuEdit;
2143
    subCase.parent := menuEdit;
2144
    subBookmark := CreateMenuBookmark();
2145
    menuSearch := CreateMenuSearch();
2146
    subBookmark.parent := menuSearch;
8728 leency 2147
    menuEncoding := CreateMenuEncoding();
9180 akron1 2148
    menuEOL := CreateMenuEOL();
8728 leency 2149
    menuView := CreateMenuView();
2150
    menuSyntax := CreateMenuSyntax();
2151
    menuProgram := CreateMenuProgram();
2152
    menuTools := CreateMenuTools();
9174 akron1 2153
 
2154
    Ini.getSettings(buildScript, runScript, debugScript);
8728 leency 2155
    IF fileName = "" THEN
2156
        text := T.New();
2157
        filePath := "/rd/1"
2158
    ELSE
2159
        text := T.open(fileName, err);
2160
        IF text = NIL THEN
2161
            error("'cedit: error opening file' -E");
9181 akron1 2162
            K.Exit
8728 leency 2163
        ELSE
2164
            U.getPath(fileName, filePath)
2165
        END
2166
    END;
2167
    OD := OpenDlg.Create(draw_window, OpenDlg.topen, filePath, "");
9050 leency 2168
    insert(0, text);
9181 akron1 2169
    Scroll.create(FALSE, canvas.width + 1, scrollWidth, scrollWidth, scrollWidth, hScroll);
2170
    Scroll.create(TRUE, scrollWidth, canvas.height + 1, scrollWidth, scrollWidth, vScroll);
8728 leency 2171
    T.resize(canvas.width, canvas.height);
2172
    T.SetPos(text, 0, 0);
2173
    confirm := FALSE;
2174
    notFound := FALSE;
9175 akron1 2175
    menuFindClicked := FALSE;
2176
    menuActive := FALSE;
8728 leency 2177
    search := FALSE;
9073 leency 2178
    searchOpened := FALSE;
8728 leency 2179
    createSearchForm;
2180
    new_searchText := "";
2181
    searchText := "";
2182
    cs := FALSE;
2183
    whole := FALSE;
2184
    replaced := 0;
9073 leency 2185
    K.SetEventsMask({0, 1, 2, 5, 6, 31});
9174 akron1 2186
    Menu.init(resetTimer);
8728 leency 2187
    draw_window;
9174 akron1 2188
    Timer.create(mainTID);
8728 leency 2189
    WHILE TRUE DO
2190
        CASE K.WaitForEvent() OF
9174 akron1 2191
        |1: IF Menu.redraw THEN
2192
        		Redraw(resized, width, height, cliWidth, cliHeight)
2193
        	ELSE
2194
        		Menu.Redraw;
2195
        		K.CreateWindow(30 + K.GetTickCount() MOD 128, 30 + K.GetTickCount() MOD 128, winWidth, winHeight, K.winColor, 73H, 0, 0, header);
2196
        		repaint
2197
        	END
9073 leency 2198
        |2: KeyDown(K.GetKey())
2199
        |3: BtnClick
2200
        |6: MouseEvent(resized, firstClickX, firstClickY, time)
8728 leency 2201
        |7: receiveIPC
2202
        END
2203
    END
2204
END main;
2205
 
2206
 
2207
BEGIN
2208
    main
2209
END CEdit.