Subversion Repositories Kolibri OS

Rev

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