Subversion Repositories Kolibri OS

Rev

Rev 8741 | Go to most recent revision | Details | 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
23
    SYSTEM, OpenDlg, K := KolibriOS,
24
    U := Utils, Lines, Menu, List,
25
    G := Graph, T := Text, E := Encodings,
26
    CB := Clipboard, Languages,
27
    ChangeLog, Scroll,
28
    RW, Ini, box_lib, LibImg;
29
 
30
CONST
31
    header = "CEdit (20-may-2021)";
32
 
33
    ShellFilter = "";(* "SH|"; *)
34
    EditFilter = "SH|ASM|TXT|INC|OB07|C|CPP|H|PAS|PP|LUA|INI";
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;
51
    btnUp = 30;
52
    btnDown = 31;
53
    btnLeft = 32;
54
    btnRight = 33;
55
    btnYes = 40;
56
    btnNo = 41;
57
    btnFindEdit = 50;
58
    btnReplaceEdit = 51;
59
    btnGotoEdit = 52;
60
    btnFindNext = 60;
61
    btnReplace = 61;
62
    btnReplaceAll = 62;
63
    btnGoto = 63;
64
    btnCloseFind = 64;
65
 
66
    btnFile = 70;
67
    btnEdit = 71;
68
    btnEncoding = 72;
69
    btnView = 73;
70
    btnSyntax = 74;
71
    btnProgram = 75;
72
    btnTools = 76;
73
 
74
    MainMenuHeight = fontHeight + 7;
75
 
76
    btnColor = 0CCCCCCH;
77
    btnHeight = 25;
78
    btnWidth = 75;
79
    btnTop = MainMenuHeight + 3;
80
    toolBtnSize = 24;
81
    toolbarDelim = 7;
82
 
83
    TOP = btnTop + toolBtnSize + 7;
84
    RIGHT = scrollWidth - 2;
85
    BOTTOM = scrollWidth + 25;
86
 
87
    winColor = K.winColor; minWinWidth = 635; minWinHeight = 542;
88
 
89
    toolbarColor = 0DFDFDFH;
90
 
91
    SEARCH_PADDING = 10;
92
    searchLeft = 10;
93
    EditBox_Width = 180;
94
    EDITBOX_MAXCHARS = 500;
95
 
96
    menuFileX = searchLeft;
97
    menuEditX = menuFileX + 4*fontWidth + 2 + 7;
98
    menuEncodingX = menuEditX + 4*fontWidth + 2 + 7;
99
    menuViewX = menuEncodingX + 8*fontWidth + 2 + 7;
100
    menuSyntaxX = menuViewX + 4*fontWidth + 2 + 7;
101
    menuProgramX = menuSyntaxX + 6*fontWidth + 2 + 7;
102
    menuToolsX = menuProgramX + 7*fontWidth + 2 + 7;
103
 
104
    menuCut = 1;
105
    menuCopy = 2;
106
    menuPaste = 3;
107
    menuDelete = 4;
108
    menuSelectAll = 5;
109
 
110
    menuUndo = 6;
111
    menuRedo = 7;
112
 
113
    menuSearch = 8;
114
    menuGoto = 9;
115
 
116
    menuNew = 10;
117
    menuOpen = 11;
118
    menuSave = 12;
119
    menuSaveAs = 13;
120
    menuFolder = 14;
121
    menuExit = 15;
122
 
123
    menuNumbers = 20;
124
    (*menuSettings = 21;*)
125
    menuColors = 1000;
126
    menuMaxColors = menuColors + Ini.MAX_SECTIONS - 1;
127
 
128
    menuNone = 30;
129
    menuC = 31;
130
    menuFasm = 32;
131
    menuIni = 33;
132
    menuLua = 34;
133
    menuOberon = 35;
134
    menuPascal = 36;
135
 
136
    menuBuild = 50;
137
    menuBuildScript = 51;
138
    menuRun = 52;
139
    menuRunScript = 53;
140
    menuDebug = 54;
141
    menuDebugScript = 55;
142
 
143
    menuUTF8BOM = 60;
144
    menuUTF8 = 61;
145
    menuCP866 = 62;
146
    menuWin1251 = 63;
147
 
148
    menuPipet = 70;
149
    menuSysFunc = 71;
150
 
151
VAR
152
    canvas: G.tCanvas;
153
    font: G.tFont;
154
    text: T.tText;
155
    winWidth, winHeight: INTEGER;
156
    shift: SET;
157
    AppPath, runScript, buildScript, debugScript: RW.tFileName;
158
    OD: OpenDlg.Dialog;
159
    confirm, notFound, search, modified: BOOLEAN;
160
 
161
    leftButton, VScroll, HScroll: BOOLEAN;
162
    vScroll, hScroll: Scroll.tScroll;
163
    LEFT: INTEGER;
164
 
165
    FindEdit, ReplaceEdit, GotoEdit: box_lib.edit_box;
166
    CS, WH, BKW: box_lib.checkbox;
167
 
168
    new_searchText, searchText, replaceText, gotoText: T.tString;
169
    cs, whole: BOOLEAN;
170
 
171
    replaced: INTEGER;
172
 
173
    mainTID: INTEGER;
174
 
175
    context, menuFile, menuEdit, menuEncoding, menuView, menuSyntax, menuProgram, menuTools: Menu.tMenu;
176
 
177
    icons: INTEGER;
178
    grayIcons: INTEGER;
179
 
180
    IPC: ARRAY 64 OF INTEGER;
181
 
182
 
183
PROCEDURE WritePos (y: INTEGER);
184
VAR
185
    s1, s2: ARRAY 32 OF WCHAR;
186
    line, col: INTEGER;
187
BEGIN
188
    T.getPos(text, col, line);
189
    U.int2str(line, s1);
190
    U.int2str(col, s2);
191
    U.append(s1, ": ");
192
    U.append(s1, s2);
193
    K.DrawText(LEFT, y, 0, s1)
194
END WritePos;
195
 
196
 
197
PROCEDURE EditBox_Focus (edit: box_lib.edit_box): BOOLEAN;
198
    RETURN 1 IN BITS(edit.flags)
199
END EditBox_Focus;
200
 
201
 
202
PROCEDURE EditBox_SetFocus (edit: box_lib.edit_box; value: BOOLEAN);
203
BEGIN
204
    IF value THEN
205
        edit.flags := ORD(BITS(edit.flags) + {1})
206
    ELSE
207
        edit.flags := ORD(BITS(edit.flags) - {1})
208
    END;
209
(*    IF value THEN
210
        edit.color := 0FFFFFFH
211
    ELSE
212
        edit.color := 0D0D0D0H
213
    END;*)
214
    IF search THEN
215
        box_lib.edit_box_draw(edit)
216
    END
217
END EditBox_SetFocus;
218
 
219
 
220
PROCEDURE Rect (left, top, right, bottom, color: INTEGER);
221
BEGIN
222
    K.DrawLine(left, top, right, top, color);
223
    K.DrawLine(left, bottom, right, bottom, color);
224
    K.DrawLine(left, top, left, bottom, color);
225
    K.DrawLine(right, top, right, bottom, color);
226
END Rect;
227
 
228
 
229
PROCEDURE Message (s: ARRAY OF WCHAR);
230
CONST
231
    minWidth = 30;
232
    height = 40;
233
    borderColor = 808080H;
234
VAR
235
    top, left, right, bottom, x, y, width: INTEGER;
236
BEGIN
237
    width := minWidth + LENGTH(s)*fontWidth;
238
    left := (canvas.width - width) DIV 2 + LEFT;
239
    top := (canvas.height - height) DIV 2 + TOP;
240
    bottom := top + height - 1;
241
    right := left + width - 1;
242
    x := minWidth DIV 2 + left;
243
    y := (height - fontHeight) DIV 2 + top;
244
    K.DrawRect(left, top, width, height, winColor);
245
    Rect(left, top, right, bottom, borderColor);
246
    K.DrawText(x, y, 0, s);
247
END Message;
248
 
249
 
250
PROCEDURE NotFound;
251
BEGIN
252
    IF notFound THEN
253
        Message("not found");
254
        notFound := FALSE;
255
        EditBox_SetFocus(FindEdit, TRUE);
256
        EditBox_SetFocus(ReplaceEdit, FALSE);
257
        EditBox_SetFocus(GotoEdit, FALSE)
258
    END
259
END NotFound;
260
 
261
 
262
PROCEDURE Replaced;
263
VAR
264
    s, s1: ARRAY 32 OF WCHAR;
265
BEGIN
266
    IF replaced # 0 THEN
267
        s := "replaced: ";
268
        U.int2str(replaced, s1);
269
        U.append(s, s1);
270
        Message(s);
271
        replaced := 0;
272
        EditBox_SetFocus(FindEdit, TRUE);
273
        EditBox_SetFocus(ReplaceEdit, FALSE);
274
        EditBox_SetFocus(GotoEdit, FALSE)
275
    END
276
END Replaced;
277
 
278
 
