Rev 965 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 965 | Rev 992 | ||
---|---|---|---|
1 | program OIDPLUS; |
1 | program OIDPLUS; |
2 | 2 | ||
3 | (************************************************) |
3 | (************************************************) |
4 | (* OIDPLUS.PAS *) |
4 | (* OIDPLUS.PAS *) |
5 | (* Author: Daniel Marschall *) |
5 | (* Author: Daniel Marschall *) |
6 | (* Revision: 2022-09-26 *) |
6 | (* Revision: 2022-10-10 *) |
7 | (* License: Apache 2.0 *) |
7 | (* License: Apache 2.0 *) |
8 | (* This file contains: *) |
8 | (* This file contains: *) |
9 | (* - "OIDplus for DOS" program *) |
9 | (* - "OIDplus for DOS" program *) |
10 | (************************************************) |
10 | (************************************************) |
11 | 11 | ||
12 | (* IMPORTANT: *) |
12 | (* IMPORTANT: *) |
13 | (* When you compile this code with Turbo Pascal 7.01, *) |
13 | (* When you compile this code with Turbo Pascal 7.01, *) |
14 | (* it won't run on fast PCs (Runtime Error 200). *) |
14 | (* it won't run on fast PCs (Runtime Error 200). *) |
15 | (* The built EXE file needs to be patched. *) |
15 | (* The built EXE file needs to be patched. *) |
16 | (* The program "PatchCRT" by Kennedy Software *) |
16 | (* The program "PatchCRT" by Kennedy Software *) |
17 | (* WON'T work because it somehow breaks our "_Pause" function. *) |
17 | (* WON'T work because it somehow breaks our "_Pause" function. *) |
18 | (* Instead, use the tool "TPPATCH" by Andreas Bauer. *) |
18 | (* Instead, use the tool "TPPATCH" by Andreas Bauer. *) |
19 | 19 | ||
20 | uses |
20 | uses |
21 | Dos, Crt, Drivers, StrList, VtsFuncs, VtsCui, OidFile, OidUtils, |
21 | Dos, Crt, Drivers, StrList, VtsFuncs, VtsCui, OidFile, OidUtils, |
22 | Weid; |
22 | Weid; |
23 | 23 | ||
24 | const |
24 | const |
25 | VERSIONINFO = 'Revision: 2022-09-26'; |
25 | VERSIONINFO = 'Revision: 2022-10-10'; |
26 | TITLEBAR_LEFT_TEXT = 'OIDplus'; |
26 | TITLEBAR_LEFT_TEXT = 'OIDplus'; |
27 | DISKIO_SOUND_DEBUGGING = false; |
27 | DISKIO_SOUND_DEBUGGING = false; |
28 | DISKIO_SOUND_DELAY = 500; |
28 | DISKIO_SOUND_DELAY = 500; |
29 | ASNEDIT_LINES = 10; |
29 | ASNEDIT_LINES = 10; |
30 | DESCEDIT_LINES = 10; |
30 | DESCEDIT_LINES = 10; |
31 | DESCEDIT_PADDING = 3; |
31 | DESCEDIT_PADDING = 3; |
32 | ACTIONMENU_SIZE = 5; |
32 | ACTIONMENU_SIZE = 5; |
33 | MAINMENU_WIDTH = 15; |
33 | MAINMENU_WIDTH = 15; |
34 | MAINMENU_HEIGHT = 3; |
34 | MAINMENU_HEIGHT = 3; |
35 | MAINMENU_ALLOW_ESC = false; |
35 | MAINMENU_ALLOW_ESC = false; |
36 | TREEVIEW_INDENT = 0; |
36 | TREEVIEW_INDENT = 0; |
37 | TREEVIEW_INCLUDE_DESC = true; |
37 | TREEVIEW_INCLUDE_DESC = true; |
38 | TREEVIEW_WIDTH = 80; |
38 | TREEVIEW_WIDTH = 80; |
39 | OID_EXTENSION = '.OID'; |
39 | OID_EXTENSION = '.OID'; |
40 | TREEVIEW_FILENAME = 'OIDTREE.TXT'; |
40 | TREEVIEW_FILENAME = 'OIDTREE.TXT'; |
41 | 41 | ||
42 | procedure _Pause; |
42 | procedure _Pause; |
43 | begin |
43 | begin |
44 | DrawStatusBar('Press any key to continue'); |
44 | DrawStatusBar('Press any key to continue'); |
45 | CursorOn; |
45 | CursorOn; |
46 | ReadKey; |
46 | ReadKey; |
47 | CursorOff; |
47 | CursorOff; |
48 | DrawStatusBar(''); |
48 | DrawStatusBar(''); |
49 | end; |
49 | end; |
50 | 50 | ||
51 | function _WriteOidFile(filename: string; oid: POid; ShowErrorMessage: boolean): boolean; |
51 | function _WriteOidFile(filename: string; oid: POid; ShowErrorMessage: boolean): boolean; |
52 | var |
52 | var |
53 | res: boolean; |
53 | res: boolean; |
54 | begin |
54 | begin |
55 | DrawStatusBar('Write file ' + filename + '...'); |
55 | DrawStatusBar('Write file ' + filename + '...'); |
56 | res := WriteOidFile(filename, oid); |
56 | res := WriteOidFile(filename, oid); |
57 | if DISKIO_SOUND_DEBUGGING then |
57 | if DISKIO_SOUND_DEBUGGING then |
58 | begin |
58 | begin |
59 | Sound(70); |
59 | Sound(70); |
60 | Delay(DISKIO_SOUND_DELAY - 10); |
60 | Delay(DISKIO_SOUND_DELAY - 10); |
61 | NoSound; |
61 | NoSound; |
62 | Delay(10); |
62 | Delay(10); |
63 | end; |
63 | end; |
64 | DrawStatusBar(''); |
64 | DrawStatusBar(''); |
65 | 65 | ||
66 | _WriteOidFile := res; |
66 | _WriteOidFile := res; |
67 | 67 | ||
68 | if ShowErrorMessage and not res then |
68 | if ShowErrorMessage and not res then |
69 | begin |
69 | begin |
70 | ShowMessage('Cannot write to file ' + filename, 'ERROR', true); |
70 | ShowMessage('Cannot write to file ' + filename, 'ERROR', true); |
71 | _Pause; |
71 | _Pause; |
72 | end; |
72 | end; |
73 | end; |
73 | end; |
74 | 74 | ||
75 | function _ReadOidFile(filename: string; oid: POid; ShowErrorMessage: boolean): boolean; |
75 | function _ReadOidFile(filename: string; oid: POid; ShowErrorMessage: boolean): boolean; |
76 | var |
76 | var |
77 | res: boolean; |
77 | res: boolean; |
78 | begin |
78 | begin |
79 | DrawStatusBar('Read file ' + filename + '...'); |
79 | DrawStatusBar('Read file ' + filename + '...'); |
80 | res := ReadOidFile(filename, oid); |
80 | res := ReadOidFile(filename, oid); |
81 | if DISKIO_SOUND_DEBUGGING then |
81 | if DISKIO_SOUND_DEBUGGING then |
82 | begin |
82 | begin |
83 | Sound(50); |
83 | Sound(50); |
84 | Delay(DISKIO_SOUND_DELAY - 10); |
84 | Delay(DISKIO_SOUND_DELAY - 10); |
85 | NoSound; |
85 | NoSound; |
86 | Delay(10); |
86 | Delay(10); |
87 | end; |
87 | end; |
88 | DrawStatusBar(''); |
88 | DrawStatusBar(''); |
89 | 89 | ||
90 | _ReadOidFile := res; |
90 | _ReadOidFile := res; |
91 | 91 | ||
92 | if ShowErrorMessage and not res then |
92 | if ShowErrorMessage and not res then |
93 | begin |
93 | begin |
94 | ShowMessage('Cannot read file ' + filename, 'ERROR', true); |
94 | ShowMessage('Cannot read file ' + filename, 'ERROR', true); |
95 | _Pause; |
95 | _Pause; |
96 | end; |
96 | end; |
97 | end; |
97 | end; |
98 | 98 | ||
99 | function _ShowASNIds(childOID: POID): string; |
99 | function _ShowASNIds(childOID: POID): string; |
100 | var |
100 | var |
101 | j, jmax: integer; |
101 | j, jmax: integer; |
102 | sTmp: string; |
102 | sTmp: string; |
103 | begin |
103 | begin |
104 | sTmp := ''; |
104 | sTmp := ''; |
105 | jmax := ListCount(childOID^.ASNIds)-1; |
105 | jmax := ListCount(childOID^.ASNIds)-1; |
106 | for j := 0 to jmax do |
106 | for j := 0 to jmax do |
107 | begin |
107 | begin |
108 | if j = 0 then sTmp := sTmp + ' ('; |
108 | if j = 0 then sTmp := sTmp + ' ('; |
109 | sTmp := sTmp + ListGetElement(childOID^.ASNIds, j); |
109 | sTmp := sTmp + ListGetElement(childOID^.ASNIds, j); |
110 | if j = jmax then |
110 | if j = jmax then |
111 | sTmp := sTmp + ')' |
111 | sTmp := sTmp + ')' |
112 | else |
112 | else |
113 | sTmp := sTmp + ', '; |
113 | sTmp := sTmp + ', '; |
114 | end; |
114 | end; |
115 | _ShowASNIds := sTmp; |
115 | _ShowASNIds := sTmp; |
116 | end; |
116 | end; |
117 | 117 | ||
118 | function AsnAlreadyExisting(oid: POID; asnid: string): boolean; |
118 | function AsnAlreadyExisting(oid: POID; asnid: string): boolean; |
119 | begin |
119 | begin |
120 | AsnAlreadyExisting := ListContains(oid^.AsnIds, asnid); |
120 | AsnAlreadyExisting := ListContains(oid^.AsnIds, asnid); |
121 | end; |
121 | end; |
122 | 122 | ||
123 | function AsnEditor(oid: POID): boolean; |
123 | function AsnEditor(oid: POID): boolean; |
124 | var |
124 | var |
125 | asnList: PStringList; |
125 | asnList: PStringList; |
126 | i: integer; |
126 | i: integer; |
127 | x, y, w, h: integer; |
127 | x, y, w, h: integer; |
128 | res: integer; |
128 | res: integer; |
129 | sInput: string; |
129 | sInput: string; |
130 | menuIdNew, menuIdSave, menuIdExit: integer; |
130 | menuIdNew, menuIdSave, menuIdExit: integer; |
131 | begin |
131 | begin |
132 | AsnEditor := false; |
132 | AsnEditor := false; |
133 | 133 | ||
134 | repeat |
134 | repeat |
135 | CreateList(asnList); |
135 | CreateList(asnList); |
136 | 136 | ||
137 | for i := 0 to ListCount(oid^.ASNIds)-1 do |
137 | for i := 0 to ListCount(oid^.ASNIds)-1 do |
138 | begin |
138 | begin |
139 | ListAppend(asnList, ListGetElement(oid^.ASNIDs, i)); |
139 | ListAppend(asnList, ListGetElement(oid^.ASNIDs, i)); |
140 | end; |
140 | end; |
141 | menuIdNew := ListAppend(asnList, '<NEW>'); |
141 | menuIdNew := ListAppend(asnList, '<NEW>'); |
142 | menuIdSave := ListAppend(asnList, '<SAVE>'); |
142 | menuIdSave := ListAppend(asnList, '<SAVE>'); |
143 | menuIdExit := ListAppend(asnList, '<CANCEL>'); |
143 | menuIdExit := ListAppend(asnList, '<CANCEL>'); |
144 | 144 | ||
145 | DrawStatusBar(''); |
145 | DrawStatusBar(''); |
146 | x := SINGLE_LINE_BOX_PADDING; |
146 | x := SINGLE_LINE_BOX_PADDING; |
147 | y := ScreenHeight div 2 - ASNEDIT_LINES div 2; |
147 | y := ScreenHeight div 2 - ASNEDIT_LINES div 2; |
148 | w := ScreenWidth - (SINGLE_LINE_BOX_PADDING-1)*2; |
148 | w := ScreenWidth - (SINGLE_LINE_BOX_PADDING-1)*2; |
149 | h := ASNEDIT_LINES; |
149 | h := ASNEDIT_LINES; |
150 | res := DrawSelectionList(x, y, w, h, |
150 | res := DrawSelectionList(x, y, w, h, |
151 | asnList, true, |
151 | asnList, true, |
152 | 'EDIT ASN.1 IDENTIFIERS', |
152 | 'EDIT ASN.1 IDENTIFIERS', |
153 | 2); |
153 | 2); |
154 | FreeList(asnList); |
154 | FreeList(asnList); |
155 | 155 | ||
156 | (* Change double-border to thin-border *) |
156 | (* Change double-border to thin-border *) |
157 | DrawThinBorder(x-1, y-1, w+2, h+2); |
157 | DrawThinBorder(x-1, y-1, w+2, h+2); |
158 | GoToXY(x+1, y-1); |
158 | GoToXY(x+1, y-1); |
159 | Write('EDIT ASN.1 IDENTIFIERS'); |
159 | Write('EDIT ASN.1 IDENTIFIERS'); |
160 | 160 | ||
161 | if res = -1 then |
161 | if res = -1 then |
162 | begin |
162 | begin |
163 | exit; |
163 | exit; |
164 | end |
164 | end |
165 | else if res = menuIdNew then |
165 | else if res = menuIdNew then |
166 | begin |
166 | begin |
167 | (* "NEW" item was selected *) |
167 | (* "NEW" item was selected *) |
168 | sInput := ''; |
168 | sInput := ''; |
169 | CursorOn; |
169 | CursorOn; |
170 | repeat |
170 | repeat |
171 | if QueryVal(sInput, |
171 | if QueryVal(sInput, |
172 | SINGLE_LINE_BOX_PADDING_INNER, |
172 | SINGLE_LINE_BOX_PADDING_INNER, |
173 | ScreenHeight div 2, |
173 | ScreenHeight div 2, |
174 | ScreenWidth - (SINGLE_LINE_BOX_PADDING_INNER-1)*2, |
174 | ScreenWidth - (SINGLE_LINE_BOX_PADDING_INNER-1)*2, |
175 | 1, |
175 | 1, |
176 | 'ADD SINGLE ASN.1 ID', |
176 | 'ADD SINGLE ASN.1 ID', |
177 | 2) then |
177 | 2) then |
178 | begin |
178 | begin |
179 | if sInput = '' then continue; |
179 | if sInput = '' then continue; |
180 | if not ASN1IDValid(sInput) then |
180 | if not ASN1IDValid(sInput) then |
181 | begin |
181 | begin |
182 | ShowMessage('Invalid ASN1.ID! (Require -, a..z, A..Z, 0..9, begin with a-z)', 'ERROR', true); |
182 | ShowMessage('Invalid ASN1.ID! (Require -, a..z, A..Z, 0..9, begin with a-z)', 'ERROR', true); |
183 | _Pause; |
183 | _Pause; |
184 | end |
184 | end |
185 | else if AsnAlreadyExisting(oid, sInput) then |
185 | else if AsnAlreadyExisting(oid, sInput) then |
186 | begin |
186 | begin |
187 | ShowMessage('ASN.1 identifier is already existing on this arc', 'ERROR', true); |
187 | ShowMessage('ASN.1 identifier is already existing on this arc', 'ERROR', true); |
188 | _Pause; |
188 | _Pause; |
189 | end |
189 | end |
190 | else |
190 | else |
191 | begin |
191 | begin |
192 | ListAppend(oid^.ASNIDs, sInput); |
192 | ListAppend(oid^.ASNIDs, sInput); |
193 | break; |
193 | break; |
194 | end; |
194 | end; |
195 | end |
195 | end |
196 | else break; |
196 | else break; |
197 | until false; |
197 | until false; |
198 | CursorOff; |
198 | CursorOff; |
199 | end |
199 | end |
200 | else if res = menuIdSave then |
200 | else if res = menuIdSave then |
201 | begin |
201 | begin |
202 | (* "SAVE" item was selected *) |
202 | (* "SAVE" item was selected *) |
203 | AsnEditor := true; |
203 | AsnEditor := true; |
204 | Exit; |
204 | Exit; |
205 | end |
205 | end |
206 | else if res = menuIdExit then |
206 | else if res = menuIdExit then |
207 | begin |
207 | begin |
208 | (* "CANCEL" item was selected *) |
208 | (* "CANCEL" item was selected *) |
209 | AsnEditor := false; |
209 | AsnEditor := false; |
210 | Exit; |
210 | Exit; |
211 | end |
211 | end |
212 | else |
212 | else |
213 | begin |
213 | begin |
214 | DrawStatusBar('Note: Remove the text to delete the ASN.1 identifier'); |
214 | DrawStatusBar('Note: Remove the text to delete the ASN.1 identifier'); |
215 | sInput := ListGetElement(oid^.ASNIDs, res); |
215 | sInput := ListGetElement(oid^.ASNIDs, res); |
216 | CursorOn; |
216 | CursorOn; |
217 | repeat |
217 | repeat |
218 | if QueryVal(sInput, |
218 | if QueryVal(sInput, |
219 | SINGLE_LINE_BOX_PADDING_INNER, |
219 | SINGLE_LINE_BOX_PADDING_INNER, |
220 | ScreenHeight div 2, |
220 | ScreenHeight div 2, |
221 | ScreenWidth - (SINGLE_LINE_BOX_PADDING_INNER-1)*2, |
221 | ScreenWidth - (SINGLE_LINE_BOX_PADDING_INNER-1)*2, |
222 | 1, |
222 | 1, |
223 | 'EDIT SINGLE ASN.1 ID', |
223 | 'EDIT SINGLE ASN.1 ID', |
224 | 2) then |
224 | 2) then |
225 | begin |
225 | begin |
226 | if sInput = '' then |
226 | if sInput = '' then |
227 | begin |
227 | begin |
228 | (* Empty input = Delete ASN.1 ID *) |
228 | (* Empty input = Delete ASN.1 ID *) |
229 | ListDeleteElementByIndex(oid^.ASNIDs, res); |
229 | ListDeleteElementByIndex(oid^.ASNIDs, res); |
230 | break; |
230 | break; |
231 | end |
231 | end |
232 | else if not ASN1IDValid(sInput) then |
232 | else if not ASN1IDValid(sInput) then |
233 | begin |
233 | begin |
234 | ShowMessage('Invalid ASN1.ID! (Require -, a..z, A..Z, 0..9, begin with a-z)', 'ERROR', true); |
234 | ShowMessage('Invalid ASN1.ID! (Require -, a..z, A..Z, 0..9, begin with a-z)', 'ERROR', true); |
235 | _Pause; |
235 | _Pause; |
236 | end |
236 | end |
237 | else if AsnAlreadyExisting(oid, sInput) and |
237 | else if AsnAlreadyExisting(oid, sInput) and |
238 | not (ListGetElement(oid^.ASNIDs, res) = sInput) then |
238 | not (ListGetElement(oid^.ASNIDs, res) = sInput) then |
239 | begin |
239 | begin |
240 | ShowMessage('ASN.1 identifier is already existing on this arc', 'ERROR', true); |
240 | ShowMessage('ASN.1 identifier is already existing on this arc', 'ERROR', true); |
241 | _Pause; |
241 | _Pause; |
242 | end |
242 | end |
243 | else |
243 | else |
244 | begin |
244 | begin |
245 | ListSetElement(oid^.ASNIDs, res, sInput); |
245 | ListSetElement(oid^.ASNIDs, res, sInput); |
246 | break; |
246 | break; |
247 | end; |
247 | end; |
248 | end |
248 | end |
249 | else break; |
249 | else break; |
250 | until false; |
250 | until false; |
251 | CursorOff; |
251 | CursorOff; |
252 | end; |
252 | end; |
253 | until false; |
253 | until false; |
254 | end; |
254 | end; |
255 | 255 | ||
256 | function UnicodeLabelAlreadyExisting(oid: POID; unicodeLabel: string): boolean; |
256 | function UnicodeLabelAlreadyExisting(oid: POID; unicodeLabel: string): boolean; |
257 | begin |
257 | begin |
258 | UnicodeLabelAlreadyExisting := ListContains(oid^.UnicodeLabels, unicodeLabel); |
258 | UnicodeLabelAlreadyExisting := ListContains(oid^.UnicodeLabels, unicodeLabel); |
259 | end; |
259 | end; |
260 | 260 | ||
261 | function IriEditor(oid: POID): boolean; |
261 | function IriEditor(oid: POID): boolean; |
262 | var |
262 | var |
263 | iriList: PStringList; |
263 | iriList: PStringList; |
264 | i: integer; |
264 | i: integer; |
265 | x, y, w, h: integer; |
265 | x, y, w, h: integer; |
266 | res: integer; |
266 | res: integer; |
267 | sInput: string; |
267 | sInput: string; |
268 | menuIdNew, menuIdSave, menuIdExit: integer; |
268 | menuIdNew, menuIdSave, menuIdExit: integer; |
269 | begin |
269 | begin |
270 | IriEditor := false; |
270 | IriEditor := false; |
271 | 271 | ||
272 | repeat |
272 | repeat |
273 | CreateList(iriList); |
273 | CreateList(iriList); |
274 | 274 | ||
275 | for i := 0 to ListCount(oid^.UnicodeLabels)-1 do |
275 | for i := 0 to ListCount(oid^.UnicodeLabels)-1 do |
276 | begin |
276 | begin |
277 | ListAppend(iriList, ListGetElement(oid^.UnicodeLabels, i)); |
277 | ListAppend(iriList, ListGetElement(oid^.UnicodeLabels, i)); |
278 | end; |
278 | end; |
279 | menuIdNew := ListAppend(iriList, '<NEW>'); |
279 | menuIdNew := ListAppend(iriList, '<NEW>'); |
280 | menuIdSave := ListAppend(iriList, '<SAVE>'); |
280 | menuIdSave := ListAppend(iriList, '<SAVE>'); |
281 | menuIdExit := ListAppend(iriList, '<CANCEL>'); |
281 | menuIdExit := ListAppend(iriList, '<CANCEL>'); |
282 | 282 | ||
283 | DrawStatusBar(''); |
283 | DrawStatusBar(''); |
284 | x := SINGLE_LINE_BOX_PADDING; |
284 | x := SINGLE_LINE_BOX_PADDING; |
285 | y := ScreenHeight div 2 - ASNEDIT_LINES div 2; |
285 | y := ScreenHeight div 2 - ASNEDIT_LINES div 2; |
286 | w := ScreenWidth - (SINGLE_LINE_BOX_PADDING-1)*2; |
286 | w := ScreenWidth - (SINGLE_LINE_BOX_PADDING-1)*2; |
287 | h := ASNEDIT_LINES; |
287 | h := ASNEDIT_LINES; |
288 | res := DrawSelectionList(x, y, w, h, |
288 | res := DrawSelectionList(x, y, w, h, |
289 | iriList, true, |
289 | iriList, true, |
290 | 'EDIT UNICODE LABELS', |
290 | 'EDIT UNICODE LABELS', |
291 | 2); |
291 | 2); |
292 | FreeList(iriList); |
292 | FreeList(iriList); |
293 | 293 | ||
294 | (* Change double-border to thin-border *) |
294 | (* Change double-border to thin-border *) |
295 | DrawThinBorder(x-1, y-1, w+2, h+2); |
295 | DrawThinBorder(x-1, y-1, w+2, h+2); |
296 | GoToXY(x+1, y-1); |
296 | GoToXY(x+1, y-1); |
297 | Write('EDIT UNICODE LABELS'); |
297 | Write('EDIT UNICODE LABELS'); |
298 | 298 | ||
299 | if res = -1 then |
299 | if res = -1 then |
300 | begin |
300 | begin |
301 | exit; |
301 | exit; |
302 | end |
302 | end |
303 | else if res = menuIdNew then |
303 | else if res = menuIdNew then |
304 | begin |
304 | begin |
305 | (* "NEW" item was selected *) |
305 | (* "NEW" item was selected *) |
306 | sInput := ''; |
306 | sInput := ''; |
307 | CursorOn; |
307 | CursorOn; |
308 | repeat |
308 | repeat |
309 | if QueryVal(sInput, |
309 | if QueryVal(sInput, |
310 | SINGLE_LINE_BOX_PADDING_INNER, |
310 | SINGLE_LINE_BOX_PADDING_INNER, |
311 | ScreenHeight div 2, |
311 | ScreenHeight div 2, |
312 | ScreenWidth - (SINGLE_LINE_BOX_PADDING_INNER-1)*2, |
312 | ScreenWidth - (SINGLE_LINE_BOX_PADDING_INNER-1)*2, |
313 | 1, |
313 | 1, |
314 | 'ADD SINGLE UNICODE LABEL', |
314 | 'ADD SINGLE UNICODE LABEL', |
315 | 2) then |
315 | 2) then |
316 | begin |
316 | begin |
317 | if sInput = '' then continue; |
317 | if sInput = '' then continue; |
318 | if not UnicodeLabelValid(sInput) then |
318 | if not UnicodeLabelValid(sInput) then |
319 | begin |
319 | begin |
320 | ShowMessage('Invalid Unicode Label!', 'ERROR', true); |
320 | ShowMessage('Invalid Unicode Label!', 'ERROR', true); |
321 | _Pause; |
321 | _Pause; |
322 | end |
322 | end |
323 | else if UnicodeLabelAlreadyExisting(oid, sInput) then |
323 | else if UnicodeLabelAlreadyExisting(oid, sInput) then |
324 | begin |
324 | begin |
325 | ShowMessage('Unicode Label is already existing on this arc', 'ERROR', true); |
325 | ShowMessage('Unicode Label is already existing on this arc', 'ERROR', true); |
326 | _Pause; |
326 | _Pause; |
327 | end |
327 | end |
328 | else |
328 | else |
329 | begin |
329 | begin |
330 | ListAppend(oid^.UnicodeLabels, sInput); |
330 | ListAppend(oid^.UnicodeLabels, sInput); |
331 | break; |
331 | break; |
332 | end; |
332 | end; |
333 | end |
333 | end |
334 | else break; |
334 | else break; |
335 | until false; |
335 | until false; |
336 | CursorOff; |
336 | CursorOff; |
337 | end |
337 | end |
338 | else if res = menuIdSave then |
338 | else if res = menuIdSave then |
339 | begin |
339 | begin |
340 | (* "SAVE" item was selected *) |
340 | (* "SAVE" item was selected *) |
341 | IriEditor := true; |
341 | IriEditor := true; |
342 | Exit; |
342 | Exit; |
343 | end |
343 | end |
344 | else if res = menuIdExit then |
344 | else if res = menuIdExit then |
345 | begin |
345 | begin |
346 | (* "CANCEL" item was selected *) |
346 | (* "CANCEL" item was selected *) |
347 | IriEditor := false; |
347 | IriEditor := false; |
348 | Exit; |
348 | Exit; |
349 | end |
349 | end |
350 | else |
350 | else |
351 | begin |
351 | begin |
352 | DrawStatusBar('Note: Remove the text to delete the Unicode Label'); |
352 | DrawStatusBar('Note: Remove the text to delete the Unicode Label'); |
353 | sInput := ListGetElement(oid^.UnicodeLabels, res); |
353 | sInput := ListGetElement(oid^.UnicodeLabels, res); |
354 | CursorOn; |
354 | CursorOn; |
355 | repeat |
355 | repeat |
356 | if QueryVal(sInput, |
356 | if QueryVal(sInput, |
357 | SINGLE_LINE_BOX_PADDING_INNER, |
357 | SINGLE_LINE_BOX_PADDING_INNER, |
358 | ScreenHeight div 2, |
358 | ScreenHeight div 2, |
359 | ScreenWidth - (SINGLE_LINE_BOX_PADDING_INNER-1)*2, |
359 | ScreenWidth - (SINGLE_LINE_BOX_PADDING_INNER-1)*2, |
360 | 1, |
360 | 1, |
361 | 'EDIT SINGLE UNICODE LABEL', |
361 | 'EDIT SINGLE UNICODE LABEL', |
362 | 2) then |
362 | 2) then |
363 | begin |
363 | begin |
364 | if sInput = '' then |
364 | if sInput = '' then |
365 | begin |
365 | begin |
366 | (* Empty input = Delete Unicode label *) |
366 | (* Empty input = Delete Unicode label *) |
367 | ListDeleteElementByIndex(oid^.UnicodeLabels, res); |
367 | ListDeleteElementByIndex(oid^.UnicodeLabels, res); |
368 | break; |
368 | break; |
369 | end |
369 | end |
370 | else if not UnicodeLabelValid(sInput) then |
370 | else if not UnicodeLabelValid(sInput) then |
371 | begin |
371 | begin |
372 | ShowMessage('Invalid Unicode Label!', 'ERROR', true); |
372 | ShowMessage('Invalid Unicode Label!', 'ERROR', true); |
373 | _Pause; |
373 | _Pause; |
374 | end |
374 | end |
375 | else if UnicodeLabelAlreadyExisting(oid, sInput) and |
375 | else if UnicodeLabelAlreadyExisting(oid, sInput) and |
376 | not (ListGetElement(oid^.UnicodeLabels, res) = sInput) then |
376 | not (ListGetElement(oid^.UnicodeLabels, res) = sInput) then |
377 | begin |
377 | begin |
378 | ShowMessage('Unicode Label is already existing on this arc', 'ERROR', true); |
378 | ShowMessage('Unicode Label is already existing on this arc', 'ERROR', true); |
379 | _Pause; |
379 | _Pause; |
380 | end |
380 | end |
381 | else |
381 | else |
382 | begin |
382 | begin |
383 | ListSetElement(oid^.UnicodeLabels, res, sInput); |
383 | ListSetElement(oid^.UnicodeLabels, res, sInput); |
384 | break; |
384 | break; |
385 | end; |
385 | end; |
386 | end |
386 | end |
387 | else break; |
387 | else break; |
388 | until false; |
388 | until false; |
389 | CursorOff; |
389 | CursorOff; |
390 | end; |
390 | end; |
391 | until false; |
391 | until false; |
392 | end; |
392 | end; |
393 | 393 | ||
394 | function DescEditor(oid: POID): boolean; |
394 | function DescEditor(oid: POID): boolean; |
395 | var |
395 | var |
396 | sInput: string; |
396 | sInput: string; |
397 | begin |
397 | begin |
398 | DescEditor := false; |
398 | DescEditor := false; |
399 | 399 | ||
400 | DrawStatusBar('Note: Press Ctrl+Return for a line-break.'); |
400 | DrawStatusBar('Note: Press Ctrl+Return for a line-break.'); |
401 | sInput := oid^.description; |
401 | sInput := oid^.description; |
402 | CursorOn; |
402 | CursorOn; |
403 | if QueryVal(sInput, |
403 | if QueryVal(sInput, |
404 | DESCEDIT_PADDING, |
404 | DESCEDIT_PADDING, |
405 | ScreenHeight div 2 - DESCEDIT_LINES div 2, |
405 | ScreenHeight div 2 - DESCEDIT_LINES div 2, |
406 | ScreenWidth - (DESCEDIT_PADDING-1)*2, |
406 | ScreenWidth - (DESCEDIT_PADDING-1)*2, |
407 | DESCEDIT_LINES, |
407 | DESCEDIT_LINES, |
408 | 'EDIT DESCRIPTION', |
408 | 'EDIT DESCRIPTION', |
409 | 2) then |
409 | 2) then |
410 | begin |
410 | begin |
411 | oid^.description := sInput; |
411 | oid^.description := sInput; |
412 | DescEditor := true; (* request caller to save <oid> *) |
412 | DescEditor := true; (* request caller to save <oid> *) |
413 | end; |
413 | end; |
414 | CursorOff; |
414 | CursorOff; |
415 | end; |
415 | end; |
416 | 416 | ||
417 | function NextPossibleFileID: string; |
417 | function NextPossibleFileID: string; |
418 | var |
418 | var |
419 | DirInfo: SearchRec; |
419 | DirInfo: SearchRec; |
420 | list: PStringList; |
420 | list: PStringList; |
421 | iId: LongInt; |
421 | iId: LongInt; |
422 | sId: string; |
422 | sId: string; |
423 | begin |
423 | begin |
424 | (* Put all found files into a list *) |
424 | (* Put all found files into a list *) |
425 | CreateList(list); |
425 | CreateList(list); |
426 | FindFirst(RepeatStr('?',8)+OID_EXTENSION, Archive, DirInfo); |
426 | FindFirst(RepeatStr('?',8)+OID_EXTENSION, Archive, DirInfo); |
427 | while DosError = 0 do |
427 | while DosError = 0 do |
428 | begin |
428 | begin |
429 | sId := Copy(DirInfo.Name, 1, 8); |
429 | sId := Copy(DirInfo.Name, 1, 8); |
430 | ListAppend(list, sId); |
430 | ListAppend(list, sId); |
431 | FindNext(DirInfo); |
431 | FindNext(DirInfo); |
432 | end; |
432 | end; |
433 | 433 | ||
434 | (* Search for the first non existing item in the list *) |
434 | (* Search for the first non existing item in the list *) |
435 | sId := ''; |
435 | sId := ''; |
436 | for iId := 0 to 99999999 do |
436 | for iId := 0 to 99999999 do |
437 | begin |
437 | begin |
438 | sId := ZeroPad(iId, 8); |
438 | sId := ZeroPad(iId, 8); |
439 | if not ListContains(list, sId) then break; |
439 | if not ListContains(list, sId) then break; |
440 | end; |
440 | end; |
441 | NextPossibleFileId := sId; |
441 | NextPossibleFileId := sId; |
442 | FreeList(list); |
442 | FreeList(list); |
443 | end; |
443 | end; |
444 | 444 | ||
445 | function NumIdAlreadyExisting(parentOID: POID; arcval: string): boolean; |
445 | function NumIdAlreadyExisting(parentOID: POID; arcval: string): boolean; |
446 | var |
446 | var |
447 | searchDotNotation: string; |
447 | searchDotNotation: string; |
448 | sTmp: string; |
448 | sTmp: string; |
449 | i: integer; |
449 | i: integer; |
450 | begin |
450 | begin |
451 | if parentOID^.DotNotation = '' then |
451 | if parentOID^.DotNotation = '' then |
452 | searchDotNotation := arcval |
452 | searchDotNotation := arcval |
453 | else |
453 | else |
454 | searchDotNotation := parentOID^.DotNotation + '.' + arcval; |
454 | searchDotNotation := parentOID^.DotNotation + '.' + arcval; |
455 | for i := 0 to ListCount(parentOID^.SubIds)-1 do |
455 | for i := 0 to ListCount(parentOID^.SubIds)-1 do |
456 | begin |
456 | begin |
457 | sTmp := ListGetElement(parentOID^.SubIds, i); |
457 | sTmp := ListGetElement(parentOID^.SubIds, i); |
458 | if DotNotationPart(sTmp) = searchDotNotation then |
458 | if DotNotationPart(sTmp) = searchDotNotation then |
459 | begin |
459 | begin |
460 | NumIdAlreadyExisting := true; |
460 | NumIdAlreadyExisting := true; |
461 | exit; |
461 | exit; |
462 | end; |
462 | end; |
463 | end; |
463 | end; |
464 | NumIdAlreadyExisting := false; |
464 | NumIdAlreadyExisting := false; |
465 | end; |
465 | end; |
466 | 466 | ||
467 | function NumIdEditor(oid: POID; parentOID: POID): boolean; |
467 | function NumIdEditor(oid: POID; parentOID: POID): boolean; |
468 | var |
468 | var |
469 | sInput: string; |
469 | sInput: string; |
470 | title: string; |
470 | title: string; |
471 | base36mode: boolean; |
471 | base36mode: boolean; |
472 | arcval: string; |
472 | arcval: string; |
473 | begin |
473 | begin |
474 | NumIdEditor := false; |
474 | NumIdEditor := false; |
475 | sInput := ''; |
475 | sInput := ''; |
476 | 476 | ||
477 | base36mode := false; |
477 | base36mode := false; |
478 | CursorOn; |
478 | CursorOn; |
479 | repeat |
479 | repeat |
480 | if base36mode then |
480 | if base36mode then |
481 | begin |
481 | begin |
482 | DrawStatusBar('Press ESC to cancel'); |
482 | DrawStatusBar('Press ESC to cancel'); |
483 | title := 'ENTER BASE36 ID' |
483 | title := 'ENTER BASE36 ID' |
484 | end |
484 | end |
485 | else |
485 | else |
486 | begin |
486 | begin |
487 | DrawStatusBar('Enter "WEID" to enter a Base36 instead of Base10; press ESC to cancel'); |
487 | DrawStatusBar('Enter "WEID" to enter a Base36 instead of Base10; press ESC to cancel'); |
488 | title := 'ENTER NUMERIC ID'; |
488 | title := 'ENTER NUMERIC ID'; |
489 | end; |
489 | end; |
490 | if QueryVal(sInput, |
490 | if QueryVal(sInput, |
491 | SINGLE_LINE_BOX_PADDING_INNER, |
491 | SINGLE_LINE_BOX_PADDING_INNER, |
492 | ScreenHeight div 2, |
492 | ScreenHeight div 2, |
493 | ScreenWidth - (SINGLE_LINE_BOX_PADDING_INNER-1)*2, |
493 | ScreenWidth - (SINGLE_LINE_BOX_PADDING_INNER-1)*2, |
494 | 1, |
494 | 1, |
495 | title, |
495 | title, |
496 | 2) then |
496 | 2) then |
497 | begin |
497 | begin |
498 | if sInput = '' then continue; |
498 | if sInput = '' then continue; |
499 | if not base36mode and (sInput = 'WEID') then |
499 | if not base36mode and (sInput = 'WEID') then |
500 | begin |
500 | begin |
501 | sInput := ''; |
501 | sInput := ''; |
502 | base36mode := true; |
502 | base36mode := true; |
503 | end |
503 | end |
504 | else if not base36mode and not IsPositiveIntegerOrZero(sInput) then |
504 | else if not base36mode and not IsPositiveIntegerOrZero(sInput) then |
505 | begin |
505 | begin |
506 | ShowMessage('Invalid numeric ID (must be a positive integer)', 'ERROR', true); |
506 | ShowMessage('Invalid numeric ID (must be a positive integer)', 'ERROR', true); |
507 | _Pause; |
507 | _Pause; |
508 | end |
508 | end |
509 | else if base36mode and not IsBase36String(sInput) then |
509 | else if base36mode and not IsBase36String(sInput) then |
510 | begin |
510 | begin |
511 | ShowMessage('Invalid base36 ID (must be 0..9, A..Z)', 'ERROR', true); |
511 | ShowMessage('Invalid base36 ID (must be 0..9, A..Z)', 'ERROR', true); |
512 | _Pause; |
512 | _Pause; |
513 | end |
513 | end |
514 | else |
514 | else |
515 | begin |
515 | begin |
516 | if base36mode then |
516 | if base36mode then |
517 | arcval := base_convert_bigint(sInput, 36, 10) |
517 | arcval := base_convert_bigint(sInput, 36, 10) |
518 | else |
518 | else |
519 | arcval := sInput; |
519 | arcval := sInput; |
520 | arcval := StripLeadingZeros(arcval); |
520 | arcval := StripLeadingZeros(arcval); |
521 | 521 | ||
522 | if (parentOID^.DotNotation='') and (arcval <> '0') and (arcval <> '1') and (arcval <> '2') then |
522 | if (parentOID^.DotNotation='') and (arcval <> '0') and (arcval <> '1') and (arcval <> '2') then |
523 | begin |
523 | begin |
524 | ShowMessage('Invalid numeric ID (root arc can only be 0, 1, or 2)', 'ERROR', true); |
524 | ShowMessage('Invalid numeric ID (root arc can only be 0, 1, or 2)', 'ERROR', true); |
525 | _Pause; |
525 | _Pause; |
526 | end |
526 | end |
527 | else if ((parentOID^.DotNotation='0') or (parentOID^.DotNotation='1')) and |
527 | else if ((parentOID^.DotNotation='0') or (parentOID^.DotNotation='1')) and |
528 | ((Length(arcval)>2) or (StrToInt(arcval) > 39)) then |
528 | ((Length(arcval)>2) or (StrToInt(arcval) > 39)) then |
529 | begin |
529 | begin |
530 | ShowMessage('Invalid numeric ID (root 0 and 1 must have sub-arc of 0..39)', 'ERROR', true); |
530 | ShowMessage('Invalid numeric ID (root 0 and 1 must have sub-arc of 0..39)', 'ERROR', true); |
531 | _Pause; |
531 | _Pause; |
532 | end |
532 | end |
533 | else if NumIdAlreadyExisting(parentOID, arcval) then |
533 | else if NumIdAlreadyExisting(parentOID, arcval) then |
534 | begin |
534 | begin |
535 | ShowMessage('This numeric ID is already used in this arc', 'ERROR', true); |
535 | ShowMessage('This numeric ID is already used in this arc', 'ERROR', true); |
536 | _Pause; |
536 | _Pause; |
537 | end |
537 | end |
538 | else |
538 | else |
539 | begin |
539 | begin |
540 | if parentOID^.DotNotation = '' then |
540 | if parentOID^.DotNotation = '' then |
541 | oid^.DotNotation := arcval |
541 | oid^.DotNotation := arcval |
542 | else |
542 | else |
543 | oid^.DotNotation := parentOID^.DotNotation + '.' + arcval; |
543 | oid^.DotNotation := parentOID^.DotNotation + '.' + arcval; |
544 | NumIdEditor := true; (* request caller to save <oid> *) |
544 | NumIdEditor := true; (* request caller to save <oid> *) |
545 | Break; |
545 | Break; |
546 | end; |
546 | end; |
547 | end; |
547 | end; |
548 | end |
548 | end |
549 | else |
549 | else |
550 | begin |
550 | begin |
551 | (* User pressed ESC *) |
551 | (* User pressed ESC *) |
552 | Break; |
552 | Break; |
553 | end; |
553 | end; |
554 | until false; |
554 | until false; |
555 | CursorOff; |
555 | CursorOff; |
556 | end; |
556 | end; |
557 | 557 | ||
558 | function NewOidEditor(oid: POID): boolean; |
558 | function NewOidEditor(oid: POID): boolean; |
559 | var |
559 | var |
560 | newfilename: string; |
560 | newfilename: string; |
561 | newOID: POID; |
561 | newOID: POID; |
562 | begin |
562 | begin |
563 | NewOidEditor := false; |
563 | NewOidEditor := false; |
564 | 564 | ||
565 | CreateOidDef(newOID); |
565 | CreateOidDef(newOID); |
566 | newOID^.FileId := NextPossibleFileID; |
566 | newOID^.FileId := NextPossibleFileID; |
567 | newOID^.ParentFileId := oid^.FileId; |
567 | newOID^.ParentFileId := oid^.FileId; |
568 | newOID^.ParentDotNotation := oid^.DotNotation; |
568 | newOID^.ParentDotNotation := oid^.DotNotation; |
569 | if NumIdEditor(newOID, oid) and |
569 | if NumIdEditor(newOID, oid) and |
570 | AsnEditor(newOID) and |
570 | AsnEditor(newOID) and |
571 | IriEditor(newOID) and |
571 | IriEditor(newOID) and |
572 | DescEditor(newOID) then |
572 | DescEditor(newOID) then |
573 | begin |
573 | begin |
574 | newfilename := newOID^.FileId + OID_EXTENSION; |
574 | newfilename := newOID^.FileId + OID_EXTENSION; |
575 | if _WriteOidFile(newfilename, newOID, true) then |
575 | if _WriteOidFile(newfilename, newOID, true) then |
576 | begin |
576 | begin |
577 | (* Add link to original file and enable the saving of it *) |
577 | (* Add link to original file and enable the saving of it *) |
578 | ListAppend(oid^.SubIds, newOID^.FileId + newOID^.DotNotation); |
578 | ListAppend(oid^.SubIds, newOID^.FileId + newOID^.DotNotation); |
579 | NewOidEditor := true; (* request caller to save <oid> *) |
579 | NewOidEditor := true; (* request caller to save <oid> *) |
580 | end; |
580 | end; |
581 | end; |
581 | end; |
582 | FreeOidDef(newOID); |
582 | FreeOidDef(newOID); |
583 | end; |
583 | end; |
584 | 584 | ||
585 | procedure DeleteChildrenRecursive(oid: POID); |
585 | procedure DeleteChildrenRecursive(oid: POID); |
586 | var |
586 | var |
587 | i: integer; |
587 | i: integer; |
588 | childOID: POID; |
588 | childOID: POID; |
589 | filenameChild: string; |
589 | filenameChild: string; |
590 | begin |
590 | begin |
591 | for i := 0 to ListCount(oid^.SubIds)-1 do |
591 | for i := 0 to ListCount(oid^.SubIds)-1 do |
592 | begin |
592 | begin |
593 | filenameChild := FileIdPart(ListGetElement(oid^.SubIds, i)) + OID_EXTENSION; |
593 | filenameChild := FileIdPart(ListGetElement(oid^.SubIds, i)) + OID_EXTENSION; |
594 | if FileExists(filenameChild) then |
594 | if FileExists(filenameChild) then |
595 | begin |
595 | begin |
596 | CreateOidDef(childOID); |
596 | CreateOidDef(childOID); |
597 | if _ReadOidFile(filenameChild, childOID, false) and |
597 | if _ReadOidFile(filenameChild, childOID, false) and |
598 | (childOID^.ParentFileId = oid^.FileId) and |
598 | (childOID^.ParentFileId = oid^.FileId) and |
599 | (childOID^.ParentDotNotation = oid^.DotNotation) then |
599 | (childOID^.ParentDotNotation = oid^.DotNotation) then |
600 | begin |
600 | begin |
601 | DeleteChildrenRecursive(childOID); |
601 | DeleteChildrenRecursive(childOID); |
602 | end; |
602 | end; |
603 | FreeOidDef(childOID); |
603 | FreeOidDef(childOID); |
604 | DeleteFile(filenameChild); |
604 | DeleteFile(filenameChild); |
605 | end; |
605 | end; |
606 | end; |
606 | end; |
607 | ListClear(oid^.SubIds); |
607 | ListClear(oid^.SubIds); |
608 | end; |
608 | end; |
609 | 609 | ||
610 | procedure DeleteOidRecursive(selfOID: POID); |
610 | procedure DeleteOidRecursive(selfOID: POID); |
611 | var |
611 | var |
612 | i: integer; |
612 | i: integer; |
613 | parentOID: POID; |
613 | parentOID: POID; |
614 | filenameSelf, filenameParent: string; |
614 | filenameSelf, filenameParent: string; |
615 | begin |
615 | begin |
616 | (* Remove all children and their files recursively *) |
616 | (* Remove all children and their files recursively *) |
617 | DeleteChildrenRecursive(selfOID); |
617 | DeleteChildrenRecursive(selfOID); |
618 | 618 | ||
619 | (* Remove forward reference in parent OID *) |
619 | (* Remove forward reference in parent OID *) |
620 | (* (this is the most important part) *) |
620 | (* (this is the most important part) *) |
621 | filenameParent := selfOID^.ParentFileId + OID_EXTENSION; |
621 | filenameParent := selfOID^.ParentFileId + OID_EXTENSION; |
622 | if FileExists(filenameParent) then |
622 | if FileExists(filenameParent) then |
623 | begin |
623 | begin |
624 | CreateOidDef(parentOID); |
624 | CreateOidDef(parentOID); |
625 | if _ReadOidFile(filenameParent, parentOID, true) then |
625 | if _ReadOidFile(filenameParent, parentOID, true) then |
626 | begin |
626 | begin |
627 | if ListDeleteElementByValue(parentOID^.SubIds, selfOID^.FileId + selfOID^.DotNotation) then |
627 | if ListDeleteElementByValue(parentOID^.SubIds, selfOID^.FileId + selfOID^.DotNotation) then |
628 | begin |
628 | begin |
629 | _WriteOidFile(filenameParent, parentOID, true); |
629 | _WriteOidFile(filenameParent, parentOID, true); |
630 | end; |
630 | end; |
631 | end; |
631 | end; |
632 | FreeOidDef(parentOID); |
632 | FreeOidDef(parentOID); |
633 | end; |
633 | end; |
634 | 634 | ||
635 | (* Delete own file *) |
635 | (* Delete own file *) |
636 | filenameSelf := selfOID^.FileId + OID_EXTENSION; |
636 | filenameSelf := selfOID^.FileId + OID_EXTENSION; |
637 | if FileExists(filenameSelf) then |
637 | if FileExists(filenameSelf) then |
638 | begin |
638 | begin |
639 | DeleteFile(filenameSelf); |
639 | DeleteFile(filenameSelf); |
640 | end; |
640 | end; |
641 | end; |
641 | end; |
642 | 642 | ||
643 | function _DeleteConfirmation: boolean; |
643 | function _DeleteConfirmation: boolean; |
644 | var |
644 | var |
645 | sc: Char; |
645 | sc: Char; |
646 | begin |
646 | begin |
647 | repeat |
647 | repeat |
648 | ShowMessage('Are you sure you want to delete this OID? (Y/N)', 'DELETE OID', true); |
648 | ShowMessage('Are you sure you want to delete this OID? (Y/N)', 'DELETE OID', true); |
649 | DrawStatusBar('Y=Yes, N=No'); |
649 | DrawStatusBar('Y=Yes, N=No'); |
650 | 650 | ||
651 | CursorOn; |
651 | CursorOn; |
652 | sc := ReadKey; |
652 | sc := ReadKey; |
653 | CursorOff; |
653 | CursorOff; |
654 | if sc = #0 then |
654 | if sc = #0 then |
655 | begin |
655 | begin |
656 | (* Extended key. Nothing we care about. *) |
656 | (* Extended key. Nothing we care about. *) |
657 | ReadKey; |
657 | ReadKey; |
658 | continue; |
658 | continue; |
659 | end; |
659 | end; |
660 | 660 | ||
661 | if UpCase(sc) = 'Y' then |
661 | if UpCase(sc) = 'Y' then |
662 | begin |
662 | begin |
663 | _DeleteConfirmation := true; |
663 | _DeleteConfirmation := true; |
664 | break; |
664 | break; |
665 | end |
665 | end |
666 | else if UpCase(sc) = 'N' then |
666 | else if UpCase(sc) = 'N' then |
667 | begin |
667 | begin |
668 | _DeleteConfirmation := false; |
668 | _DeleteConfirmation := false; |
669 | break; |
669 | break; |
670 | end; |
670 | end; |
671 | until false; |
671 | until false; |
672 | end; |
672 | end; |
673 | 673 | ||
674 | procedure _DrawOidTitleBar(filename: string; oid: POID); |
674 | procedure _DrawOidTitleBar(filename: string; oid: POID); |
675 | begin |
675 | begin |
676 | if oid^.DotNotation = '' then |
676 | if oid^.DotNotation = '' then |
677 | DrawTitleBar('OID ROOT', TITLEBAR_LEFT_TEXT, filename) |
677 | DrawTitleBar('OID ROOT', TITLEBAR_LEFT_TEXT, filename) |
678 | else |
678 | else |
679 | DrawTitleBar('OID ' + oid^.DotNotation, TITLEBAR_LEFT_TEXT, filename); |
679 | DrawTitleBar('OID ' + oid^.DotNotation, TITLEBAR_LEFT_TEXT, filename); |
680 | end; |
680 | end; |
681 | 681 | ||
682 | function DotNotation(oid: POid): string; |
682 | function DotNotation(oid: POid): string; |
683 | var |
683 | var |
684 | res: string; |
684 | res: string; |
685 | begin |
685 | begin |
686 | res := oid^.DotNotation; |
686 | res := oid^.DotNotation; |
687 | if res = '' then res := '.'; (* root *) |
687 | if res = '' then res := '.'; (* root *) |
688 | DotNotation := res; |
688 | DotNotation := res; |
689 | end; |
689 | end; |
690 | 690 | ||
691 | function OidLastArc(oid: POid): string; |
691 | function OidLastArc(oid: POid): string; |
692 | var |
692 | var |
693 | s: string; |
693 | s: string; |
694 | p: integer; |
694 | p: integer; |
695 | begin |
695 | begin |
696 | s := oid^.DotNotation; |
696 | s := oid^.DotNotation; |
697 | 697 | ||
698 | while true do |
698 | while true do |
699 | begin |
699 | begin |
700 | p := Pos('.', s); |
700 | p := Pos('.', s); |
701 | if p = 0 then break; |
701 | if p = 0 then break; |
702 | Delete(s, 1, p); |
702 | Delete(s, 1, p); |
703 | end; |
703 | end; |
704 | 704 | ||
705 | OidLastArc := s; |
705 | OidLastArc := s; |
706 | end; |
706 | end; |
707 | 707 | ||
708 | function AsnNotation(oid: POid): string; |
708 | function AsnNotation(oid: POid): string; |
709 | var |
709 | var |
710 | prevOid, curOid: POid; |
710 | prevOid, curOid: POid; |
711 | res: string; |
711 | res: string; |
712 | begin |
712 | begin |
713 | CreateOidDef(curOid); |
713 | CreateOidDef(curOid); |
714 | prevOid := oid; |
714 | prevOid := oid; |
715 | res := ''; |
715 | res := ''; |
716 | 716 | ||
717 | while true do |
717 | while true do |
718 | begin |
718 | begin |
719 | (* Note: BackRef is not checked yet! Infinite loop is possible! (TODO) *) |
719 | (* Note: BackRef is not checked yet! Infinite loop is possible! (TODO) *) |
720 | ReadOidFile(prevOid^.ParentFileId + '.OID', curOid); |
720 | ReadOidFile(prevOid^.ParentFileId + '.OID', curOid); |
721 | if curOid^.ParentFileId = '' then break; |
721 | if curOid^.ParentFileId = '' then break; |
722 | if curOid^.ParentFileId = curOid^.FileId then break; |
722 | if curOid^.ParentFileId = curOid^.FileId then break; |
723 | if ListCount(curOid^.AsnIds) > 0 then |
723 | if ListCount(curOid^.AsnIds) > 0 then |
724 | res := ListGetElement(curOid^.AsnIds, 0) + '('+OidLastArc(curOid)+') ' + res |
724 | res := ListGetElement(curOid^.AsnIds, 0) + '('+OidLastArc(curOid)+') ' + res |
725 | else |
725 | else |
726 | res := OidLastArc(curOid) + ' ' + res; |
726 | res := OidLastArc(curOid) + ' ' + res; |
727 | prevOid := curOid; |
727 | prevOid := curOid; |
728 | end; |
728 | end; |
729 | FreeOidDef(curOid); |
729 | FreeOidDef(curOid); |
730 | if ListCount(oid^.AsnIds) > 0 then |
730 | if ListCount(oid^.AsnIds) > 0 then |
731 | res := res + ListGetElement(oid^.AsnIds, 0) + '('+OidLastArc(oid)+')' |
731 | res := res + ListGetElement(oid^.AsnIds, 0) + '('+OidLastArc(oid)+')' |
732 | else |
732 | else |
733 | res := res + OidLastArc(oid); |
733 | res := res + OidLastArc(oid); |
734 | if res = '' then |
734 | if res = '' then |
735 | AsnNotation := '' |
735 | AsnNotation := '' |
736 | else |
736 | else |
737 | AsnNotation := '{ ' + res + ' }'; |
737 | AsnNotation := '{ ' + res + ' }'; |
738 | end; |
738 | end; |
739 | 739 | ||
740 | function IriNotation(oid: POid): string; |
740 | function IriNotation(oid: POid): string; |
741 | var |
741 | var |
742 | prevOid, curOid: POid; |
742 | prevOid, curOid: POid; |
743 | res: string; |
743 | res: string; |
744 | begin |
744 | begin |
745 | CreateOidDef(curOid); |
745 | CreateOidDef(curOid); |
746 | prevOid := oid; |
746 | prevOid := oid; |
747 | res := ''; |
747 | res := ''; |
748 | 748 | ||
749 | while true do |
749 | while true do |
750 | begin |
750 | begin |
751 | (* Note: BackRef is not checked yet! Infinite loop is possible! (TODO) *) |
751 | (* Note: BackRef is not checked yet! Infinite loop is possible! (TODO) *) |
752 | ReadOidFile(prevOid^.ParentFileId + '.OID', curOid); |
752 | ReadOidFile(prevOid^.ParentFileId + '.OID', curOid); |
753 | if curOid^.ParentFileId = '' then break; |
753 | if curOid^.ParentFileId = '' then break; |
754 | if curOid^.ParentFileId = curOid^.FileId then break; |
754 | if curOid^.ParentFileId = curOid^.FileId then break; |
755 | if ListCount(curOid^.UnicodeLabels) > 0 then |
755 | if ListCount(curOid^.UnicodeLabels) > 0 then |
756 | res := ListGetElement(curOid^.UnicodeLabels, 0) + '/' + res |
756 | res := ListGetElement(curOid^.UnicodeLabels, 0) + '/' + res |
757 | else |
757 | else |
758 | res := OidLastArc(curOid) + '/' + res; |
758 | res := OidLastArc(curOid) + '/' + res; |
759 | prevOid := curOid; |
759 | prevOid := curOid; |
760 | end; |
760 | end; |
761 | FreeOidDef(curOid); |
761 | FreeOidDef(curOid); |
762 | if ListCount(oid^.UnicodeLabels) > 0 then |
762 | if ListCount(oid^.UnicodeLabels) > 0 then |
763 | res := res + ListGetElement(oid^.UnicodeLabels, 0) |
763 | res := res + ListGetElement(oid^.UnicodeLabels, 0) |
764 | else |
764 | else |
765 | res := res + OidLastArc(oid); |
765 | res := res + OidLastArc(oid); |
766 | IriNotation := '/' + res; |
766 | IriNotation := '/' + res; |
767 | end; |
767 | end; |
768 | 768 | ||
769 | function WeidNotation(oid: POid): string; |
769 | function WeidNotation(oid: POid): string; |
770 | begin |
770 | begin |
771 | WeidNotation := OidToWeid(oid^.DotNotation); |
771 | WeidNotation := OidToWeid(oid^.DotNotation); |
772 | end; |
772 | end; |
773 | 773 | ||
774 | procedure DisplayOIDFile(filename, from: string); |
774 | procedure DisplayOIDFile(filename, from: string); |
775 | var |
775 | var |
776 | isRoot: boolean; |
776 | isRoot: boolean; |
777 | oid, tmpOID: POID; |
777 | oid, tmpOID: POID; |
778 | i: integer; |
778 | i: integer; |
779 | sTmp, subfile: string; |
779 | sTmp, subfile: string; |
780 | subsel, subfiles: PStringList; |
780 | subsel, subfiles: PStringList; |
781 | subselres: integer; |
781 | subselres: integer; |
782 | exitRequest: boolean; |
782 | exitRequest: boolean; |
783 | menuIdExit, menuIdAsnEdit, menuIdIriEdit, menuIdDescEdit, menuIdAdd, menuIdDelete: integer; |
783 | menuIdExit, menuIdAsnEdit, menuIdIriEdit, menuIdDescEdit, menuIdAdd, menuIdDelete: integer; |
784 | menuX, menuY: integer; |
784 | menuX, menuY: integer; |
785 | begin |
785 | begin |
786 | exitRequest := false; |
786 | exitRequest := false; |
787 | repeat |
787 | repeat |
788 | CreateOidDef(oid); |
788 | CreateOidDef(oid); |
789 | 789 | ||
790 | if not _ReadOidFile(filename, oid, true) then |
790 | if not _ReadOidFile(filename, oid, true) then |
791 | begin |
791 | begin |
792 | FreeOidDef(oid); |
792 | FreeOidDef(oid); |
793 | exit; |
793 | exit; |
794 | end; |
794 | end; |
795 | 795 | ||
796 | (* Print OID information *) |
796 | (* Print OID information *) |
797 | 797 | ||
798 | ClrScr; |
798 | ClrScr; |
799 | _DrawOidTitleBar(filename, oid); |
799 | _DrawOidTitleBar(filename, oid); |
800 | DrawStatusBar(''); |
800 | DrawStatusBar(''); |
801 | GotoXY(1,2); |
801 | GotoXY(1,2); |
802 | 802 | ||
803 | Write('Dot notation: '); |
803 | Write('Dot notation: '); |
804 | WriteLnKeepX(DotNotation(oid)); |
804 | WriteLnKeepX(DotNotation(oid)); |
805 | Write('ASN.1 notation: '); |
805 | Write('ASN.1 notation: '); |
806 | WriteLnKeepX(AsnNotation(oid)); |
806 | WriteLnKeepX(AsnNotation(oid)); |
807 | Write('OID-IRI: '); |
807 | Write('OID-IRI: '); |
808 | WriteLnKeepX(IriNotation(oid)); |
808 | WriteLnKeepX(IriNotation(oid)); |
809 | Write('WEID notation: '); |
809 | Write('WEID notation: '); |
810 | WriteLnKeepX(WeidNotation(oid)); |
810 | WriteLnKeepX(WeidNotation(oid)); |
811 | WriteLn(''); |
811 | WriteLn(''); |
812 | 812 | ||
813 | if Trim(oid^.Description) <> '' then |
813 | if Trim(oid^.Description) <> '' then |
814 | begin |
814 | begin |
815 | (* WriteLn('Description:'); *) |
815 | (* WriteLn('Description:'); *) |
- | 816 | (* TODO: We should avoid that this is more than 10 lines *) |
|
816 | WriteLn(oid^.Description); |
817 | WriteLn(oid^.Description); |
817 | WriteLn(''); |
818 | WriteLn(''); |
818 | end |
819 | end |
819 | else |
820 | else |
820 | begin |
821 | begin |
821 | WriteLn('(No description has been added to this OID.)'); |
822 | WriteLn('(No description has been added to this OID.)'); |
822 | WriteLn(''); |
823 | WriteLn(''); |
823 | end; |
824 | end; |
824 | 825 | ||
825 | (* Now prepare the menu entries *) |
826 | (* Now prepare the menu entries *) |
826 | 827 | ||
827 | CreateList(subsel); (* Contains the human-readable OID name *) |
828 | CreateList(subsel); (* Contains the human-readable OID name *) |
828 | CreateList(subfiles); (* Contains the file name *) |
829 | CreateList(subfiles); (* Contains the file name *) |
829 | 830 | ||
830 | if oid^.ParentFileId = '' then |
831 | if oid^.ParentFileId = '' then |
831 | begin |
832 | begin |
832 | isRoot := true; |
833 | isRoot := true; |
833 | end |
834 | end |
834 | else |
835 | else |
835 | begin |
836 | begin |
836 | isRoot := oid^.ParentDotNotation = oid^.DotNotation; |
837 | isRoot := oid^.ParentDotNotation = oid^.DotNotation; |
837 | end; |
838 | end; |
838 | 839 | ||
839 | if (oid^.ParentFileId <> '') and not isRoot then |
840 | if (oid^.ParentFileId <> '') and not isRoot then |
840 | begin |
841 | begin |
841 | subfile := oid^.ParentFileId + OID_EXTENSION; |
842 | subfile := oid^.ParentFileId + OID_EXTENSION; |
842 | if FileExists(subfile) then |
843 | if FileExists(subfile) then |
843 | begin |
844 | begin |
844 | CreateOidDef(tmpOID); |
845 | CreateOidDef(tmpOID); |
845 | if not _ReadOidFile(subfile, tmpOID, true) then |
846 | if not _ReadOidFile(subfile, tmpOID, true) then |
846 | begin |
847 | begin |
847 | ListAppend(subsel, 'Go to parent ' + oid^.ParentDotNotation + ' (READ ERROR)'); |
848 | ListAppend(subsel, 'Go to parent ' + oid^.ParentDotNotation + ' (READ ERROR)'); |
848 | ListAppend(subfiles, 'ERROR: '+subfile+' Read error or file invalid'); |
849 | ListAppend(subfiles, 'ERROR: '+subfile+' Read error or file invalid'); |
849 | end |
850 | end |
850 | else |
851 | else |
851 | begin |
852 | begin |
852 | ListAppend(subsel, 'Go to parent ' + oid^.ParentDotNotation + _ShowASNIds(tmpOID)); |
853 | ListAppend(subsel, 'Go to parent ' + oid^.ParentDotNotation + _ShowASNIds(tmpOID)); |
853 | ListAppend(subfiles, subfile); |
854 | ListAppend(subfiles, subfile); |
854 | end; |
855 | end; |
855 | FreeOidDef(tmpOID); |
856 | FreeOidDef(tmpOID); |
856 | end |
857 | end |
857 | else |
858 | else |
858 | begin |
859 | begin |
859 | ListAppend(subsel, 'Go to parent ' + oid^.ParentDotNotation + ' (FILE NOT FOUND)'); |
860 | ListAppend(subsel, 'Go to parent ' + oid^.ParentDotNotation + ' (FILE NOT FOUND)'); |
860 | ListAppend(subfiles, 'ERROR: File '+subfile+' was not found'); |
861 | ListAppend(subfiles, 'ERROR: File '+subfile+' was not found'); |
861 | end; |
862 | end; |
862 | end; |
863 | end; |
863 | 864 | ||
864 | if isRoot then |
865 | if isRoot then |
865 | begin |
866 | begin |
866 | menuIdExit := ListAppend(subsel, 'Back to '+from); |
867 | menuIdExit := ListAppend(subsel, 'Back to '+from); |
867 | ListAppend(subfiles, ''); |
868 | ListAppend(subfiles, ''); |
868 | end |
869 | end |
869 | else menuIdExit := -99; |
870 | else menuIdExit := -99; |
870 | 871 | ||
871 | for i := 0 to ListCount(oid^.SubIds)-1 do |
872 | for i := 0 to ListCount(oid^.SubIds)-1 do |
872 | begin |
873 | begin |
873 | sTmp := ListGetElement(oid^.SubIds, i); |
874 | sTmp := ListGetElement(oid^.SubIds, i); |
874 | subfile := FileIdPart(sTmp) + OID_EXTENSION; |
875 | subfile := FileIdPart(sTmp) + OID_EXTENSION; |
875 | if FileExists(subfile) then |
876 | if FileExists(subfile) then |
876 | begin |
877 | begin |
877 | CreateOidDef(tmpOID); |
878 | CreateOidDef(tmpOID); |
878 | if not _ReadOidFile(subfile, tmpOID, true) then |
879 | if not _ReadOidFile(subfile, tmpOID, true) then |
879 | begin |
880 | begin |
880 | ListAppend(subsel, 'Go to child ' + DotNotationPart(sTmp) + ' (READ ERROR)'); |
881 | ListAppend(subsel, 'Go to child ' + DotNotationPart(sTmp) + ' (READ ERROR)'); |
881 | ListAppend(subfiles, 'ERROR: Read error at file '+subfile+', or file is invalid.'); |
882 | ListAppend(subfiles, 'ERROR: Read error at file '+subfile+', or file is invalid.'); |
882 | end |
883 | end |
883 | else if (tmpOID^.ParentFileId <> oid^.FileId) or |
884 | else if (tmpOID^.ParentFileId <> oid^.FileId) or |
884 | (tmpOID^.ParentDotNotation <> oid^.DotNotation) then |
885 | (tmpOID^.ParentDotNotation <> oid^.DotNotation) then |
885 | begin |
886 | begin |
886 | ListAppend(subsel, 'Go to child ' + DotNotationPart(sTmp) + ' (BAD BACKREF)'); |
887 | ListAppend(subsel, 'Go to child ' + DotNotationPart(sTmp) + ' (BAD BACKREF)'); |
887 | ListAppend(subfiles, 'ERROR: File '+subfile+' has a wrong back-reference.'); |
888 | ListAppend(subfiles, 'ERROR: File '+subfile+' has a wrong back-reference.'); |
888 | end |
889 | end |
889 | else |
890 | else |
890 | begin |
891 | begin |
891 | ListAppend(subsel, 'Go to child ' + DotNotationPart(sTmp) + _ShowASNIds(tmpOID)); |
892 | ListAppend(subsel, 'Go to child ' + DotNotationPart(sTmp) + _ShowASNIds(tmpOID)); |
892 | ListAppend(subfiles, subfile); |
893 | ListAppend(subfiles, subfile); |
893 | end; |
894 | end; |
894 | FreeOidDef(tmpOID); |
895 | FreeOidDef(tmpOID); |
895 | end |
896 | end |
896 | else |
897 | else |
897 | begin |
898 | begin |
898 | ListAppend(subsel, 'Go to child ' + DotNotationPart(sTmp) + ' (FILE NOT FOUND)'); |
899 | ListAppend(subsel, 'Go to child ' + DotNotationPart(sTmp) + ' (FILE NOT FOUND)'); |
899 | ListAppend(subfiles, 'ERROR: File '+subfile+' was not found'); |
900 | ListAppend(subfiles, 'ERROR: File '+subfile+' was not found'); |
900 | end; |
901 | end; |
901 | end; |
902 | end; |
902 | 903 | ||
903 | if oid^.DotNotation <> '' then |
904 | if oid^.DotNotation <> '' then |
904 | begin |
905 | begin |
905 | menuIdAsnEdit := ListAppend(subsel, 'View/Edit ASN.1 identifiers'); |
906 | menuIdAsnEdit := ListAppend(subsel, 'View/Edit ASN.1 identifiers'); |
906 | ListAppend(subfiles, ''); |
907 | ListAppend(subfiles, ''); |
907 | end |
908 | end |
908 | else menuIdAsnEdit := -99; |
909 | else menuIdAsnEdit := -99; |
909 | 910 | ||
910 | if oid^.DotNotation <> '' then |
911 | if oid^.DotNotation <> '' then |
911 | begin |
912 | begin |
912 | menuIdIriEdit := ListAppend(subsel, 'View/Edit Unicode Labels (OID-IRI)'); |
913 | menuIdIriEdit := ListAppend(subsel, 'View/Edit Unicode Labels (OID-IRI)'); |
913 | ListAppend(subfiles, ''); |
914 | ListAppend(subfiles, ''); |
914 | end |
915 | end |
915 | else menuIdIriEdit := -99; |
916 | else menuIdIriEdit := -99; |
916 | 917 | ||
917 | menuIdDescEdit := ListAppend(subsel, 'Edit description'); |
918 | menuIdDescEdit := ListAppend(subsel, 'Edit description'); |
918 | ListAppend(subfiles, ''); |
919 | ListAppend(subfiles, ''); |
919 | 920 | ||
920 | menuIdAdd := ListAppend(subsel, 'Add child'); |
921 | menuIdAdd := ListAppend(subsel, 'Add child'); |
921 | ListAppend(subfiles, ''); |
922 | ListAppend(subfiles, ''); |
922 | 923 | ||
923 | if not isRoot then |
924 | if not isRoot then |
924 | begin |
925 | begin |
925 | menuIdDelete := ListAppend(subsel, 'Delete OID'); |
926 | menuIdDelete := ListAppend(subsel, 'Delete OID'); |
926 | ListAppend(subfiles, ''); |
927 | ListAppend(subfiles, ''); |
927 | end |
928 | end |
928 | else menuIdDelete := -99; |
929 | else menuIdDelete := -99; |
929 | 930 | ||
930 | (* Show menu *) |
931 | (* Show menu *) |
931 | 932 | ||
932 | menuX := WhereX + 1; |
933 | menuX := WhereX + 1; |
933 | menuY := ScreenHeight - ACTIONMENU_SIZE - 1; |
934 | menuY := ScreenHeight - ACTIONMENU_SIZE - 1; |
934 | subselres := DrawSelectionList(menuX, menuY, |
935 | subselres := DrawSelectionList(menuX, menuY, |
935 | ScreenWidth-2, |
936 | ScreenWidth-2, |
936 | ACTIONMENU_SIZE, |
937 | ACTIONMENU_SIZE, |
937 | subsel, |
938 | subsel, |
938 | true, |
939 | true, |
939 | 'SELECT ACTION', |
940 | 'SELECT ACTION', |
940 | 1); |
941 | 1); |
941 | 942 | ||
942 | (* Process user selection *) |
943 | (* Process user selection *) |
943 | 944 | ||
944 | if subselres = -1 then |
945 | if subselres = -1 then |
945 | begin |
946 | begin |
946 | exitRequest := true; |
947 | exitRequest := true; |
947 | end |
948 | end |
948 | else if subselres = menuIdAsnEdit then |
949 | else if subselres = menuIdAsnEdit then |
949 | begin |
950 | begin |
950 | if AsnEditor(oid) then |
951 | if AsnEditor(oid) then |
951 | _WriteOidFile(filename, oid, true); |
952 | _WriteOidFile(filename, oid, true); |
952 | end |
953 | end |
953 | else if subselres = menuIdIriEdit then |
954 | else if subselres = menuIdIriEdit then |
954 | begin |
955 | begin |
955 | if IriEditor(oid) then |
956 | if IriEditor(oid) then |
956 | _WriteOidFile(filename, oid, true); |
957 | _WriteOidFile(filename, oid, true); |
957 | end |
958 | end |
958 | else if subselres = menuIdDescEdit then |
959 | else if subselres = menuIdDescEdit then |
959 | begin |
960 | begin |
960 | if DescEditor(oid) then |
961 | if DescEditor(oid) then |
961 | _WriteOidFile(filename, oid, true); |
962 | _WriteOidFile(filename, oid, true); |
962 | end |
963 | end |
963 | else if subselres = menuIdAdd then |
964 | else if subselres = menuIdAdd then |
964 | begin |
965 | begin |
965 | if NewOidEditor(oid) then |
966 | if NewOidEditor(oid) then |
966 | _WriteOidFile(filename, oid, true); |
967 | _WriteOidFile(filename, oid, true); |
967 | end |
968 | end |
968 | else if subselres = menuIdDelete then |
969 | else if subselres = menuIdDelete then |
969 | begin |
970 | begin |
970 | if _DeleteConfirmation then |
971 | if _DeleteConfirmation then |
971 | begin |
972 | begin |
972 | sTmp := oid^.ParentFileId + OID_EXTENSION; |
973 | sTmp := oid^.ParentFileId + OID_EXTENSION; |
973 | DeleteOidRecursive(oid); |
974 | DeleteOidRecursive(oid); |
974 | if FileExists(sTmp) then |
975 | if FileExists(sTmp) then |
975 | begin |
976 | begin |
976 | filename := sTmp; |
977 | filename := sTmp; |
977 | end |
978 | end |
978 | else |
979 | else |
979 | begin |
980 | begin |
980 | ShowMessage('Parent file ' + sTmp + ' was not found', 'ERROR', true); |
981 | ShowMessage('Parent file ' + sTmp + ' was not found', 'ERROR', true); |
981 | _Pause; |
982 | _Pause; |
982 | exitRequest := true; |
983 | exitRequest := true; |
983 | end; |
984 | end; |
984 | end; |
985 | end; |
985 | end |
986 | end |
986 | else if subselres = menuIdExit then |
987 | else if subselres = menuIdExit then |
987 | begin |
988 | begin |
988 | exitRequest := true; |
989 | exitRequest := true; |
989 | end |
990 | end |
990 | else |
991 | else |
991 | begin |
992 | begin |
992 | (* Normal OID *) |
993 | (* Normal OID *) |
993 | (* Above we already checked if the files are valild and existing *) |
994 | (* Above we already checked if the files are valild and existing *) |
994 | sTmp := ListGetElement(subfiles, subselres); |
995 | sTmp := ListGetElement(subfiles, subselres); |
995 | if Copy(sTmp, 1, Length('ERROR: ')) = 'ERROR: ' then |
996 | if Copy(sTmp, 1, Length('ERROR: ')) = 'ERROR: ' then |
996 | begin |
997 | begin |
997 | Delete(sTmp, 1, Length('ERROR: ')); |
998 | Delete(sTmp, 1, Length('ERROR: ')); |
998 | ShowMessage(sTmp, 'ERROR', true); |
999 | ShowMessage(sTmp, 'ERROR', true); |
999 | _Pause; |
1000 | _Pause; |
1000 | end |
1001 | end |
1001 | else |
1002 | else |
1002 | begin |
1003 | begin |
1003 | filename := sTmp; |
1004 | filename := sTmp; |
1004 | end; |
1005 | end; |
1005 | end; |
1006 | end; |
1006 | FreeList(subsel); |
1007 | FreeList(subsel); |
1007 | FreeList(subfiles); |
1008 | FreeList(subfiles); |
1008 | 1009 | ||
1009 | FreeOidDef(oid); |
1010 | FreeOidDef(oid); |
1010 | until exitRequest; |
1011 | until exitRequest; |
1011 | end; |
1012 | end; |
1012 | 1013 | ||
1013 | function CreateRootOIDFile(filename: string; ShowErrorMessage: boolean): boolean; |
1014 | function CreateRootOIDFile(filename: string; ShowErrorMessage: boolean): boolean; |
1014 | var |
1015 | var |
1015 | oid: POID; |
1016 | oid: POID; |
1016 | begin |
1017 | begin |
1017 | CreateOidDef(oid); |
1018 | CreateOidDef(oid); |
1018 | oid^.Description := 'This is the root of the OID tree.' +#13#10 + |
1019 | oid^.Description := 'This is the root of the OID tree.' +#13#10 + |
1019 | #13#10 + |
1020 | #13#10 + |
1020 | 'Valid subsequent arcs are per definition:' + #13#10 + |
1021 | 'Valid subsequent arcs are per definition:' + #13#10 + |
1021 | '- 0 (itu-t)' + #13#10 + |
1022 | '- 0 (itu-t)' + #13#10 + |
1022 | '- 1 (iso)' + #13#10 + |
1023 | '- 1 (iso)' + #13#10 + |
1023 | '- 2 (joint-iso-itu-t)'; |
1024 | '- 2 (joint-iso-itu-t)'; |
1024 | oid^.FileId := ZeroPad(0, 8); |
1025 | oid^.FileId := ZeroPad(0, 8); |
1025 | oid^.DotNotation := ''; |
1026 | oid^.DotNotation := ''; |
1026 | oid^.ParentFileId := ZeroPad(0, 8); |
1027 | oid^.ParentFileId := ZeroPad(0, 8); |
1027 | oid^.ParentDotNotation := ''; |
1028 | oid^.ParentDotNotation := ''; |
1028 | CreateRootOIDFile := _WriteOidFile(filename, oid, ShowErrorMessage); |
1029 | CreateRootOIDFile := _WriteOidFile(filename, oid, ShowErrorMessage); |
1029 | FreeOidDef(oid); |
1030 | FreeOidDef(oid); |
1030 | end; |
1031 | end; |
1031 | 1032 | ||
1032 | function _GetRootFile(ShowErrorMessage: boolean): string; |
1033 | function _GetRootFile(ShowErrorMessage: boolean): string; |
1033 | var |
1034 | var |
1034 | rootFile: string; |
1035 | rootFile: string; |
1035 | begin |
1036 | begin |
1036 | rootFile := ZeroPad(0, 8) + OID_EXTENSION; |
1037 | rootFile := ZeroPad(0, 8) + OID_EXTENSION; |
1037 | _GetRootFile := rootFile; |
1038 | _GetRootFile := rootFile; |
1038 | if not FileExists(rootFile) then |
1039 | if not FileExists(rootFile) then |
1039 | begin |
1040 | begin |
1040 | if not CreateRootOIDFile(rootFile, ShowErrorMessage) then |
1041 | if not CreateRootOIDFile(rootFile, ShowErrorMessage) then |
1041 | begin |
1042 | begin |
1042 | _GetRootFile := ''; |
1043 | _GetRootFile := ''; |
1043 | end; |
1044 | end; |
1044 | end; |
1045 | end; |
1045 | end; |
1046 | end; |
1046 | 1047 | ||
1047 | procedure OP_ManageOIDs; |
1048 | procedure OP_ManageOIDs; |
1048 | var |
1049 | var |
1049 | rootfile: string; |
1050 | rootfile: string; |
1050 | begin |
1051 | begin |
1051 | ClrScr; |
1052 | ClrScr; |
1052 | DrawTitleBar('Manage Object Identifiers', TITLEBAR_LEFT_TEXT, ''); |
1053 | DrawTitleBar('Manage Object Identifiers', TITLEBAR_LEFT_TEXT, ''); |
1053 | DrawStatusBar('Loading data... please wait...'); |
1054 | DrawStatusBar('Loading data... please wait...'); |
1054 | 1055 | ||
1055 | (* This will try creating a new root file if it does not exist *) |
1056 | (* This will try creating a new root file if it does not exist *) |
1056 | rootfile := _GetRootFile(true); |
1057 | rootfile := _GetRootFile(true); |
1057 | if rootfile = '' then Exit; |
1058 | if rootfile = '' then Exit; |
1058 | 1059 | ||
1059 | DisplayOIDFile(rootfile, 'main menu'); |
1060 | DisplayOIDFile(rootfile, 'main menu'); |
1060 | end; |
1061 | end; |
1061 | 1062 | ||
1062 | procedure OP_ReturnToMSDOS; |
1063 | procedure OP_ReturnToMSDOS; |
1063 | begin |
1064 | begin |
1064 | (* Note: These two lines don't seem to be necessary if you use DoneVideo *) |
1065 | (* Note: These two lines don't seem to be necessary if you use DoneVideo *) |
1065 | ResetDefaultDosColors; |
1066 | ResetDefaultDosColors; |
1066 | ClrScr; (*Important, so that the DOS command prompt is also LightGray *) |
1067 | ClrScr; (*Important, so that the DOS command prompt is also LightGray *) |
1067 | 1068 | ||
1068 | WriteLn('Thank you for using OIDplus for DOS.'); |
1069 | WriteLn('Thank you for using OIDplus for DOS.'); |
1069 | WriteLn(''); |
1070 | WriteLn(''); |
1070 | end; |
1071 | end; |
1071 | 1072 | ||
1072 | function _GetTreeViewLine(oid: POID; indent: integer): string; |
1073 | function _GetTreeViewLine(oid: POID; indent: integer): string; |
1073 | var |
1074 | var |
1074 | i: integer; |
1075 | i: integer; |
1075 | sTmp, sTmp2: string; |
1076 | sTmp, sTmp2: string; |
1076 | begin |
1077 | begin |
1077 | (* Build line *) |
1078 | (* Build line *) |
1078 | sTmp := RepeatStr(' ', indent*TREEVIEW_INDENT); |
1079 | sTmp := RepeatStr(' ', indent*TREEVIEW_INDENT); |
1079 | if oid^.DotNotation = '' then |
1080 | if oid^.DotNotation = '' then |
1080 | sTmp := sTmp + 'Object Identifiers' |
1081 | sTmp := sTmp + 'Object Identifiers' |
1081 | else |
1082 | else |
1082 | sTmp := sTmp + oid^.DotNotation; |
1083 | sTmp := sTmp + oid^.DotNotation; |
1083 | sTmp := sTmp + _ShowAsnIds(oid); |
1084 | sTmp := sTmp + _ShowAsnIds(oid); |
1084 | if TREEVIEW_INCLUDE_DESC then |
1085 | if TREEVIEW_INCLUDE_DESC then |
1085 | begin |
1086 | begin |
1086 | if Trim(oid^.Description) <> '' then |
1087 | if Trim(oid^.Description) <> '' then |
1087 | begin |
1088 | begin |
1088 | sTmp := sTmp + ': ' + oid^.Description; |
1089 | sTmp := sTmp + ': ' + oid^.Description; |
1089 | end; |
1090 | end; |
1090 | end; |
1091 | end; |
1091 | 1092 | ||
1092 | sTmp := StringReplace(sTmp, #13#10, ' '); |
1093 | sTmp := StringReplace(sTmp, #13#10, ' '); |
1093 | repeat |
1094 | repeat |
1094 | sTmp2 := sTmp; |
1095 | sTmp2 := sTmp; |
1095 | sTmp := StringReplace(sTmp, ' ', ' '); |
1096 | sTmp := StringReplace(sTmp, ' ', ' '); |
1096 | until sTmp = sTmp2; |
1097 | until sTmp = sTmp2; |
1097 | 1098 | ||
1098 | sTmp := TrimLineToWidth(sTmp, TREEVIEW_WIDTH); |
1099 | sTmp := TrimLineToWidth(sTmp, TREEVIEW_WIDTH); |
1099 | _GetTreeViewLine := sTmp; |
1100 | _GetTreeViewLine := sTmp; |
1100 | end; |
1101 | end; |
1101 | 1102 | ||
1102 | procedure _RecTreeExport(oid: POID; visList, targetList: PStringList; indent: integer); |
1103 | procedure _RecTreeExport(oid: POID; visList, targetList: PStringList; indent: integer); |
1103 | var |
1104 | var |
1104 | i: integer; |
1105 | i: integer; |
1105 | sTmp: string; |
1106 | sTmp: string; |
1106 | suboid: POID; |
1107 | suboid: POID; |
1107 | childFilename: string; |
1108 | childFilename: string; |
1108 | begin |
1109 | begin |
1109 | sTmp := _GetTreeViewLine(oid, indent); |
1110 | sTmp := _GetTreeViewLine(oid, indent); |
1110 | sTmp := TrimLineToWidth(sTmp, TREEVIEW_WIDTH); |
1111 | sTmp := TrimLineToWidth(sTmp, TREEVIEW_WIDTH); |
1111 | ListAppend(visList, sTmp); |
1112 | ListAppend(visList, sTmp); |
1112 | ListAppend(targetList, oid^.FileID); |
1113 | ListAppend(targetList, oid^.FileID); |
1113 | 1114 | ||
1114 | (* Recursively call children *) |
1115 | (* Recursively call children *) |
1115 | for i := 0 to ListCount(oid^.SubIds)-1 do |
1116 | for i := 0 to ListCount(oid^.SubIds)-1 do |
1116 | begin |
1117 | begin |
1117 | sTmp := ListGetElement(oid^.SubIds, i); |
1118 | sTmp := ListGetElement(oid^.SubIds, i); |
1118 | CreateOidDef(suboid); |
1119 | CreateOidDef(suboid); |
1119 | childFilename := FileIdPart(sTmp) + OID_EXTENSION; |
1120 | childFilename := FileIdPart(sTmp) + OID_EXTENSION; |
1120 | if not FileExists(childFilename) then |
1121 | if not FileExists(childFilename) then |
1121 | begin |
1122 | begin |
1122 | sTmp := 'ERROR: MISSING ' + childFilename + ' (SHALL CONTAIN ' + DotNotationPart(sTmp) + ')!'; |
1123 | sTmp := 'ERROR: MISSING ' + childFilename + ' (SHALL CONTAIN ' + DotNotationPart(sTmp) + ')!'; |
1123 | sTmp := TrimLineToWidth(sTmp, TREEVIEW_WIDTH); |
1124 | sTmp := TrimLineToWidth(sTmp, TREEVIEW_WIDTH); |
1124 | ListAppend(visList, sTmp); |
1125 | ListAppend(visList, sTmp); |
1125 | ListAppend(targetList, 'ERROR'); |
1126 | ListAppend(targetList, 'ERROR'); |
1126 | end |
1127 | end |
1127 | else if not _ReadOidFile(childFilename, suboid, false) then |
1128 | else if not _ReadOidFile(childFilename, suboid, false) then |
1128 | begin |
1129 | begin |
1129 | sTmp := 'ERROR: READ ERROR AT ' + childFilename + ' (SHALL CONTAIN ' + DotNotationPart(sTmp) + ')!'; |
1130 | sTmp := 'ERROR: READ ERROR AT ' + childFilename + ' (SHALL CONTAIN ' + DotNotationPart(sTmp) + ')!'; |
1130 | sTmp := TrimLineToWidth(sTmp, TREEVIEW_WIDTH); |
1131 | sTmp := TrimLineToWidth(sTmp, TREEVIEW_WIDTH); |
1131 | ListAppend(visList, sTmp); |
1132 | ListAppend(visList, sTmp); |
1132 | ListAppend(targetList, 'ERROR'); |
1133 | ListAppend(targetList, 'ERROR'); |
1133 | end |
1134 | end |
1134 | else if (suboid^.ParentFileId <> oid^.FileId) or |
1135 | else if (suboid^.ParentFileId <> oid^.FileId) or |
1135 | (suboid^.ParentDotNotation <> oid^.DotNotation) then |
1136 | (suboid^.ParentDotNotation <> oid^.DotNotation) then |
1136 | begin |
1137 | begin |
1137 | (* This can happen if a file is missing, and then another OID gets this filename since the number seems to be free *) |
1138 | (* This can happen if a file is missing, and then another OID gets this filename since the number seems to be free *) |
1138 | sTmp := 'ERROR: BAD BACKREF AT ' + childFilename + ' (SHALL CONTAIN ' + DotNotationPart(sTmp) + ')!'; |
1139 | sTmp := 'ERROR: BAD BACKREF AT ' + childFilename + ' (SHALL CONTAIN ' + DotNotationPart(sTmp) + ')!'; |
1139 | sTmp := TrimLineToWidth(sTmp, TREEVIEW_WIDTH); |
1140 | sTmp := TrimLineToWidth(sTmp, TREEVIEW_WIDTH); |
1140 | ListAppend(visList, sTmp); |
1141 | ListAppend(visList, sTmp); |
1141 | ListAppend(targetList, 'ERROR'); |
1142 | ListAppend(targetList, 'ERROR'); |
1142 | end |
1143 | end |
1143 | else |
1144 | else |
1144 | begin |
1145 | begin |
1145 | _RecTreeExport(suboid, visList, targetList, indent+1); |
1146 | _RecTreeExport(suboid, visList, targetList, indent+1); |
1146 | FreeOidDef(suboid); |
1147 | FreeOidDef(suboid); |
1147 | end |
1148 | end |
1148 | end; |
1149 | end; |
1149 | end; |
1150 | end; |
1150 | 1151 | ||
1151 | procedure TreeViewPreview(visList, targetList: PStringList); |
1152 | procedure TreeViewPreview(visList, targetList: PStringList); |
1152 | var |
1153 | var |
1153 | res: integer; |
1154 | res: integer; |
1154 | sTmp: string; |
1155 | sTmp: string; |
1155 | begin |
1156 | begin |
1156 | ClrScr; |
1157 | ClrScr; |
1157 | DrawTitleBar('TreeView Export', TITLEBAR_LEFT_TEXT, TREEVIEW_FILENAME); |
1158 | DrawTitleBar('TreeView Export', TITLEBAR_LEFT_TEXT, TREEVIEW_FILENAME); |
1158 | DrawStatusBar('Press ESC to return to the main menu. Enter to jump to OID.'); |
1159 | DrawStatusBar('Press ESC to return to the main menu. Enter to jump to OID.'); |
1159 | 1160 | ||
1160 | while true do |
1161 | while true do |
1161 | begin |
1162 | begin |
1162 | res := DrawSelectionList(2, 3, ScreenWidth-2, ScreenHeight-4, |
1163 | res := DrawSelectionList(2, 3, ScreenWidth-2, ScreenHeight-4, |
1163 | visList, true, 'PREVIEW OF '+TREEVIEW_FILENAME, 2); |
1164 | visList, true, 'PREVIEW OF '+TREEVIEW_FILENAME, 2); |
1164 | if res > -1 then |
1165 | if res > -1 then |
1165 | begin |
1166 | begin |
1166 | (* Jump to selected OID or show error *) |
1167 | (* Jump to selected OID or show error *) |
1167 | sTmp := ListGetElement(targetList, res); |
1168 | sTmp := ListGetElement(targetList, res); |
1168 | if sTmp = 'ERROR' then |
1169 | if sTmp = 'ERROR' then |
1169 | begin |
1170 | begin |
1170 | ShowMessage(ListGetElement(visList, res), 'ERROR', true); |
1171 | ShowMessage(ListGetElement(visList, res), 'ERROR', true); |
1171 | _Pause; |
1172 | _Pause; |
1172 | end |
1173 | end |
1173 | else |
1174 | else |
1174 | begin |
1175 | begin |
1175 | DisplayOidFile(sTmp + '.OID', 'TreeView Export'); |
1176 | DisplayOidFile(sTmp + '.OID', 'TreeView Export'); |
1176 | end; |
1177 | end; |
1177 | end |
1178 | end |
1178 | else |
1179 | else |
1179 | begin |
1180 | begin |
1180 | break; |
1181 | break; |
1181 | end; |
1182 | end; |
1182 | end; |
1183 | end; |
1183 | 1184 | ||
1184 | DrawStatusBar(''); |
1185 | DrawStatusBar(''); |
1185 | end; |
1186 | end; |
1186 | 1187 | ||
1187 | procedure OP_TreeView; |
1188 | procedure OP_TreeView; |
1188 | var |
1189 | var |
1189 | F: Text; |
1190 | F: Text; |
1190 | rootoid: POID; |
1191 | rootoid: POID; |
1191 | rootfile: string; |
1192 | rootfile: string; |
1192 | res: boolean; |
1193 | res: boolean; |
1193 | visList, targetList: PStringList; |
1194 | visList, targetList: PStringList; |
1194 | begin |
1195 | begin |
1195 | ClrScr; |
1196 | ClrScr; |
1196 | DrawTitleBar('TreeView Export', TITLEBAR_LEFT_TEXT, ''); |
1197 | DrawTitleBar('TreeView Export', TITLEBAR_LEFT_TEXT, ''); |
1197 | DrawStatusBar('Exporting data... please wait...'); |
1198 | DrawStatusBar('Exporting data... please wait...'); |
1198 | 1199 | ||
1199 | (* This will try creating a new root file if it does not exist *) |
1200 | (* This will try creating a new root file if it does not exist *) |
1200 | rootfile := _GetRootFile(true); |
1201 | rootfile := _GetRootFile(true); |
1201 | if rootfile = '' then |
1202 | if rootfile = '' then |
1202 | begin |
1203 | begin |
1203 | DrawStatusBar(''); |
1204 | DrawStatusBar(''); |
1204 | Exit; |
1205 | Exit; |
1205 | end; |
1206 | end; |
1206 | 1207 | ||
1207 | CreateList(visList); |
1208 | CreateList(visList); |
1208 | CreateList(targetList); |
1209 | CreateList(targetList); |
1209 | 1210 | ||
1210 | (* First check if the disk is read-only *) |
1211 | (* First check if the disk is read-only *) |
1211 | Assign(F, TREEVIEW_FILENAME); |
1212 | Assign(F, TREEVIEW_FILENAME); |
1212 | {$I-} |
1213 | {$I-} |
1213 | Rewrite(F); |
1214 | Rewrite(F); |
1214 | {$I+} |
1215 | {$I+} |
1215 | if IoResult <> 0 then |
1216 | if IoResult <> 0 then |
1216 | begin |
1217 | begin |
1217 | (* Can happen if disk is read-only (Runtime Error 150) *) |
1218 | (* Can happen if disk is read-only (Runtime Error 150) *) |
1218 | ShowMessage('Cannot open '+TREEVIEW_FILENAME+' for writing.', 'ERROR', true); |
1219 | ShowMessage('Cannot open '+TREEVIEW_FILENAME+' for writing.', 'ERROR', true); |
1219 | _Pause; |
1220 | _Pause; |
1220 | DrawStatusBar(''); |
1221 | DrawStatusBar(''); |
1221 | Exit; |
1222 | Exit; |
1222 | end; |
1223 | end; |
1223 | Close(F); |
1224 | Close(F); |
1224 | 1225 | ||
1225 | (* Now do the export *) |
1226 | (* Now do the export *) |
1226 | res := false; |
1227 | res := false; |
1227 | CreateOidDef(rootoid); |
1228 | CreateOidDef(rootoid); |
1228 | if _ReadOidFile(rootfile, rootoid, true) then |
1229 | if _ReadOidFile(rootfile, rootoid, true) then |
1229 | begin |
1230 | begin |
1230 | _RecTreeExport(rootoid, visList, targetList, 0); |
1231 | _RecTreeExport(rootoid, visList, targetList, 0); |
1231 | res := true; |
1232 | res := true; |
1232 | end; |
1233 | end; |
1233 | FreeOidDef(rootoid); |
1234 | FreeOidDef(rootoid); |
1234 | 1235 | ||
1235 | (* Save the list (visual part only) *) |
1236 | (* Save the list (visual part only) *) |
1236 | ListSaveToFile(visList, TREEVIEW_FILENAME); |
1237 | ListSaveToFile(visList, TREEVIEW_FILENAME); |
1237 | 1238 | ||
1238 | DrawStatusBar(''); |
1239 | DrawStatusBar(''); |
1239 | if res then |
1240 | if res then |
1240 | begin |
1241 | begin |
1241 | ShowMessage('TreeView successfully exported as '+TREEVIEW_FILENAME, 'TREEVIEW EXPORT', true); |
1242 | ShowMessage('TreeView successfully exported as '+TREEVIEW_FILENAME, 'TREEVIEW EXPORT', true); |
1242 | _Pause; |
1243 | _Pause; |
1243 | end; |
1244 | end; |
1244 | 1245 | ||
1245 | TreeViewPreview(visList, targetList); |
1246 | TreeViewPreview(visList, targetList); |
1246 | 1247 | ||
1247 | FreeList(visList); |
1248 | FreeList(visList); |
1248 | FreeList(targetList); |
1249 | FreeList(targetList); |
1249 | end; |
1250 | end; |
1250 | 1251 | ||
1251 | procedure OP_MainMenu; |
1252 | procedure OP_MainMenu; |
1252 | var |
1253 | var |
1253 | menu: PStringList; |
1254 | menu: PStringList; |
1254 | menuRes, menuLeft, menuTop: integer; |
1255 | menuRes, menuLeft, menuTop: integer; |
1255 | menuIdOID, menuIdTree, menuIdExit: integer; |
1256 | menuIdOID, menuIdTree, menuIdExit: integer; |
1256 | begin |
1257 | begin |
1257 | repeat |
1258 | repeat |
1258 | ClrScr; |
1259 | ClrScr; |
1259 | 1260 | ||
1260 | DrawTitleBar('Welcome to OIDplus for DOS', '', ''); |
1261 | DrawTitleBar('Welcome to OIDplus for DOS', '', ''); |
1261 | DrawStatusBar('(C)2020-2022 ViaThinkSoft. Licensed under the terms of the Apache 2.0 license.'); |
1262 | DrawStatusBar('(C)2020-2022 ViaThinkSoft. Licensed under the terms of the Apache 2.0 license.'); |
1262 | GoToXY(ScreenWidth-Length(VERSIONINFO), ScreenHeight-1); |
1263 | GoToXY(ScreenWidth-Length(VERSIONINFO), ScreenHeight-1); |
1263 | Write(VERSIONINFO); |
1264 | Write(VERSIONINFO); |
1264 | 1265 | ||
1265 | CreateList(menu); |
1266 | CreateList(menu); |
1266 | 1267 | ||
1267 | menuIdOID := ListAppend(menu, 'Manage OIDs'); |
1268 | menuIdOID := ListAppend(menu, 'Manage OIDs'); |
1268 | menuIdTree := ListAppend(menu, 'Export TreeView'); |
1269 | menuIdTree := ListAppend(menu, 'Export TreeView'); |
1269 | menuIdExit := ListAppend(menu, 'Return to DOS'); |
1270 | menuIdExit := ListAppend(menu, 'Return to DOS'); |
1270 | 1271 | ||
1271 | menuLeft := round(ScreenWidth/2 -MAINMENU_WIDTH/2); |
1272 | menuLeft := round(ScreenWidth/2 -MAINMENU_WIDTH/2); |
1272 | menuTop := round(ScreenHeight/2-MAINMENU_HEIGHT/2); |
1273 | menuTop := round(ScreenHeight/2-MAINMENU_HEIGHT/2); |
1273 | menuRes := DrawSelectionList(menuLeft, menuTop, |
1274 | menuRes := DrawSelectionList(menuLeft, menuTop, |
1274 | MAINMENU_WIDTH, MAINMENU_HEIGHT, |
1275 | MAINMENU_WIDTH, MAINMENU_HEIGHT, |
1275 | menu, true, 'MAIN MENU', 2); |
1276 | menu, true, 'MAIN MENU', 2); |
1276 | FreeList(menu); |
1277 | FreeList(menu); |
1277 | 1278 | ||
1278 | if menuRes = menuIdOID then |
1279 | if menuRes = menuIdOID then |
1279 | begin |
1280 | begin |
1280 | OP_ManageOIDs; |
1281 | OP_ManageOIDs; |
1281 | end |
1282 | end |
1282 | else if menuRes = menuIdTree then |
1283 | else if menuRes = menuIdTree then |
1283 | begin |
1284 | begin |
1284 | OP_Treeview; |
1285 | OP_Treeview; |
1285 | end; |
1286 | end; |
1286 | until (menuRes = menuIdExit) or (MAINMENU_ALLOW_ESC and (menuRes = -1)); |
1287 | until (menuRes = menuIdExit) or (MAINMENU_ALLOW_ESC and (menuRes = -1)); |
1287 | 1288 | ||
1288 | OP_ReturnToMSDOS; |
1289 | OP_ReturnToMSDOS; |
1289 | end; |
1290 | end; |
1290 | 1291 | ||
1291 | begin |
1292 | begin |
1292 | InitVideo; (* sets ScreenWidth and ScreenHeight *) |
1293 | InitVideo; (* sets ScreenWidth and ScreenHeight *) |
1293 | CursorOff; |
1294 | CursorOff; |
1294 | OP_MainMenu; |
1295 | OP_MainMenu; |
1295 | CursorOn; |
1296 | CursorOn; |
1296 | DoneVideo; |
1297 | DoneVideo; |
1297 | end. |
1298 | end. |
1298 | 1299 |