Subversion Repositories Kolibri OS

Rev

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