Fix for SF bug #1122813: Tab-related crash on posting unload calltips file
[nedit.git] / source / preferences.c
blobd3deae0fb08d8951120083aa17a14eb366faf92a
1 static const char CVSID[] = "$Id: preferences.c,v 1.135 2005/02/15 01:10:15 n8gray 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. In addition, you may distribute version of this program linked to *
12 * Motif or Open Motif. See README for details. *
13 * *
14 * This software is distributed in the hope that it will be useful, but WITHOUT *
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
17 * for more details. *
18 * *
19 * You should have received a copy of the GNU General Public License along with *
20 * software; if not, write to the Free Software Foundation, Inc., 59 Temple *
21 * Place, Suite 330, Boston, MA 02111-1307 USA *
22 * *
23 * Nirvana Text Editor *
24 * April 20, 1993 *
25 * *
26 * Written by Mark Edel *
27 * *
28 *******************************************************************************/
30 #ifdef HAVE_CONFIG_H
31 #include "../config.h"
32 #endif
34 #include "preferences.h"
35 #include "textBuf.h"
36 #include "nedit.h"
37 #include "menu.h"
38 #include "text.h"
39 #include "search.h"
40 #include "window.h"
41 #include "userCmds.h"
42 #include "highlight.h"
43 #include "highlightData.h"
44 #include "help.h"
45 #include "regularExp.h"
46 #include "smartIndent.h"
47 #include "windowTitle.h"
48 #include "server.h"
49 #include "tags.h"
50 #include "../util/prefFile.h"
51 #include "../util/misc.h"
52 #include "../util/DialogF.h"
53 #include "../util/managedList.h"
54 #include "../util/fontsel.h"
55 #include "../util/fileUtils.h"
56 #include "../util/utils.h"
58 #include <stdlib.h>
59 #include <string.h>
60 #include <stdio.h>
61 #include <ctype.h>
62 #ifdef VMS
63 #include "../util/VMSparam.h"
64 #else
65 #ifndef __MVS__
66 #include <sys/param.h>
67 #endif
68 #include "../util/clearcase.h"
69 #endif /*VMS*/
71 #include <Xm/Xm.h>
72 #include <Xm/SelectioB.h>
73 #include <Xm/Form.h>
74 #include <Xm/List.h>
75 #include <Xm/SeparatoG.h>
76 #include <Xm/LabelG.h>
77 #include <Xm/Label.h>
78 #include <Xm/PushBG.h>
79 #include <Xm/PushB.h>
80 #include <Xm/ToggleBG.h>
81 #include <Xm/ToggleB.h>
82 #include <Xm/RowColumn.h>
83 #include <Xm/CascadeBG.h>
84 #include <Xm/Frame.h>
85 #include <Xm/Text.h>
87 #ifdef HAVE_DEBUG_H
88 #include "../debug.h"
89 #endif
91 #if XmVersion >= 1002
92 #define MENU_WIDGET(w) (XmGetPostedFromWidget(XtParent(w)))
93 #else
94 #define MENU_WIDGET(w) (w)
95 #endif
97 #define PREF_FILE_VERSION "5.5"
99 /* New styles added in 5.2 for auto-upgrade */
100 #define ADD_5_2_STYLES " Pointer:#660000:Bold\nRegex:#009944:Bold\nWarning:brown2:Italic"
102 /* maximum number of word delimiters allowed (256 allows whole character set) */
103 #define MAX_WORD_DELIMITERS 256
105 /* maximum number of file extensions allowed in a language mode */
106 #define MAX_FILE_EXTENSIONS 20
108 /* Return values for checkFontStatus */
109 enum fontStatus {GOOD_FONT, BAD_PRIMARY, BAD_FONT, BAD_SIZE, BAD_SPACING};
111 /* enumerated type preference strings
112 ** The order of the elements in this array must be exactly the same
113 ** as the order of the corresponding integers of the enum SearchType
114 ** defined in search.h (!!)
116 static char *SearchMethodStrings[] = {
117 "Literal", "CaseSense", "RegExp",
118 "LiteralWord", "CaseSenseWord", "RegExpNoCase",
119 NULL
122 #ifdef REPLACE_SCOPE
123 /* enumerated default scope for replace dialog if a selection exists when
124 ** the dialog is popped up.
126 static char *ReplaceDefScopeStrings[] = {
127 "Window", "Selection", "Smart", NULL
129 #endif
131 #define N_WRAP_STYLES 3
132 static char *AutoWrapTypes[N_WRAP_STYLES+3] = {"None", "Newline", "Continuous",
133 "True", "False", NULL};
134 #define N_INDENT_STYLES 3
135 static char *AutoIndentTypes[N_INDENT_STYLES+3] = {"None", "Auto",
136 "Smart", "True", "False", NULL};
137 #define N_VIRTKEY_OVERRIDE_MODES 3
138 static char *VirtKeyOverrideModes[N_VIRTKEY_OVERRIDE_MODES+1] = { "Never",
139 "Auto", "Always", NULL};
141 #define N_SHOW_MATCHING_STYLES 3
142 /* For backward compatibility, "False" and "True" are still accepted.
143 They are internally converted to "Off" and "Delimiter" respectively.
144 NOTE: N_SHOW_MATCHING_STYLES must correspond to the number of
145 _real_ matching styles, not counting False & True.
146 False and True should also be the last ones in the list. */
147 static char *ShowMatchingTypes[] = {"Off", "Delimiter", "Range",
148 "False", "True", NULL};
150 /* suplement wrap and indent styles w/ a value meaning "use default" for
151 the override fields in the language modes dialog */
152 #define DEFAULT_WRAP -1
153 #define DEFAULT_INDENT -1
154 #define DEFAULT_TAB_DIST -1
155 #define DEFAULT_EM_TAB_DIST -1
157 /* list of available language modes and language specific preferences */
158 static int NLanguageModes = 0;
159 typedef struct {
160 char *name;
161 int nExtensions;
162 char **extensions;
163 char *recognitionExpr;
164 char *defTipsFile;
165 char *delimiters;
166 int wrapStyle;
167 int indentStyle;
168 int tabDist;
169 int emTabDist;
170 } languageModeRec;
171 static languageModeRec *LanguageModes[MAX_LANGUAGE_MODES];
173 /* Language mode dialog information */
174 static struct {
175 Widget shell;
176 Widget nameW;
177 Widget extW;
178 Widget recogW;
179 Widget defTipsW;
180 Widget delimitW;
181 Widget managedListW;
182 Widget tabW;
183 Widget emTabW;
184 Widget defaultIndentW;
185 Widget noIndentW;
186 Widget autoIndentW;
187 Widget smartIndentW;
188 Widget defaultWrapW;
189 Widget noWrapW;
190 Widget newlineWrapW;
191 Widget contWrapW;
192 languageModeRec **languageModeList;
193 int nLanguageModes;
194 } LMDialog = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
195 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0};
197 /* Font dialog information */
198 typedef struct {
199 Widget shell;
200 Widget primaryW;
201 Widget fillW;
202 Widget italicW;
203 Widget italicErrW;
204 Widget boldW;
205 Widget boldErrW;
206 Widget boldItalicW;
207 Widget boldItalicErrW;
208 WindowInfo *window;
209 int forWindow;
210 } fontDialog;
212 /* Color dialog information */
213 typedef struct {
214 Widget shell;
215 Widget textFgW;
216 Widget textFgErrW;
217 Widget textBgW;
218 Widget textBgErrW;
219 Widget selectFgW;
220 Widget selectFgErrW;
221 Widget selectBgW;
222 Widget selectBgErrW;
223 Widget hiliteFgW;
224 Widget hiliteFgErrW;
225 Widget hiliteBgW;
226 Widget hiliteBgErrW;
227 Widget lineNoFgW;
228 Widget lineNoFgErrW;
229 Widget cursorFgW;
230 Widget cursorFgErrW;
231 WindowInfo *window;
232 } colorDialog;
234 /* Repository for simple preferences settings */
235 static struct prefData {
236 int openInTab; /* open files in new tabs */
237 int wrapStyle; /* what kind of wrapping to do */
238 int wrapMargin; /* 0=wrap at window width, other=wrap margin */
239 int autoIndent; /* style for auto-indent */
240 int autoSave; /* whether automatic backup feature is on */
241 int saveOldVersion; /* whether to preserve a copy of last version */
242 int searchDlogs; /* whether to show explanatory search dialogs */
243 int searchWrapBeep; /* 1=beep when search restarts at begin/end */
244 int keepSearchDlogs; /* whether to retain find and replace dialogs */
245 int searchWraps; /* whether to attempt search again if reach bof or eof */
246 int statsLine; /* whether to show the statistics line */
247 int iSearchLine; /* whether to show the incremental search line*/
248 int tabBar; /* whether to show the tab bar */
249 int tabBarHideOne; /* hide tab bar if only one document in window */
250 int globalTabNavigate; /* prev/next document across windows */
251 int toolTips; /* whether to show the tooltips */
252 int lineNums; /* whether to show line numbers */
253 int pathInWindowsMenu; /* whether to show path in windows menu */
254 int warnFileMods; /* warn user if files externally modified */
255 int warnRealFileMods; /* only warn if file contents modified */
256 int warnExit; /* whether to warn on exit */
257 int searchMethod; /* initial search method as a text string */
258 #ifdef REPLACE_SCOPE
259 int replaceDefScope; /* default replace scope if selection exists */
260 #endif
261 int textRows; /* initial window height in characters */
262 int textCols; /* initial window width in characters */
263 int tabDist; /* number of characters between tab stops */
264 int emTabDist; /* non-zero tab dist. if emulated tabs are on */
265 int insertTabs; /* whether to use tabs for padding */
266 int showMatchingStyle; /* how to flash matching parenthesis */
267 int matchSyntaxBased; /* use syntax info to match parenthesis */
268 int highlightSyntax; /* whether to highlight syntax by default */
269 int smartTags; /* look for tag in current window first */
270 int alwaysCheckRelativeTagsSpecs; /* for every new opened file of session */
271 int stickyCaseSenseBtn; /* whether Case Word Btn is sticky to Regex Btn */
272 int prefFileRead; /* detects whether a .nedit existed */
273 int backlightChars; /* whether to apply character "backlighting" */
274 char *backlightCharTypes; /* the backlighting color definitions */
275 #ifdef SGI_CUSTOM
276 int shortMenus; /* short menu mode */
277 #endif
278 char fontString[MAX_FONT_LEN]; /* names of fonts for text widget */
279 char boldFontString[MAX_FONT_LEN];
280 char italicFontString[MAX_FONT_LEN];
281 char boldItalicFontString[MAX_FONT_LEN];
282 XmFontList fontList; /* XmFontLists corresp. to above named fonts */
283 XFontStruct *boldFontStruct;
284 XFontStruct *italicFontStruct;
285 XFontStruct *boldItalicFontStruct;
286 int sortTabs; /* sort tabs alphabetically */
287 int repositionDialogs; /* w. to reposition dialogs under the pointer */
288 int autoScroll; /* w. to autoscroll near top/bottom of screen */
289 int autoScrollVPadding; /* how close to get before autoscrolling */
290 int sortOpenPrevMenu; /* whether to sort the "Open Previous" menu */
291 int appendLF; /* Whether to append LF at the end of each file */
292 int mapDelete; /* whether to map delete to backspace */
293 int stdOpenDialog; /* w. to retain redundant text field in Open */
294 char tagFile[MAXPATHLEN]; /* name of tags file to look for at startup */
295 int maxPrevOpenFiles; /* limit to size of Open Previous menu */
296 int typingHidesPointer; /* hide mouse pointer when typing */
297 char delimiters[MAX_WORD_DELIMITERS]; /* punctuation characters */
298 char shell[MAXPATHLEN]; /* shell to use for executing commands */
299 char geometry[MAX_GEOM_STRING_LEN]; /* per-application geometry string,
300 only for the clueless */
301 char serverName[MAXPATHLEN];/* server name for multiple servers per disp. */
302 char bgMenuBtn[MAX_ACCEL_LEN]; /* X event description for triggering
303 posting of background menu */
304 char fileVersion[6]; /* Version of nedit which wrote the .nedit
305 file we're reading */
306 int findReplaceUsesSelection; /* whether the find replace dialog is automatically
307 loaded with the primary selection */
308 int virtKeyOverride; /* Override Motif default virtual key bindings
309 never, if invalid, or always */
310 char titleFormat[MAX_TITLE_FORMAT_LEN];
311 char helpFontNames[NUM_HELP_FONTS][MAX_FONT_LEN];/* fonts for help system */
312 char helpLinkColor[MAX_COLOR_LEN]; /* Color for hyperlinks in the help system */
313 char colorNames[NUM_COLORS][MAX_COLOR_LEN];
314 char tooltipBgColor[MAX_COLOR_LEN];
315 int undoModifiesSelection;
316 int focusOnRaise;
317 } PrefData;
319 /* Temporary storage for preferences strings which are discarded after being
320 read */
321 static struct {
322 char *shellCmds;
323 char *macroCmds;
324 char *bgMenuCmds;
325 char *highlight;
326 char *language;
327 char *styles;
328 char *smartIndent;
329 char *smartIndentCommon;
330 } TempStringPrefs;
332 /* preference descriptions for SavePreferences and RestorePreferences. */
333 static PrefDescripRec PrefDescrip[] = {
334 {"fileVersion", "FileVersion" , PREF_STRING, "", PrefData.fileVersion,
335 (void *)sizeof(PrefData.fileVersion), True},
336 #ifndef VMS
337 #ifdef linux
338 {"shellCommands", "ShellCommands", PREF_ALLOC_STRING, "spell:Alt+B:s:EX:\n\
339 cat>spellTmp; xterm -e ispell -x spellTmp; cat spellTmp; rm spellTmp\n\
340 wc::w:ED:\nwc | awk '{print $1 \" lines, \" $2 \" words, \" $3 \" characters\"}'\n\
341 sort::o:EX:\nsort\nnumber lines::n:AW:\nnl -ba\nmake:Alt+Z:m:W:\nmake\n\
342 expand::p:EX:\nexpand\nunexpand::u:EX:\nunexpand\n",
343 &TempStringPrefs.shellCmds, NULL, True},
344 #elif __FreeBSD__
345 {"shellCommands", "ShellCommands", PREF_ALLOC_STRING, "spell:Alt+B:s:EX:\n\
346 cat>spellTmp; xterm -e ispell -x spellTmp; cat spellTmp; rm spellTmp\n\
347 wc::w:ED:\nwc | awk '{print $2 \" lines, \" $1 \" words, \" $3 \" characters\"}'\n\
348 sort::o:EX:\nsort\nnumber lines::n:AW:\npr -tn\nmake:Alt+Z:m:W:\nmake\n\
349 expand::p:EX:\nexpand\nunexpand::u:EX:\nunexpand\n",
350 &TempStringPrefs.shellCmds, NULL, True},
351 #else
352 {"shellCommands", "ShellCommands", PREF_ALLOC_STRING, "spell:Alt+B:s:ED:\n\
353 (cat;echo \"\") | spell\nwc::w:ED:\nwc | awk '{print $1 \" lines, \" $2 \" words, \" $3 \" characters\"}'\n\
354 \nsort::o:EX:\nsort\nnumber lines::n:AW:\nnl -ba\nmake:Alt+Z:m:W:\nmake\n\
355 expand::p:EX:\nexpand\nunexpand::u:EX:\nunexpand\n",
356 &TempStringPrefs.shellCmds, NULL, True},
357 #endif /* linux, __FreeBSD__ */
358 #endif /* VMS */
359 {"macroCommands", "MacroCommands", PREF_ALLOC_STRING,
360 "Complete Word:Alt+D::: {\n\
361 # Tuning parameters\n\
362 ScanDistance = 200\n\
364 # Search back to a word boundary to find the word to complete\n\
365 startScan = max(0, $cursor - ScanDistance)\n\
366 endScan = min($text_length, $cursor + ScanDistance)\n\
367 scanString = get_range(startScan, endScan)\n\
368 keyEnd = $cursor-startScan\n\
369 keyStart = search_string(scanString, \"<\", keyEnd, \"backward\", \"regex\")\n\
370 if (keyStart == -1)\n\
371 return\n\
372 keyString = \"<\" substring(scanString, keyStart, keyEnd)\n\
374 # search both forward and backward from the cursor position. Note that\n\
375 # using a regex search can lead to incorrect results if any of the special\n\
376 # regex characters is encountered, which is not considered a delimiter\n\
377 backwardSearchResult = search_string(scanString, keyString, keyStart-1, \\\n\
378 \"backward\", \"regex\")\n\
379 forwardSearchResult = search_string(scanString, keyString, keyEnd, \"regex\")\n\
380 if (backwardSearchResult == -1 && forwardSearchResult == -1) {\n\
381 beep()\n\
382 return\n\
383 }\n\
385 # if only one direction matched, use that, otherwise use the nearest\n\
386 if (backwardSearchResult == -1)\n\
387 matchStart = forwardSearchResult\n\
388 else if (forwardSearchResult == -1)\n\
389 matchStart = backwardSearchResult\n\
390 else {\n\
391 if (keyStart - backwardSearchResult <= forwardSearchResult - keyEnd)\n\
392 matchStart = backwardSearchResult\n\
393 else\n\
394 matchStart = forwardSearchResult\n\
395 }\n\
397 # find the complete word\n\
398 matchEnd = search_string(scanString, \">\", matchStart, \"regex\")\n\
399 completedWord = substring(scanString, matchStart, matchEnd)\n\
401 # replace it in the window\n\
402 replace_range(startScan + keyStart, $cursor, completedWord)\n\
403 }\n\
404 Fill Sel. w/Char:::R: {\n\
405 if ($selection_start == -1) {\n\
406 beep()\n\
407 return\n\
408 }\n\
410 # Ask the user what character to fill with\n\
411 fillChar = string_dialog(\"Fill selection with what character?\", \"OK\", \"Cancel\")\n\
412 if ($string_dialog_button == 2 || $string_dialog_button == 0)\n\
413 return\n\
415 # Count the number of lines in the selection\n\
416 nLines = 0\n\
417 for (i=$selection_start; i<$selection_end; i++)\n\
418 if (get_character(i) == \"\\n\")\n\
419 nLines++\n\
421 # Create the fill text\n\
422 rectangular = $selection_left != -1\n\
423 line = \"\"\n\
424 fillText = \"\"\n\
425 if (rectangular) {\n\
426 for (i=0; i<$selection_right-$selection_left; i++)\n\
427 line = line fillChar\n\
428 for (i=0; i<nLines; i++)\n\
429 fillText = fillText line \"\\n\"\n\
430 fillText = fillText line\n\
431 } else {\n\
432 if (nLines == 0) {\n\
433 for (i=$selection_start; i<$selection_end; i++)\n\
434 fillText = fillText fillChar\n\
435 } else {\n\
436 startIndent = 0\n\
437 for (i=$selection_start-1; i>=0 && get_character(i)!=\"\\n\"; i--)\n\
438 startIndent++\n\
439 for (i=0; i<$wrap_margin-startIndent; i++)\n\
440 fillText = fillText fillChar\n\
441 fillText = fillText \"\\n\"\n\
442 for (i=0; i<$wrap_margin; i++)\n\
443 line = line fillChar\n\
444 for (i=0; i<nLines-1; i++)\n\
445 fillText = fillText line \"\\n\"\n\
446 for (i=$selection_end-1; i>=$selection_start && get_character(i)!=\"\\n\"; \\\n\
447 i--)\n\
448 fillText = fillText fillChar\n\
449 }\n\
450 }\n\
452 # Replace the selection with the fill text\n\
453 replace_selection(fillText)\n\
454 }\n\
455 Quote Mail Reply:::: {\n\
456 if ($selection_start == -1)\n\
457 replace_all(\"^.*$\", \"\\\\> &\", \"regex\")\n\
458 else\n\
459 replace_in_selection(\"^.*$\", \"\\\\> &\", \"regex\")\n\
460 }\n\
461 Unquote Mail Reply:::: {\n\
462 if ($selection_start == -1)\n\
463 replace_all(\"(^\\\\> )(.*)$\", \"\\\\2\", \"regex\")\n\
464 else\n\
465 replace_in_selection(\"(^\\\\> )(.*)$\", \"\\\\2\", \"regex\")\n\
466 }\n\
467 Comments>/* Comment */@C@C++@Java@CSS@JavaScript@Lex:::R: {\n\
468 selStart = $selection_start\n\
469 selEnd = $selection_end\n\
470 replace_range(selStart, selEnd, \"/* \" get_selection() \" */\")\n\
471 select(selStart, selEnd + 6)\n\
472 }\n\
473 Comments>/* Uncomment */@C@C++@Java@CSS@JavaScript@Lex:::R: {\n\
474 sel = get_selection()\n\
475 selStart = $selection_start\n\
476 selEnd = $selection_end\n\
477 commentStart = search_string(sel, \"/*\", 0)\n\
478 if (substring(sel, commentStart + 2, commentStart + 3) == \" \")\n\
479 keepStart = commentStart + 3\n\
480 else\n\
481 keepStart = commentStart + 2\n\
482 keepEnd = search_string(sel, \"*/\", length(sel), \"backward\")\n\
483 commentEnd = keepEnd + 2\n\
484 if (substring(sel, keepEnd - 1, keepEnd) == \" \")\n\
485 keepEnd = keepEnd - 1\n\
486 replace_range(selStart + commentStart, selStart + commentEnd, \\\n\
487 substring(sel, keepStart, keepEnd))\n\
488 select(selStart, selEnd - (keepStart-commentStart) - \\\n\
489 (commentEnd - keepEnd))\n\
490 }\n\
491 Comments>// Comment@C@C++@Java@JavaScript:::R: {\n\
492 replace_in_selection(\"^.*$\", \"// &\", \"regex\")\n\
493 }\n\
494 Comments>// Uncomment@C@C++@Java@JavaScript:::R: {\n\
495 replace_in_selection(\"(^[ \\\\t]*// ?)(.*)$\", \"\\\\2\", \"regex\")\n\
496 }\n\
497 Comments># Comment@Perl@Sh Ksh Bash@NEdit Macro@Makefile@Awk@Csh@Python@Tcl:::R: {\n\
498 replace_in_selection(\"^.*$\", \"#&\", \"regex\")\n\
499 }\n\
500 Comments># Uncomment@Perl@Sh Ksh Bash@NEdit Macro@Makefile@Awk@Csh@Python@Tcl:::R: {\n\
501 replace_in_selection(\"(^[ \\\\t]*#)(.*)$\", \"\\\\2\", \"regex\")\n\
502 }\n\
503 Comments>-- Comment@SQL:::R: {\n\
504 replace_in_selection(\"^.*$\", \"--&\", \"regex\")\n\
505 }\n\
506 Comments>-- Uncomment@SQL:::R: {\n\
507 replace_in_selection(\"(^[ \\\\t]*--)(.*)$\", \"\\\\2\", \"regex\")\n\
508 }\n\
509 Comments>! Comment@X Resources:::R: {\n\
510 replace_in_selection(\"^.*$\", \"!&\", \"regex\")\n\
511 }\n\
512 Comments>! Uncomment@X Resources:::R: {\n\
513 replace_in_selection(\"(^[ \\\\t]*!)(.*)$\", \"\\\\2\", \"regex\")\n\
514 }\n\
515 Comments>% Comment@LaTeX:::R: {\n\
516 replace_in_selection(\"^.*$\", \"%&\", \"regex\")\n\
517 }\n\
518 Comments>% Uncomment@LaTeX:::R: {\n\
519 replace_in_selection(\"(^[ \\\\t]*%)(.*)$\", \"\\\\2\", \"regex\")\n\
520 }\n\
521 Comments>Bar Comment@C:::R: {\n\
522 if ($selection_left != -1) {\n\
523 dialog(\"Selection must not be rectangular\")\n\
524 return\n\
525 }\n\
526 start = $selection_start\n\
527 end = $selection_end-1\n\
528 origText = get_range($selection_start, $selection_end-1)\n\
529 newText = \"/*\\n\" replace_in_string(get_range(start, end), \\\n\
530 \"^\", \" * \", \"regex\") \"\\n */\\n\"\n\
531 replace_selection(newText)\n\
532 select(start, start + length(newText))\n\
533 }\n\
534 Comments>Bar Uncomment@C:::R: {\n\
535 selStart = $selection_start\n\
536 selEnd = $selection_end\n\
537 newText = get_range(selStart+3, selEnd-4)\n\
538 newText = replace_in_string(newText, \"^ \\\\* \", \"\", \"regex\")\n\
539 replace_range(selStart, selEnd, newText)\n\
540 select(selStart, selStart + length(newText))\n\
541 }\n\
542 Make C Prototypes@C@C++:::: {\n\
543 if ($selection_start == -1) {\n\
544 start = 0\n\
545 end = $text_length\n\
546 } else {\n\
547 start = $selection_start\n\
548 end = $selection_end\n\
549 }\n\
550 string = get_range(start, end)\n\
551 nDefs = 0\n\
552 searchPos = 0\n\
553 prototypes = \"\"\n\
554 staticPrototypes = \"\"\n\
555 for (;;) {\n\
556 headerStart = search_string(string, \\\n\
557 \"^[a-zA-Z]([^;#\\\"'{}=><!/]|\\n)*\\\\)[ \\t]*\\n?[ \\t]*\\\\{\", \\\n\
558 searchPos, \"regex\")\n\
559 if (headerStart == -1)\n\
560 break\n\
561 headerEnd = search_string(string, \")\", $search_end,\"backward\") + 1\n\
562 prototype = substring(string, headerStart, headerEnd) \";\\n\"\n\
563 if (substring(string, headerStart, headerStart+6) == \"static\")\n\
564 staticPrototypes = staticPrototypes prototype\n\
565 else\n\
566 prototypes = prototypes prototype\n\
567 searchPos = headerEnd\n\
568 nDefs++\n\
569 }\n\
570 if (nDefs == 0) {\n\
571 dialog(\"No function declarations found\")\n\
572 return\n\
573 }\n\
574 new()\n\
575 focus_window(\"last\")\n\
576 replace_range(0, 0, prototypes staticPrototypes)\n\
577 }", &TempStringPrefs.macroCmds, NULL, True},
578 {"bgMenuCommands", "BGMenuCommands", PREF_ALLOC_STRING,
579 "Undo:::: {\nundo()\n}\n\
580 Redo:::: {\nredo()\n}\n\
581 Cut:::R: {\ncut_clipboard()\n}\n\
582 Copy:::R: {\ncopy_clipboard()\n}\n\
583 Paste:::: {\npaste_clipboard()\n}", &TempStringPrefs.bgMenuCmds,
584 NULL, True},
585 #ifdef VMS
586 /* The VAX compiler can't compile Java-Script's definition in highlightData.c */
587 {"highlightPatterns", "HighlightPatterns", PREF_ALLOC_STRING,
588 "Ada:Default\n\
589 Awk:Default\n\
590 C++:Default\n\
591 C:Default\n\
592 CSS:Default\n\
593 Csh:Default\n\
594 Fortran:Default\n\
595 Java:Default\n\
596 LaTeX:Default\n\
597 Lex:Default\n\
598 Makefile:Default\n\
599 Matlab:Default\n\
600 NEdit Macro:Default\n\
601 Pascal:Default\n\
602 Perl:Default\n\
603 PostScript:Default\n\
604 Python:Default\n\
605 Regex:Default\n\
606 SGML HTML:Default\n\
607 SQL:Default\n\
608 Sh Ksh Bash:Default\n\
609 Tcl:Default\n\
610 VHDL:Default\n\
611 Verilog:Default\n\
612 XML:Default\n\
613 X Resources:Default\n\
614 Yacc:Default",
615 &TempStringPrefs.highlight, NULL, True},
616 {"languageModes", "LanguageModes", PREF_ALLOC_STRING,
617 #else
618 {"highlightPatterns", "HighlightPatterns", PREF_ALLOC_STRING,
619 "Ada:Default\n\
620 Awk:Default\n\
621 C++:Default\n\
622 C:Default\n\
623 CSS:Default\n\
624 Csh:Default\n\
625 Fortran:Default\n\
626 Java:Default\n\
627 JavaScript:Default\n\
628 LaTeX:Default\n\
629 Lex:Default\n\
630 Makefile:Default\n\
631 Matlab:Default\n\
632 NEdit Macro:Default\n\
633 Pascal:Default\n\
634 Perl:Default\n\
635 PostScript:Default\n\
636 Python:Default\n\
637 Regex:Default\n\
638 SGML HTML:Default\n\
639 SQL:Default\n\
640 Sh Ksh Bash:Default\n\
641 Tcl:Default\n\
642 VHDL:Default\n\
643 Verilog:Default\n\
644 XML:Default\n\
645 X Resources:Default\n\
646 Yacc:Default",
647 &TempStringPrefs.highlight, NULL, True},
648 {"languageModes", "LanguageModes", PREF_ALLOC_STRING,
649 #endif /*VMS*/
650 #ifdef VMS
651 "Ada:.ADA .AD .ADS .ADB .A:::::::\n\
652 Awk:.AWK:::::::\n\
653 C++:.CC .HH .C .H .I .CXX .HXX .CPP::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":\n\
654 C:.C .H::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":\n\
655 CSS:CSS::Auto:None:::\".,/\\`'!|@#%^&*()=+{}[]\"\":;<>?~\":\n\
656 Csh:.csh .cshrc .login .logout:\"^[ \\t]*#[ \\t]*![ \\t]*/bin/csh\"::::::\n\
657 Fortran:.F .F77 .FOR:::::::\n\
658 Java:.JAVA:::::::\n\
659 LaTeX:.TEX .STY .CLS .LTX .INS:::::::\n\
660 Lex:.lex:::::::\n\
661 Makefile:MAKEFILE:::None:8:8::\n\
662 Matlab:.m .oct .sci:::::::\n\
663 NEdit Macro:.NM .NEDITMACRO:::::::\n\
664 Pascal:.PAS .P .INT:::::::\n\
665 Perl:.PL .PM .P5:\"^[ \\t]*#[ \\t]*!.*perl\":Auto:None:::\".,/\\\\`'!$@#%^&*()-=+{}[]\"\":;<>?~|\":\n\
666 PostScript:.ps .PS .eps .EPS .epsf .epsi:\"^%!\":::::\"/%(){}[]<>\":\n\
667 Python:.PY:\"^#!.*python\":Auto:None:::\"!\"\"#$%&'()*+,-./:;<=>?@[\\\\]^`{|}~\":\n\
668 Regex:.reg .regex:\"\\(\\?[:#=!iInN].+\\)\":None:Continuous::::\n\
669 SGML HTML:.sgml .sgm .html .htm:\"\\<[Hh][Tt][Mm][Ll]\\>\"::::::\n\
670 SQL:.sql:::::::\n\
671 Sh Ksh Bash:.sh .bash .ksh .profile .bashrc .bash_logout .bash_login .bash_profile:\"^[ \\t]*#[ \\t]*![ \\t]*/.*bin/(bash|ksh|sh|zsh)\"::::::\n\
672 Tcl:.TCL::Smart:None::::\n\
673 VHDL:.VHD .VHDL .VDL:::::::\n\
674 Verilog:.V:::::::\n\
675 XML:.xml .xsl .dtd:\"\\<(?i\\?xml|!doctype)\"::None:::\"<>/=\"\"'()+*?|\":\n\
676 X Resources:.XRESOURCES .XDEFAULTS .NEDIT:\"^[!#].*([Aa]pp|[Xx]).*[Dd]efaults\"::::::\n\
677 Yacc:.Y::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":",
678 #else
679 "Ada:.ada .ad .ads .adb .a:::::::\n\
680 Awk:.awk:::::::\n\
681 C++:.cc .hh .C .H .i .cxx .hxx .cpp .c++::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":\n\
682 C:.c .h::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":\n\
683 CSS:css::Auto:None:::\".,/\\`'!|@#%^&*()=+{}[]\"\":;<>?~\":\n\
684 Csh:.csh .cshrc .login .logout:\"^[ \\t]*#[ \\t]*![ \\t]*/bin/csh\"::::::\n\
685 Fortran:.f .f77 .for:::::::\n\
686 Java:.java:::::::\n\
687 JavaScript:.js:::::::\n\
688 LaTeX:.tex .sty .cls .ltx .ins:::::::\n\
689 Lex:.lex:::::::\n\
690 Makefile:Makefile makefile .gmk:::None:8:8::\n\
691 Matlab:.m .oct .sci:::::::\n\
692 NEdit Macro:.nm .neditmacro:::::::\n\
693 Pascal:.pas .p .int:::::::\n\
694 Perl:.pl .pm .p5 .PL:\"^[ \\t]*#[ \\t]*!.*perl\":Auto:None:::\".,/\\\\`'!$@#%^&*()-=+{}[]\"\":;<>?~|\":\n\
695 PostScript:.ps .eps .epsf .epsi:\"^%!\":::::\"/%(){}[]<>\":\n\
696 Python:.py:\"^#!.*python\":Auto:None:::\"!\"\"#$%&'()*+,-./:;<=>?@[\\\\]^`{|}~\":\n\
697 Regex:.reg .regex:\"\\(\\?[:#=!iInN].+\\)\":None:Continuous::::\n\
698 SGML HTML:.sgml .sgm .html .htm:\"\\<[Hh][Tt][Mm][Ll]\\>\"::::::\n\
699 SQL:.sql:::::::\n\
700 Sh Ksh Bash:.sh .bash .ksh .profile .bashrc .bash_logout .bash_login .bash_profile:\"^[ \\t]*#[ \\t]*![ \\t]*/.*bin/(bash|ksh|sh|zsh)\"::::::\n\
701 Tcl:.tcl .tk .itcl .itk::Smart:None::::\n\
702 VHDL:.vhd .vhdl .vdl:::::::\n\
703 Verilog:.v:::::::\n\
704 XML:.xml .xsl .dtd:\"\\<(?i\\?xml|!doctype)\"::None:::\"<>/=\"\"'()+*?|\":\n\
705 X Resources:.Xresources .Xdefaults .nedit:\"^[!#].*([Aa]pp|[Xx]).*[Dd]efaults\"::::::\n\
706 Yacc:.y::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":",
707 #endif
708 &TempStringPrefs.language, NULL, True},
709 {"styles", "Styles", PREF_ALLOC_STRING, "Plain:black:Plain\n\
710 Comment:gray20:Italic\n\
711 Keyword:black:Bold\n\
712 Storage Type:brown:Bold\n\
713 Storage Type1:saddle brown:Bold\n\
714 String:darkGreen:Plain\n\
715 String1:SeaGreen:Plain\n\
716 String2:darkGreen:Bold\n\
717 Preprocessor:RoyalBlue4:Plain\n\
718 Preprocessor1:blue:Plain\n\
719 Character Const:darkGreen:Plain\n\
720 Numeric Const:darkGreen:Plain\n\
721 Identifier:brown:Plain\n\
722 Identifier1:RoyalBlue4:Plain\n\
723 Identifier2:SteelBlue:Plain\n\
724 Subroutine:brown:Plain\n\
725 Subroutine1:chocolate:Plain\n\
726 Ada Attributes:plum:Bold\n\
727 Label:red:Italic\n\
728 Flag:red:Bold\n\
729 Text Comment:SteelBlue4:Italic\n\
730 Text Key:VioletRed4:Bold\n\
731 Text Key1:VioletRed4:Plain\n\
732 Text Arg:RoyalBlue4:Bold\n\
733 Text Arg1:SteelBlue4:Bold\n\
734 Text Arg2:RoyalBlue4:Plain\n\
735 Text Escape:gray30:Bold\n\
736 LaTeX Math:darkGreen:Plain\n"
737 ADD_5_2_STYLES,
738 &TempStringPrefs.styles, NULL, True},
739 {"smartIndentInit", "SmartIndentInit", PREF_ALLOC_STRING,
740 "C:Default\n\
741 C++:Default\n\
742 Python:Default\n\
743 Matlab:Default", &TempStringPrefs.smartIndent, NULL, True},
744 {"smartIndentInitCommon", "SmartIndentInitCommon", PREF_ALLOC_STRING,
745 "Default", &TempStringPrefs.smartIndentCommon, NULL, True},
746 {"autoWrap", "AutoWrap", PREF_ENUM, "Newline",
747 &PrefData.wrapStyle, AutoWrapTypes, True},
748 {"wrapMargin", "WrapMargin", PREF_INT, "0",
749 &PrefData.wrapMargin, NULL, True},
750 {"autoIndent", "AutoIndent", PREF_ENUM, "Auto",
751 &PrefData.autoIndent, AutoIndentTypes, True},
752 {"autoSave", "AutoSave", PREF_BOOLEAN, "True",
753 &PrefData.autoSave, NULL, True},
754 {"openInTab", "OpenInTab", PREF_BOOLEAN, "True",
755 &PrefData.openInTab, NULL, True},
756 {"saveOldVersion", "SaveOldVersion", PREF_BOOLEAN, "False",
757 &PrefData.saveOldVersion, NULL, True},
758 {"showMatching", "ShowMatching", PREF_ENUM, "Delimiter",
759 &PrefData.showMatchingStyle, ShowMatchingTypes, True},
760 {"matchSyntaxBased", "MatchSyntaxBased", PREF_BOOLEAN, "True",
761 &PrefData.matchSyntaxBased, NULL, True},
762 {"highlightSyntax", "HighlightSyntax", PREF_BOOLEAN, "True",
763 &PrefData.highlightSyntax, NULL, True},
764 {"backlightChars", "BacklightChars", PREF_BOOLEAN, "False",
765 &PrefData.backlightChars, NULL, True},
766 {"backlightCharTypes", "BacklightCharTypes", PREF_ALLOC_STRING,
767 "0-8,10-31,127:red;9:#dedede;32,160-255:#f0f0f0;128-159:orange",
768 /* gray87 gray94 */
769 &PrefData.backlightCharTypes, NULL, False},
770 {"searchDialogs", "SearchDialogs", PREF_BOOLEAN, "False",
771 &PrefData.searchDlogs, NULL, True},
772 {"beepOnSearchWrap", "BeepOnSearchWrap", PREF_BOOLEAN, "False",
773 &PrefData.searchWrapBeep, NULL, True},
774 {"retainSearchDialogs", "RetainSearchDialogs", PREF_BOOLEAN, "False",
775 &PrefData.keepSearchDlogs, NULL, True},
776 {"searchWraps", "SearchWraps", PREF_BOOLEAN, "True",
777 &PrefData.searchWraps, NULL, True},
778 {"stickyCaseSenseButton", "StickyCaseSenseButton", PREF_BOOLEAN, "True",
779 &PrefData.stickyCaseSenseBtn, NULL, True},
780 #if XmVersion < 1002 /* Flashing is annoying in 1.1 versions */
781 {"repositionDialogs", "RepositionDialogs", PREF_BOOLEAN, "False",
782 &PrefData.repositionDialogs, NULL, True},
783 #else
784 {"repositionDialogs", "RepositionDialogs", PREF_BOOLEAN, "True",
785 &PrefData.repositionDialogs, NULL, True},
786 #endif
787 {"autoScroll", "AutoScroll", PREF_BOOLEAN, "False",
788 &PrefData.autoScroll, NULL, True},
789 {"autoScrollVPadding", "AutoScrollVPadding", PREF_INT, "4",
790 &PrefData.autoScrollVPadding, NULL, False},
791 {"appendLF", "AppendLF", PREF_BOOLEAN, "True",
792 &PrefData.appendLF, NULL, True},
793 {"sortOpenPrevMenu", "SortOpenPrevMenu", PREF_BOOLEAN, "True",
794 &PrefData.sortOpenPrevMenu, NULL, True},
795 {"statisticsLine", "StatisticsLine", PREF_BOOLEAN, "False",
796 &PrefData.statsLine, NULL, True},
797 {"iSearchLine", "ISearchLine", PREF_BOOLEAN, "False",
798 &PrefData.iSearchLine, NULL, True},
799 {"sortTabs", "SortTabs", PREF_BOOLEAN, "False",
800 &PrefData.sortTabs, NULL, True},
801 {"tabBar", "TabBar", PREF_BOOLEAN, "True",
802 &PrefData.tabBar, NULL, True},
803 {"tabBarHideOne", "TabBarHideOne", PREF_BOOLEAN, "True",
804 &PrefData.tabBarHideOne, NULL, True},
805 {"toolTips", "ToolTips", PREF_BOOLEAN, "True",
806 &PrefData.toolTips, NULL, True},
807 {"globalTabNavigate", "GlobalTabNavigate", PREF_BOOLEAN, "False",
808 &PrefData.globalTabNavigate, NULL, True},
809 {"lineNumbers", "LineNumbers", PREF_BOOLEAN, "False",
810 &PrefData.lineNums, NULL, True},
811 {"pathInWindowsMenu", "PathInWindowsMenu", PREF_BOOLEAN, "True",
812 &PrefData.pathInWindowsMenu, NULL, True},
813 {"warnFileMods", "WarnFileMods", PREF_BOOLEAN, "True",
814 &PrefData.warnFileMods, NULL, True},
815 {"warnRealFileMods", "WarnRealFileMods", PREF_BOOLEAN, "True",
816 &PrefData.warnRealFileMods, NULL, True},
817 {"warnExit", "WarnExit", PREF_BOOLEAN, "True",
818 &PrefData.warnExit, NULL, True},
819 {"searchMethod", "SearchMethod", PREF_ENUM, "Literal",
820 &PrefData.searchMethod, SearchMethodStrings, True},
821 #ifdef REPLACE_SCOPE
822 {"replaceDefaultScope", "ReplaceDefaultScope", PREF_ENUM, "Smart",
823 &PrefData.replaceDefScope, ReplaceDefScopeStrings, True},
824 #endif
825 {"textRows", "TextRows", PREF_INT, "24",
826 &PrefData.textRows, NULL, True},
827 {"textCols", "TextCols", PREF_INT, "80",
828 &PrefData.textCols, NULL, True},
829 {"tabDistance", "TabDistance", PREF_INT, "8",
830 &PrefData.tabDist, NULL, True},
831 {"emulateTabs", "EmulateTabs", PREF_INT, "0",
832 &PrefData.emTabDist, NULL, True},
833 {"insertTabs", "InsertTabs", PREF_BOOLEAN, "True",
834 &PrefData.insertTabs, NULL, True},
835 {"textFont", "TextFont", PREF_STRING,
836 "-*-courier-medium-r-normal--*-120-*-*-*-iso8859-1",
837 PrefData.fontString, (void *)sizeof(PrefData.fontString), True},
838 {"boldHighlightFont", "BoldHighlightFont", PREF_STRING,
839 "-*-courier-bold-r-normal--*-120-*-*-*-iso8859-1",
840 PrefData.boldFontString, (void *)sizeof(PrefData.boldFontString), True},
841 {"italicHighlightFont", "ItalicHighlightFont", PREF_STRING,
842 "-*-courier-medium-o-normal--*-120-*-*-*-iso8859-1",
843 PrefData.italicFontString,
844 (void *)sizeof(PrefData.italicFontString), True},
845 {"boldItalicHighlightFont", "BoldItalicHighlightFont", PREF_STRING,
846 "-*-courier-bold-o-normal--*-120-*-*-*-iso8859-1",
847 PrefData.boldItalicFontString,
848 (void *)sizeof(PrefData.boldItalicFontString), True},
849 {"helpFont", "HelpFont", PREF_STRING,
850 "-*-helvetica-medium-r-normal--*-120-*-*-*-iso8859-1",
851 PrefData.helpFontNames[HELP_FONT],
852 (void *)sizeof(PrefData.helpFontNames[HELP_FONT]), False},
853 {"boldHelpFont", "BoldHelpFont", PREF_STRING,
854 "-*-helvetica-bold-r-normal--*-120-*-*-*-iso8859-1",
855 PrefData.helpFontNames[BOLD_HELP_FONT],
856 (void *)sizeof(PrefData.helpFontNames[BOLD_HELP_FONT]), False},
857 {"italicHelpFont", "ItalicHelpFont", PREF_STRING,
858 "-*-helvetica-medium-o-normal--*-120-*-*-*-iso8859-1",
859 PrefData.helpFontNames[ITALIC_HELP_FONT],
860 (void *)sizeof(PrefData.helpFontNames[ITALIC_HELP_FONT]), False},
861 {"boldItalicHelpFont", "BoldItalicHelpFont", PREF_STRING,
862 "-*-helvetica-bold-o-normal--*-120-*-*-*-iso8859-1",
863 PrefData.helpFontNames[BOLD_ITALIC_HELP_FONT],
864 (void *)sizeof(PrefData.helpFontNames[BOLD_ITALIC_HELP_FONT]), False},
865 {"fixedHelpFont", "FixedHelpFont", PREF_STRING,
866 "-*-courier-medium-r-normal--*-120-*-*-*-iso8859-1",
867 PrefData.helpFontNames[FIXED_HELP_FONT],
868 (void *)sizeof(PrefData.helpFontNames[FIXED_HELP_FONT]), False},
869 {"boldFixedHelpFont", "BoldFixedHelpFont", PREF_STRING,
870 "-*-courier-bold-r-normal--*-120-*-*-*-iso8859-1",
871 PrefData.helpFontNames[BOLD_FIXED_HELP_FONT],
872 (void *)sizeof(PrefData.helpFontNames[BOLD_FIXED_HELP_FONT]), False},
873 {"italicFixedHelpFont", "ItalicFixedHelpFont", PREF_STRING,
874 "-*-courier-medium-o-normal--*-120-*-*-*-iso8859-1",
875 PrefData.helpFontNames[ITALIC_FIXED_HELP_FONT],
876 (void *)sizeof(PrefData.helpFontNames[ITALIC_FIXED_HELP_FONT]), False},
877 {"boldItalicFixedHelpFont", "BoldItalicFixedHelpFont", PREF_STRING,
878 "-*-courier-bold-o-normal--*-120-*-*-*-iso8859-1",
879 PrefData.helpFontNames[BOLD_ITALIC_FIXED_HELP_FONT],
880 (void *)sizeof(PrefData.helpFontNames[BOLD_ITALIC_FIXED_HELP_FONT]), False},
881 {"helpLinkFont", "HelpLinkFont", PREF_STRING,
882 "-*-helvetica-medium-r-normal--*-120-*-*-*-iso8859-1",
883 PrefData.helpFontNames[HELP_LINK_FONT],
884 (void *)sizeof(PrefData.helpFontNames[HELP_LINK_FONT]), False},
885 {"h1HelpFont", "H1HelpFont", PREF_STRING,
886 "-*-helvetica-bold-r-normal--*-140-*-*-*-iso8859-1",
887 PrefData.helpFontNames[H1_HELP_FONT],
888 (void *)sizeof(PrefData.helpFontNames[H1_HELP_FONT]), False},
889 {"h2HelpFont", "H2HelpFont", PREF_STRING,
890 "-*-helvetica-bold-o-normal--*-120-*-*-*-iso8859-1",
891 PrefData.helpFontNames[H2_HELP_FONT],
892 (void *)sizeof(PrefData.helpFontNames[H2_HELP_FONT]), False},
893 {"h3HelpFont", "H3HelpFont", PREF_STRING,
894 "-*-courier-bold-r-normal--*-120-*-*-*-iso8859-1",
895 PrefData.helpFontNames[H3_HELP_FONT],
896 (void *)sizeof(PrefData.helpFontNames[H3_HELP_FONT]), False},
897 {"helpLinkColor", "HelpLinkColor", PREF_STRING, "#009900",
898 PrefData.helpLinkColor,
899 (void *)sizeof(PrefData.helpLinkColor), False},
901 {"textFgColor", "TextFgColor", PREF_STRING, NEDIT_DEFAULT_FG,
902 PrefData.colorNames[TEXT_FG_COLOR],
903 (void *)sizeof(PrefData.colorNames[TEXT_FG_COLOR]), True},
904 {"textBgColor", "TextBgColor", PREF_STRING, NEDIT_DEFAULT_TEXT_BG,
905 PrefData.colorNames[TEXT_BG_COLOR],
906 (void *)sizeof(PrefData.colorNames[TEXT_BG_COLOR]), True},
907 {"selectFgColor", "SelectFgColor", PREF_STRING, NEDIT_DEFAULT_SEL_FG,
908 PrefData.colorNames[SELECT_FG_COLOR],
909 (void *)sizeof(PrefData.colorNames[SELECT_FG_COLOR]), True},
910 {"selectBgColor", "SelectBgColor", PREF_STRING, NEDIT_DEFAULT_SEL_BG,
911 PrefData.colorNames[SELECT_BG_COLOR],
912 (void *)sizeof(PrefData.colorNames[SELECT_BG_COLOR]), True},
913 {"hiliteFgColor", "HiliteFgColor", PREF_STRING, NEDIT_DEFAULT_HI_FG,
914 PrefData.colorNames[HILITE_FG_COLOR],
915 (void *)sizeof(PrefData.colorNames[HILITE_FG_COLOR]), True},
916 {"hiliteBgColor", "HiliteBgColor", PREF_STRING, NEDIT_DEFAULT_HI_BG,
917 PrefData.colorNames[HILITE_BG_COLOR],
918 (void *)sizeof(PrefData.colorNames[HILITE_BG_COLOR]), True},
919 {"lineNoFgColor", "LineNoFgColor", PREF_STRING, NEDIT_DEFAULT_LINENO_FG,
920 PrefData.colorNames[LINENO_FG_COLOR],
921 (void *)sizeof(PrefData.colorNames[LINENO_FG_COLOR]), True},
922 {"cursorFgColor", "CursorFgColor", PREF_STRING, NEDIT_DEFAULT_CURSOR_FG,
923 PrefData.colorNames[CURSOR_FG_COLOR],
924 (void *)sizeof(PrefData.colorNames[CURSOR_FG_COLOR]), True},
925 {"tooltipBgColor", "TooltipBgColor", PREF_STRING, "LemonChiffon1",
926 PrefData.tooltipBgColor,
927 (void *)sizeof(PrefData.tooltipBgColor), False},
929 {"shell", "Shell", PREF_STRING,
930 #if defined(__MVS__) || defined(__EMX__)
931 "/bin/sh",
932 #else
933 "/bin/csh",
934 #endif
935 PrefData.shell, (void *)sizeof(PrefData.shell), False},
936 {"geometry", "Geometry", PREF_STRING, "",
937 PrefData.geometry, (void *)sizeof(PrefData.geometry), False},
938 {"remapDeleteKey", "RemapDeleteKey", PREF_BOOLEAN, "False",
939 &PrefData.mapDelete, NULL, False},
940 {"stdOpenDialog", "StdOpenDialog", PREF_BOOLEAN, "False",
941 &PrefData.stdOpenDialog, NULL, False},
942 {"tagFile", "TagFile", PREF_STRING,
943 "", PrefData.tagFile, (void *)sizeof(PrefData.tagFile), False},
944 {"wordDelimiters", "WordDelimiters", PREF_STRING,
945 ".,/\\`'!|@#%^&*()-=+{}[]\":;<>?",
946 PrefData.delimiters, (void *)sizeof(PrefData.delimiters), False},
947 {"serverName", "ServerName", PREF_STRING, "", PrefData.serverName,
948 (void *)sizeof(PrefData.serverName), False},
949 {"maxPrevOpenFiles", "MaxPrevOpenFiles", PREF_INT, "30",
950 &PrefData.maxPrevOpenFiles, NULL, False},
951 {"bgMenuButton", "BGMenuButton" , PREF_STRING,
952 "~Shift~Ctrl~Meta~Alt<Btn3Down>", PrefData.bgMenuBtn,
953 (void *)sizeof(PrefData.bgMenuBtn), False},
954 {"smartTags", "SmartTags", PREF_BOOLEAN, "True",
955 &PrefData.smartTags, NULL, True},
956 {"typingHidesPointer", "TypingHidesPointer", PREF_BOOLEAN, "False",
957 &PrefData.typingHidesPointer, NULL, False},
958 {"alwaysCheckRelativeTagsSpecs", "AlwaysCheckRelativeTagsSpecs",
959 PREF_BOOLEAN, "True", &PrefData.alwaysCheckRelativeTagsSpecs, NULL, False},
960 {"prefFileRead", "PrefFileRead", PREF_BOOLEAN, "False",
961 &PrefData.prefFileRead, NULL, True},
962 #ifdef SGI_CUSTOM
963 {"shortMenus", "ShortMenus", PREF_BOOLEAN, "False", &PrefData.shortMenus,
964 NULL, True},
965 #endif
966 {"findReplaceUsesSelection", "FindReplaceUsesSelection", PREF_BOOLEAN, "False",
967 &PrefData.findReplaceUsesSelection, NULL, False},
968 {"overrideDefaultVirtualKeyBindings", "OverrideDefaultVirtualKeyBindings",
969 PREF_ENUM, "Auto", &PrefData.virtKeyOverride, VirtKeyOverrideModes, False},
970 {"titleFormat", "TitleFormat", PREF_STRING, "{%c} [%s] %f (%S) - %d",
971 PrefData.titleFormat, (void *)sizeof(PrefData.titleFormat), True},
972 {"undoModifiesSelection", "UndoModifiesSelection", PREF_BOOLEAN,
973 "True", &PrefData.undoModifiesSelection, NULL, False},
974 {"focusOnRaise", "FocusOnRaise", PREF_BOOLEAN,
975 "False", &PrefData.focusOnRaise, NULL, False}
978 static XrmOptionDescRec OpTable[] = {
979 {"-wrap", ".autoWrap", XrmoptionNoArg, (caddr_t)"Continuous"},
980 {"-nowrap", ".autoWrap", XrmoptionNoArg, (caddr_t)"None"},
981 {"-autowrap", ".autoWrap", XrmoptionNoArg, (caddr_t)"Newline"},
982 {"-noautowrap", ".autoWrap", XrmoptionNoArg, (caddr_t)"None"},
983 {"-autoindent", ".autoIndent", XrmoptionNoArg, (caddr_t)"Auto"},
984 {"-noautoindent", ".autoIndent", XrmoptionNoArg, (caddr_t)"False"},
985 {"-autosave", ".autoSave", XrmoptionNoArg, (caddr_t)"True"},
986 {"-noautosave", ".autoSave", XrmoptionNoArg, (caddr_t)"False"},
987 {"-rows", ".textRows", XrmoptionSepArg, (caddr_t)NULL},
988 {"-columns", ".textCols", XrmoptionSepArg, (caddr_t)NULL},
989 {"-tabs", ".tabDistance", XrmoptionSepArg, (caddr_t)NULL},
990 {"-font", ".textFont", XrmoptionSepArg, (caddr_t)NULL},
991 {"-fn", ".textFont", XrmoptionSepArg, (caddr_t)NULL},
992 {"-svrname", ".serverName", XrmoptionSepArg, (caddr_t)NULL},
995 static const char HeaderText[] = "\
996 ! Preferences file for NEdit\n\
997 !\n\
998 ! This file is overwritten by the \"Save Defaults...\" command in NEdit \n\
999 ! and serves only the interactively settable options presented in the NEdit\n\
1000 ! \"Preferences\" menu. To modify other options, such as key bindings, use \n\
1001 ! the .Xdefaults file in your home directory (or the X resource \n\
1002 ! specification method appropriate to your system). The contents of this \n\
1003 ! file can be moved into an X resource file, but since resources in this file\n\
1004 ! override their corresponding X resources, either this file should be \n\
1005 ! deleted or individual resource lines in the file should be deleted for the\n\
1006 ! moved lines to take effect.\n";
1008 /* Module-global variable set when any preference changes (for asking the
1009 user about re-saving on exit) */
1010 static int PrefsHaveChanged = False;
1012 /* Module-global variable set when user uses -import to load additional
1013 preferences on top of the defaults. Contains name of file loaded */
1014 static char *ImportedFile = NULL;
1016 /* Module-global variables to support Initial Window Size... dialog */
1017 static int DoneWithSizeDialog;
1018 static Widget RowText, ColText;
1020 /* Module-global variables for Tabs dialog */
1021 static int DoneWithTabsDialog;
1022 static WindowInfo *TabsDialogForWindow;
1023 static Widget TabDistText, EmTabText, EmTabToggle, UseTabsToggle, EmTabLabel;
1025 /* Module-global variables for Wrap Margin dialog */
1026 static int DoneWithWrapDialog;
1027 static WindowInfo *WrapDialogForWindow;
1028 static Widget WrapText, WrapTextLabel, WrapWindowToggle;
1030 static void translatePrefFormats(int convertOld, int fileVer);
1031 static void setIntPref(int *prefDataField, int newValue);
1032 static void setStringPref(char *prefDataField, const char *newValue);
1033 static void sizeOKCB(Widget w, XtPointer clientData, XtPointer callData);
1034 static void setStringAllocPref(char **pprefDataField, char *newValue);
1035 static void sizeCancelCB(Widget w, XtPointer clientData, XtPointer callData);
1036 static void tabsOKCB(Widget w, XtPointer clientData, XtPointer callData);
1037 static void tabsCancelCB(Widget w, XtPointer clientData, XtPointer callData);
1038 static void tabsHelpCB(Widget w, XtPointer clientData, XtPointer callData);
1039 static void emTabsCB(Widget w, XtPointer clientData, XtPointer callData);
1040 static void wrapOKCB(Widget w, XtPointer clientData, XtPointer callData);
1041 static void wrapCancelCB(Widget w, XtPointer clientData, XtPointer callData);
1042 static void wrapWindowCB(Widget w, XtPointer clientData, XtPointer callData);
1043 static void reapplyLanguageMode(WindowInfo *window, int mode,int forceDefaults);
1046 static void fillFromPrimaryCB(Widget w, XtPointer clientData,
1047 XtPointer callData);
1048 static int checkFontStatus(fontDialog *fd, Widget fontTextFieldW);
1049 static int showFontStatus(fontDialog *fd, Widget fontTextFieldW,
1050 Widget errorLabelW);
1051 static void primaryModifiedCB(Widget w, XtPointer clientData,
1052 XtPointer callData);
1053 static void italicModifiedCB(Widget w, XtPointer clientData,
1054 XtPointer callData);
1055 static void boldModifiedCB(Widget w, XtPointer clientData, XtPointer callData);
1056 static void boldItalicModifiedCB(Widget w, XtPointer clientData,
1057 XtPointer callData);
1058 static void primaryBrowseCB(Widget w, XtPointer clientData, XtPointer callData);
1059 static void italicBrowseCB(Widget w, XtPointer clientData, XtPointer callData);
1060 static void boldBrowseCB(Widget w, XtPointer clientData, XtPointer callData);
1061 static void boldItalicBrowseCB(Widget w, XtPointer clientData,
1062 XtPointer callData);
1063 static void browseFont(Widget parent, Widget fontTextW);
1064 static void fontDestroyCB(Widget w, XtPointer clientData, XtPointer callData);
1065 static void fontOkCB(Widget w, XtPointer clientData, XtPointer callData);
1066 static void fontApplyCB(Widget w, XtPointer clientData, XtPointer callData);
1067 static void fontCancelCB(Widget w, XtPointer clientData, XtPointer callData);
1068 static void updateFonts(fontDialog *fd);
1070 static Boolean checkColorStatus(colorDialog *cd, Widget colorFieldW);
1071 static int verifyAllColors (colorDialog *cd);
1072 static void showColorStatus (colorDialog *cd, Widget colorFieldW,
1073 Widget errorLabelW);
1074 static void updateColors(colorDialog *cd);
1075 static void colorDestroyCB(Widget w, XtPointer clientData, XtPointer callData);
1076 static void colorOkCB (Widget w, XtPointer clientData, XtPointer callData);
1077 static void colorApplyCB (Widget w, XtPointer clientData, XtPointer callData);
1078 static void colorCloseCB(Widget w, XtPointer clientData, XtPointer callData);
1079 static void textFgModifiedCB (Widget w, XtPointer clientData,
1080 XtPointer callData);
1081 static void textBgModifiedCB (Widget w, XtPointer clientData,
1082 XtPointer callData);
1083 static void selectFgModifiedCB(Widget w, XtPointer clientData,
1084 XtPointer callData);
1085 static void selectBgModifiedCB(Widget w, XtPointer clientData,
1086 XtPointer callData);
1087 static void hiliteFgModifiedCB(Widget w, XtPointer clientData,
1088 XtPointer callData);
1089 static void hiliteBgModifiedCB(Widget w, XtPointer clientData,
1090 XtPointer callData);
1091 static void lineNoFgModifiedCB(Widget w, XtPointer clientData,
1092 XtPointer callData);
1093 static void cursorFgModifiedCB(Widget w, XtPointer clientData,
1094 XtPointer callData);
1096 static int matchLanguageMode(WindowInfo *window);
1097 static int loadLanguageModesString(char *inString, int fileVer);
1098 static char *writeLanguageModesString(void);
1099 static char *createExtString(char **extensions, int nExtensions);
1100 static char **readExtensionList(char **inPtr, int *nExtensions);
1101 static void updateLanguageModeSubmenu(WindowInfo *window);
1102 static void setLangModeCB(Widget w, XtPointer clientData, XtPointer callData);
1103 static int modeError(languageModeRec *lm, const char *stringStart,
1104 const char *stoppedAt, const char *message);
1105 static void lmDestroyCB(Widget w, XtPointer clientData, XtPointer callData);
1106 static void lmOkCB(Widget w, XtPointer clientData, XtPointer callData);
1107 static void lmApplyCB(Widget w, XtPointer clientData, XtPointer callData);
1108 static void lmCloseCB(Widget w, XtPointer clientData, XtPointer callData);
1109 static int lmDeleteConfirmCB(int itemIndex, void *cbArg);
1110 static int updateLMList(void);
1111 static languageModeRec *copyLanguageModeRec(languageModeRec *lm);
1112 static void *lmGetDisplayedCB(void *oldItem, int explicitRequest, int *abort,
1113 void *cbArg);
1114 static void lmSetDisplayedCB(void *item, void *cbArg);
1115 static languageModeRec *readLMDialogFields(int silent);
1116 static void lmFreeItemCB(void *item);
1117 static void freeLanguageModeRec(languageModeRec *lm);
1118 static int lmDialogEmpty(void);
1119 static void updatePatternsTo5dot1(void);
1120 static void updatePatternsTo5dot2(void);
1121 static void updatePatternsTo5dot3(void);
1122 static void updatePatternsTo5dot4(void);
1123 static void updateShellCmdsTo5dot3(void);
1124 static void updateShellCmdsTo5dot4(void);
1125 static void updateMacroCmdsTo5dot5(void);
1126 static void migrateColorResources(XrmDatabase prefDB, XrmDatabase appDB);
1127 static void spliceString(char **intoString, const char *insertString, const char *atExpr);
1128 static int regexFind(const char *inString, const char *expr);
1129 static int regexReplace(char **inString, const char *expr,
1130 const char *replaceWith);
1132 #ifdef SGI_CUSTOM
1133 static int shortPrefToDefault(Widget parent, const char *settingName, int *setDefault);
1134 #endif
1136 XrmDatabase CreateNEditPrefDB(int *argcInOut, char **argvInOut)
1138 return CreatePreferencesDatabase(GetRCFileName(NEDIT_RC), APP_NAME,
1139 OpTable, XtNumber(OpTable), (unsigned int *)argcInOut, argvInOut);
1142 void RestoreNEditPrefs(XrmDatabase prefDB, XrmDatabase appDB)
1144 int requiresConversion;
1145 int major; /* The integral part of version number */
1146 int minor; /* fractional part of version number */
1147 int fileVer = 0; /* Both combined into an integer */
1148 int nparsed;
1150 /* Load preferences */
1151 RestorePreferences(prefDB, appDB, APP_NAME,
1152 APP_CLASS, PrefDescrip, XtNumber(PrefDescrip));
1154 /* If the preferences file was written by an older version of NEdit,
1155 warn the user that it will be converted. */
1156 requiresConversion = PrefData.prefFileRead &&
1157 PrefData.fileVersion[0] == '\0';
1158 if (requiresConversion) {
1159 updatePatternsTo5dot1();
1162 if (PrefData.prefFileRead) {
1163 if (PrefData.fileVersion[0] == '\0') {
1164 fileVer = 0; /* Pre-5.1 */
1166 else {
1167 /* Note: do not change the format of this. Older executables
1168 need to read this field for forward compatability. */
1169 nparsed = sscanf(PrefData.fileVersion, "%d.%d", &major, &minor);
1170 if (nparsed >= 2) {
1171 /* Use OSF-style numbering scheme */
1172 fileVer = major * 1000 + minor;
1177 if (PrefData.prefFileRead && fileVer < 5002) {
1178 updatePatternsTo5dot2();
1181 if (PrefData.prefFileRead && fileVer < 5003) {
1182 updateShellCmdsTo5dot3();
1183 updatePatternsTo5dot3();
1186 /* Note that we don't care about unreleased file versions. Anyone
1187 who is running a CVS or alpha version of NEdit is resposnbile
1188 for managing the preferences file themselves. Otherwise, it
1189 gets impossible to track the number of "in-between" file formats.
1190 We only do auto-upgrading for a real release. */
1192 if (PrefData.prefFileRead && (fileVer < 5004)) {
1193 migrateColorResources(prefDB, appDB);
1194 updateShellCmdsTo5dot4();
1195 updatePatternsTo5dot4();
1197 if (PrefData.prefFileRead && (fileVer < 5005)) {
1198 fprintf(stderr, "NEdit: Converting .nedit file to 5.5 version.\n"
1199 " To keep, use Preferences -> Save Defaults\n");
1200 updateMacroCmdsTo5dot5();
1202 /* Migrate colors if there's no config file yet */
1203 if (!PrefData.prefFileRead) {
1204 migrateColorResources(prefDB, appDB);
1207 /* Do further parsing on resource types which RestorePreferences does
1208 not understand and reads as strings, to put them in the final form
1209 in which nedit stores and uses. If the preferences file was
1210 written by an older version of NEdit, update regular expressions in
1211 highlight patterns to quote braces and use & instead of \0 */
1212 translatePrefFormats(requiresConversion, fileVer);
1216 ** Many of of NEdit's preferences are much more complicated than just simple
1217 ** integers or strings. These are read as strings, but must be parsed and
1218 ** translated into something meaningful. This routine does the translation,
1219 ** and, in most cases, frees the original string, which is no longer useful.
1221 ** The argument convertOld attempts a conversion from pre 5.1 format .nedit
1222 ** files (which means patterns and macros may contain regular expressions
1223 ** which are of the older syntax where braces were not quoted, and \0 was a
1224 ** legal substitution character). Macros, so far can not be automatically
1225 ** converted, unfortunately.
1227 static void translatePrefFormats(int convertOld, int fileVer)
1229 XFontStruct *font;
1231 /* Parse the strings which represent types which are not decoded by
1232 the standard resource manager routines */
1233 #ifndef VMS
1234 if (TempStringPrefs.shellCmds != NULL) {
1235 LoadShellCmdsString(TempStringPrefs.shellCmds);
1236 XtFree(TempStringPrefs.shellCmds);
1237 TempStringPrefs.shellCmds = NULL;
1239 #endif /* VMS */
1240 if (TempStringPrefs.macroCmds != NULL) {
1241 LoadMacroCmdsString(TempStringPrefs.macroCmds);
1242 XtFree(TempStringPrefs.macroCmds);
1243 TempStringPrefs.macroCmds = NULL;
1245 if (TempStringPrefs.bgMenuCmds != NULL) {
1246 LoadBGMenuCmdsString(TempStringPrefs.bgMenuCmds);
1247 XtFree(TempStringPrefs.bgMenuCmds);
1248 TempStringPrefs.bgMenuCmds = NULL;
1250 if (TempStringPrefs.highlight != NULL) {
1251 LoadHighlightString(TempStringPrefs.highlight, convertOld);
1252 XtFree(TempStringPrefs.highlight);
1253 TempStringPrefs.highlight = NULL;
1255 if (TempStringPrefs.styles != NULL) {
1256 LoadStylesString(TempStringPrefs.styles);
1257 XtFree(TempStringPrefs.styles);
1258 TempStringPrefs.styles = NULL;
1260 if (TempStringPrefs.language != NULL) {
1261 loadLanguageModesString(TempStringPrefs.language, fileVer);
1262 XtFree(TempStringPrefs.language);
1263 TempStringPrefs.language = NULL;
1265 if (TempStringPrefs.smartIndent != NULL) {
1266 LoadSmartIndentString(TempStringPrefs.smartIndent);
1267 XtFree(TempStringPrefs.smartIndent);
1268 TempStringPrefs.smartIndent = NULL;
1270 if (TempStringPrefs.smartIndentCommon != NULL) {
1271 LoadSmartIndentCommonString(TempStringPrefs.smartIndentCommon);
1272 XtFree(TempStringPrefs.smartIndentCommon);
1273 TempStringPrefs.smartIndentCommon = NULL;
1276 /* translate the font names into fontLists suitable for the text widget */
1277 font = XLoadQueryFont(TheDisplay, PrefData.fontString);
1278 PrefData.fontList = font==NULL ? NULL :
1279 XmFontListCreate(font, XmSTRING_DEFAULT_CHARSET);
1280 PrefData.boldFontStruct = XLoadQueryFont(TheDisplay,
1281 PrefData.boldFontString);
1282 PrefData.italicFontStruct = XLoadQueryFont(TheDisplay,
1283 PrefData.italicFontString);
1284 PrefData.boldItalicFontStruct = XLoadQueryFont(TheDisplay,
1285 PrefData.boldItalicFontString);
1287 /* For compatability with older (4.0.3 and before) versions, the autoWrap
1288 and autoIndent resources can accept values of True and False. Translate
1289 them into acceptable wrap and indent styles */
1290 if (PrefData.wrapStyle == 3) PrefData.wrapStyle = NEWLINE_WRAP;
1291 if (PrefData.wrapStyle == 4) PrefData.wrapStyle = NO_WRAP;
1292 if (PrefData.autoIndent == 3) PrefData.autoIndent = AUTO_INDENT;
1293 if (PrefData.autoIndent == 4) PrefData.autoIndent = NO_AUTO_INDENT;
1295 /* setup language mode dependent info of user menus (to increase
1296 performance when switching between documents of different
1297 language modes) */
1298 SetupUserMenuInfo();
1301 void SaveNEditPrefs(Widget parent, int quietly)
1303 const char* prefFileName = GetRCFileName(NEDIT_RC);
1304 if (prefFileName == NULL)
1306 /* GetRCFileName() might return NULL if an error occurs during
1307 creation of the preference file directory. */
1308 DialogF(DF_WARN, parent, 1, "Error saving Preferences",
1309 "Unable to save preferences: Cannot determine filename.",
1310 "OK");
1311 return;
1314 if (!quietly) {
1315 if (DialogF(DF_INF, parent, 2, "Save Preferences",
1316 ImportedFile == NULL ?
1317 "Default preferences will be saved in the file:\n"
1318 "%s\n"
1319 "NEdit automatically loads this file\n"
1320 "each time it is started." :
1321 "Default preferences will be saved in the file:\n"
1322 "%s\n"
1323 "SAVING WILL INCORPORATE SETTINGS\n"
1324 "FROM FILE: %s", "OK", "Cancel",
1325 prefFileName, ImportedFile) == 2)
1326 return;
1328 #ifndef VMS
1329 TempStringPrefs.shellCmds = WriteShellCmdsString();
1330 #endif /* VMS */
1331 TempStringPrefs.macroCmds = WriteMacroCmdsString();
1332 TempStringPrefs.bgMenuCmds = WriteBGMenuCmdsString();
1333 TempStringPrefs.highlight = WriteHighlightString();
1334 TempStringPrefs.language = writeLanguageModesString();
1335 TempStringPrefs.styles = WriteStylesString();
1336 TempStringPrefs.smartIndent = WriteSmartIndentString();
1337 TempStringPrefs.smartIndentCommon = WriteSmartIndentCommonString();
1338 strcpy(PrefData.fileVersion, PREF_FILE_VERSION);
1339 if (!SavePreferences(XtDisplay(parent), prefFileName, HeaderText,
1340 PrefDescrip, XtNumber(PrefDescrip)))
1342 DialogF(DF_WARN, parent, 1, "Save Preferences",
1343 "Unable to save preferences in %s", "OK", prefFileName);
1346 #ifndef VMS
1347 XtFree(TempStringPrefs.shellCmds);
1348 #endif /* VMS */
1349 XtFree(TempStringPrefs.macroCmds);
1350 XtFree(TempStringPrefs.bgMenuCmds);
1351 XtFree(TempStringPrefs.highlight);
1352 XtFree(TempStringPrefs.language);
1353 XtFree(TempStringPrefs.styles);
1354 XtFree(TempStringPrefs.smartIndent);
1355 XtFree(TempStringPrefs.smartIndentCommon);
1357 PrefsHaveChanged = False;
1361 ** Load an additional preferences file on top of the existing preferences
1362 ** derived from defaults, the .nedit file, and X resources.
1364 void ImportPrefFile(const char *filename, int convertOld)
1366 XrmDatabase db;
1367 char *fileString;
1369 fileString = ReadAnyTextFile(filename);
1370 if (fileString != NULL){
1371 db = XrmGetStringDatabase(fileString);
1372 XtFree(fileString);
1373 OverlayPreferences(db, APP_NAME, APP_CLASS, PrefDescrip,
1374 XtNumber(PrefDescrip));
1375 translatePrefFormats(convertOld, -1);
1376 ImportedFile = XtNewString(filename);
1377 } else
1379 fprintf(stderr, "Could not read additional preferences file: ");
1380 fprintf(stderr, filename);
1381 fprintf(stderr, "\n");
1385 void SetPrefOpenInTab(int state)
1387 WindowInfo *w = WindowList;
1388 setIntPref(&PrefData.openInTab, state);
1389 for(; w != NULL; w = w->next)
1390 UpdateNewOppositeMenu(w, state);
1393 int GetPrefOpenInTab(void)
1395 return PrefData.openInTab;
1398 void SetPrefWrap(int state)
1400 setIntPref(&PrefData.wrapStyle, state);
1403 int GetPrefWrap(int langMode)
1405 if (langMode == PLAIN_LANGUAGE_MODE ||
1406 LanguageModes[langMode]->wrapStyle == DEFAULT_WRAP)
1407 return PrefData.wrapStyle;
1408 return LanguageModes[langMode]->wrapStyle;
1411 void SetPrefWrapMargin(int margin)
1413 setIntPref(&PrefData.wrapMargin, margin);
1416 int GetPrefWrapMargin(void)
1418 return PrefData.wrapMargin;
1421 void SetPrefSearch(int searchType)
1423 setIntPref(&PrefData.searchMethod, searchType);
1426 int GetPrefSearch(void)
1428 return PrefData.searchMethod;
1431 #ifdef REPLACE_SCOPE
1432 void SetPrefReplaceDefScope(int scope)
1434 setIntPref(&PrefData.replaceDefScope, scope);
1437 int GetPrefReplaceDefScope(void)
1439 return PrefData.replaceDefScope;
1441 #endif
1443 void SetPrefAutoIndent(int state)
1445 setIntPref(&PrefData.autoIndent, state);
1448 int GetPrefAutoIndent(int langMode)
1450 if (langMode == PLAIN_LANGUAGE_MODE ||
1451 LanguageModes[langMode]->indentStyle == DEFAULT_INDENT)
1452 return PrefData.autoIndent;
1453 return LanguageModes[langMode]->indentStyle;
1456 void SetPrefAutoSave(int state)
1458 setIntPref(&PrefData.autoSave, state);
1461 int GetPrefAutoSave(void)
1463 return PrefData.autoSave;
1466 void SetPrefSaveOldVersion(int state)
1468 setIntPref(&PrefData.saveOldVersion, state);
1471 int GetPrefSaveOldVersion(void)
1473 return PrefData.saveOldVersion;
1476 void SetPrefSearchDlogs(int state)
1478 setIntPref(&PrefData.searchDlogs, state);
1481 int GetPrefSearchDlogs(void)
1483 return PrefData.searchDlogs;
1486 void SetPrefBeepOnSearchWrap(int state)
1488 setIntPref(&PrefData.searchWrapBeep, state);
1491 int GetPrefBeepOnSearchWrap(void)
1493 return PrefData.searchWrapBeep;
1496 void SetPrefKeepSearchDlogs(int state)
1498 setIntPref(&PrefData.keepSearchDlogs, state);
1501 int GetPrefKeepSearchDlogs(void)
1503 return PrefData.keepSearchDlogs;
1506 void SetPrefSearchWraps(int state)
1508 setIntPref(&PrefData.searchWraps, state);
1511 int GetPrefStickyCaseSenseBtn(void)
1513 return PrefData.stickyCaseSenseBtn;
1516 void SetPrefStickyCaseSenseBtn(int state)
1518 setIntPref(&PrefData.stickyCaseSenseBtn, state);
1521 int GetPrefSearchWraps(void)
1523 return PrefData.searchWraps;
1526 void SetPrefStatsLine(int state)
1528 setIntPref(&PrefData.statsLine, state);
1531 int GetPrefStatsLine(void)
1533 return PrefData.statsLine;
1536 void SetPrefISearchLine(int state)
1538 setIntPref(&PrefData.iSearchLine, state);
1541 int GetPrefISearchLine(void)
1543 return PrefData.iSearchLine;
1546 void SetPrefSortTabs(int state)
1548 setIntPref(&PrefData.sortTabs, state);
1551 int GetPrefSortTabs(void)
1553 return PrefData.sortTabs;
1556 void SetPrefTabBar(int state)
1558 setIntPref(&PrefData.tabBar, state);
1561 int GetPrefTabBar(void)
1563 return PrefData.tabBar;
1566 void SetPrefTabBarHideOne(int state)
1568 setIntPref(&PrefData.tabBarHideOne, state);
1571 int GetPrefTabBarHideOne(void)
1573 return PrefData.tabBarHideOne;
1576 void SetPrefGlobalTabNavigate(int state)
1578 setIntPref(&PrefData.globalTabNavigate, state);
1581 int GetPrefGlobalTabNavigate(void)
1583 return PrefData.globalTabNavigate;
1586 void SetPrefToolTips(int state)
1588 setIntPref(&PrefData.toolTips, state);
1591 int GetPrefToolTips(void)
1593 return PrefData.toolTips;
1596 void SetPrefLineNums(int state)
1598 setIntPref(&PrefData.lineNums, state);
1601 int GetPrefLineNums(void)
1603 return PrefData.lineNums;
1606 void SetPrefShowPathInWindowsMenu(int state)
1608 setIntPref(&PrefData.pathInWindowsMenu, state);
1611 int GetPrefShowPathInWindowsMenu(void)
1613 return PrefData.pathInWindowsMenu;
1616 void SetPrefWarnFileMods(int state)
1618 setIntPref(&PrefData.warnFileMods, state);
1621 int GetPrefWarnFileMods(void)
1623 return PrefData.warnFileMods;
1626 void SetPrefWarnRealFileMods(int state)
1628 setIntPref(&PrefData.warnRealFileMods, state);
1631 int GetPrefWarnRealFileMods(void)
1633 return PrefData.warnRealFileMods;
1636 void SetPrefWarnExit(int state)
1638 setIntPref(&PrefData.warnExit, state);
1641 int GetPrefWarnExit(void)
1643 return PrefData.warnExit;
1646 void SetPrefv(int state)
1648 setIntPref(&PrefData.findReplaceUsesSelection, state);
1651 int GetPrefFindReplaceUsesSelection(void)
1653 return PrefData.findReplaceUsesSelection;
1656 void SetPrefMapDelete(int state)
1658 setIntPref(&PrefData.mapDelete, state);
1661 int GetPrefMapDelete(void)
1663 return PrefData.mapDelete;
1666 void SetPrefStdOpenDialog(int state)
1668 setIntPref(&PrefData.stdOpenDialog, state);
1671 int GetPrefStdOpenDialog(void)
1673 return PrefData.stdOpenDialog;
1676 void SetPrefRows(int nRows)
1678 setIntPref(&PrefData.textRows, nRows);
1681 int GetPrefRows(void)
1683 return PrefData.textRows;
1686 void SetPrefCols(int nCols)
1688 setIntPref(&PrefData.textCols, nCols);
1691 int GetPrefCols(void)
1693 return PrefData.textCols;
1696 void SetPrefTabDist(int tabDist)
1698 setIntPref(&PrefData.tabDist, tabDist);
1701 int GetPrefTabDist(int langMode)
1703 int tabDist;
1704 if (langMode == PLAIN_LANGUAGE_MODE ||
1705 LanguageModes[langMode]->tabDist == DEFAULT_TAB_DIST) {
1706 tabDist = PrefData.tabDist;
1707 } else {
1708 tabDist = LanguageModes[langMode]->tabDist;
1710 /* Make sure that the tab distance is in range (garbage may have
1711 been entered via the command line or the X resources, causing
1712 errors later on, like division by zero). */
1713 if (tabDist <= 0) return 1;
1714 if (tabDist > MAX_EXP_CHAR_LEN) return MAX_EXP_CHAR_LEN;
1715 return tabDist;
1718 void SetPrefEmTabDist(int tabDist)
1720 setIntPref(&PrefData.emTabDist, tabDist);
1723 int GetPrefEmTabDist(int langMode)
1725 if (langMode == PLAIN_LANGUAGE_MODE ||
1726 LanguageModes[langMode]->emTabDist == DEFAULT_EM_TAB_DIST)
1727 return PrefData.emTabDist;
1728 return LanguageModes[langMode]->emTabDist;
1731 void SetPrefInsertTabs(int state)
1733 setIntPref(&PrefData.insertTabs, state);
1736 int GetPrefInsertTabs(void)
1738 return PrefData.insertTabs;
1741 void SetPrefShowMatching(int state)
1743 setIntPref(&PrefData.showMatchingStyle, state);
1746 int GetPrefShowMatching(void)
1749 * For backwards compatibility with pre-5.2 versions, the boolean
1750 * False/True matching behavior is converted to NO_FLASH/FLASH_DELIMIT.
1752 if (PrefData.showMatchingStyle >= N_SHOW_MATCHING_STYLES)
1753 PrefData.showMatchingStyle -= N_SHOW_MATCHING_STYLES;
1754 return PrefData.showMatchingStyle;
1757 void SetPrefMatchSyntaxBased(int state)
1759 setIntPref(&PrefData.matchSyntaxBased, state);
1762 int GetPrefMatchSyntaxBased(void)
1764 return PrefData.matchSyntaxBased;
1767 void SetPrefHighlightSyntax(int state)
1769 setIntPref(&PrefData.highlightSyntax, state);
1772 int GetPrefHighlightSyntax(void)
1774 return PrefData.highlightSyntax;
1777 void SetPrefBacklightChars(int state)
1779 setIntPref(&PrefData.backlightChars, state);
1782 int GetPrefBacklightChars(void)
1784 return PrefData.backlightChars;
1787 void SetPrefBacklightCharTypes(char *types)
1789 setStringAllocPref(&PrefData.backlightCharTypes, types);
1792 char *GetPrefBacklightCharTypes(void)
1794 return PrefData.backlightCharTypes;
1797 void SetPrefRepositionDialogs(int state)
1799 setIntPref(&PrefData.repositionDialogs, state);
1802 int GetPrefRepositionDialogs(void)
1804 return PrefData.repositionDialogs;
1807 void SetPrefAutoScroll(int state)
1809 WindowInfo *w = WindowList;
1810 int margin = state ? PrefData.autoScrollVPadding : 0;
1812 setIntPref(&PrefData.autoScroll, state);
1813 for(w = WindowList; w != NULL; w = w->next)
1814 SetAutoScroll(w, margin);
1817 int GetPrefAutoScroll(void)
1819 return PrefData.autoScroll;
1822 int GetVerticalAutoScroll(void)
1824 return PrefData.autoScroll ? PrefData.autoScrollVPadding : 0;
1827 void SetPrefAppendLF(int state)
1829 setIntPref(&PrefData.appendLF, state);
1832 int GetPrefAppendLF(void)
1834 return PrefData.appendLF;
1837 void SetPrefSortOpenPrevMenu(int state)
1839 setIntPref(&PrefData.sortOpenPrevMenu, state);
1842 int GetPrefSortOpenPrevMenu(void)
1844 return PrefData.sortOpenPrevMenu;
1847 void SetPrefTagFile(const char *tagFileName)
1849 setStringPref(PrefData.tagFile, tagFileName);
1852 char *GetPrefTagFile(void)
1854 return PrefData.tagFile;
1857 void SetPrefSmartTags(int state)
1859 setIntPref(&PrefData.smartTags, state);
1862 int GetPrefSmartTags(void)
1864 return PrefData.smartTags;
1867 int GetPrefAlwaysCheckRelTagsSpecs(void)
1869 return PrefData.alwaysCheckRelativeTagsSpecs;
1872 char *GetPrefDelimiters(void)
1874 return PrefData.delimiters;
1877 char *GetPrefColorName(int index)
1879 return PrefData.colorNames[index];
1882 void SetPrefColorName(int index, const char *name)
1884 setStringPref(PrefData.colorNames[index], name);
1888 ** Set the font preferences using the font name (the fontList is generated
1889 ** in this call). Note that this leaks memory and server resources each
1890 ** time the default font is re-set. See note on SetFontByName in window.c
1891 ** for more information.
1893 void SetPrefFont(char *fontName)
1895 XFontStruct *font;
1897 setStringPref(PrefData.fontString, fontName);
1898 font = XLoadQueryFont(TheDisplay, fontName);
1899 PrefData.fontList = font==NULL ? NULL :
1900 XmFontListCreate(font, XmSTRING_DEFAULT_CHARSET);
1903 void SetPrefBoldFont(char *fontName)
1905 setStringPref(PrefData.boldFontString, fontName);
1906 PrefData.boldFontStruct = XLoadQueryFont(TheDisplay, fontName);
1909 void SetPrefItalicFont(char *fontName)
1911 setStringPref(PrefData.italicFontString, fontName);
1912 PrefData.italicFontStruct = XLoadQueryFont(TheDisplay, fontName);
1914 void SetPrefBoldItalicFont(char *fontName)
1916 setStringPref(PrefData.boldItalicFontString, fontName);
1917 PrefData.boldItalicFontStruct = XLoadQueryFont(TheDisplay, fontName);
1920 char *GetPrefFontName(void)
1922 return PrefData.fontString;
1925 char *GetPrefBoldFontName(void)
1927 return PrefData.boldFontString;
1930 char *GetPrefItalicFontName(void)
1932 return PrefData.italicFontString;
1935 char *GetPrefBoldItalicFontName(void)
1937 return PrefData.boldItalicFontString;
1940 XmFontList GetPrefFontList(void)
1942 return PrefData.fontList;
1945 XFontStruct *GetPrefBoldFont(void)
1947 return PrefData.boldFontStruct;
1950 XFontStruct *GetPrefItalicFont(void)
1952 return PrefData.italicFontStruct;
1955 XFontStruct *GetPrefBoldItalicFont(void)
1957 return PrefData.boldItalicFontStruct;
1960 char *GetPrefHelpFontName(int index)
1962 return PrefData.helpFontNames[index];
1965 char *GetPrefHelpLinkColor(void)
1967 return PrefData.helpLinkColor;
1970 char *GetPrefTooltipBgColor(void)
1972 return PrefData.tooltipBgColor;
1975 void SetPrefShell(const char *shell)
1977 setStringPref(PrefData.shell, shell);
1980 char *GetPrefShell(void)
1982 return PrefData.shell;
1985 void SetPrefGeometry(const char *geometry)
1987 setStringPref(PrefData.geometry, geometry);
1990 char *GetPrefGeometry(void)
1992 return PrefData.geometry;
1995 char *GetPrefServerName(void)
1997 return PrefData.serverName;
2000 char *GetPrefBGMenuBtn(void)
2002 return PrefData.bgMenuBtn;
2005 int GetPrefMaxPrevOpenFiles(void)
2007 return PrefData.maxPrevOpenFiles;
2010 int GetPrefTypingHidesPointer(void)
2012 return(PrefData.typingHidesPointer);
2015 #ifdef SGI_CUSTOM
2016 void SetPrefShortMenus(int state)
2018 setIntPref(&PrefData.shortMenus, state);
2021 int GetPrefShortMenus(void)
2023 return PrefData.shortMenus;
2025 #endif
2027 void SetPrefTitleFormat(const char* format)
2029 const WindowInfo* window;
2031 setStringPref(PrefData.titleFormat, format);
2033 /* update all windows */
2034 for (window=WindowList; window!=NULL; window=window->next) {
2035 UpdateWindowTitle(window);
2038 const char* GetPrefTitleFormat(void)
2040 return PrefData.titleFormat;
2043 void SetPrefUndoModifiesSelection(Boolean value)
2045 setIntPref(&PrefData.undoModifiesSelection, value);
2048 Boolean GetPrefUndoModifiesSelection(void)
2050 return (Boolean)PrefData.undoModifiesSelection;
2053 void SetPrefFocusOnRaise(Boolean value)
2055 setIntPref(&PrefData.focusOnRaise, value);
2058 Boolean GetPrefFocusOnRaise(void)
2060 return (Boolean)PrefData.focusOnRaise;
2063 int GetPrefOverrideVirtKeyBindings(void)
2065 return PrefData.virtKeyOverride;
2069 ** If preferences don't get saved, ask the user on exit whether to save
2071 void MarkPrefsChanged(void)
2073 PrefsHaveChanged = True;
2077 ** Check if preferences have changed, and if so, ask the user if he wants
2078 ** to re-save. Returns False if user requests cancelation of Exit (or whatever
2079 ** operation triggered this call to be made).
2081 int CheckPrefsChangesSaved(Widget dialogParent)
2083 int resp;
2085 if (!PrefsHaveChanged)
2086 return True;
2088 resp = DialogF(DF_WARN, dialogParent, 3, "Default Preferences",
2089 ImportedFile == NULL ?
2090 "Default Preferences have changed.\n"
2091 "Save changes to NEdit preference file?" :
2092 "Default Preferences have changed. SAVING \n"
2093 "CHANGES WILL INCORPORATE ADDITIONAL\nSETTINGS FROM FILE: %s",
2094 "Save", "Don't Save", "Cancel", ImportedFile);
2095 if (resp == 2)
2096 return True;
2097 if (resp == 3)
2098 return False;
2100 SaveNEditPrefs(dialogParent, True);
2101 return True;
2105 ** set *prefDataField to newValue, but first check if they're different
2106 ** and update PrefsHaveChanged if a preference setting has now changed.
2108 static void setIntPref(int *prefDataField, int newValue)
2110 if (newValue != *prefDataField)
2111 PrefsHaveChanged = True;
2112 *prefDataField = newValue;
2115 static void setStringPref(char *prefDataField, const char *newValue)
2117 if (strcmp(prefDataField, newValue))
2118 PrefsHaveChanged = True;
2119 strcpy(prefDataField, newValue);
2122 static void setStringAllocPref(char **pprefDataField, char *newValue)
2124 char *p_newField;
2126 /* treat empty strings as nulls */
2127 if (newValue && *newValue == '\0')
2128 newValue = NULL;
2129 if (*pprefDataField && **pprefDataField == '\0')
2130 *pprefDataField = NULL; /* assume statically alloc'ed "" */
2132 /* check changes */
2133 if (!*pprefDataField && !newValue)
2134 return;
2135 else if (!*pprefDataField && newValue)
2136 PrefsHaveChanged = True;
2137 else if (*pprefDataField && !newValue)
2138 PrefsHaveChanged = True;
2139 else if (strcmp(*pprefDataField, newValue))
2140 PrefsHaveChanged = True;
2142 /* get rid of old preference */
2143 if (*pprefDataField)
2144 XtFree(*pprefDataField);
2146 /* store new preference */
2147 if (newValue) {
2148 p_newField = XtMalloc(strlen(newValue) + 1);
2149 strcpy(p_newField, newValue);
2151 *pprefDataField = newValue;
2155 ** Set the language mode for the window, update the menu and trigger language
2156 ** mode specific actions (turn on/off highlighting). If forceNewDefaults is
2157 ** true, re-establish default settings for language-specific preferences
2158 ** regardless of whether they were previously set by the user.
2160 void SetLanguageMode(WindowInfo *window, int mode, int forceNewDefaults)
2162 Widget menu;
2163 WidgetList items;
2164 int n;
2165 Cardinal nItems;
2166 void *userData;
2168 /* Do mode-specific actions */
2169 reapplyLanguageMode(window, mode, forceNewDefaults);
2171 /* Select the correct language mode in the sub-menu */
2172 if (IsTopDocument(window)) {
2173 XtVaGetValues(window->langModeCascade, XmNsubMenuId, &menu, NULL);
2174 XtVaGetValues(menu, XmNchildren, &items, XmNnumChildren, &nItems, NULL);
2175 for (n=0; n<(int)nItems; n++) {
2176 XtVaGetValues(items[n], XmNuserData, &userData, NULL);
2177 XmToggleButtonSetState(items[n], (int)userData == mode, False);
2183 ** Lookup a language mode by name, returning the index of the language
2184 ** mode or PLAIN_LANGUAGE_MODE if the name is not found
2186 int FindLanguageMode(const char *languageName)
2188 int i;
2190 /* Compare each language mode to the one we were presented */
2191 for (i=0; i<NLanguageModes; i++)
2192 if (!strcmp(languageName, LanguageModes[i]->name))
2193 return i;
2195 return PLAIN_LANGUAGE_MODE;
2200 ** Apply language mode matching criteria and set window->languageMode to
2201 ** the appropriate mode for the current file, trigger language mode
2202 ** specific actions (turn on/off highlighting), and update the language
2203 ** mode menu item. If forceNewDefaults is true, re-establish default
2204 ** settings for language-specific preferences regardless of whether
2205 ** they were previously set by the user.
2207 void DetermineLanguageMode(WindowInfo *window, int forceNewDefaults)
2209 SetLanguageMode(window, matchLanguageMode(window), forceNewDefaults);
2213 ** Return the name of the current language mode set in "window", or NULL
2214 ** if the current mode is "Plain".
2216 char *LanguageModeName(int mode)
2218 if (mode == PLAIN_LANGUAGE_MODE)
2219 return NULL;
2220 else
2221 return LanguageModes[mode]->name;
2225 ** Get the set of word delimiters for the language mode set in the current
2226 ** window. Returns NULL when no language mode is set (it would be easy to
2227 ** return the default delimiter set when the current language mode is "Plain",
2228 ** or the mode doesn't have its own delimiters, but this is usually used
2229 ** to supply delimiters for RE searching, and ExecRE can skip compiling a
2230 ** delimiter table when delimiters is NULL).
2232 char *GetWindowDelimiters(WindowInfo *window)
2234 if (window->languageMode == PLAIN_LANGUAGE_MODE)
2235 return NULL;
2236 else
2237 return LanguageModes[window->languageMode]->delimiters;
2241 ** Put up a dialog for selecting a custom initial window size
2243 void RowColumnPrefDialog(Widget parent)
2245 Widget form, selBox, topLabel;
2246 Arg selBoxArgs[2];
2247 XmString s1;
2249 XtSetArg(selBoxArgs[0], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL);
2250 XtSetArg(selBoxArgs[1], XmNautoUnmanage, False);
2251 selBox = CreatePromptDialog(parent, "customSize", selBoxArgs, 2);
2252 XtAddCallback(selBox, XmNokCallback, (XtCallbackProc)sizeOKCB, NULL);
2253 XtAddCallback(selBox, XmNcancelCallback, (XtCallbackProc)sizeCancelCB,NULL);
2254 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_TEXT));
2255 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_SELECTION_LABEL));
2256 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_HELP_BUTTON));
2257 XtVaSetValues(XtParent(selBox), XmNtitle, "Initial Window Size", NULL);
2259 form = XtVaCreateManagedWidget("form", xmFormWidgetClass, selBox, NULL);
2261 topLabel = XtVaCreateManagedWidget("topLabel", xmLabelGadgetClass, form,
2262 XmNlabelString, s1=MKSTRING(
2263 "Enter desired size in rows\nand columns of characters:"), NULL);
2264 XmStringFree(s1);
2266 RowText = XtVaCreateManagedWidget("rows", xmTextWidgetClass, form,
2267 XmNcolumns, 3,
2268 XmNtopAttachment, XmATTACH_WIDGET,
2269 XmNleftAttachment, XmATTACH_POSITION,
2270 XmNrightAttachment, XmATTACH_POSITION,
2271 XmNtopWidget, topLabel,
2272 XmNleftPosition, 5,
2273 XmNrightPosition, 45, NULL);
2274 RemapDeleteKey(RowText);
2276 XtVaCreateManagedWidget("xLabel", xmLabelGadgetClass, form,
2277 XmNlabelString, s1=MKSTRING("x"),
2278 XmNtopAttachment, XmATTACH_WIDGET,
2279 XmNleftAttachment, XmATTACH_POSITION,
2280 XmNrightAttachment, XmATTACH_POSITION,
2281 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
2282 XmNtopWidget, topLabel,
2283 XmNbottomWidget, RowText,
2284 XmNleftPosition, 45,
2285 XmNrightPosition, 55, NULL);
2286 XmStringFree(s1);
2288 ColText = XtVaCreateManagedWidget("cols", xmTextWidgetClass, form,
2289 XmNcolumns, 3,
2290 XmNtopAttachment, XmATTACH_WIDGET,
2291 XmNleftAttachment, XmATTACH_POSITION,
2292 XmNrightAttachment, XmATTACH_POSITION,
2293 XmNtopWidget, topLabel,
2294 XmNleftPosition, 55,
2295 XmNrightPosition, 95, NULL);
2296 RemapDeleteKey(ColText);
2298 /* put up dialog and wait for user to press ok or cancel */
2299 DoneWithSizeDialog = False;
2300 ManageDialogCenteredOnPointer(selBox);
2301 while (!DoneWithSizeDialog)
2303 XEvent event;
2304 XtAppNextEvent(XtWidgetToApplicationContext(parent), &event);
2305 ServerDispatchEvent(&event);
2308 XtDestroyWidget(selBox);
2311 static void sizeOKCB(Widget w, XtPointer clientData, XtPointer callData)
2313 int rowValue, colValue, stat;
2315 /* get the values that the user entered and make sure they're ok */
2316 stat = GetIntTextWarn(RowText, &rowValue, "number of rows", True);
2317 if (stat != TEXT_READ_OK)
2318 return;
2319 stat = GetIntTextWarn(ColText, &colValue, "number of columns", True);
2320 if (stat != TEXT_READ_OK)
2321 return;
2323 /* set the corresponding preferences and dismiss the dialog */
2324 SetPrefRows(rowValue);
2325 SetPrefCols(colValue);
2326 DoneWithSizeDialog = True;
2329 static void sizeCancelCB(Widget w, XtPointer clientData, XtPointer callData)
2331 DoneWithSizeDialog = True;
2335 ** Present the user a dialog for setting tab related preferences, either as
2336 ** defaults, or for a specific window (pass "forWindow" as NULL to set default
2337 ** preference, or a window to set preferences for the specific window.
2339 void TabsPrefDialog(Widget parent, WindowInfo *forWindow)
2341 Widget form, selBox;
2342 Arg selBoxArgs[2];
2343 XmString s1;
2344 int emulate, emTabDist, useTabs, tabDist;
2346 XtSetArg(selBoxArgs[0], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL);
2347 XtSetArg(selBoxArgs[1], XmNautoUnmanage, False);
2348 selBox = CreatePromptDialog(parent, "customSize", selBoxArgs, 2);
2349 XtAddCallback(selBox, XmNokCallback, (XtCallbackProc)tabsOKCB, NULL);
2350 XtAddCallback(selBox, XmNcancelCallback, (XtCallbackProc)tabsCancelCB,NULL);
2351 XtAddCallback(selBox, XmNhelpCallback, (XtCallbackProc)tabsHelpCB,NULL);
2352 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_TEXT));
2353 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_SELECTION_LABEL));
2354 XtVaSetValues(XtParent(selBox), XmNtitle, "Tabs", NULL);
2356 form = XtVaCreateManagedWidget("form", xmFormWidgetClass, selBox, NULL);
2358 TabDistText = XtVaCreateManagedWidget("tabDistText", xmTextWidgetClass,
2359 form, XmNcolumns, 7,
2360 XmNtopAttachment, XmATTACH_FORM,
2361 XmNrightAttachment, XmATTACH_FORM, NULL);
2362 RemapDeleteKey(TabDistText);
2363 XtVaCreateManagedWidget("tabDistLabel", xmLabelGadgetClass, form,
2364 XmNlabelString, s1=XmStringCreateSimple(
2365 "Tab spacing (for hardware tab characters)"),
2366 XmNmnemonic, 'T',
2367 XmNuserData, TabDistText,
2368 XmNtopAttachment, XmATTACH_FORM,
2369 XmNleftAttachment, XmATTACH_FORM,
2370 XmNrightAttachment, XmATTACH_WIDGET,
2371 XmNrightWidget, TabDistText,
2372 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
2373 XmNbottomWidget, TabDistText, NULL);
2374 XmStringFree(s1);
2376 EmTabText = XtVaCreateManagedWidget("emTabText", xmTextWidgetClass, form,
2377 XmNcolumns, 7,
2378 XmNtopAttachment, XmATTACH_WIDGET,
2379 XmNtopWidget, TabDistText,
2380 XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET,
2381 XmNrightWidget, TabDistText, NULL);
2382 RemapDeleteKey(EmTabText);
2383 EmTabLabel = XtVaCreateManagedWidget("emTabLabel", xmLabelGadgetClass, form,
2384 XmNlabelString, s1=XmStringCreateSimple("Emulated tab spacing"),
2385 XmNmnemonic, 's',
2386 XmNuserData, EmTabText,
2387 XmNtopAttachment, XmATTACH_WIDGET,
2388 XmNtopWidget, TabDistText,
2389 XmNrightAttachment, XmATTACH_WIDGET,
2390 XmNrightWidget, EmTabText,
2391 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
2392 XmNbottomWidget, EmTabText, NULL);
2393 XmStringFree(s1);
2394 EmTabToggle = XtVaCreateManagedWidget("emTabToggle",
2395 xmToggleButtonWidgetClass, form, XmNlabelString,
2396 s1=XmStringCreateSimple("Emulate tabs"),
2397 XmNmnemonic, 'E',
2398 XmNtopAttachment, XmATTACH_WIDGET,
2399 XmNtopWidget, TabDistText,
2400 XmNleftAttachment, XmATTACH_FORM,
2401 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
2402 XmNbottomWidget, EmTabText, NULL);
2403 XmStringFree(s1);
2404 XtAddCallback(EmTabToggle, XmNvalueChangedCallback, emTabsCB, NULL);
2405 UseTabsToggle = XtVaCreateManagedWidget("useTabsToggle",
2406 xmToggleButtonWidgetClass, form,
2407 XmNlabelString, s1=XmStringCreateSimple(
2408 "Use tab characters in padding and emulated tabs"),
2409 XmNmnemonic, 'U',
2410 XmNtopAttachment, XmATTACH_WIDGET,
2411 XmNtopWidget, EmTabText,
2412 XmNtopOffset, 5,
2413 XmNleftAttachment, XmATTACH_FORM, NULL);
2414 XmStringFree(s1);
2416 /* Set default values */
2417 if (forWindow == NULL) {
2418 emTabDist = GetPrefEmTabDist(PLAIN_LANGUAGE_MODE);
2419 useTabs = GetPrefInsertTabs();
2420 tabDist = GetPrefTabDist(PLAIN_LANGUAGE_MODE);
2421 } else {
2422 XtVaGetValues(forWindow->textArea, textNemulateTabs, &emTabDist, NULL);
2423 useTabs = forWindow->buffer->useTabs;
2424 tabDist = BufGetTabDistance(forWindow->buffer);
2426 emulate = emTabDist != 0;
2427 SetIntText(TabDistText, tabDist);
2428 XmToggleButtonSetState(EmTabToggle, emulate, True);
2429 if (emulate)
2430 SetIntText(EmTabText, emTabDist);
2431 XmToggleButtonSetState(UseTabsToggle, useTabs, False);
2432 XtSetSensitive(EmTabText, emulate);
2433 XtSetSensitive(EmTabLabel, emulate);
2435 /* Handle mnemonic selection of buttons and focus to dialog */
2436 AddDialogMnemonicHandler(form, FALSE);
2438 /* Set the widget to get focus */
2439 #if XmVersion >= 1002
2440 XtVaSetValues(form, XmNinitialFocus, TabDistText, NULL);
2441 #endif
2443 /* put up dialog and wait for user to press ok or cancel */
2444 TabsDialogForWindow = forWindow;
2445 DoneWithTabsDialog = False;
2446 ManageDialogCenteredOnPointer(selBox);
2447 while (!DoneWithTabsDialog)
2449 XEvent event;
2450 XtAppNextEvent(XtWidgetToApplicationContext(parent), &event);
2451 ServerDispatchEvent(&event);
2454 XtDestroyWidget(selBox);
2457 static void tabsOKCB(Widget w, XtPointer clientData, XtPointer callData)
2459 int emulate, useTabs, stat, tabDist, emTabDist;
2460 WindowInfo *window = TabsDialogForWindow;
2462 /* get the values that the user entered and make sure they're ok */
2463 emulate = XmToggleButtonGetState(EmTabToggle);
2464 useTabs = XmToggleButtonGetState(UseTabsToggle);
2465 stat = GetIntTextWarn(TabDistText, &tabDist, "tab spacing", True);
2466 if (stat != TEXT_READ_OK)
2467 return;
2469 if (tabDist <= 0 || tabDist > MAX_EXP_CHAR_LEN)
2471 DialogF(DF_WARN, TabDistText, 1, "Tab Spacing",
2472 "Tab spacing out of range", "OK");
2473 return;
2476 if (emulate) {
2477 stat = GetIntTextWarn(EmTabText, &emTabDist, "emulated tab spacing",True);
2478 if (stat != TEXT_READ_OK)
2479 return;
2481 if (emTabDist <= 0 || tabDist >= 1000)
2483 DialogF(DF_WARN, EmTabText, 1, "Tab Spacing",
2484 "Emulated tab spacing out of range", "OK");
2485 return;
2487 } else
2488 emTabDist = 0;
2490 #ifdef SGI_CUSTOM
2491 /* Ask the user about saving as a default preference */
2492 if (TabsDialogForWindow != NULL) {
2493 int setDefault;
2494 if (!shortPrefToDefault(window->shell, "Tab Settings", &setDefault)) {
2495 DoneWithTabsDialog = True;
2496 return;
2498 if (setDefault) {
2499 SetPrefTabDist(tabDist);
2500 SetPrefEmTabDist(emTabDist);
2501 SetPrefInsertTabs(useTabs);
2502 SaveNEditPrefs(window->shell, GetPrefShortMenus());
2505 #endif
2507 /* Set the value in either the requested window or default preferences */
2508 if (TabsDialogForWindow == NULL) {
2509 SetPrefTabDist(tabDist);
2510 SetPrefEmTabDist(emTabDist);
2511 SetPrefInsertTabs(useTabs);
2512 } else {
2513 char *params[1];
2514 char numStr[25];
2516 params[0] = numStr;
2517 sprintf(numStr, "%d", tabDist);
2518 XtCallActionProc(window->textArea, "set_tab_dist", NULL, params, 1);
2519 params[0] = numStr;
2520 sprintf(numStr, "%d", emTabDist);
2521 XtCallActionProc(window->textArea, "set_em_tab_dist", NULL, params, 1);
2522 params[0] = numStr;
2523 sprintf(numStr, "%d", useTabs);
2524 XtCallActionProc(window->textArea, "set_use_tabs", NULL, params, 1);
2526 setTabDist(window, tabDist);
2527 setEmTabDist(window, emTabDist);
2528 window->buffer->useTabs = useTabs;
2531 DoneWithTabsDialog = True;
2534 static void tabsCancelCB(Widget w, XtPointer clientData, XtPointer callData)
2536 DoneWithTabsDialog = True;
2539 static void tabsHelpCB(Widget w, XtPointer clientData, XtPointer callData)
2541 Help(HELP_TABS_DIALOG);
2544 static void emTabsCB(Widget w, XtPointer clientData, XtPointer callData)
2546 int state = XmToggleButtonGetState(w);
2548 XtSetSensitive(EmTabLabel, state);
2549 XtSetSensitive(EmTabText, state);
2553 ** Present the user a dialog for setting wrap margin.
2555 void WrapMarginDialog(Widget parent, WindowInfo *forWindow)
2557 Widget form, selBox;
2558 Arg selBoxArgs[2];
2559 XmString s1;
2560 int margin;
2562 XtSetArg(selBoxArgs[0], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL);
2563 XtSetArg(selBoxArgs[1], XmNautoUnmanage, False);
2564 selBox = CreatePromptDialog(parent, "wrapMargin", selBoxArgs, 2);
2565 XtAddCallback(selBox, XmNokCallback, (XtCallbackProc)wrapOKCB, NULL);
2566 XtAddCallback(selBox, XmNcancelCallback, (XtCallbackProc)wrapCancelCB,NULL);
2567 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_TEXT));
2568 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_SELECTION_LABEL));
2569 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_HELP_BUTTON));
2570 XtVaSetValues(XtParent(selBox), XmNtitle, "Wrap Margin", NULL);
2572 form = XtVaCreateManagedWidget("form", xmFormWidgetClass, selBox, NULL);
2574 WrapWindowToggle = XtVaCreateManagedWidget("wrapWindowToggle",
2575 xmToggleButtonWidgetClass, form, XmNlabelString,
2576 s1=XmStringCreateSimple("Wrap and Fill at width of window"),
2577 XmNmnemonic, 'W',
2578 XmNtopAttachment, XmATTACH_FORM,
2579 XmNleftAttachment, XmATTACH_FORM, NULL);
2580 XmStringFree(s1);
2581 XtAddCallback(WrapWindowToggle, XmNvalueChangedCallback, wrapWindowCB,NULL);
2582 WrapText = XtVaCreateManagedWidget("wrapText", xmTextWidgetClass, form,
2583 XmNcolumns, 5,
2584 XmNtopAttachment, XmATTACH_WIDGET,
2585 XmNtopWidget, WrapWindowToggle,
2586 XmNrightAttachment, XmATTACH_FORM, NULL);
2587 RemapDeleteKey(WrapText);
2588 WrapTextLabel = XtVaCreateManagedWidget("wrapMarginLabel",
2589 xmLabelGadgetClass, form,
2590 XmNlabelString, s1=XmStringCreateSimple(
2591 "Margin for Wrap and Fill"),
2592 XmNmnemonic, 'M',
2593 XmNuserData, WrapText,
2594 XmNtopAttachment, XmATTACH_WIDGET,
2595 XmNtopWidget, WrapWindowToggle,
2596 XmNleftAttachment, XmATTACH_FORM,
2597 XmNrightAttachment, XmATTACH_WIDGET,
2598 XmNrightWidget, WrapText,
2599 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
2600 XmNbottomWidget, WrapText, NULL);
2601 XmStringFree(s1);
2603 /* Set default value */
2604 if (forWindow == NULL)
2605 margin = GetPrefWrapMargin();
2606 else
2607 XtVaGetValues(forWindow->textArea, textNwrapMargin, &margin, NULL);
2608 XmToggleButtonSetState(WrapWindowToggle, margin==0, True);
2609 if (margin != 0)
2610 SetIntText(WrapText, margin);
2611 XtSetSensitive(WrapText, margin!=0);
2612 XtSetSensitive(WrapTextLabel, margin!=0);
2614 /* Handle mnemonic selection of buttons and focus to dialog */
2615 AddDialogMnemonicHandler(form, FALSE);
2617 /* put up dialog and wait for user to press ok or cancel */
2618 WrapDialogForWindow = forWindow;
2619 DoneWithWrapDialog = False;
2620 ManageDialogCenteredOnPointer(selBox);
2621 while (!DoneWithWrapDialog)
2623 XEvent event;
2624 XtAppNextEvent(XtWidgetToApplicationContext(parent), &event);
2625 ServerDispatchEvent(&event);
2628 XtDestroyWidget(selBox);
2631 static void wrapOKCB(Widget w, XtPointer clientData, XtPointer callData)
2633 int wrapAtWindow, margin, stat;
2634 WindowInfo *window = WrapDialogForWindow;
2636 /* get the values that the user entered and make sure they're ok */
2637 wrapAtWindow = XmToggleButtonGetState(WrapWindowToggle);
2638 if (wrapAtWindow)
2639 margin = 0;
2640 else {
2641 stat = GetIntTextWarn(WrapText, &margin, "wrap Margin", True);
2642 if (stat != TEXT_READ_OK)
2643 return;
2645 if (margin <= 0 || margin >= 1000)
2647 DialogF(DF_WARN, WrapText, 1, "Wrap Margin",
2648 "Wrap margin out of range", "OK");
2649 return;
2654 #ifdef SGI_CUSTOM
2655 /* Ask the user about saving as a default preference */
2656 if (WrapDialogForWindow != NULL) {
2657 int setDefault;
2658 if (!shortPrefToDefault(window->shell, "Wrap Margin Settings",
2659 &setDefault)) {
2660 DoneWithWrapDialog = True;
2661 return;
2663 if (setDefault) {
2664 SetPrefWrapMargin(margin);
2665 SaveNEditPrefs(window->shell, GetPrefShortMenus());
2668 #endif
2670 /* Set the value in either the requested window or default preferences */
2671 if (WrapDialogForWindow == NULL)
2672 SetPrefWrapMargin(margin);
2673 else {
2674 char *params[1];
2675 char marginStr[25];
2676 sprintf(marginStr, "%d", margin);
2677 params[0] = marginStr;
2678 XtCallActionProc(window->textArea, "set_wrap_margin", NULL, params, 1);
2680 DoneWithWrapDialog = True;
2683 static void wrapCancelCB(Widget w, XtPointer clientData, XtPointer callData)
2685 DoneWithWrapDialog = True;
2688 static void wrapWindowCB(Widget w, XtPointer clientData, XtPointer callData)
2690 int wrapAtWindow = XmToggleButtonGetState(w);
2692 XtSetSensitive(WrapTextLabel, !wrapAtWindow);
2693 XtSetSensitive(WrapText, !wrapAtWindow);
2697 ** Present a dialog for editing language mode information
2699 void EditLanguageModes(void)
2701 #define LIST_RIGHT 40
2702 #define LEFT_MARGIN_POS 1
2703 #define RIGHT_MARGIN_POS 99
2704 #define H_MARGIN 5
2705 Widget form, nameLbl, topLbl, extLbl, recogLbl, delimitLbl, defTipsLbl;
2706 Widget okBtn, applyBtn, closeBtn;
2707 Widget overrideFrame, overrideForm, delimitForm;
2708 Widget tabForm, tabLbl, indentBox, wrapBox;
2709 XmString s1;
2710 int i, ac;
2711 Arg args[20];
2713 /* if the dialog is already displayed, just pop it to the top and return */
2714 if (LMDialog.shell != NULL) {
2715 RaiseDialogWindow(LMDialog.shell);
2716 return;
2719 LMDialog.languageModeList = (languageModeRec **)XtMalloc(
2720 sizeof(languageModeRec *) * MAX_LANGUAGE_MODES);
2721 for (i=0; i<NLanguageModes; i++)
2722 LMDialog.languageModeList[i] = copyLanguageModeRec(LanguageModes[i]);
2723 LMDialog.nLanguageModes = NLanguageModes;
2725 /* Create a form widget in an application shell */
2726 ac = 0;
2727 XtSetArg(args[ac], XmNdeleteResponse, XmDO_NOTHING); ac++;
2728 XtSetArg(args[ac], XmNiconName, "NEdit Language Modes"); ac++;
2729 XtSetArg(args[ac], XmNtitle, "Language Modes"); ac++;
2730 LMDialog.shell = CreateWidget(TheAppShell, "langModes",
2731 topLevelShellWidgetClass, args, ac);
2732 AddSmallIcon(LMDialog.shell);
2733 form = XtVaCreateManagedWidget("editLanguageModes", xmFormWidgetClass,
2734 LMDialog.shell, XmNautoUnmanage, False,
2735 XmNresizePolicy, XmRESIZE_NONE, NULL);
2736 XtAddCallback(form, XmNdestroyCallback, lmDestroyCB, NULL);
2737 AddMotifCloseCallback(LMDialog.shell, lmCloseCB, NULL);
2739 topLbl = XtVaCreateManagedWidget("topLabel", xmLabelGadgetClass, form,
2740 XmNlabelString, s1=MKSTRING(
2741 "To modify the properties of an existing language mode, select the name from\n\
2742 the list on the left. To add a new language, select \"New\" from the list."),
2743 XmNmnemonic, 'N',
2744 XmNtopAttachment, XmATTACH_POSITION,
2745 XmNtopPosition, 2,
2746 XmNleftAttachment, XmATTACH_POSITION,
2747 XmNleftPosition, LEFT_MARGIN_POS,
2748 XmNrightAttachment, XmATTACH_POSITION,
2749 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
2750 XmStringFree(s1);
2752 nameLbl = XtVaCreateManagedWidget("nameLbl", xmLabelGadgetClass, form,
2753 XmNlabelString, s1=XmStringCreateSimple("Name"),
2754 XmNmnemonic, 'm',
2755 XmNalignment, XmALIGNMENT_BEGINNING,
2756 XmNleftAttachment, XmATTACH_POSITION,
2757 XmNleftPosition, LIST_RIGHT,
2758 XmNtopAttachment, XmATTACH_WIDGET,
2759 XmNtopOffset, H_MARGIN,
2760 XmNtopWidget, topLbl, NULL);
2761 XmStringFree(s1);
2763 LMDialog.nameW = XtVaCreateManagedWidget("name", xmTextWidgetClass, form,
2764 XmNcolumns, 15,
2765 XmNleftAttachment, XmATTACH_POSITION,
2766 XmNleftPosition, LIST_RIGHT,
2767 XmNtopAttachment, XmATTACH_WIDGET,
2768 XmNtopWidget, nameLbl,
2769 XmNrightAttachment, XmATTACH_POSITION,
2770 XmNrightPosition, (RIGHT_MARGIN_POS + LIST_RIGHT)/2, NULL);
2771 RemapDeleteKey(LMDialog.nameW);
2772 XtVaSetValues(nameLbl, XmNuserData, LMDialog.nameW, NULL);
2774 extLbl = XtVaCreateManagedWidget("extLbl", xmLabelGadgetClass, form,
2775 XmNlabelString,
2776 s1=XmStringCreateSimple("File extensions (separate w/ space)"),
2777 XmNmnemonic, 'F',
2778 XmNalignment, XmALIGNMENT_BEGINNING,
2779 XmNleftAttachment, XmATTACH_POSITION,
2780 XmNleftPosition, LIST_RIGHT,
2781 XmNtopAttachment, XmATTACH_WIDGET,
2782 XmNtopOffset, H_MARGIN,
2783 XmNtopWidget, LMDialog.nameW, NULL);
2784 XmStringFree(s1);
2786 LMDialog.extW = XtVaCreateManagedWidget("ext", xmTextWidgetClass, form,
2787 XmNleftAttachment, XmATTACH_POSITION,
2788 XmNleftPosition, LIST_RIGHT,
2789 XmNtopAttachment, XmATTACH_WIDGET,
2790 XmNtopWidget, extLbl,
2791 XmNrightAttachment, XmATTACH_POSITION,
2792 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
2793 RemapDeleteKey(LMDialog.extW);
2794 XtVaSetValues(extLbl, XmNuserData, LMDialog.extW, NULL);
2796 recogLbl = XtVaCreateManagedWidget("recogLbl", xmLabelGadgetClass, form,
2797 XmNlabelString, s1=MKSTRING(
2798 "Recognition regular expression (applied to first 200\n\
2799 characters of file to determine type from content)"),
2800 XmNalignment, XmALIGNMENT_BEGINNING,
2801 XmNmnemonic, 'R',
2802 XmNleftAttachment, XmATTACH_POSITION,
2803 XmNleftPosition, LIST_RIGHT,
2804 XmNtopAttachment, XmATTACH_WIDGET,
2805 XmNtopOffset, H_MARGIN,
2806 XmNtopWidget, LMDialog.extW, NULL);
2807 XmStringFree(s1);
2809 LMDialog.recogW = XtVaCreateManagedWidget("recog", xmTextWidgetClass, form,
2810 XmNleftAttachment, XmATTACH_POSITION,
2811 XmNleftPosition, LIST_RIGHT,
2812 XmNtopAttachment, XmATTACH_WIDGET,
2813 XmNtopWidget, recogLbl,
2814 XmNrightAttachment, XmATTACH_POSITION,
2815 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
2816 RemapDeleteKey(LMDialog.recogW);
2817 XtVaSetValues(recogLbl, XmNuserData, LMDialog.recogW, NULL);
2819 defTipsLbl = XtVaCreateManagedWidget("defTipsLbl", xmLabelGadgetClass, form,
2820 XmNlabelString, s1=MKSTRING(
2821 "Default calltips file(s) (separate w/colons)"),
2822 XmNalignment, XmALIGNMENT_BEGINNING,
2823 XmNmnemonic, 'c',
2824 XmNleftAttachment, XmATTACH_POSITION,
2825 XmNleftPosition, LIST_RIGHT,
2826 XmNtopAttachment, XmATTACH_WIDGET,
2827 XmNtopOffset, H_MARGIN,
2828 XmNtopWidget, LMDialog.recogW, NULL);
2829 XmStringFree(s1);
2831 LMDialog.defTipsW = XtVaCreateManagedWidget("defTips", xmTextWidgetClass,
2832 form,
2833 XmNleftAttachment, XmATTACH_POSITION,
2834 XmNleftPosition, LIST_RIGHT,
2835 XmNtopAttachment, XmATTACH_WIDGET,
2836 XmNtopWidget, defTipsLbl,
2837 XmNrightAttachment, XmATTACH_POSITION,
2838 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
2839 RemapDeleteKey(LMDialog.defTipsW);
2840 XtVaSetValues(defTipsLbl, XmNuserData, LMDialog.defTipsW, NULL);
2842 okBtn = XtVaCreateManagedWidget("ok", xmPushButtonWidgetClass, form,
2843 XmNlabelString, s1=XmStringCreateSimple("OK"),
2844 XmNmarginWidth, BUTTON_WIDTH_MARGIN,
2845 XmNleftAttachment, XmATTACH_POSITION,
2846 XmNleftPosition, 10,
2847 XmNrightAttachment, XmATTACH_POSITION,
2848 XmNrightPosition, 30,
2849 XmNbottomAttachment, XmATTACH_POSITION,
2850 XmNbottomPosition, 99, NULL);
2851 XtAddCallback(okBtn, XmNactivateCallback, lmOkCB, NULL);
2852 XmStringFree(s1);
2854 applyBtn = XtVaCreateManagedWidget("apply", xmPushButtonWidgetClass, form,
2855 XmNlabelString, s1=XmStringCreateSimple("Apply"),
2856 XmNmnemonic, 'A',
2857 XmNleftAttachment, XmATTACH_POSITION,
2858 XmNleftPosition, 40,
2859 XmNrightAttachment, XmATTACH_POSITION,
2860 XmNrightPosition, 60,
2861 XmNbottomAttachment, XmATTACH_POSITION,
2862 XmNbottomPosition, 99, NULL);
2863 XtAddCallback(applyBtn, XmNactivateCallback, lmApplyCB, NULL);
2864 XmStringFree(s1);
2866 closeBtn = XtVaCreateManagedWidget("close",xmPushButtonWidgetClass,form,
2867 XmNlabelString, s1=XmStringCreateSimple("Close"),
2868 XmNleftAttachment, XmATTACH_POSITION,
2869 XmNleftPosition, 70,
2870 XmNrightAttachment, XmATTACH_POSITION,
2871 XmNrightPosition, 90,
2872 XmNbottomAttachment, XmATTACH_POSITION,
2873 XmNbottomPosition, 99, NULL);
2874 XtAddCallback(closeBtn, XmNactivateCallback, lmCloseCB, NULL);
2875 XmStringFree(s1);
2877 overrideFrame = XtVaCreateManagedWidget("overrideFrame",
2878 xmFrameWidgetClass, form,
2879 XmNleftAttachment, XmATTACH_POSITION,
2880 XmNleftPosition, LEFT_MARGIN_POS,
2881 XmNrightAttachment, XmATTACH_POSITION,
2882 XmNrightPosition, RIGHT_MARGIN_POS,
2883 XmNbottomAttachment, XmATTACH_WIDGET,
2884 XmNbottomWidget, closeBtn,
2885 XmNbottomOffset, H_MARGIN, NULL);
2886 overrideForm = XtVaCreateManagedWidget("overrideForm", xmFormWidgetClass,
2887 overrideFrame, NULL);
2888 XtVaCreateManagedWidget("overrideLbl", xmLabelGadgetClass, overrideFrame,
2889 XmNlabelString, s1=XmStringCreateSimple("Override Defaults"),
2890 XmNchildType, XmFRAME_TITLE_CHILD,
2891 XmNchildHorizontalAlignment, XmALIGNMENT_CENTER, NULL);
2892 XmStringFree(s1);
2894 delimitForm = XtVaCreateManagedWidget("delimitForm", xmFormWidgetClass,
2895 overrideForm,
2896 XmNleftAttachment, XmATTACH_POSITION,
2897 XmNleftPosition, LEFT_MARGIN_POS,
2898 XmNtopAttachment, XmATTACH_FORM,
2899 XmNtopOffset, H_MARGIN,
2900 XmNrightAttachment, XmATTACH_POSITION,
2901 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
2902 delimitLbl = XtVaCreateManagedWidget("delimitLbl", xmLabelGadgetClass,
2903 delimitForm,
2904 XmNlabelString, s1=XmStringCreateSimple("Word delimiters"),
2905 XmNmnemonic, 'W',
2906 XmNleftAttachment, XmATTACH_FORM,
2907 XmNtopAttachment, XmATTACH_FORM,
2908 XmNbottomAttachment, XmATTACH_FORM, NULL);
2909 XmStringFree(s1);
2910 LMDialog.delimitW = XtVaCreateManagedWidget("delimit", xmTextWidgetClass,
2911 delimitForm,
2912 XmNtopAttachment, XmATTACH_FORM,
2913 XmNleftAttachment, XmATTACH_WIDGET,
2914 XmNleftWidget, delimitLbl,
2915 XmNrightAttachment, XmATTACH_FORM,
2916 XmNbottomAttachment, XmATTACH_FORM, NULL);
2917 RemapDeleteKey(LMDialog.delimitW);
2918 XtVaSetValues(delimitLbl, XmNuserData, LMDialog.delimitW, NULL);
2920 tabForm = XtVaCreateManagedWidget("tabForm", xmFormWidgetClass,
2921 overrideForm,
2922 XmNleftAttachment, XmATTACH_POSITION,
2923 XmNleftPosition, LEFT_MARGIN_POS,
2924 XmNtopAttachment, XmATTACH_WIDGET,
2925 XmNtopWidget, delimitForm,
2926 XmNtopOffset, H_MARGIN,
2927 XmNrightAttachment, XmATTACH_POSITION,
2928 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
2929 tabLbl = XtVaCreateManagedWidget("tabLbl", xmLabelGadgetClass, tabForm,
2930 XmNlabelString, s1=XmStringCreateSimple(
2931 "Alternative hardware tab spacing"),
2932 XmNmnemonic, 't',
2933 XmNleftAttachment, XmATTACH_FORM,
2934 XmNtopAttachment, XmATTACH_FORM,
2935 XmNbottomAttachment, XmATTACH_FORM, NULL);
2936 XmStringFree(s1);
2937 LMDialog.tabW = XtVaCreateManagedWidget("delimit", xmTextWidgetClass,
2938 tabForm,
2939 XmNcolumns, 3,
2940 XmNtopAttachment, XmATTACH_FORM,
2941 XmNleftAttachment, XmATTACH_WIDGET,
2942 XmNleftWidget, tabLbl,
2943 XmNbottomAttachment, XmATTACH_FORM, NULL);
2944 RemapDeleteKey(LMDialog.tabW);
2945 XtVaSetValues(tabLbl, XmNuserData, LMDialog.tabW, NULL);
2946 LMDialog.emTabW = XtVaCreateManagedWidget("delimit", xmTextWidgetClass,
2947 tabForm,
2948 XmNcolumns, 3,
2949 XmNtopAttachment, XmATTACH_FORM,
2950 XmNrightAttachment, XmATTACH_FORM,
2951 XmNbottomAttachment, XmATTACH_FORM, NULL);
2952 RemapDeleteKey(LMDialog.emTabW);
2953 XtVaCreateManagedWidget("emTabLbl", xmLabelGadgetClass, tabForm,
2954 XmNlabelString,
2955 s1=XmStringCreateSimple("Alternative emulated tab spacing"),
2956 XmNalignment, XmALIGNMENT_END,
2957 XmNmnemonic, 'e',
2958 XmNuserData, LMDialog.emTabW,
2959 XmNleftAttachment, XmATTACH_WIDGET,
2960 XmNleftWidget, LMDialog.tabW,
2961 XmNrightAttachment, XmATTACH_WIDGET,
2962 XmNrightWidget, LMDialog.emTabW,
2963 XmNtopAttachment, XmATTACH_FORM,
2964 XmNbottomAttachment, XmATTACH_FORM, NULL);
2965 XmStringFree(s1);
2967 indentBox = XtVaCreateManagedWidget("indentBox", xmRowColumnWidgetClass,
2968 overrideForm,
2969 XmNorientation, XmHORIZONTAL,
2970 XmNpacking, XmPACK_TIGHT,
2971 XmNradioBehavior, True,
2972 XmNleftAttachment, XmATTACH_POSITION,
2973 XmNleftPosition, LEFT_MARGIN_POS,
2974 XmNtopAttachment, XmATTACH_WIDGET,
2975 XmNtopWidget, tabForm,
2976 XmNtopOffset, H_MARGIN, NULL);
2977 LMDialog.defaultIndentW = XtVaCreateManagedWidget("defaultIndent",
2978 xmToggleButtonWidgetClass, indentBox,
2979 XmNset, True,
2980 XmNmarginHeight, 0,
2981 XmNlabelString, s1=XmStringCreateSimple("Default indent style"),
2982 XmNmnemonic, 'D', NULL);
2983 XmStringFree(s1);
2984 LMDialog.noIndentW = XtVaCreateManagedWidget("noIndent",
2985 xmToggleButtonWidgetClass, indentBox,
2986 XmNmarginHeight, 0,
2987 XmNlabelString, s1=XmStringCreateSimple("No automatic indent"),
2988 XmNmnemonic, 'N', NULL);
2989 XmStringFree(s1);
2990 LMDialog.autoIndentW = XtVaCreateManagedWidget("autoIndent",
2991 xmToggleButtonWidgetClass, indentBox,
2992 XmNmarginHeight, 0,
2993 XmNlabelString, s1=XmStringCreateSimple("Auto-indent"),
2994 XmNmnemonic, 'A', NULL);
2995 XmStringFree(s1);
2996 LMDialog.smartIndentW = XtVaCreateManagedWidget("smartIndent",
2997 xmToggleButtonWidgetClass, indentBox,
2998 XmNmarginHeight, 0,
2999 XmNlabelString, s1=XmStringCreateSimple("Smart-indent"),
3000 XmNmnemonic, 'S', NULL);
3001 XmStringFree(s1);
3003 wrapBox = XtVaCreateManagedWidget("wrapBox", xmRowColumnWidgetClass,
3004 overrideForm,
3005 XmNorientation, XmHORIZONTAL,
3006 XmNpacking, XmPACK_TIGHT,
3007 XmNradioBehavior, True,
3008 XmNleftAttachment, XmATTACH_POSITION,
3009 XmNleftPosition, LEFT_MARGIN_POS,
3010 XmNtopAttachment, XmATTACH_WIDGET,
3011 XmNtopWidget, indentBox,
3012 XmNtopOffset, H_MARGIN,
3013 XmNbottomAttachment, XmATTACH_FORM,
3014 XmNbottomOffset, H_MARGIN, NULL);
3015 LMDialog.defaultWrapW = XtVaCreateManagedWidget("defaultWrap",
3016 xmToggleButtonWidgetClass, wrapBox,
3017 XmNset, True,
3018 XmNmarginHeight, 0,
3019 XmNlabelString, s1=XmStringCreateSimple("Default wrap style"),
3020 XmNmnemonic, 'D', NULL);
3021 XmStringFree(s1);
3022 LMDialog.noWrapW = XtVaCreateManagedWidget("noWrap",
3023 xmToggleButtonWidgetClass, wrapBox,
3024 XmNmarginHeight, 0,
3025 XmNlabelString, s1=XmStringCreateSimple("No wrapping"),
3026 XmNmnemonic, 'N', NULL);
3027 XmStringFree(s1);
3028 LMDialog.newlineWrapW = XtVaCreateManagedWidget("newlineWrap",
3029 xmToggleButtonWidgetClass, wrapBox,
3030 XmNmarginHeight, 0,
3031 XmNlabelString, s1=XmStringCreateSimple("Auto newline wrap"),
3032 XmNmnemonic, 'A', NULL);
3033 XmStringFree(s1);
3034 LMDialog.contWrapW = XtVaCreateManagedWidget("contWrap",
3035 xmToggleButtonWidgetClass, wrapBox,
3036 XmNmarginHeight, 0,
3037 XmNlabelString, s1=XmStringCreateSimple("Continuous wrap"),
3038 XmNmnemonic, 'C', NULL);
3039 XmStringFree(s1);
3041 XtVaCreateManagedWidget("stretchForm", xmFormWidgetClass, form,
3042 XmNtopAttachment, XmATTACH_WIDGET,
3043 XmNtopWidget, LMDialog.defTipsW,
3044 XmNleftAttachment, XmATTACH_POSITION,
3045 XmNleftPosition, LIST_RIGHT,
3046 XmNrightAttachment, XmATTACH_POSITION,
3047 XmNrightPosition, RIGHT_MARGIN_POS,
3048 XmNbottomAttachment, XmATTACH_WIDGET,
3049 XmNbottomWidget, overrideFrame,
3050 XmNbottomOffset, H_MARGIN*2, NULL);
3052 ac = 0;
3053 XtSetArg(args[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
3054 XtSetArg(args[ac], XmNtopOffset, H_MARGIN); ac++;
3055 XtSetArg(args[ac], XmNtopWidget, topLbl); ac++;
3056 XtSetArg(args[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
3057 XtSetArg(args[ac], XmNleftPosition, LEFT_MARGIN_POS); ac++;
3058 XtSetArg(args[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
3059 XtSetArg(args[ac], XmNrightPosition, LIST_RIGHT-1); ac++;
3060 XtSetArg(args[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
3061 XtSetArg(args[ac], XmNbottomWidget, overrideFrame); ac++;
3062 XtSetArg(args[ac], XmNbottomOffset, H_MARGIN*2); ac++;
3063 LMDialog.managedListW = CreateManagedList(form, "list", args, ac,
3064 (void **)LMDialog.languageModeList, &LMDialog.nLanguageModes,
3065 MAX_LANGUAGE_MODES, 15, lmGetDisplayedCB, NULL, lmSetDisplayedCB,
3066 NULL, lmFreeItemCB);
3067 AddDeleteConfirmCB(LMDialog.managedListW, lmDeleteConfirmCB, NULL);
3068 XtVaSetValues(topLbl, XmNuserData, LMDialog.managedListW, NULL);
3070 /* Set initial default button */
3071 XtVaSetValues(form, XmNdefaultButton, okBtn, NULL);
3072 XtVaSetValues(form, XmNcancelButton, closeBtn, NULL);
3074 /* Handle mnemonic selection of buttons and focus to dialog */
3075 AddDialogMnemonicHandler(form, FALSE);
3077 /* Realize all of the widgets in the new dialog */
3078 RealizeWithoutForcingPosition(LMDialog.shell);
3081 static void lmDestroyCB(Widget w, XtPointer clientData, XtPointer callData)
3083 int i;
3085 for (i=0; i<LMDialog.nLanguageModes; i++)
3086 freeLanguageModeRec(LMDialog.languageModeList[i]);
3087 XtFree((char *)LMDialog.languageModeList);
3090 static void lmOkCB(Widget w, XtPointer clientData, XtPointer callData)
3092 if (!updateLMList())
3093 return;
3095 /* pop down and destroy the dialog */
3096 XtDestroyWidget(LMDialog.shell);
3097 LMDialog.shell = NULL;
3100 static void lmApplyCB(Widget w, XtPointer clientData, XtPointer callData)
3102 updateLMList();
3105 static void lmCloseCB(Widget w, XtPointer clientData, XtPointer callData)
3107 /* pop down and destroy the dialog */
3108 XtDestroyWidget(LMDialog.shell);
3109 LMDialog.shell = NULL;
3112 static int lmDeleteConfirmCB(int itemIndex, void *cbArg)
3114 int i;
3116 /* Allow duplicate names to be deleted regardless of dependencies */
3117 for (i=0; i<LMDialog.nLanguageModes; i++)
3118 if (i != itemIndex && !strcmp(LMDialog.languageModeList[i]->name,
3119 LMDialog.languageModeList[itemIndex]->name))
3120 return True;
3122 /* don't allow deletion if data will be lost */
3123 if (LMHasHighlightPatterns(LMDialog.languageModeList[itemIndex]->name))
3125 DialogF(DF_WARN, LMDialog.shell, 1, "Patterns exist",
3126 "This language mode has syntax highlighting\n"
3127 "patterns defined. Please delete the patterns\n"
3128 "first, in Preferences -> Default Settings ->\n"
3129 "Syntax Highlighting, before proceeding here.", "OK");
3130 return False;
3133 /* don't allow deletion if data will be lost */
3134 if (LMHasSmartIndentMacros(LMDialog.languageModeList[itemIndex]->name))
3136 DialogF(DF_WARN, LMDialog.shell, 1, "Smart Indent Macros exist",
3137 "This language mode has smart indent macros\n"
3138 "defined. Please delete the macros first,\n"
3139 "in Preferences -> Default Settings ->\n"
3140 "Auto Indent -> Program Smart Indent,\n"
3141 "before proceeding here.", "OK");
3142 return False;
3145 return True;
3149 ** Apply the changes that the user has made in the language modes dialog to the
3150 ** stored language mode information for this NEdit session (the data array
3151 ** LanguageModes)
3153 static int updateLMList(void)
3155 WindowInfo *window;
3156 int oldLanguageMode;
3157 char *oldModeName, *newDelimiters;
3158 int i, j;
3160 /* Get the current contents of the dialog fields */
3161 if (!UpdateManagedList(LMDialog.managedListW, True))
3162 return False;
3164 /* Fix up language mode indices in all open windows (which may change
3165 if the currently selected mode is deleted or has changed position),
3166 and update word delimiters */
3167 for (window=WindowList; window!=NULL; window=window->next) {
3168 if (window->languageMode != PLAIN_LANGUAGE_MODE) {
3169 oldLanguageMode = window->languageMode;
3170 oldModeName = LanguageModes[window->languageMode]->name;
3171 window->languageMode = PLAIN_LANGUAGE_MODE;
3172 for (i=0; i<LMDialog.nLanguageModes; i++) {
3173 if (!strcmp(oldModeName, LMDialog.languageModeList[i]->name)) {
3174 newDelimiters = LMDialog.languageModeList[i]->delimiters;
3175 if (newDelimiters == NULL)
3176 newDelimiters = GetPrefDelimiters();
3177 XtVaSetValues(window->textArea, textNwordDelimiters,
3178 newDelimiters, NULL);
3179 for (j=0; j<window->nPanes; j++)
3180 XtVaSetValues(window->textPanes[j],
3181 textNwordDelimiters, newDelimiters, NULL);
3182 /* don't forget to adapt the LM stored within the user menu cache */
3183 if (window->userMenuCache->umcLanguageMode == oldLanguageMode)
3184 window->userMenuCache->umcLanguageMode = i;
3185 if (window->userBGMenuCache.ubmcLanguageMode == oldLanguageMode)
3186 window->userBGMenuCache.ubmcLanguageMode = i;
3187 /* update the language mode of this window (document) */
3188 window->languageMode = i;
3189 break;
3195 /* If there were any name changes, re-name dependent highlight patterns
3196 and smart-indent macros and fix up the weird rename-format names */
3197 for (i=0; i<LMDialog.nLanguageModes; i++) {
3198 if (strchr(LMDialog.languageModeList[i]->name, ':') != NULL) {
3199 char *newName = strrchr(LMDialog.languageModeList[i]->name, ':')+1;
3200 *strchr(LMDialog.languageModeList[i]->name, ':') = '\0';
3201 RenameHighlightPattern(LMDialog.languageModeList[i]->name, newName);
3202 RenameSmartIndentMacros(LMDialog.languageModeList[i]->name, newName);
3203 memmove(LMDialog.languageModeList[i]->name, newName,
3204 strlen(newName) + 1);
3205 ChangeManagedListData(LMDialog.managedListW);
3209 /* Replace the old language mode list with the new one from the dialog */
3210 for (i=0; i<NLanguageModes; i++)
3211 freeLanguageModeRec(LanguageModes[i]);
3212 for (i=0; i<LMDialog.nLanguageModes; i++)
3213 LanguageModes[i] = copyLanguageModeRec(LMDialog.languageModeList[i]);
3214 NLanguageModes = LMDialog.nLanguageModes;
3216 /* Update user menu info to update language mode dependencies of
3217 user menu items */
3218 UpdateUserMenuInfo();
3220 /* Update the menus in the window menu bars and load any needed
3221 calltips files */
3222 for (window=WindowList; window!=NULL; window=window->next) {
3223 updateLanguageModeSubmenu(window);
3224 if (window->languageMode != PLAIN_LANGUAGE_MODE &&
3225 LanguageModes[window->languageMode]->defTipsFile != NULL)
3226 AddTagsFile(LanguageModes[window->languageMode]->defTipsFile, TIP);
3227 /* cache user menus: Rebuild all user menus of this window */
3228 RebuildAllMenus(window);
3231 /* If a syntax highlighting dialog is up, update its menu */
3232 UpdateLanguageModeMenu();
3233 /* The same for the smart indent macro dialog */
3234 UpdateLangModeMenuSmartIndent();
3235 /* Note that preferences have been changed */
3236 MarkPrefsChanged();
3238 return True;
3241 static void *lmGetDisplayedCB(void *oldItem, int explicitRequest, int *abort,
3242 void *cbArg)
3244 languageModeRec *lm, *oldLM = (languageModeRec *)oldItem;
3245 char *tempName;
3246 int i, nCopies, oldLen;
3248 /* If the dialog is currently displaying the "new" entry and the
3249 fields are empty, that's just fine */
3250 if (oldItem == NULL && lmDialogEmpty())
3251 return NULL;
3253 /* Read the data the user has entered in the dialog fields */
3254 lm = readLMDialogFields(True);
3256 /* If there was a name change of a non-duplicate language mode, modify the
3257 name to the weird format of: ":old name:new name". This signals that a
3258 name change is necessary in lm dependent data such as highlight
3259 patterns. Duplicate language modes may be re-named at will, since no
3260 data will be lost due to the name change. */
3261 if (lm != NULL && oldLM != NULL && strcmp(oldLM->name, lm->name)) {
3262 nCopies = 0;
3263 for (i=0; i<LMDialog.nLanguageModes; i++)
3264 if (!strcmp(oldLM->name, LMDialog.languageModeList[i]->name))
3265 nCopies++;
3266 if (nCopies <= 1) {
3267 oldLen = strchr(oldLM->name, ':') == NULL ? strlen(oldLM->name) :
3268 strchr(oldLM->name, ':') - oldLM->name;
3269 tempName = XtMalloc(oldLen + strlen(lm->name) + 2);
3270 strncpy(tempName, oldLM->name, oldLen);
3271 sprintf(&tempName[oldLen], ":%s", lm->name);
3272 XtFree(lm->name);
3273 lm->name = tempName;
3277 /* If there are no problems reading the data, just return it */
3278 if (lm != NULL)
3279 return (void *)lm;
3281 /* If there are problems, and the user didn't ask for the fields to be
3282 read, give more warning */
3283 if (!explicitRequest)
3285 if (DialogF(DF_WARN, LMDialog.shell, 2, "Discard Language Mode",
3286 "Discard incomplete entry\nfor current language mode?", "Keep",
3287 "Discard") == 2)
3289 return oldItem == NULL
3290 ? NULL
3291 : (void *)copyLanguageModeRec((languageModeRec *)oldItem);
3295 /* Do readLMDialogFields again without "silent" mode to display warning */
3296 lm = readLMDialogFields(False);
3297 *abort = True;
3298 return NULL;
3301 static void lmSetDisplayedCB(void *item, void *cbArg)
3303 languageModeRec *lm = (languageModeRec *)item;
3304 char *extStr;
3306 if (item == NULL) {
3307 XmTextSetString(LMDialog.nameW, "");
3308 XmTextSetString(LMDialog.extW, "");
3309 XmTextSetString(LMDialog.recogW, "");
3310 XmTextSetString(LMDialog.defTipsW, "");
3311 XmTextSetString(LMDialog.delimitW, "");
3312 XmTextSetString(LMDialog.tabW, "");
3313 XmTextSetString(LMDialog.emTabW, "");
3314 RadioButtonChangeState(LMDialog.defaultIndentW, True, True);
3315 RadioButtonChangeState(LMDialog.defaultWrapW, True, True);
3316 } else {
3317 XmTextSetString(LMDialog.nameW, strchr(lm->name, ':') == NULL ?
3318 lm->name : strchr(lm->name, ':')+1);
3319 extStr = createExtString(lm->extensions, lm->nExtensions);
3320 XmTextSetString(LMDialog.extW, extStr);
3321 XtFree(extStr);
3322 XmTextSetString(LMDialog.recogW, lm->recognitionExpr);
3323 XmTextSetString(LMDialog.defTipsW, lm->defTipsFile);
3324 XmTextSetString(LMDialog.delimitW, lm->delimiters);
3325 if (lm->tabDist == DEFAULT_TAB_DIST)
3326 XmTextSetString(LMDialog.tabW, "");
3327 else
3328 SetIntText(LMDialog.tabW, lm->tabDist);
3329 if (lm->emTabDist == DEFAULT_EM_TAB_DIST)
3330 XmTextSetString(LMDialog.emTabW, "");
3331 else
3332 SetIntText(LMDialog.emTabW, lm->emTabDist);
3333 RadioButtonChangeState(LMDialog.defaultIndentW,
3334 lm->indentStyle == DEFAULT_INDENT, False);
3335 RadioButtonChangeState(LMDialog.noIndentW,
3336 lm->indentStyle == NO_AUTO_INDENT, False);
3337 RadioButtonChangeState(LMDialog.autoIndentW,
3338 lm->indentStyle == AUTO_INDENT, False);
3339 RadioButtonChangeState(LMDialog.smartIndentW,
3340 lm->indentStyle == SMART_INDENT, False);
3341 RadioButtonChangeState(LMDialog.defaultWrapW,
3342 lm->wrapStyle == DEFAULT_WRAP, False);
3343 RadioButtonChangeState(LMDialog.noWrapW,
3344 lm->wrapStyle == NO_WRAP, False);
3345 RadioButtonChangeState(LMDialog.newlineWrapW,
3346 lm->wrapStyle == NEWLINE_WRAP, False);
3347 RadioButtonChangeState(LMDialog.contWrapW,
3348 lm->wrapStyle == CONTINUOUS_WRAP, False);
3352 static void lmFreeItemCB(void *item)
3354 freeLanguageModeRec((languageModeRec *)item);
3357 static void freeLanguageModeRec(languageModeRec *lm)
3359 int i;
3361 XtFree(lm->name);
3362 if (lm->recognitionExpr != NULL)
3363 XtFree(lm->recognitionExpr);
3364 if (lm->defTipsFile != NULL)
3365 XtFree(lm->defTipsFile);
3366 if (lm->delimiters != NULL)
3367 XtFree(lm->delimiters);
3368 for (i=0; i<lm->nExtensions; i++)
3369 XtFree(lm->extensions[i]);
3370 if (lm->nExtensions != 0)
3371 XtFree((char *)lm->extensions);
3372 XtFree((char *)lm);
3376 ** Copy a languageModeRec data structure and all of the allocated data it contains
3378 static languageModeRec *copyLanguageModeRec(languageModeRec *lm)
3380 languageModeRec *newLM;
3381 int i;
3383 newLM = (languageModeRec *)XtMalloc(sizeof(languageModeRec));
3384 newLM->name = XtMalloc(strlen(lm->name)+1);
3385 strcpy(newLM->name, lm->name);
3386 newLM->nExtensions = lm->nExtensions;
3387 newLM->extensions = (char **)XtMalloc(sizeof(char *) * lm->nExtensions);
3388 for (i=0; i<lm->nExtensions; i++) {
3389 newLM->extensions[i] = XtMalloc(strlen(lm->extensions[i]) + 1);
3390 strcpy(newLM->extensions[i], lm->extensions[i]);
3392 if (lm->recognitionExpr == NULL)
3393 newLM->recognitionExpr = NULL;
3394 else {
3395 newLM->recognitionExpr = XtMalloc(strlen(lm->recognitionExpr)+1);
3396 strcpy(newLM->recognitionExpr, lm->recognitionExpr);
3398 if (lm->defTipsFile == NULL)
3399 newLM->defTipsFile = NULL;
3400 else {
3401 newLM->defTipsFile = XtMalloc(strlen(lm->defTipsFile)+1);
3402 strcpy(newLM->defTipsFile, lm->defTipsFile);
3404 if (lm->delimiters == NULL)
3405 newLM->delimiters = NULL;
3406 else {
3407 newLM->delimiters = XtMalloc(strlen(lm->delimiters)+1);
3408 strcpy(newLM->delimiters, lm->delimiters);
3410 newLM->wrapStyle = lm->wrapStyle;
3411 newLM->indentStyle = lm->indentStyle;
3412 newLM->tabDist = lm->tabDist;
3413 newLM->emTabDist = lm->emTabDist;
3414 return newLM;
3418 ** Read the fields in the language modes dialog and create a languageModeRec data
3419 ** structure reflecting the current state of the selected language mode in the dialog.
3420 ** If any of the information is incorrect or missing, display a warning dialog and
3421 ** return NULL. Passing "silent" as True, suppresses the warning dialogs.
3423 static languageModeRec *readLMDialogFields(int silent)
3425 languageModeRec *lm;
3426 regexp *compiledRE;
3427 char *compileMsg, *extStr, *extPtr;
3429 /* Allocate a language mode structure to return, set unread fields to
3430 empty so everything can be freed on errors by freeLanguageModeRec */
3431 lm = (languageModeRec *)XtMalloc(sizeof(languageModeRec));
3432 lm->nExtensions = 0;
3433 lm->recognitionExpr = NULL;
3434 lm->defTipsFile = NULL;
3435 lm->delimiters = NULL;
3437 /* read the name field */
3438 lm->name = ReadSymbolicFieldTextWidget(LMDialog.nameW,
3439 "language mode name", silent);
3440 if (lm->name == NULL) {
3441 XtFree((char *)lm);
3442 return NULL;
3445 if (*lm->name == '\0')
3447 if (!silent)
3449 DialogF(DF_WARN, LMDialog.shell, 1, "Language Mode Name",
3450 "Please specify a name\nfor the language mode", "OK");
3451 XmProcessTraversal(LMDialog.nameW, XmTRAVERSE_CURRENT);
3453 freeLanguageModeRec(lm);
3454 return NULL;
3457 /* read the extension list field */
3458 extStr = extPtr = XmTextGetString(LMDialog.extW);
3459 lm->extensions = readExtensionList(&extPtr, &lm->nExtensions);
3460 XtFree(extStr);
3462 /* read recognition expression */
3463 lm->recognitionExpr = XmTextGetString(LMDialog.recogW);
3464 if (*lm->recognitionExpr == '\0') {
3465 XtFree(lm->recognitionExpr);
3466 lm->recognitionExpr = NULL;
3467 } else
3469 compiledRE = CompileRE(lm->recognitionExpr, &compileMsg, REDFLT_STANDARD);
3471 if (compiledRE == NULL)
3473 if (!silent)
3475 DialogF(DF_WARN, LMDialog.shell, 1, "Regex",
3476 "Recognition expression:\n%s", "OK", compileMsg);
3477 XmProcessTraversal(LMDialog.recogW, XmTRAVERSE_CURRENT);
3479 XtFree((char *)compiledRE);
3480 freeLanguageModeRec(lm);
3481 return NULL;
3484 XtFree((char *)compiledRE);
3487 /* Read the default calltips file for the language mode */
3488 lm->defTipsFile = XmTextGetString(LMDialog.defTipsW);
3489 if (*lm->defTipsFile == '\0') {
3490 /* Empty string */
3491 XtFree(lm->defTipsFile);
3492 lm->defTipsFile = NULL;
3493 } else {
3494 /* Ensure that AddTagsFile will work */
3495 if (AddTagsFile(lm->defTipsFile, TIP) == FALSE) {
3496 if (!silent)
3498 DialogF(DF_WARN, LMDialog.shell, 1, "Error reading Calltips",
3499 "Can't read default calltips file(s):\n \"%s\"\n",
3500 "OK", lm->defTipsFile);
3501 XmProcessTraversal(LMDialog.recogW, XmTRAVERSE_CURRENT);
3503 freeLanguageModeRec(lm);
3504 return NULL;
3505 } else
3506 if (DeleteTagsFile(lm->defTipsFile, TIP, False) == FALSE)
3507 fprintf(stderr, "nedit: Internal error: Trouble deleting "
3508 "calltips file(s):\n \"%s\"\n", lm->defTipsFile);
3511 /* read tab spacing field */
3512 if (TextWidgetIsBlank(LMDialog.tabW))
3513 lm->tabDist = DEFAULT_TAB_DIST;
3514 else {
3515 if (GetIntTextWarn(LMDialog.tabW, &lm->tabDist, "tab spacing", False)
3516 != TEXT_READ_OK) {
3517 freeLanguageModeRec(lm);
3518 return NULL;
3521 if (lm->tabDist <= 0 || lm->tabDist > 100)
3523 if (!silent)
3525 DialogF(DF_WARN, LMDialog.shell, 1, "Invalid Tab Spacing",
3526 "Invalid tab spacing: %d", "OK", lm->tabDist);
3527 XmProcessTraversal(LMDialog.tabW, XmTRAVERSE_CURRENT);
3529 freeLanguageModeRec(lm);
3530 return NULL;
3534 /* read emulated tab field */
3535 if (TextWidgetIsBlank(LMDialog.emTabW))
3537 lm->emTabDist = DEFAULT_EM_TAB_DIST;
3538 } else
3540 if (GetIntTextWarn(LMDialog.emTabW, &lm->emTabDist,
3541 "emulated tab spacing", False) != TEXT_READ_OK)
3543 freeLanguageModeRec(lm);
3544 return NULL;
3547 if (lm->emTabDist < 0 || lm->emTabDist > 100)
3549 if (!silent)
3551 DialogF(DF_WARN, LMDialog.shell, 1, "Invalid Tab Spacing",
3552 "Invalid emulated tab spacing: %d", "OK",
3553 lm->emTabDist);
3554 XmProcessTraversal(LMDialog.emTabW, XmTRAVERSE_CURRENT);
3556 freeLanguageModeRec(lm);
3557 return NULL;
3561 /* read delimiters string */
3562 lm->delimiters = XmTextGetString(LMDialog.delimitW);
3563 if (*lm->delimiters == '\0') {
3564 XtFree(lm->delimiters);
3565 lm->delimiters = NULL;
3568 /* read indent style */
3569 if (XmToggleButtonGetState(LMDialog.noIndentW))
3570 lm->indentStyle = NO_AUTO_INDENT;
3571 else if (XmToggleButtonGetState(LMDialog.autoIndentW))
3572 lm->indentStyle = AUTO_INDENT;
3573 else if (XmToggleButtonGetState(LMDialog.smartIndentW))
3574 lm->indentStyle = SMART_INDENT;
3575 else
3576 lm->indentStyle = DEFAULT_INDENT;
3578 /* read wrap style */
3579 if (XmToggleButtonGetState(LMDialog.noWrapW))
3580 lm->wrapStyle = NO_WRAP;
3581 else if (XmToggleButtonGetState(LMDialog.newlineWrapW))
3582 lm->wrapStyle = NEWLINE_WRAP;
3583 else if (XmToggleButtonGetState(LMDialog.contWrapW))
3584 lm->wrapStyle = CONTINUOUS_WRAP;
3585 else
3586 lm->wrapStyle = DEFAULT_WRAP;
3588 return lm;
3592 ** Return True if the language mode dialog fields are blank (unchanged from the "New"
3593 ** language mode state).
3595 static int lmDialogEmpty(void)
3597 return TextWidgetIsBlank(LMDialog.nameW) &&
3598 TextWidgetIsBlank(LMDialog.extW) &&
3599 TextWidgetIsBlank(LMDialog.recogW) &&
3600 TextWidgetIsBlank(LMDialog.delimitW) &&
3601 TextWidgetIsBlank(LMDialog.tabW) &&
3602 TextWidgetIsBlank(LMDialog.emTabW) &&
3603 XmToggleButtonGetState(LMDialog.defaultIndentW) &&
3604 XmToggleButtonGetState(LMDialog.defaultWrapW);
3608 ** Present a dialog for changing fonts (primary, and for highlighting).
3610 void ChooseFonts(WindowInfo *window, int forWindow)
3612 #define MARGIN_SPACING 10
3613 #define BTN_TEXT_OFFSET 3
3614 Widget form, primaryLbl, primaryBtn, italicLbl, italicBtn;
3615 Widget boldLbl, boldBtn, boldItalicLbl, boldItalicBtn;
3616 Widget primaryFrame, primaryForm, highlightFrame, highlightForm;
3617 Widget okBtn, applyBtn, cancelBtn;
3618 fontDialog *fd;
3619 XmString s1;
3620 int ac;
3621 Arg args[20];
3623 /* if the dialog is already displayed, just pop it to the top and return */
3624 if (window->fontDialog != NULL) {
3625 RaiseDialogWindow(((fontDialog *)window->fontDialog)->shell);
3626 return;
3629 /* Create a structure for keeping track of dialog state */
3630 fd = (fontDialog *)XtMalloc(sizeof(fontDialog));
3631 fd->window = window;
3632 fd->forWindow = forWindow;
3633 window->fontDialog = (void*)fd;
3635 /* Create a form widget in a dialog shell */
3636 ac = 0;
3637 XtSetArg(args[ac], XmNautoUnmanage, False); ac++;
3638 XtSetArg(args[ac], XmNresizePolicy, XmRESIZE_NONE); ac++;
3639 form = CreateFormDialog(window->shell, "choose Fonts", args, ac);
3640 XtVaSetValues(form, XmNshadowThickness, 0, NULL);
3641 fd->shell = XtParent(form);
3642 XtVaSetValues(fd->shell, XmNtitle, "Text Fonts", NULL);
3643 AddMotifCloseCallback(XtParent(form), fontCancelCB, fd);
3644 XtAddCallback(form, XmNdestroyCallback, fontDestroyCB, fd);
3646 primaryFrame = XtVaCreateManagedWidget("primaryFrame", xmFrameWidgetClass,
3647 form, XmNmarginHeight, 3,
3648 XmNtopAttachment, XmATTACH_POSITION,
3649 XmNtopPosition, 2,
3650 XmNleftAttachment, XmATTACH_POSITION,
3651 XmNleftPosition, 1,
3652 XmNrightAttachment, XmATTACH_POSITION,
3653 XmNrightPosition, 99, NULL);
3654 primaryForm = XtVaCreateManagedWidget("primaryForm", xmFormWidgetClass,
3655 primaryFrame, NULL);
3656 primaryLbl = XtVaCreateManagedWidget("primaryFont", xmLabelGadgetClass,
3657 primaryFrame,
3658 XmNlabelString, s1=XmStringCreateSimple("Primary Font"),
3659 XmNmnemonic, 'P',
3660 XmNchildType, XmFRAME_TITLE_CHILD,
3661 XmNchildHorizontalAlignment, XmALIGNMENT_CENTER, NULL);
3662 XmStringFree(s1);
3664 primaryBtn = XtVaCreateManagedWidget("primaryBtn",
3665 xmPushButtonWidgetClass, primaryForm,
3666 XmNlabelString, s1=XmStringCreateSimple("Browse..."),
3667 XmNmnemonic, 'r',
3668 XmNtopAttachment, XmATTACH_POSITION,
3669 XmNtopPosition, 2,
3670 XmNtopOffset, BTN_TEXT_OFFSET,
3671 XmNleftAttachment, XmATTACH_POSITION,
3672 XmNleftPosition, 1, NULL);
3673 XmStringFree(s1);
3674 XtAddCallback(primaryBtn, XmNactivateCallback, primaryBrowseCB, fd);
3676 fd->primaryW = XtVaCreateManagedWidget("primary", xmTextWidgetClass,
3677 primaryForm,
3678 XmNcolumns, 70,
3679 XmNmaxLength, MAX_FONT_LEN,
3680 XmNleftAttachment, XmATTACH_WIDGET,
3681 XmNleftWidget, primaryBtn,
3682 XmNtopAttachment, XmATTACH_POSITION,
3683 XmNtopPosition, 2,
3684 XmNrightAttachment, XmATTACH_POSITION,
3685 XmNrightPosition, 99, NULL);
3686 RemapDeleteKey(fd->primaryW);
3687 XtAddCallback(fd->primaryW, XmNvalueChangedCallback,
3688 primaryModifiedCB, fd);
3689 XtVaSetValues(primaryLbl, XmNuserData, fd->primaryW, NULL);
3691 highlightFrame = XtVaCreateManagedWidget("highlightFrame",
3692 xmFrameWidgetClass, form,
3693 XmNmarginHeight, 3,
3694 XmNnavigationType, XmTAB_GROUP,
3695 XmNtopAttachment, XmATTACH_WIDGET,
3696 XmNtopWidget, primaryFrame,
3697 XmNtopOffset, 20,
3698 XmNleftAttachment, XmATTACH_POSITION,
3699 XmNleftPosition, 1,
3700 XmNrightAttachment, XmATTACH_POSITION,
3701 XmNrightPosition, 99, NULL);
3702 highlightForm = XtVaCreateManagedWidget("highlightForm", xmFormWidgetClass,
3703 highlightFrame, NULL);
3704 XtVaCreateManagedWidget("highlightFonts", xmLabelGadgetClass,
3705 highlightFrame,
3706 XmNlabelString,
3707 s1=XmStringCreateSimple("Fonts for Syntax Highlighting"),
3708 XmNchildType, XmFRAME_TITLE_CHILD,
3709 XmNchildHorizontalAlignment, XmALIGNMENT_CENTER, NULL);
3710 XmStringFree(s1);
3712 fd->fillW = XtVaCreateManagedWidget("fillBtn",
3713 xmPushButtonWidgetClass, highlightForm,
3714 XmNlabelString,
3715 s1=XmStringCreateSimple("Fill Highlight Fonts from Primary"),
3716 XmNmnemonic, 'F',
3717 XmNtopAttachment, XmATTACH_POSITION,
3718 XmNtopPosition, 2,
3719 XmNtopOffset, BTN_TEXT_OFFSET,
3720 XmNleftAttachment, XmATTACH_POSITION,
3721 XmNleftPosition, 1, NULL);
3722 XmStringFree(s1);
3723 XtAddCallback(fd->fillW, XmNactivateCallback, fillFromPrimaryCB, fd);
3725 italicLbl = XtVaCreateManagedWidget("italicLbl", xmLabelGadgetClass,
3726 highlightForm,
3727 XmNlabelString, s1=XmStringCreateSimple("Italic Font"),
3728 XmNmnemonic, 'I',
3729 XmNalignment, XmALIGNMENT_BEGINNING,
3730 XmNtopAttachment, XmATTACH_WIDGET,
3731 XmNtopWidget, fd->fillW,
3732 XmNtopOffset, MARGIN_SPACING,
3733 XmNleftAttachment, XmATTACH_POSITION,
3734 XmNleftPosition, 1, NULL);
3735 XmStringFree(s1);
3737 fd->italicErrW = XtVaCreateManagedWidget("italicErrLbl",
3738 xmLabelGadgetClass, highlightForm,
3739 XmNlabelString, s1=XmStringCreateSimple(
3740 "(vvv spacing is inconsistent with primary font vvv)"),
3741 XmNalignment, XmALIGNMENT_END,
3742 XmNtopAttachment, XmATTACH_WIDGET,
3743 XmNtopWidget, fd->fillW,
3744 XmNtopOffset, MARGIN_SPACING,
3745 XmNleftAttachment, XmATTACH_WIDGET,
3746 XmNleftWidget, italicLbl,
3747 XmNrightAttachment, XmATTACH_POSITION,
3748 XmNrightPosition, 99, NULL);
3749 XmStringFree(s1);
3751 italicBtn = XtVaCreateManagedWidget("italicBtn",
3752 xmPushButtonWidgetClass, highlightForm,
3753 XmNlabelString, s1=XmStringCreateSimple("Browse..."),
3754 XmNmnemonic, 'o',
3755 XmNtopAttachment, XmATTACH_WIDGET,
3756 XmNtopWidget, italicLbl,
3757 XmNtopOffset, BTN_TEXT_OFFSET,
3758 XmNleftAttachment, XmATTACH_POSITION,
3759 XmNleftPosition, 1, NULL);
3760 XmStringFree(s1);
3761 XtAddCallback(italicBtn, XmNactivateCallback, italicBrowseCB, fd);
3763 fd->italicW = XtVaCreateManagedWidget("italic", xmTextWidgetClass,
3764 highlightForm,
3765 XmNmaxLength, MAX_FONT_LEN,
3766 XmNleftAttachment, XmATTACH_WIDGET,
3767 XmNleftWidget, italicBtn,
3768 XmNtopAttachment, XmATTACH_WIDGET,
3769 XmNtopWidget, italicLbl,
3770 XmNrightAttachment, XmATTACH_POSITION,
3771 XmNrightPosition, 99, NULL);
3772 RemapDeleteKey(fd->italicW);
3773 XtAddCallback(fd->italicW, XmNvalueChangedCallback,
3774 italicModifiedCB, fd);
3775 XtVaSetValues(italicLbl, XmNuserData, fd->italicW, NULL);
3777 boldLbl = XtVaCreateManagedWidget("boldLbl", xmLabelGadgetClass,
3778 highlightForm,
3779 XmNlabelString, s1=XmStringCreateSimple("Bold Font"),
3780 XmNmnemonic, 'B',
3781 XmNalignment, XmALIGNMENT_BEGINNING,
3782 XmNtopAttachment, XmATTACH_WIDGET,
3783 XmNtopWidget, italicBtn,
3784 XmNtopOffset, MARGIN_SPACING,
3785 XmNleftAttachment, XmATTACH_POSITION,
3786 XmNleftPosition, 1, NULL);
3787 XmStringFree(s1);
3789 fd->boldErrW = XtVaCreateManagedWidget("boldErrLbl",
3790 xmLabelGadgetClass, highlightForm,
3791 XmNlabelString, s1=XmStringCreateSimple(""),
3792 XmNalignment, XmALIGNMENT_END,
3793 XmNtopAttachment, XmATTACH_WIDGET,
3794 XmNtopWidget, italicBtn,
3795 XmNtopOffset, MARGIN_SPACING,
3796 XmNleftAttachment, XmATTACH_WIDGET,
3797 XmNleftWidget, boldLbl,
3798 XmNrightAttachment, XmATTACH_POSITION,
3799 XmNrightPosition, 99, NULL);
3800 XmStringFree(s1);
3802 boldBtn = XtVaCreateManagedWidget("boldBtn",
3803 xmPushButtonWidgetClass, highlightForm,
3804 XmNlabelString, s1=XmStringCreateSimple("Browse..."),
3805 XmNmnemonic, 'w',
3806 XmNtopAttachment, XmATTACH_WIDGET,
3807 XmNtopWidget, boldLbl,
3808 XmNtopOffset, BTN_TEXT_OFFSET,
3809 XmNleftAttachment, XmATTACH_POSITION,
3810 XmNleftPosition, 1, NULL);
3811 XmStringFree(s1);
3812 XtAddCallback(boldBtn, XmNactivateCallback, boldBrowseCB, fd);
3814 fd->boldW = XtVaCreateManagedWidget("bold", xmTextWidgetClass,
3815 highlightForm,
3816 XmNmaxLength, MAX_FONT_LEN,
3817 XmNleftAttachment, XmATTACH_WIDGET,
3818 XmNleftWidget, boldBtn,
3819 XmNtopAttachment, XmATTACH_WIDGET,
3820 XmNtopWidget, boldLbl,
3821 XmNrightAttachment, XmATTACH_POSITION,
3822 XmNrightPosition, 99, NULL);
3823 RemapDeleteKey(fd->boldW);
3824 XtAddCallback(fd->boldW, XmNvalueChangedCallback,
3825 boldModifiedCB, fd);
3826 XtVaSetValues(boldLbl, XmNuserData, fd->boldW, NULL);
3828 boldItalicLbl = XtVaCreateManagedWidget("boldItalicLbl", xmLabelGadgetClass,
3829 highlightForm,
3830 XmNlabelString, s1=XmStringCreateSimple("Bold Italic Font"),
3831 XmNmnemonic, 'l',
3832 XmNalignment, XmALIGNMENT_BEGINNING,
3833 XmNtopAttachment, XmATTACH_WIDGET,
3834 XmNtopWidget, boldBtn,
3835 XmNtopOffset, MARGIN_SPACING,
3836 XmNleftAttachment, XmATTACH_POSITION,
3837 XmNleftPosition, 1, NULL);
3838 XmStringFree(s1);
3840 fd->boldItalicErrW = XtVaCreateManagedWidget("boldItalicErrLbl",
3841 xmLabelGadgetClass, highlightForm,
3842 XmNlabelString, s1=XmStringCreateSimple(""),
3843 XmNalignment, XmALIGNMENT_END,
3844 XmNtopAttachment, XmATTACH_WIDGET,
3845 XmNtopWidget, boldBtn,
3846 XmNtopOffset, MARGIN_SPACING,
3847 XmNleftAttachment, XmATTACH_WIDGET,
3848 XmNleftWidget, boldItalicLbl,
3849 XmNrightAttachment, XmATTACH_POSITION,
3850 XmNrightPosition, 99, NULL);
3851 XmStringFree(s1);
3853 boldItalicBtn = XtVaCreateManagedWidget("boldItalicBtn",
3854 xmPushButtonWidgetClass, highlightForm,
3855 XmNlabelString, s1=XmStringCreateSimple("Browse..."),
3856 XmNmnemonic, 's',
3857 XmNtopAttachment, XmATTACH_WIDGET,
3858 XmNtopWidget, boldItalicLbl,
3859 XmNtopOffset, BTN_TEXT_OFFSET,
3860 XmNleftAttachment, XmATTACH_POSITION,
3861 XmNleftPosition, 1, NULL);
3862 XmStringFree(s1);
3863 XtAddCallback(boldItalicBtn, XmNactivateCallback, boldItalicBrowseCB, fd);
3865 fd->boldItalicW = XtVaCreateManagedWidget("boldItalic",
3866 xmTextWidgetClass, highlightForm,
3867 XmNmaxLength, MAX_FONT_LEN,
3868 XmNleftAttachment, XmATTACH_WIDGET,
3869 XmNleftWidget, boldItalicBtn,
3870 XmNtopAttachment, XmATTACH_WIDGET,
3871 XmNtopWidget, boldItalicLbl,
3872 XmNrightAttachment, XmATTACH_POSITION,
3873 XmNrightPosition, 99, NULL);
3874 RemapDeleteKey(fd->boldItalicW);
3875 XtAddCallback(fd->boldItalicW, XmNvalueChangedCallback,
3876 boldItalicModifiedCB, fd);
3877 XtVaSetValues(boldItalicLbl, XmNuserData, fd->boldItalicW, NULL);
3879 okBtn = XtVaCreateManagedWidget("ok", xmPushButtonWidgetClass, form,
3880 XmNlabelString, s1=XmStringCreateSimple("OK"),
3881 XmNmarginWidth, BUTTON_WIDTH_MARGIN,
3882 XmNtopAttachment, XmATTACH_WIDGET,
3883 XmNtopWidget, highlightFrame,
3884 XmNtopOffset, MARGIN_SPACING,
3885 XmNleftAttachment, XmATTACH_POSITION,
3886 XmNleftPosition, forWindow ? 13 : 26,
3887 XmNrightAttachment, XmATTACH_POSITION,
3888 XmNrightPosition, forWindow ? 27 : 40, NULL);
3889 XtAddCallback(okBtn, XmNactivateCallback, fontOkCB, fd);
3890 XmStringFree(s1);
3892 if (forWindow) {
3893 applyBtn = XtVaCreateManagedWidget("apply",xmPushButtonWidgetClass,form,
3894 XmNlabelString, s1=XmStringCreateSimple("Apply"),
3895 XmNmnemonic, 'A',
3896 XmNtopAttachment, XmATTACH_WIDGET,
3897 XmNtopWidget, highlightFrame,
3898 XmNtopOffset, MARGIN_SPACING,
3899 XmNleftAttachment, XmATTACH_POSITION,
3900 XmNleftPosition, 43,
3901 XmNrightAttachment, XmATTACH_POSITION,
3902 XmNrightPosition, 57, NULL);
3903 XtAddCallback(applyBtn, XmNactivateCallback, fontApplyCB, fd);
3904 XmStringFree(s1);
3907 cancelBtn = XtVaCreateManagedWidget("cancel",
3908 xmPushButtonWidgetClass, form,
3909 XmNlabelString,
3910 s1 = XmStringCreateSimple(forWindow ? "Close" : "Cancel"),
3911 XmNtopAttachment, XmATTACH_WIDGET,
3912 XmNtopWidget, highlightFrame,
3913 XmNtopOffset, MARGIN_SPACING,
3914 XmNleftAttachment, XmATTACH_POSITION,
3915 XmNleftPosition, forWindow ? 73 : 59,
3916 XmNrightAttachment, XmATTACH_POSITION,
3917 XmNrightPosition, forWindow ? 87 : 73,
3918 NULL);
3919 XtAddCallback(cancelBtn, XmNactivateCallback, fontCancelCB, fd);
3920 XmStringFree(s1);
3922 /* Set initial default button */
3923 XtVaSetValues(form, XmNdefaultButton, okBtn, NULL);
3924 XtVaSetValues(form, XmNcancelButton, cancelBtn, NULL);
3926 /* Set initial values */
3927 if (forWindow) {
3928 XmTextSetString(fd->primaryW, window->fontName);
3929 XmTextSetString(fd->boldW, window->boldFontName);
3930 XmTextSetString(fd->italicW, window->italicFontName);
3931 XmTextSetString(fd->boldItalicW, window->boldItalicFontName);
3932 } else {
3933 XmTextSetString(fd->primaryW, GetPrefFontName());
3934 XmTextSetString(fd->boldW, GetPrefBoldFontName());
3935 XmTextSetString(fd->italicW, GetPrefItalicFontName());
3936 XmTextSetString(fd->boldItalicW, GetPrefBoldItalicFontName());
3939 /* Handle mnemonic selection of buttons and focus to dialog */
3940 AddDialogMnemonicHandler(form, FALSE);
3942 /* put up dialog */
3943 ManageDialogCenteredOnPointer(form);
3946 static void fillFromPrimaryCB(Widget w, XtPointer clientData,
3947 XtPointer callData)
3949 fontDialog *fd = (fontDialog *)clientData;
3950 char *primaryName, *errMsg;
3951 char modifiedFontName[MAX_FONT_LEN];
3952 char *searchString = "(-[^-]*-[^-]*)-([^-]*)-([^-]*)-(.*)";
3953 char *italicReplaceString = "\\1-\\2-o-\\4";
3954 char *boldReplaceString = "\\1-bold-\\3-\\4";
3955 char *boldItalicReplaceString = "\\1-bold-o-\\4";
3956 regexp *compiledRE;
3958 /* Match the primary font agains RE pattern for font names. If it
3959 doesn't match, we can't generate highlight font names, so return */
3960 compiledRE = CompileRE(searchString, &errMsg, REDFLT_STANDARD);
3961 primaryName = XmTextGetString(fd->primaryW);
3962 if (!ExecRE(compiledRE, NULL, primaryName, NULL, False, '\0', '\0', NULL, NULL, NULL)) {
3963 XBell(XtDisplay(fd->shell), 0);
3964 free(compiledRE);
3965 XtFree(primaryName);
3966 return;
3969 /* Make up names for new fonts based on RE replace patterns */
3970 SubstituteRE(compiledRE, italicReplaceString, modifiedFontName,
3971 MAX_FONT_LEN);
3972 XmTextSetString(fd->italicW, modifiedFontName);
3973 SubstituteRE(compiledRE, boldReplaceString, modifiedFontName,
3974 MAX_FONT_LEN);
3975 XmTextSetString(fd->boldW, modifiedFontName);
3976 SubstituteRE(compiledRE, boldItalicReplaceString, modifiedFontName,
3977 MAX_FONT_LEN);
3978 XmTextSetString(fd->boldItalicW, modifiedFontName);
3979 XtFree(primaryName);
3980 free(compiledRE);
3983 static void primaryModifiedCB(Widget w, XtPointer clientData,
3984 XtPointer callData)
3986 fontDialog *fd = (fontDialog *)clientData;
3988 showFontStatus(fd, fd->italicW, fd->italicErrW);
3989 showFontStatus(fd, fd->boldW, fd->boldErrW);
3990 showFontStatus(fd, fd->boldItalicW, fd->boldItalicErrW);
3992 static void italicModifiedCB(Widget w, XtPointer clientData, XtPointer callData)
3994 fontDialog *fd = (fontDialog *)clientData;
3996 showFontStatus(fd, fd->italicW, fd->italicErrW);
3998 static void boldModifiedCB(Widget w, XtPointer clientData, XtPointer callData)
4000 fontDialog *fd = (fontDialog *)clientData;
4002 showFontStatus(fd, fd->boldW, fd->boldErrW);
4004 static void boldItalicModifiedCB(Widget w, XtPointer clientData,
4005 XtPointer callData)
4007 fontDialog *fd = (fontDialog *)clientData;
4009 showFontStatus(fd, fd->boldItalicW, fd->boldItalicErrW);
4012 static void primaryBrowseCB(Widget w, XtPointer clientData, XtPointer callData)
4014 fontDialog *fd = (fontDialog *)clientData;
4016 browseFont(fd->shell, fd->primaryW);
4018 static void italicBrowseCB(Widget w, XtPointer clientData, XtPointer callData)
4020 fontDialog *fd = (fontDialog *)clientData;
4022 browseFont(fd->shell, fd->italicW);
4024 static void boldBrowseCB(Widget w, XtPointer clientData, XtPointer callData)
4026 fontDialog *fd = (fontDialog *)clientData;
4028 browseFont(fd->shell, fd->boldW);
4030 static void boldItalicBrowseCB(Widget w, XtPointer clientData,
4031 XtPointer callData)
4033 fontDialog *fd = (fontDialog *)clientData;
4035 browseFont(fd->shell, fd->boldItalicW);
4038 static void fontDestroyCB(Widget w, XtPointer clientData, XtPointer callData)
4040 fontDialog *fd = (fontDialog *)clientData;
4042 fd->window->fontDialog = NULL;
4043 XtFree((char *)fd);
4046 static void fontOkCB(Widget w, XtPointer clientData, XtPointer callData)
4048 fontDialog *fd = (fontDialog *)clientData;
4050 updateFonts(fd);
4052 /* pop down and destroy the dialog */
4053 XtDestroyWidget(fd->shell);
4056 static void fontApplyCB(Widget w, XtPointer clientData, XtPointer callData)
4058 fontDialog *fd = (fontDialog *)clientData;
4060 updateFonts(fd);
4063 static void fontCancelCB(Widget w, XtPointer clientData, XtPointer callData)
4065 fontDialog *fd = (fontDialog *)clientData;
4067 /* pop down and destroy the dialog */
4068 XtDestroyWidget(fd->shell);
4072 ** Check over a font name in a text field to make sure it agrees with the
4073 ** primary font in height and spacing.
4075 static int checkFontStatus(fontDialog *fd, Widget fontTextFieldW)
4077 char *primaryName, *testName;
4078 XFontStruct *primaryFont, *testFont;
4079 Display *display = XtDisplay(fontTextFieldW);
4080 int primaryWidth, primaryHeight, testWidth, testHeight;
4082 /* Get width and height of the font to check. Note the test for empty
4083 name: X11R6 clients freak out X11R5 servers if they ask them to load
4084 an empty font name, and kill the whole application! */
4085 testName = XmTextGetString(fontTextFieldW);
4086 if (testName[0] == '\0') {
4087 XtFree(testName);
4088 return BAD_FONT;
4090 testFont = XLoadQueryFont(display, testName);
4091 if (testFont == NULL) {
4092 XtFree(testName);
4093 return BAD_FONT;
4095 XtFree(testName);
4096 testWidth = testFont->min_bounds.width;
4097 testHeight = testFont->ascent + testFont->descent;
4098 XFreeFont(display, testFont);
4100 /* Get width and height of the primary font */
4101 primaryName = XmTextGetString(fd->primaryW);
4102 if (primaryName[0] == '\0') {
4103 XtFree(primaryName);
4104 return BAD_FONT;
4106 primaryFont = XLoadQueryFont(display, primaryName);
4107 if (primaryFont == NULL) {
4108 XtFree(primaryName);
4109 return BAD_PRIMARY;
4111 XtFree(primaryName);
4112 primaryWidth = primaryFont->min_bounds.width;
4113 primaryHeight = primaryFont->ascent + primaryFont->descent;
4114 XFreeFont(display, primaryFont);
4116 /* Compare font information */
4117 if (testWidth != primaryWidth)
4118 return BAD_SPACING;
4119 if (testHeight != primaryHeight)
4120 return BAD_SIZE;
4121 return GOOD_FONT;
4125 ** Update the error label for a font text field to reflect its validity and degree
4126 ** of agreement with the currently selected primary font
4128 static int showFontStatus(fontDialog *fd, Widget fontTextFieldW,
4129 Widget errorLabelW)
4131 int status;
4132 XmString s;
4133 char *msg;
4135 status = checkFontStatus(fd, fontTextFieldW);
4136 if (status == BAD_PRIMARY)
4137 msg = "(font below may not match primary font)";
4138 else if (status == BAD_FONT)
4139 msg = "(xxx font below is invalid xxx)";
4140 else if (status == BAD_SIZE)
4141 msg = "(height of font below does not match primary)";
4142 else if (status == BAD_SPACING)
4143 msg = "(spacing of font below does not match primary)";
4144 else
4145 msg = "";
4147 XtVaSetValues(errorLabelW, XmNlabelString, s=XmStringCreateSimple(msg),
4148 NULL);
4149 XmStringFree(s);
4150 return status;
4154 ** Put up a font selector panel to set the font name in the text widget "fontTextW"
4156 static void browseFont(Widget parent, Widget fontTextW)
4158 char *origFontName, *newFontName;
4159 Pixel fgPixel, bgPixel;
4160 int dummy;
4162 origFontName = XmTextGetString(fontTextW);
4164 /* Get the values from the defaults */
4165 fgPixel = AllocColor(parent, GetPrefColorName(TEXT_FG_COLOR),
4166 &dummy, &dummy, &dummy);
4167 bgPixel = AllocColor(parent, GetPrefColorName(TEXT_BG_COLOR),
4168 &dummy, &dummy, &dummy);
4170 newFontName = FontSel(parent, PREF_FIXED, origFontName, fgPixel, bgPixel);
4171 XtFree(origFontName);
4172 if (newFontName == NULL)
4173 return;
4174 XmTextSetString(fontTextW, newFontName);
4175 XtFree(newFontName);
4179 ** Accept the changes in the dialog and set the fonts regardless of errors
4181 static void updateFonts(fontDialog *fd)
4183 char *fontName, *italicName, *boldName, *boldItalicName;
4185 fontName = XmTextGetString(fd->primaryW);
4186 italicName = XmTextGetString(fd->italicW);
4187 boldName = XmTextGetString(fd->boldW);
4188 boldItalicName = XmTextGetString(fd->boldItalicW);
4190 if (fd->forWindow) {
4191 char *params[4];
4192 params[0] = fontName;
4193 params[1] = italicName;
4194 params[2] = boldName;
4195 params[3] = boldItalicName;
4196 XtCallActionProc(fd->window->textArea, "set_fonts", NULL, params, 4);
4198 SetFonts(fd->window, fontName, italicName, boldName, boldItalicName);
4201 else {
4202 SetPrefFont(fontName);
4203 SetPrefItalicFont(italicName);
4204 SetPrefBoldFont(boldName);
4205 SetPrefBoldItalicFont(boldItalicName);
4207 XtFree(fontName);
4208 XtFree(italicName);
4209 XtFree(boldName);
4210 XtFree(boldItalicName);
4214 ** Change the language mode to the one indexed by "mode", reseting word
4215 ** delimiters, syntax highlighting and other mode specific parameters
4217 static void reapplyLanguageMode(WindowInfo *window, int mode, int forceDefaults)
4219 char *delimiters;
4220 int i, wrapMode, indentStyle, tabDist, emTabDist, highlight, oldEmTabDist;
4221 int wrapModeIsDef, tabDistIsDef, emTabDistIsDef, indentStyleIsDef;
4222 int highlightIsDef, haveHighlightPatterns, haveSmartIndentMacros;
4223 int oldMode = window->languageMode;
4225 /* If the mode is the same, and changes aren't being forced (as might
4226 happen with Save As...), don't mess with already correct settings */
4227 if (window->languageMode == mode && !forceDefaults)
4228 return;
4230 /* Change the mode name stored in the window */
4231 window->languageMode = mode;
4233 /* Decref oldMode's default calltips file if needed */
4234 if (oldMode != PLAIN_LANGUAGE_MODE && LanguageModes[oldMode]->defTipsFile) {
4235 DeleteTagsFile( LanguageModes[oldMode]->defTipsFile, TIP, False );
4238 /* Set delimiters for all text widgets */
4239 if (mode == PLAIN_LANGUAGE_MODE || LanguageModes[mode]->delimiters == NULL)
4240 delimiters = GetPrefDelimiters();
4241 else
4242 delimiters = LanguageModes[mode]->delimiters;
4243 XtVaSetValues(window->textArea, textNwordDelimiters, delimiters, NULL);
4244 for (i=0; i<window->nPanes; i++)
4245 XtVaSetValues(window->textPanes[i], textNautoIndent, delimiters, NULL);
4247 /* Decide on desired values for language-specific parameters. If a
4248 parameter was set to its default value, set it to the new default,
4249 otherwise, leave it alone */
4250 wrapModeIsDef = window->wrapMode == GetPrefWrap(oldMode);
4251 tabDistIsDef = BufGetTabDistance(window->buffer) == GetPrefTabDist(oldMode);
4252 XtVaGetValues(window->textArea, textNemulateTabs, &oldEmTabDist, NULL);
4253 emTabDistIsDef = oldEmTabDist == GetPrefEmTabDist(oldMode);
4254 indentStyleIsDef = window->indentStyle == GetPrefAutoIndent(oldMode) ||
4255 (GetPrefAutoIndent(oldMode) == SMART_INDENT &&
4256 window->indentStyle == AUTO_INDENT &&
4257 !SmartIndentMacrosAvailable(LanguageModeName(oldMode)));
4258 highlightIsDef = window->highlightSyntax == GetPrefHighlightSyntax()
4259 || (GetPrefHighlightSyntax() &&
4260 FindPatternSet(LanguageModeName(oldMode)) == NULL);
4261 wrapMode = wrapModeIsDef || forceDefaults ?
4262 GetPrefWrap(mode) : window->wrapMode;
4263 tabDist = tabDistIsDef || forceDefaults ?
4264 GetPrefTabDist(mode) : BufGetTabDistance(window->buffer);
4265 emTabDist = emTabDistIsDef || forceDefaults ?
4266 GetPrefEmTabDist(mode) : oldEmTabDist;
4267 indentStyle = indentStyleIsDef || forceDefaults ?
4268 GetPrefAutoIndent(mode) : window->indentStyle;
4269 highlight = highlightIsDef || forceDefaults ?
4270 GetPrefHighlightSyntax() : window->highlightSyntax;
4272 /* Dim/undim smart-indent and highlighting menu items depending on
4273 whether patterns/macros are available */
4274 haveHighlightPatterns = FindPatternSet(LanguageModeName(mode)) != NULL;
4275 haveSmartIndentMacros = SmartIndentMacrosAvailable(LanguageModeName(mode));
4276 if (IsTopDocument(window)) {
4277 XtSetSensitive(window->highlightItem, haveHighlightPatterns);
4278 XtSetSensitive(window->smartIndentItem, haveSmartIndentMacros);
4281 /* Turn off requested options which are not available */
4282 highlight = haveHighlightPatterns && highlight;
4283 if (indentStyle == SMART_INDENT && !haveSmartIndentMacros)
4284 indentStyle = AUTO_INDENT;
4286 /* Change highlighting */
4287 window->highlightSyntax = highlight;
4288 SetToggleButtonState(window, window->highlightItem, highlight, False);
4289 StopHighlighting(window);
4291 /* we defer highlighting to RaiseDocument() if doc is hidden */
4292 if (IsTopDocument(window) && highlight)
4293 StartHighlighting(window, False);
4295 /* Force a change of smart indent macros (SetAutoIndent will re-start) */
4296 if (window->indentStyle == SMART_INDENT) {
4297 EndSmartIndent(window);
4298 window->indentStyle = AUTO_INDENT;
4301 /* set requested wrap, indent, and tabs */
4302 SetAutoWrap(window, wrapMode);
4303 SetAutoIndent(window, indentStyle);
4304 SetTabDist(window, tabDist);
4305 SetEmTabDist(window, emTabDist);
4307 /* Load calltips files for new mode */
4308 if (mode != PLAIN_LANGUAGE_MODE && LanguageModes[mode]->defTipsFile) {
4309 AddTagsFile( LanguageModes[mode]->defTipsFile, TIP );
4312 /* Add/remove language specific menu items */
4313 UpdateUserMenus(window);
4317 ** Find and return the name of the appropriate languange mode for
4318 ** the file in "window". Returns a pointer to a string, which will
4319 ** remain valid until a change is made to the language modes list.
4321 static int matchLanguageMode(WindowInfo *window)
4323 char *ext, *first200;
4324 int i, j, fileNameLen, extLen, beginPos, endPos, start;
4325 const char *versionExtendedPath;
4327 /*... look for an explicit mode statement first */
4329 /* Do a regular expression search on for recognition pattern */
4330 first200 = BufGetRange(window->buffer, 0, 200);
4331 for (i=0; i<NLanguageModes; i++) {
4332 if (LanguageModes[i]->recognitionExpr != NULL) {
4333 if (SearchString(first200, LanguageModes[i]->recognitionExpr,
4334 SEARCH_FORWARD, SEARCH_REGEX, False, 0, &beginPos,
4335 &endPos, NULL, NULL, NULL))
4337 XtFree(first200);
4338 return i;
4342 XtFree(first200);
4344 /* Look at file extension ("@@/" starts a ClearCase version extended path,
4345 which gets appended after the file extension, and therefore must be
4346 stripped off to recognize the extension to make ClearCase users happy) */
4347 fileNameLen = strlen(window->filename);
4348 #ifdef VMS
4349 if (strchr(window->filename, ';') != NULL)
4350 fileNameLen = strchr(window->filename, ';') - window->filename;
4351 #else
4352 if ((versionExtendedPath = GetClearCaseVersionExtendedPath(window->filename)) != NULL)
4353 fileNameLen = versionExtendedPath - window->filename;
4354 #endif
4355 for (i=0; i<NLanguageModes; i++) {
4356 for (j=0; j<LanguageModes[i]->nExtensions; j++) {
4357 ext = LanguageModes[i]->extensions[j];
4358 extLen = strlen(ext);
4359 start = fileNameLen - extLen;
4360 #if defined(__VMS) && (__VMS_VER >= 70200000)
4361 /* VMS v7.2 has case-preserving filenames */
4362 if (start >= 0 && !strncasecmp(&window->filename[start], ext, extLen))
4363 return i;
4364 #else
4365 if (start >= 0 && !strncmp(&window->filename[start], ext, extLen))
4366 return i;
4367 #endif
4371 /* no appropriate mode was found */
4372 return PLAIN_LANGUAGE_MODE;
4375 static int loadLanguageModesString(char *inString, int fileVer)
4377 char *errMsg, *styleName, *inPtr = inString;
4378 languageModeRec *lm;
4379 int i;
4381 for (;;) {
4383 /* skip over blank space */
4384 inPtr += strspn(inPtr, " \t\n");
4386 /* Allocate a language mode structure to return, set unread fields to
4387 empty so everything can be freed on errors by freeLanguageModeRec */
4388 lm = (languageModeRec *)XtMalloc(sizeof(languageModeRec));
4389 lm->nExtensions = 0;
4390 lm->recognitionExpr = NULL;
4391 lm->defTipsFile = NULL;
4392 lm->delimiters = NULL;
4394 /* read language mode name */
4395 lm->name = ReadSymbolicField(&inPtr);
4396 if (lm->name == NULL) {
4397 XtFree((char *)lm);
4398 return modeError(NULL,inString,inPtr,"language mode name required");
4400 if (!SkipDelimiter(&inPtr, &errMsg))
4401 return modeError(lm, inString, inPtr, errMsg);
4403 /* read list of extensions */
4404 lm->extensions = readExtensionList(&inPtr,
4405 &lm->nExtensions);
4406 if (!SkipDelimiter(&inPtr, &errMsg))
4407 return modeError(lm, inString, inPtr, errMsg);
4409 /* read the recognition regular expression */
4410 if (*inPtr == '\n' || *inPtr == '\0' || *inPtr == ':')
4411 lm->recognitionExpr = NULL;
4412 else if (!ReadQuotedString(&inPtr, &errMsg, &lm->recognitionExpr))
4413 return modeError(lm, inString,inPtr, errMsg);
4414 if (!SkipDelimiter(&inPtr, &errMsg))
4415 return modeError(lm, inString, inPtr, errMsg);
4417 /* read the indent style */
4418 styleName = ReadSymbolicField(&inPtr);
4419 if (styleName == NULL)
4420 lm->indentStyle = DEFAULT_INDENT;
4421 else {
4422 for (i=0; i<N_INDENT_STYLES; i++) {
4423 if (!strcmp(styleName, AutoIndentTypes[i])) {
4424 lm->indentStyle = i;
4425 break;
4428 XtFree(styleName);
4429 if (i == N_INDENT_STYLES)
4430 return modeError(lm,inString,inPtr,"unrecognized indent style");
4432 if (!SkipDelimiter(&inPtr, &errMsg))
4433 return modeError(lm, inString, inPtr, errMsg);
4435 /* read the wrap style */
4436 styleName = ReadSymbolicField(&inPtr);
4437 if (styleName == NULL)
4438 lm->wrapStyle = DEFAULT_WRAP;
4439 else {
4440 for (i=0; i<N_WRAP_STYLES; i++) {
4441 if (!strcmp(styleName, AutoWrapTypes[i])) {
4442 lm->wrapStyle = i;
4443 break;
4446 XtFree(styleName);
4447 if (i == N_WRAP_STYLES)
4448 return modeError(lm, inString, inPtr,"unrecognized wrap style");
4450 if (!SkipDelimiter(&inPtr, &errMsg))
4451 return modeError(lm, inString, inPtr, errMsg);
4453 /* read the tab distance */
4454 if (*inPtr == '\n' || *inPtr == '\0' || *inPtr == ':')
4455 lm->tabDist = DEFAULT_TAB_DIST;
4456 else if (!ReadNumericField(&inPtr, &lm->tabDist))
4457 return modeError(lm, inString, inPtr, "bad tab spacing");
4458 if (!SkipDelimiter(&inPtr, &errMsg))
4459 return modeError(lm, inString, inPtr, errMsg);
4461 /* read emulated tab distance */
4462 if (*inPtr == '\n' || *inPtr == '\0' || *inPtr == ':')
4463 lm->emTabDist = DEFAULT_EM_TAB_DIST;
4464 else if (!ReadNumericField(&inPtr, &lm->emTabDist))
4465 return modeError(lm, inString, inPtr, "bad emulated tab spacing");
4466 if (!SkipDelimiter(&inPtr, &errMsg))
4467 return modeError(lm, inString, inPtr, errMsg);
4469 /* read the delimiters string */
4470 if (*inPtr == '\n' || *inPtr == '\0' || *inPtr == ':')
4471 lm->delimiters = NULL;
4472 else if (!ReadQuotedString(&inPtr, &errMsg, &lm->delimiters))
4473 return modeError(lm, inString, inPtr, errMsg);
4475 /* After 5.3 all language modes need a default tips file field */
4476 if (!SkipDelimiter(&inPtr, &errMsg))
4477 if (fileVer > 5003)
4478 return modeError(lm, inString, inPtr, errMsg);
4480 /* read the default tips file */
4481 if (*inPtr == '\n' || *inPtr == '\0')
4482 lm->defTipsFile = NULL;
4483 else if (!ReadQuotedString(&inPtr, &errMsg, &lm->defTipsFile))
4484 return modeError(lm, inString, inPtr, errMsg);
4486 /* pattern set was read correctly, add/replace it in the list */
4487 for (i=0; i<NLanguageModes; i++) {
4488 if (!strcmp(LanguageModes[i]->name, lm->name)) {
4489 freeLanguageModeRec(LanguageModes[i]);
4490 LanguageModes[i] = lm;
4491 break;
4494 if (i == NLanguageModes) {
4495 LanguageModes[NLanguageModes++] = lm;
4496 if (NLanguageModes > MAX_LANGUAGE_MODES)
4497 return modeError(NULL, inString, inPtr,
4498 "maximum allowable number of language modes exceeded");
4501 /* if the string ends here, we're done */
4502 inPtr += strspn(inPtr, " \t\n");
4503 if (*inPtr == '\0')
4504 return True;
4505 } /* End for(;;) */
4508 static char *writeLanguageModesString(void)
4510 int i;
4511 char *outStr, *escapedStr, *str, numBuf[25];
4512 textBuffer *outBuf;
4514 outBuf = BufCreate();
4515 for (i=0; i<NLanguageModes; i++) {
4516 BufInsert(outBuf, outBuf->length, "\t");
4517 BufInsert(outBuf, outBuf->length, LanguageModes[i]->name);
4518 BufInsert(outBuf, outBuf->length, ":");
4519 BufInsert(outBuf, outBuf->length, str = createExtString(
4520 LanguageModes[i]->extensions, LanguageModes[i]->nExtensions));
4521 XtFree(str);
4522 BufInsert(outBuf, outBuf->length, ":");
4523 if (LanguageModes[i]->recognitionExpr != NULL) {
4524 BufInsert(outBuf, outBuf->length,
4525 str=MakeQuotedString(LanguageModes[i]->recognitionExpr));
4526 XtFree(str);
4528 BufInsert(outBuf, outBuf->length, ":");
4529 if (LanguageModes[i]->indentStyle != DEFAULT_INDENT)
4530 BufInsert(outBuf, outBuf->length,
4531 AutoIndentTypes[LanguageModes[i]->indentStyle]);
4532 BufInsert(outBuf, outBuf->length, ":");
4533 if (LanguageModes[i]->wrapStyle != DEFAULT_WRAP)
4534 BufInsert(outBuf, outBuf->length,
4535 AutoWrapTypes[LanguageModes[i]->wrapStyle]);
4536 BufInsert(outBuf, outBuf->length, ":");
4537 if (LanguageModes[i]->tabDist != DEFAULT_TAB_DIST) {
4538 sprintf(numBuf, "%d", LanguageModes[i]->tabDist);
4539 BufInsert(outBuf, outBuf->length, numBuf);
4541 BufInsert(outBuf, outBuf->length, ":");
4542 if (LanguageModes[i]->emTabDist != DEFAULT_EM_TAB_DIST) {
4543 sprintf(numBuf, "%d", LanguageModes[i]->emTabDist);
4544 BufInsert(outBuf, outBuf->length, numBuf);
4546 BufInsert(outBuf, outBuf->length, ":");
4547 if (LanguageModes[i]->delimiters != NULL) {
4548 BufInsert(outBuf, outBuf->length,
4549 str=MakeQuotedString(LanguageModes[i]->delimiters));
4550 XtFree(str);
4552 BufInsert(outBuf, outBuf->length, ":");
4553 if (LanguageModes[i]->defTipsFile != NULL) {
4554 BufInsert(outBuf, outBuf->length,
4555 str=MakeQuotedString(LanguageModes[i]->defTipsFile));
4556 XtFree(str);
4559 BufInsert(outBuf, outBuf->length, "\n");
4562 /* Get the output, and lop off the trailing newline */
4563 outStr = BufGetRange(outBuf, 0, outBuf->length - 1);
4564 BufFree(outBuf);
4565 escapedStr = EscapeSensitiveChars(outStr);
4566 XtFree(outStr);
4567 return escapedStr;
4570 static char *createExtString(char **extensions, int nExtensions)
4572 int e, length = 1;
4573 char *outStr, *outPtr;
4575 for (e=0; e<nExtensions; e++)
4576 length += strlen(extensions[e]) + 1;
4577 outStr = outPtr = XtMalloc(length);
4578 for (e=0; e<nExtensions; e++) {
4579 strcpy(outPtr, extensions[e]);
4580 outPtr += strlen(extensions[e]);
4581 *outPtr++ = ' ';
4583 if (nExtensions == 0)
4584 *outPtr = '\0';
4585 else
4586 *(outPtr-1) = '\0';
4587 return outStr;
4590 static char **readExtensionList(char **inPtr, int *nExtensions)
4592 char *extensionList[MAX_FILE_EXTENSIONS];
4593 char **retList, *strStart;
4594 int i, len;
4596 /* skip over blank space */
4597 *inPtr += strspn(*inPtr, " \t");
4599 for (i=0; i<MAX_FILE_EXTENSIONS && **inPtr!=':' && **inPtr!='\0'; i++) {
4600 *inPtr += strspn(*inPtr, " \t");
4601 strStart = *inPtr;
4602 while (**inPtr!=' ' && **inPtr!='\t' && **inPtr!=':' && **inPtr!='\0')
4603 (*inPtr)++;
4604 len = *inPtr - strStart;
4605 extensionList[i] = XtMalloc(len + 1);
4606 strncpy(extensionList[i], strStart, len);
4607 extensionList[i][len] = '\0';
4609 *nExtensions = i;
4610 if (i == 0)
4611 return NULL;
4612 retList = (char **)XtMalloc(sizeof(char *) * i);
4613 memcpy(retList, extensionList, sizeof(char *) * i);
4614 return retList;
4617 int ReadNumericField(char **inPtr, int *value)
4619 int charsRead;
4621 /* skip over blank space */
4622 *inPtr += strspn(*inPtr, " \t");
4624 if (sscanf(*inPtr, "%d%n", value, &charsRead) != 1)
4625 return False;
4626 *inPtr += charsRead;
4627 return True;
4631 ** Parse a symbolic field, skipping initial and trailing whitespace,
4632 ** stops on first invalid character or end of string. Valid characters
4633 ** are letters, numbers, _, -, +, $, #, and internal whitespace. Internal
4634 ** whitespace is compressed to single space characters.
4636 char *ReadSymbolicField(char **inPtr)
4638 char *outStr, *outPtr, *strStart, *strPtr;
4639 int len;
4641 /* skip over initial blank space */
4642 *inPtr += strspn(*inPtr, " \t");
4644 /* Find the first invalid character or end of string to know how
4645 much memory to allocate for the returned string */
4646 strStart = *inPtr;
4647 while (isalnum((unsigned char)**inPtr) || **inPtr=='_' || **inPtr=='-' ||
4648 **inPtr=='+' || **inPtr=='$' || **inPtr=='#' || **inPtr==' ' ||
4649 **inPtr=='\t')
4650 (*inPtr)++;
4651 len = *inPtr - strStart;
4652 if (len == 0)
4653 return NULL;
4654 outStr = outPtr = XtMalloc(len + 1);
4656 /* Copy the string, compressing internal whitespace to a single space */
4657 strPtr = strStart;
4658 while (strPtr - strStart < len) {
4659 if (*strPtr == ' ' || *strPtr == '\t') {
4660 strPtr += strspn(strPtr, " \t");
4661 *outPtr++ = ' ';
4662 } else
4663 *outPtr++ = *strPtr++;
4666 /* If there's space on the end, take it back off */
4667 if (outPtr > outStr && *(outPtr-1) == ' ')
4668 outPtr--;
4669 if (outPtr == outStr) {
4670 XtFree(outStr);
4671 return NULL;
4673 *outPtr = '\0';
4674 return outStr;
4678 ** parse an individual quoted string. Anything between
4679 ** double quotes is acceptable, quote characters can be escaped by "".
4680 ** Returns allocated string "string" containing
4681 ** argument minus quotes. If not successful, returns False with
4682 ** (statically allocated) message in "errMsg".
4684 int ReadQuotedString(char **inPtr, char **errMsg, char **string)
4686 char *outPtr, *c;
4688 /* skip over blank space */
4689 *inPtr += strspn(*inPtr, " \t");
4691 /* look for initial quote */
4692 if (**inPtr != '\"') {
4693 *errMsg = "expecting quoted string";
4694 return False;
4696 (*inPtr)++;
4698 /* calculate max length and allocate returned string */
4699 for (c= *inPtr; ; c++) {
4700 if (*c == '\0') {
4701 *errMsg = "string not terminated";
4702 return False;
4703 } else if (*c == '\"') {
4704 if (*(c+1) == '\"')
4705 c++;
4706 else
4707 break;
4711 /* copy string up to end quote, transforming escaped quotes into quotes */
4712 *string = XtMalloc(c - *inPtr + 1);
4713 outPtr = *string;
4714 while (True) {
4715 if (**inPtr == '\"') {
4716 if (*(*inPtr+1) == '\"')
4717 (*inPtr)++;
4718 else
4719 break;
4721 *outPtr++ = *(*inPtr)++;
4723 *outPtr = '\0';
4725 /* skip end quote */
4726 (*inPtr)++;
4727 return True;
4731 ** Replace characters which the X resource file reader considers control
4732 ** characters, such that a string will read back as it appears in "string".
4733 ** (So far, newline characters are replaced with with \n\<newline> and
4734 ** backslashes with \\. This has not been tested exhaustively, and
4735 ** probably should be. It would certainly be more asthetic if other
4736 ** control characters were replaced as well).
4738 ** Returns an allocated string which must be freed by the caller with XtFree.
4740 char *EscapeSensitiveChars(const char *string)
4742 const char *c;
4743 char *outStr, *outPtr;
4744 int length = 0;
4746 /* calculate length and allocate returned string */
4747 for (c=string; *c!='\0'; c++) {
4748 if (*c == '\\')
4749 length++;
4750 else if (*c == '\n')
4751 length += 3;
4752 length++;
4754 outStr = XtMalloc(length + 1);
4755 outPtr = outStr;
4757 /* add backslashes */
4758 for (c=string; *c!='\0'; c++) {
4759 if (*c == '\\')
4760 *outPtr++ = '\\';
4761 else if (*c == '\n') {
4762 *outPtr++ = '\\';
4763 *outPtr++ = 'n';
4764 *outPtr++ = '\\';
4766 *outPtr++ = *c;
4768 *outPtr = '\0';
4769 return outStr;
4773 ** Adds double quotes around a string and escape existing double quote
4774 ** characters with two double quotes. Enables the string to be read back
4775 ** by ReadQuotedString.
4777 char *MakeQuotedString(const char *string)
4779 const char *c;
4780 char *outStr, *outPtr;
4781 int length = 0;
4783 /* calculate length and allocate returned string */
4784 for (c=string; *c!='\0'; c++) {
4785 if (*c == '\"')
4786 length++;
4787 length++;
4789 outStr = XtMalloc(length + 3);
4790 outPtr = outStr;
4792 /* add starting quote */
4793 *outPtr++ = '\"';
4795 /* copy string, escaping quotes with "" */
4796 for (c=string; *c!='\0'; c++) {
4797 if (*c == '\"')
4798 *outPtr++ = '\"';
4799 *outPtr++ = *c;
4802 /* add ending quote */
4803 *outPtr++ = '\"';
4805 /* terminate string and return */
4806 *outPtr = '\0';
4807 return outStr;
4811 ** Read a dialog text field containing a symbolic name (language mode names,
4812 ** style names, highlight pattern names, colors, and fonts), clean the
4813 ** entered text of leading and trailing whitespace, compress all
4814 ** internal whitespace to one space character, and check it over for
4815 ** colons, which interfere with the preferences file reader/writer syntax.
4816 ** Returns NULL on error, and puts up a dialog if silent is False. Returns
4817 ** an empty string if the text field is blank.
4819 char *ReadSymbolicFieldTextWidget(Widget textW, const char *fieldName, int silent)
4821 char *string, *stringPtr, *parsedString;
4823 /* read from the text widget */
4824 string = stringPtr = XmTextGetString(textW);
4826 /* parse it with the same routine used to read symbolic fields from
4827 files. If the string is not read entirely, there are invalid
4828 characters, so warn the user if not in silent mode. */
4829 parsedString = ReadSymbolicField(&stringPtr);
4830 if (*stringPtr != '\0')
4832 if (!silent)
4834 *(stringPtr + 1) = '\0';
4835 DialogF(DF_WARN, textW, 1, "Invalid Character",
4836 "Invalid character \"%s\" in %s", "OK", stringPtr,
4837 fieldName);
4838 XmProcessTraversal(textW, XmTRAVERSE_CURRENT);
4840 XtFree(string);
4841 if (parsedString != NULL)
4842 XtFree(parsedString);
4843 return NULL;
4845 XtFree(string);
4846 if (parsedString == NULL) {
4847 parsedString = XtMalloc(1);
4848 *parsedString = '\0';
4850 return parsedString;
4854 ** Create a pulldown menu pane with the names of the current language modes.
4855 ** XmNuserData for each item contains the language mode name.
4857 Widget CreateLanguageModeMenu(Widget parent, XtCallbackProc cbProc, void *cbArg)
4859 Widget menu, btn;
4860 int i;
4861 XmString s1;
4863 menu = CreatePulldownMenu(parent, "languageModes", NULL, 0);
4864 for (i=0; i<NLanguageModes; i++) {
4865 btn = XtVaCreateManagedWidget("languageMode", xmPushButtonGadgetClass,
4866 menu,
4867 XmNlabelString, s1=XmStringCreateSimple(LanguageModes[i]->name),
4868 XmNmarginHeight, 0,
4869 XmNuserData, (void *)LanguageModes[i]->name, NULL);
4870 XmStringFree(s1);
4871 XtAddCallback(btn, XmNactivateCallback, cbProc, cbArg);
4873 return menu;
4877 ** Set the language mode menu in option menu "optMenu" to
4878 ** show a particular language mode
4880 void SetLangModeMenu(Widget optMenu, const char *modeName)
4882 int i;
4883 Cardinal nItems;
4884 WidgetList items;
4885 Widget pulldown, selectedItem;
4886 char *itemName;
4888 XtVaGetValues(optMenu, XmNsubMenuId, &pulldown, NULL);
4889 XtVaGetValues(pulldown, XmNchildren, &items, XmNnumChildren, &nItems, NULL);
4890 if (nItems == 0)
4891 return;
4892 selectedItem = items[0];
4893 for (i=0; i<(int)nItems; i++) {
4894 XtVaGetValues(items[i], XmNuserData, &itemName, NULL);
4895 if (!strcmp(itemName, modeName)) {
4896 selectedItem = items[i];
4897 break;
4900 XtVaSetValues(optMenu, XmNmenuHistory, selectedItem,NULL);
4904 ** Create a submenu for chosing language mode for the current window.
4906 Widget CreateLanguageModeSubMenu(WindowInfo *window, Widget parent, char *name,
4907 char *label, char mnemonic)
4909 XmString s1=XmStringCreateSimple(label);
4911 window->langModeCascade = XtVaCreateManagedWidget(name,
4912 xmCascadeButtonGadgetClass, parent, XmNlabelString,
4913 s1, XmNmnemonic, mnemonic,
4914 XmNsubMenuId, NULL, NULL);
4915 XmStringFree(s1);
4916 updateLanguageModeSubmenu(window);
4917 return window->langModeCascade;
4921 ** Re-build the language mode sub-menu using the current data stored
4922 ** in the master list: LanguageModes.
4924 static void updateLanguageModeSubmenu(WindowInfo *window)
4926 int i;
4927 XmString s1;
4928 Widget menu, btn;
4929 Arg args[1] = {{XmNradioBehavior, (XtArgVal)True}};
4931 /* Destroy and re-create the menu pane */
4932 XtVaGetValues(window->langModeCascade, XmNsubMenuId, &menu, NULL);
4933 if (menu != NULL)
4934 XtDestroyWidget(menu);
4935 menu = CreatePulldownMenu(XtParent(window->langModeCascade),
4936 "languageModes", args, 1);
4937 btn = XtVaCreateManagedWidget("languageMode",
4938 xmToggleButtonGadgetClass, menu,
4939 XmNlabelString, s1=XmStringCreateSimple("Plain"),
4940 XmNuserData, (void *)PLAIN_LANGUAGE_MODE,
4941 XmNset, window->languageMode==PLAIN_LANGUAGE_MODE, NULL);
4942 XmStringFree(s1);
4943 XtAddCallback(btn, XmNvalueChangedCallback, setLangModeCB, window);
4944 for (i=0; i<NLanguageModes; i++) {
4945 btn = XtVaCreateManagedWidget("languageMode",
4946 xmToggleButtonGadgetClass, menu,
4947 XmNlabelString, s1=XmStringCreateSimple(LanguageModes[i]->name),
4948 XmNmarginHeight, 0,
4949 XmNuserData, (void *)i,
4950 XmNset, window->languageMode==i, NULL);
4951 XmStringFree(s1);
4952 XtAddCallback(btn, XmNvalueChangedCallback, setLangModeCB, window);
4954 XtVaSetValues(window->langModeCascade, XmNsubMenuId, menu, NULL);
4957 static void setLangModeCB(Widget w, XtPointer clientData, XtPointer callData)
4959 WindowInfo *window = WidgetToWindow(MENU_WIDGET(w));
4960 char *params[1];
4961 void *mode;
4963 if (!XmToggleButtonGetState(w))
4964 return;
4966 /* get name of language mode stored in userData field of menu item */
4967 XtVaGetValues(w, XmNuserData, &mode, NULL);
4969 /* If the mode didn't change, do nothing */
4970 if (window->languageMode == (int)mode)
4971 return;
4973 /* redo syntax highlighting word delimiters, etc. */
4975 reapplyLanguageMode(window, (int)mode, False);
4977 params[0] = (((int)mode) == PLAIN_LANGUAGE_MODE) ? "" : LanguageModes[(int)mode]->name;
4978 XtCallActionProc(window->textArea, "set_language_mode", NULL, params, 1);
4982 ** Skip a delimiter and it's surrounding whitespace
4984 int SkipDelimiter(char **inPtr, char **errMsg)
4986 *inPtr += strspn(*inPtr, " \t");
4987 if (**inPtr != ':') {
4988 *errMsg = "syntax error";
4989 return False;
4991 (*inPtr)++;
4992 *inPtr += strspn(*inPtr, " \t");
4993 return True;
4997 ** Skip an optional separator and its surrounding whitespace
4998 ** return true if delimiter found
5000 int SkipOptSeparator(char separator, char **inPtr)
5002 *inPtr += strspn(*inPtr, " \t");
5003 if (**inPtr != separator) {
5004 return False;
5006 (*inPtr)++;
5007 *inPtr += strspn(*inPtr, " \t");
5008 return True;
5012 ** Short-hand error processing for language mode parsing errors, frees
5013 ** lm (if non-null), prints a formatted message explaining where the
5014 ** error is, and returns False;
5016 static int modeError(languageModeRec *lm, const char *stringStart,
5017 const char *stoppedAt, const char *message)
5019 if (lm != NULL)
5020 freeLanguageModeRec(lm);
5021 return ParseError(NULL, stringStart, stoppedAt,
5022 "language mode specification", message);
5026 ** Report parsing errors in resource strings or macros, formatted nicely so
5027 ** the user can tell where things became botched. Errors can be sent either
5028 ** to stderr, or displayed in a dialog. For stderr, pass toDialog as NULL.
5029 ** For a dialog, pass the dialog parent in toDialog.
5031 int ParseError(Widget toDialog, const char *stringStart, const char *stoppedAt,
5032 const char *errorIn, const char *message)
5034 int len, nNonWhite = 0;
5035 const char *c;
5036 char *errorLine;
5038 for (c=stoppedAt; c>=stringStart; c--) {
5039 if (c == stringStart)
5040 break;
5041 else if (*c == '\n' && nNonWhite >= 5)
5042 break;
5043 else if (*c != ' ' && *c != '\t')
5044 nNonWhite++;
5046 len = stoppedAt - c + (*stoppedAt == '\0' ? 0 : 1);
5047 errorLine = XtMalloc(len+4);
5048 strncpy(errorLine, c, len);
5049 errorLine[len++] = '<';
5050 errorLine[len++] = '=';
5051 errorLine[len++] = '=';
5052 errorLine[len] = '\0';
5053 if (toDialog == NULL)
5055 fprintf(stderr, "NEdit: %s in %s:\n%s\n", message, errorIn, errorLine);
5056 } else
5058 DialogF(DF_WARN, toDialog, 1, "Parse Error", "%s in %s:\n%s", "OK",
5059 message, errorIn, errorLine);
5061 XtFree(errorLine);
5062 return False;
5066 ** Compare two strings which may be NULL
5068 int AllocatedStringsDiffer(const char *s1, const char *s2)
5070 if (s1 == NULL && s2 == NULL)
5071 return False;
5072 if (s1 == NULL || s2 == NULL)
5073 return True;
5074 return strcmp(s1, s2);
5077 static void updatePatternsTo5dot1(void)
5079 const char *htmlDefaultExpr = "^[ \t]*HTML[ \t]*:[ \t]*Default[ \t]*$";
5080 const char *vhdlAnchorExpr = "^[ \t]*VHDL:";
5082 /* Add new patterns if there aren't already existing patterns with
5083 the same name. If possible, insert before VHDL in language mode
5084 list. If not, just add to end */
5085 if (!regexFind(TempStringPrefs.highlight, "^[ \t]*PostScript:"))
5086 spliceString(&TempStringPrefs.highlight, "PostScript:Default",
5087 vhdlAnchorExpr);
5088 if (!regexFind(TempStringPrefs.language, "^[ \t]*PostScript:"))
5089 spliceString(&TempStringPrefs.language,
5090 "PostScript:.ps .PS .eps .EPS .epsf .epsi::::::",
5091 vhdlAnchorExpr);
5092 if (!regexFind(TempStringPrefs.highlight, "^[ \t]*Lex:"))
5093 spliceString(&TempStringPrefs.highlight, "Lex:Default",
5094 vhdlAnchorExpr);
5095 if (!regexFind(TempStringPrefs.language, "^[ \t]*Lex:"))
5096 spliceString(&TempStringPrefs.language, "Lex:.lex::::::",
5097 vhdlAnchorExpr);
5098 if (!regexFind(TempStringPrefs.highlight, "^[ \t]*SQL:"))
5099 spliceString(&TempStringPrefs.highlight, "SQL:Default",
5100 vhdlAnchorExpr);
5101 if (!regexFind(TempStringPrefs.language, "^[ \t]*SQL:"))
5102 spliceString(&TempStringPrefs.language, "SQL:.sql::::::",
5103 vhdlAnchorExpr);
5104 if (!regexFind(TempStringPrefs.highlight, "^[ \t]*Matlab:"))
5105 spliceString(&TempStringPrefs.highlight, "Matlab:Default",
5106 vhdlAnchorExpr);
5107 if (!regexFind(TempStringPrefs.language, "^[ \t]*Matlab:"))
5108 spliceString(&TempStringPrefs.language, "Matlab:..m .oct .sci::::::",
5109 vhdlAnchorExpr);
5110 if (!regexFind(TempStringPrefs.smartIndent, "^[ \t]*Matlab:"))
5111 spliceString(&TempStringPrefs.smartIndent, "Matlab:Default", NULL);
5112 if (!regexFind(TempStringPrefs.styles, "^[ \t]*Label:"))
5113 spliceString(&TempStringPrefs.styles, "Label:red:Italic",
5114 "^[ \t]*Flag:");
5115 if (!regexFind(TempStringPrefs.styles, "^[ \t]*Storage Type1:"))
5116 spliceString(&TempStringPrefs.styles, "Storage Type1:saddle brown:Bold",
5117 "^[ \t]*String:");
5119 /* Replace html pattern with sgml html pattern, as long as there
5120 isn't an existing html pattern which will be overwritten */
5121 if (regexFind(TempStringPrefs.highlight, htmlDefaultExpr)) {
5122 regexReplace(&TempStringPrefs.highlight, htmlDefaultExpr,
5123 "SGML HTML:Default");
5124 if (!regexReplace(&TempStringPrefs.language, "^[ \t]*HTML:.*$",
5125 "SGML HTML:.sgml .sgm .html .htm:\"\\<(?ihtml)\\>\":::::\n")) {
5126 spliceString(&TempStringPrefs.language,
5127 "SGML HTML:.sgml .sgm .html .htm:\"\\<(?ihtml)\\>\":::::\n",
5128 vhdlAnchorExpr);
5133 static void updatePatternsTo5dot2(void)
5135 #ifdef VMS
5136 const char *cppLm5dot1 =
5137 "^[ \t]*C\\+\\+:\\.CC \\.HH \\.I::::::\"\\.,/\\\\`'!\\|@#%\\^&\\*\\(\\)-=\\+\\{\\}\\[\\]\"\":;\\<\\>\\?~\"";
5138 const char *perlLm5dot1 =
5139 "^[ \t]*Perl:\\.PL \\.PM \\.P5:\"\\^\\[ \\\\t\\]\\*#\\[ \\\\t\\]\\*!\\.\\*perl\":::::";
5140 const char *psLm5dot1 =
5141 "^[ \t]*PostScript:\\.ps \\.PS \\.eps \\.EPS \\.epsf \\.epsi:\"\\^%!\":::::\"/%\\(\\)\\{\\}\\[\\]\\<\\>\"";
5142 const char *tclLm5dot1 = "^[ \t]*Tcl:\\.TCL::::::";
5144 const char *cppLm5dot2 =
5145 "C++:.CC .HH .C .H .I .CXX .HXX .CPP::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\"";
5146 const char *perlLm5dot2 =
5147 "Perl:.PL .PM .P5:\"^[ \\t]*#[ \\t]*!.*perl\":Auto:None:::\".,/\\\\`'!$@#%^&*()-=+{}[]\"\":;<>?~|\"";
5148 const char *psLm5dot2 =
5149 "PostScript:.ps .PS .eps .EPS .epsf .epsi:\"^%!\":::::\"/%(){}[]<>\"";
5150 const char *tclLm5dot2 =
5151 "Tcl:.TCL::Smart:None:::";
5152 #else
5153 const char *cppLm5dot1 =
5154 "^[ \t]*C\\+\\+:\\.cc \\.hh \\.C \\.H \\.i \\.cxx \\.hxx::::::\"\\.,/\\\\`'!\\|@#%\\^&\\*\\(\\)-=\\+\\{\\}\\[\\]\"\":;\\<\\>\\?~\"";
5155 const char *perlLm5dot1 =
5156 "^[ \t]*Perl:\\.pl \\.pm \\.p5:\"\\^\\[ \\\\t\\]\\*#\\[ \\\\t\\]\\*!\\.\\*perl\":::::";
5157 const char *psLm5dot1 =
5158 "^[ \t]*PostScript:\\.ps \\.PS \\.eps \\.EPS \\.epsf \\.epsi:\"\\^%!\":::::\"/%\\(\\)\\{\\}\\[\\]\\<\\>\"";
5159 const char *shLm5dot1 =
5160 "^[ \t]*Sh Ksh Bash:\\.sh \\.bash \\.ksh \\.profile:\"\\^\\[ \\\\t\\]\\*#\\[ \\\\t\\]\\*!\\[ \\\\t\\]\\*/bin/\\(sh\\|ksh\\|bash\\)\":::::";
5161 const char *tclLm5dot1 = "^[ \t]*Tcl:\\.tcl::::::";
5163 const char *cppLm5dot2 =
5164 "C++:.cc .hh .C .H .i .cxx .hxx .cpp::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\"";
5165 const char *perlLm5dot2 =
5166 "Perl:.pl .pm .p5 .PL:\"^[ \\t]*#[ \\t]*!.*perl\":Auto:None:::\".,/\\\\`'!$@#%^&*()-=+{}[]\"\":;<>?~|\"";
5167 const char *psLm5dot2 =
5168 "PostScript:.ps .eps .epsf .epsi:\"^%!\":::::\"/%(){}[]<>\"";
5169 const char *shLm5dot2 =
5170 "Sh Ksh Bash:.sh .bash .ksh .profile .bashrc .bash_logout .bash_login .bash_profile:\"^[ \\t]*#[ \\t]*![ \\t]*/.*bin/(sh|ksh|bash)\":::::";
5171 const char *tclLm5dot2 =
5172 "Tcl:.tcl .tk .itcl .itk::Smart:None:::";
5173 #endif /* VMS */
5175 const char *cssLm5dot2 =
5176 "CSS:css::Auto:None:::\".,/\\`'!|@#%^&*()=+{}[]\"\":;<>?~\"";
5177 const char *reLm5dot2 =
5178 "Regex:.reg .regex:\"\\(\\?[:#=!iInN].+\\)\":None:Continuous:::";
5179 const char *xmlLm5dot2 =
5180 "XML:.xml .xsl .dtd:\"\\<(?i\\?xml|!doctype)\"::None:::\"<>/=\"\"'()+*?|\"";
5182 const char *cssHl5dot2 = "CSS:Default";
5183 const char *reHl5dot2 = "Regex:Default";
5184 const char *xmlHl5dot2 = "XML:Default";
5186 const char *ptrStyle = "Pointer:#660000:Bold";
5187 const char *reStyle = "Regex:#009944:Bold";
5188 const char *wrnStyle = "Warning:brown2:Italic";
5190 /* First upgrade modified language modes, only if the user hasn't
5191 altered the default 5.1 definitions. */
5192 if (regexFind(TempStringPrefs.language, cppLm5dot1))
5193 regexReplace(&TempStringPrefs.language, cppLm5dot1, cppLm5dot2);
5194 if (regexFind(TempStringPrefs.language, perlLm5dot1))
5195 regexReplace(&TempStringPrefs.language, perlLm5dot1, perlLm5dot2);
5196 if (regexFind(TempStringPrefs.language, psLm5dot1))
5197 regexReplace(&TempStringPrefs.language, psLm5dot1, psLm5dot2);
5198 #ifndef VMS
5199 if (regexFind(TempStringPrefs.language, shLm5dot1))
5200 regexReplace(&TempStringPrefs.language, shLm5dot1, shLm5dot2);
5201 #endif
5202 if (regexFind(TempStringPrefs.language, tclLm5dot1))
5203 regexReplace(&TempStringPrefs.language, tclLm5dot1, tclLm5dot2);
5205 /* Then append the new modes (trying to keep them in alphabetical order
5206 makes no sense, since 5.1 didn't use alphabetical order). */
5207 if (!regexFind(TempStringPrefs.language, "^[ \t]*CSS:"))
5208 spliceString(&TempStringPrefs.language, cssLm5dot2, NULL);
5209 if (!regexFind(TempStringPrefs.language, "^[ \t]*Regex:"))
5210 spliceString(&TempStringPrefs.language, reLm5dot2, NULL);
5211 if (!regexFind(TempStringPrefs.language, "^[ \t]*XML:"))
5212 spliceString(&TempStringPrefs.language, xmlLm5dot2, NULL);
5214 /* Enable default highlighting patterns for these modes, unless already
5215 present */
5216 if (!regexFind(TempStringPrefs.highlight, "^[ \t]*CSS:"))
5217 spliceString(&TempStringPrefs.highlight, cssHl5dot2, NULL);
5218 if (!regexFind(TempStringPrefs.highlight, "^[ \t]*Regex:"))
5219 spliceString(&TempStringPrefs.highlight, reHl5dot2, NULL);
5220 if (!regexFind(TempStringPrefs.highlight, "^[ \t]*XML:"))
5221 spliceString(&TempStringPrefs.highlight, xmlHl5dot2, NULL);
5223 /* Finally, append the new highlight styles */
5225 if (!regexFind(TempStringPrefs.styles, "^[ \t]*Warning:"))
5226 spliceString(&TempStringPrefs.styles, wrnStyle, NULL);
5227 if (!regexFind(TempStringPrefs.styles, "^[ \t]*Regex:"))
5228 spliceString(&TempStringPrefs.styles, reStyle, "^[ \t]*Warning:");
5229 if (!regexFind(TempStringPrefs.styles, "^[ \t]*Pointer:"))
5230 spliceString(&TempStringPrefs.styles, ptrStyle, "^[ \t]*Regex:");
5233 static void updatePatternsTo5dot3(void)
5235 /* This is a bogus function on non-VMS */
5236 #ifdef VMS
5237 const char *psLm5dot2 =
5238 "^[ \t]*PostScript:\\.ps \\.PS \\.eps \\.EPS \\.epsf \\.epsi:\"\\^%!\":::::\"/%\\(\\)\\{\\}\\[\\]\\<\\>\"";
5240 const char *psLm5dot3 =
5241 "PostScript:.ps .PS .eps .EPS .epsf .EPSF .epsi .EPSI:\"^%!\":::::\"/%(){}[]<>\"";
5243 /* Upgrade modified language modes, only if the user hasn't
5244 altered the default 5.2 definitions. */
5245 if (regexFind(TempStringPrefs.language, psLm5dot2))
5246 regexReplace(&TempStringPrefs.language, psLm5dot2, psLm5dot3);
5247 #endif
5250 static void updatePatternsTo5dot4(void)
5252 #ifdef VMS
5253 const char *pyLm5dot3 =
5254 "Python:\\.PY:\"\\^#!\\.\\*python\":Auto:None::::?\n";
5255 const char *xrLm5dot3 =
5256 "X Resources:\\.XRESOURCES \\.XDEFAULTS \\.NEDIT:\"\\^\\[!#\\]\\.\\*\\(\\[Aa\\]pp\\|\\[Xx\\]\\)\\.\\*\\[Dd\\]efaults\"::::::?\n";
5258 const char *pyLm5dot4 =
5259 "Python:.PY:\"^#!.*python\":Auto:None:::\"!\"\"#$%&'()*+,-./:;<=>?@[\\\\]^`{|}~\":\n";
5260 const char *xrLm5dot4 =
5261 "X Resources:.XRESOURCES .XDEFAULTS .NEDIT NEDIT.RC:\"^[!#].*([Aa]pp|[Xx]).*[Dd]efaults\"::::::\n";
5262 #else
5263 const char *pyLm5dot3 =
5264 "Python:\\.py:\"\\^#!\\.\\*python\":Auto:None::::?\n";
5265 const char *xrLm5dot3 =
5266 "X Resources:\\.Xresources \\.Xdefaults \\.nedit:\"\\^\\[!#\\]\\.\\*\\(\\[Aa\\]pp\\|\\[Xx\\]\\)\\.\\*\\[Dd\\]efaults\"::::::?\n";
5268 const char *pyLm5dot4 =
5269 "Python:.py:\"^#!.*python\":Auto:None:::\"!\"\"#$%&'()*+,-./:;<=>?@[\\\\]^`{|}~\":\n";
5270 const char *xrLm5dot4 =
5271 "X Resources:.Xresources .Xdefaults .nedit nedit.rc:\"^[!#].*([Aa]pp|[Xx]).*[Dd]efaults\"::::::\n";
5272 #endif
5274 /* Upgrade modified language modes, only if the user hasn't
5275 altered the default 5.3 definitions. */
5276 if (regexFind(TempStringPrefs.language, pyLm5dot3))
5277 regexReplace(&TempStringPrefs.language, pyLm5dot3, pyLm5dot4);
5278 if (regexFind(TempStringPrefs.language, xrLm5dot3))
5279 regexReplace(&TempStringPrefs.language, xrLm5dot3, xrLm5dot4);
5281 /* Add new styles */
5282 if (!regexFind(TempStringPrefs.styles, "^[ \t]*Identifier2:"))
5283 spliceString(&TempStringPrefs.styles, "Identifier2:SteelBlue:Plain",
5284 "^[ \t]*Subroutine:");
5288 * We migrate a color from the X resources to the prefs if:
5289 * 1. The prefs entry is equal to the default entry
5290 * 2. The X resource is not equal to the default entry
5292 static void migrateColor(XrmDatabase prefDB, XrmDatabase appDB,
5293 char *class, char *name, int color_index, char *default_val)
5295 char *type, *valueString;
5296 XrmValue rsrcValue;
5298 /* If this color has been customized in the color dialog then use
5299 that value */
5300 if ( strcmp(default_val, PrefData.colorNames[color_index]) )
5301 return;
5303 /* Retrieve the value of the resource from the DB */
5304 if (XrmGetResource(prefDB, name, class, &type, &rsrcValue)) {
5305 if (strcmp(type, XmRString)) {
5306 fprintf(stderr,"Internal Error: Unexpected resource type, %s\n",
5307 type);
5308 return;
5310 valueString = rsrcValue.addr;
5311 } else if (XrmGetResource(appDB, name, class, &type, &rsrcValue)) {
5312 if (strcmp(type, XmRString)) {
5313 fprintf(stderr,"Internal Error: Unexpected resource type, %s\n",
5314 type);
5315 return;
5317 valueString = rsrcValue.addr;
5318 } else
5319 /* No resources set */
5320 return;
5322 /* An X resource is set. If it's non-default, update the prefs. */
5323 if ( strcmp(valueString, default_val) ) {
5324 strncpy(PrefData.colorNames[color_index], valueString,
5325 MAX_COLOR_LEN);
5330 * In 5.4 we moved color preferences from X resources to a color dialog,
5331 * meaning they're in the normal prefs system. Users who have customized
5332 * their colors with X resources would probably prefer not to have to redo
5333 * the customization in the dialog, so we migrate them to the prefs for them.
5335 static void migrateColorResources(XrmDatabase prefDB, XrmDatabase appDB)
5337 migrateColor(prefDB, appDB, APP_CLASS ".Text.Foreground",
5338 APP_NAME ".text.foreground", TEXT_FG_COLOR,
5339 NEDIT_DEFAULT_FG);
5340 migrateColor(prefDB, appDB, APP_CLASS ".Text.Background",
5341 APP_NAME ".text.background", TEXT_BG_COLOR,
5342 NEDIT_DEFAULT_TEXT_BG);
5343 migrateColor(prefDB, appDB, APP_CLASS ".Text.SelectForeground",
5344 APP_NAME ".text.selectForeground", SELECT_FG_COLOR,
5345 NEDIT_DEFAULT_SEL_FG);
5346 migrateColor(prefDB, appDB, APP_CLASS ".Text.SelectBackground",
5347 APP_NAME ".text.selectBackground", SELECT_BG_COLOR,
5348 NEDIT_DEFAULT_SEL_BG);
5349 migrateColor(prefDB, appDB, APP_CLASS ".Text.HighlightForeground",
5350 APP_NAME ".text.highlightForeground", HILITE_FG_COLOR,
5351 NEDIT_DEFAULT_HI_FG);
5352 migrateColor(prefDB, appDB, APP_CLASS ".Text.HighlightBackground",
5353 APP_NAME ".text.highlightBackground", HILITE_BG_COLOR,
5354 NEDIT_DEFAULT_HI_BG);
5355 migrateColor(prefDB, appDB, APP_CLASS ".Text.LineNumForeground",
5356 APP_NAME ".text.lineNumForeground", LINENO_FG_COLOR,
5357 NEDIT_DEFAULT_LINENO_FG);
5358 migrateColor(prefDB, appDB, APP_CLASS ".Text.CursorForeground",
5359 APP_NAME ".text.cursorForeground", CURSOR_FG_COLOR,
5360 NEDIT_DEFAULT_CURSOR_FG);
5364 ** Inserts a string into intoString, reallocating it with XtMalloc. If
5365 ** regular expression atExpr is found, inserts the string before atExpr
5366 ** followed by a newline. If atExpr is not found, inserts insertString
5367 ** at the end, PRECEDED by a newline.
5369 static void spliceString(char **intoString, const char *insertString, const char *atExpr)
5371 int beginPos, endPos;
5372 int intoLen = strlen(*intoString);
5373 int insertLen = strlen(insertString);
5374 char *newString = XtMalloc(intoLen + insertLen + 2);
5376 if (atExpr != NULL && SearchString(*intoString, atExpr,
5377 SEARCH_FORWARD, SEARCH_REGEX, False, 0, &beginPos, &endPos,
5378 NULL, NULL, NULL)) {
5379 strncpy(newString, *intoString, beginPos);
5380 strncpy(&newString[beginPos], insertString, insertLen);
5381 newString[beginPos+insertLen] = '\n';
5382 strncpy(&newString[beginPos+insertLen+1],
5383 &((*intoString)[beginPos]), intoLen - beginPos);
5384 } else {
5385 strncpy(newString, *intoString, intoLen);
5386 newString[intoLen] = '\n';
5387 strncpy(&newString[intoLen+1], insertString, insertLen);
5389 newString[intoLen + insertLen + 1] = '\0';
5390 XtFree(*intoString);
5391 *intoString = newString;
5395 ** Simplified regular expression search routine which just returns true
5396 ** or false depending on whether inString matches expr
5398 static int regexFind(const char *inString, const char *expr)
5400 int beginPos, endPos;
5401 return SearchString(inString, expr, SEARCH_FORWARD, SEARCH_REGEX, False,
5402 0, &beginPos, &endPos, NULL, NULL, NULL);
5406 ** Simplified regular expression replacement routine which replaces the
5407 ** first occurence of expr in inString with replaceWith, reallocating
5408 ** inString with XtMalloc. If expr is not found, does nothing and
5409 ** returns false.
5411 static int regexReplace(char **inString, const char *expr, const char *replaceWith)
5413 int beginPos, endPos, newLen;
5414 char *newString;
5415 int replaceLen = strlen(replaceWith);
5416 int inLen = strlen(*inString);
5418 if (!SearchString(*inString, expr, SEARCH_FORWARD, SEARCH_REGEX, False,
5419 0, &beginPos, &endPos, NULL, NULL, NULL))
5420 return FALSE;
5421 newLen = inLen + replaceLen - (endPos-beginPos);
5422 newString = XtMalloc(newLen + 1);
5423 strncpy(newString, *inString, beginPos);
5424 strncpy(&newString[beginPos], replaceWith, replaceLen);
5425 strncpy(&newString[beginPos+replaceLen],
5426 &((*inString)[endPos]), inLen - endPos);
5427 newString[newLen] = '\0';
5428 XtFree(*inString);
5429 *inString = newString;
5430 return TRUE;
5434 #ifndef VMS
5436 ** Replace all '#' characters in shell commands by '##' to keep commands
5437 ** containing those working. '#' is a line number placeholder in 5.3 and
5438 ** had no special meaning before.
5440 static void updateShellCmdsTo5dot3(void)
5442 char *cOld, *cNew, *pCol, *pNL;
5443 int nHash, isCmd;
5444 char *newString;
5446 if(!TempStringPrefs.shellCmds)
5447 return;
5449 /* Count number of '#'. If there are '#' characters in the non-command
5450 ** part of the definition we count too much and later allocate too much
5451 ** memory for the new string, but this doesn't hurt.
5453 for(cOld=TempStringPrefs.shellCmds, nHash=0; *cOld; cOld++)
5454 if(*cOld == '#')
5455 nHash++;
5457 /* No '#' -> no conversion necessary. */
5458 if(!nHash)
5459 return;
5461 newString=XtMalloc(strlen(TempStringPrefs.shellCmds) + 1 + nHash);
5463 cOld = TempStringPrefs.shellCmds;
5464 cNew = newString;
5465 isCmd = 0;
5466 pCol = NULL;
5467 pNL = NULL;
5469 /* Copy all characters from TempStringPrefs.shellCmds into newString
5470 ** and duplicate '#' in command parts. A simple check for really beeing
5471 ** inside a command part (starting with '\n', between the the two last
5472 ** '\n' a colon ':' must have been found) is preformed.
5474 while(*cOld) {
5475 /* actually every 2nd line is a command. We additionally
5476 ** check if there is a colon ':' in the previous line.
5478 if(*cOld=='\n') {
5479 if((pCol > pNL) && !isCmd)
5480 isCmd=1;
5481 else
5482 isCmd=0;
5483 pNL=cOld;
5486 if(!isCmd && *cOld ==':')
5487 pCol = cOld;
5489 /* Duplicate hashes if we're in a command part */
5490 if(isCmd && *cOld=='#')
5491 *cNew++ = '#';
5493 /* Copy every character */
5494 *cNew++ = *cOld++;
5498 /* Terminate new preferences string */
5499 *cNew = 0;
5501 /* free the old memory */
5502 XtFree(TempStringPrefs.shellCmds);
5504 /* exchange the string */
5505 TempStringPrefs.shellCmds = newString;
5509 #else
5511 static void updateShellCmdsTo5dot3(void) {
5512 /* No shell commands in VMS ! */
5513 return;
5516 #endif
5518 static void updateShellCmdsTo5dot4(void)
5520 #ifndef VMS /* No shell commands on VMS */
5522 #ifdef __FreeBSD__
5523 const char* wc5dot3 =
5524 "^(\\s*)set wc=`wc`; echo \\$wc\\[1\\] \"words,\" \\$wc\\[2\\] \"lines,\" \\$wc\\[3\\] \"characters\"\\n";
5525 const char* wc5dot4 =
5526 "wc | awk '{print $2 \" lines, \" $1 \" words, \" $3 \" characters\"}'\n";
5527 #else
5528 const char* wc5dot3 =
5529 "^(\\s*)set wc=`wc`; echo \\$wc\\[1\\] \"lines,\" \\$wc\\[2\\] \"words,\" \\$wc\\[3\\] \"characters\"\\n";
5530 const char* wc5dot4 =
5531 "wc | awk '{print $1 \" lines, \" $2 \" words, \" $3 \" characters\"}'\n";
5532 #endif /* __FreeBSD__ */
5534 if (regexFind(TempStringPrefs.shellCmds, wc5dot3))
5535 regexReplace(&TempStringPrefs.shellCmds, wc5dot3, wc5dot4);
5537 #endif /* VMS */
5539 return;
5542 static void updateMacroCmdsTo5dot5(void)
5544 const char* uc5dot4 =
5545 "^(\\s*)if \\(substring\\(sel, keepEnd - 1, keepEnd == \" \"\\)\\)\\n";
5546 const char* uc5dot5 =
5547 " if (substring(sel, keepEnd - 1, keepEnd) == \" \")\n";
5548 if (regexFind(TempStringPrefs.macroCmds, uc5dot4))
5549 regexReplace(&TempStringPrefs.macroCmds, uc5dot4, uc5dot5);
5551 return;
5554 #ifdef SGI_CUSTOM
5556 ** Present the user a dialog for specifying whether or not a short
5557 ** menu mode preference should be applied toward the default setting.
5558 ** Return False (function value) if operation was canceled, return True
5559 ** in setDefault if requested to reset the default value.
5561 static int shortPrefToDefault(Widget parent, const char *settingName, int *setDefault)
5563 char msg[100] = "";
5565 if (!GetPrefShortMenus()) {
5566 *setDefault = False;
5567 return True;
5570 sprintf(msg, "%s\nSave as default for future windows as well?", settingName);
5571 switch (DialogF (DF_QUES, parent, 3, "Save Default", msg, "Yes", "No",
5572 "Cancel"))
5574 case 1: /* yes */
5575 *setDefault = True;
5576 return True;
5577 case 2: /* no */
5578 *setDefault = False;
5579 return True;
5580 case 3: /* cancel */
5581 return False;
5583 return False; /* not reached */
5585 #endif
5587 /* Decref the default calltips file(s) for this window */
5588 void UnloadLanguageModeTipsFile(WindowInfo *window) {
5589 int mode;
5591 mode = window->languageMode;
5592 if (mode != PLAIN_LANGUAGE_MODE && LanguageModes[mode]->defTipsFile) {
5593 DeleteTagsFile( LanguageModes[mode]->defTipsFile, TIP, False );
5597 /******************************************************************************
5598 * The Color selection dialog
5599 ******************************************************************************/
5602 There are 8 colors: And 8 indices:
5603 textFg TEXT_FG_COLOR
5604 textBg TEXT_BG_COLOR
5605 selectFg SELECT_FG_COLOR
5606 selectBg SELECT_BG_COLOR
5607 hiliteFg HILITE_FG_COLOR
5608 hiliteBg HILITE_BG_COLOR
5609 lineNoFg LINENO_FG_COLOR
5610 cursorFg CURSOR_FG_COLOR
5613 #define MARGIN_SPACING 10
5616 * Callbacks for field modifications
5618 static void textFgModifiedCB(Widget w, XtPointer clientData,
5619 XtPointer callData)
5621 colorDialog *cd = (colorDialog *)clientData;
5622 showColorStatus(cd, cd->textFgW, cd->textFgErrW);
5625 static void textBgModifiedCB(Widget w, XtPointer clientData,
5626 XtPointer callData)
5628 colorDialog *cd = (colorDialog *)clientData;
5629 showColorStatus(cd, cd->textBgW, cd->textBgErrW);
5632 static void selectFgModifiedCB(Widget w, XtPointer clientData,
5633 XtPointer callData)
5635 colorDialog *cd = (colorDialog *)clientData;
5636 showColorStatus(cd, cd->selectFgW, cd->selectFgErrW);
5639 static void selectBgModifiedCB(Widget w, XtPointer clientData,
5640 XtPointer callData)
5642 colorDialog *cd = (colorDialog *)clientData;
5643 showColorStatus(cd, cd->selectBgW, cd->selectBgErrW);
5646 static void hiliteFgModifiedCB(Widget w, XtPointer clientData,
5647 XtPointer callData)
5649 colorDialog *cd = (colorDialog *)clientData;
5650 showColorStatus(cd, cd->hiliteFgW, cd->hiliteFgErrW);
5653 static void hiliteBgModifiedCB(Widget w, XtPointer clientData,
5654 XtPointer callData)
5656 colorDialog *cd = (colorDialog *)clientData;
5657 showColorStatus(cd, cd->hiliteBgW, cd->hiliteBgErrW);
5660 static void lineNoFgModifiedCB(Widget w, XtPointer clientData,
5661 XtPointer callData)
5663 colorDialog *cd = (colorDialog *)clientData;
5664 showColorStatus(cd, cd->lineNoFgW, cd->lineNoFgErrW);
5667 static void cursorFgModifiedCB(Widget w, XtPointer clientData,
5668 XtPointer callData)
5670 colorDialog *cd = (colorDialog *)clientData;
5671 showColorStatus(cd, cd->cursorFgW, cd->cursorFgErrW);
5676 * Helper functions for validating colors
5678 static int verifyAllColors(colorDialog *cd) {
5679 /* Maybe just check for empty strings in error widgets instead? */
5680 return (checkColorStatus(cd, cd->textFgW) &&
5681 checkColorStatus(cd, cd->textBgW) &&
5682 checkColorStatus(cd, cd->selectFgW) &&
5683 checkColorStatus(cd, cd->selectBgW) &&
5684 checkColorStatus(cd, cd->hiliteFgW) &&
5685 checkColorStatus(cd, cd->hiliteBgW) &&
5686 checkColorStatus(cd, cd->lineNoFgW) &&
5687 checkColorStatus(cd, cd->cursorFgW) );
5690 /* Returns True if the color is valid, False if it's not */
5691 static Boolean checkColorStatus(colorDialog *cd, Widget colorFieldW)
5693 Colormap cMap;
5694 XColor colorDef;
5695 Status status;
5696 Display *display = XtDisplay(cd->shell);
5697 char *text = XmTextGetString(colorFieldW);
5698 XtVaGetValues(cd->shell, XtNcolormap, &cMap, NULL);
5699 status = XParseColor(display, cMap, text, &colorDef);
5700 XtFree(text);
5701 return (status != 0);
5704 /* Show or hide errorLabelW depending on whether or not colorFieldW
5705 contains a valid color name. */
5706 static void showColorStatus(colorDialog *cd, Widget colorFieldW,
5707 Widget errorLabelW)
5709 /* Should set the OK/Apply button sensitivity here, instead
5710 of leaving is sensitive and then complaining if an error. */
5711 XtSetMappedWhenManaged( errorLabelW, !checkColorStatus(cd, colorFieldW) );
5714 /* Update the colors in the window or in the preferences */
5715 static void updateColors(colorDialog *cd)
5717 WindowInfo *window;
5719 char *textFg = XmTextGetString(cd->textFgW),
5720 *textBg = XmTextGetString(cd->textBgW),
5721 *selectFg = XmTextGetString(cd->selectFgW),
5722 *selectBg = XmTextGetString(cd->selectBgW),
5723 *hiliteFg = XmTextGetString(cd->hiliteFgW),
5724 *hiliteBg = XmTextGetString(cd->hiliteBgW),
5725 *lineNoFg = XmTextGetString(cd->lineNoFgW),
5726 *cursorFg = XmTextGetString(cd->cursorFgW);
5728 for (window = WindowList; window != NULL; window = window->next)
5730 SetColors(window, textFg, textBg, selectFg, selectBg, hiliteFg,
5731 hiliteBg, lineNoFg, cursorFg);
5734 SetPrefColorName(TEXT_FG_COLOR , textFg );
5735 SetPrefColorName(TEXT_BG_COLOR , textBg );
5736 SetPrefColorName(SELECT_FG_COLOR, selectFg);
5737 SetPrefColorName(SELECT_BG_COLOR, selectBg);
5738 SetPrefColorName(HILITE_FG_COLOR, hiliteFg);
5739 SetPrefColorName(HILITE_BG_COLOR, hiliteBg);
5740 SetPrefColorName(LINENO_FG_COLOR, lineNoFg);
5741 SetPrefColorName(CURSOR_FG_COLOR, cursorFg);
5743 XtFree(textFg);
5744 XtFree(textBg);
5745 XtFree(selectFg);
5746 XtFree(selectBg);
5747 XtFree(hiliteFg);
5748 XtFree(hiliteBg);
5749 XtFree(lineNoFg);
5750 XtFree(cursorFg);
5755 * Dialog button callbacks
5758 static void colorDestroyCB(Widget w, XtPointer clientData, XtPointer callData)
5760 colorDialog *cd = (colorDialog *)clientData;
5762 cd->window->colorDialog = NULL;
5763 XtFree((char *)cd);
5766 static void colorOkCB(Widget w, XtPointer clientData, XtPointer callData)
5768 colorDialog *cd = (colorDialog *)clientData;
5770 if(!verifyAllColors(cd))
5772 DialogF(DF_ERR, w, 1, "Invalid Colors",
5773 "All colors must be valid to proceed.", "OK");
5774 return;
5776 updateColors(cd);
5778 /* pop down and destroy the dialog */
5779 XtDestroyWidget(cd->shell);
5782 static void colorApplyCB(Widget w, XtPointer clientData, XtPointer callData)
5784 colorDialog *cd = (colorDialog *)clientData;
5786 if(!verifyAllColors(cd))
5788 DialogF(DF_ERR, w, 1, "Invalid Colors",
5789 "All colors must be valid to be applied.", "OK");
5790 return;
5792 updateColors(cd);
5795 static void colorCloseCB(Widget w, XtPointer clientData, XtPointer callData)
5797 colorDialog *cd = (colorDialog *)clientData;
5799 /* pop down and destroy the dialog */
5800 XtDestroyWidget(cd->shell);
5804 /* Add a label, error label, and text entry label with a validation
5805 callback */
5806 static Widget addColorGroup( Widget parent, const char *name, char mnemonic,
5807 char *label, Widget *fieldW, Widget *errW, Widget topWidget,
5808 int leftPos, int rightPos, XtCallbackProc modCallback,
5809 colorDialog *cd )
5811 Widget lblW;
5812 char *longerName;
5813 XmString s1;
5814 int nameLen = strlen(name);
5816 /* The label widget */
5817 longerName = XtMalloc(nameLen+7);
5818 strcpy(longerName, name);
5819 strcat(longerName, "Lbl");
5820 lblW = XtVaCreateManagedWidget(longerName,
5821 xmLabelGadgetClass, parent,
5822 XmNlabelString, s1=XmStringCreateSimple( label ),
5823 XmNmnemonic, mnemonic,
5824 XmNtopAttachment, XmATTACH_WIDGET,
5825 XmNtopWidget, topWidget,
5826 XmNtopOffset, MARGIN_SPACING,
5827 XmNleftAttachment, XmATTACH_POSITION,
5828 XmNleftPosition, leftPos, NULL);
5829 XmStringFree(s1);
5831 /* The error label widget */
5832 strcpy(&(longerName[nameLen]), "ErrLbl");
5833 *errW = XtVaCreateManagedWidget(longerName,
5834 xmLabelWidgetClass, parent,
5835 XmNlabelString, s1=XmStringCreateSimple("(Invalid!)"),
5836 XmNalignment, XmALIGNMENT_END,
5837 XmNtopAttachment, XmATTACH_WIDGET,
5838 XmNtopWidget, topWidget,
5839 XmNtopOffset, MARGIN_SPACING,
5840 XmNleftAttachment, XmATTACH_WIDGET,
5841 XmNleftWidget, lblW,
5842 XmNrightAttachment, XmATTACH_POSITION,
5843 XmNrightPosition, rightPos, NULL);
5844 XmStringFree(s1);
5846 /* The text field entry widget */
5847 *fieldW = XtVaCreateManagedWidget(name, xmTextWidgetClass,
5848 parent,
5849 XmNcolumns, MAX_COLOR_LEN-1,
5850 XmNmaxLength, MAX_COLOR_LEN-1,
5851 XmNleftAttachment, XmATTACH_POSITION,
5852 XmNleftPosition, leftPos,
5853 XmNrightAttachment, XmATTACH_POSITION,
5854 XmNrightPosition, rightPos,
5855 XmNtopAttachment, XmATTACH_WIDGET,
5856 XmNtopWidget, lblW, NULL);
5857 RemapDeleteKey(*fieldW);
5858 XtAddCallback(*fieldW, XmNvalueChangedCallback,
5859 modCallback, cd);
5860 XtVaSetValues(lblW, XmNuserData, *fieldW, NULL);
5862 XtFree(longerName);
5863 return *fieldW;
5868 * Code for the dialog itself
5870 void ChooseColors(WindowInfo *window)
5872 Widget form, tmpW, topW, infoLbl;
5873 Widget okBtn, applyBtn, closeBtn;
5874 colorDialog *cd;
5875 XmString s1;
5876 int ac;
5877 Arg args[20];
5879 /* if the dialog is already displayed, just pop it to the top and return */
5880 if (window->colorDialog != NULL) {
5881 RaiseDialogWindow(((colorDialog *)window->colorDialog)->shell);
5882 return;
5885 /* Create a structure for keeping track of dialog state */
5886 cd = XtNew(colorDialog);
5887 window->colorDialog = (void*)cd;
5889 /* Create a form widget in a dialog shell */
5890 ac = 0;
5891 XtSetArg(args[ac], XmNautoUnmanage, False); ac++;
5892 XtSetArg(args[ac], XmNresizePolicy, XmRESIZE_NONE); ac++;
5893 form = CreateFormDialog(window->shell, "choose colors", args, ac);
5894 XtVaSetValues(form, XmNshadowThickness, 0, NULL);
5895 cd->shell = XtParent(form);
5896 cd->window = window;
5897 XtVaSetValues(cd->shell, XmNtitle, "Colors", NULL);
5898 AddMotifCloseCallback(XtParent(form), colorCloseCB, cd);
5899 XtAddCallback(form, XmNdestroyCallback, colorDestroyCB, cd);
5901 /* Information label */
5902 infoLbl = XtVaCreateManagedWidget("infoLbl",
5903 xmLabelGadgetClass, form,
5904 XmNtopAttachment, XmATTACH_POSITION,
5905 XmNtopPosition, 2,
5906 XmNleftAttachment, XmATTACH_POSITION,
5907 XmNleftPosition, 1,
5908 XmNrightAttachment, XmATTACH_POSITION,
5909 XmNrightPosition, 99,
5910 XmNalignment, XmALIGNMENT_CENTER,
5911 XmNlabelString, s1 = XmStringCreateLtoR(
5912 "Colors can be entered as names (e.g. red, blue) or "
5913 "as RGB triples\nin the format #RRGGBB, where each digit "
5914 "is in the range 0-f.", XmFONTLIST_DEFAULT_TAG),
5915 NULL);
5916 XmStringFree(s1);
5918 topW = infoLbl;
5920 /* The left column (foregrounds) of color entry groups */
5921 tmpW = addColorGroup( form, "textFg", 'P', "Plain Text Foreground",
5922 &(cd->textFgW), &(cd->textFgErrW), topW, 1, 49,
5923 textFgModifiedCB, cd );
5924 tmpW = addColorGroup( form, "selectFg", 'S', "Selection Foreground",
5925 &(cd->selectFgW), &(cd->selectFgErrW), tmpW, 1, 49,
5926 selectFgModifiedCB, cd );
5927 tmpW = addColorGroup( form, "hiliteFg", 'M', "Matching (..) Foreground",
5928 &(cd->hiliteFgW), &(cd->hiliteFgErrW), tmpW, 1, 49,
5929 hiliteFgModifiedCB, cd );
5930 tmpW = addColorGroup( form, "lineNoFg", 'L', "Line Numbers",
5931 &(cd->lineNoFgW), &(cd->lineNoFgErrW), tmpW, 1, 49,
5932 lineNoFgModifiedCB, cd );
5934 /* The right column (backgrounds) */
5935 tmpW = addColorGroup( form, "textBg", 'T', "Text Area Background",
5936 &(cd->textBgW), &(cd->textBgErrW), topW, 51, 99,
5937 textBgModifiedCB, cd );
5938 tmpW = addColorGroup( form, "selectBg", 'B', "Selection Background",
5939 &(cd->selectBgW), &(cd->selectBgErrW), tmpW, 51, 99,
5940 selectBgModifiedCB, cd );
5941 tmpW = addColorGroup( form, "hiliteBg", 'h', "Matching (..) Background",
5942 &(cd->hiliteBgW), &(cd->hiliteBgErrW), tmpW, 51, 99,
5943 hiliteBgModifiedCB, cd );
5944 tmpW = addColorGroup( form, "cursorFg", 'C', "Cursor Color",
5945 &(cd->cursorFgW), &(cd->cursorFgErrW), tmpW, 51, 99,
5946 cursorFgModifiedCB, cd );
5948 tmpW = XtVaCreateManagedWidget("infoLbl",
5949 xmLabelGadgetClass, form,
5950 XmNtopAttachment, XmATTACH_WIDGET,
5951 XmNtopWidget, tmpW,
5952 XmNtopOffset, MARGIN_SPACING,
5953 XmNleftAttachment, XmATTACH_POSITION,
5954 XmNleftPosition, 1,
5955 XmNrightAttachment, XmATTACH_POSITION,
5956 XmNrightPosition, 99,
5957 XmNalignment, XmALIGNMENT_CENTER,
5958 XmNlabelString, s1 = XmStringCreateLtoR(
5959 "NOTE: Foreground colors only apply when syntax highlighting "
5960 "is DISABLED.\n", XmFONTLIST_DEFAULT_TAG),
5961 NULL);
5962 XmStringFree(s1);
5964 tmpW = XtVaCreateManagedWidget("sep",
5965 xmSeparatorGadgetClass, form,
5966 XmNtopAttachment, XmATTACH_WIDGET,
5967 XmNtopWidget, tmpW,
5968 XmNleftAttachment, XmATTACH_FORM,
5969 XmNrightAttachment, XmATTACH_FORM, NULL);
5971 /* The OK, Apply, and Cancel buttons */
5972 okBtn = XtVaCreateManagedWidget("ok",
5973 xmPushButtonWidgetClass, form,
5974 XmNlabelString, s1=XmStringCreateSimple("OK"),
5975 XmNmarginWidth, BUTTON_WIDTH_MARGIN,
5976 XmNtopAttachment, XmATTACH_WIDGET,
5977 XmNtopWidget, tmpW,
5978 XmNtopOffset, MARGIN_SPACING,
5979 XmNleftAttachment, XmATTACH_POSITION,
5980 XmNleftPosition, 10,
5981 XmNrightAttachment, XmATTACH_POSITION,
5982 XmNrightPosition, 30,
5983 NULL);
5984 XtAddCallback(okBtn, XmNactivateCallback, colorOkCB, cd);
5985 XmStringFree(s1);
5987 applyBtn = XtVaCreateManagedWidget(
5988 "apply", xmPushButtonWidgetClass, form,
5989 XmNlabelString, s1=XmStringCreateSimple("Apply"),
5990 XmNtopAttachment, XmATTACH_WIDGET,
5991 XmNtopWidget, tmpW,
5992 XmNtopOffset, MARGIN_SPACING,
5993 XmNmnemonic, 'A',
5994 XmNleftAttachment, XmATTACH_POSITION,
5995 XmNleftPosition, 40,
5996 XmNrightAttachment, XmATTACH_POSITION,
5997 XmNrightPosition, 60, NULL);
5998 XtAddCallback(applyBtn, XmNactivateCallback, colorApplyCB, cd);
5999 XmStringFree(s1);
6001 closeBtn = XtVaCreateManagedWidget("close",
6002 xmPushButtonWidgetClass, form,
6003 XmNlabelString, s1=XmStringCreateSimple("Close"),
6004 XmNtopAttachment, XmATTACH_WIDGET,
6005 XmNtopWidget, tmpW,
6006 XmNtopOffset, MARGIN_SPACING,
6007 XmNleftAttachment, XmATTACH_POSITION,
6008 XmNleftPosition, 70,
6009 XmNrightAttachment, XmATTACH_POSITION,
6010 XmNrightPosition, 90,
6011 NULL);
6012 XtAddCallback(closeBtn, XmNactivateCallback, colorCloseCB, cd);
6013 XmStringFree(s1);
6015 /* Set initial default button */
6016 XtVaSetValues(form, XmNdefaultButton, okBtn, NULL);
6017 XtVaSetValues(form, XmNcancelButton, closeBtn, NULL);
6019 /* Set initial values */
6020 XmTextSetString(cd->textFgW, GetPrefColorName(TEXT_FG_COLOR ));
6021 XmTextSetString(cd->textBgW, GetPrefColorName(TEXT_BG_COLOR ));
6022 XmTextSetString(cd->selectFgW, GetPrefColorName(SELECT_FG_COLOR));
6023 XmTextSetString(cd->selectBgW, GetPrefColorName(SELECT_BG_COLOR));
6024 XmTextSetString(cd->hiliteFgW, GetPrefColorName(HILITE_FG_COLOR));
6025 XmTextSetString(cd->hiliteBgW, GetPrefColorName(HILITE_BG_COLOR));
6026 XmTextSetString(cd->lineNoFgW, GetPrefColorName(LINENO_FG_COLOR));
6027 XmTextSetString(cd->cursorFgW, GetPrefColorName(CURSOR_FG_COLOR));
6029 /* Handle mnemonic selection of buttons and focus to dialog */
6030 AddDialogMnemonicHandler(form, FALSE);
6032 /* put up dialog */
6033 ManageDialogCenteredOnPointer(form);