Fix for SF bug #991700: 5.5 crash. The workaround to prevent this crash
[nedit.git] / source / preferences.c
blob4bfa19f7334afc3b291e40dbdfb0bc009ab0292f
1 static const char CVSID[] = "$Id: preferences.c,v 1.120 2004/07/15 01:47:57 yooden 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 "menu.h"
37 #include "text.h"
38 #include "search.h"
39 #include "window.h"
40 #include "userCmds.h"
41 #include "highlight.h"
42 #include "highlightData.h"
43 #include "help.h"
44 #include "regularExp.h"
45 #include "smartIndent.h"
46 #include "windowTitle.h"
47 #include "server.h"
48 #include "tags.h"
49 #include "../util/prefFile.h"
50 #include "../util/misc.h"
51 #include "../util/DialogF.h"
52 #include "../util/managedList.h"
53 #include "../util/fontsel.h"
54 #include "../util/fileUtils.h"
55 #include "../util/utils.h"
57 #include <stdlib.h>
58 #include <string.h>
59 #include <stdio.h>
60 #include <ctype.h>
61 #ifdef VMS
62 #include "../util/VMSparam.h"
63 #else
64 #ifndef __MVS__
65 #include <sys/param.h>
66 #endif
67 #include "../util/clearcase.h"
68 #endif /*VMS*/
70 #include <Xm/Xm.h>
71 #include <Xm/SelectioB.h>
72 #include <Xm/Form.h>
73 #include <Xm/List.h>
74 #include <Xm/SeparatoG.h>
75 #include <Xm/LabelG.h>
76 #include <Xm/Label.h>
77 #include <Xm/PushBG.h>
78 #include <Xm/PushB.h>
79 #include <Xm/ToggleBG.h>
80 #include <Xm/ToggleB.h>
81 #include <Xm/RowColumn.h>
82 #include <Xm/CascadeBG.h>
83 #include <Xm/Frame.h>
84 #include <Xm/Text.h>
86 #ifdef HAVE_DEBUG_H
87 #include "../debug.h"
88 #endif
90 #if XmVersion >= 1002
91 #define MENU_WIDGET(w) (XmGetPostedFromWidget(XtParent(w)))
92 #else
93 #define MENU_WIDGET(w) (w)
94 #endif
96 #define PREF_FILE_VERSION "5.4"
98 /* New styles added in 5.2 for auto-upgrade */
99 #define ADD_5_2_STYLES " Pointer:#660000:Bold\nRegex:#009944:Bold\nWarning:brown2:Italic"
101 /* maximum number of word delimiters allowed (256 allows whole character set) */
102 #define MAX_WORD_DELIMITERS 256
104 /* maximum number of file extensions allowed in a language mode */
105 #define MAX_FILE_EXTENSIONS 20
107 /* Return values for checkFontStatus */
108 enum fontStatus {GOOD_FONT, BAD_PRIMARY, BAD_FONT, BAD_SIZE, BAD_SPACING};
110 /* enumerated type preference strings
111 ** The order of the elements in this array must be exactly the same
112 ** as the order of the corresponding integers of the enum SearchType
113 ** defined in search.h (!!)
115 static char *SearchMethodStrings[] = {
116 "Literal", "CaseSense", "RegExp",
117 "LiteralWord", "CaseSenseWord", "RegExpNoCase",
118 NULL
121 #ifdef REPLACE_SCOPE
122 /* enumerated default scope for replace dialog if a selection exists when
123 ** the dialog is popped up.
125 static char *ReplaceDefScopeStrings[] = {
126 "Window", "Selection", "Smart", NULL
128 #endif
130 #define N_WRAP_STYLES 3
131 static char *AutoWrapTypes[N_WRAP_STYLES+3] = {"None", "Newline", "Continuous",
132 "True", "False", NULL};
133 #define N_INDENT_STYLES 3
134 static char *AutoIndentTypes[N_INDENT_STYLES+3] = {"None", "Auto",
135 "Smart", "True", "False", NULL};
136 #define N_VIRTKEY_OVERRIDE_MODES 3
137 static char *VirtKeyOverrideModes[N_VIRTKEY_OVERRIDE_MODES+1] = { "Never",
138 "Auto", "Always", NULL};
140 #define N_SHOW_MATCHING_STYLES 3
141 /* For backward compatibility, "False" and "True" are still accepted.
142 They are internally converted to "Off" and "Delimiter" respectively.
143 NOTE: N_SHOW_MATCHING_STYLES must correspond to the number of
144 _real_ matching styles, not counting False & True.
145 False and True should also be the last ones in the list. */
146 static char *ShowMatchingTypes[] = {"Off", "Delimiter", "Range",
147 "False", "True", NULL};
149 /* suplement wrap and indent styles w/ a value meaning "use default" for
150 the override fields in the language modes dialog */
151 #define DEFAULT_WRAP -1
152 #define DEFAULT_INDENT -1
153 #define DEFAULT_TAB_DIST -1
154 #define DEFAULT_EM_TAB_DIST -1
156 /* list of available language modes and language specific preferences */
157 static int NLanguageModes = 0;
158 typedef struct {
159 char *name;
160 int nExtensions;
161 char **extensions;
162 char *recognitionExpr;
163 char *defTipsFile;
164 char *delimiters;
165 int wrapStyle;
166 int indentStyle;
167 int tabDist;
168 int emTabDist;
169 } languageModeRec;
170 static languageModeRec *LanguageModes[MAX_LANGUAGE_MODES];
172 /* Language mode dialog information */
173 static struct {
174 Widget shell;
175 Widget nameW;
176 Widget extW;
177 Widget recogW;
178 Widget defTipsW;
179 Widget delimitW;
180 Widget managedListW;
181 Widget tabW;
182 Widget emTabW;
183 Widget defaultIndentW;
184 Widget noIndentW;
185 Widget autoIndentW;
186 Widget smartIndentW;
187 Widget defaultWrapW;
188 Widget noWrapW;
189 Widget newlineWrapW;
190 Widget contWrapW;
191 languageModeRec **languageModeList;
192 int nLanguageModes;
193 } LMDialog = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
194 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0};
196 /* Font dialog information */
197 typedef struct {
198 Widget shell;
199 Widget primaryW;
200 Widget fillW;
201 Widget italicW;
202 Widget italicErrW;
203 Widget boldW;
204 Widget boldErrW;
205 Widget boldItalicW;
206 Widget boldItalicErrW;
207 WindowInfo *window;
208 int forWindow;
209 } fontDialog;
211 /* Color dialog information */
212 typedef struct {
213 Widget shell;
214 Widget textFgW;
215 Widget textFgErrW;
216 Widget textBgW;
217 Widget textBgErrW;
218 Widget selectFgW;
219 Widget selectFgErrW;
220 Widget selectBgW;
221 Widget selectBgErrW;
222 Widget hiliteFgW;
223 Widget hiliteFgErrW;
224 Widget hiliteBgW;
225 Widget hiliteBgErrW;
226 Widget lineNoFgW;
227 Widget lineNoFgErrW;
228 Widget cursorFgW;
229 Widget cursorFgErrW;
230 WindowInfo *window;
231 } colorDialog;
233 /* Repository for simple preferences settings */
234 static struct prefData {
235 int openInTab; /* open files in new tabs */
236 int wrapStyle; /* what kind of wrapping to do */
237 int wrapMargin; /* 0=wrap at window width, other=wrap margin */
238 int autoIndent; /* style for auto-indent */
239 int autoSave; /* whether automatic backup feature is on */
240 int saveOldVersion; /* whether to preserve a copy of last version */
241 int searchDlogs; /* whether to show explanatory search dialogs */
242 int searchWrapBeep; /* 1=beep when search restarts at begin/end */
243 int keepSearchDlogs; /* whether to retain find and replace dialogs */
244 int searchWraps; /* whether to attempt search again if reach bof or eof */
245 int statsLine; /* whether to show the statistics line */
246 int iSearchLine; /* whether to show the incremental search line*/
247 int tabBar; /* whether to show the tab bar */
248 int tabBarHideOne; /* hide tab bar if only one document in window */
249 int globalTabNavigate; /* prev/next document across windows */
250 int toolTips; /* whether to show the tooltips */
251 int lineNums; /* whether to show line numbers */
252 int pathInWindowsMenu; /* whether to show path in windows menu */
253 int warnFileMods; /* warn user if files externally modified */
254 int warnRealFileMods; /* only warn if file contents modified */
255 int warnExit; /* whether to warn on exit */
256 int searchMethod; /* initial search method as a text string */
257 #ifdef REPLACE_SCOPE
258 int replaceDefScope; /* default replace scope if selection exists */
259 #endif
260 int textRows; /* initial window height in characters */
261 int textCols; /* initial window width in characters */
262 int tabDist; /* number of characters between tab stops */
263 int emTabDist; /* non-zero tab dist. if emulated tabs are on */
264 int insertTabs; /* whether to use tabs for padding */
265 int showMatchingStyle; /* how to flash matching parenthesis */
266 int matchSyntaxBased; /* use syntax info to match parenthesis */
267 int highlightSyntax; /* whether to highlight syntax by default */
268 int smartTags; /* look for tag in current window first */
269 int alwaysCheckRelativeTagsSpecs; /* for every new opened file of session */
270 int stickyCaseSenseBtn; /* whether Case Word Btn is sticky to Regex Btn */
271 int prefFileRead; /* detects whether a .nedit existed */
272 int backlightChars; /* whether to apply character "backlighting" */
273 char *backlightCharTypes; /* the backlighting color definitions */
274 #ifdef SGI_CUSTOM
275 int shortMenus; /* short menu mode */
276 #endif
277 char fontString[MAX_FONT_LEN]; /* names of fonts for text widget */
278 char boldFontString[MAX_FONT_LEN];
279 char italicFontString[MAX_FONT_LEN];
280 char boldItalicFontString[MAX_FONT_LEN];
281 XmFontList fontList; /* XmFontLists corresp. to above named fonts */
282 XFontStruct *boldFontStruct;
283 XFontStruct *italicFontStruct;
284 XFontStruct *boldItalicFontStruct;
285 int sortTabs; /* sort tabs alphabetically */
286 int repositionDialogs; /* w. to reposition dialogs under the pointer */
287 int autoScroll; /* w. to autoscroll near top/bottom of screen */
288 int autoScrollVPadding; /* how close to get before autoscrolling */
289 int sortOpenPrevMenu; /* whether to sort the "Open Previous" menu */
290 int appendLF; /* Whether to append LF at the end of each file */
291 int mapDelete; /* whether to map delete to backspace */
292 int stdOpenDialog; /* w. to retain redundant text field in Open */
293 char tagFile[MAXPATHLEN]; /* name of tags file to look for at startup */
294 int maxPrevOpenFiles; /* limit to size of Open Previous menu */
295 int typingHidesPointer; /* hide mouse pointer when typing */
296 char delimiters[MAX_WORD_DELIMITERS]; /* punctuation characters */
297 char shell[MAXPATHLEN]; /* shell to use for executing commands */
298 char geometry[MAX_GEOM_STRING_LEN]; /* per-application geometry string,
299 only for the clueless */
300 char serverName[MAXPATHLEN];/* server name for multiple servers per disp. */
301 char bgMenuBtn[MAX_ACCEL_LEN]; /* X event description for triggering
302 posting of background menu */
303 char fileVersion[6]; /* Version of nedit which wrote the .nedit
304 file we're reading */
305 int findReplaceUsesSelection; /* whether the find replace dialog is automatically
306 loaded with the primary selection */
307 int virtKeyOverride; /* Override Motif default virtual key bindings
308 never, if invalid, or always */
309 char titleFormat[MAX_TITLE_FORMAT_LEN];
310 char helpFontNames[NUM_HELP_FONTS][MAX_FONT_LEN];/* fonts for help system */
311 char helpLinkColor[MAX_COLOR_LEN]; /* Color for hyperlinks in the help system */
312 char colorNames[NUM_COLORS][MAX_COLOR_LEN];
313 char tooltipBgColor[MAX_COLOR_LEN];
314 int undoModifiesSelection;
315 } PrefData;
317 /* Temporary storage for preferences strings which are discarded after being
318 read */
319 static struct {
320 char *shellCmds;
321 char *macroCmds;
322 char *bgMenuCmds;
323 char *highlight;
324 char *language;
325 char *styles;
326 char *smartIndent;
327 char *smartIndentCommon;
328 } TempStringPrefs;
330 /* preference descriptions for SavePreferences and RestorePreferences. */
331 static PrefDescripRec PrefDescrip[] = {
332 {"fileVersion", "FileVersion" , PREF_STRING, "", PrefData.fileVersion,
333 (void *)sizeof(PrefData.fileVersion), True},
334 #ifndef VMS
335 #ifdef linux
336 {"shellCommands", "ShellCommands", PREF_ALLOC_STRING, "spell:Alt+B:s:EX:\n\
337 cat>spellTmp; xterm -e ispell -x spellTmp; cat spellTmp; rm spellTmp\n\
338 wc::w:ED:\nwc | awk '{print $1 \" lines, \" $2 \" words, \" $3 \" characters\"}'\n\
339 sort::o:EX:\nsort\nnumber lines::n:AW:\nnl -ba\nmake:Alt+Z:m:W:\nmake\n\
340 expand::p:EX:\nexpand\nunexpand::u:EX:\nunexpand\n",
341 &TempStringPrefs.shellCmds, NULL, True},
342 #elif __FreeBSD__
343 {"shellCommands", "ShellCommands", PREF_ALLOC_STRING, "spell:Alt+B:s:EX:\n\
344 cat>spellTmp; xterm -e ispell -x spellTmp; cat spellTmp; rm spellTmp\n\
345 wc::w:ED:\nwc | awk '{print $2 \" lines, \" $1 \" words, \" $3 \" characters\"}'\n\
346 sort::o:EX:\nsort\nnumber lines::n:AW:\npr -tn\nmake:Alt+Z:m:W:\nmake\n\
347 expand::p:EX:\nexpand\nunexpand::u:EX:\nunexpand\n",
348 &TempStringPrefs.shellCmds, NULL, True},
349 #else
350 {"shellCommands", "ShellCommands", PREF_ALLOC_STRING, "spell:Alt+B:s:ED:\n\
351 (cat;echo \"\") | spell\nwc::w:ED:\nwc | awk '{print $1 \" lines, \" $2 \" words, \" $3 \" characters\"}'\n\
352 \nsort::o:EX:\nsort\nnumber lines::n:AW:\nnl -ba\nmake:Alt+Z:m:W:\nmake\n\
353 expand::p:EX:\nexpand\nunexpand::u:EX:\nunexpand\n",
354 &TempStringPrefs.shellCmds, NULL, True},
355 #endif /* linux, __FreeBSD__ */
356 #endif /* VMS */
357 {"macroCommands", "MacroCommands", PREF_ALLOC_STRING,
358 "Complete Word:Alt+D::: {\n\
359 # Tuning parameters\n\
360 ScanDistance = 200\n\
362 # Search back to a word boundary to find the word to complete\n\
363 startScan = max(0, $cursor - ScanDistance)\n\
364 endScan = min($text_length, $cursor + ScanDistance)\n\
365 scanString = get_range(startScan, endScan)\n\
366 keyEnd = $cursor-startScan\n\
367 keyStart = search_string(scanString, \"<\", keyEnd, \"backward\", \"regex\")\n\
368 if (keyStart == -1)\n\
369 return\n\
370 keyString = \"<\" substring(scanString, keyStart, keyEnd)\n\
372 # search both forward and backward from the cursor position. Note that\n\
373 # using a regex search can lead to incorrect results if any of the special\n\
374 # regex characters is encountered, which is not considered a delimiter\n\
375 backwardSearchResult = search_string(scanString, keyString, keyStart-1, \\\n\
376 \"backward\", \"regex\")\n\
377 forwardSearchResult = search_string(scanString, keyString, keyEnd, \"regex\")\n\
378 if (backwardSearchResult == -1 && forwardSearchResult == -1) {\n\
379 beep()\n\
380 return\n\
381 }\n\
383 # if only one direction matched, use that, otherwise use the nearest\n\
384 if (backwardSearchResult == -1)\n\
385 matchStart = forwardSearchResult\n\
386 else if (forwardSearchResult == -1)\n\
387 matchStart = backwardSearchResult\n\
388 else {\n\
389 if (keyStart - backwardSearchResult <= forwardSearchResult - keyEnd)\n\
390 matchStart = backwardSearchResult\n\
391 else\n\
392 matchStart = forwardSearchResult\n\
393 }\n\
395 # find the complete word\n\
396 matchEnd = search_string(scanString, \">\", matchStart, \"regex\")\n\
397 completedWord = substring(scanString, matchStart, matchEnd)\n\
399 # replace it in the window\n\
400 replace_range(startScan + keyStart, $cursor, completedWord)\n\
401 }\n\
402 Fill Sel. w/Char:::R: {\n\
403 if ($selection_start == -1) {\n\
404 beep()\n\
405 return\n\
406 }\n\
408 # Ask the user what character to fill with\n\
409 fillChar = string_dialog(\"Fill selection with what character?\", \"OK\", \"Cancel\")\n\
410 if ($string_dialog_button == 2 || $string_dialog_button == 0)\n\
411 return\n\
413 # Count the number of lines in the selection\n\
414 nLines = 0\n\
415 for (i=$selection_start; i<$selection_end; i++)\n\
416 if (get_character(i) == \"\\n\")\n\
417 nLines++\n\
419 # Create the fill text\n\
420 rectangular = $selection_left != -1\n\
421 line = \"\"\n\
422 fillText = \"\"\n\
423 if (rectangular) {\n\
424 for (i=0; i<$selection_right-$selection_left; i++)\n\
425 line = line fillChar\n\
426 for (i=0; i<nLines; i++)\n\
427 fillText = fillText line \"\\n\"\n\
428 fillText = fillText line\n\
429 } else {\n\
430 if (nLines == 0) {\n\
431 for (i=$selection_start; i<$selection_end; i++)\n\
432 fillText = fillText fillChar\n\
433 } else {\n\
434 startIndent = 0\n\
435 for (i=$selection_start-1; i>=0 && get_character(i)!=\"\\n\"; i--)\n\
436 startIndent++\n\
437 for (i=0; i<$wrap_margin-startIndent; i++)\n\
438 fillText = fillText fillChar\n\
439 fillText = fillText \"\\n\"\n\
440 for (i=0; i<$wrap_margin; i++)\n\
441 line = line fillChar\n\
442 for (i=0; i<nLines-1; i++)\n\
443 fillText = fillText line \"\\n\"\n\
444 for (i=$selection_end-1; i>=$selection_start && get_character(i)!=\"\\n\"; \\\n\
445 i--)\n\
446 fillText = fillText fillChar\n\
447 }\n\
448 }\n\
450 # Replace the selection with the fill text\n\
451 replace_selection(fillText)\n\
452 }\n\
453 Quote Mail Reply:::: {\n\
454 if ($selection_start == -1)\n\
455 replace_all(\"^.*$\", \"\\\\> &\", \"regex\")\n\
456 else\n\
457 replace_in_selection(\"^.*$\", \"\\\\> &\", \"regex\")\n\
458 }\n\
459 Unquote Mail Reply:::: {\n\
460 if ($selection_start == -1)\n\
461 replace_all(\"(^\\\\> )(.*)$\", \"\\\\2\", \"regex\")\n\
462 else\n\
463 replace_in_selection(\"(^\\\\> )(.*)$\", \"\\\\2\", \"regex\")\n\
464 }\n\
465 Comments>/* Comment */@C@C++@Java@CSS@JavaScript@Lex:::R: {\n\
466 selStart = $selection_start\n\
467 selEnd = $selection_end\n\
468 replace_range(selStart, selEnd, \"/* \" get_selection() \" */\")\n\
469 select(selStart, selEnd + 6)\n\
470 }\n\
471 Comments>/* Uncomment */@C@C++@Java@CSS@JavaScript@Lex:::R: {\n\
472 sel = get_selection()\n\
473 selStart = $selection_start\n\
474 selEnd = $selection_end\n\
475 commentStart = search_string(sel, \"/*\", 0)\n\
476 if (substring(sel, commentStart + 2, commentStart + 3) == \" \")\n\
477 keepStart = commentStart + 3\n\
478 else\n\
479 keepStart = commentStart + 2\n\
480 keepEnd = search_string(sel, \"*/\", length(sel), \"backward\")\n\
481 commentEnd = keepEnd + 2\n\
482 if (substring(sel, keepEnd - 1, keepEnd) == \" \")\n\
483 keepEnd = keepEnd - 1\n\
484 replace_range(selStart + commentStart, selStart + commentEnd, \\\n\
485 substring(sel, keepStart, keepEnd))\n\
486 select(selStart, selEnd - (keepStart-commentStart) - \\\n\
487 (commentEnd - keepEnd))\n\
488 }\n\
489 Comments>// Comment@C@C++@Java@JavaScript:::R: {\n\
490 replace_in_selection(\"^.*$\", \"// &\", \"regex\")\n\
491 }\n\
492 Comments>// Uncomment@C@C++@Java@JavaScript:::R: {\n\
493 replace_in_selection(\"(^[ \\\\t]*// ?)(.*)$\", \"\\\\2\", \"regex\")\n\
494 }\n\
495 Comments># Comment@Perl@Sh Ksh Bash@NEdit Macro@Makefile@Awk@Csh@Python@Tcl:::R: {\n\
496 replace_in_selection(\"^.*$\", \"#&\", \"regex\")\n\
497 }\n\
498 Comments># Uncomment@Perl@Sh Ksh Bash@NEdit Macro@Makefile@Awk@Csh@Python@Tcl:::R: {\n\
499 replace_in_selection(\"(^[ \\\\t]*#)(.*)$\", \"\\\\2\", \"regex\")\n\
500 }\n\
501 Comments>-- Comment@SQL:::R: {\n\
502 replace_in_selection(\"^.*$\", \"--&\", \"regex\")\n\
503 }\n\
504 Comments>-- Uncomment@SQL:::R: {\n\
505 replace_in_selection(\"(^[ \\\\t]*--)(.*)$\", \"\\\\2\", \"regex\")\n\
506 }\n\
507 Comments>! Comment@X Resources:::R: {\n\
508 replace_in_selection(\"^.*$\", \"!&\", \"regex\")\n\
509 }\n\
510 Comments>! Uncomment@X Resources:::R: {\n\
511 replace_in_selection(\"(^[ \\\\t]*!)(.*)$\", \"\\\\2\", \"regex\")\n\
512 }\n\
513 Comments>% Comment@LaTeX:::R: {\n\
514 replace_in_selection(\"^.*$\", \"%&\", \"regex\")\n\
515 }\n\
516 Comments>% Uncomment@LaTeX:::R: {\n\
517 replace_in_selection(\"(^[ \\\\t]*%)(.*)$\", \"\\\\2\", \"regex\")\n\
518 }\n\
519 Comments>Bar Comment@C:::R: {\n\
520 if ($selection_left != -1) {\n\
521 dialog(\"Selection must not be rectangular\")\n\
522 return\n\
523 }\n\
524 start = $selection_start\n\
525 end = $selection_end-1\n\
526 origText = get_range($selection_start, $selection_end-1)\n\
527 newText = \"/*\\n\" replace_in_string(get_range(start, end), \\\n\
528 \"^\", \" * \", \"regex\") \"\\n */\\n\"\n\
529 replace_selection(newText)\n\
530 select(start, start + length(newText))\n\
531 }\n\
532 Comments>Bar Uncomment@C:::R: {\n\
533 selStart = $selection_start\n\
534 selEnd = $selection_end\n\
535 newText = get_range(selStart+3, selEnd-4)\n\
536 newText = replace_in_string(newText, \"^ \\\\* \", \"\", \"regex\")\n\
537 replace_range(selStart, selEnd, newText)\n\
538 select(selStart, selStart + length(newText))\n\
539 }\n\
540 Make C Prototypes@C@C++:::: {\n\
541 if ($selection_start == -1) {\n\
542 start = 0\n\
543 end = $text_length\n\
544 } else {\n\
545 start = $selection_start\n\
546 end = $selection_end\n\
547 }\n\
548 string = get_range(start, end)\n\
549 nDefs = 0\n\
550 searchPos = 0\n\
551 prototypes = \"\"\n\
552 staticPrototypes = \"\"\n\
553 for (;;) {\n\
554 headerStart = search_string(string, \\\n\
555 \"^[a-zA-Z]([^;#\\\"'{}=><!/]|\\n)*\\\\)[ \\t]*\\n?[ \\t]*\\\\{\", \\\n\
556 searchPos, \"regex\")\n\
557 if (headerStart == -1)\n\
558 break\n\
559 headerEnd = search_string(string, \")\", $search_end,\"backward\") + 1\n\
560 prototype = substring(string, headerStart, headerEnd) \";\\n\"\n\
561 if (substring(string, headerStart, headerStart+6) == \"static\")\n\
562 staticPrototypes = staticPrototypes prototype\n\
563 else\n\
564 prototypes = prototypes prototype\n\
565 searchPos = headerEnd\n\
566 nDefs++\n\
567 }\n\
568 if (nDefs == 0) {\n\
569 dialog(\"No function declarations found\")\n\
570 return\n\
571 }\n\
572 new()\n\
573 focus_window(\"last\")\n\
574 replace_range(0, 0, prototypes staticPrototypes)\n\
575 }", &TempStringPrefs.macroCmds, NULL, True},
576 {"bgMenuCommands", "BGMenuCommands", PREF_ALLOC_STRING,
577 "Undo:::: {\nundo()\n}\n\
578 Redo:::: {\nredo()\n}\n\
579 Cut:::R: {\ncut_clipboard()\n}\n\
580 Copy:::R: {\ncopy_clipboard()\n}\n\
581 Paste:::: {\npaste_clipboard()\n}", &TempStringPrefs.bgMenuCmds,
582 NULL, True},
583 #ifdef VMS
584 /* The VAX compiler can't compile Java-Script's definition in highlightData.c */
585 {"highlightPatterns", "HighlightPatterns", PREF_ALLOC_STRING,
586 "Ada:Default\n\
587 Awk:Default\n\
588 C++:Default\n\
589 C:Default\n\
590 CSS:Default\n\
591 Csh:Default\n\
592 Fortran:Default\n\
593 Java:Default\n\
594 LaTeX:Default\n\
595 Lex:Default\n\
596 Makefile:Default\n\
597 Matlab:Default\n\
598 NEdit Macro:Default\n\
599 Pascal:Default\n\
600 Perl:Default\n\
601 PostScript:Default\n\
602 Python:Default\n\
603 Regex:Default\n\
604 SGML HTML:Default\n\
605 SQL:Default\n\
606 Sh Ksh Bash:Default\n\
607 Tcl:Default\n\
608 VHDL:Default\n\
609 Verilog:Default\n\
610 XML:Default\n\
611 X Resources:Default\n\
612 Yacc:Default",
613 &TempStringPrefs.highlight, NULL, True},
614 {"languageModes", "LanguageModes", PREF_ALLOC_STRING,
615 #else
616 {"highlightPatterns", "HighlightPatterns", PREF_ALLOC_STRING,
617 "Ada:Default\n\
618 Awk:Default\n\
619 C++:Default\n\
620 C:Default\n\
621 CSS:Default\n\
622 Csh:Default\n\
623 Fortran:Default\n\
624 Java:Default\n\
625 JavaScript:Default\n\
626 LaTeX:Default\n\
627 Lex:Default\n\
628 Makefile:Default\n\
629 Matlab:Default\n\
630 NEdit Macro:Default\n\
631 Pascal:Default\n\
632 Perl:Default\n\
633 PostScript:Default\n\
634 Python:Default\n\
635 Regex:Default\n\
636 SGML HTML:Default\n\
637 SQL:Default\n\
638 Sh Ksh Bash:Default\n\
639 Tcl:Default\n\
640 VHDL:Default\n\
641 Verilog:Default\n\
642 XML:Default\n\
643 X Resources:Default\n\
644 Yacc:Default",
645 &TempStringPrefs.highlight, NULL, True},
646 {"languageModes", "LanguageModes", PREF_ALLOC_STRING,
647 #endif /*VMS*/
648 #ifdef VMS
649 "Ada:.ADA .AD .ADS .ADB .A:::::::\n\
650 Awk:.AWK:::::::\n\
651 C++:.CC .HH .C .H .I .CXX .HXX .CPP::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":\n\
652 C:.C .H::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":\n\
653 CSS:CSS::Auto:None:::\".,/\\`'!|@#%^&*()=+{}[]\"\":;<>?~\":\n\
654 Csh:.csh .cshrc .login .logout:\"^[ \\t]*#[ \\t]*![ \\t]*/bin/csh\"::::::\n\
655 Fortran:.F .F77 .FOR:::::::\n\
656 Java:.JAVA:::::::\n\
657 LaTeX:.TEX .STY .CLS .LTX .INS:::::::\n\
658 Lex:.lex:::::::\n\
659 Makefile:MAKEFILE:::None:8:8::\n\
660 Matlab:.m .oct .sci:::::::\n\
661 NEdit Macro:.NM .NEDITMACRO:::::::\n\
662 Pascal:.PAS .P .INT:::::::\n\
663 Perl:.PL .PM .P5:\"^[ \\t]*#[ \\t]*!.*perl\":Auto:None:::\".,/\\\\`'!$@#%^&*()-=+{}[]\"\":;<>?~|\":\n\
664 PostScript:.ps .PS .eps .EPS .epsf .epsi:\"^%!\":::::\"/%(){}[]<>\":\n\
665 Python:.PY:\"^#!.*python\":Auto:None:::\"!\"\"#$%&'()*+,-./:;<=>?@[\\\\]^`{|}~\":\n\
666 Regex:.reg .regex:\"\\(\\?[:#=!iInN].+\\)\":None:Continuous::::\n\
667 SGML HTML:.sgml .sgm .html .htm:\"\\<[Hh][Tt][Mm][Ll]\\>\"::::::\n\
668 SQL:.sql:::::::\n\
669 Sh Ksh Bash:.sh .bash .ksh .profile .bashrc .bash_logout .bash_login .bash_profile:\"^[ \\t]*#[ \\t]*![ \\t]*/.*bin/(bash|ksh|sh|zsh)\"::::::\n\
670 Tcl:.TCL::Smart:None::::\n\
671 VHDL:.VHD .VHDL .VDL:::::::\n\
672 Verilog:.V:::::::\n\
673 XML:.xml .xsl .dtd:\"\\<(?i\\?xml|!doctype)\"::None:::\"<>/=\"\"'()+*?|\":\n\
674 X Resources:.XRESOURCES .XDEFAULTS .NEDIT:\"^[!#].*([Aa]pp|[Xx]).*[Dd]efaults\"::::::\n\
675 Yacc:.Y::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":",
676 #else
677 "Ada:.ada .ad .ads .adb .a:::::::\n\
678 Awk:.awk:::::::\n\
679 C++:.cc .hh .C .H .i .cxx .hxx .cpp .c++::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":\n\
680 C:.c .h::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":\n\
681 CSS:css::Auto:None:::\".,/\\`'!|@#%^&*()=+{}[]\"\":;<>?~\":\n\
682 Csh:.csh .cshrc .login .logout:\"^[ \\t]*#[ \\t]*![ \\t]*/bin/csh\"::::::\n\
683 Fortran:.f .f77 .for:::::::\n\
684 Java:.java:::::::\n\
685 JavaScript:.js:::::::\n\
686 LaTeX:.tex .sty .cls .ltx .ins:::::::\n\
687 Lex:.lex:::::::\n\
688 Makefile:Makefile makefile .gmk:::None:8:8::\n\
689 Matlab:.m .oct .sci:::::::\n\
690 NEdit Macro:.nm .neditmacro:::::::\n\
691 Pascal:.pas .p .int:::::::\n\
692 Perl:.pl .pm .p5 .PL:\"^[ \\t]*#[ \\t]*!.*perl\":Auto:None:::\".,/\\\\`'!$@#%^&*()-=+{}[]\"\":;<>?~|\":\n\
693 PostScript:.ps .eps .epsf .epsi:\"^%!\":::::\"/%(){}[]<>\":\n\
694 Python:.py:\"^#!.*python\":Auto:None:::\"!\"\"#$%&'()*+,-./:;<=>?@[\\\\]^`{|}~\":\n\
695 Regex:.reg .regex:\"\\(\\?[:#=!iInN].+\\)\":None:Continuous::::\n\
696 SGML HTML:.sgml .sgm .html .htm:\"\\<[Hh][Tt][Mm][Ll]\\>\"::::::\n\
697 SQL:.sql:::::::\n\
698 Sh Ksh Bash:.sh .bash .ksh .profile .bashrc .bash_logout .bash_login .bash_profile:\"^[ \\t]*#[ \\t]*![ \\t]*/.*bin/(bash|ksh|sh|zsh)\"::::::\n\
699 Tcl:.tcl .tk .itcl .itk::Smart:None::::\n\
700 VHDL:.vhd .vhdl .vdl:::::::\n\
701 Verilog:.v:::::::\n\
702 XML:.xml .xsl .dtd:\"\\<(?i\\?xml|!doctype)\"::None:::\"<>/=\"\"'()+*?|\":\n\
703 X Resources:.Xresources .Xdefaults .nedit:\"^[!#].*([Aa]pp|[Xx]).*[Dd]efaults\"::::::\n\
704 Yacc:.y::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":",
705 #endif
706 &TempStringPrefs.language, NULL, True},
707 {"styles", "Styles", PREF_ALLOC_STRING, "Plain:black:Plain\n\
708 Comment:gray20:Italic\n\
709 Keyword:black:Bold\n\
710 Storage Type:brown:Bold\n\
711 Storage Type1:saddle brown:Bold\n\
712 String:darkGreen:Plain\n\
713 String1:SeaGreen:Plain\n\
714 String2:darkGreen:Bold\n\
715 Preprocessor:RoyalBlue4:Plain\n\
716 Preprocessor1:blue:Plain\n\
717 Character Const:darkGreen:Plain\n\
718 Numeric Const:darkGreen:Plain\n\
719 Identifier:brown:Plain\n\
720 Identifier1:RoyalBlue4:Plain\n\
721 Identifier2:SteelBlue:Plain\n\
722 Subroutine:brown:Plain\n\
723 Subroutine1:chocolate:Plain\n\
724 Ada Attributes:plum:Bold\n\
725 Label:red:Italic\n\
726 Flag:red:Bold\n\
727 Text Comment:SteelBlue4:Italic\n\
728 Text Key:VioletRed4:Bold\n\
729 Text Key1:VioletRed4:Plain\n\
730 Text Arg:RoyalBlue4:Bold\n\
731 Text Arg1:SteelBlue4:Bold\n\
732 Text Arg2:RoyalBlue4:Plain\n\
733 Text Escape:gray30:Bold\n\
734 LaTeX Math:darkGreen:Plain\n"
735 ADD_5_2_STYLES,
736 &TempStringPrefs.styles, NULL, True},
737 {"smartIndentInit", "SmartIndentInit", PREF_ALLOC_STRING,
738 "C:Default\n\
739 C++:Default\n\
740 Python:Default\n\
741 Matlab:Default", &TempStringPrefs.smartIndent, NULL, True},
742 {"smartIndentInitCommon", "SmartIndentInitCommon", PREF_ALLOC_STRING,
743 "Default", &TempStringPrefs.smartIndentCommon, NULL, True},
744 {"autoWrap", "AutoWrap", PREF_ENUM, "Newline",
745 &PrefData.wrapStyle, AutoWrapTypes, True},
746 {"wrapMargin", "WrapMargin", PREF_INT, "0",
747 &PrefData.wrapMargin, NULL, True},
748 {"autoIndent", "AutoIndent", PREF_ENUM, "Auto",
749 &PrefData.autoIndent, AutoIndentTypes, True},
750 {"autoSave", "AutoSave", PREF_BOOLEAN, "True",
751 &PrefData.autoSave, NULL, True},
752 {"openInTab", "OpenInTab", PREF_BOOLEAN, "True",
753 &PrefData.openInTab, NULL, True},
754 {"saveOldVersion", "SaveOldVersion", PREF_BOOLEAN, "False",
755 &PrefData.saveOldVersion, NULL, True},
756 {"showMatching", "ShowMatching", PREF_ENUM, "Delimiter",
757 &PrefData.showMatchingStyle, ShowMatchingTypes, True},
758 {"matchSyntaxBased", "MatchSyntaxBased", PREF_BOOLEAN, "True",
759 &PrefData.matchSyntaxBased, NULL, True},
760 {"highlightSyntax", "HighlightSyntax", PREF_BOOLEAN, "True",
761 &PrefData.highlightSyntax, NULL, True},
762 {"backlightChars", "BacklightChars", PREF_BOOLEAN, "False",
763 &PrefData.backlightChars, NULL, True},
764 {"backlightCharTypes", "BacklightCharTypes", PREF_ALLOC_STRING,
765 "0-8,10-31,127:red;9:#dedede;32,160-255:#f0f0f0;128-159:orange",
766 /* gray87 gray94 */
767 &PrefData.backlightCharTypes, NULL, False},
768 {"searchDialogs", "SearchDialogs", PREF_BOOLEAN, "False",
769 &PrefData.searchDlogs, NULL, True},
770 {"beepOnSearchWrap", "BeepOnSearchWrap", PREF_BOOLEAN, "False",
771 &PrefData.searchWrapBeep, NULL, True},
772 {"retainSearchDialogs", "RetainSearchDialogs", PREF_BOOLEAN, "False",
773 &PrefData.keepSearchDlogs, NULL, True},
774 {"searchWraps", "SearchWraps", PREF_BOOLEAN, "True",
775 &PrefData.searchWraps, NULL, True},
776 {"stickyCaseSenseButton", "StickyCaseSenseButton", PREF_BOOLEAN, "True",
777 &PrefData.stickyCaseSenseBtn, NULL, True},
778 #if XmVersion < 1002 /* Flashing is annoying in 1.1 versions */
779 {"repositionDialogs", "RepositionDialogs", PREF_BOOLEAN, "False",
780 &PrefData.repositionDialogs, NULL, True},
781 #else
782 {"repositionDialogs", "RepositionDialogs", PREF_BOOLEAN, "True",
783 &PrefData.repositionDialogs, NULL, True},
784 #endif
785 {"autoScroll", "AutoScroll", PREF_BOOLEAN, "False",
786 &PrefData.autoScroll, NULL, True},
787 {"autoScrollVPadding", "AutoScrollVPadding", PREF_INT, "4",
788 &PrefData.autoScrollVPadding, NULL, False},
789 {"appendLF", "AppendLF", PREF_BOOLEAN, "True",
790 &PrefData.appendLF, NULL, True},
791 {"sortOpenPrevMenu", "SortOpenPrevMenu", PREF_BOOLEAN, "True",
792 &PrefData.sortOpenPrevMenu, NULL, True},
793 {"statisticsLine", "StatisticsLine", PREF_BOOLEAN, "False",
794 &PrefData.statsLine, NULL, True},
795 {"iSearchLine", "ISearchLine", PREF_BOOLEAN, "False",
796 &PrefData.iSearchLine, NULL, True},
797 {"sortTabs", "SortTabs", PREF_BOOLEAN, "False",
798 &PrefData.sortTabs, NULL, True},
799 {"tabBar", "TabBar", PREF_BOOLEAN, "True",
800 &PrefData.tabBar, NULL, True},
801 {"tabBarHideOne", "TabBarHideOne", PREF_BOOLEAN, "True",
802 &PrefData.tabBarHideOne, NULL, True},
803 {"toolTips", "ToolTips", PREF_BOOLEAN, "True",
804 &PrefData.toolTips, NULL, True},
805 {"globalTabNavigate", "GlobalTabNavigate", PREF_BOOLEAN, "False",
806 &PrefData.globalTabNavigate, NULL, True},
807 {"lineNumbers", "LineNumbers", PREF_BOOLEAN, "False",
808 &PrefData.lineNums, NULL, True},
809 {"pathInWindowsMenu", "PathInWindowsMenu", PREF_BOOLEAN, "True",
810 &PrefData.pathInWindowsMenu, NULL, True},
811 {"warnFileMods", "WarnFileMods", PREF_BOOLEAN, "True",
812 &PrefData.warnFileMods, NULL, True},
813 {"warnRealFileMods", "WarnRealFileMods", PREF_BOOLEAN, "True",
814 &PrefData.warnRealFileMods, NULL, True},
815 {"warnExit", "WarnExit", PREF_BOOLEAN, "True",
816 &PrefData.warnExit, NULL, True},
817 {"searchMethod", "SearchMethod", PREF_ENUM, "Literal",
818 &PrefData.searchMethod, SearchMethodStrings, True},
819 #ifdef REPLACE_SCOPE
820 {"replaceDefaultScope", "ReplaceDefaultScope", PREF_ENUM, "Smart",
821 &PrefData.replaceDefScope, ReplaceDefScopeStrings, True},
822 #endif
823 {"textRows", "TextRows", PREF_INT, "24",
824 &PrefData.textRows, NULL, True},
825 {"textCols", "TextCols", PREF_INT, "80",
826 &PrefData.textCols, NULL, True},
827 {"tabDistance", "TabDistance", PREF_INT, "8",
828 &PrefData.tabDist, NULL, True},
829 {"emulateTabs", "EmulateTabs", PREF_INT, "0",
830 &PrefData.emTabDist, NULL, True},
831 {"insertTabs", "InsertTabs", PREF_BOOLEAN, "True",
832 &PrefData.insertTabs, NULL, True},
833 {"textFont", "TextFont", PREF_STRING,
834 "-*-courier-medium-r-normal--*-120-*-*-*-iso8859-1",
835 PrefData.fontString, (void *)sizeof(PrefData.fontString), True},
836 {"boldHighlightFont", "BoldHighlightFont", PREF_STRING,
837 "-*-courier-bold-r-normal--*-120-*-*-*-iso8859-1",
838 PrefData.boldFontString, (void *)sizeof(PrefData.boldFontString), True},
839 {"italicHighlightFont", "ItalicHighlightFont", PREF_STRING,
840 "-*-courier-medium-o-normal--*-120-*-*-*-iso8859-1",
841 PrefData.italicFontString,
842 (void *)sizeof(PrefData.italicFontString), True},
843 {"boldItalicHighlightFont", "BoldItalicHighlightFont", PREF_STRING,
844 "-*-courier-bold-o-normal--*-120-*-*-*-iso8859-1",
845 PrefData.boldItalicFontString,
846 (void *)sizeof(PrefData.boldItalicFontString), True},
847 {"helpFont", "HelpFont", PREF_STRING,
848 "-*-helvetica-medium-r-normal--*-120-*-*-*-iso8859-1",
849 PrefData.helpFontNames[HELP_FONT],
850 (void *)sizeof(PrefData.helpFontNames[HELP_FONT]), False},
851 {"boldHelpFont", "BoldHelpFont", PREF_STRING,
852 "-*-helvetica-bold-r-normal--*-120-*-*-*-iso8859-1",
853 PrefData.helpFontNames[BOLD_HELP_FONT],
854 (void *)sizeof(PrefData.helpFontNames[BOLD_HELP_FONT]), False},
855 {"italicHelpFont", "ItalicHelpFont", PREF_STRING,
856 "-*-helvetica-medium-o-normal--*-120-*-*-*-iso8859-1",
857 PrefData.helpFontNames[ITALIC_HELP_FONT],
858 (void *)sizeof(PrefData.helpFontNames[ITALIC_HELP_FONT]), False},
859 {"boldItalicHelpFont", "BoldItalicHelpFont", PREF_STRING,
860 "-*-helvetica-bold-o-normal--*-120-*-*-*-iso8859-1",
861 PrefData.helpFontNames[BOLD_ITALIC_HELP_FONT],
862 (void *)sizeof(PrefData.helpFontNames[BOLD_ITALIC_HELP_FONT]), False},
863 {"fixedHelpFont", "FixedHelpFont", PREF_STRING,
864 "-*-courier-medium-r-normal--*-120-*-*-*-iso8859-1",
865 PrefData.helpFontNames[FIXED_HELP_FONT],
866 (void *)sizeof(PrefData.helpFontNames[FIXED_HELP_FONT]), False},
867 {"boldFixedHelpFont", "BoldFixedHelpFont", PREF_STRING,
868 "-*-courier-bold-r-normal--*-120-*-*-*-iso8859-1",
869 PrefData.helpFontNames[BOLD_FIXED_HELP_FONT],
870 (void *)sizeof(PrefData.helpFontNames[BOLD_FIXED_HELP_FONT]), False},
871 {"italicFixedHelpFont", "ItalicFixedHelpFont", PREF_STRING,
872 "-*-courier-medium-o-normal--*-120-*-*-*-iso8859-1",
873 PrefData.helpFontNames[ITALIC_FIXED_HELP_FONT],
874 (void *)sizeof(PrefData.helpFontNames[ITALIC_FIXED_HELP_FONT]), False},
875 {"boldItalicFixedHelpFont", "BoldItalicFixedHelpFont", PREF_STRING,
876 "-*-courier-bold-o-normal--*-120-*-*-*-iso8859-1",
877 PrefData.helpFontNames[BOLD_ITALIC_FIXED_HELP_FONT],
878 (void *)sizeof(PrefData.helpFontNames[BOLD_ITALIC_FIXED_HELP_FONT]), False},
879 {"helpLinkFont", "HelpLinkFont", PREF_STRING,
880 "-*-helvetica-medium-r-normal--*-120-*-*-*-iso8859-1",
881 PrefData.helpFontNames[HELP_LINK_FONT],
882 (void *)sizeof(PrefData.helpFontNames[HELP_LINK_FONT]), False},
883 {"h1HelpFont", "H1HelpFont", PREF_STRING,
884 "-*-helvetica-bold-r-normal--*-140-*-*-*-iso8859-1",
885 PrefData.helpFontNames[H1_HELP_FONT],
886 (void *)sizeof(PrefData.helpFontNames[H1_HELP_FONT]), False},
887 {"h2HelpFont", "H2HelpFont", PREF_STRING,
888 "-*-helvetica-bold-o-normal--*-120-*-*-*-iso8859-1",
889 PrefData.helpFontNames[H2_HELP_FONT],
890 (void *)sizeof(PrefData.helpFontNames[H2_HELP_FONT]), False},
891 {"h3HelpFont", "H3HelpFont", PREF_STRING,
892 "-*-courier-bold-r-normal--*-120-*-*-*-iso8859-1",
893 PrefData.helpFontNames[H3_HELP_FONT],
894 (void *)sizeof(PrefData.helpFontNames[H3_HELP_FONT]), False},
895 {"helpLinkColor", "HelpLinkColor", PREF_STRING, "#009900",
896 PrefData.helpLinkColor,
897 (void *)sizeof(PrefData.helpLinkColor), False},
899 {"textFgColor", "TextFgColor", PREF_STRING, NEDIT_DEFAULT_FG,
900 PrefData.colorNames[TEXT_FG_COLOR],
901 (void *)sizeof(PrefData.colorNames[TEXT_FG_COLOR]), True},
902 {"textBgColor", "TextBgColor", PREF_STRING, NEDIT_DEFAULT_TEXT_BG,
903 PrefData.colorNames[TEXT_BG_COLOR],
904 (void *)sizeof(PrefData.colorNames[TEXT_BG_COLOR]), True},
905 {"selectFgColor", "SelectFgColor", PREF_STRING, NEDIT_DEFAULT_SEL_FG,
906 PrefData.colorNames[SELECT_FG_COLOR],
907 (void *)sizeof(PrefData.colorNames[SELECT_FG_COLOR]), True},
908 {"selectBgColor", "SelectBgColor", PREF_STRING, NEDIT_DEFAULT_SEL_BG,
909 PrefData.colorNames[SELECT_BG_COLOR],
910 (void *)sizeof(PrefData.colorNames[SELECT_BG_COLOR]), True},
911 {"hiliteFgColor", "HiliteFgColor", PREF_STRING, NEDIT_DEFAULT_HI_FG,
912 PrefData.colorNames[HILITE_FG_COLOR],
913 (void *)sizeof(PrefData.colorNames[HILITE_FG_COLOR]), True},
914 {"hiliteBgColor", "HiliteBgColor", PREF_STRING, NEDIT_DEFAULT_HI_BG,
915 PrefData.colorNames[HILITE_BG_COLOR],
916 (void *)sizeof(PrefData.colorNames[HILITE_BG_COLOR]), True},
917 {"lineNoFgColor", "LineNoFgColor", PREF_STRING, NEDIT_DEFAULT_LINENO_FG,
918 PrefData.colorNames[LINENO_FG_COLOR],
919 (void *)sizeof(PrefData.colorNames[LINENO_FG_COLOR]), True},
920 {"cursorFgColor", "CursorFgColor", PREF_STRING, NEDIT_DEFAULT_CURSOR_FG,
921 PrefData.colorNames[CURSOR_FG_COLOR],
922 (void *)sizeof(PrefData.colorNames[CURSOR_FG_COLOR]), True},
923 {"tooltipBgColor", "TooltipBgColor", PREF_STRING, "LemonChiffon1",
924 PrefData.tooltipBgColor,
925 (void *)sizeof(PrefData.tooltipBgColor), False},
927 {"shell", "Shell", PREF_STRING,
928 #if defined(__MVS__) || defined(__EMX__)
929 "/bin/sh",
930 #else
931 "/bin/csh",
932 #endif
933 PrefData.shell, (void *)sizeof(PrefData.shell), False},
934 {"geometry", "Geometry", PREF_STRING, "",
935 PrefData.geometry, (void *)sizeof(PrefData.geometry), False},
936 {"remapDeleteKey", "RemapDeleteKey", PREF_BOOLEAN, "False",
937 &PrefData.mapDelete, NULL, False},
938 {"stdOpenDialog", "StdOpenDialog", PREF_BOOLEAN, "False",
939 &PrefData.stdOpenDialog, NULL, False},
940 {"tagFile", "TagFile", PREF_STRING,
941 "", PrefData.tagFile, (void *)sizeof(PrefData.tagFile), False},
942 {"wordDelimiters", "WordDelimiters", PREF_STRING,
943 ".,/\\`'!|@#%^&*()-=+{}[]\":;<>?",
944 PrefData.delimiters, (void *)sizeof(PrefData.delimiters), False},
945 {"serverName", "ServerName", PREF_STRING, "", PrefData.serverName,
946 (void *)sizeof(PrefData.serverName), False},
947 {"maxPrevOpenFiles", "MaxPrevOpenFiles", PREF_INT, "30",
948 &PrefData.maxPrevOpenFiles, NULL, False},
949 {"bgMenuButton", "BGMenuButton" , PREF_STRING,
950 "~Shift~Ctrl~Meta~Alt<Btn3Down>", PrefData.bgMenuBtn,
951 (void *)sizeof(PrefData.bgMenuBtn), False},
952 {"smartTags", "SmartTags", PREF_BOOLEAN, "True",
953 &PrefData.smartTags, NULL, True},
954 {"typingHidesPointer", "TypingHidesPointer", PREF_BOOLEAN, "False",
955 &PrefData.typingHidesPointer, NULL, False},
956 {"alwaysCheckRelativeTagsSpecs", "AlwaysCheckRelativeTagsSpecs",
957 PREF_BOOLEAN, "True", &PrefData.alwaysCheckRelativeTagsSpecs, NULL, False},
958 {"prefFileRead", "PrefFileRead", PREF_BOOLEAN, "False",
959 &PrefData.prefFileRead, NULL, True},
960 #ifdef SGI_CUSTOM
961 {"shortMenus", "ShortMenus", PREF_BOOLEAN, "False", &PrefData.shortMenus,
962 NULL, True},
963 #endif
964 {"findReplaceUsesSelection", "FindReplaceUsesSelection", PREF_BOOLEAN, "False",
965 &PrefData.findReplaceUsesSelection, NULL, False},
966 {"overrideDefaultVirtualKeyBindings", "OverrideDefaultVirtualKeyBindings",
967 PREF_ENUM, "Auto", &PrefData.virtKeyOverride, VirtKeyOverrideModes, False},
968 {"titleFormat", "TitleFormat", PREF_STRING, "{%c} [%s] %f (%S) - %d",
969 PrefData.titleFormat, (void *)sizeof(PrefData.titleFormat), True},
970 {"undoModifiesSelection", "UndoModifiesSelection", PREF_BOOLEAN,
971 "True", &PrefData.undoModifiesSelection, NULL, False},
974 static XrmOptionDescRec OpTable[] = {
975 {"-wrap", ".autoWrap", XrmoptionNoArg, (caddr_t)"Continuous"},
976 {"-nowrap", ".autoWrap", XrmoptionNoArg, (caddr_t)"None"},
977 {"-autowrap", ".autoWrap", XrmoptionNoArg, (caddr_t)"Newline"},
978 {"-noautowrap", ".autoWrap", XrmoptionNoArg, (caddr_t)"None"},
979 {"-autoindent", ".autoIndent", XrmoptionNoArg, (caddr_t)"Auto"},
980 {"-noautoindent", ".autoIndent", XrmoptionNoArg, (caddr_t)"False"},
981 {"-autosave", ".autoSave", XrmoptionNoArg, (caddr_t)"True"},
982 {"-noautosave", ".autoSave", XrmoptionNoArg, (caddr_t)"False"},
983 {"-rows", ".textRows", XrmoptionSepArg, (caddr_t)NULL},
984 {"-columns", ".textCols", XrmoptionSepArg, (caddr_t)NULL},
985 {"-tabs", ".tabDistance", XrmoptionSepArg, (caddr_t)NULL},
986 {"-font", ".textFont", XrmoptionSepArg, (caddr_t)NULL},
987 {"-fn", ".textFont", XrmoptionSepArg, (caddr_t)NULL},
988 {"-svrname", ".serverName", XrmoptionSepArg, (caddr_t)NULL},
991 static const char HeaderText[] = "\
992 ! Preferences file for NEdit\n\
993 !\n\
994 ! This file is overwritten by the \"Save Defaults...\" command in NEdit \n\
995 ! and serves only the interactively settable options presented in the NEdit\n\
996 ! \"Preferences\" menu. To modify other options, such as key bindings, use \n\
997 ! the .Xdefaults file in your home directory (or the X resource \n\
998 ! specification method appropriate to your system). The contents of this \n\
999 ! file can be moved into an X resource file, but since resources in this file\n\
1000 ! override their corresponding X resources, either this file should be \n\
1001 ! deleted or individual resource lines in the file should be deleted for the\n\
1002 ! moved lines to take effect.\n";
1004 /* Module-global variable set when any preference changes (for asking the
1005 user about re-saving on exit) */
1006 static int PrefsHaveChanged = False;
1008 /* Module-global variable set when user uses -import to load additional
1009 preferences on top of the defaults. Contains name of file loaded */
1010 static char *ImportedFile = NULL;
1012 /* Module-global variables to support Initial Window Size... dialog */
1013 static int DoneWithSizeDialog;
1014 static Widget RowText, ColText;
1016 /* Module-global variables for Tabs dialog */
1017 static int DoneWithTabsDialog;
1018 static WindowInfo *TabsDialogForWindow;
1019 static Widget TabDistText, EmTabText, EmTabToggle, UseTabsToggle, EmTabLabel;
1021 /* Module-global variables for Wrap Margin dialog */
1022 static int DoneWithWrapDialog;
1023 static WindowInfo *WrapDialogForWindow;
1024 static Widget WrapText, WrapTextLabel, WrapWindowToggle;
1026 static void translatePrefFormats(int convertOld, int fileVer);
1027 static void setIntPref(int *prefDataField, int newValue);
1028 static void setStringPref(char *prefDataField, const char *newValue);
1029 static void sizeOKCB(Widget w, XtPointer clientData, XtPointer callData);
1030 static void setStringAllocPref(char **pprefDataField, char *newValue);
1031 static void sizeCancelCB(Widget w, XtPointer clientData, XtPointer callData);
1032 static void tabsOKCB(Widget w, XtPointer clientData, XtPointer callData);
1033 static void tabsCancelCB(Widget w, XtPointer clientData, XtPointer callData);
1034 static void tabsHelpCB(Widget w, XtPointer clientData, XtPointer callData);
1035 static void emTabsCB(Widget w, XtPointer clientData, XtPointer callData);
1036 static void wrapOKCB(Widget w, XtPointer clientData, XtPointer callData);
1037 static void wrapCancelCB(Widget w, XtPointer clientData, XtPointer callData);
1038 static void wrapWindowCB(Widget w, XtPointer clientData, XtPointer callData);
1039 static void reapplyLanguageMode(WindowInfo *window, int mode,int forceDefaults);
1042 static void fillFromPrimaryCB(Widget w, XtPointer clientData,
1043 XtPointer callData);
1044 static int checkFontStatus(fontDialog *fd, Widget fontTextFieldW);
1045 static int showFontStatus(fontDialog *fd, Widget fontTextFieldW,
1046 Widget errorLabelW);
1047 static void primaryModifiedCB(Widget w, XtPointer clientData,
1048 XtPointer callData);
1049 static void italicModifiedCB(Widget w, XtPointer clientData,
1050 XtPointer callData);
1051 static void boldModifiedCB(Widget w, XtPointer clientData, XtPointer callData);
1052 static void boldItalicModifiedCB(Widget w, XtPointer clientData,
1053 XtPointer callData);
1054 static void primaryBrowseCB(Widget w, XtPointer clientData, XtPointer callData);
1055 static void italicBrowseCB(Widget w, XtPointer clientData, XtPointer callData);
1056 static void boldBrowseCB(Widget w, XtPointer clientData, XtPointer callData);
1057 static void boldItalicBrowseCB(Widget w, XtPointer clientData,
1058 XtPointer callData);
1059 static void browseFont(Widget parent, Widget fontTextW);
1060 static void fontDestroyCB(Widget w, XtPointer clientData, XtPointer callData);
1061 static void fontOkCB(Widget w, XtPointer clientData, XtPointer callData);
1062 static void fontApplyCB(Widget w, XtPointer clientData, XtPointer callData);
1063 static void fontDismissCB(Widget w, XtPointer clientData, XtPointer callData);
1064 static void updateFonts(fontDialog *fd);
1066 static Boolean checkColorStatus(colorDialog *cd, Widget colorFieldW);
1067 static int verifyAllColors (colorDialog *cd);
1068 static void showColorStatus (colorDialog *cd, Widget colorFieldW,
1069 Widget errorLabelW);
1070 static void updateColors(colorDialog *cd);
1071 static void colorDestroyCB(Widget w, XtPointer clientData, XtPointer callData);
1072 static void colorOkCB (Widget w, XtPointer clientData, XtPointer callData);
1073 static void colorApplyCB (Widget w, XtPointer clientData, XtPointer callData);
1074 static void colorDismissCB(Widget w, XtPointer clientData, XtPointer callData);
1075 static void textFgModifiedCB (Widget w, XtPointer clientData,
1076 XtPointer callData);
1077 static void textBgModifiedCB (Widget w, XtPointer clientData,
1078 XtPointer callData);
1079 static void selectFgModifiedCB(Widget w, XtPointer clientData,
1080 XtPointer callData);
1081 static void selectBgModifiedCB(Widget w, XtPointer clientData,
1082 XtPointer callData);
1083 static void hiliteFgModifiedCB(Widget w, XtPointer clientData,
1084 XtPointer callData);
1085 static void hiliteBgModifiedCB(Widget w, XtPointer clientData,
1086 XtPointer callData);
1087 static void lineNoFgModifiedCB(Widget w, XtPointer clientData,
1088 XtPointer callData);
1089 static void cursorFgModifiedCB(Widget w, XtPointer clientData,
1090 XtPointer callData);
1092 static int matchLanguageMode(WindowInfo *window);
1093 static int loadLanguageModesString(char *inString, int fileVer);
1094 static char *writeLanguageModesString(void);
1095 static char *createExtString(char **extensions, int nExtensions);
1096 static char **readExtensionList(char **inPtr, int *nExtensions);
1097 static void updateLanguageModeSubmenu(WindowInfo *window);
1098 static void setLangModeCB(Widget w, XtPointer clientData, XtPointer callData);
1099 static int modeError(languageModeRec *lm, const char *stringStart,
1100 const char *stoppedAt, const char *message);
1101 static void lmDestroyCB(Widget w, XtPointer clientData, XtPointer callData);
1102 static void lmOkCB(Widget w, XtPointer clientData, XtPointer callData);
1103 static void lmApplyCB(Widget w, XtPointer clientData, XtPointer callData);
1104 static void lmDismissCB(Widget w, XtPointer clientData, XtPointer callData);
1105 static int lmDeleteConfirmCB(int itemIndex, void *cbArg);
1106 static int updateLMList(void);
1107 static languageModeRec *copyLanguageModeRec(languageModeRec *lm);
1108 static void *lmGetDisplayedCB(void *oldItem, int explicitRequest, int *abort,
1109 void *cbArg);
1110 static void lmSetDisplayedCB(void *item, void *cbArg);
1111 static languageModeRec *readLMDialogFields(int silent);
1112 static void lmFreeItemCB(void *item);
1113 static void freeLanguageModeRec(languageModeRec *lm);
1114 static int lmDialogEmpty(void);
1115 static void updatePatternsTo5dot1(void);
1116 static void updatePatternsTo5dot2(void);
1117 static void updatePatternsTo5dot3(void);
1118 static void updatePatternsTo5dot4(void);
1119 static void updateShellCmdsTo5dot3(void);
1120 static void updateShellCmdsTo5dot4(void);
1121 static void updateMacroCmdsTo5dot5(void);
1122 static void migrateColorResources(XrmDatabase prefDB, XrmDatabase appDB);
1123 static void spliceString(char **intoString, const char *insertString, const char *atExpr);
1124 static int regexFind(const char *inString, const char *expr);
1125 static int regexReplace(char **inString, const char *expr,
1126 const char *replaceWith);
1128 #ifdef SGI_CUSTOM
1129 static int shortPrefToDefault(Widget parent, const char *settingName, int *setDefault);
1130 #endif
1132 XrmDatabase CreateNEditPrefDB(int *argcInOut, char **argvInOut)
1134 return CreatePreferencesDatabase(GetRCFileName(NEDIT_RC), APP_NAME,
1135 OpTable, XtNumber(OpTable), (unsigned int *)argcInOut, argvInOut);
1138 void RestoreNEditPrefs(XrmDatabase prefDB, XrmDatabase appDB)
1140 int requiresConversion;
1141 int major; /* The integral part of version number */
1142 int minor; /* fractional part of version number */
1143 int fileVer = 0; /* Both combined into an integer */
1144 int nparsed;
1146 /* Load preferences */
1147 RestorePreferences(prefDB, appDB, APP_NAME,
1148 APP_CLASS, PrefDescrip, XtNumber(PrefDescrip));
1150 /* If the preferences file was written by an older version of NEdit,
1151 warn the user that it will be converted. */
1152 requiresConversion = PrefData.prefFileRead &&
1153 PrefData.fileVersion[0] == '\0';
1154 if (requiresConversion) {
1155 updatePatternsTo5dot1();
1158 if (PrefData.prefFileRead) {
1159 if (PrefData.fileVersion[0] == '\0') {
1160 fileVer = 0; /* Pre-5.1 */
1162 else {
1163 /* Note: do not change the format of this. Older executables
1164 need to read this field for forward compatability. */
1165 nparsed = sscanf(PrefData.fileVersion, "%d.%d", &major, &minor);
1166 if (nparsed >= 2) {
1167 /* Use OSF-style numbering scheme */
1168 fileVer = major * 1000 + minor;
1173 if (PrefData.prefFileRead && fileVer < 5002) {
1174 updatePatternsTo5dot2();
1177 if (PrefData.prefFileRead && fileVer < 5003) {
1178 updateShellCmdsTo5dot3();
1179 updatePatternsTo5dot3();
1182 /* Note that we don't care about unreleased file versions. Anyone
1183 who is running a CVS or alpha version of NEdit is resposnbile
1184 for managing the preferences file themselves. Otherwise, it
1185 gets impossible to track the number of "in-between" file formats.
1186 We only do auto-upgrading for a real release. */
1188 if (PrefData.prefFileRead && (fileVer < 5004)) {
1189 /* There are some implict conversions done later - show this
1190 message even if there's no explicit call to upgrade. */
1191 fprintf(stderr, "NEdit: Converting .nedit file to 5.4 version.\n"
1192 " To keep, use Preferences -> Save Defaults\n");
1193 migrateColorResources(prefDB, appDB);
1194 updateShellCmdsTo5dot4();
1195 updatePatternsTo5dot4();
1197 if (PrefData.prefFileRead && (fileVer < 5005)) {
1198 /* Uncomment this in the next release
1199 fprintf(stderr, "NEdit: Converting .nedit file to 5.5 version.\n"
1200 " To keep, use Preferences -> Save Defaults\n"); */
1201 updateMacroCmdsTo5dot5();
1203 /* Migrate colors if there's no config file yet */
1204 if (!PrefData.prefFileRead) {
1205 migrateColorResources(prefDB, appDB);
1208 /* Do further parsing on resource types which RestorePreferences does
1209 not understand and reads as strings, to put them in the final form
1210 in which nedit stores and uses. If the preferences file was
1211 written by an older version of NEdit, update regular expressions in
1212 highlight patterns to quote braces and use & instead of \0 */
1213 translatePrefFormats(requiresConversion, fileVer);
1217 ** Many of of NEdit's preferences are much more complicated than just simple
1218 ** integers or strings. These are read as strings, but must be parsed and
1219 ** translated into something meaningful. This routine does the translation,
1220 ** and, in most cases, frees the original string, which is no longer useful.
1222 ** The argument convertOld attempts a conversion from pre 5.1 format .nedit
1223 ** files (which means patterns and macros may contain regular expressions
1224 ** which are of the older syntax where braces were not quoted, and \0 was a
1225 ** legal substitution character). Macros, so far can not be automatically
1226 ** converted, unfortunately.
1228 static void translatePrefFormats(int convertOld, int fileVer)
1230 XFontStruct *font;
1232 /* Parse the strings which represent types which are not decoded by
1233 the standard resource manager routines */
1234 #ifndef VMS
1235 if (TempStringPrefs.shellCmds != NULL) {
1236 LoadShellCmdsString(TempStringPrefs.shellCmds);
1237 XtFree(TempStringPrefs.shellCmds);
1238 TempStringPrefs.shellCmds = NULL;
1240 #endif /* VMS */
1241 if (TempStringPrefs.macroCmds != NULL) {
1242 LoadMacroCmdsString(TempStringPrefs.macroCmds);
1243 XtFree(TempStringPrefs.macroCmds);
1244 TempStringPrefs.macroCmds = NULL;
1246 if (TempStringPrefs.bgMenuCmds != NULL) {
1247 LoadBGMenuCmdsString(TempStringPrefs.bgMenuCmds);
1248 XtFree(TempStringPrefs.bgMenuCmds);
1249 TempStringPrefs.bgMenuCmds = NULL;
1251 if (TempStringPrefs.highlight != NULL) {
1252 LoadHighlightString(TempStringPrefs.highlight, convertOld);
1253 XtFree(TempStringPrefs.highlight);
1254 TempStringPrefs.highlight = NULL;
1256 if (TempStringPrefs.styles != NULL) {
1257 LoadStylesString(TempStringPrefs.styles);
1258 XtFree(TempStringPrefs.styles);
1259 TempStringPrefs.styles = NULL;
1261 if (TempStringPrefs.language != NULL) {
1262 loadLanguageModesString(TempStringPrefs.language, fileVer);
1263 XtFree(TempStringPrefs.language);
1264 TempStringPrefs.language = NULL;
1266 if (TempStringPrefs.smartIndent != NULL) {
1267 LoadSmartIndentString(TempStringPrefs.smartIndent);
1268 XtFree(TempStringPrefs.smartIndent);
1269 TempStringPrefs.smartIndent = NULL;
1271 if (TempStringPrefs.smartIndentCommon != NULL) {
1272 LoadSmartIndentCommonString(TempStringPrefs.smartIndentCommon);
1273 XtFree(TempStringPrefs.smartIndentCommon);
1274 TempStringPrefs.smartIndentCommon = NULL;
1277 /* translate the font names into fontLists suitable for the text widget */
1278 font = XLoadQueryFont(TheDisplay, PrefData.fontString);
1279 PrefData.fontList = font==NULL ? NULL :
1280 XmFontListCreate(font, XmSTRING_DEFAULT_CHARSET);
1281 PrefData.boldFontStruct = XLoadQueryFont(TheDisplay,
1282 PrefData.boldFontString);
1283 PrefData.italicFontStruct = XLoadQueryFont(TheDisplay,
1284 PrefData.italicFontString);
1285 PrefData.boldItalicFontStruct = XLoadQueryFont(TheDisplay,
1286 PrefData.boldItalicFontString);
1288 /* For compatability with older (4.0.3 and before) versions, the autoWrap
1289 and autoIndent resources can accept values of True and False. Translate
1290 them into acceptable wrap and indent styles */
1291 if (PrefData.wrapStyle == 3) PrefData.wrapStyle = NEWLINE_WRAP;
1292 if (PrefData.wrapStyle == 4) PrefData.wrapStyle = NO_WRAP;
1293 if (PrefData.autoIndent == 3) PrefData.autoIndent = AUTO_INDENT;
1294 if (PrefData.autoIndent == 4) PrefData.autoIndent = NO_AUTO_INDENT;
1296 /* setup language mode dependent info of user menus (to increase
1297 performance when switching between documents of different
1298 language modes) */
1299 SetupUserMenuInfo();
1302 void SaveNEditPrefs(Widget parent, int quietly)
1304 const char* prefFileName = GetRCFileName(NEDIT_RC);
1305 if (prefFileName == NULL)
1307 /* GetRCFileName() might return NULL if an error occurs during
1308 creation of the preference file directory. */
1309 DialogF(DF_WARN, parent, 1, "Error saving Preferences",
1310 "Unable to save preferences: Cannot determine filename.",
1311 "Dismiss");
1312 return;
1315 if (!quietly) {
1316 if (DialogF(DF_INF, parent, 2, "Save Preferences",
1317 ImportedFile == NULL ?
1318 "Default preferences will be saved in the file:\n"
1319 "%s\n"
1320 "NEdit automatically loads this file\n"
1321 "each time it is started." :
1322 "Default preferences will be saved in the file:\n"
1323 "%s\n"
1324 "SAVING WILL INCORPORATE SETTINGS\n"
1325 "FROM FILE: %s", "OK", "Cancel",
1326 prefFileName, ImportedFile) == 2)
1327 return;
1329 #ifndef VMS
1330 TempStringPrefs.shellCmds = WriteShellCmdsString();
1331 #endif /* VMS */
1332 TempStringPrefs.macroCmds = WriteMacroCmdsString();
1333 TempStringPrefs.bgMenuCmds = WriteBGMenuCmdsString();
1334 TempStringPrefs.highlight = WriteHighlightString();
1335 TempStringPrefs.language = writeLanguageModesString();
1336 TempStringPrefs.styles = WriteStylesString();
1337 TempStringPrefs.smartIndent = WriteSmartIndentString();
1338 TempStringPrefs.smartIndentCommon = WriteSmartIndentCommonString();
1339 strcpy(PrefData.fileVersion, PREF_FILE_VERSION);
1340 if (!SavePreferences(XtDisplay(parent), prefFileName, HeaderText,
1341 PrefDescrip, XtNumber(PrefDescrip)))
1343 DialogF(DF_WARN, parent, 1, "Save Preferences",
1344 "Unable to save preferences in %s", "Dismiss", prefFileName);
1347 #ifndef VMS
1348 XtFree(TempStringPrefs.shellCmds);
1349 #endif /* VMS */
1350 XtFree(TempStringPrefs.macroCmds);
1351 XtFree(TempStringPrefs.bgMenuCmds);
1352 XtFree(TempStringPrefs.highlight);
1353 XtFree(TempStringPrefs.language);
1354 XtFree(TempStringPrefs.styles);
1355 XtFree(TempStringPrefs.smartIndent);
1356 XtFree(TempStringPrefs.smartIndentCommon);
1358 PrefsHaveChanged = False;
1362 ** Load an additional preferences file on top of the existing preferences
1363 ** derived from defaults, the .nedit file, and X resources.
1365 void ImportPrefFile(const char *filename, int convertOld)
1367 XrmDatabase db;
1368 char *fileString;
1370 fileString = ReadAnyTextFile(filename);
1371 if (fileString != NULL){
1372 db = XrmGetStringDatabase(fileString);
1373 XtFree(fileString);
1374 OverlayPreferences(db, APP_NAME, APP_CLASS, PrefDescrip,
1375 XtNumber(PrefDescrip));
1376 translatePrefFormats(convertOld, -1);
1377 ImportedFile = XtNewString(filename);
1378 } else
1380 fprintf(stderr, "Could not read additional preferences file: ");
1381 fprintf(stderr, filename);
1382 fprintf(stderr, "\n");
1386 void SetPrefOpenInTab(int state)
1388 setIntPref(&PrefData.openInTab, state);
1391 int GetPrefOpenInTab(void)
1393 return PrefData.openInTab;
1396 void SetPrefWrap(int state)
1398 setIntPref(&PrefData.wrapStyle, state);
1401 int GetPrefWrap(int langMode)
1403 if (langMode == PLAIN_LANGUAGE_MODE ||
1404 LanguageModes[langMode]->wrapStyle == DEFAULT_WRAP)
1405 return PrefData.wrapStyle;
1406 return LanguageModes[langMode]->wrapStyle;
1409 void SetPrefWrapMargin(int margin)
1411 setIntPref(&PrefData.wrapMargin, margin);
1414 int GetPrefWrapMargin(void)
1416 return PrefData.wrapMargin;
1419 void SetPrefSearch(int searchType)
1421 setIntPref(&PrefData.searchMethod, searchType);
1424 int GetPrefSearch(void)
1426 return PrefData.searchMethod;
1429 #ifdef REPLACE_SCOPE
1430 void SetPrefReplaceDefScope(int scope)
1432 setIntPref(&PrefData.replaceDefScope, scope);
1435 int GetPrefReplaceDefScope(void)
1437 return PrefData.replaceDefScope;
1439 #endif
1441 void SetPrefAutoIndent(int state)
1443 setIntPref(&PrefData.autoIndent, state);
1446 int GetPrefAutoIndent(int langMode)
1448 if (langMode == PLAIN_LANGUAGE_MODE ||
1449 LanguageModes[langMode]->indentStyle == DEFAULT_INDENT)
1450 return PrefData.autoIndent;
1451 return LanguageModes[langMode]->indentStyle;
1454 void SetPrefAutoSave(int state)
1456 setIntPref(&PrefData.autoSave, state);
1459 int GetPrefAutoSave(void)
1461 return PrefData.autoSave;
1464 void SetPrefSaveOldVersion(int state)
1466 setIntPref(&PrefData.saveOldVersion, state);
1469 int GetPrefSaveOldVersion(void)
1471 return PrefData.saveOldVersion;
1474 void SetPrefSearchDlogs(int state)
1476 setIntPref(&PrefData.searchDlogs, state);
1479 int GetPrefSearchDlogs(void)
1481 return PrefData.searchDlogs;
1484 void SetPrefBeepOnSearchWrap(int state)
1486 setIntPref(&PrefData.searchWrapBeep, state);
1489 int GetPrefBeepOnSearchWrap(void)
1491 return PrefData.searchWrapBeep;
1494 void SetPrefKeepSearchDlogs(int state)
1496 setIntPref(&PrefData.keepSearchDlogs, state);
1499 int GetPrefKeepSearchDlogs(void)
1501 return PrefData.keepSearchDlogs;
1504 void SetPrefSearchWraps(int state)
1506 setIntPref(&PrefData.searchWraps, state);
1509 int GetPrefStickyCaseSenseBtn(void)
1511 return PrefData.stickyCaseSenseBtn;
1514 void SetPrefStickyCaseSenseBtn(int state)
1516 setIntPref(&PrefData.stickyCaseSenseBtn, state);
1519 int GetPrefSearchWraps(void)
1521 return PrefData.searchWraps;
1524 void SetPrefStatsLine(int state)
1526 setIntPref(&PrefData.statsLine, state);
1529 int GetPrefStatsLine(void)
1531 return PrefData.statsLine;
1534 void SetPrefISearchLine(int state)
1536 setIntPref(&PrefData.iSearchLine, state);
1539 int GetPrefISearchLine(void)
1541 return PrefData.iSearchLine;
1544 void SetPrefSortTabs(int state)
1546 setIntPref(&PrefData.sortTabs, state);
1549 int GetPrefSortTabs(void)
1551 return PrefData.sortTabs;
1554 void SetPrefTabBar(int state)
1556 setIntPref(&PrefData.tabBar, state);
1559 int GetPrefTabBar(void)
1561 return PrefData.tabBar;
1564 void SetPrefTabBarHideOne(int state)
1566 setIntPref(&PrefData.tabBarHideOne, state);
1569 int GetPrefTabBarHideOne(void)
1571 return PrefData.tabBarHideOne;
1574 void SetPrefGlobalTabNavigate(int state)
1576 setIntPref(&PrefData.globalTabNavigate, state);
1579 int GetPrefGlobalTabNavigate(void)
1581 return PrefData.globalTabNavigate;
1584 void SetPrefToolTips(int state)
1586 setIntPref(&PrefData.toolTips, state);
1589 int GetPrefToolTips(void)
1591 return PrefData.toolTips;
1594 void SetPrefLineNums(int state)
1596 setIntPref(&PrefData.lineNums, state);
1599 int GetPrefLineNums(void)
1601 return PrefData.lineNums;
1604 void SetPrefShowPathInWindowsMenu(int state)
1606 setIntPref(&PrefData.pathInWindowsMenu, state);
1609 int GetPrefShowPathInWindowsMenu(void)
1611 return PrefData.pathInWindowsMenu;
1614 void SetPrefWarnFileMods(int state)
1616 setIntPref(&PrefData.warnFileMods, state);
1619 int GetPrefWarnFileMods(void)
1621 return PrefData.warnFileMods;
1624 void SetPrefWarnRealFileMods(int state)
1626 setIntPref(&PrefData.warnRealFileMods, state);
1629 int GetPrefWarnRealFileMods(void)
1631 return PrefData.warnRealFileMods;
1634 void SetPrefWarnExit(int state)
1636 setIntPref(&PrefData.warnExit, state);
1639 int GetPrefWarnExit(void)
1641 return PrefData.warnExit;
1644 void SetPrefv(int state)
1646 setIntPref(&PrefData.findReplaceUsesSelection, state);
1649 int GetPrefFindReplaceUsesSelection(void)
1651 return PrefData.findReplaceUsesSelection;
1654 void SetPrefMapDelete(int state)
1656 setIntPref(&PrefData.mapDelete, state);
1659 int GetPrefMapDelete(void)
1661 return PrefData.mapDelete;
1664 void SetPrefStdOpenDialog(int state)
1666 setIntPref(&PrefData.stdOpenDialog, state);
1669 int GetPrefStdOpenDialog(void)
1671 return PrefData.stdOpenDialog;
1674 void SetPrefRows(int nRows)
1676 setIntPref(&PrefData.textRows, nRows);
1679 int GetPrefRows(void)
1681 return PrefData.textRows;
1684 void SetPrefCols(int nCols)
1686 setIntPref(&PrefData.textCols, nCols);
1689 int GetPrefCols(void)
1691 return PrefData.textCols;
1694 void SetPrefTabDist(int tabDist)
1696 setIntPref(&PrefData.tabDist, tabDist);
1699 int GetPrefTabDist(int langMode)
1701 int tabDist;
1702 if (langMode == PLAIN_LANGUAGE_MODE ||
1703 LanguageModes[langMode]->tabDist == DEFAULT_TAB_DIST) {
1704 tabDist = PrefData.tabDist;
1705 } else {
1706 tabDist = LanguageModes[langMode]->tabDist;
1708 /* Make sure that the tab distance is in range (garbage may have
1709 been entered via the command line or the X resources, causing
1710 errors later on, like division by zero). */
1711 if (tabDist <= 0) return 1;
1712 if (tabDist > MAX_EXP_CHAR_LEN) return MAX_EXP_CHAR_LEN;
1713 return tabDist;
1716 void SetPrefEmTabDist(int tabDist)
1718 setIntPref(&PrefData.emTabDist, tabDist);
1721 int GetPrefEmTabDist(int langMode)
1723 if (langMode == PLAIN_LANGUAGE_MODE ||
1724 LanguageModes[langMode]->emTabDist == DEFAULT_EM_TAB_DIST)
1725 return PrefData.emTabDist;
1726 return LanguageModes[langMode]->emTabDist;
1729 void SetPrefInsertTabs(int state)
1731 setIntPref(&PrefData.insertTabs, state);
1734 int GetPrefInsertTabs(void)
1736 return PrefData.insertTabs;
1739 void SetPrefShowMatching(int state)
1741 setIntPref(&PrefData.showMatchingStyle, state);
1744 int GetPrefShowMatching(void)
1747 * For backwards compatibility with pre-5.2 versions, the boolean
1748 * False/True matching behavior is converted to NO_FLASH/FLASH_DELIMIT.
1750 if (PrefData.showMatchingStyle >= N_SHOW_MATCHING_STYLES)
1751 PrefData.showMatchingStyle -= N_SHOW_MATCHING_STYLES;
1752 return PrefData.showMatchingStyle;
1755 void SetPrefMatchSyntaxBased(int state)
1757 setIntPref(&PrefData.matchSyntaxBased, state);
1760 int GetPrefMatchSyntaxBased(void)
1762 return PrefData.matchSyntaxBased;
1765 void SetPrefHighlightSyntax(int state)
1767 setIntPref(&PrefData.highlightSyntax, state);
1770 int GetPrefHighlightSyntax(void)
1772 return PrefData.highlightSyntax;
1775 void SetPrefBacklightChars(int state)
1777 setIntPref(&PrefData.backlightChars, state);
1780 int GetPrefBacklightChars(void)
1782 return PrefData.backlightChars;
1785 void SetPrefBacklightCharTypes(char *types)
1787 setStringAllocPref(&PrefData.backlightCharTypes, types);
1790 char *GetPrefBacklightCharTypes(void)
1792 return PrefData.backlightCharTypes;
1795 void SetPrefRepositionDialogs(int state)
1797 setIntPref(&PrefData.repositionDialogs, state);
1800 int GetPrefRepositionDialogs(void)
1802 return PrefData.repositionDialogs;
1805 void SetPrefAutoScroll(int state)
1807 WindowInfo *w = WindowList;
1808 int margin = state ? PrefData.autoScrollVPadding : 0;
1810 setIntPref(&PrefData.autoScroll, state);
1811 for(w = WindowList; w != NULL; w = w->next)
1812 SetAutoScroll(w, margin);
1815 int GetPrefAutoScroll(void)
1817 return PrefData.autoScroll;
1820 int GetVerticalAutoScroll(void)
1822 return PrefData.autoScroll ? PrefData.autoScrollVPadding : 0;
1825 void SetPrefAppendLF(int state)
1827 setIntPref(&PrefData.appendLF, state);
1830 int GetPrefAppendLF(void)
1832 return PrefData.appendLF;
1835 void SetPrefSortOpenPrevMenu(int state)
1837 setIntPref(&PrefData.sortOpenPrevMenu, state);
1840 int GetPrefSortOpenPrevMenu(void)
1842 return PrefData.sortOpenPrevMenu;
1845 void SetPrefTagFile(const char *tagFileName)
1847 setStringPref(PrefData.tagFile, tagFileName);
1850 char *GetPrefTagFile(void)
1852 return PrefData.tagFile;
1855 void SetPrefSmartTags(int state)
1857 setIntPref(&PrefData.smartTags, state);
1860 int GetPrefSmartTags(void)
1862 return PrefData.smartTags;
1865 int GetPrefAlwaysCheckRelTagsSpecs(void)
1867 return PrefData.alwaysCheckRelativeTagsSpecs;
1870 char *GetPrefDelimiters(void)
1872 return PrefData.delimiters;
1875 char *GetPrefColorName(int index)
1877 return PrefData.colorNames[index];
1880 void SetPrefColorName(int index, const char *name)
1882 setStringPref(PrefData.colorNames[index], name);
1886 ** Set the font preferences using the font name (the fontList is generated
1887 ** in this call). Note that this leaks memory and server resources each
1888 ** time the default font is re-set. See note on SetFontByName in window.c
1889 ** for more information.
1891 void SetPrefFont(char *fontName)
1893 XFontStruct *font;
1895 setStringPref(PrefData.fontString, fontName);
1896 font = XLoadQueryFont(TheDisplay, fontName);
1897 PrefData.fontList = font==NULL ? NULL :
1898 XmFontListCreate(font, XmSTRING_DEFAULT_CHARSET);
1901 void SetPrefBoldFont(char *fontName)
1903 setStringPref(PrefData.boldFontString, fontName);
1904 PrefData.boldFontStruct = XLoadQueryFont(TheDisplay, fontName);
1907 void SetPrefItalicFont(char *fontName)
1909 setStringPref(PrefData.italicFontString, fontName);
1910 PrefData.italicFontStruct = XLoadQueryFont(TheDisplay, fontName);
1912 void SetPrefBoldItalicFont(char *fontName)
1914 setStringPref(PrefData.boldItalicFontString, fontName);
1915 PrefData.boldItalicFontStruct = XLoadQueryFont(TheDisplay, fontName);
1918 char *GetPrefFontName(void)
1920 return PrefData.fontString;
1923 char *GetPrefBoldFontName(void)
1925 return PrefData.boldFontString;
1928 char *GetPrefItalicFontName(void)
1930 return PrefData.italicFontString;
1933 char *GetPrefBoldItalicFontName(void)
1935 return PrefData.boldItalicFontString;
1938 XmFontList GetPrefFontList(void)
1940 return PrefData.fontList;
1943 XFontStruct *GetPrefBoldFont(void)
1945 return PrefData.boldFontStruct;
1948 XFontStruct *GetPrefItalicFont(void)
1950 return PrefData.italicFontStruct;
1953 XFontStruct *GetPrefBoldItalicFont(void)
1955 return PrefData.boldItalicFontStruct;
1958 char *GetPrefHelpFontName(int index)
1960 return PrefData.helpFontNames[index];
1963 char *GetPrefHelpLinkColor(void)
1965 return PrefData.helpLinkColor;
1968 char *GetPrefTooltipBgColor(void)
1970 return PrefData.tooltipBgColor;
1973 void SetPrefShell(const char *shell)
1975 setStringPref(PrefData.shell, shell);
1978 char *GetPrefShell(void)
1980 return PrefData.shell;
1983 void SetPrefGeometry(const char *geometry)
1985 setStringPref(PrefData.geometry, geometry);
1988 char *GetPrefGeometry(void)
1990 return PrefData.geometry;
1993 char *GetPrefServerName(void)
1995 return PrefData.serverName;
1998 char *GetPrefBGMenuBtn(void)
2000 return PrefData.bgMenuBtn;
2003 int GetPrefMaxPrevOpenFiles(void)
2005 return PrefData.maxPrevOpenFiles;
2008 int GetPrefTypingHidesPointer(void)
2010 return(PrefData.typingHidesPointer);
2013 #ifdef SGI_CUSTOM
2014 void SetPrefShortMenus(int state)
2016 setIntPref(&PrefData.shortMenus, state);
2019 int GetPrefShortMenus(void)
2021 return PrefData.shortMenus;
2023 #endif
2025 void SetPrefTitleFormat(const char* format)
2027 const WindowInfo* window;
2029 setStringPref(PrefData.titleFormat, format);
2031 /* update all windows */
2032 for (window=WindowList; window!=NULL; window=window->next) {
2033 UpdateWindowTitle(window);
2036 const char* GetPrefTitleFormat(void)
2038 return PrefData.titleFormat;
2041 void SetPrefUndoModifiesSelection(Boolean value)
2043 setIntPref(&PrefData.undoModifiesSelection, value);
2046 Boolean GetPrefUndoModifiesSelection(void)
2048 return (Boolean)PrefData.undoModifiesSelection;
2051 int GetPrefOverrideVirtKeyBindings(void)
2053 return PrefData.virtKeyOverride;
2057 ** If preferences don't get saved, ask the user on exit whether to save
2059 void MarkPrefsChanged(void)
2061 PrefsHaveChanged = True;
2065 ** Check if preferences have changed, and if so, ask the user if he wants
2066 ** to re-save. Returns False if user requests cancelation of Exit (or whatever
2067 ** operation triggered this call to be made).
2069 int CheckPrefsChangesSaved(Widget dialogParent)
2071 int resp;
2073 if (!PrefsHaveChanged)
2074 return True;
2076 resp = DialogF(DF_WARN, dialogParent, 3, "Default Preferences",
2077 ImportedFile == NULL ?
2078 "Default Preferences have changed.\n"
2079 "Save changes to NEdit preference file?" :
2080 "Default Preferences have changed. SAVING \n"
2081 "CHANGES WILL INCORPORATE ADDITIONAL\nSETTINGS FROM FILE: %s",
2082 "Save", "Don't Save", "Cancel", ImportedFile);
2083 if (resp == 2)
2084 return True;
2085 if (resp == 3)
2086 return False;
2088 SaveNEditPrefs(dialogParent, True);
2089 return True;
2093 ** set *prefDataField to newValue, but first check if they're different
2094 ** and update PrefsHaveChanged if a preference setting has now changed.
2096 static void setIntPref(int *prefDataField, int newValue)
2098 if (newValue != *prefDataField)
2099 PrefsHaveChanged = True;
2100 *prefDataField = newValue;
2103 static void setStringPref(char *prefDataField, const char *newValue)
2105 if (strcmp(prefDataField, newValue))
2106 PrefsHaveChanged = True;
2107 strcpy(prefDataField, newValue);
2110 static void setStringAllocPref(char **pprefDataField, char *newValue)
2112 char *p_newField;
2114 /* treat empty strings as nulls */
2115 if (newValue && *newValue == '\0')
2116 newValue = NULL;
2117 if (*pprefDataField && **pprefDataField == '\0')
2118 *pprefDataField = NULL; /* assume statically alloc'ed "" */
2120 /* check changes */
2121 if (!*pprefDataField && !newValue)
2122 return;
2123 else if (!*pprefDataField && newValue)
2124 PrefsHaveChanged = True;
2125 else if (*pprefDataField && !newValue)
2126 PrefsHaveChanged = True;
2127 else if (strcmp(*pprefDataField, newValue))
2128 PrefsHaveChanged = True;
2130 /* get rid of old preference */
2131 if (*pprefDataField)
2132 XtFree(*pprefDataField);
2134 /* store new preference */
2135 if (newValue) {
2136 p_newField = XtMalloc(strlen(newValue) + 1);
2137 strcpy(p_newField, newValue);
2139 *pprefDataField = newValue;
2143 ** Set the language mode for the window, update the menu and trigger language
2144 ** mode specific actions (turn on/off highlighting). If forceNewDefaults is
2145 ** true, re-establish default settings for language-specific preferences
2146 ** regardless of whether they were previously set by the user.
2148 void SetLanguageMode(WindowInfo *window, int mode, int forceNewDefaults)
2150 Widget menu;
2151 WidgetList items;
2152 int n;
2153 Cardinal nItems;
2154 void *userData;
2156 /* Do mode-specific actions */
2157 reapplyLanguageMode(window, mode, forceNewDefaults);
2159 /* Select the correct language mode in the sub-menu */
2160 if (IsTopDocument(window)) {
2161 XtVaGetValues(window->langModeCascade, XmNsubMenuId, &menu, NULL);
2162 XtVaGetValues(menu, XmNchildren, &items, XmNnumChildren, &nItems, NULL);
2163 for (n=0; n<(int)nItems; n++) {
2164 XtVaGetValues(items[n], XmNuserData, &userData, NULL);
2165 XmToggleButtonSetState(items[n], (int)userData == mode, False);
2171 ** Lookup a language mode by name, returning the index of the language
2172 ** mode or PLAIN_LANGUAGE_MODE if the name is not found
2174 int FindLanguageMode(const char *languageName)
2176 int i;
2178 /* Compare each language mode to the one we were presented */
2179 for (i=0; i<NLanguageModes; i++)
2180 if (!strcmp(languageName, LanguageModes[i]->name))
2181 return i;
2183 return PLAIN_LANGUAGE_MODE;
2188 ** Apply language mode matching criteria and set window->languageMode to
2189 ** the appropriate mode for the current file, trigger language mode
2190 ** specific actions (turn on/off highlighting), and update the language
2191 ** mode menu item. If forceNewDefaults is true, re-establish default
2192 ** settings for language-specific preferences regardless of whether
2193 ** they were previously set by the user.
2195 void DetermineLanguageMode(WindowInfo *window, int forceNewDefaults)
2197 SetLanguageMode(window, matchLanguageMode(window), forceNewDefaults);
2201 ** Return the name of the current language mode set in "window", or NULL
2202 ** if the current mode is "Plain".
2204 char *LanguageModeName(int mode)
2206 if (mode == PLAIN_LANGUAGE_MODE)
2207 return NULL;
2208 else
2209 return LanguageModes[mode]->name;
2213 ** Get the set of word delimiters for the language mode set in the current
2214 ** window. Returns NULL when no language mode is set (it would be easy to
2215 ** return the default delimiter set when the current language mode is "Plain",
2216 ** or the mode doesn't have its own delimiters, but this is usually used
2217 ** to supply delimiters for RE searching, and ExecRE can skip compiling a
2218 ** delimiter table when delimiters is NULL).
2220 char *GetWindowDelimiters(WindowInfo *window)
2222 if (window->languageMode == PLAIN_LANGUAGE_MODE)
2223 return NULL;
2224 else
2225 return LanguageModes[window->languageMode]->delimiters;
2229 ** Put up a dialog for selecting a custom initial window size
2231 void RowColumnPrefDialog(Widget parent)
2233 Widget form, selBox, topLabel;
2234 Arg selBoxArgs[2];
2235 XmString s1;
2237 XtSetArg(selBoxArgs[0], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL);
2238 XtSetArg(selBoxArgs[1], XmNautoUnmanage, False);
2239 selBox = CreatePromptDialog(parent, "customSize", selBoxArgs, 2);
2240 XtAddCallback(selBox, XmNokCallback, (XtCallbackProc)sizeOKCB, NULL);
2241 XtAddCallback(selBox, XmNcancelCallback, (XtCallbackProc)sizeCancelCB,NULL);
2242 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_TEXT));
2243 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_SELECTION_LABEL));
2244 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_HELP_BUTTON));
2245 XtVaSetValues(XtParent(selBox), XmNtitle, "Initial Window Size", NULL);
2247 form = XtVaCreateManagedWidget("form", xmFormWidgetClass, selBox, NULL);
2249 topLabel = XtVaCreateManagedWidget("topLabel", xmLabelGadgetClass, form,
2250 XmNlabelString, s1=MKSTRING(
2251 "Enter desired size in rows\nand columns of characters:"), NULL);
2252 XmStringFree(s1);
2254 RowText = XtVaCreateManagedWidget("rows", xmTextWidgetClass, form,
2255 XmNcolumns, 3,
2256 XmNtopAttachment, XmATTACH_WIDGET,
2257 XmNleftAttachment, XmATTACH_POSITION,
2258 XmNrightAttachment, XmATTACH_POSITION,
2259 XmNtopWidget, topLabel,
2260 XmNleftPosition, 5,
2261 XmNrightPosition, 45, NULL);
2262 RemapDeleteKey(RowText);
2264 XtVaCreateManagedWidget("xLabel", xmLabelGadgetClass, form,
2265 XmNlabelString, s1=MKSTRING("x"),
2266 XmNtopAttachment, XmATTACH_WIDGET,
2267 XmNleftAttachment, XmATTACH_POSITION,
2268 XmNrightAttachment, XmATTACH_POSITION,
2269 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
2270 XmNtopWidget, topLabel,
2271 XmNbottomWidget, RowText,
2272 XmNleftPosition, 45,
2273 XmNrightPosition, 55, NULL);
2274 XmStringFree(s1);
2276 ColText = XtVaCreateManagedWidget("cols", xmTextWidgetClass, form,
2277 XmNcolumns, 3,
2278 XmNtopAttachment, XmATTACH_WIDGET,
2279 XmNleftAttachment, XmATTACH_POSITION,
2280 XmNrightAttachment, XmATTACH_POSITION,
2281 XmNtopWidget, topLabel,
2282 XmNleftPosition, 55,
2283 XmNrightPosition, 95, NULL);
2284 RemapDeleteKey(ColText);
2286 /* put up dialog and wait for user to press ok or cancel */
2287 DoneWithSizeDialog = False;
2288 ManageDialogCenteredOnPointer(selBox);
2289 while (!DoneWithSizeDialog)
2291 XEvent event;
2292 XtAppNextEvent(XtWidgetToApplicationContext(parent), &event);
2293 ServerDispatchEvent(&event);
2296 XtDestroyWidget(selBox);
2299 static void sizeOKCB(Widget w, XtPointer clientData, XtPointer callData)
2301 int rowValue, colValue, stat;
2303 /* get the values that the user entered and make sure they're ok */
2304 stat = GetIntTextWarn(RowText, &rowValue, "number of rows", True);
2305 if (stat != TEXT_READ_OK)
2306 return;
2307 stat = GetIntTextWarn(ColText, &colValue, "number of columns", True);
2308 if (stat != TEXT_READ_OK)
2309 return;
2311 /* set the corresponding preferences and dismiss the dialog */
2312 SetPrefRows(rowValue);
2313 SetPrefCols(colValue);
2314 DoneWithSizeDialog = True;
2317 static void sizeCancelCB(Widget w, XtPointer clientData, XtPointer callData)
2319 DoneWithSizeDialog = True;
2323 ** Present the user a dialog for setting tab related preferences, either as
2324 ** defaults, or for a specific window (pass "forWindow" as NULL to set default
2325 ** preference, or a window to set preferences for the specific window.
2327 void TabsPrefDialog(Widget parent, WindowInfo *forWindow)
2329 Widget form, selBox;
2330 Arg selBoxArgs[2];
2331 XmString s1;
2332 int emulate, emTabDist, useTabs, tabDist;
2334 XtSetArg(selBoxArgs[0], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL);
2335 XtSetArg(selBoxArgs[1], XmNautoUnmanage, False);
2336 selBox = CreatePromptDialog(parent, "customSize", selBoxArgs, 2);
2337 XtAddCallback(selBox, XmNokCallback, (XtCallbackProc)tabsOKCB, NULL);
2338 XtAddCallback(selBox, XmNcancelCallback, (XtCallbackProc)tabsCancelCB,NULL);
2339 XtAddCallback(selBox, XmNhelpCallback, (XtCallbackProc)tabsHelpCB,NULL);
2340 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_TEXT));
2341 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_SELECTION_LABEL));
2342 XtVaSetValues(XtParent(selBox), XmNtitle, "Tabs", NULL);
2344 form = XtVaCreateManagedWidget("form", xmFormWidgetClass, selBox, NULL);
2346 TabDistText = XtVaCreateManagedWidget("tabDistText", xmTextWidgetClass,
2347 form, XmNcolumns, 7,
2348 XmNtopAttachment, XmATTACH_FORM,
2349 XmNrightAttachment, XmATTACH_FORM, NULL);
2350 RemapDeleteKey(TabDistText);
2351 XtVaCreateManagedWidget("tabDistLabel", xmLabelGadgetClass, form,
2352 XmNlabelString, s1=XmStringCreateSimple(
2353 "Tab spacing (for hardware tab characters)"),
2354 XmNmnemonic, 'T',
2355 XmNuserData, TabDistText,
2356 XmNtopAttachment, XmATTACH_FORM,
2357 XmNleftAttachment, XmATTACH_FORM,
2358 XmNrightAttachment, XmATTACH_WIDGET,
2359 XmNrightWidget, TabDistText,
2360 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
2361 XmNbottomWidget, TabDistText, NULL);
2362 XmStringFree(s1);
2364 EmTabText = XtVaCreateManagedWidget("emTabText", xmTextWidgetClass, form,
2365 XmNcolumns, 7,
2366 XmNtopAttachment, XmATTACH_WIDGET,
2367 XmNtopWidget, TabDistText,
2368 XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET,
2369 XmNrightWidget, TabDistText, NULL);
2370 RemapDeleteKey(EmTabText);
2371 EmTabLabel = XtVaCreateManagedWidget("emTabLabel", xmLabelGadgetClass, form,
2372 XmNlabelString, s1=XmStringCreateSimple("Emulated tab spacing"),
2373 XmNmnemonic, 's',
2374 XmNuserData, EmTabText,
2375 XmNtopAttachment, XmATTACH_WIDGET,
2376 XmNtopWidget, TabDistText,
2377 XmNrightAttachment, XmATTACH_WIDGET,
2378 XmNrightWidget, EmTabText,
2379 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
2380 XmNbottomWidget, EmTabText, NULL);
2381 XmStringFree(s1);
2382 EmTabToggle = XtVaCreateManagedWidget("emTabToggle",
2383 xmToggleButtonWidgetClass, form, XmNlabelString,
2384 s1=XmStringCreateSimple("Emulate tabs"),
2385 XmNmnemonic, 'E',
2386 XmNtopAttachment, XmATTACH_WIDGET,
2387 XmNtopWidget, TabDistText,
2388 XmNleftAttachment, XmATTACH_FORM,
2389 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
2390 XmNbottomWidget, EmTabText, NULL);
2391 XmStringFree(s1);
2392 XtAddCallback(EmTabToggle, XmNvalueChangedCallback, emTabsCB, NULL);
2393 UseTabsToggle = XtVaCreateManagedWidget("useTabsToggle",
2394 xmToggleButtonWidgetClass, form,
2395 XmNlabelString, s1=XmStringCreateSimple(
2396 "Use tab characters in padding and emulated tabs"),
2397 XmNmnemonic, 'U',
2398 XmNtopAttachment, XmATTACH_WIDGET,
2399 XmNtopWidget, EmTabText,
2400 XmNtopOffset, 5,
2401 XmNleftAttachment, XmATTACH_FORM, NULL);
2402 XmStringFree(s1);
2404 /* Set default values */
2405 if (forWindow == NULL) {
2406 emTabDist = GetPrefEmTabDist(PLAIN_LANGUAGE_MODE);
2407 useTabs = GetPrefInsertTabs();
2408 tabDist = GetPrefTabDist(PLAIN_LANGUAGE_MODE);
2409 } else {
2410 XtVaGetValues(forWindow->textArea, textNemulateTabs, &emTabDist, NULL);
2411 useTabs = forWindow->buffer->useTabs;
2412 tabDist = BufGetTabDistance(forWindow->buffer);
2414 emulate = emTabDist != 0;
2415 SetIntText(TabDistText, tabDist);
2416 XmToggleButtonSetState(EmTabToggle, emulate, True);
2417 if (emulate)
2418 SetIntText(EmTabText, emTabDist);
2419 XmToggleButtonSetState(UseTabsToggle, useTabs, False);
2420 XtSetSensitive(EmTabText, emulate);
2421 XtSetSensitive(EmTabLabel, emulate);
2423 /* Handle mnemonic selection of buttons and focus to dialog */
2424 AddDialogMnemonicHandler(form, FALSE);
2426 /* Set the widget to get focus */
2427 #if XmVersion >= 1002
2428 XtVaSetValues(form, XmNinitialFocus, TabDistText, NULL);
2429 #endif
2431 /* put up dialog and wait for user to press ok or cancel */
2432 TabsDialogForWindow = forWindow;
2433 DoneWithTabsDialog = False;
2434 ManageDialogCenteredOnPointer(selBox);
2435 while (!DoneWithTabsDialog)
2437 XEvent event;
2438 XtAppNextEvent(XtWidgetToApplicationContext(parent), &event);
2439 ServerDispatchEvent(&event);
2442 XtDestroyWidget(selBox);
2445 static void tabsOKCB(Widget w, XtPointer clientData, XtPointer callData)
2447 int emulate, useTabs, stat, tabDist, emTabDist;
2448 WindowInfo *window = TabsDialogForWindow;
2450 /* get the values that the user entered and make sure they're ok */
2451 emulate = XmToggleButtonGetState(EmTabToggle);
2452 useTabs = XmToggleButtonGetState(UseTabsToggle);
2453 stat = GetIntTextWarn(TabDistText, &tabDist, "tab spacing", True);
2454 if (stat != TEXT_READ_OK)
2455 return;
2457 if (tabDist <= 0 || tabDist > MAX_EXP_CHAR_LEN)
2459 DialogF(DF_WARN, TabDistText, 1, "Tab Spacing",
2460 "Tab spacing out of range", "Dismiss");
2461 return;
2464 if (emulate) {
2465 stat = GetIntTextWarn(EmTabText, &emTabDist, "emulated tab spacing",True);
2466 if (stat != TEXT_READ_OK)
2467 return;
2469 if (emTabDist <= 0 || tabDist >= 1000)
2471 DialogF(DF_WARN, EmTabText, 1, "Tab Spacing",
2472 "Emulated tab spacing out of range", "Dismiss");
2473 return;
2475 } else
2476 emTabDist = 0;
2478 #ifdef SGI_CUSTOM
2479 /* Ask the user about saving as a default preference */
2480 if (TabsDialogForWindow != NULL) {
2481 int setDefault;
2482 if (!shortPrefToDefault(window->shell, "Tab Settings", &setDefault)) {
2483 DoneWithTabsDialog = True;
2484 return;
2486 if (setDefault) {
2487 SetPrefTabDist(tabDist);
2488 SetPrefEmTabDist(emTabDist);
2489 SetPrefInsertTabs(useTabs);
2490 SaveNEditPrefs(window->shell, GetPrefShortMenus());
2493 #endif
2495 /* Set the value in either the requested window or default preferences */
2496 if (TabsDialogForWindow == NULL) {
2497 SetPrefTabDist(tabDist);
2498 SetPrefEmTabDist(emTabDist);
2499 SetPrefInsertTabs(useTabs);
2500 } else {
2501 char *params[1];
2502 char numStr[25];
2504 params[0] = numStr;
2505 sprintf(numStr, "%d", tabDist);
2506 XtCallActionProc(window->textArea, "set_tab_dist", NULL, params, 1);
2507 params[0] = numStr;
2508 sprintf(numStr, "%d", emTabDist);
2509 XtCallActionProc(window->textArea, "set_em_tab_dist", NULL, params, 1);
2510 params[0] = numStr;
2511 sprintf(numStr, "%d", useTabs);
2512 XtCallActionProc(window->textArea, "set_use_tabs", NULL, params, 1);
2514 setTabDist(window, tabDist);
2515 setEmTabDist(window, emTabDist);
2516 window->buffer->useTabs = useTabs;
2519 DoneWithTabsDialog = True;
2522 static void tabsCancelCB(Widget w, XtPointer clientData, XtPointer callData)
2524 DoneWithTabsDialog = True;
2527 static void tabsHelpCB(Widget w, XtPointer clientData, XtPointer callData)
2529 Help(HELP_TABS_DIALOG);
2532 static void emTabsCB(Widget w, XtPointer clientData, XtPointer callData)
2534 int state = XmToggleButtonGetState(w);
2536 XtSetSensitive(EmTabLabel, state);
2537 XtSetSensitive(EmTabText, state);
2541 ** Present the user a dialog for setting wrap margin.
2543 void WrapMarginDialog(Widget parent, WindowInfo *forWindow)
2545 Widget form, selBox;
2546 Arg selBoxArgs[2];
2547 XmString s1;
2548 int margin;
2550 XtSetArg(selBoxArgs[0], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL);
2551 XtSetArg(selBoxArgs[1], XmNautoUnmanage, False);
2552 selBox = CreatePromptDialog(parent, "wrapMargin", selBoxArgs, 2);
2553 XtAddCallback(selBox, XmNokCallback, (XtCallbackProc)wrapOKCB, NULL);
2554 XtAddCallback(selBox, XmNcancelCallback, (XtCallbackProc)wrapCancelCB,NULL);
2555 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_TEXT));
2556 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_SELECTION_LABEL));
2557 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_HELP_BUTTON));
2558 XtVaSetValues(XtParent(selBox), XmNtitle, "Wrap Margin", NULL);
2560 form = XtVaCreateManagedWidget("form", xmFormWidgetClass, selBox, NULL);
2562 WrapWindowToggle = XtVaCreateManagedWidget("wrapWindowToggle",
2563 xmToggleButtonWidgetClass, form, XmNlabelString,
2564 s1=XmStringCreateSimple("Wrap and Fill at width of window"),
2565 XmNmnemonic, 'W',
2566 XmNtopAttachment, XmATTACH_FORM,
2567 XmNleftAttachment, XmATTACH_FORM, NULL);
2568 XmStringFree(s1);
2569 XtAddCallback(WrapWindowToggle, XmNvalueChangedCallback, wrapWindowCB,NULL);
2570 WrapText = XtVaCreateManagedWidget("wrapText", xmTextWidgetClass, form,
2571 XmNcolumns, 5,
2572 XmNtopAttachment, XmATTACH_WIDGET,
2573 XmNtopWidget, WrapWindowToggle,
2574 XmNrightAttachment, XmATTACH_FORM, NULL);
2575 RemapDeleteKey(WrapText);
2576 WrapTextLabel = XtVaCreateManagedWidget("wrapMarginLabel",
2577 xmLabelGadgetClass, form,
2578 XmNlabelString, s1=XmStringCreateSimple(
2579 "Margin for Wrap and Fill"),
2580 XmNmnemonic, 'M',
2581 XmNuserData, WrapText,
2582 XmNtopAttachment, XmATTACH_WIDGET,
2583 XmNtopWidget, WrapWindowToggle,
2584 XmNleftAttachment, XmATTACH_FORM,
2585 XmNrightAttachment, XmATTACH_WIDGET,
2586 XmNrightWidget, WrapText,
2587 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
2588 XmNbottomWidget, WrapText, NULL);
2589 XmStringFree(s1);
2591 /* Set default value */
2592 if (forWindow == NULL)
2593 margin = GetPrefWrapMargin();
2594 else
2595 XtVaGetValues(forWindow->textArea, textNwrapMargin, &margin, NULL);
2596 XmToggleButtonSetState(WrapWindowToggle, margin==0, True);
2597 if (margin != 0)
2598 SetIntText(WrapText, margin);
2599 XtSetSensitive(WrapText, margin!=0);
2600 XtSetSensitive(WrapTextLabel, margin!=0);
2602 /* Handle mnemonic selection of buttons and focus to dialog */
2603 AddDialogMnemonicHandler(form, FALSE);
2605 /* put up dialog and wait for user to press ok or cancel */
2606 WrapDialogForWindow = forWindow;
2607 DoneWithWrapDialog = False;
2608 ManageDialogCenteredOnPointer(selBox);
2609 while (!DoneWithWrapDialog)
2611 XEvent event;
2612 XtAppNextEvent(XtWidgetToApplicationContext(parent), &event);
2613 ServerDispatchEvent(&event);
2616 XtDestroyWidget(selBox);
2619 static void wrapOKCB(Widget w, XtPointer clientData, XtPointer callData)
2621 int wrapAtWindow, margin, stat;
2622 WindowInfo *window = WrapDialogForWindow;
2624 /* get the values that the user entered and make sure they're ok */
2625 wrapAtWindow = XmToggleButtonGetState(WrapWindowToggle);
2626 if (wrapAtWindow)
2627 margin = 0;
2628 else {
2629 stat = GetIntTextWarn(WrapText, &margin, "wrap Margin", True);
2630 if (stat != TEXT_READ_OK)
2631 return;
2633 if (margin <= 0 || margin >= 1000)
2635 DialogF(DF_WARN, WrapText, 1, "Wrap Margin",
2636 "Wrap margin out of range", "Dismiss");
2637 return;
2642 #ifdef SGI_CUSTOM
2643 /* Ask the user about saving as a default preference */
2644 if (WrapDialogForWindow != NULL) {
2645 int setDefault;
2646 if (!shortPrefToDefault(window->shell, "Wrap Margin Settings",
2647 &setDefault)) {
2648 DoneWithWrapDialog = True;
2649 return;
2651 if (setDefault) {
2652 SetPrefWrapMargin(margin);
2653 SaveNEditPrefs(window->shell, GetPrefShortMenus());
2656 #endif
2658 /* Set the value in either the requested window or default preferences */
2659 if (WrapDialogForWindow == NULL)
2660 SetPrefWrapMargin(margin);
2661 else {
2662 char *params[1];
2663 char marginStr[25];
2664 sprintf(marginStr, "%d", margin);
2665 params[0] = marginStr;
2666 XtCallActionProc(window->textArea, "set_wrap_margin", NULL, params, 1);
2668 DoneWithWrapDialog = True;
2671 static void wrapCancelCB(Widget w, XtPointer clientData, XtPointer callData)
2673 DoneWithWrapDialog = True;
2676 static void wrapWindowCB(Widget w, XtPointer clientData, XtPointer callData)
2678 int wrapAtWindow = XmToggleButtonGetState(w);
2680 XtSetSensitive(WrapTextLabel, !wrapAtWindow);
2681 XtSetSensitive(WrapText, !wrapAtWindow);
2685 ** Present a dialog for editing language mode information
2687 void EditLanguageModes()
2689 #define LIST_RIGHT 40
2690 #define LEFT_MARGIN_POS 1
2691 #define RIGHT_MARGIN_POS 99
2692 #define H_MARGIN 5
2693 Widget form, nameLbl, topLbl, extLbl, recogLbl, delimitLbl, defTipsLbl;
2694 Widget okBtn, applyBtn, dismissBtn;
2695 Widget overrideFrame, overrideForm, delimitForm;
2696 Widget tabForm, tabLbl, indentBox, wrapBox;
2697 XmString s1;
2698 int i, ac;
2699 Arg args[20];
2701 /* if the dialog is already displayed, just pop it to the top and return */
2702 if (LMDialog.shell != NULL) {
2703 RaiseShellWindow(LMDialog.shell);
2704 return;
2707 LMDialog.languageModeList = (languageModeRec **)XtMalloc(
2708 sizeof(languageModeRec *) * MAX_LANGUAGE_MODES);
2709 for (i=0; i<NLanguageModes; i++)
2710 LMDialog.languageModeList[i] = copyLanguageModeRec(LanguageModes[i]);
2711 LMDialog.nLanguageModes = NLanguageModes;
2713 /* Create a form widget in an application shell */
2714 ac = 0;
2715 XtSetArg(args[ac], XmNdeleteResponse, XmDO_NOTHING); ac++;
2716 XtSetArg(args[ac], XmNiconName, "NEdit Language Modes"); ac++;
2717 XtSetArg(args[ac], XmNtitle, "Language Modes"); ac++;
2718 LMDialog.shell = CreateWidget(TheAppShell, "langModes",
2719 topLevelShellWidgetClass, args, ac);
2720 AddSmallIcon(LMDialog.shell);
2721 form = XtVaCreateManagedWidget("editLanguageModes", xmFormWidgetClass,
2722 LMDialog.shell, XmNautoUnmanage, False,
2723 XmNresizePolicy, XmRESIZE_NONE, NULL);
2724 XtAddCallback(form, XmNdestroyCallback, lmDestroyCB, NULL);
2725 AddMotifCloseCallback(LMDialog.shell, lmDismissCB, NULL);
2727 topLbl = XtVaCreateManagedWidget("topLabel", xmLabelGadgetClass, form,
2728 XmNlabelString, s1=MKSTRING(
2729 "To modify the properties of an existing language mode, select the name from\n\
2730 the list on the left. To add a new language, select \"New\" from the list."),
2731 XmNmnemonic, 'N',
2732 XmNtopAttachment, XmATTACH_POSITION,
2733 XmNtopPosition, 2,
2734 XmNleftAttachment, XmATTACH_POSITION,
2735 XmNleftPosition, LEFT_MARGIN_POS,
2736 XmNrightAttachment, XmATTACH_POSITION,
2737 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
2738 XmStringFree(s1);
2740 nameLbl = XtVaCreateManagedWidget("nameLbl", xmLabelGadgetClass, form,
2741 XmNlabelString, s1=XmStringCreateSimple("Name"),
2742 XmNmnemonic, 'm',
2743 XmNalignment, XmALIGNMENT_BEGINNING,
2744 XmNleftAttachment, XmATTACH_POSITION,
2745 XmNleftPosition, LIST_RIGHT,
2746 XmNtopAttachment, XmATTACH_WIDGET,
2747 XmNtopOffset, H_MARGIN,
2748 XmNtopWidget, topLbl, NULL);
2749 XmStringFree(s1);
2751 LMDialog.nameW = XtVaCreateManagedWidget("name", xmTextWidgetClass, form,
2752 XmNcolumns, 15,
2753 XmNleftAttachment, XmATTACH_POSITION,
2754 XmNleftPosition, LIST_RIGHT,
2755 XmNtopAttachment, XmATTACH_WIDGET,
2756 XmNtopWidget, nameLbl,
2757 XmNrightAttachment, XmATTACH_POSITION,
2758 XmNrightPosition, (RIGHT_MARGIN_POS + LIST_RIGHT)/2, NULL);
2759 RemapDeleteKey(LMDialog.nameW);
2760 XtVaSetValues(nameLbl, XmNuserData, LMDialog.nameW, NULL);
2762 extLbl = XtVaCreateManagedWidget("extLbl", xmLabelGadgetClass, form,
2763 XmNlabelString,
2764 s1=XmStringCreateSimple("File extensions (separate w/ space)"),
2765 XmNmnemonic, 'F',
2766 XmNalignment, XmALIGNMENT_BEGINNING,
2767 XmNleftAttachment, XmATTACH_POSITION,
2768 XmNleftPosition, LIST_RIGHT,
2769 XmNtopAttachment, XmATTACH_WIDGET,
2770 XmNtopOffset, H_MARGIN,
2771 XmNtopWidget, LMDialog.nameW, NULL);
2772 XmStringFree(s1);
2774 LMDialog.extW = XtVaCreateManagedWidget("ext", xmTextWidgetClass, form,
2775 XmNleftAttachment, XmATTACH_POSITION,
2776 XmNleftPosition, LIST_RIGHT,
2777 XmNtopAttachment, XmATTACH_WIDGET,
2778 XmNtopWidget, extLbl,
2779 XmNrightAttachment, XmATTACH_POSITION,
2780 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
2781 RemapDeleteKey(LMDialog.extW);
2782 XtVaSetValues(extLbl, XmNuserData, LMDialog.extW, NULL);
2784 recogLbl = XtVaCreateManagedWidget("recogLbl", xmLabelGadgetClass, form,
2785 XmNlabelString, s1=MKSTRING(
2786 "Recognition regular expression (applied to first 200\n\
2787 characters of file to determine type from content)"),
2788 XmNalignment, XmALIGNMENT_BEGINNING,
2789 XmNmnemonic, 'R',
2790 XmNleftAttachment, XmATTACH_POSITION,
2791 XmNleftPosition, LIST_RIGHT,
2792 XmNtopAttachment, XmATTACH_WIDGET,
2793 XmNtopOffset, H_MARGIN,
2794 XmNtopWidget, LMDialog.extW, NULL);
2795 XmStringFree(s1);
2797 LMDialog.recogW = XtVaCreateManagedWidget("recog", xmTextWidgetClass, form,
2798 XmNleftAttachment, XmATTACH_POSITION,
2799 XmNleftPosition, LIST_RIGHT,
2800 XmNtopAttachment, XmATTACH_WIDGET,
2801 XmNtopWidget, recogLbl,
2802 XmNrightAttachment, XmATTACH_POSITION,
2803 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
2804 RemapDeleteKey(LMDialog.recogW);
2805 XtVaSetValues(recogLbl, XmNuserData, LMDialog.recogW, NULL);
2807 defTipsLbl = XtVaCreateManagedWidget("defTipsLbl", xmLabelGadgetClass, form,
2808 XmNlabelString, s1=MKSTRING(
2809 "Default calltips file(s) (separate w/colons)"),
2810 XmNalignment, XmALIGNMENT_BEGINNING,
2811 XmNmnemonic, 'c',
2812 XmNleftAttachment, XmATTACH_POSITION,
2813 XmNleftPosition, LIST_RIGHT,
2814 XmNtopAttachment, XmATTACH_WIDGET,
2815 XmNtopOffset, H_MARGIN,
2816 XmNtopWidget, LMDialog.recogW, NULL);
2817 XmStringFree(s1);
2819 LMDialog.defTipsW = XtVaCreateManagedWidget("defTips", xmTextWidgetClass,
2820 form,
2821 XmNleftAttachment, XmATTACH_POSITION,
2822 XmNleftPosition, LIST_RIGHT,
2823 XmNtopAttachment, XmATTACH_WIDGET,
2824 XmNtopWidget, defTipsLbl,
2825 XmNrightAttachment, XmATTACH_POSITION,
2826 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
2827 RemapDeleteKey(LMDialog.defTipsW);
2828 XtVaSetValues(defTipsLbl, XmNuserData, LMDialog.defTipsW, NULL);
2830 okBtn = XtVaCreateManagedWidget("ok", xmPushButtonWidgetClass, form,
2831 XmNlabelString, s1=XmStringCreateSimple("OK"),
2832 XmNleftAttachment, XmATTACH_POSITION,
2833 XmNleftPosition, 10,
2834 XmNrightAttachment, XmATTACH_POSITION,
2835 XmNrightPosition, 30,
2836 XmNbottomAttachment, XmATTACH_POSITION,
2837 XmNbottomPosition, 99, NULL);
2838 XtAddCallback(okBtn, XmNactivateCallback, lmOkCB, NULL);
2839 XmStringFree(s1);
2841 applyBtn = XtVaCreateManagedWidget("apply", xmPushButtonWidgetClass, form,
2842 XmNlabelString, s1=XmStringCreateSimple("Apply"),
2843 XmNmnemonic, 'A',
2844 XmNleftAttachment, XmATTACH_POSITION,
2845 XmNleftPosition, 40,
2846 XmNrightAttachment, XmATTACH_POSITION,
2847 XmNrightPosition, 60,
2848 XmNbottomAttachment, XmATTACH_POSITION,
2849 XmNbottomPosition, 99, NULL);
2850 XtAddCallback(applyBtn, XmNactivateCallback, lmApplyCB, NULL);
2851 XmStringFree(s1);
2853 dismissBtn = XtVaCreateManagedWidget("dismiss",xmPushButtonWidgetClass,form,
2854 XmNlabelString, s1=XmStringCreateSimple("Dismiss"),
2855 XmNleftAttachment, XmATTACH_POSITION,
2856 XmNleftPosition, 70,
2857 XmNrightAttachment, XmATTACH_POSITION,
2858 XmNrightPosition, 90,
2859 XmNbottomAttachment, XmATTACH_POSITION,
2860 XmNbottomPosition, 99, NULL);
2861 XtAddCallback(dismissBtn, XmNactivateCallback, lmDismissCB, NULL);
2862 XmStringFree(s1);
2864 overrideFrame = XtVaCreateManagedWidget("overrideFrame",
2865 xmFrameWidgetClass, form,
2866 XmNleftAttachment, XmATTACH_POSITION,
2867 XmNleftPosition, LEFT_MARGIN_POS,
2868 XmNrightAttachment, XmATTACH_POSITION,
2869 XmNrightPosition, RIGHT_MARGIN_POS,
2870 XmNbottomAttachment, XmATTACH_WIDGET,
2871 XmNbottomWidget, dismissBtn,
2872 XmNbottomOffset, H_MARGIN, NULL);
2873 overrideForm = XtVaCreateManagedWidget("overrideForm", xmFormWidgetClass,
2874 overrideFrame, NULL);
2875 XtVaCreateManagedWidget("overrideLbl", xmLabelGadgetClass, overrideFrame,
2876 XmNlabelString, s1=XmStringCreateSimple("Override Defaults"),
2877 XmNchildType, XmFRAME_TITLE_CHILD,
2878 XmNchildHorizontalAlignment, XmALIGNMENT_CENTER, NULL);
2879 XmStringFree(s1);
2881 delimitForm = XtVaCreateManagedWidget("delimitForm", xmFormWidgetClass,
2882 overrideForm,
2883 XmNleftAttachment, XmATTACH_POSITION,
2884 XmNleftPosition, LEFT_MARGIN_POS,
2885 XmNtopAttachment, XmATTACH_FORM,
2886 XmNtopOffset, H_MARGIN,
2887 XmNrightAttachment, XmATTACH_POSITION,
2888 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
2889 delimitLbl = XtVaCreateManagedWidget("delimitLbl", xmLabelGadgetClass,
2890 delimitForm,
2891 XmNlabelString, s1=XmStringCreateSimple("Word delimiters"),
2892 XmNmnemonic, 'W',
2893 XmNleftAttachment, XmATTACH_FORM,
2894 XmNtopAttachment, XmATTACH_FORM,
2895 XmNbottomAttachment, XmATTACH_FORM, NULL);
2896 XmStringFree(s1);
2897 LMDialog.delimitW = XtVaCreateManagedWidget("delimit", xmTextWidgetClass,
2898 delimitForm,
2899 XmNtopAttachment, XmATTACH_FORM,
2900 XmNleftAttachment, XmATTACH_WIDGET,
2901 XmNleftWidget, delimitLbl,
2902 XmNrightAttachment, XmATTACH_FORM,
2903 XmNbottomAttachment, XmATTACH_FORM, NULL);
2904 RemapDeleteKey(LMDialog.delimitW);
2905 XtVaSetValues(delimitLbl, XmNuserData, LMDialog.delimitW, NULL);
2907 tabForm = XtVaCreateManagedWidget("tabForm", xmFormWidgetClass,
2908 overrideForm,
2909 XmNleftAttachment, XmATTACH_POSITION,
2910 XmNleftPosition, LEFT_MARGIN_POS,
2911 XmNtopAttachment, XmATTACH_WIDGET,
2912 XmNtopWidget, delimitForm,
2913 XmNtopOffset, H_MARGIN,
2914 XmNrightAttachment, XmATTACH_POSITION,
2915 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
2916 tabLbl = XtVaCreateManagedWidget("tabLbl", xmLabelGadgetClass, tabForm,
2917 XmNlabelString, s1=XmStringCreateSimple(
2918 "Alternative hardware tab spacing"),
2919 XmNmnemonic, 't',
2920 XmNleftAttachment, XmATTACH_FORM,
2921 XmNtopAttachment, XmATTACH_FORM,
2922 XmNbottomAttachment, XmATTACH_FORM, NULL);
2923 XmStringFree(s1);
2924 LMDialog.tabW = XtVaCreateManagedWidget("delimit", xmTextWidgetClass,
2925 tabForm,
2926 XmNcolumns, 3,
2927 XmNtopAttachment, XmATTACH_FORM,
2928 XmNleftAttachment, XmATTACH_WIDGET,
2929 XmNleftWidget, tabLbl,
2930 XmNbottomAttachment, XmATTACH_FORM, NULL);
2931 RemapDeleteKey(LMDialog.tabW);
2932 XtVaSetValues(tabLbl, XmNuserData, LMDialog.tabW, NULL);
2933 LMDialog.emTabW = XtVaCreateManagedWidget("delimit", xmTextWidgetClass,
2934 tabForm,
2935 XmNcolumns, 3,
2936 XmNtopAttachment, XmATTACH_FORM,
2937 XmNrightAttachment, XmATTACH_FORM,
2938 XmNbottomAttachment, XmATTACH_FORM, NULL);
2939 RemapDeleteKey(LMDialog.emTabW);
2940 XtVaCreateManagedWidget("emTabLbl", xmLabelGadgetClass, tabForm,
2941 XmNlabelString,
2942 s1=XmStringCreateSimple("Alternative emulated tab spacing"),
2943 XmNalignment, XmALIGNMENT_END,
2944 XmNmnemonic, 'e',
2945 XmNuserData, LMDialog.emTabW,
2946 XmNleftAttachment, XmATTACH_WIDGET,
2947 XmNleftWidget, LMDialog.tabW,
2948 XmNrightAttachment, XmATTACH_WIDGET,
2949 XmNrightWidget, LMDialog.emTabW,
2950 XmNtopAttachment, XmATTACH_FORM,
2951 XmNbottomAttachment, XmATTACH_FORM, NULL);
2952 XmStringFree(s1);
2954 indentBox = XtVaCreateManagedWidget("indentBox", xmRowColumnWidgetClass,
2955 overrideForm,
2956 XmNorientation, XmHORIZONTAL,
2957 XmNpacking, XmPACK_TIGHT,
2958 XmNradioBehavior, True,
2959 XmNleftAttachment, XmATTACH_POSITION,
2960 XmNleftPosition, LEFT_MARGIN_POS,
2961 XmNtopAttachment, XmATTACH_WIDGET,
2962 XmNtopWidget, tabForm,
2963 XmNtopOffset, H_MARGIN, NULL);
2964 LMDialog.defaultIndentW = XtVaCreateManagedWidget("defaultIndent",
2965 xmToggleButtonWidgetClass, indentBox,
2966 XmNset, True,
2967 XmNmarginHeight, 0,
2968 XmNlabelString, s1=XmStringCreateSimple("Default indent style"),
2969 XmNmnemonic, 'D', NULL);
2970 XmStringFree(s1);
2971 LMDialog.noIndentW = XtVaCreateManagedWidget("noIndent",
2972 xmToggleButtonWidgetClass, indentBox,
2973 XmNmarginHeight, 0,
2974 XmNlabelString, s1=XmStringCreateSimple("No automatic indent"),
2975 XmNmnemonic, 'N', NULL);
2976 XmStringFree(s1);
2977 LMDialog.autoIndentW = XtVaCreateManagedWidget("autoIndent",
2978 xmToggleButtonWidgetClass, indentBox,
2979 XmNmarginHeight, 0,
2980 XmNlabelString, s1=XmStringCreateSimple("Auto-indent"),
2981 XmNmnemonic, 'A', NULL);
2982 XmStringFree(s1);
2983 LMDialog.smartIndentW = XtVaCreateManagedWidget("smartIndent",
2984 xmToggleButtonWidgetClass, indentBox,
2985 XmNmarginHeight, 0,
2986 XmNlabelString, s1=XmStringCreateSimple("Smart-indent"),
2987 XmNmnemonic, 'S', NULL);
2988 XmStringFree(s1);
2990 wrapBox = XtVaCreateManagedWidget("wrapBox", xmRowColumnWidgetClass,
2991 overrideForm,
2992 XmNorientation, XmHORIZONTAL,
2993 XmNpacking, XmPACK_TIGHT,
2994 XmNradioBehavior, True,
2995 XmNleftAttachment, XmATTACH_POSITION,
2996 XmNleftPosition, LEFT_MARGIN_POS,
2997 XmNtopAttachment, XmATTACH_WIDGET,
2998 XmNtopWidget, indentBox,
2999 XmNtopOffset, H_MARGIN,
3000 XmNbottomAttachment, XmATTACH_FORM,
3001 XmNbottomOffset, H_MARGIN, NULL);
3002 LMDialog.defaultWrapW = XtVaCreateManagedWidget("defaultWrap",
3003 xmToggleButtonWidgetClass, wrapBox,
3004 XmNset, True,
3005 XmNmarginHeight, 0,
3006 XmNlabelString, s1=XmStringCreateSimple("Default wrap style"),
3007 XmNmnemonic, 'D', NULL);
3008 XmStringFree(s1);
3009 LMDialog.noWrapW = XtVaCreateManagedWidget("noWrap",
3010 xmToggleButtonWidgetClass, wrapBox,
3011 XmNmarginHeight, 0,
3012 XmNlabelString, s1=XmStringCreateSimple("No wrapping"),
3013 XmNmnemonic, 'N', NULL);
3014 XmStringFree(s1);
3015 LMDialog.newlineWrapW = XtVaCreateManagedWidget("newlineWrap",
3016 xmToggleButtonWidgetClass, wrapBox,
3017 XmNmarginHeight, 0,
3018 XmNlabelString, s1=XmStringCreateSimple("Auto newline wrap"),
3019 XmNmnemonic, 'A', NULL);
3020 XmStringFree(s1);
3021 LMDialog.contWrapW = XtVaCreateManagedWidget("contWrap",
3022 xmToggleButtonWidgetClass, wrapBox,
3023 XmNmarginHeight, 0,
3024 XmNlabelString, s1=XmStringCreateSimple("Continuous wrap"),
3025 XmNmnemonic, 'C', NULL);
3026 XmStringFree(s1);
3028 XtVaCreateManagedWidget("stretchForm", xmFormWidgetClass, form,
3029 XmNtopAttachment, XmATTACH_WIDGET,
3030 XmNtopWidget, LMDialog.defTipsW,
3031 XmNleftAttachment, XmATTACH_POSITION,
3032 XmNleftPosition, LIST_RIGHT,
3033 XmNrightAttachment, XmATTACH_POSITION,
3034 XmNrightPosition, RIGHT_MARGIN_POS,
3035 XmNbottomAttachment, XmATTACH_WIDGET,
3036 XmNbottomWidget, overrideFrame,
3037 XmNbottomOffset, H_MARGIN*2, NULL);
3039 ac = 0;
3040 XtSetArg(args[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
3041 XtSetArg(args[ac], XmNtopOffset, H_MARGIN); ac++;
3042 XtSetArg(args[ac], XmNtopWidget, topLbl); ac++;
3043 XtSetArg(args[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
3044 XtSetArg(args[ac], XmNleftPosition, LEFT_MARGIN_POS); ac++;
3045 XtSetArg(args[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
3046 XtSetArg(args[ac], XmNrightPosition, LIST_RIGHT-1); ac++;
3047 XtSetArg(args[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
3048 XtSetArg(args[ac], XmNbottomWidget, overrideFrame); ac++;
3049 XtSetArg(args[ac], XmNbottomOffset, H_MARGIN*2); ac++;
3050 LMDialog.managedListW = CreateManagedList(form, "list", args, ac,
3051 (void **)LMDialog.languageModeList, &LMDialog.nLanguageModes,
3052 MAX_LANGUAGE_MODES, 15, lmGetDisplayedCB, NULL, lmSetDisplayedCB,
3053 NULL, lmFreeItemCB);
3054 AddDeleteConfirmCB(LMDialog.managedListW, lmDeleteConfirmCB, NULL);
3055 XtVaSetValues(topLbl, XmNuserData, LMDialog.managedListW, NULL);
3057 /* Set initial default button */
3058 XtVaSetValues(form, XmNdefaultButton, okBtn, NULL);
3059 XtVaSetValues(form, XmNcancelButton, dismissBtn, NULL);
3061 /* Handle mnemonic selection of buttons and focus to dialog */
3062 AddDialogMnemonicHandler(form, FALSE);
3064 /* Realize all of the widgets in the new dialog */
3065 RealizeWithoutForcingPosition(LMDialog.shell);
3068 static void lmDestroyCB(Widget w, XtPointer clientData, XtPointer callData)
3070 int i;
3072 for (i=0; i<LMDialog.nLanguageModes; i++)
3073 freeLanguageModeRec(LMDialog.languageModeList[i]);
3074 XtFree((char *)LMDialog.languageModeList);
3077 static void lmOkCB(Widget w, XtPointer clientData, XtPointer callData)
3079 if (!updateLMList())
3080 return;
3082 /* pop down and destroy the dialog */
3083 XtDestroyWidget(LMDialog.shell);
3084 LMDialog.shell = NULL;
3087 static void lmApplyCB(Widget w, XtPointer clientData, XtPointer callData)
3089 updateLMList();
3092 static void lmDismissCB(Widget w, XtPointer clientData, XtPointer callData)
3094 /* pop down and destroy the dialog */
3095 XtDestroyWidget(LMDialog.shell);
3096 LMDialog.shell = NULL;
3099 static int lmDeleteConfirmCB(int itemIndex, void *cbArg)
3101 int i;
3103 /* Allow duplicate names to be deleted regardless of dependencies */
3104 for (i=0; i<LMDialog.nLanguageModes; i++)
3105 if (i != itemIndex && !strcmp(LMDialog.languageModeList[i]->name,
3106 LMDialog.languageModeList[itemIndex]->name))
3107 return True;
3109 /* don't allow deletion if data will be lost */
3110 if (LMHasHighlightPatterns(LMDialog.languageModeList[itemIndex]->name))
3112 DialogF(DF_WARN, LMDialog.shell, 1, "Patterns exist",
3113 "This language mode has syntax highlighting\n"
3114 "patterns defined. Please delete the patterns\n"
3115 "first, in Preferences -> Default Settings ->\n"
3116 "Syntax Highlighting, before proceeding here.", "Dismiss");
3117 return False;
3120 /* don't allow deletion if data will be lost */
3121 if (LMHasSmartIndentMacros(LMDialog.languageModeList[itemIndex]->name))
3123 DialogF(DF_WARN, LMDialog.shell, 1, "Smart Indent Macros exist",
3124 "This language mode has smart indent macros\n"
3125 "defined. Please delete the macros first,\n"
3126 "in Preferences -> Default Settings ->\n"
3127 "Auto Indent -> Program Smart Indent,\n"
3128 "before proceeding here.", "Dismiss");
3129 return False;
3132 return True;
3136 ** Apply the changes that the user has made in the language modes dialog to the
3137 ** stored language mode information for this NEdit session (the data array
3138 ** LanguageModes)
3140 static int updateLMList(void)
3142 WindowInfo *window;
3143 char *oldModeName, *newDelimiters;
3144 int i, j;
3146 /* Get the current contents of the dialog fields */
3147 if (!UpdateManagedList(LMDialog.managedListW, True))
3148 return False;
3150 /* Fix up language mode indices in all open windows (which may change
3151 if the currently selected mode is deleted or has changed position),
3152 and update word delimiters */
3153 for (window=WindowList; window!=NULL; window=window->next) {
3154 if (window->languageMode != PLAIN_LANGUAGE_MODE) {
3155 oldModeName = LanguageModes[window->languageMode]->name;
3156 window->languageMode = PLAIN_LANGUAGE_MODE;
3157 for (i=0; i<LMDialog.nLanguageModes; i++) {
3158 if (!strcmp(oldModeName, LMDialog.languageModeList[i]->name)) {
3159 newDelimiters = LMDialog.languageModeList[i]->delimiters;
3160 if (newDelimiters == NULL)
3161 newDelimiters = GetPrefDelimiters();
3162 XtVaSetValues(window->textArea, textNwordDelimiters,
3163 newDelimiters, NULL);
3164 for (j=0; j<window->nPanes; j++)
3165 XtVaSetValues(window->textPanes[j],
3166 textNwordDelimiters, newDelimiters, NULL);
3167 window->languageMode = i;
3168 break;
3174 /* If there were any name changes, re-name dependent highlight patterns
3175 and smart-indent macros and fix up the weird rename-format names */
3176 for (i=0; i<LMDialog.nLanguageModes; i++) {
3177 if (strchr(LMDialog.languageModeList[i]->name, ':') != NULL) {
3178 char *newName = strrchr(LMDialog.languageModeList[i]->name, ':')+1;
3179 *strchr(LMDialog.languageModeList[i]->name, ':') = '\0';
3180 RenameHighlightPattern(LMDialog.languageModeList[i]->name, newName);
3181 RenameSmartIndentMacros(LMDialog.languageModeList[i]->name, newName);
3182 memmove(LMDialog.languageModeList[i]->name, newName,
3183 strlen(newName) + 1);
3184 ChangeManagedListData(LMDialog.managedListW);
3188 /* Unload any default calltips file that is no longer a default. */
3189 for (i=0; i<NLanguageModes; i++) {
3190 if (!LanguageModes[i]->defTipsFile)
3191 continue;
3192 for (j=0; j<LMDialog.nLanguageModes; j++) {
3193 if (!LMDialog.languageModeList[j]->defTipsFile)
3194 continue;
3195 if (!strcmp(LanguageModes[i]->defTipsFile,
3196 LMDialog.languageModeList[j]->defTipsFile))
3197 break;
3199 if ( j==LMDialog.nLanguageModes )
3200 DeleteTagsFile(LanguageModes[i]->defTipsFile, TIP);
3203 /* Replace the old language mode list with the new one from the dialog */
3204 for (i=0; i<NLanguageModes; i++)
3205 freeLanguageModeRec(LanguageModes[i]);
3206 for (i=0; i<LMDialog.nLanguageModes; i++)
3207 LanguageModes[i] = copyLanguageModeRec(LMDialog.languageModeList[i]);
3208 NLanguageModes = LMDialog.nLanguageModes;
3210 /* Update the menus in the window menu bars and load any needed
3211 calltips files */
3212 for (window=WindowList; window!=NULL; window=window->next) {
3213 updateLanguageModeSubmenu(window);
3214 if (window->languageMode != PLAIN_LANGUAGE_MODE &&
3215 LanguageModes[window->languageMode]->defTipsFile != NULL)
3216 AddTagsFile(LanguageModes[window->languageMode]->defTipsFile, TIP);
3217 /* cache user menus: Rebuild all user menus of this window */
3218 RebuildAllMenus(window);
3221 /* If a syntax highlighting dialog is up, update its menu */
3222 UpdateLanguageModeMenu();
3223 /* The same for the smart indent macro dialog */
3224 UpdateLangModeMenuSmartIndent();
3225 /* Note that preferences have been changed */
3226 MarkPrefsChanged();
3228 return True;
3231 static void *lmGetDisplayedCB(void *oldItem, int explicitRequest, int *abort,
3232 void *cbArg)
3234 languageModeRec *lm, *oldLM = (languageModeRec *)oldItem;
3235 char *tempName;
3236 int i, nCopies, oldLen;
3238 /* If the dialog is currently displaying the "new" entry and the
3239 fields are empty, that's just fine */
3240 if (oldItem == NULL && lmDialogEmpty())
3241 return NULL;
3243 /* Read the data the user has entered in the dialog fields */
3244 lm = readLMDialogFields(True);
3246 /* If there was a name change of a non-duplicate language mode, modify the
3247 name to the weird format of: ":old name:new name". This signals that a
3248 name change is necessary in lm dependent data such as highlight
3249 patterns. Duplicate language modes may be re-named at will, since no
3250 data will be lost due to the name change. */
3251 if (lm != NULL && oldLM != NULL && strcmp(oldLM->name, lm->name)) {
3252 nCopies = 0;
3253 for (i=0; i<LMDialog.nLanguageModes; i++)
3254 if (!strcmp(oldLM->name, LMDialog.languageModeList[i]->name))
3255 nCopies++;
3256 if (nCopies <= 1) {
3257 oldLen = strchr(oldLM->name, ':') == NULL ? strlen(oldLM->name) :
3258 strchr(oldLM->name, ':') - oldLM->name;
3259 tempName = XtMalloc(oldLen + strlen(lm->name) + 2);
3260 strncpy(tempName, oldLM->name, oldLen);
3261 sprintf(&tempName[oldLen], ":%s", lm->name);
3262 XtFree(lm->name);
3263 lm->name = tempName;
3267 /* If there are no problems reading the data, just return it */
3268 if (lm != NULL)
3269 return (void *)lm;
3271 /* If there are problems, and the user didn't ask for the fields to be
3272 read, give more warning */
3273 if (!explicitRequest)
3275 if (DialogF(DF_WARN, LMDialog.shell, 2, "Discard Language Mode",
3276 "Discard incomplete entry\nfor current language mode?", "Keep",
3277 "Discard") == 2)
3279 return oldItem == NULL
3280 ? NULL
3281 : (void *)copyLanguageModeRec((languageModeRec *)oldItem);
3285 /* Do readLMDialogFields again without "silent" mode to display warning */
3286 lm = readLMDialogFields(False);
3287 *abort = True;
3288 return NULL;
3291 static void lmSetDisplayedCB(void *item, void *cbArg)
3293 languageModeRec *lm = (languageModeRec *)item;
3294 char *extStr;
3296 if (item == NULL) {
3297 XmTextSetString(LMDialog.nameW, "");
3298 XmTextSetString(LMDialog.extW, "");
3299 XmTextSetString(LMDialog.recogW, "");
3300 XmTextSetString(LMDialog.defTipsW, "");
3301 XmTextSetString(LMDialog.delimitW, "");
3302 XmTextSetString(LMDialog.tabW, "");
3303 XmTextSetString(LMDialog.emTabW, "");
3304 RadioButtonChangeState(LMDialog.defaultIndentW, True, True);
3305 RadioButtonChangeState(LMDialog.defaultWrapW, True, True);
3306 } else {
3307 XmTextSetString(LMDialog.nameW, strchr(lm->name, ':') == NULL ?
3308 lm->name : strchr(lm->name, ':')+1);
3309 extStr = createExtString(lm->extensions, lm->nExtensions);
3310 XmTextSetString(LMDialog.extW, extStr);
3311 XtFree(extStr);
3312 XmTextSetString(LMDialog.recogW, lm->recognitionExpr);
3313 XmTextSetString(LMDialog.defTipsW, lm->defTipsFile);
3314 XmTextSetString(LMDialog.delimitW, lm->delimiters);
3315 if (lm->tabDist == DEFAULT_TAB_DIST)
3316 XmTextSetString(LMDialog.tabW, "");
3317 else
3318 SetIntText(LMDialog.tabW, lm->tabDist);
3319 if (lm->emTabDist == DEFAULT_EM_TAB_DIST)
3320 XmTextSetString(LMDialog.emTabW, "");
3321 else
3322 SetIntText(LMDialog.emTabW, lm->emTabDist);
3323 RadioButtonChangeState(LMDialog.defaultIndentW,
3324 lm->indentStyle == DEFAULT_INDENT, False);
3325 RadioButtonChangeState(LMDialog.noIndentW,
3326 lm->indentStyle == NO_AUTO_INDENT, False);
3327 RadioButtonChangeState(LMDialog.autoIndentW,
3328 lm->indentStyle == AUTO_INDENT, False);
3329 RadioButtonChangeState(LMDialog.smartIndentW,
3330 lm->indentStyle == SMART_INDENT, False);
3331 RadioButtonChangeState(LMDialog.defaultWrapW,
3332 lm->wrapStyle == DEFAULT_WRAP, False);
3333 RadioButtonChangeState(LMDialog.noWrapW,
3334 lm->wrapStyle == NO_WRAP, False);
3335 RadioButtonChangeState(LMDialog.newlineWrapW,
3336 lm->wrapStyle == NEWLINE_WRAP, False);
3337 RadioButtonChangeState(LMDialog.contWrapW,
3338 lm->wrapStyle == CONTINUOUS_WRAP, False);
3342 static void lmFreeItemCB(void *item)
3344 freeLanguageModeRec((languageModeRec *)item);
3347 static void freeLanguageModeRec(languageModeRec *lm)
3349 int i;
3351 XtFree(lm->name);
3352 if (lm->recognitionExpr != NULL)
3353 XtFree(lm->recognitionExpr);
3354 if (lm->defTipsFile != NULL)
3355 XtFree(lm->defTipsFile);
3356 if (lm->delimiters != NULL)
3357 XtFree(lm->delimiters);
3358 for (i=0; i<lm->nExtensions; i++)
3359 XtFree(lm->extensions[i]);
3360 if (lm->nExtensions != 0)
3361 XtFree((char *)lm->extensions);
3362 XtFree((char *)lm);
3366 ** Copy a languageModeRec data structure and all of the allocated data it contains
3368 static languageModeRec *copyLanguageModeRec(languageModeRec *lm)
3370 languageModeRec *newLM;
3371 int i;
3373 newLM = (languageModeRec *)XtMalloc(sizeof(languageModeRec));
3374 newLM->name = XtMalloc(strlen(lm->name)+1);
3375 strcpy(newLM->name, lm->name);
3376 newLM->nExtensions = lm->nExtensions;
3377 newLM->extensions = (char **)XtMalloc(sizeof(char *) * lm->nExtensions);
3378 for (i=0; i<lm->nExtensions; i++) {
3379 newLM->extensions[i] = XtMalloc(strlen(lm->extensions[i]) + 1);
3380 strcpy(newLM->extensions[i], lm->extensions[i]);
3382 if (lm->recognitionExpr == NULL)
3383 newLM->recognitionExpr = NULL;
3384 else {
3385 newLM->recognitionExpr = XtMalloc(strlen(lm->recognitionExpr)+1);
3386 strcpy(newLM->recognitionExpr, lm->recognitionExpr);
3388 if (lm->defTipsFile == NULL)
3389 newLM->defTipsFile = NULL;
3390 else {
3391 newLM->defTipsFile = XtMalloc(strlen(lm->defTipsFile)+1);
3392 strcpy(newLM->defTipsFile, lm->defTipsFile);
3394 if (lm->delimiters == NULL)
3395 newLM->delimiters = NULL;
3396 else {
3397 newLM->delimiters = XtMalloc(strlen(lm->delimiters)+1);
3398 strcpy(newLM->delimiters, lm->delimiters);
3400 newLM->wrapStyle = lm->wrapStyle;
3401 newLM->indentStyle = lm->indentStyle;
3402 newLM->tabDist = lm->tabDist;
3403 newLM->emTabDist = lm->emTabDist;
3404 return newLM;
3408 ** Read the fields in the language modes dialog and create a languageModeRec data
3409 ** structure reflecting the current state of the selected language mode in the dialog.
3410 ** If any of the information is incorrect or missing, display a warning dialog and
3411 ** return NULL. Passing "silent" as True, suppresses the warning dialogs.
3413 static languageModeRec *readLMDialogFields(int silent)
3415 languageModeRec *lm;
3416 regexp *compiledRE;
3417 char *compileMsg, *extStr, *extPtr;
3419 /* Allocate a language mode structure to return, set unread fields to
3420 empty so everything can be freed on errors by freeLanguageModeRec */
3421 lm = (languageModeRec *)XtMalloc(sizeof(languageModeRec));
3422 lm->nExtensions = 0;
3423 lm->recognitionExpr = NULL;
3424 lm->defTipsFile = NULL;
3425 lm->delimiters = NULL;
3427 /* read the name field */
3428 lm->name = ReadSymbolicFieldTextWidget(LMDialog.nameW,
3429 "language mode name", silent);
3430 if (lm->name == NULL) {
3431 XtFree((char *)lm);
3432 return NULL;
3435 if (*lm->name == '\0')
3437 if (!silent)
3439 DialogF(DF_WARN, LMDialog.shell, 1, "Language Mode Name",
3440 "Please specify a name\nfor the language mode", "Dismiss");
3441 XmProcessTraversal(LMDialog.nameW, XmTRAVERSE_CURRENT);
3443 freeLanguageModeRec(lm);
3444 return NULL;
3447 /* read the extension list field */
3448 extStr = extPtr = XmTextGetString(LMDialog.extW);
3449 lm->extensions = readExtensionList(&extPtr, &lm->nExtensions);
3450 XtFree(extStr);
3452 /* read recognition expression */
3453 lm->recognitionExpr = XmTextGetString(LMDialog.recogW);
3454 if (*lm->recognitionExpr == '\0') {
3455 XtFree(lm->recognitionExpr);
3456 lm->recognitionExpr = NULL;
3457 } else
3459 compiledRE = CompileRE(lm->recognitionExpr, &compileMsg, REDFLT_STANDARD);
3461 if (compiledRE == NULL)
3463 if (!silent)
3465 DialogF(DF_WARN, LMDialog.shell, 1, "Regex",
3466 "Recognition expression:\n%s", "Dismiss", compileMsg);
3467 XmProcessTraversal(LMDialog.recogW, XmTRAVERSE_CURRENT);
3469 XtFree((char *)compiledRE);
3470 freeLanguageModeRec(lm);
3471 return NULL;
3474 XtFree((char *)compiledRE);
3477 /* Read the default calltips file for the language mode */
3478 lm->defTipsFile = XmTextGetString(LMDialog.defTipsW);
3479 if (*lm->defTipsFile == '\0') {
3480 /* Empty string */
3481 XtFree(lm->defTipsFile);
3482 lm->defTipsFile = NULL;
3483 } else {
3484 /* Ensure that AddTagsFile will work */
3485 if (AddTagsFile(lm->defTipsFile, TIP) == FALSE) {
3486 if (!silent)
3488 DialogF(DF_WARN, LMDialog.shell, 1, "Error reading Calltips",
3489 "Can't read default calltips file(s):\n \"%s\"\n",
3490 "Dismiss", lm->defTipsFile);
3491 XmProcessTraversal(LMDialog.recogW, XmTRAVERSE_CURRENT);
3493 freeLanguageModeRec(lm);
3494 return NULL;
3495 } else
3496 if (DeleteTagsFile(lm->defTipsFile, TIP) == FALSE)
3497 fprintf(stderr, "nedit: Internal error: Trouble deleting "
3498 "calltips file(s):\n \"%s\"\n", lm->defTipsFile);
3501 /* read tab spacing field */
3502 if (TextWidgetIsBlank(LMDialog.tabW))
3503 lm->tabDist = DEFAULT_TAB_DIST;
3504 else {
3505 if (GetIntTextWarn(LMDialog.tabW, &lm->tabDist, "tab spacing", False)
3506 != TEXT_READ_OK) {
3507 freeLanguageModeRec(lm);
3508 return NULL;
3511 if (lm->tabDist <= 0 || lm->tabDist > 100)
3513 if (!silent)
3515 DialogF(DF_WARN, LMDialog.shell, 1, "Invalid Tab Spacing",
3516 "Invalid tab spacing: %d", "Dismiss", lm->tabDist);
3517 XmProcessTraversal(LMDialog.tabW, XmTRAVERSE_CURRENT);
3519 freeLanguageModeRec(lm);
3520 return NULL;
3524 /* read emulated tab field */
3525 if (TextWidgetIsBlank(LMDialog.emTabW))
3527 lm->emTabDist = DEFAULT_EM_TAB_DIST;
3528 } else
3530 if (GetIntTextWarn(LMDialog.emTabW, &lm->emTabDist,
3531 "emulated tab spacing", False) != TEXT_READ_OK)
3533 freeLanguageModeRec(lm);
3534 return NULL;
3537 if (lm->emTabDist < 0 || lm->emTabDist > 100)
3539 if (!silent)
3541 DialogF(DF_WARN, LMDialog.shell, 1, "Invalid Tab Spacing",
3542 "Invalid emulated tab spacing: %d", "Dismiss",
3543 lm->emTabDist);
3544 XmProcessTraversal(LMDialog.emTabW, XmTRAVERSE_CURRENT);
3546 freeLanguageModeRec(lm);
3547 return NULL;
3551 /* read delimiters string */
3552 lm->delimiters = XmTextGetString(LMDialog.delimitW);
3553 if (*lm->delimiters == '\0') {
3554 XtFree(lm->delimiters);
3555 lm->delimiters = NULL;
3558 /* read indent style */
3559 if (XmToggleButtonGetState(LMDialog.noIndentW))
3560 lm->indentStyle = NO_AUTO_INDENT;
3561 else if (XmToggleButtonGetState(LMDialog.autoIndentW))
3562 lm->indentStyle = AUTO_INDENT;
3563 else if (XmToggleButtonGetState(LMDialog.smartIndentW))
3564 lm->indentStyle = SMART_INDENT;
3565 else
3566 lm->indentStyle = DEFAULT_INDENT;
3568 /* read wrap style */
3569 if (XmToggleButtonGetState(LMDialog.noWrapW))
3570 lm->wrapStyle = NO_WRAP;
3571 else if (XmToggleButtonGetState(LMDialog.newlineWrapW))
3572 lm->wrapStyle = NEWLINE_WRAP;
3573 else if (XmToggleButtonGetState(LMDialog.contWrapW))
3574 lm->wrapStyle = CONTINUOUS_WRAP;
3575 else
3576 lm->wrapStyle = DEFAULT_WRAP;
3578 return lm;
3582 ** Return True if the language mode dialog fields are blank (unchanged from the "New"
3583 ** language mode state).
3585 static int lmDialogEmpty(void)
3587 return TextWidgetIsBlank(LMDialog.nameW) &&
3588 TextWidgetIsBlank(LMDialog.extW) &&
3589 TextWidgetIsBlank(LMDialog.recogW) &&
3590 TextWidgetIsBlank(LMDialog.delimitW) &&
3591 TextWidgetIsBlank(LMDialog.tabW) &&
3592 TextWidgetIsBlank(LMDialog.emTabW) &&
3593 XmToggleButtonGetState(LMDialog.defaultIndentW) &&
3594 XmToggleButtonGetState(LMDialog.defaultWrapW);
3598 ** Present a dialog for changing fonts (primary, and for highlighting).
3600 void ChooseFonts(WindowInfo *window, int forWindow)
3602 #define MARGIN_SPACING 10
3603 #define BTN_TEXT_OFFSET 3
3604 Widget form, primaryLbl, primaryBtn, italicLbl, italicBtn;
3605 Widget boldLbl, boldBtn, boldItalicLbl, boldItalicBtn;
3606 Widget primaryFrame, primaryForm, highlightFrame, highlightForm;
3607 Widget okBtn, applyBtn, dismissBtn;
3608 fontDialog *fd;
3609 XmString s1;
3610 int ac;
3611 Arg args[20];
3613 /* if the dialog is already displayed, just pop it to the top and return */
3614 if (window->fontDialog != NULL) {
3615 RaiseShellWindow(((fontDialog *)window->fontDialog)->shell);
3616 return;
3619 /* Create a structure for keeping track of dialog state */
3620 fd = (fontDialog *)XtMalloc(sizeof(fontDialog));
3621 fd->window = window;
3622 fd->forWindow = forWindow;
3623 window->fontDialog = (void*)fd;
3625 /* Create a form widget in a dialog shell */
3626 ac = 0;
3627 XtSetArg(args[ac], XmNautoUnmanage, False); ac++;
3628 XtSetArg(args[ac], XmNresizePolicy, XmRESIZE_NONE); ac++;
3629 form = CreateFormDialog(window->shell, "choose Fonts", args, ac);
3630 XtVaSetValues(form, XmNshadowThickness, 0, NULL);
3631 fd->shell = XtParent(form);
3632 XtVaSetValues(fd->shell, XmNtitle, "Text Fonts", NULL);
3633 AddMotifCloseCallback(XtParent(form), fontDismissCB, fd);
3634 XtAddCallback(form, XmNdestroyCallback, fontDestroyCB, fd);
3636 primaryFrame = XtVaCreateManagedWidget("primaryFrame", xmFrameWidgetClass,
3637 form, XmNmarginHeight, 3,
3638 XmNtopAttachment, XmATTACH_POSITION,
3639 XmNtopPosition, 2,
3640 XmNleftAttachment, XmATTACH_POSITION,
3641 XmNleftPosition, 1,
3642 XmNrightAttachment, XmATTACH_POSITION,
3643 XmNrightPosition, 99, NULL);
3644 primaryForm = XtVaCreateManagedWidget("primaryForm", xmFormWidgetClass,
3645 primaryFrame, NULL);
3646 primaryLbl = XtVaCreateManagedWidget("primaryFont", xmLabelGadgetClass,
3647 primaryFrame,
3648 XmNlabelString, s1=XmStringCreateSimple("Primary Font"),
3649 XmNmnemonic, 'P',
3650 XmNchildType, XmFRAME_TITLE_CHILD,
3651 XmNchildHorizontalAlignment, XmALIGNMENT_CENTER, NULL);
3652 XmStringFree(s1);
3654 primaryBtn = XtVaCreateManagedWidget("primaryBtn",
3655 xmPushButtonWidgetClass, primaryForm,
3656 XmNlabelString, s1=XmStringCreateSimple("Browse..."),
3657 XmNmnemonic, 'r',
3658 XmNtopAttachment, XmATTACH_POSITION,
3659 XmNtopPosition, 2,
3660 XmNtopOffset, BTN_TEXT_OFFSET,
3661 XmNleftAttachment, XmATTACH_POSITION,
3662 XmNleftPosition, 1, NULL);
3663 XmStringFree(s1);
3664 XtAddCallback(primaryBtn, XmNactivateCallback, primaryBrowseCB, fd);
3666 fd->primaryW = XtVaCreateManagedWidget("primary", xmTextWidgetClass,
3667 primaryForm,
3668 XmNcolumns, 70,
3669 XmNmaxLength, MAX_FONT_LEN,
3670 XmNleftAttachment, XmATTACH_WIDGET,
3671 XmNleftWidget, primaryBtn,
3672 XmNtopAttachment, XmATTACH_POSITION,
3673 XmNtopPosition, 2,
3674 XmNrightAttachment, XmATTACH_POSITION,
3675 XmNrightPosition, 99, NULL);
3676 RemapDeleteKey(fd->primaryW);
3677 XtAddCallback(fd->primaryW, XmNvalueChangedCallback,
3678 primaryModifiedCB, fd);
3679 XtVaSetValues(primaryLbl, XmNuserData, fd->primaryW, NULL);
3681 highlightFrame = XtVaCreateManagedWidget("highlightFrame",
3682 xmFrameWidgetClass, form,
3683 XmNmarginHeight, 3,
3684 XmNnavigationType, XmTAB_GROUP,
3685 XmNtopAttachment, XmATTACH_WIDGET,
3686 XmNtopWidget, primaryFrame,
3687 XmNtopOffset, 20,
3688 XmNleftAttachment, XmATTACH_POSITION,
3689 XmNleftPosition, 1,
3690 XmNrightAttachment, XmATTACH_POSITION,
3691 XmNrightPosition, 99, NULL);
3692 highlightForm = XtVaCreateManagedWidget("highlightForm", xmFormWidgetClass,
3693 highlightFrame, NULL);
3694 XtVaCreateManagedWidget("highlightFonts", xmLabelGadgetClass,
3695 highlightFrame,
3696 XmNlabelString,
3697 s1=XmStringCreateSimple("Fonts for Syntax Highlighting"),
3698 XmNchildType, XmFRAME_TITLE_CHILD,
3699 XmNchildHorizontalAlignment, XmALIGNMENT_CENTER, NULL);
3700 XmStringFree(s1);
3702 fd->fillW = XtVaCreateManagedWidget("fillBtn",
3703 xmPushButtonWidgetClass, highlightForm,
3704 XmNlabelString,
3705 s1=XmStringCreateSimple("Fill Highlight Fonts from Primary"),
3706 XmNmnemonic, 'F',
3707 XmNtopAttachment, XmATTACH_POSITION,
3708 XmNtopPosition, 2,
3709 XmNtopOffset, BTN_TEXT_OFFSET,
3710 XmNleftAttachment, XmATTACH_POSITION,
3711 XmNleftPosition, 1, NULL);
3712 XmStringFree(s1);
3713 XtAddCallback(fd->fillW, XmNactivateCallback, fillFromPrimaryCB, fd);
3715 italicLbl = XtVaCreateManagedWidget("italicLbl", xmLabelGadgetClass,
3716 highlightForm,
3717 XmNlabelString, s1=XmStringCreateSimple("Italic Font"),
3718 XmNmnemonic, 'I',
3719 XmNalignment, XmALIGNMENT_BEGINNING,
3720 XmNtopAttachment, XmATTACH_WIDGET,
3721 XmNtopWidget, fd->fillW,
3722 XmNtopOffset, MARGIN_SPACING,
3723 XmNleftAttachment, XmATTACH_POSITION,
3724 XmNleftPosition, 1, NULL);
3725 XmStringFree(s1);
3727 fd->italicErrW = XtVaCreateManagedWidget("italicErrLbl",
3728 xmLabelGadgetClass, highlightForm,
3729 XmNlabelString, s1=XmStringCreateSimple(
3730 "(vvv spacing is inconsistent with primary font vvv)"),
3731 XmNalignment, XmALIGNMENT_END,
3732 XmNtopAttachment, XmATTACH_WIDGET,
3733 XmNtopWidget, fd->fillW,
3734 XmNtopOffset, MARGIN_SPACING,
3735 XmNleftAttachment, XmATTACH_WIDGET,
3736 XmNleftWidget, italicLbl,
3737 XmNrightAttachment, XmATTACH_POSITION,
3738 XmNrightPosition, 99, NULL);
3739 XmStringFree(s1);
3741 italicBtn = XtVaCreateManagedWidget("italicBtn",
3742 xmPushButtonWidgetClass, highlightForm,
3743 XmNlabelString, s1=XmStringCreateSimple("Browse..."),
3744 XmNmnemonic, 'o',
3745 XmNtopAttachment, XmATTACH_WIDGET,
3746 XmNtopWidget, italicLbl,
3747 XmNtopOffset, BTN_TEXT_OFFSET,
3748 XmNleftAttachment, XmATTACH_POSITION,
3749 XmNleftPosition, 1, NULL);
3750 XmStringFree(s1);
3751 XtAddCallback(italicBtn, XmNactivateCallback, italicBrowseCB, fd);
3753 fd->italicW = XtVaCreateManagedWidget("italic", xmTextWidgetClass,
3754 highlightForm,
3755 XmNmaxLength, MAX_FONT_LEN,
3756 XmNleftAttachment, XmATTACH_WIDGET,
3757 XmNleftWidget, italicBtn,
3758 XmNtopAttachment, XmATTACH_WIDGET,
3759 XmNtopWidget, italicLbl,
3760 XmNrightAttachment, XmATTACH_POSITION,
3761 XmNrightPosition, 99, NULL);
3762 RemapDeleteKey(fd->italicW);
3763 XtAddCallback(fd->italicW, XmNvalueChangedCallback,
3764 italicModifiedCB, fd);
3765 XtVaSetValues(italicLbl, XmNuserData, fd->italicW, NULL);
3767 boldLbl = XtVaCreateManagedWidget("boldLbl", xmLabelGadgetClass,
3768 highlightForm,
3769 XmNlabelString, s1=XmStringCreateSimple("Bold Font"),
3770 XmNmnemonic, 'B',
3771 XmNalignment, XmALIGNMENT_BEGINNING,
3772 XmNtopAttachment, XmATTACH_WIDGET,
3773 XmNtopWidget, italicBtn,
3774 XmNtopOffset, MARGIN_SPACING,
3775 XmNleftAttachment, XmATTACH_POSITION,
3776 XmNleftPosition, 1, NULL);
3777 XmStringFree(s1);
3779 fd->boldErrW = XtVaCreateManagedWidget("boldErrLbl",
3780 xmLabelGadgetClass, highlightForm,
3781 XmNlabelString, s1=XmStringCreateSimple(""),
3782 XmNalignment, XmALIGNMENT_END,
3783 XmNtopAttachment, XmATTACH_WIDGET,
3784 XmNtopWidget, italicBtn,
3785 XmNtopOffset, MARGIN_SPACING,
3786 XmNleftAttachment, XmATTACH_WIDGET,
3787 XmNleftWidget, boldLbl,
3788 XmNrightAttachment, XmATTACH_POSITION,
3789 XmNrightPosition, 99, NULL);
3790 XmStringFree(s1);
3792 boldBtn = XtVaCreateManagedWidget("boldBtn",
3793 xmPushButtonWidgetClass, highlightForm,
3794 XmNlabelString, s1=XmStringCreateSimple("Browse..."),
3795 XmNmnemonic, 'w',
3796 XmNtopAttachment, XmATTACH_WIDGET,
3797 XmNtopWidget, boldLbl,
3798 XmNtopOffset, BTN_TEXT_OFFSET,
3799 XmNleftAttachment, XmATTACH_POSITION,
3800 XmNleftPosition, 1, NULL);
3801 XmStringFree(s1);
3802 XtAddCallback(boldBtn, XmNactivateCallback, boldBrowseCB, fd);
3804 fd->boldW = XtVaCreateManagedWidget("bold", xmTextWidgetClass,
3805 highlightForm,
3806 XmNmaxLength, MAX_FONT_LEN,
3807 XmNleftAttachment, XmATTACH_WIDGET,
3808 XmNleftWidget, boldBtn,
3809 XmNtopAttachment, XmATTACH_WIDGET,
3810 XmNtopWidget, boldLbl,
3811 XmNrightAttachment, XmATTACH_POSITION,
3812 XmNrightPosition, 99, NULL);
3813 RemapDeleteKey(fd->boldW);
3814 XtAddCallback(fd->boldW, XmNvalueChangedCallback,
3815 boldModifiedCB, fd);
3816 XtVaSetValues(boldLbl, XmNuserData, fd->boldW, NULL);
3818 boldItalicLbl = XtVaCreateManagedWidget("boldItalicLbl", xmLabelGadgetClass,
3819 highlightForm,
3820 XmNlabelString, s1=XmStringCreateSimple("Bold Italic Font"),
3821 XmNmnemonic, 'l',
3822 XmNalignment, XmALIGNMENT_BEGINNING,
3823 XmNtopAttachment, XmATTACH_WIDGET,
3824 XmNtopWidget, boldBtn,
3825 XmNtopOffset, MARGIN_SPACING,
3826 XmNleftAttachment, XmATTACH_POSITION,
3827 XmNleftPosition, 1, NULL);
3828 XmStringFree(s1);
3830 fd->boldItalicErrW = XtVaCreateManagedWidget("boldItalicErrLbl",
3831 xmLabelGadgetClass, highlightForm,
3832 XmNlabelString, s1=XmStringCreateSimple(""),
3833 XmNalignment, XmALIGNMENT_END,
3834 XmNtopAttachment, XmATTACH_WIDGET,
3835 XmNtopWidget, boldBtn,
3836 XmNtopOffset, MARGIN_SPACING,
3837 XmNleftAttachment, XmATTACH_WIDGET,
3838 XmNleftWidget, boldItalicLbl,
3839 XmNrightAttachment, XmATTACH_POSITION,
3840 XmNrightPosition, 99, NULL);
3841 XmStringFree(s1);
3843 boldItalicBtn = XtVaCreateManagedWidget("boldItalicBtn",
3844 xmPushButtonWidgetClass, highlightForm,
3845 XmNlabelString, s1=XmStringCreateSimple("Browse..."),
3846 XmNmnemonic, 's',
3847 XmNtopAttachment, XmATTACH_WIDGET,
3848 XmNtopWidget, boldItalicLbl,
3849 XmNtopOffset, BTN_TEXT_OFFSET,
3850 XmNleftAttachment, XmATTACH_POSITION,
3851 XmNleftPosition, 1, NULL);
3852 XmStringFree(s1);
3853 XtAddCallback(boldItalicBtn, XmNactivateCallback, boldItalicBrowseCB, fd);
3855 fd->boldItalicW = XtVaCreateManagedWidget("boldItalic",
3856 xmTextWidgetClass, highlightForm,
3857 XmNmaxLength, MAX_FONT_LEN,
3858 XmNleftAttachment, XmATTACH_WIDGET,
3859 XmNleftWidget, boldItalicBtn,
3860 XmNtopAttachment, XmATTACH_WIDGET,
3861 XmNtopWidget, boldItalicLbl,
3862 XmNrightAttachment, XmATTACH_POSITION,
3863 XmNrightPosition, 99, NULL);
3864 RemapDeleteKey(fd->boldItalicW);
3865 XtAddCallback(fd->boldItalicW, XmNvalueChangedCallback,
3866 boldItalicModifiedCB, fd);
3867 XtVaSetValues(boldItalicLbl, XmNuserData, fd->boldItalicW, NULL);
3869 okBtn = XtVaCreateManagedWidget("ok", xmPushButtonWidgetClass, form,
3870 XmNlabelString, s1=XmStringCreateSimple("OK"),
3871 XmNtopAttachment, XmATTACH_WIDGET,
3872 XmNtopWidget, highlightFrame,
3873 XmNtopOffset, MARGIN_SPACING,
3874 XmNleftAttachment, XmATTACH_POSITION,
3875 XmNleftPosition, forWindow ? 13 : 26,
3876 XmNrightAttachment, XmATTACH_POSITION,
3877 XmNrightPosition, forWindow ? 27 : 40, NULL);
3878 XtAddCallback(okBtn, XmNactivateCallback, fontOkCB, fd);
3879 XmStringFree(s1);
3881 if (forWindow) {
3882 applyBtn = XtVaCreateManagedWidget("apply",xmPushButtonWidgetClass,form,
3883 XmNlabelString, s1=XmStringCreateSimple("Apply"),
3884 XmNmnemonic, 'A',
3885 XmNtopAttachment, XmATTACH_WIDGET,
3886 XmNtopWidget, highlightFrame,
3887 XmNtopOffset, MARGIN_SPACING,
3888 XmNleftAttachment, XmATTACH_POSITION,
3889 XmNleftPosition, 43,
3890 XmNrightAttachment, XmATTACH_POSITION,
3891 XmNrightPosition, 57, NULL);
3892 XtAddCallback(applyBtn, XmNactivateCallback, fontApplyCB, fd);
3893 XmStringFree(s1);
3896 dismissBtn = XtVaCreateManagedWidget("dismiss",xmPushButtonWidgetClass,form,
3897 XmNlabelString, s1=XmStringCreateSimple("Dismiss"),
3898 XmNtopAttachment, XmATTACH_WIDGET,
3899 XmNtopWidget, highlightFrame,
3900 XmNtopOffset, MARGIN_SPACING,
3901 XmNleftAttachment, XmATTACH_POSITION,
3902 XmNleftPosition, forWindow ? 73 : 59,
3903 XmNrightAttachment, XmATTACH_POSITION,
3904 XmNrightPosition, forWindow ? 87 : 73, NULL);
3905 XtAddCallback(dismissBtn, XmNactivateCallback, fontDismissCB, fd);
3906 XmStringFree(s1);
3908 /* Set initial default button */
3909 XtVaSetValues(form, XmNdefaultButton, okBtn, NULL);
3910 XtVaSetValues(form, XmNcancelButton, dismissBtn, NULL);
3912 /* Set initial values */
3913 if (forWindow) {
3914 XmTextSetString(fd->primaryW, window->fontName);
3915 XmTextSetString(fd->boldW, window->boldFontName);
3916 XmTextSetString(fd->italicW, window->italicFontName);
3917 XmTextSetString(fd->boldItalicW, window->boldItalicFontName);
3918 } else {
3919 XmTextSetString(fd->primaryW, GetPrefFontName());
3920 XmTextSetString(fd->boldW, GetPrefBoldFontName());
3921 XmTextSetString(fd->italicW, GetPrefItalicFontName());
3922 XmTextSetString(fd->boldItalicW, GetPrefBoldItalicFontName());
3925 /* Handle mnemonic selection of buttons and focus to dialog */
3926 AddDialogMnemonicHandler(form, FALSE);
3928 /* put up dialog */
3929 ManageDialogCenteredOnPointer(form);
3932 static void fillFromPrimaryCB(Widget w, XtPointer clientData,
3933 XtPointer callData)
3935 fontDialog *fd = (fontDialog *)clientData;
3936 char *primaryName, *errMsg;
3937 char modifiedFontName[MAX_FONT_LEN];
3938 char *searchString = "(-[^-]*-[^-]*)-([^-]*)-([^-]*)-(.*)";
3939 char *italicReplaceString = "\\1-\\2-o-\\4";
3940 char *boldReplaceString = "\\1-bold-\\3-\\4";
3941 char *boldItalicReplaceString = "\\1-bold-o-\\4";
3942 regexp *compiledRE;
3944 /* Match the primary font agains RE pattern for font names. If it
3945 doesn't match, we can't generate highlight font names, so return */
3946 compiledRE = CompileRE(searchString, &errMsg, REDFLT_STANDARD);
3947 primaryName = XmTextGetString(fd->primaryW);
3948 if (!ExecRE(compiledRE, NULL, primaryName, NULL, False, '\0', '\0', NULL, NULL)) {
3949 XBell(XtDisplay(fd->shell), 0);
3950 free(compiledRE);
3951 XtFree(primaryName);
3952 return;
3955 /* Make up names for new fonts based on RE replace patterns */
3956 SubstituteRE(compiledRE, italicReplaceString, modifiedFontName,
3957 MAX_FONT_LEN);
3958 XmTextSetString(fd->italicW, modifiedFontName);
3959 SubstituteRE(compiledRE, boldReplaceString, modifiedFontName,
3960 MAX_FONT_LEN);
3961 XmTextSetString(fd->boldW, modifiedFontName);
3962 SubstituteRE(compiledRE, boldItalicReplaceString, modifiedFontName,
3963 MAX_FONT_LEN);
3964 XmTextSetString(fd->boldItalicW, modifiedFontName);
3965 XtFree(primaryName);
3966 free(compiledRE);
3969 static void primaryModifiedCB(Widget w, XtPointer clientData,
3970 XtPointer callData)
3972 fontDialog *fd = (fontDialog *)clientData;
3974 showFontStatus(fd, fd->italicW, fd->italicErrW);
3975 showFontStatus(fd, fd->boldW, fd->boldErrW);
3976 showFontStatus(fd, fd->boldItalicW, fd->boldItalicErrW);
3978 static void italicModifiedCB(Widget w, XtPointer clientData, XtPointer callData)
3980 fontDialog *fd = (fontDialog *)clientData;
3982 showFontStatus(fd, fd->italicW, fd->italicErrW);
3984 static void boldModifiedCB(Widget w, XtPointer clientData, XtPointer callData)
3986 fontDialog *fd = (fontDialog *)clientData;
3988 showFontStatus(fd, fd->boldW, fd->boldErrW);
3990 static void boldItalicModifiedCB(Widget w, XtPointer clientData,
3991 XtPointer callData)
3993 fontDialog *fd = (fontDialog *)clientData;
3995 showFontStatus(fd, fd->boldItalicW, fd->boldItalicErrW);
3998 static void primaryBrowseCB(Widget w, XtPointer clientData, XtPointer callData)
4000 fontDialog *fd = (fontDialog *)clientData;
4002 browseFont(fd->shell, fd->primaryW);
4004 static void italicBrowseCB(Widget w, XtPointer clientData, XtPointer callData)
4006 fontDialog *fd = (fontDialog *)clientData;
4008 browseFont(fd->shell, fd->italicW);
4010 static void boldBrowseCB(Widget w, XtPointer clientData, XtPointer callData)
4012 fontDialog *fd = (fontDialog *)clientData;
4014 browseFont(fd->shell, fd->boldW);
4016 static void boldItalicBrowseCB(Widget w, XtPointer clientData,
4017 XtPointer callData)
4019 fontDialog *fd = (fontDialog *)clientData;
4021 browseFont(fd->shell, fd->boldItalicW);
4024 static void fontDestroyCB(Widget w, XtPointer clientData, XtPointer callData)
4026 fontDialog *fd = (fontDialog *)clientData;
4028 fd->window->fontDialog = NULL;
4029 XtFree((char *)fd);
4032 static void fontOkCB(Widget w, XtPointer clientData, XtPointer callData)
4034 fontDialog *fd = (fontDialog *)clientData;
4036 updateFonts(fd);
4038 /* pop down and destroy the dialog */
4039 XtDestroyWidget(fd->shell);
4042 static void fontApplyCB(Widget w, XtPointer clientData, XtPointer callData)
4044 fontDialog *fd = (fontDialog *)clientData;
4046 updateFonts(fd);
4049 static void fontDismissCB(Widget w, XtPointer clientData, XtPointer callData)
4051 fontDialog *fd = (fontDialog *)clientData;
4053 /* pop down and destroy the dialog */
4054 XtDestroyWidget(fd->shell);
4058 ** Check over a font name in a text field to make sure it agrees with the
4059 ** primary font in height and spacing.
4061 static int checkFontStatus(fontDialog *fd, Widget fontTextFieldW)
4063 char *primaryName, *testName;
4064 XFontStruct *primaryFont, *testFont;
4065 Display *display = XtDisplay(fontTextFieldW);
4066 int primaryWidth, primaryHeight, testWidth, testHeight;
4068 /* Get width and height of the font to check. Note the test for empty
4069 name: X11R6 clients freak out X11R5 servers if they ask them to load
4070 an empty font name, and kill the whole application! */
4071 testName = XmTextGetString(fontTextFieldW);
4072 if (testName[0] == '\0') {
4073 XtFree(testName);
4074 return BAD_FONT;
4076 testFont = XLoadQueryFont(display, testName);
4077 if (testFont == NULL) {
4078 XtFree(testName);
4079 return BAD_FONT;
4081 XtFree(testName);
4082 testWidth = testFont->min_bounds.width;
4083 testHeight = testFont->ascent + testFont->descent;
4084 XFreeFont(display, testFont);
4086 /* Get width and height of the primary font */
4087 primaryName = XmTextGetString(fd->primaryW);
4088 if (primaryName[0] == '\0') {
4089 XtFree(primaryName);
4090 return BAD_FONT;
4092 primaryFont = XLoadQueryFont(display, primaryName);
4093 if (primaryFont == NULL) {
4094 XtFree(primaryName);
4095 return BAD_PRIMARY;
4097 XtFree(primaryName);
4098 primaryWidth = primaryFont->min_bounds.width;
4099 primaryHeight = primaryFont->ascent + primaryFont->descent;
4100 XFreeFont(display, primaryFont);
4102 /* Compare font information */
4103 if (testWidth != primaryWidth)
4104 return BAD_SPACING;
4105 if (testHeight != primaryHeight)
4106 return BAD_SIZE;
4107 return GOOD_FONT;
4111 ** Update the error label for a font text field to reflect its validity and degree
4112 ** of agreement with the currently selected primary font
4114 static int showFontStatus(fontDialog *fd, Widget fontTextFieldW,
4115 Widget errorLabelW)
4117 int status;
4118 XmString s;
4119 char *msg;
4121 status = checkFontStatus(fd, fontTextFieldW);
4122 if (status == BAD_PRIMARY)
4123 msg = "(font below may not match primary font)";
4124 else if (status == BAD_FONT)
4125 msg = "(xxx font below is invalid xxx)";
4126 else if (status == BAD_SIZE)
4127 msg = "(height of font below does not match primary)";
4128 else if (status == BAD_SPACING)
4129 msg = "(spacing of font below does not match primary)";
4130 else
4131 msg = "";
4133 XtVaSetValues(errorLabelW, XmNlabelString, s=XmStringCreateSimple(msg),
4134 NULL);
4135 XmStringFree(s);
4136 return status;
4140 ** Put up a font selector panel to set the font name in the text widget "fontTextW"
4142 static void browseFont(Widget parent, Widget fontTextW)
4144 char *origFontName, *newFontName;
4145 Pixel fgPixel, bgPixel;
4146 int dummy;
4148 origFontName = XmTextGetString(fontTextW);
4150 /* Get the values from the defaults */
4151 fgPixel = AllocColor(parent, GetPrefColorName(TEXT_FG_COLOR),
4152 &dummy, &dummy, &dummy);
4153 bgPixel = AllocColor(parent, GetPrefColorName(TEXT_BG_COLOR),
4154 &dummy, &dummy, &dummy);
4156 newFontName = FontSel(parent, PREF_FIXED, origFontName, fgPixel, bgPixel);
4157 XtFree(origFontName);
4158 if (newFontName == NULL)
4159 return;
4160 XmTextSetString(fontTextW, newFontName);
4161 XtFree(newFontName);
4165 ** Accept the changes in the dialog and set the fonts regardless of errors
4167 static void updateFonts(fontDialog *fd)
4169 char *fontName, *italicName, *boldName, *boldItalicName;
4171 fontName = XmTextGetString(fd->primaryW);
4172 italicName = XmTextGetString(fd->italicW);
4173 boldName = XmTextGetString(fd->boldW);
4174 boldItalicName = XmTextGetString(fd->boldItalicW);
4176 if (fd->forWindow) {
4177 char *params[4];
4178 params[0] = fontName;
4179 params[1] = italicName;
4180 params[2] = boldName;
4181 params[3] = boldItalicName;
4182 XtCallActionProc(fd->window->textArea, "set_fonts", NULL, params, 4);
4184 SetFonts(fd->window, fontName, italicName, boldName, boldItalicName);
4187 else {
4188 SetPrefFont(fontName);
4189 SetPrefItalicFont(italicName);
4190 SetPrefBoldFont(boldName);
4191 SetPrefBoldItalicFont(boldItalicName);
4193 XtFree(fontName);
4194 XtFree(italicName);
4195 XtFree(boldName);
4196 XtFree(boldItalicName);
4200 ** Change the language mode to the one indexed by "mode", reseting word
4201 ** delimiters, syntax highlighting and other mode specific parameters
4203 static void reapplyLanguageMode(WindowInfo *window, int mode, int forceDefaults)
4205 char *delimiters;
4206 int i, wrapMode, indentStyle, tabDist, emTabDist, highlight, oldEmTabDist;
4207 int wrapModeIsDef, tabDistIsDef, emTabDistIsDef, indentStyleIsDef;
4208 int highlightIsDef, haveHighlightPatterns, haveSmartIndentMacros;
4209 int oldMode = window->languageMode;
4210 WindowInfo *wi;
4212 /* If the mode is the same, and changes aren't being forced (as might
4213 happen with Save As...), don't mess with already correct settings */
4214 if (window->languageMode == mode && !forceDefaults)
4215 return;
4217 /* Change the mode name stored in the window */
4218 window->languageMode = mode;
4220 /* Unload oldMode's default calltips file if there are no more windows
4221 in that mode and the mode has a default file */
4222 if (oldMode != PLAIN_LANGUAGE_MODE && LanguageModes[oldMode]->defTipsFile) {
4223 for (wi = WindowList; wi; wi = wi->next)
4224 if (wi->languageMode == oldMode) break;
4225 if (!wi) DeleteTagsFile( LanguageModes[oldMode]->defTipsFile, TIP );
4228 /* Make sure we didn't accidentally delete a default calltips file that
4229 also belongs another language mode (also load the tips file for the
4230 new lang. mode) */
4231 for (wi = WindowList; wi; wi = wi->next) {
4232 i = wi->languageMode;
4233 if (i != PLAIN_LANGUAGE_MODE && LanguageModes[i]->defTipsFile)
4234 if (AddTagsFile( LanguageModes[i]->defTipsFile, TIP ) == FALSE)
4235 fprintf( stderr, "Error loading default calltips file:\n"
4236 " \"%s\"\n", LanguageModes[i]->defTipsFile );
4239 /* Set delimiters for all text widgets */
4240 if (mode == PLAIN_LANGUAGE_MODE || LanguageModes[mode]->delimiters == NULL)
4241 delimiters = GetPrefDelimiters();
4242 else
4243 delimiters = LanguageModes[mode]->delimiters;
4244 XtVaSetValues(window->textArea, textNwordDelimiters, delimiters, NULL);
4245 for (i=0; i<window->nPanes; i++)
4246 XtVaSetValues(window->textPanes[i], textNautoIndent, delimiters, NULL);
4248 /* Decide on desired values for language-specific parameters. If a
4249 parameter was set to its default value, set it to the new default,
4250 otherwise, leave it alone */
4251 wrapModeIsDef = window->wrapMode == GetPrefWrap(oldMode);
4252 tabDistIsDef = BufGetTabDistance(window->buffer) == GetPrefTabDist(oldMode);
4253 XtVaGetValues(window->textArea, textNemulateTabs, &oldEmTabDist, NULL);
4254 emTabDistIsDef = oldEmTabDist == GetPrefEmTabDist(oldMode);
4255 indentStyleIsDef = window->indentStyle == GetPrefAutoIndent(oldMode) ||
4256 (GetPrefAutoIndent(oldMode) == SMART_INDENT &&
4257 window->indentStyle == AUTO_INDENT &&
4258 !SmartIndentMacrosAvailable(LanguageModeName(oldMode)));
4259 highlightIsDef = window->highlightSyntax == GetPrefHighlightSyntax()
4260 || (GetPrefHighlightSyntax() &&
4261 FindPatternSet(LanguageModeName(oldMode)) == NULL);
4262 wrapMode = wrapModeIsDef || forceDefaults ?
4263 GetPrefWrap(mode) : window->wrapMode;
4264 tabDist = tabDistIsDef || forceDefaults ?
4265 GetPrefTabDist(mode) : BufGetTabDistance(window->buffer);
4266 emTabDist = emTabDistIsDef || forceDefaults ?
4267 GetPrefEmTabDist(mode) : oldEmTabDist;
4268 indentStyle = indentStyleIsDef || forceDefaults ?
4269 GetPrefAutoIndent(mode) : window->indentStyle;
4270 highlight = highlightIsDef || forceDefaults ?
4271 GetPrefHighlightSyntax() : window->highlightSyntax;
4273 /* Dim/undim smart-indent and highlighting menu items depending on
4274 whether patterns/macros are available */
4275 haveHighlightPatterns = FindPatternSet(LanguageModeName(mode)) != NULL;
4276 haveSmartIndentMacros = SmartIndentMacrosAvailable(LanguageModeName(mode));
4277 if (IsTopDocument(window)) {
4278 XtSetSensitive(window->highlightItem, haveHighlightPatterns);
4279 XtSetSensitive(window->smartIndentItem, haveSmartIndentMacros);
4282 /* Turn off requested options which are not available */
4283 highlight = haveHighlightPatterns && highlight;
4284 if (indentStyle == SMART_INDENT && !haveSmartIndentMacros)
4285 indentStyle = AUTO_INDENT;
4287 /* Change highlighting */
4288 window->highlightSyntax = highlight;
4289 SetToggleButtonState(window, window->highlightItem, highlight, False);
4290 StopHighlighting(window);
4292 /* we defer highlighting to RaiseDocument() if doc is hidden */
4293 if (IsTopDocument(window) && highlight)
4294 StartHighlighting(window, False);
4296 /* Force a change of smart indent macros (SetAutoIndent will re-start) */
4297 if (window->indentStyle == SMART_INDENT) {
4298 EndSmartIndent(window);
4299 window->indentStyle = AUTO_INDENT;
4302 /* set requested wrap, indent, and tabs */
4303 SetAutoWrap(window, wrapMode);
4304 SetAutoIndent(window, indentStyle);
4305 SetTabDist(window, tabDist);
4306 SetEmTabDist(window, emTabDist);
4308 /* Add/remove language specific menu items */
4309 UpdateUserMenus(window);
4313 ** Find and return the name of the appropriate languange mode for
4314 ** the file in "window". Returns a pointer to a string, which will
4315 ** remain valid until a change is made to the language modes list.
4317 static int matchLanguageMode(WindowInfo *window)
4319 char *ext, *first200;
4320 int i, j, fileNameLen, extLen, beginPos, endPos, start;
4321 const char *versionExtendedPath;
4323 /*... look for an explicit mode statement first */
4325 /* Do a regular expression search on for recognition pattern */
4326 first200 = BufGetRange(window->buffer, 0, 200);
4327 for (i=0; i<NLanguageModes; i++) {
4328 if (LanguageModes[i]->recognitionExpr != NULL) {
4329 if (SearchString(first200, LanguageModes[i]->recognitionExpr,
4330 SEARCH_FORWARD, SEARCH_REGEX, False, 0, &beginPos,
4331 &endPos, NULL, NULL, NULL))
4333 XtFree(first200);
4334 return i;
4338 XtFree(first200);
4340 /* Look at file extension ("@@/" starts a ClearCase version extended path,
4341 which gets appended after the file extension, and therefore must be
4342 stripped off to recognize the extension to make ClearCase users happy) */
4343 fileNameLen = strlen(window->filename);
4344 #ifdef VMS
4345 if (strchr(window->filename, ';') != NULL)
4346 fileNameLen = strchr(window->filename, ';') - window->filename;
4347 #else
4348 if ((versionExtendedPath = GetClearCaseVersionExtendedPath(window->filename)) != NULL)
4349 fileNameLen = versionExtendedPath - window->filename;
4350 #endif
4351 for (i=0; i<NLanguageModes; i++) {
4352 for (j=0; j<LanguageModes[i]->nExtensions; j++) {
4353 ext = LanguageModes[i]->extensions[j];
4354 extLen = strlen(ext);
4355 start = fileNameLen - extLen;
4356 #if defined(__VMS) && (__VMS_VER >= 70200000)
4357 /* VMS v7.2 has case-preserving filenames */
4358 if (start >= 0 && !strncasecmp(&window->filename[start], ext, extLen))
4359 return i;
4360 #else
4361 if (start >= 0 && !strncmp(&window->filename[start], ext, extLen))
4362 return i;
4363 #endif
4367 /* no appropriate mode was found */
4368 return PLAIN_LANGUAGE_MODE;
4371 static int loadLanguageModesString(char *inString, int fileVer)
4373 char *errMsg, *styleName, *inPtr = inString;
4374 languageModeRec *lm;
4375 int i;
4377 for (;;) {
4379 /* skip over blank space */
4380 inPtr += strspn(inPtr, " \t\n");
4382 /* Allocate a language mode structure to return, set unread fields to
4383 empty so everything can be freed on errors by freeLanguageModeRec */
4384 lm = (languageModeRec *)XtMalloc(sizeof(languageModeRec));
4385 lm->nExtensions = 0;
4386 lm->recognitionExpr = NULL;
4387 lm->defTipsFile = NULL;
4388 lm->delimiters = NULL;
4390 /* read language mode name */
4391 lm->name = ReadSymbolicField(&inPtr);
4392 if (lm->name == NULL) {
4393 XtFree((char *)lm);
4394 return modeError(NULL,inString,inPtr,"language mode name required");
4396 if (!SkipDelimiter(&inPtr, &errMsg))
4397 return modeError(lm, inString, inPtr, errMsg);
4399 /* read list of extensions */
4400 lm->extensions = readExtensionList(&inPtr,
4401 &lm->nExtensions);
4402 if (!SkipDelimiter(&inPtr, &errMsg))
4403 return modeError(lm, inString, inPtr, errMsg);
4405 /* read the recognition regular expression */
4406 if (*inPtr == '\n' || *inPtr == '\0' || *inPtr == ':')
4407 lm->recognitionExpr = NULL;
4408 else if (!ReadQuotedString(&inPtr, &errMsg, &lm->recognitionExpr))
4409 return modeError(lm, inString,inPtr, errMsg);
4410 if (!SkipDelimiter(&inPtr, &errMsg))
4411 return modeError(lm, inString, inPtr, errMsg);
4413 /* read the indent style */
4414 styleName = ReadSymbolicField(&inPtr);
4415 if (styleName == NULL)
4416 lm->indentStyle = DEFAULT_INDENT;
4417 else {
4418 for (i=0; i<N_INDENT_STYLES; i++) {
4419 if (!strcmp(styleName, AutoIndentTypes[i])) {
4420 lm->indentStyle = i;
4421 break;
4424 XtFree(styleName);
4425 if (i == N_INDENT_STYLES)
4426 return modeError(lm,inString,inPtr,"unrecognized indent style");
4428 if (!SkipDelimiter(&inPtr, &errMsg))
4429 return modeError(lm, inString, inPtr, errMsg);
4431 /* read the wrap style */
4432 styleName = ReadSymbolicField(&inPtr);
4433 if (styleName == NULL)
4434 lm->wrapStyle = DEFAULT_WRAP;
4435 else {
4436 for (i=0; i<N_WRAP_STYLES; i++) {
4437 if (!strcmp(styleName, AutoWrapTypes[i])) {
4438 lm->wrapStyle = i;
4439 break;
4442 XtFree(styleName);
4443 if (i == N_WRAP_STYLES)
4444 return modeError(lm, inString, inPtr,"unrecognized wrap style");
4446 if (!SkipDelimiter(&inPtr, &errMsg))
4447 return modeError(lm, inString, inPtr, errMsg);
4449 /* read the tab distance */
4450 if (*inPtr == '\n' || *inPtr == '\0' || *inPtr == ':')
4451 lm->tabDist = DEFAULT_TAB_DIST;
4452 else if (!ReadNumericField(&inPtr, &lm->tabDist))
4453 return modeError(lm, inString, inPtr, "bad tab spacing");
4454 if (!SkipDelimiter(&inPtr, &errMsg))
4455 return modeError(lm, inString, inPtr, errMsg);
4457 /* read emulated tab distance */
4458 if (*inPtr == '\n' || *inPtr == '\0' || *inPtr == ':')
4459 lm->emTabDist = DEFAULT_EM_TAB_DIST;
4460 else if (!ReadNumericField(&inPtr, &lm->emTabDist))
4461 return modeError(lm, inString, inPtr, "bad emulated tab spacing");
4462 if (!SkipDelimiter(&inPtr, &errMsg))
4463 return modeError(lm, inString, inPtr, errMsg);
4465 /* read the delimiters string */
4466 if (*inPtr == '\n' || *inPtr == '\0' || *inPtr == ':')
4467 lm->delimiters = NULL;
4468 else if (!ReadQuotedString(&inPtr, &errMsg, &lm->delimiters))
4469 return modeError(lm, inString, inPtr, errMsg);
4471 /* After 5.3 all language modes need a default tips file field */
4472 if (!SkipDelimiter(&inPtr, &errMsg))
4473 if (fileVer > 5003)
4474 return modeError(lm, inString, inPtr, errMsg);
4476 /* read the default tips file */
4477 if (*inPtr == '\n' || *inPtr == '\0')
4478 lm->defTipsFile = NULL;
4479 else if (!ReadQuotedString(&inPtr, &errMsg, &lm->defTipsFile))
4480 return modeError(lm, inString, inPtr, errMsg);
4482 /* pattern set was read correctly, add/replace it in the list */
4483 for (i=0; i<NLanguageModes; i++) {
4484 if (!strcmp(LanguageModes[i]->name, lm->name)) {
4485 freeLanguageModeRec(LanguageModes[i]);
4486 LanguageModes[i] = lm;
4487 break;
4490 if (i == NLanguageModes) {
4491 LanguageModes[NLanguageModes++] = lm;
4492 if (NLanguageModes > MAX_LANGUAGE_MODES)
4493 return modeError(NULL, inString, inPtr,
4494 "maximum allowable number of language modes exceeded");
4497 /* if the string ends here, we're done */
4498 inPtr += strspn(inPtr, " \t\n");
4499 if (*inPtr == '\0')
4500 return True;
4501 } /* End for(;;) */
4504 static char *writeLanguageModesString(void)
4506 int i;
4507 char *outStr, *escapedStr, *str, numBuf[25];
4508 textBuffer *outBuf;
4510 outBuf = BufCreate();
4511 for (i=0; i<NLanguageModes; i++) {
4512 BufInsert(outBuf, outBuf->length, "\t");
4513 BufInsert(outBuf, outBuf->length, LanguageModes[i]->name);
4514 BufInsert(outBuf, outBuf->length, ":");
4515 BufInsert(outBuf, outBuf->length, str = createExtString(
4516 LanguageModes[i]->extensions, LanguageModes[i]->nExtensions));
4517 XtFree(str);
4518 BufInsert(outBuf, outBuf->length, ":");
4519 if (LanguageModes[i]->recognitionExpr != NULL) {
4520 BufInsert(outBuf, outBuf->length,
4521 str=MakeQuotedString(LanguageModes[i]->recognitionExpr));
4522 XtFree(str);
4524 BufInsert(outBuf, outBuf->length, ":");
4525 if (LanguageModes[i]->indentStyle != DEFAULT_INDENT)
4526 BufInsert(outBuf, outBuf->length,
4527 AutoIndentTypes[LanguageModes[i]->indentStyle]);
4528 BufInsert(outBuf, outBuf->length, ":");
4529 if (LanguageModes[i]->wrapStyle != DEFAULT_WRAP)
4530 BufInsert(outBuf, outBuf->length,
4531 AutoWrapTypes[LanguageModes[i]->wrapStyle]);
4532 BufInsert(outBuf, outBuf->length, ":");
4533 if (LanguageModes[i]->tabDist != DEFAULT_TAB_DIST) {
4534 sprintf(numBuf, "%d", LanguageModes[i]->tabDist);
4535 BufInsert(outBuf, outBuf->length, numBuf);
4537 BufInsert(outBuf, outBuf->length, ":");
4538 if (LanguageModes[i]->emTabDist != DEFAULT_EM_TAB_DIST) {
4539 sprintf(numBuf, "%d", LanguageModes[i]->emTabDist);
4540 BufInsert(outBuf, outBuf->length, numBuf);
4542 BufInsert(outBuf, outBuf->length, ":");
4543 if (LanguageModes[i]->delimiters != NULL) {
4544 BufInsert(outBuf, outBuf->length,
4545 str=MakeQuotedString(LanguageModes[i]->delimiters));
4546 XtFree(str);
4548 BufInsert(outBuf, outBuf->length, ":");
4549 if (LanguageModes[i]->defTipsFile != NULL) {
4550 BufInsert(outBuf, outBuf->length,
4551 str=MakeQuotedString(LanguageModes[i]->defTipsFile));
4552 XtFree(str);
4555 BufInsert(outBuf, outBuf->length, "\n");
4558 /* Get the output, and lop off the trailing newline */
4559 outStr = BufGetRange(outBuf, 0, outBuf->length - 1);
4560 BufFree(outBuf);
4561 escapedStr = EscapeSensitiveChars(outStr);
4562 XtFree(outStr);
4563 return escapedStr;
4566 static char *createExtString(char **extensions, int nExtensions)
4568 int e, length = 1;
4569 char *outStr, *outPtr;
4571 for (e=0; e<nExtensions; e++)
4572 length += strlen(extensions[e]) + 1;
4573 outStr = outPtr = XtMalloc(length);
4574 for (e=0; e<nExtensions; e++) {
4575 strcpy(outPtr, extensions[e]);
4576 outPtr += strlen(extensions[e]);
4577 *outPtr++ = ' ';
4579 if (nExtensions == 0)
4580 *outPtr = '\0';
4581 else
4582 *(outPtr-1) = '\0';
4583 return outStr;
4586 static char **readExtensionList(char **inPtr, int *nExtensions)
4588 char *extensionList[MAX_FILE_EXTENSIONS];
4589 char **retList, *strStart;
4590 int i, len;
4592 /* skip over blank space */
4593 *inPtr += strspn(*inPtr, " \t");
4595 for (i=0; i<MAX_FILE_EXTENSIONS && **inPtr!=':' && **inPtr!='\0'; i++) {
4596 *inPtr += strspn(*inPtr, " \t");
4597 strStart = *inPtr;
4598 while (**inPtr!=' ' && **inPtr!='\t' && **inPtr!=':' && **inPtr!='\0')
4599 (*inPtr)++;
4600 len = *inPtr - strStart;
4601 extensionList[i] = XtMalloc(len + 1);
4602 strncpy(extensionList[i], strStart, len);
4603 extensionList[i][len] = '\0';
4605 *nExtensions = i;
4606 if (i == 0)
4607 return NULL;
4608 retList = (char **)XtMalloc(sizeof(char *) * i);
4609 memcpy(retList, extensionList, sizeof(char *) * i);
4610 return retList;
4613 int ReadNumericField(char **inPtr, int *value)
4615 int charsRead;
4617 /* skip over blank space */
4618 *inPtr += strspn(*inPtr, " \t");
4620 if (sscanf(*inPtr, "%d%n", value, &charsRead) != 1)
4621 return False;
4622 *inPtr += charsRead;
4623 return True;
4627 ** Parse a symbolic field, skipping initial and trailing whitespace,
4628 ** stops on first invalid character or end of string. Valid characters
4629 ** are letters, numbers, _, -, +, $, #, and internal whitespace. Internal
4630 ** whitespace is compressed to single space characters.
4632 char *ReadSymbolicField(char **inPtr)
4634 char *outStr, *outPtr, *strStart, *strPtr;
4635 int len;
4637 /* skip over initial blank space */
4638 *inPtr += strspn(*inPtr, " \t");
4640 /* Find the first invalid character or end of string to know how
4641 much memory to allocate for the returned string */
4642 strStart = *inPtr;
4643 while (isalnum((unsigned char)**inPtr) || **inPtr=='_' || **inPtr=='-' ||
4644 **inPtr=='+' || **inPtr=='$' || **inPtr=='#' || **inPtr==' ' ||
4645 **inPtr=='\t')
4646 (*inPtr)++;
4647 len = *inPtr - strStart;
4648 if (len == 0)
4649 return NULL;
4650 outStr = outPtr = XtMalloc(len + 1);
4652 /* Copy the string, compressing internal whitespace to a single space */
4653 strPtr = strStart;
4654 while (strPtr - strStart < len) {
4655 if (*strPtr == ' ' || *strPtr == '\t') {
4656 strPtr += strspn(strPtr, " \t");
4657 *outPtr++ = ' ';
4658 } else
4659 *outPtr++ = *strPtr++;
4662 /* If there's space on the end, take it back off */
4663 if (outPtr > outStr && *(outPtr-1) == ' ')
4664 outPtr--;
4665 if (outPtr == outStr) {
4666 XtFree(outStr);
4667 return NULL;
4669 *outPtr = '\0';
4670 return outStr;
4674 ** parse an individual quoted string. Anything between
4675 ** double quotes is acceptable, quote characters can be escaped by "".
4676 ** Returns allocated string "string" containing
4677 ** argument minus quotes. If not successful, returns False with
4678 ** (statically allocated) message in "errMsg".
4680 int ReadQuotedString(char **inPtr, char **errMsg, char **string)
4682 char *outPtr, *c;
4684 /* skip over blank space */
4685 *inPtr += strspn(*inPtr, " \t");
4687 /* look for initial quote */
4688 if (**inPtr != '\"') {
4689 *errMsg = "expecting quoted string";
4690 return False;
4692 (*inPtr)++;
4694 /* calculate max length and allocate returned string */
4695 for (c= *inPtr; ; c++) {
4696 if (*c == '\0') {
4697 *errMsg = "string not terminated";
4698 return False;
4699 } else if (*c == '\"') {
4700 if (*(c+1) == '\"')
4701 c++;
4702 else
4703 break;
4707 /* copy string up to end quote, transforming escaped quotes into quotes */
4708 *string = XtMalloc(c - *inPtr + 1);
4709 outPtr = *string;
4710 while (True) {
4711 if (**inPtr == '\"') {
4712 if (*(*inPtr+1) == '\"')
4713 (*inPtr)++;
4714 else
4715 break;
4717 *outPtr++ = *(*inPtr)++;
4719 *outPtr = '\0';
4721 /* skip end quote */
4722 (*inPtr)++;
4723 return True;
4727 ** Replace characters which the X resource file reader considers control
4728 ** characters, such that a string will read back as it appears in "string".
4729 ** (So far, newline characters are replaced with with \n\<newline> and
4730 ** backslashes with \\. This has not been tested exhaustively, and
4731 ** probably should be. It would certainly be more asthetic if other
4732 ** control characters were replaced as well).
4734 ** Returns an allocated string which must be freed by the caller with XtFree.
4736 char *EscapeSensitiveChars(const char *string)
4738 const char *c;
4739 char *outStr, *outPtr;
4740 int length = 0;
4742 /* calculate length and allocate returned string */
4743 for (c=string; *c!='\0'; c++) {
4744 if (*c == '\\')
4745 length++;
4746 else if (*c == '\n')
4747 length += 3;
4748 length++;
4750 outStr = XtMalloc(length + 1);
4751 outPtr = outStr;
4753 /* add backslashes */
4754 for (c=string; *c!='\0'; c++) {
4755 if (*c == '\\')
4756 *outPtr++ = '\\';
4757 else if (*c == '\n') {
4758 *outPtr++ = '\\';
4759 *outPtr++ = 'n';
4760 *outPtr++ = '\\';
4762 *outPtr++ = *c;
4764 *outPtr = '\0';
4765 return outStr;
4769 ** Adds double quotes around a string and escape existing double quote
4770 ** characters with two double quotes. Enables the string to be read back
4771 ** by ReadQuotedString.
4773 char *MakeQuotedString(const char *string)
4775 const char *c;
4776 char *outStr, *outPtr;
4777 int length = 0;
4779 /* calculate length and allocate returned string */
4780 for (c=string; *c!='\0'; c++) {
4781 if (*c == '\"')
4782 length++;
4783 length++;
4785 outStr = XtMalloc(length + 3);
4786 outPtr = outStr;
4788 /* add starting quote */
4789 *outPtr++ = '\"';
4791 /* copy string, escaping quotes with "" */
4792 for (c=string; *c!='\0'; c++) {
4793 if (*c == '\"')
4794 *outPtr++ = '\"';
4795 *outPtr++ = *c;
4798 /* add ending quote */
4799 *outPtr++ = '\"';
4801 /* terminate string and return */
4802 *outPtr = '\0';
4803 return outStr;
4807 ** Read a dialog text field containing a symbolic name (language mode names,
4808 ** style names, highlight pattern names, colors, and fonts), clean the
4809 ** entered text of leading and trailing whitespace, compress all
4810 ** internal whitespace to one space character, and check it over for
4811 ** colons, which interfere with the preferences file reader/writer syntax.
4812 ** Returns NULL on error, and puts up a dialog if silent is False. Returns
4813 ** an empty string if the text field is blank.
4815 char *ReadSymbolicFieldTextWidget(Widget textW, const char *fieldName, int silent)
4817 char *string, *stringPtr, *parsedString;
4819 /* read from the text widget */
4820 string = stringPtr = XmTextGetString(textW);
4822 /* parse it with the same routine used to read symbolic fields from
4823 files. If the string is not read entirely, there are invalid
4824 characters, so warn the user if not in silent mode. */
4825 parsedString = ReadSymbolicField(&stringPtr);
4826 if (*stringPtr != '\0')
4828 if (!silent)
4830 *(stringPtr + 1) = '\0';
4831 DialogF(DF_WARN, textW, 1, "Invalid Character",
4832 "Invalid character \"%s\" in %s", "Dismiss", stringPtr,
4833 fieldName);
4834 XmProcessTraversal(textW, XmTRAVERSE_CURRENT);
4836 XtFree(string);
4837 if (parsedString != NULL)
4838 XtFree(parsedString);
4839 return NULL;
4841 XtFree(string);
4842 if (parsedString == NULL) {
4843 parsedString = XtMalloc(1);
4844 *parsedString = '\0';
4846 return parsedString;
4850 ** Create a pulldown menu pane with the names of the current language modes.
4851 ** XmNuserData for each item contains the language mode name.
4853 Widget CreateLanguageModeMenu(Widget parent, XtCallbackProc cbProc, void *cbArg)
4855 Widget menu, btn;
4856 int i;
4857 XmString s1;
4859 menu = CreatePulldownMenu(parent, "languageModes", NULL, 0);
4860 for (i=0; i<NLanguageModes; i++) {
4861 btn = XtVaCreateManagedWidget("languageMode", xmPushButtonGadgetClass,
4862 menu,
4863 XmNlabelString, s1=XmStringCreateSimple(LanguageModes[i]->name),
4864 XmNmarginHeight, 0,
4865 XmNuserData, (void *)LanguageModes[i]->name, NULL);
4866 XmStringFree(s1);
4867 XtAddCallback(btn, XmNactivateCallback, cbProc, cbArg);
4869 return menu;
4873 ** Set the language mode menu in option menu "optMenu" to
4874 ** show a particular language mode
4876 void SetLangModeMenu(Widget optMenu, const char *modeName)
4878 int i;
4879 Cardinal nItems;
4880 WidgetList items;
4881 Widget pulldown, selectedItem;
4882 char *itemName;
4884 XtVaGetValues(optMenu, XmNsubMenuId, &pulldown, NULL);
4885 XtVaGetValues(pulldown, XmNchildren, &items, XmNnumChildren, &nItems, NULL);
4886 if (nItems == 0)
4887 return;
4888 selectedItem = items[0];
4889 for (i=0; i<(int)nItems; i++) {
4890 XtVaGetValues(items[i], XmNuserData, &itemName, NULL);
4891 if (!strcmp(itemName, modeName)) {
4892 selectedItem = items[i];
4893 break;
4896 XtVaSetValues(optMenu, XmNmenuHistory, selectedItem,NULL);
4900 ** Create a submenu for chosing language mode for the current window.
4902 Widget CreateLanguageModeSubMenu(WindowInfo *window, Widget parent, char *name,
4903 char *label, char mnemonic)
4905 XmString s1=XmStringCreateSimple(label);
4907 window->langModeCascade = XtVaCreateManagedWidget(name,
4908 xmCascadeButtonGadgetClass, parent, XmNlabelString,
4909 s1, XmNmnemonic, mnemonic,
4910 XmNsubMenuId, NULL, NULL);
4911 XmStringFree(s1);
4912 updateLanguageModeSubmenu(window);
4913 return window->langModeCascade;
4917 ** Re-build the language mode sub-menu using the current data stored
4918 ** in the master list: LanguageModes.
4920 static void updateLanguageModeSubmenu(WindowInfo *window)
4922 int i;
4923 XmString s1;
4924 Widget menu, btn;
4925 Arg args[1] = {{XmNradioBehavior, (XtArgVal)True}};
4927 /* Destroy and re-create the menu pane */
4928 XtVaGetValues(window->langModeCascade, XmNsubMenuId, &menu, NULL);
4929 if (menu != NULL)
4930 XtDestroyWidget(menu);
4931 menu = CreatePulldownMenu(XtParent(window->langModeCascade),
4932 "languageModes", args, 1);
4933 btn = XtVaCreateManagedWidget("languageMode",
4934 xmToggleButtonGadgetClass, menu,
4935 XmNlabelString, s1=XmStringCreateSimple("Plain"),
4936 XmNuserData, (void *)PLAIN_LANGUAGE_MODE,
4937 XmNset, window->languageMode==PLAIN_LANGUAGE_MODE, NULL);
4938 XmStringFree(s1);
4939 XtAddCallback(btn, XmNvalueChangedCallback, setLangModeCB, window);
4940 for (i=0; i<NLanguageModes; i++) {
4941 btn = XtVaCreateManagedWidget("languageMode",
4942 xmToggleButtonGadgetClass, menu,
4943 XmNlabelString, s1=XmStringCreateSimple(LanguageModes[i]->name),
4944 XmNmarginHeight, 0,
4945 XmNuserData, (void *)i,
4946 XmNset, window->languageMode==i, NULL);
4947 XmStringFree(s1);
4948 XtAddCallback(btn, XmNvalueChangedCallback, setLangModeCB, window);
4950 XtVaSetValues(window->langModeCascade, XmNsubMenuId, menu, NULL);
4953 static void setLangModeCB(Widget w, XtPointer clientData, XtPointer callData)
4955 WindowInfo *window = WidgetToWindow(MENU_WIDGET(w));
4956 char *params[1];
4957 void *mode;
4959 if (!XmToggleButtonGetState(w))
4960 return;
4962 /* get name of language mode stored in userData field of menu item */
4963 XtVaGetValues(w, XmNuserData, &mode, NULL);
4965 /* If the mode didn't change, do nothing */
4966 if (window->languageMode == (int)mode)
4967 return;
4969 /* redo syntax highlighting word delimiters, etc. */
4971 reapplyLanguageMode(window, (int)mode, False);
4973 params[0] = (((int)mode) == PLAIN_LANGUAGE_MODE) ? "" : LanguageModes[(int)mode]->name;
4974 XtCallActionProc(window->textArea, "set_language_mode", NULL, params, 1);
4978 ** Skip a delimiter and it's surrounding whitespace
4980 int SkipDelimiter(char **inPtr, char **errMsg)
4982 *inPtr += strspn(*inPtr, " \t");
4983 if (**inPtr != ':') {
4984 *errMsg = "syntax error";
4985 return False;
4987 (*inPtr)++;
4988 *inPtr += strspn(*inPtr, " \t");
4989 return True;
4993 ** Skip an optional separator and its surrounding whitespace
4994 ** return true if delimiter found
4996 int SkipOptSeparator(char separator, char **inPtr)
4998 *inPtr += strspn(*inPtr, " \t");
4999 if (**inPtr != separator) {
5000 return False;
5002 (*inPtr)++;
5003 *inPtr += strspn(*inPtr, " \t");
5004 return True;
5008 ** Short-hand error processing for language mode parsing errors, frees
5009 ** lm (if non-null), prints a formatted message explaining where the
5010 ** error is, and returns False;
5012 static int modeError(languageModeRec *lm, const char *stringStart,
5013 const char *stoppedAt, const char *message)
5015 if (lm != NULL)
5016 freeLanguageModeRec(lm);
5017 return ParseError(NULL, stringStart, stoppedAt,
5018 "language mode specification", message);
5022 ** Report parsing errors in resource strings or macros, formatted nicely so
5023 ** the user can tell where things became botched. Errors can be sent either
5024 ** to stderr, or displayed in a dialog. For stderr, pass toDialog as NULL.
5025 ** For a dialog, pass the dialog parent in toDialog.
5027 int ParseError(Widget toDialog, const char *stringStart, const char *stoppedAt,
5028 const char *errorIn, const char *message)
5030 int len, nNonWhite = 0;
5031 const char *c;
5032 char *errorLine;
5034 for (c=stoppedAt; c>=stringStart; c--) {
5035 if (c == stringStart)
5036 break;
5037 else if (*c == '\n' && nNonWhite >= 5)
5038 break;
5039 else if (*c != ' ' && *c != '\t')
5040 nNonWhite++;
5042 len = stoppedAt - c + (*stoppedAt == '\0' ? 0 : 1);
5043 errorLine = XtMalloc(len+4);
5044 strncpy(errorLine, c, len);
5045 errorLine[len++] = '<';
5046 errorLine[len++] = '=';
5047 errorLine[len++] = '=';
5048 errorLine[len] = '\0';
5049 if (toDialog == NULL)
5051 fprintf(stderr, "NEdit: %s in %s:\n%s\n", message, errorIn, errorLine);
5052 } else
5054 DialogF(DF_WARN, toDialog, 1, "Parse Error", "%s in %s:\n%s", "Dismiss",
5055 message, errorIn, errorLine);
5057 XtFree(errorLine);
5058 return False;
5062 ** Compare two strings which may be NULL
5064 int AllocatedStringsDiffer(const char *s1, const char *s2)
5066 if (s1 == NULL && s2 == NULL)
5067 return False;
5068 if (s1 == NULL || s2 == NULL)
5069 return True;
5070 return strcmp(s1, s2);
5073 static void updatePatternsTo5dot1(void)
5075 const char *htmlDefaultExpr = "^[ \t]*HTML[ \t]*:[ \t]*Default[ \t]*$";
5076 const char *vhdlAnchorExpr = "^[ \t]*VHDL:";
5078 /* Add new patterns if there aren't already existing patterns with
5079 the same name. If possible, insert before VHDL in language mode
5080 list. If not, just add to end */
5081 if (!regexFind(TempStringPrefs.highlight, "^[ \t]*PostScript:"))
5082 spliceString(&TempStringPrefs.highlight, "PostScript:Default",
5083 vhdlAnchorExpr);
5084 if (!regexFind(TempStringPrefs.language, "^[ \t]*PostScript:"))
5085 spliceString(&TempStringPrefs.language,
5086 "PostScript:.ps .PS .eps .EPS .epsf .epsi::::::",
5087 vhdlAnchorExpr);
5088 if (!regexFind(TempStringPrefs.highlight, "^[ \t]*Lex:"))
5089 spliceString(&TempStringPrefs.highlight, "Lex:Default",
5090 vhdlAnchorExpr);
5091 if (!regexFind(TempStringPrefs.language, "^[ \t]*Lex:"))
5092 spliceString(&TempStringPrefs.language, "Lex:.lex::::::",
5093 vhdlAnchorExpr);
5094 if (!regexFind(TempStringPrefs.highlight, "^[ \t]*SQL:"))
5095 spliceString(&TempStringPrefs.highlight, "SQL:Default",
5096 vhdlAnchorExpr);
5097 if (!regexFind(TempStringPrefs.language, "^[ \t]*SQL:"))
5098 spliceString(&TempStringPrefs.language, "SQL:.sql::::::",
5099 vhdlAnchorExpr);
5100 if (!regexFind(TempStringPrefs.highlight, "^[ \t]*Matlab:"))
5101 spliceString(&TempStringPrefs.highlight, "Matlab:Default",
5102 vhdlAnchorExpr);
5103 if (!regexFind(TempStringPrefs.language, "^[ \t]*Matlab:"))
5104 spliceString(&TempStringPrefs.language, "Matlab:..m .oct .sci::::::",
5105 vhdlAnchorExpr);
5106 if (!regexFind(TempStringPrefs.smartIndent, "^[ \t]*Matlab:"))
5107 spliceString(&TempStringPrefs.smartIndent, "Matlab:Default", NULL);
5108 if (!regexFind(TempStringPrefs.styles, "^[ \t]*Label:"))
5109 spliceString(&TempStringPrefs.styles, "Label:red:Italic",
5110 "^[ \t]*Flag:");
5111 if (!regexFind(TempStringPrefs.styles, "^[ \t]*Storage Type1:"))
5112 spliceString(&TempStringPrefs.styles, "Storage Type1:saddle brown:Bold",
5113 "^[ \t]*String:");
5115 /* Replace html pattern with sgml html pattern, as long as there
5116 isn't an existing html pattern which will be overwritten */
5117 if (regexFind(TempStringPrefs.highlight, htmlDefaultExpr)) {
5118 regexReplace(&TempStringPrefs.highlight, htmlDefaultExpr,
5119 "SGML HTML:Default");
5120 if (!regexReplace(&TempStringPrefs.language, "^[ \t]*HTML:.*$",
5121 "SGML HTML:.sgml .sgm .html .htm:\"\\<(?ihtml)\\>\":::::\n")) {
5122 spliceString(&TempStringPrefs.language,
5123 "SGML HTML:.sgml .sgm .html .htm:\"\\<(?ihtml)\\>\":::::\n",
5124 vhdlAnchorExpr);
5129 static void updatePatternsTo5dot2(void)
5131 #ifdef VMS
5132 const char *cppLm5dot1 =
5133 "^[ \t]*C\\+\\+:\\.CC \\.HH \\.I::::::\"\\.,/\\\\`'!\\|@#%\\^&\\*\\(\\)-=\\+\\{\\}\\[\\]\"\":;\\<\\>\\?~\"";
5134 const char *perlLm5dot1 =
5135 "^[ \t]*Perl:\\.PL \\.PM \\.P5:\"\\^\\[ \\\\t\\]\\*#\\[ \\\\t\\]\\*!\\.\\*perl\":::::";
5136 const char *psLm5dot1 =
5137 "^[ \t]*PostScript:\\.ps \\.PS \\.eps \\.EPS \\.epsf \\.epsi:\"\\^%!\":::::\"/%\\(\\)\\{\\}\\[\\]\\<\\>\"";
5138 const char *tclLm5dot1 = "^[ \t]*Tcl:\\.TCL::::::";
5140 const char *cppLm5dot2 =
5141 "C++:.CC .HH .C .H .I .CXX .HXX .CPP::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\"";
5142 const char *perlLm5dot2 =
5143 "Perl:.PL .PM .P5:\"^[ \\t]*#[ \\t]*!.*perl\":Auto:None:::\".,/\\\\`'!$@#%^&*()-=+{}[]\"\":;<>?~|\"";
5144 const char *psLm5dot2 =
5145 "PostScript:.ps .PS .eps .EPS .epsf .epsi:\"^%!\":::::\"/%(){}[]<>\"";
5146 const char *tclLm5dot2 =
5147 "Tcl:.TCL::Smart:None:::";
5148 #else
5149 const char *cppLm5dot1 =
5150 "^[ \t]*C\\+\\+:\\.cc \\.hh \\.C \\.H \\.i \\.cxx \\.hxx::::::\"\\.,/\\\\`'!\\|@#%\\^&\\*\\(\\)-=\\+\\{\\}\\[\\]\"\":;\\<\\>\\?~\"";
5151 const char *perlLm5dot1 =
5152 "^[ \t]*Perl:\\.pl \\.pm \\.p5:\"\\^\\[ \\\\t\\]\\*#\\[ \\\\t\\]\\*!\\.\\*perl\":::::";
5153 const char *psLm5dot1 =
5154 "^[ \t]*PostScript:\\.ps \\.PS \\.eps \\.EPS \\.epsf \\.epsi:\"\\^%!\":::::\"/%\\(\\)\\{\\}\\[\\]\\<\\>\"";
5155 const char *shLm5dot1 =
5156 "^[ \t]*Sh Ksh Bash:\\.sh \\.bash \\.ksh \\.profile:\"\\^\\[ \\\\t\\]\\*#\\[ \\\\t\\]\\*!\\[ \\\\t\\]\\*/bin/\\(sh\\|ksh\\|bash\\)\":::::";
5157 const char *tclLm5dot1 = "^[ \t]*Tcl:\\.tcl::::::";
5159 const char *cppLm5dot2 =
5160 "C++:.cc .hh .C .H .i .cxx .hxx .cpp::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\"";
5161 const char *perlLm5dot2 =
5162 "Perl:.pl .pm .p5 .PL:\"^[ \\t]*#[ \\t]*!.*perl\":Auto:None:::\".,/\\\\`'!$@#%^&*()-=+{}[]\"\":;<>?~|\"";
5163 const char *psLm5dot2 =
5164 "PostScript:.ps .eps .epsf .epsi:\"^%!\":::::\"/%(){}[]<>\"";
5165 const char *shLm5dot2 =
5166 "Sh Ksh Bash:.sh .bash .ksh .profile .bashrc .bash_logout .bash_login .bash_profile:\"^[ \\t]*#[ \\t]*![ \\t]*/.*bin/(sh|ksh|bash)\":::::";
5167 const char *tclLm5dot2 =
5168 "Tcl:.tcl .tk .itcl .itk::Smart:None:::";
5169 #endif /* VMS */
5171 const char *cssLm5dot2 =
5172 "CSS:css::Auto:None:::\".,/\\`'!|@#%^&*()=+{}[]\"\":;<>?~\"";
5173 const char *reLm5dot2 =
5174 "Regex:.reg .regex:\"\\(\\?[:#=!iInN].+\\)\":None:Continuous:::";
5175 const char *xmlLm5dot2 =
5176 "XML:.xml .xsl .dtd:\"\\<(?i\\?xml|!doctype)\"::None:::\"<>/=\"\"'()+*?|\"";
5178 const char *cssHl5dot2 = "CSS:Default";
5179 const char *reHl5dot2 = "Regex:Default";
5180 const char *xmlHl5dot2 = "XML:Default";
5182 const char *ptrStyle = "Pointer:#660000:Bold";
5183 const char *reStyle = "Regex:#009944:Bold";
5184 const char *wrnStyle = "Warning:brown2:Italic";
5186 /* First upgrade modified language modes, only if the user hasn't
5187 altered the default 5.1 definitions. */
5188 if (regexFind(TempStringPrefs.language, cppLm5dot1))
5189 regexReplace(&TempStringPrefs.language, cppLm5dot1, cppLm5dot2);
5190 if (regexFind(TempStringPrefs.language, perlLm5dot1))
5191 regexReplace(&TempStringPrefs.language, perlLm5dot1, perlLm5dot2);
5192 if (regexFind(TempStringPrefs.language, psLm5dot1))
5193 regexReplace(&TempStringPrefs.language, psLm5dot1, psLm5dot2);
5194 #ifndef VMS
5195 if (regexFind(TempStringPrefs.language, shLm5dot1))
5196 regexReplace(&TempStringPrefs.language, shLm5dot1, shLm5dot2);
5197 #endif
5198 if (regexFind(TempStringPrefs.language, tclLm5dot1))
5199 regexReplace(&TempStringPrefs.language, tclLm5dot1, tclLm5dot2);
5201 /* Then append the new modes (trying to keep them in alphabetical order
5202 makes no sense, since 5.1 didn't use alphabetical order). */
5203 if (!regexFind(TempStringPrefs.language, "^[ \t]*CSS:"))
5204 spliceString(&TempStringPrefs.language, cssLm5dot2, NULL);
5205 if (!regexFind(TempStringPrefs.language, "^[ \t]*Regex:"))
5206 spliceString(&TempStringPrefs.language, reLm5dot2, NULL);
5207 if (!regexFind(TempStringPrefs.language, "^[ \t]*XML:"))
5208 spliceString(&TempStringPrefs.language, xmlLm5dot2, NULL);
5210 /* Enable default highlighting patterns for these modes, unless already
5211 present */
5212 if (!regexFind(TempStringPrefs.highlight, "^[ \t]*CSS:"))
5213 spliceString(&TempStringPrefs.highlight, cssHl5dot2, NULL);
5214 if (!regexFind(TempStringPrefs.highlight, "^[ \t]*Regex:"))
5215 spliceString(&TempStringPrefs.highlight, reHl5dot2, NULL);
5216 if (!regexFind(TempStringPrefs.highlight, "^[ \t]*XML:"))
5217 spliceString(&TempStringPrefs.highlight, xmlHl5dot2, NULL);
5219 /* Finally, append the new highlight styles */
5221 if (!regexFind(TempStringPrefs.styles, "^[ \t]*Warning:"))
5222 spliceString(&TempStringPrefs.styles, wrnStyle, NULL);
5223 if (!regexFind(TempStringPrefs.styles, "^[ \t]*Regex:"))
5224 spliceString(&TempStringPrefs.styles, reStyle, "^[ \t]*Warning:");
5225 if (!regexFind(TempStringPrefs.styles, "^[ \t]*Pointer:"))
5226 spliceString(&TempStringPrefs.styles, ptrStyle, "^[ \t]*Regex:");
5229 static void updatePatternsTo5dot3(void)
5231 /* This is a bogus function on non-VMS */
5232 #ifdef VMS
5233 const char *psLm5dot2 =
5234 "^[ \t]*PostScript:\\.ps \\.PS \\.eps \\.EPS \\.epsf \\.epsi:\"\\^%!\":::::\"/%\\(\\)\\{\\}\\[\\]\\<\\>\"";
5236 const char *psLm5dot3 =
5237 "PostScript:.ps .PS .eps .EPS .epsf .EPSF .epsi .EPSI:\"^%!\":::::\"/%(){}[]<>\"";
5239 /* Upgrade modified language modes, only if the user hasn't
5240 altered the default 5.2 definitions. */
5241 if (regexFind(TempStringPrefs.language, psLm5dot2))
5242 regexReplace(&TempStringPrefs.language, psLm5dot2, psLm5dot3);
5243 #endif
5246 static void updatePatternsTo5dot4(void)
5248 #ifdef VMS
5249 const char *pyLm5dot3 =
5250 "Python:\\.PY:\"\\^#!\\.\\*python\":Auto:None::::?\n";
5251 const char *xrLm5dot3 =
5252 "X Resources:\\.XRESOURCES \\.XDEFAULTS \\.NEDIT:\"\\^\\[!#\\]\\.\\*\\(\\[Aa\\]pp\\|\\[Xx\\]\\)\\.\\*\\[Dd\\]efaults\"::::::?\n";
5254 const char *pyLm5dot4 =
5255 "Python:.PY:\"^#!.*python\":Auto:None:::\"!\"\"#$%&'()*+,-./:;<=>?@[\\\\]^`{|}~\":\n";
5256 const char *xrLm5dot4 =
5257 "X Resources:.XRESOURCES .XDEFAULTS .NEDIT NEDIT.RC:\"^[!#].*([Aa]pp|[Xx]).*[Dd]efaults\"::::::\n";
5258 #else
5259 const char *pyLm5dot3 =
5260 "Python:\\.py:\"\\^#!\\.\\*python\":Auto:None::::?\n";
5261 const char *xrLm5dot3 =
5262 "X Resources:\\.Xresources \\.Xdefaults \\.nedit:\"\\^\\[!#\\]\\.\\*\\(\\[Aa\\]pp\\|\\[Xx\\]\\)\\.\\*\\[Dd\\]efaults\"::::::?\n";
5264 const char *pyLm5dot4 =
5265 "Python:.py:\"^#!.*python\":Auto:None:::\"!\"\"#$%&'()*+,-./:;<=>?@[\\\\]^`{|}~\":\n";
5266 const char *xrLm5dot4 =
5267 "X Resources:.Xresources .Xdefaults .nedit nedit.rc:\"^[!#].*([Aa]pp|[Xx]).*[Dd]efaults\"::::::\n";
5268 #endif
5270 /* Upgrade modified language modes, only if the user hasn't
5271 altered the default 5.3 definitions. */
5272 if (regexFind(TempStringPrefs.language, pyLm5dot3))
5273 regexReplace(&TempStringPrefs.language, pyLm5dot3, pyLm5dot4);
5274 if (regexFind(TempStringPrefs.language, xrLm5dot3))
5275 regexReplace(&TempStringPrefs.language, xrLm5dot3, xrLm5dot4);
5277 /* Add new styles */
5278 if (!regexFind(TempStringPrefs.styles, "^[ \t]*Identifier2:"))
5279 spliceString(&TempStringPrefs.styles, "Identifier2:SteelBlue:Plain",
5280 "^[ \t]*Subroutine:");
5284 * We migrate a color from the X resources to the prefs if:
5285 * 1. The prefs entry is equal to the default entry
5286 * 2. The X resource is not equal to the default entry
5288 static void migrateColor(XrmDatabase prefDB, XrmDatabase appDB,
5289 char *class, char *name, int color_index, char *default_val)
5291 char *type, *valueString;
5292 XrmValue rsrcValue;
5294 /* If this color has been customized in the color dialog then use
5295 that value */
5296 if ( strcmp(default_val, PrefData.colorNames[color_index]) )
5297 return;
5299 /* Retrieve the value of the resource from the DB */
5300 if (XrmGetResource(prefDB, name, class, &type, &rsrcValue)) {
5301 if (strcmp(type, XmRString)) {
5302 fprintf(stderr,"Internal Error: Unexpected resource type, %s\n",
5303 type);
5304 return;
5306 valueString = rsrcValue.addr;
5307 } else if (XrmGetResource(appDB, name, class, &type, &rsrcValue)) {
5308 if (strcmp(type, XmRString)) {
5309 fprintf(stderr,"Internal Error: Unexpected resource type, %s\n",
5310 type);
5311 return;
5313 valueString = rsrcValue.addr;
5314 } else
5315 /* No resources set */
5316 return;
5318 /* An X resource is set. If it's non-default, update the prefs. */
5319 if ( strcmp(valueString, default_val) ) {
5320 strncpy(PrefData.colorNames[color_index], valueString,
5321 MAX_COLOR_LEN);
5326 * In 5.4 we moved color preferences from X resources to a color dialog,
5327 * meaning they're in the normal prefs system. Users who have customized
5328 * their colors with X resources would probably prefer not to have to redo
5329 * the customization in the dialog, so we migrate them to the prefs for them.
5331 static void migrateColorResources(XrmDatabase prefDB, XrmDatabase appDB)
5333 migrateColor(prefDB, appDB, APP_CLASS ".Text.Foreground",
5334 APP_NAME ".text.foreground", TEXT_FG_COLOR,
5335 NEDIT_DEFAULT_FG);
5336 migrateColor(prefDB, appDB, APP_CLASS ".Text.Background",
5337 APP_NAME ".text.background", TEXT_BG_COLOR,
5338 NEDIT_DEFAULT_TEXT_BG);
5339 migrateColor(prefDB, appDB, APP_CLASS ".Text.SelectForeground",
5340 APP_NAME ".text.selectForeground", SELECT_FG_COLOR,
5341 NEDIT_DEFAULT_SEL_FG);
5342 migrateColor(prefDB, appDB, APP_CLASS ".Text.SelectBackground",
5343 APP_NAME ".text.selectBackground", SELECT_BG_COLOR,
5344 NEDIT_DEFAULT_SEL_BG);
5345 migrateColor(prefDB, appDB, APP_CLASS ".Text.HighlightForeground",
5346 APP_NAME ".text.highlightForeground", HILITE_FG_COLOR,
5347 NEDIT_DEFAULT_HI_FG);
5348 migrateColor(prefDB, appDB, APP_CLASS ".Text.HighlightBackground",
5349 APP_NAME ".text.highlightBackground", HILITE_BG_COLOR,
5350 NEDIT_DEFAULT_HI_BG);
5351 migrateColor(prefDB, appDB, APP_CLASS ".Text.LineNumForeground",
5352 APP_NAME ".text.lineNumForeground", LINENO_FG_COLOR,
5353 NEDIT_DEFAULT_LINENO_FG);
5354 migrateColor(prefDB, appDB, APP_CLASS ".Text.CursorForeground",
5355 APP_NAME ".text.cursorForeground", CURSOR_FG_COLOR,
5356 NEDIT_DEFAULT_CURSOR_FG);
5360 ** Inserts a string into intoString, reallocating it with XtMalloc. If
5361 ** regular expression atExpr is found, inserts the string before atExpr
5362 ** followed by a newline. If atExpr is not found, inserts insertString
5363 ** at the end, PRECEDED by a newline.
5365 static void spliceString(char **intoString, const char *insertString, const char *atExpr)
5367 int beginPos, endPos;
5368 int intoLen = strlen(*intoString);
5369 int insertLen = strlen(insertString);
5370 char *newString = XtMalloc(intoLen + insertLen + 2);
5372 if (atExpr != NULL && SearchString(*intoString, atExpr,
5373 SEARCH_FORWARD, SEARCH_REGEX, False, 0, &beginPos, &endPos,
5374 NULL, NULL, NULL)) {
5375 strncpy(newString, *intoString, beginPos);
5376 strncpy(&newString[beginPos], insertString, insertLen);
5377 newString[beginPos+insertLen] = '\n';
5378 strncpy(&newString[beginPos+insertLen+1],
5379 &((*intoString)[beginPos]), intoLen - beginPos);
5380 } else {
5381 strncpy(newString, *intoString, intoLen);
5382 newString[intoLen] = '\n';
5383 strncpy(&newString[intoLen+1], insertString, insertLen);
5385 newString[intoLen + insertLen + 1] = '\0';
5386 XtFree(*intoString);
5387 *intoString = newString;
5391 ** Simplified regular expression search routine which just returns true
5392 ** or false depending on whether inString matches expr
5394 static int regexFind(const char *inString, const char *expr)
5396 int beginPos, endPos;
5397 return SearchString(inString, expr, SEARCH_FORWARD, SEARCH_REGEX, False,
5398 0, &beginPos, &endPos, NULL, NULL, NULL);
5402 ** Simplified regular expression replacement routine which replaces the
5403 ** first occurence of expr in inString with replaceWith, reallocating
5404 ** inString with XtMalloc. If expr is not found, does nothing and
5405 ** returns false.
5407 static int regexReplace(char **inString, const char *expr, const char *replaceWith)
5409 int beginPos, endPos, newLen;
5410 char *newString;
5411 int replaceLen = strlen(replaceWith);
5412 int inLen = strlen(*inString);
5414 if (!SearchString(*inString, expr, SEARCH_FORWARD, SEARCH_REGEX, False,
5415 0, &beginPos, &endPos, NULL, NULL, NULL))
5416 return FALSE;
5417 newLen = inLen + replaceLen - (endPos-beginPos);
5418 newString = XtMalloc(newLen + 1);
5419 strncpy(newString, *inString, beginPos);
5420 strncpy(&newString[beginPos], replaceWith, replaceLen);
5421 strncpy(&newString[beginPos+replaceLen],
5422 &((*inString)[endPos]), inLen - endPos);
5423 newString[newLen] = '\0';
5424 XtFree(*inString);
5425 *inString = newString;
5426 return TRUE;
5430 #ifndef VMS
5432 ** Replace all '#' characters in shell commands by '##' to keep commands
5433 ** containing those working. '#' is a line number placeholder in 5.3 and
5434 ** had no special meaning before.
5436 static void updateShellCmdsTo5dot3(void)
5438 char *cOld, *cNew, *pCol, *pNL;
5439 int nHash, isCmd;
5440 char *newString;
5442 if(!TempStringPrefs.shellCmds)
5443 return;
5445 /* Count number of '#'. If there are '#' characters in the non-command
5446 ** part of the definition we count too much and later allocate too much
5447 ** memory for the new string, but this doesn't hurt.
5449 for(cOld=TempStringPrefs.shellCmds, nHash=0; *cOld; cOld++)
5450 if(*cOld == '#')
5451 nHash++;
5453 /* No '#' -> no conversion necessary. */
5454 if(!nHash)
5455 return;
5457 newString=XtMalloc(strlen(TempStringPrefs.shellCmds) + 1 + nHash);
5459 cOld = TempStringPrefs.shellCmds;
5460 cNew = newString;
5461 isCmd = 0;
5462 pCol = NULL;
5463 pNL = NULL;
5465 /* Copy all characters from TempStringPrefs.shellCmds into newString
5466 ** and duplicate '#' in command parts. A simple check for really beeing
5467 ** inside a command part (starting with '\n', between the the two last
5468 ** '\n' a colon ':' must have been found) is preformed.
5470 while(*cOld) {
5471 /* actually every 2nd line is a command. We additionally
5472 ** check if there is a colon ':' in the previous line.
5474 if(*cOld=='\n') {
5475 if((pCol > pNL) && !isCmd)
5476 isCmd=1;
5477 else
5478 isCmd=0;
5479 pNL=cOld;
5482 if(!isCmd && *cOld ==':')
5483 pCol = cOld;
5485 /* Duplicate hashes if we're in a command part */
5486 if(isCmd && *cOld=='#')
5487 *cNew++ = '#';
5489 /* Copy every character */
5490 *cNew++ = *cOld++;
5494 /* Terminate new preferences string */
5495 *cNew = 0;
5497 /* free the old memory */
5498 XtFree(TempStringPrefs.shellCmds);
5500 /* exchange the string */
5501 TempStringPrefs.shellCmds = newString;
5505 #else
5507 static void updateShellCmdsTo5dot3(void) {
5508 /* No shell commands in VMS ! */
5509 return;
5512 #endif
5514 static void updateShellCmdsTo5dot4(void)
5516 #ifndef VMS /* No shell commands on VMS */
5518 #ifdef __FreeBSD__
5519 const char* wc5dot3 =
5520 "^(\\s*)set wc=`wc`; echo \\$wc\\[1\\] \"words,\" \\$wc\\[2\\] \"lines,\" \\$wc\\[3\\] \"characters\"\\n";
5521 const char* wc5dot4 =
5522 "wc | awk '{print $2 \" lines, \" $1 \" words, \" $3 \" characters\"}'\n";
5523 #else
5524 const char* wc5dot3 =
5525 "^(\\s*)set wc=`wc`; echo \\$wc\\[1\\] \"lines,\" \\$wc\\[2\\] \"words,\" \\$wc\\[3\\] \"characters\"\\n";
5526 const char* wc5dot4 =
5527 "wc | awk '{print $1 \" lines, \" $2 \" words, \" $3 \" characters\"}'\n";
5528 #endif /* __FreeBSD__ */
5530 if (regexFind(TempStringPrefs.shellCmds, wc5dot3))
5531 regexReplace(&TempStringPrefs.shellCmds, wc5dot3, wc5dot4);
5533 #endif /* VMS */
5535 return;
5538 static void updateMacroCmdsTo5dot5(void)
5540 const char* uc5dot4 =
5541 "^(\\s*)if \\(substring\\(sel, keepEnd - 1, keepEnd == \" \"\\)\\)\\n";
5542 const char* uc5dot5 =
5543 " if (substring(sel, keepEnd - 1, keepEnd) == \" \")\n";
5544 if (regexFind(TempStringPrefs.macroCmds, uc5dot4))
5545 regexReplace(&TempStringPrefs.macroCmds, uc5dot4, uc5dot5);
5547 return;
5550 #ifdef SGI_CUSTOM
5552 ** Present the user a dialog for specifying whether or not a short
5553 ** menu mode preference should be applied toward the default setting.
5554 ** Return False (function value) if operation was canceled, return True
5555 ** in setDefault if requested to reset the default value.
5557 static int shortPrefToDefault(Widget parent, const char *settingName, int *setDefault)
5559 char msg[100] = "";
5561 if (!GetPrefShortMenus()) {
5562 *setDefault = False;
5563 return True;
5566 sprintf(msg, "%s\nSave as default for future windows as well?", settingName);
5567 switch (DialogF (DF_QUES, parent, 3, "Save Default", msg, "Yes", "No",
5568 "Cancel"))
5570 case 1: /* yes */
5571 *setDefault = True;
5572 return True;
5573 case 2: /* no */
5574 *setDefault = False;
5575 return True;
5576 case 3: /* cancel */
5577 return False;
5579 return False; /* not reached */
5581 #endif
5583 /* Unload the default calltips file for this window unless somebody else
5584 is using it */
5585 void UnloadLanguageModeTipsFile(WindowInfo *window) {
5586 int mode;
5587 WindowInfo *wi;
5589 mode = window->languageMode;
5590 if (mode != PLAIN_LANGUAGE_MODE && LanguageModes[mode]->defTipsFile) {
5591 for (wi = WindowList; wi; wi = wi->next)
5592 if (wi->languageMode == mode && wi != window)
5593 break;
5594 if (!wi) /* If we got to end of WindowList... */
5595 DeleteTagsFile( LanguageModes[mode]->defTipsFile, TIP );
5598 /* Make sure we didn't accidentally delete a default calltips file that
5599 also belongs to another language mode */
5600 for (wi = WindowList; wi; wi = wi->next) {
5601 if (wi == window)
5602 continue;
5603 mode = wi->languageMode;
5604 if (mode != PLAIN_LANGUAGE_MODE && LanguageModes[mode]->defTipsFile)
5605 if (AddTagsFile( LanguageModes[mode]->defTipsFile, TIP ) == FALSE)
5606 fprintf( stderr, "Error loading default calltips file:\n"
5607 " \"%s\"\n", LanguageModes[mode]->defTipsFile );
5611 /******************************************************************************
5612 * The Color selection dialog
5613 ******************************************************************************/
5616 There are 8 colors: And 8 indices:
5617 textFg TEXT_FG_COLOR
5618 textBg TEXT_BG_COLOR
5619 selectFg SELECT_FG_COLOR
5620 selectBg SELECT_BG_COLOR
5621 hiliteFg HILITE_FG_COLOR
5622 hiliteBg HILITE_BG_COLOR
5623 lineNoFg LINENO_FG_COLOR
5624 cursorFg CURSOR_FG_COLOR
5627 #define MARGIN_SPACING 10
5630 * Callbacks for field modifications
5632 static void textFgModifiedCB(Widget w, XtPointer clientData,
5633 XtPointer callData)
5635 colorDialog *cd = (colorDialog *)clientData;
5636 showColorStatus(cd, cd->textFgW, cd->textFgErrW);
5639 static void textBgModifiedCB(Widget w, XtPointer clientData,
5640 XtPointer callData)
5642 colorDialog *cd = (colorDialog *)clientData;
5643 showColorStatus(cd, cd->textBgW, cd->textBgErrW);
5646 static void selectFgModifiedCB(Widget w, XtPointer clientData,
5647 XtPointer callData)
5649 colorDialog *cd = (colorDialog *)clientData;
5650 showColorStatus(cd, cd->selectFgW, cd->selectFgErrW);
5653 static void selectBgModifiedCB(Widget w, XtPointer clientData,
5654 XtPointer callData)
5656 colorDialog *cd = (colorDialog *)clientData;
5657 showColorStatus(cd, cd->selectBgW, cd->selectBgErrW);
5660 static void hiliteFgModifiedCB(Widget w, XtPointer clientData,
5661 XtPointer callData)
5663 colorDialog *cd = (colorDialog *)clientData;
5664 showColorStatus(cd, cd->hiliteFgW, cd->hiliteFgErrW);
5667 static void hiliteBgModifiedCB(Widget w, XtPointer clientData,
5668 XtPointer callData)
5670 colorDialog *cd = (colorDialog *)clientData;
5671 showColorStatus(cd, cd->hiliteBgW, cd->hiliteBgErrW);
5674 static void lineNoFgModifiedCB(Widget w, XtPointer clientData,
5675 XtPointer callData)
5677 colorDialog *cd = (colorDialog *)clientData;
5678 showColorStatus(cd, cd->lineNoFgW, cd->lineNoFgErrW);
5681 static void cursorFgModifiedCB(Widget w, XtPointer clientData,
5682 XtPointer callData)
5684 colorDialog *cd = (colorDialog *)clientData;
5685 showColorStatus(cd, cd->cursorFgW, cd->cursorFgErrW);
5690 * Helper functions for validating colors
5692 static int verifyAllColors(colorDialog *cd) {
5693 /* Maybe just check for empty strings in error widgets instead? */
5694 return (checkColorStatus(cd, cd->textFgW) &&
5695 checkColorStatus(cd, cd->textBgW) &&
5696 checkColorStatus(cd, cd->selectFgW) &&
5697 checkColorStatus(cd, cd->selectBgW) &&
5698 checkColorStatus(cd, cd->hiliteFgW) &&
5699 checkColorStatus(cd, cd->hiliteBgW) &&
5700 checkColorStatus(cd, cd->lineNoFgW) &&
5701 checkColorStatus(cd, cd->cursorFgW) );
5704 /* Returns True if the color is valid, False if it's not */
5705 static Boolean checkColorStatus(colorDialog *cd, Widget colorFieldW)
5707 Colormap cMap;
5708 XColor colorDef;
5709 Status status;
5710 Display *display = XtDisplay(cd->shell);
5711 char *text = XmTextGetString(colorFieldW);
5712 XtVaGetValues(cd->shell, XtNcolormap, &cMap, NULL);
5713 status = XParseColor(display, cMap, text, &colorDef);
5714 XtFree(text);
5715 return (status != 0);
5718 /* Show or hide errorLabelW depending on whether or not colorFieldW
5719 contains a valid color name. */
5720 static void showColorStatus(colorDialog *cd, Widget colorFieldW,
5721 Widget errorLabelW)
5723 /* Should set the OK/Apply button sensitivity here, instead
5724 of leaving is sensitive and then complaining if an error. */
5725 XtSetMappedWhenManaged( errorLabelW, !checkColorStatus(cd, colorFieldW) );
5728 /* Update the colors in the window or in the preferences */
5729 static void updateColors(colorDialog *cd)
5731 WindowInfo *window;
5733 char *textFg = XmTextGetString(cd->textFgW),
5734 *textBg = XmTextGetString(cd->textBgW),
5735 *selectFg = XmTextGetString(cd->selectFgW),
5736 *selectBg = XmTextGetString(cd->selectBgW),
5737 *hiliteFg = XmTextGetString(cd->hiliteFgW),
5738 *hiliteBg = XmTextGetString(cd->hiliteBgW),
5739 *lineNoFg = XmTextGetString(cd->lineNoFgW),
5740 *cursorFg = XmTextGetString(cd->cursorFgW);
5742 for (window = WindowList; window != NULL; window = window->next)
5744 SetColors(window, textFg, textBg, selectFg, selectBg, hiliteFg,
5745 hiliteBg, lineNoFg, cursorFg);
5748 SetPrefColorName(TEXT_FG_COLOR , textFg );
5749 SetPrefColorName(TEXT_BG_COLOR , textBg );
5750 SetPrefColorName(SELECT_FG_COLOR, selectFg);
5751 SetPrefColorName(SELECT_BG_COLOR, selectBg);
5752 SetPrefColorName(HILITE_FG_COLOR, hiliteFg);
5753 SetPrefColorName(HILITE_BG_COLOR, hiliteBg);
5754 SetPrefColorName(LINENO_FG_COLOR, lineNoFg);
5755 SetPrefColorName(CURSOR_FG_COLOR, cursorFg);
5757 XtFree(textFg);
5758 XtFree(textBg);
5759 XtFree(selectFg);
5760 XtFree(selectBg);
5761 XtFree(hiliteFg);
5762 XtFree(hiliteBg);
5763 XtFree(lineNoFg);
5764 XtFree(cursorFg);
5769 * Dialog button callbacks
5772 static void colorDestroyCB(Widget w, XtPointer clientData, XtPointer callData)
5774 colorDialog *cd = (colorDialog *)clientData;
5776 cd->window->colorDialog = NULL;
5777 XtFree((char *)cd);
5780 static void colorOkCB(Widget w, XtPointer clientData, XtPointer callData)
5782 colorDialog *cd = (colorDialog *)clientData;
5784 if(!verifyAllColors(cd))
5786 DialogF(DF_ERR, w, 1, "Invalid Colors",
5787 "All colors must be valid to proceed.", "Dismiss");
5788 return;
5790 updateColors(cd);
5792 /* pop down and destroy the dialog */
5793 XtDestroyWidget(cd->shell);
5796 static void colorApplyCB(Widget w, XtPointer clientData, XtPointer callData)
5798 colorDialog *cd = (colorDialog *)clientData;
5800 if(!verifyAllColors(cd))
5802 DialogF(DF_ERR, w, 1, "Invalid Colors",
5803 "All colors must be valid to be applied.", "Dismiss");
5804 return;
5806 updateColors(cd);
5809 static void colorDismissCB(Widget w, XtPointer clientData, XtPointer callData)
5811 colorDialog *cd = (colorDialog *)clientData;
5813 /* pop down and destroy the dialog */
5814 XtDestroyWidget(cd->shell);
5818 /* Add a label, error label, and text entry label with a validation
5819 callback */
5820 static Widget addColorGroup( Widget parent, const char *name, char mnemonic,
5821 char *label, Widget *fieldW, Widget *errW, Widget topWidget,
5822 int leftPos, int rightPos, XtCallbackProc modCallback,
5823 colorDialog *cd )
5825 Widget lblW;
5826 char *longerName;
5827 XmString s1;
5828 int nameLen = strlen(name);
5830 /* The label widget */
5831 longerName = XtMalloc(nameLen+7);
5832 strcpy(longerName, name);
5833 strcat(longerName, "Lbl");
5834 lblW = XtVaCreateManagedWidget(longerName,
5835 xmLabelGadgetClass, parent,
5836 XmNlabelString, s1=XmStringCreateSimple( label ),
5837 XmNmnemonic, mnemonic,
5838 XmNtopAttachment, XmATTACH_WIDGET,
5839 XmNtopWidget, topWidget,
5840 XmNtopOffset, MARGIN_SPACING,
5841 XmNleftAttachment, XmATTACH_POSITION,
5842 XmNleftPosition, leftPos, NULL);
5843 XmStringFree(s1);
5845 /* The error label widget */
5846 strcpy(&(longerName[nameLen]), "ErrLbl");
5847 *errW = XtVaCreateManagedWidget(longerName,
5848 xmLabelWidgetClass, parent,
5849 XmNlabelString, s1=XmStringCreateSimple("(Invalid!)"),
5850 XmNalignment, XmALIGNMENT_END,
5851 XmNtopAttachment, XmATTACH_WIDGET,
5852 XmNtopWidget, topWidget,
5853 XmNtopOffset, MARGIN_SPACING,
5854 XmNleftAttachment, XmATTACH_WIDGET,
5855 XmNleftWidget, lblW,
5856 XmNrightAttachment, XmATTACH_POSITION,
5857 XmNrightPosition, rightPos, NULL);
5858 XmStringFree(s1);
5860 /* The text field entry widget */
5861 *fieldW = XtVaCreateManagedWidget(name, xmTextWidgetClass,
5862 parent,
5863 XmNcolumns, MAX_COLOR_LEN-1,
5864 XmNmaxLength, MAX_COLOR_LEN-1,
5865 XmNleftAttachment, XmATTACH_POSITION,
5866 XmNleftPosition, leftPos,
5867 XmNrightAttachment, XmATTACH_POSITION,
5868 XmNrightPosition, rightPos,
5869 XmNtopAttachment, XmATTACH_WIDGET,
5870 XmNtopWidget, lblW, NULL);
5871 RemapDeleteKey(*fieldW);
5872 XtAddCallback(*fieldW, XmNvalueChangedCallback,
5873 modCallback, cd);
5874 XtVaSetValues(lblW, XmNuserData, *fieldW, NULL);
5876 XtFree(longerName);
5877 return *fieldW;
5882 * Code for the dialog itself
5884 void ChooseColors(WindowInfo *window)
5886 Widget form, tmpW, topW, infoLbl;
5887 Widget okBtn, applyBtn, dismissBtn;
5888 colorDialog *cd;
5889 XmString s1;
5890 int ac;
5891 Arg args[20];
5893 /* if the dialog is already displayed, just pop it to the top and return */
5894 if (window->colorDialog != NULL) {
5895 RaiseShellWindow(((colorDialog *)window->colorDialog)->shell);
5896 return;
5899 /* Create a structure for keeping track of dialog state */
5900 cd = XtNew(colorDialog);
5901 window->colorDialog = (void*)cd;
5903 /* Create a form widget in a dialog shell */
5904 ac = 0;
5905 XtSetArg(args[ac], XmNautoUnmanage, False); ac++;
5906 XtSetArg(args[ac], XmNresizePolicy, XmRESIZE_NONE); ac++;
5907 form = CreateFormDialog(window->shell, "choose colors", args, ac);
5908 XtVaSetValues(form, XmNshadowThickness, 0, NULL);
5909 cd->shell = XtParent(form);
5910 cd->window = window;
5911 XtVaSetValues(cd->shell, XmNtitle, "Colors", NULL);
5912 AddMotifCloseCallback(XtParent(form), colorDismissCB, cd);
5913 XtAddCallback(form, XmNdestroyCallback, colorDestroyCB, cd);
5915 /* Information label */
5916 infoLbl = XtVaCreateManagedWidget("infoLbl",
5917 xmLabelGadgetClass, form,
5918 XmNtopAttachment, XmATTACH_POSITION,
5919 XmNtopPosition, 2,
5920 XmNleftAttachment, XmATTACH_POSITION,
5921 XmNleftPosition, 1,
5922 XmNrightAttachment, XmATTACH_POSITION,
5923 XmNrightPosition, 99,
5924 XmNalignment, XmALIGNMENT_CENTER,
5925 XmNlabelString, s1 = XmStringCreateLtoR(
5926 "Colors can be entered as names (e.g. red, blue) or "
5927 "as RGB triples\nin the format #RRGGBB, where each digit "
5928 "is in the range 0-f.", XmFONTLIST_DEFAULT_TAG),
5929 NULL);
5930 XmStringFree(s1);
5932 topW = infoLbl;
5934 /* The left column (foregrounds) of color entry groups */
5935 tmpW = addColorGroup( form, "textFg", 'P', "Plain Text Foreground",
5936 &(cd->textFgW), &(cd->textFgErrW), topW, 1, 49,
5937 textFgModifiedCB, cd );
5938 tmpW = addColorGroup( form, "selectFg", 'S', "Selection Foreground",
5939 &(cd->selectFgW), &(cd->selectFgErrW), tmpW, 1, 49,
5940 selectFgModifiedCB, cd );
5941 tmpW = addColorGroup( form, "hiliteFg", 'M', "Matching (..) Foreground",
5942 &(cd->hiliteFgW), &(cd->hiliteFgErrW), tmpW, 1, 49,
5943 hiliteFgModifiedCB, cd );
5944 tmpW = addColorGroup( form, "lineNoFg", 'L', "Line Numbers",
5945 &(cd->lineNoFgW), &(cd->lineNoFgErrW), tmpW, 1, 49,
5946 lineNoFgModifiedCB, cd );
5948 /* The right column (backgrounds) */
5949 tmpW = addColorGroup( form, "textBg", 'T', "Text Area Background",
5950 &(cd->textBgW), &(cd->textBgErrW), topW, 51, 99,
5951 textBgModifiedCB, cd );
5952 tmpW = addColorGroup( form, "selectBg", 'B', "Selection Background",
5953 &(cd->selectBgW), &(cd->selectBgErrW), tmpW, 51, 99,
5954 selectBgModifiedCB, cd );
5955 tmpW = addColorGroup( form, "hiliteBg", 'h', "Matching (..) Background",
5956 &(cd->hiliteBgW), &(cd->hiliteBgErrW), tmpW, 51, 99,
5957 hiliteBgModifiedCB, cd );
5958 tmpW = addColorGroup( form, "cursorFg", 'C', "Cursor Color",
5959 &(cd->cursorFgW), &(cd->cursorFgErrW), tmpW, 51, 99,
5960 cursorFgModifiedCB, cd );
5962 tmpW = XtVaCreateManagedWidget("infoLbl",
5963 xmLabelGadgetClass, form,
5964 XmNtopAttachment, XmATTACH_WIDGET,
5965 XmNtopWidget, tmpW,
5966 XmNtopOffset, MARGIN_SPACING,
5967 XmNleftAttachment, XmATTACH_POSITION,
5968 XmNleftPosition, 1,
5969 XmNrightAttachment, XmATTACH_POSITION,
5970 XmNrightPosition, 99,
5971 XmNalignment, XmALIGNMENT_CENTER,
5972 XmNlabelString, s1 = XmStringCreateLtoR(
5973 "NOTE: Foreground colors only apply when syntax highlighting "
5974 "is DISABLED.\n", XmFONTLIST_DEFAULT_TAG),
5975 NULL);
5976 XmStringFree(s1);
5978 tmpW = XtVaCreateManagedWidget("sep",
5979 xmSeparatorGadgetClass, form,
5980 XmNtopAttachment, XmATTACH_WIDGET,
5981 XmNtopWidget, tmpW,
5982 XmNleftAttachment, XmATTACH_FORM,
5983 XmNrightAttachment, XmATTACH_FORM, NULL);
5985 /* The OK, Apply, and Cancel buttons */
5986 okBtn = XtVaCreateManagedWidget("ok", xmPushButtonWidgetClass, form,
5987 XmNlabelString, s1=XmStringCreateSimple("OK"),
5988 XmNtopAttachment, XmATTACH_WIDGET,
5989 XmNtopWidget, tmpW,
5990 XmNtopOffset, MARGIN_SPACING,
5991 XmNleftAttachment, XmATTACH_POSITION,
5992 XmNleftPosition, 10,
5993 XmNrightAttachment, XmATTACH_POSITION,
5994 XmNrightPosition, 30, NULL);
5995 XtAddCallback(okBtn, XmNactivateCallback, colorOkCB, cd);
5996 XmStringFree(s1);
5998 applyBtn = XtVaCreateManagedWidget(
5999 "apply", xmPushButtonWidgetClass, form,
6000 XmNlabelString, s1=XmStringCreateSimple("Apply"),
6001 XmNtopAttachment, XmATTACH_WIDGET,
6002 XmNtopWidget, tmpW,
6003 XmNtopOffset, MARGIN_SPACING,
6004 XmNmnemonic, 'A',
6005 XmNleftAttachment, XmATTACH_POSITION,
6006 XmNleftPosition, 40,
6007 XmNrightAttachment, XmATTACH_POSITION,
6008 XmNrightPosition, 60, NULL);
6009 XtAddCallback(applyBtn, XmNactivateCallback, colorApplyCB, cd);
6010 XmStringFree(s1);
6012 dismissBtn = XtVaCreateManagedWidget(
6013 "dismiss", xmPushButtonWidgetClass, form,
6014 XmNlabelString, s1=XmStringCreateSimple("Dismiss"),
6015 XmNtopAttachment, XmATTACH_WIDGET,
6016 XmNtopWidget, tmpW,
6017 XmNtopOffset, MARGIN_SPACING,
6018 XmNleftAttachment, XmATTACH_POSITION,
6019 XmNleftPosition, 70,
6020 XmNrightAttachment, XmATTACH_POSITION,
6021 XmNrightPosition, 90, NULL);
6022 XtAddCallback(dismissBtn, XmNactivateCallback, colorDismissCB, cd);
6023 XmStringFree(s1);
6025 /* Set initial default button */
6026 XtVaSetValues(form, XmNdefaultButton, okBtn, NULL);
6027 XtVaSetValues(form, XmNcancelButton, dismissBtn, NULL);
6029 /* Set initial values */
6030 XmTextSetString(cd->textFgW, GetPrefColorName(TEXT_FG_COLOR ));
6031 XmTextSetString(cd->textBgW, GetPrefColorName(TEXT_BG_COLOR ));
6032 XmTextSetString(cd->selectFgW, GetPrefColorName(SELECT_FG_COLOR));
6033 XmTextSetString(cd->selectBgW, GetPrefColorName(SELECT_BG_COLOR));
6034 XmTextSetString(cd->hiliteFgW, GetPrefColorName(HILITE_FG_COLOR));
6035 XmTextSetString(cd->hiliteBgW, GetPrefColorName(HILITE_BG_COLOR));
6036 XmTextSetString(cd->lineNoFgW, GetPrefColorName(LINENO_FG_COLOR));
6037 XmTextSetString(cd->cursorFgW, GetPrefColorName(CURSOR_FG_COLOR));
6039 /* Handle mnemonic selection of buttons and focus to dialog */
6040 AddDialogMnemonicHandler(form, FALSE);
6042 /* put up dialog */
6043 ManageDialogCenteredOnPointer(form);