Subversion Repositories Kolibri OS

Rev

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

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