279
PROCEDURE icons16 (icons, n, x, y: INTEGER);
280
VAR
281
    sizeX, sizeY, data: INTEGER;
282
BEGIN
283
    LibImg.GetInf(icons, sizeX, sizeY, data);
284
    K.DrawImage(data + 16*16*3*n, 16, 16, x, y)
285
END icons16;
286
 
287
 
288
PROCEDURE toolbarIcons;
289
CONST
290
    iconPad = (toolBtnSize - 16) DIV 2;
291
VAR
292
    x, color: INTEGER;
293
BEGIN
294
    x := searchLeft + (toolBtnSize + 5)*2;
295
    IF text.modified THEN
296
        icons16(icons, 5, x + iconPad, btnTop + iconPad)
297
    ELSE
298
        icons16(grayIcons, 5, x + iconPad, btnTop + iconPad)
299
    END;
300
 
301
    IF text.edition # NIL THEN
302
        x := searchLeft + (toolBtnSize + 5)*4 + toolbarDelim*2;
303
        IF ChangeLog.isFirstGuard(text.edition) THEN
304
            icons16(grayIcons, 37, x + iconPad, btnTop + iconPad)
305
        ELSE
306
            icons16(icons, 37, x + iconPad, btnTop + iconPad)
307
        END;
308
 
309
        x := searchLeft + (toolBtnSize + 5)*5 + toolbarDelim*2;
310
        IF ChangeLog.isLastGuard(text.edition) THEN
311
            icons16(grayIcons, 36, x + iconPad, btnTop + iconPad)
312
        ELSE
313
            icons16(icons, 36, x + iconPad, btnTop + iconPad)
314
        END
315
(*    ELSE
316
        x := searchLeft + (toolBtnSize + 5)*4;
317
        icons16(grayIcons, 37, x + iconPad, btnTop + iconPad);
318
        x := searchLeft + (toolBtnSize + 5)*5;
319
        icons16(grayIcons, 36, x + iconPad, btnTop + iconPad)*)
320
    END;
321
 
322
    IF T.selected(text) THEN
323
        color := 00000FFH
324
    ELSE
325
        color := 0808080H
326
    END;
327
 
328
    x := searchLeft + (toolBtnSize + 5)*6 + toolbarDelim*3;
329
    K.DrawRect(x, btnTop, toolBtnSize, toolBtnSize, toolbarColor);
330
    K.DrawText69(x + (toolBtnSize - 12) DIV 2, btnTop + (toolBtnSize - 9) DIV 2 + 2, color, "AB");
331
    INC(x, toolBtnSize + 5);
332
    K.DrawRect(x, btnTop, toolBtnSize, toolBtnSize, toolbarColor);
333
    K.DrawText69(x + (toolBtnSize - 12) DIV 2, btnTop + (toolBtnSize - 9) DIV 2 + 2, color, "ab");
334
 
335
    x := searchLeft + (toolBtnSize + 5)*8 + toolbarDelim*4;
336
    IF buildScript # "" THEN
337
        icons16(icons, 54, x + iconPad, btnTop + iconPad)
338
    ELSE
339
        icons16(grayIcons, 54, x + iconPad, btnTop + iconPad)
340
    END;
341
    INC(x, toolBtnSize + 5);
342
    IF runScript # "" THEN
343
        icons16(icons, 53, x + iconPad, btnTop + iconPad)
344
    ELSE
345
        icons16(grayIcons, 53, x + iconPad, btnTop + iconPad)
346
    END
347
END toolbarIcons;
348
 
349
 
350
PROCEDURE WriteModified (x, y: INTEGER);
351
BEGIN
352
    modified := text.modified;
353
    K.DrawRect(x, TOP + canvas.height + scrollWidth - 1, 9*fontWidth, BOTTOM - scrollWidth + 1, winColor);
354
    IF modified THEN
355
        K.DrawText866(x, y, 0, "modified")
356
    END
357
END WriteModified;
358
 
359
 
360
PROCEDURE repaint;
361
VAR
362
    width, height, scrollX, scrollY, y: INTEGER;
363
BEGIN
364
    IF text # NIL THEN
365
        IF confirm THEN
366
            K.DeleteButton(btnYes);
367
            K.DeleteButton(btnNo);
368
            confirm := FALSE
369
        END;
370
        T.draw(text);
371
        K.ClientSize(width, height);
372
        y := height - (BOTTOM - scrollWidth) + (BOTTOM - scrollWidth - 16) DIV 2;
373
        K.DrawRect(LEFT, TOP + canvas.height + scrollWidth - 1, 16*fontWidth, BOTTOM - scrollWidth + 1, winColor);
374
        WritePos(y);
375
 
376
        IF modified # text.modified THEN
377
            WriteModified(width - 9*fontWidth, y)
378
        END;
379
 
380
        T.getScroll(text, scrollX, scrollY);
381
        vScroll.value := scrollY; vScroll.maxVal := text.count - 1;
382
        hScroll.value := scrollX; hScroll.maxVal := Lines.maxLength;
383
        Scroll.draw(vScroll, LEFT + canvas.width - 1, TOP + scrollWidth - 1);
384
        Scroll.draw(hScroll, LEFT + scrollWidth, TOP + canvas.height - 1);
385
 
386
        G.DrawCanvas(canvas, LEFT, TOP);
387
        NotFound;
388
        Replaced;
389
        toolbarIcons
390
    END
391
END repaint;
392
 
393
 
394
PROCEDURE resize;
395
VAR
396
    cliWidth, cliHeight: INTEGER;
397
BEGIN
398
    K.WinSize(winWidth, winHeight);
399
    IF winWidth < minWinWidth THEN
400
        winWidth := minWinWidth
401
    END;
402
    IF winHeight < minWinHeight THEN
403
        winHeight := minWinHeight
404
    END;
405
    K.SetWinSize(winWidth, winHeight);
406
    K.WinSize(winWidth, winHeight);
407
    K.ClientSize(cliWidth, cliHeight);
408
    G.destroy(canvas);
409
    canvas := G.CreateCanvas(cliWidth - (LEFT + RIGHT + 1), cliHeight - (TOP + BOTTOM));
410
    G.SetFont(canvas, font);
411
    T.setCanvas(canvas);
412
    T.resize(canvas.width, canvas.height);
413
    Scroll.resize(vScroll, vScroll.xSize, canvas.height - scrollWidth*2 + 1);
414
    Scroll.resize(hScroll, canvas.width - scrollWidth*2, hScroll.ySize);
415
END resize;
416
 
417
 
418
PROCEDURE SearchPanel (left, top: INTEGER);
419
VAR
420
    y, right, bottom, color: INTEGER;
421
BEGIN
422
    right := left + EditBox_Width + SEARCH_PADDING*2;
423
    bottom := top + 395 + btnHeight + SEARCH_PADDING;
424
    color := T.colors.border;
425
    Rect(left, top, right, bottom, color);
426
    K.CreateButton(btnCloseFind, right - 20, top, 20, 20, 0EF999FH, "");
427
    K.DrawLine(right - 14, top + 5, right - 5, top + 14, 0FFFFFFH);
428
    K.DrawLine(right - 15, top + 5, right - 5, top + 15, 0FFFFFFH);
429
    K.DrawLine(right - 15, top + 6, right - 6, top + 15, 0FFFFFFH);
430
    K.DrawLine(right - 15, top + 14, right - 6, top + 5, 0FFFFFFH);
431
    K.DrawLine(right - 15, top + 15, right - 5, top + 5, 0FFFFFFH);
432
    K.DrawLine(right - 14, top + 15, right - 5, top + 6, 0FFFFFFH);
433
 
434
    INC(top, 15);
435
    INC(left, SEARCH_PADDING);
436
    K.DrawText866(left, top, 0, "find");
437
    K.DrawText866(left, top + 55, 0, "replace with");
438
    K.CreateButton(btnFindEdit + ORD({30}), left, top + 20, EditBox_Width, fontHeight + 5, 0, "");
439
    K.CreateButton(btnReplaceEdit + ORD({30}), left, top + 75, EditBox_Width, fontHeight + 5, 0, "");
440
    K.DrawText866(left, top + 330, 0, "go to line");
441
    K.CreateButton(btnGotoEdit + ORD({30}), left, top + 350, EditBox_Width, fontHeight + 5, 0, "");
442
    BKW.top_s := BKW.top_s MOD 65536 + (top + 110) * 65536;
443
    CS.top_s := CS.top_s MOD 65536 + (top + 140) * 65536;
444
    WH.top_s := WH.top_s MOD 65536 + (top + 170) * 65536;
445
    BKW.left_s := BKW.left_s MOD 65536 + left * 65536;
446
    CS.left_s := CS.left_s MOD 65536 + left * 65536;
447
    WH.left_s := WH.left_s MOD 65536 + left * 65536;
448
    FindEdit.top := top + 20;
449
    ReplaceEdit.top := top + 75;
450
    GotoEdit.top := top + 350;
451
    FindEdit.left := left;
452
    ReplaceEdit.left := left;
