Imported from antiword-0.37.tar.gz.
[antiword.git] / options.c
blob8379fef92382364aa8c961dcc2e199eeded9b7ed
1 /*
2 * options.c
3 * Copyright (C) 1998-2004 A.J. van Os; Released under GNU GPL
5 * Description:
6 * Read and write the options
7 */
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #if defined(__riscos)
13 #include "DeskLib:Error.h"
14 #include "DeskLib:Wimp.h"
15 #else
16 #include <stdlib.h>
17 #if defined(__dos) || defined(N_PLAT_NLM)
18 extern int getopt(int, char **, const char *);
19 #else
20 #include <unistd.h>
21 #endif /* __dos */
22 #endif /* __riscos */
23 #include "antiword.h"
25 #if defined(__riscos)
26 #define PARAGRAPH_BREAK "set paragraph_break=%d"
27 #define AUTOFILETYPE "set autofiletype_allowed=%d"
28 #define USE_OUTLINEFONTS "set use_outlinefonts=%d"
29 #define SHOW_IMAGES "set show_images=%d"
30 #define HIDE_HIDDEN_TEXT "set hide_hidden_text=%d"
31 #define SCALE_FACTOR_START "set scale_factor_start=%d"
32 #else
33 #define LEAFNAME_SIZE (32+1)
34 #endif /* __riscos */
36 /* Current values for options */
37 static options_type tOptionsCurr;
38 #if defined(__riscos)
39 /* Temporary values for options */
40 static options_type tOptionsTemp;
41 #else
42 typedef struct papersize_tag {
43 char szName[16]; /* Papersize name */
44 USHORT usWidth; /* In points */
45 USHORT usHeight; /* In points */
46 } papersize_type;
48 static const papersize_type atPaperSizes[] = {
49 { "10x14", 720, 1008 },
50 { "a3", 842, 1191 },
51 { "a4", 595, 842 },
52 { "a5", 420, 595 },
53 { "b4", 729, 1032 },
54 { "b5", 516, 729 },
55 { "executive", 540, 720 },
56 { "folio", 612, 936 },
57 { "legal", 612, 1008 },
58 { "letter", 612, 792 },
59 { "note", 540, 720 },
60 { "quarto", 610, 780 },
61 { "statement", 396, 612 },
62 { "tabloid", 792, 1224 },
63 { "", 0, 0 },
65 #endif /* __riscos */
66 /* Default values for options */
67 static const options_type tOptionsDefault = {
68 DEFAULT_SCREEN_WIDTH,
69 #if defined(__riscos)
70 conversion_draw,
71 #else
72 conversion_text,
73 #endif /* __riscos */
74 TRUE,
75 TRUE,
76 FALSE,
77 encoding_latin_1,
78 INT_MAX,
79 INT_MAX,
80 level_default,
81 #if defined(__riscos)
82 TRUE,
83 DEFAULT_SCALE_FACTOR,
84 #endif /* __riscos */
88 #if !defined(__riscos)
90 * bCorrectPapersize - see if the papersize is correct
92 * TRUE if the papersize is correct, otherwise FALSE
94 static BOOL
95 bCorrectPapersize(const char *szName, conversion_type eConversionType)
97 const papersize_type *pPaperSize;
99 for (pPaperSize = atPaperSizes;
100 pPaperSize->szName[0] != '\0';
101 pPaperSize++) {
102 if (!STRCEQ(pPaperSize->szName, szName)) {
103 continue;
105 DBG_DEC(pPaperSize->usWidth);
106 DBG_DEC(pPaperSize->usHeight);
107 tOptionsCurr.eConversionType = eConversionType;
108 tOptionsCurr.iPageHeight = (int)pPaperSize->usHeight;
109 tOptionsCurr.iPageWidth = (int)pPaperSize->usWidth;
110 return TRUE;
112 return FALSE;
113 } /* end of bCorrectPapersize */
116 * szCreateSuffix - create a suffix for the file
118 * Returns the suffix
120 static const char *
121 szCreateSuffix(const char *szLeafname)
123 const char *pcDot;
125 pcDot = strrchr(szLeafname, '.');
126 if (pcDot != NULL && STRCEQ(pcDot, ".txt")) {
127 /* There is already a .txt suffix, no need for another one */
128 return "";
130 return ".txt";
131 } /* end of szCreateSuffix */
134 * eMappingFile2Encoding - convert the mapping file to an encoding
136 static encoding_type
137 eMappingFile2Encoding(const char *szLeafname)
139 char szMappingFile[LEAFNAME_SIZE+4];
141 fail(szLeafname == NULL);
143 if (strlen(szLeafname) + 4 >= sizeof(szMappingFile)) {
144 DBG_MSG(szLeafname);
145 return encoding_latin_1;
148 sprintf(szMappingFile, "%s%s", szLeafname, szCreateSuffix(szLeafname));
150 DBG_MSG(szMappingFile);
152 if (STRCEQ(szMappingFile, MAPPING_FILE_UTF_8)) {
153 return encoding_utf_8;
155 if (STRCEQ(szMappingFile, MAPPING_FILE_CP852) ||
156 STRCEQ(szMappingFile, MAPPING_FILE_CP1250) ||
157 STRCEQ(szMappingFile, MAPPING_FILE_8859_2)) {
158 return encoding_latin_2;
160 if (STRCEQ(szMappingFile, MAPPING_FILE_KOI8_R) ||
161 STRCEQ(szMappingFile, MAPPING_FILE_KOI8_U) ||
162 STRCEQ(szMappingFile, MAPPING_FILE_CP866) ||
163 STRCEQ(szMappingFile, MAPPING_FILE_CP1251) ||
164 STRCEQ(szMappingFile, MAPPING_FILE_8859_5)) {
165 return encoding_cyrillic;
167 return encoding_latin_1;
168 } /* end of eMappingFile2Encoding */
169 #endif /* !__riscos */
172 * pOpenCharacterMappingFile - open the mapping file
174 * Returns the file pointer or NULL
176 static FILE *
177 pOpenCharacterMappingFile(const char *szLeafname)
179 #if !defined(__riscos)
180 FILE *pFile;
181 const char *szHome, *szAntiword, *szSuffix;
182 size_t tFilenameLen;
183 char szMappingFile[PATH_MAX+1];
184 #endif /* !__riscos */
186 if (szLeafname == NULL || szLeafname[0] == '\0') {
187 return NULL;
190 DBG_MSG(szLeafname);
192 #if defined(__riscos)
193 return fopen(szLeafname, "r");
194 #else
195 /* Set the suffix */
196 szSuffix = szCreateSuffix(szLeafname);
198 /* Set length */
199 tFilenameLen = strlen(szLeafname) + strlen(szSuffix);
201 /* Try the environment version of the mapping file */
202 szAntiword = szGetAntiwordDirectory();
203 if (szAntiword != NULL && szAntiword[0] != '\0') {
204 if (strlen(szAntiword) + tFilenameLen <
205 sizeof(szMappingFile) -
206 sizeof(FILE_SEPARATOR)) {
207 sprintf(szMappingFile,
208 "%s" FILE_SEPARATOR "%s%s",
209 szAntiword, szLeafname, szSuffix);
210 DBG_MSG(szMappingFile);
211 pFile = fopen(szMappingFile, "r");
212 if (pFile != NULL) {
213 return pFile;
215 } else {
216 werr(0, "Environment mappingfilename ignored");
220 /* Try the local version of the mapping file */
221 szHome = szGetHomeDirectory();
222 if (strlen(szHome) + tFilenameLen <
223 sizeof(szMappingFile) -
224 sizeof(ANTIWORD_DIR) -
225 2 * sizeof(FILE_SEPARATOR)) {
226 sprintf(szMappingFile,
227 "%s" FILE_SEPARATOR ANTIWORD_DIR FILE_SEPARATOR "%s%s",
228 szHome, szLeafname, szSuffix);
229 DBG_MSG(szMappingFile);
230 pFile = fopen(szMappingFile, "r");
231 if (pFile != NULL) {
232 return pFile;
234 } else {
235 werr(0, "Local mappingfilename too long, ignored");
238 /* Try the global version of the mapping file */
239 if (tFilenameLen <
240 sizeof(szMappingFile) -
241 sizeof(GLOBAL_ANTIWORD_DIR) -
242 sizeof(FILE_SEPARATOR)) {
243 sprintf(szMappingFile,
244 GLOBAL_ANTIWORD_DIR FILE_SEPARATOR "%s%s",
245 szLeafname, szSuffix);
246 DBG_MSG(szMappingFile);
247 pFile = fopen(szMappingFile, "r");
248 if (pFile != NULL) {
249 return pFile;
251 } else {
252 werr(0, "Global mappingfilename too long, ignored");
254 werr(0, "I can't open your mapping file (%s%s)\n"
255 "It is not in '%s" FILE_SEPARATOR ANTIWORD_DIR "' nor in '"
256 GLOBAL_ANTIWORD_DIR "'.", szLeafname, szSuffix, szHome);
257 return NULL;
258 #endif /* __riscos */
259 } /* end of pOpenCharacterMappingFile */
262 * vCloseCharacterMappingFile - close the mapping file
264 static void
265 vCloseCharacterMappingFile(FILE *pFile)
267 (void)fclose(pFile);
268 } /* end of pCloseCharacterMappingFile */
272 * iReadOptions - read options
274 * returns: -1: error
275 * 0: help
276 * >0: index first file argument
279 iReadOptions(int argc, char **argv)
281 #if defined(__riscos)
282 FILE *pFile;
283 const char *szAlphabet;
284 int iAlphabet;
285 char szLine[81];
286 #else
287 extern char *optarg;
288 extern int optind;
289 char *pcChar, *szTmp;
290 int iChar;
291 char szLeafname[LEAFNAME_SIZE];
292 #endif /* __riscos */
293 FILE *pCharacterMappingFile;
294 int iTmp;
295 BOOL bSuccess;
297 DBG_MSG("iReadOptions");
299 /* Defaults */
300 tOptionsCurr = tOptionsDefault;
302 #if defined(__riscos)
303 /* Choices file */
304 pFile = fopen("<AntiWord$ChoicesFile>", "r");
305 DBG_MSG_C(pFile == NULL, "Choices file not found");
306 DBG_HEX_C(pFile != NULL, pFile);
307 if (pFile != NULL) {
308 while (fgets(szLine, (int)sizeof(szLine), pFile) != NULL) {
309 DBG_MSG(szLine);
310 if (szLine[0] == '#' ||
311 szLine[0] == '\r' ||
312 szLine[0] == '\n') {
313 continue;
315 if (sscanf(szLine, PARAGRAPH_BREAK, &iTmp) == 1 &&
316 (iTmp == 0 ||
317 (iTmp >= MIN_SCREEN_WIDTH &&
318 iTmp <= MAX_SCREEN_WIDTH))) {
319 tOptionsCurr.iParagraphBreak = iTmp;
320 DBG_DEC(tOptionsCurr.iParagraphBreak);
321 } else if (sscanf(szLine, AUTOFILETYPE, &iTmp)
322 == 1) {
323 tOptionsCurr.bAutofiletypeAllowed =
324 iTmp != 0;
325 DBG_DEC(tOptionsCurr.bAutofiletypeAllowed);
326 } else if (sscanf(szLine, USE_OUTLINEFONTS, &iTmp)
327 == 1) {
328 tOptionsCurr.eConversionType =
329 iTmp == 0 ?
330 conversion_text : conversion_draw;
331 DBG_DEC(tOptionsCurr.eConversionType);
332 } else if (sscanf(szLine, SHOW_IMAGES, &iTmp)
333 == 1) {
334 tOptionsCurr.eImageLevel = iTmp != 0 ?
335 level_default : level_no_images;
336 } else if (sscanf(szLine, HIDE_HIDDEN_TEXT, &iTmp)
337 == 1) {
338 tOptionsCurr.bHideHiddenText = iTmp != 0;
339 DBG_DEC(tOptionsCurr.bHideHiddenText);
340 } else if (sscanf(szLine, SCALE_FACTOR_START, &iTmp)
341 == 1) {
342 if (iTmp >= MIN_SCALE_FACTOR &&
343 iTmp <= MAX_SCALE_FACTOR) {
344 tOptionsCurr.iScaleFactor = iTmp;
345 DBG_DEC(tOptionsCurr.iScaleFactor);
349 (void)fclose(pFile);
351 iAlphabet = iReadCurrentAlphabetNumber();
352 switch (iAlphabet) {
353 case 101: /* ISO-8859-1 aka Latin1 */
354 szAlphabet = "<AntiWord$Latin1>";
355 break;
356 case 112: /* ISO-8859-15 aka Latin9 */
357 szAlphabet = "<AntiWord$Latin9>";
358 break;
359 default:
360 werr(0, "Alphabet '%d' is not supported", iAlphabet);
361 return -1;
363 pCharacterMappingFile = pOpenCharacterMappingFile(szAlphabet);
364 if (pCharacterMappingFile != NULL) {
365 bSuccess = bReadCharacterMappingTable(pCharacterMappingFile);
366 vCloseCharacterMappingFile(pCharacterMappingFile);
367 } else {
368 bSuccess = FALSE;
370 return bSuccess ? 1 : -1;
371 #else
372 /* Environment */
373 szTmp = getenv("COLUMNS");
374 if (szTmp != NULL) {
375 DBG_MSG(szTmp);
376 iTmp = (int)strtol(szTmp, &pcChar, 10);
377 if (*pcChar == '\0') {
378 iTmp -= 4; /* This is for the edge */
379 if (iTmp < MIN_SCREEN_WIDTH) {
380 iTmp = MIN_SCREEN_WIDTH;
381 } else if (iTmp > MAX_SCREEN_WIDTH) {
382 iTmp = MAX_SCREEN_WIDTH;
384 tOptionsCurr.iParagraphBreak = iTmp;
385 DBG_DEC(tOptionsCurr.iParagraphBreak);
388 strncpy(szLeafname, szGetDefaultMappingFile(), sizeof(szLeafname) - 1);
389 szLeafname[sizeof(szLeafname) - 1] = '\0';
390 /* Command line */
391 while ((iChar = getopt(argc, argv, "La:fhi:m:p:rstw:x:")) != -1) {
392 switch (iChar) {
393 case 'L':
394 tOptionsCurr.bUseLandscape = TRUE;
395 break;
396 case 'a':
397 if (!bCorrectPapersize(optarg, conversion_pdf)) {
398 werr(0, "-a without a valid papersize");
399 return -1;
401 break;
402 case 'f':
403 tOptionsCurr.eConversionType = conversion_fmt_text;
404 break;
405 case 'h':
406 return 0;
407 case 'i':
408 iTmp = (int)strtol(optarg, &pcChar, 10);
409 if (*pcChar != '\0') {
410 break;
412 switch (iTmp) {
413 case 0:
414 tOptionsCurr.eImageLevel = level_gs_special;
415 break;
416 case 1:
417 tOptionsCurr.eImageLevel = level_no_images;
418 break;
419 case 2:
420 tOptionsCurr.eImageLevel = level_ps_2;
421 break;
422 case 3:
423 tOptionsCurr.eImageLevel = level_ps_3;
424 break;
425 default:
426 tOptionsCurr.eImageLevel = level_default;
427 break;
429 DBG_DEC(tOptionsCurr.eImageLevel);
430 break;
431 case 'm':
432 if (tOptionsCurr.eConversionType == conversion_xml) {
433 werr(0, "XML doesn't need a mapping file");
434 break;
436 strncpy(szLeafname, optarg, sizeof(szLeafname) - 1);
437 szLeafname[sizeof(szLeafname) - 1] = '\0';
438 DBG_MSG(szLeafname);
439 break;
440 case 'p':
441 if (!bCorrectPapersize(optarg, conversion_ps)) {
442 werr(0, "-p without a valid papersize");
443 return -1;
445 break;
446 case 'r':
447 tOptionsCurr.bRemoveRemovedText = FALSE;
448 break;
449 case 's':
450 tOptionsCurr.bHideHiddenText = FALSE;
451 break;
452 case 't':
453 tOptionsCurr.eConversionType = conversion_text;
454 break;
455 case 'w':
456 iTmp = (int)strtol(optarg, &pcChar, 10);
457 if (*pcChar == '\0') {
458 if (iTmp != 0 && iTmp < MIN_SCREEN_WIDTH) {
459 iTmp = MIN_SCREEN_WIDTH;
460 } else if (iTmp > MAX_SCREEN_WIDTH) {
461 iTmp = MAX_SCREEN_WIDTH;
463 tOptionsCurr.iParagraphBreak = iTmp;
464 DBG_DEC(tOptionsCurr.iParagraphBreak);
466 break;
467 case 'x':
468 if (STREQ(optarg, "db")) {
469 tOptionsCurr.iParagraphBreak = 0;
470 tOptionsCurr.eConversionType = conversion_xml;
471 strcpy(szLeafname, MAPPING_FILE_UTF_8);
472 } else {
473 werr(0, "-x %s is not supported", optarg);
474 return -1;
476 break;
477 default:
478 return -1;
482 tOptionsCurr.eEncoding = eMappingFile2Encoding(szLeafname);
483 DBG_DEC(tOptionsCurr.eEncoding);
485 if (tOptionsCurr.eConversionType == conversion_ps &&
486 tOptionsCurr.eEncoding == encoding_utf_8) {
487 werr(0,
488 "The combination PostScript and UTF-8 is not supported");
489 return -1;
492 if (tOptionsCurr.eConversionType == conversion_pdf &&
493 tOptionsCurr.eEncoding == encoding_utf_8) {
494 werr(0,
495 "The combination PDF and UTF-8 is not supported");
496 return -1;
499 if (tOptionsCurr.eConversionType == conversion_pdf &&
500 tOptionsCurr.eEncoding == encoding_cyrillic) {
501 werr(0,
502 "The combination PDF and Cyrillic is not supported");
503 return -1;
506 if (tOptionsCurr.eConversionType == conversion_ps ||
507 tOptionsCurr.eConversionType == conversion_pdf) {
508 /* PostScript or PDF mode */
509 if (tOptionsCurr.bUseLandscape) {
510 /* Swap the page height and width */
511 iTmp = tOptionsCurr.iPageHeight;
512 tOptionsCurr.iPageHeight = tOptionsCurr.iPageWidth;
513 tOptionsCurr.iPageWidth = iTmp;
515 /* The paragraph break depends on the width of the paper */
516 tOptionsCurr.iParagraphBreak = iMilliPoints2Char(
517 (long)tOptionsCurr.iPageWidth * 1000 -
518 lDrawUnits2MilliPoints(
519 PS_LEFT_MARGIN + PS_RIGHT_MARGIN));
520 DBG_DEC(tOptionsCurr.iParagraphBreak);
523 pCharacterMappingFile = pOpenCharacterMappingFile(szLeafname);
524 if (pCharacterMappingFile != NULL) {
525 bSuccess = bReadCharacterMappingTable(pCharacterMappingFile);
526 vCloseCharacterMappingFile(pCharacterMappingFile);
527 } else {
528 bSuccess = FALSE;
530 return bSuccess ? optind : -1;
531 #endif /* __riscos */
532 } /* end of iReadOptions */
535 * vGetOptions - get a copy of the current option values
537 void
538 vGetOptions(options_type *pOptions)
540 fail(pOptions == NULL);
542 *pOptions = tOptionsCurr;
543 } /* end of vGetOptions */
545 #if defined(__riscos)
547 * vWriteOptions - write the current options to the Options file
549 static void
550 vWriteOptions(void)
552 FILE *pFile;
553 char *szOptionsFile;
555 TRACE_MSG("vWriteOptions");
557 szOptionsFile = getenv("AntiWord$ChoicesSave");
558 if (szOptionsFile == NULL) {
559 werr(0, "Warning: Name of the Choices file not found");
560 return;
562 if (!bMakeDirectory(szOptionsFile)) {
563 werr(0,
564 "Warning: I can't make a directory for the Choices file");
565 return;
567 pFile = fopen(szOptionsFile, "w");
568 if (pFile == NULL) {
569 werr(0, "Warning: I can't write the Choices file");
570 return;
572 (void)fprintf(pFile, PARAGRAPH_BREAK"\n",
573 tOptionsCurr.iParagraphBreak);
574 (void)fprintf(pFile, AUTOFILETYPE"\n",
575 tOptionsCurr.bAutofiletypeAllowed);
576 (void)fprintf(pFile, USE_OUTLINEFONTS"\n",
577 tOptionsCurr.eConversionType == conversion_text ? 0 : 1);
578 (void)fprintf(pFile, SHOW_IMAGES"\n",
579 tOptionsCurr.eImageLevel == level_no_images ? 0 : 1);
580 (void)fprintf(pFile, HIDE_HIDDEN_TEXT"\n",
581 tOptionsCurr.bHideHiddenText);
582 (void)fprintf(pFile, SCALE_FACTOR_START"\n",
583 tOptionsCurr.iScaleFactor);
584 (void)fclose(pFile);
585 } /* end of vWriteOptions */
588 * vChoicesOpenAction - action to be taken when the Choices window opens
590 void
591 vChoicesOpenAction(window_handle tWindow)
593 TRACE_MSG("vChoicesOpenAction");
595 tOptionsTemp = tOptionsCurr;
596 if (tOptionsTemp.iParagraphBreak == 0) {
597 vUpdateRadioButton(tWindow, CHOICES_BREAK_BUTTON, FALSE);
598 vUpdateRadioButton(tWindow, CHOICES_NO_BREAK_BUTTON, TRUE);
599 vUpdateWriteableNumber(tWindow, CHOICES_BREAK_WRITEABLE,
600 DEFAULT_SCREEN_WIDTH);
601 } else {
602 vUpdateRadioButton(tWindow, CHOICES_BREAK_BUTTON, TRUE);
603 vUpdateRadioButton(tWindow, CHOICES_NO_BREAK_BUTTON, FALSE);
604 vUpdateWriteableNumber(tWindow,
605 CHOICES_BREAK_WRITEABLE,
606 tOptionsTemp.iParagraphBreak);
608 vUpdateRadioButton(tWindow, CHOICES_AUTOFILETYPE_BUTTON,
609 tOptionsTemp.bAutofiletypeAllowed);
610 vUpdateRadioButton(tWindow, CHOICES_HIDDEN_TEXT_BUTTON,
611 tOptionsTemp.bHideHiddenText);
612 if (tOptionsTemp.eConversionType == conversion_draw) {
613 vUpdateRadioButton(tWindow,
614 CHOICES_WITH_IMAGES_BUTTON,
615 tOptionsTemp.eImageLevel != level_no_images);
616 vUpdateRadioButton(tWindow,
617 CHOICES_NO_IMAGES_BUTTON,
618 tOptionsTemp.eImageLevel == level_no_images);
619 vUpdateRadioButton(tWindow,
620 CHOICES_TEXTONLY_BUTTON, FALSE);
621 } else {
622 vUpdateRadioButton(tWindow,
623 CHOICES_WITH_IMAGES_BUTTON, FALSE);
624 vUpdateRadioButton(tWindow,
625 CHOICES_NO_IMAGES_BUTTON, FALSE);
626 vUpdateRadioButton(tWindow,
627 CHOICES_TEXTONLY_BUTTON, TRUE);
629 vUpdateWriteableNumber(tWindow,
630 CHOICES_SCALE_WRITEABLE, tOptionsTemp.iScaleFactor);
631 TRACE_MSG("end of vChoicesOpenAction");
632 } /* end of vChoicesOpenAction */
635 * vDefaultButtonAction - action when the default button is clicked
637 static void
638 vDefaultButtonAction(window_handle tWindow)
640 TRACE_MSG("vDefaultButtonAction");
642 tOptionsTemp = tOptionsDefault;
643 vUpdateRadioButton(tWindow, CHOICES_BREAK_BUTTON, TRUE);
644 vUpdateRadioButton(tWindow, CHOICES_NO_BREAK_BUTTON, FALSE);
645 vUpdateWriteableNumber(tWindow, CHOICES_BREAK_WRITEABLE,
646 tOptionsTemp.iParagraphBreak);
647 vUpdateRadioButton(tWindow, CHOICES_AUTOFILETYPE_BUTTON,
648 tOptionsTemp.bAutofiletypeAllowed);
649 vUpdateRadioButton(tWindow, CHOICES_HIDDEN_TEXT_BUTTON,
650 tOptionsTemp.bHideHiddenText);
651 vUpdateRadioButton(tWindow, CHOICES_WITH_IMAGES_BUTTON,
652 tOptionsTemp.eConversionType == conversion_draw &&
653 tOptionsTemp.eImageLevel != level_no_images);
654 vUpdateRadioButton(tWindow, CHOICES_NO_IMAGES_BUTTON,
655 tOptionsTemp.eConversionType == conversion_draw &&
656 tOptionsTemp.eImageLevel == level_no_images);
657 vUpdateRadioButton(tWindow, CHOICES_TEXTONLY_BUTTON,
658 tOptionsTemp.eConversionType == conversion_text);
659 vUpdateWriteableNumber(tWindow, CHOICES_SCALE_WRITEABLE,
660 tOptionsTemp.iScaleFactor);
661 } /* end of vDefaultButtonAction */
664 * vApplyButtonAction - action to be taken when the OK button is clicked
666 static void
667 vApplyButtonAction(void)
669 TRACE_MSG("vApplyButtonAction");
671 tOptionsCurr = tOptionsTemp;
672 } /* end of vApplyButtonAction */
675 * vSaveButtonAction - action to be taken when the save button is clicked
677 static void
678 vSaveButtonAction(void)
680 TRACE_MSG("vSaveButtonAction");
682 vApplyButtonAction();
683 vWriteOptions();
684 } /* end of vSaveButtonAction */
687 * vSetParagraphBreak - set the paragraph break to the given number
689 static void
690 vSetParagraphBreak(window_handle tWindow, int iNumber)
692 tOptionsTemp.iParagraphBreak = iNumber;
693 if (tOptionsTemp.iParagraphBreak == 0) {
694 return;
696 vUpdateWriteableNumber(tWindow,
697 CHOICES_BREAK_WRITEABLE,
698 tOptionsTemp.iParagraphBreak);
699 } /* end of vSetParagraphBreak */
702 * vChangeParagraphBreak - change the paragraph break with the given number
704 static void
705 vChangeParagraphBreak(window_handle tWindow, int iNumber)
707 int iTmp;
709 iTmp = tOptionsTemp.iParagraphBreak + iNumber;
710 if (iTmp < MIN_SCREEN_WIDTH || iTmp > MAX_SCREEN_WIDTH) {
711 /* Ignore */
712 return;
714 tOptionsTemp.iParagraphBreak = iTmp;
715 vUpdateWriteableNumber(tWindow,
716 CHOICES_BREAK_WRITEABLE,
717 tOptionsTemp.iParagraphBreak);
718 } /* end of vChangeParagraphBreak */
721 * vChangeAutofiletype - invert the permission to autofiletype
723 static void
724 vChangeAutofiletype(window_handle tWindow)
726 tOptionsTemp.bAutofiletypeAllowed =
727 !tOptionsTemp.bAutofiletypeAllowed;
728 vUpdateRadioButton(tWindow,
729 CHOICES_AUTOFILETYPE_BUTTON,
730 tOptionsTemp.bAutofiletypeAllowed);
731 } /* end of vChangeAutofiletype */
734 * vChangeHiddenText - invert the hide/show hidden text
736 static void
737 vChangeHiddenText(window_handle tWindow)
739 tOptionsTemp.bHideHiddenText = !tOptionsTemp.bHideHiddenText;
740 vUpdateRadioButton(tWindow,
741 CHOICES_HIDDEN_TEXT_BUTTON,
742 tOptionsTemp.bHideHiddenText);
743 } /* end of vChangeHiddenText */
746 * vUseFontsImages - use outline fonts, show images
748 static void
749 vUseFontsImages(BOOL bUseOutlineFonts, BOOL bShowImages)
751 tOptionsTemp.eConversionType =
752 bUseOutlineFonts ? conversion_draw : conversion_text;
753 tOptionsTemp.eImageLevel =
754 bUseOutlineFonts && bShowImages ?
755 level_default : level_no_images;
756 } /* end of vUseFontsImages */
759 * vSetScaleFactor - set the scale factor to the given number
761 static void
762 vSetScaleFactor(window_handle tWindow, int iNumber)
764 tOptionsTemp.iScaleFactor = iNumber;
765 vUpdateWriteableNumber(tWindow,
766 CHOICES_SCALE_WRITEABLE,
767 tOptionsTemp.iScaleFactor);
768 } /* end of vSetScaleFactor */
771 * vChangeScaleFactor - change the scale factor with the given number
773 static void
774 vChangeScaleFactor(window_handle tWindow, int iNumber)
776 int iTmp;
778 iTmp = tOptionsTemp.iScaleFactor + iNumber;
779 if (iTmp < MIN_SCALE_FACTOR || iTmp > MAX_SCALE_FACTOR) {
780 /* Ignore */
781 return;
783 tOptionsTemp.iScaleFactor = iTmp;
784 vUpdateWriteableNumber(tWindow,
785 CHOICES_SCALE_WRITEABLE,
786 tOptionsTemp.iScaleFactor);
787 } /* end of vChangeScaleFactor */
790 * bChoicesMouseClick - handle a mouse click in the Choices window
792 BOOL
793 bChoicesMouseClick(event_pollblock *pEvent, void *pvReference)
795 icon_handle tAction;
796 mouse_block *pMouse;
797 BOOL bCloseWindow;
799 TRACE_MSG("bChoicesMouseClick");
801 fail(pEvent == NULL);
802 fail(pEvent->type != event_CLICK);
804 pMouse = &pEvent->data.mouse;
805 if (!pMouse->button.data.select && !pMouse->button.data.adjust) {
806 /* Not handled here */
807 DBG_HEX(pMouse->button.value);
808 return FALSE;
811 /* Which action should be taken */
812 tAction = pMouse->icon;
813 if (pMouse->button.data.adjust) {
814 /* The adjust button reverses the direction */
815 switch (pMouse->icon) {
816 case CHOICES_BREAK_UP_BUTTON:
817 tAction = CHOICES_BREAK_DOWN_BUTTON;
818 break;
819 case CHOICES_BREAK_DOWN_BUTTON:
820 tAction = CHOICES_BREAK_UP_BUTTON;
821 break;
822 case CHOICES_SCALE_UP_BUTTON:
823 tAction = CHOICES_SCALE_DOWN_BUTTON;
824 break;
825 case CHOICES_SCALE_DOWN_BUTTON:
826 tAction = CHOICES_SCALE_UP_BUTTON;
827 break;
828 default:
829 break;
833 /* Actions */
834 bCloseWindow = FALSE;
835 switch (tAction) {
836 case CHOICES_DEFAULT_BUTTON:
837 vDefaultButtonAction(pMouse->window);
838 break;
839 case CHOICES_SAVE_BUTTON:
840 vSaveButtonAction();
841 break;
842 case CHOICES_CANCEL_BUTTON:
843 bCloseWindow = TRUE;
844 break;
845 case CHOICES_APPLY_BUTTON:
846 vApplyButtonAction();
847 bCloseWindow = TRUE;
848 break;
849 case CHOICES_BREAK_BUTTON:
850 vSetParagraphBreak(pMouse->window, DEFAULT_SCREEN_WIDTH);
851 break;
852 case CHOICES_BREAK_UP_BUTTON:
853 vChangeParagraphBreak(pMouse->window, 1);
854 break;
855 case CHOICES_BREAK_DOWN_BUTTON:
856 vChangeParagraphBreak(pMouse->window, -1);
857 break;
858 case CHOICES_NO_BREAK_BUTTON:
859 vSetParagraphBreak(pMouse->window, 0);
860 break;
861 case CHOICES_AUTOFILETYPE_BUTTON:
862 vChangeAutofiletype(pMouse->window);
863 break;
864 case CHOICES_HIDDEN_TEXT_BUTTON:
865 vChangeHiddenText(pMouse->window);
866 break;
867 case CHOICES_WITH_IMAGES_BUTTON:
868 vUseFontsImages(TRUE, TRUE);
869 break;
870 case CHOICES_NO_IMAGES_BUTTON:
871 vUseFontsImages(TRUE, FALSE);
872 break;
873 case CHOICES_TEXTONLY_BUTTON:
874 vUseFontsImages(FALSE, FALSE);
875 break;
876 case CHOICES_SCALE_UP_BUTTON:
877 vChangeScaleFactor(pMouse->window, 5);
878 break;
879 case CHOICES_SCALE_DOWN_BUTTON:
880 vChangeScaleFactor(pMouse->window, -5);
881 break;
882 default:
883 DBG_DEC(pMouse->icon);
884 break;
886 if (bCloseWindow) {
887 Error_CheckFatal(Wimp_CloseWindow(pMouse->window));
889 return TRUE;
890 } /* end of bChoicesMouseClick */
893 * bChoicesKeyPressed - handle a key in the Choices window
895 BOOL
896 bChoicesKeyPressed(event_pollblock *pEvent, void *pvReference)
898 icon_block tIcon;
899 caret_block *pCaret;
900 char *pcChar;
901 int iNumber;
903 DBG_MSG("bChoicesKeyPressed");
905 fail(pEvent == NULL);
906 fail(pEvent->type != event_KEY);
908 if (pEvent->data.key.code != '\r') {
909 Error_CheckFatal(Wimp_ProcessKey(pEvent->data.key.code));
910 return TRUE;
913 pCaret = &pEvent->data.key.caret;
915 Error_CheckFatal(Wimp_GetIconState(pCaret->window, pCaret->icon, &tIcon));
916 if (!tIcon.flags.data.text || !tIcon.flags.data.indirected) {
917 werr(1, "Icon %d must be indirected text", (int)pCaret->icon);
919 iNumber = (int)strtol(tIcon.data.indirecttext.buffer, &pcChar, 10);
921 switch(pCaret->icon) {
922 case CHOICES_BREAK_WRITEABLE:
923 if (*pcChar != '\0' && *pcChar != '\r') {
924 DBG_DEC(*pcChar);
925 iNumber = DEFAULT_SCREEN_WIDTH;
926 } else if (iNumber < MIN_SCREEN_WIDTH) {
927 iNumber = MIN_SCREEN_WIDTH;
928 } else if (iNumber > MAX_SCREEN_WIDTH) {
929 iNumber = MAX_SCREEN_WIDTH;
931 vSetParagraphBreak(pCaret->window, iNumber);
932 break;
933 case CHOICES_SCALE_WRITEABLE:
934 if (*pcChar != '\0' && *pcChar != '\r') {
935 DBG_DEC(*pcChar);
936 iNumber = DEFAULT_SCALE_FACTOR;
937 } else if (iNumber < MIN_SCALE_FACTOR) {
938 iNumber = MIN_SCALE_FACTOR;
939 } else if (iNumber > MAX_SCALE_FACTOR) {
940 iNumber = MAX_SCALE_FACTOR;
942 vSetScaleFactor(pCaret->window, iNumber);
943 break;
944 default:
945 DBG_DEC(pCaret->icon);
946 break;
948 return TRUE;
949 } /* end of bChoicesKeyPressed */
950 #endif /* __riscos */