Subversion Repositories Kolibri OS

Rev

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

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