453
    GotoEdit.left := left;
454
    box_lib.edit_box_draw(FindEdit);
455
    box_lib.edit_box_draw(ReplaceEdit);
456
    box_lib.edit_box_draw(GotoEdit);
457
    box_lib.check_box_draw2(BKW); K.DrawText866(left + 20, top + 110, 0, "backward");
458
    box_lib.check_box_draw2(CS); K.DrawText866(left + 20, top + 140, 0, "match case");
459
    box_lib.check_box_draw2(WH); K.DrawText866(left + 20, top + 170, 0, "whole word");
460
    y := top + 200;
461
    K.CreateButton(btnFindNext, left, y, btnWidth, btnHeight, btnColor, "next"); INC(y, btnHeight + 10);
462
    K.CreateButton(btnReplace, left, y, btnWidth, btnHeight, btnColor, "replace"); INC(y, btnHeight + 10);
463
    K.CreateButton(btnReplaceAll, left, y, btnWidth + 5*fontWidth - 2, btnHeight, btnColor, "replace all");
464
    K.CreateButton(btnGoto, left, top + 380, btnWidth, btnHeight, btnColor, "go");
465
END SearchPanel;
466
 
467
 
468
PROCEDURE gray (icons: INTEGER);
469
VAR
470
    sizeX, sizeY, data, x, y: INTEGER;
471
    b, g, r, gr: BYTE;
472
BEGIN
473
    LibImg.GetInf(icons, sizeX, sizeY, data);
474
    FOR y := 0 TO sizeY - 1 DO
475
        FOR x := 0 TO sizeX - 1 DO
476
            SYSTEM.GET8(data, b);
477
            SYSTEM.GET8(data + 1, g);
478
            SYSTEM.GET8(data + 2, r);
479
            gr := (r + g + b) DIV 3;
480
            SYSTEM.PUT8(data, gr);
481
            SYSTEM.PUT8(data + 1, gr);
482
            SYSTEM.PUT8(data + 2, gr);
483
            INC(data, 3);
484
        END
485
    END
486
END gray;
487
 
488
 
489
PROCEDURE iconsBackColor (icons: INTEGER);
490
VAR
491
    sizeX, sizeY, data, x, y: INTEGER;
492
    b, g, r: BYTE;
493
BEGIN
494
    LibImg.GetInf(icons, sizeX, sizeY, data);
495
    FOR y := 0 TO sizeY - 1 DO
496
        FOR x := 0 TO sizeX - 1 DO
497
            SYSTEM.GET8(data, b);
498
            SYSTEM.GET8(data + 1, g);
499
            SYSTEM.GET8(data + 2, r);
500
            IF b + g + r = 765 THEN
501
                b := toolbarColor MOD 256;
502
                g := toolbarColor DIV 256 MOD 256;
503
                r := toolbarColor DIV 65536 MOD 256
504
            END;
505
            SYSTEM.PUT8(data, b);
506
            SYSTEM.PUT8(data + 1, g);
507
            SYSTEM.PUT8(data + 2, r);
508
            INC(data, 3);
509
        END
510
    END
511
END iconsBackColor;
512
 
513
 
514
PROCEDURE draw_window;
515
CONST
516
    selMenuColor = 0CCE8FFH;
517
    iconPad = (toolBtnSize - 16) DIV 2;
518
VAR
519
    width, height, x, y: INTEGER;
520
 
521
 
522
    PROCEDURE drawToolbarBtn (id, x: INTEGER);
523
    BEGIN
524
        K.DrawRect(x, btnTop, toolBtnSize, toolBtnSize, toolbarColor);
525
        K.DrawLine(x, btnTop + toolBtnSize, x + toolBtnSize, btnTop + toolBtnSize, 0808080H);
526
        K.DrawLine(x + toolBtnSize, btnTop, x + toolBtnSize, btnTop + toolBtnSize, 0808080H);
527
        K.CreateButton(id + ORD({30}), x, btnTop, toolBtnSize, toolBtnSize, btnColor, "");
528
    END drawToolbarBtn;
529
 
530
 
531
    PROCEDURE drawMainMenu (menu: Menu.tMenu; x: INTEGER; btn: INTEGER; caption: ARRAY OF WCHAR);
532
    VAR
533
        menuColor, n: INTEGER;
534
    BEGIN
535
        IF menu.tid # 0 THEN
536
            menuColor := selMenuColor
537
        ELSE
538
            menuColor := winColor
539
        END;
540
        n := LENGTH(caption);
541
        K.DrawRect(x, 0, n*fontWidth + 2, MainMenuHeight, menuColor);
542
        K.CreateButton(btn + ORD({30}), x, 0, n*fontWidth + 2, MainMenuHeight, btnColor, caption);
543
    END drawMainMenu;
544
 
545
 
546
BEGIN
547
    K.BeginDraw;
548
    K.CreateWindow(50 + K.GetTickCount() MOD 128, 50 + K.GetTickCount() MOD 128, winWidth, winHeight, winColor, 73H, 0, 0, header);
