Fix for SF bug #1060749: focusWindowMS (macro.c) causes crash.
[nedit.git] / source / preferences.c
blob7e2e9cbcf51ca3c7ac23521345b853ae04aaeb43
1 static const char CVSID[] = "$Id: preferences.c,v 1.131 2004/10/15 18:04:21 arnef 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 } PrefData;
318 /* Temporary storage for preferences strings which are discarded after being
319 read */
320 static struct {
321 char *shellCmds;
322 char *macroCmds;
323 char *bgMenuCmds;
324 char *highlight;
325 char *language;
326 char *styles;
327 char *smartIndent;
328 char *smartIndentCommon;
329 } TempStringPrefs;
331 /* preference descriptions for SavePreferences and RestorePreferences. */
332 static PrefDescripRec PrefDescrip[] = {
333 {"fileVersion", "FileVersion" , PREF_STRING, "", PrefData.fileVersion,
334 (void *)sizeof(PrefData.fileVersion), True},
335 #ifndef VMS
336 #ifdef linux
337 {"shellCommands", "ShellCommands", PREF_ALLOC_STRING, "spell:Alt+B:s:EX:\n\
338 cat>spellTmp; xterm -e ispell -x spellTmp; cat spellTmp; rm spellTmp\n\
339 wc::w:ED:\nwc | awk '{print $1 \" lines, \" $2 \" words, \" $3 \" characters\"}'\n\
340 sort::o:EX:\nsort\nnumber lines::n:AW:\nnl -ba\nmake:Alt+Z:m:W:\nmake\n\
341 expand::p:EX:\nexpand\nunexpand::u:EX:\nunexpand\n",
342 &TempStringPrefs.shellCmds, NULL, True},
343 #elif __FreeBSD__
344 {"shellCommands", "ShellCommands", PREF_ALLOC_STRING, "spell:Alt+B:s:EX:\n\
345 cat>spellTmp; xterm -e ispell -x spellTmp; cat spellTmp; rm spellTmp\n\
346 wc::w:ED:\nwc | awk '{print $2 \" lines, \" $1 \" words, \" $3 \" characters\"}'\n\
347 sort::o:EX:\nsort\nnumber lines::n:AW:\npr -tn\nmake:Alt+Z:m:W:\nmake\n\
348 expand::p:EX:\nexpand\nunexpand::u:EX:\nunexpand\n",
349 &TempStringPrefs.shellCmds, NULL, True},
350 #else
351 {"shellCommands", "ShellCommands", PREF_ALLOC_STRING, "spell:Alt+B:s:ED:\n\
352 (cat;echo \"\") | spell\nwc::w:ED:\nwc | awk '{print $1 \" lines, \" $2 \" words, \" $3 \" characters\"}'\n\
353 \nsort::o:EX:\nsort\nnumber lines::n:AW:\nnl -ba\nmake:Alt+Z:m:W:\nmake\n\
354 expand::p:EX:\nexpand\nunexpand::u:EX:\nunexpand\n",
355 &TempStringPrefs.shellCmds, NULL, True},
356 #endif /* linux, __FreeBSD__ */
357 #endif /* VMS */
358 {"macroCommands", "MacroCommands", PREF_ALLOC_STRING,
359 "Complete Word:Alt+D::: {\n\
360 # Tuning parameters\n\
361 ScanDistance = 200\n\
363 # Search back to a word boundary to find the word to complete\n\
364 startScan = max(0, $cursor - ScanDistance)\n\
365 endScan = min($text_length, $cursor + ScanDistance)\n\
366 scanString = get_range(startScan, endScan)\n\
367 keyEnd = $cursor-startScan\n\
368 keyStart = search_string(scanString, \"<\", keyEnd, \"backward\", \"regex\")\n\
369 if (keyStart == -1)\n\
370 return\n\
371 keyString = \"<\" substring(scanString, keyStart, keyEnd)\n\
373 # search both forward and backward from the cursor position. Note that\n\
374 # using a regex search can lead to incorrect results if any of the special\n\
375 # regex characters is encountered, which is not considered a delimiter\n\
376 backwardSearchResult = search_string(scanString, keyString, keyStart-1, \\\n\
377 \"backward\", \"regex\")\n\
378 forwardSearchResult = search_string(scanString, keyString, keyEnd, \"regex\")\n\
379 if (backwardSearchResult == -1 && forwardSearchResult == -1) {\n\
380 beep()\n\
381 return\n\
382 }\n\
384 # if only one direction matched, use that, otherwise use the nearest\n\
385 if (backwardSearchResult == -1)\n\
386 matchStart = forwardSearchResult\n\
387 else if (forwardSearchResult == -1)\n\
388 matchStart = backwardSearchResult\n\
389 else {\n\
390 if (keyStart - backwardSearchResult <= forwardSearchResult - keyEnd)\n\
391 matchStart = backwardSearchResult\n\
392 else\n\
393 matchStart = forwardSearchResult\n\
394 }\n\
396 # find the complete word\n\
397 matchEnd = search_string(scanString, \">\", matchStart, \"regex\")\n\
398 completedWord = substring(scanString, matchStart, matchEnd)\n\
400 # replace it in the window\n\
401 replace_range(startScan + keyStart, $cursor, completedWord)\n\
402 }\n\
403 Fill Sel. w/Char:::R: {\n\
404 if ($selection_start == -1) {\n\
405 beep()\n\
406 return\n\
407 }\n\
409 # Ask the user what character to fill with\n\
410 fillChar = string_dialog(\"Fill selection with what character?\", \"OK\", \"Cancel\")\n\
411 if ($string_dialog_button == 2 || $string_dialog_button == 0)\n\
412 return\n\
414 # Count the number of lines in the selection\n\
415 nLines = 0\n\
416 for (i=$selection_start; i<$selection_end; i++)\n\
417 if (get_character(i) == \"\\n\")\n\
418 nLines++\n\
420 # Create the fill text\n\
421 rectangular = $selection_left != -1\n\
422 line = \"\"\n\
423 fillText = \"\"\n\
424 if (rectangular) {\n\
425 for (i=0; i<$selection_right-$selection_left; i++)\n\
426 line = line fillChar\n\
427 for (i=0; i<nLines; i++)\n\
428 fillText = fillText line \"\\n\"\n\
429 fillText = fillText line\n\
430 } else {\n\
431 if (nLines == 0) {\n\
432 for (i=$selection_start; i<$selection_end; i++)\n\
433 fillText = fillText fillChar\n\
434 } else {\n\
435 startIndent = 0\n\
436 for (i=$selection_start-1; i>=0 && get_character(i)!=\"\\n\"; i--)\n\
437 startIndent++\n\
438 for (i=0; i<$wrap_margin-startIndent; i++)\n\
439 fillText = fillText fillChar\n\
440 fillText = fillText \"\\n\"\n\
441 for (i=0; i<$wrap_margin; i++)\n\
442 line = line fillChar\n\
443 for (i=0; i<nLines-1; i++)\n\
444 fillText = fillText line \"\\n\"\n\
445 for (i=$selection_end-1; i>=$selection_start && get_character(i)!=\"\\n\"; \\\n\
446 i--)\n\
447 fillText = fillText fillChar\n\
448 }\n\
449 }\n\
451 # Replace the selection with the fill text\n\
452 replace_selection(fillText)\n\
453 }\n\
454 Quote Mail Reply:::: {\n\
455 if ($selection_start == -1)\n\
456 replace_all(\"^.*$\", \"\\\\> &\", \"regex\")\n\
457 else\n\
458 replace_in_selection(\"^.*$\", \"\\\\> &\", \"regex\")\n\
459 }\n\
460 Unquote Mail Reply:::: {\n\
461 if ($selection_start == -1)\n\
462 replace_all(\"(^\\\\> )(.*)$\", \"\\\\2\", \"regex\")\n\
463 else\n\
464 replace_in_selection(\"(^\\\\> )(.*)$\", \"\\\\2\", \"regex\")\n\
465 }\n\
466 Comments>/* Comment */@C@C++@Java@CSS@JavaScript@Lex:::R: {\n\
467 selStart = $selection_start\n\
468 selEnd = $selection_end\n\
469 replace_range(selStart, selEnd, \"/* \" get_selection() \" */\")\n\
470 select(selStart, selEnd + 6)\n\
471 }\n\
472 Comments>/* Uncomment */@C@C++@Java@CSS@JavaScript@Lex:::R: {\n\
473 sel = get_selection()\n\
474 selStart = $selection_start\n\
475 selEnd = $selection_end\n\
476 commentStart = search_string(sel, \"/*\", 0)\n\
477 if (substring(sel, commentStart + 2, commentStart + 3) == \" \")\n\
478 keepStart = commentStart + 3\n\
479 else\n\
480 keepStart = commentStart + 2\n\
481 keepEnd = search_string(sel, \"*/\", length(sel), \"backward\")\n\
482 commentEnd = keepEnd + 2\n\
483 if (substring(sel, keepEnd - 1, keepEnd) == \" \")\n\
484 keepEnd = keepEnd - 1\n\
485 replace_range(selStart + commentStart, selStart + commentEnd, \\\n\
486 substring(sel, keepStart, keepEnd))\n\
487 select(selStart, selEnd - (keepStart-commentStart) - \\\n\
488 (commentEnd - keepEnd))\n\
489 }\n\
490 Comments>// Comment@C@C++@Java@JavaScript:::R: {\n\
491 replace_in_selection(\"^.*$\", \"// &\", \"regex\")\n\
492 }\n\
493 Comments>// Uncomment@C@C++@Java@JavaScript:::R: {\n\
494 replace_in_selection(\"(^[ \\\\t]*// ?)(.*)$\", \"\\\\2\", \"regex\")\n\
495 }\n\
496 Comments># Comment@Perl@Sh Ksh Bash@NEdit Macro@Makefile@Awk@Csh@Python@Tcl:::R: {\n\
497 replace_in_selection(\"^.*$\", \"#&\", \"regex\")\n\
498 }\n\
499 Comments># Uncomment@Perl@Sh Ksh Bash@NEdit Macro@Makefile@Awk@Csh@Python@Tcl:::R: {\n\
500 replace_in_selection(\"(^[ \\\\t]*#)(.*)$\", \"\\\\2\", \"regex\")\n\
501 }\n\
502 Comments>-- Comment@SQL:::R: {\n\
503 replace_in_selection(\"^.*$\", \"--&\", \"regex\")\n\
504 }\n\
505 Comments>-- Uncomment@SQL:::R: {\n\
506 replace_in_selection(\"(^[ \\\\t]*--)(.*)$\", \"\\\\2\", \"regex\")\n\
507 }\n\
508 Comments>! Comment@X Resources:::R: {\n\
509 replace_in_selection(\"^.*$\", \"!&\", \"regex\")\n\
510 }\n\
511 Comments>! Uncomment@X Resources:::R: {\n\
512 replace_in_selection(\"(^[ \\\\t]*!)(.*)$\", \"\\\\2\", \"regex\")\n\
513 }\n\
514 Comments>% Comment@LaTeX:::R: {\n\
515 replace_in_selection(\"^.*$\", \"%&\", \"regex\")\n\
516 }\n\
517 Comments>% Uncomment@LaTeX:::R: {\n\
518 replace_in_selection(\"(^[ \\\\t]*%)(.*)$\", \"\\\\2\", \"regex\")\n\
519 }\n\
520 Comments>Bar Comment@C:::R: {\n\
521 if ($selection_left != -1) {\n\
522 dialog(\"Selection must not be rectangular\")\n\
523 return\n\
524 }\n\
525 start = $selection_start\n\
526 end = $selection_end-1\n\
527 origText = get_range($selection_start, $selection_end-1)\n\
528 newText = \"/*\\n\" replace_in_string(get_range(start, end), \\\n\
529 \"^\", \" * \", \"regex\") \"\\n */\\n\"\n\
530 replace_selection(newText)\n\
531 select(start, start + length(newText))\n\
532 }\n\
533 Comments>Bar Uncomment@C:::R: {\n\
534 selStart = $selection_start\n\
535 selEnd = $selection_end\n\
536 newText = get_range(selStart+3, selEnd-4)\n\
537 newText = replace_in_string(newText, \"^ \\\\* \", \"\", \"regex\")\n\
538 replace_range(selStart, selEnd, newText)\n\
539 select(selStart, selStart + length(newText))\n\
540 }\n\
541 Make C Prototypes@C@C++:::: {\n\
542 if ($selection_start == -1) {\n\
543 start = 0\n\
544 end = $text_length\n\
545 } else {\n\
546 start = $selection_start\n\
547 end = $selection_end\n\
548 }\n\
549 string = get_range(start, end)\n\
550 nDefs = 0\n\
551 searchPos = 0\n\
552 prototypes = \"\"\n\
553 staticPrototypes = \"\"\n\
554 for (;;) {\n\
555 headerStart = search_string(string, \\\n\
556 \"^[a-zA-Z]([^;#\\\"'{}=><!/]|\\n)*\\\\)[ \\t]*\\n?[ \\t]*\\\\{\", \\\n\
557 searchPos, \"regex\")\n\
558 if (headerStart == -1)\n\
559 break\n\
560 headerEnd = search_string(string, \")\", $search_end,\"backward\") + 1\n\
561 prototype = substring(string, headerStart, headerEnd) \";\\n\"\n\
562 if (substring(string, headerStart, headerStart+6) == \"static\")\n\
563 staticPrototypes = staticPrototypes prototype\n\
564 else\n\
565 prototypes = prototypes prototype\n\
566 searchPos = headerEnd\n\
567 nDefs++\n\
568 }\n\
569 if (nDefs == 0) {\n\
570 dialog(\"No function declarations found\")\n\
571 return\n\
572 }\n\
573 new()\n\
574 focus_window(\"last\")\n\
575 replace_range(0, 0, prototypes staticPrototypes)\n\
576 }", &TempStringPrefs.macroCmds, NULL, True},
577 {"bgMenuCommands", "BGMenuCommands", PREF_ALLOC_STRING,
578 "Undo:::: {\nundo()\n}\n\
579 Redo:::: {\nredo()\n}\n\
580 Cut:::R: {\ncut_clipboard()\n}\n\
581 Copy:::R: {\ncopy_clipboard()\n}\n\
582 Paste:::: {\npaste_clipboard()\n}", &TempStringPrefs.bgMenuCmds,
583 NULL, True},
584 #ifdef VMS
585 /* The VAX compiler can't compile Java-Script's definition in highlightData.c */
586 {"highlightPatterns", "HighlightPatterns", PREF_ALLOC_STRING,
587 "Ada:Default\n\
588 Awk:Default\n\
589 C++:Default\n\
590 C:Default\n\
591 CSS:Default\n\
592 Csh:Default\n\
593 Fortran:Default\n\
594 Java:Default\n\
595 LaTeX:Default\n\
596 Lex:Default\n\
597 Makefile:Default\n\
598 Matlab:Default\n\
599 NEdit Macro:Default\n\
600 Pascal:Default\n\
601 Perl:Default\n\
602 PostScript:Default\n\
603 Python:Default\n\
604 Regex:Default\n\
605 SGML HTML:Default\n\
606 SQL:Default\n\
607 Sh Ksh Bash:Default\n\
608 Tcl:Default\n\
609 VHDL:Default\n\
610 Verilog:Default\n\
611 XML:Default\n\
612 X Resources:Default\n\
613 Yacc:Default",
614 &TempStringPrefs.highlight, NULL, True},
615 {"languageModes", "LanguageModes", PREF_ALLOC_STRING,
616 #else
617 {"highlightPatterns", "HighlightPatterns", PREF_ALLOC_STRING,
618 "Ada:Default\n\
619 Awk:Default\n\
620 C++:Default\n\
621 C:Default\n\
622 CSS:Default\n\
623 Csh:Default\n\
624 Fortran:Default\n\
625 Java:Default\n\
626 JavaScript:Default\n\
627 LaTeX:Default\n\
628 Lex:Default\n\
629 Makefile:Default\n\
630 Matlab:Default\n\
631 NEdit Macro:Default\n\
632 Pascal:Default\n\
633 Perl:Default\n\
634 PostScript:Default\n\
635 Python:Default\n\
636 Regex:Default\n\
637 SGML HTML:Default\n\
638 SQL:Default\n\
639 Sh Ksh Bash:Default\n\
640 Tcl:Default\n\
641 VHDL:Default\n\
642 Verilog:Default\n\
643 XML:Default\n\
644 X Resources:Default\n\
645 Yacc:Default",
646 &TempStringPrefs.highlight, NULL, True},
647 {"languageModes", "LanguageModes", PREF_ALLOC_STRING,
648 #endif /*VMS*/
649 #ifdef VMS
650 "Ada:.ADA .AD .ADS .ADB .A:::::::\n\
651 Awk:.AWK:::::::\n\
652 C++:.CC .HH .C .H .I .CXX .HXX .CPP::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":\n\
653 C:.C .H::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":\n\
654 CSS:CSS::Auto:None:::\".,/\\`'!|@#%^&*()=+{}[]\"\":;<>?~\":\n\
655 Csh:.csh .cshrc .login .logout:\"^[ \\t]*#[ \\t]*![ \\t]*/bin/csh\"::::::\n\
656 Fortran:.F .F77 .FOR:::::::\n\
657 Java:.JAVA:::::::\n\
658 LaTeX:.TEX .STY .CLS .LTX .INS:::::::\n\
659 Lex:.lex:::::::\n\
660 Makefile:MAKEFILE:::None:8:8::\n\
661 Matlab:.m .oct .sci:::::::\n\
662 NEdit Macro:.NM .NEDITMACRO:::::::\n\
663 Pascal:.PAS .P .INT:::::::\n\
664 Perl:.PL .PM .P5:\"^[ \\t]*#[ \\t]*!.*perl\":Auto:None:::\".,/\\\\`'!$@#%^&*()-=+{}[]\"\":;<>?~|\":\n\
665 PostScript:.ps .PS .eps .EPS .epsf .epsi:\"^%!\":::::\"/%(){}[]<>\":\n\
666 Python:.PY:\"^#!.*python\":Auto:None:::\"!\"\"#$%&'()*+,-./:;<=>?@[\\\\]^`{|}~\":\n\
667 Regex:.reg .regex:\"\\(\\?[:#=!iInN].+\\)\":None:Continuous::::\n\
668 SGML HTML:.sgml .sgm .html .htm:\"\\<[Hh][Tt][Mm][Ll]\\>\"::::::\n\
669 SQL:.sql:::::::\n\
670 Sh Ksh Bash:.sh .bash .ksh .profile .bashrc .bash_logout .bash_login .bash_profile:\"^[ \\t]*#[ \\t]*![ \\t]*/.*bin/(bash|ksh|sh|zsh)\"::::::\n\
671 Tcl:.TCL::Smart:None::::\n\
672 VHDL:.VHD .VHDL .VDL:::::::\n\
673 Verilog:.V:::::::\n\
674 XML:.xml .xsl .dtd:\"\\<(?i\\?xml|!doctype)\"::None:::\"<>/=\"\"'()+*?|\":\n\
675 X Resources:.XRESOURCES .XDEFAULTS .NEDIT:\"^[!#].*([Aa]pp|[Xx]).*[Dd]efaults\"::::::\n\
676 Yacc:.Y::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":",
677 #else
678 "Ada:.ada .ad .ads .adb .a:::::::\n\
679 Awk:.awk:::::::\n\
680 C++:.cc .hh .C .H .i .cxx .hxx .cpp .c++::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":\n\
681 C:.c .h::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":\n\
682 CSS:css::Auto:None:::\".,/\\`'!|@#%^&*()=+{}[]\"\":;<>?~\":\n\
683 Csh:.csh .cshrc .login .logout:\"^[ \\t]*#[ \\t]*![ \\t]*/bin/csh\"::::::\n\
684 Fortran:.f .f77 .for:::::::\n\
685 Java:.java:::::::\n\
686 JavaScript:.js:::::::\n\
687 LaTeX:.tex .sty .cls .ltx .ins:::::::\n\
688 Lex:.lex:::::::\n\
689 Makefile:Makefile makefile .gmk:::None:8:8::\n\
690 Matlab:.m .oct .sci:::::::\n\
691 NEdit Macro:.nm .neditmacro:::::::\n\
692 Pascal:.pas .p .int:::::::\n\
693 Perl:.pl .pm .p5 .PL:\"^[ \\t]*#[ \\t]*!.*perl\":Auto:None:::\".,/\\\\`'!$@#%^&*()-=+{}[]\"\":;<>?~|\":\n\
694 PostScript:.ps .eps .epsf .epsi:\"^%!\":::::\"/%(){}[]<>\":\n\
695 Python:.py:\"^#!.*python\":Auto:None:::\"!\"\"#$%&'()*+,-./:;<=>?@[\\\\]^`{|}~\":\n\
696 Regex:.reg .regex:\"\\(\\?[:#=!iInN].+\\)\":None:Continuous::::\n\
697 SGML HTML:.sgml .sgm .html .htm:\"\\<[Hh][Tt][Mm][Ll]\\>\"::::::\n\
698 SQL:.sql:::::::\n\
699 Sh Ksh Bash:.sh .bash .ksh .profile .bashrc .bash_logout .bash_login .bash_profile:\"^[ \\t]*#[ \\t]*![ \\t]*/.*bin/(bash|ksh|sh|zsh)\"::::::\n\
700 Tcl:.tcl .tk .itcl .itk::Smart:None::::\n\
701 VHDL:.vhd .vhdl .vdl:::::::\n\
702 Verilog:.v:::::::\n\
703 XML:.xml .xsl .dtd:\"\\<(?i\\?xml|!doctype)\"::None:::\"<>/=\"\"'()+*?|\":\n\
704 X Resources:.Xresources .Xdefaults .nedit:\"^[!#].*([Aa]pp|[Xx]).*[Dd]efaults\"::::::\n\
705 Yacc:.y::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":",
706 #endif
707 &TempStringPrefs.language, NULL, True},
708 {"styles", "Styles", PREF_ALLOC_STRING, "Plain:black:Plain\n\
709 Comment:gray20:Italic\n\
710 Keyword:black:Bold\n\
711 Storage Type:brown:Bold\n\
712 Storage Type1:saddle brown:Bold\n\
713 String:darkGreen:Plain\n\
714 String1:SeaGreen:Plain\n\
715 String2:darkGreen:Bold\n\
716 Preprocessor:RoyalBlue4:Plain\n\
717 Preprocessor1:blue:Plain\n\
718 Character Const:darkGreen:Plain\n\
719 Numeric Const:darkGreen:Plain\n\
720 Identifier:brown:Plain\n\
721 Identifier1:RoyalBlue4:Plain\n\
722 Identifier2:SteelBlue:Plain\n\
723 Subroutine:brown:Plain\n\
724 Subroutine1:chocolate:Plain\n\
725 Ada Attributes:plum:Bold\n\
726 Label:red:Italic\n\
727 Flag:red:Bold\n\
728 Text Comment:SteelBlue4:Italic\n\
729 Text Key:VioletRed4:Bold\n\
730 Text Key1:VioletRed4:Plain\n\
731 Text Arg:RoyalBlue4:Bold\n\
732 Text Arg1:SteelBlue4:Bold\n\
733 Text Arg2:RoyalBlue4:Plain\n\
734 Text Escape:gray30:Bold\n\
735 LaTeX Math:darkGreen:Plain\n"
736 ADD_5_2_STYLES,
737 &TempStringPrefs.styles, NULL, True},
738 {"smartIndentInit", "SmartIndentInit", PREF_ALLOC_STRING,
739 "C:Default\n\
740 C++:Default\n\
741 Python:Default\n\
742 Matlab:Default", &TempStringPrefs.smartIndent, NULL, True},
743 {"smartIndentInitCommon", "SmartIndentInitCommon", PREF_ALLOC_STRING,
744 "Default", &TempStringPrefs.smartIndentCommon, NULL, True},
745 {"autoWrap", "AutoWrap", PREF_ENUM, "Newline",
746 &PrefData.wrapStyle, AutoWrapTypes, True},
747 {"wrapMargin", "WrapMargin", PREF_INT, "0",
748 &PrefData.wrapMargin, NULL, True},
749 {"autoIndent", "AutoIndent", PREF_ENUM, "Auto",
750 &PrefData.autoIndent, AutoIndentTypes, True},
751 {"autoSave", "AutoSave", PREF_BOOLEAN, "True",
752 &PrefData.autoSave, NULL, True},
753 {"openInTab", "OpenInTab", PREF_BOOLEAN, "True",
754 &PrefData.openInTab, NULL, True},
755 {"saveOldVersion", "SaveOldVersion", PREF_BOOLEAN, "False",
756 &PrefData.saveOldVersion, NULL, True},
757 {"showMatching", "ShowMatching", PREF_ENUM, "Delimiter",
758 &PrefData.showMatchingStyle, ShowMatchingTypes, True},
759 {"matchSyntaxBased", "MatchSyntaxBased", PREF_BOOLEAN, "True",
760 &PrefData.matchSyntaxBased, NULL, True},
761 {"highlightSyntax", "HighlightSyntax", PREF_BOOLEAN, "True",
762 &PrefData.highlightSyntax, NULL, True},
763 {"backlightChars", "BacklightChars", PREF_BOOLEAN, "False",
764 &PrefData.backlightChars, NULL, True},
765 {"backlightCharTypes", "BacklightCharTypes", PREF_ALLOC_STRING,
766 "0-8,10-31,127:red;9:#dedede;32,160-255:#f0f0f0;128-159:orange",
767 /* gray87 gray94 */
768 &PrefData.backlightCharTypes, NULL, False},
769 {"searchDialogs", "SearchDialogs", PREF_BOOLEAN, "False",
770 &PrefData.searchDlogs, NULL, True},
771 {"beepOnSearchWrap", "BeepOnSearchWrap", PREF_BOOLEAN, "False",
772 &PrefData.searchWrapBeep, NULL, True},
773 {"retainSearchDialogs", "RetainSearchDialogs", PREF_BOOLEAN, "False",
774 &PrefData.keepSearchDlogs, NULL, True},
775 {"searchWraps", "SearchWraps", PREF_BOOLEAN, "True",
776 &PrefData.searchWraps, NULL, True},
777 {"stickyCaseSenseButton", "StickyCaseSenseButton", PREF_BOOLEAN, "True",
778 &PrefData.stickyCaseSenseBtn, NULL, True},
779 #if XmVersion < 1002 /* Flashing is annoying in 1.1 versions */
780 {"repositionDialogs", "RepositionDialogs", PREF_BOOLEAN, "False",
781 &PrefData.repositionDialogs, NULL, True},
782 #else
783 {"repositionDialogs", "RepositionDialogs", PREF_BOOLEAN, "True",
784 &PrefData.repositionDialogs, NULL, True},
785 #endif
786 {"autoScroll", "AutoScroll", PREF_BOOLEAN, "False",
787 &PrefData.autoScroll, NULL, True},
788 {"autoScrollVPadding", "AutoScrollVPadding", PREF_INT, "4",
789 &PrefData.autoScrollVPadding, NULL, False},
790 {"appendLF", "AppendLF", PREF_BOOLEAN, "True",
791 &PrefData.appendLF, NULL, True},
792 {"sortOpenPrevMenu", "SortOpenPrevMenu", PREF_BOOLEAN, "True",
793 &PrefData.sortOpenPrevMenu, NULL, True},
794 {"statisticsLine", "StatisticsLine", PREF_BOOLEAN, "False",
795 &PrefData.statsLine, NULL, True},
796 {"iSearchLine", "ISearchLine", PREF_BOOLEAN, "False",
797 &PrefData.iSearchLine, NULL, True},
798 {"sortTabs", "SortTabs", PREF_BOOLEAN, "False",
799 &PrefData.sortTabs, NULL, True},
800 {"tabBar", "TabBar", PREF_BOOLEAN, "True",
801 &PrefData.tabBar, NULL, True},
802 {"tabBarHideOne", "TabBarHideOne", PREF_BOOLEAN, "True",
803 &PrefData.tabBarHideOne, NULL, True},
804 {"toolTips", "ToolTips", PREF_BOOLEAN, "True",
805 &PrefData.toolTips, NULL, True},
806 {"globalTabNavigate", "GlobalTabNavigate", PREF_BOOLEAN, "False",
807 &PrefData.globalTabNavigate, NULL, True},
808 {"lineNumbers", "LineNumbers", PREF_BOOLEAN, "False",
809 &PrefData.lineNums, NULL, True},
810 {"pathInWindowsMenu", "PathInWindowsMenu", PREF_BOOLEAN, "True",
811 &PrefData.pathInWindowsMenu, NULL, True},
812 {"warnFileMods", "WarnFileMods", PREF_BOOLEAN, "True",
813 &PrefData.warnFileMods, NULL, True},
814 {"warnRealFileMods", "WarnRealFileMods", PREF_BOOLEAN, "True",
815 &PrefData.warnRealFileMods, NULL, True},
816 {"warnExit", "WarnExit", PREF_BOOLEAN, "True",
817 &PrefData.warnExit, NULL, True},
818 {"searchMethod", "SearchMethod", PREF_ENUM, "Literal",
819 &PrefData.searchMethod, SearchMethodStrings, True},
820 #ifdef REPLACE_SCOPE
821 {"replaceDefaultScope", "ReplaceDefaultScope", PREF_ENUM, "Smart",
822 &PrefData.replaceDefScope, ReplaceDefScopeStrings, True},
823 #endif
824 {"textRows", "TextRows", PREF_INT, "24",
825 &PrefData.textRows, NULL, True},
826 {"textCols", "TextCols", PREF_INT, "80",
827 &PrefData.textCols, NULL, True},
828 {"tabDistance", "TabDistance", PREF_INT, "8",
829 &PrefData.tabDist, NULL, True},
830 {"emulateTabs", "EmulateTabs", PREF_INT, "0",
831 &PrefData.emTabDist, NULL, True},
832 {"insertTabs", "InsertTabs", PREF_BOOLEAN, "True",
833 &PrefData.insertTabs, NULL, True},
834 {"textFont", "TextFont", PREF_STRING,
835 "-*-courier-medium-r-normal--*-120-*-*-*-iso8859-1",
836 PrefData.fontString, (void *)sizeof(PrefData.fontString), True},
837 {"boldHighlightFont", "BoldHighlightFont", PREF_STRING,
838 "-*-courier-bold-r-normal--*-120-*-*-*-iso8859-1",
839 PrefData.boldFontString, (void *)sizeof(PrefData.boldFontString), True},
840 {"italicHighlightFont", "ItalicHighlightFont", PREF_STRING,
841 "-*-courier-medium-o-normal--*-120-*-*-*-iso8859-1",
842 PrefData.italicFontString,
843 (void *)sizeof(PrefData.italicFontString), True},
844 {"boldItalicHighlightFont", "BoldItalicHighlightFont", PREF_STRING,
845 "-*-courier-bold-o-normal--*-120-*-*-*-iso8859-1",
846 PrefData.boldItalicFontString,
847 (void *)sizeof(PrefData.boldItalicFontString), True},
848 {"helpFont", "HelpFont", PREF_STRING,
849 "-*-helvetica-medium-r-normal--*-120-*-*-*-iso8859-1",
850 PrefData.helpFontNames[HELP_FONT],
851 (void *)sizeof(PrefData.helpFontNames[HELP_FONT]), False},
852 {"boldHelpFont", "BoldHelpFont", PREF_STRING,
853 "-*-helvetica-bold-r-normal--*-120-*-*-*-iso8859-1",
854 PrefData.helpFontNames[BOLD_HELP_FONT],
855 (void *)sizeof(PrefData.helpFontNames[BOLD_HELP_FONT]), False},
856 {"italicHelpFont", "ItalicHelpFont", PREF_STRING,
857 "-*-helvetica-medium-o-normal--*-120-*-*-*-iso8859-1",
858 PrefData.helpFontNames[ITALIC_HELP_FONT],
859 (void *)sizeof(PrefData.helpFontNames[ITALIC_HELP_FONT]), False},
860 {"boldItalicHelpFont", "BoldItalicHelpFont", PREF_STRING,
861 "-*-helvetica-bold-o-normal--*-120-*-*-*-iso8859-1",
862 PrefData.helpFontNames[BOLD_ITALIC_HELP_FONT],
863 (void *)sizeof(PrefData.helpFontNames[BOLD_ITALIC_HELP_FONT]), False},
864 {"fixedHelpFont", "FixedHelpFont", PREF_STRING,
865 "-*-courier-medium-r-normal--*-120-*-*-*-iso8859-1",
866 PrefData.helpFontNames[FIXED_HELP_FONT],
867 (void *)sizeof(PrefData.helpFontNames[FIXED_HELP_FONT]), False},
868 {"boldFixedHelpFont", "BoldFixedHelpFont", PREF_STRING,
869 "-*-courier-bold-r-normal--*-120-*-*-*-iso8859-1",
870 PrefData.helpFontNames[BOLD_FIXED_HELP_FONT],
871 (void *)sizeof(PrefData.helpFontNames[BOLD_FIXED_HELP_FONT]), False},
872 {"italicFixedHelpFont", "ItalicFixedHelpFont", PREF_STRING,
873 "-*-courier-medium-o-normal--*-120-*-*-*-iso8859-1",
874 PrefData.helpFontNames[ITALIC_FIXED_HELP_FONT],
875 (void *)sizeof(PrefData.helpFontNames[ITALIC_FIXED_HELP_FONT]), False},
876 {"boldItalicFixedHelpFont", "BoldItalicFixedHelpFont", PREF_STRING,
877 "-*-courier-bold-o-normal--*-120-*-*-*-iso8859-1",
878 PrefData.helpFontNames[BOLD_ITALIC_FIXED_HELP_FONT],
879 (void *)sizeof(PrefData.helpFontNames[BOLD_ITALIC_FIXED_HELP_FONT]), False},
880 {"helpLinkFont", "HelpLinkFont", PREF_STRING,
881 "-*-helvetica-medium-r-normal--*-120-*-*-*-iso8859-1",
882 PrefData.helpFontNames[HELP_LINK_FONT],
883 (void *)sizeof(PrefData.helpFontNames[HELP_LINK_FONT]), False},
884 {"h1HelpFont", "H1HelpFont", PREF_STRING,
885 "-*-helvetica-bold-r-normal--*-140-*-*-*-iso8859-1",
886 PrefData.helpFontNames[H1_HELP_FONT],
887 (void *)sizeof(PrefData.helpFontNames[H1_HELP_FONT]), False},
888 {"h2HelpFont", "H2HelpFont", PREF_STRING,
889 "-*-helvetica-bold-o-normal--*-120-*-*-*-iso8859-1",
890 PrefData.helpFontNames[H2_HELP_FONT],
891 (void *)sizeof(PrefData.helpFontNames[H2_HELP_FONT]), False},
892 {"h3HelpFont", "H3HelpFont", PREF_STRING,
893 "-*-courier-bold-r-normal--*-120-*-*-*-iso8859-1",
894 PrefData.helpFontNames[H3_HELP_FONT],
895 (void *)sizeof(PrefData.helpFontNames[H3_HELP_FONT]), False},
896 {"helpLinkColor", "HelpLinkColor", PREF_STRING, "#009900",
897 PrefData.helpLinkColor,
898 (void *)sizeof(PrefData.helpLinkColor), False},
900 {"textFgColor", "TextFgColor", PREF_STRING, NEDIT_DEFAULT_FG,
901 PrefData.colorNames[TEXT_FG_COLOR],
902 (void *)sizeof(PrefData.colorNames[TEXT_FG_COLOR]), True},
903 {"textBgColor", "TextBgColor", PREF_STRING, NEDIT_DEFAULT_TEXT_BG,
904 PrefData.colorNames[TEXT_BG_COLOR],
905 (void *)sizeof(PrefData.colorNames[TEXT_BG_COLOR]), True},
906 {"selectFgColor", "SelectFgColor", PREF_STRING, NEDIT_DEFAULT_SEL_FG,
907 PrefData.colorNames[SELECT_FG_COLOR],
908 (void *)sizeof(PrefData.colorNames[SELECT_FG_COLOR]), True},
909 {"selectBgColor", "SelectBgColor", PREF_STRING, NEDIT_DEFAULT_SEL_BG,
910 PrefData.colorNames[SELECT_BG_COLOR],
911 (void *)sizeof(PrefData.colorNames[SELECT_BG_COLOR]), True},
912 {"hiliteFgColor", "HiliteFgColor", PREF_STRING, NEDIT_DEFAULT_HI_FG,
913 PrefData.colorNames[HILITE_FG_COLOR],
914 (void *)sizeof(PrefData.colorNames[HILITE_FG_COLOR]), True},
915 {"hiliteBgColor", "HiliteBgColor", PREF_STRING, NEDIT_DEFAULT_HI_BG,
916 PrefData.colorNames[HILITE_BG_COLOR],
917 (void *)sizeof(PrefData.colorNames[HILITE_BG_COLOR]), True},
918 {"lineNoFgColor", "LineNoFgColor", PREF_STRING, NEDIT_DEFAULT_LINENO_FG,
919 PrefData.colorNames[LINENO_FG_COLOR],
920 (void *)sizeof(PrefData.colorNames[LINENO_FG_COLOR]), True},
921 {"cursorFgColor", "CursorFgColor", PREF_STRING, NEDIT_DEFAULT_CURSOR_FG,
922 PrefData.colorNames[CURSOR_FG_COLOR],
923 (void *)sizeof(PrefData.colorNames[CURSOR_FG_COLOR]), True},
924 {"tooltipBgColor", "TooltipBgColor", PREF_STRING, "LemonChiffon1",
925 PrefData.tooltipBgColor,
926 (void *)sizeof(PrefData.tooltipBgColor), False},
928 {"shell", "Shell", PREF_STRING,
929 #if defined(__MVS__) || defined(__EMX__)
930 "/bin/sh",
931 #else
932 "/bin/csh",
933 #endif
934 PrefData.shell, (void *)sizeof(PrefData.shell), False},
935 {"geometry", "Geometry", PREF_STRING, "",
936 PrefData.geometry, (void *)sizeof(PrefData.geometry), False},
937 {"remapDeleteKey", "RemapDeleteKey", PREF_BOOLEAN, "False",
938 &PrefData.mapDelete, NULL, False},
939 {"stdOpenDialog", "StdOpenDialog", PREF_BOOLEAN, "False",
940 &PrefData.stdOpenDialog, NULL, False},
941 {"tagFile", "TagFile", PREF_STRING,
942 "", PrefData.tagFile, (void *)sizeof(PrefData.tagFile), False},
943 {"wordDelimiters", "WordDelimiters", PREF_STRING,
944 ".,/\\`'!|@#%^&*()-=+{}[]\":;<>?",
945 PrefData.delimiters, (void *)sizeof(PrefData.delimiters), False},
946 {"serverName", "ServerName", PREF_STRING, "", PrefData.serverName,
947 (void *)sizeof(PrefData.serverName), False},
948 {"maxPrevOpenFiles", "MaxPrevOpenFiles", PREF_INT, "30",
949 &PrefData.maxPrevOpenFiles, NULL, False},
950 {"bgMenuButton", "BGMenuButton" , PREF_STRING,
951 "~Shift~Ctrl~Meta~Alt<Btn3Down>", PrefData.bgMenuBtn,
952 (void *)sizeof(PrefData.bgMenuBtn), False},
953 {"smartTags", "SmartTags", PREF_BOOLEAN, "True",
954 &PrefData.smartTags, NULL, True},
955 {"typingHidesPointer", "TypingHidesPointer", PREF_BOOLEAN, "False",
956 &PrefData.typingHidesPointer, NULL, False},
957 {"alwaysCheckRelativeTagsSpecs", "AlwaysCheckRelativeTagsSpecs",
958 PREF_BOOLEAN, "True", &PrefData.alwaysCheckRelativeTagsSpecs, NULL, False},
959 {"prefFileRead", "PrefFileRead", PREF_BOOLEAN, "False",
960 &PrefData.prefFileRead, NULL, True},
961 #ifdef SGI_CUSTOM
962 {"shortMenus", "ShortMenus", PREF_BOOLEAN, "False", &PrefData.shortMenus,
963 NULL, True},
964 #endif
965 {"findReplaceUsesSelection", "FindReplaceUsesSelection", PREF_BOOLEAN, "False",
966 &PrefData.findReplaceUsesSelection, NULL, False},
967 {"overrideDefaultVirtualKeyBindings", "OverrideDefaultVirtualKeyBindings",
968 PREF_ENUM, "Auto", &PrefData.virtKeyOverride, VirtKeyOverrideModes, False},
969 {"titleFormat", "TitleFormat", PREF_STRING, "{%c} [%s] %f (%S) - %d",
970 PrefData.titleFormat, (void *)sizeof(PrefData.titleFormat), True},
971 {"undoModifiesSelection", "UndoModifiesSelection", PREF_BOOLEAN,
972 "True", &PrefData.undoModifiesSelection, NULL, False},
975 static XrmOptionDescRec OpTable[] = {
976 {"-wrap", ".autoWrap", XrmoptionNoArg, (caddr_t)"Continuous"},
977 {"-nowrap", ".autoWrap", XrmoptionNoArg, (caddr_t)"None"},
978 {"-autowrap", ".autoWrap", XrmoptionNoArg, (caddr_t)"Newline"},
979 {"-noautowrap", ".autoWrap", XrmoptionNoArg, (caddr_t)"None"},
980 {"-autoindent", ".autoIndent", XrmoptionNoArg, (caddr_t)"Auto"},
981 {"-noautoindent", ".autoIndent", XrmoptionNoArg, (caddr_t)"False"},
982 {"-autosave", ".autoSave", XrmoptionNoArg, (caddr_t)"True"},
983 {"-noautosave", ".autoSave", XrmoptionNoArg, (caddr_t)"False"},
984 {"-rows", ".textRows", XrmoptionSepArg, (caddr_t)NULL},
985 {"-columns", ".textCols", XrmoptionSepArg, (caddr_t)NULL},
986 {"-tabs", ".tabDistance", XrmoptionSepArg, (caddr_t)NULL},
987 {"-font", ".textFont", XrmoptionSepArg, (caddr_t)NULL},
988 {"-fn", ".textFont", XrmoptionSepArg, (caddr_t)NULL},
989 {"-svrname", ".serverName", XrmoptionSepArg, (caddr_t)NULL},
992 static const char HeaderText[] = "\
993 ! Preferences file for NEdit\n\
994 !\n\
995 ! This file is overwritten by the \"Save Defaults...\" command in NEdit \n\
996 ! and serves only the interactively settable options presented in the NEdit\n\
997 ! \"Preferences\" menu. To modify other options, such as key bindings, use \n\
998 ! the .Xdefaults file in your home directory (or the X resource \n\
999 ! specification method appropriate to your system). The contents of this \n\
1000 ! file can be moved into an X resource file, but since resources in this file\n\
1001 ! override their corresponding X resources, either this file should be \n\
1002 ! deleted or individual resource lines in the file should be deleted for the\n\
1003 ! moved lines to take effect.\n";
1005 /* Module-global variable set when any preference changes (for asking the
1006 user about re-saving on exit) */
1007 static int PrefsHaveChanged = False;
1009 /* Module-global variable set when user uses -import to load additional
1010 preferences on top of the defaults. Contains name of file loaded */
1011 static char *ImportedFile = NULL;
1013 /* Module-global variables to support Initial Window Size... dialog */
1014 static int DoneWithSizeDialog;
1015 static Widget RowText, ColText;
1017 /* Module-global variables for Tabs dialog */
1018 static int DoneWithTabsDialog;
1019 static WindowInfo *TabsDialogForWindow;
1020 static Widget TabDistText, EmTabText, EmTabToggle, UseTabsToggle, EmTabLabel;
1022 /* Module-global variables for Wrap Margin dialog */
1023 static int DoneWithWrapDialog;
1024 static WindowInfo *WrapDialogForWindow;
1025 static Widget WrapText, WrapTextLabel, WrapWindowToggle;
1027 static void translatePrefFormats(int convertOld, int fileVer);
1028 static void setIntPref(int *prefDataField, int newValue);
1029 static void setStringPref(char *prefDataField, const char *newValue);
1030 static void sizeOKCB(Widget w, XtPointer clientData, XtPointer callData);
1031 static void setStringAllocPref(char **pprefDataField, char *newValue);
1032 static void sizeCancelCB(Widget w, XtPointer clientData, XtPointer callData);
1033 static void tabsOKCB(Widget w, XtPointer clientData, XtPointer callData);
1034 static void tabsCancelCB(Widget w, XtPointer clientData, XtPointer callData);
1035 static void tabsHelpCB(Widget w, XtPointer clientData, XtPointer callData);
1036 static void emTabsCB(Widget w, XtPointer clientData, XtPointer callData);
1037 static void wrapOKCB(Widget w, XtPointer clientData, XtPointer callData);
1038 static void wrapCancelCB(Widget w, XtPointer clientData, XtPointer callData);
1039 static void wrapWindowCB(Widget w, XtPointer clientData, XtPointer callData);
1040 static void reapplyLanguageMode(WindowInfo *window, int mode,int forceDefaults);
1043 static void fillFromPrimaryCB(Widget w, XtPointer clientData,
1044 XtPointer callData);
1045 static int checkFontStatus(fontDialog *fd, Widget fontTextFieldW);
1046 static int showFontStatus(fontDialog *fd, Widget fontTextFieldW,
1047 Widget errorLabelW);
1048 static void primaryModifiedCB(Widget w, XtPointer clientData,
1049 XtPointer callData);
1050 static void italicModifiedCB(Widget w, XtPointer clientData,
1051 XtPointer callData);
1052 static void boldModifiedCB(Widget w, XtPointer clientData, XtPointer callData);
1053 static void boldItalicModifiedCB(Widget w, XtPointer clientData,
1054 XtPointer callData);
1055 static void primaryBrowseCB(Widget w, XtPointer clientData, XtPointer callData);
1056 static void italicBrowseCB(Widget w, XtPointer clientData, XtPointer callData);
1057 static void boldBrowseCB(Widget w, XtPointer clientData, XtPointer callData);
1058 static void boldItalicBrowseCB(Widget w, XtPointer clientData,
1059 XtPointer callData);
1060 static void browseFont(Widget parent, Widget fontTextW);
1061 static void fontDestroyCB(Widget w, XtPointer clientData, XtPointer callData);
1062 static void fontOkCB(Widget w, XtPointer clientData, XtPointer callData);
1063 static void fontApplyCB(Widget w, XtPointer clientData, XtPointer callData);
1064 static void fontCancelCB(Widget w, XtPointer clientData, XtPointer callData);
1065 static void updateFonts(fontDialog *fd);
1067 static Boolean checkColorStatus(colorDialog *cd, Widget colorFieldW);
1068 static int verifyAllColors (colorDialog *cd);
1069 static void showColorStatus (colorDialog *cd, Widget colorFieldW,
1070 Widget errorLabelW);
1071 static void updateColors(colorDialog *cd);
1072 static void colorDestroyCB(Widget w, XtPointer clientData, XtPointer callData);
1073 static void colorOkCB (Widget w, XtPointer clientData, XtPointer callData);
1074 static void colorApplyCB (Widget w, XtPointer clientData, XtPointer callData);
1075 static void colorCloseCB(Widget w, XtPointer clientData, XtPointer callData);
1076 static void textFgModifiedCB (Widget w, XtPointer clientData,
1077 XtPointer callData);
1078 static void textBgModifiedCB (Widget w, XtPointer clientData,
1079 XtPointer callData);
1080 static void selectFgModifiedCB(Widget w, XtPointer clientData,
1081 XtPointer callData);
1082 static void selectBgModifiedCB(Widget w, XtPointer clientData,
1083 XtPointer callData);
1084 static void hiliteFgModifiedCB(Widget w, XtPointer clientData,
1085 XtPointer callData);
1086 static void hiliteBgModifiedCB(Widget w, XtPointer clientData,
1087 XtPointer callData);
1088 static void lineNoFgModifiedCB(Widget w, XtPointer clientData,
1089 XtPointer callData);
1090 static void cursorFgModifiedCB(Widget w, XtPointer clientData,
1091 XtPointer callData);
1093 static int matchLanguageMode(WindowInfo *window);
1094 static int loadLanguageModesString(char *inString, int fileVer);
1095 static char *writeLanguageModesString(void);
1096 static char *createExtString(char **extensions, int nExtensions);
1097 static char **readExtensionList(char **inPtr, int *nExtensions);
1098 static void updateLanguageModeSubmenu(WindowInfo *window);
1099 static void setLangModeCB(Widget w, XtPointer clientData, XtPointer callData);
1100 static int modeError(languageModeRec *lm, const char *stringStart,
1101 const char *stoppedAt, const char *message);
1102 static void lmDestroyCB(Widget w, XtPointer clientData, XtPointer callData);
1103 static void lmOkCB(Widget w, XtPointer clientData, XtPointer callData);
1104 static void lmApplyCB(Widget w, XtPointer clientData, XtPointer callData);
1105 static void lmCloseCB(Widget w, XtPointer clientData, XtPointer callData);
1106 static int lmDeleteConfirmCB(int itemIndex, void *cbArg);
1107 static int updateLMList(void);
1108 static languageModeRec *copyLanguageModeRec(languageModeRec *lm);
1109 static void *lmGetDisplayedCB(void *oldItem, int explicitRequest, int *abort,
1110 void *cbArg);
1111 static void lmSetDisplayedCB(void *item, void *cbArg);
1112 static languageModeRec *readLMDialogFields(int silent);
1113 static void lmFreeItemCB(void *item);
1114 static void freeLanguageModeRec(languageModeRec *lm);
1115 static int lmDialogEmpty(void);
1116 static void updatePatternsTo5dot1(void);
1117 static void updatePatternsTo5dot2(void);
1118 static void updatePatternsTo5dot3(void);
1119 static void updatePatternsTo5dot4(void);
1120 static void updateShellCmdsTo5dot3(void);
1121 static void updateShellCmdsTo5dot4(void);
1122 static void updateMacroCmdsTo5dot5(void);
1123 static void migrateColorResources(XrmDatabase prefDB, XrmDatabase appDB);
1124 static void spliceString(char **intoString, const char *insertString, const char *atExpr);
1125 static int regexFind(const char *inString, const char *expr);
1126 static int regexReplace(char **inString, const char *expr,
1127 const char *replaceWith);
1129 #ifdef SGI_CUSTOM
1130 static int shortPrefToDefault(Widget parent, const char *settingName, int *setDefault);
1131 #endif
1133 XrmDatabase CreateNEditPrefDB(int *argcInOut, char **argvInOut)
1135 return CreatePreferencesDatabase(GetRCFileName(NEDIT_RC), APP_NAME,
1136 OpTable, XtNumber(OpTable), (unsigned int *)argcInOut, argvInOut);
1139 void RestoreNEditPrefs(XrmDatabase prefDB, XrmDatabase appDB)
1141 int requiresConversion;
1142 int major; /* The integral part of version number */
1143 int minor; /* fractional part of version number */
1144 int fileVer = 0; /* Both combined into an integer */
1145 int nparsed;
1147 /* Load preferences */
1148 RestorePreferences(prefDB, appDB, APP_NAME,
1149 APP_CLASS, PrefDescrip, XtNumber(PrefDescrip));
1151 /* If the preferences file was written by an older version of NEdit,
1152 warn the user that it will be converted. */
1153 requiresConversion = PrefData.prefFileRead &&
1154 PrefData.fileVersion[0] == '\0';
1155 if (requiresConversion) {
1156 updatePatternsTo5dot1();
1159 if (PrefData.prefFileRead) {
1160 if (PrefData.fileVersion[0] == '\0') {
1161 fileVer = 0; /* Pre-5.1 */
1163 else {
1164 /* Note: do not change the format of this. Older executables
1165 need to read this field for forward compatability. */
1166 nparsed = sscanf(PrefData.fileVersion, "%d.%d", &major, &minor);
1167 if (nparsed >= 2) {
1168 /* Use OSF-style numbering scheme */
1169 fileVer = major * 1000 + minor;
1174 if (PrefData.prefFileRead && fileVer < 5002) {
1175 updatePatternsTo5dot2();
1178 if (PrefData.prefFileRead && fileVer < 5003) {
1179 updateShellCmdsTo5dot3();
1180 updatePatternsTo5dot3();
1183 /* Note that we don't care about unreleased file versions. Anyone
1184 who is running a CVS or alpha version of NEdit is resposnbile
1185 for managing the preferences file themselves. Otherwise, it
1186 gets impossible to track the number of "in-between" file formats.
1187 We only do auto-upgrading for a real release. */
1189 if (PrefData.prefFileRead && (fileVer < 5004)) {
1190 migrateColorResources(prefDB, appDB);
1191 updateShellCmdsTo5dot4();
1192 updatePatternsTo5dot4();
1194 if (PrefData.prefFileRead && (fileVer < 5005)) {
1195 fprintf(stderr, "NEdit: Converting .nedit file to 5.5 version.\n"
1196 " To keep, use Preferences -> Save Defaults\n");
1197 updateMacroCmdsTo5dot5();
1199 /* Migrate colors if there's no config file yet */
1200 if (!PrefData.prefFileRead) {
1201 migrateColorResources(prefDB, appDB);
1204 /* Do further parsing on resource types which RestorePreferences does
1205 not understand and reads as strings, to put them in the final form
1206 in which nedit stores and uses. If the preferences file was
1207 written by an older version of NEdit, update regular expressions in
1208 highlight patterns to quote braces and use & instead of \0 */
1209 translatePrefFormats(requiresConversion, fileVer);
1213 ** Many of of NEdit's preferences are much more complicated than just simple
1214 ** integers or strings. These are read as strings, but must be parsed and
1215 ** translated into something meaningful. This routine does the translation,
1216 ** and, in most cases, frees the original string, which is no longer useful.
1218 ** The argument convertOld attempts a conversion from pre 5.1 format .nedit
1219 ** files (which means patterns and macros may contain regular expressions
1220 ** which are of the older syntax where braces were not quoted, and \0 was a
1221 ** legal substitution character). Macros, so far can not be automatically
1222 ** converted, unfortunately.
1224 static void translatePrefFormats(int convertOld, int fileVer)
1226 XFontStruct *font;
1228 /* Parse the strings which represent types which are not decoded by
1229 the standard resource manager routines */
1230 #ifndef VMS
1231 if (TempStringPrefs.shellCmds != NULL) {
1232 LoadShellCmdsString(TempStringPrefs.shellCmds);
1233 XtFree(TempStringPrefs.shellCmds);
1234 TempStringPrefs.shellCmds = NULL;
1236 #endif /* VMS */
1237 if (TempStringPrefs.macroCmds != NULL) {
1238 LoadMacroCmdsString(TempStringPrefs.macroCmds);
1239 XtFree(TempStringPrefs.macroCmds);
1240 TempStringPrefs.macroCmds = NULL;
1242 if (TempStringPrefs.bgMenuCmds != NULL) {
1243 LoadBGMenuCmdsString(TempStringPrefs.bgMenuCmds);
1244 XtFree(TempStringPrefs.bgMenuCmds);
1245 TempStringPrefs.bgMenuCmds = NULL;
1247 if (TempStringPrefs.highlight != NULL) {
1248 LoadHighlightString(TempStringPrefs.highlight, convertOld);
1249 XtFree(TempStringPrefs.highlight);
1250 TempStringPrefs.highlight = NULL;
1252 if (TempStringPrefs.styles != NULL) {
1253 LoadStylesString(TempStringPrefs.styles);
1254 XtFree(TempStringPrefs.styles);
1255 TempStringPrefs.styles = NULL;
1257 if (TempStringPrefs.language != NULL) {
1258 loadLanguageModesString(TempStringPrefs.language, fileVer);
1259 XtFree(TempStringPrefs.language);
1260 TempStringPrefs.language = NULL;
1262 if (TempStringPrefs.smartIndent != NULL) {
1263 LoadSmartIndentString(TempStringPrefs.smartIndent);
1264 XtFree(TempStringPrefs.smartIndent);
1265 TempStringPrefs.smartIndent = NULL;
1267 if (TempStringPrefs.smartIndentCommon != NULL) {
1268 LoadSmartIndentCommonString(TempStringPrefs.smartIndentCommon);
1269 XtFree(TempStringPrefs.smartIndentCommon);
1270 TempStringPrefs.smartIndentCommon = NULL;
1273 /* translate the font names into fontLists suitable for the text widget */
1274 font = XLoadQueryFont(TheDisplay, PrefData.fontString);
1275 PrefData.fontList = font==NULL ? NULL :
1276 XmFontListCreate(font, XmSTRING_DEFAULT_CHARSET);
1277 PrefData.boldFontStruct = XLoadQueryFont(TheDisplay,
1278 PrefData.boldFontString);
1279 PrefData.italicFontStruct = XLoadQueryFont(TheDisplay,
1280 PrefData.italicFontString);
1281 PrefData.boldItalicFontStruct = XLoadQueryFont(TheDisplay,
1282 PrefData.boldItalicFontString);
1284 /* For compatability with older (4.0.3 and before) versions, the autoWrap
1285 and autoIndent resources can accept values of True and False. Translate
1286 them into acceptable wrap and indent styles */
1287 if (PrefData.wrapStyle == 3) PrefData.wrapStyle = NEWLINE_WRAP;
1288 if (PrefData.wrapStyle == 4) PrefData.wrapStyle = NO_WRAP;
1289 if (PrefData.autoIndent == 3) PrefData.autoIndent = AUTO_INDENT;
1290 if (PrefData.autoIndent == 4) PrefData.autoIndent = NO_AUTO_INDENT;
1292 /* setup language mode dependent info of user menus (to increase
1293 performance when switching between documents of different
1294 language modes) */
1295 SetupUserMenuInfo();
1298 void SaveNEditPrefs(Widget parent, int quietly)
1300 const char* prefFileName = GetRCFileName(NEDIT_RC);
1301 if (prefFileName == NULL)
1303 /* GetRCFileName() might return NULL if an error occurs during
1304 creation of the preference file directory. */
1305 DialogF(DF_WARN, parent, 1, "Error saving Preferences",
1306 "Unable to save preferences: Cannot determine filename.",
1307 "OK");
1308 return;
1311 if (!quietly) {
1312 if (DialogF(DF_INF, parent, 2, "Save Preferences",
1313 ImportedFile == NULL ?
1314 "Default preferences will be saved in the file:\n"
1315 "%s\n"
1316 "NEdit automatically loads this file\n"
1317 "each time it is started." :
1318 "Default preferences will be saved in the file:\n"
1319 "%s\n"
1320 "SAVING WILL INCORPORATE SETTINGS\n"
1321 "FROM FILE: %s", "OK", "Cancel",
1322 prefFileName, ImportedFile) == 2)
1323 return;
1325 #ifndef VMS
1326 TempStringPrefs.shellCmds = WriteShellCmdsString();
1327 #endif /* VMS */
1328 TempStringPrefs.macroCmds = WriteMacroCmdsString();
1329 TempStringPrefs.bgMenuCmds = WriteBGMenuCmdsString();
1330 TempStringPrefs.highlight = WriteHighlightString();
1331 TempStringPrefs.language = writeLanguageModesString();
1332 TempStringPrefs.styles = WriteStylesString();
1333 TempStringPrefs.smartIndent = WriteSmartIndentString();
1334 TempStringPrefs.smartIndentCommon = WriteSmartIndentCommonString();
1335 strcpy(PrefData.fileVersion, PREF_FILE_VERSION);
1336 if (!SavePreferences(XtDisplay(parent), prefFileName, HeaderText,
1337 PrefDescrip, XtNumber(PrefDescrip)))
1339 DialogF(DF_WARN, parent, 1, "Save Preferences",
1340 "Unable to save preferences in %s", "OK", prefFileName);
1343 #ifndef VMS
1344 XtFree(TempStringPrefs.shellCmds);
1345 #endif /* VMS */
1346 XtFree(TempStringPrefs.macroCmds);
1347 XtFree(TempStringPrefs.bgMenuCmds);
1348 XtFree(TempStringPrefs.highlight);
1349 XtFree(TempStringPrefs.language);
1350 XtFree(TempStringPrefs.styles);
1351 XtFree(TempStringPrefs.smartIndent);
1352 XtFree(TempStringPrefs.smartIndentCommon);
1354 PrefsHaveChanged = False;
1358 ** Load an additional preferences file on top of the existing preferences
1359 ** derived from defaults, the .nedit file, and X resources.
1361 void ImportPrefFile(const char *filename, int convertOld)
1363 XrmDatabase db;
1364 char *fileString;
1366 fileString = ReadAnyTextFile(filename);
1367 if (fileString != NULL){
1368 db = XrmGetStringDatabase(fileString);
1369 XtFree(fileString);
1370 OverlayPreferences(db, APP_NAME, APP_CLASS, PrefDescrip,
1371 XtNumber(PrefDescrip));
1372 translatePrefFormats(convertOld, -1);
1373 ImportedFile = XtNewString(filename);
1374 } else
1376 fprintf(stderr, "Could not read additional preferences file: ");
1377 fprintf(stderr, filename);
1378 fprintf(stderr, "\n");
1382 void SetPrefOpenInTab(int state)
1384 WindowInfo *w = WindowList;
1385 setIntPref(&PrefData.openInTab, state);
1386 for(; w != NULL; w = w->next)
1387 UpdateNewOppositeMenu(w, state);
1390 int GetPrefOpenInTab(void)
1392 return PrefData.openInTab;
1395 void SetPrefWrap(int state)
1397 setIntPref(&PrefData.wrapStyle, state);
1400 int GetPrefWrap(int langMode)
1402 if (langMode == PLAIN_LANGUAGE_MODE ||
1403 LanguageModes[langMode]->wrapStyle == DEFAULT_WRAP)
1404 return PrefData.wrapStyle;
1405 return LanguageModes[langMode]->wrapStyle;
1408 void SetPrefWrapMargin(int margin)
1410 setIntPref(&PrefData.wrapMargin, margin);
1413 int GetPrefWrapMargin(void)
1415 return PrefData.wrapMargin;
1418 void SetPrefSearch(int searchType)
1420 setIntPref(&PrefData.searchMethod, searchType);
1423 int GetPrefSearch(void)
1425 return PrefData.searchMethod;
1428 #ifdef REPLACE_SCOPE
1429 void SetPrefReplaceDefScope(int scope)
1431 setIntPref(&PrefData.replaceDefScope, scope);
1434 int GetPrefReplaceDefScope(void)
1436 return PrefData.replaceDefScope;
1438 #endif
1440 void SetPrefAutoIndent(int state)
1442 setIntPref(&PrefData.autoIndent, state);
1445 int GetPrefAutoIndent(int langMode)
1447 if (langMode == PLAIN_LANGUAGE_MODE ||
1448 LanguageModes[langMode]->indentStyle == DEFAULT_INDENT)
1449 return PrefData.autoIndent;
1450 return LanguageModes[langMode]->indentStyle;
1453 void SetPrefAutoSave(int state)
1455 setIntPref(&PrefData.autoSave, state);
1458 int GetPrefAutoSave(void)
1460 return PrefData.autoSave;
1463 void SetPrefSaveOldVersion(int state)
1465 setIntPref(&PrefData.saveOldVersion, state);
1468 int GetPrefSaveOldVersion(void)
1470 return PrefData.saveOldVersion;
1473 void SetPrefSearchDlogs(int state)
1475 setIntPref(&PrefData.searchDlogs, state);
1478 int GetPrefSearchDlogs(void)
1480 return PrefData.searchDlogs;
1483 void SetPrefBeepOnSearchWrap(int state)
1485 setIntPref(&PrefData.searchWrapBeep, state);
1488 int GetPrefBeepOnSearchWrap(void)
1490 return PrefData.searchWrapBeep;
1493 void SetPrefKeepSearchDlogs(int state)
1495 setIntPref(&PrefData.keepSearchDlogs, state);
1498 int GetPrefKeepSearchDlogs(void)
1500 return PrefData.keepSearchDlogs;
1503 void SetPrefSearchWraps(int state)
1505 setIntPref(&PrefData.searchWraps, state);
1508 int GetPrefStickyCaseSenseBtn(void)
1510 return PrefData.stickyCaseSenseBtn;
1513 void SetPrefStickyCaseSenseBtn(int state)
1515 setIntPref(&PrefData.stickyCaseSenseBtn, state);
1518 int GetPrefSearchWraps(void)
1520 return PrefData.searchWraps;
1523 void SetPrefStatsLine(int state)
1525 setIntPref(&PrefData.statsLine, state);
1528 int GetPrefStatsLine(void)
1530 return PrefData.statsLine;
1533 void SetPrefISearchLine(int state)
1535 setIntPref(&PrefData.iSearchLine, state);
1538 int GetPrefISearchLine(void)
1540 return PrefData.iSearchLine;
1543 void SetPrefSortTabs(int state)
1545 setIntPref(&PrefData.sortTabs, state);
1548 int GetPrefSortTabs(void)
1550 return PrefData.sortTabs;
1553 void SetPrefTabBar(int state)
1555 setIntPref(&PrefData.tabBar, state);
1558 int GetPrefTabBar(void)
1560 return PrefData.tabBar;
1563 void SetPrefTabBarHideOne(int state)
1565 setIntPref(&PrefData.tabBarHideOne, state);
1568 int GetPrefTabBarHideOne(void)
1570 return PrefData.tabBarHideOne;
1573 void SetPrefGlobalTabNavigate(int state)
1575 setIntPref(&PrefData.globalTabNavigate, state);
1578 int GetPrefGlobalTabNavigate(void)
1580 return PrefData.globalTabNavigate;
1583 void SetPrefToolTips(int state)
1585 setIntPref(&PrefData.toolTips, state);
1588 int GetPrefToolTips(void)
1590 return PrefData.toolTips;
1593 void SetPrefLineNums(int state)
1595 setIntPref(&PrefData.lineNums, state);
1598 int GetPrefLineNums(void)
1600 return PrefData.lineNums;
1603 void SetPrefShowPathInWindowsMenu(int state)
1605 setIntPref(&PrefData.pathInWindowsMenu, state);
1608 int GetPrefShowPathInWindowsMenu(void)
1610 return PrefData.pathInWindowsMenu;
1613 void SetPrefWarnFileMods(int state)
1615 setIntPref(&PrefData.warnFileMods, state);
1618 int GetPrefWarnFileMods(void)
1620 return PrefData.warnFileMods;
1623 void SetPrefWarnRealFileMods(int state)
1625 setIntPref(&PrefData.warnRealFileMods, state);
1628 int GetPrefWarnRealFileMods(void)
1630 return PrefData.warnRealFileMods;
1633 void SetPrefWarnExit(int state)
1635 setIntPref(&PrefData.warnExit, state);
1638 int GetPrefWarnExit(void)
1640 return PrefData.warnExit;
1643 void SetPrefv(int state)
1645 setIntPref(&PrefData.findReplaceUsesSelection, state);
1648 int GetPrefFindReplaceUsesSelection(void)
1650 return PrefData.findReplaceUsesSelection;
1653 void SetPrefMapDelete(int state)
1655 setIntPref(&PrefData.mapDelete, state);
1658 int GetPrefMapDelete(void)
1660 return PrefData.mapDelete;
1663 void SetPrefStdOpenDialog(int state)
1665 setIntPref(&PrefData.stdOpenDialog, state);
1668 int GetPrefStdOpenDialog(void)
1670 return PrefData.stdOpenDialog;
1673 void SetPrefRows(int nRows)
1675 setIntPref(&PrefData.textRows, nRows);
1678 int GetPrefRows(void)
1680 return PrefData.textRows;
1683 void SetPrefCols(int nCols)
1685 setIntPref(&PrefData.textCols, nCols);
1688 int GetPrefCols(void)
1690 return PrefData.textCols;
1693 void SetPrefTabDist(int tabDist)
1695 setIntPref(&PrefData.tabDist, tabDist);
1698 int GetPrefTabDist(int langMode)
1700 int tabDist;
1701 if (langMode == PLAIN_LANGUAGE_MODE ||
1702 LanguageModes[langMode]->tabDist == DEFAULT_TAB_DIST) {
1703 tabDist = PrefData.tabDist;
1704 } else {
1705 tabDist = LanguageModes[langMode]->tabDist;
1707 /* Make sure that the tab distance is in range (garbage may have
1708 been entered via the command line or the X resources, causing
1709 errors later on, like division by zero). */
1710 if (tabDist <= 0) return 1;
1711 if (tabDist > MAX_EXP_CHAR_LEN) return MAX_EXP_CHAR_LEN;
1712 return tabDist;
1715 void SetPrefEmTabDist(int tabDist)
1717 setIntPref(&PrefData.emTabDist, tabDist);
1720 int GetPrefEmTabDist(int langMode)
1722 if (langMode == PLAIN_LANGUAGE_MODE ||
1723 LanguageModes[langMode]->emTabDist == DEFAULT_EM_TAB_DIST)
1724 return PrefData.emTabDist;
1725 return LanguageModes[langMode]->emTabDist;
1728 void SetPrefInsertTabs(int state)
1730 setIntPref(&PrefData.insertTabs, state);
1733 int GetPrefInsertTabs(void)
1735 return PrefData.insertTabs;
1738 void SetPrefShowMatching(int state)
1740 setIntPref(&PrefData.showMatchingStyle, state);
1743 int GetPrefShowMatching(void)
1746 * For backwards compatibility with pre-5.2 versions, the boolean
1747 * False/True matching behavior is converted to NO_FLASH/FLASH_DELIMIT.
1749 if (PrefData.showMatchingStyle >= N_SHOW_MATCHING_STYLES)
1750 PrefData.showMatchingStyle -= N_SHOW_MATCHING_STYLES;
1751 return PrefData.showMatchingStyle;
1754 void SetPrefMatchSyntaxBased(int state)
1756 setIntPref(&PrefData.matchSyntaxBased, state);
1759 int GetPrefMatchSyntaxBased(void)
1761 return PrefData.matchSyntaxBased;
1764 void SetPrefHighlightSyntax(int state)
1766 setIntPref(&PrefData.highlightSyntax, state);
1769 int GetPrefHighlightSyntax(void)
1771 return PrefData.highlightSyntax;
1774 void SetPrefBacklightChars(int state)
1776 setIntPref(&PrefData.backlightChars, state);
1779 int GetPrefBacklightChars(void)
1781 return PrefData.backlightChars;
1784 void SetPrefBacklightCharTypes(char *types)
1786 setStringAllocPref(&PrefData.backlightCharTypes, types);
1789 char *GetPrefBacklightCharTypes(void)
1791 return PrefData.backlightCharTypes;
1794 void SetPrefRepositionDialogs(int state)
1796 setIntPref(&PrefData.repositionDialogs, state);
1799 int GetPrefRepositionDialogs(void)
1801 return PrefData.repositionDialogs;
1804 void SetPrefAutoScroll(int state)
1806 WindowInfo *w = WindowList;
1807 int margin = state ? PrefData.autoScrollVPadding : 0;
1809 setIntPref(&PrefData.autoScroll, state);
1810 for(w = WindowList; w != NULL; w = w->next)
1811 SetAutoScroll(w, margin);
1814 int GetPrefAutoScroll(void)
1816 return PrefData.autoScroll;
1819 int GetVerticalAutoScroll(void)
1821 return PrefData.autoScroll ? PrefData.autoScrollVPadding : 0;
1824 void SetPrefAppendLF(int state)
1826 setIntPref(&PrefData.appendLF, state);
1829 int GetPrefAppendLF(void)
1831 return PrefData.appendLF;
1834 void SetPrefSortOpenPrevMenu(int state)
1836 setIntPref(&PrefData.sortOpenPrevMenu, state);
1839 int GetPrefSortOpenPrevMenu(void)
1841 return PrefData.sortOpenPrevMenu;
1844 void SetPrefTagFile(const char *tagFileName)
1846 setStringPref(PrefData.tagFile, tagFileName);
1849 char *GetPrefTagFile(void)
1851 return PrefData.tagFile;
1854 void SetPrefSmartTags(int state)
1856 setIntPref(&PrefData.smartTags, state);
1859 int GetPrefSmartTags(void)
1861 return PrefData.smartTags;
1864 int GetPrefAlwaysCheckRelTagsSpecs(void)
1866 return PrefData.alwaysCheckRelativeTagsSpecs;
1869 char *GetPrefDelimiters(void)
1871 return PrefData.delimiters;
1874 char *GetPrefColorName(int index)
1876 return PrefData.colorNames[index];
1879 void SetPrefColorName(int index, const char *name)
1881 setStringPref(PrefData.colorNames[index], name);
1885 ** Set the font preferences using the font name (the fontList is generated
1886 ** in this call). Note that this leaks memory and server resources each
1887 ** time the default font is re-set. See note on SetFontByName in window.c
1888 ** for more information.
1890 void SetPrefFont(char *fontName)
1892 XFontStruct *font;
1894 setStringPref(PrefData.fontString, fontName);
1895 font = XLoadQueryFont(TheDisplay, fontName);
1896 PrefData.fontList = font==NULL ? NULL :
1897 XmFontListCreate(font, XmSTRING_DEFAULT_CHARSET);
1900 void SetPrefBoldFont(char *fontName)
1902 setStringPref(PrefData.boldFontString, fontName);
1903 PrefData.boldFontStruct = XLoadQueryFont(TheDisplay, fontName);
1906 void SetPrefItalicFont(char *fontName)
1908 setStringPref(PrefData.italicFontString, fontName);
1909 PrefData.italicFontStruct = XLoadQueryFont(TheDisplay, fontName);
1911 void SetPrefBoldItalicFont(char *fontName)
1913 setStringPref(PrefData.boldItalicFontString, fontName);
1914 PrefData.boldItalicFontStruct = XLoadQueryFont(TheDisplay, fontName);
1917 char *GetPrefFontName(void)
1919 return PrefData.fontString;
1922 char *GetPrefBoldFontName(void)
1924 return PrefData.boldFontString;
1927 char *GetPrefItalicFontName(void)
1929 return PrefData.italicFontString;
1932 char *GetPrefBoldItalicFontName(void)
1934 return PrefData.boldItalicFontString;
1937 XmFontList GetPrefFontList(void)
1939 return PrefData.fontList;
1942 XFontStruct *GetPrefBoldFont(void)
1944 return PrefData.boldFontStruct;
1947 XFontStruct *GetPrefItalicFont(void)
1949 return PrefData.italicFontStruct;
1952 XFontStruct *GetPrefBoldItalicFont(void)
1954 return PrefData.boldItalicFontStruct;
1957 char *GetPrefHelpFontName(int index)
1959 return PrefData.helpFontNames[index];
1962 char *GetPrefHelpLinkColor(void)
1964 return PrefData.helpLinkColor;
1967 char *GetPrefTooltipBgColor(void)
1969 return PrefData.tooltipBgColor;
1972 void SetPrefShell(const char *shell)
1974 setStringPref(PrefData.shell, shell);
1977 char *GetPrefShell(void)
1979 return PrefData.shell;
1982 void SetPrefGeometry(const char *geometry)
1984 setStringPref(PrefData.geometry, geometry);
1987 char *GetPrefGeometry(void)
1989 return PrefData.geometry;
1992 char *GetPrefServerName(void)
1994 return PrefData.serverName;
1997 char *GetPrefBGMenuBtn(void)
1999 return PrefData.bgMenuBtn;
2002 int GetPrefMaxPrevOpenFiles(void)
2004 return PrefData.maxPrevOpenFiles;
2007 int GetPrefTypingHidesPointer(void)
2009 return(PrefData.typingHidesPointer);
2012 #ifdef SGI_CUSTOM
2013 void SetPrefShortMenus(int state)
2015 setIntPref(&PrefData.shortMenus, state);
2018 int GetPrefShortMenus(void)
2020 return PrefData.shortMenus;
2022 #endif
2024 void SetPrefTitleFormat(const char* format)
2026 const WindowInfo* window;
2028 setStringPref(PrefData.titleFormat, format);
2030 /* update all windows */
2031 for (window=WindowList; window!=NULL; window=window->next) {
2032 UpdateWindowTitle(window);
2035 const char* GetPrefTitleFormat(void)
2037 return PrefData.titleFormat;
2040 void SetPrefUndoModifiesSelection(Boolean value)
2042 setIntPref(&PrefData.undoModifiesSelection, value);
2045 Boolean GetPrefUndoModifiesSelection(void)
2047 return (Boolean)PrefData.undoModifiesSelection;
2050 int GetPrefOverrideVirtKeyBindings(void)
2052 return PrefData.virtKeyOverride;
2056 ** If preferences don't get saved, ask the user on exit whether to save
2058 void MarkPrefsChanged(void)
2060 PrefsHaveChanged = True;
2064 ** Check if preferences have changed, and if so, ask the user if he wants
2065 ** to re-save. Returns False if user requests cancelation of Exit (or whatever
2066 ** operation triggered this call to be made).
2068 int CheckPrefsChangesSaved(Widget dialogParent)
2070 int resp;
2072 if (!PrefsHaveChanged)
2073 return True;
2075 resp = DialogF(DF_WARN, dialogParent, 3, "Default Preferences",
2076 ImportedFile == NULL ?
2077 "Default Preferences have changed.\n"
2078 "Save changes to NEdit preference file?" :
2079 "Default Preferences have changed. SAVING \n"
2080 "CHANGES WILL INCORPORATE ADDITIONAL\nSETTINGS FROM FILE: %s",
2081 "Save", "Don't Save", "Cancel", ImportedFile);
2082 if (resp == 2)
2083 return True;
2084 if (resp == 3)
2085 return False;
2087 SaveNEditPrefs(dialogParent, True);
2088 return True;
2092 ** set *prefDataField to newValue, but first check if they're different
2093 ** and update PrefsHaveChanged if a preference setting has now changed.
2095 static void setIntPref(int *prefDataField, int newValue)
2097 if (newValue != *prefDataField)
2098 PrefsHaveChanged = True;
2099 *prefDataField = newValue;
2102 static void setStringPref(char *prefDataField, const char *newValue)
2104 if (strcmp(prefDataField, newValue))
2105 PrefsHaveChanged = True;
2106 strcpy(prefDataField, newValue);
2109 static void setStringAllocPref(char **pprefDataField, char *newValue)
2111 char *p_newField;
2113 /* treat empty strings as nulls */
2114 if (newValue && *newValue == '\0')
2115 newValue = NULL;
2116 if (*pprefDataField && **pprefDataField == '\0')
2117 *pprefDataField = NULL; /* assume statically alloc'ed "" */
2119 /* check changes */
2120 if (!*pprefDataField && !newValue)
2121 return;
2122 else if (!*pprefDataField && newValue)
2123 PrefsHaveChanged = True;
2124 else if (*pprefDataField && !newValue)
2125 PrefsHaveChanged = True;
2126 else if (strcmp(*pprefDataField, newValue))
2127 PrefsHaveChanged = True;
2129 /* get rid of old preference */
2130 if (*pprefDataField)
2131 XtFree(*pprefDataField);
2133 /* store new preference */
2134 if (newValue) {
2135 p_newField = XtMalloc(strlen(newValue) + 1);
2136 strcpy(p_newField, newValue);
2138 *pprefDataField = newValue;
2142 ** Set the language mode for the window, update the menu and trigger language
2143 ** mode specific actions (turn on/off highlighting). If forceNewDefaults is
2144 ** true, re-establish default settings for language-specific preferences
2145 ** regardless of whether they were previously set by the user.
2147 void SetLanguageMode(WindowInfo *window, int mode, int forceNewDefaults)
2149 Widget menu;
2150 WidgetList items;
2151 int n;
2152 Cardinal nItems;
2153 void *userData;
2155 /* Do mode-specific actions */
2156 reapplyLanguageMode(window, mode, forceNewDefaults);
2158 /* Select the correct language mode in the sub-menu */
2159 if (IsTopDocument(window)) {
2160 XtVaGetValues(window->langModeCascade, XmNsubMenuId, &menu, NULL);
2161 XtVaGetValues(menu, XmNchildren, &items, XmNnumChildren, &nItems, NULL);
2162 for (n=0; n<(int)nItems; n++) {
2163 XtVaGetValues(items[n], XmNuserData, &userData, NULL);
2164 XmToggleButtonSetState(items[n], (int)userData == mode, False);
2170 ** Lookup a language mode by name, returning the index of the language
2171 ** mode or PLAIN_LANGUAGE_MODE if the name is not found
2173 int FindLanguageMode(const char *languageName)
2175 int i;
2177 /* Compare each language mode to the one we were presented */
2178 for (i=0; i<NLanguageModes; i++)
2179 if (!strcmp(languageName, LanguageModes[i]->name))
2180 return i;
2182 return PLAIN_LANGUAGE_MODE;
2187 ** Apply language mode matching criteria and set window->languageMode to
2188 ** the appropriate mode for the current file, trigger language mode
2189 ** specific actions (turn on/off highlighting), and update the language
2190 ** mode menu item. If forceNewDefaults is true, re-establish default
2191 ** settings for language-specific preferences regardless of whether
2192 ** they were previously set by the user.
2194 void DetermineLanguageMode(WindowInfo *window, int forceNewDefaults)
2196 SetLanguageMode(window, matchLanguageMode(window), forceNewDefaults);
2200 ** Return the name of the current language mode set in "window", or NULL
2201 ** if the current mode is "Plain".
2203 char *LanguageModeName(int mode)
2205 if (mode == PLAIN_LANGUAGE_MODE)
2206 return NULL;
2207 else
2208 return LanguageModes[mode]->name;
2212 ** Get the set of word delimiters for the language mode set in the current
2213 ** window. Returns NULL when no language mode is set (it would be easy to
2214 ** return the default delimiter set when the current language mode is "Plain",
2215 ** or the mode doesn't have its own delimiters, but this is usually used
2216 ** to supply delimiters for RE searching, and ExecRE can skip compiling a
2217 ** delimiter table when delimiters is NULL).
2219 char *GetWindowDelimiters(WindowInfo *window)
2221 if (window->languageMode == PLAIN_LANGUAGE_MODE)
2222 return NULL;
2223 else
2224 return LanguageModes[window->languageMode]->delimiters;
2228 ** Put up a dialog for selecting a custom initial window size
2230 void RowColumnPrefDialog(Widget parent)
2232 Widget form, selBox, topLabel;
2233 Arg selBoxArgs[2];
2234 XmString s1;
2236 XtSetArg(selBoxArgs[0], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL);
2237 XtSetArg(selBoxArgs[1], XmNautoUnmanage, False);
2238 selBox = CreatePromptDialog(parent, "customSize", selBoxArgs, 2);
2239 XtAddCallback(selBox, XmNokCallback, (XtCallbackProc)sizeOKCB, NULL);
2240 XtAddCallback(selBox, XmNcancelCallback, (XtCallbackProc)sizeCancelCB,NULL);
2241 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_TEXT));
2242 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_SELECTION_LABEL));
2243 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_HELP_BUTTON));
2244 XtVaSetValues(XtParent(selBox), XmNtitle, "Initial Window Size", NULL);
2246 form = XtVaCreateManagedWidget("form", xmFormWidgetClass, selBox, NULL);
2248 topLabel = XtVaCreateManagedWidget("topLabel", xmLabelGadgetClass, form,
2249 XmNlabelString, s1=MKSTRING(
2250 "Enter desired size in rows\nand columns of characters:"), NULL);
2251 XmStringFree(s1);
2253 RowText = XtVaCreateManagedWidget("rows", xmTextWidgetClass, form,
2254 XmNcolumns, 3,
2255 XmNtopAttachment, XmATTACH_WIDGET,
2256 XmNleftAttachment, XmATTACH_POSITION,
2257 XmNrightAttachment, XmATTACH_POSITION,
2258 XmNtopWidget, topLabel,
2259 XmNleftPosition, 5,
2260 XmNrightPosition, 45, NULL);
2261 RemapDeleteKey(RowText);
2263 XtVaCreateManagedWidget("xLabel", xmLabelGadgetClass, form,
2264 XmNlabelString, s1=MKSTRING("x"),
2265 XmNtopAttachment, XmATTACH_WIDGET,
2266 XmNleftAttachment, XmATTACH_POSITION,
2267 XmNrightAttachment, XmATTACH_POSITION,
2268 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
2269 XmNtopWidget, topLabel,
2270 XmNbottomWidget, RowText,
2271 XmNleftPosition, 45,
2272 XmNrightPosition, 55, NULL);
2273 XmStringFree(s1);
2275 ColText = XtVaCreateManagedWidget("cols", xmTextWidgetClass, form,
2276 XmNcolumns, 3,
2277 XmNtopAttachment, XmATTACH_WIDGET,
2278 XmNleftAttachment, XmATTACH_POSITION,
2279 XmNrightAttachment, XmATTACH_POSITION,
2280 XmNtopWidget, topLabel,
2281 XmNleftPosition, 55,
2282 XmNrightPosition, 95, NULL);
2283 RemapDeleteKey(ColText);
2285 /* put up dialog and wait for user to press ok or cancel */
2286 DoneWithSizeDialog = False;
2287 ManageDialogCenteredOnPointer(selBox);
2288 while (!DoneWithSizeDialog)
2290 XEvent event;
2291 XtAppNextEvent(XtWidgetToApplicationContext(parent), &event);
2292 ServerDispatchEvent(&event);
2295 XtDestroyWidget(selBox);
2298 static void sizeOKCB(Widget w, XtPointer clientData, XtPointer callData)
2300 int rowValue, colValue, stat;
2302 /* get the values that the user entered and make sure they're ok */
2303 stat = GetIntTextWarn(RowText, &rowValue, "number of rows", True);
2304 if (stat != TEXT_READ_OK)
2305 return;
2306 stat = GetIntTextWarn(ColText, &colValue, "number of columns", True);
2307 if (stat != TEXT_READ_OK)
2308 return;
2310 /* set the corresponding preferences and dismiss the dialog */
2311 SetPrefRows(rowValue);
2312 SetPrefCols(colValue);
2313 DoneWithSizeDialog = True;
2316 static void sizeCancelCB(Widget w, XtPointer clientData, XtPointer callData)
2318 DoneWithSizeDialog = True;
2322 ** Present the user a dialog for setting tab related preferences, either as
2323 ** defaults, or for a specific window (pass "forWindow" as NULL to set default
2324 ** preference, or a window to set preferences for the specific window.
2326 void TabsPrefDialog(Widget parent, WindowInfo *forWindow)
2328 Widget form, selBox;
2329 Arg selBoxArgs[2];
2330 XmString s1;
2331 int emulate, emTabDist, useTabs, tabDist;
2333 XtSetArg(selBoxArgs[0], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL);
2334 XtSetArg(selBoxArgs[1], XmNautoUnmanage, False);
2335 selBox = CreatePromptDialog(parent, "customSize", selBoxArgs, 2);
2336 XtAddCallback(selBox, XmNokCallback, (XtCallbackProc)tabsOKCB, NULL);
2337 XtAddCallback(selBox, XmNcancelCallback, (XtCallbackProc)tabsCancelCB,NULL);
2338 XtAddCallback(selBox, XmNhelpCallback, (XtCallbackProc)tabsHelpCB,NULL);
2339 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_TEXT));
2340 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_SELECTION_LABEL));
2341 XtVaSetValues(XtParent(selBox), XmNtitle, "Tabs", NULL);
2343 form = XtVaCreateManagedWidget("form", xmFormWidgetClass, selBox, NULL);
2345 TabDistText = XtVaCreateManagedWidget("tabDistText", xmTextWidgetClass,
2346 form, XmNcolumns, 7,
2347 XmNtopAttachment, XmATTACH_FORM,
2348 XmNrightAttachment, XmATTACH_FORM, NULL);
2349 RemapDeleteKey(TabDistText);
2350 XtVaCreateManagedWidget("tabDistLabel", xmLabelGadgetClass, form,
2351 XmNlabelString, s1=XmStringCreateSimple(
2352 "Tab spacing (for hardware tab characters)"),
2353 XmNmnemonic, 'T',
2354 XmNuserData, TabDistText,
2355 XmNtopAttachment, XmATTACH_FORM,
2356 XmNleftAttachment, XmATTACH_FORM,
2357 XmNrightAttachment, XmATTACH_WIDGET,
2358 XmNrightWidget, TabDistText,
2359 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
2360 XmNbottomWidget, TabDistText, NULL);
2361 XmStringFree(s1);
2363 EmTabText = XtVaCreateManagedWidget("emTabText", xmTextWidgetClass, form,
2364 XmNcolumns, 7,
2365 XmNtopAttachment, XmATTACH_WIDGET,
2366 XmNtopWidget, TabDistText,
2367 XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET,
2368 XmNrightWidget, TabDistText, NULL);
2369 RemapDeleteKey(EmTabText);
2370 EmTabLabel = XtVaCreateManagedWidget("emTabLabel", xmLabelGadgetClass, form,
2371 XmNlabelString, s1=XmStringCreateSimple("Emulated tab spacing"),
2372 XmNmnemonic, 's',
2373 XmNuserData, EmTabText,
2374 XmNtopAttachment, XmATTACH_WIDGET,
2375 XmNtopWidget, TabDistText,
2376 XmNrightAttachment, XmATTACH_WIDGET,
2377 XmNrightWidget, EmTabText,
2378 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
2379 XmNbottomWidget, EmTabText, NULL);
2380 XmStringFree(s1);
2381 EmTabToggle = XtVaCreateManagedWidget("emTabToggle",
2382 xmToggleButtonWidgetClass, form, XmNlabelString,
2383 s1=XmStringCreateSimple("Emulate tabs"),
2384 XmNmnemonic, 'E',
2385 XmNtopAttachment, XmATTACH_WIDGET,
2386 XmNtopWidget, TabDistText,
2387 XmNleftAttachment, XmATTACH_FORM,
2388 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
2389 XmNbottomWidget, EmTabText, NULL);
2390 XmStringFree(s1);
2391 XtAddCallback(EmTabToggle, XmNvalueChangedCallback, emTabsCB, NULL);
2392 UseTabsToggle = XtVaCreateManagedWidget("useTabsToggle",
2393 xmToggleButtonWidgetClass, form,
2394 XmNlabelString, s1=XmStringCreateSimple(
2395 "Use tab characters in padding and emulated tabs"),
2396 XmNmnemonic, 'U',
2397 XmNtopAttachment, XmATTACH_WIDGET,
2398 XmNtopWidget, EmTabText,
2399 XmNtopOffset, 5,
2400 XmNleftAttachment, XmATTACH_FORM, NULL);
2401 XmStringFree(s1);
2403 /* Set default values */
2404 if (forWindow == NULL) {
2405 emTabDist = GetPrefEmTabDist(PLAIN_LANGUAGE_MODE);
2406 useTabs = GetPrefInsertTabs();
2407 tabDist = GetPrefTabDist(PLAIN_LANGUAGE_MODE);
2408 } else {
2409 XtVaGetValues(forWindow->textArea, textNemulateTabs, &emTabDist, NULL);
2410 useTabs = forWindow->buffer->useTabs;
2411 tabDist = BufGetTabDistance(forWindow->buffer);
2413 emulate = emTabDist != 0;
2414 SetIntText(TabDistText, tabDist);
2415 XmToggleButtonSetState(EmTabToggle, emulate, True);
2416 if (emulate)
2417 SetIntText(EmTabText, emTabDist);
2418 XmToggleButtonSetState(UseTabsToggle, useTabs, False);
2419 XtSetSensitive(EmTabText, emulate);
2420 XtSetSensitive(EmTabLabel, emulate);
2422 /* Handle mnemonic selection of buttons and focus to dialog */
2423 AddDialogMnemonicHandler(form, FALSE);
2425 /* Set the widget to get focus */
2426 #if XmVersion >= 1002
2427 XtVaSetValues(form, XmNinitialFocus, TabDistText, NULL);
2428 #endif
2430 /* put up dialog and wait for user to press ok or cancel */
2431 TabsDialogForWindow = forWindow;
2432 DoneWithTabsDialog = False;
2433 ManageDialogCenteredOnPointer(selBox);
2434 while (!DoneWithTabsDialog)
2436 XEvent event;
2437 XtAppNextEvent(XtWidgetToApplicationContext(parent), &event);
2438 ServerDispatchEvent(&event);
2441 XtDestroyWidget(selBox);
2444 static void tabsOKCB(Widget w, XtPointer clientData, XtPointer callData)
2446 int emulate, useTabs, stat, tabDist, emTabDist;
2447 WindowInfo *window = TabsDialogForWindow;
2449 /* get the values that the user entered and make sure they're ok */
2450 emulate = XmToggleButtonGetState(EmTabToggle);
2451 useTabs = XmToggleButtonGetState(UseTabsToggle);
2452 stat = GetIntTextWarn(TabDistText, &tabDist, "tab spacing", True);
2453 if (stat != TEXT_READ_OK)
2454 return;
2456 if (tabDist <= 0 || tabDist > MAX_EXP_CHAR_LEN)
2458 DialogF(DF_WARN, TabDistText, 1, "Tab Spacing",
2459 "Tab spacing out of range", "OK");
2460 return;
2463 if (emulate) {
2464 stat = GetIntTextWarn(EmTabText, &emTabDist, "emulated tab spacing",True);
2465 if (stat != TEXT_READ_OK)
2466 return;
2468 if (emTabDist <= 0 || tabDist >= 1000)
2470 DialogF(DF_WARN, EmTabText, 1, "Tab Spacing",
2471 "Emulated tab spacing out of range", "OK");
2472 return;
2474 } else
2475 emTabDist = 0;
2477 #ifdef SGI_CUSTOM
2478 /* Ask the user about saving as a default preference */
2479 if (TabsDialogForWindow != NULL) {
2480 int setDefault;
2481 if (!shortPrefToDefault(window->shell, "Tab Settings", &setDefault)) {
2482 DoneWithTabsDialog = True;
2483 return;
2485 if (setDefault) {
2486 SetPrefTabDist(tabDist);
2487 SetPrefEmTabDist(emTabDist);
2488 SetPrefInsertTabs(useTabs);
2489 SaveNEditPrefs(window->shell, GetPrefShortMenus());
2492 #endif
2494 /* Set the value in either the requested window or default preferences */
2495 if (TabsDialogForWindow == NULL) {
2496 SetPrefTabDist(tabDist);
2497 SetPrefEmTabDist(emTabDist);
2498 SetPrefInsertTabs(useTabs);
2499 } else {
2500 char *params[1];
2501 char numStr[25];
2503 params[0] = numStr;
2504 sprintf(numStr, "%d", tabDist);
2505 XtCallActionProc(window->textArea, "set_tab_dist", NULL, params, 1);
2506 params[0] = numStr;
2507 sprintf(numStr, "%d", emTabDist);
2508 XtCallActionProc(window->textArea, "set_em_tab_dist", NULL, params, 1);
2509 params[0] = numStr;
2510 sprintf(numStr, "%d", useTabs);
2511 XtCallActionProc(window->textArea, "set_use_tabs", NULL, params, 1);
2513 setTabDist(window, tabDist);
2514 setEmTabDist(window, emTabDist);
2515 window->buffer->useTabs = useTabs;
2518 DoneWithTabsDialog = True;
2521 static void tabsCancelCB(Widget w, XtPointer clientData, XtPointer callData)
2523 DoneWithTabsDialog = True;
2526 static void tabsHelpCB(Widget w, XtPointer clientData, XtPointer callData)
2528 Help(HELP_TABS_DIALOG);
2531 static void emTabsCB(Widget w, XtPointer clientData, XtPointer callData)
2533 int state = XmToggleButtonGetState(w);
2535 XtSetSensitive(EmTabLabel, state);
2536 XtSetSensitive(EmTabText, state);
2540 ** Present the user a dialog for setting wrap margin.
2542 void WrapMarginDialog(Widget parent, WindowInfo *forWindow)
2544 Widget form, selBox;
2545 Arg selBoxArgs[2];
2546 XmString s1;
2547 int margin;
2549 XtSetArg(selBoxArgs[0], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL);
2550 XtSetArg(selBoxArgs[1], XmNautoUnmanage, False);
2551 selBox = CreatePromptDialog(parent, "wrapMargin", selBoxArgs, 2);
2552 XtAddCallback(selBox, XmNokCallback, (XtCallbackProc)wrapOKCB, NULL);
2553 XtAddCallback(selBox, XmNcancelCallback, (XtCallbackProc)wrapCancelCB,NULL);
2554 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_TEXT));
2555 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_SELECTION_LABEL));
2556 XtUnmanageChild(XmSelectionBoxGetChild(selBox, XmDIALOG_HELP_BUTTON));
2557 XtVaSetValues(XtParent(selBox), XmNtitle, "Wrap Margin", NULL);
2559 form = XtVaCreateManagedWidget("form", xmFormWidgetClass, selBox, NULL);
2561 WrapWindowToggle = XtVaCreateManagedWidget("wrapWindowToggle",
2562 xmToggleButtonWidgetClass, form, XmNlabelString,
2563 s1=XmStringCreateSimple("Wrap and Fill at width of window"),
2564 XmNmnemonic, 'W',
2565 XmNtopAttachment, XmATTACH_FORM,
2566 XmNleftAttachment, XmATTACH_FORM, NULL);
2567 XmStringFree(s1);
2568 XtAddCallback(WrapWindowToggle, XmNvalueChangedCallback, wrapWindowCB,NULL);
2569 WrapText = XtVaCreateManagedWidget("wrapText", xmTextWidgetClass, form,
2570 XmNcolumns, 5,
2571 XmNtopAttachment, XmATTACH_WIDGET,
2572 XmNtopWidget, WrapWindowToggle,
2573 XmNrightAttachment, XmATTACH_FORM, NULL);
2574 RemapDeleteKey(WrapText);
2575 WrapTextLabel = XtVaCreateManagedWidget("wrapMarginLabel",
2576 xmLabelGadgetClass, form,
2577 XmNlabelString, s1=XmStringCreateSimple(
2578 "Margin for Wrap and Fill"),
2579 XmNmnemonic, 'M',
2580 XmNuserData, WrapText,
2581 XmNtopAttachment, XmATTACH_WIDGET,
2582 XmNtopWidget, WrapWindowToggle,
2583 XmNleftAttachment, XmATTACH_FORM,
2584 XmNrightAttachment, XmATTACH_WIDGET,
2585 XmNrightWidget, WrapText,
2586 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
2587 XmNbottomWidget, WrapText, NULL);
2588 XmStringFree(s1);
2590 /* Set default value */
2591 if (forWindow == NULL)
2592 margin = GetPrefWrapMargin();
2593 else
2594 XtVaGetValues(forWindow->textArea, textNwrapMargin, &margin, NULL);
2595 XmToggleButtonSetState(WrapWindowToggle, margin==0, True);
2596 if (margin != 0)
2597 SetIntText(WrapText, margin);
2598 XtSetSensitive(WrapText, margin!=0);
2599 XtSetSensitive(WrapTextLabel, margin!=0);
2601 /* Handle mnemonic selection of buttons and focus to dialog */
2602 AddDialogMnemonicHandler(form, FALSE);
2604 /* put up dialog and wait for user to press ok or cancel */
2605 WrapDialogForWindow = forWindow;
2606 DoneWithWrapDialog = False;
2607 ManageDialogCenteredOnPointer(selBox);
2608 while (!DoneWithWrapDialog)
2610 XEvent event;
2611 XtAppNextEvent(XtWidgetToApplicationContext(parent), &event);
2612 ServerDispatchEvent(&event);
2615 XtDestroyWidget(selBox);
2618 static void wrapOKCB(Widget w, XtPointer clientData, XtPointer callData)
2620 int wrapAtWindow, margin, stat;
2621 WindowInfo *window = WrapDialogForWindow;
2623 /* get the values that the user entered and make sure they're ok */
2624 wrapAtWindow = XmToggleButtonGetState(WrapWindowToggle);
2625 if (wrapAtWindow)
2626 margin = 0;
2627 else {
2628 stat = GetIntTextWarn(WrapText, &margin, "wrap Margin", True);
2629 if (stat != TEXT_READ_OK)
2630 return;
2632 if (margin <= 0 || margin >= 1000)
2634 DialogF(DF_WARN, WrapText, 1, "Wrap Margin",
2635 "Wrap margin out of range", "OK");
2636 return;
2641 #ifdef SGI_CUSTOM
2642 /* Ask the user about saving as a default preference */
2643 if (WrapDialogForWindow != NULL) {
2644 int setDefault;
2645 if (!shortPrefToDefault(window->shell, "Wrap Margin Settings",
2646 &setDefault)) {
2647 DoneWithWrapDialog = True;
2648 return;
2650 if (setDefault) {
2651 SetPrefWrapMargin(margin);
2652 SaveNEditPrefs(window->shell, GetPrefShortMenus());
2655 #endif
2657 /* Set the value in either the requested window or default preferences */
2658 if (WrapDialogForWindow == NULL)
2659 SetPrefWrapMargin(margin);
2660 else {
2661 char *params[1];
2662 char marginStr[25];
2663 sprintf(marginStr, "%d", margin);
2664 params[0] = marginStr;
2665 XtCallActionProc(window->textArea, "set_wrap_margin", NULL, params, 1);
2667 DoneWithWrapDialog = True;
2670 static void wrapCancelCB(Widget w, XtPointer clientData, XtPointer callData)
2672 DoneWithWrapDialog = True;
2675 static void wrapWindowCB(Widget w, XtPointer clientData, XtPointer callData)
2677 int wrapAtWindow = XmToggleButtonGetState(w);
2679 XtSetSensitive(WrapTextLabel, !wrapAtWindow);
2680 XtSetSensitive(WrapText, !wrapAtWindow);
2684 ** Present a dialog for editing language mode information
2686 void EditLanguageModes(void)
2688 #define LIST_RIGHT 40
2689 #define LEFT_MARGIN_POS 1
2690 #define RIGHT_MARGIN_POS 99
2691 #define H_MARGIN 5
2692 Widget form, nameLbl, topLbl, extLbl, recogLbl, delimitLbl, defTipsLbl;
2693 Widget okBtn, applyBtn, closeBtn;
2694 Widget overrideFrame, overrideForm, delimitForm;
2695 Widget tabForm, tabLbl, indentBox, wrapBox;
2696 XmString s1;
2697 int i, ac;
2698 Arg args[20];
2700 /* if the dialog is already displayed, just pop it to the top and return */
2701 if (LMDialog.shell != NULL) {
2702 RaiseShellWindow(LMDialog.shell);
2703 return;
2706 LMDialog.languageModeList = (languageModeRec **)XtMalloc(
2707 sizeof(languageModeRec *) * MAX_LANGUAGE_MODES);
2708 for (i=0; i<NLanguageModes; i++)
2709 LMDialog.languageModeList[i] = copyLanguageModeRec(LanguageModes[i]);
2710 LMDialog.nLanguageModes = NLanguageModes;
2712 /* Create a form widget in an application shell */
2713 ac = 0;
2714 XtSetArg(args[ac], XmNdeleteResponse, XmDO_NOTHING); ac++;
2715 XtSetArg(args[ac], XmNiconName, "NEdit Language Modes"); ac++;
2716 XtSetArg(args[ac], XmNtitle, "Language Modes"); ac++;
2717 LMDialog.shell = CreateWidget(TheAppShell, "langModes",
2718 topLevelShellWidgetClass, args, ac);
2719 AddSmallIcon(LMDialog.shell);
2720 form = XtVaCreateManagedWidget("editLanguageModes", xmFormWidgetClass,
2721 LMDialog.shell, XmNautoUnmanage, False,
2722 XmNresizePolicy, XmRESIZE_NONE, NULL);
2723 XtAddCallback(form, XmNdestroyCallback, lmDestroyCB, NULL);
2724 AddMotifCloseCallback(LMDialog.shell, lmCloseCB, NULL);
2726 topLbl = XtVaCreateManagedWidget("topLabel", xmLabelGadgetClass, form,
2727 XmNlabelString, s1=MKSTRING(
2728 "To modify the properties of an existing language mode, select the name from\n\
2729 the list on the left. To add a new language, select \"New\" from the list."),
2730 XmNmnemonic, 'N',
2731 XmNtopAttachment, XmATTACH_POSITION,
2732 XmNtopPosition, 2,
2733 XmNleftAttachment, XmATTACH_POSITION,
2734 XmNleftPosition, LEFT_MARGIN_POS,
2735 XmNrightAttachment, XmATTACH_POSITION,
2736 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
2737 XmStringFree(s1);
2739 nameLbl = XtVaCreateManagedWidget("nameLbl", xmLabelGadgetClass, form,
2740 XmNlabelString, s1=XmStringCreateSimple("Name"),
2741 XmNmnemonic, 'm',
2742 XmNalignment, XmALIGNMENT_BEGINNING,
2743 XmNleftAttachment, XmATTACH_POSITION,
2744 XmNleftPosition, LIST_RIGHT,
2745 XmNtopAttachment, XmATTACH_WIDGET,
2746 XmNtopOffset, H_MARGIN,
2747 XmNtopWidget, topLbl, NULL);
2748 XmStringFree(s1);
2750 LMDialog.nameW = XtVaCreateManagedWidget("name", xmTextWidgetClass, form,
2751 XmNcolumns, 15,
2752 XmNleftAttachment, XmATTACH_POSITION,
2753 XmNleftPosition, LIST_RIGHT,
2754 XmNtopAttachment, XmATTACH_WIDGET,
2755 XmNtopWidget, nameLbl,
2756 XmNrightAttachment, XmATTACH_POSITION,
2757 XmNrightPosition, (RIGHT_MARGIN_POS + LIST_RIGHT)/2, NULL);
2758 RemapDeleteKey(LMDialog.nameW);
2759 XtVaSetValues(nameLbl, XmNuserData, LMDialog.nameW, NULL);
2761 extLbl = XtVaCreateManagedWidget("extLbl", xmLabelGadgetClass, form,
2762 XmNlabelString,
2763 s1=XmStringCreateSimple("File extensions (separate w/ space)"),
2764 XmNmnemonic, 'F',
2765 XmNalignment, XmALIGNMENT_BEGINNING,
2766 XmNleftAttachment, XmATTACH_POSITION,
2767 XmNleftPosition, LIST_RIGHT,
2768 XmNtopAttachment, XmATTACH_WIDGET,
2769 XmNtopOffset, H_MARGIN,
2770 XmNtopWidget, LMDialog.nameW, NULL);
2771 XmStringFree(s1);
2773 LMDialog.extW = XtVaCreateManagedWidget("ext", xmTextWidgetClass, form,
2774 XmNleftAttachment, XmATTACH_POSITION,
2775 XmNleftPosition, LIST_RIGHT,
2776 XmNtopAttachment, XmATTACH_WIDGET,
2777 XmNtopWidget, extLbl,
2778 XmNrightAttachment, XmATTACH_POSITION,
2779 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
2780 RemapDeleteKey(LMDialog.extW);
2781 XtVaSetValues(extLbl, XmNuserData, LMDialog.extW, NULL);
2783 recogLbl = XtVaCreateManagedWidget("recogLbl", xmLabelGadgetClass, form,
2784 XmNlabelString, s1=MKSTRING(
2785 "Recognition regular expression (applied to first 200\n\
2786 characters of file to determine type from content)"),
2787 XmNalignment, XmALIGNMENT_BEGINNING,
2788 XmNmnemonic, 'R',
2789 XmNleftAttachment, XmATTACH_POSITION,
2790 XmNleftPosition, LIST_RIGHT,
2791 XmNtopAttachment, XmATTACH_WIDGET,
2792 XmNtopOffset, H_MARGIN,
2793 XmNtopWidget, LMDialog.extW, NULL);
2794 XmStringFree(s1);
2796 LMDialog.recogW = XtVaCreateManagedWidget("recog", xmTextWidgetClass, form,
2797 XmNleftAttachment, XmATTACH_POSITION,
2798 XmNleftPosition, LIST_RIGHT,
2799 XmNtopAttachment, XmATTACH_WIDGET,
2800 XmNtopWidget, recogLbl,
2801 XmNrightAttachment, XmATTACH_POSITION,
2802 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
2803 RemapDeleteKey(LMDialog.recogW);
2804 XtVaSetValues(recogLbl, XmNuserData, LMDialog.recogW, NULL);
2806 defTipsLbl = XtVaCreateManagedWidget("defTipsLbl", xmLabelGadgetClass, form,
2807 XmNlabelString, s1=MKSTRING(
2808 "Default calltips file(s) (separate w/colons)"),
2809 XmNalignment, XmALIGNMENT_BEGINNING,
2810 XmNmnemonic, 'c',
2811 XmNleftAttachment, XmATTACH_POSITION,
2812 XmNleftPosition, LIST_RIGHT,
2813 XmNtopAttachment, XmATTACH_WIDGET,
2814 XmNtopOffset, H_MARGIN,
2815 XmNtopWidget, LMDialog.recogW, NULL);
2816 XmStringFree(s1);
2818 LMDialog.defTipsW = XtVaCreateManagedWidget("defTips", xmTextWidgetClass,
2819 form,
2820 XmNleftAttachment, XmATTACH_POSITION,
2821 XmNleftPosition, LIST_RIGHT,
2822 XmNtopAttachment, XmATTACH_WIDGET,
2823 XmNtopWidget, defTipsLbl,
2824 XmNrightAttachment, XmATTACH_POSITION,
2825 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
2826 RemapDeleteKey(LMDialog.defTipsW);
2827 XtVaSetValues(defTipsLbl, XmNuserData, LMDialog.defTipsW, NULL);
2829 okBtn = XtVaCreateManagedWidget("ok", xmPushButtonWidgetClass, form,
2830 XmNlabelString, s1=XmStringCreateSimple("OK"),
2831 XmNmarginWidth, BUTTON_WIDTH_MARGIN,
2832 XmNleftAttachment, XmATTACH_POSITION,
2833 XmNleftPosition, 10,
2834 XmNrightAttachment, XmATTACH_POSITION,
2835 XmNrightPosition, 30,
2836 XmNbottomAttachment, XmATTACH_POSITION,
2837 XmNbottomPosition, 99, NULL);
2838 XtAddCallback(okBtn, XmNactivateCallback, lmOkCB, NULL);
2839 XmStringFree(s1);
2841 applyBtn = XtVaCreateManagedWidget("apply", xmPushButtonWidgetClass, form,
2842 XmNlabelString, s1=XmStringCreateSimple("Apply"),
2843 XmNmnemonic, 'A',
2844 XmNleftAttachment, XmATTACH_POSITION,
2845 XmNleftPosition, 40,
2846 XmNrightAttachment, XmATTACH_POSITION,
2847 XmNrightPosition, 60,
2848 XmNbottomAttachment, XmATTACH_POSITION,
2849 XmNbottomPosition, 99, NULL);
2850 XtAddCallback(applyBtn, XmNactivateCallback, lmApplyCB, NULL);
2851 XmStringFree(s1);
2853 closeBtn = XtVaCreateManagedWidget("close",xmPushButtonWidgetClass,form,
2854 XmNlabelString, s1=XmStringCreateSimple("Close"),
2855 XmNleftAttachment, XmATTACH_POSITION,
2856 XmNleftPosition, 70,
2857 XmNrightAttachment, XmATTACH_POSITION,
2858 XmNrightPosition, 90,
2859 XmNbottomAttachment, XmATTACH_POSITION,
2860 XmNbottomPosition, 99, NULL);
2861 XtAddCallback(closeBtn, XmNactivateCallback, lmCloseCB, NULL);
2862 XmStringFree(s1);
2864 overrideFrame = XtVaCreateManagedWidget("overrideFrame",
2865 xmFrameWidgetClass, form,
2866 XmNleftAttachment, XmATTACH_POSITION,
2867 XmNleftPosition, LEFT_MARGIN_POS,
2868 XmNrightAttachment, XmATTACH_POSITION,
2869 XmNrightPosition, RIGHT_MARGIN_POS,
2870 XmNbottomAttachment, XmATTACH_WIDGET,
2871 XmNbottomWidget, closeBtn,
2872 XmNbottomOffset, H_MARGIN, NULL);
2873 overrideForm = XtVaCreateManagedWidget("overrideForm", xmFormWidgetClass,
2874 overrideFrame, NULL);
2875 XtVaCreateManagedWidget("overrideLbl", xmLabelGadgetClass, overrideFrame,
2876 XmNlabelString, s1=XmStringCreateSimple("Override Defaults"),
2877 XmNchildType, XmFRAME_TITLE_CHILD,
2878 XmNchildHorizontalAlignment, XmALIGNMENT_CENTER, NULL);
2879 XmStringFree(s1);
2881 delimitForm = XtVaCreateManagedWidget("delimitForm", xmFormWidgetClass,
2882 overrideForm,
2883 XmNleftAttachment, XmATTACH_POSITION,
2884 XmNleftPosition, LEFT_MARGIN_POS,
2885 XmNtopAttachment, XmATTACH_FORM,
2886 XmNtopOffset, H_MARGIN,
2887 XmNrightAttachment, XmATTACH_POSITION,
2888 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
2889 delimitLbl = XtVaCreateManagedWidget("delimitLbl", xmLabelGadgetClass,
2890 delimitForm,
2891 XmNlabelString, s1=XmStringCreateSimple("Word delimiters"),
2892 XmNmnemonic, 'W',
2893 XmNleftAttachment, XmATTACH_FORM,
2894 XmNtopAttachment, XmATTACH_FORM,
2895 XmNbottomAttachment, XmATTACH_FORM, NULL);
2896 XmStringFree(s1);
2897 LMDialog.delimitW = XtVaCreateManagedWidget("delimit", xmTextWidgetClass,
2898 delimitForm,
2899 XmNtopAttachment, XmATTACH_FORM,
2900 XmNleftAttachment, XmATTACH_WIDGET,
2901 XmNleftWidget, delimitLbl,
2902 XmNrightAttachment, XmATTACH_FORM,
2903 XmNbottomAttachment, XmATTACH_FORM, NULL);
2904 RemapDeleteKey(LMDialog.delimitW);
2905 XtVaSetValues(delimitLbl, XmNuserData, LMDialog.delimitW, NULL);
2907 tabForm = XtVaCreateManagedWidget("tabForm", xmFormWidgetClass,
2908 overrideForm,
2909 XmNleftAttachment, XmATTACH_POSITION,
2910 XmNleftPosition, LEFT_MARGIN_POS,
2911 XmNtopAttachment, XmATTACH_WIDGET,
2912 XmNtopWidget, delimitForm,
2913 XmNtopOffset, H_MARGIN,
2914 XmNrightAttachment, XmATTACH_POSITION,
2915 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
2916 tabLbl = XtVaCreateManagedWidget("tabLbl", xmLabelGadgetClass, tabForm,
2917 XmNlabelString, s1=XmStringCreateSimple(
2918 "Alternative hardware tab spacing"),
2919 XmNmnemonic, 't',
2920 XmNleftAttachment, XmATTACH_FORM,
2921 XmNtopAttachment, XmATTACH_FORM,
2922 XmNbottomAttachment, XmATTACH_FORM, NULL);
2923 XmStringFree(s1);
2924 LMDialog.tabW = XtVaCreateManagedWidget("delimit", xmTextWidgetClass,
2925 tabForm,
2926 XmNcolumns, 3,
2927 XmNtopAttachment, XmATTACH_FORM,
2928 XmNleftAttachment, XmATTACH_WIDGET,
2929 XmNleftWidget, tabLbl,
2930 XmNbottomAttachment, XmATTACH_FORM, NULL);
2931 RemapDeleteKey(LMDialog.tabW);
2932 XtVaSetValues(tabLbl, XmNuserData, LMDialog.tabW, NULL);
2933 LMDialog.emTabW = XtVaCreateManagedWidget("delimit", xmTextWidgetClass,
2934 tabForm,
2935 XmNcolumns, 3,
2936 XmNtopAttachment, XmATTACH_FORM,
2937 XmNrightAttachment, XmATTACH_FORM,
2938 XmNbottomAttachment, XmATTACH_FORM, NULL);
2939 RemapDeleteKey(LMDialog.emTabW);
2940 XtVaCreateManagedWidget("emTabLbl", xmLabelGadgetClass, tabForm,
2941 XmNlabelString,
2942 s1=XmStringCreateSimple("Alternative emulated tab spacing"),
2943 XmNalignment, XmALIGNMENT_END,
2944 XmNmnemonic, 'e',
2945 XmNuserData, LMDialog.emTabW,
2946 XmNleftAttachment, XmATTACH_WIDGET,
2947 XmNleftWidget, LMDialog.tabW,
2948 XmNrightAttachment, XmATTACH_WIDGET,
2949 XmNrightWidget, LMDialog.emTabW,
2950 XmNtopAttachment, XmATTACH_FORM,
2951 XmNbottomAttachment, XmATTACH_FORM, NULL);
2952 XmStringFree(s1);
2954 indentBox = XtVaCreateManagedWidget("indentBox", xmRowColumnWidgetClass,
2955 overrideForm,
2956 XmNorientation, XmHORIZONTAL,
2957 XmNpacking, XmPACK_TIGHT,
2958 XmNradioBehavior, True,
2959 XmNleftAttachment, XmATTACH_POSITION,
2960 XmNleftPosition, LEFT_MARGIN_POS,
2961 XmNtopAttachment, XmATTACH_WIDGET,
2962 XmNtopWidget, tabForm,
2963 XmNtopOffset, H_MARGIN, NULL);
2964 LMDialog.defaultIndentW = XtVaCreateManagedWidget("defaultIndent",
2965 xmToggleButtonWidgetClass, indentBox,
2966 XmNset, True,
2967 XmNmarginHeight, 0,
2968 XmNlabelString, s1=XmStringCreateSimple("Default indent style"),
2969 XmNmnemonic, 'D', NULL);
2970 XmStringFree(s1);
2971 LMDialog.noIndentW = XtVaCreateManagedWidget("noIndent",
2972 xmToggleButtonWidgetClass, indentBox,
2973 XmNmarginHeight, 0,
2974 XmNlabelString, s1=XmStringCreateSimple("No automatic indent"),
2975 XmNmnemonic, 'N', NULL);
2976 XmStringFree(s1);
2977 LMDialog.autoIndentW = XtVaCreateManagedWidget("autoIndent",
2978 xmToggleButtonWidgetClass, indentBox,
2979 XmNmarginHeight, 0,
2980 XmNlabelString, s1=XmStringCreateSimple("Auto-indent"),
2981 XmNmnemonic, 'A', NULL);
2982 XmStringFree(s1);
2983 LMDialog.smartIndentW = XtVaCreateManagedWidget("smartIndent",
2984 xmToggleButtonWidgetClass, indentBox,
2985 XmNmarginHeight, 0,
2986 XmNlabelString, s1=XmStringCreateSimple("Smart-indent"),
2987 XmNmnemonic, 'S', NULL);
2988 XmStringFree(s1);
2990 wrapBox = XtVaCreateManagedWidget("wrapBox", xmRowColumnWidgetClass,
2991 overrideForm,
2992 XmNorientation, XmHORIZONTAL,
2993 XmNpacking, XmPACK_TIGHT,
2994 XmNradioBehavior, True,
2995 XmNleftAttachment, XmATTACH_POSITION,
2996 XmNleftPosition, LEFT_MARGIN_POS,
2997 XmNtopAttachment, XmATTACH_WIDGET,
2998 XmNtopWidget, indentBox,
2999 XmNtopOffset, H_MARGIN,
3000 XmNbottomAttachment, XmATTACH_FORM,
3001 XmNbottomOffset, H_MARGIN, NULL);
3002 LMDialog.defaultWrapW = XtVaCreateManagedWidget("defaultWrap",
3003 xmToggleButtonWidgetClass, wrapBox,
3004 XmNset, True,
3005 XmNmarginHeight, 0,
3006 XmNlabelString, s1=XmStringCreateSimple("Default wrap style"),
3007 XmNmnemonic, 'D', NULL);
3008 XmStringFree(s1);
3009 LMDialog.noWrapW = XtVaCreateManagedWidget("noWrap",
3010 xmToggleButtonWidgetClass, wrapBox,
3011 XmNmarginHeight, 0,
3012 XmNlabelString, s1=XmStringCreateSimple("No wrapping"),
3013 XmNmnemonic, 'N', NULL);
3014 XmStringFree(s1);
3015 LMDialog.newlineWrapW = XtVaCreateManagedWidget("newlineWrap",
3016 xmToggleButtonWidgetClass, wrapBox,
3017 XmNmarginHeight, 0,
3018 XmNlabelString, s1=XmStringCreateSimple("Auto newline wrap"),
3019 XmNmnemonic, 'A', NULL);
3020 XmStringFree(s1);
3021 LMDialog.contWrapW = XtVaCreateManagedWidget("contWrap",
3022 xmToggleButtonWidgetClass, wrapBox,
3023 XmNmarginHeight, 0,
3024 XmNlabelString, s1=XmStringCreateSimple("Continuous wrap"),
3025 XmNmnemonic, 'C', NULL);
3026 XmStringFree(s1);
3028 XtVaCreateManagedWidget("stretchForm", xmFormWidgetClass, form,
3029 XmNtopAttachment, XmATTACH_WIDGET,
3030 XmNtopWidget, LMDialog.defTipsW,
3031 XmNleftAttachment, XmATTACH_POSITION,
3032 XmNleftPosition, LIST_RIGHT,
3033 XmNrightAttachment, XmATTACH_POSITION,
3034 XmNrightPosition, RIGHT_MARGIN_POS,
3035 XmNbottomAttachment, XmATTACH_WIDGET,
3036 XmNbottomWidget, overrideFrame,
3037 XmNbottomOffset, H_MARGIN*2, NULL);
3039 ac = 0;
3040 XtSetArg(args[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
3041 XtSetArg(args[ac], XmNtopOffset, H_MARGIN); ac++;
3042 XtSetArg(args[ac], XmNtopWidget, topLbl); ac++;
3043 XtSetArg(args[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
3044 XtSetArg(args[ac], XmNleftPosition, LEFT_MARGIN_POS); ac++;
3045 XtSetArg(args[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
3046 XtSetArg(args[ac], XmNrightPosition, LIST_RIGHT-1); ac++;
3047 XtSetArg(args[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
3048 XtSetArg(args[ac], XmNbottomWidget, overrideFrame); ac++;
3049 XtSetArg(args[ac], XmNbottomOffset, H_MARGIN*2); ac++;
3050 LMDialog.managedListW = CreateManagedList(form, "list", args, ac,
3051 (void **)LMDialog.languageModeList, &LMDialog.nLanguageModes,
3052 MAX_LANGUAGE_MODES, 15, lmGetDisplayedCB, NULL, lmSetDisplayedCB,
3053 NULL, lmFreeItemCB);
3054 AddDeleteConfirmCB(LMDialog.managedListW, lmDeleteConfirmCB, NULL);
3055 XtVaSetValues(topLbl, XmNuserData, LMDialog.managedListW, NULL);
3057 /* Set initial default button */
3058 XtVaSetValues(form, XmNdefaultButton, okBtn, NULL);
3059 XtVaSetValues(form, XmNcancelButton, closeBtn, NULL);
3061 /* Handle mnemonic selection of buttons and focus to dialog */
3062 AddDialogMnemonicHandler(form, FALSE);
3064 /* Realize all of the widgets in the new dialog */
3065 RealizeWithoutForcingPosition(LMDialog.shell);
3068 static void lmDestroyCB(Widget w, XtPointer clientData, XtPointer callData)
3070 int i;
3072 for (i=0; i<LMDialog.nLanguageModes; i++)
3073 freeLanguageModeRec(LMDialog.languageModeList[i]);
3074 XtFree((char *)LMDialog.languageModeList);
3077 static void lmOkCB(Widget w, XtPointer clientData, XtPointer callData)
3079 if (!updateLMList())
3080 return;
3082 /* pop down and destroy the dialog */
3083 XtDestroyWidget(LMDialog.shell);
3084 LMDialog.shell = NULL;
3087 static void lmApplyCB(Widget w, XtPointer clientData, XtPointer callData)
3089 updateLMList();
3092 static void lmCloseCB(Widget w, XtPointer clientData, XtPointer callData)
3094 /* pop down and destroy the dialog */
3095 XtDestroyWidget(LMDialog.shell);
3096 LMDialog.shell = NULL;
3099 static int lmDeleteConfirmCB(int itemIndex, void *cbArg)
3101 int i;
3103 /* Allow duplicate names to be deleted regardless of dependencies */
3104 for (i=0; i<LMDialog.nLanguageModes; i++)
3105 if (i != itemIndex && !strcmp(LMDialog.languageModeList[i]->name,
3106 LMDialog.languageModeList[itemIndex]->name))
3107 return True;
3109 /* don't allow deletion if data will be lost */
3110 if (LMHasHighlightPatterns(LMDialog.languageModeList[itemIndex]->name))
3112 DialogF(DF_WARN, LMDialog.shell, 1, "Patterns exist",
3113 "This language mode has syntax highlighting\n"
3114 "patterns defined. Please delete the patterns\n"
3115 "first, in Preferences -> Default Settings ->\n"
3116 "Syntax Highlighting, before proceeding here.", "OK");
3117 return False;
3120 /* don't allow deletion if data will be lost */
3121 if (LMHasSmartIndentMacros(LMDialog.languageModeList[itemIndex]->name))
3123 DialogF(DF_WARN, LMDialog.shell, 1, "Smart Indent Macros exist",
3124 "This language mode has smart indent macros\n"
3125 "defined. Please delete the macros first,\n"
3126 "in Preferences -> Default Settings ->\n"
3127 "Auto Indent -> Program Smart Indent,\n"
3128 "before proceeding here.", "OK");
3129 return False;
3132 return True;
3136 ** Apply the changes that the user has made in the language modes dialog to the
3137 ** stored language mode information for this NEdit session (the data array
3138 ** LanguageModes)
3140 static int updateLMList(void)
3142 WindowInfo *window;
3143 char *oldModeName, *newDelimiters;
3144 int i, j;
3146 /* Get the current contents of the dialog fields */
3147 if (!UpdateManagedList(LMDialog.managedListW, True))
3148 return False;
3150 /* Fix up language mode indices in all open windows (which may change
3151 if the currently selected mode is deleted or has changed position),
3152 and update word delimiters */
3153 for (window=WindowList; window!=NULL; window=window->next) {
3154 if (window->languageMode != PLAIN_LANGUAGE_MODE) {
3155 oldModeName = LanguageModes[window->languageMode]->name;
3156 window->languageMode = PLAIN_LANGUAGE_MODE;
3157 for (i=0; i<LMDialog.nLanguageModes; i++) {
3158 if (!strcmp(oldModeName, LMDialog.languageModeList[i]->name)) {
3159 newDelimiters = LMDialog.languageModeList[i]->delimiters;
3160 if (newDelimiters == NULL)
3161 newDelimiters = GetPrefDelimiters();
3162 XtVaSetValues(window->textArea, textNwordDelimiters,
3163 newDelimiters, NULL);
3164 for (j=0; j<window->nPanes; j++)
3165 XtVaSetValues(window->textPanes[j],
3166 textNwordDelimiters, newDelimiters, NULL);
3167 window->languageMode = i;
3168 break;
3174 /* If there were any name changes, re-name dependent highlight patterns
3175 and smart-indent macros and fix up the weird rename-format names */
3176 for (i=0; i<LMDialog.nLanguageModes; i++) {
3177 if (strchr(LMDialog.languageModeList[i]->name, ':') != NULL) {
3178 char *newName = strrchr(LMDialog.languageModeList[i]->name, ':')+1;
3179 *strchr(LMDialog.languageModeList[i]->name, ':') = '\0';
3180 RenameHighlightPattern(LMDialog.languageModeList[i]->name, newName);
3181 RenameSmartIndentMacros(LMDialog.languageModeList[i]->name, newName);
3182 memmove(LMDialog.languageModeList[i]->name, newName,
3183 strlen(newName) + 1);
3184 ChangeManagedListData(LMDialog.managedListW);
3188 /* Unload any default calltips file that is no longer a default. */
3189 for (i=0; i<NLanguageModes; i++) {
3190 if (!LanguageModes[i]->defTipsFile)
3191 continue;
3192 for (j=0; j<LMDialog.nLanguageModes; j++) {
3193 if (!LMDialog.languageModeList[j]->defTipsFile)
3194 continue;
3195 if (!strcmp(LanguageModes[i]->defTipsFile,
3196 LMDialog.languageModeList[j]->defTipsFile))
3197 break;
3199 if ( j==LMDialog.nLanguageModes )
3200 DeleteTagsFile(LanguageModes[i]->defTipsFile, TIP);
3203 /* Replace the old language mode list with the new one from the dialog */
3204 for (i=0; i<NLanguageModes; i++)
3205 freeLanguageModeRec(LanguageModes[i]);
3206 for (i=0; i<LMDialog.nLanguageModes; i++)
3207 LanguageModes[i] = copyLanguageModeRec(LMDialog.languageModeList[i]);
3208 NLanguageModes = LMDialog.nLanguageModes;
3210 /* Update the menus in the window menu bars and load any needed
3211 calltips files */
3212 for (window=WindowList; window!=NULL; window=window->next) {
3213 updateLanguageModeSubmenu(window);
3214 if (window->languageMode != PLAIN_LANGUAGE_MODE &&
3215 LanguageModes[window->languageMode]->defTipsFile != NULL)
3216 AddTagsFile(LanguageModes[window->languageMode]->defTipsFile, TIP);
3217 /* cache user menus: Rebuild all user menus of this window */
3218 RebuildAllMenus(window);
3221 /* If a syntax highlighting dialog is up, update its menu */
3222 UpdateLanguageModeMenu();
3223 /* The same for the smart indent macro dialog */
3224 UpdateLangModeMenuSmartIndent();
3225 /* Note that preferences have been changed */
3226 MarkPrefsChanged();
3228 return True;
3231 static void *lmGetDisplayedCB(void *oldItem, int explicitRequest, int *abort,
3232 void *cbArg)
3234 languageModeRec *lm, *oldLM = (languageModeRec *)oldItem;
3235 char *tempName;
3236 int i, nCopies, oldLen;
3238 /* If the dialog is currently displaying the "new" entry and the
3239 fields are empty, that's just fine */
3240 if (oldItem == NULL && lmDialogEmpty())
3241 return NULL;
3243 /* Read the data the user has entered in the dialog fields */
3244 lm = readLMDialogFields(True);
3246 /* If there was a name change of a non-duplicate language mode, modify the
3247 name to the weird format of: ":old name:new name". This signals that a
3248 name change is necessary in lm dependent data such as highlight
3249 patterns. Duplicate language modes may be re-named at will, since no
3250 data will be lost due to the name change. */
3251 if (lm != NULL && oldLM != NULL && strcmp(oldLM->name, lm->name)) {
3252 nCopies = 0;
3253 for (i=0; i<LMDialog.nLanguageModes; i++)
3254 if (!strcmp(oldLM->name, LMDialog.languageModeList[i]->name))
3255 nCopies++;
3256 if (nCopies <= 1) {
3257 oldLen = strchr(oldLM->name, ':') == NULL ? strlen(oldLM->name) :
3258 strchr(oldLM->name, ':') - oldLM->name;
3259 tempName = XtMalloc(oldLen + strlen(lm->name) + 2);
3260 strncpy(tempName, oldLM->name, oldLen);
3261 sprintf(&tempName[oldLen], ":%s", lm->name);
3262 XtFree(lm->name);
3263 lm->name = tempName;
3267 /* If there are no problems reading the data, just return it */
3268 if (lm != NULL)
3269 return (void *)lm;
3271 /* If there are problems, and the user didn't ask for the fields to be
3272 read, give more warning */
3273 if (!explicitRequest)
3275 if (DialogF(DF_WARN, LMDialog.shell, 2, "Discard Language Mode",
3276 "Discard incomplete entry\nfor current language mode?", "Keep",
3277 "Discard") == 2)
3279 return oldItem == NULL
3280 ? NULL
3281 : (void *)copyLanguageModeRec((languageModeRec *)oldItem);
3285 /* Do readLMDialogFields again without "silent" mode to display warning */
3286 lm = readLMDialogFields(False);
3287 *abort = True;
3288 return NULL;
3291 static void lmSetDisplayedCB(void *item, void *cbArg)
3293 languageModeRec *lm = (languageModeRec *)item;
3294 char *extStr;
3296 if (item == NULL) {
3297 XmTextSetString(LMDialog.nameW, "");
3298 XmTextSetString(LMDialog.extW, "");
3299 XmTextSetString(LMDialog.recogW, "");
3300 XmTextSetString(LMDialog.defTipsW, "");
3301 XmTextSetString(LMDialog.delimitW, "");
3302 XmTextSetString(LMDialog.tabW, "");
3303 XmTextSetString(LMDialog.emTabW, "");
3304 RadioButtonChangeState(LMDialog.defaultIndentW, True, True);
3305 RadioButtonChangeState(LMDialog.defaultWrapW, True, True);
3306 } else {
3307 XmTextSetString(LMDialog.nameW, strchr(lm->name, ':') == NULL ?
3308 lm->name : strchr(lm->name, ':')+1);
3309 extStr = createExtString(lm->extensions, lm->nExtensions);
3310 XmTextSetString(LMDialog.extW, extStr);
3311 XtFree(extStr);
3312 XmTextSetString(LMDialog.recogW, lm->recognitionExpr);
3313 XmTextSetString(LMDialog.defTipsW, lm->defTipsFile);
3314 XmTextSetString(LMDialog.delimitW, lm->delimiters);
3315 if (lm->tabDist == DEFAULT_TAB_DIST)
3316 XmTextSetString(LMDialog.tabW, "");
3317 else
3318 SetIntText(LMDialog.tabW, lm->tabDist);
3319 if (lm->emTabDist == DEFAULT_EM_TAB_DIST)
3320 XmTextSetString(LMDialog.emTabW, "");
3321 else
3322 SetIntText(LMDialog.emTabW, lm->emTabDist);
3323 RadioButtonChangeState(LMDialog.defaultIndentW,
3324 lm->indentStyle == DEFAULT_INDENT, False);
3325 RadioButtonChangeState(LMDialog.noIndentW,
3326 lm->indentStyle == NO_AUTO_INDENT, False);
3327 RadioButtonChangeState(LMDialog.autoIndentW,
3328 lm->indentStyle == AUTO_INDENT, False);
3329 RadioButtonChangeState(LMDialog.smartIndentW,
3330 lm->indentStyle == SMART_INDENT, False);
3331 RadioButtonChangeState(LMDialog.defaultWrapW,
3332 lm->wrapStyle == DEFAULT_WRAP, False);
3333 RadioButtonChangeState(LMDialog.noWrapW,
3334 lm->wrapStyle == NO_WRAP, False);
3335 RadioButtonChangeState(LMDialog.newlineWrapW,
3336 lm->wrapStyle == NEWLINE_WRAP, False);
3337 RadioButtonChangeState(LMDialog.contWrapW,
3338 lm->wrapStyle == CONTINUOUS_WRAP, False);
3342 static void lmFreeItemCB(void *item)
3344 freeLanguageModeRec((languageModeRec *)item);
3347 static void freeLanguageModeRec(languageModeRec *lm)
3349 int i;
3351 XtFree(lm->name);
3352 if (lm->recognitionExpr != NULL)
3353 XtFree(lm->recognitionExpr);
3354 if (lm->defTipsFile != NULL)
3355 XtFree(lm->defTipsFile);
3356 if (lm->delimiters != NULL)
3357 XtFree(lm->delimiters);
3358 for (i=0; i<lm->nExtensions; i++)
3359 XtFree(lm->extensions[i]);
3360 if (lm->nExtensions != 0)
3361 XtFree((char *)lm->extensions);
3362 XtFree((char *)lm);
3366 ** Copy a languageModeRec data structure and all of the allocated data it contains
3368 static languageModeRec *copyLanguageModeRec(languageModeRec *lm)
3370 languageModeRec *newLM;
3371 int i;
3373 newLM = (languageModeRec *)XtMalloc(sizeof(languageModeRec));
3374 newLM->name = XtMalloc(strlen(lm->name)+1);
3375 strcpy(newLM->name, lm->name);
3376 newLM->nExtensions = lm->nExtensions;
3377 newLM->extensions = (char **)XtMalloc(sizeof(char *) * lm->nExtensions);
3378 for (i=0; i<lm->nExtensions; i++) {
3379 newLM->extensions[i] = XtMalloc(strlen(lm->extensions[i]) + 1);
3380 strcpy(newLM->extensions[i], lm->extensions[i]);
3382 if (lm->recognitionExpr == NULL)
3383 newLM->recognitionExpr = NULL;
3384 else {
3385 newLM->recognitionExpr = XtMalloc(strlen(lm->recognitionExpr)+1);
3386 strcpy(newLM->recognitionExpr, lm->recognitionExpr);
3388 if (lm->defTipsFile == NULL)
3389 newLM->defTipsFile = NULL;
3390 else {
3391 newLM->defTipsFile = XtMalloc(strlen(lm->defTipsFile)+1);
3392 strcpy(newLM->defTipsFile, lm->defTipsFile);
3394 if (lm->delimiters == NULL)
3395 newLM->delimiters = NULL;
3396 else {
3397 newLM->delimiters = XtMalloc(strlen(lm->delimiters)+1);
3398 strcpy(newLM->delimiters, lm->delimiters);
3400 newLM->wrapStyle = lm->wrapStyle;
3401 newLM->indentStyle = lm->indentStyle;
3402 newLM->tabDist = lm->tabDist;
3403 newLM->emTabDist = lm->emTabDist;
3404 return newLM;
3408 ** Read the fields in the language modes dialog and create a languageModeRec data
3409 ** structure reflecting the current state of the selected language mode in the dialog.
3410 ** If any of the information is incorrect or missing, display a warning dialog and
3411 ** return NULL. Passing "silent" as True, suppresses the warning dialogs.
3413 static languageModeRec *readLMDialogFields(int silent)
3415 languageModeRec *lm;
3416 regexp *compiledRE;
3417 char *compileMsg, *extStr, *extPtr;
3419 /* Allocate a language mode structure to return, set unread fields to
3420 empty so everything can be freed on errors by freeLanguageModeRec */
3421 lm = (languageModeRec *)XtMalloc(sizeof(languageModeRec));
3422 lm->nExtensions = 0;
3423 lm->recognitionExpr = NULL;
3424 lm->defTipsFile = NULL;
3425 lm->delimiters = NULL;
3427 /* read the name field */
3428 lm->name = ReadSymbolicFieldTextWidget(LMDialog.nameW,
3429 "language mode name", silent);
3430 if (lm->name == NULL) {
3431 XtFree((char *)lm);
3432 return NULL;
3435 if (*lm->name == '\0')
3437 if (!silent)
3439 DialogF(DF_WARN, LMDialog.shell, 1, "Language Mode Name",
3440 "Please specify a name\nfor the language mode", "OK");
3441 XmProcessTraversal(LMDialog.nameW, XmTRAVERSE_CURRENT);
3443 freeLanguageModeRec(lm);
3444 return NULL;
3447 /* read the extension list field */
3448 extStr = extPtr = XmTextGetString(LMDialog.extW);
3449 lm->extensions = readExtensionList(&extPtr, &lm->nExtensions);
3450 XtFree(extStr);
3452 /* read recognition expression */
3453 lm->recognitionExpr = XmTextGetString(LMDialog.recogW);
3454 if (*lm->recognitionExpr == '\0') {
3455 XtFree(lm->recognitionExpr);
3456 lm->recognitionExpr = NULL;
3457 } else
3459 compiledRE = CompileRE(lm->recognitionExpr, &compileMsg, REDFLT_STANDARD);
3461 if (compiledRE == NULL)
3463 if (!silent)
3465 DialogF(DF_WARN, LMDialog.shell, 1, "Regex",
3466 "Recognition expression:\n%s", "OK", compileMsg);
3467 XmProcessTraversal(LMDialog.recogW, XmTRAVERSE_CURRENT);
3469 XtFree((char *)compiledRE);
3470 freeLanguageModeRec(lm);
3471 return NULL;
3474 XtFree((char *)compiledRE);
3477 /* Read the default calltips file for the language mode */
3478 lm->defTipsFile = XmTextGetString(LMDialog.defTipsW);
3479 if (*lm->defTipsFile == '\0') {
3480 /* Empty string */
3481 XtFree(lm->defTipsFile);
3482 lm->defTipsFile = NULL;
3483 } else {
3484 /* Ensure that AddTagsFile will work */
3485 if (AddTagsFile(lm->defTipsFile, TIP) == FALSE) {
3486 if (!silent)
3488 DialogF(DF_WARN, LMDialog.shell, 1, "Error reading Calltips",
3489 "Can't read default calltips file(s):\n \"%s\"\n",
3490 "OK", lm->defTipsFile);
3491 XmProcessTraversal(LMDialog.recogW, XmTRAVERSE_CURRENT);
3493 freeLanguageModeRec(lm);
3494 return NULL;
3495 } else
3496 if (DeleteTagsFile(lm->defTipsFile, TIP) == FALSE)
3497 fprintf(stderr, "nedit: Internal error: Trouble deleting "
3498 "calltips file(s):\n \"%s\"\n", lm->defTipsFile);
3501 /* read tab spacing field */
3502 if (TextWidgetIsBlank(LMDialog.tabW))
3503 lm->tabDist = DEFAULT_TAB_DIST;
3504 else {
3505 if (GetIntTextWarn(LMDialog.tabW, &lm->tabDist, "tab spacing", False)
3506 != TEXT_READ_OK) {
3507 freeLanguageModeRec(lm);
3508 return NULL;
3511 if (lm->tabDist <= 0 || lm->tabDist > 100)
3513 if (!silent)
3515 DialogF(DF_WARN, LMDialog.shell, 1, "Invalid Tab Spacing",
3516 "Invalid tab spacing: %d", "OK", lm->tabDist);
3517 XmProcessTraversal(LMDialog.tabW, XmTRAVERSE_CURRENT);
3519 freeLanguageModeRec(lm);
3520 return NULL;
3524 /* read emulated tab field */
3525 if (TextWidgetIsBlank(LMDialog.emTabW))
3527 lm->emTabDist = DEFAULT_EM_TAB_DIST;
3528 } else
3530 if (GetIntTextWarn(LMDialog.emTabW, &lm->emTabDist,
3531 "emulated tab spacing", False) != TEXT_READ_OK)
3533 freeLanguageModeRec(lm);
3534 return NULL;
3537 if (lm->emTabDist < 0 || lm->emTabDist > 100)
3539 if (!silent)
3541 DialogF(DF_WARN, LMDialog.shell, 1, "Invalid Tab Spacing",
3542 "Invalid emulated tab spacing: %d", "OK",
3543 lm->emTabDist);
3544 XmProcessTraversal(LMDialog.emTabW, XmTRAVERSE_CURRENT);
3546 freeLanguageModeRec(lm);
3547 return NULL;
3551 /* read delimiters string */
3552 lm->delimiters = XmTextGetString(LMDialog.delimitW);
3553 if (*lm->delimiters == '\0') {
3554 XtFree(lm->delimiters);
3555 lm->delimiters = NULL;
3558 /* read indent style */
3559 if (XmToggleButtonGetState(LMDialog.noIndentW))
3560 lm->indentStyle = NO_AUTO_INDENT;
3561 else if (XmToggleButtonGetState(LMDialog.autoIndentW))
3562 lm->indentStyle = AUTO_INDENT;
3563 else if (XmToggleButtonGetState(LMDialog.smartIndentW))
3564 lm->indentStyle = SMART_INDENT;
3565 else
3566 lm->indentStyle = DEFAULT_INDENT;
3568 /* read wrap style */
3569 if (XmToggleButtonGetState(LMDialog.noWrapW))
3570 lm->wrapStyle = NO_WRAP;
3571 else if (XmToggleButtonGetState(LMDialog.newlineWrapW))
3572 lm->wrapStyle = NEWLINE_WRAP;
3573 else if (XmToggleButtonGetState(LMDialog.contWrapW))
3574 lm->wrapStyle = CONTINUOUS_WRAP;
3575 else
3576 lm->wrapStyle = DEFAULT_WRAP;
3578 return lm;
3582 ** Return True if the language mode dialog fields are blank (unchanged from the "New"
3583 ** language mode state).
3585 static int lmDialogEmpty(void)
3587 return TextWidgetIsBlank(LMDialog.nameW) &&
3588 TextWidgetIsBlank(LMDialog.extW) &&
3589 TextWidgetIsBlank(LMDialog.recogW) &&
3590 TextWidgetIsBlank(LMDialog.delimitW) &&
3591 TextWidgetIsBlank(LMDialog.tabW) &&
3592 TextWidgetIsBlank(LMDialog.emTabW) &&
3593 XmToggleButtonGetState(LMDialog.defaultIndentW) &&
3594 XmToggleButtonGetState(LMDialog.defaultWrapW);
3598 ** Present a dialog for changing fonts (primary, and for highlighting).
3600 void ChooseFonts(WindowInfo *window, int forWindow)
3602 #define MARGIN_SPACING 10
3603 #define BTN_TEXT_OFFSET 3
3604 Widget form, primaryLbl, primaryBtn, italicLbl, italicBtn;
3605 Widget boldLbl, boldBtn, boldItalicLbl, boldItalicBtn;
3606 Widget primaryFrame, primaryForm, highlightFrame, highlightForm;
3607 Widget okBtn, applyBtn, cancelBtn;
3608 fontDialog *fd;
3609 XmString s1;
3610 int ac;
3611 Arg args[20];
3613 /* if the dialog is already displayed, just pop it to the top and return */
3614 if (window->fontDialog != NULL) {
3615 RaiseShellWindow(((fontDialog *)window->fontDialog)->shell);
3616 return;
3619 /* Create a structure for keeping track of dialog state */
3620 fd = (fontDialog *)XtMalloc(sizeof(fontDialog));
3621 fd->window = window;
3622 fd->forWindow = forWindow;
3623 window->fontDialog = (void*)fd;
3625 /* Create a form widget in a dialog shell */
3626 ac = 0;
3627 XtSetArg(args[ac], XmNautoUnmanage, False); ac++;
3628 XtSetArg(args[ac], XmNresizePolicy, XmRESIZE_NONE); ac++;
3629 form = CreateFormDialog(window->shell, "choose Fonts", args, ac);
3630 XtVaSetValues(form, XmNshadowThickness, 0, NULL);
3631 fd->shell = XtParent(form);
3632 XtVaSetValues(fd->shell, XmNtitle, "Text Fonts", NULL);
3633 AddMotifCloseCallback(XtParent(form), fontCancelCB, fd);
3634 XtAddCallback(form, XmNdestroyCallback, fontDestroyCB, fd);
3636 primaryFrame = XtVaCreateManagedWidget("primaryFrame", xmFrameWidgetClass,
3637 form, XmNmarginHeight, 3,
3638 XmNtopAttachment, XmATTACH_POSITION,
3639 XmNtopPosition, 2,
3640 XmNleftAttachment, XmATTACH_POSITION,
3641 XmNleftPosition, 1,
3642 XmNrightAttachment, XmATTACH_POSITION,
3643 XmNrightPosition, 99, NULL);
3644 primaryForm = XtVaCreateManagedWidget("primaryForm", xmFormWidgetClass,
3645 primaryFrame, NULL);
3646 primaryLbl = XtVaCreateManagedWidget("primaryFont", xmLabelGadgetClass,
3647 primaryFrame,
3648 XmNlabelString, s1=XmStringCreateSimple("Primary Font"),
3649 XmNmnemonic, 'P',
3650 XmNchildType, XmFRAME_TITLE_CHILD,
3651 XmNchildHorizontalAlignment, XmALIGNMENT_CENTER, NULL);
3652 XmStringFree(s1);
3654 primaryBtn = XtVaCreateManagedWidget("primaryBtn",
3655 xmPushButtonWidgetClass, primaryForm,
3656 XmNlabelString, s1=XmStringCreateSimple("Browse..."),
3657 XmNmnemonic, 'r',
3658 XmNtopAttachment, XmATTACH_POSITION,
3659 XmNtopPosition, 2,
3660 XmNtopOffset, BTN_TEXT_OFFSET,
3661 XmNleftAttachment, XmATTACH_POSITION,
3662 XmNleftPosition, 1, NULL);
3663 XmStringFree(s1);
3664 XtAddCallback(primaryBtn, XmNactivateCallback, primaryBrowseCB, fd);
3666 fd->primaryW = XtVaCreateManagedWidget("primary", xmTextWidgetClass,
3667 primaryForm,
3668 XmNcolumns, 70,
3669 XmNmaxLength, MAX_FONT_LEN,
3670 XmNleftAttachment, XmATTACH_WIDGET,
3671 XmNleftWidget, primaryBtn,
3672 XmNtopAttachment, XmATTACH_POSITION,
3673 XmNtopPosition, 2,
3674 XmNrightAttachment, XmATTACH_POSITION,
3675 XmNrightPosition, 99, NULL);
3676 RemapDeleteKey(fd->primaryW);
3677 XtAddCallback(fd->primaryW, XmNvalueChangedCallback,
3678 primaryModifiedCB, fd);
3679 XtVaSetValues(primaryLbl, XmNuserData, fd->primaryW, NULL);
3681 highlightFrame = XtVaCreateManagedWidget("highlightFrame",
3682 xmFrameWidgetClass, form,
3683 XmNmarginHeight, 3,
3684 XmNnavigationType, XmTAB_GROUP,
3685 XmNtopAttachment, XmATTACH_WIDGET,
3686 XmNtopWidget, primaryFrame,
3687 XmNtopOffset, 20,
3688 XmNleftAttachment, XmATTACH_POSITION,
3689 XmNleftPosition, 1,
3690 XmNrightAttachment, XmATTACH_POSITION,
3691 XmNrightPosition, 99, NULL);
3692 highlightForm = XtVaCreateManagedWidget("highlightForm", xmFormWidgetClass,
3693 highlightFrame, NULL);
3694 XtVaCreateManagedWidget("highlightFonts", xmLabelGadgetClass,
3695 highlightFrame,
3696 XmNlabelString,
3697 s1=XmStringCreateSimple("Fonts for Syntax Highlighting"),
3698 XmNchildType, XmFRAME_TITLE_CHILD,
3699 XmNchildHorizontalAlignment, XmALIGNMENT_CENTER, NULL);
3700 XmStringFree(s1);
3702 fd->fillW = XtVaCreateManagedWidget("fillBtn",
3703 xmPushButtonWidgetClass, highlightForm,
3704 XmNlabelString,
3705 s1=XmStringCreateSimple("Fill Highlight Fonts from Primary"),
3706 XmNmnemonic, 'F',
3707 XmNtopAttachment, XmATTACH_POSITION,
3708 XmNtopPosition, 2,
3709 XmNtopOffset, BTN_TEXT_OFFSET,
3710 XmNleftAttachment, XmATTACH_POSITION,
3711 XmNleftPosition, 1, NULL);
3712 XmStringFree(s1);
3713 XtAddCallback(fd->fillW, XmNactivateCallback, fillFromPrimaryCB, fd);
3715 italicLbl = XtVaCreateManagedWidget("italicLbl", xmLabelGadgetClass,
3716 highlightForm,
3717 XmNlabelString, s1=XmStringCreateSimple("Italic Font"),
3718 XmNmnemonic, 'I',
3719 XmNalignment, XmALIGNMENT_BEGINNING,
3720 XmNtopAttachment, XmATTACH_WIDGET,
3721 XmNtopWidget, fd->fillW,
3722 XmNtopOffset, MARGIN_SPACING,
3723 XmNleftAttachment, XmATTACH_POSITION,
3724 XmNleftPosition, 1, NULL);
3725 XmStringFree(s1);
3727 fd->italicErrW = XtVaCreateManagedWidget("italicErrLbl",
3728 xmLabelGadgetClass, highlightForm,
3729 XmNlabelString, s1=XmStringCreateSimple(
3730 "(vvv spacing is inconsistent with primary font vvv)"),
3731 XmNalignment, XmALIGNMENT_END,
3732 XmNtopAttachment, XmATTACH_WIDGET,
3733 XmNtopWidget, fd->fillW,
3734 XmNtopOffset, MARGIN_SPACING,
3735 XmNleftAttachment, XmATTACH_WIDGET,
3736 XmNleftWidget, italicLbl,
3737 XmNrightAttachment, XmATTACH_POSITION,
3738 XmNrightPosition, 99, NULL);
3739 XmStringFree(s1);
3741 italicBtn = XtVaCreateManagedWidget("italicBtn",
3742 xmPushButtonWidgetClass, highlightForm,
3743 XmNlabelString, s1=XmStringCreateSimple("Browse..."),
3744 XmNmnemonic, 'o',
3745 XmNtopAttachment, XmATTACH_WIDGET,
3746 XmNtopWidget, italicLbl,
3747 XmNtopOffset, BTN_TEXT_OFFSET,
3748 XmNleftAttachment, XmATTACH_POSITION,
3749 XmNleftPosition, 1, NULL);
3750 XmStringFree(s1);
3751 XtAddCallback(italicBtn, XmNactivateCallback, italicBrowseCB, fd);
3753 fd->italicW = XtVaCreateManagedWidget("italic", xmTextWidgetClass,
3754 highlightForm,
3755 XmNmaxLength, MAX_FONT_LEN,
3756 XmNleftAttachment, XmATTACH_WIDGET,
3757 XmNleftWidget, italicBtn,
3758 XmNtopAttachment, XmATTACH_WIDGET,
3759 XmNtopWidget, italicLbl,
3760 XmNrightAttachment, XmATTACH_POSITION,
3761 XmNrightPosition, 99, NULL);
3762 RemapDeleteKey(fd->italicW);
3763 XtAddCallback(fd->italicW, XmNvalueChangedCallback,
3764 italicModifiedCB, fd);
3765 XtVaSetValues(italicLbl, XmNuserData, fd->italicW, NULL);
3767 boldLbl = XtVaCreateManagedWidget("boldLbl", xmLabelGadgetClass,
3768 highlightForm,
3769 XmNlabelString, s1=XmStringCreateSimple("Bold Font"),
3770 XmNmnemonic, 'B',
3771 XmNalignment, XmALIGNMENT_BEGINNING,
3772 XmNtopAttachment, XmATTACH_WIDGET,
3773 XmNtopWidget, italicBtn,
3774 XmNtopOffset, MARGIN_SPACING,
3775 XmNleftAttachment, XmATTACH_POSITION,
3776 XmNleftPosition, 1, NULL);
3777 XmStringFree(s1);
3779 fd->boldErrW = XtVaCreateManagedWidget("boldErrLbl",
3780 xmLabelGadgetClass, highlightForm,
3781 XmNlabelString, s1=XmStringCreateSimple(""),
3782 XmNalignment, XmALIGNMENT_END,
3783 XmNtopAttachment, XmATTACH_WIDGET,
3784 XmNtopWidget, italicBtn,
3785 XmNtopOffset, MARGIN_SPACING,
3786 XmNleftAttachment, XmATTACH_WIDGET,
3787 XmNleftWidget, boldLbl,
3788 XmNrightAttachment, XmATTACH_POSITION,
3789 XmNrightPosition, 99, NULL);
3790 XmStringFree(s1);
3792 boldBtn = XtVaCreateManagedWidget("boldBtn",
3793 xmPushButtonWidgetClass, highlightForm,
3794 XmNlabelString, s1=XmStringCreateSimple("Browse..."),
3795 XmNmnemonic, 'w',
3796 XmNtopAttachment, XmATTACH_WIDGET,
3797 XmNtopWidget, boldLbl,
3798 XmNtopOffset, BTN_TEXT_OFFSET,
3799 XmNleftAttachment, XmATTACH_POSITION,
3800 XmNleftPosition, 1, NULL);
3801 XmStringFree(s1);
3802 XtAddCallback(boldBtn, XmNactivateCallback, boldBrowseCB, fd);
3804 fd->boldW = XtVaCreateManagedWidget("bold", xmTextWidgetClass,
3805 highlightForm,
3806 XmNmaxLength, MAX_FONT_LEN,
3807 XmNleftAttachment, XmATTACH_WIDGET,
3808 XmNleftWidget, boldBtn,
3809 XmNtopAttachment, XmATTACH_WIDGET,
3810 XmNtopWidget, boldLbl,
3811 XmNrightAttachment, XmATTACH_POSITION,
3812 XmNrightPosition, 99, NULL);
3813 RemapDeleteKey(fd->boldW);
3814 XtAddCallback(fd->boldW, XmNvalueChangedCallback,
3815 boldModifiedCB, fd);
3816 XtVaSetValues(boldLbl, XmNuserData, fd->boldW, NULL);
3818 boldItalicLbl = XtVaCreateManagedWidget("boldItalicLbl", xmLabelGadgetClass,
3819 highlightForm,
3820 XmNlabelString, s1=XmStringCreateSimple("Bold Italic Font"),
3821 XmNmnemonic, 'l',
3822 XmNalignment, XmALIGNMENT_BEGINNING,
3823 XmNtopAttachment, XmATTACH_WIDGET,
3824 XmNtopWidget, boldBtn,
3825 XmNtopOffset, MARGIN_SPACING,
3826 XmNleftAttachment, XmATTACH_POSITION,
3827 XmNleftPosition, 1, NULL);
3828 XmStringFree(s1);
3830 fd->boldItalicErrW = XtVaCreateManagedWidget("boldItalicErrLbl",
3831 xmLabelGadgetClass, highlightForm,
3832 XmNlabelString, s1=XmStringCreateSimple(""),
3833 XmNalignment, XmALIGNMENT_END,
3834 XmNtopAttachment, XmATTACH_WIDGET,
3835 XmNtopWidget, boldBtn,
3836 XmNtopOffset, MARGIN_SPACING,
3837 XmNleftAttachment, XmATTACH_WIDGET,
3838 XmNleftWidget, boldItalicLbl,
3839 XmNrightAttachment, XmATTACH_POSITION,
3840 XmNrightPosition, 99, NULL);
3841 XmStringFree(s1);
3843 boldItalicBtn = XtVaCreateManagedWidget("boldItalicBtn",
3844 xmPushButtonWidgetClass, highlightForm,
3845 XmNlabelString, s1=XmStringCreateSimple("Browse..."),
3846 XmNmnemonic, 's',
3847 XmNtopAttachment, XmATTACH_WIDGET,
3848 XmNtopWidget, boldItalicLbl,
3849 XmNtopOffset, BTN_TEXT_OFFSET,
3850 XmNleftAttachment, XmATTACH_POSITION,
3851 XmNleftPosition, 1, NULL);
3852 XmStringFree(s1);
3853 XtAddCallback(boldItalicBtn, XmNactivateCallback, boldItalicBrowseCB, fd);
3855 fd->boldItalicW = XtVaCreateManagedWidget("boldItalic",
3856 xmTextWidgetClass, highlightForm,
3857 XmNmaxLength, MAX_FONT_LEN,
3858 XmNleftAttachment, XmATTACH_WIDGET,
3859 XmNleftWidget, boldItalicBtn,
3860 XmNtopAttachment, XmATTACH_WIDGET,
3861 XmNtopWidget, boldItalicLbl,
3862 XmNrightAttachment, XmATTACH_POSITION,
3863 XmNrightPosition, 99, NULL);
3864 RemapDeleteKey(fd->boldItalicW);
3865 XtAddCallback(fd->boldItalicW, XmNvalueChangedCallback,
3866 boldItalicModifiedCB, fd);
3867 XtVaSetValues(boldItalicLbl, XmNuserData, fd->boldItalicW, NULL);
3869 okBtn = XtVaCreateManagedWidget("ok", xmPushButtonWidgetClass, form,
3870 XmNlabelString, s1=XmStringCreateSimple("OK"),
3871 XmNmarginWidth, BUTTON_WIDTH_MARGIN,
3872 XmNtopAttachment, XmATTACH_WIDGET,
3873 XmNtopWidget, highlightFrame,
3874 XmNtopOffset, MARGIN_SPACING,
3875 XmNleftAttachment, XmATTACH_POSITION,
3876 XmNleftPosition, forWindow ? 13 : 26,
3877 XmNrightAttachment, XmATTACH_POSITION,
3878 XmNrightPosition, forWindow ? 27 : 40, NULL);
3879 XtAddCallback(okBtn, XmNactivateCallback, fontOkCB, fd);
3880 XmStringFree(s1);
3882 if (forWindow) {
3883 applyBtn = XtVaCreateManagedWidget("apply",xmPushButtonWidgetClass,form,
3884 XmNlabelString, s1=XmStringCreateSimple("Apply"),
3885 XmNmnemonic, 'A',
3886 XmNtopAttachment, XmATTACH_WIDGET,
3887 XmNtopWidget, highlightFrame,
3888 XmNtopOffset, MARGIN_SPACING,
3889 XmNleftAttachment, XmATTACH_POSITION,
3890 XmNleftPosition, 43,
3891 XmNrightAttachment, XmATTACH_POSITION,
3892 XmNrightPosition, 57, NULL);
3893 XtAddCallback(applyBtn, XmNactivateCallback, fontApplyCB, fd);
3894 XmStringFree(s1);
3897 cancelBtn = XtVaCreateManagedWidget("cancel",
3898 xmPushButtonWidgetClass, form,
3899 XmNlabelString,
3900 s1 = XmStringCreateSimple(forWindow ? "Close" : "Cancel"),
3901 XmNtopAttachment, XmATTACH_WIDGET,
3902 XmNtopWidget, highlightFrame,
3903 XmNtopOffset, MARGIN_SPACING,
3904 XmNleftAttachment, XmATTACH_POSITION,
3905 XmNleftPosition, forWindow ? 73 : 59,
3906 XmNrightAttachment, XmATTACH_POSITION,
3907 XmNrightPosition, forWindow ? 87 : 73,
3908 NULL);
3909 XtAddCallback(cancelBtn, XmNactivateCallback, fontCancelCB, fd);
3910 XmStringFree(s1);
3912 /* Set initial default button */
3913 XtVaSetValues(form, XmNdefaultButton, okBtn, NULL);
3914 XtVaSetValues(form, XmNcancelButton, cancelBtn, NULL);
3916 /* Set initial values */
3917 if (forWindow) {
3918 XmTextSetString(fd->primaryW, window->fontName);
3919 XmTextSetString(fd->boldW, window->boldFontName);
3920 XmTextSetString(fd->italicW, window->italicFontName);
3921 XmTextSetString(fd->boldItalicW, window->boldItalicFontName);
3922 } else {
3923 XmTextSetString(fd->primaryW, GetPrefFontName());
3924 XmTextSetString(fd->boldW, GetPrefBoldFontName());
3925 XmTextSetString(fd->italicW, GetPrefItalicFontName());
3926 XmTextSetString(fd->boldItalicW, GetPrefBoldItalicFontName());
3929 /* Handle mnemonic selection of buttons and focus to dialog */
3930 AddDialogMnemonicHandler(form, FALSE);
3932 /* put up dialog */
3933 ManageDialogCenteredOnPointer(form);
3936 static void fillFromPrimaryCB(Widget w, XtPointer clientData,
3937 XtPointer callData)
3939 fontDialog *fd = (fontDialog *)clientData;
3940 char *primaryName, *errMsg;
3941 char modifiedFontName[MAX_FONT_LEN];
3942 char *searchString = "(-[^-]*-[^-]*)-([^-]*)-([^-]*)-(.*)";
3943 char *italicReplaceString = "\\1-\\2-o-\\4";
3944 char *boldReplaceString = "\\1-bold-\\3-\\4";
3945 char *boldItalicReplaceString = "\\1-bold-o-\\4";
3946 regexp *compiledRE;
3948 /* Match the primary font agains RE pattern for font names. If it
3949 doesn't match, we can't generate highlight font names, so return */
3950 compiledRE = CompileRE(searchString, &errMsg, REDFLT_STANDARD);
3951 primaryName = XmTextGetString(fd->primaryW);
3952 if (!ExecRE(compiledRE, NULL, primaryName, NULL, False, '\0', '\0', NULL, NULL)) {
3953 XBell(XtDisplay(fd->shell), 0);
3954 free(compiledRE);
3955 XtFree(primaryName);
3956 return;
3959 /* Make up names for new fonts based on RE replace patterns */
3960 SubstituteRE(compiledRE, italicReplaceString, modifiedFontName,
3961 MAX_FONT_LEN);
3962 XmTextSetString(fd->italicW, modifiedFontName);
3963 SubstituteRE(compiledRE, boldReplaceString, modifiedFontName,
3964 MAX_FONT_LEN);
3965 XmTextSetString(fd->boldW, modifiedFontName);
3966 SubstituteRE(compiledRE, boldItalicReplaceString, modifiedFontName,
3967 MAX_FONT_LEN);
3968 XmTextSetString(fd->boldItalicW, modifiedFontName);
3969 XtFree(primaryName);
3970 free(compiledRE);
3973 static void primaryModifiedCB(Widget w, XtPointer clientData,
3974 XtPointer callData)
3976 fontDialog *fd = (fontDialog *)clientData;
3978 showFontStatus(fd, fd->italicW, fd->italicErrW);
3979 showFontStatus(fd, fd->boldW, fd->boldErrW);
3980 showFontStatus(fd, fd->boldItalicW, fd->boldItalicErrW);
3982 static void italicModifiedCB(Widget w, XtPointer clientData, XtPointer callData)
3984 fontDialog *fd = (fontDialog *)clientData;
3986 showFontStatus(fd, fd->italicW, fd->italicErrW);
3988 static void boldModifiedCB(Widget w, XtPointer clientData, XtPointer callData)
3990 fontDialog *fd = (fontDialog *)clientData;
3992 showFontStatus(fd, fd->boldW, fd->boldErrW);
3994 static void boldItalicModifiedCB(Widget w, XtPointer clientData,
3995 XtPointer callData)
3997 fontDialog *fd = (fontDialog *)clientData;
3999 showFontStatus(fd, fd->boldItalicW, fd->boldItalicErrW);
4002 static void primaryBrowseCB(Widget w, XtPointer clientData, XtPointer callData)
4004 fontDialog *fd = (fontDialog *)clientData;
4006 browseFont(fd->shell, fd->primaryW);
4008 static void italicBrowseCB(Widget w, XtPointer clientData, XtPointer callData)
4010 fontDialog *fd = (fontDialog *)clientData;
4012 browseFont(fd->shell, fd->italicW);
4014 static void boldBrowseCB(Widget w, XtPointer clientData, XtPointer callData)
4016 fontDialog *fd = (fontDialog *)clientData;
4018 browseFont(fd->shell, fd->boldW);
4020 static void boldItalicBrowseCB(Widget w, XtPointer clientData,
4021 XtPointer callData)
4023 fontDialog *fd = (fontDialog *)clientData;
4025 browseFont(fd->shell, fd->boldItalicW);
4028 static void fontDestroyCB(Widget w, XtPointer clientData, XtPointer callData)
4030 fontDialog *fd = (fontDialog *)clientData;
4032 fd->window->fontDialog = NULL;
4033 XtFree((char *)fd);
4036 static void fontOkCB(Widget w, XtPointer clientData, XtPointer callData)
4038 fontDialog *fd = (fontDialog *)clientData;
4040 updateFonts(fd);
4042 /* pop down and destroy the dialog */
4043 XtDestroyWidget(fd->shell);
4046 static void fontApplyCB(Widget w, XtPointer clientData, XtPointer callData)
4048 fontDialog *fd = (fontDialog *)clientData;
4050 updateFonts(fd);
4053 static void fontCancelCB(Widget w, XtPointer clientData, XtPointer callData)
4055 fontDialog *fd = (fontDialog *)clientData;
4057 /* pop down and destroy the dialog */
4058 XtDestroyWidget(fd->shell);
4062 ** Check over a font name in a text field to make sure it agrees with the
4063 ** primary font in height and spacing.
4065 static int checkFontStatus(fontDialog *fd, Widget fontTextFieldW)
4067 char *primaryName, *testName;
4068 XFontStruct *primaryFont, *testFont;
4069 Display *display = XtDisplay(fontTextFieldW);
4070 int primaryWidth, primaryHeight, testWidth, testHeight;
4072 /* Get width and height of the font to check. Note the test for empty
4073 name: X11R6 clients freak out X11R5 servers if they ask them to load
4074 an empty font name, and kill the whole application! */
4075 testName = XmTextGetString(fontTextFieldW);
4076 if (testName[0] == '\0') {
4077 XtFree(testName);
4078 return BAD_FONT;
4080 testFont = XLoadQueryFont(display, testName);
4081 if (testFont == NULL) {
4082 XtFree(testName);
4083 return BAD_FONT;
4085 XtFree(testName);
4086 testWidth = testFont->min_bounds.width;
4087 testHeight = testFont->ascent + testFont->descent;
4088 XFreeFont(display, testFont);
4090 /* Get width and height of the primary font */
4091 primaryName = XmTextGetString(fd->primaryW);
4092 if (primaryName[0] == '\0') {
4093 XtFree(primaryName);
4094 return BAD_FONT;
4096 primaryFont = XLoadQueryFont(display, primaryName);
4097 if (primaryFont == NULL) {
4098 XtFree(primaryName);
4099 return BAD_PRIMARY;
4101 XtFree(primaryName);
4102 primaryWidth = primaryFont->min_bounds.width;
4103 primaryHeight = primaryFont->ascent + primaryFont->descent;
4104 XFreeFont(display, primaryFont);
4106 /* Compare font information */
4107 if (testWidth != primaryWidth)
4108 return BAD_SPACING;
4109 if (testHeight != primaryHeight)
4110 return BAD_SIZE;
4111 return GOOD_FONT;
4115 ** Update the error label for a font text field to reflect its validity and degree
4116 ** of agreement with the currently selected primary font
4118 static int showFontStatus(fontDialog *fd, Widget fontTextFieldW,
4119 Widget errorLabelW)
4121 int status;
4122 XmString s;
4123 char *msg;
4125 status = checkFontStatus(fd, fontTextFieldW);
4126 if (status == BAD_PRIMARY)
4127 msg = "(font below may not match primary font)";
4128 else if (status == BAD_FONT)
4129 msg = "(xxx font below is invalid xxx)";
4130 else if (status == BAD_SIZE)
4131 msg = "(height of font below does not match primary)";
4132 else if (status == BAD_SPACING)
4133 msg = "(spacing of font below does not match primary)";
4134 else
4135 msg = "";
4137 XtVaSetValues(errorLabelW, XmNlabelString, s=XmStringCreateSimple(msg),
4138 NULL);
4139 XmStringFree(s);
4140 return status;
4144 ** Put up a font selector panel to set the font name in the text widget "fontTextW"
4146 static void browseFont(Widget parent, Widget fontTextW)
4148 char *origFontName, *newFontName;
4149 Pixel fgPixel, bgPixel;
4150 int dummy;
4152 origFontName = XmTextGetString(fontTextW);
4154 /* Get the values from the defaults */
4155 fgPixel = AllocColor(parent, GetPrefColorName(TEXT_FG_COLOR),
4156 &dummy, &dummy, &dummy);
4157 bgPixel = AllocColor(parent, GetPrefColorName(TEXT_BG_COLOR),
4158 &dummy, &dummy, &dummy);
4160 newFontName = FontSel(parent, PREF_FIXED, origFontName, fgPixel, bgPixel);
4161 XtFree(origFontName);
4162 if (newFontName == NULL)
4163 return;
4164 XmTextSetString(fontTextW, newFontName);
4165 XtFree(newFontName);
4169 ** Accept the changes in the dialog and set the fonts regardless of errors
4171 static void updateFonts(fontDialog *fd)
4173 char *fontName, *italicName, *boldName, *boldItalicName;
4175 fontName = XmTextGetString(fd->primaryW);
4176 italicName = XmTextGetString(fd->italicW);
4177 boldName = XmTextGetString(fd->boldW);
4178 boldItalicName = XmTextGetString(fd->boldItalicW);
4180 if (fd->forWindow) {
4181 char *params[4];
4182 params[0] = fontName;
4183 params[1] = italicName;
4184 params[2] = boldName;
4185 params[3] = boldItalicName;
4186 XtCallActionProc(fd->window->textArea, "set_fonts", NULL, params, 4);
4188 SetFonts(fd->window, fontName, italicName, boldName, boldItalicName);
4191 else {
4192 SetPrefFont(fontName);
4193 SetPrefItalicFont(italicName);
4194 SetPrefBoldFont(boldName);
4195 SetPrefBoldItalicFont(boldItalicName);
4197 XtFree(fontName);
4198 XtFree(italicName);
4199 XtFree(boldName);
4200 XtFree(boldItalicName);
4204 ** Change the language mode to the one indexed by "mode", reseting word
4205 ** delimiters, syntax highlighting and other mode specific parameters
4207 static void reapplyLanguageMode(WindowInfo *window, int mode, int forceDefaults)
4209 char *delimiters;
4210 int i, wrapMode, indentStyle, tabDist, emTabDist, highlight, oldEmTabDist;
4211 int wrapModeIsDef, tabDistIsDef, emTabDistIsDef, indentStyleIsDef;
4212 int highlightIsDef, haveHighlightPatterns, haveSmartIndentMacros;
4213 int oldMode = window->languageMode;
4214 WindowInfo *wi;
4216 /* If the mode is the same, and changes aren't being forced (as might
4217 happen with Save As...), don't mess with already correct settings */
4218 if (window->languageMode == mode && !forceDefaults)
4219 return;
4221 /* Change the mode name stored in the window */
4222 window->languageMode = mode;
4224 /* Unload oldMode's default calltips file if there are no more windows
4225 in that mode and the mode has a default file */
4226 if (oldMode != PLAIN_LANGUAGE_MODE && LanguageModes[oldMode]->defTipsFile) {
4227 for (wi = WindowList; wi; wi = wi->next)
4228 if (wi->languageMode == oldMode) break;
4229 if (!wi) DeleteTagsFile( LanguageModes[oldMode]->defTipsFile, TIP );
4232 /* Make sure we didn't accidentally delete a default calltips file that
4233 also belongs another language mode (also load the tips file for the
4234 new lang. mode) */
4235 for (wi = WindowList; wi; wi = wi->next) {
4236 i = wi->languageMode;
4237 if (i != PLAIN_LANGUAGE_MODE && LanguageModes[i]->defTipsFile)
4238 if (AddTagsFile( LanguageModes[i]->defTipsFile, TIP ) == FALSE)
4239 fprintf( stderr, "Error loading default calltips file:\n"
4240 " \"%s\"\n", LanguageModes[i]->defTipsFile );
4243 /* Set delimiters for all text widgets */
4244 if (mode == PLAIN_LANGUAGE_MODE || LanguageModes[mode]->delimiters == NULL)
4245 delimiters = GetPrefDelimiters();
4246 else
4247 delimiters = LanguageModes[mode]->delimiters;
4248 XtVaSetValues(window->textArea, textNwordDelimiters, delimiters, NULL);
4249 for (i=0; i<window->nPanes; i++)
4250 XtVaSetValues(window->textPanes[i], textNautoIndent, delimiters, NULL);
4252 /* Decide on desired values for language-specific parameters. If a
4253 parameter was set to its default value, set it to the new default,
4254 otherwise, leave it alone */
4255 wrapModeIsDef = window->wrapMode == GetPrefWrap(oldMode);
4256 tabDistIsDef = BufGetTabDistance(window->buffer) == GetPrefTabDist(oldMode);
4257 XtVaGetValues(window->textArea, textNemulateTabs, &oldEmTabDist, NULL);
4258 emTabDistIsDef = oldEmTabDist == GetPrefEmTabDist(oldMode);
4259 indentStyleIsDef = window->indentStyle == GetPrefAutoIndent(oldMode) ||
4260 (GetPrefAutoIndent(oldMode) == SMART_INDENT &&
4261 window->indentStyle == AUTO_INDENT &&
4262 !SmartIndentMacrosAvailable(LanguageModeName(oldMode)));
4263 highlightIsDef = window->highlightSyntax == GetPrefHighlightSyntax()
4264 || (GetPrefHighlightSyntax() &&
4265 FindPatternSet(LanguageModeName(oldMode)) == NULL);
4266 wrapMode = wrapModeIsDef || forceDefaults ?
4267 GetPrefWrap(mode) : window->wrapMode;
4268 tabDist = tabDistIsDef || forceDefaults ?
4269 GetPrefTabDist(mode) : BufGetTabDistance(window->buffer);
4270 emTabDist = emTabDistIsDef || forceDefaults ?
4271 GetPrefEmTabDist(mode) : oldEmTabDist;
4272 indentStyle = indentStyleIsDef || forceDefaults ?
4273 GetPrefAutoIndent(mode) : window->indentStyle;
4274 highlight = highlightIsDef || forceDefaults ?
4275 GetPrefHighlightSyntax() : window->highlightSyntax;
4277 /* Dim/undim smart-indent and highlighting menu items depending on
4278 whether patterns/macros are available */
4279 haveHighlightPatterns = FindPatternSet(LanguageModeName(mode)) != NULL;
4280 haveSmartIndentMacros = SmartIndentMacrosAvailable(LanguageModeName(mode));
4281 if (IsTopDocument(window)) {
4282 XtSetSensitive(window->highlightItem, haveHighlightPatterns);
4283 XtSetSensitive(window->smartIndentItem, haveSmartIndentMacros);
4286 /* Turn off requested options which are not available */
4287 highlight = haveHighlightPatterns && highlight;
4288 if (indentStyle == SMART_INDENT && !haveSmartIndentMacros)
4289 indentStyle = AUTO_INDENT;
4291 /* Change highlighting */
4292 window->highlightSyntax = highlight;
4293 SetToggleButtonState(window, window->highlightItem, highlight, False);
4294 StopHighlighting(window);
4296 /* we defer highlighting to RaiseDocument() if doc is hidden */
4297 if (IsTopDocument(window) && highlight)
4298 StartHighlighting(window, False);
4300 /* Force a change of smart indent macros (SetAutoIndent will re-start) */
4301 if (window->indentStyle == SMART_INDENT) {
4302 EndSmartIndent(window);
4303 window->indentStyle = AUTO_INDENT;
4306 /* set requested wrap, indent, and tabs */
4307 SetAutoWrap(window, wrapMode);
4308 SetAutoIndent(window, indentStyle);
4309 SetTabDist(window, tabDist);
4310 SetEmTabDist(window, emTabDist);
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 /* Unload the default calltips file for this window unless somebody else
5588 is using it */
5589 void UnloadLanguageModeTipsFile(WindowInfo *window) {
5590 int mode;
5591 WindowInfo *wi;
5593 mode = window->languageMode;
5594 if (mode != PLAIN_LANGUAGE_MODE && LanguageModes[mode]->defTipsFile) {
5595 for (wi = WindowList; wi; wi = wi->next)
5596 if (wi->languageMode == mode && wi != window)
5597 break;
5598 if (!wi) /* If we got to end of WindowList... */
5599 DeleteTagsFile( LanguageModes[mode]->defTipsFile, TIP );
5602 /* Make sure we didn't accidentally delete a default calltips file that
5603 also belongs to another language mode */
5604 for (wi = WindowList; wi; wi = wi->next) {
5605 if (wi == window)
5606 continue;
5607 mode = wi->languageMode;
5608 if (mode != PLAIN_LANGUAGE_MODE && LanguageModes[mode]->defTipsFile)
5609 if (AddTagsFile( LanguageModes[mode]->defTipsFile, TIP ) == FALSE)
5610 fprintf( stderr, "Error loading default calltips file:\n"
5611 " \"%s\"\n", LanguageModes[mode]->defTipsFile );
5615 /******************************************************************************
5616 * The Color selection dialog
5617 ******************************************************************************/
5620 There are 8 colors: And 8 indices:
5621 textFg TEXT_FG_COLOR
5622 textBg TEXT_BG_COLOR
5623 selectFg SELECT_FG_COLOR
5624 selectBg SELECT_BG_COLOR
5625 hiliteFg HILITE_FG_COLOR
5626 hiliteBg HILITE_BG_COLOR
5627 lineNoFg LINENO_FG_COLOR
5628 cursorFg CURSOR_FG_COLOR
5631 #define MARGIN_SPACING 10
5634 * Callbacks for field modifications
5636 static void textFgModifiedCB(Widget w, XtPointer clientData,
5637 XtPointer callData)
5639 colorDialog *cd = (colorDialog *)clientData;
5640 showColorStatus(cd, cd->textFgW, cd->textFgErrW);
5643 static void textBgModifiedCB(Widget w, XtPointer clientData,
5644 XtPointer callData)
5646 colorDialog *cd = (colorDialog *)clientData;
5647 showColorStatus(cd, cd->textBgW, cd->textBgErrW);
5650 static void selectFgModifiedCB(Widget w, XtPointer clientData,
5651 XtPointer callData)
5653 colorDialog *cd = (colorDialog *)clientData;
5654 showColorStatus(cd, cd->selectFgW, cd->selectFgErrW);
5657 static void selectBgModifiedCB(Widget w, XtPointer clientData,
5658 XtPointer callData)
5660 colorDialog *cd = (colorDialog *)clientData;
5661 showColorStatus(cd, cd->selectBgW, cd->selectBgErrW);
5664 static void hiliteFgModifiedCB(Widget w, XtPointer clientData,
5665 XtPointer callData)
5667 colorDialog *cd = (colorDialog *)clientData;
5668 showColorStatus(cd, cd->hiliteFgW, cd->hiliteFgErrW);
5671 static void hiliteBgModifiedCB(Widget w, XtPointer clientData,
5672 XtPointer callData)
5674 colorDialog *cd = (colorDialog *)clientData;
5675 showColorStatus(cd, cd->hiliteBgW, cd->hiliteBgErrW);
5678 static void lineNoFgModifiedCB(Widget w, XtPointer clientData,
5679 XtPointer callData)
5681 colorDialog *cd = (colorDialog *)clientData;
5682 showColorStatus(cd, cd->lineNoFgW, cd->lineNoFgErrW);
5685 static void cursorFgModifiedCB(Widget w, XtPointer clientData,
5686 XtPointer callData)
5688 colorDialog *cd = (colorDialog *)clientData;
5689 showColorStatus(cd, cd->cursorFgW, cd->cursorFgErrW);
5694 * Helper functions for validating colors
5696 static int verifyAllColors(colorDialog *cd) {
5697 /* Maybe just check for empty strings in error widgets instead? */
5698 return (checkColorStatus(cd, cd->textFgW) &&
5699 checkColorStatus(cd, cd->textBgW) &&
5700 checkColorStatus(cd, cd->selectFgW) &&
5701 checkColorStatus(cd, cd->selectBgW) &&
5702 checkColorStatus(cd, cd->hiliteFgW) &&
5703 checkColorStatus(cd, cd->hiliteBgW) &&
5704 checkColorStatus(cd, cd->lineNoFgW) &&
5705 checkColorStatus(cd, cd->cursorFgW) );
5708 /* Returns True if the color is valid, False if it's not */
5709 static Boolean checkColorStatus(colorDialog *cd, Widget colorFieldW)
5711 Colormap cMap;
5712 XColor colorDef;
5713 Status status;
5714 Display *display = XtDisplay(cd->shell);
5715 char *text = XmTextGetString(colorFieldW);
5716 XtVaGetValues(cd->shell, XtNcolormap, &cMap, NULL);
5717 status = XParseColor(display, cMap, text, &colorDef);
5718 XtFree(text);
5719 return (status != 0);
5722 /* Show or hide errorLabelW depending on whether or not colorFieldW
5723 contains a valid color name. */
5724 static void showColorStatus(colorDialog *cd, Widget colorFieldW,
5725 Widget errorLabelW)
5727 /* Should set the OK/Apply button sensitivity here, instead
5728 of leaving is sensitive and then complaining if an error. */
5729 XtSetMappedWhenManaged( errorLabelW, !checkColorStatus(cd, colorFieldW) );
5732 /* Update the colors in the window or in the preferences */
5733 static void updateColors(colorDialog *cd)
5735 WindowInfo *window;
5737 char *textFg = XmTextGetString(cd->textFgW),
5738 *textBg = XmTextGetString(cd->textBgW),
5739 *selectFg = XmTextGetString(cd->selectFgW),
5740 *selectBg = XmTextGetString(cd->selectBgW),
5741 *hiliteFg = XmTextGetString(cd->hiliteFgW),
5742 *hiliteBg = XmTextGetString(cd->hiliteBgW),
5743 *lineNoFg = XmTextGetString(cd->lineNoFgW),
5744 *cursorFg = XmTextGetString(cd->cursorFgW);
5746 for (window = WindowList; window != NULL; window = window->next)
5748 SetColors(window, textFg, textBg, selectFg, selectBg, hiliteFg,
5749 hiliteBg, lineNoFg, cursorFg);
5752 SetPrefColorName(TEXT_FG_COLOR , textFg );
5753 SetPrefColorName(TEXT_BG_COLOR , textBg );
5754 SetPrefColorName(SELECT_FG_COLOR, selectFg);
5755 SetPrefColorName(SELECT_BG_COLOR, selectBg);
5756 SetPrefColorName(HILITE_FG_COLOR, hiliteFg);
5757 SetPrefColorName(HILITE_BG_COLOR, hiliteBg);
5758 SetPrefColorName(LINENO_FG_COLOR, lineNoFg);
5759 SetPrefColorName(CURSOR_FG_COLOR, cursorFg);
5761 XtFree(textFg);
5762 XtFree(textBg);
5763 XtFree(selectFg);
5764 XtFree(selectBg);
5765 XtFree(hiliteFg);
5766 XtFree(hiliteBg);
5767 XtFree(lineNoFg);
5768 XtFree(cursorFg);
5773 * Dialog button callbacks
5776 static void colorDestroyCB(Widget w, XtPointer clientData, XtPointer callData)
5778 colorDialog *cd = (colorDialog *)clientData;
5780 cd->window->colorDialog = NULL;
5781 XtFree((char *)cd);
5784 static void colorOkCB(Widget w, XtPointer clientData, XtPointer callData)
5786 colorDialog *cd = (colorDialog *)clientData;
5788 if(!verifyAllColors(cd))
5790 DialogF(DF_ERR, w, 1, "Invalid Colors",
5791 "All colors must be valid to proceed.", "OK");
5792 return;
5794 updateColors(cd);
5796 /* pop down and destroy the dialog */
5797 XtDestroyWidget(cd->shell);
5800 static void colorApplyCB(Widget w, XtPointer clientData, XtPointer callData)
5802 colorDialog *cd = (colorDialog *)clientData;
5804 if(!verifyAllColors(cd))
5806 DialogF(DF_ERR, w, 1, "Invalid Colors",
5807 "All colors must be valid to be applied.", "OK");
5808 return;
5810 updateColors(cd);
5813 static void colorCloseCB(Widget w, XtPointer clientData, XtPointer callData)
5815 colorDialog *cd = (colorDialog *)clientData;
5817 /* pop down and destroy the dialog */
5818 XtDestroyWidget(cd->shell);
5822 /* Add a label, error label, and text entry label with a validation
5823 callback */
5824 static Widget addColorGroup( Widget parent, const char *name, char mnemonic,
5825 char *label, Widget *fieldW, Widget *errW, Widget topWidget,
5826 int leftPos, int rightPos, XtCallbackProc modCallback,
5827 colorDialog *cd )
5829 Widget lblW;
5830 char *longerName;
5831 XmString s1;
5832 int nameLen = strlen(name);
5834 /* The label widget */
5835 longerName = XtMalloc(nameLen+7);
5836 strcpy(longerName, name);
5837 strcat(longerName, "Lbl");
5838 lblW = XtVaCreateManagedWidget(longerName,
5839 xmLabelGadgetClass, parent,
5840 XmNlabelString, s1=XmStringCreateSimple( label ),
5841 XmNmnemonic, mnemonic,
5842 XmNtopAttachment, XmATTACH_WIDGET,
5843 XmNtopWidget, topWidget,
5844 XmNtopOffset, MARGIN_SPACING,
5845 XmNleftAttachment, XmATTACH_POSITION,
5846 XmNleftPosition, leftPos, NULL);
5847 XmStringFree(s1);
5849 /* The error label widget */
5850 strcpy(&(longerName[nameLen]), "ErrLbl");
5851 *errW = XtVaCreateManagedWidget(longerName,
5852 xmLabelWidgetClass, parent,
5853 XmNlabelString, s1=XmStringCreateSimple("(Invalid!)"),
5854 XmNalignment, XmALIGNMENT_END,
5855 XmNtopAttachment, XmATTACH_WIDGET,
5856 XmNtopWidget, topWidget,
5857 XmNtopOffset, MARGIN_SPACING,
5858 XmNleftAttachment, XmATTACH_WIDGET,
5859 XmNleftWidget, lblW,
5860 XmNrightAttachment, XmATTACH_POSITION,
5861 XmNrightPosition, rightPos, NULL);
5862 XmStringFree(s1);
5864 /* The text field entry widget */
5865 *fieldW = XtVaCreateManagedWidget(name, xmTextWidgetClass,
5866 parent,
5867 XmNcolumns, MAX_COLOR_LEN-1,
5868 XmNmaxLength, MAX_COLOR_LEN-1,
5869 XmNleftAttachment, XmATTACH_POSITION,
5870 XmNleftPosition, leftPos,
5871 XmNrightAttachment, XmATTACH_POSITION,
5872 XmNrightPosition, rightPos,
5873 XmNtopAttachment, XmATTACH_WIDGET,
5874 XmNtopWidget, lblW, NULL);
5875 RemapDeleteKey(*fieldW);
5876 XtAddCallback(*fieldW, XmNvalueChangedCallback,
5877 modCallback, cd);
5878 XtVaSetValues(lblW, XmNuserData, *fieldW, NULL);
5880 XtFree(longerName);
5881 return *fieldW;
5886 * Code for the dialog itself
5888 void ChooseColors(WindowInfo *window)
5890 Widget form, tmpW, topW, infoLbl;
5891 Widget okBtn, applyBtn, closeBtn;
5892 colorDialog *cd;
5893 XmString s1;
5894 int ac;
5895 Arg args[20];
5897 /* if the dialog is already displayed, just pop it to the top and return */
5898 if (window->colorDialog != NULL) {
5899 RaiseShellWindow(((colorDialog *)window->colorDialog)->shell);
5900 return;
5903 /* Create a structure for keeping track of dialog state */
5904 cd = XtNew(colorDialog);
5905 window->colorDialog = (void*)cd;
5907 /* Create a form widget in a dialog shell */
5908 ac = 0;
5909 XtSetArg(args[ac], XmNautoUnmanage, False); ac++;
5910 XtSetArg(args[ac], XmNresizePolicy, XmRESIZE_NONE); ac++;
5911 form = CreateFormDialog(window->shell, "choose colors", args, ac);
5912 XtVaSetValues(form, XmNshadowThickness, 0, NULL);
5913 cd->shell = XtParent(form);
5914 cd->window = window;
5915 XtVaSetValues(cd->shell, XmNtitle, "Colors", NULL);
5916 AddMotifCloseCallback(XtParent(form), colorCloseCB, cd);
5917 XtAddCallback(form, XmNdestroyCallback, colorDestroyCB, cd);
5919 /* Information label */
5920 infoLbl = XtVaCreateManagedWidget("infoLbl",
5921 xmLabelGadgetClass, form,
5922 XmNtopAttachment, XmATTACH_POSITION,
5923 XmNtopPosition, 2,
5924 XmNleftAttachment, XmATTACH_POSITION,
5925 XmNleftPosition, 1,
5926 XmNrightAttachment, XmATTACH_POSITION,
5927 XmNrightPosition, 99,
5928 XmNalignment, XmALIGNMENT_CENTER,
5929 XmNlabelString, s1 = XmStringCreateLtoR(
5930 "Colors can be entered as names (e.g. red, blue) or "
5931 "as RGB triples\nin the format #RRGGBB, where each digit "
5932 "is in the range 0-f.", XmFONTLIST_DEFAULT_TAG),
5933 NULL);
5934 XmStringFree(s1);
5936 topW = infoLbl;
5938 /* The left column (foregrounds) of color entry groups */
5939 tmpW = addColorGroup( form, "textFg", 'P', "Plain Text Foreground",
5940 &(cd->textFgW), &(cd->textFgErrW), topW, 1, 49,
5941 textFgModifiedCB, cd );
5942 tmpW = addColorGroup( form, "selectFg", 'S', "Selection Foreground",
5943 &(cd->selectFgW), &(cd->selectFgErrW), tmpW, 1, 49,
5944 selectFgModifiedCB, cd );
5945 tmpW = addColorGroup( form, "hiliteFg", 'M', "Matching (..) Foreground",
5946 &(cd->hiliteFgW), &(cd->hiliteFgErrW), tmpW, 1, 49,
5947 hiliteFgModifiedCB, cd );
5948 tmpW = addColorGroup( form, "lineNoFg", 'L', "Line Numbers",
5949 &(cd->lineNoFgW), &(cd->lineNoFgErrW), tmpW, 1, 49,
5950 lineNoFgModifiedCB, cd );
5952 /* The right column (backgrounds) */
5953 tmpW = addColorGroup( form, "textBg", 'T', "Text Area Background",
5954 &(cd->textBgW), &(cd->textBgErrW), topW, 51, 99,
5955 textBgModifiedCB, cd );
5956 tmpW = addColorGroup( form, "selectBg", 'B', "Selection Background",
5957 &(cd->selectBgW), &(cd->selectBgErrW), tmpW, 51, 99,
5958 selectBgModifiedCB, cd );
5959 tmpW = addColorGroup( form, "hiliteBg", 'h', "Matching (..) Background",
5960 &(cd->hiliteBgW), &(cd->hiliteBgErrW), tmpW, 51, 99,
5961 hiliteBgModifiedCB, cd );
5962 tmpW = addColorGroup( form, "cursorFg", 'C', "Cursor Color",
5963 &(cd->cursorFgW), &(cd->cursorFgErrW), tmpW, 51, 99,
5964 cursorFgModifiedCB, cd );
5966 tmpW = XtVaCreateManagedWidget("infoLbl",
5967 xmLabelGadgetClass, form,
5968 XmNtopAttachment, XmATTACH_WIDGET,
5969 XmNtopWidget, tmpW,
5970 XmNtopOffset, MARGIN_SPACING,
5971 XmNleftAttachment, XmATTACH_POSITION,
5972 XmNleftPosition, 1,
5973 XmNrightAttachment, XmATTACH_POSITION,
5974 XmNrightPosition, 99,
5975 XmNalignment, XmALIGNMENT_CENTER,
5976 XmNlabelString, s1 = XmStringCreateLtoR(
5977 "NOTE: Foreground colors only apply when syntax highlighting "
5978 "is DISABLED.\n", XmFONTLIST_DEFAULT_TAG),
5979 NULL);
5980 XmStringFree(s1);
5982 tmpW = XtVaCreateManagedWidget("sep",
5983 xmSeparatorGadgetClass, form,
5984 XmNtopAttachment, XmATTACH_WIDGET,
5985 XmNtopWidget, tmpW,
5986 XmNleftAttachment, XmATTACH_FORM,
5987 XmNrightAttachment, XmATTACH_FORM, NULL);
5989 /* The OK, Apply, and Cancel buttons */
5990 okBtn = XtVaCreateManagedWidget("ok",
5991 xmPushButtonWidgetClass, form,
5992 XmNlabelString, s1=XmStringCreateSimple("OK"),
5993 XmNmarginWidth, BUTTON_WIDTH_MARGIN,
5994 XmNtopAttachment, XmATTACH_WIDGET,
5995 XmNtopWidget, tmpW,
5996 XmNtopOffset, MARGIN_SPACING,
5997 XmNleftAttachment, XmATTACH_POSITION,
5998 XmNleftPosition, 10,
5999 XmNrightAttachment, XmATTACH_POSITION,
6000 XmNrightPosition, 30,
6001 NULL);
6002 XtAddCallback(okBtn, XmNactivateCallback, colorOkCB, cd);
6003 XmStringFree(s1);
6005 applyBtn = XtVaCreateManagedWidget(
6006 "apply", xmPushButtonWidgetClass, form,
6007 XmNlabelString, s1=XmStringCreateSimple("Apply"),
6008 XmNtopAttachment, XmATTACH_WIDGET,
6009 XmNtopWidget, tmpW,
6010 XmNtopOffset, MARGIN_SPACING,
6011 XmNmnemonic, 'A',
6012 XmNleftAttachment, XmATTACH_POSITION,
6013 XmNleftPosition, 40,
6014 XmNrightAttachment, XmATTACH_POSITION,
6015 XmNrightPosition, 60, NULL);
6016 XtAddCallback(applyBtn, XmNactivateCallback, colorApplyCB, cd);
6017 XmStringFree(s1);
6019 closeBtn = XtVaCreateManagedWidget("close",
6020 xmPushButtonWidgetClass, form,
6021 XmNlabelString, s1=XmStringCreateSimple("Close"),
6022 XmNtopAttachment, XmATTACH_WIDGET,
6023 XmNtopWidget, tmpW,
6024 XmNtopOffset, MARGIN_SPACING,
6025 XmNleftAttachment, XmATTACH_POSITION,
6026 XmNleftPosition, 70,
6027 XmNrightAttachment, XmATTACH_POSITION,
6028 XmNrightPosition, 90,
6029 NULL);
6030 XtAddCallback(closeBtn, XmNactivateCallback, colorCloseCB, cd);
6031 XmStringFree(s1);
6033 /* Set initial default button */
6034 XtVaSetValues(form, XmNdefaultButton, okBtn, NULL);
6035 XtVaSetValues(form, XmNcancelButton, closeBtn, NULL);
6037 /* Set initial values */
6038 XmTextSetString(cd->textFgW, GetPrefColorName(TEXT_FG_COLOR ));
6039 XmTextSetString(cd->textBgW, GetPrefColorName(TEXT_BG_COLOR ));
6040 XmTextSetString(cd->selectFgW, GetPrefColorName(SELECT_FG_COLOR));
6041 XmTextSetString(cd->selectBgW, GetPrefColorName(SELECT_BG_COLOR));
6042 XmTextSetString(cd->hiliteFgW, GetPrefColorName(HILITE_FG_COLOR));
6043 XmTextSetString(cd->hiliteBgW, GetPrefColorName(HILITE_BG_COLOR));
6044 XmTextSetString(cd->lineNoFgW, GetPrefColorName(LINENO_FG_COLOR));
6045 XmTextSetString(cd->cursorFgW, GetPrefColorName(CURSOR_FG_COLOR));
6047 /* Handle mnemonic selection of buttons and focus to dialog */
6048 AddDialogMnemonicHandler(form, FALSE);
6050 /* put up dialog */
6051 ManageDialogCenteredOnPointer(form);