Subversion Repositories Kolibri OS

Rev

Rev 9896 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
9896 akron1 1
(*
9898 akron1 2
    Copyright 2016, 2018, 2020-2023 Anton Krotov
9896 akron1 3
 
4
    This file is part of fb2read.
5
 
6
    fb2read 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
    fb2read 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 fb2read. If not, see .
18
*)
19
 
20
MODULE SelEnc;
21
 
22
IMPORT
9898 akron1 23
    SU := SysUtils, W := Window, S := Strings, SYSTEM, K := KOSAPI, File;
9896 akron1 24
 
25
 
26
CONST
9898 akron1 27
	AUTO     =  15;
28
	CP866    =  16;
29
	CP1251   =  17;
30
	CP1252   =  18;
31
	CP1250   =  19;
32
	UTF8     =  20;
9896 akron1 33
 
9898 akron1 34
    BtnH     =  30;
35
    BtnW     = 150;
36
    BtnX     =   5;
37
    BtnY     =  10;
38
    BtnInter =  10;
9896 akron1 39
 
40
    tempfile* = "/tmp0/1/~temp.fb2";
41
 
42
 
43
VAR
9898 akron1 44
    Window: W.tWindow;
45
    pos, mem, mem2, pos2: INTEGER;
9896 akron1 46
 
47
 
48
PROCEDURE Buttons;
49
VAR
50
    Y : INTEGER;
51
BEGIN
52
    Y := BtnY;
9898 akron1 53
    SU.CreateButton(AUTO,   BtnX, Y, BtnW, BtnH, SU.btnColor, "AUTO"   ); INC(Y, BtnH + BtnInter);
54
    SU.CreateButton(CP866,  BtnX, Y, BtnW, BtnH, SU.btnColor, "CP-866" ); INC(Y, BtnH + BtnInter);
55
    SU.CreateButton(CP1251, BtnX, Y, BtnW, BtnH, SU.btnColor, "CP-1251"); INC(Y, BtnH + BtnInter);
56
    SU.CreateButton(CP1252, BtnX, Y, BtnW, BtnH, SU.btnColor, "CP-1252"); INC(Y, BtnH + BtnInter);
57
    SU.CreateButton(CP1250, BtnX, Y, BtnW, BtnH, SU.btnColor, "CP-1250"); INC(Y, BtnH + BtnInter);
58
    SU.CreateButton(UTF8,   BtnX, Y, BtnW, BtnH, SU.btnColor, "UTF-8"  )
9896 akron1 59
END Buttons;
60
 
61
 
62
PROCEDURE DrawWindow;
63
BEGIN
64
	SU.GetSystemColors;
65
    SU.WindowRedrawStatus(1);
9898 akron1 66
    SU.DefineAndDrawWindow(Window.left, Window.top, Window.width, Window.height,
67
          SU.winColor, LSL(ORD({0, 1}), 4) + 4, Window.caption);
9896 akron1 68
    Buttons;
69
    SU.WindowRedrawStatus(2)
70
END DrawWindow;
71
 
72
 
9898 akron1 73
PROCEDURE getch (): CHAR;
9896 akron1 74
VAR
9898 akron1 75
	ch: CHAR;
76
BEGIN
77
	SYSTEM.GET(mem + pos, ch);
78
	INC(pos)
79
	RETURN ch
80
END getch;
9896 akron1 81
 
82
 
9898 akron1 83
PROCEDURE WriteStr (s: ARRAY OF CHAR);
84
BEGIN
85
	SYSTEM.MOVE(SYSTEM.ADR(s[0]), mem2 + pos2, LENGTH(s));
86
	pos2 := pos2 + LENGTH(s)
87
END WriteStr;
88
 
89
 
90
PROCEDURE WriteChar (ch: CHAR);
91
BEGIN
92
	SYSTEM.PUT(mem2 + pos2, ch);
93
	INC(pos2)
94
END WriteChar;
95
 
96
 
97
PROCEDURE convert (ibuf, size: INTEGER; out: S.STRING; encoding: INTEGER);
98
CONST
99
	buf_size = 1024*16;
100
VAR
101
	F: File.FS;
102
	n: INTEGER;
103
	CR: BOOLEAN;
104
	ch: CHAR;
105
	buffer: ARRAY buf_size OF BYTE;
106
BEGIN
107
	mem := ibuf;
108
	pos := 0;
109
	F := File.Create(out);
110
	mem2 := SYSTEM.ADR(buffer[0]);
111
	pos2 := 0;