549
    IF (text # NIL) & ~K.RolledUp() THEN
550
        confirm := FALSE;
551
        K.ClientSize(width, height);
552
 
553
        K.DrawRect(0, 0, width, TOP, winColor);
554
        K.DrawRect(0, 0, LEFT, height, winColor);
555
        K.DrawRect(LEFT + canvas.width - 1, TOP + canvas.height - 1, scrollWidth, scrollWidth, winColor);
556
 
557
        drawMainMenu(menuFile, menuFileX, btnFile, "file");
558
        drawMainMenu(menuEdit, menuEditX, btnEdit, "edit");
559
        drawMainMenu(menuEncoding, menuEncodingX, btnEncoding, "encoding");
560
        drawMainMenu(menuView, menuViewX, btnView, "view");
561
        drawMainMenu(menuSyntax, menuSyntaxX, btnSyntax, "syntax");
562
        drawMainMenu(menuProgram, menuProgramX, btnProgram, "program");
563
        drawMainMenu(menuTools, menuToolsX, btnTools, "tools");
564
 
565
        x := searchLeft;
566
 
567
        drawToolbarBtn(btnNew, x);
568
        icons16(icons, 2, x + iconPad, btnTop + iconPad);
569
        INC(x, toolBtnSize + 5);
570
 
571
        drawToolbarBtn(btnOpen, x);
572
        icons16(icons, 0, x + iconPad, btnTop + iconPad);
573
        INC(x, toolBtnSize + 5);
574
 
575
        drawToolbarBtn(btnSave, x);
576
        INC(x, toolBtnSize + 5 + toolbarDelim);
577
 
578
        drawToolbarBtn(btnSearch, x);
579
        icons16(icons, 49, x + iconPad, btnTop + iconPad);
580
        INC(x, toolBtnSize + 5 + toolbarDelim);
581
 
582
        drawToolbarBtn(btnUndo, x);
583
        INC(x, toolBtnSize + 5);
584
 
585
        drawToolbarBtn(btnRedo, x);
586
        INC(x, toolBtnSize + 5 + toolbarDelim);
587
 
588
        drawToolbarBtn(btnUpper, x);
589
        K.DrawText69(x + (toolBtnSize - 12) DIV 2, btnTop + (toolBtnSize - 9) DIV 2 + 2, 0, "AB");
590
        INC(x, toolBtnSize + 5);
591
 
592
        drawToolbarBtn(btnLower, x);
593
        K.DrawText69(x + (toolBtnSize - 12) DIV 2, btnTop + (toolBtnSize - 9) DIV 2 + 2, 0, "ab");
594
        INC(x, toolBtnSize + 5 + toolbarDelim);
595
 
596
        drawToolbarBtn(btnBuild, x);
597
        icons16(icons, 54, x + iconPad, btnTop + iconPad);
598
        INC(x, toolBtnSize + 5);
599
 
600
        drawToolbarBtn(btnRun, x);
601
        icons16(icons, 53, x + iconPad, btnTop + iconPad);
602
        INC(x, toolBtnSize + 5);
603
 
604
        K.CreateButton(btnUp, LEFT + canvas.width - 1, TOP, scrollWidth - 1, scrollWidth, btnColor, 0X);
605
        K.DrawText69(LEFT + canvas.width - 1 + (scrollWidth - 6) DIV 2, TOP + (scrollWidth - 9) DIV 2, 0, 18X);
606
        K.CreateButton(btnDown, LEFT + canvas.width - 1, TOP + canvas.height - scrollWidth - 1, scrollWidth - 1, scrollWidth, btnColor, 0X);
607
        K.DrawText69(LEFT + canvas.width - 1 + (scrollWidth - 6) DIV 2, TOP + canvas.height - scrollWidth + (scrollWidth - 9) DIV 2, 0, 19X);
608
 
609
        K.CreateButton(btnLeft, LEFT, TOP + canvas.height - 1, scrollWidth, scrollWidth - 1, btnColor, 0X);
610
        K.DrawText69(LEFT + (scrollWidth - 6) DIV 2, TOP + canvas.height - 1 + (scrollWidth - 9) DIV 2 + 1, 0, 1BX);
611
        K.CreateButton(btnRight, LEFT + canvas.width - scrollWidth - 1, TOP + canvas.height - 1, scrollWidth, scrollWidth - 1, btnColor, 0X);
612
        K.DrawText69(LEFT + canvas.width - scrollWidth - 1 + (scrollWidth - 6) DIV 2, TOP + canvas.height - 1 + (scrollWidth - 9) DIV 2 + 1, 0, 1AX);
613
 
614
        y := (btnHeight - fontHeight) DIV 2 + btnTop;
615
        CASE text.enc OF
616
        |E.UTF8:    K.DrawText866(width -  6*fontWidth, y, 0, "UTF-8")
617
        |E.UTF8BOM: K.DrawText866(width - 10*fontWidth, y, 0, "UTF-8-BOM")
618
        |E.CP866:   K.DrawText866(width -  6*fontWidth, y, 0, "CP866")
619
        |E.W1251:   K.DrawText866(width - 13*fontWidth, y, 0, "Windows-1251")
620
        END;
621
        IF search THEN
622
            SearchPanel(searchLeft, TOP)
623
        END;
624
 
625
        y := height - (BOTTOM - scrollWidth) + (BOTTOM - scrollWidth - 16) DIV 2;
626
        K.DrawRect(LEFT + 16*fontWidth, TOP + canvas.height + scrollWidth - 1, width - LEFT - 25*fontWidth, BOTTOM - scrollWidth + 1, winColor);
627
        K.DrawText866(LEFT + 16*fontWidth, y, 0, text.fileName);
628
        WriteModified(width - 9*fontWidth, y);
629
        repaint
630
    END;
631
    K.EndDraw
632
END draw_window;
633
 
634
 
635
PROCEDURE mouse (VAR x, y: INTEGER);
636
VAR
637
    mouseX, mouseY,
638
    cliX, cliY,
639
    winX, winY: INTEGER;
640
BEGIN
641
    K.MousePos(mouseX, mouseY);
642
    K.WinPos(winX, winY);
643
    K.ClientPos(cliX, cliY);
644
    x := mouseX - winX - cliX - LEFT;
645
    y := mouseY - winY - cliY - TOP;
646
END mouse;
647
 
648
 
649
PROCEDURE getKBState;
650
VAR
651
    kbState: SET;
652
BEGIN
653
    kbState := K.GetControlKeys();
654
    IF {0, 1} * kbState # {} THEN
655
        INCL(shift, T.SHIFT)
656
    ELSE
657
        EXCL(shift, T.SHIFT)
658
    END;
659
 
660
    IF {2, 3} * kbState # {} THEN
661
        INCL(shift, T.CTRL)
662
    ELSE
663
        EXCL(shift, T.CTRL)
664
    END
665
END getKBState;
666
 
667
 
668
PROCEDURE OpenFile (VAR FileName: RW.tFileName; filter: ARRAY OF CHAR);
669
BEGIN
670
    OpenDlg.SetFilter(OD, filter);
671
    OpenDlg.Show(OD, 500, 400);
672
    WHILE OD.status = 2 DO
673
        K.Pause(30)
674
    END;
675
    IF OD.status = 1 THEN
676
        COPY(OD.FilePath, FileName)
677
    ELSE
678
        FileName := ""
679
    END
680
END OpenFile;
681
 
682
 
683
PROCEDURE error (s: RW.tFileName);
684
BEGIN
685
    K.Run("/rd/1/@notify", s)
686
END error;
687
 
688
 
689
PROCEDURE saveAs;
690
VAR
691
    fileName: RW.tFileName;
692
    ext: ARRAY 8 OF CHAR;
693
BEGIN
694
    OD._type := OpenDlg.tsave;
695
    U.getFileName(text.fileName, OD.FileName, U.SLASH);
696
    IF OD.FileName = "" THEN
697
        OD.FileName := "NewFile.";
698
        CASE text.lang OF
699
        |Languages.langNone:   ext := "txt"
700
        |Languages.langC:      ext := "c"
701
        |Languages.langFasm:   ext := "asm"
702
        |Languages.langIni:    ext := "ini"
703
        |Languages.langLua:    ext := "lua"
704
        |Languages.langOberon: ext := "ob07"
705
        |Languages.langPascal: ext := "pas"
706
        END;
707
        U.append8(OD.FileName, ext)
708
    END;
709
    OpenFile(fileName, EditFilter);
710
    IF fileName # "" THEN
711
        IF T.save(text, fileName, text.enc, RW.EOL_CRLF) THEN
712
            T.setName(text, fileName)
713
        ELSE
714
            error("'cedit: error saving file' -E")
715
        END
716
    END
717
END saveAs;
718
 
719
 
720
PROCEDURE save;
721
BEGIN
722
    IF text.modified THEN
723
        IF text.fileName # "" THEN
724
            IF ~T.save(text, text.fileName, text.enc, RW.EOL_CRLF) THEN
725
                error("'cedit: error saving file' -E")
726
            END
727
        ELSE
728
            saveAs
729
        END
730
    END
731
END save;
732
 
733
 
734
PROCEDURE SelfRun (file: ARRAY OF CHAR);
735
BEGIN
736
    K.Run(AppPath, file)
737
END SelfRun;
738
 
739
 
740
PROCEDURE open;
741
VAR
742
    fileName: RW.tFileName;
743
BEGIN
744
    OD._type := OpenDlg.topen;
745
    OpenFile(fileName, EditFilter);
746
    IF fileName # "" THEN
747
        SelfRun(fileName)
748
    END
749
END open;
750
 
751
 
752
PROCEDURE Confirm;
753
CONST
754
    width  = btnWidth*2 + 30;
755
    height = btnHeight*2 + 20;
756
    lineColor = 808080H;
757
VAR
758
    left, top, right, bottom: INTEGER;
759
BEGIN
760
    draw_window;
761
    confirm := TRUE;
762
    left := (canvas.width - width) DIV 2 + LEFT;
763
    top := (canvas.height - height) DIV 2 + TOP;
764
    right := left + width - 1;
765
    bottom := top + height - 1;
766
    K.DrawRect(left, top, width, height, winColor);
767
    Rect(left, top, right, bottom, lineColor);
768
    K.DrawText866(left + (width - 10*fontWidth) DIV 2, top + 10, 0, "save file?");
769
    K.CreateButton(btnYes, left + 10, top + 35, btnWidth, btnHeight, btnColor, "yes");
770
    K.CreateButton(btnNo, left + 20 + btnWidth, top + 35, btnWidth, btnHeight, btnColor, "no");
771
END Confirm;
772
 
773
 
774
PROCEDURE createEdit (left, top: INTEGER): box_lib.edit_box;
775
VAR
776
    edit, EditBox0: box_lib.edit_box;
777
BEGIN
778
    NEW(EditBox0);
779
    EditBox0.text := K.malloc(EDITBOX_MAXCHARS + 2);
780
    ASSERT(EditBox0.text # 0);
781
    edit := box_lib.kolibri_new_edit_box(left, top, EditBox_Width, EDITBOX_MAXCHARS, EditBox0);
782
    edit.flags := 4002H;
783
    edit.text_color := 30000000H;
784
    EditBox_SetFocus(edit, FALSE)
785
    RETURN edit
786
END createEdit;
787
 
788
 
789
PROCEDURE createSearchForm;
790
BEGIN
791
    FindEdit := createEdit(searchLeft, TOP + 20);
792
    ReplaceEdit := createEdit(searchLeft, TOP + 20 + 55);
793
    GotoEdit := createEdit(searchLeft, TOP + 20 + 330);
794
    GotoEdit.flags := ORD(BITS(GotoEdit.flags) + BITS(8000H));
795
    BKW := box_lib.kolibri_new_check_box(searchLeft, TOP + 90 + 20, 16, 16, "", 8*fontWidth + 4);
796
    CS := box_lib.kolibri_new_check_box(searchLeft, TOP + 120 + 20, 16, 16, "", 10*fontWidth + 4);
797
    WH := box_lib.kolibri_new_check_box(searchLeft, TOP + 150 + 20, 16, 16, "", 10*fontWidth + 4);
798
END createSearchForm;
799
 
800
 
801
PROCEDURE EditBox_GetValue (edit: box_lib.edit_box; VAR s: ARRAY OF WCHAR);
802
VAR
803
    str: ARRAY EDITBOX_MAXCHARS + 1 OF CHAR;
804
    i: INTEGER;
805
BEGIN
806
    box_lib.edit_box_get_value(edit, str);
807
    i := 0;
808
    WHILE str[i] # 0X DO
809
        s[i] := WCHR(E.cp866[ORD(str[i])]);
810
        INC(i)
811
    END;
812
    s[i] := 0X
813
END EditBox_GetValue;
814
 
815
 
816
PROCEDURE Search;
817
BEGIN
818
    search := ~search;
819
    IF search THEN
820
        LEFT := searchLeft + EditBox_Width + SEARCH_PADDING*3;
821
        IF T.search(text, searchText, cs, whole) THEN END
822
    ELSE
823
        LEFT := searchLeft;
824
        IF T.search(text, "", FALSE, FALSE) THEN END
825
    END;
826
    EditBox_SetFocus(FindEdit, search);
827
    EditBox_SetFocus(ReplaceEdit, FALSE);
828
    EditBox_SetFocus(GotoEdit, FALSE);
829
    resize;
830
    draw_window
831
END Search;
832
 
833
 
834
PROCEDURE click (x, y: INTEGER): INTEGER;
835
VAR
836
    scrollX, scrollY: INTEGER;
837
BEGIN
838
    IF (0 <= x) & (x < canvas.width) & (0 <= y) & (y < canvas.height) THEN
839
        leftButton := TRUE;
840
        EditBox_SetFocus(FindEdit, FALSE);
841
        EditBox_SetFocus(ReplaceEdit, FALSE);
842
        EditBox_SetFocus(GotoEdit, FALSE);
843
        IF ~(T.SHIFT IN shift) THEN
844
            T.resetSelect(text)
845
        END;
846
        T.mouse(text, x, y);
847
        repaint
848
    ELSIF (canvas.width < x) & (x < canvas.width + scrollWidth) & (scrollWidth < y) & (y < canvas.height - scrollWidth) THEN
849
        VScroll := TRUE;
850
        DEC(x, canvas.width);
851
        DEC(y, scrollWidth);
852
        Scroll.mouse(vScroll, x, y);
853
        T.getScroll(text, scrollX, scrollY);
854
        T.scroll(text, 0, vScroll.value - scrollY);
855
        repaint
856
    ELSIF (scrollWidth < x) & (x < canvas.width - scrollWidth) & (canvas.height < y) & (y < canvas.height + scrollWidth) THEN
857
        HScroll := TRUE;
858
        DEC(x, scrollWidth);
859
        DEC(y, canvas.height);
860
        Scroll.mouse(hScroll, x, y);
861
        T.getScroll(text, scrollX, scrollY);
862
        T.scroll(text, hScroll.value - scrollX, 0);
863
        repaint
864
    END
865
    RETURN K.GetTickCount()
866
END click;
867
 
868
 
869
PROCEDURE LeftButtonUp;
870
BEGIN
871
    leftButton := FALSE;
872
    VScroll := FALSE;
873
    HScroll := FALSE;
874
    Scroll.MouseUp(vScroll);
875
    Scroll.MouseUp(hScroll);
876
END LeftButtonUp;
877
 
878
 
879
PROCEDURE close;
880
BEGIN
881
    IF text.modified THEN
882
        Confirm
883
    ELSE
884
        K.Exit
885
    END
886
END close;
887
 
888
 
889
PROCEDURE MenuItemClick (menu: Menu.tMenu; id: INTEGER);
890
BEGIN
891
    K.SendIPC(mainTID, id)
892
END MenuItemClick;
893
 
894
 
895
PROCEDURE goto;
896
VAR
897
    gotoVal: INTEGER;
898
BEGIN
899
    EditBox_GetValue(GotoEdit, gotoText);
900
    IF U.str2int(gotoText, gotoVal) & T.goto(text, gotoVal) THEN END
901
END goto;
902
 
903
 
904
PROCEDURE Script (script: ARRAY OF CHAR);
905
BEGIN
906
    IF script # "" THEN
907
        K.Run("/rd/1/@open", script)
908
    END
909
END Script;
910
 
911
 
912
PROCEDURE receiveIPC;
913
BEGIN
914
    IF IPC[0] # Menu.lastTID THEN
915
        IPC[2] := 0
916
    END;
917
    CASE IPC[2] OF
918
    |0:
919
    |menuCut:       T.key(text, ORD("X"), {T.CTRL})
920
    |menuCopy:      T.key(text, ORD("C"), {T.CTRL})
921
    |menuPaste:     T.key(text, ORD("V"), {T.CTRL})
922
    |menuDelete:    T.key(text, 46, {})
923
    |menuSelectAll: T.key(text, ORD("A"), {T.CTRL})
924
 
925
    |menuNew:
926
        SelfRun("")
927
    |menuOpen:
928
        open
929
    |menuSave:
930
        save;
931
        repaint
932
    |menuSaveAs:
933
        saveAs;
934
        repaint
935
    |menuFolder:
936
        K.Run("/rd/1/File Managers/Eolite", text.fileName)
937
    |menuExit:
938
        close
939
    |menuUndo:
940
        T.undo(text);
941
        repaint
942
    |menuRedo:
943
        T.redo(text);
944
        repaint
945
    |menuSearch:
946
        IF ~search THEN
947
            Search
948
        END;
949
        EditBox_SetFocus(FindEdit, TRUE);
950
        EditBox_SetFocus(ReplaceEdit, FALSE);
951
        EditBox_SetFocus(GotoEdit, FALSE)
952
    |menuGoto:
953
        IF ~search THEN
954
            Search
955
        END;
956
        EditBox_SetFocus(GotoEdit, TRUE);
957
        EditBox_SetFocus(FindEdit, FALSE);
958
        EditBox_SetFocus(ReplaceEdit, FALSE)
959
    |menuNumbers:
960
        T.toggleNumbers(text)
961
    |menuNone:
962
        T.setLang(text, Languages.langNone)
963
    |menuC:
964
        T.setLang(text, Languages.langC)
965
    |menuFasm:
966
        T.setLang(text, Languages.langFasm)
967
    |menuIni:
968
        T.setLang(text, Languages.langIni)
969
    |menuLua:
970
        T.setLang(text, Languages.langLua)
971
    |menuOberon:
972
        T.setLang(text, Languages.langOberon)
973
    |menuPascal:
974
        T.setLang(text, Languages.langPascal)
975
    |menuBuild:
976
        Script(buildScript)
977
    |menuBuildScript:
978
        OpenFile(buildScript, ShellFilter)
979
    |menuRun:
980
        Script(runScript)
981
    |menuRunScript:
982
        OpenFile(runScript, ShellFilter)
983
    |menuDebug:
984
        Script(debugScript)
985
    |menuDebugScript:
986
        OpenFile(debugScript, ShellFilter)
987
    |menuUTF8BOM:
988
        text.enc := E.UTF8BOM
989
    |menuUTF8:
990
        text.enc := E.UTF8
991
    |menuCP866:
992
        text.enc := E.CP866
993
    |menuWin1251:
994
        text.enc := E.W1251
995
    |menuPipet:
996
        K.Run("/rd/1/develop/pipet", "")
997
    |menuSysFunc:
998
        K.Run("/rd/1/docpack", "f")
999
    |menuColors..menuMaxColors:
1000
        Ini.selectSection(IPC[2] - menuColors)
1001
    END;
1002
    IPC[0] := 0;
1003
    IPC[1] := 0
1004
END receiveIPC;
1005
 
1006
 
1007
PROCEDURE MenuKeyDown (menu: Menu.tMenu; key: INTEGER): BOOLEAN;
1008
VAR
1009
    menuItem: INTEGER;
1010
BEGIN
1011
    menuItem := -1;
1012
    getKBState;
1013
    IF (T.CTRL IN shift) THEN
1014
        CASE key DIV 65536 OF
1015
        |21: menuItem := menuRedo
1016
        |30: menuItem := menuSelectAll
1017
        |33: menuItem := menuSearch
1018
        |34: menuItem := menuGoto
1019
        |44: menuItem := menuUndo
1020
        |45: menuItem := menuCut
1021
        |46: menuItem := menuCopy
1022
        |47: menuItem := menuPaste
1023
        |24: menuItem := menuOpen
1024
        |31: menuItem := menuSave
1025
        |49: menuItem := menuNew
1026
        |67: menuItem := menuBuild
1027
        ELSE
1028
        END
1029
    ELSE
1030
        IF key DIV 65536 = 83 THEN
1031
            menuItem := menuDelete
1032
        ELSIF key DIV 65536 = 67 THEN
1033
            menuItem := menuRun
1034
        END
1035
    END;
1036
    IF menuItem # -1 THEN
1037
        IF Menu.isEnabled(menu, menuItem) THEN
1038
            MenuItemClick(menu, menuItem)
1039
        ELSE
1040
            menuItem := -1
1041
        END
1042
    END
1043
    RETURN menuItem # -1
1044
END MenuKeyDown;
1045
 
1046
 
1047
PROCEDURE CreateContextMenu (): Menu.tMenu;
1048
VAR
1049
    menu: List.tList;
1050
BEGIN
1051
    menu := List.create(NIL);
1052
    Menu.AddMenuItem(menu, menuUndo,      "undo         ctrl-Z");
1053
    Menu.AddMenuItem(menu, menuRedo,      "redo         ctrl-Y");
1054
    Menu.delimiter(menu);
1055
    Menu.AddMenuItem(menu, menuCut,       "cut          ctrl-X");
1056
    Menu.AddMenuItem(menu, menuCopy,      "copy         ctrl-C");
1057
    Menu.AddMenuItem(menu, menuPaste,     "paste        ctrl-V");
1058
    Menu.AddMenuItem(menu, menuDelete,    "delete");
1059
    Menu.delimiter(menu);
1060
    Menu.AddMenuItem(menu, menuSelectAll, "select all   ctrl-A");
1061
    RETURN Menu.create(menu, MenuItemClick, MenuKeyDown)
1062
END CreateContextMenu;
1063
 
1064
 
1065
PROCEDURE CreateMenuFile (): Menu.tMenu;
1066
VAR
1067
    menu: List.tList;
1068
BEGIN
1069
    menu := List.create(NIL);
1070
    Menu.AddMenuItem(menu, menuNew,    "new       ctrl-N");
1071
    Menu.AddMenuItem(menu, menuOpen,   "open      ctrl-O");
1072
    Menu.AddMenuItem(menu, menuSave,   "save      ctrl-S");
1073
    Menu.AddMenuItem(menu, menuSaveAs, "save as");
1074
    Menu.AddMenuItem(menu, menuFolder, "folder");
1075
    Menu.delimiter(menu);
1076
    Menu.AddMenuItem(menu, menuExit,   "exit");
1077
    RETURN Menu.create(menu, MenuItemClick, MenuKeyDown)
1078
END CreateMenuFile;
1079
 
1080
 
1081
PROCEDURE CreateMenuEdit (): Menu.tMenu;
1082
VAR
1083
    menu: List.tList;
1084
BEGIN
1085
    menu := List.create(NIL);
1086
    Menu.AddMenuItem(menu, menuUndo,      "undo          ctrl-Z");
1087
    Menu.AddMenuItem(menu, menuRedo,      "redo          ctrl-Y");
1088
    Menu.delimiter(menu);
1089
    Menu.AddMenuItem(menu, menuSearch,    "search        ctrl-F");
1090
    Menu.AddMenuItem(menu, menuGoto,      "go to line    ctrl-G");
1091
    Menu.delimiter(menu);
1092
    Menu.AddMenuItem(menu, menuCut,       "cut           ctrl-X");
1093
    Menu.AddMenuItem(menu, menuCopy,      "copy          ctrl-C");
1094
    Menu.AddMenuItem(menu, menuPaste,     "paste         ctrl-V");
1095
    Menu.AddMenuItem(menu, menuDelete,    "delete");
1096
    Menu.delimiter(menu);
1097
    Menu.AddMenuItem(menu, menuSelectAll, "select all    ctrl-A");
1098
    RETURN Menu.create(menu, MenuItemClick, MenuKeyDown)
1099
END CreateMenuEdit;
1100
 
1101
 
1102
PROCEDURE CreateMenuEncoding (): Menu.tMenu;
1103
VAR
1104
    menu: List.tList;
1105
BEGIN
1106
    menu := List.create(NIL);
1107
    Menu.AddMenuItem(menu, menuUTF8BOM, "UTF-8-BOM");
1108
    Menu.AddMenuItem(menu, menuUTF8,    "UTF-8");
1109
    Menu.AddMenuItem(menu, menuCP866,   "CP866");
1110
    Menu.AddMenuItem(menu, menuWin1251, "Windows-1251");
1111
    RETURN Menu.create(menu, MenuItemClick, MenuKeyDown)
1112
END CreateMenuEncoding;
1113
 
1114
 
1115
PROCEDURE CreateMenuView (): Menu.tMenu;
1116
VAR
1117
    menu: List.tList;
1118
    colors: Ini.tSection;
1119
    idx: INTEGER;
1120
BEGIN
1121
    menu := List.create(NIL);
1122
    Menu.AddMenuItem(menu, menuNumbers,  "line numbers");
1123
    Menu.delimiter(menu);
1124
    (*Menu.AddMenuItem(menu, menuSettings, "settings");*)
1125
 
1126
    colors := Ini.sections.first(Ini.tSection);
1127
    idx := menuColors;
1128
    WHILE colors # NIL DO
1129
        Menu.AddMenuItem(menu, idx, colors.name);
1130
        INC(idx);
1131
        colors := colors.next(Ini.tSection)
1132
    END;
1133
 
1134
    RETURN Menu.create(menu, MenuItemClick, MenuKeyDown)
1135
END CreateMenuView;
1136
 
1137
 
1138
PROCEDURE CreateMenuSyntax (): Menu.tMenu;
1139
VAR
1140
    menu: List.tList;
1141
BEGIN
1142
    menu := List.create(NIL);
1143
    Menu.AddMenuItem(menu, menuC,      "C");
1144
    Menu.AddMenuItem(menu, menuFasm,   "Fasm");
1145
    Menu.AddMenuItem(menu, menuIni,    "Ini");
1146
    Menu.AddMenuItem(menu, menuLua,    "Lua");
1147
    Menu.AddMenuItem(menu, menuOberon, "Oberon");
1148
    Menu.AddMenuItem(menu, menuPascal, "Pascal");
1149
    Menu.delimiter(menu);
1150
    Menu.AddMenuItem(menu, menuNone,   "none");
1151
    RETURN Menu.create(menu, MenuItemClick, MenuKeyDown)
1152
END CreateMenuSyntax;
1153
 
1154
 
1155
PROCEDURE CreateMenuProgram (): Menu.tMenu;
1156
VAR
1157
    menu: List.tList;
1158
BEGIN
1159
    menu := List.create(NIL);
1160
    Menu.AddMenuItem(menu, menuBuild,       "build    ctrl+F9");
1161
    Menu.AddMenuItem(menu, menuBuildScript, "script");
1162
    Menu.delimiter(menu);
1163
    Menu.AddMenuItem(menu, menuRun,         "run           F9");
1164
    Menu.AddMenuItem(menu, menuRunScript,   "script");
1165
    Menu.delimiter(menu);
1166
    Menu.AddMenuItem(menu, menuDebug,       "debug");
1167
    Menu.AddMenuItem(menu, menuDebugScript, "script");
1168
    RETURN Menu.create(menu, MenuItemClick, MenuKeyDown)
1169
END CreateMenuProgram;
1170
 
1171
 
1172
PROCEDURE CreateMenuTools (): Menu.tMenu;
1173
VAR
1174
    menu: List.tList;
1175
BEGIN
1176
    menu := List.create(NIL);
1177
    Menu.AddMenuItem(menu, menuPipet,   "pipet");
1178
    Menu.AddMenuItem(menu, menuSysFunc, "system functions");
1179
    RETURN Menu.create(menu, MenuItemClick, MenuKeyDown)
1180
END CreateMenuTools;
1181
 
1182
 
1183
PROCEDURE CanvasToScreen (VAR x, y: INTEGER);
1184
VAR
1185
    cliX, cliY,
1186
    winX, winY: INTEGER;
1187
BEGIN
1188
    K.WinPos(winX, winY);
1189
    K.ClientPos(cliX, cliY);
1190
    x := x + winX + cliX + LEFT;
1191
    y := y + winY + cliY + TOP;
1192
END CanvasToScreen;
1193
 
1194
 
1195
PROCEDURE ShowMenu (menu: Menu.tMenu);
1196
VAR
1197
    winX, winY, cliX, cliY, x, y, i: INTEGER;
1198
    selected: BOOLEAN;
1199
BEGIN
1200
    IF menu # context THEN
1201
        K.WinPos(winX, winY);
1202
        K.ClientPos(cliX, cliY);
1203
        x := winX + cliX;
1204
        y := MainMenuHeight + winY + cliY
1205
    ELSE
1206
        mouse(x, y);
1207
        IF ~((0 <= x) & (x < canvas.width) & (0 <= y) & (y < canvas.height)) THEN
1208
            menu := NIL
1209
        END
1210
    END;
1211
 
1212
    IF menu = menuFile THEN
1213
        Menu.setEnabled(menu, menuSave, text.modified);
1214
        Menu.setEnabled(menu, menuFolder, text.fileName # "");
1215
        INC(x, menuFileX)
1216
    ELSIF (menu = menuEdit) OR (menu = context) THEN
1217
        Menu.setEnabled(menu, menuUndo, ~ChangeLog.isFirstGuard(text.edition));
1218
        Menu.setEnabled(menu, menuRedo, ~ChangeLog.isLastGuard(text.edition));
1219
        selected := T.selected(text);
1220
        Menu.setEnabled(menu, menuCut, selected);
1221
        Menu.setEnabled(menu, menuCopy, selected);
1222
        Menu.setEnabled(menu, menuDelete, selected);
1223
        Menu.setEnabled(menu, menuPaste, CB.available());
1224
        IF menu = menuEdit THEN
1225
            INC(x, menuEditX)
1226
        ELSE
1227
            IF y + menu.height >= canvas.height THEN
1228
                DEC(y, menu.height)
1229
            END;
1230
            IF x + menu.width >= canvas.width THEN
1231
                DEC(x, menu.width)
1232
            END;
1233
            CanvasToScreen(x, y)
1234
        END
1235
    ELSIF menu = menuEncoding THEN
1236
        Menu.setCheck(menu, menuUTF8BOM, ORD(text.enc = E.UTF8BOM)*2);
1237
        Menu.setCheck(menu, menuUTF8,    ORD(text.enc = E.UTF8)*2);
1238
        Menu.setCheck(menu, menuCP866,   ORD(text.enc = E.CP866)*2);
1239
        Menu.setCheck(menu, menuWin1251, ORD(text.enc = E.W1251)*2);
1240
        INC(x, menuEncodingX)
1241
    ELSIF menu = menuView THEN
1242
        (*Menu.setEnabled(menu, menuSettings, FALSE);*)
1243
        Menu.setCheck(menu, menuNumbers, ORD(text.numbers));
1244
        FOR i := 0 TO Ini.sections.count - 1 DO
1245
            Menu.setCheck(menu, menuColors + i, ORD(Ini.curSectionNum = i)*2)
1246
        END;
1247
        INC(x, menuViewX)
1248
    ELSIF menu = menuSyntax THEN
1249
        Menu.setCheck(menu, menuNone,   ORD(text.lang = Languages.langNone)*2);
1250
        Menu.setCheck(menu, menuC,      ORD(text.lang = Languages.langC)*2);
1251
        Menu.setCheck(menu, menuFasm,   ORD(text.lang = Languages.langFasm)*2);
1252
        Menu.setCheck(menu, menuIni,    ORD(text.lang = Languages.langIni)*2);
1253
        Menu.setCheck(menu, menuLua,    ORD(text.lang = Languages.langLua)*2);
1254
        Menu.setCheck(menu, menuOberon, ORD(text.lang = Languages.langOberon)*2);
1255
        Menu.setCheck(menu, menuPascal, ORD(text.lang = Languages.langPascal)*2);
1256
        INC(x, menuSyntaxX)
1257
    ELSIF menu = menuProgram THEN
1258
        Menu.setEnabled(menu, menuBuild, buildScript # "");
1259
        Menu.setEnabled(menu, menuDebug, debugScript # "");
1260
        Menu.setEnabled(menu, menuRun, runScript # "");
1261
        INC(x, menuProgramX)
1262
    ELSIF menu = menuTools THEN
1263
        INC(x, menuToolsX)
1264
    END;
1265
 
1266
    IF menu # NIL THEN
1267
        IF Menu.opened(menu) THEN
1268
            Menu.close(menu)
1269
        END;
1270
        Menu.open(menu, x, y)
1271
    END
1272
END ShowMenu;
1273
 
1274
 
1275
PROCEDURE main;
1276
VAR
1277
    width, height, x, y, scrollX, scrollY: INTEGER;
1278
    key: INTEGER;
1279
    msState: SET;
1280
    scroll: INTEGER;
1281
    err: INTEGER;
1282
    fileName, filePath: RW.tFileName;
1283
    resized: BOOLEAN;
1284
    firstClickX, firstClickY, time: INTEGER;
1285
BEGIN
1286
    modified := FALSE;
1287
    mainTID := K.ThreadID();
1288
    K.SetIPC(IPC);
1289
    U.ptr2str(K.GetName(), AppPath);
1290
    U.getPath(AppPath, fileName);
1291
    U.append8(fileName, "/Icons16.png");
1292
    icons := LibImg.LoadFromFile(fileName, 16, y);
1293
    grayIcons := LibImg.LoadFromFile(fileName, 16, y);
1294
    gray(grayIcons);
1295
    iconsBackColor(icons);
1296
    iconsBackColor(grayIcons);
1297
    Ini.load(AppPath);
1298
    K.SetEventsMask({0, 1, 2, 5, 6, 31});
1299
    LeftButtonUp;
1300
    resized := FALSE;
1301
    shift := {};
1302
    winWidth := minWinWidth;
1303
    winHeight := minWinHeight;
1304
    LEFT := 10;
1305
    canvas := G.CreateCanvas(winWidth - (LEFT + RIGHT + 10), winHeight - (TOP + BOTTOM + 4) - K.SkinHeight());
1306
    font := G.CreateFont(1, "", {});
1307
    G.SetFont(canvas, font);
1308
    T.init(NIL);
1309
    T.setCanvas(canvas);
1310
    U.ptr2str(K.GetCommandLine(), fileName);
1311
    context := CreateContextMenu();
1312
    menuFile := CreateMenuFile();
1313
    menuEdit := CreateMenuEdit();
1314
    menuEncoding := CreateMenuEncoding();
1315
    menuView := CreateMenuView();
1316
    menuSyntax := CreateMenuSyntax();
1317
    menuProgram := CreateMenuProgram();
1318
    menuTools := CreateMenuTools();
1319
    IF fileName = "" THEN
1320
        text := T.New();
1321
        filePath := "/rd/1"
1322
    ELSE
1323
        text := T.open(fileName, err);
1324
        IF text = NIL THEN
1325
            error("'cedit: error opening file' -E");
1326
            K.Exit
1327
        ELSE
1328
            U.getPath(fileName, filePath)
1329
        END
1330
    END;
1331
    OD := OpenDlg.Create(draw_window, OpenDlg.topen, filePath, "");
1332
 
1333
    vScroll := Scroll.create(scrollWidth, canvas.height - scrollWidth*2 + 1, 0A0A0A0H, winColor);
1334
    hScroll := Scroll.create(canvas.width - scrollWidth*2, scrollWidth, 0A0A0A0H, winColor);
1335
    T.resize(canvas.width, canvas.height);
1336
    T.SetPos(text, 0, 0);
1337
    confirm := FALSE;
1338
    notFound := FALSE;
1339
    search := FALSE;
1340
    createSearchForm;
1341
    new_searchText := "";
1342
    searchText := "";
1343
    cs := FALSE;
1344
    whole := FALSE;
1345
    replaced := 0;
1346
    draw_window;
1347
    repaint;
1348
    buildScript := "";
1349
    runScript := "";
1350
    debugScript := "";
1351
    WHILE TRUE DO
1352
        CASE K.WaitForEvent() OF
1353
        |1:
1354
            IF ~K.RolledUp() THEN
1355
                K.WinSize(width, height);
1356
                IF (width # winWidth) OR (height # winHeight) THEN
1357
                    resize;
1358
                    resized := TRUE
1359
                END;
1360
                K.SetEventsMask({0, 1, 2, 5, 6, 31})
1361
            ELSE
1362
                K.SetEventsMask({0, 30, 31})
1363
            END;
1364
            draw_window
1365
        |2:
1366
            key := K.GetKey();
1367
            getKBState;
1368
            IF key DIV 65536 = 61 THEN (* F3 *)
1369
                key := -1;
1370
                IF search & (searchText # "") THEN
1371
                    notFound := ~T.findNext(text, box_lib.check_box_get_value(BKW))
1372
                END
1373
            ELSIF key DIV 65536 = 67 THEN (* F9 *)
1374
                key := -1;
1375
                IF T.CTRL IN shift THEN
1376
                    Script(buildScript)
1377
                ELSE
1378
                    Script(runScript)
1379
                END
1380
            ELSIF (key DIV 65536 = 55) & (key DIV 256 MOD 256 = 52) THEN
1381
                key := -1 (* PrtScn *)
1382
            ELSIF (T.CTRL IN shift) & (key DIV 65536 = 33) THEN
1383
                key := -1;
1384
                IF ~search THEN
1385
                    Search
1386
                END;
1387
                EditBox_SetFocus(FindEdit, TRUE);
1388
                EditBox_SetFocus(ReplaceEdit, FALSE);
1389
                EditBox_SetFocus(GotoEdit, FALSE);
1390
            ELSIF (T.CTRL IN shift) & (key DIV 65536 = 34) THEN
1391
                key := -1;
1392
                IF ~search THEN
1393
                    Search
1394
                END;
1395
                EditBox_SetFocus(GotoEdit, TRUE);
1396
                EditBox_SetFocus(FindEdit, FALSE);
1397
                EditBox_SetFocus(ReplaceEdit, FALSE)
1398
            END;
1399
            IF (key # -1) & EditBox_Focus(FindEdit) THEN
1400
                box_lib.edit_box_key(FindEdit, key);
1401
                EditBox_GetValue(FindEdit, new_searchText);
1402
                IF new_searchText # searchText THEN
1403
                    searchText := new_searchText;
1404
                    notFound := ~T.search(text, searchText, cs, whole)
1405
                END
1406
            ELSIF (key # -1) & EditBox_Focus(ReplaceEdit) THEN
1407
                box_lib.edit_box_key(ReplaceEdit, key);
1408
                EditBox_GetValue(ReplaceEdit, replaceText)
1409
            ELSIF (key # -1) & EditBox_Focus(GotoEdit) THEN
1410
                IF (key DIV 256) MOD 256 = 13 THEN
1411
                    goto
1412
                ELSE
1413
                    box_lib.edit_box_key(GotoEdit, key)
1414
                END
1415
            ELSIF key # -1 THEN
1416
                CASE key DIV 65536 OF
1417
                |73: key := 33
1418
                |81: key := 34
1419
                |71: key := 36
1420
                |79: key := 35
1421
                |72: key := 38
1422
                |80: key := 40
1423
                |75: key := 37
1424
                |77: key := 39
1425
                |82: key := -1 (* insert *)
1426
                |83: key := 46
1427
                |59, 60, 62..66, 68, 87, 88: key := -1 (* F1, F2, F4..F8, F10, F11, F12 *)
1428
                ELSE
1429
                    IF (T.CTRL IN shift) THEN
1430
                        CASE key DIV 65536 OF
1431
                        |21: T.redo(text);
1432
                             key := -1
1433
                        |22: key := ORD("U")
1434
                        |24: key := -1;
1435
                             open
1436
                        |30: key := ORD("A")
1437
                        |31: key := -1;
1438
                             save
1439
                        |38: key := ORD("L")
1440
                        |44: T.undo(text);
1441
                             key := -1
1442
                        |45: key := ORD("X")
1443
                        |46: key := ORD("C")
1444
                        |47: key := ORD("V")
1445
                        |49: key := -1;
1446
                             SelfRun("")
1447
                        ELSE
1448
                            key := -1
1449
                        END
1450
                    ELSE
1451
                        T.input(text, E.cp866[key DIV 256 MOD 256]);
1452
                        key := -1
1453
                    END
1454
                END;
1455
                IF key # -1 THEN
1456
                    T.key(text, key, shift)
1457
                END
1458
            END;
1459
            repaint
1460
        |3:
1461
            CASE K.ButtonCode() OF
1462
            |0:
1463
 
1464
            |btnFile:
1465
                ShowMenu(menuFile)
1466
            |btnEdit:
1467
                ShowMenu(menuEdit)
1468
            |btnEncoding:
1469
                ShowMenu(menuEncoding)
1470
            |btnView:
1471
                ShowMenu(menuView)
1472
            |btnSyntax:
1473
                ShowMenu(menuSyntax)
1474
            |btnProgram:
1475
                ShowMenu(menuProgram)
1476
            |btnTools:
1477
                ShowMenu(menuTools)
1478
            |btnNo:
1479
                K.Exit
1480
            |btnYes:
1481
                save;
1482
                IF ~text.modified THEN
1483
                    K.Exit
1484
                END;
1485
                repaint
1486
            |btnClose:
1487
                close
1488
            |btnNew:
1489
                SelfRun("")
1490
            |btnOpen:
1491
                open
1492
            |btnSave:
1493
                save;
1494
                repaint
1495
            |btnSearch:
1496
                IF ~search THEN
1497
                    Search
1498
                END
1499
            |btnCloseFind:
1500
                Search
1501
            |btnUndo:
1502
                T.undo(text);
1503
                repaint
1504
            |btnRedo:
1505
                T.redo(text);
1506
                repaint
1507
            |btnUpper:
1508
                T.chCase(text, TRUE);
1509
                repaint
1510
            |btnLower:
1511
                T.chCase(text, FALSE);
1512
                repaint
1513
            |btnBuild:
1514
                Script(buildScript)
1515
            |btnRun:
1516
                Script(runScript)
1517
            |btnUp:
1518
                T.scroll(text, 0, -1);
1519
                repaint
1520
            |btnDown:
1521
                T.scroll(text, 0, 1);
1522
                repaint
1523
            |btnLeft:
1524
                T.scroll(text, -1, 0);
1525
                repaint
1526
            |btnRight:
1527
                T.scroll(text, 1, 0);
1528
                repaint
1529
            |btnFindEdit:
1530
                EditBox_SetFocus(FindEdit, TRUE);
1531
                EditBox_SetFocus(ReplaceEdit, FALSE);
1532
                EditBox_SetFocus(GotoEdit, FALSE)
1533
            |btnReplaceEdit:
1534
                EditBox_SetFocus(ReplaceEdit, TRUE);
1535
                EditBox_SetFocus(FindEdit, FALSE);
1536
                EditBox_SetFocus(GotoEdit, FALSE)
1537
            |btnGotoEdit:
1538
                EditBox_SetFocus(GotoEdit, TRUE);
1539
                EditBox_SetFocus(FindEdit, FALSE);
1540
                EditBox_SetFocus(ReplaceEdit, FALSE)
1541
            |btnFindNext:
1542
                IF searchText # "" THEN
1543
                    notFound := ~T.findNext(text, box_lib.check_box_get_value(BKW));
1544
                    repaint
1545
                END
1546
            |btnReplace:
1547
                T.replace(text, replaceText, LENGTH(searchText));
1548
                repaint
1549
            |btnReplaceAll:
1550
                notFound := ~T.search(text, searchText, cs, whole);
1551
                IF ~notFound THEN
1552
                    replaced := T.replaceAll(text, replaceText, LENGTH(searchText));
1553
                END;
1554
                repaint
1555
            |btnGoto:
1556
                goto;
1557
                repaint
1558
            END
1559
        |6:
1560
            Menu.close(menuFile);
1561
            Menu.close(menuEdit);
1562
            Menu.close(menuEncoding);
1563
            Menu.close(menuView);
1564
            Menu.close(menuSyntax);
1565
            Menu.close(menuProgram);
1566
            Menu.close(menuTools);
1567
            Menu.close(context);
1568
            IF ~resized THEN
1569
                getKBState;
1570
                msState := K.MouseState();
1571
                IF ~(0 IN msState) OR (16 IN msState) THEN
1572
                    LeftButtonUp
1573
                END;
1574
                scroll := K.Scroll();
1575
                IF scroll # 0 THEN
1576
                    T.scroll(text, 0, scroll*3);
1577
                    repaint
1578
                END;
1579
                IF leftButton THEN
1580
                    IF K.GetTickCount() - time > 9 THEN
1581
                        mouse(x, y);
1582
                        T.mouse(text, x, y);
1583
                        repaint
1584
                    END
1585
                END;
1586
                IF VScroll THEN
1587
                    mouse(x, y);
1588
                    Scroll.mouse(vScroll, x, y - scrollWidth);
1589
                    T.getScroll(text, scrollX, scrollY);
1590
                    T.scroll(text, 0, vScroll.value - scrollY);
1591
                    repaint
1592
                END;
1593
                IF HScroll THEN
1594
                    mouse(x, y);
1595
                    Scroll.mouse(hScroll, x - scrollWidth, y);
1596
                    T.getScroll(text, scrollX, scrollY);
1597
                    T.scroll(text, hScroll.value - scrollX, 0);
1598
                    repaint
1599
                END;
1600
                IF (8 IN msState) & ~(24 IN msState) THEN
1601
                    mouse(firstClickX, firstClickY);
1602
                    time := click(firstClickX, firstClickY)
1603
                END;
1604
                IF 9 IN msState THEN
1605
                    ShowMenu(context)
1606
                END;
1607
                IF 24 IN msState THEN
1608
                    mouse(x, y);
1609
                    IF (ABS(x - firstClickX) < 5) & (ABS(y - firstClickY) < 5) THEN
1610
                        VScroll := FALSE;
1611
                        HScroll := FALSE;
1612
                        IF (0 <= x) & (x < canvas.width) & (0 <= y) & (y < canvas.height) THEN
1613
                            leftButton := FALSE;
1614
                            T.selectWord(text);
1615
                            repaint
1616
                        END
1617
                    ELSE
1618
                        firstClickX := x;
1619
                        firstClickY := y;
1620
                        time := click(firstClickX, firstClickY)
1621
                    END
1622
                END
1623
            END;
1624
            IF search THEN
1625
                IF EditBox_Focus(FindEdit) THEN
1626
                    box_lib.edit_box_mouse(FindEdit)
1627
                END;
1628
                IF EditBox_Focus(ReplaceEdit) THEN
1629
                    box_lib.edit_box_mouse(ReplaceEdit)
1630
                END;
1631
                IF EditBox_Focus(GotoEdit) THEN
1632
                    box_lib.edit_box_mouse(GotoEdit)
1633
                END;
1634
                box_lib.check_box_mouse2(CS);
1635
                box_lib.check_box_mouse2(WH);
1636
                box_lib.check_box_mouse2(BKW);
1637
                IF box_lib.check_box_get_value(CS) # cs THEN
1638
                    cs := ~cs;
1639
                    notFound := ~T.search(text, searchText, cs, whole);
1640
                    repaint
1641
                END;
1642
                IF box_lib.check_box_get_value(WH) # whole THEN
1643
                    whole := ~whole;
1644
                    notFound := ~T.search(text, searchText, cs, whole);
1645
                    repaint
1646
                END
1647
            END;
1648
            resized := FALSE
1649
        |7: receiveIPC
1650
        ELSE
1651
        END
1652
    END
1653
END main;
1654
 
1655
 
1656
BEGIN
1657
    main
1658
END CEdit.