Added preference to disable changing the selection to match Undo.
[nedit.git] / source / preferences.c
blob122f907faafe4b11afb683b998eaf40423056f4e
1 static const char CVSID[] = "$Id: preferences.c,v 1.63 2002/08/10 23:52:55 tringali Exp $";
2 /*******************************************************************************
3 * *
4 * preferences.c -- Nirvana Editor preferences processing *
5 * *
6 * Copyright (C) 1999 Mark Edel *
7 * *
8 * This is free software; you can redistribute it and/or modify it under the *
9 * terms of the GNU General Public License as published by the Free Software *
10 * Foundation; either version 2 of the License, or (at your option) any later *
11 * version. *
12 * *
13 * This software is distributed in the hope that it will be useful, but WITHOUT *
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
16 * for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License along with *
19 * software; if not, write to the Free Software Foundation, Inc., 59 Temple *
20 * Place, Suite 330, Boston, MA 02111-1307 USA *
21 * *
22 * Nirvana Text Editor *
23 * April 20, 1993 *
24 * *
25 * Written by Mark Edel *
26 * *
27 *******************************************************************************/
29 #ifdef HAVE_CONFIG_H
30 #include "../config.h"
31 #endif
33 #include "preferences.h"
34 #include "textBuf.h"
35 #include "nedit.h"
36 #include "text.h"
37 #include "search.h"
38 #include "window.h"
39 #include "userCmds.h"
40 #include "highlight.h"
41 #include "highlightData.h"
42 #include "help.h"
43 #include "regularExp.h"
44 #include "smartIndent.h"
45 #include "windowTitle.h"
46 #include "tags.h"
47 #include "../util/prefFile.h"
48 #include "../util/misc.h"
49 #include "../util/DialogF.h"
50 #include "../util/managedList.h"
51 #include "../util/fontsel.h"
52 #include "../util/utils.h"
54 #include <stdlib.h>
55 #include <string.h>
56 #include <stdio.h>
57 #include <ctype.h>
58 #ifdef VMS
59 #include "../util/VMSparam.h"
60 #else
61 #ifndef __MVS__
62 #include <sys/param.h>
63 #endif
64 #include "../util/clearcase.h"
65 #endif /*VMS*/
67 #include <Xm/Xm.h>
68 #include <Xm/SelectioB.h>
69 #include <Xm/Form.h>
70 #include <Xm/List.h>
71 #include <Xm/SeparatoG.h>
72 #include <Xm/LabelG.h>
73 #include <Xm/PushBG.h>
74 #include <Xm/PushB.h>
75 #include <Xm/ToggleBG.h>
76 #include <Xm/ToggleB.h>
77 #include <Xm/RowColumn.h>
78 #include <Xm/CascadeBG.h>
79 #include <Xm/Frame.h>
80 #include <Xm/Text.h>
82 #ifdef HAVE_DEBUG_H
83 #include "../debug.h"
84 #endif
86 #define PREF_FILE_VERSION "5.4"
87 /* Undefine PREF_FILE_ALPHA to activate release code.
88 Bump alpha version each time a preferences file upgrade is required.
90 alpha 1: calltips patch
92 #define PREF_FILE_ALPHA 1
94 /* New styles added in 5.2 for auto-upgrade */
95 #define ADD_5_2_STYLES " Pointer:#660000:Bold\nRegex:#009944:Bold\nWarning:brown2:Italic"
97 /* maximum number of word delimiters allowed (256 allows whole character set) */
98 #define MAX_WORD_DELIMITERS 256
100 /* maximum number of file extensions allowed in a language mode */
101 #define MAX_FILE_EXTENSIONS 20
103 /* Return values for checkFontStatus */
104 enum fontStatus {GOOD_FONT, BAD_PRIMARY, BAD_FONT, BAD_SIZE, BAD_SPACING};
106 /* enumerated type preference strings
107 ** The order of the elements in this array must be exactly the same
108 ** as the order of the corresponding integers of the enum SearchType
109 ** defined in search.h (!!)
111 static char *SearchMethodStrings[] = {
112 "Literal", "CaseSense", "RegExp",
113 "LiteralWord", "CaseSenseWord", "RegExpNoCase",
114 NULL
117 #ifdef REPLACE_SCOPE
118 /* enumerated default scope for replace dialog if a selection exists when
119 ** the dialog is popped up.
121 static char *ReplaceDefScopeStrings[] = {
122 "Window", "Selection", "Smart", NULL
124 #endif
126 #define N_WRAP_STYLES 3
127 static char *AutoWrapTypes[N_WRAP_STYLES+3] = {"None", "Newline", "Continuous",
128 "True", "False", NULL};
129 #define N_INDENT_STYLES 3
130 static char *AutoIndentTypes[N_INDENT_STYLES+3] = {"None", "Auto",
131 "Smart", "True", "False", NULL};
132 #define N_VIRTKEY_OVERRIDE_MODES 3
133 static char *VirtKeyOverrideModes[N_VIRTKEY_OVERRIDE_MODES+1] = { "Never",
134 "Auto", "Always", NULL};
136 #define N_SHOW_MATCHING_STYLES 3
137 /* For backward compatibility, "False" and "True" are still accepted.
138 They are internally converted to "Off" and "Delimiter" respectively.
139 NOTE: N_SHOW_MATCHING_STYLES must correspond to the number of
140 _real_ matching styles, not counting False & True.
141 False and True should also be the last ones in the list. */
142 static char *ShowMatchingTypes[] = {"Off", "Delimiter", "Range",
143 "False", "True", NULL};
145 /* suplement wrap and indent styles w/ a value meaning "use default" for
146 the override fields in the language modes dialog */
147 #define DEFAULT_WRAP -1
148 #define DEFAULT_INDENT -1
149 #define DEFAULT_TAB_DIST -1
150 #define DEFAULT_EM_TAB_DIST -1
152 /* list of available language modes and language specific preferences */
153 static int NLanguageModes = 0;
154 typedef struct {
155 char *name;
156 int nExtensions;
157 char **extensions;
158 char *recognitionExpr;
159 char *defTipsFile;
160 char *delimiters;
161 int wrapStyle;
162 int indentStyle;
163 int tabDist;
164 int emTabDist;
165 } languageModeRec;
166 static languageModeRec *LanguageModes[MAX_LANGUAGE_MODES];
168 /* Language mode dialog information */
169 static struct {
170 Widget shell;
171 Widget nameW;
172 Widget extW;
173 Widget recogW;
174 Widget defTipsW;
175 Widget delimitW;
176 Widget managedListW;
177 Widget tabW;
178 Widget emTabW;
179 Widget defaultIndentW;
180 Widget noIndentW;
181 Widget autoIndentW;
182 Widget smartIndentW;
183 Widget defaultWrapW;
184 Widget noWrapW;
185 Widget newlineWrapW;
186 Widget contWrapW;
187 languageModeRec **languageModeList;
188 int nLanguageModes;
189 } LMDialog = {NULL};
191 /* Font dialog information */
192 typedef struct {
193 Widget shell;
194 Widget primaryW;
195 Widget fillW;
196 Widget italicW;
197 Widget italicErrW;
198 Widget boldW;
199 Widget boldErrW;
200 Widget boldItalicW;
201 Widget boldItalicErrW;
202 WindowInfo *window;
203 int forWindow;
204 } fontDialog;
206 /* Repository for simple preferences settings */
207 static struct prefData {
208 int wrapStyle; /* what kind of wrapping to do */
209 int wrapMargin; /* 0=wrap at window width, other=wrap margin */
210 int autoIndent; /* style for auto-indent */
211 int autoSave; /* whether automatic backup feature is on */
212 int saveOldVersion; /* whether to preserve a copy of last version */
213 int searchDlogs; /* whether to show explanatory search dialogs */
214 int searchWrapBeep; /* 1=beep when search restarts at begin/end */
215 int keepSearchDlogs; /* whether to retain find and replace dialogs */
216 int searchWraps; /* whether to attempt search again if reach bof or eof */
217 int statsLine; /* whether to show the statistics line */
218 int iSearchLine; /* whether to show the incremental search line*/
219 int lineNums; /* whether to show line numbers */
220 int pathInWindowsMenu; /* whether to show path in windows menu */
221 int warnFileMods; /* " warn user if files externally modified */
222 int warnExit; /* whether to warn on exit */
223 int searchMethod; /* initial search method as a text string */
224 #ifdef REPLACE_SCOPE
225 int replaceDefScope; /* default replace scope if selection exists */
226 #endif
227 int textRows; /* initial window height in characters */
228 int textCols; /* initial window width in characters */
229 int tabDist; /* number of characters between tab stops */
230 int emTabDist; /* non-zero tab dist. if emulated tabs are on */
231 int insertTabs; /* whether to use tabs for padding */
232 int showMatchingStyle; /* how to flash matching parenthesis */
233 int matchSyntaxBased; /* use syntax info to match parenthesis */
234 int highlightSyntax; /* whether to highlight syntax by default */
235 int smartTags; /* look for tag in current window first */
236 int alwaysCheckRelativeTagsSpecs; /* for every new opened file of session */
237 int stickyCaseSenseBtn; /* whether Case Word Btn is sticky to Regex Btn */
238 int prefFileRead; /* detects whether a .nedit existed */
239 #ifdef SGI_CUSTOM
240 int shortMenus; /* short menu mode */
241 #endif
242 char fontString[MAX_FONT_LEN]; /* names of fonts for text widget */
243 char boldFontString[MAX_FONT_LEN];
244 char italicFontString[MAX_FONT_LEN];
245 char boldItalicFontString[MAX_FONT_LEN];
246 XmFontList fontList; /* XmFontLists corresp. to above named fonts */
247 XFontStruct *boldFontStruct;
248 XFontStruct *italicFontStruct;
249 XFontStruct *boldItalicFontStruct;
250 int repositionDialogs; /* w. to reposition dialogs under the pointer */
251 int sortOpenPrevMenu; /* whether to sort the "Open Previous" menu */
252 int appendLF; /* Whether to append LF at the end of each file */
253 int mapDelete; /* whether to map delete to backspace */
254 int stdOpenDialog; /* w. to retain redundant text field in Open */
255 char tagFile[MAXPATHLEN]; /* name of tags file to look for at startup */
256 int maxPrevOpenFiles; /* limit to size of Open Previous menu */
257 int typingHidesPointer; /* hide mouse pointer when typing */
258 char delimiters[MAX_WORD_DELIMITERS]; /* punctuation characters */
259 char shell[MAXPATHLEN]; /* shell to use for executing commands */
260 char geometry[MAX_GEOM_STRING_LEN]; /* per-application geometry string,
261 only for the clueless */
262 char serverName[MAXPATHLEN];/* server name for multiple servers per disp. */
263 char bgMenuBtn[MAX_ACCEL_LEN]; /* X event description for triggering
264 posting of background menu */
265 char fileVersion[6]; /* Version of nedit which wrote the .nedit
266 file we're reading */
267 int findReplaceUsesSelection; /* whether the find replace dialog is automatically
268 loaded with the primary selection */
269 int virtKeyOverride; /* Override Motif default virtual key bindings
270 never, if invalid, or always */
271 char titleFormat[MAX_TITLE_FORMAT_LEN];
272 char helpFontNames[NUM_HELP_FONTS][MAX_FONT_LEN];/* fonts for help system */
273 char helpLinkColor[30]; /* Color for hyperlinks in the help system */
274 int undoModifiesSelection;
275 } PrefData;
277 /* Temporary storage for preferences strings which are discarded after being
278 read */
279 static struct {
280 char *shellCmds;
281 char *macroCmds;
282 char *bgMenuCmds;
283 char *highlight;
284 char *language;
285 char *styles;
286 char *smartIndent;
287 char *smartIndentCommon;
288 } TempStringPrefs;
290 /* preference descriptions for SavePreferences and RestorePreferences. */
291 static PrefDescripRec PrefDescrip[] = {
292 {"fileVersion", "FileVersion" , PREF_STRING, "", PrefData.fileVersion,
293 (void *)sizeof(PrefData.fileVersion), True},
294 #ifndef VMS
295 #ifdef linux
296 {"shellCommands", "ShellCommands", PREF_ALLOC_STRING, "spell:Alt+B:s:EX:\n\
297 cat>spellTmp; xterm -e ispell -x spellTmp; cat spellTmp; rm spellTmp\n\
298 wc::w:ED:\nset wc=`wc`; echo $wc[1] \"lines,\" $wc[2] \"words,\" $wc[3] \"characters\"\n\
299 sort::o:EX:\nsort\nnumber lines::n:AW:\nnl -ba\nmake:Alt+Z:m:W:\nmake\n\
300 expand::p:EX:\nexpand\nunexpand::u:EX:\nunexpand\n",
301 &TempStringPrefs.shellCmds, NULL, True},
302 #elif __FreeBSD__
303 {"shellCommands", "ShellCommands", PREF_ALLOC_STRING, "spell:Alt+B:s:EX:\n\
304 cat>spellTmp; xterm -e ispell -x spellTmp; cat spellTmp; rm spellTmp\n\
305 wc::w:ED:\nset wc=`wc`; echo $wc[1] \"words,\" $wc[2] \"lines,\" $wc[3] \"characters\"\n\
306 sort::o:EX:\nsort\nnumber lines::n:AW:\npr -tn\nmake:Alt+Z:m:W:\nmake\n\
307 expand::p:EX:\nexpand\nunexpand::u:EX:\nunexpand\n",
308 &TempStringPrefs.shellCmds, NULL, True},
309 #else
310 {"shellCommands", "ShellCommands", PREF_ALLOC_STRING, "spell:Alt+B:s:ED:\n\
311 (cat;echo \"\") | spell\nwc::w:ED:\nset wc=`wc`; echo $wc[1] \"lines,\" $wc[2] \"words,\" $wc[3] \"characters\"\n\
312 \nsort::o:EX:\nsort\nnumber lines::n:AW:\nnl -ba\nmake:Alt+Z:m:W:\nmake\n\
313 expand::p:EX:\nexpand\nunexpand::u:EX:\nunexpand\n",
314 &TempStringPrefs.shellCmds, NULL, True},
315 #endif /* linux, __FreeBSD__ */
316 #endif /* VMS */
317 {"macroCommands", "MacroCommands", PREF_ALLOC_STRING,
318 "Complete Word:Alt+D::: {\n\
319 # Tuning parameters\n\
320 ScanDistance = 200\n\
322 # Search back to a word boundary to find the word to complete\n\
323 startScan = max(0, $cursor - ScanDistance)\n\
324 endScan = min($text_length, $cursor + ScanDistance)\n\
325 scanString = get_range(startScan, endScan)\n\
326 keyEnd = $cursor-startScan\n\
327 keyStart = search_string(scanString, \"<\", keyEnd, \"backward\", \"regex\")\n\
328 if (keyStart == -1)\n\
329 return\n\
330 keyString = \"<\" substring(scanString, keyStart, keyEnd)\n\
332 # search both forward and backward from the cursor position. Note that\n\
333 # using a regex search can lead to incorrect results if any of the special\n\
334 # regex characters is encountered, which is not considered a delimiter\n\
335 backwardSearchResult = search_string(scanString, keyString, keyStart-1, \\\n\
336 \"backward\", \"regex\")\n\
337 forwardSearchResult = search_string(scanString, keyString, keyEnd, \"regex\")\n\
338 if (backwardSearchResult == -1 && forwardSearchResult == -1) {\n\
339 beep()\n\
340 return\n\
341 }\n\
343 # if only one direction matched, use that, otherwise use the nearest\n\
344 if (backwardSearchResult == -1)\n\
345 matchStart = forwardSearchResult\n\
346 else if (forwardSearchResult == -1)\n\
347 matchStart = backwardSearchResult\n\
348 else {\n\
349 if (keyStart - backwardSearchResult <= forwardSearchResult - keyEnd)\n\
350 matchStart = backwardSearchResult\n\
351 else\n\
352 matchStart = forwardSearchResult\n\
353 }\n\
355 # find the complete word\n\
356 matchEnd = search_string(scanString, \">\", matchStart, \"regex\")\n\
357 completedWord = substring(scanString, matchStart, matchEnd)\n\
359 # replace it in the window\n\
360 replace_range(startScan + keyStart, $cursor, completedWord)\n\
361 }\n\
362 Fill Sel. w/Char:::R: {\n\
363 if ($selection_start == -1) {\n\
364 beep()\n\
365 return\n\
366 }\n\
368 # Ask the user what character to fill with\n\
369 fillChar = string_dialog(\"Fill selection with what character?\", \"OK\", \"Cancel\")\n\
370 if ($string_dialog_button == 2 || $string_dialog_button == 0)\n\
371 return\n\
373 # Count the number of lines in the selection\n\
374 nLines = 0\n\
375 for (i=$selection_start; i<$selection_end; i++)\n\
376 if (get_character(i) == \"\\n\")\n\
377 nLines++\n\
379 # Create the fill text\n\
380 rectangular = $selection_left != -1\n\
381 line = \"\"\n\
382 fillText = \"\"\n\
383 if (rectangular) {\n\
384 for (i=0; i<$selection_right-$selection_left; i++)\n\
385 line = line fillChar\n\
386 for (i=0; i<nLines; i++)\n\
387 fillText = fillText line \"\\n\"\n\
388 fillText = fillText line\n\
389 } else {\n\
390 if (nLines == 0) {\n\
391 for (i=$selection_start; i<$selection_end; i++)\n\
392 fillText = fillText fillChar\n\
393 } else {\n\
394 startIndent = 0\n\
395 for (i=$selection_start-1; i>=0 && get_character(i)!=\"\\n\"; i--)\n\
396 startIndent++\n\
397 for (i=0; i<$wrap_margin-startIndent; i++)\n\
398 fillText = fillText fillChar\n\
399 fillText = fillText \"\\n\"\n\
400 for (i=0; i<$wrap_margin; i++)\n\
401 line = line fillChar\n\
402 for (i=0; i<nLines-1; i++)\n\
403 fillText = fillText line \"\\n\"\n\
404 for (i=$selection_end-1; i>=$selection_start && get_character(i)!=\"\\n\"; \\\n\
405 i--)\n\
406 fillText = fillText fillChar\n\
407 }\n\
408 }\n\
410 # Replace the selection with the fill text\n\
411 replace_selection(fillText)\n\
412 }\n\
413 Quote Mail Reply:::: {\n\
414 if ($selection_start == -1)\n\
415 replace_all(\"^.*$\", \"\\\\> &\", \"regex\")\n\
416 else\n\
417 replace_in_selection(\"^.*$\", \"\\\\> &\", \"regex\")\n\
418 }\n\
419 Unquote Mail Reply:::: {\n\
420 if ($selection_start == -1)\n\
421 replace_all(\"(^\\\\> )(.*)$\", \"\\\\2\", \"regex\")\n\
422 else\n\
423 replace_in_selection(\"(^\\\\> )(.*)$\", \"\\\\2\", \"regex\")\n\
424 }\n\
425 Comments>/* Comment */@C@C++@Java@CSS@JavaScript@Lex:::R: {\n\
426 selStart = $selection_start\n\
427 selEnd = $selection_end\n\
428 replace_range(selStart, selEnd, \"/* \" get_selection() \" */\")\n\
429 select(selStart, selEnd + 6)\n\
430 }\n\
431 Comments>/* Uncomment */@C@C++@Java@CSS@JavaScript@Lex:::R: {\n\
432 sel = get_selection()\n\
433 selStart = $selection_start\n\
434 selEnd = $selection_end\n\
435 commentStart = search_string(sel, \"/*\", 0)\n\
436 if (substring(sel, commentStart + 2, commentStart + 3) == \" \")\n\
437 keepStart = commentStart + 3\n\
438 else\n\
439 keepStart = commentStart + 2\n\
440 keepEnd = search_string(sel, \"*/\", length(sel), \"backward\")\n\
441 commentEnd = keepEnd + 2\n\
442 if (substring(sel, keepEnd - 1, keepEnd == \" \"))\n\
443 keepEnd = keepEnd - 1\n\
444 replace_range(selStart + commentStart, selStart + commentEnd, \\\n\
445 substring(sel, keepStart, keepEnd))\n\
446 select(selStart, selEnd - (keepStart-commentStart) - \\\n\
447 (commentEnd - keepEnd))\n\
448 }\n\
449 Comments>// Comment@C@C++@Java@JavaScript:::R: {\n\
450 replace_in_selection(\"^.*$\", \"// &\", \"regex\")\n\
451 }\n\
452 Comments>// Uncomment@C@C++@Java@JavaScript:::R: {\n\
453 replace_in_selection(\"(^[ \\\\t]*// ?)(.*)$\", \"\\\\2\", \"regex\")\n\
454 }\n\
455 Comments># Comment@Perl@Sh Ksh Bash@NEdit Macro@Makefile@Awk@Csh@Python@Tcl:::R: {\n\
456 replace_in_selection(\"^.*$\", \"#&\", \"regex\")\n\
457 }\n\
458 Comments># Uncomment@Perl@Sh Ksh Bash@NEdit Macro@Makefile@Awk@Csh@Python@Tcl:::R: {\n\
459 replace_in_selection(\"(^[ \\\\t]*#)(.*)$\", \"\\\\2\", \"regex\")\n\
460 }\n\
461 Comments>-- Comment@SQL:::R: {\n\
462 replace_in_selection(\"^.*$\", \"--&\", \"regex\")\n\
463 }\n\
464 Comments>-- Uncomment@SQL:::R: {\n\
465 replace_in_selection(\"(^[ \\\\t]*--)(.*)$\", \"\\\\2\", \"regex\")\n\
466 }\n\
467 Comments>! Comment@X Resources:::R: {\n\
468 replace_in_selection(\"^.*$\", \"!&\", \"regex\")\n\
469 }\n\
470 Comments>! Uncomment@X Resources:::R: {\n\
471 replace_in_selection(\"(^[ \\\\t]*!)(.*)$\", \"\\\\2\", \"regex\")\n\
472 }\n\
473 Comments>Bar Comment@C:::R: {\n\
474 if ($selection_left != -1) {\n\
475 dialog(\"Selection must not be rectangular\")\n\
476 return\n\
477 }\n\
478 start = $selection_start\n\
479 end = $selection_end-1\n\
480 origText = get_range($selection_start, $selection_end-1)\n\
481 newText = \"/*\\n\" replace_in_string(get_range(start, end), \\\n\
482 \"^\", \" * \", \"regex\") \"\\n */\\n\"\n\
483 replace_selection(newText)\n\
484 select(start, start + length(newText))\n\
485 }\n\
486 Comments>Bar Uncomment@C:::R: {\n\
487 selStart = $selection_start\n\
488 selEnd = $selection_end\n\
489 newText = get_range(selStart+3, selEnd-4)\n\
490 newText = replace_in_string(newText, \"^ \\\\* \", \"\", \"regex\")\n\
491 replace_range(selStart, selEnd, newText)\n\
492 select(selStart, selStart + length(newText))\n\
493 }\n\
494 Make C Prototypes@C@C++:::: {\n\
495 if ($selection_start == -1) {\n\
496 start = 0\n\
497 end = $text_length\n\
498 } else {\n\
499 start = $selection_start\n\
500 end = $selection_end\n\
501 }\n\
502 string = get_range(start, end)\n\
503 nDefs = 0\n\
504 searchPos = 0\n\
505 prototypes = \"\"\n\
506 staticPrototypes = \"\"\n\
507 for (;;) {\n\
508 headerStart = search_string(string, \\\n\
509 \"^[a-zA-Z]([^;#\\\"'{}=><!/]|\\n)*\\\\)[ \\t]*\\n?[ \\t]*\\\\{\", \\\n\
510 searchPos, \"regex\")\n\
511 if (headerStart == -1)\n\
512 break\n\
513 headerEnd = search_string(string, \")\", $search_end,\"backward\") + 1\n\
514 prototype = substring(string, headerStart, headerEnd) \";\\n\"\n\
515 if (substring(string, headerStart, headerStart+6) == \"static\")\n\
516 staticPrototypes = staticPrototypes prototype\n\
517 else\n\
518 prototypes = prototypes prototype\n\
519 searchPos = headerEnd\n\
520 nDefs++\n\
521 }\n\
522 if (nDefs == 0) {\n\
523 dialog(\"No function declarations found\")\n\
524 return\n\
525 }\n\
526 new()\n\
527 focus_window(\"last\")\n\
528 replace_range(0, 0, prototypes staticPrototypes)\n\
529 }", &TempStringPrefs.macroCmds, NULL, True},
530 {"bgMenuCommands", "BGMenuCommands", PREF_ALLOC_STRING,
531 "Undo:::: {\nundo()\n}\n\
532 Redo:::: {\nredo()\n}\n\
533 Cut:::R: {\ncut_clipboard()\n}\n\
534 Copy:::R: {\ncopy_clipboard()\n}\n\
535 Paste:::: {\npaste_clipboard()\n}", &TempStringPrefs.bgMenuCmds,
536 NULL, True},
537 #ifdef VMS
538 /* The VAX compiler can't compile Java-Script's definition in highlightData.c */
539 {"highlightPatterns", "HighlightPatterns", PREF_ALLOC_STRING,
540 "Ada:Default\n\
541 Awk:Default\n\
542 C++:Default\n\
543 C:Default\n\
544 CSS:Default\n\
545 Csh:Default\n\
546 Fortran:Default\n\
547 Java:Default\n\
548 LaTeX:Default\n\
549 Lex:Default\n\
550 Makefile:Default\n\
551 Matlab:Default\n\
552 NEdit Macro:Default\n\
553 Pascal:Default\n\
554 Perl:Default\n\
555 PostScript:Default\n\
556 Python:Default\n\
557 Regex:Default\n\
558 SGML HTML:Default\n\
559 SQL:Default\n\
560 Sh Ksh Bash:Default\n\
561 Tcl:Default\n\
562 VHDL:Default\n\
563 Verilog:Default\n\
564 XML:Default\n\
565 X Resources:Default\n\
566 Yacc:Default",
567 &TempStringPrefs.highlight, NULL, True},
568 {"languageModes", "LanguageModes", PREF_ALLOC_STRING,
569 #else
570 {"highlightPatterns", "HighlightPatterns", PREF_ALLOC_STRING,
571 "Ada:Default\n\
572 Awk:Default\n\
573 C++:Default\n\
574 C:Default\n\
575 CSS:Default\n\
576 Csh:Default\n\
577 Fortran:Default\n\
578 Java:Default\n\
579 JavaScript:Default\n\
580 LaTeX:Default\n\
581 Lex:Default\n\
582 Makefile:Default\n\
583 Matlab:Default\n\
584 NEdit Macro:Default\n\
585 Pascal:Default\n\
586 Perl:Default\n\
587 PostScript:Default\n\
588 Python:Default\n\
589 Regex:Default\n\
590 SGML HTML:Default\n\
591 SQL:Default\n\
592 Sh Ksh Bash:Default\n\
593 Tcl:Default\n\
594 VHDL:Default\n\
595 Verilog:Default\n\
596 XML:Default\n\
597 X Resources:Default\n\
598 Yacc:Default",
599 &TempStringPrefs.highlight, NULL, True},
600 {"languageModes", "LanguageModes", PREF_ALLOC_STRING,
601 #endif /*VMS*/
602 #ifdef VMS
603 "Ada:.ADA .AD .ADS .ADB .A:::::::\n\
604 Awk:.AWK:::::::\n\
605 C++:.CC .HH .C .H .I .CXX .HXX .CPP::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":\n\
606 C:.C .H::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":\n\
607 CSS:CSS::Auto:None:::\".,/\\`'!|@#%^&*()=+{}[]\"\":;<>?~\":\n\
608 Csh:.csh .cshrc .login .logout:\"^[ \\t]*#[ \\t]*![ \\t]*/bin/csh\"::::::\n\
609 Fortran:.F .F77 .FOR:::::::\n\
610 Java:.JAVA:::::::\n\
611 LaTeX:.TEX .STY .CLS .DTX .INS:::::::\n\
612 Lex:.lex:::::::\n\
613 Makefile:MAKEFILE:::None:8:8::\n\
614 Matlab:.m .oct .sci:::::::\n\
615 NEdit Macro:.NM .NEDITMACRO:::::::\n\
616 Pascal:.PAS .P .INT:::::::\n\
617 Perl:.PL .PM .P5:\"^[ \\t]*#[ \\t]*!.*perl\":Auto:None:::\".,/\\\\`'!$@#%^&*()-=+{}[]\"\":;<>?~|\":\n\
618 PostScript:.ps .PS .eps .EPS .epsf .epsi:\"^%!\":::::\"/%(){}[]<>\":\n\
619 Python:.PY:\"^#!.*python\":Auto:None::::\n\
620 Regex:.reg .regex:\"\\(\\?[:#=!iInN].+\\)\":None:Continuous::::\n\
621 SGML HTML:.sgml .sgm .html .htm:\"\\<[Hh][Tt][Mm][Ll]\\>\"::::::\n\
622 SQL:.sql:::::::\n\
623 Sh Ksh Bash:.sh .bash .ksh .profile .bashrc .bash_logout .bash_login .bash_profile:\"^[ \\t]*#[ \\t]*![ \\t]*/.*bin/(sh|ksh|bash)\"::::::\n\
624 Tcl:.TCL::Smart:None::::\n\
625 VHDL:.VHD .VHDL .VDL:::::::\n\
626 Verilog:.V:::::::\n\
627 XML:.xml .xsl .dtd:\"\\<(?i\\?xml|!doctype)\"::None:::\"<>/=\"\"'()+*?|\":\n\
628 X Resources:.XRESOURCES .XDEFAULTS .NEDIT:\"^[!#].*([Aa]pp|[Xx]).*[Dd]efaults\"::::::\n\
629 Yacc:.Y::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":",
630 #else
631 "Ada:.ada .ad .ads .adb .a:::::::\n\
632 Awk:.awk:::::::\n\
633 C++:.cc .hh .C .H .i .cxx .hxx .cpp::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":\n\
634 C:.c .h::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":\n\
635 CSS:css::Auto:None:::\".,/\\`'!|@#%^&*()=+{}[]\"\":;<>?~\":\n\
636 Csh:.csh .cshrc .login .logout:\"^[ \\t]*#[ \\t]*![ \\t]*/bin/csh\"::::::\n\
637 Fortran:.f .f77 .for:::::::\n\
638 Java:.java:::::::\n\
639 JavaScript:.js:::::::\n\
640 LaTeX:.tex .sty .cls .dtx .ins:::::::\n\
641 Lex:.lex:::::::\n\
642 Makefile:Makefile makefile .gmk:::None:8:8::\n\
643 Matlab:.m .oct .sci:::::::\n\
644 NEdit Macro:.nm .neditmacro:::::::\n\
645 Pascal:.pas .p .int:::::::\n\
646 Perl:.pl .pm .p5 .PL:\"^[ \\t]*#[ \\t]*!.*perl\":Auto:None:::\".,/\\\\`'!$@#%^&*()-=+{}[]\"\":;<>?~|\":\n\
647 PostScript:.ps .eps .epsf .epsi:\"^%!\":::::\"/%(){}[]<>\":\n\
648 Python:.py:\"^#!.*python\":Auto:None::::\n\
649 Regex:.reg .regex:\"\\(\\?[:#=!iInN].+\\)\":None:Continuous::::\n\
650 SGML HTML:.sgml .sgm .html .htm:\"\\<[Hh][Tt][Mm][Ll]\\>\"::::::\n\
651 SQL:.sql:::::::\n\
652 Sh Ksh Bash:.sh .bash .ksh .profile .bashrc .bash_logout .bash_login .bash_profile:\"^[ \\t]*#[ \\t]*![ \\t]*/.*bin/(sh|ksh|bash)\"::::::\n\
653 Tcl:.tcl .tk .itcl .itk::Smart:None::::\n\
654 VHDL:.vhd .vhdl .vdl:::::::\n\
655 Verilog:.v:::::::\n\
656 XML:.xml .xsl .dtd:\"\\<(?i\\?xml|!doctype)\"::None:::\"<>/=\"\"'()+*?|\":\n\
657 X Resources:.Xresources .Xdefaults .nedit:\"^[!#].*([Aa]pp|[Xx]).*[Dd]efaults\"::::::\n\
658 Yacc:.y::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":",
659 #endif
660 &TempStringPrefs.language, NULL, True},
661 {"styles", "Styles", PREF_ALLOC_STRING, "Plain:black:Plain\n\
662 Comment:gray20:Italic\n\
663 Keyword:black:Bold\n\
664 Storage Type:brown:Bold\n\
665 Storage Type1:saddle brown:Bold\n\
666 String:darkGreen:Plain\n\
667 String1:SeaGreen:Plain\n\
668 String2:darkGreen:Bold\n\
669 Preprocessor:RoyalBlue4:Plain\n\
670 Preprocessor1:blue:Plain\n\
671 Character Const:darkGreen:Plain\n\
672 Numeric Const:darkGreen:Plain\n\
673 Identifier:brown:Plain\n\
674 Identifier1:RoyalBlue4:Plain\n\
675 Subroutine:brown:Plain\n\
676 Subroutine1:chocolate:Plain\n\
677 Ada Attributes:plum:Bold\n\
678 Label:red:Italic\n\
679 Flag:red:Bold\n\
680 Text Comment:SteelBlue4:Italic\n\
681 Text Key:VioletRed4:Bold\n\
682 Text Key1:VioletRed4:Plain\n\
683 Text Arg:RoyalBlue4:Bold\n\
684 Text Arg1:SteelBlue4:Bold\n\
685 Text Arg2:RoyalBlue4:Plain\n\
686 Text Escape:gray30:Bold\n\
687 LaTeX Math:darkGreen:Plain\n"
688 ADD_5_2_STYLES,
689 &TempStringPrefs.styles, NULL, True},
690 {"smartIndentInit", "SmartIndentInit", PREF_ALLOC_STRING,
691 "C:Default\n\
692 C++:Default\n\
693 Python:Default\n\
694 Matlab:Default", &TempStringPrefs.smartIndent, NULL, True},
695 {"smartIndentInitCommon", "SmartIndentInitCommon", PREF_ALLOC_STRING,
696 "Default", &TempStringPrefs.smartIndentCommon, NULL, True},
697 {"autoWrap", "AutoWrap", PREF_ENUM, "Newline",
698 &PrefData.wrapStyle, AutoWrapTypes, True},
699 {"wrapMargin", "WrapMargin", PREF_INT, "0",
700 &PrefData.wrapMargin, NULL, True},
701 {"autoIndent", "AutoIndent", PREF_ENUM, "Auto",
702 &PrefData.autoIndent, AutoIndentTypes, True},
703 {"autoSave", "AutoSave", PREF_BOOLEAN, "True",
704 &PrefData.autoSave, NULL, True},
705 {"saveOldVersion", "SaveOldVersion", PREF_BOOLEAN, "False",
706 &PrefData.saveOldVersion, NULL, True},
707 {"showMatching", "ShowMatching", PREF_ENUM, "Delimiter",
708 &PrefData.showMatchingStyle, ShowMatchingTypes, True},
709 {"matchSyntaxBased", "MatchSyntaxBased", PREF_BOOLEAN, "True",
710 &PrefData.matchSyntaxBased, NULL, True},
711 {"highlightSyntax", "HighlightSyntax", PREF_BOOLEAN, "True",
712 &PrefData.highlightSyntax, NULL, True},
713 {"searchDialogs", "SearchDialogs", PREF_BOOLEAN, "False",
714 &PrefData.searchDlogs, NULL, True},
715 {"beepOnSearchWrap", "BeepOnSearchWrap", PREF_BOOLEAN, "False",
716 &PrefData.searchWrapBeep, NULL, True},
717 {"retainSearchDialogs", "RetainSearchDialogs", PREF_BOOLEAN, "False",
718 &PrefData.keepSearchDlogs, NULL, True},
719 {"searchWraps", "SearchWraps", PREF_BOOLEAN, "True",
720 &PrefData.searchWraps, NULL, True},
721 {"stickyCaseSenseButton", "StickyCaseSenseButton", PREF_BOOLEAN, "True",
722 &PrefData.stickyCaseSenseBtn, NULL, True},
723 #if XmVersion < 1002 /* Flashing is annoying in 1.1 versions */
724 {"repositionDialogs", "RepositionDialogs", PREF_BOOLEAN, "False",
725 &PrefData.repositionDialogs, NULL, True},
726 #else
727 {"repositionDialogs", "RepositionDialogs", PREF_BOOLEAN, "True",
728 &PrefData.repositionDialogs, NULL, True},
729 #endif
730 {"appendLF", "AppendLF", PREF_BOOLEAN, "True",
731 &PrefData.appendLF, NULL, True},
732 {"sortOpenPrevMenu", "SortOpenPrevMenu", PREF_BOOLEAN, "True",
733 &PrefData.sortOpenPrevMenu, NULL, True},
734 {"statisticsLine", "StatisticsLine", PREF_BOOLEAN, "False",
735 &PrefData.statsLine, NULL, True},
736 {"iSearchLine", "ISearchLine", PREF_BOOLEAN, "False",
737 &PrefData.iSearchLine, NULL, True},
738 {"lineNumbers", "LineNumbers", PREF_BOOLEAN, "False",
739 &PrefData.lineNums, NULL, True},
740 {"pathInWindowsMenu", "PathInWindowsMenu", PREF_BOOLEAN, "True",
741 &PrefData.pathInWindowsMenu, NULL, True},
742 {"warnFileMods", "WarnFileMods", PREF_BOOLEAN, "True",
743 &PrefData.warnFileMods, NULL, True},
744 {"warnExit", "WarnExit", PREF_BOOLEAN, "True",
745 &PrefData.warnExit, NULL, True},
746 {"searchMethod", "SearchMethod", PREF_ENUM, "Literal",
747 &PrefData.searchMethod, SearchMethodStrings, True},
748 #ifdef REPLACE_SCOPE
749 {"replaceDefaultScope", "ReplaceDefaultAllScope", PREF_ENUM, "Smart",
750 &PrefData.replaceDefScope, ReplaceDefScopeStrings, True},
751 #endif
752 {"textRows", "TextRows", PREF_INT, "24",
753 &PrefData.textRows, NULL, True},
754 {"textCols", "TextCols", PREF_INT, "80",
755 &PrefData.textCols, NULL, True},
756 {"tabDistance", "TabDistance", PREF_INT, "8",
757 &PrefData.tabDist, NULL, True},
758 {"emulateTabs", "EmulateTabs", PREF_INT, "0",
759 &PrefData.emTabDist, NULL, True},
760 {"insertTabs", "InsertTabs", PREF_BOOLEAN, "True",
761 &PrefData.insertTabs, NULL, True},
762 {"textFont", "TextFont", PREF_STRING,
763 "-*-courier-medium-r-normal--*-120-*-*-*-iso8859-*",
764 PrefData.fontString, (void *)sizeof(PrefData.fontString), True},
765 {"boldHighlightFont", "BoldHighlightFont", PREF_STRING,
766 "-*-courier-bold-r-normal--*-120-*-*-*-iso8859-*",
767 PrefData.boldFontString, (void *)sizeof(PrefData.boldFontString), True},
768 {"italicHighlightFont", "ItalicHighlightFont", PREF_STRING,
769 "-*-courier-medium-o-normal--*-120-*-*-*-iso8859-*",
770 PrefData.italicFontString,
771 (void *)sizeof(PrefData.italicFontString), True},
772 {"boldItalicHighlightFont", "BoldItalicHighlightFont", PREF_STRING,
773 "-*-courier-bold-o-normal--*-120-*-*-*-iso8859-*",
774 PrefData.boldItalicFontString,
775 (void *)sizeof(PrefData.boldItalicFontString), True},
776 {"helpFont", "helpFont", PREF_STRING,
777 "-*-helvetica-medium-r-normal--*-120-*-*-*-iso8859-*",
778 PrefData.helpFontNames[HELP_FONT],
779 (void *)sizeof(PrefData.helpFontNames[HELP_FONT]), False},
780 {"boldHelpFont", "BoldHelpFont", PREF_STRING,
781 "-*-helvetica-bold-r-normal--*-120-*-*-*-iso8859-*",
782 PrefData.helpFontNames[BOLD_HELP_FONT],
783 (void *)sizeof(PrefData.helpFontNames[BOLD_HELP_FONT]), False},
784 {"italicHelpFont", "ItalicHelpFont", PREF_STRING,
785 "-*-helvetica-medium-o-normal--*-120-*-*-*-iso8859-*",
786 PrefData.helpFontNames[ITALIC_HELP_FONT],
787 (void *)sizeof(PrefData.helpFontNames[ITALIC_HELP_FONT]), False},
788 {"boldItalicHelpFont", "BoldItalicHelpFont", PREF_STRING,
789 "-*-helvetica-bold-o-normal--*-120-*-*-*-iso8859-*",
790 PrefData.helpFontNames[BOLD_ITALIC_HELP_FONT],
791 (void *)sizeof(PrefData.helpFontNames[BOLD_ITALIC_HELP_FONT]), False},
792 {"fixedHelpFont", "fixedHelpFont", PREF_STRING,
793 "-*-courier-medium-r-normal--*-120-*-*-*-iso8859-*",
794 PrefData.helpFontNames[FIXED_HELP_FONT],
795 (void *)sizeof(PrefData.helpFontNames[FIXED_HELP_FONT]), False},
796 {"boldFixedHelpFont", "BoldFixedHelpFont", PREF_STRING,
797 "-*-courier-bold-r-normal--*-120-*-*-*-iso8859-*",
798 PrefData.helpFontNames[BOLD_FIXED_HELP_FONT],
799 (void *)sizeof(PrefData.helpFontNames[BOLD_FIXED_HELP_FONT]), False},
800 {"italicFixedHelpFont", "ItalicFixedHelpFont", PREF_STRING,
801 "-*-courier-medium-o-normal--*-120-*-*-*-iso8859-*",
802 PrefData.helpFontNames[ITALIC_FIXED_HELP_FONT],
803 (void *)sizeof(PrefData.helpFontNames[ITALIC_FIXED_HELP_FONT]), False},
804 {"boldItalicFixedHelpFont", "BoldItalicFixedHelpFont", PREF_STRING,
805 "-*-courier-bold-o-normal--*-120-*-*-*-iso8859-*",
806 PrefData.helpFontNames[BOLD_ITALIC_FIXED_HELP_FONT],
807 (void *)sizeof(PrefData.helpFontNames[BOLD_ITALIC_FIXED_HELP_FONT]), False},
808 {"helpLinkFont", "helpLinkFont", PREF_STRING,
809 "-*-helvetica-medium-r-normal--*-120-*-*-*-iso8859-*",
810 PrefData.helpFontNames[HELP_LINK_FONT],
811 (void *)sizeof(PrefData.helpFontNames[HELP_LINK_FONT]), False},
812 {"h1HelpFont", "H1HelpFont", PREF_STRING,
813 "-*-helvetica-bold-r-normal--*-140-*-*-*-iso8859-*",
814 PrefData.helpFontNames[H1_HELP_FONT],
815 (void *)sizeof(PrefData.helpFontNames[H1_HELP_FONT]), False},
816 {"h2HelpFont", "H2HelpFont", PREF_STRING,
817 "-*-helvetica-bold-o-normal--*-120-*-*-*-iso8859-*",
818 PrefData.helpFontNames[H2_HELP_FONT],
819 (void *)sizeof(PrefData.helpFontNames[H2_HELP_FONT]), False},
820 {"h3HelpFont", "H3HelpFont", PREF_STRING,
821 "-*-courier-bold-r-normal--*-120-*-*-*-iso8859-*",
822 PrefData.helpFontNames[H3_HELP_FONT],
823 (void *)sizeof(PrefData.helpFontNames[H3_HELP_FONT]), False},
824 {"helpLinkColor", "helpLinkColor", PREF_STRING, "#009900",
825 PrefData.helpLinkColor,
826 (void *)sizeof(PrefData.helpLinkColor), False},
827 {"shell", "Shell", PREF_STRING,
828 #if defined(__MVS__) || defined(__EMX__)
829 "/bin/sh",
830 #else
831 "/bin/csh",
832 #endif
833 PrefData.shell, (void *)sizeof(PrefData.shell), False},
834 {"geometry", "Geometry", PREF_STRING, "",
835 PrefData.geometry, (void *)sizeof(PrefData.geometry), False},
836 {"remapDeleteKey", "RemapDeleteKey", PREF_BOOLEAN, "False",
837 &PrefData.mapDelete, NULL, False},
838 {"stdOpenDialog", "StdOpenDialog", PREF_BOOLEAN, "False",
839 &PrefData.stdOpenDialog, NULL, False},
840 {"tagFile", "TagFile", PREF_STRING,
841 "", PrefData.tagFile, (void *)sizeof(PrefData.tagFile), False},
842 {"wordDelimiters", "WordDelimiters", PREF_STRING,
843 ".,/\\`'!|@#%^&*()-=+{}[]\":;<>?",
844 PrefData.delimiters, (void *)sizeof(PrefData.delimiters), False},
845 {"serverName", "serverName", PREF_STRING, "", PrefData.serverName,
846 (void *)sizeof(PrefData.serverName), False},
847 {"maxPrevOpenFiles", "MaxPrevOpenFiles", PREF_INT, "30",
848 &PrefData.maxPrevOpenFiles, NULL, False},
849 {"bgMenuButton", "BGMenuButton" , PREF_STRING,
850 "~Shift~Ctrl~Meta~Alt<Btn3Down>", PrefData.bgMenuBtn,
851 (void *)sizeof(PrefData.bgMenuBtn), False},
852 {"smartTags", "SmartTags", PREF_BOOLEAN, "True",
853 &PrefData.smartTags, NULL, True},
854 {"typingHidesPointer", "TypingHidesPointer", PREF_BOOLEAN, "False",
855 &PrefData.typingHidesPointer, NULL, False},
856 {"alwaysCheckRelativeTagsSpecs", "AlwaysCheckRelativeTagsSpecs",
857 PREF_BOOLEAN, "True", &PrefData.alwaysCheckRelativeTagsSpecs, NULL, False},
858 {"prefFileRead", "PrefFileRead", PREF_BOOLEAN, "False",
859 &PrefData.prefFileRead, NULL, True},
860 #ifdef SGI_CUSTOM
861 {"shortMenus", "ShortMenus", PREF_BOOLEAN, "False", &PrefData.shortMenus,
862 NULL, True},
863 #endif
864 {"findReplaceUsesSelection", "FindReplaceUsesSelection", PREF_BOOLEAN, "False",
865 &PrefData.findReplaceUsesSelection, NULL, False},
866 {"overrideDefaultVirtualKeyBindings", "OverrideDefaultVirtualKeyBindings",
867 PREF_ENUM, "Auto", &PrefData.virtKeyOverride, VirtKeyOverrideModes, False},
868 {"titleFormat", "TitleFormat", PREF_STRING, "{%c} [%s] %f (%S) - %d",
869 PrefData.titleFormat, (void *)sizeof(PrefData.titleFormat), True},
870 {"undoModifiesSelection", "UndoModifiesSelection", PREF_BOOLEAN,
871 "True", &PrefData.undoModifiesSelection, NULL, True},
874 static XrmOptionDescRec OpTable[] = {
875 {"-wrap", ".autoWrap", XrmoptionNoArg, (caddr_t)"Continuous"},
876 {"-nowrap", ".autoWrap", XrmoptionNoArg, (caddr_t)"None"},
877 {"-autowrap", ".autoWrap", XrmoptionNoArg, (caddr_t)"Newline"},
878 {"-noautowrap", ".autoWrap", XrmoptionNoArg, (caddr_t)"None"},
879 {"-autoindent", ".autoIndent", XrmoptionNoArg, (caddr_t)"Auto"},
880 {"-noautoindent", ".autoIndent", XrmoptionNoArg, (caddr_t)"False"},
881 {"-autosave", ".autoSave", XrmoptionNoArg, (caddr_t)"True"},
882 {"-noautosave", ".autoSave", XrmoptionNoArg, (caddr_t)"False"},
883 {"-rows", ".textRows", XrmoptionSepArg, (caddr_t)NULL},
884 {"-columns", ".textCols", XrmoptionSepArg, (caddr_t)NULL},
885 {"-tabs", ".tabDistance", XrmoptionSepArg, (caddr_t)NULL},
886 {"-font", ".textFont", XrmoptionSepArg, (caddr_t)NULL},
887 {"-fn", ".textFont", XrmoptionSepArg, (caddr_t)NULL},
888 {"-svrname", ".serverName", XrmoptionSepArg, (caddr_t)NULL},
891 static const char HeaderText[] = "\
892 ! Preferences file for NEdit\n\
893 !\n\
894 ! This file is overwritten by the \"Save Defaults...\" command in NEdit \n\
895 ! and serves only the interactively settable options presented in the NEdit\n\
896 ! \"Preferences\" menu. To modify other options, such as background colors\n\
897 ! and key bindings, use the .Xdefaults file in your home directory (or\n\
898 ! the X resource specification method appropriate to your system). The\n\
899 ! contents of this file can be moved into an X resource file, but since\n\
900 ! resources in this file override their corresponding X resources, either\n\
901 ! this file should be deleted or individual resource lines in the file\n\
902 ! should be deleted for the moved lines to take effect.\n";
904 /* Module-global variable set when any preference changes (for asking the
905 user about re-saving on exit) */
906 static int PrefsHaveChanged = False;
908 /* Module-global variable set when user uses -import to load additional
909 preferences on top of the defaults. Contains name of file loaded */
910 static char *ImportedFile = NULL;
912 /* Module-global variables to support Initial Window Size... dialog */
913 static int DoneWithSizeDialog;
914 static Widget RowText, ColText;
916 /* Module-global variables for Tabs dialog */
917 static int DoneWithTabsDialog;
918 static WindowInfo *TabsDialogForWindow;
919 static Widget TabDistText, EmTabText, EmTabToggle, UseTabsToggle, EmTabLabel;
921 /* Module-global variables for Wrap Margin dialog */
922 static int DoneWithWrapDialog;
923 static WindowInfo *WrapDialogForWindow;
924 static Widget WrapText, WrapTextLabel, WrapWindowToggle;
926 static void translatePrefFormats(int convertOld, int fileVer);
927 static void setIntPref(int *prefDataField, int newValue);
928 static void setStringPref(char *prefDataField, const char *newValue);
929 static void sizeOKCB(Widget w, XtPointer clientData, XtPointer callData);
930 static void sizeCancelCB(Widget w, XtPointer clientData, XtPointer callData);
931 static void tabsOKCB(Widget w, XtPointer clientData, XtPointer callData);
932 static void tabsCancelCB(Widget w, XtPointer clientData, XtPointer callData);
933 static void tabsHelpCB(Widget w, XtPointer clientData, XtPointer callData);
934 static void emTabsCB(Widget w, XtPointer clientData, XtPointer callData);
935 static void wrapOKCB(Widget w, XtPointer clientData, XtPointer callData);
936 static void wrapCancelCB(Widget w, XtPointer clientData, XtPointer callData);
937 static void wrapWindowCB(Widget w, XtPointer clientData, XtPointer callData);
938 static void reapplyLanguageMode(WindowInfo *window, int mode,int forceDefaults);
939 static void fillFromPrimaryCB(Widget w, XtPointer clientData,
940 XtPointer callData);
941 static int checkFontStatus(fontDialog *fd, Widget fontTextFieldW);
942 static int showFontStatus(fontDialog *fd, Widget fontTextFieldW,
943 Widget errorLabelW);
944 static void primaryModifiedCB(Widget w, XtPointer clientData,
945 XtPointer callData);
946 static void italicModifiedCB(Widget w, XtPointer clientData,
947 XtPointer callData);
948 static void boldModifiedCB(Widget w, XtPointer clientData, XtPointer callData);
949 static void boldItalicModifiedCB(Widget w, XtPointer clientData,
950 XtPointer callData);
951 static void primaryBrowseCB(Widget w, XtPointer clientData, XtPointer callData);
952 static void italicBrowseCB(Widget w, XtPointer clientData, XtPointer callData);
953 static void boldBrowseCB(Widget w, XtPointer clientData, XtPointer callData);
954 static void boldItalicBrowseCB(Widget w, XtPointer clientData,
955 XtPointer callData);
956 static void browseFont(Widget parent, Widget fontTextW);
957 static void fontDestroyCB(Widget w, XtPointer clientData, XtPointer callData);
958 static void fontOkCB(Widget w, XtPointer clientData, XtPointer callData);
959 static void fontApplyCB(Widget w, XtPointer clientData, XtPointer callData);
960 static void fontDismissCB(Widget w, XtPointer clientData, XtPointer callData);
961 static void updateFonts(fontDialog *fd);
962 static int matchLanguageMode(WindowInfo *window);
963 static int loadLanguageModesString(char *inString, int fileVer);
964 static char *writeLanguageModesString(void);
965 static char *createExtString(char **extensions, int nExtensions);
966 static char **readExtensionList(char **inPtr, int *nExtensions);
967 static void updateLanguageModeSubmenu(WindowInfo *window);
968 static void setLangModeCB(Widget w, XtPointer clientData, XtPointer callData);
969 static int modeError(languageModeRec *lm, const char *stringStart,
970 const char *stoppedAt, const char *message);
971 static void lmDestroyCB(Widget w, XtPointer clientData, XtPointer callData);
972 static void lmOkCB(Widget w, XtPointer clientData, XtPointer callData);
973 static void lmApplyCB(Widget w, XtPointer clientData, XtPointer callData);
974 static void lmDismissCB(Widget w, XtPointer clientData, XtPointer callData);
975 static int lmDeleteConfirmCB(int itemIndex, void *cbArg);
976 static int updateLMList(void);
977 static languageModeRec *copyLanguageModeRec(languageModeRec *lm);
978 static void *lmGetDisplayedCB(void *oldItem, int explicitRequest, int *abort,
979 void *cbArg);
980 static void lmSetDisplayedCB(void *item, void *cbArg);
981 static languageModeRec *readLMDialogFields(int silent);
982 static void lmFreeItemCB(void *item);
983 static void freeLanguageModeRec(languageModeRec *lm);
984 static int lmDialogEmpty(void);
985 static void updatePatternsTo5dot1(void);
986 static void updatePatternsTo5dot2(void);
987 static void updatePatternsTo5dot3(void);
988 static void updateShellCmdsTo5dot3(void);
989 static void spliceString(char **intoString, const char *insertString, const char *atExpr);
990 static int regexFind(const char *inString, const char *expr);
991 static int regexReplace(char **inString, const char *expr,
992 const char *replaceWith);
994 #ifdef SGI_CUSTOM
995 static int shortPrefToDefault(Widget parent, const char *settingName, int *setDefault);
996 #endif
998 XrmDatabase CreateNEditPrefDB(int *argcInOut, char **argvInOut)
1000 return CreatePreferencesDatabase(GetRCFileName(NEDIT_RC), APP_NAME,
1001 OpTable, XtNumber(OpTable), (unsigned int *)argcInOut, argvInOut);
1004 void RestoreNEditPrefs(XrmDatabase prefDB, XrmDatabase appDB)
1006 int requiresConversion;
1007 int major; /* The integral part of version number */
1008 int minor; /* fractional part of version number */
1009 int alpha = 0; /* Development sub-versions */
1010 int fileVer = 0; /* Both combined into an integer */
1011 int nparsed;
1013 /* Load preferences */
1014 RestorePreferences(prefDB, appDB, APP_NAME,
1015 APP_CLASS, PrefDescrip, XtNumber(PrefDescrip));
1017 /* If the preferences file was written by an older version of NEdit,
1018 warn the user that it will be converted. */
1019 requiresConversion = PrefData.prefFileRead &&
1020 PrefData.fileVersion[0] == '\0';
1021 if (requiresConversion) {
1022 updatePatternsTo5dot1();
1025 if (PrefData.prefFileRead) {
1026 if (PrefData.fileVersion[0] == '\0') {
1027 fileVer = 0; /* Pre-5.1 */
1029 else {
1030 nparsed = sscanf(PrefData.fileVersion, "%d.%da%d", &major, &minor,
1031 &alpha);
1032 if (nparsed >= 2) {
1033 /* Use OSF-style numbering scheme */
1034 fileVer = major * 1000 + minor;
1039 if (PrefData.prefFileRead && fileVer < 5002) {
1040 updatePatternsTo5dot2();
1043 if (PrefData.prefFileRead && fileVer < 5003) {
1044 updateShellCmdsTo5dot3();
1045 updatePatternsTo5dot3();
1048 #ifdef PREF_FILE_ALPHA
1049 /* Development code */
1050 if (PrefData.prefFileRead && fileVer <= 5004) {
1051 switch (alpha) {
1052 case 0: /* Calltips - no conversion needed. Note that adding
1053 default tips file field happens while parsing the
1054 language modes */
1055 /* fall through */
1056 case 1: /* Whatever comes next */
1057 /* fall through */
1058 default:
1059 break;
1061 if (alpha < PREF_FILE_ALPHA) {
1062 fprintf(stderr, "NEdit: Converting .nedit file to 5.4a%d version.\n"
1063 " To keep, use Preferences -> Save Defaults\n",
1064 PREF_FILE_ALPHA);
1067 #else
1068 /* Release code */
1069 if (PrefData.prefFileRead && (fileVer < 5004 ||
1070 (fileVer == 5004 && alpha > 0))) {
1071 /* Add all necessary 5.3 -> 5.4 conversions here */
1072 fprintf(stderr, "NEdit: Converting .nedit file to 5.4 version.\n"
1073 " To keep, use Preferences -> Save Defaults\n");
1075 #endif /* PREF_FILE_ALPHA */
1077 /* Do further parsing on resource types which RestorePreferences does
1078 not understand and reads as strings, to put them in the final form
1079 in which nedit stores and uses. If the preferences file was
1080 written by an older version of NEdit, update regular expressions in
1081 highlight patterns to quote braces and use & instead of \0 */
1082 translatePrefFormats(requiresConversion, fileVer);
1086 ** Many of of NEdit's preferences are much more complicated than just simple
1087 ** integers or strings. These are read as strings, but must be parsed and
1088 ** translated into something meaningful. This routine does the translation,
1089 ** and, in most cases, frees the original string, which is no longer useful.
1091 ** The argument convertOld attempts a conversion from pre 5.1 format .nedit
1092 ** files (which means patterns and macros may contain regular expressions
1093 ** which are of the older syntax where braces were not quoted, and \0 was a
1094 ** legal substitution character). Macros, so far can not be automatically
1095 ** converted, unfortunately.
1097 static void translatePrefFormats(int convertOld, int fileVer)
1099 XFontStruct *font;
1101 /* Parse the strings which represent types which are not decoded by
1102 the standard resource manager routines */
1103 #ifndef VMS
1104 if (TempStringPrefs.shellCmds != NULL) {
1105 LoadShellCmdsString(TempStringPrefs.shellCmds);
1106 XtFree(TempStringPrefs.shellCmds);
1107 TempStringPrefs.shellCmds = NULL;
1109 #endif /* VMS */
1110 if (TempStringPrefs.macroCmds != NULL) {
1111 LoadMacroCmdsString(TempStringPrefs.macroCmds);
1112 XtFree(TempStringPrefs.macroCmds);
1113 TempStringPrefs.macroCmds = NULL;
1115 if (TempStringPrefs.bgMenuCmds != NULL) {
1116 LoadBGMenuCmdsString(TempStringPrefs.bgMenuCmds);
1117 XtFree(TempStringPrefs.bgMenuCmds);
1118 TempStringPrefs.bgMenuCmds = NULL;
1120 if (TempStringPrefs.highlight != NULL) {
1121 LoadHighlightString(TempStringPrefs.highlight, convertOld);
1122 XtFree(TempStringPrefs.highlight);
1123 TempStringPrefs.highlight = NULL;
1125 if (TempStringPrefs.styles != NULL) {
1126 LoadStylesString(TempStringPrefs.styles);
1127 XtFree(TempStringPrefs.styles);
1128 TempStringPrefs.styles = NULL;
1130 if (TempStringPrefs.language != NULL) {
1131 loadLanguageModesString(TempStringPrefs.language, fileVer);
1132 XtFree(TempStringPrefs.language);
1133 TempStringPrefs.language = NULL;
1135 if (TempStringPrefs.smartIndent != NULL) {
1136 LoadSmartIndentString(TempStringPrefs.smartIndent);
1137 XtFree(TempStringPrefs.smartIndent);
1138 TempStringPrefs.smartIndent = NULL;
1140 if (TempStringPrefs.smartIndentCommon != NULL) {
1141 LoadSmartIndentCommonString(TempStringPrefs.smartIndentCommon);
1142 XtFree(TempStringPrefs.smartIndentCommon);
1143 TempStringPrefs.smartIndentCommon = NULL;
1146 /* translate the font names into fontLists suitable for the text widget */
1147 font = XLoadQueryFont(TheDisplay, PrefData.fontString);
1148 PrefData.fontList = font==NULL ? NULL :
1149 XmFontListCreate(font, XmSTRING_DEFAULT_CHARSET);
1150 PrefData.boldFontStruct = XLoadQueryFont(TheDisplay,
1151 PrefData.boldFontString);
1152 PrefData.italicFontStruct = XLoadQueryFont(TheDisplay,
1153 PrefData.italicFontString);
1154 PrefData.boldItalicFontStruct = XLoadQueryFont(TheDisplay,
1155 PrefData.boldItalicFontString);
1157 /* For compatability with older (4.0.3 and before) versions, the autoWrap
1158 and autoIndent resources can accept values of True and False. Translate
1159 them into acceptable wrap and indent styles */
1160 if (PrefData.wrapStyle == 3) PrefData.wrapStyle = NEWLINE_WRAP;
1161 if (PrefData.wrapStyle == 4) PrefData.wrapStyle = NO_WRAP;
1162 if (PrefData.autoIndent == 3) PrefData.autoIndent = AUTO_INDENT;
1163 if (PrefData.autoIndent == 4) PrefData.autoIndent = NO_AUTO_INDENT;
1166 void SaveNEditPrefs(Widget parent, int quietly)
1168 if (!quietly) {
1169 if (DialogF(DF_INF, parent, 2, ImportedFile == NULL ?
1170 "Default preferences will be saved in the file:\n"
1171 "%s\n"
1172 "NEdit automatically loads this file\n"
1173 "each time it is started." :
1174 "Default preferences will be saved in the file:\n"
1175 "%s\n"
1176 "SAVING WILL INCORPORATE SETTINGS\n"
1177 "FROM FILE: %s", "OK", "Cancel",
1178 GetRCFileName(NEDIT_RC), ImportedFile) == 2)
1179 return;
1181 #ifndef VMS
1182 TempStringPrefs.shellCmds = WriteShellCmdsString();
1183 #endif /* VMS */
1184 TempStringPrefs.macroCmds = WriteMacroCmdsString();
1185 TempStringPrefs.bgMenuCmds = WriteBGMenuCmdsString();
1186 TempStringPrefs.highlight = WriteHighlightString();
1187 TempStringPrefs.language = writeLanguageModesString();
1188 TempStringPrefs.styles = WriteStylesString();
1189 TempStringPrefs.smartIndent = WriteSmartIndentString();
1190 TempStringPrefs.smartIndentCommon = WriteSmartIndentCommonString();
1191 #ifdef PREF_FILE_ALPHA
1192 sprintf(PrefData.fileVersion, "%sa%d", PREF_FILE_VERSION, PREF_FILE_ALPHA);
1193 #else
1194 strcpy(PrefData.fileVersion, PREF_FILE_VERSION);
1195 #endif /* PREF_FILE_ALPHA */
1196 if (!SavePreferences(XtDisplay(parent), GetRCFileName(NEDIT_RC), HeaderText,
1197 PrefDescrip, XtNumber(PrefDescrip)))
1199 DialogF(DF_WARN,
1200 parent,
1202 "Unable to save preferences in %s",
1203 "Dismiss",
1204 GetRCFileName(NEDIT_RC));
1207 #ifndef VMS
1208 XtFree(TempStringPrefs.shellCmds);
1209 #endif /* VMS */
1210 XtFree(TempStringPrefs.macroCmds);
1211 XtFree(TempStringPrefs.bgMenuCmds);
1212 XtFree(TempStringPrefs.highlight);
1213 XtFree(TempStringPrefs.language);
1214 XtFree(TempStringPrefs.styles);
1215 XtFree(TempStringPrefs.smartIndent);
1216 XtFree(TempStringPrefs.smartIndentCommon);
1218 PrefsHaveChanged = False;
1222 ** Load an additional preferences file on top of the existing preferences
1223 ** derived from defaults, the .nedit file, and X resources.
1225 void ImportPrefFile(const char *filename, int convertOld)
1227 XrmDatabase db;
1229 if ((db = XrmGetFileDatabase(filename)) != NULL)
1231 OverlayPreferences(db, APP_NAME, APP_CLASS, PrefDescrip,
1232 XtNumber(PrefDescrip));
1234 translatePrefFormats(convertOld, -1);
1235 ImportedFile = XtNewString(filename);
1236 } else
1238 fprintf(stderr, "Could not open additional preferences file: ");
1239 fprintf(stderr, filename);
1240 fprintf(stderr, "\n");
1244 void SetPrefWrap(int state)
1246 setIntPref(&PrefData.wrapStyle, state);
1249 int GetPrefWrap(int langMode)
1251 if (langMode == PLAIN_LANGUAGE_MODE ||
1252 LanguageModes[langMode]->wrapStyle == DEFAULT_WRAP)
1253 return PrefData.wrapStyle;
1254 return LanguageModes[langMode]->wrapStyle;
1257 void SetPrefWrapMargin(int margin)
1259 setIntPref(&PrefData.wrapMargin, margin);
1262 int GetPrefWrapMargin(void)
1264 return PrefData.wrapMargin;
1267 void SetPrefSearch(int searchType)
1269 setIntPref(&PrefData.searchMethod, searchType);
1272 int GetPrefSearch(void)
1274 return PrefData.searchMethod;
1277 #ifdef REPLACE_SCOPE
1278 void SetPrefReplaceDefScope(int scope)
1280 setIntPref(&PrefData.replaceDefScope, scope);
1283 int GetPrefReplaceDefScope(void)
1285 return PrefData.replaceDefScope;
1287 #endif
1289 void SetPrefAutoIndent(int state)
1291 setIntPref(&PrefData.autoIndent, state);
1294 int GetPrefAutoIndent(int langMode)
1296 if (langMode == PLAIN_LANGUAGE_MODE ||
1297 LanguageModes[langMode]->indentStyle == DEFAULT_INDENT)
1298 return PrefData.autoIndent;
1299 return LanguageModes[langMode]->indentStyle;
1302 void SetPrefAutoSave(int state)
1304 setIntPref(&PrefData.autoSave, state);
1307 int GetPrefAutoSave(void)
1309 return PrefData.autoSave;
1312 void SetPrefSaveOldVersion(int state)
1314 setIntPref(&PrefData.saveOldVersion, state);
1317 int GetPrefSaveOldVersion(void)
1319 return PrefData.saveOldVersion;
1322 void SetPrefSearchDlogs(int state)
1324 setIntPref(&PrefData.searchDlogs, state);
1327 int GetPrefSearchDlogs(void)
1329 return PrefData.searchDlogs;
1332 void SetPrefBeepOnSearchWrap(int state)
1334 setIntPref(&PrefData.searchWrapBeep, state);
1337 int GetPrefBeepOnSearchWrap(void)
1339 return PrefData.searchWrapBeep;
1342 void SetPrefKeepSearchDlogs(int state)
1344 setIntPref(&PrefData.keepSearchDlogs, state);
1347 int GetPrefKeepSearchDlogs(void)
1349 return PrefData.keepSearchDlogs;
1352 void SetPrefSearchWraps(int state)
1354 setIntPref(&PrefData.searchWraps, state);
1357 int GetPrefStickyCaseSenseBtn(void)
1359 return PrefData.stickyCaseSenseBtn;
1362 void SetPrefStickyCaseSenseBtn(int state)
1364 setIntPref(&PrefData.stickyCaseSenseBtn, state);
1367 int GetPrefSearchWraps(void)
1369 return PrefData.searchWraps;
1372 void SetPrefStatsLine(int state)
1374 setIntPref(&PrefData.statsLine, state);
1377 int GetPrefStatsLine(void)
1379 return PrefData.statsLine;
1382 void SetPrefISearchLine(int state)
1384 setIntPref(&PrefData.iSearchLine, state);
1387 int GetPrefISearchLine(void)
1389 return PrefData.iSearchLine;
1392 void SetPrefLineNums(int state)
1394 setIntPref(&PrefData.lineNums, state);
1397 int GetPrefLineNums(void)
1399 return PrefData.lineNums;
1402 void SetPrefShowPathInWindowsMenu(int state)
1404 setIntPref(&PrefData.pathInWindowsMenu, state);
1407 int GetPrefShowPathInWindowsMenu(void)
1409 return PrefData.pathInWindowsMenu;
1412 void SetPrefWarnFileMods(int state)
1414 setIntPref(&PrefData.warnFileMods, state);
1417 int GetPrefWarnFileMods(void)
1419 return PrefData.warnFileMods;
1422 void SetPrefWarnExit(int state)
1424 setIntPref(&PrefData.warnExit, state);
1427 int GetPrefWarnExit(void)
1429 return PrefData.warnExit;
1432 void SetPrefv(int state)
1434 setIntPref(&PrefData.findReplaceUsesSelection, state);
1437 int GetPrefFindReplaceUsesSelection(void)
1439 return PrefData.findReplaceUsesSelection;
1442 void SetPrefMapDelete(int state)
1444 setIntPref(&PrefData.mapDelete, state);
1447 int GetPrefMapDelete(void)
1449 return PrefData.mapDelete;
1452 void SetPrefStdOpenDialog(int state)
1454 setIntPref(&PrefData.stdOpenDialog, state);
1457 int GetPrefStdOpenDialog(void)
1459 return PrefData.stdOpenDialog;
1462 void SetPrefRows(int nRows)
1464 setIntPref(&PrefData.textRows, nRows);
1467 int GetPrefRows(void)
1469 return PrefData.textRows;
1472 void SetPrefCols(int nCols)
1474 setIntPref(&PrefData.textCols, nCols);
1477 int GetPrefCols(void)
1479 return PrefData.textCols;
1482 void SetPrefTabDist(int tabDist)
1484 setIntPref(&PrefData.tabDist, tabDist);
1487 int GetPrefTabDist(int langMode)
1489 if (langMode == PLAIN_LANGUAGE_MODE ||
1490 LanguageModes[langMode]->tabDist == DEFAULT_TAB_DIST)
1491 return PrefData.tabDist;
1492 return LanguageModes[langMode]->tabDist;
1495 void SetPrefEmTabDist(int tabDist)
1497 setIntPref(&PrefData.emTabDist, tabDist);
1500 int GetPrefEmTabDist(int langMode)
1502 if (langMode == PLAIN_LANGUAGE_MODE ||
1503 LanguageModes[langMode]->emTabDist == DEFAULT_EM_TAB_DIST)
1504 return PrefData.emTabDist;
1505 return LanguageModes[langMode]->emTabDist;
1508 void SetPrefInsertTabs(int state)
1510 setIntPref(&PrefData.insertTabs, state);
1513 int GetPrefInsertTabs(void)
1515 return PrefData.insertTabs;
1518 void SetPrefShowMatching(int state)
1520 setIntPref(&PrefData.showMatchingStyle, state);
1523 int GetPrefShowMatching(void)
1526 * For backwards compatibility with pre-5.2 versions, the boolean
1527 * False/True matching behavior is converted to NO_FLASH/FLASH_DELIMIT.
1529 if (PrefData.showMatchingStyle >= N_SHOW_MATCHING_STYLES)
1530 PrefData.showMatchingStyle -= N_SHOW_MATCHING_STYLES;
1531 return PrefData.showMatchingStyle;
1534 void SetPrefMatchSyntaxBased(int state)
1536 setIntPref(&PrefData.matchSyntaxBased, state);
1539 int GetPrefMatchSyntaxBased(void)
1541 return PrefData.matchSyntaxBased;
1544 void SetPrefHighlightSyntax(int state)
1546 setIntPref(&PrefData.highlightSyntax, state);
1549 int GetPrefHighlightSyntax(void)
1551 return PrefData.highlightSyntax;
1554 void SetPrefRepositionDialogs(int state)
1556 setIntPref(&PrefData.repositionDialogs, state);
1559 int GetPrefRepositionDialogs(void)
1561 return PrefData.repositionDialogs;
1564 void SetPrefAppendLF(int state)
1566 setIntPref(&PrefData.appendLF, state);
1569 int GetPrefAppendLF(void)
1571 return PrefData.appendLF;
1574 void SetPrefSortOpenPrevMenu(int state)
1576 setIntPref(&PrefData.sortOpenPrevMenu, state);
1579 int GetPrefSortOpenPrevMenu(void)
1581 return PrefData.sortOpenPrevMenu;
1584 void SetPrefTagFile(const char *tagFileName)
1586 setStringPref(PrefData.tagFile, tagFileName);
1589 char *GetPrefTagFile(void)
1591 return PrefData.tagFile;
1594 void SetPrefSmartTags(int state)
1596 setIntPref(&PrefData.smartTags, state);
1599 int GetPrefSmartTags(void)
1601 return PrefData.smartTags;
1604 int GetPrefAlwaysCheckRelTagsSpecs(void)
1606 return PrefData.alwaysCheckRelativeTagsSpecs;
1609 char *GetPrefDelimiters(void)
1611 return PrefData.delimiters;
1615 ** Set the font preferences using the font name (the fontList is generated
1616 ** in this call). Note that this leaks memory and server resources each
1617 ** time the default font is re-set. See note on SetFontByName in window.c
1618 ** for more information.
1620 void SetPrefFont(char *fontName)
1622 XFontStruct *font;
1624 setStringPref(PrefData.fontString, fontName);
1625 font = XLoadQueryFont(TheDisplay, fontName);
1626 PrefData.fontList = font==NULL ? NULL :
1627 XmFontListCreate(font, XmSTRING_DEFAULT_CHARSET);
1630 void SetPrefBoldFont(char *fontName)
1632 setStringPref(PrefData.boldFontString, fontName);
1633 PrefData.boldFontStruct = XLoadQueryFont(TheDisplay, fontName);
1636 void SetPrefItalicFont(char *fontName)
1638 setStringPref(PrefData.italicFontString, fontName);
1639 PrefData.italicFontStruct = XLoadQueryFont(TheDisplay, fontName);
1641 void SetPrefBoldItalicFont(char *fontName)
1643 setStringPref(PrefData.boldItalicFontString, fontName);
1644 PrefData.boldItalicFontStruct = XLoadQueryFont(TheDisplay, fontName);
1647 char *GetPrefFontName(void)
1649 return PrefData.fontString;
1652 char *GetPrefBoldFontName(void)
1654 return PrefData.boldFontString;
1657 char *GetPrefItalicFontName(void)
1659 return PrefData.italicFontString;
1662 char *GetPrefBoldItalicFontName(void)
1664 return PrefData.boldItalicFontString;
1667 XmFontList GetPrefFontList(void)
1669 return PrefData.fontList;
1672 XFontStruct *GetPrefBoldFont(void)
1674 return PrefData.boldFontStruct;
1677 XFontStruct *GetPrefItalicFont(void)
1679 return PrefData.italicFontStruct;
1682 XFontStruct *GetPrefBoldItalicFont(void)
1684 return PrefData.boldItalicFontStruct;
1687 char *GetPrefHelpFontName(int index)
1689 return PrefData.helpFontNames[index];
1692 char *GetPrefHelpLinkColor(void)
1694 return PrefData.helpLinkColor;
1697 void SetPrefShell(const char *shell)
1699 setStringPref(PrefData.shell, shell);
1702 char *GetPrefShell(void)
1704 return PrefData.shell;
1707 void SetPrefGeometry(const char *geometry)
1709 setStringPref(PrefData.geometry, geometry);
1712 char *GetPrefGeometry(void)
1714 return PrefData.geometry;
1717 char *GetPrefServerName(void)
1719 return PrefData.serverName;
1722 char *GetPrefBGMenuBtn(void)
1724 return PrefData.bgMenuBtn;
1727 int GetPrefMaxPrevOpenFiles(void)
1729 return PrefData.maxPrevOpenFiles;
1732 int GetPrefTypingHidesPointer(void)
1734 return(PrefData.typingHidesPointer);
1737 #ifdef SGI_CUSTOM
1738 void SetPrefShortMenus(int state)
1740 setIntPref(&PrefData.shortMenus, state);
1743 int GetPrefShortMenus(void)
1745 return PrefData.shortMenus;
1747 #endif
1749 void SetPrefTitleFormat(const char* format)
1751 const WindowInfo* window;
1753 setStringPref(PrefData.titleFormat, format);
1755 /* update all windows */
1756 for (window=WindowList; window!=NULL; window=window->next) {
1757 UpdateWindowTitle(window);
1760 const char* GetPrefTitleFormat(void)
1762 return PrefData.titleFormat;
1765 void SetPrefUndoModifiesSelection(Boolean value)
1767 setIntPref(&PrefData.undoModifiesSelection, value);
1770 Boolean GetPrefUndoModifiesSelection(void)
1772 return (Boolean)PrefData.undoModifiesSelection;
1775 int GetPrefOverrideVirtKeyBindings(void)
1777 return PrefData.virtKeyOverride;
1781 ** If preferences don't get saved, ask the user on exit whether to save
1783 void MarkPrefsChanged(void)
1785 PrefsHaveChanged = True;
1789 ** Check if preferences have changed, and if so, ask the user if he wants
1790 ** to re-save. Returns False if user requests cancelation of Exit (or whatever
1791 ** operation triggered this call to be made).
1793 int CheckPrefsChangesSaved(Widget dialogParent)
1795 int resp;
1797 if (!PrefsHaveChanged)
1798 return True;
1800 resp = DialogF(DF_WARN, dialogParent, 3, ImportedFile == NULL ?
1801 "Default Preferences have changed.\n"
1802 "Save changes to NEdit preference file?" :
1803 "Default Preferences have changed. SAVING \n"
1804 "CHANGES WILL INCORPORATE ADDITIONAL\nSETTINGS FROM FILE: %s",
1805 "Save", "Don't Save", "Cancel", ImportedFile);
1806 if (resp == 2)
1807 return True;
1808 if (resp == 3)
1809 return False;
1811 SaveNEditPrefs(dialogParent, True);
1812 return True;
1816 ** set *prefDataField to newValue, but first check if they're different
1817 ** and update PrefsHaveChanged if a preference setting has now changed.
1819 static void setIntPref(int *prefDataField, int newValue)
1821 if (newValue != *prefDataField)
1822 PrefsHaveChanged = True;
1823 *prefDataField = newValue;
1826 static void setStringPref(char *prefDataField, const char *newValue)
1828 if (strcmp(prefDataField, newValue))
1829 PrefsHaveChanged = True;
1830 strcpy(prefDataField, newValue);
1835 ** Set the language mode for the window, update the menu and trigger language
1836 ** mode specific actions (turn on/off highlighting). If forceNewDefaults is
1837 ** true, re-establish default settings for language-specific preferences
1838 ** regardless of whether they were previously set by the user.
1840 void SetLanguageMode(WindowInfo *window, int mode, int forceNewDefaults)
1842 Widget menu;
1843 WidgetList items;
1844 int n;
1845 Cardinal nItems;
1846 void *userData;
1848 /* Do mode-specific actions */
1849 reapplyLanguageMode(window, mode, forceNewDefaults);
1851 /* Select the correct language mode in the sub-menu */
1852 XtVaGetValues(window->langModeCascade, XmNsubMenuId, &menu, NULL);
1853 XtVaGetValues(menu, XmNchildren, &items, XmNnumChildren, &nItems, NULL);
1854 for (n=0; n<(int)nItems; n++) {
1855 XtVaGetValues(items[n], XmNuserData, &userData, NULL);
1856 XmToggleButtonSetState(items[n], (int)userData == mode, False);
1861 ** Lookup a language mode by name, returning the index of the language
1862 ** mode or PLAIN_LANGUAGE_MODE if the name is not found
1864 int FindLanguageMode(const char *languageName)
1866 int i;
1868 /* Compare each language mode to the one we were presented */
1869 for (i=0; i<NLanguageModes; i++)
1870 if (!strcmp(languageName, LanguageModes[i]->name))
1871 return i;
1873 return PLAIN_LANGUAGE_MODE;
1878 ** Apply language mode matching criteria and set window->languageMode to
1879 ** the appropriate mode for the current file, trigger language mode
1880 ** specific actions (turn on/off highlighting), and update the language
1881 ** mode menu item. If forceNewDefaults is true, re-establish default
1882 ** settings for language-specific preferences regardless of whether
1883 ** they were previously set by the user.
1885 void DetermineLanguageMode(WindowInfo *window, int forceNewDefaults)
1887 SetLanguageMode(window, matchLanguageMode(window), forceNewDefaults);
1891 ** Return the name of the current language mode set in "window", or NULL
1892 ** if the current mode is "Plain".
1894 char *LanguageModeName(int mode)
1896 if (mode == PLAIN_LANGUAGE_MODE)
1897 return NULL;
1898 else
1899 return LanguageModes[mode]->name;
1903 ** Get the set of word delimiters for the language mode set in the current
1904 ** window. Returns NULL when no language mode is set (it would be easy to
1905 ** return the default delimiter set when the current language mode is "Plain",
1906 ** or the mode doesn't have its own delimiters, but this is usually used
1907 ** to supply delimiters for RE searching, and ExecRE can skip compiling a
1908 ** delimiter table when delimiters is NULL).
1910 char *GetWindowDelimiters(WindowInfo *window)
1912 if (window->languageMode == PLAIN_LANGUAGE_MODE)
1913 return NULL;
1914 else
1915 return LanguageModes[window->languageMode]->delimiters;
1919 ** Put up a dialog for selecting a custom initial window size
1921 void RowColumnPrefDialog(Widget parent)
1923 Widget form, selBox, topLabel;
1924 Arg selBoxArgs[2];
1925 XmString s1;
1927 XtSetArg(selBoxArgs[0], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL);
1928 XtSetArg(selBoxArgs[1], XmNautoUnmanage, False);
1929 selBox = CreatePromptDialog(parent, "customSize", selBoxArgs, 2);
1930 XtAddCallback(selBox, XmNokCallback, (XtCallbackProc)sizeOKCB, NULL);
1931 XtAddCallback(selBox, XmNcancelCallback, (XtCallbackProc)sizeCancelCB,NULL);
1932 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_TEXT));
1933 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_SELECTION_LABEL));
1934 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_HELP_BUTTON));
1935 XtVaSetValues(XtParent(selBox), XmNtitle, "Initial Window Size", NULL);
1937 form = XtVaCreateManagedWidget("form", xmFormWidgetClass, selBox, NULL);
1939 topLabel = XtVaCreateManagedWidget("topLabel", xmLabelGadgetClass, form,
1940 XmNlabelString, s1=MKSTRING(
1941 "Enter desired size in rows\nand columns of characters:"), NULL);
1942 XmStringFree(s1);
1944 RowText = XtVaCreateManagedWidget("rows", xmTextWidgetClass, form,
1945 XmNcolumns, 3,
1946 XmNtopAttachment, XmATTACH_WIDGET,
1947 XmNleftAttachment, XmATTACH_POSITION,
1948 XmNrightAttachment, XmATTACH_POSITION,
1949 XmNtopWidget, topLabel,
1950 XmNleftPosition, 5,
1951 XmNrightPosition, 45, NULL);
1952 RemapDeleteKey(RowText);
1954 XtVaCreateManagedWidget("xLabel", xmLabelGadgetClass, form,
1955 XmNlabelString, s1=MKSTRING("x"),
1956 XmNtopAttachment, XmATTACH_WIDGET,
1957 XmNleftAttachment, XmATTACH_POSITION,
1958 XmNrightAttachment, XmATTACH_POSITION,
1959 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
1960 XmNtopWidget, topLabel,
1961 XmNbottomWidget, RowText,
1962 XmNleftPosition, 45,
1963 XmNrightPosition, 55, NULL);
1964 XmStringFree(s1);
1966 ColText = XtVaCreateManagedWidget("cols", xmTextWidgetClass, form,
1967 XmNcolumns, 3,
1968 XmNtopAttachment, XmATTACH_WIDGET,
1969 XmNleftAttachment, XmATTACH_POSITION,
1970 XmNrightAttachment, XmATTACH_POSITION,
1971 XmNtopWidget, topLabel,
1972 XmNleftPosition, 55,
1973 XmNrightPosition, 95, NULL);
1974 RemapDeleteKey(ColText);
1976 /* put up dialog and wait for user to press ok or cancel */
1977 DoneWithSizeDialog = False;
1978 ManageDialogCenteredOnPointer(selBox);
1979 while (!DoneWithSizeDialog)
1980 XtAppProcessEvent (XtWidgetToApplicationContext(parent), XtIMAll);
1982 XtDestroyWidget(selBox);
1985 static void sizeOKCB(Widget w, XtPointer clientData, XtPointer callData)
1987 int rowValue, colValue, stat;
1989 /* get the values that the user entered and make sure they're ok */
1990 stat = GetIntTextWarn(RowText, &rowValue, "number of rows", True);
1991 if (stat != TEXT_READ_OK)
1992 return;
1993 stat = GetIntTextWarn(ColText, &colValue, "number of columns", True);
1994 if (stat != TEXT_READ_OK)
1995 return;
1997 /* set the corresponding preferences and dismiss the dialog */
1998 SetPrefRows(rowValue);
1999 SetPrefCols(colValue);
2000 DoneWithSizeDialog = True;
2003 static void sizeCancelCB(Widget w, XtPointer clientData, XtPointer callData)
2005 DoneWithSizeDialog = True;
2009 ** Present the user a dialog for setting tab related preferences, either as
2010 ** defaults, or for a specific window (pass "forWindow" as NULL to set default
2011 ** preference, or a window to set preferences for the specific window.
2013 void TabsPrefDialog(Widget parent, WindowInfo *forWindow)
2015 Widget form, selBox;
2016 Arg selBoxArgs[2];
2017 XmString s1;
2018 int emulate, emTabDist, useTabs, tabDist;
2020 XtSetArg(selBoxArgs[0], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL);
2021 XtSetArg(selBoxArgs[1], XmNautoUnmanage, False);
2022 selBox = CreatePromptDialog(parent, "customSize", selBoxArgs, 2);
2023 XtAddCallback(selBox, XmNokCallback, (XtCallbackProc)tabsOKCB, NULL);
2024 XtAddCallback(selBox, XmNcancelCallback, (XtCallbackProc)tabsCancelCB,NULL);
2025 XtAddCallback(selBox, XmNhelpCallback, (XtCallbackProc)tabsHelpCB,NULL);
2026 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_TEXT));
2027 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_SELECTION_LABEL));
2028 XtVaSetValues(XtParent(selBox), XmNtitle, "Tabs", NULL);
2030 form = XtVaCreateManagedWidget("form", xmFormWidgetClass, selBox, NULL);
2032 TabDistText = XtVaCreateManagedWidget("tabDistText", xmTextWidgetClass,
2033 form, XmNcolumns, 7,
2034 XmNtopAttachment, XmATTACH_FORM,
2035 XmNrightAttachment, XmATTACH_FORM, NULL);
2036 RemapDeleteKey(TabDistText);
2037 XtVaCreateManagedWidget("tabDistLabel", xmLabelGadgetClass, form,
2038 XmNlabelString, s1=XmStringCreateSimple(
2039 "Tab spacing (for hardware tab characters)"),
2040 XmNmnemonic, 'T',
2041 XmNuserData, TabDistText,
2042 XmNtopAttachment, XmATTACH_FORM,
2043 XmNleftAttachment, XmATTACH_FORM,
2044 XmNrightAttachment, XmATTACH_WIDGET,
2045 XmNrightWidget, TabDistText,
2046 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
2047 XmNbottomWidget, TabDistText, NULL);
2048 XmStringFree(s1);
2050 EmTabText = XtVaCreateManagedWidget("emTabText", xmTextWidgetClass, form,
2051 XmNcolumns, 7,
2052 XmNtopAttachment, XmATTACH_WIDGET,
2053 XmNtopWidget, TabDistText,
2054 XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET,
2055 XmNrightWidget, TabDistText, NULL);
2056 RemapDeleteKey(EmTabText);
2057 EmTabLabel = XtVaCreateManagedWidget("emTabLabel", xmLabelGadgetClass, form,
2058 XmNlabelString, s1=XmStringCreateSimple("Emulated tab spacing"),
2059 XmNmnemonic, 's',
2060 XmNuserData, EmTabText,
2061 XmNtopAttachment, XmATTACH_WIDGET,
2062 XmNtopWidget, TabDistText,
2063 XmNrightAttachment, XmATTACH_WIDGET,
2064 XmNrightWidget, EmTabText,
2065 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
2066 XmNbottomWidget, EmTabText, NULL);
2067 XmStringFree(s1);
2068 EmTabToggle = XtVaCreateManagedWidget("emTabToggle",
2069 xmToggleButtonWidgetClass, form, XmNlabelString,
2070 s1=XmStringCreateSimple("Emulate tabs"),
2071 XmNmnemonic, 'E',
2072 XmNtopAttachment, XmATTACH_WIDGET,
2073 XmNtopWidget, TabDistText,
2074 XmNleftAttachment, XmATTACH_FORM,
2075 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
2076 XmNbottomWidget, EmTabText, NULL);
2077 XmStringFree(s1);
2078 XtAddCallback(EmTabToggle, XmNvalueChangedCallback, emTabsCB, NULL);
2079 UseTabsToggle = XtVaCreateManagedWidget("useTabsToggle",
2080 xmToggleButtonWidgetClass, form,
2081 XmNlabelString, s1=XmStringCreateSimple(
2082 "Use tab characters in padding and emulated tabs"),
2083 XmNmnemonic, 'U',
2084 XmNtopAttachment, XmATTACH_WIDGET,
2085 XmNtopWidget, EmTabText,
2086 XmNtopOffset, 5,
2087 XmNleftAttachment, XmATTACH_FORM, NULL);
2088 XmStringFree(s1);
2090 /* Set default values */
2091 if (forWindow == NULL) {
2092 emTabDist = GetPrefEmTabDist(PLAIN_LANGUAGE_MODE);
2093 useTabs = GetPrefInsertTabs();
2094 tabDist = GetPrefTabDist(PLAIN_LANGUAGE_MODE);
2095 } else {
2096 XtVaGetValues(forWindow->textArea, textNemulateTabs, &emTabDist, NULL);
2097 useTabs = forWindow->buffer->useTabs;
2098 tabDist = BufGetTabDistance(forWindow->buffer);
2100 emulate = emTabDist != 0;
2101 SetIntText(TabDistText, tabDist);
2102 XmToggleButtonSetState(EmTabToggle, emulate, True);
2103 if (emulate)
2104 SetIntText(EmTabText, emTabDist);
2105 XmToggleButtonSetState(UseTabsToggle, useTabs, False);
2106 XtSetSensitive(EmTabText, emulate);
2107 XtSetSensitive(EmTabLabel, emulate);
2109 /* Handle mnemonic selection of buttons and focus to dialog */
2110 AddDialogMnemonicHandler(form, FALSE);
2112 /* Set the widget to get focus */
2113 #if XmVersion >= 1002
2114 XtVaSetValues(form, XmNinitialFocus, TabDistText, NULL);
2115 #endif
2117 /* put up dialog and wait for user to press ok or cancel */
2118 TabsDialogForWindow = forWindow;
2119 DoneWithTabsDialog = False;
2120 ManageDialogCenteredOnPointer(selBox);
2121 while (!DoneWithTabsDialog)
2122 XtAppProcessEvent(XtWidgetToApplicationContext(parent), XtIMAll);
2124 XtDestroyWidget(selBox);
2127 static void tabsOKCB(Widget w, XtPointer clientData, XtPointer callData)
2129 int emulate, useTabs, stat, tabDist, emTabDist;
2130 WindowInfo *window = TabsDialogForWindow;
2132 /* get the values that the user entered and make sure they're ok */
2133 emulate = XmToggleButtonGetState(EmTabToggle);
2134 useTabs = XmToggleButtonGetState(UseTabsToggle);
2135 stat = GetIntTextWarn(TabDistText, &tabDist, "tab spacing", True);
2136 if (stat != TEXT_READ_OK)
2137 return;
2138 if (tabDist <= 0 || tabDist > MAX_EXP_CHAR_LEN) {
2139 DialogF(DF_WARN, TabDistText, 1, "Tab spacing out of range", "Dismiss");
2140 return;
2142 if (emulate) {
2143 stat = GetIntTextWarn(EmTabText, &emTabDist, "emulated tab spacing",True);
2144 if (stat != TEXT_READ_OK)
2145 return;
2146 if (emTabDist <= 0 || tabDist >= 1000) {
2147 DialogF(DF_WARN, EmTabText, 1, "Emulated tab spacing out of range",
2148 "Dismiss");
2149 return;
2151 } else
2152 emTabDist = 0;
2154 #ifdef SGI_CUSTOM
2155 /* Ask the user about saving as a default preference */
2156 if (TabsDialogForWindow != NULL) {
2157 int setDefault;
2158 if (!shortPrefToDefault(window->shell, "Tab Settings", &setDefault)) {
2159 DoneWithTabsDialog = True;
2160 return;
2162 if (setDefault) {
2163 SetPrefTabDist(tabDist);
2164 SetPrefEmTabDist(emTabDist);
2165 SetPrefInsertTabs(useTabs);
2166 SaveNEditPrefs(window->shell, GetPrefShortMenus());
2169 #endif
2171 /* Set the value in either the requested window or default preferences */
2172 if (TabsDialogForWindow == NULL) {
2173 SetPrefTabDist(tabDist);
2174 SetPrefEmTabDist(emTabDist);
2175 SetPrefInsertTabs(useTabs);
2176 } else {
2177 char *params[1];
2178 char numStr[25];
2180 params[0] = numStr;
2181 sprintf(numStr, "%d", tabDist);
2182 XtCallActionProc(window->textArea, "set_tab_dist", NULL, params, 1);
2183 params[0] = numStr;
2184 sprintf(numStr, "%d", emTabDist);
2185 XtCallActionProc(window->textArea, "set_em_tab_dist", NULL, params, 1);
2186 params[0] = numStr;
2187 sprintf(numStr, "%d", useTabs);
2188 XtCallActionProc(window->textArea, "set_use_tabs", NULL, params, 1);
2190 setTabDist(window, tabDist);
2191 setEmTabDist(window, emTabDist);
2192 window->buffer->useTabs = useTabs;
2195 DoneWithTabsDialog = True;
2198 static void tabsCancelCB(Widget w, XtPointer clientData, XtPointer callData)
2200 DoneWithTabsDialog = True;
2203 static void tabsHelpCB(Widget w, XtPointer clientData, XtPointer callData)
2205 Help(XtParent(EmTabLabel), HELP_TABS_DIALOG);
2208 static void emTabsCB(Widget w, XtPointer clientData, XtPointer callData)
2210 int state = XmToggleButtonGetState(w);
2212 XtSetSensitive(EmTabLabel, state);
2213 XtSetSensitive(EmTabText, state);
2217 ** Present the user a dialog for setting wrap margin.
2219 void WrapMarginDialog(Widget parent, WindowInfo *forWindow)
2221 Widget form, selBox;
2222 Arg selBoxArgs[2];
2223 XmString s1;
2224 int margin;
2226 XtSetArg(selBoxArgs[0], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL);
2227 XtSetArg(selBoxArgs[1], XmNautoUnmanage, False);
2228 selBox = CreatePromptDialog(parent, "wrapMargin", selBoxArgs, 2);
2229 XtAddCallback(selBox, XmNokCallback, (XtCallbackProc)wrapOKCB, NULL);
2230 XtAddCallback(selBox, XmNcancelCallback, (XtCallbackProc)wrapCancelCB,NULL);
2231 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_TEXT));
2232 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_SELECTION_LABEL));
2233 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_HELP_BUTTON));
2234 XtVaSetValues(XtParent(selBox), XmNtitle, "Wrap Margin", NULL);
2236 form = XtVaCreateManagedWidget("form", xmFormWidgetClass, selBox, NULL);
2238 WrapWindowToggle = XtVaCreateManagedWidget("wrapWindowToggle",
2239 xmToggleButtonWidgetClass, form, XmNlabelString,
2240 s1=XmStringCreateSimple("Wrap and Fill at width of window"),
2241 XmNmnemonic, 'W',
2242 XmNtopAttachment, XmATTACH_FORM,
2243 XmNleftAttachment, XmATTACH_FORM, NULL);
2244 XmStringFree(s1);
2245 XtAddCallback(WrapWindowToggle, XmNvalueChangedCallback, wrapWindowCB,NULL);
2246 WrapText = XtVaCreateManagedWidget("wrapText", xmTextWidgetClass, form,
2247 XmNcolumns, 5,
2248 XmNtopAttachment, XmATTACH_WIDGET,
2249 XmNtopWidget, WrapWindowToggle,
2250 XmNrightAttachment, XmATTACH_FORM, NULL);
2251 RemapDeleteKey(WrapText);
2252 WrapTextLabel = XtVaCreateManagedWidget("wrapMarginLabel",
2253 xmLabelGadgetClass, form,
2254 XmNlabelString, s1=XmStringCreateSimple(
2255 "Margin for Wrap and Fill"),
2256 XmNmnemonic, 'M',
2257 XmNuserData, WrapText,
2258 XmNtopAttachment, XmATTACH_WIDGET,
2259 XmNtopWidget, WrapWindowToggle,
2260 XmNleftAttachment, XmATTACH_FORM,
2261 XmNrightAttachment, XmATTACH_WIDGET,
2262 XmNrightWidget, WrapText,
2263 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
2264 XmNbottomWidget, WrapText, NULL);
2265 XmStringFree(s1);
2267 /* Set default value */
2268 if (forWindow == NULL)
2269 margin = GetPrefWrapMargin();
2270 else
2271 XtVaGetValues(forWindow->textArea, textNwrapMargin, &margin, NULL);
2272 XmToggleButtonSetState(WrapWindowToggle, margin==0, True);
2273 if (margin != 0)
2274 SetIntText(WrapText, margin);
2275 XtSetSensitive(WrapText, margin!=0);
2276 XtSetSensitive(WrapTextLabel, margin!=0);
2278 /* Handle mnemonic selection of buttons and focus to dialog */
2279 AddDialogMnemonicHandler(form, FALSE);
2281 /* put up dialog and wait for user to press ok or cancel */
2282 WrapDialogForWindow = forWindow;
2283 DoneWithWrapDialog = False;
2284 ManageDialogCenteredOnPointer(selBox);
2285 while (!DoneWithWrapDialog)
2286 XtAppProcessEvent(XtWidgetToApplicationContext(parent), XtIMAll);
2288 XtDestroyWidget(selBox);
2291 static void wrapOKCB(Widget w, XtPointer clientData, XtPointer callData)
2293 int wrapAtWindow, margin, stat;
2294 WindowInfo *window = WrapDialogForWindow;
2296 /* get the values that the user entered and make sure they're ok */
2297 wrapAtWindow = XmToggleButtonGetState(WrapWindowToggle);
2298 if (wrapAtWindow)
2299 margin = 0;
2300 else {
2301 stat = GetIntTextWarn(WrapText, &margin, "wrap Margin", True);
2302 if (stat != TEXT_READ_OK)
2303 return;
2304 if (margin <= 0 || margin >= 1000) {
2305 DialogF(DF_WARN, WrapText, 1, "Wrap margin out of range", "Dismiss");
2306 return;
2310 #ifdef SGI_CUSTOM
2311 /* Ask the user about saving as a default preference */
2312 if (WrapDialogForWindow != NULL) {
2313 int setDefault;
2314 if (!shortPrefToDefault(window->shell, "Wrap Margin Settings",
2315 &setDefault)) {
2316 DoneWithWrapDialog = True;
2317 return;
2319 if (setDefault) {
2320 SetPrefWrapMargin(margin);
2321 SaveNEditPrefs(window->shell, GetPrefShortMenus());
2324 #endif
2326 /* Set the value in either the requested window or default preferences */
2327 if (WrapDialogForWindow == NULL)
2328 SetPrefWrapMargin(margin);
2329 else {
2330 char *params[1];
2331 char marginStr[25];
2332 sprintf(marginStr, "%d", margin);
2333 params[0] = marginStr;
2334 XtCallActionProc(window->textArea, "set_wrap_margin", NULL, params, 1);
2336 DoneWithWrapDialog = True;
2339 static void wrapCancelCB(Widget w, XtPointer clientData, XtPointer callData)
2341 DoneWithWrapDialog = True;
2344 static void wrapWindowCB(Widget w, XtPointer clientData, XtPointer callData)
2346 int wrapAtWindow = XmToggleButtonGetState(w);
2348 XtSetSensitive(WrapTextLabel, !wrapAtWindow);
2349 XtSetSensitive(WrapText, !wrapAtWindow);
2353 ** Present a dialog for editing language mode information
2355 void EditLanguageModes(Widget parent)
2357 #define LIST_RIGHT 40
2358 #define LEFT_MARGIN_POS 1
2359 #define RIGHT_MARGIN_POS 99
2360 #define H_MARGIN 5
2361 Widget form, nameLbl, topLbl, extLbl, recogLbl, delimitLbl, defTipsLbl;
2362 Widget okBtn, applyBtn, dismissBtn;
2363 Widget overrideFrame, overrideForm, delimitForm;
2364 Widget tabForm, tabLbl, indentBox, wrapBox;
2365 XmString s1;
2366 int i, ac;
2367 Arg args[20];
2369 /* if the dialog is already displayed, just pop it to the top and return */
2370 if (LMDialog.shell != NULL) {
2371 RaiseShellWindow(LMDialog.shell);
2372 return;
2375 LMDialog.languageModeList = (languageModeRec **)XtMalloc(
2376 sizeof(languageModeRec *) * MAX_LANGUAGE_MODES);
2377 for (i=0; i<NLanguageModes; i++)
2378 LMDialog.languageModeList[i] = copyLanguageModeRec(LanguageModes[i]);
2379 LMDialog.nLanguageModes = NLanguageModes;
2381 /* Create a form widget in an application shell */
2382 ac = 0;
2383 XtSetArg(args[ac], XmNdeleteResponse, XmDO_NOTHING); ac++;
2384 XtSetArg(args[ac], XmNiconName, "Language Modes"); ac++;
2385 XtSetArg(args[ac], XmNtitle, "Language Modes"); ac++;
2386 LMDialog.shell = CreateShellWithBestVis(APP_NAME, APP_CLASS,
2387 applicationShellWidgetClass, TheDisplay, args, ac);
2388 AddSmallIcon(LMDialog.shell);
2389 form = XtVaCreateManagedWidget("editLanguageModes", xmFormWidgetClass,
2390 LMDialog.shell, XmNautoUnmanage, False,
2391 XmNresizePolicy, XmRESIZE_NONE, NULL);
2392 XtAddCallback(form, XmNdestroyCallback, lmDestroyCB, NULL);
2393 AddMotifCloseCallback(LMDialog.shell, lmDismissCB, NULL);
2395 topLbl = XtVaCreateManagedWidget("topLabel", xmLabelGadgetClass, form,
2396 XmNlabelString, s1=MKSTRING(
2397 "To modify the properties of an existing language mode, select the name from\n\
2398 the list on the left. To add a new language, select \"New\" from the list."),
2399 XmNmnemonic, 'N',
2400 XmNtopAttachment, XmATTACH_POSITION,
2401 XmNtopPosition, 2,
2402 XmNleftAttachment, XmATTACH_POSITION,
2403 XmNleftPosition, LEFT_MARGIN_POS,
2404 XmNrightAttachment, XmATTACH_POSITION,
2405 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
2406 XmStringFree(s1);
2408 nameLbl = XtVaCreateManagedWidget("nameLbl", xmLabelGadgetClass, form,
2409 XmNlabelString, s1=XmStringCreateSimple("Name"),
2410 XmNmnemonic, 'm',
2411 XmNalignment, XmALIGNMENT_BEGINNING,
2412 XmNleftAttachment, XmATTACH_POSITION,
2413 XmNleftPosition, LIST_RIGHT,
2414 XmNtopAttachment, XmATTACH_WIDGET,
2415 XmNtopOffset, H_MARGIN,
2416 XmNtopWidget, topLbl, NULL);
2417 XmStringFree(s1);
2419 LMDialog.nameW = XtVaCreateManagedWidget("name", xmTextWidgetClass, form,
2420 XmNcolumns, 15,
2421 XmNleftAttachment, XmATTACH_POSITION,
2422 XmNleftPosition, LIST_RIGHT,
2423 XmNtopAttachment, XmATTACH_WIDGET,
2424 XmNtopWidget, nameLbl,
2425 XmNrightAttachment, XmATTACH_POSITION,
2426 XmNrightPosition, (RIGHT_MARGIN_POS + LIST_RIGHT)/2, NULL);
2427 RemapDeleteKey(LMDialog.nameW);
2428 XtVaSetValues(nameLbl, XmNuserData, LMDialog.nameW, NULL);
2430 extLbl = XtVaCreateManagedWidget("extLbl", xmLabelGadgetClass, form,
2431 XmNlabelString,
2432 s1=XmStringCreateSimple("File extensions (separate w/ space)"),
2433 XmNmnemonic, 'F',
2434 XmNalignment, XmALIGNMENT_BEGINNING,
2435 XmNleftAttachment, XmATTACH_POSITION,
2436 XmNleftPosition, LIST_RIGHT,
2437 XmNtopAttachment, XmATTACH_WIDGET,
2438 XmNtopOffset, H_MARGIN,
2439 XmNtopWidget, LMDialog.nameW, NULL);
2440 XmStringFree(s1);
2442 LMDialog.extW = XtVaCreateManagedWidget("ext", xmTextWidgetClass, form,
2443 XmNleftAttachment, XmATTACH_POSITION,
2444 XmNleftPosition, LIST_RIGHT,
2445 XmNtopAttachment, XmATTACH_WIDGET,
2446 XmNtopWidget, extLbl,
2447 XmNrightAttachment, XmATTACH_POSITION,
2448 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
2449 RemapDeleteKey(LMDialog.extW);
2450 XtVaSetValues(extLbl, XmNuserData, LMDialog.extW, NULL);
2452 recogLbl = XtVaCreateManagedWidget("recogLbl", xmLabelGadgetClass, form,
2453 XmNlabelString, s1=MKSTRING(
2454 "Recognition regular expression (applied to first 200\n\
2455 characters of file to determine type from content)"),
2456 XmNalignment, XmALIGNMENT_BEGINNING,
2457 XmNmnemonic, 'R',
2458 XmNleftAttachment, XmATTACH_POSITION,
2459 XmNleftPosition, LIST_RIGHT,
2460 XmNtopAttachment, XmATTACH_WIDGET,
2461 XmNtopOffset, H_MARGIN,
2462 XmNtopWidget, LMDialog.extW, NULL);
2463 XmStringFree(s1);
2465 LMDialog.recogW = XtVaCreateManagedWidget("recog", xmTextWidgetClass, form,
2466 XmNleftAttachment, XmATTACH_POSITION,
2467 XmNleftPosition, LIST_RIGHT,
2468 XmNtopAttachment, XmATTACH_WIDGET,
2469 XmNtopWidget, recogLbl,
2470 XmNrightAttachment, XmATTACH_POSITION,
2471 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
2472 RemapDeleteKey(LMDialog.recogW);
2473 XtVaSetValues(recogLbl, XmNuserData, LMDialog.recogW, NULL);
2475 defTipsLbl = XtVaCreateManagedWidget("defTipsLbl", xmLabelGadgetClass, form,
2476 XmNlabelString, s1=MKSTRING(
2477 "Default calltips file(s) (separate w/colons)"),
2478 XmNalignment, XmALIGNMENT_BEGINNING,
2479 XmNmnemonic, 'c',
2480 XmNleftAttachment, XmATTACH_POSITION,
2481 XmNleftPosition, LIST_RIGHT,
2482 XmNtopAttachment, XmATTACH_WIDGET,
2483 XmNtopOffset, H_MARGIN,
2484 XmNtopWidget, LMDialog.recogW, NULL);
2485 XmStringFree(s1);
2487 LMDialog.defTipsW = XtVaCreateManagedWidget("defTips", xmTextWidgetClass,
2488 form,
2489 XmNleftAttachment, XmATTACH_POSITION,
2490 XmNleftPosition, LIST_RIGHT,
2491 XmNtopAttachment, XmATTACH_WIDGET,
2492 XmNtopWidget, defTipsLbl,
2493 XmNrightAttachment, XmATTACH_POSITION,
2494 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
2495 RemapDeleteKey(LMDialog.defTipsW);
2496 XtVaSetValues(defTipsLbl, XmNuserData, LMDialog.defTipsW, NULL);
2498 okBtn = XtVaCreateManagedWidget("ok", xmPushButtonWidgetClass, form,
2499 XmNlabelString, s1=XmStringCreateSimple("OK"),
2500 XmNleftAttachment, XmATTACH_POSITION,
2501 XmNleftPosition, 10,
2502 XmNrightAttachment, XmATTACH_POSITION,
2503 XmNrightPosition, 30,
2504 XmNbottomAttachment, XmATTACH_POSITION,
2505 XmNbottomPosition, 99, NULL);
2506 XtAddCallback(okBtn, XmNactivateCallback, lmOkCB, NULL);
2507 XmStringFree(s1);
2509 applyBtn = XtVaCreateManagedWidget("apply", xmPushButtonWidgetClass, form,
2510 XmNlabelString, s1=XmStringCreateSimple("Apply"),
2511 XmNmnemonic, 'A',
2512 XmNleftAttachment, XmATTACH_POSITION,
2513 XmNleftPosition, 40,
2514 XmNrightAttachment, XmATTACH_POSITION,
2515 XmNrightPosition, 60,
2516 XmNbottomAttachment, XmATTACH_POSITION,
2517 XmNbottomPosition, 99, NULL);
2518 XtAddCallback(applyBtn, XmNactivateCallback, lmApplyCB, NULL);
2519 XmStringFree(s1);
2521 dismissBtn = XtVaCreateManagedWidget("dismiss",xmPushButtonWidgetClass,form,
2522 XmNlabelString, s1=XmStringCreateSimple("Dismiss"),
2523 XmNleftAttachment, XmATTACH_POSITION,
2524 XmNleftPosition, 70,
2525 XmNrightAttachment, XmATTACH_POSITION,
2526 XmNrightPosition, 90,
2527 XmNbottomAttachment, XmATTACH_POSITION,
2528 XmNbottomPosition, 99, NULL);
2529 XtAddCallback(dismissBtn, XmNactivateCallback, lmDismissCB, NULL);
2530 XmStringFree(s1);
2532 overrideFrame = XtVaCreateManagedWidget("overrideFrame",
2533 xmFrameWidgetClass, form,
2534 XmNleftAttachment, XmATTACH_POSITION,
2535 XmNleftPosition, LEFT_MARGIN_POS,
2536 XmNrightAttachment, XmATTACH_POSITION,
2537 XmNrightPosition, RIGHT_MARGIN_POS,
2538 XmNbottomAttachment, XmATTACH_WIDGET,
2539 XmNbottomWidget, dismissBtn,
2540 XmNbottomOffset, H_MARGIN, NULL);
2541 overrideForm = XtVaCreateManagedWidget("overrideForm", xmFormWidgetClass,
2542 overrideFrame, NULL);
2543 XtVaCreateManagedWidget("overrideLbl", xmLabelGadgetClass, overrideFrame,
2544 XmNlabelString, s1=XmStringCreateSimple("Override Defaults"),
2545 XmNchildType, XmFRAME_TITLE_CHILD,
2546 XmNchildHorizontalAlignment, XmALIGNMENT_CENTER, NULL);
2547 XmStringFree(s1);
2549 delimitForm = XtVaCreateManagedWidget("delimitForm", xmFormWidgetClass,
2550 overrideForm,
2551 XmNleftAttachment, XmATTACH_POSITION,
2552 XmNleftPosition, LEFT_MARGIN_POS,
2553 XmNtopAttachment, XmATTACH_FORM,
2554 XmNtopOffset, H_MARGIN,
2555 XmNrightAttachment, XmATTACH_POSITION,
2556 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
2557 delimitLbl = XtVaCreateManagedWidget("delimitLbl", xmLabelGadgetClass,
2558 delimitForm,
2559 XmNlabelString, s1=XmStringCreateSimple("Word delimiters"),
2560 XmNmnemonic, 'W',
2561 XmNleftAttachment, XmATTACH_FORM,
2562 XmNtopAttachment, XmATTACH_FORM,
2563 XmNbottomAttachment, XmATTACH_FORM, NULL);
2564 XmStringFree(s1);
2565 LMDialog.delimitW = XtVaCreateManagedWidget("delimit", xmTextWidgetClass,
2566 delimitForm,
2567 XmNtopAttachment, XmATTACH_FORM,
2568 XmNleftAttachment, XmATTACH_WIDGET,
2569 XmNleftWidget, delimitLbl,
2570 XmNrightAttachment, XmATTACH_FORM,
2571 XmNbottomAttachment, XmATTACH_FORM, NULL);
2572 RemapDeleteKey(LMDialog.delimitW);
2573 XtVaSetValues(delimitLbl, XmNuserData, LMDialog.delimitW, NULL);
2575 tabForm = XtVaCreateManagedWidget("tabForm", xmFormWidgetClass,
2576 overrideForm,
2577 XmNleftAttachment, XmATTACH_POSITION,
2578 XmNleftPosition, LEFT_MARGIN_POS,
2579 XmNtopAttachment, XmATTACH_WIDGET,
2580 XmNtopWidget, delimitForm,
2581 XmNtopOffset, H_MARGIN,
2582 XmNrightAttachment, XmATTACH_POSITION,
2583 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
2584 tabLbl = XtVaCreateManagedWidget("tabLbl", xmLabelGadgetClass, tabForm,
2585 XmNlabelString, s1=XmStringCreateSimple(
2586 "Alternative hardware tab spacing"),
2587 XmNmnemonic, 't',
2588 XmNleftAttachment, XmATTACH_FORM,
2589 XmNtopAttachment, XmATTACH_FORM,
2590 XmNbottomAttachment, XmATTACH_FORM, NULL);
2591 XmStringFree(s1);
2592 LMDialog.tabW = XtVaCreateManagedWidget("delimit", xmTextWidgetClass,
2593 tabForm,
2594 XmNcolumns, 3,
2595 XmNtopAttachment, XmATTACH_FORM,
2596 XmNleftAttachment, XmATTACH_WIDGET,
2597 XmNleftWidget, tabLbl,
2598 XmNbottomAttachment, XmATTACH_FORM, NULL);
2599 RemapDeleteKey(LMDialog.tabW);
2600 XtVaSetValues(tabLbl, XmNuserData, LMDialog.tabW, NULL);
2601 LMDialog.emTabW = XtVaCreateManagedWidget("delimit", xmTextWidgetClass,
2602 tabForm,
2603 XmNcolumns, 3,
2604 XmNtopAttachment, XmATTACH_FORM,
2605 XmNrightAttachment, XmATTACH_FORM,
2606 XmNbottomAttachment, XmATTACH_FORM, NULL);
2607 RemapDeleteKey(LMDialog.emTabW);
2608 XtVaCreateManagedWidget("emTabLbl", xmLabelGadgetClass, tabForm,
2609 XmNlabelString,
2610 s1=XmStringCreateSimple("Alternative emulated tab spacing"),
2611 XmNalignment, XmALIGNMENT_END,
2612 XmNmnemonic, 'e',
2613 XmNuserData, LMDialog.emTabW,
2614 XmNleftAttachment, XmATTACH_WIDGET,
2615 XmNleftWidget, LMDialog.tabW,
2616 XmNrightAttachment, XmATTACH_WIDGET,
2617 XmNrightWidget, LMDialog.emTabW,
2618 XmNtopAttachment, XmATTACH_FORM,
2619 XmNbottomAttachment, XmATTACH_FORM, NULL);
2620 XmStringFree(s1);
2622 indentBox = XtVaCreateManagedWidget("indentBox", xmRowColumnWidgetClass,
2623 overrideForm,
2624 XmNorientation, XmHORIZONTAL,
2625 XmNpacking, XmPACK_TIGHT,
2626 XmNradioBehavior, True,
2627 XmNleftAttachment, XmATTACH_POSITION,
2628 XmNleftPosition, LEFT_MARGIN_POS,
2629 XmNtopAttachment, XmATTACH_WIDGET,
2630 XmNtopWidget, tabForm,
2631 XmNtopOffset, H_MARGIN, NULL);
2632 LMDialog.defaultIndentW = XtVaCreateManagedWidget("defaultIndent",
2633 xmToggleButtonWidgetClass, indentBox,
2634 XmNset, True,
2635 XmNmarginHeight, 0,
2636 XmNlabelString, s1=XmStringCreateSimple("Default indent style"),
2637 XmNmnemonic, 'D', NULL);
2638 XmStringFree(s1);
2639 LMDialog.noIndentW = XtVaCreateManagedWidget("noIndent",
2640 xmToggleButtonWidgetClass, indentBox,
2641 XmNmarginHeight, 0,
2642 XmNlabelString, s1=XmStringCreateSimple("No automatic indent"),
2643 XmNmnemonic, 'N', NULL);
2644 XmStringFree(s1);
2645 LMDialog.autoIndentW = XtVaCreateManagedWidget("autoIndent",
2646 xmToggleButtonWidgetClass, indentBox,
2647 XmNmarginHeight, 0,
2648 XmNlabelString, s1=XmStringCreateSimple("Auto-indent"),
2649 XmNmnemonic, 'A', NULL);
2650 XmStringFree(s1);
2651 LMDialog.smartIndentW = XtVaCreateManagedWidget("smartIndent",
2652 xmToggleButtonWidgetClass, indentBox,
2653 XmNmarginHeight, 0,
2654 XmNlabelString, s1=XmStringCreateSimple("Smart-indent"),
2655 XmNmnemonic, 'S', NULL);
2656 XmStringFree(s1);
2658 wrapBox = XtVaCreateManagedWidget("wrapBox", xmRowColumnWidgetClass,
2659 overrideForm,
2660 XmNorientation, XmHORIZONTAL,
2661 XmNpacking, XmPACK_TIGHT,
2662 XmNradioBehavior, True,
2663 XmNleftAttachment, XmATTACH_POSITION,
2664 XmNleftPosition, LEFT_MARGIN_POS,
2665 XmNtopAttachment, XmATTACH_WIDGET,
2666 XmNtopWidget, indentBox,
2667 XmNtopOffset, H_MARGIN,
2668 XmNbottomAttachment, XmATTACH_FORM,
2669 XmNbottomOffset, H_MARGIN, NULL);
2670 LMDialog.defaultWrapW = XtVaCreateManagedWidget("defaultWrap",
2671 xmToggleButtonWidgetClass, wrapBox,
2672 XmNset, True,
2673 XmNmarginHeight, 0,
2674 XmNlabelString, s1=XmStringCreateSimple("Default wrap style"),
2675 XmNmnemonic, 'D', NULL);
2676 XmStringFree(s1);
2677 LMDialog.noWrapW = XtVaCreateManagedWidget("noWrap",
2678 xmToggleButtonWidgetClass, wrapBox,
2679 XmNmarginHeight, 0,
2680 XmNlabelString, s1=XmStringCreateSimple("No wrapping"),
2681 XmNmnemonic, 'N', NULL);
2682 XmStringFree(s1);
2683 LMDialog.newlineWrapW = XtVaCreateManagedWidget("newlineWrap",
2684 xmToggleButtonWidgetClass, wrapBox,
2685 XmNmarginHeight, 0,
2686 XmNlabelString, s1=XmStringCreateSimple("Auto newline wrap"),
2687 XmNmnemonic, 'A', NULL);
2688 XmStringFree(s1);
2689 LMDialog.contWrapW = XtVaCreateManagedWidget("contWrap",
2690 xmToggleButtonWidgetClass, wrapBox,
2691 XmNmarginHeight, 0,
2692 XmNlabelString, s1=XmStringCreateSimple("Continuous wrap"),
2693 XmNmnemonic, 'C', NULL);
2694 XmStringFree(s1);
2696 XtVaCreateManagedWidget("stretchForm", xmFormWidgetClass, form,
2697 XmNtopAttachment, XmATTACH_WIDGET,
2698 XmNtopWidget, LMDialog.defTipsW,
2699 XmNleftAttachment, XmATTACH_POSITION,
2700 XmNleftPosition, LIST_RIGHT,
2701 XmNrightAttachment, XmATTACH_POSITION,
2702 XmNrightPosition, RIGHT_MARGIN_POS,
2703 XmNbottomAttachment, XmATTACH_WIDGET,
2704 XmNbottomWidget, overrideFrame,
2705 XmNbottomOffset, H_MARGIN*2, NULL);
2707 ac = 0;
2708 XtSetArg(args[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
2709 XtSetArg(args[ac], XmNtopOffset, H_MARGIN); ac++;
2710 XtSetArg(args[ac], XmNtopWidget, topLbl); ac++;
2711 XtSetArg(args[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
2712 XtSetArg(args[ac], XmNleftPosition, LEFT_MARGIN_POS); ac++;
2713 XtSetArg(args[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
2714 XtSetArg(args[ac], XmNrightPosition, LIST_RIGHT-1); ac++;
2715 XtSetArg(args[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
2716 XtSetArg(args[ac], XmNbottomWidget, overrideFrame); ac++;
2717 XtSetArg(args[ac], XmNbottomOffset, H_MARGIN*2); ac++;
2718 LMDialog.managedListW = CreateManagedList(form, "list", args, ac,
2719 (void **)LMDialog.languageModeList, &LMDialog.nLanguageModes,
2720 MAX_LANGUAGE_MODES, 15, lmGetDisplayedCB, NULL, lmSetDisplayedCB,
2721 NULL, lmFreeItemCB);
2722 AddDeleteConfirmCB(LMDialog.managedListW, lmDeleteConfirmCB, NULL);
2723 XtVaSetValues(topLbl, XmNuserData, LMDialog.managedListW, NULL);
2725 /* Set initial default button */
2726 XtVaSetValues(form, XmNdefaultButton, okBtn, NULL);
2727 XtVaSetValues(form, XmNcancelButton, dismissBtn, NULL);
2729 /* Handle mnemonic selection of buttons and focus to dialog */
2730 AddDialogMnemonicHandler(form, FALSE);
2732 /* Realize all of the widgets in the new dialog */
2733 RealizeWithoutForcingPosition(LMDialog.shell);
2736 static void lmDestroyCB(Widget w, XtPointer clientData, XtPointer callData)
2738 int i;
2740 for (i=0; i<LMDialog.nLanguageModes; i++)
2741 freeLanguageModeRec(LMDialog.languageModeList[i]);
2742 XtFree((char *)LMDialog.languageModeList);
2745 static void lmOkCB(Widget w, XtPointer clientData, XtPointer callData)
2747 if (!updateLMList())
2748 return;
2750 /* pop down and destroy the dialog */
2751 XtDestroyWidget(LMDialog.shell);
2752 LMDialog.shell = NULL;
2755 static void lmApplyCB(Widget w, XtPointer clientData, XtPointer callData)
2757 updateLMList();
2760 static void lmDismissCB(Widget w, XtPointer clientData, XtPointer callData)
2762 /* pop down and destroy the dialog */
2763 XtDestroyWidget(LMDialog.shell);
2764 LMDialog.shell = NULL;
2767 static int lmDeleteConfirmCB(int itemIndex, void *cbArg)
2769 int i;
2771 /* Allow duplicate names to be deleted regardless of dependencies */
2772 for (i=0; i<LMDialog.nLanguageModes; i++)
2773 if (i != itemIndex && !strcmp(LMDialog.languageModeList[i]->name,
2774 LMDialog.languageModeList[itemIndex]->name))
2775 return True;
2777 /* don't allow deletion if data will be lost */
2778 if (LMHasHighlightPatterns(LMDialog.languageModeList[itemIndex]->name)) {
2779 DialogF(DF_WARN, LMDialog.shell, 1,
2780 "This language mode has syntax highlighting\n\
2781 patterns defined. Please delete the patterns\n\
2782 first, in Preferences -> Default Settings ->\n\
2783 Syntax Highlighting, before proceeding here.", "Dismiss");
2784 return False;
2786 return True;
2790 ** Apply the changes that the user has made in the language modes dialog to the
2791 ** stored language mode information for this NEdit session (the data array
2792 ** LanguageModes)
2794 static int updateLMList(void)
2796 WindowInfo *window;
2797 char *oldModeName, *newDelimiters;
2798 int i, j;
2800 /* Get the current contents of the dialog fields */
2801 if (!UpdateManagedList(LMDialog.managedListW, True))
2802 return False;
2804 /* Fix up language mode indices in all open windows (which may change
2805 if the currently selected mode is deleted or has changed position),
2806 and update word delimiters */
2807 for (window=WindowList; window!=NULL; window=window->next) {
2808 if (window->languageMode != PLAIN_LANGUAGE_MODE) {
2809 oldModeName = LanguageModes[window->languageMode]->name;
2810 window->languageMode = PLAIN_LANGUAGE_MODE;
2811 for (i=0; i<LMDialog.nLanguageModes; i++) {
2812 if (!strcmp(oldModeName, LMDialog.languageModeList[i]->name)) {
2813 newDelimiters = LMDialog.languageModeList[i]->delimiters;
2814 if (newDelimiters == NULL)
2815 newDelimiters = GetPrefDelimiters();
2816 XtVaSetValues(window->textArea, textNwordDelimiters,
2817 newDelimiters, NULL);
2818 for (j=0; j<window->nPanes; j++)
2819 XtVaSetValues(window->textPanes[j],
2820 textNwordDelimiters, newDelimiters, NULL);
2821 window->languageMode = i;
2822 break;
2828 /* If there were any name changes, re-name dependent highlight patterns
2829 and fix up the weird rename-format names */
2830 for (i=0; i<LMDialog.nLanguageModes; i++) {
2831 if (strchr(LMDialog.languageModeList[i]->name, ':') != NULL) {
2832 char *newName = strrchr(LMDialog.languageModeList[i]->name, ':')+1;
2833 *strchr(LMDialog.languageModeList[i]->name, ':') = '\0';
2834 RenameHighlightPattern(LMDialog.languageModeList[i]->name, newName);
2835 memmove(LMDialog.languageModeList[i]->name, newName,
2836 strlen(newName) + 1);
2837 ChangeManagedListData(LMDialog.managedListW);
2841 /* Unload any default calltips file that is no longer a default. */
2842 for (i=0; i<NLanguageModes; i++) {
2843 if (!LanguageModes[i]->defTipsFile)
2844 continue;
2845 for (j=0; j<LMDialog.nLanguageModes; j++) {
2846 if (!LMDialog.languageModeList[j]->defTipsFile)
2847 continue;
2848 if (!strcmp(LanguageModes[i]->defTipsFile,
2849 LMDialog.languageModeList[j]->defTipsFile))
2850 break;
2852 if ( j==LMDialog.nLanguageModes )
2853 DeleteTagsFile(LanguageModes[i]->defTipsFile, TIP);
2856 /* Replace the old language mode list with the new one from the dialog */
2857 for (i=0; i<NLanguageModes; i++)
2858 freeLanguageModeRec(LanguageModes[i]);
2859 for (i=0; i<LMDialog.nLanguageModes; i++)
2860 LanguageModes[i] = copyLanguageModeRec(LMDialog.languageModeList[i]);
2861 NLanguageModes = LMDialog.nLanguageModes;
2863 /* Update the menus in the window menu bars and load any needed
2864 calltips files */
2865 for (window=WindowList; window!=NULL; window=window->next) {
2866 updateLanguageModeSubmenu(window);
2867 if (window->languageMode != PLAIN_LANGUAGE_MODE &&
2868 LanguageModes[window->languageMode]->defTipsFile != NULL)
2869 AddTagsFile(LanguageModes[window->languageMode]->defTipsFile, TIP);
2872 /* If a syntax highlighting dialog is up, update its menu */
2873 UpdateLanguageModeMenu();
2875 /* Note that preferences have been changed */
2876 MarkPrefsChanged();
2878 return True;
2881 static void *lmGetDisplayedCB(void *oldItem, int explicitRequest, int *abort,
2882 void *cbArg)
2884 languageModeRec *lm, *oldLM = (languageModeRec *)oldItem;
2885 char *tempName;
2886 int i, nCopies, oldLen;
2888 /* If the dialog is currently displaying the "new" entry and the
2889 fields are empty, that's just fine */
2890 if (oldItem == NULL && lmDialogEmpty())
2891 return NULL;
2893 /* Read the data the user has entered in the dialog fields */
2894 lm = readLMDialogFields(True);
2896 /* If there was a name change of a non-duplicate language mode, modify the
2897 name to the weird format of: ":old name:new name". This signals that a
2898 name change is necessary in lm dependent data such as highlight
2899 patterns. Duplicate language modes may be re-named at will, since no
2900 data will be lost due to the name change. */
2901 if (lm != NULL && oldLM != NULL && strcmp(oldLM->name, lm->name)) {
2902 nCopies = 0;
2903 for (i=0; i<LMDialog.nLanguageModes; i++)
2904 if (!strcmp(oldLM->name, LMDialog.languageModeList[i]->name))
2905 nCopies++;
2906 if (nCopies <= 1) {
2907 oldLen = strchr(oldLM->name, ':') == NULL ? strlen(oldLM->name) :
2908 strchr(oldLM->name, ':') - oldLM->name;
2909 tempName = XtMalloc(oldLen + strlen(lm->name) + 2);
2910 strncpy(tempName, oldLM->name, oldLen);
2911 sprintf(&tempName[oldLen], ":%s", lm->name);
2912 XtFree(lm->name);
2913 lm->name = tempName;
2917 /* If there are no problems reading the data, just return it */
2918 if (lm != NULL)
2919 return (void *)lm;
2921 /* If there are problems, and the user didn't ask for the fields to be
2922 read, give more warning */
2923 if (!explicitRequest) {
2924 if (DialogF(DF_WARN, LMDialog.shell, 2,
2925 "Discard incomplete entry\nfor current language mode?", "Keep",
2926 "Discard") == 2) {
2927 return oldItem == NULL ? NULL :
2928 (void *)copyLanguageModeRec((languageModeRec *)oldItem);
2932 /* Do readLMDialogFields again without "silent" mode to display warning */
2933 lm = readLMDialogFields(False);
2934 *abort = True;
2935 return NULL;
2938 static void lmSetDisplayedCB(void *item, void *cbArg)
2940 languageModeRec *lm = (languageModeRec *)item;
2941 char *extStr;
2943 if (item == NULL) {
2944 XmTextSetString(LMDialog.nameW, "");
2945 XmTextSetString(LMDialog.extW, "");
2946 XmTextSetString(LMDialog.recogW, "");
2947 XmTextSetString(LMDialog.defTipsW, "");
2948 XmTextSetString(LMDialog.delimitW, "");
2949 XmTextSetString(LMDialog.tabW, "");
2950 XmTextSetString(LMDialog.emTabW, "");
2951 XmToggleButtonSetState(LMDialog.defaultIndentW, True, True);
2952 XmToggleButtonSetState(LMDialog.defaultWrapW, True, True);
2953 } else {
2954 XmTextSetString(LMDialog.nameW, strchr(lm->name, ':') == NULL ?
2955 lm->name : strchr(lm->name, ':')+1);
2956 extStr = createExtString(lm->extensions, lm->nExtensions);
2957 XmTextSetString(LMDialog.extW, extStr);
2958 XtFree(extStr);
2959 XmTextSetString(LMDialog.recogW, lm->recognitionExpr);
2960 XmTextSetString(LMDialog.defTipsW, lm->defTipsFile);
2961 XmTextSetString(LMDialog.delimitW, lm->delimiters);
2962 if (lm->tabDist == DEFAULT_TAB_DIST)
2963 XmTextSetString(LMDialog.tabW, "");
2964 else
2965 SetIntText(LMDialog.tabW, lm->tabDist);
2966 if (lm->emTabDist == DEFAULT_EM_TAB_DIST)
2967 XmTextSetString(LMDialog.emTabW, "");
2968 else
2969 SetIntText(LMDialog.emTabW, lm->emTabDist);
2970 XmToggleButtonSetState(LMDialog.defaultIndentW,
2971 lm->indentStyle == DEFAULT_INDENT, False);
2972 XmToggleButtonSetState(LMDialog.noIndentW,
2973 lm->indentStyle == NO_AUTO_INDENT, False);
2974 XmToggleButtonSetState(LMDialog.autoIndentW,
2975 lm->indentStyle == AUTO_INDENT, False);
2976 XmToggleButtonSetState(LMDialog.smartIndentW,
2977 lm->indentStyle == SMART_INDENT, False);
2978 XmToggleButtonSetState(LMDialog.defaultWrapW,
2979 lm->wrapStyle == DEFAULT_WRAP, False);
2980 XmToggleButtonSetState(LMDialog.noWrapW,
2981 lm->wrapStyle == NO_WRAP, False);
2982 XmToggleButtonSetState(LMDialog.newlineWrapW,
2983 lm->wrapStyle == NEWLINE_WRAP, False);
2984 XmToggleButtonSetState(LMDialog.contWrapW,
2985 lm->wrapStyle == CONTINUOUS_WRAP, False);
2989 static void lmFreeItemCB(void *item)
2991 freeLanguageModeRec((languageModeRec *)item);
2994 static void freeLanguageModeRec(languageModeRec *lm)
2996 int i;
2998 XtFree(lm->name);
2999 if (lm->recognitionExpr != NULL)
3000 XtFree(lm->recognitionExpr);
3001 if (lm->defTipsFile != NULL)
3002 XtFree(lm->defTipsFile);
3003 if (lm->delimiters != NULL)
3004 XtFree(lm->delimiters);
3005 for (i=0; i<lm->nExtensions; i++)
3006 XtFree(lm->extensions[i]);
3007 if (lm->nExtensions != 0)
3008 XtFree((char *)lm->extensions);
3009 XtFree((char *)lm);
3013 ** Copy a languageModeRec data structure and all of the allocated data it contains
3015 static languageModeRec *copyLanguageModeRec(languageModeRec *lm)
3017 languageModeRec *newLM;
3018 int i;
3020 newLM = (languageModeRec *)XtMalloc(sizeof(languageModeRec));
3021 newLM->name = XtMalloc(strlen(lm->name)+1);
3022 strcpy(newLM->name, lm->name);
3023 newLM->nExtensions = lm->nExtensions;
3024 newLM->extensions = (char **)XtMalloc(sizeof(char *) * lm->nExtensions);
3025 for (i=0; i<lm->nExtensions; i++) {
3026 newLM->extensions[i] = XtMalloc(strlen(lm->extensions[i]) + 1);
3027 strcpy(newLM->extensions[i], lm->extensions[i]);
3029 if (lm->recognitionExpr == NULL)
3030 newLM->recognitionExpr = NULL;
3031 else {
3032 newLM->recognitionExpr = XtMalloc(strlen(lm->recognitionExpr)+1);
3033 strcpy(newLM->recognitionExpr, lm->recognitionExpr);
3035 if (lm->defTipsFile == NULL)
3036 newLM->defTipsFile = NULL;
3037 else {
3038 newLM->defTipsFile = XtMalloc(strlen(lm->defTipsFile)+1);
3039 strcpy(newLM->defTipsFile, lm->defTipsFile);
3041 if (lm->delimiters == NULL)
3042 newLM->delimiters = NULL;
3043 else {
3044 newLM->delimiters = XtMalloc(strlen(lm->delimiters)+1);
3045 strcpy(newLM->delimiters, lm->delimiters);
3047 newLM->wrapStyle = lm->wrapStyle;
3048 newLM->indentStyle = lm->indentStyle;
3049 newLM->tabDist = lm->tabDist;
3050 newLM->emTabDist = lm->emTabDist;
3051 return newLM;
3055 ** Read the fields in the language modes dialog and create a languageModeRec data
3056 ** structure reflecting the current state of the selected language mode in the dialog.
3057 ** If any of the information is incorrect or missing, display a warning dialog and
3058 ** return NULL. Passing "silent" as True, suppresses the warning dialogs.
3060 static languageModeRec *readLMDialogFields(int silent)
3062 languageModeRec *lm;
3063 regexp *compiledRE;
3064 char *compileMsg, *extStr, *extPtr;
3066 /* Allocate a language mode structure to return, set unread fields to
3067 empty so everything can be freed on errors by freeLanguageModeRec */
3068 lm = (languageModeRec *)XtMalloc(sizeof(languageModeRec));
3069 lm->nExtensions = 0;
3070 lm->recognitionExpr = NULL;
3071 lm->defTipsFile = NULL;
3072 lm->delimiters = NULL;
3074 /* read the name field */
3075 lm->name = ReadSymbolicFieldTextWidget(LMDialog.nameW,
3076 "language mode name", silent);
3077 if (lm->name == NULL) {
3078 XtFree((char *)lm);
3079 return NULL;
3081 if (*lm->name == '\0') {
3082 if (!silent) {
3083 DialogF(DF_WARN, LMDialog.shell, 1,
3084 "Please specify a name\nfor the language mode", "Dismiss");
3085 XmProcessTraversal(LMDialog.nameW, XmTRAVERSE_CURRENT);
3087 freeLanguageModeRec(lm);
3088 return NULL;
3091 /* read the extension list field */
3092 extStr = extPtr = XmTextGetString(LMDialog.extW);
3093 lm->extensions = readExtensionList(&extPtr, &lm->nExtensions);
3094 XtFree(extStr);
3096 /* read recognition expression */
3097 lm->recognitionExpr = XmTextGetString(LMDialog.recogW);
3098 if (*lm->recognitionExpr == '\0') {
3099 XtFree(lm->recognitionExpr);
3100 lm->recognitionExpr = NULL;
3101 } else {
3102 compiledRE = CompileRE(lm->recognitionExpr, &compileMsg, REDFLT_STANDARD);
3103 if (compiledRE == NULL) {
3104 if (!silent) {
3105 DialogF(DF_WARN, LMDialog.shell, 1, "Recognition expression:\n%s",
3106 "Dismiss", compileMsg);
3107 XmProcessTraversal(LMDialog.recogW, XmTRAVERSE_CURRENT);
3109 XtFree((char *)compiledRE);
3110 freeLanguageModeRec(lm);
3111 return NULL;
3113 XtFree((char *)compiledRE);
3116 /* Read the default calltips file for the language mode */
3117 lm->defTipsFile = XmTextGetString(LMDialog.defTipsW);
3118 if (*lm->defTipsFile == '\0') {
3119 /* Empty string */
3120 XtFree(lm->defTipsFile);
3121 lm->defTipsFile = NULL;
3122 } else {
3123 /* Ensure that AddTagsFile will work */
3124 if (AddTagsFile(lm->defTipsFile, TIP) == FALSE) {
3125 if (!silent) {
3126 DialogF(DF_WARN, LMDialog.shell, 1, "Can't read default "
3127 "calltips file(s):\n \"%s\"\n", "Dismiss",
3128 lm->defTipsFile);
3129 XmProcessTraversal(LMDialog.recogW, XmTRAVERSE_CURRENT);
3131 freeLanguageModeRec(lm);
3132 return NULL;
3133 } else
3134 if (DeleteTagsFile(lm->defTipsFile, TIP) == FALSE)
3135 fprintf(stderr, "nedit: Internal error: Trouble deleting "
3136 "calltips file(s):\n \"%s\"\n", lm->defTipsFile);
3139 /* read tab spacing field */
3140 if (TextWidgetIsBlank(LMDialog.tabW))
3141 lm->tabDist = DEFAULT_TAB_DIST;
3142 else {
3143 if (GetIntTextWarn(LMDialog.tabW, &lm->tabDist, "tab spacing", False)
3144 != TEXT_READ_OK) {
3145 freeLanguageModeRec(lm);
3146 return NULL;
3148 if (lm->tabDist <= 0 || lm->tabDist > 100) {
3149 if (!silent) {
3150 DialogF(DF_WARN, LMDialog.shell, 1, "Invalid tab spacing: %d",
3151 "Dismiss", lm->tabDist);
3152 XmProcessTraversal(LMDialog.tabW, XmTRAVERSE_CURRENT);
3154 freeLanguageModeRec(lm);
3155 return NULL;
3159 /* read emulated tab field */
3160 if (TextWidgetIsBlank(LMDialog.emTabW))
3161 lm->emTabDist = DEFAULT_EM_TAB_DIST;
3162 else {
3163 if (GetIntTextWarn(LMDialog.emTabW, &lm->emTabDist,
3164 "emulated tab spacing", False) != TEXT_READ_OK) {
3165 freeLanguageModeRec(lm);
3166 return NULL;
3168 if (lm->emTabDist < 0 || lm->emTabDist > 100) {
3169 if (!silent) {
3170 DialogF(DF_WARN, LMDialog.shell, 1,
3171 "Invalid emulated tab spacing: %d", "Dismiss",
3172 lm->emTabDist);
3173 XmProcessTraversal(LMDialog.emTabW, XmTRAVERSE_CURRENT);
3175 freeLanguageModeRec(lm);
3176 return NULL;
3180 /* read delimiters string */
3181 lm->delimiters = XmTextGetString(LMDialog.delimitW);
3182 if (*lm->delimiters == '\0') {
3183 XtFree(lm->delimiters);
3184 lm->delimiters = NULL;
3187 /* read indent style */
3188 if (XmToggleButtonGetState(LMDialog.noIndentW))
3189 lm->indentStyle = NO_AUTO_INDENT;
3190 else if (XmToggleButtonGetState(LMDialog.autoIndentW))
3191 lm->indentStyle = AUTO_INDENT;
3192 else if (XmToggleButtonGetState(LMDialog.smartIndentW))
3193 lm->indentStyle = SMART_INDENT;
3194 else
3195 lm->indentStyle = DEFAULT_INDENT;
3197 /* read wrap style */
3198 if (XmToggleButtonGetState(LMDialog.noWrapW))
3199 lm->wrapStyle = NO_WRAP;
3200 else if (XmToggleButtonGetState(LMDialog.newlineWrapW))
3201 lm->wrapStyle = NEWLINE_WRAP;
3202 else if (XmToggleButtonGetState(LMDialog.contWrapW))
3203 lm->wrapStyle = CONTINUOUS_WRAP;
3204 else
3205 lm->wrapStyle = DEFAULT_WRAP;
3207 return lm;
3211 ** Return True if the language mode dialog fields are blank (unchanged from the "New"
3212 ** language mode state).
3214 static int lmDialogEmpty(void)
3216 return TextWidgetIsBlank(LMDialog.nameW) &&
3217 TextWidgetIsBlank(LMDialog.extW) &&
3218 TextWidgetIsBlank(LMDialog.recogW) &&
3219 TextWidgetIsBlank(LMDialog.delimitW) &&
3220 TextWidgetIsBlank(LMDialog.tabW) &&
3221 TextWidgetIsBlank(LMDialog.emTabW) &&
3222 XmToggleButtonGetState(LMDialog.defaultIndentW) &&
3223 XmToggleButtonGetState(LMDialog.defaultWrapW);
3227 ** Present a dialog for changing fonts (primary, and for highlighting).
3229 void ChooseFonts(WindowInfo *window, int forWindow)
3231 #define MARGIN_SPACING 10
3232 #define BTN_TEXT_OFFSET 3
3233 Widget form, primaryLbl, primaryBtn, italicLbl, italicBtn;
3234 Widget boldLbl, boldBtn, boldItalicLbl, boldItalicBtn;
3235 Widget primaryFrame, primaryForm, highlightFrame, highlightForm;
3236 Widget okBtn, applyBtn, dismissBtn;
3237 fontDialog *fd;
3238 XmString s1;
3239 int ac;
3240 Arg args[20];
3242 /* if the dialog is already displayed, just pop it to the top and return */
3243 if (window->fontDialog != NULL) {
3244 RaiseShellWindow(((fontDialog *)window->fontDialog)->shell);
3245 return;
3248 /* Create a structure for keeping track of dialog state */
3249 fd = (fontDialog *)XtMalloc(sizeof(fontDialog));
3250 fd->window = window;
3251 fd->forWindow = forWindow;
3252 window->fontDialog = (void*)fd;
3254 /* Create a form widget in a dialog shell */
3255 ac = 0;
3256 XtSetArg(args[ac], XmNautoUnmanage, False); ac++;
3257 XtSetArg(args[ac], XmNresizePolicy, XmRESIZE_NONE); ac++;
3258 form = CreateFormDialog(window->shell, "choose Fonts", args, ac);
3259 XtVaSetValues(form, XmNshadowThickness, 0, NULL);
3260 fd->shell = XtParent(form);
3261 XtVaSetValues(fd->shell, XmNtitle, "Fonts", NULL);
3262 AddMotifCloseCallback(XtParent(form), fontDismissCB, fd);
3263 XtAddCallback(form, XmNdestroyCallback, fontDestroyCB, fd);
3265 primaryFrame = XtVaCreateManagedWidget("primaryFrame", xmFrameWidgetClass,
3266 form, XmNmarginHeight, 3,
3267 XmNtopAttachment, XmATTACH_POSITION,
3268 XmNtopPosition, 2,
3269 XmNleftAttachment, XmATTACH_POSITION,
3270 XmNleftPosition, 1,
3271 XmNrightAttachment, XmATTACH_POSITION,
3272 XmNrightPosition, 99, NULL);
3273 primaryForm = XtVaCreateManagedWidget("primaryForm", xmFormWidgetClass,
3274 primaryFrame, NULL);
3275 primaryLbl = XtVaCreateManagedWidget("primaryFont", xmLabelGadgetClass,
3276 primaryFrame,
3277 XmNlabelString, s1=XmStringCreateSimple("Primary Font"),
3278 XmNmnemonic, 'P',
3279 XmNchildType, XmFRAME_TITLE_CHILD,
3280 XmNchildHorizontalAlignment, XmALIGNMENT_CENTER, NULL);
3281 XmStringFree(s1);
3283 primaryBtn = XtVaCreateManagedWidget("primaryBtn",
3284 xmPushButtonWidgetClass, primaryForm,
3285 XmNlabelString, s1=XmStringCreateSimple("Browse..."),
3286 XmNmnemonic, 'r',
3287 XmNtopAttachment, XmATTACH_POSITION,
3288 XmNtopPosition, 2,
3289 XmNtopOffset, BTN_TEXT_OFFSET,
3290 XmNleftAttachment, XmATTACH_POSITION,
3291 XmNleftPosition, 1, NULL);
3292 XmStringFree(s1);
3293 XtAddCallback(primaryBtn, XmNactivateCallback, primaryBrowseCB, fd);
3295 fd->primaryW = XtVaCreateManagedWidget("primary", xmTextWidgetClass,
3296 primaryForm,
3297 XmNcolumns, 70,
3298 XmNmaxLength, MAX_FONT_LEN,
3299 XmNleftAttachment, XmATTACH_WIDGET,
3300 XmNleftWidget, primaryBtn,
3301 XmNtopAttachment, XmATTACH_POSITION,
3302 XmNtopPosition, 2,
3303 XmNrightAttachment, XmATTACH_POSITION,
3304 XmNrightPosition, 99, NULL);
3305 RemapDeleteKey(fd->primaryW);
3306 XtAddCallback(fd->primaryW, XmNvalueChangedCallback,
3307 primaryModifiedCB, fd);
3308 XtVaSetValues(primaryLbl, XmNuserData, fd->primaryW, NULL);
3310 highlightFrame = XtVaCreateManagedWidget("highlightFrame",
3311 xmFrameWidgetClass, form,
3312 XmNmarginHeight, 3,
3313 XmNnavigationType, XmTAB_GROUP,
3314 XmNtopAttachment, XmATTACH_WIDGET,
3315 XmNtopWidget, primaryFrame,
3316 XmNtopOffset, 20,
3317 XmNleftAttachment, XmATTACH_POSITION,
3318 XmNleftPosition, 1,
3319 XmNrightAttachment, XmATTACH_POSITION,
3320 XmNrightPosition, 99, NULL);
3321 highlightForm = XtVaCreateManagedWidget("highlightForm", xmFormWidgetClass,
3322 highlightFrame, NULL);
3323 XtVaCreateManagedWidget("highlightFonts", xmLabelGadgetClass,
3324 highlightFrame,
3325 XmNlabelString,
3326 s1=XmStringCreateSimple("Fonts for Syntax Highlighting"),
3327 XmNchildType, XmFRAME_TITLE_CHILD,
3328 XmNchildHorizontalAlignment, XmALIGNMENT_CENTER, NULL);
3329 XmStringFree(s1);
3331 fd->fillW = XtVaCreateManagedWidget("fillBtn",
3332 xmPushButtonWidgetClass, highlightForm,
3333 XmNlabelString,
3334 s1=XmStringCreateSimple("Fill Highlight Fonts from Primary"),
3335 XmNmnemonic, 'F',
3336 XmNtopAttachment, XmATTACH_POSITION,
3337 XmNtopPosition, 2,
3338 XmNtopOffset, BTN_TEXT_OFFSET,
3339 XmNleftAttachment, XmATTACH_POSITION,
3340 XmNleftPosition, 1, NULL);
3341 XmStringFree(s1);
3342 XtAddCallback(fd->fillW, XmNactivateCallback, fillFromPrimaryCB, fd);
3344 italicLbl = XtVaCreateManagedWidget("italicLbl", xmLabelGadgetClass,
3345 highlightForm,
3346 XmNlabelString, s1=XmStringCreateSimple("Italic Font"),
3347 XmNmnemonic, 'I',
3348 XmNalignment, XmALIGNMENT_BEGINNING,
3349 XmNtopAttachment, XmATTACH_WIDGET,
3350 XmNtopWidget, fd->fillW,
3351 XmNtopOffset, MARGIN_SPACING,
3352 XmNleftAttachment, XmATTACH_POSITION,
3353 XmNleftPosition, 1, NULL);
3354 XmStringFree(s1);
3356 fd->italicErrW = XtVaCreateManagedWidget("italicErrLbl",
3357 xmLabelGadgetClass, highlightForm,
3358 XmNlabelString, s1=XmStringCreateSimple(
3359 "(vvv spacing is inconsistent with primary font vvv)"),
3360 XmNalignment, XmALIGNMENT_END,
3361 XmNtopAttachment, XmATTACH_WIDGET,
3362 XmNtopWidget, fd->fillW,
3363 XmNtopOffset, MARGIN_SPACING,
3364 XmNleftAttachment, XmATTACH_WIDGET,
3365 XmNleftWidget, italicLbl,
3366 XmNrightAttachment, XmATTACH_POSITION,
3367 XmNrightPosition, 99, NULL);
3368 XmStringFree(s1);
3370 italicBtn = XtVaCreateManagedWidget("italicBtn",
3371 xmPushButtonWidgetClass, highlightForm,
3372 XmNlabelString, s1=XmStringCreateSimple("Browse..."),
3373 XmNmnemonic, 'o',
3374 XmNtopAttachment, XmATTACH_WIDGET,
3375 XmNtopWidget, italicLbl,
3376 XmNtopOffset, BTN_TEXT_OFFSET,
3377 XmNleftAttachment, XmATTACH_POSITION,
3378 XmNleftPosition, 1, NULL);
3379 XmStringFree(s1);
3380 XtAddCallback(italicBtn, XmNactivateCallback, italicBrowseCB, fd);
3382 fd->italicW = XtVaCreateManagedWidget("italic", xmTextWidgetClass,
3383 highlightForm,
3384 XmNmaxLength, MAX_FONT_LEN,
3385 XmNleftAttachment, XmATTACH_WIDGET,
3386 XmNleftWidget, italicBtn,
3387 XmNtopAttachment, XmATTACH_WIDGET,
3388 XmNtopWidget, italicLbl,
3389 XmNrightAttachment, XmATTACH_POSITION,
3390 XmNrightPosition, 99, NULL);
3391 RemapDeleteKey(fd->italicW);
3392 XtAddCallback(fd->italicW, XmNvalueChangedCallback,
3393 italicModifiedCB, fd);
3394 XtVaSetValues(italicLbl, XmNuserData, fd->italicW, NULL);
3396 boldLbl = XtVaCreateManagedWidget("boldLbl", xmLabelGadgetClass,
3397 highlightForm,
3398 XmNlabelString, s1=XmStringCreateSimple("Bold Font"),
3399 XmNmnemonic, 'B',
3400 XmNalignment, XmALIGNMENT_BEGINNING,
3401 XmNtopAttachment, XmATTACH_WIDGET,
3402 XmNtopWidget, italicBtn,
3403 XmNtopOffset, MARGIN_SPACING,
3404 XmNleftAttachment, XmATTACH_POSITION,
3405 XmNleftPosition, 1, NULL);
3406 XmStringFree(s1);
3408 fd->boldErrW = XtVaCreateManagedWidget("boldErrLbl",
3409 xmLabelGadgetClass, highlightForm,
3410 XmNlabelString, s1=XmStringCreateSimple(""),
3411 XmNalignment, XmALIGNMENT_END,
3412 XmNtopAttachment, XmATTACH_WIDGET,
3413 XmNtopWidget, italicBtn,
3414 XmNtopOffset, MARGIN_SPACING,
3415 XmNleftAttachment, XmATTACH_WIDGET,
3416 XmNleftWidget, boldLbl,
3417 XmNrightAttachment, XmATTACH_POSITION,
3418 XmNrightPosition, 99, NULL);
3419 XmStringFree(s1);
3421 boldBtn = XtVaCreateManagedWidget("boldBtn",
3422 xmPushButtonWidgetClass, highlightForm,
3423 XmNlabelString, s1=XmStringCreateSimple("Browse..."),
3424 XmNmnemonic, 'w',
3425 XmNtopAttachment, XmATTACH_WIDGET,
3426 XmNtopWidget, boldLbl,
3427 XmNtopOffset, BTN_TEXT_OFFSET,
3428 XmNleftAttachment, XmATTACH_POSITION,
3429 XmNleftPosition, 1, NULL);
3430 XmStringFree(s1);
3431 XtAddCallback(boldBtn, XmNactivateCallback, boldBrowseCB, fd);
3433 fd->boldW = XtVaCreateManagedWidget("bold", xmTextWidgetClass,
3434 highlightForm,
3435 XmNmaxLength, MAX_FONT_LEN,
3436 XmNleftAttachment, XmATTACH_WIDGET,
3437 XmNleftWidget, boldBtn,
3438 XmNtopAttachment, XmATTACH_WIDGET,
3439 XmNtopWidget, boldLbl,
3440 XmNrightAttachment, XmATTACH_POSITION,
3441 XmNrightPosition, 99, NULL);
3442 RemapDeleteKey(fd->boldW);
3443 XtAddCallback(fd->boldW, XmNvalueChangedCallback,
3444 boldModifiedCB, fd);
3445 XtVaSetValues(boldLbl, XmNuserData, fd->boldW, NULL);
3447 boldItalicLbl = XtVaCreateManagedWidget("boldItalicLbl", xmLabelGadgetClass,
3448 highlightForm,
3449 XmNlabelString, s1=XmStringCreateSimple("Bold Italic Font"),
3450 XmNmnemonic, 'l',
3451 XmNalignment, XmALIGNMENT_BEGINNING,
3452 XmNtopAttachment, XmATTACH_WIDGET,
3453 XmNtopWidget, boldBtn,
3454 XmNtopOffset, MARGIN_SPACING,
3455 XmNleftAttachment, XmATTACH_POSITION,
3456 XmNleftPosition, 1, NULL);
3457 XmStringFree(s1);
3459 fd->boldItalicErrW = XtVaCreateManagedWidget("boldItalicErrLbl",
3460 xmLabelGadgetClass, highlightForm,
3461 XmNlabelString, s1=XmStringCreateSimple(""),
3462 XmNalignment, XmALIGNMENT_END,
3463 XmNtopAttachment, XmATTACH_WIDGET,
3464 XmNtopWidget, boldBtn,
3465 XmNtopOffset, MARGIN_SPACING,
3466 XmNleftAttachment, XmATTACH_WIDGET,
3467 XmNleftWidget, boldItalicLbl,
3468 XmNrightAttachment, XmATTACH_POSITION,
3469 XmNrightPosition, 99, NULL);
3470 XmStringFree(s1);
3472 boldItalicBtn = XtVaCreateManagedWidget("boldItalicBtn",
3473 xmPushButtonWidgetClass, highlightForm,
3474 XmNlabelString, s1=XmStringCreateSimple("Browse..."),
3475 XmNmnemonic, 's',
3476 XmNtopAttachment, XmATTACH_WIDGET,
3477 XmNtopWidget, boldItalicLbl,
3478 XmNtopOffset, BTN_TEXT_OFFSET,
3479 XmNleftAttachment, XmATTACH_POSITION,
3480 XmNleftPosition, 1, NULL);
3481 XmStringFree(s1);
3482 XtAddCallback(boldItalicBtn, XmNactivateCallback, boldItalicBrowseCB, fd);
3484 fd->boldItalicW = XtVaCreateManagedWidget("boldItalic",
3485 xmTextWidgetClass, highlightForm,
3486 XmNmaxLength, MAX_FONT_LEN,
3487 XmNleftAttachment, XmATTACH_WIDGET,
3488 XmNleftWidget, boldItalicBtn,
3489 XmNtopAttachment, XmATTACH_WIDGET,
3490 XmNtopWidget, boldItalicLbl,
3491 XmNrightAttachment, XmATTACH_POSITION,
3492 XmNrightPosition, 99, NULL);
3493 RemapDeleteKey(fd->boldItalicW);
3494 XtAddCallback(fd->boldItalicW, XmNvalueChangedCallback,
3495 boldItalicModifiedCB, fd);
3496 XtVaSetValues(boldItalicLbl, XmNuserData, fd->boldItalicW, NULL);
3498 okBtn = XtVaCreateManagedWidget("ok", xmPushButtonWidgetClass, form,
3499 XmNlabelString, s1=XmStringCreateSimple("OK"),
3500 XmNtopAttachment, XmATTACH_WIDGET,
3501 XmNtopWidget, highlightFrame,
3502 XmNtopOffset, MARGIN_SPACING,
3503 XmNleftAttachment, XmATTACH_POSITION,
3504 XmNleftPosition, forWindow ? 13 : 26,
3505 XmNrightAttachment, XmATTACH_POSITION,
3506 XmNrightPosition, forWindow ? 27 : 40, NULL);
3507 XtAddCallback(okBtn, XmNactivateCallback, fontOkCB, fd);
3508 XmStringFree(s1);
3510 if (forWindow) {
3511 applyBtn = XtVaCreateManagedWidget("apply",xmPushButtonWidgetClass,form,
3512 XmNlabelString, s1=XmStringCreateSimple("Apply"),
3513 XmNmnemonic, 'A',
3514 XmNtopAttachment, XmATTACH_WIDGET,
3515 XmNtopWidget, highlightFrame,
3516 XmNtopOffset, MARGIN_SPACING,
3517 XmNleftAttachment, XmATTACH_POSITION,
3518 XmNleftPosition, 43,
3519 XmNrightAttachment, XmATTACH_POSITION,
3520 XmNrightPosition, 57, NULL);
3521 XtAddCallback(applyBtn, XmNactivateCallback, fontApplyCB, fd);
3522 XmStringFree(s1);
3525 dismissBtn = XtVaCreateManagedWidget("dismiss",xmPushButtonWidgetClass,form,
3526 XmNlabelString, s1=XmStringCreateSimple("Dismiss"),
3527 XmNtopAttachment, XmATTACH_WIDGET,
3528 XmNtopWidget, highlightFrame,
3529 XmNtopOffset, MARGIN_SPACING,
3530 XmNleftAttachment, XmATTACH_POSITION,
3531 XmNleftPosition, forWindow ? 73 : 59,
3532 XmNrightAttachment, XmATTACH_POSITION,
3533 XmNrightPosition, forWindow ? 87 : 73, NULL);
3534 XtAddCallback(dismissBtn, XmNactivateCallback, fontDismissCB, fd);
3535 XmStringFree(s1);
3537 /* Set initial default button */
3538 XtVaSetValues(form, XmNdefaultButton, okBtn, NULL);
3539 XtVaSetValues(form, XmNcancelButton, dismissBtn, NULL);
3541 /* Set initial values */
3542 if (forWindow) {
3543 XmTextSetString(fd->primaryW, window->fontName);
3544 XmTextSetString(fd->boldW, window->boldFontName);
3545 XmTextSetString(fd->italicW, window->italicFontName);
3546 XmTextSetString(fd->boldItalicW, window->boldItalicFontName);
3547 } else {
3548 XmTextSetString(fd->primaryW, GetPrefFontName());
3549 XmTextSetString(fd->boldW, GetPrefBoldFontName());
3550 XmTextSetString(fd->italicW, GetPrefItalicFontName());
3551 XmTextSetString(fd->boldItalicW, GetPrefBoldItalicFontName());
3554 /* Handle mnemonic selection of buttons and focus to dialog */
3555 AddDialogMnemonicHandler(form, FALSE);
3557 /* put up dialog */
3558 ManageDialogCenteredOnPointer(form);
3561 static void fillFromPrimaryCB(Widget w, XtPointer clientData,
3562 XtPointer callData)
3564 fontDialog *fd = (fontDialog *)clientData;
3565 char *primaryName, *errMsg;
3566 char modifiedFontName[MAX_FONT_LEN];
3567 char *searchString = "(-[^-]*-[^-]*)-([^-]*)-([^-]*)-(.*)";
3568 char *italicReplaceString = "\\1-\\2-o-\\4";
3569 char *boldReplaceString = "\\1-bold-\\3-\\4";
3570 char *boldItalicReplaceString = "\\1-bold-o-\\4";
3571 regexp *compiledRE;
3573 /* Match the primary font agains RE pattern for font names. If it
3574 doesn't match, we can't generate highlight font names, so return */
3575 compiledRE = CompileRE(searchString, &errMsg, REDFLT_STANDARD);
3576 primaryName = XmTextGetString(fd->primaryW);
3577 if (!ExecRE(compiledRE, NULL, primaryName, NULL, False, '\0', '\0', NULL, NULL)) {
3578 XBell(XtDisplay(fd->shell), 0);
3579 free(compiledRE);
3580 XtFree(primaryName);
3581 return;
3584 /* Make up names for new fonts based on RE replace patterns */
3585 SubstituteRE(compiledRE, italicReplaceString, modifiedFontName,
3586 MAX_FONT_LEN);
3587 XmTextSetString(fd->italicW, modifiedFontName);
3588 SubstituteRE(compiledRE, boldReplaceString, modifiedFontName,
3589 MAX_FONT_LEN);
3590 XmTextSetString(fd->boldW, modifiedFontName);
3591 SubstituteRE(compiledRE, boldItalicReplaceString, modifiedFontName,
3592 MAX_FONT_LEN);
3593 XmTextSetString(fd->boldItalicW, modifiedFontName);
3594 XtFree(primaryName);
3595 free(compiledRE);
3598 static void primaryModifiedCB(Widget w, XtPointer clientData,
3599 XtPointer callData)
3601 fontDialog *fd = (fontDialog *)clientData;
3603 showFontStatus(fd, fd->italicW, fd->italicErrW);
3604 showFontStatus(fd, fd->boldW, fd->boldErrW);
3605 showFontStatus(fd, fd->boldItalicW, fd->boldItalicErrW);
3607 static void italicModifiedCB(Widget w, XtPointer clientData, XtPointer callData)
3609 fontDialog *fd = (fontDialog *)clientData;
3611 showFontStatus(fd, fd->italicW, fd->italicErrW);
3613 static void boldModifiedCB(Widget w, XtPointer clientData, XtPointer callData)
3615 fontDialog *fd = (fontDialog *)clientData;
3617 showFontStatus(fd, fd->boldW, fd->boldErrW);
3619 static void boldItalicModifiedCB(Widget w, XtPointer clientData,
3620 XtPointer callData)
3622 fontDialog *fd = (fontDialog *)clientData;
3624 showFontStatus(fd, fd->boldItalicW, fd->boldItalicErrW);
3627 static void primaryBrowseCB(Widget w, XtPointer clientData, XtPointer callData)
3629 fontDialog *fd = (fontDialog *)clientData;
3631 browseFont(fd->shell, fd->primaryW);
3633 static void italicBrowseCB(Widget w, XtPointer clientData, XtPointer callData)
3635 fontDialog *fd = (fontDialog *)clientData;
3637 browseFont(fd->shell, fd->italicW);
3639 static void boldBrowseCB(Widget w, XtPointer clientData, XtPointer callData)
3641 fontDialog *fd = (fontDialog *)clientData;
3643 browseFont(fd->shell, fd->boldW);
3645 static void boldItalicBrowseCB(Widget w, XtPointer clientData,
3646 XtPointer callData)
3648 fontDialog *fd = (fontDialog *)clientData;
3650 browseFont(fd->shell, fd->boldItalicW);
3653 static void fontDestroyCB(Widget w, XtPointer clientData, XtPointer callData)
3655 fontDialog *fd = (fontDialog *)clientData;
3657 fd->window->fontDialog = NULL;
3658 XtFree((char *)fd);
3661 static void fontOkCB(Widget w, XtPointer clientData, XtPointer callData)
3663 fontDialog *fd = (fontDialog *)clientData;
3665 updateFonts(fd);
3667 /* pop down and destroy the dialog */
3668 XtDestroyWidget(fd->shell);
3671 static void fontApplyCB(Widget w, XtPointer clientData, XtPointer callData)
3673 fontDialog *fd = (fontDialog *)clientData;
3675 updateFonts(fd);
3678 static void fontDismissCB(Widget w, XtPointer clientData, XtPointer callData)
3680 fontDialog *fd = (fontDialog *)clientData;
3682 /* pop down and destroy the dialog */
3683 XtDestroyWidget(fd->shell);
3687 ** Check over a font name in a text field to make sure it agrees with the
3688 ** primary font in height and spacing.
3690 static int checkFontStatus(fontDialog *fd, Widget fontTextFieldW)
3692 char *primaryName, *testName;
3693 XFontStruct *primaryFont, *testFont;
3694 Display *display = XtDisplay(fontTextFieldW);
3695 int primaryWidth, primaryHeight, testWidth, testHeight;
3697 /* Get width and height of the font to check. Note the test for empty
3698 name: X11R6 clients freak out X11R5 servers if they ask them to load
3699 an empty font name, and kill the whole application! */
3700 testName = XmTextGetString(fontTextFieldW);
3701 if (testName[0] == '\0') {
3702 XtFree(testName);
3703 return BAD_FONT;
3705 testFont = XLoadQueryFont(display, testName);
3706 if (testFont == NULL) {
3707 XtFree(testName);
3708 return BAD_FONT;
3710 XtFree(testName);
3711 testWidth = testFont->min_bounds.width;
3712 testHeight = testFont->ascent + testFont->descent;
3713 XFreeFont(display, testFont);
3715 /* Get width and height of the primary font */
3716 primaryName = XmTextGetString(fd->primaryW);
3717 if (primaryName[0] == '\0') {
3718 XtFree(primaryName);
3719 return BAD_FONT;
3721 primaryFont = XLoadQueryFont(display, primaryName);
3722 if (primaryFont == NULL) {
3723 XtFree(primaryName);
3724 return BAD_PRIMARY;
3726 XtFree(primaryName);
3727 primaryWidth = primaryFont->min_bounds.width;
3728 primaryHeight = primaryFont->ascent + primaryFont->descent;
3729 XFreeFont(display, primaryFont);
3731 /* Compare font information */
3732 if (testWidth != primaryWidth)
3733 return BAD_SPACING;
3734 if (testHeight != primaryHeight)
3735 return BAD_SIZE;
3736 return GOOD_FONT;
3740 ** Update the error label for a font text field to reflect its validity and degree
3741 ** of agreement with the currently selected primary font
3743 static int showFontStatus(fontDialog *fd, Widget fontTextFieldW,
3744 Widget errorLabelW)
3746 int status;
3747 XmString s;
3748 char *msg;
3750 status = checkFontStatus(fd, fontTextFieldW);
3751 if (status == BAD_PRIMARY)
3752 msg = "(font below may not match primary font)";
3753 else if (status == BAD_FONT)
3754 msg = "(xxx font below is invalid xxx)";
3755 else if (status == BAD_SIZE)
3756 msg = "(height of font below does not match primary)";
3757 else if (status == BAD_SPACING)
3758 msg = "(spacing of font below does not match primary)";
3759 else
3760 msg = "";
3762 XtVaSetValues(errorLabelW, XmNlabelString, s=XmStringCreateSimple(msg),
3763 NULL);
3764 XmStringFree(s);
3765 return status;
3769 ** Put up a font selector panel to set the font name in the text widget "fontTextW"
3771 static void browseFont(Widget parent, Widget fontTextW)
3773 char *origFontName, *newFontName;
3775 origFontName = XmTextGetString(fontTextW);
3776 newFontName = FontSel(parent, PREF_FIXED, origFontName);
3777 XtFree(origFontName);
3778 if (newFontName == NULL)
3779 return;
3780 XmTextSetString(fontTextW, newFontName);
3781 XtFree(newFontName);
3785 ** Accept the changes in the dialog and set the fonts regardless of errors
3787 static void updateFonts(fontDialog *fd)
3789 char *fontName, *italicName, *boldName, *boldItalicName;
3791 fontName = XmTextGetString(fd->primaryW);
3792 italicName = XmTextGetString(fd->italicW);
3793 boldName = XmTextGetString(fd->boldW);
3794 boldItalicName = XmTextGetString(fd->boldItalicW);
3796 if (fd->forWindow) {
3797 char *params[4];
3798 params[0] = fontName;
3799 params[1] = italicName;
3800 params[2] = boldName;
3801 params[3] = boldItalicName;
3802 XtCallActionProc(fd->window->textArea, "set_fonts", NULL, params, 4);
3804 SetFonts(fd->window, fontName, italicName, boldName, boldItalicName);
3807 else {
3808 SetPrefFont(fontName);
3809 SetPrefItalicFont(italicName);
3810 SetPrefBoldFont(boldName);
3811 SetPrefBoldItalicFont(boldItalicName);
3813 XtFree(fontName);
3814 XtFree(italicName);
3815 XtFree(boldName);
3816 XtFree(boldItalicName);
3820 ** Change the language mode to the one indexed by "mode", reseting word
3821 ** delimiters, syntax highlighting and other mode specific parameters
3823 static void reapplyLanguageMode(WindowInfo *window, int mode, int forceDefaults)
3825 char *delimiters;
3826 int i, wrapMode, indentStyle, tabDist, emTabDist, highlight, oldEmTabDist;
3827 int wrapModeIsDef, tabDistIsDef, emTabDistIsDef, indentStyleIsDef;
3828 int highlightIsDef, haveHighlightPatterns, haveSmartIndentMacros;
3829 int oldMode = window->languageMode;
3830 WindowInfo *wi;
3832 /* If the mode is the same, and changes aren't being forced (as might
3833 happen with Save As...), don't mess with already correct settings */
3834 if (window->languageMode == mode && !forceDefaults)
3835 return;
3837 /* Change the mode name stored in the window */
3838 window->languageMode = mode;
3840 /* Unload oldMode's default calltips file if there are no more windows
3841 in that mode and the mode has a default file */
3842 if (oldMode != PLAIN_LANGUAGE_MODE && LanguageModes[oldMode]->defTipsFile) {
3843 for (wi = WindowList; wi; wi = wi->next)
3844 if (wi->languageMode == oldMode) break;
3845 if (!wi) DeleteTagsFile( LanguageModes[oldMode]->defTipsFile, TIP );
3848 /* Make sure we didn't accidentally delete a default calltips file that
3849 also belongs another language mode (also load the tips file for the
3850 new lang. mode) */
3851 for (wi = WindowList; wi; wi = wi->next) {
3852 i = wi->languageMode;
3853 if (i != PLAIN_LANGUAGE_MODE && LanguageModes[i]->defTipsFile)
3854 if (AddTagsFile( LanguageModes[i]->defTipsFile, TIP ) == FALSE)
3855 fprintf( stderr, "Error loading default calltips file:\n"
3856 " \"%s\"\n", LanguageModes[mode]->defTipsFile );
3859 /* Set delimiters for all text widgets */
3860 if (mode == PLAIN_LANGUAGE_MODE || LanguageModes[mode]->delimiters == NULL)
3861 delimiters = GetPrefDelimiters();
3862 else
3863 delimiters = LanguageModes[mode]->delimiters;
3864 XtVaSetValues(window->textArea, textNwordDelimiters, delimiters, NULL);
3865 for (i=0; i<window->nPanes; i++)
3866 XtVaSetValues(window->textPanes[i], textNautoIndent, delimiters, NULL);
3868 /* Decide on desired values for language-specific parameters. If a
3869 parameter was set to its default value, set it to the new default,
3870 otherwise, leave it alone */
3871 wrapModeIsDef = window->wrapMode == GetPrefWrap(oldMode);
3872 tabDistIsDef = BufGetTabDistance(window->buffer) == GetPrefTabDist(oldMode);
3873 XtVaGetValues(window->textArea, textNemulateTabs, &oldEmTabDist, NULL);
3874 emTabDistIsDef = oldEmTabDist == GetPrefEmTabDist(oldMode);
3875 indentStyleIsDef = window->indentStyle == GetPrefAutoIndent(oldMode) ||
3876 (GetPrefAutoIndent(oldMode) == SMART_INDENT &&
3877 window->indentStyle == AUTO_INDENT &&
3878 !SmartIndentMacrosAvailable(LanguageModeName(oldMode)));
3879 highlightIsDef = window->highlightSyntax == GetPrefHighlightSyntax()
3880 || (GetPrefHighlightSyntax() &&
3881 FindPatternSet(LanguageModeName(oldMode)) == NULL);
3882 wrapMode = wrapModeIsDef || forceDefaults ?
3883 GetPrefWrap(mode) : window->wrapMode;
3884 tabDist = tabDistIsDef || forceDefaults ?
3885 GetPrefTabDist(mode) : BufGetTabDistance(window->buffer);
3886 emTabDist = emTabDistIsDef || forceDefaults ?
3887 GetPrefEmTabDist(mode) : oldEmTabDist;
3888 indentStyle = indentStyleIsDef || forceDefaults ?
3889 GetPrefAutoIndent(mode) : window->indentStyle;
3890 highlight = highlightIsDef || forceDefaults ?
3891 GetPrefHighlightSyntax() : window->highlightSyntax;
3893 /* Dim/undim smart-indent and highlighting menu items depending on
3894 whether patterns/macros are available */
3895 haveHighlightPatterns = FindPatternSet(LanguageModeName(mode)) != NULL;
3896 haveSmartIndentMacros = SmartIndentMacrosAvailable(LanguageModeName(mode));
3897 XtSetSensitive(window->highlightItem, haveHighlightPatterns);
3898 XtSetSensitive(window->smartIndentItem, haveSmartIndentMacros);
3900 /* Turn off requested options which are not available */
3901 highlight = haveHighlightPatterns && highlight;
3902 if (indentStyle == SMART_INDENT && !haveSmartIndentMacros)
3903 indentStyle = AUTO_INDENT;
3905 /* Change highlighting */
3906 window->highlightSyntax = highlight;
3907 XmToggleButtonSetState(window->highlightItem, highlight, False);
3908 StopHighlighting(window);
3909 if (highlight)
3910 StartHighlighting(window, False);
3912 /* Force a change of smart indent macros (SetAutoIndent will re-start) */
3913 if (window->indentStyle == SMART_INDENT) {
3914 EndSmartIndent(window);
3915 window->indentStyle = AUTO_INDENT;
3918 /* set requested wrap, indent, and tabs */
3919 SetAutoWrap(window, wrapMode);
3920 SetAutoIndent(window, indentStyle);
3921 SetTabDist(window, tabDist);
3922 SetEmTabDist(window, emTabDist);
3924 /* Add/remove language specific menu items */
3925 #ifndef VMS
3926 UpdateShellMenu(window);
3927 #endif
3928 UpdateMacroMenu(window);
3929 UpdateBGMenu(window);
3933 ** Find and return the name of the appropriate languange mode for
3934 ** the file in "window". Returns a pointer to a string, which will
3935 ** remain valid until a change is made to the language modes list.
3937 static int matchLanguageMode(WindowInfo *window)
3939 char *ext, *first200;
3940 int i, j, fileNameLen, extLen, beginPos, endPos, start;
3941 const char *versionExtendedPath;
3943 /*... look for an explicit mode statement first */
3945 /* Do a regular expression search on for recognition pattern */
3946 first200 = BufGetRange(window->buffer, 0, 200);
3947 for (i=0; i<NLanguageModes; i++) {
3948 if (LanguageModes[i]->recognitionExpr != NULL) {
3949 if (SearchString(first200, LanguageModes[i]->recognitionExpr,
3950 SEARCH_FORWARD, SEARCH_REGEX, False, 0, &beginPos,
3951 &endPos, NULL, NULL, NULL))
3953 XtFree(first200);
3954 return i;
3958 XtFree(first200);
3960 /* Look at file extension ("@@/" starts a ClearCase version extended path,
3961 which gets appended after the file extension, and therefore must be
3962 stripped off to recognize the extension to make ClearCase users happy) */
3963 fileNameLen = strlen(window->filename);
3964 #ifdef VMS
3965 if (strchr(window->filename, ';') != NULL)
3966 fileNameLen = strchr(window->filename, ';') - window->filename;
3967 #else
3968 if ((versionExtendedPath = GetClearCaseVersionExtendedPath(window->filename)) != NULL)
3969 fileNameLen = versionExtendedPath - window->filename;
3970 #endif
3971 for (i=0; i<NLanguageModes; i++) {
3972 for (j=0; j<LanguageModes[i]->nExtensions; j++) {
3973 ext = LanguageModes[i]->extensions[j];
3974 extLen = strlen(ext);
3975 start = fileNameLen - extLen;
3976 #if defined(__VMS) && (__VMS_VER >= 70200000)
3977 /* VMS v7.2 has case-preserving filenames */
3978 if (start >= 0 && !strncasecmp(&window->filename[start], ext, extLen))
3979 return i;
3980 #else
3981 if (start >= 0 && !strncmp(&window->filename[start], ext, extLen))
3982 return i;
3983 #endif
3987 /* no appropriate mode was found */
3988 return PLAIN_LANGUAGE_MODE;
3991 static int loadLanguageModesString(char *inString, int fileVer)
3993 char *errMsg, *styleName, *inPtr = inString;
3994 languageModeRec *lm;
3995 int i;
3997 for (;;) {
3999 /* skip over blank space */
4000 inPtr += strspn(inPtr, " \t\n");
4002 /* Allocate a language mode structure to return, set unread fields to
4003 empty so everything can be freed on errors by freeLanguageModeRec */
4004 lm = (languageModeRec *)XtMalloc(sizeof(languageModeRec));
4005 lm->nExtensions = 0;
4006 lm->recognitionExpr = NULL;
4007 lm->defTipsFile = NULL;
4008 lm->delimiters = NULL;
4010 /* read language mode name */
4011 lm->name = ReadSymbolicField(&inPtr);
4012 if (lm->name == NULL) {
4013 XtFree((char *)lm);
4014 return modeError(NULL,inString,inPtr,"language mode name required");
4016 if (!SkipDelimiter(&inPtr, &errMsg))
4017 return modeError(lm, inString, inPtr, errMsg);
4019 /* read list of extensions */
4020 lm->extensions = readExtensionList(&inPtr,
4021 &lm->nExtensions);
4022 if (!SkipDelimiter(&inPtr, &errMsg))
4023 return modeError(lm, inString, inPtr, errMsg);
4025 /* read the recognition regular expression */
4026 if (*inPtr == '\n' || *inPtr == '\0' || *inPtr == ':')
4027 lm->recognitionExpr = NULL;
4028 else if (!ReadQuotedString(&inPtr, &errMsg, &lm->recognitionExpr))
4029 return modeError(lm, inString,inPtr, errMsg);
4030 if (!SkipDelimiter(&inPtr, &errMsg))
4031 return modeError(lm, inString, inPtr, errMsg);
4033 /* read the indent style */
4034 styleName = ReadSymbolicField(&inPtr);
4035 if (styleName == NULL)
4036 lm->indentStyle = DEFAULT_INDENT;
4037 else {
4038 for (i=0; i<N_INDENT_STYLES; i++) {
4039 if (!strcmp(styleName, AutoIndentTypes[i])) {
4040 lm->indentStyle = i;
4041 break;
4044 XtFree(styleName);
4045 if (i == N_INDENT_STYLES)
4046 return modeError(lm,inString,inPtr,"unrecognized indent style");
4048 if (!SkipDelimiter(&inPtr, &errMsg))
4049 return modeError(lm, inString, inPtr, errMsg);
4051 /* read the wrap style */
4052 styleName = ReadSymbolicField(&inPtr);
4053 if (styleName == NULL)
4054 lm->wrapStyle = DEFAULT_WRAP;
4055 else {
4056 for (i=0; i<N_WRAP_STYLES; i++) {
4057 if (!strcmp(styleName, AutoWrapTypes[i])) {
4058 lm->wrapStyle = i;
4059 break;
4062 XtFree(styleName);
4063 if (i == N_WRAP_STYLES)
4064 return modeError(lm, inString, inPtr,"unrecognized wrap style");
4066 if (!SkipDelimiter(&inPtr, &errMsg))
4067 return modeError(lm, inString, inPtr, errMsg);
4069 /* read the tab distance */
4070 if (*inPtr == '\n' || *inPtr == '\0' || *inPtr == ':')
4071 lm->tabDist = DEFAULT_TAB_DIST;
4072 else if (!ReadNumericField(&inPtr, &lm->tabDist))
4073 return modeError(lm, inString, inPtr, "bad tab spacing");
4074 if (!SkipDelimiter(&inPtr, &errMsg))
4075 return modeError(lm, inString, inPtr, errMsg);
4077 /* read emulated tab distance */
4078 if (*inPtr == '\n' || *inPtr == '\0' || *inPtr == ':')
4079 lm->emTabDist = DEFAULT_EM_TAB_DIST;
4080 else if (!ReadNumericField(&inPtr, &lm->emTabDist))
4081 return modeError(lm, inString, inPtr, "bad emulated tab spacing");
4082 if (!SkipDelimiter(&inPtr, &errMsg))
4083 return modeError(lm, inString, inPtr, errMsg);
4085 /* read the delimiters string */
4086 if (*inPtr == '\n' || *inPtr == '\0' || *inPtr == ':')
4087 lm->delimiters = NULL;
4088 else if (!ReadQuotedString(&inPtr, &errMsg, &lm->delimiters))
4089 return modeError(lm, inString, inPtr, errMsg);
4091 /* After 5.3 all language modes need a default tips file field */
4092 if (!SkipDelimiter(&inPtr, &errMsg))
4093 if (fileVer > 5003)
4094 return modeError(lm, inString, inPtr, errMsg);
4096 /* read the default tips file */
4097 if (*inPtr == '\n' || *inPtr == '\0')
4098 lm->defTipsFile = NULL;
4099 else if (!ReadQuotedString(&inPtr, &errMsg, &lm->defTipsFile))
4100 return modeError(lm, inString, inPtr, errMsg);
4102 /* pattern set was read correctly, add/replace it in the list */
4103 for (i=0; i<NLanguageModes; i++) {
4104 if (!strcmp(LanguageModes[i]->name, lm->name)) {
4105 freeLanguageModeRec(LanguageModes[i]);
4106 LanguageModes[i] = lm;
4107 break;
4110 if (i == NLanguageModes) {
4111 LanguageModes[NLanguageModes++] = lm;
4112 if (NLanguageModes > MAX_LANGUAGE_MODES)
4113 return modeError(NULL, inString, inPtr,
4114 "maximum allowable number of language modes exceeded");
4117 /* if the string ends here, we're done */
4118 inPtr += strspn(inPtr, " \t\n");
4119 if (*inPtr == '\0')
4120 return True;
4121 } /* End for(;;) */
4124 static char *writeLanguageModesString(void)
4126 int i;
4127 char *outStr, *escapedStr, *str, numBuf[25];
4128 textBuffer *outBuf;
4130 outBuf = BufCreate();
4131 for (i=0; i<NLanguageModes; i++) {
4132 BufInsert(outBuf, outBuf->length, "\t");
4133 BufInsert(outBuf, outBuf->length, LanguageModes[i]->name);
4134 BufInsert(outBuf, outBuf->length, ":");
4135 BufInsert(outBuf, outBuf->length, str = createExtString(
4136 LanguageModes[i]->extensions, LanguageModes[i]->nExtensions));
4137 XtFree(str);
4138 BufInsert(outBuf, outBuf->length, ":");
4139 if (LanguageModes[i]->recognitionExpr != NULL) {
4140 BufInsert(outBuf, outBuf->length,
4141 str=MakeQuotedString(LanguageModes[i]->recognitionExpr));
4142 XtFree(str);
4144 BufInsert(outBuf, outBuf->length, ":");
4145 if (LanguageModes[i]->indentStyle != DEFAULT_INDENT)
4146 BufInsert(outBuf, outBuf->length,
4147 AutoIndentTypes[LanguageModes[i]->indentStyle]);
4148 BufInsert(outBuf, outBuf->length, ":");
4149 if (LanguageModes[i]->wrapStyle != DEFAULT_WRAP)
4150 BufInsert(outBuf, outBuf->length,
4151 AutoWrapTypes[LanguageModes[i]->wrapStyle]);
4152 BufInsert(outBuf, outBuf->length, ":");
4153 if (LanguageModes[i]->tabDist != DEFAULT_TAB_DIST) {
4154 sprintf(numBuf, "%d", LanguageModes[i]->tabDist);
4155 BufInsert(outBuf, outBuf->length, numBuf);
4157 BufInsert(outBuf, outBuf->length, ":");
4158 if (LanguageModes[i]->emTabDist != DEFAULT_EM_TAB_DIST) {
4159 sprintf(numBuf, "%d", LanguageModes[i]->emTabDist);
4160 BufInsert(outBuf, outBuf->length, numBuf);
4162 BufInsert(outBuf, outBuf->length, ":");
4163 if (LanguageModes[i]->delimiters != NULL) {
4164 BufInsert(outBuf, outBuf->length,
4165 str=MakeQuotedString(LanguageModes[i]->delimiters));
4166 XtFree(str);
4168 BufInsert(outBuf, outBuf->length, ":");
4169 if (LanguageModes[i]->defTipsFile != NULL) {
4170 BufInsert(outBuf, outBuf->length,
4171 str=MakeQuotedString(LanguageModes[i]->defTipsFile));
4172 XtFree(str);
4175 BufInsert(outBuf, outBuf->length, "\n");
4178 /* Get the output, and lop off the trailing newline */
4179 outStr = BufGetRange(outBuf, 0, outBuf->length - 1);
4180 BufFree(outBuf);
4181 escapedStr = EscapeSensitiveChars(outStr);
4182 XtFree(outStr);
4183 return escapedStr;
4186 static char *createExtString(char **extensions, int nExtensions)
4188 int e, length = 1;
4189 char *outStr, *outPtr;
4191 for (e=0; e<nExtensions; e++)
4192 length += strlen(extensions[e]) + 1;
4193 outStr = outPtr = XtMalloc(length);
4194 for (e=0; e<nExtensions; e++) {
4195 strcpy(outPtr, extensions[e]);
4196 outPtr += strlen(extensions[e]);
4197 *outPtr++ = ' ';
4199 if (nExtensions == 0)
4200 *outPtr = '\0';
4201 else
4202 *(outPtr-1) = '\0';
4203 return outStr;
4206 static char **readExtensionList(char **inPtr, int *nExtensions)
4208 char *extensionList[MAX_FILE_EXTENSIONS];
4209 char **retList, *strStart;
4210 int i, len;
4212 /* skip over blank space */
4213 *inPtr += strspn(*inPtr, " \t");
4215 for (i=0; i<MAX_FILE_EXTENSIONS && **inPtr!=':' && **inPtr!='\0'; i++) {
4216 *inPtr += strspn(*inPtr, " \t");
4217 strStart = *inPtr;
4218 while (**inPtr!=' ' && **inPtr!='\t' && **inPtr!=':' && **inPtr!='\0')
4219 (*inPtr)++;
4220 len = *inPtr - strStart;
4221 extensionList[i] = XtMalloc(len + 1);
4222 strncpy(extensionList[i], strStart, len);
4223 extensionList[i][len] = '\0';
4225 *nExtensions = i;
4226 if (i == 0)
4227 return NULL;
4228 retList = (char **)XtMalloc(sizeof(char *) * i);
4229 memcpy(retList, extensionList, sizeof(char *) * i);
4230 return retList;
4233 int ReadNumericField(char **inPtr, int *value)
4235 int charsRead;
4237 /* skip over blank space */
4238 *inPtr += strspn(*inPtr, " \t");
4240 if (sscanf(*inPtr, "%d%n", value, &charsRead) != 1)
4241 return False;
4242 *inPtr += charsRead;
4243 return True;
4247 ** Parse a symbolic field, skipping initial and trailing whitespace,
4248 ** stops on first invalid character or end of string. Valid characters
4249 ** are letters, numbers, _, -, +, $, #, and internal whitespace. Internal
4250 ** whitespace is compressed to single space characters.
4252 char *ReadSymbolicField(char **inPtr)
4254 char *outStr, *outPtr, *strStart, *strPtr;
4255 int len;
4257 /* skip over initial blank space */
4258 *inPtr += strspn(*inPtr, " \t");
4260 /* Find the first invalid character or end of string to know how
4261 much memory to allocate for the returned string */
4262 strStart = *inPtr;
4263 while (isalnum((unsigned char)**inPtr) || **inPtr=='_' || **inPtr=='-' ||
4264 **inPtr=='+' || **inPtr=='$' || **inPtr=='#' || **inPtr==' ' ||
4265 **inPtr=='\t')
4266 (*inPtr)++;
4267 len = *inPtr - strStart;
4268 if (len == 0)
4269 return NULL;
4270 outStr = outPtr = XtMalloc(len + 1);
4272 /* Copy the string, compressing internal whitespace to a single space */
4273 strPtr = strStart;
4274 while (strPtr - strStart < len) {
4275 if (*strPtr == ' ' || *strPtr == '\t') {
4276 strPtr += strspn(strPtr, " \t");
4277 *outPtr++ = ' ';
4278 } else
4279 *outPtr++ = *strPtr++;
4282 /* If there's space on the end, take it back off */
4283 if (outPtr > outStr && *(outPtr-1) == ' ')
4284 outPtr--;
4285 if (outPtr == outStr) {
4286 XtFree(outStr);
4287 return NULL;
4289 *outPtr = '\0';
4290 return outStr;
4294 ** parse an individual quoted string. Anything between
4295 ** double quotes is acceptable, quote characters can be escaped by "".
4296 ** Returns allocated string "string" containing
4297 ** argument minus quotes. If not successful, returns False with
4298 ** (statically allocated) message in "errMsg".
4300 int ReadQuotedString(char **inPtr, char **errMsg, char **string)
4302 char *outPtr, *c;
4304 /* skip over blank space */
4305 *inPtr += strspn(*inPtr, " \t");
4307 /* look for initial quote */
4308 if (**inPtr != '\"') {
4309 *errMsg = "expecting quoted string";
4310 return False;
4312 (*inPtr)++;
4314 /* calculate max length and allocate returned string */
4315 for (c= *inPtr; ; c++) {
4316 if (*c == '\0') {
4317 *errMsg = "string not terminated";
4318 return False;
4319 } else if (*c == '\"') {
4320 if (*(c+1) == '\"')
4321 c++;
4322 else
4323 break;
4327 /* copy string up to end quote, transforming escaped quotes into quotes */
4328 *string = XtMalloc(c - *inPtr + 1);
4329 outPtr = *string;
4330 while (True) {
4331 if (**inPtr == '\"') {
4332 if (*(*inPtr+1) == '\"')
4333 (*inPtr)++;
4334 else
4335 break;
4337 *outPtr++ = *(*inPtr)++;
4339 *outPtr = '\0';
4341 /* skip end quote */
4342 (*inPtr)++;
4343 return True;
4347 ** Replace characters which the X resource file reader considers control
4348 ** characters, such that a string will read back as it appears in "string".
4349 ** (So far, newline characters are replaced with with \n\<newline> and
4350 ** backslashes with \\. This has not been tested exhaustively, and
4351 ** probably should be. It would certainly be more asthetic if other
4352 ** control characters were replaced as well).
4354 ** Returns an allocated string which must be freed by the caller with XtFree.
4356 char *EscapeSensitiveChars(const char *string)
4358 const char *c;
4359 char *outStr, *outPtr;
4360 int length = 0;
4362 /* calculate length and allocate returned string */
4363 for (c=string; *c!='\0'; c++) {
4364 if (*c == '\\')
4365 length++;
4366 else if (*c == '\n')
4367 length += 3;
4368 length++;
4370 outStr = XtMalloc(length + 1);
4371 outPtr = outStr;
4373 /* add backslashes */
4374 for (c=string; *c!='\0'; c++) {
4375 if (*c == '\\')
4376 *outPtr++ = '\\';
4377 else if (*c == '\n') {
4378 *outPtr++ = '\\';
4379 *outPtr++ = 'n';
4380 *outPtr++ = '\\';
4382 *outPtr++ = *c;
4384 *outPtr = '\0';
4385 return outStr;
4389 ** Adds double quotes around a string and escape existing double quote
4390 ** characters with two double quotes. Enables the string to be read back
4391 ** by ReadQuotedString.
4393 char *MakeQuotedString(const char *string)
4395 const char *c;
4396 char *outStr, *outPtr;
4397 int length = 0;
4399 /* calculate length and allocate returned string */
4400 for (c=string; *c!='\0'; c++) {
4401 if (*c == '\"')
4402 length++;
4403 length++;
4405 outStr = XtMalloc(length + 3);
4406 outPtr = outStr;
4408 /* add starting quote */
4409 *outPtr++ = '\"';
4411 /* copy string, escaping quotes with "" */
4412 for (c=string; *c!='\0'; c++) {
4413 if (*c == '\"')
4414 *outPtr++ = '\"';
4415 *outPtr++ = *c;
4418 /* add ending quote */
4419 *outPtr++ = '\"';
4421 /* terminate string and return */
4422 *outPtr = '\0';
4423 return outStr;
4427 ** Read a dialog text field containing a symbolic name (language mode names,
4428 ** style names, highlight pattern names, colors, and fonts), clean the
4429 ** entered text of leading and trailing whitespace, compress all
4430 ** internal whitespace to one space character, and check it over for
4431 ** colons, which interfere with the preferences file reader/writer syntax.
4432 ** Returns NULL on error, and puts up a dialog if silent is False. Returns
4433 ** an empty string if the text field is blank.
4435 char *ReadSymbolicFieldTextWidget(Widget textW, const char *fieldName, int silent)
4437 char *string, *stringPtr, *parsedString;
4439 /* read from the text widget */
4440 string = stringPtr = XmTextGetString(textW);
4442 /* parse it with the same routine used to read symbolic fields from
4443 files. If the string is not read entirely, there are invalid
4444 characters, so warn the user if not in silent mode. */
4445 parsedString = ReadSymbolicField(&stringPtr);
4446 if (*stringPtr != '\0') {
4447 if (!silent) {
4448 *(stringPtr+1) = '\0';
4449 DialogF(DF_WARN, textW, 1,"Invalid character \"%s\" in %s",
4450 "Dismiss", stringPtr, fieldName);
4451 XmProcessTraversal(textW, XmTRAVERSE_CURRENT);
4453 XtFree(string);
4454 if (parsedString != NULL)
4455 XtFree(parsedString);
4456 return NULL;
4458 XtFree(string);
4459 if (parsedString == NULL) {
4460 parsedString = XtMalloc(1);
4461 *parsedString = '\0';
4463 return parsedString;
4467 ** Create a pulldown menu pane with the names of the current language modes.
4468 ** XmNuserData for each item contains the language mode name.
4470 Widget CreateLanguageModeMenu(Widget parent, XtCallbackProc cbProc, void *cbArg)
4472 Widget menu, btn;
4473 int i;
4474 XmString s1;
4476 menu = CreatePulldownMenu(parent, "languageModes", NULL, 0);
4477 for (i=0; i<NLanguageModes; i++) {
4478 btn = XtVaCreateManagedWidget("languageMode", xmPushButtonGadgetClass,
4479 menu,
4480 XmNlabelString, s1=XmStringCreateSimple(LanguageModes[i]->name),
4481 XmNmarginHeight, 0,
4482 XmNuserData, (void *)LanguageModes[i]->name, NULL);
4483 XmStringFree(s1);
4484 XtAddCallback(btn, XmNactivateCallback, cbProc, cbArg);
4486 return menu;
4490 ** Set the language mode menu in option menu "optMenu" to
4491 ** show a particular language mode
4493 void SetLangModeMenu(Widget optMenu, const char *modeName)
4495 int i;
4496 Cardinal nItems;
4497 WidgetList items;
4498 Widget pulldown, selectedItem;
4499 char *itemName;
4501 XtVaGetValues(optMenu, XmNsubMenuId, &pulldown, NULL);
4502 XtVaGetValues(pulldown, XmNchildren, &items, XmNnumChildren, &nItems, NULL);
4503 if (nItems == 0)
4504 return;
4505 selectedItem = items[0];
4506 for (i=0; i<(int)nItems; i++) {
4507 XtVaGetValues(items[i], XmNuserData, &itemName, NULL);
4508 if (!strcmp(itemName, modeName)) {
4509 selectedItem = items[i];
4510 break;
4513 XtVaSetValues(optMenu, XmNmenuHistory, selectedItem,NULL);
4517 ** Create a submenu for chosing language mode for the current window.
4519 Widget CreateLanguageModeSubMenu(WindowInfo *window, Widget parent, char *name,
4520 char *label, char mnemonic)
4522 XmString s1=XmStringCreateSimple(label);
4524 window->langModeCascade = XtVaCreateManagedWidget(name,
4525 xmCascadeButtonGadgetClass, parent, XmNlabelString,
4526 s1, XmNmnemonic, mnemonic,
4527 XmNsubMenuId, NULL, NULL);
4528 XmStringFree(s1);
4529 updateLanguageModeSubmenu(window);
4530 return window->langModeCascade;
4534 ** Re-build the language mode sub-menu using the current data stored
4535 ** in the master list: LanguageModes.
4537 static void updateLanguageModeSubmenu(WindowInfo *window)
4539 int i;
4540 XmString s1;
4541 Widget menu, btn;
4542 Arg args[1] = {{XmNradioBehavior, (XtArgVal)True}};
4544 /* Destroy and re-create the menu pane */
4545 XtVaGetValues(window->langModeCascade, XmNsubMenuId, &menu, NULL);
4546 if (menu != NULL)
4547 XtDestroyWidget(menu);
4548 menu = CreatePulldownMenu(XtParent(window->langModeCascade),
4549 "languageModes", args, 1);
4550 btn = XtVaCreateManagedWidget("languageMode",
4551 xmToggleButtonGadgetClass, menu,
4552 XmNlabelString, s1=XmStringCreateSimple("Plain"),
4553 XmNuserData, (void *)PLAIN_LANGUAGE_MODE,
4554 XmNset, window->languageMode==PLAIN_LANGUAGE_MODE, NULL);
4555 XmStringFree(s1);
4556 XtAddCallback(btn, XmNvalueChangedCallback, setLangModeCB, window);
4557 for (i=0; i<NLanguageModes; i++) {
4558 btn = XtVaCreateManagedWidget("languageMode",
4559 xmToggleButtonGadgetClass, menu,
4560 XmNlabelString, s1=XmStringCreateSimple(LanguageModes[i]->name),
4561 XmNmarginHeight, 0,
4562 XmNuserData, (void *)i,
4563 XmNset, window->languageMode==i, NULL);
4564 XmStringFree(s1);
4565 XtAddCallback(btn, XmNvalueChangedCallback, setLangModeCB, window);
4567 XtVaSetValues(window->langModeCascade, XmNsubMenuId, menu, NULL);
4570 static void setLangModeCB(Widget w, XtPointer clientData, XtPointer callData)
4572 WindowInfo *window = (WindowInfo *)clientData;
4573 char *params[1];
4574 void *mode;
4576 if (!XmToggleButtonGetState(w))
4577 return;
4579 /* get name of language mode stored in userData field of menu item */
4580 XtVaGetValues(w, XmNuserData, &mode, NULL);
4582 /* If the mode didn't change, do nothing */
4583 if (window->languageMode == (int)mode)
4584 return;
4586 /* redo syntax highlighting word delimiters, etc. */
4588 reapplyLanguageMode(window, (int)mode, False);
4590 params[0] = (((int)mode) == PLAIN_LANGUAGE_MODE) ? "" : LanguageModes[(int)mode]->name;
4591 XtCallActionProc(window->textArea, "set_language_mode", NULL, params, 1);
4595 ** Skip a delimiter and it's surrounding whitespace
4597 int SkipDelimiter(char **inPtr, char **errMsg)
4599 *inPtr += strspn(*inPtr, " \t");
4600 if (**inPtr != ':') {
4601 *errMsg = "syntax error";
4602 return False;
4604 (*inPtr)++;
4605 *inPtr += strspn(*inPtr, " \t");
4606 return True;
4610 ** Short-hand error processing for language mode parsing errors, frees
4611 ** lm (if non-null), prints a formatted message explaining where the
4612 ** error is, and returns False;
4614 static int modeError(languageModeRec *lm, const char *stringStart,
4615 const char *stoppedAt, const char *message)
4617 if (lm != NULL)
4618 freeLanguageModeRec(lm);
4619 return ParseError(NULL, stringStart, stoppedAt,
4620 "language mode specification", message);
4624 ** Report parsing errors in resource strings or macros, formatted nicely so
4625 ** the user can tell where things became botched. Errors can be sent either
4626 ** to stderr, or displayed in a dialog. For stderr, pass toDialog as NULL.
4627 ** For a dialog, pass the dialog parent in toDialog.
4629 int ParseError(Widget toDialog, const char *stringStart, const char *stoppedAt,
4630 const char *errorIn, const char *message)
4632 int len, nNonWhite = 0;
4633 const char *c;
4634 char *errorLine;
4636 for (c=stoppedAt; c>=stringStart; c--) {
4637 if (c == stringStart)
4638 break;
4639 else if (*c == '\n' && nNonWhite >= 5)
4640 break;
4641 else if (*c != ' ' && *c != '\t')
4642 nNonWhite++;
4644 len = stoppedAt - c + (*stoppedAt == '\0' ? 0 : 1);
4645 errorLine = XtMalloc(len+4);
4646 strncpy(errorLine, c, len);
4647 errorLine[len++] = '<';
4648 errorLine[len++] = '=';
4649 errorLine[len++] = '=';
4650 errorLine[len] = '\0';
4651 if (toDialog == NULL)
4652 fprintf(stderr, "NEdit: %s in %s:\n%s\n", message, errorIn, errorLine);
4653 else
4654 DialogF(DF_WARN, toDialog, 1, "%s in %s:\n%s", "Dismiss", message,
4655 errorIn, errorLine);
4656 XtFree(errorLine);
4657 return False;
4661 ** Compare two strings which may be NULL
4663 int AllocatedStringsDiffer(const char *s1, const char *s2)
4665 if (s1 == NULL && s2 == NULL)
4666 return False;
4667 if (s1 == NULL || s2 == NULL)
4668 return True;
4669 return strcmp(s1, s2);
4672 static void updatePatternsTo5dot1(void)
4674 const char *htmlDefaultExpr = "^[ \t]*HTML[ \t]*:[ \t]*Default[ \t]*$";
4675 const char *vhdlAnchorExpr = "^[ \t]*VHDL:";
4677 /* Add new patterns if there aren't already existing patterns with
4678 the same name. If possible, insert before VHDL in language mode
4679 list. If not, just add to end */
4680 if (!regexFind(TempStringPrefs.highlight, "^[ \t]*PostScript:"))
4681 spliceString(&TempStringPrefs.highlight, "PostScript:Default",
4682 vhdlAnchorExpr);
4683 if (!regexFind(TempStringPrefs.language, "^[ \t]*PostScript:"))
4684 spliceString(&TempStringPrefs.language,
4685 "PostScript:.ps .PS .eps .EPS .epsf .epsi::::::",
4686 vhdlAnchorExpr);
4687 if (!regexFind(TempStringPrefs.highlight, "^[ \t]*Lex:"))
4688 spliceString(&TempStringPrefs.highlight, "Lex:Default",
4689 vhdlAnchorExpr);
4690 if (!regexFind(TempStringPrefs.language, "^[ \t]*Lex:"))
4691 spliceString(&TempStringPrefs.language, "Lex:.lex::::::",
4692 vhdlAnchorExpr);
4693 if (!regexFind(TempStringPrefs.highlight, "^[ \t]*SQL:"))
4694 spliceString(&TempStringPrefs.highlight, "SQL:Default",
4695 vhdlAnchorExpr);
4696 if (!regexFind(TempStringPrefs.language, "^[ \t]*SQL:"))
4697 spliceString(&TempStringPrefs.language, "SQL:.sql::::::",
4698 vhdlAnchorExpr);
4699 if (!regexFind(TempStringPrefs.highlight, "^[ \t]*Matlab:"))
4700 spliceString(&TempStringPrefs.highlight, "Matlab:Default",
4701 vhdlAnchorExpr);
4702 if (!regexFind(TempStringPrefs.language, "^[ \t]*Matlab:"))
4703 spliceString(&TempStringPrefs.language, "Matlab:..m .oct .sci::::::",
4704 vhdlAnchorExpr);
4705 if (!regexFind(TempStringPrefs.smartIndent, "^[ \t]*Matlab:"))
4706 spliceString(&TempStringPrefs.smartIndent, "Matlab:Default", NULL);
4707 if (!regexFind(TempStringPrefs.styles, "^[ \t]*Label:"))
4708 spliceString(&TempStringPrefs.styles, "Label:red:Italic",
4709 "^[ \t]*Flag:");
4710 if (!regexFind(TempStringPrefs.styles, "^[ \t]*Storage Type1:"))
4711 spliceString(&TempStringPrefs.styles, "Storage Type1:saddle brown:Bold",
4712 "^[ \t]*String:");
4714 /* Replace html pattern with sgml html pattern, as long as there
4715 isn't an existing html pattern which will be overwritten */
4716 if (regexFind(TempStringPrefs.highlight, htmlDefaultExpr)) {
4717 regexReplace(&TempStringPrefs.highlight, htmlDefaultExpr,
4718 "SGML HTML:Default");
4719 if (!regexReplace(&TempStringPrefs.language, "^[ \t]*HTML:.*$",
4720 "SGML HTML:.sgml .sgm .html .htm:\"\\<(?ihtml)\\>\":::::\n")) {
4721 spliceString(&TempStringPrefs.language,
4722 "SGML HTML:.sgml .sgm .html .htm:\"\\<(?ihtml)\\>\":::::\n",
4723 vhdlAnchorExpr);
4728 static void updatePatternsTo5dot2(void)
4730 #ifdef VMS
4731 const char *cppLm5dot1 =
4732 "^[ \t]*C\\+\\+:\\.CC \\.HH \\.I::::::\"\\.,/\\\\`'!\\|@#%\\^&\\*\\(\\)-=\\+\\{\\}\\[\\]\"\":;\\<\\>\\?~\"";
4733 const char *perlLm5dot1 =
4734 "^[ \t]*Perl:\\.PL \\.PM \\.P5:\"\\^\\[ \\\\t\\]\\*#\\[ \\\\t\\]\\*!\\.\\*perl\":::::";
4735 const char *psLm5dot1 =
4736 "^[ \t]*PostScript:\\.ps \\.PS \\.eps \\.EPS \\.epsf \\.epsi:\"\\^%!\":::::\"/%\\(\\)\\{\\}\\[\\]\\<\\>\"";
4737 const char *tclLm5dot1 = "^[ \t]*Tcl:\\.TCL::::::";
4739 const char *cppLm5dot2 =
4740 "C++:.CC .HH .C .H .I .CXX .HXX .CPP::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\"";
4741 const char *perlLm5dot2 =
4742 "Perl:.PL .PM .P5:\"^[ \\t]*#[ \\t]*!.*perl\":Auto:None:::\".,/\\\\`'!$@#%^&*()-=+{}[]\"\":;<>?~|\"";
4743 const char *psLm5dot2 =
4744 "PostScript:.ps .PS .eps .EPS .epsf .epsi:\"^%!\":::::\"/%(){}[]<>\"";
4745 const char *tclLm5dot2 =
4746 "Tcl:.TCL::Smart:None:::";
4747 #else
4748 const char *cppLm5dot1 =
4749 "^[ \t]*C\\+\\+:\\.cc \\.hh \\.C \\.H \\.i \\.cxx \\.hxx::::::\"\\.,/\\\\`'!\\|@#%\\^&\\*\\(\\)-=\\+\\{\\}\\[\\]\"\":;\\<\\>\\?~\"";
4750 const char *perlLm5dot1 =
4751 "^[ \t]*Perl:\\.pl \\.pm \\.p5:\"\\^\\[ \\\\t\\]\\*#\\[ \\\\t\\]\\*!\\.\\*perl\":::::";
4752 const char *psLm5dot1 =
4753 "^[ \t]*PostScript:\\.ps \\.PS \\.eps \\.EPS \\.epsf \\.epsi:\"\\^%!\":::::\"/%\\(\\)\\{\\}\\[\\]\\<\\>\"";
4754 const char *shLm5dot1 =
4755 "^[ \t]*Sh Ksh Bash:\\.sh \\.bash \\.ksh \\.profile:\"\\^\\[ \\\\t\\]\\*#\\[ \\\\t\\]\\*!\\[ \\\\t\\]\\*/bin/\\(sh\\|ksh\\|bash\\)\":::::";
4756 const char *tclLm5dot1 = "^[ \t]*Tcl:\\.tcl::::::";
4758 const char *cppLm5dot2 =
4759 "C++:.cc .hh .C .H .i .cxx .hxx .cpp::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\"";
4760 const char *perlLm5dot2 =
4761 "Perl:.pl .pm .p5 .PL:\"^[ \\t]*#[ \\t]*!.*perl\":Auto:None:::\".,/\\\\`'!$@#%^&*()-=+{}[]\"\":;<>?~|\"";
4762 const char *psLm5dot2 =
4763 "PostScript:.ps .eps .epsf .epsi:\"^%!\":::::\"/%(){}[]<>\"";
4764 const char *shLm5dot2 =
4765 "Sh Ksh Bash:.sh .bash .ksh .profile .bashrc .bash_logout .bash_login .bash_profile:\"^[ \\t]*#[ \\t]*![ \\t]*/.*bin/(sh|ksh|bash)\":::::";
4766 const char *tclLm5dot2 =
4767 "Tcl:.tcl .tk .itcl .itk::Smart:None:::";
4768 #endif /* VMS */
4770 const char *cssLm5dot2 =
4771 "CSS:css::Auto:None:::\".,/\\`'!|@#%^&*()=+{}[]\"\":;<>?~\"";
4772 const char *reLm5dot2 =
4773 "Regex:.reg .regex:\"\\(\\?[:#=!iInN].+\\)\":None:Continuous:::";
4774 const char *xmlLm5dot2 =
4775 "XML:.xml .xsl .dtd:\"\\<(?i\\?xml|!doctype)\"::None:::\"<>/=\"\"'()+*?|\"";
4777 const char *cssHl5dot2 = "CSS:Default";
4778 const char *reHl5dot2 = "Regex:Default";
4779 const char *xmlHl5dot2 = "XML:Default";
4781 const char *ptrStyle = "Pointer:#660000:Bold";
4782 const char *reStyle = "Regex:#009944:Bold";
4783 const char *wrnStyle = "Warning:brown2:Italic";
4785 /* First upgrade modified language modes, only if the user hasn't
4786 altered the default 5.1 definitions. */
4787 if (regexFind(TempStringPrefs.language, cppLm5dot1))
4788 regexReplace(&TempStringPrefs.language, cppLm5dot1, cppLm5dot2);
4789 if (regexFind(TempStringPrefs.language, perlLm5dot1))
4790 regexReplace(&TempStringPrefs.language, perlLm5dot1, perlLm5dot2);
4791 if (regexFind(TempStringPrefs.language, psLm5dot1))
4792 regexReplace(&TempStringPrefs.language, psLm5dot1, psLm5dot2);
4793 #ifndef VMS
4794 if (regexFind(TempStringPrefs.language, shLm5dot1))
4795 regexReplace(&TempStringPrefs.language, shLm5dot1, shLm5dot2);
4796 #endif
4797 if (regexFind(TempStringPrefs.language, tclLm5dot1))
4798 regexReplace(&TempStringPrefs.language, tclLm5dot1, tclLm5dot2);
4800 /* Then append the new modes (trying to keep them in alphabetical order
4801 makes no sense, since 5.1 didn't use alphabetical order). */
4802 if (!regexFind(TempStringPrefs.language, "^[ \t]*CSS:"))
4803 spliceString(&TempStringPrefs.language, cssLm5dot2, NULL);
4804 if (!regexFind(TempStringPrefs.language, "^[ \t]*Regex:"))
4805 spliceString(&TempStringPrefs.language, reLm5dot2, NULL);
4806 if (!regexFind(TempStringPrefs.language, "^[ \t]*XML:"))
4807 spliceString(&TempStringPrefs.language, xmlLm5dot2, NULL);
4809 /* Enable default highlighting patterns for these modes, unless already
4810 present */
4811 if (!regexFind(TempStringPrefs.highlight, "^[ \t]*CSS:"))
4812 spliceString(&TempStringPrefs.highlight, cssHl5dot2, NULL);
4813 if (!regexFind(TempStringPrefs.highlight, "^[ \t]*Regex:"))
4814 spliceString(&TempStringPrefs.highlight, reHl5dot2, NULL);
4815 if (!regexFind(TempStringPrefs.highlight, "^[ \t]*XML:"))
4816 spliceString(&TempStringPrefs.highlight, xmlHl5dot2, NULL);
4818 /* Finally, append the new highlight styles */
4820 if (!regexFind(TempStringPrefs.styles, "^[ \t]*Warning:"))
4821 spliceString(&TempStringPrefs.styles, wrnStyle, NULL);
4822 if (!regexFind(TempStringPrefs.styles, "^[ \t]*Regex:"))
4823 spliceString(&TempStringPrefs.styles, reStyle, "^[ \t]*Warning:");
4824 if (!regexFind(TempStringPrefs.styles, "^[ \t]*Pointer:"))
4825 spliceString(&TempStringPrefs.styles, ptrStyle, "^[ \t]*Regex:");
4828 static void updatePatternsTo5dot3(void)
4830 /* This is a bogus function on non-VMS */
4831 #ifdef VMS
4832 const char *psLm5dot2 =
4833 "^[ \t]*PostScript:\\.ps \\.PS \\.eps \\.EPS \\.epsf \\.epsi:\"\\^%!\":::::\"/%\\(\\)\\{\\}\\[\\]\\<\\>\"";
4835 const char *psLm5dot3 =
4836 "PostScript:.ps .PS .eps .EPS .epsf .EPSF .epsi .EPSI:\"^%!\":::::\"/%(){}[]<>\"";
4838 /* Upgrade modified language modes, only if the user hasn't
4839 altered the default 5.2 definitions. */
4840 if (regexFind(TempStringPrefs.language, psLm5dot2))
4841 regexReplace(&TempStringPrefs.language, psLm5dot2, psLm5dot3);
4842 #endif
4846 ** Inserts a string into intoString, reallocating it with XtMalloc. If
4847 ** regular expression atExpr is found, inserts the string before atExpr
4848 ** followed by a newline. If atExpr is not found, inserts insertString
4849 ** at the end, PRECEDED by a newline.
4851 static void spliceString(char **intoString, const char *insertString, const char *atExpr)
4853 int beginPos, endPos;
4854 int intoLen = strlen(*intoString);
4855 int insertLen = strlen(insertString);
4856 char *newString = XtMalloc(intoLen + insertLen + 2);
4858 if (atExpr != NULL && SearchString(*intoString, atExpr,
4859 SEARCH_FORWARD, SEARCH_REGEX, False, 0, &beginPos, &endPos,
4860 NULL, NULL, NULL)) {
4861 strncpy(newString, *intoString, beginPos);
4862 strncpy(&newString[beginPos], insertString, insertLen);
4863 newString[beginPos+insertLen] = '\n';
4864 strncpy(&newString[beginPos+insertLen+1],
4865 &((*intoString)[beginPos]), intoLen - beginPos);
4866 } else {
4867 strncpy(newString, *intoString, intoLen);
4868 newString[intoLen] = '\n';
4869 strncpy(&newString[intoLen+1], insertString, insertLen);
4871 newString[intoLen + insertLen + 1] = '\0';
4872 XtFree(*intoString);
4873 *intoString = newString;
4877 ** Simplified regular expression search routine which just returns true
4878 ** or false depending on whether inString matches expr
4880 static int regexFind(const char *inString, const char *expr)
4882 int beginPos, endPos;
4883 return SearchString(inString, expr, SEARCH_FORWARD, SEARCH_REGEX, False,
4884 0, &beginPos, &endPos, NULL, NULL, NULL);
4888 ** Simplified regular expression replacement routine which replaces the
4889 ** first occurence of expr in inString with replaceWith, reallocating
4890 ** inString with XtMalloc. If expr is not found, does nothing and
4891 ** returns false.
4893 static int regexReplace(char **inString, const char *expr, const char *replaceWith)
4895 int beginPos, endPos, newLen;
4896 char *newString;
4897 int replaceLen = strlen(replaceWith);
4898 int inLen = strlen(*inString);
4900 if (!SearchString(*inString, expr, SEARCH_FORWARD, SEARCH_REGEX, False,
4901 0, &beginPos, &endPos, NULL, NULL, NULL))
4902 return FALSE;
4903 newLen = inLen + replaceLen - (endPos-beginPos);
4904 newString = XtMalloc(newLen + 1);
4905 strncpy(newString, *inString, beginPos);
4906 strncpy(&newString[beginPos], replaceWith, replaceLen);
4907 strncpy(&newString[beginPos+replaceLen],
4908 &((*inString)[endPos]), inLen - endPos);
4909 newString[newLen] = '\0';
4910 XtFree(*inString);
4911 *inString = newString;
4912 return TRUE;
4916 #ifndef VMS
4918 ** Replace all '#' characters in shell commands by '##' to keep commands
4919 ** containing those working. '#' is a line number placeholder in 5.3 and
4920 ** had no special meaning before.
4922 static void updateShellCmdsTo5dot3(void)
4924 char *cOld, *cNew, *pCol, *pNL;
4925 int nHash, isCmd;
4926 char *newString;
4928 if(!TempStringPrefs.shellCmds)
4929 return;
4931 /* Count number of '#'. If there are '#' characters in the non-command
4932 ** part of the definition we count too much and later allocate too much
4933 ** memory for the new string, but this doesn't hurt.
4935 for(cOld=TempStringPrefs.shellCmds, nHash=0; *cOld; cOld++)
4936 if(*cOld == '#')
4937 nHash++;
4939 /* No '#' -> no conversion necessary. */
4940 if(!nHash)
4941 return;
4943 newString=XtMalloc(strlen(TempStringPrefs.shellCmds) + 1 + nHash);
4945 cOld = TempStringPrefs.shellCmds;
4946 cNew = newString;
4947 isCmd = 0;
4948 pCol = NULL;
4949 pNL = NULL;
4951 /* Copy all characters from TempStringPrefs.shellCmds into newString
4952 ** and duplicate '#' in command parts. A simple check for really beeing
4953 ** inside a command part (starting with '\n', between the the two last
4954 ** '\n' a colon ':' must have been found) is preformed.
4956 while(*cOld) {
4957 /* actually every 2nd line is a command. We additionally
4958 ** check if there is a colon ':' in the previous line.
4960 if(*cOld=='\n') {
4961 if((pCol > pNL) && !isCmd)
4962 isCmd=1;
4963 else
4964 isCmd=0;
4965 pNL=cOld;
4968 if(!isCmd && *cOld ==':')
4969 pCol = cOld;
4971 /* Duplicate hashes if we're in a command part */
4972 if(isCmd && *cOld=='#')
4973 *cNew++ = '#';
4975 /* Copy every character */
4976 *cNew++ = *cOld++;
4980 /* Terminate new preferences string */
4981 *cNew = 0;
4983 /* free the old memory */
4984 XtFree(TempStringPrefs.shellCmds);
4986 /* exchange the string */
4987 TempStringPrefs.shellCmds = newString;
4991 #else
4993 static void updateShellCmdsTo5dot3(void) {
4994 /* No shell commands in VMS ! */
4995 return;
4998 #endif
5000 #ifdef SGI_CUSTOM
5002 ** Present the user a dialog for specifying whether or not a short
5003 ** menu mode preference should be applied toward the default setting.
5004 ** Return False (function value) if operation was canceled, return True
5005 ** in setDefault if requested to reset the default value.
5007 static int shortPrefToDefault(Widget parent, const char *settingName, int *setDefault)
5009 char msg[100] = "";
5011 if (!GetPrefShortMenus()) {
5012 *setDefault = False;
5013 return True;
5016 sprintf(msg, "%s\nSave as default for future windows as well?", settingName);
5017 switch(DialogF (DF_QUES, parent, 3, msg, "Yes", "No", "Cancel")) {
5018 case 1: /* yes */
5019 *setDefault = True;
5020 return True;
5021 case 2: /* no */
5022 *setDefault = False;
5023 return True;
5024 case 3: /* cancel */
5025 return False;
5027 return False; /* not reached */
5029 #endif