112
	WriteStr('
113
	CASE encoding OF
114
	|CP866  : WriteStr("cp866")
115
	|CP1251 : WriteStr("windows-1251")
116
	|CP1252 : WriteStr("windows-1252")
117
	|CP1250 : WriteStr("windows-1250")
118
	|UTF8   : WriteStr("utf-8")
119
	ELSE
120
		SU.Halt
121
	END;
122
	WriteStr('"?>' + 0DX + 0AX + "");
123
 
124
	WHILE pos < size DO
125
		IF pos2 > buf_size - 32 THEN
126
			n := File.Write(F, mem2, pos2);
127
			pos2 := 0
128
		END;
129
		ch := getch();
130
		CASE ch OF
131
		|"<": WriteStr("<")
132
		|">": WriteStr(">")
133
		|"&": WriteStr("&")
134
		|"'": WriteStr("'")
135
		|'"': WriteStr(""")
136
		|0DX: WriteStr("")
137
		|0AX: IF ~CR THEN WriteStr("") END
138
		| 0X: WriteChar(20X)
139
		ELSE
140
			WriteChar(ch)
141
		END;
142
		CR := ch = 0DX
143
	END;
144
 
145
	WriteStr("");
146
	n := File.Write(F, mem2, pos2);
147
	File.Close(F)
148
END convert;
149
 
150
 
151
PROCEDURE auto (ptr, size: INTEGER): INTEGER;
152
VAR
153
    enc: INTEGER;
154
 
155
 
9896 akron1 156
    PROCEDURE SearchPair (ptr, size: INTEGER; chr1, chr2: BYTE): BOOLEAN;
157
    VAR
158
        c, c0: BYTE;
159
        res: BOOLEAN;
160
 
161
    BEGIN
162
        c := 0;
163
        res := FALSE;
164
        WHILE (size > 0) & ~res DO
165
            c0 := c;
166
            SYSTEM.GET(ptr, c);
167
            IF (c = chr2) & (c0 = chr1) THEN
168
                res := TRUE
169
            END;
170
            INC(ptr);
171
            DEC(size)
172
        END
173
 
174
        RETURN res
175
    END SearchPair;
176
 
177
 
178
BEGIN
179
    IF SearchPair(ptr, size, 208, 190) THEN
9898 akron1 180
        enc := UTF8
9896 akron1 181
    ELSE
182
        IF SearchPair(ptr, size, 239, 240) OR SearchPair(ptr, size, 241, 242) THEN
9898 akron1 183
            enc := CP1251
9896 akron1 184
        ELSE
9898 akron1 185
            enc := CP866
9896 akron1 186
        END
9898 akron1 187
    END
9896 akron1 188
    RETURN enc
189
END auto;
190
 
191
 
9898 akron1 192
PROCEDURE ButtonClick (fname: S.STRING);
9896 akron1 193
VAR
9898 akron1 194
    encoding: INTEGER;
9896 akron1 195
    program, file: S.STRING;
9898 akron1 196
    data, size: INTEGER;
9896 akron1 197
BEGIN
9898 akron1 198
    data := File.Load(fname, size);
199
    SU.ErrorIf(data = 0, 1);
200
    encoding := SU.GetButtonCode();
201
    IF encoding = AUTO THEN
202
        encoding := auto(data, size)
9896 akron1 203
    END;
9898 akron1 204
    convert(data, size, tempfile, encoding);
9896 akron1 205
    S.PtrToString(K.GetName(), program);
206
    file := tempfile;
207
    file[0] := "!";
208
    SU.Run(program, SYSTEM.ADR(file));
209
    SU.Halt
210
END ButtonClick;
211
 
212
 
9898 akron1 213
PROCEDURE Show* (fname: S.STRING);
9896 akron1 214
VAR
215
    X1, Y1, X2, Y2: INTEGER;
216
BEGIN
217
    SU.SetEventsMask({0, 2, 31});
218
    SU.GetScreenArea(X1, Y1, X2, Y2);
9898 akron1 219
    W.init(Window, 0, 0, BtnX * 2 + BtnW + 10, (BtnH + BtnInter) * 6 + BtnY * 2 + SU.SkinHeight() - 5, "Encoding");
220
    Window.left := (X2 - X1 - Window.width) DIV 2;
221
    Window.top  := (Y2 - Y1 - Window.height) DIV 2;
9896 akron1 222
    DrawWindow;
223
    WHILE TRUE DO
224
        CASE SU.WaitForEvent() OF
9898 akron1 225
        |1: DrawWindow
226
        |3: ButtonClick(fname)
9896 akron1 227
        END
228
    END
229
END Show;
230
 
231
 
232
END SelEnc.