1 static const char CVSID
[] = "$Id: preferences.c,v 1.160 2008/10/22 09:00:48 lebert Exp $";
2 /*******************************************************************************
4 * preferences.c -- Nirvana Editor preferences processing *
6 * Copyright (C) 1999 Mark Edel *
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. *
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 *
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 *
23 * Nirvana Text Editor *
26 * Written by Mark Edel *
28 *******************************************************************************/
31 #include "../config.h"
34 #include "preferences.h"
42 #include "highlight.h"
43 #include "highlightData.h"
45 #include "regularExp.h"
46 #include "smartIndent.h"
47 #include "windowTitle.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"
66 #include "../util/VMSparam.h"
69 #include <sys/param.h>
71 #include "../util/clearcase.h"
75 #include <Xm/SelectioB.h>
78 #include <Xm/SeparatoG.h>
79 #include <Xm/LabelG.h>
81 #include <Xm/PushBG.h>
83 #include <Xm/ToggleBG.h>
84 #include <Xm/ToggleB.h>
85 #include <Xm/RowColumn.h>
86 #include <Xm/CascadeBG.h>
95 #define MENU_WIDGET(w) (XmGetPostedFromWidget(XtParent(w)))
97 #define MENU_WIDGET(w) (w)
100 #define PREF_FILE_VERSION "5.6"
102 /* New styles added in 5.2 for auto-upgrade */
103 #define ADD_5_2_STYLES " Pointer:#660000:Bold\nRegex:#009944:Bold\nWarning:brown2:Italic"
105 /* maximum number of word delimiters allowed (256 allows whole character set) */
106 #define MAX_WORD_DELIMITERS 256
108 /* maximum number of file extensions allowed in a language mode */
109 #define MAX_FILE_EXTENSIONS 20
111 /* Return values for checkFontStatus */
112 enum fontStatus
{GOOD_FONT
, BAD_PRIMARY
, BAD_FONT
, BAD_SIZE
, BAD_SPACING
};
114 /* enumerated type preference strings
115 ** The order of the elements in this array must be exactly the same
116 ** as the order of the corresponding integers of the enum SearchType
117 ** defined in search.h (!!)
119 static char *SearchMethodStrings
[] = {
120 "Literal", "CaseSense", "RegExp",
121 "LiteralWord", "CaseSenseWord", "RegExpNoCase",
126 /* enumerated default scope for replace dialog if a selection exists when
127 ** the dialog is popped up.
129 static char *ReplaceDefScopeStrings
[] = {
130 "Window", "Selection", "Smart", NULL
134 #define N_WRAP_STYLES 3
135 static char *AutoWrapTypes
[N_WRAP_STYLES
+3] = {"None", "Newline", "Continuous",
136 "True", "False", NULL
};
137 #define N_INDENT_STYLES 3
138 static char *AutoIndentTypes
[N_INDENT_STYLES
+3] = {"None", "Auto",
139 "Smart", "True", "False", NULL
};
140 #define N_VIRTKEY_OVERRIDE_MODES 3
141 static char *VirtKeyOverrideModes
[N_VIRTKEY_OVERRIDE_MODES
+1] = { "Never",
142 "Auto", "Always", NULL
};
144 #define N_SHOW_MATCHING_STYLES 3
145 /* For backward compatibility, "False" and "True" are still accepted.
146 They are internally converted to "Off" and "Delimiter" respectively.
147 NOTE: N_SHOW_MATCHING_STYLES must correspond to the number of
148 _real_ matching styles, not counting False & True.
149 False and True should also be the last ones in the list. */
150 static char *ShowMatchingTypes
[] = {"Off", "Delimiter", "Range",
151 "False", "True", NULL
};
153 /* This array must be kept in parallel to the enum truncSubstitution
155 static char* TruncSubstitutionModes
[] = {"Silent", "Fail", "Warn", "Ignore", NULL
};
157 /* suplement wrap and indent styles w/ a value meaning "use default" for
158 the override fields in the language modes dialog */
159 #define DEFAULT_WRAP -1
160 #define DEFAULT_INDENT -1
161 #define DEFAULT_TAB_DIST -1
162 #define DEFAULT_EM_TAB_DIST -1
164 /* list of available language modes and language specific preferences */
165 static int NLanguageModes
= 0;
170 char *recognitionExpr
;
178 static languageModeRec
*LanguageModes
[MAX_LANGUAGE_MODES
];
180 /* Language mode dialog information */
191 Widget defaultIndentW
;
199 languageModeRec
**languageModeList
;
201 } LMDialog
= {NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,
202 NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,0};
204 /* Font dialog information */
214 Widget boldItalicErrW
;
219 /* Color dialog information */
241 /* Repository for simple preferences settings */
242 static struct prefData
{
243 int openInTab
; /* open files in new tabs */
244 int wrapStyle
; /* what kind of wrapping to do */
245 int wrapMargin
; /* 0=wrap at window width, other=wrap margin */
246 int autoIndent
; /* style for auto-indent */
247 int autoSave
; /* whether automatic backup feature is on */
248 int saveOldVersion
; /* whether to preserve a copy of last version */
249 int searchDlogs
; /* whether to show explanatory search dialogs */
250 int searchWrapBeep
; /* 1=beep when search restarts at begin/end */
251 int keepSearchDlogs
; /* whether to retain find and replace dialogs */
252 int searchWraps
; /* whether to attempt search again if reach bof or eof */
253 int statsLine
; /* whether to show the statistics line */
254 int iSearchLine
; /* whether to show the incremental search line*/
255 int tabBar
; /* whether to show the tab bar */
256 int tabBarHideOne
; /* hide tab bar if only one document in window */
257 int globalTabNavigate
; /* prev/next document across windows */
258 int toolTips
; /* whether to show the tooltips */
259 int lineNums
; /* whether to show line numbers */
260 int pathInWindowsMenu
; /* whether to show path in windows menu */
261 int warnFileMods
; /* warn user if files externally modified */
262 int warnRealFileMods
; /* only warn if file contents modified */
263 int warnExit
; /* whether to warn on exit */
264 int searchMethod
; /* initial search method as a text string */
266 int replaceDefScope
; /* default replace scope if selection exists */
268 int textRows
; /* initial window height in characters */
269 int textCols
; /* initial window width in characters */
270 int tabDist
; /* number of characters between tab stops */
271 int emTabDist
; /* non-zero tab dist. if emulated tabs are on */
272 int insertTabs
; /* whether to use tabs for padding */
273 int showMatchingStyle
; /* how to flash matching parenthesis */
274 int matchSyntaxBased
; /* use syntax info to match parenthesis */
275 int highlightSyntax
; /* whether to highlight syntax by default */
276 int smartTags
; /* look for tag in current window first */
277 int alwaysCheckRelativeTagsSpecs
; /* for every new opened file of session */
278 int stickyCaseSenseBtn
; /* whether Case Word Btn is sticky to Regex Btn */
279 int prefFileRead
; /* detects whether a .nedit existed */
280 int backlightChars
; /* whether to apply character "backlighting" */
281 char *backlightCharTypes
; /* the backlighting color definitions */
283 int shortMenus
; /* short menu mode */
285 char fontString
[MAX_FONT_LEN
]; /* names of fonts for text widget */
286 char boldFontString
[MAX_FONT_LEN
];
287 char italicFontString
[MAX_FONT_LEN
];
288 char boldItalicFontString
[MAX_FONT_LEN
];
289 XmFontList fontList
; /* XmFontLists corresp. to above named fonts */
290 XFontStruct
*boldFontStruct
;
291 XFontStruct
*italicFontStruct
;
292 XFontStruct
*boldItalicFontStruct
;
293 int sortTabs
; /* sort tabs alphabetically */
294 int repositionDialogs
; /* w. to reposition dialogs under the pointer */
295 int autoScroll
; /* w. to autoscroll near top/bottom of screen */
296 int autoScrollVPadding
; /* how close to get before autoscrolling */
297 int sortOpenPrevMenu
; /* whether to sort the "Open Previous" menu */
298 int appendLF
; /* Whether to append LF at the end of each file */
299 int mapDelete
; /* whether to map delete to backspace */
300 int stdOpenDialog
; /* w. to retain redundant text field in Open */
301 char tagFile
[MAXPATHLEN
]; /* name of tags file to look for at startup */
302 int maxPrevOpenFiles
; /* limit to size of Open Previous menu */
303 int typingHidesPointer
; /* hide mouse pointer when typing */
304 char delimiters
[MAX_WORD_DELIMITERS
]; /* punctuation characters */
305 char shell
[MAXPATHLEN
+ 1]; /* shell to use for executing commands */
306 char geometry
[MAX_GEOM_STRING_LEN
]; /* per-application geometry string,
307 only for the clueless */
308 char serverName
[MAXPATHLEN
];/* server name for multiple servers per disp. */
309 char bgMenuBtn
[MAX_ACCEL_LEN
]; /* X event description for triggering
310 posting of background menu */
311 char fileVersion
[6]; /* Version of nedit which wrote the .nedit
312 file we're reading */
313 int findReplaceUsesSelection
; /* whether the find replace dialog is automatically
314 loaded with the primary selection */
315 int virtKeyOverride
; /* Override Motif default virtual key bindings
316 never, if invalid, or always */
317 char titleFormat
[MAX_TITLE_FORMAT_LEN
];
318 char helpFontNames
[NUM_HELP_FONTS
][MAX_FONT_LEN
];/* fonts for help system */
319 char helpLinkColor
[MAX_COLOR_LEN
]; /* Color for hyperlinks in the help system */
320 char colorNames
[NUM_COLORS
][MAX_COLOR_LEN
];
321 char tooltipBgColor
[MAX_COLOR_LEN
];
322 int undoModifiesSelection
;
324 Boolean honorSymlinks
;
325 int truncSubstitution
;
326 Boolean forceOSConversion
;
329 /* Temporary storage for preferences strings which are discarded after being
339 char *smartIndentCommon
;
343 /* preference descriptions for SavePreferences and RestorePreferences. */
344 static PrefDescripRec PrefDescrip
[] = {
345 {"fileVersion", "FileVersion" , PREF_STRING
, "", PrefData
.fileVersion
,
346 (void *)sizeof(PrefData
.fileVersion
), True
},
349 {"shellCommands", "ShellCommands", PREF_ALLOC_STRING
, "spell:Alt+B:s:EX:\n\
350 cat>spellTmp; xterm -e ispell -x spellTmp; cat spellTmp; rm spellTmp\n\
351 wc::w:ED:\nwc | awk '{print $1 \" lines, \" $2 \" words, \" $3 \" characters\"}'\n\
352 sort::o:EX:\nsort\nnumber lines::n:AW:\nnl -ba\nmake:Alt+Z:m:W:\nmake\n\
353 expand::p:EX:\nexpand\nunexpand::u:EX:\nunexpand\n",
354 &TempStringPrefs
.shellCmds
, NULL
, True
},
356 {"shellCommands", "ShellCommands", PREF_ALLOC_STRING
, "spell:Alt+B:s:EX:\n\
357 cat>spellTmp; xterm -e ispell -x spellTmp; cat spellTmp; rm spellTmp\n\
358 wc::w:ED:\nwc | awk '{print $2 \" lines, \" $1 \" words, \" $3 \" characters\"}'\n\
359 sort::o:EX:\nsort\nnumber lines::n:AW:\npr -tn\nmake:Alt+Z:m:W:\nmake\n\
360 expand::p:EX:\nexpand\nunexpand::u:EX:\nunexpand\n",
361 &TempStringPrefs
.shellCmds
, NULL
, True
},
363 {"shellCommands", "ShellCommands", PREF_ALLOC_STRING
, "spell:Alt+B:s:ED:\n\
364 (cat;echo \"\") | spell\nwc::w:ED:\nwc | awk '{print $1 \" lines, \" $2 \" words, \" $3 \" characters\"}'\n\
365 \nsort::o:EX:\nsort\nnumber lines::n:AW:\nnl -ba\nmake:Alt+Z:m:W:\nmake\n\
366 expand::p:EX:\nexpand\nunexpand::u:EX:\nunexpand\n",
367 &TempStringPrefs
.shellCmds
, NULL
, True
},
368 #endif /* linux, __FreeBSD__ */
370 {"macroCommands", "MacroCommands", PREF_ALLOC_STRING
,
371 "Complete Word:Alt+D::: {\n\
372 # This macro attempts to complete the current word by\n\
373 # finding another word in the same document that has\n\
374 # the same prefix; repeated invocations of the macro\n\
375 # (by repeated typing of its accelerator, say) cycles\n\
376 # through the alternatives found.\n\
378 # Make sure $compWord contains something (a dummy index)\n\
379 $compWord[\"\"] = \"\"\n\
381 # Test whether the rest of $compWord has been initialized:\n\
382 # this avoids having to initialize the global variable\n\
383 # $compWord in an external macro file\n\
384 if (!(\"wordEnd\" in $compWord)) {\n\
385 # we need to initialize it\n\
386 $compWord[\"wordEnd\"] = 0\n\
387 $compWord[\"repeat\"] = 0\n\
388 $compWord[\"init\"] = 0\n\
389 $compWord[\"wordStart\"] = 0\n\
392 if ($compWord[\"wordEnd\"] == $cursor) {\n\
393 $compWord[\"repeat\"] += 1\n\
396 $compWord[\"repeat\"] = 1\n\
397 $compWord[\"init\"] = $cursor\n\
399 # search back to a word boundary to find the word to complete\n\
400 # (we use \\w here to allow for programming \"words\" that can include\n\
401 # digits and underscores; use \\l for letters only)\n\
402 $compWord[\"wordStart\"] = search(\"<\\\\w+\", $cursor, \"backward\", \"regex\", \"wrap\")\n\
404 if ($compWord[\"wordStart\"] == -1)\n\
407 if ($search_end == $cursor)\n\
408 $compWord[\"word\"] = get_range($compWord[\"wordStart\"], $cursor)\n\
413 for (i=0; i <= $compWord[\"repeat\"]; i++)\n\
414 s = search($compWord[\"word\"], s - 1, \"backward\", \"regex\", \"wrap\")\n\
416 if (s == $compWord[\"wordStart\"]) {\n\
418 $compWord[\"repeat\"] = 0\n\
419 s = $compWord[\"wordStart\"]\n\
420 se = $compWord[\"init\"]\n\
423 se = search(\">\", s, \"regex\")\n\
425 replace_range($compWord[\"wordStart\"], $cursor, get_range(s, se))\n\
427 $compWord[\"wordEnd\"] = $cursor\n\
429 Fill Sel. w/Char:::R: {\n\
430 # This macro replaces each character position in\n\
431 # the selection with the string typed into the dialog\n\
433 if ($selection_start == -1) {\n\
438 # Ask the user what character to fill with\n\
439 fillChar = string_dialog(\"Fill selection with what character?\", \\\n\
440 \"OK\", \"Cancel\")\n\
441 if ($string_dialog_button == 2 || $string_dialog_button == 0)\n\
444 # Count the number of lines (NL characters) in the selection\n\
445 # (by removing all non-NLs in selection and counting the remainder)\n\
446 nLines = length(replace_in_string(get_selection(), \\\n\
447 \"^.*$\", \"\", \"regex\"))\n\
449 rectangular = $selection_left != -1\n\
451 # work out the pieces of required of the replacement text\n\
452 # this will be top mid bot where top is empty or ends in NL,\n\
453 # mid is 0 or more lines of repeats ending with NL, and\n\
454 # bot is 0 or more repeats of the fillChar\n\
456 toplen = -1 # top piece by default empty (no NL)\n\
460 if (rectangular) {\n\
461 # just fill the rectangle: mid\\n \\ nLines\n\
463 # bot - last line with no nl\n\
464 midlen = $selection_right - $selection_left\n\
465 botlen = $selection_right - $selection_left\n\
468 # .........toptoptop\\n |col[0]\n\
469 # either midmidmidmidmidmid\\n \\ nLines - 1 or ...botbot...\n\
470 # midmidmidmidmidmid\\n / |col[1]\n\
472 # |col[1] |wrap margin\n\
473 # we need column positions col[0], col[1] of selection start and\n\
474 # end (use a loop and arrays to do the two positions)\n\
475 sel[0] = $selection_start\n\
476 sel[1] = $selection_end\n\
478 # col[0] = pos_to_column($selection_start)\n\
479 # col[1] = pos_to_column($selection_end)\n\
481 for (i = 0; i < 2; ++i) {\n\
483 pos = search(\"^\", end, \"regex\", \"backward\")\n\
485 while (pos < end) {\n\
486 nexttab = search(\"\\t\", pos)\n\
487 if (nexttab < 0 || nexttab >= end) {\n\
488 thisCol += end - pos # count remaining non-tabs\n\
491 thisCol += nexttab - pos + $tab_dist\n\
492 thisCol -= (thisCol % $tab_dist)\n\
494 pos = nexttab + 1 # skip past the tab or end\n\
498 toplen = max($wrap_margin - col[0], 0)\n\
499 botlen = min(col[1], $wrap_margin)\n\
501 if (nLines == 0) {\n\
503 botlen = max(botlen - col[0], 0)\n\
505 midlen = $wrap_margin\n\
508 nLines-- # top piece will end in a NL\n\
512 # Create the fill text\n\
513 # which is the longest piece? make a line of that length\n\
514 # (use string doubling - this allows the piece to be\n\
515 # appended to double in size at each iteration)\n\
517 len = max(toplen, midlen, botlen)\n\
518 charlen = length(fillChar) # maybe more than one char given!\n\
523 line = line fillChar\n\
526 fillChar = fillChar fillChar\n\
528 # assemble our pieces\n\
533 toppiece = substring(line, 0, toplen * charlen) \"\\n\"\n\
535 botpiece = substring(line, 0, botlen * charlen)\n\
537 # assemble midpiece (use doubling again)\n\
538 line = substring(line, 0, midlen * charlen) \"\\n\"\n\
539 while (nLines > 0) {\n\
541 midpiece = midpiece line\n\
546 # Replace the selection with the complete fill text\n\
547 replace_selection(toppiece midpiece botpiece)\n\
549 Quote Mail Reply:::: {\n\
550 if ($selection_start == -1)\n\
551 replace_all(\"^.*$\", \"\\\\> &\", \"regex\")\n\
553 replace_in_selection(\"^.*$\", \"\\\\> &\", \"regex\")\n\
555 Unquote Mail Reply:::: {\n\
556 if ($selection_start == -1)\n\
557 replace_all(\"(^\\\\> )(.*)$\", \"\\\\2\", \"regex\")\n\
559 replace_in_selection(\"(^\\\\> )(.*)$\", \"\\\\2\", \"regex\")\n\
561 Comments>/* Comment */@C@C++@Java@CSS@JavaScript@Lex:::R: {\n\
562 selStart = $selection_start\n\
563 selEnd = $selection_end\n\
564 replace_range(selStart, selEnd, \"/* \" get_selection() \" */\")\n\
565 select(selStart, selEnd + 6)\n\
567 Comments>/* Uncomment */@C@C++@Java@CSS@JavaScript@Lex:::R: {\n\
568 pos = search(\"(?n\\\\s*/\\\\*\\\\s*)\", $selection_start, \"regex\")\n\
569 start = $search_end\n\
570 end = search(\"(?n\\\\*/\\\\s*)\", $selection_end, \"regex\", \"backward\")\n\
571 if (pos != $selection_start || end == -1 )\n\
573 replace_selection(get_range(start, end))\n\
574 select(pos, $cursor)\n\
576 Comments>// Comment@C@C++@Java@JavaScript:::R: {\n\
577 replace_in_selection(\"^.*$\", \"// &\", \"regex\")\n\
579 Comments>// Uncomment@C@C++@Java@JavaScript:::R: {\n\
580 replace_in_selection(\"(^[ \\\\t]*// ?)(.*)$\", \"\\\\2\", \"regex\")\n\
582 Comments># Comment@Perl@Sh Ksh Bash@NEdit Macro@Makefile@Awk@Csh@Python@Tcl:::R: {\n\
583 replace_in_selection(\"^.*$\", \"#&\", \"regex\")\n\
585 Comments># Uncomment@Perl@Sh Ksh Bash@NEdit Macro@Makefile@Awk@Csh@Python@Tcl:::R: {\n\
586 replace_in_selection(\"(^[ \\\\t]*#)(.*)$\", \"\\\\2\", \"regex\")\n\
588 Comments>-- Comment@SQL:::R: {\n\
589 replace_in_selection(\"^.*$\", \"--&\", \"regex\")\n\
591 Comments>-- Uncomment@SQL:::R: {\n\
592 replace_in_selection(\"(^[ \\\\t]*--)(.*)$\", \"\\\\2\", \"regex\")\n\
594 Comments>! Comment@X Resources:::R: {\n\
595 replace_in_selection(\"^.*$\", \"!&\", \"regex\")\n\
597 Comments>! Uncomment@X Resources:::R: {\n\
598 replace_in_selection(\"(^[ \\\\t]*!)(.*)$\", \"\\\\2\", \"regex\")\n\
600 Comments>% Comment@LaTeX:::R: {\n\
601 replace_in_selection(\"^.*$\", \"%&\", \"regex\")\n\
603 Comments>% Uncomment@LaTeX:::R: {\n\
604 replace_in_selection(\"(^[ \\\\t]*%)(.*)$\", \"\\\\2\", \"regex\")\n\
606 Comments>Bar Comment@C:::R: {\n\
607 if ($selection_left != -1) {\n\
608 dialog(\"Selection must not be rectangular\")\n\
611 start = $selection_start\n\
612 end = $selection_end-1\n\
613 origText = get_range($selection_start, $selection_end-1)\n\
614 newText = \"/*\\n\" replace_in_string(get_range(start, end), \\\n\
615 \"^\", \" * \", \"regex\") \"\\n */\\n\"\n\
616 replace_selection(newText)\n\
617 select(start, start + length(newText))\n\
619 Comments>Bar Uncomment@C:::R: {\n\
620 selStart = $selection_start\n\
621 selEnd = $selection_end\n\
622 pos = search(\"/\\\\*\\\\s*\\\\n\", selStart, \"regex\")\n\
623 if (pos != selStart) return\n\
624 start = $search_end\n\
625 end = search(\"\\\\n\\\\s*\\\\*/\\\\s*\\\\n?\", selEnd, \"regex\", \"backward\")\n\
626 if (end == -1 || $search_end < selEnd) return\n\
627 newText = get_range(start, end)\n\
628 newText = replace_in_string(newText,\"^ *\\\\* ?\", \"\", \"regex\", \"copy\")\n\
629 if (get_range(selEnd, selEnd - 1) == \"\\n\") selEnd -= 1\n\
630 replace_range(selStart, selEnd, newText)\n\
631 select(selStart, selStart + length(newText))\n\
633 Make C Prototypes@C@C++:::: {\n\
634 # simplistic extraction of C function prototypes, usually good enough\n\
635 if ($selection_start == -1) {\n\
637 end = $text_length\n\
639 start = $selection_start\n\
640 end = $selection_end\n\
642 string = get_range(start, end)\n\
643 # remove all C++ and C comments, then all blank lines in the extracted range\n\
644 string = replace_in_string(string, \"//.*$\", \"\", \"regex\", \"copy\")\n\
645 string = replace_in_string(string, \"(?n/\\\\*.*?\\\\*/)\", \"\", \"regex\", \"copy\")\n\
646 string = replace_in_string(string, \"^\\\\s*\\n\", \"\", \"regex\", \"copy\")\n\
650 staticPrototypes = \"\"\n\
652 headerStart = search_string(string, \\\n\
653 \"^[a-zA-Z]([^;#\\\"'{}=><!/]|\\n)*\\\\)[ \\t]*\\n?[ \\t]*\\\\{\", \\\n\
654 searchPos, \"regex\")\n\
655 if (headerStart == -1)\n\
657 headerEnd = search_string(string, \")\", $search_end,\"backward\") + 1\n\
658 prototype = substring(string, headerStart, headerEnd) \";\\n\"\n\
659 if (substring(string, headerStart, headerStart+6) == \"static\")\n\
660 staticPrototypes = staticPrototypes prototype\n\
662 prototypes = prototypes prototype\n\
663 searchPos = headerEnd\n\
667 dialog(\"No function declarations found\")\n\
671 focus_window(\"last\")\n\
672 replace_range(0, 0, prototypes staticPrototypes)\n\
673 }", &TempStringPrefs
.macroCmds
, NULL
, True
},
674 {"bgMenuCommands", "BGMenuCommands", PREF_ALLOC_STRING
,
675 "Undo:::: {\nundo()\n}\n\
676 Redo:::: {\nredo()\n}\n\
677 Cut:::R: {\ncut_clipboard()\n}\n\
678 Copy:::R: {\ncopy_clipboard()\n}\n\
679 Paste:::: {\npaste_clipboard()\n}", &TempStringPrefs
.bgMenuCmds
,
682 /* The VAX compiler can't compile Java-Script's definition in highlightData.c */
683 {"highlightPatterns", "HighlightPatterns", PREF_ALLOC_STRING
,
696 NEdit Macro:Default\n\
699 PostScript:Default\n\
704 Sh Ksh Bash:Default\n\
709 X Resources:Default\n\
711 &TempStringPrefs
.highlight
, NULL
, True
},
712 {"languageModes", "LanguageModes", PREF_ALLOC_STRING
,
714 {"highlightPatterns", "HighlightPatterns", PREF_ALLOC_STRING
,
723 JavaScript:Default\n\
728 NEdit Macro:Default\n\
731 PostScript:Default\n\
736 Sh Ksh Bash:Default\n\
741 X Resources:Default\n\
743 &TempStringPrefs
.highlight
, NULL
, True
},
744 {"languageModes", "LanguageModes", PREF_ALLOC_STRING
,
747 /* TODO: Some tests indicate that these have to be upper case, but what about
748 the PostScript pattern then? How does VMS handle caseness anyway? */
749 "Ada:.ADA .AD .ADS .ADB .A:::::::\n\
751 C++:.CC .HH .C .H .I .CXX .HXX .CPP::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":\n\
752 C:.C .H::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":\n\
753 CSS:CSS::Auto:None:::\".,/\\`'!|@#%^&*()=+{}[]\"\":;<>?~\":\n\
754 Csh:.CSH .CSHRC .TCSHRC .LOGIN .LOGOUT:\"^[ \\t]*#[ \\t]*![ \\t]*/bin/t?csh\"::::::\n\
755 Fortran:.F .F77 .FOR:::::::\n\
757 LaTeX:.TEX .STY .CLS .LTX .INS .CLO .FD:::::::\n\
759 Makefile:MAKEFILE:::None:8:8::\n\
760 Matlab:.M .OCT .SCI:::::::\n\
761 NEdit Macro:.NM .NEDITMACRO:::::::\n\
762 Pascal:.PAS .P .INT:::::::\n\
763 Perl:.PL .PM .P5:\"^[ \\t]*#[ \\t]*!.*perl\":Auto:None:::\".,/\\\\`'!$@#%^&*()-=+{}[]\"\":;<>?~|\":\n\
764 PostScript:.ps .PS .eps .EPS .epsf .epsi:\"^%!\":::::\"/%(){}[]<>\":\n\
765 Python:.PY:\"^#!.*python\":Auto:None:::\"!\"\"#$%&'()*+,-./:;<=>?@[\\\\]^`{|}~\":\n\
766 Regex:.REG .REGEX:\"\\(\\?[:#=!iInN].+\\)\":None:Continuous::::\n\
767 SGML HTML:.SGML .SGM .HTML .HTM:\"\\<[Hh][Tt][Mm][Ll]\\>\"::::::\n\
769 Sh Ksh Bash:.SH .BASH .KSH .PROFILE .BASHRC .BASH_LOGOUT .BASH_LOGIN .BASH_PROFILE:\"^[ \\t]*#[ \\t]*![ \\t]*/.*bin/(bash|ksh|sh|zsh)\"::::::\n\
770 Tcl:.TCL::Smart:None::::\n\
771 VHDL:.VHD .VHDL .VDL:::::::\n\
773 XML:.XML .XSL .DTD:\"\\<(?i\\?xml|!doctype)\"::None:::\"<>/=\"\"'()+*?|\":\n\
774 X Resources:.XRESOURCES .XDEFAULTS .NEDIT .PATS NEDIT.RC:\"^[!#].*([Aa]pp|[Xx]).*[Dd]efaults\"::::::\n\
775 Yacc:.Y::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":",
777 "Ada:.ada .ad .ads .adb .a:::::::\n\
779 C++:.cc .hh .C .H .i .cxx .hxx .cpp .c++::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":\n\
780 C:.c .h::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":\n\
781 CSS:css::Auto:None:::\".,/\\`'!|@#%^&*()=+{}[]\"\":;<>?~\":\n\
782 Csh:.csh .cshrc .tcshrc .login .logout:\"^[ \\t]*#[ \\t]*![ \\t]*/bin/t?csh\"::::::\n\
783 Fortran:.f .f77 .for:::::::\n\
785 JavaScript:.js:::::::\n\
786 LaTeX:.tex .sty .cls .ltx .ins .clo .fd:::::::\n\
788 Makefile:Makefile makefile .gmk:::None:8:8::\n\
789 Matlab:.m .oct .sci:::::::\n\
790 NEdit Macro:.nm .neditmacro:::::::\n\
791 Pascal:.pas .p .int:::::::\n\
792 Perl:.pl .pm .p5 .PL:\"^[ \\t]*#[ \\t]*!.*perl\":Auto:None:::\".,/\\\\`'!$@#%^&*()-=+{}[]\"\":;<>?~|\":\n\
793 PostScript:.ps .eps .epsf .epsi:\"^%!\":::::\"/%(){}[]<>\":\n\
794 Python:.py:\"^#!.*python\":Auto:None:::\"!\"\"#$%&'()*+,-./:;<=>?@[\\\\]^`{|}~\":\n\
795 Regex:.reg .regex:\"\\(\\?[:#=!iInN].+\\)\":None:Continuous::::\n\
796 SGML HTML:.sgml .sgm .html .htm:\"\\<[Hh][Tt][Mm][Ll]\\>\"::::::\n\
798 Sh Ksh Bash:.sh .bash .ksh .profile .bashrc .bash_logout .bash_login .bash_profile:\"^[ \\t]*#[ \\t]*![ \\t]*/.*bin/(bash|ksh|sh|zsh)\"::::::\n\
799 Tcl:.tcl .tk .itcl .itk::Smart:None::::\n\
800 VHDL:.vhd .vhdl .vdl:::::::\n\
802 XML:.xml .xsl .dtd:\"\\<(?i\\?xml|!doctype)\"::None:::\"<>/=\"\"'()+*?|\":\n\
803 X Resources:.Xresources .Xdefaults .nedit .pats nedit.rc:\"^[!#].*([Aa]pp|[Xx]).*[Dd]efaults\"::::::\n\
804 Yacc:.y::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\":",
806 &TempStringPrefs
.language
, NULL
, True
},
807 {"styles", "Styles", PREF_ALLOC_STRING
, "Plain:black:Plain\n\
808 Comment:gray20:Italic\n\
809 Keyword:black:Bold\n\
810 Operator:dark blue:Bold\n\
811 Bracket:dark blue:Bold\n\
812 Storage Type:brown:Bold\n\
813 Storage Type1:saddle brown:Bold\n\
814 String:darkGreen:Plain\n\
815 String1:SeaGreen:Plain\n\
816 String2:darkGreen:Bold\n\
817 Preprocessor:RoyalBlue4:Plain\n\
818 Preprocessor1:blue:Plain\n\
819 Character Const:darkGreen:Plain\n\
820 Numeric Const:darkGreen:Plain\n\
821 Identifier:brown:Plain\n\
822 Identifier1:RoyalBlue4:Plain\n\
823 Identifier2:SteelBlue:Plain\n\
824 Subroutine:brown:Plain\n\
825 Subroutine1:chocolate:Plain\n\
826 Ada Attributes:plum:Bold\n\
829 Text Comment:SteelBlue4:Italic\n\
830 Text Key:VioletRed4:Bold\n\
831 Text Key1:VioletRed4:Plain\n\
832 Text Arg:RoyalBlue4:Bold\n\
833 Text Arg1:SteelBlue4:Bold\n\
834 Text Arg2:RoyalBlue4:Plain\n\
835 Text Escape:gray30:Bold\n\
836 LaTeX Math:darkGreen:Plain\n"
838 &TempStringPrefs
.styles
, NULL
, True
},
839 {"smartIndentInit", "SmartIndentInit", PREF_ALLOC_STRING
,
843 Matlab:Default", &TempStringPrefs
.smartIndent
, NULL
, True
},
844 {"smartIndentInitCommon", "SmartIndentInitCommon", PREF_ALLOC_STRING
,
845 "Default", &TempStringPrefs
.smartIndentCommon
, NULL
, True
},
846 {"autoWrap", "AutoWrap", PREF_ENUM
, "Continuous",
847 &PrefData
.wrapStyle
, AutoWrapTypes
, True
},
848 {"wrapMargin", "WrapMargin", PREF_INT
, "0",
849 &PrefData
.wrapMargin
, NULL
, True
},
850 {"autoIndent", "AutoIndent", PREF_ENUM
, "Auto",
851 &PrefData
.autoIndent
, AutoIndentTypes
, True
},
852 {"autoSave", "AutoSave", PREF_BOOLEAN
, "True",
853 &PrefData
.autoSave
, NULL
, True
},
854 {"openInTab", "OpenInTab", PREF_BOOLEAN
, "True",
855 &PrefData
.openInTab
, NULL
, True
},
856 {"saveOldVersion", "SaveOldVersion", PREF_BOOLEAN
, "False",
857 &PrefData
.saveOldVersion
, NULL
, True
},
858 {"showMatching", "ShowMatching", PREF_ENUM
, "Delimiter",
859 &PrefData
.showMatchingStyle
, ShowMatchingTypes
, True
},
860 {"matchSyntaxBased", "MatchSyntaxBased", PREF_BOOLEAN
, "True",
861 &PrefData
.matchSyntaxBased
, NULL
, True
},
862 {"highlightSyntax", "HighlightSyntax", PREF_BOOLEAN
, "True",
863 &PrefData
.highlightSyntax
, NULL
, True
},
864 {"backlightChars", "BacklightChars", PREF_BOOLEAN
, "False",
865 &PrefData
.backlightChars
, NULL
, True
},
866 {"backlightCharTypes", "BacklightCharTypes", PREF_ALLOC_STRING
,
867 "0-8,10-31,127:red;9:#dedede;32,160-255:#f0f0f0;128-159:orange",
869 &PrefData
.backlightCharTypes
, NULL
, False
},
870 {"searchDialogs", "SearchDialogs", PREF_BOOLEAN
, "False",
871 &PrefData
.searchDlogs
, NULL
, True
},
872 {"beepOnSearchWrap", "BeepOnSearchWrap", PREF_BOOLEAN
, "False",
873 &PrefData
.searchWrapBeep
, NULL
, True
},
874 {"retainSearchDialogs", "RetainSearchDialogs", PREF_BOOLEAN
, "False",
875 &PrefData
.keepSearchDlogs
, NULL
, True
},
876 {"searchWraps", "SearchWraps", PREF_BOOLEAN
, "True",
877 &PrefData
.searchWraps
, NULL
, True
},
878 {"stickyCaseSenseButton", "StickyCaseSenseButton", PREF_BOOLEAN
, "True",
879 &PrefData
.stickyCaseSenseBtn
, NULL
, True
},
880 #if XmVersion < 1002 /* Flashing is annoying in 1.1 versions */
881 {"repositionDialogs", "RepositionDialogs", PREF_BOOLEAN
, "False",
882 &PrefData
.repositionDialogs
, NULL
, True
},
884 {"repositionDialogs", "RepositionDialogs", PREF_BOOLEAN
, "True",
885 &PrefData
.repositionDialogs
, NULL
, True
},
887 {"autoScroll", "AutoScroll", PREF_BOOLEAN
, "False",
888 &PrefData
.autoScroll
, NULL
, True
},
889 {"autoScrollVPadding", "AutoScrollVPadding", PREF_INT
, "4",
890 &PrefData
.autoScrollVPadding
, NULL
, False
},
891 {"appendLF", "AppendLF", PREF_BOOLEAN
, "True",
892 &PrefData
.appendLF
, NULL
, True
},
893 {"sortOpenPrevMenu", "SortOpenPrevMenu", PREF_BOOLEAN
, "True",
894 &PrefData
.sortOpenPrevMenu
, NULL
, True
},
895 {"statisticsLine", "StatisticsLine", PREF_BOOLEAN
, "False",
896 &PrefData
.statsLine
, NULL
, True
},
897 {"iSearchLine", "ISearchLine", PREF_BOOLEAN
, "False",
898 &PrefData
.iSearchLine
, NULL
, True
},
899 {"sortTabs", "SortTabs", PREF_BOOLEAN
, "False",
900 &PrefData
.sortTabs
, NULL
, True
},
901 {"tabBar", "TabBar", PREF_BOOLEAN
, "True",
902 &PrefData
.tabBar
, NULL
, True
},
903 {"tabBarHideOne", "TabBarHideOne", PREF_BOOLEAN
, "True",
904 &PrefData
.tabBarHideOne
, NULL
, True
},
905 {"toolTips", "ToolTips", PREF_BOOLEAN
, "True",
906 &PrefData
.toolTips
, NULL
, True
},
907 {"globalTabNavigate", "GlobalTabNavigate", PREF_BOOLEAN
, "False",
908 &PrefData
.globalTabNavigate
, NULL
, True
},
909 {"lineNumbers", "LineNumbers", PREF_BOOLEAN
, "False",
910 &PrefData
.lineNums
, NULL
, True
},
911 {"pathInWindowsMenu", "PathInWindowsMenu", PREF_BOOLEAN
, "True",
912 &PrefData
.pathInWindowsMenu
, NULL
, True
},
913 {"warnFileMods", "WarnFileMods", PREF_BOOLEAN
, "True",
914 &PrefData
.warnFileMods
, NULL
, True
},
915 {"warnRealFileMods", "WarnRealFileMods", PREF_BOOLEAN
, "True",
916 &PrefData
.warnRealFileMods
, NULL
, True
},
917 {"warnExit", "WarnExit", PREF_BOOLEAN
, "True",
918 &PrefData
.warnExit
, NULL
, True
},
919 {"searchMethod", "SearchMethod", PREF_ENUM
, "Literal",
920 &PrefData
.searchMethod
, SearchMethodStrings
, True
},
922 {"replaceDefaultScope", "ReplaceDefaultScope", PREF_ENUM
, "Smart",
923 &PrefData
.replaceDefScope
, ReplaceDefScopeStrings
, True
},
925 {"textRows", "TextRows", PREF_INT
, "24",
926 &PrefData
.textRows
, NULL
, True
},
927 {"textCols", "TextCols", PREF_INT
, "80",
928 &PrefData
.textCols
, NULL
, True
},
929 {"tabDistance", "TabDistance", PREF_INT
, "8",
930 &PrefData
.tabDist
, NULL
, True
},
931 {"emulateTabs", "EmulateTabs", PREF_INT
, "0",
932 &PrefData
.emTabDist
, NULL
, True
},
933 {"insertTabs", "InsertTabs", PREF_BOOLEAN
, "True",
934 &PrefData
.insertTabs
, NULL
, True
},
935 {"textFont", "TextFont", PREF_STRING
,
936 "-*-courier-medium-r-normal--*-120-*-*-*-iso8859-1",
937 PrefData
.fontString
, (void *)sizeof(PrefData
.fontString
), True
},
938 {"boldHighlightFont", "BoldHighlightFont", PREF_STRING
,
939 "-*-courier-bold-r-normal--*-120-*-*-*-iso8859-1",
940 PrefData
.boldFontString
, (void *)sizeof(PrefData
.boldFontString
), True
},
941 {"italicHighlightFont", "ItalicHighlightFont", PREF_STRING
,
942 "-*-courier-medium-o-normal--*-120-*-*-*-iso8859-1",
943 PrefData
.italicFontString
,
944 (void *)sizeof(PrefData
.italicFontString
), True
},
945 {"boldItalicHighlightFont", "BoldItalicHighlightFont", PREF_STRING
,
946 "-*-courier-bold-o-normal--*-120-*-*-*-iso8859-1",
947 PrefData
.boldItalicFontString
,
948 (void *)sizeof(PrefData
.boldItalicFontString
), True
},
949 {"helpFont", "HelpFont", PREF_STRING
,
950 "-*-helvetica-medium-r-normal--*-120-*-*-*-iso8859-1",
951 PrefData
.helpFontNames
[HELP_FONT
],
952 (void *)sizeof(PrefData
.helpFontNames
[HELP_FONT
]), False
},
953 {"boldHelpFont", "BoldHelpFont", PREF_STRING
,
954 "-*-helvetica-bold-r-normal--*-120-*-*-*-iso8859-1",
955 PrefData
.helpFontNames
[BOLD_HELP_FONT
],
956 (void *)sizeof(PrefData
.helpFontNames
[BOLD_HELP_FONT
]), False
},
957 {"italicHelpFont", "ItalicHelpFont", PREF_STRING
,
958 "-*-helvetica-medium-o-normal--*-120-*-*-*-iso8859-1",
959 PrefData
.helpFontNames
[ITALIC_HELP_FONT
],
960 (void *)sizeof(PrefData
.helpFontNames
[ITALIC_HELP_FONT
]), False
},
961 {"boldItalicHelpFont", "BoldItalicHelpFont", PREF_STRING
,
962 "-*-helvetica-bold-o-normal--*-120-*-*-*-iso8859-1",
963 PrefData
.helpFontNames
[BOLD_ITALIC_HELP_FONT
],
964 (void *)sizeof(PrefData
.helpFontNames
[BOLD_ITALIC_HELP_FONT
]), False
},
965 {"fixedHelpFont", "FixedHelpFont", PREF_STRING
,
966 "-*-courier-medium-r-normal--*-120-*-*-*-iso8859-1",
967 PrefData
.helpFontNames
[FIXED_HELP_FONT
],
968 (void *)sizeof(PrefData
.helpFontNames
[FIXED_HELP_FONT
]), False
},
969 {"boldFixedHelpFont", "BoldFixedHelpFont", PREF_STRING
,
970 "-*-courier-bold-r-normal--*-120-*-*-*-iso8859-1",
971 PrefData
.helpFontNames
[BOLD_FIXED_HELP_FONT
],
972 (void *)sizeof(PrefData
.helpFontNames
[BOLD_FIXED_HELP_FONT
]), False
},
973 {"italicFixedHelpFont", "ItalicFixedHelpFont", PREF_STRING
,
974 "-*-courier-medium-o-normal--*-120-*-*-*-iso8859-1",
975 PrefData
.helpFontNames
[ITALIC_FIXED_HELP_FONT
],
976 (void *)sizeof(PrefData
.helpFontNames
[ITALIC_FIXED_HELP_FONT
]), False
},
977 {"boldItalicFixedHelpFont", "BoldItalicFixedHelpFont", PREF_STRING
,
978 "-*-courier-bold-o-normal--*-120-*-*-*-iso8859-1",
979 PrefData
.helpFontNames
[BOLD_ITALIC_FIXED_HELP_FONT
],
980 (void *)sizeof(PrefData
.helpFontNames
[BOLD_ITALIC_FIXED_HELP_FONT
]), False
},
981 {"helpLinkFont", "HelpLinkFont", PREF_STRING
,
982 "-*-helvetica-medium-r-normal--*-120-*-*-*-iso8859-1",
983 PrefData
.helpFontNames
[HELP_LINK_FONT
],
984 (void *)sizeof(PrefData
.helpFontNames
[HELP_LINK_FONT
]), False
},
985 {"h1HelpFont", "H1HelpFont", PREF_STRING
,
986 "-*-helvetica-bold-r-normal--*-140-*-*-*-iso8859-1",
987 PrefData
.helpFontNames
[H1_HELP_FONT
],
988 (void *)sizeof(PrefData
.helpFontNames
[H1_HELP_FONT
]), False
},
989 {"h2HelpFont", "H2HelpFont", PREF_STRING
,
990 "-*-helvetica-bold-o-normal--*-120-*-*-*-iso8859-1",
991 PrefData
.helpFontNames
[H2_HELP_FONT
],
992 (void *)sizeof(PrefData
.helpFontNames
[H2_HELP_FONT
]), False
},
993 {"h3HelpFont", "H3HelpFont", PREF_STRING
,
994 "-*-courier-bold-r-normal--*-120-*-*-*-iso8859-1",
995 PrefData
.helpFontNames
[H3_HELP_FONT
],
996 (void *)sizeof(PrefData
.helpFontNames
[H3_HELP_FONT
]), False
},
997 {"helpLinkColor", "HelpLinkColor", PREF_STRING
, "#009900",
998 PrefData
.helpLinkColor
,
999 (void *)sizeof(PrefData
.helpLinkColor
), False
},
1001 {"textFgColor", "TextFgColor", PREF_STRING
, NEDIT_DEFAULT_FG
,
1002 PrefData
.colorNames
[TEXT_FG_COLOR
],
1003 (void *)sizeof(PrefData
.colorNames
[TEXT_FG_COLOR
]), True
},
1004 {"textBgColor", "TextBgColor", PREF_STRING
, NEDIT_DEFAULT_TEXT_BG
,
1005 PrefData
.colorNames
[TEXT_BG_COLOR
],
1006 (void *)sizeof(PrefData
.colorNames
[TEXT_BG_COLOR
]), True
},
1007 {"selectFgColor", "SelectFgColor", PREF_STRING
, NEDIT_DEFAULT_SEL_FG
,
1008 PrefData
.colorNames
[SELECT_FG_COLOR
],
1009 (void *)sizeof(PrefData
.colorNames
[SELECT_FG_COLOR
]), True
},
1010 {"selectBgColor", "SelectBgColor", PREF_STRING
, NEDIT_DEFAULT_SEL_BG
,
1011 PrefData
.colorNames
[SELECT_BG_COLOR
],
1012 (void *)sizeof(PrefData
.colorNames
[SELECT_BG_COLOR
]), True
},
1013 {"hiliteFgColor", "HiliteFgColor", PREF_STRING
, NEDIT_DEFAULT_HI_FG
,
1014 PrefData
.colorNames
[HILITE_FG_COLOR
],
1015 (void *)sizeof(PrefData
.colorNames
[HILITE_FG_COLOR
]), True
},
1016 {"hiliteBgColor", "HiliteBgColor", PREF_STRING
, NEDIT_DEFAULT_HI_BG
,
1017 PrefData
.colorNames
[HILITE_BG_COLOR
],
1018 (void *)sizeof(PrefData
.colorNames
[HILITE_BG_COLOR
]), True
},
1019 {"lineNoFgColor", "LineNoFgColor", PREF_STRING
, NEDIT_DEFAULT_LINENO_FG
,
1020 PrefData
.colorNames
[LINENO_FG_COLOR
],
1021 (void *)sizeof(PrefData
.colorNames
[LINENO_FG_COLOR
]), True
},
1022 {"cursorFgColor", "CursorFgColor", PREF_STRING
, NEDIT_DEFAULT_CURSOR_FG
,
1023 PrefData
.colorNames
[CURSOR_FG_COLOR
],
1024 (void *)sizeof(PrefData
.colorNames
[CURSOR_FG_COLOR
]), True
},
1025 {"tooltipBgColor", "TooltipBgColor", PREF_STRING
, "LemonChiffon1",
1026 PrefData
.tooltipBgColor
,
1027 (void *)sizeof(PrefData
.tooltipBgColor
), False
},
1028 {"shell", "Shell", PREF_STRING
, "DEFAULT", PrefData
.shell
,
1029 (void*) sizeof(PrefData
.shell
), True
},
1030 {"geometry", "Geometry", PREF_STRING
, "",
1031 PrefData
.geometry
, (void *)sizeof(PrefData
.geometry
), False
},
1032 {"remapDeleteKey", "RemapDeleteKey", PREF_BOOLEAN
, "False",
1033 &PrefData
.mapDelete
, NULL
, False
},
1034 {"stdOpenDialog", "StdOpenDialog", PREF_BOOLEAN
, "False",
1035 &PrefData
.stdOpenDialog
, NULL
, False
},
1036 {"tagFile", "TagFile", PREF_STRING
,
1037 "", PrefData
.tagFile
, (void *)sizeof(PrefData
.tagFile
), False
},
1038 {"wordDelimiters", "WordDelimiters", PREF_STRING
,
1039 ".,/\\`'!|@#%^&*()-=+{}[]\":;<>?",
1040 PrefData
.delimiters
, (void *)sizeof(PrefData
.delimiters
), False
},
1041 {"serverName", "ServerName", PREF_STRING
, "", PrefData
.serverName
,
1042 (void *)sizeof(PrefData
.serverName
), False
},
1043 {"maxPrevOpenFiles", "MaxPrevOpenFiles", PREF_INT
, "30",
1044 &PrefData
.maxPrevOpenFiles
, NULL
, False
},
1045 {"bgMenuButton", "BGMenuButton" , PREF_STRING
,
1046 "~Shift~Ctrl~Meta~Alt<Btn3Down>", PrefData
.bgMenuBtn
,
1047 (void *)sizeof(PrefData
.bgMenuBtn
), False
},
1048 {"smartTags", "SmartTags", PREF_BOOLEAN
, "True",
1049 &PrefData
.smartTags
, NULL
, True
},
1050 {"typingHidesPointer", "TypingHidesPointer", PREF_BOOLEAN
, "False",
1051 &PrefData
.typingHidesPointer
, NULL
, False
},
1052 {"alwaysCheckRelativeTagsSpecs", "AlwaysCheckRelativeTagsSpecs",
1053 PREF_BOOLEAN
, "True", &PrefData
.alwaysCheckRelativeTagsSpecs
, NULL
, False
},
1054 {"prefFileRead", "PrefFileRead", PREF_BOOLEAN
, "False",
1055 &PrefData
.prefFileRead
, NULL
, True
},
1057 {"shortMenus", "ShortMenus", PREF_BOOLEAN
, "False", &PrefData
.shortMenus
,
1060 {"findReplaceUsesSelection", "FindReplaceUsesSelection", PREF_BOOLEAN
, "False",
1061 &PrefData
.findReplaceUsesSelection
, NULL
, False
},
1062 {"overrideDefaultVirtualKeyBindings", "OverrideDefaultVirtualKeyBindings",
1063 PREF_ENUM
, "Auto", &PrefData
.virtKeyOverride
, VirtKeyOverrideModes
, False
},
1064 {"titleFormat", "TitleFormat", PREF_STRING
, "{%c} [%s] %f (%S) - %d",
1065 PrefData
.titleFormat
, (void *)sizeof(PrefData
.titleFormat
), True
},
1066 {"undoModifiesSelection", "UndoModifiesSelection", PREF_BOOLEAN
,
1067 "True", &PrefData
.undoModifiesSelection
, NULL
, False
},
1068 {"focusOnRaise", "FocusOnRaise", PREF_BOOLEAN
,
1069 "False", &PrefData
.focusOnRaise
, NULL
, False
},
1070 {"forceOSConversion", "ForceOSConversion", PREF_BOOLEAN
, "True",
1071 &PrefData
.forceOSConversion
, NULL
, False
},
1072 {"truncSubstitution", "TruncSubstitution", PREF_ENUM
, "Fail",
1073 &PrefData
.truncSubstitution
, TruncSubstitutionModes
, False
},
1074 {"honorSymlinks", "HonorSymlinks", PREF_BOOLEAN
, "True",
1075 &PrefData
.honorSymlinks
, NULL
, False
}
1078 static XrmOptionDescRec OpTable
[] = {
1079 {"-wrap", ".autoWrap", XrmoptionNoArg
, (caddr_t
)"Continuous"},
1080 {"-nowrap", ".autoWrap", XrmoptionNoArg
, (caddr_t
)"None"},
1081 {"-autowrap", ".autoWrap", XrmoptionNoArg
, (caddr_t
)"Newline"},
1082 {"-noautowrap", ".autoWrap", XrmoptionNoArg
, (caddr_t
)"None"},
1083 {"-autoindent", ".autoIndent", XrmoptionNoArg
, (caddr_t
)"Auto"},
1084 {"-noautoindent", ".autoIndent", XrmoptionNoArg
, (caddr_t
)"False"},
1085 {"-autosave", ".autoSave", XrmoptionNoArg
, (caddr_t
)"True"},
1086 {"-noautosave", ".autoSave", XrmoptionNoArg
, (caddr_t
)"False"},
1087 {"-rows", ".textRows", XrmoptionSepArg
, (caddr_t
)NULL
},
1088 {"-columns", ".textCols", XrmoptionSepArg
, (caddr_t
)NULL
},
1089 {"-tabs", ".tabDistance", XrmoptionSepArg
, (caddr_t
)NULL
},
1090 {"-font", ".textFont", XrmoptionSepArg
, (caddr_t
)NULL
},
1091 {"-fn", ".textFont", XrmoptionSepArg
, (caddr_t
)NULL
},
1092 {"-svrname", ".serverName", XrmoptionSepArg
, (caddr_t
)NULL
},
1095 static const char HeaderText
[] = "\
1096 ! Preferences file for NEdit\n\
1097 ! (User settings in X \"application defaults\" format)\n\
1099 ! This file is overwritten by the \"Save Defaults...\" command in NEdit\n\
1100 ! and serves only the interactively settable options presented in the NEdit\n\
1101 ! \"Preferences\" menu. To modify other options, such as key bindings, use\n\
1102 ! the .Xdefaults file in your home directory (or the X resource\n\
1103 ! specification method appropriate to your system). The contents of this\n\
1104 ! file can be moved into an X resource file, but since resources in this file\n\
1105 ! override their corresponding X resources, either this file should be \n\
1106 ! deleted or individual resource lines in the file should be deleted for the\n\
1107 ! moved lines to take effect.\n";
1109 /* Module-global variable set when any preference changes (for asking the
1110 user about re-saving on exit) */
1111 static int PrefsHaveChanged
= False
;
1113 /* Module-global variable set when user uses -import to load additional
1114 preferences on top of the defaults. Contains name of file loaded */
1115 static char *ImportedFile
= NULL
;
1117 /* Module-global variables to support Initial Window Size... dialog */
1118 static int DoneWithSizeDialog
;
1119 static Widget RowText
, ColText
;
1121 /* Module-global variables for Tabs dialog */
1122 static int DoneWithTabsDialog
;
1123 static WindowInfo
*TabsDialogForWindow
;
1124 static Widget TabDistText
, EmTabText
, EmTabToggle
, UseTabsToggle
, EmTabLabel
;
1126 /* Module-global variables for Wrap Margin dialog */
1127 static int DoneWithWrapDialog
;
1128 static WindowInfo
*WrapDialogForWindow
;
1129 static Widget WrapText
, WrapTextLabel
, WrapWindowToggle
;
1131 /* Module-global variables for shell selection dialog */
1132 static int DoneWithShellSelDialog
= False
;
1134 static void translatePrefFormats(int convertOld
, int fileVer
);
1135 static void setIntPref(int *prefDataField
, int newValue
);
1136 static void setStringPref(char *prefDataField
, const char *newValue
);
1137 static void sizeOKCB(Widget w
, XtPointer clientData
, XtPointer callData
);
1138 static void setStringAllocPref(char **pprefDataField
, char *newValue
);
1139 static void sizeCancelCB(Widget w
, XtPointer clientData
, XtPointer callData
);
1140 static void tabsOKCB(Widget w
, XtPointer clientData
, XtPointer callData
);
1141 static void tabsCancelCB(Widget w
, XtPointer clientData
, XtPointer callData
);
1142 static void tabsHelpCB(Widget w
, XtPointer clientData
, XtPointer callData
);
1143 static void emTabsCB(Widget w
, XtPointer clientData
, XtPointer callData
);
1144 static void wrapOKCB(Widget w
, XtPointer clientData
, XtPointer callData
);
1145 static void wrapCancelCB(Widget w
, XtPointer clientData
, XtPointer callData
);
1146 static void wrapWindowCB(Widget w
, XtPointer clientData
, XtPointer callData
);
1147 static void shellSelOKCB(Widget widget
, XtPointer clientData
,
1148 XtPointer callData
);
1149 static void shellSelCancelCB(Widget widgget
, XtPointer clientData
,
1150 XtPointer callData
);
1151 static void reapplyLanguageMode(WindowInfo
*window
, int mode
,int forceDefaults
);
1153 static void fillFromPrimaryCB(Widget w
, XtPointer clientData
,
1154 XtPointer callData
);
1155 static int checkFontStatus(fontDialog
*fd
, Widget fontTextFieldW
);
1156 static int showFontStatus(fontDialog
*fd
, Widget fontTextFieldW
,
1157 Widget errorLabelW
);
1158 static void primaryModifiedCB(Widget w
, XtPointer clientData
,
1159 XtPointer callData
);
1160 static void italicModifiedCB(Widget w
, XtPointer clientData
,
1161 XtPointer callData
);
1162 static void boldModifiedCB(Widget w
, XtPointer clientData
, XtPointer callData
);
1163 static void boldItalicModifiedCB(Widget w
, XtPointer clientData
,
1164 XtPointer callData
);
1165 static void primaryBrowseCB(Widget w
, XtPointer clientData
, XtPointer callData
);
1166 static void italicBrowseCB(Widget w
, XtPointer clientData
, XtPointer callData
);
1167 static void boldBrowseCB(Widget w
, XtPointer clientData
, XtPointer callData
);
1168 static void boldItalicBrowseCB(Widget w
, XtPointer clientData
,
1169 XtPointer callData
);
1170 static void browseFont(Widget parent
, Widget fontTextW
);
1171 static void fontDestroyCB(Widget w
, XtPointer clientData
, XtPointer callData
);
1172 static void fontOkCB(Widget w
, XtPointer clientData
, XtPointer callData
);
1173 static void fontApplyCB(Widget w
, XtPointer clientData
, XtPointer callData
);
1174 static void fontCancelCB(Widget w
, XtPointer clientData
, XtPointer callData
);
1175 static void updateFonts(fontDialog
*fd
);
1177 static Boolean
checkColorStatus(colorDialog
*cd
, Widget colorFieldW
);
1178 static int verifyAllColors (colorDialog
*cd
);
1179 static void showColorStatus (colorDialog
*cd
, Widget colorFieldW
,
1180 Widget errorLabelW
);
1181 static void updateColors(colorDialog
*cd
);
1182 static void colorDestroyCB(Widget w
, XtPointer clientData
, XtPointer callData
);
1183 static void colorOkCB (Widget w
, XtPointer clientData
, XtPointer callData
);
1184 static void colorApplyCB (Widget w
, XtPointer clientData
, XtPointer callData
);
1185 static void colorCloseCB(Widget w
, XtPointer clientData
, XtPointer callData
);
1186 static void textFgModifiedCB (Widget w
, XtPointer clientData
,
1187 XtPointer callData
);
1188 static void textBgModifiedCB (Widget w
, XtPointer clientData
,
1189 XtPointer callData
);
1190 static void selectFgModifiedCB(Widget w
, XtPointer clientData
,
1191 XtPointer callData
);
1192 static void selectBgModifiedCB(Widget w
, XtPointer clientData
,
1193 XtPointer callData
);
1194 static void hiliteFgModifiedCB(Widget w
, XtPointer clientData
,
1195 XtPointer callData
);
1196 static void hiliteBgModifiedCB(Widget w
, XtPointer clientData
,
1197 XtPointer callData
);
1198 static void lineNoFgModifiedCB(Widget w
, XtPointer clientData
,
1199 XtPointer callData
);
1200 static void cursorFgModifiedCB(Widget w
, XtPointer clientData
,
1201 XtPointer callData
);
1203 static int matchLanguageMode(WindowInfo
*window
);
1204 static int loadLanguageModesString(char *inString
, int fileVer
);
1205 static char *writeLanguageModesString(void);
1206 static char *createExtString(char **extensions
, int nExtensions
);
1207 static char **readExtensionList(char **inPtr
, int *nExtensions
);
1208 static void updateLanguageModeSubmenu(WindowInfo
*window
);
1209 static void setLangModeCB(Widget w
, XtPointer clientData
, XtPointer callData
);
1210 static int modeError(languageModeRec
*lm
, const char *stringStart
,
1211 const char *stoppedAt
, const char *message
);
1212 static void lmDestroyCB(Widget w
, XtPointer clientData
, XtPointer callData
);
1213 static void lmOkCB(Widget w
, XtPointer clientData
, XtPointer callData
);
1214 static void lmApplyCB(Widget w
, XtPointer clientData
, XtPointer callData
);
1215 static void lmCloseCB(Widget w
, XtPointer clientData
, XtPointer callData
);
1216 static int lmDeleteConfirmCB(int itemIndex
, void *cbArg
);
1217 static int updateLMList(void);
1218 static languageModeRec
*copyLanguageModeRec(languageModeRec
*lm
);
1219 static void *lmGetDisplayedCB(void *oldItem
, int explicitRequest
, int *abort
,
1221 static void lmSetDisplayedCB(void *item
, void *cbArg
);
1222 static languageModeRec
*readLMDialogFields(int silent
);
1223 static void lmFreeItemCB(void *item
);
1224 static void freeLanguageModeRec(languageModeRec
*lm
);
1225 static int lmDialogEmpty(void);
1226 static void updatePatternsTo5dot1(void);
1227 static void updatePatternsTo5dot2(void);
1228 static void updatePatternsTo5dot3(void);
1229 static void updatePatternsTo5dot4(void);
1230 static void updateShellCmdsTo5dot3(void);
1231 static void updateShellCmdsTo5dot4(void);
1232 static void updateMacroCmdsTo5dot5(void);
1233 static void updatePatternsTo5dot6(void);
1234 static void updateMacroCmdsTo5dot6(void);
1235 static void migrateColorResources(XrmDatabase prefDB
, XrmDatabase appDB
);
1236 static void spliceString(char **intoString
, const char *insertString
, const char *atExpr
);
1237 static int regexFind(const char *inString
, const char *expr
);
1238 static int regexReplace(char **inString
, const char *expr
,
1239 const char *replaceWith
);
1240 static int caseFind(const char *inString
, const char *expr
);
1241 static int caseReplace(char **inString
, const char *expr
,
1242 const char *replaceWith
, int replaceLen
);
1243 static int stringReplace(char **inString
, const char *expr
,
1244 const char *replaceWith
, int searchType
,
1246 static int replaceMacroIfUnchanged(const char* oldText
, const char* newStart
,
1247 const char* newEnd
);
1248 static const char* getDefaultShell(void);
1252 static int shortPrefToDefault(Widget parent
, const char *settingName
, int *setDefault
);
1255 XrmDatabase
CreateNEditPrefDB(int *argcInOut
, char **argvInOut
)
1257 return CreatePreferencesDatabase(GetRCFileName(NEDIT_RC
), APP_NAME
,
1258 OpTable
, XtNumber(OpTable
), (unsigned int *)argcInOut
, argvInOut
);
1261 void RestoreNEditPrefs(XrmDatabase prefDB
, XrmDatabase appDB
)
1263 int requiresConversion
;
1264 int major
; /* The integral part of version number */
1265 int minor
; /* fractional part of version number */
1266 int fileVer
= 0; /* Both combined into an integer */
1269 /* Load preferences */
1270 RestorePreferences(prefDB
, appDB
, APP_NAME
,
1271 APP_CLASS
, PrefDescrip
, XtNumber(PrefDescrip
));
1273 /* If the preferences file was written by an older version of NEdit,
1274 warn the user that it will be converted. */
1275 requiresConversion
= PrefData
.prefFileRead
&&
1276 PrefData
.fileVersion
[0] == '\0';
1277 if (requiresConversion
) {
1278 updatePatternsTo5dot1();
1281 if (PrefData
.prefFileRead
) {
1282 if (PrefData
.fileVersion
[0] == '\0') {
1283 fileVer
= 0; /* Pre-5.1 */
1286 /* Note: do not change the format of this. Older executables
1287 need to read this field for forward compatability. */
1288 nparsed
= sscanf(PrefData
.fileVersion
, "%d.%d", &major
, &minor
);
1290 /* Use OSF-style numbering scheme */
1291 fileVer
= major
* 1000 + minor
;
1296 if (PrefData
.prefFileRead
&& fileVer
< 5002) {
1297 updatePatternsTo5dot2();
1300 if (PrefData
.prefFileRead
&& fileVer
< 5003) {
1301 updateShellCmdsTo5dot3();
1302 updatePatternsTo5dot3();
1305 /* Note that we don't care about unreleased file versions. Anyone
1306 who is running a CVS or alpha version of NEdit is resposnbile
1307 for managing the preferences file themselves. Otherwise, it
1308 gets impossible to track the number of "in-between" file formats.
1309 We only do auto-upgrading for a real release. */
1311 if (PrefData
.prefFileRead
&& (fileVer
< 5004)) {
1312 migrateColorResources(prefDB
, appDB
);
1313 updateShellCmdsTo5dot4();
1314 updatePatternsTo5dot4();
1316 if (PrefData
.prefFileRead
&& (fileVer
< 5005)) {
1317 updateMacroCmdsTo5dot5();
1319 if (PrefData
.prefFileRead
&& (fileVer
< 5006)) {
1320 fprintf(stderr
, "NEdit: Converting .nedit file to 5.6 version.\n"
1321 " To keep, use Preferences -> Save Defaults\n");
1322 updateMacroCmdsTo5dot6();
1323 updatePatternsTo5dot6();
1325 /* Migrate colors if there's no config file yet */
1326 if (!PrefData
.prefFileRead
) {
1327 migrateColorResources(prefDB
, appDB
);
1330 /* Do further parsing on resource types which RestorePreferences does
1331 not understand and reads as strings, to put them in the final form
1332 in which nedit stores and uses. If the preferences file was
1333 written by an older version of NEdit, update regular expressions in
1334 highlight patterns to quote braces and use & instead of \0 */
1335 translatePrefFormats(requiresConversion
, fileVer
);
1339 ** Many of of NEdit's preferences are much more complicated than just simple
1340 ** integers or strings. These are read as strings, but must be parsed and
1341 ** translated into something meaningful. This routine does the translation,
1342 ** and, in most cases, frees the original string, which is no longer useful.
1344 ** In addition this function covers settings that, while simple, require
1345 ** additional steps before they can be published.
1347 ** The argument convertOld attempts a conversion from pre 5.1 format .nedit
1348 ** files (which means patterns and macros may contain regular expressions
1349 ** which are of the older syntax where braces were not quoted, and \0 was a
1350 ** legal substitution character). Macros, so far can not be automatically
1351 ** converted, unfortunately.
1353 static void translatePrefFormats(int convertOld
, int fileVer
)
1357 /* Parse the strings which represent types which are not decoded by
1358 the standard resource manager routines */
1360 if (TempStringPrefs
.shellCmds
!= NULL
) {
1361 LoadShellCmdsString(TempStringPrefs
.shellCmds
);
1362 XtFree(TempStringPrefs
.shellCmds
);
1363 TempStringPrefs
.shellCmds
= NULL
;
1366 if (TempStringPrefs
.macroCmds
!= NULL
) {
1367 LoadMacroCmdsString(TempStringPrefs
.macroCmds
);
1368 XtFree(TempStringPrefs
.macroCmds
);
1369 TempStringPrefs
.macroCmds
= NULL
;
1371 if (TempStringPrefs
.bgMenuCmds
!= NULL
) {
1372 LoadBGMenuCmdsString(TempStringPrefs
.bgMenuCmds
);
1373 XtFree(TempStringPrefs
.bgMenuCmds
);
1374 TempStringPrefs
.bgMenuCmds
= NULL
;
1376 if (TempStringPrefs
.highlight
!= NULL
) {
1377 LoadHighlightString(TempStringPrefs
.highlight
, convertOld
);
1378 XtFree(TempStringPrefs
.highlight
);
1379 TempStringPrefs
.highlight
= NULL
;
1381 if (TempStringPrefs
.styles
!= NULL
) {
1382 LoadStylesString(TempStringPrefs
.styles
);
1383 XtFree(TempStringPrefs
.styles
);
1384 TempStringPrefs
.styles
= NULL
;
1386 if (TempStringPrefs
.language
!= NULL
) {
1387 loadLanguageModesString(TempStringPrefs
.language
, fileVer
);
1388 XtFree(TempStringPrefs
.language
);
1389 TempStringPrefs
.language
= NULL
;
1391 if (TempStringPrefs
.smartIndent
!= NULL
) {
1392 LoadSmartIndentString(TempStringPrefs
.smartIndent
);
1393 XtFree(TempStringPrefs
.smartIndent
);
1394 TempStringPrefs
.smartIndent
= NULL
;
1396 if (TempStringPrefs
.smartIndentCommon
!= NULL
) {
1397 LoadSmartIndentCommonString(TempStringPrefs
.smartIndentCommon
);
1398 XtFree(TempStringPrefs
.smartIndentCommon
);
1399 TempStringPrefs
.smartIndentCommon
= NULL
;
1402 /* translate the font names into fontLists suitable for the text widget */
1403 font
= XLoadQueryFont(TheDisplay
, PrefData
.fontString
);
1404 PrefData
.fontList
= font
==NULL
? NULL
:
1405 XmFontListCreate(font
, XmSTRING_DEFAULT_CHARSET
);
1406 PrefData
.boldFontStruct
= XLoadQueryFont(TheDisplay
,
1407 PrefData
.boldFontString
);
1408 PrefData
.italicFontStruct
= XLoadQueryFont(TheDisplay
,
1409 PrefData
.italicFontString
);
1410 PrefData
.boldItalicFontStruct
= XLoadQueryFont(TheDisplay
,
1411 PrefData
.boldItalicFontString
);
1414 ** The default set for the comand shell in PrefDescrip ("DEFAULT") is
1415 ** only a place-holder, the actual default is the user's login shell
1416 ** (or whatever is implemented in getDefaultShell()). We put the login
1417 ** shell's name in PrefData here.
1419 if (0 == strcmp(PrefData
.shell
, "DEFAULT")) {
1420 strncpy(PrefData
.shell
, getDefaultShell(), MAXPATHLEN
);
1421 PrefData
.shell
[MAXPATHLEN
] = '\0';
1424 /* For compatability with older (4.0.3 and before) versions, the autoWrap
1425 and autoIndent resources can accept values of True and False. Translate
1426 them into acceptable wrap and indent styles */
1427 if (PrefData
.wrapStyle
== 3) PrefData
.wrapStyle
= CONTINUOUS_WRAP
;
1428 if (PrefData
.wrapStyle
== 4) PrefData
.wrapStyle
= NO_WRAP
;
1429 if (PrefData
.autoIndent
== 3) PrefData
.autoIndent
= AUTO_INDENT
;
1430 if (PrefData
.autoIndent
== 4) PrefData
.autoIndent
= NO_AUTO_INDENT
;
1432 /* setup language mode dependent info of user menus (to increase
1433 performance when switching between documents of different
1435 SetupUserMenuInfo();
1438 void SaveNEditPrefs(Widget parent
, int quietly
)
1440 const char* prefFileName
= GetRCFileName(NEDIT_RC
);
1441 if (prefFileName
== NULL
)
1443 /* GetRCFileName() might return NULL if an error occurs during
1444 creation of the preference file directory. */
1445 DialogF(DF_WARN
, parent
, 1, "Error saving Preferences",
1446 "Unable to save preferences: Cannot determine filename.",
1452 if (DialogF(DF_INF
, parent
, 2, "Save Preferences",
1453 ImportedFile
== NULL
?
1454 "Default preferences will be saved in the file:\n"
1456 "NEdit automatically loads this file\n"
1457 "each time it is started." :
1458 "Default preferences will be saved in the file:\n"
1460 "SAVING WILL INCORPORATE SETTINGS\n"
1461 "FROM FILE: %s", "OK", "Cancel",
1462 prefFileName
, ImportedFile
) == 2) {
1467 /* Write the more dynamic settings into TempStringPrefs.
1468 These locations are set in PrefDescrip, so this is where
1469 SavePreferences() will look for them. */
1471 TempStringPrefs
.shellCmds
= WriteShellCmdsString();
1473 TempStringPrefs
.macroCmds
= WriteMacroCmdsString();
1474 TempStringPrefs
.bgMenuCmds
= WriteBGMenuCmdsString();
1475 TempStringPrefs
.highlight
= WriteHighlightString();
1476 TempStringPrefs
.language
= writeLanguageModesString();
1477 TempStringPrefs
.styles
= WriteStylesString();
1478 TempStringPrefs
.smartIndent
= WriteSmartIndentString();
1479 TempStringPrefs
.smartIndentCommon
= WriteSmartIndentCommonString();
1480 strcpy(PrefData
.fileVersion
, PREF_FILE_VERSION
);
1482 if (!SavePreferences(XtDisplay(parent
), prefFileName
, HeaderText
,
1483 PrefDescrip
, XtNumber(PrefDescrip
)))
1485 DialogF(DF_WARN
, parent
, 1, "Save Preferences",
1486 "Unable to save preferences in %s", "OK", prefFileName
);
1490 XtFree(TempStringPrefs
.shellCmds
);
1492 XtFree(TempStringPrefs
.macroCmds
);
1493 XtFree(TempStringPrefs
.bgMenuCmds
);
1494 XtFree(TempStringPrefs
.highlight
);
1495 XtFree(TempStringPrefs
.language
);
1496 XtFree(TempStringPrefs
.styles
);
1497 XtFree(TempStringPrefs
.smartIndent
);
1498 XtFree(TempStringPrefs
.smartIndentCommon
);
1500 PrefsHaveChanged
= False
;
1504 ** Load an additional preferences file on top of the existing preferences
1505 ** derived from defaults, the .nedit file, and X resources.
1507 void ImportPrefFile(const char *filename
, int convertOld
)
1512 fileString
= ReadAnyTextFile(filename
, False
);
1513 if (fileString
!= NULL
){
1514 db
= XrmGetStringDatabase(fileString
);
1516 OverlayPreferences(db
, APP_NAME
, APP_CLASS
, PrefDescrip
,
1517 XtNumber(PrefDescrip
));
1518 translatePrefFormats(convertOld
, -1);
1519 ImportedFile
= XtNewString(filename
);
1522 fprintf(stderr
, "Could not read additional preferences file: %s\n",
1527 void SetPrefOpenInTab(int state
)
1529 WindowInfo
*w
= WindowList
;
1530 setIntPref(&PrefData
.openInTab
, state
);
1531 for(; w
!= NULL
; w
= w
->next
)
1532 UpdateNewOppositeMenu(w
, state
);
1535 int GetPrefOpenInTab(void)
1537 return PrefData
.openInTab
;
1540 void SetPrefWrap(int state
)
1542 setIntPref(&PrefData
.wrapStyle
, state
);
1545 int GetPrefWrap(int langMode
)
1547 if (langMode
== PLAIN_LANGUAGE_MODE
||
1548 LanguageModes
[langMode
]->wrapStyle
== DEFAULT_WRAP
)
1549 return PrefData
.wrapStyle
;
1550 return LanguageModes
[langMode
]->wrapStyle
;
1553 void SetPrefWrapMargin(int margin
)
1555 setIntPref(&PrefData
.wrapMargin
, margin
);
1558 int GetPrefWrapMargin(void)
1560 return PrefData
.wrapMargin
;
1563 void SetPrefSearch(int searchType
)
1565 setIntPref(&PrefData
.searchMethod
, searchType
);
1568 int GetPrefSearch(void)
1570 return PrefData
.searchMethod
;
1573 #ifdef REPLACE_SCOPE
1574 void SetPrefReplaceDefScope(int scope
)
1576 setIntPref(&PrefData
.replaceDefScope
, scope
);
1579 int GetPrefReplaceDefScope(void)
1581 return PrefData
.replaceDefScope
;
1585 void SetPrefAutoIndent(int state
)
1587 setIntPref(&PrefData
.autoIndent
, state
);
1590 int GetPrefAutoIndent(int langMode
)
1592 if (langMode
== PLAIN_LANGUAGE_MODE
||
1593 LanguageModes
[langMode
]->indentStyle
== DEFAULT_INDENT
)
1594 return PrefData
.autoIndent
;
1595 return LanguageModes
[langMode
]->indentStyle
;
1598 void SetPrefAutoSave(int state
)
1600 setIntPref(&PrefData
.autoSave
, state
);
1603 int GetPrefAutoSave(void)
1605 return PrefData
.autoSave
;
1608 void SetPrefSaveOldVersion(int state
)
1610 setIntPref(&PrefData
.saveOldVersion
, state
);
1613 int GetPrefSaveOldVersion(void)
1615 return PrefData
.saveOldVersion
;
1618 void SetPrefSearchDlogs(int state
)
1620 setIntPref(&PrefData
.searchDlogs
, state
);
1623 int GetPrefSearchDlogs(void)
1625 return PrefData
.searchDlogs
;
1628 void SetPrefBeepOnSearchWrap(int state
)
1630 setIntPref(&PrefData
.searchWrapBeep
, state
);
1633 int GetPrefBeepOnSearchWrap(void)
1635 return PrefData
.searchWrapBeep
;
1638 void SetPrefKeepSearchDlogs(int state
)
1640 setIntPref(&PrefData
.keepSearchDlogs
, state
);
1643 int GetPrefKeepSearchDlogs(void)
1645 return PrefData
.keepSearchDlogs
;
1648 void SetPrefSearchWraps(int state
)
1650 setIntPref(&PrefData
.searchWraps
, state
);
1653 int GetPrefStickyCaseSenseBtn(void)
1655 return PrefData
.stickyCaseSenseBtn
;
1658 int GetPrefSearchWraps(void)
1660 return PrefData
.searchWraps
;
1663 void SetPrefStatsLine(int state
)
1665 setIntPref(&PrefData
.statsLine
, state
);
1668 int GetPrefStatsLine(void)
1670 return PrefData
.statsLine
;
1673 void SetPrefISearchLine(int state
)
1675 setIntPref(&PrefData
.iSearchLine
, state
);
1678 int GetPrefISearchLine(void)
1680 return PrefData
.iSearchLine
;
1683 void SetPrefSortTabs(int state
)
1685 setIntPref(&PrefData
.sortTabs
, state
);
1688 int GetPrefSortTabs(void)
1690 return PrefData
.sortTabs
;
1693 void SetPrefTabBar(int state
)
1695 setIntPref(&PrefData
.tabBar
, state
);
1698 int GetPrefTabBar(void)
1700 return PrefData
.tabBar
;
1703 void SetPrefTabBarHideOne(int state
)
1705 setIntPref(&PrefData
.tabBarHideOne
, state
);
1708 int GetPrefTabBarHideOne(void)
1710 return PrefData
.tabBarHideOne
;
1713 void SetPrefGlobalTabNavigate(int state
)
1715 setIntPref(&PrefData
.globalTabNavigate
, state
);
1718 int GetPrefGlobalTabNavigate(void)
1720 return PrefData
.globalTabNavigate
;
1723 void SetPrefToolTips(int state
)
1725 setIntPref(&PrefData
.toolTips
, state
);
1728 int GetPrefToolTips(void)
1730 return PrefData
.toolTips
;
1733 void SetPrefLineNums(int state
)
1735 setIntPref(&PrefData
.lineNums
, state
);
1738 int GetPrefLineNums(void)
1740 return PrefData
.lineNums
;
1743 void SetPrefShowPathInWindowsMenu(int state
)
1745 setIntPref(&PrefData
.pathInWindowsMenu
, state
);
1748 int GetPrefShowPathInWindowsMenu(void)
1750 return PrefData
.pathInWindowsMenu
;
1753 void SetPrefWarnFileMods(int state
)
1755 setIntPref(&PrefData
.warnFileMods
, state
);
1758 int GetPrefWarnFileMods(void)
1760 return PrefData
.warnFileMods
;
1763 void SetPrefWarnRealFileMods(int state
)
1765 setIntPref(&PrefData
.warnRealFileMods
, state
);
1768 int GetPrefWarnRealFileMods(void)
1770 return PrefData
.warnRealFileMods
;
1773 void SetPrefWarnExit(int state
)
1775 setIntPref(&PrefData
.warnExit
, state
);
1778 int GetPrefWarnExit(void)
1780 return PrefData
.warnExit
;
1783 void SetPrefv(int state
)
1785 setIntPref(&PrefData
.findReplaceUsesSelection
, state
);
1788 int GetPrefFindReplaceUsesSelection(void)
1790 return PrefData
.findReplaceUsesSelection
;
1793 int GetPrefMapDelete(void)
1795 return PrefData
.mapDelete
;
1798 int GetPrefStdOpenDialog(void)
1800 return PrefData
.stdOpenDialog
;
1803 void SetPrefRows(int nRows
)
1805 setIntPref(&PrefData
.textRows
, nRows
);
1808 int GetPrefRows(void)
1810 return PrefData
.textRows
;
1813 void SetPrefCols(int nCols
)
1815 setIntPref(&PrefData
.textCols
, nCols
);
1818 int GetPrefCols(void)
1820 return PrefData
.textCols
;
1823 void SetPrefTabDist(int tabDist
)
1825 setIntPref(&PrefData
.tabDist
, tabDist
);
1828 int GetPrefTabDist(int langMode
)
1831 if (langMode
== PLAIN_LANGUAGE_MODE
||
1832 LanguageModes
[langMode
]->tabDist
== DEFAULT_TAB_DIST
) {
1833 tabDist
= PrefData
.tabDist
;
1835 tabDist
= LanguageModes
[langMode
]->tabDist
;
1837 /* Make sure that the tab distance is in range (garbage may have
1838 been entered via the command line or the X resources, causing
1839 errors later on, like division by zero). */
1840 if (tabDist
<= 0) return 1;
1841 if (tabDist
> MAX_EXP_CHAR_LEN
) return MAX_EXP_CHAR_LEN
;
1845 void SetPrefEmTabDist(int tabDist
)
1847 setIntPref(&PrefData
.emTabDist
, tabDist
);
1850 int GetPrefEmTabDist(int langMode
)
1852 if (langMode
== PLAIN_LANGUAGE_MODE
||
1853 LanguageModes
[langMode
]->emTabDist
== DEFAULT_EM_TAB_DIST
)
1854 return PrefData
.emTabDist
;
1855 return LanguageModes
[langMode
]->emTabDist
;
1858 void SetPrefInsertTabs(int state
)
1860 setIntPref(&PrefData
.insertTabs
, state
);
1863 int GetPrefInsertTabs(void)
1865 return PrefData
.insertTabs
;
1868 void SetPrefShowMatching(int state
)
1870 setIntPref(&PrefData
.showMatchingStyle
, state
);
1873 int GetPrefShowMatching(void)
1876 * For backwards compatibility with pre-5.2 versions, the boolean
1877 * False/True matching behavior is converted to NO_FLASH/FLASH_DELIMIT.
1879 if (PrefData
.showMatchingStyle
>= N_SHOW_MATCHING_STYLES
)
1880 PrefData
.showMatchingStyle
-= N_SHOW_MATCHING_STYLES
;
1881 return PrefData
.showMatchingStyle
;
1884 void SetPrefMatchSyntaxBased(int state
)
1886 setIntPref(&PrefData
.matchSyntaxBased
, state
);
1889 int GetPrefMatchSyntaxBased(void)
1891 return PrefData
.matchSyntaxBased
;
1894 void SetPrefHighlightSyntax(Boolean state
)
1896 setIntPref(&PrefData
.highlightSyntax
, state
);
1899 Boolean
GetPrefHighlightSyntax(void)
1901 return PrefData
.highlightSyntax
;
1904 void SetPrefBacklightChars(int state
)
1906 setIntPref(&PrefData
.backlightChars
, state
);
1909 int GetPrefBacklightChars(void)
1911 return PrefData
.backlightChars
;
1914 void SetPrefBacklightCharTypes(char *types
)
1916 setStringAllocPref(&PrefData
.backlightCharTypes
, types
);
1919 char *GetPrefBacklightCharTypes(void)
1921 return PrefData
.backlightCharTypes
;
1924 void SetPrefRepositionDialogs(int state
)
1926 setIntPref(&PrefData
.repositionDialogs
, state
);
1929 int GetPrefRepositionDialogs(void)
1931 return PrefData
.repositionDialogs
;
1934 void SetPrefAutoScroll(int state
)
1936 WindowInfo
*w
= WindowList
;
1937 int margin
= state
? PrefData
.autoScrollVPadding
: 0;
1939 setIntPref(&PrefData
.autoScroll
, state
);
1940 for(w
= WindowList
; w
!= NULL
; w
= w
->next
)
1941 SetAutoScroll(w
, margin
);
1944 int GetPrefAutoScroll(void)
1946 return PrefData
.autoScroll
;
1949 int GetVerticalAutoScroll(void)
1951 return PrefData
.autoScroll
? PrefData
.autoScrollVPadding
: 0;
1954 void SetPrefAppendLF(int state
)
1956 setIntPref(&PrefData
.appendLF
, state
);
1959 int GetPrefAppendLF(void)
1961 return PrefData
.appendLF
;
1964 void SetPrefSortOpenPrevMenu(int state
)
1966 setIntPref(&PrefData
.sortOpenPrevMenu
, state
);
1969 int GetPrefSortOpenPrevMenu(void)
1971 return PrefData
.sortOpenPrevMenu
;
1974 char *GetPrefTagFile(void)
1976 return PrefData
.tagFile
;
1979 void SetPrefSmartTags(int state
)
1981 setIntPref(&PrefData
.smartTags
, state
);
1984 int GetPrefSmartTags(void)
1986 return PrefData
.smartTags
;
1989 int GetPrefAlwaysCheckRelTagsSpecs(void)
1991 return PrefData
.alwaysCheckRelativeTagsSpecs
;
1994 char *GetPrefDelimiters(void)
1996 return PrefData
.delimiters
;
1999 char *GetPrefColorName(int index
)
2001 return PrefData
.colorNames
[index
];
2004 void SetPrefColorName(int index
, const char *name
)
2006 setStringPref(PrefData
.colorNames
[index
], name
);
2010 ** Set the font preferences using the font name (the fontList is generated
2011 ** in this call). Note that this leaks memory and server resources each
2012 ** time the default font is re-set. See note on SetFontByName in window.c
2013 ** for more information.
2015 void SetPrefFont(char *fontName
)
2019 setStringPref(PrefData
.fontString
, fontName
);
2020 font
= XLoadQueryFont(TheDisplay
, fontName
);
2021 PrefData
.fontList
= font
==NULL
? NULL
:
2022 XmFontListCreate(font
, XmSTRING_DEFAULT_CHARSET
);
2025 void SetPrefBoldFont(char *fontName
)
2027 setStringPref(PrefData
.boldFontString
, fontName
);
2028 PrefData
.boldFontStruct
= XLoadQueryFont(TheDisplay
, fontName
);
2031 void SetPrefItalicFont(char *fontName
)
2033 setStringPref(PrefData
.italicFontString
, fontName
);
2034 PrefData
.italicFontStruct
= XLoadQueryFont(TheDisplay
, fontName
);
2036 void SetPrefBoldItalicFont(char *fontName
)
2038 setStringPref(PrefData
.boldItalicFontString
, fontName
);
2039 PrefData
.boldItalicFontStruct
= XLoadQueryFont(TheDisplay
, fontName
);
2042 char *GetPrefFontName(void)
2044 return PrefData
.fontString
;
2047 char *GetPrefBoldFontName(void)
2049 return PrefData
.boldFontString
;
2052 char *GetPrefItalicFontName(void)
2054 return PrefData
.italicFontString
;
2057 char *GetPrefBoldItalicFontName(void)
2059 return PrefData
.boldItalicFontString
;
2062 XmFontList
GetPrefFontList(void)
2064 return PrefData
.fontList
;
2067 XFontStruct
*GetPrefBoldFont(void)
2069 return PrefData
.boldFontStruct
;
2072 XFontStruct
*GetPrefItalicFont(void)
2074 return PrefData
.italicFontStruct
;
2077 XFontStruct
*GetPrefBoldItalicFont(void)
2079 return PrefData
.boldItalicFontStruct
;
2082 char *GetPrefHelpFontName(int index
)
2084 return PrefData
.helpFontNames
[index
];
2087 char *GetPrefHelpLinkColor(void)
2089 return PrefData
.helpLinkColor
;
2092 char *GetPrefTooltipBgColor(void)
2094 return PrefData
.tooltipBgColor
;
2097 void SetPrefShell(const char *shell
)
2099 setStringPref(PrefData
.shell
, shell
);
2102 const char* GetPrefShell(void)
2104 return PrefData
.shell
;
2107 char *GetPrefGeometry(void)
2109 return PrefData
.geometry
;
2112 char *GetPrefServerName(void)
2114 return PrefData
.serverName
;
2117 char *GetPrefBGMenuBtn(void)
2119 return PrefData
.bgMenuBtn
;
2122 int GetPrefMaxPrevOpenFiles(void)
2124 return PrefData
.maxPrevOpenFiles
;
2127 int GetPrefTypingHidesPointer(void)
2129 return(PrefData
.typingHidesPointer
);
2133 void SetPrefShortMenus(int state
)
2135 setIntPref(&PrefData
.shortMenus
, state
);
2138 int GetPrefShortMenus(void)
2140 return PrefData
.shortMenus
;
2144 void SetPrefTitleFormat(const char* format
)
2146 const WindowInfo
* window
;
2148 setStringPref(PrefData
.titleFormat
, format
);
2150 /* update all windows */
2151 for (window
=WindowList
; window
!=NULL
; window
=window
->next
) {
2152 UpdateWindowTitle(window
);
2155 const char* GetPrefTitleFormat(void)
2157 return PrefData
.titleFormat
;
2160 Boolean
GetPrefUndoModifiesSelection(void)
2162 return (Boolean
)PrefData
.undoModifiesSelection
;
2165 Boolean
GetPrefFocusOnRaise(void)
2167 return (Boolean
)PrefData
.focusOnRaise
;
2170 Boolean
GetPrefForceOSConversion(void)
2172 return (Boolean
) PrefData
.forceOSConversion
;
2175 Boolean
GetPrefHonorSymlinks(void)
2177 return PrefData
.honorSymlinks
;
2180 int GetPrefOverrideVirtKeyBindings(void)
2182 return PrefData
.virtKeyOverride
;
2185 int GetPrefTruncSubstitution(void)
2187 return PrefData
.truncSubstitution
;
2191 ** If preferences don't get saved, ask the user on exit whether to save
2193 void MarkPrefsChanged(void)
2195 PrefsHaveChanged
= True
;
2199 ** Check if preferences have changed, and if so, ask the user if he wants
2200 ** to re-save. Returns False if user requests cancelation of Exit (or whatever
2201 ** operation triggered this call to be made).
2203 int CheckPrefsChangesSaved(Widget dialogParent
)
2207 if (!PrefsHaveChanged
)
2210 resp
= DialogF(DF_WARN
, dialogParent
, 3, "Default Preferences",
2211 ImportedFile
== NULL
?
2212 "Default Preferences have changed.\n"
2213 "Save changes to NEdit preference file?" :
2214 "Default Preferences have changed. SAVING \n"
2215 "CHANGES WILL INCORPORATE ADDITIONAL\nSETTINGS FROM FILE: %s",
2216 "Save", "Don't Save", "Cancel", ImportedFile
);
2222 SaveNEditPrefs(dialogParent
, True
);
2227 ** set *prefDataField to newValue, but first check if they're different
2228 ** and update PrefsHaveChanged if a preference setting has now changed.
2230 static void setIntPref(int *prefDataField
, int newValue
)
2232 if (newValue
!= *prefDataField
)
2233 PrefsHaveChanged
= True
;
2234 *prefDataField
= newValue
;
2237 static void setStringPref(char *prefDataField
, const char *newValue
)
2239 if (strcmp(prefDataField
, newValue
))
2240 PrefsHaveChanged
= True
;
2241 strcpy(prefDataField
, newValue
);
2244 static void setStringAllocPref(char **pprefDataField
, char *newValue
)
2248 /* treat empty strings as nulls */
2249 if (newValue
&& *newValue
== '\0')
2251 if (*pprefDataField
&& **pprefDataField
== '\0')
2252 *pprefDataField
= NULL
; /* assume statically alloc'ed "" */
2255 if (!*pprefDataField
&& !newValue
)
2257 else if (!*pprefDataField
&& newValue
)
2258 PrefsHaveChanged
= True
;
2259 else if (*pprefDataField
&& !newValue
)
2260 PrefsHaveChanged
= True
;
2261 else if (strcmp(*pprefDataField
, newValue
))
2262 PrefsHaveChanged
= True
;
2264 /* get rid of old preference */
2265 XtFree(*pprefDataField
);
2267 /* store new preference */
2269 p_newField
= XtMalloc(strlen(newValue
) + 1);
2270 strcpy(p_newField
, newValue
);
2272 *pprefDataField
= newValue
;
2276 ** Set the language mode for the window, update the menu and trigger language
2277 ** mode specific actions (turn on/off highlighting). If forceNewDefaults is
2278 ** true, re-establish default settings for language-specific preferences
2279 ** regardless of whether they were previously set by the user.
2281 void SetLanguageMode(WindowInfo
*window
, int mode
, int forceNewDefaults
)
2289 /* Do mode-specific actions */
2290 reapplyLanguageMode(window
, mode
, forceNewDefaults
);
2292 /* Select the correct language mode in the sub-menu */
2293 if (IsTopDocument(window
)) {
2294 XtVaGetValues(window
->langModeCascade
, XmNsubMenuId
, &menu
, NULL
);
2295 XtVaGetValues(menu
, XmNchildren
, &items
, XmNnumChildren
, &nItems
, NULL
);
2296 for (n
=0; n
<(int)nItems
; n
++) {
2297 XtVaGetValues(items
[n
], XmNuserData
, &userData
, NULL
);
2298 XmToggleButtonSetState(items
[n
], (int)userData
== mode
, False
);
2304 ** Lookup a language mode by name, returning the index of the language
2305 ** mode or PLAIN_LANGUAGE_MODE if the name is not found
2307 int FindLanguageMode(const char *languageName
)
2311 /* Compare each language mode to the one we were presented */
2312 for (i
=0; i
<NLanguageModes
; i
++)
2313 if (!strcmp(languageName
, LanguageModes
[i
]->name
))
2316 return PLAIN_LANGUAGE_MODE
;
2321 ** Apply language mode matching criteria and set window->languageMode to
2322 ** the appropriate mode for the current file, trigger language mode
2323 ** specific actions (turn on/off highlighting), and update the language
2324 ** mode menu item. If forceNewDefaults is true, re-establish default
2325 ** settings for language-specific preferences regardless of whether
2326 ** they were previously set by the user.
2328 void DetermineLanguageMode(WindowInfo
*window
, int forceNewDefaults
)
2330 SetLanguageMode(window
, matchLanguageMode(window
), forceNewDefaults
);
2334 ** Return the name of the current language mode set in "window", or NULL
2335 ** if the current mode is "Plain".
2337 char *LanguageModeName(int mode
)
2339 if (mode
== PLAIN_LANGUAGE_MODE
)
2342 return LanguageModes
[mode
]->name
;
2346 ** Get the set of word delimiters for the language mode set in the current
2347 ** window. Returns NULL when no language mode is set (it would be easy to
2348 ** return the default delimiter set when the current language mode is "Plain",
2349 ** or the mode doesn't have its own delimiters, but this is usually used
2350 ** to supply delimiters for RE searching, and ExecRE can skip compiling a
2351 ** delimiter table when delimiters is NULL).
2353 char *GetWindowDelimiters(const WindowInfo
*window
)
2355 if (window
->languageMode
== PLAIN_LANGUAGE_MODE
)
2358 return LanguageModes
[window
->languageMode
]->delimiters
;
2362 ** Put up a dialog for selecting a custom initial window size
2364 void RowColumnPrefDialog(Widget parent
)
2366 Widget form
, selBox
, topLabel
;
2370 XtSetArg(selBoxArgs
[0], XmNdialogStyle
, XmDIALOG_FULL_APPLICATION_MODAL
);
2371 XtSetArg(selBoxArgs
[1], XmNautoUnmanage
, False
);
2372 selBox
= CreatePromptDialog(parent
, "customSize", selBoxArgs
, 2);
2373 XtAddCallback(selBox
, XmNokCallback
, (XtCallbackProc
)sizeOKCB
, NULL
);
2374 XtAddCallback(selBox
, XmNcancelCallback
, (XtCallbackProc
)sizeCancelCB
,NULL
);
2375 XtUnmanageChild(XmSelectionBoxGetChild(selBox
, XmDIALOG_TEXT
));
2376 XtUnmanageChild(XmSelectionBoxGetChild(selBox
, XmDIALOG_SELECTION_LABEL
));
2377 XtUnmanageChild(XmSelectionBoxGetChild(selBox
, XmDIALOG_HELP_BUTTON
));
2378 XtVaSetValues(XtParent(selBox
), XmNtitle
, "Initial Window Size", NULL
);
2380 form
= XtVaCreateManagedWidget("form", xmFormWidgetClass
, selBox
, NULL
);
2382 topLabel
= XtVaCreateManagedWidget("topLabel", xmLabelGadgetClass
, form
,
2383 XmNlabelString
, s1
=MKSTRING(
2384 "Enter desired size in rows\nand columns of characters:"), NULL
);
2387 RowText
= XtVaCreateManagedWidget("rows", xmTextWidgetClass
, form
,
2389 XmNtopAttachment
, XmATTACH_WIDGET
,
2390 XmNleftAttachment
, XmATTACH_POSITION
,
2391 XmNrightAttachment
, XmATTACH_POSITION
,
2392 XmNtopWidget
, topLabel
,
2394 XmNrightPosition
, 45, NULL
);
2395 RemapDeleteKey(RowText
);
2397 XtVaCreateManagedWidget("xLabel", xmLabelGadgetClass
, form
,
2398 XmNlabelString
, s1
=MKSTRING("x"),
2399 XmNtopAttachment
, XmATTACH_WIDGET
,
2400 XmNleftAttachment
, XmATTACH_POSITION
,
2401 XmNrightAttachment
, XmATTACH_POSITION
,
2402 XmNbottomAttachment
, XmATTACH_OPPOSITE_WIDGET
,
2403 XmNtopWidget
, topLabel
,
2404 XmNbottomWidget
, RowText
,
2405 XmNleftPosition
, 45,
2406 XmNrightPosition
, 55, NULL
);
2409 ColText
= XtVaCreateManagedWidget("cols", xmTextWidgetClass
, form
,
2411 XmNtopAttachment
, XmATTACH_WIDGET
,
2412 XmNleftAttachment
, XmATTACH_POSITION
,
2413 XmNrightAttachment
, XmATTACH_POSITION
,
2414 XmNtopWidget
, topLabel
,
2415 XmNleftPosition
, 55,
2416 XmNrightPosition
, 95, NULL
);
2417 RemapDeleteKey(ColText
);
2419 /* put up dialog and wait for user to press ok or cancel */
2420 DoneWithSizeDialog
= False
;
2421 ManageDialogCenteredOnPointer(selBox
);
2422 while (!DoneWithSizeDialog
)
2425 XtAppNextEvent(XtWidgetToApplicationContext(parent
), &event
);
2426 ServerDispatchEvent(&event
);
2429 XtDestroyWidget(selBox
);
2432 static void sizeOKCB(Widget w
, XtPointer clientData
, XtPointer callData
)
2434 int rowValue
, colValue
, stat
;
2436 /* get the values that the user entered and make sure they're ok */
2437 stat
= GetIntTextWarn(RowText
, &rowValue
, "number of rows", True
);
2438 if (stat
!= TEXT_READ_OK
)
2440 stat
= GetIntTextWarn(ColText
, &colValue
, "number of columns", True
);
2441 if (stat
!= TEXT_READ_OK
)
2444 /* set the corresponding preferences and dismiss the dialog */
2445 SetPrefRows(rowValue
);
2446 SetPrefCols(colValue
);
2447 DoneWithSizeDialog
= True
;
2450 static void sizeCancelCB(Widget w
, XtPointer clientData
, XtPointer callData
)
2452 DoneWithSizeDialog
= True
;
2456 ** Present the user a dialog for setting tab related preferences, either as
2457 ** defaults, or for a specific window (pass "forWindow" as NULL to set default
2458 ** preference, or a window to set preferences for the specific window.
2460 void TabsPrefDialog(Widget parent
, WindowInfo
*forWindow
)
2462 Widget form
, selBox
;
2465 int emulate
, emTabDist
, useTabs
, tabDist
;
2467 XtSetArg(selBoxArgs
[0], XmNdialogStyle
, XmDIALOG_FULL_APPLICATION_MODAL
);
2468 XtSetArg(selBoxArgs
[1], XmNautoUnmanage
, False
);
2469 selBox
= CreatePromptDialog(parent
, "customSize", selBoxArgs
, 2);
2470 XtAddCallback(selBox
, XmNokCallback
, (XtCallbackProc
)tabsOKCB
, NULL
);
2471 XtAddCallback(selBox
, XmNcancelCallback
, (XtCallbackProc
)tabsCancelCB
,NULL
);
2472 XtAddCallback(selBox
, XmNhelpCallback
, (XtCallbackProc
)tabsHelpCB
,NULL
);
2473 XtUnmanageChild(XmSelectionBoxGetChild(selBox
, XmDIALOG_TEXT
));
2474 XtUnmanageChild(XmSelectionBoxGetChild(selBox
, XmDIALOG_SELECTION_LABEL
));
2475 XtVaSetValues(XtParent(selBox
), XmNtitle
, "Tabs", NULL
);
2477 form
= XtVaCreateManagedWidget("form", xmFormWidgetClass
, selBox
, NULL
);
2479 TabDistText
= XtVaCreateManagedWidget("tabDistText", xmTextWidgetClass
,
2480 form
, XmNcolumns
, 7,
2481 XmNtopAttachment
, XmATTACH_FORM
,
2482 XmNrightAttachment
, XmATTACH_FORM
, NULL
);
2483 RemapDeleteKey(TabDistText
);
2484 XtVaCreateManagedWidget("tabDistLabel", xmLabelGadgetClass
, form
,
2485 XmNlabelString
, s1
=XmStringCreateSimple(
2486 "Tab spacing (for hardware tab characters)"),
2488 XmNuserData
, TabDistText
,
2489 XmNtopAttachment
, XmATTACH_FORM
,
2490 XmNleftAttachment
, XmATTACH_FORM
,
2491 XmNrightAttachment
, XmATTACH_WIDGET
,
2492 XmNrightWidget
, TabDistText
,
2493 XmNbottomAttachment
, XmATTACH_OPPOSITE_WIDGET
,
2494 XmNbottomWidget
, TabDistText
, NULL
);
2497 EmTabText
= XtVaCreateManagedWidget("emTabText", xmTextWidgetClass
, form
,
2499 XmNtopAttachment
, XmATTACH_WIDGET
,
2500 XmNtopWidget
, TabDistText
,
2501 XmNrightAttachment
, XmATTACH_OPPOSITE_WIDGET
,
2502 XmNrightWidget
, TabDistText
, NULL
);
2503 RemapDeleteKey(EmTabText
);
2504 EmTabLabel
= XtVaCreateManagedWidget("emTabLabel", xmLabelGadgetClass
, form
,
2505 XmNlabelString
, s1
=XmStringCreateSimple("Emulated tab spacing"),
2507 XmNuserData
, EmTabText
,
2508 XmNtopAttachment
, XmATTACH_WIDGET
,
2509 XmNtopWidget
, TabDistText
,
2510 XmNrightAttachment
, XmATTACH_WIDGET
,
2511 XmNrightWidget
, EmTabText
,
2512 XmNbottomAttachment
, XmATTACH_OPPOSITE_WIDGET
,
2513 XmNbottomWidget
, EmTabText
, NULL
);
2515 EmTabToggle
= XtVaCreateManagedWidget("emTabToggle",
2516 xmToggleButtonWidgetClass
, form
, XmNlabelString
,
2517 s1
=XmStringCreateSimple("Emulate tabs"),
2519 XmNtopAttachment
, XmATTACH_WIDGET
,
2520 XmNtopWidget
, TabDistText
,
2521 XmNleftAttachment
, XmATTACH_FORM
,
2522 XmNbottomAttachment
, XmATTACH_OPPOSITE_WIDGET
,
2523 XmNbottomWidget
, EmTabText
, NULL
);
2525 XtAddCallback(EmTabToggle
, XmNvalueChangedCallback
, emTabsCB
, NULL
);
2526 UseTabsToggle
= XtVaCreateManagedWidget("useTabsToggle",
2527 xmToggleButtonWidgetClass
, form
,
2528 XmNlabelString
, s1
=XmStringCreateSimple(
2529 "Use tab characters in padding and emulated tabs"),
2531 XmNtopAttachment
, XmATTACH_WIDGET
,
2532 XmNtopWidget
, EmTabText
,
2534 XmNleftAttachment
, XmATTACH_FORM
, NULL
);
2537 /* Set default values */
2538 if (forWindow
== NULL
) {
2539 emTabDist
= GetPrefEmTabDist(PLAIN_LANGUAGE_MODE
);
2540 useTabs
= GetPrefInsertTabs();
2541 tabDist
= GetPrefTabDist(PLAIN_LANGUAGE_MODE
);
2543 XtVaGetValues(forWindow
->textArea
, textNemulateTabs
, &emTabDist
, NULL
);
2544 useTabs
= forWindow
->buffer
->useTabs
;
2545 tabDist
= BufGetTabDistance(forWindow
->buffer
);
2547 emulate
= emTabDist
!= 0;
2548 SetIntText(TabDistText
, tabDist
);
2549 XmToggleButtonSetState(EmTabToggle
, emulate
, True
);
2551 SetIntText(EmTabText
, emTabDist
);
2552 XmToggleButtonSetState(UseTabsToggle
, useTabs
, False
);
2553 XtSetSensitive(EmTabText
, emulate
);
2554 XtSetSensitive(EmTabLabel
, emulate
);
2556 /* Handle mnemonic selection of buttons and focus to dialog */
2557 AddDialogMnemonicHandler(form
, FALSE
);
2559 /* Set the widget to get focus */
2560 #if XmVersion >= 1002
2561 XtVaSetValues(form
, XmNinitialFocus
, TabDistText
, NULL
);
2564 /* put up dialog and wait for user to press ok or cancel */
2565 TabsDialogForWindow
= forWindow
;
2566 DoneWithTabsDialog
= False
;
2567 ManageDialogCenteredOnPointer(selBox
);
2568 while (!DoneWithTabsDialog
)
2571 XtAppNextEvent(XtWidgetToApplicationContext(parent
), &event
);
2572 ServerDispatchEvent(&event
);
2575 XtDestroyWidget(selBox
);
2578 static void tabsOKCB(Widget w
, XtPointer clientData
, XtPointer callData
)
2580 int emulate
, useTabs
, stat
, tabDist
, emTabDist
;
2581 WindowInfo
*window
= TabsDialogForWindow
;
2583 /* get the values that the user entered and make sure they're ok */
2584 emulate
= XmToggleButtonGetState(EmTabToggle
);
2585 useTabs
= XmToggleButtonGetState(UseTabsToggle
);
2586 stat
= GetIntTextWarn(TabDistText
, &tabDist
, "tab spacing", True
);
2587 if (stat
!= TEXT_READ_OK
)
2590 if (tabDist
<= 0 || tabDist
> MAX_EXP_CHAR_LEN
)
2592 DialogF(DF_WARN
, TabDistText
, 1, "Tab Spacing",
2593 "Tab spacing out of range", "OK");
2598 stat
= GetIntTextWarn(EmTabText
, &emTabDist
, "emulated tab spacing",True
);
2599 if (stat
!= TEXT_READ_OK
)
2602 if (emTabDist
<= 0 || tabDist
>= 1000)
2604 DialogF(DF_WARN
, EmTabText
, 1, "Tab Spacing",
2605 "Emulated tab spacing out of range", "OK");
2612 /* Ask the user about saving as a default preference */
2613 if (TabsDialogForWindow
!= NULL
) {
2615 if (!shortPrefToDefault(window
->shell
, "Tab Settings", &setDefault
)) {
2616 DoneWithTabsDialog
= True
;
2620 SetPrefTabDist(tabDist
);
2621 SetPrefEmTabDist(emTabDist
);
2622 SetPrefInsertTabs(useTabs
);
2623 SaveNEditPrefs(window
->shell
, GetPrefShortMenus());
2628 /* Set the value in either the requested window or default preferences */
2629 if (TabsDialogForWindow
== NULL
) {
2630 SetPrefTabDist(tabDist
);
2631 SetPrefEmTabDist(emTabDist
);
2632 SetPrefInsertTabs(useTabs
);
2638 sprintf(numStr
, "%d", tabDist
);
2639 XtCallActionProc(window
->textArea
, "set_tab_dist", NULL
, params
, 1);
2641 sprintf(numStr
, "%d", emTabDist
);
2642 XtCallActionProc(window
->textArea
, "set_em_tab_dist", NULL
, params
, 1);
2644 sprintf(numStr
, "%d", useTabs
);
2645 XtCallActionProc(window
->textArea
, "set_use_tabs", NULL
, params
, 1);
2647 setTabDist(window, tabDist);
2648 setEmTabDist(window, emTabDist);
2649 window->buffer->useTabs = useTabs;
2652 DoneWithTabsDialog
= True
;
2655 static void tabsCancelCB(Widget w
, XtPointer clientData
, XtPointer callData
)
2657 DoneWithTabsDialog
= True
;
2660 static void tabsHelpCB(Widget w
, XtPointer clientData
, XtPointer callData
)
2662 Help(HELP_TABS_DIALOG
);
2665 static void emTabsCB(Widget w
, XtPointer clientData
, XtPointer callData
)
2667 int state
= XmToggleButtonGetState(w
);
2669 XtSetSensitive(EmTabLabel
, state
);
2670 XtSetSensitive(EmTabText
, state
);
2674 ** Present the user a dialog for setting wrap margin.
2676 void WrapMarginDialog(Widget parent
, WindowInfo
*forWindow
)
2678 Widget form
, selBox
;
2683 XtSetArg(selBoxArgs
[0], XmNdialogStyle
, XmDIALOG_FULL_APPLICATION_MODAL
);
2684 XtSetArg(selBoxArgs
[1], XmNautoUnmanage
, False
);
2685 selBox
= CreatePromptDialog(parent
, "wrapMargin", selBoxArgs
, 2);
2686 XtAddCallback(selBox
, XmNokCallback
, (XtCallbackProc
)wrapOKCB
, NULL
);
2687 XtAddCallback(selBox
, XmNcancelCallback
, (XtCallbackProc
)wrapCancelCB
,NULL
);
2688 XtUnmanageChild(XmSelectionBoxGetChild(selBox
, XmDIALOG_TEXT
));
2689 XtUnmanageChild(XmSelectionBoxGetChild(selBox
, XmDIALOG_SELECTION_LABEL
));
2690 XtUnmanageChild(XmSelectionBoxGetChild(selBox
, XmDIALOG_HELP_BUTTON
));
2691 XtVaSetValues(XtParent(selBox
), XmNtitle
, "Wrap Margin", NULL
);
2693 form
= XtVaCreateManagedWidget("form", xmFormWidgetClass
, selBox
, NULL
);
2695 WrapWindowToggle
= XtVaCreateManagedWidget("wrapWindowToggle",
2696 xmToggleButtonWidgetClass
, form
, XmNlabelString
,
2697 s1
=XmStringCreateSimple("Wrap and Fill at width of window"),
2699 XmNtopAttachment
, XmATTACH_FORM
,
2700 XmNleftAttachment
, XmATTACH_FORM
, NULL
);
2702 XtAddCallback(WrapWindowToggle
, XmNvalueChangedCallback
, wrapWindowCB
,NULL
);
2703 WrapText
= XtVaCreateManagedWidget("wrapText", xmTextWidgetClass
, form
,
2705 XmNtopAttachment
, XmATTACH_WIDGET
,
2706 XmNtopWidget
, WrapWindowToggle
,
2707 XmNrightAttachment
, XmATTACH_FORM
, NULL
);
2708 RemapDeleteKey(WrapText
);
2709 WrapTextLabel
= XtVaCreateManagedWidget("wrapMarginLabel",
2710 xmLabelGadgetClass
, form
,
2711 XmNlabelString
, s1
=XmStringCreateSimple(
2712 "Margin for Wrap and Fill"),
2714 XmNuserData
, WrapText
,
2715 XmNtopAttachment
, XmATTACH_WIDGET
,
2716 XmNtopWidget
, WrapWindowToggle
,
2717 XmNleftAttachment
, XmATTACH_FORM
,
2718 XmNrightAttachment
, XmATTACH_WIDGET
,
2719 XmNrightWidget
, WrapText
,
2720 XmNbottomAttachment
, XmATTACH_OPPOSITE_WIDGET
,
2721 XmNbottomWidget
, WrapText
, NULL
);
2724 /* Set default value */
2725 if (forWindow
== NULL
)
2726 margin
= GetPrefWrapMargin();
2728 XtVaGetValues(forWindow
->textArea
, textNwrapMargin
, &margin
, NULL
);
2729 XmToggleButtonSetState(WrapWindowToggle
, margin
==0, True
);
2731 SetIntText(WrapText
, margin
);
2732 XtSetSensitive(WrapText
, margin
!=0);
2733 XtSetSensitive(WrapTextLabel
, margin
!=0);
2735 /* Handle mnemonic selection of buttons and focus to dialog */
2736 AddDialogMnemonicHandler(form
, FALSE
);
2738 /* put up dialog and wait for user to press ok or cancel */
2739 WrapDialogForWindow
= forWindow
;
2740 DoneWithWrapDialog
= False
;
2741 ManageDialogCenteredOnPointer(selBox
);
2742 while (!DoneWithWrapDialog
)
2745 XtAppNextEvent(XtWidgetToApplicationContext(parent
), &event
);
2746 ServerDispatchEvent(&event
);
2749 XtDestroyWidget(selBox
);
2752 static void wrapOKCB(Widget w
, XtPointer clientData
, XtPointer callData
)
2754 int wrapAtWindow
, margin
, stat
;
2755 WindowInfo
*window
= WrapDialogForWindow
;
2757 /* get the values that the user entered and make sure they're ok */
2758 wrapAtWindow
= XmToggleButtonGetState(WrapWindowToggle
);
2762 stat
= GetIntTextWarn(WrapText
, &margin
, "wrap Margin", True
);
2763 if (stat
!= TEXT_READ_OK
)
2766 if (margin
<= 0 || margin
>= 1000)
2768 DialogF(DF_WARN
, WrapText
, 1, "Wrap Margin",
2769 "Wrap margin out of range", "OK");
2776 /* Ask the user about saving as a default preference */
2777 if (WrapDialogForWindow
!= NULL
) {
2779 if (!shortPrefToDefault(window
->shell
, "Wrap Margin Settings",
2781 DoneWithWrapDialog
= True
;
2785 SetPrefWrapMargin(margin
);
2786 SaveNEditPrefs(window
->shell
, GetPrefShortMenus());
2791 /* Set the value in either the requested window or default preferences */
2792 if (WrapDialogForWindow
== NULL
)
2793 SetPrefWrapMargin(margin
);
2797 sprintf(marginStr
, "%d", margin
);
2798 params
[0] = marginStr
;
2799 XtCallActionProc(window
->textArea
, "set_wrap_margin", NULL
, params
, 1);
2801 DoneWithWrapDialog
= True
;
2804 static void wrapCancelCB(Widget w
, XtPointer clientData
, XtPointer callData
)
2806 DoneWithWrapDialog
= True
;
2809 static void wrapWindowCB(Widget w
, XtPointer clientData
, XtPointer callData
)
2811 int wrapAtWindow
= XmToggleButtonGetState(w
);
2813 XtSetSensitive(WrapTextLabel
, !wrapAtWindow
);
2814 XtSetSensitive(WrapText
, !wrapAtWindow
);
2818 ** Create and show a dialog for selecting the shell
2820 void SelectShellDialog(Widget parent
, WindowInfo
* forWindow
)
2822 Widget shellSelDialog
;
2823 Arg shellSelDialogArgs
[2];
2826 /* Set up the dialog. */
2827 XtSetArg(shellSelDialogArgs
[0],
2828 XmNdialogStyle
, XmDIALOG_FULL_APPLICATION_MODAL
);
2829 XtSetArg(shellSelDialogArgs
[1], XmNautoUnmanage
, False
);
2830 shellSelDialog
= CreatePromptDialog(parent
, "shellSelDialog",
2831 shellSelDialogArgs
, 2);
2833 /* Fix dialog to our liking. */
2834 XtVaSetValues(XtParent(shellSelDialog
), XmNtitle
, "Command Shell", NULL
);
2835 XtAddCallback(shellSelDialog
, XmNokCallback
, (XtCallbackProc
) shellSelOKCB
,
2837 XtAddCallback(shellSelDialog
, XmNcancelCallback
,
2838 (XtCallbackProc
) shellSelCancelCB
, NULL
);
2839 XtUnmanageChild(XmSelectionBoxGetChild(shellSelDialog
, XmDIALOG_HELP_BUTTON
));
2840 label
= XmStringCreateLocalized("Enter shell path:");
2841 XtVaSetValues(shellSelDialog
, XmNselectionLabelString
, label
, NULL
);
2842 XmStringFree(label
);
2844 /* Set dialog's text to the current setting. */
2845 XmTextSetString(XmSelectionBoxGetChild(shellSelDialog
, XmDIALOG_TEXT
),
2846 (char*) GetPrefShell());
2848 DoneWithShellSelDialog
= False
;
2850 /* Show dialog and wait until the user made her choice. */
2851 ManageDialogCenteredOnPointer(shellSelDialog
);
2852 while (!DoneWithShellSelDialog
) {
2854 XtAppNextEvent(XtWidgetToApplicationContext(parent
), &event
);
2855 ServerDispatchEvent(&event
);
2858 XtDestroyWidget(shellSelDialog
);
2861 static void shellSelOKCB(Widget widget
, XtPointer clientData
,
2864 Widget shellSelDialog
= (Widget
) clientData
;
2865 String shellName
= XtMalloc(MAXPATHLEN
);
2866 struct stat attribute
;
2869 /* Leave with a warning if the dialog is not up. */
2870 if (!XtIsRealized(shellSelDialog
)) {
2871 fprintf(stderr
, "nedit: Callback shellSelOKCB() illegally called.\n");
2875 /* Get the string that the user entered and make sure it's ok. */
2876 shellName
= XmTextGetString(XmSelectionBoxGetChild(shellSelDialog
,
2879 if (-1 == stat(shellName
, &attribute
)) {
2880 dlgResult
= DialogF(DF_WARN
, shellSelDialog
, 2, "Command Shell",
2881 "The selected shell is not available.\nDo you want to use it anyway?",
2883 if (1 != dlgResult
) {
2888 SetPrefShell(shellName
);
2891 DoneWithShellSelDialog
= True
;
2894 static void shellSelCancelCB(Widget widgget
, XtPointer clientData
,
2897 DoneWithShellSelDialog
= True
;
2901 ** Present a dialog for editing language mode information
2903 void EditLanguageModes(void)
2905 #define LIST_RIGHT 40
2906 #define LEFT_MARGIN_POS 1
2907 #define RIGHT_MARGIN_POS 99
2909 Widget form
, nameLbl
, topLbl
, extLbl
, recogLbl
, delimitLbl
, defTipsLbl
;
2910 Widget okBtn
, applyBtn
, closeBtn
;
2911 Widget overrideFrame
, overrideForm
, delimitForm
;
2912 Widget tabForm
, tabLbl
, indentBox
, wrapBox
;
2917 /* if the dialog is already displayed, just pop it to the top and return */
2918 if (LMDialog
.shell
!= NULL
) {
2919 RaiseDialogWindow(LMDialog
.shell
);
2923 LMDialog
.languageModeList
= (languageModeRec
**)XtMalloc(
2924 sizeof(languageModeRec
*) * MAX_LANGUAGE_MODES
);
2925 for (i
=0; i
<NLanguageModes
; i
++)
2926 LMDialog
.languageModeList
[i
] = copyLanguageModeRec(LanguageModes
[i
]);
2927 LMDialog
.nLanguageModes
= NLanguageModes
;
2929 /* Create a form widget in an application shell */
2931 XtSetArg(args
[ac
], XmNdeleteResponse
, XmDO_NOTHING
); ac
++;
2932 XtSetArg(args
[ac
], XmNiconName
, "NEdit Language Modes"); ac
++;
2933 XtSetArg(args
[ac
], XmNtitle
, "Language Modes"); ac
++;
2934 LMDialog
.shell
= CreateWidget(TheAppShell
, "langModes",
2935 topLevelShellWidgetClass
, args
, ac
);
2936 AddSmallIcon(LMDialog
.shell
);
2937 form
= XtVaCreateManagedWidget("editLanguageModes", xmFormWidgetClass
,
2938 LMDialog
.shell
, XmNautoUnmanage
, False
,
2939 XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
2940 XtAddCallback(form
, XmNdestroyCallback
, lmDestroyCB
, NULL
);
2941 AddMotifCloseCallback(LMDialog
.shell
, lmCloseCB
, NULL
);
2943 topLbl
= XtVaCreateManagedWidget("topLabel", xmLabelGadgetClass
, form
,
2944 XmNlabelString
, s1
=MKSTRING(
2945 "To modify the properties of an existing language mode, select the name from\n\
2946 the list on the left. To add a new language, select \"New\" from the list."),
2948 XmNtopAttachment
, XmATTACH_POSITION
,
2950 XmNleftAttachment
, XmATTACH_POSITION
,
2951 XmNleftPosition
, LEFT_MARGIN_POS
,
2952 XmNrightAttachment
, XmATTACH_POSITION
,
2953 XmNrightPosition
, RIGHT_MARGIN_POS
, NULL
);
2956 nameLbl
= XtVaCreateManagedWidget("nameLbl", xmLabelGadgetClass
, form
,
2957 XmNlabelString
, s1
=XmStringCreateSimple("Name"),
2959 XmNalignment
, XmALIGNMENT_BEGINNING
,
2960 XmNleftAttachment
, XmATTACH_POSITION
,
2961 XmNleftPosition
, LIST_RIGHT
,
2962 XmNtopAttachment
, XmATTACH_WIDGET
,
2963 XmNtopOffset
, H_MARGIN
,
2964 XmNtopWidget
, topLbl
, NULL
);
2967 LMDialog
.nameW
= XtVaCreateManagedWidget("name", xmTextWidgetClass
, form
,
2969 XmNleftAttachment
, XmATTACH_POSITION
,
2970 XmNleftPosition
, LIST_RIGHT
,
2971 XmNtopAttachment
, XmATTACH_WIDGET
,
2972 XmNtopWidget
, nameLbl
,
2973 XmNrightAttachment
, XmATTACH_POSITION
,
2974 XmNrightPosition
, (RIGHT_MARGIN_POS
+ LIST_RIGHT
)/2, NULL
);
2975 RemapDeleteKey(LMDialog
.nameW
);
2976 XtVaSetValues(nameLbl
, XmNuserData
, LMDialog
.nameW
, NULL
);
2978 extLbl
= XtVaCreateManagedWidget("extLbl", xmLabelGadgetClass
, form
,
2980 s1
=XmStringCreateSimple("File extensions (separate w/ space)"),
2982 XmNalignment
, XmALIGNMENT_BEGINNING
,
2983 XmNleftAttachment
, XmATTACH_POSITION
,
2984 XmNleftPosition
, LIST_RIGHT
,
2985 XmNtopAttachment
, XmATTACH_WIDGET
,
2986 XmNtopOffset
, H_MARGIN
,
2987 XmNtopWidget
, LMDialog
.nameW
, NULL
);
2990 LMDialog
.extW
= XtVaCreateManagedWidget("ext", xmTextWidgetClass
, form
,
2991 XmNleftAttachment
, XmATTACH_POSITION
,
2992 XmNleftPosition
, LIST_RIGHT
,
2993 XmNtopAttachment
, XmATTACH_WIDGET
,
2994 XmNtopWidget
, extLbl
,
2995 XmNrightAttachment
, XmATTACH_POSITION
,
2996 XmNrightPosition
, RIGHT_MARGIN_POS
, NULL
);
2997 RemapDeleteKey(LMDialog
.extW
);
2998 XtVaSetValues(extLbl
, XmNuserData
, LMDialog
.extW
, NULL
);
3000 recogLbl
= XtVaCreateManagedWidget("recogLbl", xmLabelGadgetClass
, form
,
3001 XmNlabelString
, s1
=MKSTRING(
3002 "Recognition regular expression (applied to first 200\n\
3003 characters of file to determine type from content)"),
3004 XmNalignment
, XmALIGNMENT_BEGINNING
,
3006 XmNleftAttachment
, XmATTACH_POSITION
,
3007 XmNleftPosition
, LIST_RIGHT
,
3008 XmNtopAttachment
, XmATTACH_WIDGET
,
3009 XmNtopOffset
, H_MARGIN
,
3010 XmNtopWidget
, LMDialog
.extW
, NULL
);
3013 LMDialog
.recogW
= XtVaCreateManagedWidget("recog", xmTextWidgetClass
, form
,
3014 XmNleftAttachment
, XmATTACH_POSITION
,
3015 XmNleftPosition
, LIST_RIGHT
,
3016 XmNtopAttachment
, XmATTACH_WIDGET
,
3017 XmNtopWidget
, recogLbl
,
3018 XmNrightAttachment
, XmATTACH_POSITION
,
3019 XmNrightPosition
, RIGHT_MARGIN_POS
, NULL
);
3020 RemapDeleteKey(LMDialog
.recogW
);
3021 XtVaSetValues(recogLbl
, XmNuserData
, LMDialog
.recogW
, NULL
);
3023 defTipsLbl
= XtVaCreateManagedWidget("defTipsLbl", xmLabelGadgetClass
, form
,
3024 XmNlabelString
, s1
=MKSTRING(
3025 "Default calltips file(s) (separate w/colons)"),
3026 XmNalignment
, XmALIGNMENT_BEGINNING
,
3028 XmNleftAttachment
, XmATTACH_POSITION
,
3029 XmNleftPosition
, LIST_RIGHT
,
3030 XmNtopAttachment
, XmATTACH_WIDGET
,
3031 XmNtopOffset
, H_MARGIN
,
3032 XmNtopWidget
, LMDialog
.recogW
, NULL
);
3035 LMDialog
.defTipsW
= XtVaCreateManagedWidget("defTips", xmTextWidgetClass
,
3037 XmNleftAttachment
, XmATTACH_POSITION
,
3038 XmNleftPosition
, LIST_RIGHT
,
3039 XmNtopAttachment
, XmATTACH_WIDGET
,
3040 XmNtopWidget
, defTipsLbl
,
3041 XmNrightAttachment
, XmATTACH_POSITION
,
3042 XmNrightPosition
, RIGHT_MARGIN_POS
, NULL
);
3043 RemapDeleteKey(LMDialog
.defTipsW
);
3044 XtVaSetValues(defTipsLbl
, XmNuserData
, LMDialog
.defTipsW
, NULL
);
3046 okBtn
= XtVaCreateManagedWidget("ok", xmPushButtonWidgetClass
, form
,
3047 XmNlabelString
, s1
=XmStringCreateSimple("OK"),
3048 XmNmarginWidth
, BUTTON_WIDTH_MARGIN
,
3049 XmNleftAttachment
, XmATTACH_POSITION
,
3050 XmNleftPosition
, 10,
3051 XmNrightAttachment
, XmATTACH_POSITION
,
3052 XmNrightPosition
, 30,
3053 XmNbottomAttachment
, XmATTACH_POSITION
,
3054 XmNbottomPosition
, 99, NULL
);
3055 XtAddCallback(okBtn
, XmNactivateCallback
, lmOkCB
, NULL
);
3058 applyBtn
= XtVaCreateManagedWidget("apply", xmPushButtonWidgetClass
, form
,
3059 XmNlabelString
, s1
=XmStringCreateSimple("Apply"),
3061 XmNleftAttachment
, XmATTACH_POSITION
,
3062 XmNleftPosition
, 40,
3063 XmNrightAttachment
, XmATTACH_POSITION
,
3064 XmNrightPosition
, 60,
3065 XmNbottomAttachment
, XmATTACH_POSITION
,
3066 XmNbottomPosition
, 99, NULL
);
3067 XtAddCallback(applyBtn
, XmNactivateCallback
, lmApplyCB
, NULL
);
3070 closeBtn
= XtVaCreateManagedWidget("close",xmPushButtonWidgetClass
,form
,
3071 XmNlabelString
, s1
=XmStringCreateSimple("Close"),
3072 XmNleftAttachment
, XmATTACH_POSITION
,
3073 XmNleftPosition
, 70,
3074 XmNrightAttachment
, XmATTACH_POSITION
,
3075 XmNrightPosition
, 90,
3076 XmNbottomAttachment
, XmATTACH_POSITION
,
3077 XmNbottomPosition
, 99, NULL
);
3078 XtAddCallback(closeBtn
, XmNactivateCallback
, lmCloseCB
, NULL
);
3081 overrideFrame
= XtVaCreateManagedWidget("overrideFrame",
3082 xmFrameWidgetClass
, form
,
3083 XmNleftAttachment
, XmATTACH_POSITION
,
3084 XmNleftPosition
, LEFT_MARGIN_POS
,
3085 XmNrightAttachment
, XmATTACH_POSITION
,
3086 XmNrightPosition
, RIGHT_MARGIN_POS
,
3087 XmNbottomAttachment
, XmATTACH_WIDGET
,
3088 XmNbottomWidget
, closeBtn
,
3089 XmNbottomOffset
, H_MARGIN
, NULL
);
3090 overrideForm
= XtVaCreateManagedWidget("overrideForm", xmFormWidgetClass
,
3091 overrideFrame
, NULL
);
3092 XtVaCreateManagedWidget("overrideLbl", xmLabelGadgetClass
, overrideFrame
,
3093 XmNlabelString
, s1
=XmStringCreateSimple("Override Defaults"),
3094 XmNchildType
, XmFRAME_TITLE_CHILD
,
3095 XmNchildHorizontalAlignment
, XmALIGNMENT_CENTER
, NULL
);
3098 delimitForm
= XtVaCreateManagedWidget("delimitForm", xmFormWidgetClass
,
3100 XmNleftAttachment
, XmATTACH_POSITION
,
3101 XmNleftPosition
, LEFT_MARGIN_POS
,
3102 XmNtopAttachment
, XmATTACH_FORM
,
3103 XmNtopOffset
, H_MARGIN
,
3104 XmNrightAttachment
, XmATTACH_POSITION
,
3105 XmNrightPosition
, RIGHT_MARGIN_POS
, NULL
);
3106 delimitLbl
= XtVaCreateManagedWidget("delimitLbl", xmLabelGadgetClass
,
3108 XmNlabelString
, s1
=XmStringCreateSimple("Word delimiters"),
3110 XmNleftAttachment
, XmATTACH_FORM
,
3111 XmNtopAttachment
, XmATTACH_FORM
,
3112 XmNbottomAttachment
, XmATTACH_FORM
, NULL
);
3114 LMDialog
.delimitW
= XtVaCreateManagedWidget("delimit", xmTextWidgetClass
,
3116 XmNtopAttachment
, XmATTACH_FORM
,
3117 XmNleftAttachment
, XmATTACH_WIDGET
,
3118 XmNleftWidget
, delimitLbl
,
3119 XmNrightAttachment
, XmATTACH_FORM
,
3120 XmNbottomAttachment
, XmATTACH_FORM
, NULL
);
3121 RemapDeleteKey(LMDialog
.delimitW
);
3122 XtVaSetValues(delimitLbl
, XmNuserData
, LMDialog
.delimitW
, NULL
);
3124 tabForm
= XtVaCreateManagedWidget("tabForm", xmFormWidgetClass
,
3126 XmNleftAttachment
, XmATTACH_POSITION
,
3127 XmNleftPosition
, LEFT_MARGIN_POS
,
3128 XmNtopAttachment
, XmATTACH_WIDGET
,
3129 XmNtopWidget
, delimitForm
,
3130 XmNtopOffset
, H_MARGIN
,
3131 XmNrightAttachment
, XmATTACH_POSITION
,
3132 XmNrightPosition
, RIGHT_MARGIN_POS
, NULL
);
3133 tabLbl
= XtVaCreateManagedWidget("tabLbl", xmLabelGadgetClass
, tabForm
,
3134 XmNlabelString
, s1
=XmStringCreateSimple(
3135 "Alternative hardware tab spacing"),
3137 XmNleftAttachment
, XmATTACH_FORM
,
3138 XmNtopAttachment
, XmATTACH_FORM
,
3139 XmNbottomAttachment
, XmATTACH_FORM
, NULL
);
3141 LMDialog
.tabW
= XtVaCreateManagedWidget("delimit", xmTextWidgetClass
,
3144 XmNtopAttachment
, XmATTACH_FORM
,
3145 XmNleftAttachment
, XmATTACH_WIDGET
,
3146 XmNleftWidget
, tabLbl
,
3147 XmNbottomAttachment
, XmATTACH_FORM
, NULL
);
3148 RemapDeleteKey(LMDialog
.tabW
);
3149 XtVaSetValues(tabLbl
, XmNuserData
, LMDialog
.tabW
, NULL
);
3150 LMDialog
.emTabW
= XtVaCreateManagedWidget("delimit", xmTextWidgetClass
,
3153 XmNtopAttachment
, XmATTACH_FORM
,
3154 XmNrightAttachment
, XmATTACH_FORM
,
3155 XmNbottomAttachment
, XmATTACH_FORM
, NULL
);
3156 RemapDeleteKey(LMDialog
.emTabW
);
3157 XtVaCreateManagedWidget("emTabLbl", xmLabelGadgetClass
, tabForm
,
3159 s1
=XmStringCreateSimple("Alternative emulated tab spacing"),
3160 XmNalignment
, XmALIGNMENT_END
,
3162 XmNuserData
, LMDialog
.emTabW
,
3163 XmNleftAttachment
, XmATTACH_WIDGET
,
3164 XmNleftWidget
, LMDialog
.tabW
,
3165 XmNrightAttachment
, XmATTACH_WIDGET
,
3166 XmNrightWidget
, LMDialog
.emTabW
,
3167 XmNtopAttachment
, XmATTACH_FORM
,
3168 XmNbottomAttachment
, XmATTACH_FORM
, NULL
);
3171 indentBox
= XtVaCreateManagedWidget("indentBox", xmRowColumnWidgetClass
,
3173 XmNorientation
, XmHORIZONTAL
,
3174 XmNpacking
, XmPACK_TIGHT
,
3175 XmNradioBehavior
, True
,
3176 XmNleftAttachment
, XmATTACH_POSITION
,
3177 XmNleftPosition
, LEFT_MARGIN_POS
,
3178 XmNtopAttachment
, XmATTACH_WIDGET
,
3179 XmNtopWidget
, tabForm
,
3180 XmNtopOffset
, H_MARGIN
, NULL
);
3181 LMDialog
.defaultIndentW
= XtVaCreateManagedWidget("defaultIndent",
3182 xmToggleButtonWidgetClass
, indentBox
,
3185 XmNlabelString
, s1
=XmStringCreateSimple("Default indent style"),
3186 XmNmnemonic
, 'D', NULL
);
3188 LMDialog
.noIndentW
= XtVaCreateManagedWidget("noIndent",
3189 xmToggleButtonWidgetClass
, indentBox
,
3191 XmNlabelString
, s1
=XmStringCreateSimple("No automatic indent"),
3192 XmNmnemonic
, 'N', NULL
);
3194 LMDialog
.autoIndentW
= XtVaCreateManagedWidget("autoIndent",
3195 xmToggleButtonWidgetClass
, indentBox
,
3197 XmNlabelString
, s1
=XmStringCreateSimple("Auto-indent"),
3198 XmNmnemonic
, 'A', NULL
);
3200 LMDialog
.smartIndentW
= XtVaCreateManagedWidget("smartIndent",
3201 xmToggleButtonWidgetClass
, indentBox
,
3203 XmNlabelString
, s1
=XmStringCreateSimple("Smart-indent"),
3204 XmNmnemonic
, 'S', NULL
);
3207 wrapBox
= XtVaCreateManagedWidget("wrapBox", xmRowColumnWidgetClass
,
3209 XmNorientation
, XmHORIZONTAL
,
3210 XmNpacking
, XmPACK_TIGHT
,
3211 XmNradioBehavior
, True
,
3212 XmNleftAttachment
, XmATTACH_POSITION
,
3213 XmNleftPosition
, LEFT_MARGIN_POS
,
3214 XmNtopAttachment
, XmATTACH_WIDGET
,
3215 XmNtopWidget
, indentBox
,
3216 XmNtopOffset
, H_MARGIN
,
3217 XmNbottomAttachment
, XmATTACH_FORM
,
3218 XmNbottomOffset
, H_MARGIN
, NULL
);
3219 LMDialog
.defaultWrapW
= XtVaCreateManagedWidget("defaultWrap",
3220 xmToggleButtonWidgetClass
, wrapBox
,
3223 XmNlabelString
, s1
=XmStringCreateSimple("Default wrap style"),
3224 XmNmnemonic
, 'D', NULL
);
3226 LMDialog
.noWrapW
= XtVaCreateManagedWidget("noWrap",
3227 xmToggleButtonWidgetClass
, wrapBox
,
3229 XmNlabelString
, s1
=XmStringCreateSimple("No wrapping"),
3230 XmNmnemonic
, 'N', NULL
);
3232 LMDialog
.newlineWrapW
= XtVaCreateManagedWidget("newlineWrap",
3233 xmToggleButtonWidgetClass
, wrapBox
,
3235 XmNlabelString
, s1
=XmStringCreateSimple("Auto newline wrap"),
3236 XmNmnemonic
, 'A', NULL
);
3238 LMDialog
.contWrapW
= XtVaCreateManagedWidget("contWrap",
3239 xmToggleButtonWidgetClass
, wrapBox
,
3241 XmNlabelString
, s1
=XmStringCreateSimple("Continuous wrap"),
3242 XmNmnemonic
, 'C', NULL
);
3245 XtVaCreateManagedWidget("stretchForm", xmFormWidgetClass
, form
,
3246 XmNtopAttachment
, XmATTACH_WIDGET
,
3247 XmNtopWidget
, LMDialog
.defTipsW
,
3248 XmNleftAttachment
, XmATTACH_POSITION
,
3249 XmNleftPosition
, LIST_RIGHT
,
3250 XmNrightAttachment
, XmATTACH_POSITION
,
3251 XmNrightPosition
, RIGHT_MARGIN_POS
,
3252 XmNbottomAttachment
, XmATTACH_WIDGET
,
3253 XmNbottomWidget
, overrideFrame
,
3254 XmNbottomOffset
, H_MARGIN
*2, NULL
);
3257 XtSetArg(args
[ac
], XmNtopAttachment
, XmATTACH_WIDGET
); ac
++;
3258 XtSetArg(args
[ac
], XmNtopOffset
, H_MARGIN
); ac
++;
3259 XtSetArg(args
[ac
], XmNtopWidget
, topLbl
); ac
++;
3260 XtSetArg(args
[ac
], XmNleftAttachment
, XmATTACH_POSITION
); ac
++;
3261 XtSetArg(args
[ac
], XmNleftPosition
, LEFT_MARGIN_POS
); ac
++;
3262 XtSetArg(args
[ac
], XmNrightAttachment
, XmATTACH_POSITION
); ac
++;
3263 XtSetArg(args
[ac
], XmNrightPosition
, LIST_RIGHT
-1); ac
++;
3264 XtSetArg(args
[ac
], XmNbottomAttachment
, XmATTACH_WIDGET
); ac
++;
3265 XtSetArg(args
[ac
], XmNbottomWidget
, overrideFrame
); ac
++;
3266 XtSetArg(args
[ac
], XmNbottomOffset
, H_MARGIN
*2); ac
++;
3267 LMDialog
.managedListW
= CreateManagedList(form
, "list", args
, ac
,
3268 (void **)LMDialog
.languageModeList
, &LMDialog
.nLanguageModes
,
3269 MAX_LANGUAGE_MODES
, 15, lmGetDisplayedCB
, NULL
, lmSetDisplayedCB
,
3270 NULL
, lmFreeItemCB
);
3271 AddDeleteConfirmCB(LMDialog
.managedListW
, lmDeleteConfirmCB
, NULL
);
3272 XtVaSetValues(topLbl
, XmNuserData
, LMDialog
.managedListW
, NULL
);
3274 /* Set initial default button */
3275 XtVaSetValues(form
, XmNdefaultButton
, okBtn
, NULL
);
3276 XtVaSetValues(form
, XmNcancelButton
, closeBtn
, NULL
);
3278 /* Handle mnemonic selection of buttons and focus to dialog */
3279 AddDialogMnemonicHandler(form
, FALSE
);
3281 /* Realize all of the widgets in the new dialog */
3282 RealizeWithoutForcingPosition(LMDialog
.shell
);
3285 static void lmDestroyCB(Widget w
, XtPointer clientData
, XtPointer callData
)
3289 for (i
=0; i
<LMDialog
.nLanguageModes
; i
++)
3290 freeLanguageModeRec(LMDialog
.languageModeList
[i
]);
3291 XtFree((char *)LMDialog
.languageModeList
);
3294 static void lmOkCB(Widget w
, XtPointer clientData
, XtPointer callData
)
3296 if (!updateLMList())
3299 /* pop down and destroy the dialog */
3300 XtDestroyWidget(LMDialog
.shell
);
3301 LMDialog
.shell
= NULL
;
3304 static void lmApplyCB(Widget w
, XtPointer clientData
, XtPointer callData
)
3309 static void lmCloseCB(Widget w
, XtPointer clientData
, XtPointer callData
)
3311 /* pop down and destroy the dialog */
3312 XtDestroyWidget(LMDialog
.shell
);
3313 LMDialog
.shell
= NULL
;
3316 static int lmDeleteConfirmCB(int itemIndex
, void *cbArg
)
3320 /* Allow duplicate names to be deleted regardless of dependencies */
3321 for (i
=0; i
<LMDialog
.nLanguageModes
; i
++)
3322 if (i
!= itemIndex
&& !strcmp(LMDialog
.languageModeList
[i
]->name
,
3323 LMDialog
.languageModeList
[itemIndex
]->name
))
3326 /* don't allow deletion if data will be lost */
3327 if (LMHasHighlightPatterns(LMDialog
.languageModeList
[itemIndex
]->name
))
3329 DialogF(DF_WARN
, LMDialog
.shell
, 1, "Patterns exist",
3330 "This language mode has syntax highlighting\n"
3331 "patterns defined. Please delete the patterns\n"
3332 "first, in Preferences -> Default Settings ->\n"
3333 "Syntax Highlighting, before proceeding here.", "OK");
3337 /* don't allow deletion if data will be lost */
3338 if (LMHasSmartIndentMacros(LMDialog
.languageModeList
[itemIndex
]->name
))
3340 DialogF(DF_WARN
, LMDialog
.shell
, 1, "Smart Indent Macros exist",
3341 "This language mode has smart indent macros\n"
3342 "defined. Please delete the macros first,\n"
3343 "in Preferences -> Default Settings ->\n"
3344 "Auto Indent -> Program Smart Indent,\n"
3345 "before proceeding here.", "OK");
3353 ** Apply the changes that the user has made in the language modes dialog to the
3354 ** stored language mode information for this NEdit session (the data array
3357 static int updateLMList(void)
3360 int oldLanguageMode
;
3361 char *oldModeName
, *newDelimiters
;
3364 /* Get the current contents of the dialog fields */
3365 if (!UpdateManagedList(LMDialog
.managedListW
, True
))
3368 /* Fix up language mode indices in all open windows (which may change
3369 if the currently selected mode is deleted or has changed position),
3370 and update word delimiters */
3371 for (window
=WindowList
; window
!=NULL
; window
=window
->next
) {
3372 if (window
->languageMode
!= PLAIN_LANGUAGE_MODE
) {
3373 oldLanguageMode
= window
->languageMode
;
3374 oldModeName
= LanguageModes
[window
->languageMode
]->name
;
3375 window
->languageMode
= PLAIN_LANGUAGE_MODE
;
3376 for (i
=0; i
<LMDialog
.nLanguageModes
; i
++) {
3377 if (!strcmp(oldModeName
, LMDialog
.languageModeList
[i
]->name
)) {
3378 newDelimiters
= LMDialog
.languageModeList
[i
]->delimiters
;
3379 if (newDelimiters
== NULL
)
3380 newDelimiters
= GetPrefDelimiters();
3381 XtVaSetValues(window
->textArea
, textNwordDelimiters
,
3382 newDelimiters
, NULL
);
3383 for (j
=0; j
<window
->nPanes
; j
++)
3384 XtVaSetValues(window
->textPanes
[j
],
3385 textNwordDelimiters
, newDelimiters
, NULL
);
3386 /* don't forget to adapt the LM stored within the user menu cache */
3387 if (window
->userMenuCache
->umcLanguageMode
== oldLanguageMode
)
3388 window
->userMenuCache
->umcLanguageMode
= i
;
3389 if (window
->userBGMenuCache
.ubmcLanguageMode
== oldLanguageMode
)
3390 window
->userBGMenuCache
.ubmcLanguageMode
= i
;
3391 /* update the language mode of this window (document) */
3392 window
->languageMode
= i
;
3399 /* If there were any name changes, re-name dependent highlight patterns
3400 and smart-indent macros and fix up the weird rename-format names */
3401 for (i
=0; i
<LMDialog
.nLanguageModes
; i
++) {
3402 if (strchr(LMDialog
.languageModeList
[i
]->name
, ':') != NULL
) {
3403 char *newName
= strrchr(LMDialog
.languageModeList
[i
]->name
, ':')+1;
3404 *strchr(LMDialog
.languageModeList
[i
]->name
, ':') = '\0';
3405 RenameHighlightPattern(LMDialog
.languageModeList
[i
]->name
, newName
);
3406 RenameSmartIndentMacros(LMDialog
.languageModeList
[i
]->name
, newName
);
3407 memmove(LMDialog
.languageModeList
[i
]->name
, newName
,
3408 strlen(newName
) + 1);
3409 ChangeManagedListData(LMDialog
.managedListW
);
3413 /* Replace the old language mode list with the new one from the dialog */
3414 for (i
=0; i
<NLanguageModes
; i
++)
3415 freeLanguageModeRec(LanguageModes
[i
]);
3416 for (i
=0; i
<LMDialog
.nLanguageModes
; i
++)
3417 LanguageModes
[i
] = copyLanguageModeRec(LMDialog
.languageModeList
[i
]);
3418 NLanguageModes
= LMDialog
.nLanguageModes
;
3420 /* Update user menu info to update language mode dependencies of
3422 UpdateUserMenuInfo();
3424 /* Update the menus in the window menu bars and load any needed
3426 for (window
=WindowList
; window
!=NULL
; window
=window
->next
) {
3427 updateLanguageModeSubmenu(window
);
3428 if (window
->languageMode
!= PLAIN_LANGUAGE_MODE
&&
3429 LanguageModes
[window
->languageMode
]->defTipsFile
!= NULL
)
3430 AddTagsFile(LanguageModes
[window
->languageMode
]->defTipsFile
, TIP
);
3431 /* cache user menus: Rebuild all user menus of this window */
3432 RebuildAllMenus(window
);
3435 /* If a syntax highlighting dialog is up, update its menu */
3436 UpdateLanguageModeMenu();
3437 /* The same for the smart indent macro dialog */
3438 UpdateLangModeMenuSmartIndent();
3439 /* Note that preferences have been changed */
3445 static void *lmGetDisplayedCB(void *oldItem
, int explicitRequest
, int *abort
,
3448 languageModeRec
*lm
, *oldLM
= (languageModeRec
*)oldItem
;
3450 int i
, nCopies
, oldLen
;
3452 /* If the dialog is currently displaying the "new" entry and the
3453 fields are empty, that's just fine */
3454 if (oldItem
== NULL
&& lmDialogEmpty())
3457 /* Read the data the user has entered in the dialog fields */
3458 lm
= readLMDialogFields(True
);
3460 /* If there was a name change of a non-duplicate language mode, modify the
3461 name to the weird format of: ":old name:new name". This signals that a
3462 name change is necessary in lm dependent data such as highlight
3463 patterns. Duplicate language modes may be re-named at will, since no
3464 data will be lost due to the name change. */
3465 if (lm
!= NULL
&& oldLM
!= NULL
&& strcmp(oldLM
->name
, lm
->name
)) {
3467 for (i
=0; i
<LMDialog
.nLanguageModes
; i
++)
3468 if (!strcmp(oldLM
->name
, LMDialog
.languageModeList
[i
]->name
))
3471 oldLen
= strchr(oldLM
->name
, ':') == NULL
? strlen(oldLM
->name
) :
3472 strchr(oldLM
->name
, ':') - oldLM
->name
;
3473 tempName
= XtMalloc(oldLen
+ strlen(lm
->name
) + 2);
3474 strncpy(tempName
, oldLM
->name
, oldLen
);
3475 sprintf(&tempName
[oldLen
], ":%s", lm
->name
);
3477 lm
->name
= tempName
;
3481 /* If there are no problems reading the data, just return it */
3485 /* If there are problems, and the user didn't ask for the fields to be
3486 read, give more warning */
3487 if (!explicitRequest
)
3489 if (DialogF(DF_WARN
, LMDialog
.shell
, 2, "Discard Language Mode",
3490 "Discard incomplete entry\nfor current language mode?", "Keep",
3493 return oldItem
== NULL
3495 : (void *)copyLanguageModeRec((languageModeRec
*)oldItem
);
3499 /* Do readLMDialogFields again without "silent" mode to display warning */
3500 lm
= readLMDialogFields(False
);
3505 static void lmSetDisplayedCB(void *item
, void *cbArg
)
3507 languageModeRec
*lm
= (languageModeRec
*)item
;
3511 XmTextSetString(LMDialog
.nameW
, "");
3512 XmTextSetString(LMDialog
.extW
, "");
3513 XmTextSetString(LMDialog
.recogW
, "");
3514 XmTextSetString(LMDialog
.defTipsW
, "");
3515 XmTextSetString(LMDialog
.delimitW
, "");
3516 XmTextSetString(LMDialog
.tabW
, "");
3517 XmTextSetString(LMDialog
.emTabW
, "");
3518 RadioButtonChangeState(LMDialog
.defaultIndentW
, True
, True
);
3519 RadioButtonChangeState(LMDialog
.defaultWrapW
, True
, True
);
3521 XmTextSetString(LMDialog
.nameW
, strchr(lm
->name
, ':') == NULL
?
3522 lm
->name
: strchr(lm
->name
, ':')+1);
3523 extStr
= createExtString(lm
->extensions
, lm
->nExtensions
);
3524 XmTextSetString(LMDialog
.extW
, extStr
);
3526 XmTextSetString(LMDialog
.recogW
, lm
->recognitionExpr
);
3527 XmTextSetString(LMDialog
.defTipsW
, lm
->defTipsFile
);
3528 XmTextSetString(LMDialog
.delimitW
, lm
->delimiters
);
3529 if (lm
->tabDist
== DEFAULT_TAB_DIST
)
3530 XmTextSetString(LMDialog
.tabW
, "");
3532 SetIntText(LMDialog
.tabW
, lm
->tabDist
);
3533 if (lm
->emTabDist
== DEFAULT_EM_TAB_DIST
)
3534 XmTextSetString(LMDialog
.emTabW
, "");
3536 SetIntText(LMDialog
.emTabW
, lm
->emTabDist
);
3537 RadioButtonChangeState(LMDialog
.defaultIndentW
,
3538 lm
->indentStyle
== DEFAULT_INDENT
, False
);
3539 RadioButtonChangeState(LMDialog
.noIndentW
,
3540 lm
->indentStyle
== NO_AUTO_INDENT
, False
);
3541 RadioButtonChangeState(LMDialog
.autoIndentW
,
3542 lm
->indentStyle
== AUTO_INDENT
, False
);
3543 RadioButtonChangeState(LMDialog
.smartIndentW
,
3544 lm
->indentStyle
== SMART_INDENT
, False
);
3545 RadioButtonChangeState(LMDialog
.defaultWrapW
,
3546 lm
->wrapStyle
== DEFAULT_WRAP
, False
);
3547 RadioButtonChangeState(LMDialog
.noWrapW
,
3548 lm
->wrapStyle
== NO_WRAP
, False
);
3549 RadioButtonChangeState(LMDialog
.newlineWrapW
,
3550 lm
->wrapStyle
== NEWLINE_WRAP
, False
);
3551 RadioButtonChangeState(LMDialog
.contWrapW
,
3552 lm
->wrapStyle
== CONTINUOUS_WRAP
, False
);
3556 static void lmFreeItemCB(void *item
)
3558 freeLanguageModeRec((languageModeRec
*)item
);
3561 static void freeLanguageModeRec(languageModeRec
*lm
)
3566 XtFree(lm
->recognitionExpr
);
3567 XtFree(lm
->defTipsFile
);
3568 XtFree(lm
->delimiters
);
3569 for (i
=0; i
<lm
->nExtensions
; i
++)
3570 XtFree(lm
->extensions
[i
]);
3571 XtFree((char*) lm
->extensions
);
3576 ** Copy a languageModeRec data structure and all of the allocated data it contains
3578 static languageModeRec
*copyLanguageModeRec(languageModeRec
*lm
)
3580 languageModeRec
*newLM
;
3583 newLM
= (languageModeRec
*)XtMalloc(sizeof(languageModeRec
));
3584 newLM
->name
= XtMalloc(strlen(lm
->name
)+1);
3585 strcpy(newLM
->name
, lm
->name
);
3586 newLM
->nExtensions
= lm
->nExtensions
;
3587 newLM
->extensions
= (char **)XtMalloc(sizeof(char *) * lm
->nExtensions
);
3588 for (i
=0; i
<lm
->nExtensions
; i
++) {
3589 newLM
->extensions
[i
] = XtMalloc(strlen(lm
->extensions
[i
]) + 1);
3590 strcpy(newLM
->extensions
[i
], lm
->extensions
[i
]);
3592 if (lm
->recognitionExpr
== NULL
)
3593 newLM
->recognitionExpr
= NULL
;
3595 newLM
->recognitionExpr
= XtMalloc(strlen(lm
->recognitionExpr
)+1);
3596 strcpy(newLM
->recognitionExpr
, lm
->recognitionExpr
);
3598 if (lm
->defTipsFile
== NULL
)
3599 newLM
->defTipsFile
= NULL
;
3601 newLM
->defTipsFile
= XtMalloc(strlen(lm
->defTipsFile
)+1);
3602 strcpy(newLM
->defTipsFile
, lm
->defTipsFile
);
3604 if (lm
->delimiters
== NULL
)
3605 newLM
->delimiters
= NULL
;
3607 newLM
->delimiters
= XtMalloc(strlen(lm
->delimiters
)+1);
3608 strcpy(newLM
->delimiters
, lm
->delimiters
);
3610 newLM
->wrapStyle
= lm
->wrapStyle
;
3611 newLM
->indentStyle
= lm
->indentStyle
;
3612 newLM
->tabDist
= lm
->tabDist
;
3613 newLM
->emTabDist
= lm
->emTabDist
;
3618 ** Read the fields in the language modes dialog and create a languageModeRec data
3619 ** structure reflecting the current state of the selected language mode in the dialog.
3620 ** If any of the information is incorrect or missing, display a warning dialog and
3621 ** return NULL. Passing "silent" as True, suppresses the warning dialogs.
3623 static languageModeRec
*readLMDialogFields(int silent
)
3625 languageModeRec
*lm
;
3627 char *compileMsg
, *extStr
, *extPtr
;
3629 /* Allocate a language mode structure to return, set unread fields to
3630 empty so everything can be freed on errors by freeLanguageModeRec */
3631 lm
= (languageModeRec
*)XtMalloc(sizeof(languageModeRec
));
3632 lm
->nExtensions
= 0;
3633 lm
->recognitionExpr
= NULL
;
3634 lm
->defTipsFile
= NULL
;
3635 lm
->delimiters
= NULL
;
3637 /* read the name field */
3638 lm
->name
= ReadSymbolicFieldTextWidget(LMDialog
.nameW
,
3639 "language mode name", silent
);
3640 if (lm
->name
== NULL
) {
3645 if (*lm
->name
== '\0')
3649 DialogF(DF_WARN
, LMDialog
.shell
, 1, "Language Mode Name",
3650 "Please specify a name\nfor the language mode", "OK");
3651 XmProcessTraversal(LMDialog
.nameW
, XmTRAVERSE_CURRENT
);
3653 freeLanguageModeRec(lm
);
3657 /* read the extension list field */
3658 extStr
= extPtr
= XmTextGetString(LMDialog
.extW
);
3659 lm
->extensions
= readExtensionList(&extPtr
, &lm
->nExtensions
);
3662 /* read recognition expression */
3663 lm
->recognitionExpr
= XmTextGetString(LMDialog
.recogW
);
3664 if (*lm
->recognitionExpr
== '\0') {
3665 XtFree(lm
->recognitionExpr
);
3666 lm
->recognitionExpr
= NULL
;
3669 compiledRE
= CompileRE(lm
->recognitionExpr
, &compileMsg
, REDFLT_STANDARD
);
3671 if (compiledRE
== NULL
)
3675 DialogF(DF_WARN
, LMDialog
.shell
, 1, "Regex",
3676 "Recognition expression:\n%s", "OK", compileMsg
);
3677 XmProcessTraversal(LMDialog
.recogW
, XmTRAVERSE_CURRENT
);
3679 XtFree((char *)compiledRE
);
3680 freeLanguageModeRec(lm
);
3684 XtFree((char *)compiledRE
);
3687 /* Read the default calltips file for the language mode */
3688 lm
->defTipsFile
= XmTextGetString(LMDialog
.defTipsW
);
3689 if (*lm
->defTipsFile
== '\0') {
3691 XtFree(lm
->defTipsFile
);
3692 lm
->defTipsFile
= NULL
;
3694 /* Ensure that AddTagsFile will work */
3695 if (AddTagsFile(lm
->defTipsFile
, TIP
) == FALSE
) {
3698 DialogF(DF_WARN
, LMDialog
.shell
, 1, "Error reading Calltips",
3699 "Can't read default calltips file(s):\n \"%s\"\n",
3700 "OK", lm
->defTipsFile
);
3701 XmProcessTraversal(LMDialog
.recogW
, XmTRAVERSE_CURRENT
);
3703 freeLanguageModeRec(lm
);
3706 if (DeleteTagsFile(lm
->defTipsFile
, TIP
, False
) == FALSE
)
3707 fprintf(stderr
, "nedit: Internal error: Trouble deleting "
3708 "calltips file(s):\n \"%s\"\n", lm
->defTipsFile
);
3711 /* read tab spacing field */
3712 if (TextWidgetIsBlank(LMDialog
.tabW
))
3713 lm
->tabDist
= DEFAULT_TAB_DIST
;
3715 if (GetIntTextWarn(LMDialog
.tabW
, &lm
->tabDist
, "tab spacing", False
)
3717 freeLanguageModeRec(lm
);
3721 if (lm
->tabDist
<= 0 || lm
->tabDist
> 100)
3725 DialogF(DF_WARN
, LMDialog
.shell
, 1, "Invalid Tab Spacing",
3726 "Invalid tab spacing: %d", "OK", lm
->tabDist
);
3727 XmProcessTraversal(LMDialog
.tabW
, XmTRAVERSE_CURRENT
);
3729 freeLanguageModeRec(lm
);
3734 /* read emulated tab field */
3735 if (TextWidgetIsBlank(LMDialog
.emTabW
))
3737 lm
->emTabDist
= DEFAULT_EM_TAB_DIST
;
3740 if (GetIntTextWarn(LMDialog
.emTabW
, &lm
->emTabDist
,
3741 "emulated tab spacing", False
) != TEXT_READ_OK
)
3743 freeLanguageModeRec(lm
);
3747 if (lm
->emTabDist
< 0 || lm
->emTabDist
> 100)
3751 DialogF(DF_WARN
, LMDialog
.shell
, 1, "Invalid Tab Spacing",
3752 "Invalid emulated tab spacing: %d", "OK",
3754 XmProcessTraversal(LMDialog
.emTabW
, XmTRAVERSE_CURRENT
);
3756 freeLanguageModeRec(lm
);
3761 /* read delimiters string */
3762 lm
->delimiters
= XmTextGetString(LMDialog
.delimitW
);
3763 if (*lm
->delimiters
== '\0') {
3764 XtFree(lm
->delimiters
);
3765 lm
->delimiters
= NULL
;
3768 /* read indent style */
3769 if (XmToggleButtonGetState(LMDialog
.noIndentW
))
3770 lm
->indentStyle
= NO_AUTO_INDENT
;
3771 else if (XmToggleButtonGetState(LMDialog
.autoIndentW
))
3772 lm
->indentStyle
= AUTO_INDENT
;
3773 else if (XmToggleButtonGetState(LMDialog
.smartIndentW
))
3774 lm
->indentStyle
= SMART_INDENT
;
3776 lm
->indentStyle
= DEFAULT_INDENT
;
3778 /* read wrap style */
3779 if (XmToggleButtonGetState(LMDialog
.noWrapW
))
3780 lm
->wrapStyle
= NO_WRAP
;
3781 else if (XmToggleButtonGetState(LMDialog
.newlineWrapW
))
3782 lm
->wrapStyle
= NEWLINE_WRAP
;
3783 else if (XmToggleButtonGetState(LMDialog
.contWrapW
))
3784 lm
->wrapStyle
= CONTINUOUS_WRAP
;
3786 lm
->wrapStyle
= DEFAULT_WRAP
;
3792 ** Return True if the language mode dialog fields are blank (unchanged from the "New"
3793 ** language mode state).
3795 static int lmDialogEmpty(void)
3797 return TextWidgetIsBlank(LMDialog
.nameW
) &&
3798 TextWidgetIsBlank(LMDialog
.extW
) &&
3799 TextWidgetIsBlank(LMDialog
.recogW
) &&
3800 TextWidgetIsBlank(LMDialog
.delimitW
) &&
3801 TextWidgetIsBlank(LMDialog
.tabW
) &&
3802 TextWidgetIsBlank(LMDialog
.emTabW
) &&
3803 XmToggleButtonGetState(LMDialog
.defaultIndentW
) &&
3804 XmToggleButtonGetState(LMDialog
.defaultWrapW
);
3808 ** Present a dialog for changing fonts (primary, and for highlighting).
3810 void ChooseFonts(WindowInfo
*window
, int forWindow
)
3812 #define MARGIN_SPACING 10
3813 #define BTN_TEXT_OFFSET 3
3814 Widget form
, primaryLbl
, primaryBtn
, italicLbl
, italicBtn
;
3815 Widget boldLbl
, boldBtn
, boldItalicLbl
, boldItalicBtn
;
3816 Widget primaryFrame
, primaryForm
, highlightFrame
, highlightForm
;
3817 Widget okBtn
, applyBtn
, cancelBtn
;
3823 /* if the dialog is already displayed, just pop it to the top and return */
3824 if (window
->fontDialog
!= NULL
) {
3825 RaiseDialogWindow(((fontDialog
*)window
->fontDialog
)->shell
);
3829 /* Create a structure for keeping track of dialog state */
3830 fd
= (fontDialog
*)XtMalloc(sizeof(fontDialog
));
3831 fd
->window
= window
;
3832 fd
->forWindow
= forWindow
;
3833 window
->fontDialog
= (void*)fd
;
3835 /* Create a form widget in a dialog shell */
3837 XtSetArg(args
[ac
], XmNautoUnmanage
, False
); ac
++;
3838 XtSetArg(args
[ac
], XmNresizePolicy
, XmRESIZE_NONE
); ac
++;
3839 form
= CreateFormDialog(window
->shell
, "choose Fonts", args
, ac
);
3840 XtVaSetValues(form
, XmNshadowThickness
, 0, NULL
);
3841 fd
->shell
= XtParent(form
);
3842 XtVaSetValues(fd
->shell
, XmNtitle
, "Text Fonts", NULL
);
3843 AddMotifCloseCallback(XtParent(form
), fontCancelCB
, fd
);
3844 XtAddCallback(form
, XmNdestroyCallback
, fontDestroyCB
, fd
);
3846 primaryFrame
= XtVaCreateManagedWidget("primaryFrame", xmFrameWidgetClass
,
3847 form
, XmNmarginHeight
, 3,
3848 XmNtopAttachment
, XmATTACH_POSITION
,
3850 XmNleftAttachment
, XmATTACH_POSITION
,
3852 XmNrightAttachment
, XmATTACH_POSITION
,
3853 XmNrightPosition
, 99, NULL
);
3854 primaryForm
= XtVaCreateManagedWidget("primaryForm", xmFormWidgetClass
,
3855 primaryFrame
, NULL
);
3856 primaryLbl
= XtVaCreateManagedWidget("primaryFont", xmLabelGadgetClass
,
3858 XmNlabelString
, s1
=XmStringCreateSimple("Primary Font"),
3860 XmNchildType
, XmFRAME_TITLE_CHILD
,
3861 XmNchildHorizontalAlignment
, XmALIGNMENT_CENTER
, NULL
);
3864 primaryBtn
= XtVaCreateManagedWidget("primaryBtn",
3865 xmPushButtonWidgetClass
, primaryForm
,
3866 XmNlabelString
, s1
=XmStringCreateSimple("Browse..."),
3868 XmNtopAttachment
, XmATTACH_POSITION
,
3870 XmNtopOffset
, BTN_TEXT_OFFSET
,
3871 XmNleftAttachment
, XmATTACH_POSITION
,
3872 XmNleftPosition
, 1, NULL
);
3874 XtAddCallback(primaryBtn
, XmNactivateCallback
, primaryBrowseCB
, fd
);
3876 fd
->primaryW
= XtVaCreateManagedWidget("primary", xmTextWidgetClass
,
3879 XmNmaxLength
, MAX_FONT_LEN
,
3880 XmNleftAttachment
, XmATTACH_WIDGET
,
3881 XmNleftWidget
, primaryBtn
,
3882 XmNtopAttachment
, XmATTACH_POSITION
,
3884 XmNrightAttachment
, XmATTACH_POSITION
,
3885 XmNrightPosition
, 99, NULL
);
3886 RemapDeleteKey(fd
->primaryW
);
3887 XtAddCallback(fd
->primaryW
, XmNvalueChangedCallback
,
3888 primaryModifiedCB
, fd
);
3889 XtVaSetValues(primaryLbl
, XmNuserData
, fd
->primaryW
, NULL
);
3891 highlightFrame
= XtVaCreateManagedWidget("highlightFrame",
3892 xmFrameWidgetClass
, form
,
3894 XmNnavigationType
, XmTAB_GROUP
,
3895 XmNtopAttachment
, XmATTACH_WIDGET
,
3896 XmNtopWidget
, primaryFrame
,
3898 XmNleftAttachment
, XmATTACH_POSITION
,
3900 XmNrightAttachment
, XmATTACH_POSITION
,
3901 XmNrightPosition
, 99, NULL
);
3902 highlightForm
= XtVaCreateManagedWidget("highlightForm", xmFormWidgetClass
,
3903 highlightFrame
, NULL
);
3904 XtVaCreateManagedWidget("highlightFonts", xmLabelGadgetClass
,
3907 s1
=XmStringCreateSimple("Fonts for Syntax Highlighting"),
3908 XmNchildType
, XmFRAME_TITLE_CHILD
,
3909 XmNchildHorizontalAlignment
, XmALIGNMENT_CENTER
, NULL
);
3912 fd
->fillW
= XtVaCreateManagedWidget("fillBtn",
3913 xmPushButtonWidgetClass
, highlightForm
,
3915 s1
=XmStringCreateSimple("Fill Highlight Fonts from Primary"),
3917 XmNtopAttachment
, XmATTACH_POSITION
,
3919 XmNtopOffset
, BTN_TEXT_OFFSET
,
3920 XmNleftAttachment
, XmATTACH_POSITION
,
3921 XmNleftPosition
, 1, NULL
);
3923 XtAddCallback(fd
->fillW
, XmNactivateCallback
, fillFromPrimaryCB
, fd
);
3925 italicLbl
= XtVaCreateManagedWidget("italicLbl", xmLabelGadgetClass
,
3927 XmNlabelString
, s1
=XmStringCreateSimple("Italic Font"),
3929 XmNalignment
, XmALIGNMENT_BEGINNING
,
3930 XmNtopAttachment
, XmATTACH_WIDGET
,
3931 XmNtopWidget
, fd
->fillW
,
3932 XmNtopOffset
, MARGIN_SPACING
,
3933 XmNleftAttachment
, XmATTACH_POSITION
,
3934 XmNleftPosition
, 1, NULL
);
3937 fd
->italicErrW
= XtVaCreateManagedWidget("italicErrLbl",
3938 xmLabelGadgetClass
, highlightForm
,
3939 XmNlabelString
, s1
=XmStringCreateSimple(
3940 "(vvv spacing is inconsistent with primary font vvv)"),
3941 XmNalignment
, XmALIGNMENT_END
,
3942 XmNtopAttachment
, XmATTACH_WIDGET
,
3943 XmNtopWidget
, fd
->fillW
,
3944 XmNtopOffset
, MARGIN_SPACING
,
3945 XmNleftAttachment
, XmATTACH_WIDGET
,
3946 XmNleftWidget
, italicLbl
,
3947 XmNrightAttachment
, XmATTACH_POSITION
,
3948 XmNrightPosition
, 99, NULL
);
3951 italicBtn
= XtVaCreateManagedWidget("italicBtn",
3952 xmPushButtonWidgetClass
, highlightForm
,
3953 XmNlabelString
, s1
=XmStringCreateSimple("Browse..."),
3955 XmNtopAttachment
, XmATTACH_WIDGET
,
3956 XmNtopWidget
, italicLbl
,
3957 XmNtopOffset
, BTN_TEXT_OFFSET
,
3958 XmNleftAttachment
, XmATTACH_POSITION
,
3959 XmNleftPosition
, 1, NULL
);
3961 XtAddCallback(italicBtn
, XmNactivateCallback
, italicBrowseCB
, fd
);
3963 fd
->italicW
= XtVaCreateManagedWidget("italic", xmTextWidgetClass
,
3965 XmNmaxLength
, MAX_FONT_LEN
,
3966 XmNleftAttachment
, XmATTACH_WIDGET
,
3967 XmNleftWidget
, italicBtn
,
3968 XmNtopAttachment
, XmATTACH_WIDGET
,
3969 XmNtopWidget
, italicLbl
,
3970 XmNrightAttachment
, XmATTACH_POSITION
,
3971 XmNrightPosition
, 99, NULL
);
3972 RemapDeleteKey(fd
->italicW
);
3973 XtAddCallback(fd
->italicW
, XmNvalueChangedCallback
,
3974 italicModifiedCB
, fd
);
3975 XtVaSetValues(italicLbl
, XmNuserData
, fd
->italicW
, NULL
);
3977 boldLbl
= XtVaCreateManagedWidget("boldLbl", xmLabelGadgetClass
,
3979 XmNlabelString
, s1
=XmStringCreateSimple("Bold Font"),
3981 XmNalignment
, XmALIGNMENT_BEGINNING
,
3982 XmNtopAttachment
, XmATTACH_WIDGET
,
3983 XmNtopWidget
, italicBtn
,
3984 XmNtopOffset
, MARGIN_SPACING
,
3985 XmNleftAttachment
, XmATTACH_POSITION
,
3986 XmNleftPosition
, 1, NULL
);
3989 fd
->boldErrW
= XtVaCreateManagedWidget("boldErrLbl",
3990 xmLabelGadgetClass
, highlightForm
,
3991 XmNlabelString
, s1
=XmStringCreateSimple(""),
3992 XmNalignment
, XmALIGNMENT_END
,
3993 XmNtopAttachment
, XmATTACH_WIDGET
,
3994 XmNtopWidget
, italicBtn
,
3995 XmNtopOffset
, MARGIN_SPACING
,
3996 XmNleftAttachment
, XmATTACH_WIDGET
,
3997 XmNleftWidget
, boldLbl
,
3998 XmNrightAttachment
, XmATTACH_POSITION
,
3999 XmNrightPosition
, 99, NULL
);
4002 boldBtn
= XtVaCreateManagedWidget("boldBtn",
4003 xmPushButtonWidgetClass
, highlightForm
,
4004 XmNlabelString
, s1
=XmStringCreateSimple("Browse..."),
4006 XmNtopAttachment
, XmATTACH_WIDGET
,
4007 XmNtopWidget
, boldLbl
,
4008 XmNtopOffset
, BTN_TEXT_OFFSET
,
4009 XmNleftAttachment
, XmATTACH_POSITION
,
4010 XmNleftPosition
, 1, NULL
);
4012 XtAddCallback(boldBtn
, XmNactivateCallback
, boldBrowseCB
, fd
);
4014 fd
->boldW
= XtVaCreateManagedWidget("bold", xmTextWidgetClass
,
4016 XmNmaxLength
, MAX_FONT_LEN
,
4017 XmNleftAttachment
, XmATTACH_WIDGET
,
4018 XmNleftWidget
, boldBtn
,
4019 XmNtopAttachment
, XmATTACH_WIDGET
,
4020 XmNtopWidget
, boldLbl
,
4021 XmNrightAttachment
, XmATTACH_POSITION
,
4022 XmNrightPosition
, 99, NULL
);
4023 RemapDeleteKey(fd
->boldW
);
4024 XtAddCallback(fd
->boldW
, XmNvalueChangedCallback
,
4025 boldModifiedCB
, fd
);
4026 XtVaSetValues(boldLbl
, XmNuserData
, fd
->boldW
, NULL
);
4028 boldItalicLbl
= XtVaCreateManagedWidget("boldItalicLbl", xmLabelGadgetClass
,
4030 XmNlabelString
, s1
=XmStringCreateSimple("Bold Italic Font"),
4032 XmNalignment
, XmALIGNMENT_BEGINNING
,
4033 XmNtopAttachment
, XmATTACH_WIDGET
,
4034 XmNtopWidget
, boldBtn
,
4035 XmNtopOffset
, MARGIN_SPACING
,
4036 XmNleftAttachment
, XmATTACH_POSITION
,
4037 XmNleftPosition
, 1, NULL
);
4040 fd
->boldItalicErrW
= XtVaCreateManagedWidget("boldItalicErrLbl",
4041 xmLabelGadgetClass
, highlightForm
,
4042 XmNlabelString
, s1
=XmStringCreateSimple(""),
4043 XmNalignment
, XmALIGNMENT_END
,
4044 XmNtopAttachment
, XmATTACH_WIDGET
,
4045 XmNtopWidget
, boldBtn
,
4046 XmNtopOffset
, MARGIN_SPACING
,
4047 XmNleftAttachment
, XmATTACH_WIDGET
,
4048 XmNleftWidget
, boldItalicLbl
,
4049 XmNrightAttachment
, XmATTACH_POSITION
,
4050 XmNrightPosition
, 99, NULL
);
4053 boldItalicBtn
= XtVaCreateManagedWidget("boldItalicBtn",
4054 xmPushButtonWidgetClass
, highlightForm
,
4055 XmNlabelString
, s1
=XmStringCreateSimple("Browse..."),
4057 XmNtopAttachment
, XmATTACH_WIDGET
,
4058 XmNtopWidget
, boldItalicLbl
,
4059 XmNtopOffset
, BTN_TEXT_OFFSET
,
4060 XmNleftAttachment
, XmATTACH_POSITION
,
4061 XmNleftPosition
, 1, NULL
);
4063 XtAddCallback(boldItalicBtn
, XmNactivateCallback
, boldItalicBrowseCB
, fd
);
4065 fd
->boldItalicW
= XtVaCreateManagedWidget("boldItalic",
4066 xmTextWidgetClass
, highlightForm
,
4067 XmNmaxLength
, MAX_FONT_LEN
,
4068 XmNleftAttachment
, XmATTACH_WIDGET
,
4069 XmNleftWidget
, boldItalicBtn
,
4070 XmNtopAttachment
, XmATTACH_WIDGET
,
4071 XmNtopWidget
, boldItalicLbl
,
4072 XmNrightAttachment
, XmATTACH_POSITION
,
4073 XmNrightPosition
, 99, NULL
);
4074 RemapDeleteKey(fd
->boldItalicW
);
4075 XtAddCallback(fd
->boldItalicW
, XmNvalueChangedCallback
,
4076 boldItalicModifiedCB
, fd
);
4077 XtVaSetValues(boldItalicLbl
, XmNuserData
, fd
->boldItalicW
, NULL
);
4079 okBtn
= XtVaCreateManagedWidget("ok", xmPushButtonWidgetClass
, form
,
4080 XmNlabelString
, s1
=XmStringCreateSimple("OK"),
4081 XmNmarginWidth
, BUTTON_WIDTH_MARGIN
,
4082 XmNtopAttachment
, XmATTACH_WIDGET
,
4083 XmNtopWidget
, highlightFrame
,
4084 XmNtopOffset
, MARGIN_SPACING
,
4085 XmNleftAttachment
, XmATTACH_POSITION
,
4086 XmNleftPosition
, forWindow
? 13 : 26,
4087 XmNrightAttachment
, XmATTACH_POSITION
,
4088 XmNrightPosition
, forWindow
? 27 : 40, NULL
);
4089 XtAddCallback(okBtn
, XmNactivateCallback
, fontOkCB
, fd
);
4093 applyBtn
= XtVaCreateManagedWidget("apply",xmPushButtonWidgetClass
,form
,
4094 XmNlabelString
, s1
=XmStringCreateSimple("Apply"),
4096 XmNtopAttachment
, XmATTACH_WIDGET
,
4097 XmNtopWidget
, highlightFrame
,
4098 XmNtopOffset
, MARGIN_SPACING
,
4099 XmNleftAttachment
, XmATTACH_POSITION
,
4100 XmNleftPosition
, 43,
4101 XmNrightAttachment
, XmATTACH_POSITION
,
4102 XmNrightPosition
, 57, NULL
);
4103 XtAddCallback(applyBtn
, XmNactivateCallback
, fontApplyCB
, fd
);
4107 cancelBtn
= XtVaCreateManagedWidget("cancel",
4108 xmPushButtonWidgetClass
, form
,
4110 s1
= XmStringCreateSimple(forWindow
? "Close" : "Cancel"),
4111 XmNtopAttachment
, XmATTACH_WIDGET
,
4112 XmNtopWidget
, highlightFrame
,
4113 XmNtopOffset
, MARGIN_SPACING
,
4114 XmNleftAttachment
, XmATTACH_POSITION
,
4115 XmNleftPosition
, forWindow
? 73 : 59,
4116 XmNrightAttachment
, XmATTACH_POSITION
,
4117 XmNrightPosition
, forWindow
? 87 : 73,
4119 XtAddCallback(cancelBtn
, XmNactivateCallback
, fontCancelCB
, fd
);
4122 /* Set initial default button */
4123 XtVaSetValues(form
, XmNdefaultButton
, okBtn
, NULL
);
4124 XtVaSetValues(form
, XmNcancelButton
, cancelBtn
, NULL
);
4126 /* Set initial values */
4128 XmTextSetString(fd
->primaryW
, window
->fontName
);
4129 XmTextSetString(fd
->boldW
, window
->boldFontName
);
4130 XmTextSetString(fd
->italicW
, window
->italicFontName
);
4131 XmTextSetString(fd
->boldItalicW
, window
->boldItalicFontName
);
4133 XmTextSetString(fd
->primaryW
, GetPrefFontName());
4134 XmTextSetString(fd
->boldW
, GetPrefBoldFontName());
4135 XmTextSetString(fd
->italicW
, GetPrefItalicFontName());
4136 XmTextSetString(fd
->boldItalicW
, GetPrefBoldItalicFontName());
4139 /* Handle mnemonic selection of buttons and focus to dialog */
4140 AddDialogMnemonicHandler(form
, FALSE
);
4143 ManageDialogCenteredOnPointer(form
);
4146 static void fillFromPrimaryCB(Widget w
, XtPointer clientData
,
4149 fontDialog
*fd
= (fontDialog
*)clientData
;
4150 char *primaryName
, *errMsg
;
4151 char modifiedFontName
[MAX_FONT_LEN
];
4152 char *searchString
= "(-[^-]*-[^-]*)-([^-]*)-([^-]*)-(.*)";
4153 char *italicReplaceString
= "\\1-\\2-o-\\4";
4154 char *boldReplaceString
= "\\1-bold-\\3-\\4";
4155 char *boldItalicReplaceString
= "\\1-bold-o-\\4";
4158 /* Match the primary font agains RE pattern for font names. If it
4159 doesn't match, we can't generate highlight font names, so return */
4160 compiledRE
= CompileRE(searchString
, &errMsg
, REDFLT_STANDARD
);
4161 primaryName
= XmTextGetString(fd
->primaryW
);
4162 if (!ExecRE(compiledRE
, primaryName
, NULL
, False
, '\0', '\0', NULL
, NULL
, NULL
)) {
4163 XBell(XtDisplay(fd
->shell
), 0);
4165 XtFree(primaryName
);
4169 /* Make up names for new fonts based on RE replace patterns */
4170 SubstituteRE(compiledRE
, italicReplaceString
, modifiedFontName
,
4172 XmTextSetString(fd
->italicW
, modifiedFontName
);
4173 SubstituteRE(compiledRE
, boldReplaceString
, modifiedFontName
,
4175 XmTextSetString(fd
->boldW
, modifiedFontName
);
4176 SubstituteRE(compiledRE
, boldItalicReplaceString
, modifiedFontName
,
4178 XmTextSetString(fd
->boldItalicW
, modifiedFontName
);
4179 XtFree(primaryName
);
4183 static void primaryModifiedCB(Widget w
, XtPointer clientData
,
4186 fontDialog
*fd
= (fontDialog
*)clientData
;
4188 showFontStatus(fd
, fd
->italicW
, fd
->italicErrW
);
4189 showFontStatus(fd
, fd
->boldW
, fd
->boldErrW
);
4190 showFontStatus(fd
, fd
->boldItalicW
, fd
->boldItalicErrW
);
4192 static void italicModifiedCB(Widget w
, XtPointer clientData
, XtPointer callData
)
4194 fontDialog
*fd
= (fontDialog
*)clientData
;
4196 showFontStatus(fd
, fd
->italicW
, fd
->italicErrW
);
4198 static void boldModifiedCB(Widget w
, XtPointer clientData
, XtPointer callData
)
4200 fontDialog
*fd
= (fontDialog
*)clientData
;
4202 showFontStatus(fd
, fd
->boldW
, fd
->boldErrW
);
4204 static void boldItalicModifiedCB(Widget w
, XtPointer clientData
,
4207 fontDialog
*fd
= (fontDialog
*)clientData
;
4209 showFontStatus(fd
, fd
->boldItalicW
, fd
->boldItalicErrW
);
4212 static void primaryBrowseCB(Widget w
, XtPointer clientData
, XtPointer callData
)
4214 fontDialog
*fd
= (fontDialog
*)clientData
;
4216 browseFont(fd
->shell
, fd
->primaryW
);
4218 static void italicBrowseCB(Widget w
, XtPointer clientData
, XtPointer callData
)
4220 fontDialog
*fd
= (fontDialog
*)clientData
;
4222 browseFont(fd
->shell
, fd
->italicW
);
4224 static void boldBrowseCB(Widget w
, XtPointer clientData
, XtPointer callData
)
4226 fontDialog
*fd
= (fontDialog
*)clientData
;
4228 browseFont(fd
->shell
, fd
->boldW
);
4230 static void boldItalicBrowseCB(Widget w
, XtPointer clientData
,
4233 fontDialog
*fd
= (fontDialog
*)clientData
;
4235 browseFont(fd
->shell
, fd
->boldItalicW
);
4238 static void fontDestroyCB(Widget w
, XtPointer clientData
, XtPointer callData
)
4240 fontDialog
*fd
= (fontDialog
*)clientData
;
4242 fd
->window
->fontDialog
= NULL
;
4246 static void fontOkCB(Widget w
, XtPointer clientData
, XtPointer callData
)
4248 fontDialog
*fd
= (fontDialog
*)clientData
;
4252 /* pop down and destroy the dialog */
4253 XtDestroyWidget(fd
->shell
);
4256 static void fontApplyCB(Widget w
, XtPointer clientData
, XtPointer callData
)
4258 fontDialog
*fd
= (fontDialog
*)clientData
;
4263 static void fontCancelCB(Widget w
, XtPointer clientData
, XtPointer callData
)
4265 fontDialog
*fd
= (fontDialog
*)clientData
;
4267 /* pop down and destroy the dialog */
4268 XtDestroyWidget(fd
->shell
);
4272 ** Check over a font name in a text field to make sure it agrees with the
4273 ** primary font in height and spacing.
4275 static int checkFontStatus(fontDialog
*fd
, Widget fontTextFieldW
)
4277 char *primaryName
, *testName
;
4278 XFontStruct
*primaryFont
, *testFont
;
4279 Display
*display
= XtDisplay(fontTextFieldW
);
4280 int primaryWidth
, primaryHeight
, testWidth
, testHeight
;
4282 /* Get width and height of the font to check. Note the test for empty
4283 name: X11R6 clients freak out X11R5 servers if they ask them to load
4284 an empty font name, and kill the whole application! */
4285 testName
= XmTextGetString(fontTextFieldW
);
4286 if (testName
[0] == '\0') {
4290 testFont
= XLoadQueryFont(display
, testName
);
4291 if (testFont
== NULL
) {
4296 testWidth
= testFont
->min_bounds
.width
;
4297 testHeight
= testFont
->ascent
+ testFont
->descent
;
4298 XFreeFont(display
, testFont
);
4300 /* Get width and height of the primary font */
4301 primaryName
= XmTextGetString(fd
->primaryW
);
4302 if (primaryName
[0] == '\0') {
4303 XtFree(primaryName
);
4306 primaryFont
= XLoadQueryFont(display
, primaryName
);
4307 if (primaryFont
== NULL
) {
4308 XtFree(primaryName
);
4311 XtFree(primaryName
);
4312 primaryWidth
= primaryFont
->min_bounds
.width
;
4313 primaryHeight
= primaryFont
->ascent
+ primaryFont
->descent
;
4314 XFreeFont(display
, primaryFont
);
4316 /* Compare font information */
4317 if (testWidth
!= primaryWidth
)
4319 if (testHeight
!= primaryHeight
)
4325 ** Update the error label for a font text field to reflect its validity and degree
4326 ** of agreement with the currently selected primary font
4328 static int showFontStatus(fontDialog
*fd
, Widget fontTextFieldW
,
4335 status
= checkFontStatus(fd
, fontTextFieldW
);
4336 if (status
== BAD_PRIMARY
)
4337 msg
= "(font below may not match primary font)";
4338 else if (status
== BAD_FONT
)
4339 msg
= "(xxx font below is invalid xxx)";
4340 else if (status
== BAD_SIZE
)
4341 msg
= "(height of font below does not match primary)";
4342 else if (status
== BAD_SPACING
)
4343 msg
= "(spacing of font below does not match primary)";
4347 XtVaSetValues(errorLabelW
, XmNlabelString
, s
=XmStringCreateSimple(msg
),
4354 ** Put up a font selector panel to set the font name in the text widget "fontTextW"
4356 static void browseFont(Widget parent
, Widget fontTextW
)
4358 char *origFontName
, *newFontName
;
4359 Pixel fgPixel
, bgPixel
;
4362 origFontName
= XmTextGetString(fontTextW
);
4364 /* Get the values from the defaults */
4365 fgPixel
= AllocColor(parent
, GetPrefColorName(TEXT_FG_COLOR
),
4366 &dummy
, &dummy
, &dummy
);
4367 bgPixel
= AllocColor(parent
, GetPrefColorName(TEXT_BG_COLOR
),
4368 &dummy
, &dummy
, &dummy
);
4370 newFontName
= FontSel(parent
, PREF_FIXED
, origFontName
, fgPixel
, bgPixel
);
4371 XtFree(origFontName
);
4372 if (newFontName
== NULL
)
4374 XmTextSetString(fontTextW
, newFontName
);
4375 XtFree(newFontName
);
4379 ** Accept the changes in the dialog and set the fonts regardless of errors
4381 static void updateFonts(fontDialog
*fd
)
4383 char *fontName
, *italicName
, *boldName
, *boldItalicName
;
4385 fontName
= XmTextGetString(fd
->primaryW
);
4386 italicName
= XmTextGetString(fd
->italicW
);
4387 boldName
= XmTextGetString(fd
->boldW
);
4388 boldItalicName
= XmTextGetString(fd
->boldItalicW
);
4390 if (fd
->forWindow
) {
4392 params
[0] = fontName
;
4393 params
[1] = italicName
;
4394 params
[2] = boldName
;
4395 params
[3] = boldItalicName
;
4396 XtCallActionProc(fd
->window
->textArea
, "set_fonts", NULL
, params
, 4);
4398 SetFonts(fd->window, fontName, italicName, boldName, boldItalicName);
4402 SetPrefFont(fontName
);
4403 SetPrefItalicFont(italicName
);
4404 SetPrefBoldFont(boldName
);
4405 SetPrefBoldItalicFont(boldItalicName
);
4410 XtFree(boldItalicName
);
4414 ** Change the language mode to the one indexed by "mode", reseting word
4415 ** delimiters, syntax highlighting and other mode specific parameters
4417 static void reapplyLanguageMode(WindowInfo
*window
, int mode
, int forceDefaults
)
4420 int i
, wrapMode
, indentStyle
, tabDist
, emTabDist
, highlight
, oldEmTabDist
;
4421 int wrapModeIsDef
, tabDistIsDef
, emTabDistIsDef
, indentStyleIsDef
;
4422 int highlightIsDef
, haveHighlightPatterns
, haveSmartIndentMacros
;
4423 int oldMode
= window
->languageMode
;
4425 /* If the mode is the same, and changes aren't being forced (as might
4426 happen with Save As...), don't mess with already correct settings */
4427 if (window
->languageMode
== mode
&& !forceDefaults
)
4430 /* Change the mode name stored in the window */
4431 window
->languageMode
= mode
;
4433 /* Decref oldMode's default calltips file if needed */
4434 if (oldMode
!= PLAIN_LANGUAGE_MODE
&& LanguageModes
[oldMode
]->defTipsFile
) {
4435 DeleteTagsFile( LanguageModes
[oldMode
]->defTipsFile
, TIP
, False
);
4438 /* Set delimiters for all text widgets */
4439 if (mode
== PLAIN_LANGUAGE_MODE
|| LanguageModes
[mode
]->delimiters
== NULL
)
4440 delimiters
= GetPrefDelimiters();
4442 delimiters
= LanguageModes
[mode
]->delimiters
;
4443 XtVaSetValues(window
->textArea
, textNwordDelimiters
, delimiters
, NULL
);
4444 for (i
=0; i
<window
->nPanes
; i
++)
4445 XtVaSetValues(window
->textPanes
[i
], textNautoIndent
, delimiters
, NULL
);
4447 /* Decide on desired values for language-specific parameters. If a
4448 parameter was set to its default value, set it to the new default,
4449 otherwise, leave it alone */
4450 wrapModeIsDef
= window
->wrapMode
== GetPrefWrap(oldMode
);
4451 tabDistIsDef
= BufGetTabDistance(window
->buffer
) == GetPrefTabDist(oldMode
);
4452 XtVaGetValues(window
->textArea
, textNemulateTabs
, &oldEmTabDist
, NULL
);
4453 emTabDistIsDef
= oldEmTabDist
== GetPrefEmTabDist(oldMode
);
4454 indentStyleIsDef
= window
->indentStyle
== GetPrefAutoIndent(oldMode
) ||
4455 (GetPrefAutoIndent(oldMode
) == SMART_INDENT
&&
4456 window
->indentStyle
== AUTO_INDENT
&&
4457 !SmartIndentMacrosAvailable(LanguageModeName(oldMode
)));
4458 highlightIsDef
= window
->highlightSyntax
== GetPrefHighlightSyntax()
4459 || (GetPrefHighlightSyntax() &&
4460 FindPatternSet(LanguageModeName(oldMode
)) == NULL
);
4461 wrapMode
= wrapModeIsDef
|| forceDefaults
?
4462 GetPrefWrap(mode
) : window
->wrapMode
;
4463 tabDist
= tabDistIsDef
|| forceDefaults
?
4464 GetPrefTabDist(mode
) : BufGetTabDistance(window
->buffer
);
4465 emTabDist
= emTabDistIsDef
|| forceDefaults
?
4466 GetPrefEmTabDist(mode
) : oldEmTabDist
;
4467 indentStyle
= indentStyleIsDef
|| forceDefaults
?
4468 GetPrefAutoIndent(mode
) : window
->indentStyle
;
4469 highlight
= highlightIsDef
|| forceDefaults
?
4470 GetPrefHighlightSyntax() : window
->highlightSyntax
;
4472 /* Dim/undim smart-indent and highlighting menu items depending on
4473 whether patterns/macros are available */
4474 haveHighlightPatterns
= FindPatternSet(LanguageModeName(mode
)) != NULL
;
4475 haveSmartIndentMacros
= SmartIndentMacrosAvailable(LanguageModeName(mode
));
4476 if (IsTopDocument(window
)) {
4477 XtSetSensitive(window
->highlightItem
, haveHighlightPatterns
);
4478 XtSetSensitive(window
->smartIndentItem
, haveSmartIndentMacros
);
4481 /* Turn off requested options which are not available */
4482 highlight
= haveHighlightPatterns
&& highlight
;
4483 if (indentStyle
== SMART_INDENT
&& !haveSmartIndentMacros
)
4484 indentStyle
= AUTO_INDENT
;
4486 /* Change highlighting */
4487 window
->highlightSyntax
= highlight
;
4488 SetToggleButtonState(window
, window
->highlightItem
, highlight
, False
);
4489 StopHighlighting(window
);
4491 /* we defer highlighting to RaiseDocument() if doc is hidden */
4492 if (IsTopDocument(window
) && highlight
)
4493 StartHighlighting(window
, False
);
4495 /* Force a change of smart indent macros (SetAutoIndent will re-start) */
4496 if (window
->indentStyle
== SMART_INDENT
) {
4497 EndSmartIndent(window
);
4498 window
->indentStyle
= AUTO_INDENT
;
4501 /* set requested wrap, indent, and tabs */
4502 SetAutoWrap(window
, wrapMode
);
4503 SetAutoIndent(window
, indentStyle
);
4504 SetTabDist(window
, tabDist
);
4505 SetEmTabDist(window
, emTabDist
);
4507 /* Load calltips files for new mode */
4508 if (mode
!= PLAIN_LANGUAGE_MODE
&& LanguageModes
[mode
]->defTipsFile
) {
4509 AddTagsFile( LanguageModes
[mode
]->defTipsFile
, TIP
);
4512 /* Add/remove language specific menu items */
4513 UpdateUserMenus(window
);
4517 ** Find and return the name of the appropriate languange mode for
4518 ** the file in "window". Returns a pointer to a string, which will
4519 ** remain valid until a change is made to the language modes list.
4521 static int matchLanguageMode(WindowInfo
*window
)
4523 char *ext
, *first200
;
4524 int i
, j
, fileNameLen
, extLen
, beginPos
, endPos
, start
;
4525 const char *versionExtendedPath
;
4527 /*... look for an explicit mode statement first */
4529 /* Do a regular expression search on for recognition pattern */
4530 first200
= BufGetRange(window
->buffer
, 0, 200);
4531 for (i
=0; i
<NLanguageModes
; i
++) {
4532 if (LanguageModes
[i
]->recognitionExpr
!= NULL
) {
4533 if (SearchString(first200
, LanguageModes
[i
]->recognitionExpr
,
4534 SEARCH_FORWARD
, SEARCH_REGEX
, False
, 0, &beginPos
,
4535 &endPos
, NULL
, NULL
, NULL
))
4544 /* Look at file extension ("@@/" starts a ClearCase version extended path,
4545 which gets appended after the file extension, and therefore must be
4546 stripped off to recognize the extension to make ClearCase users happy) */
4547 fileNameLen
= strlen(window
->filename
);
4549 if (strchr(window
->filename
, ';') != NULL
)
4550 fileNameLen
= strchr(window
->filename
, ';') - window
->filename
;
4552 if ((versionExtendedPath
= GetClearCaseVersionExtendedPath(window
->filename
)) != NULL
)
4553 fileNameLen
= versionExtendedPath
- window
->filename
;
4555 for (i
=0; i
<NLanguageModes
; i
++) {
4556 for (j
=0; j
<LanguageModes
[i
]->nExtensions
; j
++) {
4557 ext
= LanguageModes
[i
]->extensions
[j
];
4558 extLen
= strlen(ext
);
4559 start
= fileNameLen
- extLen
;
4560 #if defined(__VMS) && (__VMS_VER >= 70200000)
4561 /* VMS v7.2 has case-preserving filenames */
4562 if (start
>= 0 && !strncasecmp(&window
->filename
[start
], ext
, extLen
))
4565 if (start
>= 0 && !strncmp(&window
->filename
[start
], ext
, extLen
))
4571 /* no appropriate mode was found */
4572 return PLAIN_LANGUAGE_MODE
;
4575 static int loadLanguageModesString(char *inString
, int fileVer
)
4577 char *errMsg
, *styleName
, *inPtr
= inString
;
4578 languageModeRec
*lm
;
4583 /* skip over blank space */
4584 inPtr
+= strspn(inPtr
, " \t\n");
4586 /* Allocate a language mode structure to return, set unread fields to
4587 empty so everything can be freed on errors by freeLanguageModeRec */
4588 lm
= (languageModeRec
*)XtMalloc(sizeof(languageModeRec
));
4589 lm
->nExtensions
= 0;
4590 lm
->recognitionExpr
= NULL
;
4591 lm
->defTipsFile
= NULL
;
4592 lm
->delimiters
= NULL
;
4594 /* read language mode name */
4595 lm
->name
= ReadSymbolicField(&inPtr
);
4596 if (lm
->name
== NULL
) {
4598 return modeError(NULL
,inString
,inPtr
,"language mode name required");
4600 if (!SkipDelimiter(&inPtr
, &errMsg
))
4601 return modeError(lm
, inString
, inPtr
, errMsg
);
4603 /* read list of extensions */
4604 lm
->extensions
= readExtensionList(&inPtr
,
4606 if (!SkipDelimiter(&inPtr
, &errMsg
))
4607 return modeError(lm
, inString
, inPtr
, errMsg
);
4609 /* read the recognition regular expression */
4610 if (*inPtr
== '\n' || *inPtr
== '\0' || *inPtr
== ':')
4611 lm
->recognitionExpr
= NULL
;
4612 else if (!ReadQuotedString(&inPtr
, &errMsg
, &lm
->recognitionExpr
))
4613 return modeError(lm
, inString
,inPtr
, errMsg
);
4614 if (!SkipDelimiter(&inPtr
, &errMsg
))
4615 return modeError(lm
, inString
, inPtr
, errMsg
);
4617 /* read the indent style */
4618 styleName
= ReadSymbolicField(&inPtr
);
4619 if (styleName
== NULL
)
4620 lm
->indentStyle
= DEFAULT_INDENT
;
4622 for (i
=0; i
<N_INDENT_STYLES
; i
++) {
4623 if (!strcmp(styleName
, AutoIndentTypes
[i
])) {
4624 lm
->indentStyle
= i
;
4629 if (i
== N_INDENT_STYLES
)
4630 return modeError(lm
,inString
,inPtr
,"unrecognized indent style");
4632 if (!SkipDelimiter(&inPtr
, &errMsg
))
4633 return modeError(lm
, inString
, inPtr
, errMsg
);
4635 /* read the wrap style */
4636 styleName
= ReadSymbolicField(&inPtr
);
4637 if (styleName
== NULL
)
4638 lm
->wrapStyle
= DEFAULT_WRAP
;
4640 for (i
=0; i
<N_WRAP_STYLES
; i
++) {
4641 if (!strcmp(styleName
, AutoWrapTypes
[i
])) {
4647 if (i
== N_WRAP_STYLES
)
4648 return modeError(lm
, inString
, inPtr
,"unrecognized wrap style");
4650 if (!SkipDelimiter(&inPtr
, &errMsg
))
4651 return modeError(lm
, inString
, inPtr
, errMsg
);
4653 /* read the tab distance */
4654 if (*inPtr
== '\n' || *inPtr
== '\0' || *inPtr
== ':')
4655 lm
->tabDist
= DEFAULT_TAB_DIST
;
4656 else if (!ReadNumericField(&inPtr
, &lm
->tabDist
))
4657 return modeError(lm
, inString
, inPtr
, "bad tab spacing");
4658 if (!SkipDelimiter(&inPtr
, &errMsg
))
4659 return modeError(lm
, inString
, inPtr
, errMsg
);
4661 /* read emulated tab distance */
4662 if (*inPtr
== '\n' || *inPtr
== '\0' || *inPtr
== ':')
4663 lm
->emTabDist
= DEFAULT_EM_TAB_DIST
;
4664 else if (!ReadNumericField(&inPtr
, &lm
->emTabDist
))
4665 return modeError(lm
, inString
, inPtr
, "bad emulated tab spacing");
4666 if (!SkipDelimiter(&inPtr
, &errMsg
))
4667 return modeError(lm
, inString
, inPtr
, errMsg
);
4669 /* read the delimiters string */
4670 if (*inPtr
== '\n' || *inPtr
== '\0' || *inPtr
== ':')
4671 lm
->delimiters
= NULL
;
4672 else if (!ReadQuotedString(&inPtr
, &errMsg
, &lm
->delimiters
))
4673 return modeError(lm
, inString
, inPtr
, errMsg
);
4675 /* After 5.3 all language modes need a default tips file field */
4676 if (!SkipDelimiter(&inPtr
, &errMsg
))
4678 return modeError(lm
, inString
, inPtr
, errMsg
);
4680 /* read the default tips file */
4681 if (*inPtr
== '\n' || *inPtr
== '\0')
4682 lm
->defTipsFile
= NULL
;
4683 else if (!ReadQuotedString(&inPtr
, &errMsg
, &lm
->defTipsFile
))
4684 return modeError(lm
, inString
, inPtr
, errMsg
);
4686 /* pattern set was read correctly, add/replace it in the list */
4687 for (i
=0; i
<NLanguageModes
; i
++) {
4688 if (!strcmp(LanguageModes
[i
]->name
, lm
->name
)) {
4689 freeLanguageModeRec(LanguageModes
[i
]);
4690 LanguageModes
[i
] = lm
;
4694 if (i
== NLanguageModes
) {
4695 LanguageModes
[NLanguageModes
++] = lm
;
4696 if (NLanguageModes
> MAX_LANGUAGE_MODES
)
4697 return modeError(NULL
, inString
, inPtr
,
4698 "maximum allowable number of language modes exceeded");
4701 /* if the string ends here, we're done */
4702 inPtr
+= strspn(inPtr
, " \t\n");
4708 static char *writeLanguageModesString(void)
4711 char *outStr
, *escapedStr
, *str
, numBuf
[25];
4714 outBuf
= BufCreate();
4715 for (i
=0; i
<NLanguageModes
; i
++) {
4716 BufInsert(outBuf
, outBuf
->length
, "\t");
4717 BufInsert(outBuf
, outBuf
->length
, LanguageModes
[i
]->name
);
4718 BufInsert(outBuf
, outBuf
->length
, ":");
4719 BufInsert(outBuf
, outBuf
->length
, str
= createExtString(
4720 LanguageModes
[i
]->extensions
, LanguageModes
[i
]->nExtensions
));
4722 BufInsert(outBuf
, outBuf
->length
, ":");
4723 if (LanguageModes
[i
]->recognitionExpr
!= NULL
) {
4724 BufInsert(outBuf
, outBuf
->length
,
4725 str
=MakeQuotedString(LanguageModes
[i
]->recognitionExpr
));
4728 BufInsert(outBuf
, outBuf
->length
, ":");
4729 if (LanguageModes
[i
]->indentStyle
!= DEFAULT_INDENT
)
4730 BufInsert(outBuf
, outBuf
->length
,
4731 AutoIndentTypes
[LanguageModes
[i
]->indentStyle
]);
4732 BufInsert(outBuf
, outBuf
->length
, ":");
4733 if (LanguageModes
[i
]->wrapStyle
!= DEFAULT_WRAP
)
4734 BufInsert(outBuf
, outBuf
->length
,
4735 AutoWrapTypes
[LanguageModes
[i
]->wrapStyle
]);
4736 BufInsert(outBuf
, outBuf
->length
, ":");
4737 if (LanguageModes
[i
]->tabDist
!= DEFAULT_TAB_DIST
) {
4738 sprintf(numBuf
, "%d", LanguageModes
[i
]->tabDist
);
4739 BufInsert(outBuf
, outBuf
->length
, numBuf
);
4741 BufInsert(outBuf
, outBuf
->length
, ":");
4742 if (LanguageModes
[i
]->emTabDist
!= DEFAULT_EM_TAB_DIST
) {
4743 sprintf(numBuf
, "%d", LanguageModes
[i
]->emTabDist
);
4744 BufInsert(outBuf
, outBuf
->length
, numBuf
);
4746 BufInsert(outBuf
, outBuf
->length
, ":");
4747 if (LanguageModes
[i
]->delimiters
!= NULL
) {
4748 BufInsert(outBuf
, outBuf
->length
,
4749 str
=MakeQuotedString(LanguageModes
[i
]->delimiters
));
4752 BufInsert(outBuf
, outBuf
->length
, ":");
4753 if (LanguageModes
[i
]->defTipsFile
!= NULL
) {
4754 BufInsert(outBuf
, outBuf
->length
,
4755 str
=MakeQuotedString(LanguageModes
[i
]->defTipsFile
));
4759 BufInsert(outBuf
, outBuf
->length
, "\n");
4762 /* Get the output, and lop off the trailing newline */
4763 outStr
= BufGetRange(outBuf
, 0, outBuf
->length
- 1);
4765 escapedStr
= EscapeSensitiveChars(outStr
);
4770 static char *createExtString(char **extensions
, int nExtensions
)
4773 char *outStr
, *outPtr
;
4775 for (e
=0; e
<nExtensions
; e
++)
4776 length
+= strlen(extensions
[e
]) + 1;
4777 outStr
= outPtr
= XtMalloc(length
);
4778 for (e
=0; e
<nExtensions
; e
++) {
4779 strcpy(outPtr
, extensions
[e
]);
4780 outPtr
+= strlen(extensions
[e
]);
4783 if (nExtensions
== 0)
4790 static char **readExtensionList(char **inPtr
, int *nExtensions
)
4792 char *extensionList
[MAX_FILE_EXTENSIONS
];
4793 char **retList
, *strStart
;
4796 /* skip over blank space */
4797 *inPtr
+= strspn(*inPtr
, " \t");
4799 for (i
=0; i
<MAX_FILE_EXTENSIONS
&& **inPtr
!=':' && **inPtr
!='\0'; i
++) {
4800 *inPtr
+= strspn(*inPtr
, " \t");
4802 while (**inPtr
!=' ' && **inPtr
!='\t' && **inPtr
!=':' && **inPtr
!='\0')
4804 len
= *inPtr
- strStart
;
4805 extensionList
[i
] = XtMalloc(len
+ 1);
4806 strncpy(extensionList
[i
], strStart
, len
);
4807 extensionList
[i
][len
] = '\0';
4812 retList
= (char **)XtMalloc(sizeof(char *) * i
);
4813 memcpy(retList
, extensionList
, sizeof(char *) * i
);
4817 int ReadNumericField(char **inPtr
, int *value
)
4821 /* skip over blank space */
4822 *inPtr
+= strspn(*inPtr
, " \t");
4824 if (sscanf(*inPtr
, "%d%n", value
, &charsRead
) != 1)
4826 *inPtr
+= charsRead
;
4831 ** Parse a symbolic field, skipping initial and trailing whitespace,
4832 ** stops on first invalid character or end of string. Valid characters
4833 ** are letters, numbers, _, -, +, $, #, and internal whitespace. Internal
4834 ** whitespace is compressed to single space characters.
4836 char *ReadSymbolicField(char **inPtr
)
4838 char *outStr
, *outPtr
, *strStart
, *strPtr
;
4841 /* skip over initial blank space */
4842 *inPtr
+= strspn(*inPtr
, " \t");
4844 /* Find the first invalid character or end of string to know how
4845 much memory to allocate for the returned string */
4847 while (isalnum((unsigned char)**inPtr
) || **inPtr
=='_' || **inPtr
=='-' ||
4848 **inPtr
=='+' || **inPtr
=='$' || **inPtr
=='#' || **inPtr
==' ' ||
4851 len
= *inPtr
- strStart
;
4854 outStr
= outPtr
= XtMalloc(len
+ 1);
4856 /* Copy the string, compressing internal whitespace to a single space */
4858 while (strPtr
- strStart
< len
) {
4859 if (*strPtr
== ' ' || *strPtr
== '\t') {
4860 strPtr
+= strspn(strPtr
, " \t");
4863 *outPtr
++ = *strPtr
++;
4866 /* If there's space on the end, take it back off */
4867 if (outPtr
> outStr
&& *(outPtr
-1) == ' ')
4869 if (outPtr
== outStr
) {
4878 ** parse an individual quoted string. Anything between
4879 ** double quotes is acceptable, quote characters can be escaped by "".
4880 ** Returns allocated string "string" containing
4881 ** argument minus quotes. If not successful, returns False with
4882 ** (statically allocated) message in "errMsg".
4884 int ReadQuotedString(char **inPtr
, char **errMsg
, char **string
)
4888 /* skip over blank space */
4889 *inPtr
+= strspn(*inPtr
, " \t");
4891 /* look for initial quote */
4892 if (**inPtr
!= '\"') {
4893 *errMsg
= "expecting quoted string";
4898 /* calculate max length and allocate returned string */
4899 for (c
= *inPtr
; ; c
++) {
4901 *errMsg
= "string not terminated";
4903 } else if (*c
== '\"') {
4911 /* copy string up to end quote, transforming escaped quotes into quotes */
4912 *string
= XtMalloc(c
- *inPtr
+ 1);
4915 if (**inPtr
== '\"') {
4916 if (*(*inPtr
+1) == '\"')
4921 *outPtr
++ = *(*inPtr
)++;
4925 /* skip end quote */
4931 ** Replace characters which the X resource file reader considers control
4932 ** characters, such that a string will read back as it appears in "string".
4933 ** (So far, newline characters are replaced with with \n\<newline> and
4934 ** backslashes with \\. This has not been tested exhaustively, and
4935 ** probably should be. It would certainly be more asthetic if other
4936 ** control characters were replaced as well).
4938 ** Returns an allocated string which must be freed by the caller with XtFree.
4940 char *EscapeSensitiveChars(const char *string
)
4943 char *outStr
, *outPtr
;
4946 /* calculate length and allocate returned string */
4947 for (c
=string
; *c
!='\0'; c
++) {
4950 else if (*c
== '\n')
4954 outStr
= XtMalloc(length
+ 1);
4957 /* add backslashes */
4958 for (c
=string
; *c
!='\0'; c
++) {
4961 else if (*c
== '\n') {
4973 ** Adds double quotes around a string and escape existing double quote
4974 ** characters with two double quotes. Enables the string to be read back
4975 ** by ReadQuotedString.
4977 char *MakeQuotedString(const char *string
)
4980 char *outStr
, *outPtr
;
4983 /* calculate length and allocate returned string */
4984 for (c
=string
; *c
!='\0'; c
++) {
4989 outStr
= XtMalloc(length
+ 3);
4992 /* add starting quote */
4995 /* copy string, escaping quotes with "" */
4996 for (c
=string
; *c
!='\0'; c
++) {
5002 /* add ending quote */
5005 /* terminate string and return */
5011 ** Read a dialog text field containing a symbolic name (language mode names,
5012 ** style names, highlight pattern names, colors, and fonts), clean the
5013 ** entered text of leading and trailing whitespace, compress all
5014 ** internal whitespace to one space character, and check it over for
5015 ** colons, which interfere with the preferences file reader/writer syntax.
5016 ** Returns NULL on error, and puts up a dialog if silent is False. Returns
5017 ** an empty string if the text field is blank.
5019 char *ReadSymbolicFieldTextWidget(Widget textW
, const char *fieldName
, int silent
)
5021 char *string
, *stringPtr
, *parsedString
;
5023 /* read from the text widget */
5024 string
= stringPtr
= XmTextGetString(textW
);
5026 /* parse it with the same routine used to read symbolic fields from
5027 files. If the string is not read entirely, there are invalid
5028 characters, so warn the user if not in silent mode. */
5029 parsedString
= ReadSymbolicField(&stringPtr
);
5030 if (*stringPtr
!= '\0')
5034 *(stringPtr
+ 1) = '\0';
5035 DialogF(DF_WARN
, textW
, 1, "Invalid Character",
5036 "Invalid character \"%s\" in %s", "OK", stringPtr
,
5038 XmProcessTraversal(textW
, XmTRAVERSE_CURRENT
);
5041 XtFree(parsedString
);
5045 if (parsedString
== NULL
) {
5046 parsedString
= XtMalloc(1);
5047 *parsedString
= '\0';
5049 return parsedString
;
5053 ** Create a pulldown menu pane with the names of the current language modes.
5054 ** XmNuserData for each item contains the language mode name.
5056 Widget
CreateLanguageModeMenu(Widget parent
, XtCallbackProc cbProc
, void *cbArg
)
5062 menu
= CreatePulldownMenu(parent
, "languageModes", NULL
, 0);
5063 for (i
=0; i
<NLanguageModes
; i
++) {
5064 btn
= XtVaCreateManagedWidget("languageMode", xmPushButtonGadgetClass
,
5066 XmNlabelString
, s1
=XmStringCreateSimple(LanguageModes
[i
]->name
),
5068 XmNuserData
, (void *)LanguageModes
[i
]->name
, NULL
);
5070 XtAddCallback(btn
, XmNactivateCallback
, cbProc
, cbArg
);
5076 ** Set the language mode menu in option menu "optMenu" to
5077 ** show a particular language mode
5079 void SetLangModeMenu(Widget optMenu
, const char *modeName
)
5084 Widget pulldown
, selectedItem
;
5087 XtVaGetValues(optMenu
, XmNsubMenuId
, &pulldown
, NULL
);
5088 XtVaGetValues(pulldown
, XmNchildren
, &items
, XmNnumChildren
, &nItems
, NULL
);
5091 selectedItem
= items
[0];
5092 for (i
=0; i
<(int)nItems
; i
++) {
5093 XtVaGetValues(items
[i
], XmNuserData
, &itemName
, NULL
);
5094 if (!strcmp(itemName
, modeName
)) {
5095 selectedItem
= items
[i
];
5099 XtVaSetValues(optMenu
, XmNmenuHistory
, selectedItem
,NULL
);
5103 ** Create a submenu for chosing language mode for the current window.
5105 void CreateLanguageModeSubMenu(WindowInfo
* window
, const Widget parent
,
5106 const char* name
, const char* label
, const char mnemonic
)
5108 XmString string
= XmStringCreateSimple((char*) label
);
5110 window
->langModeCascade
= XtVaCreateManagedWidget(name
,
5111 xmCascadeButtonGadgetClass
, parent
,
5112 XmNlabelString
, string
,
5113 XmNmnemonic
, mnemonic
,
5116 XmStringFree(string
);
5118 updateLanguageModeSubmenu(window
);
5122 ** Re-build the language mode sub-menu using the current data stored
5123 ** in the master list: LanguageModes.
5125 static void updateLanguageModeSubmenu(WindowInfo
*window
)
5130 Arg args
[1] = {{XmNradioBehavior
, (XtArgVal
)True
}};
5132 /* Destroy and re-create the menu pane */
5133 XtVaGetValues(window
->langModeCascade
, XmNsubMenuId
, &menu
, NULL
);
5135 XtDestroyWidget(menu
);
5136 menu
= CreatePulldownMenu(XtParent(window
->langModeCascade
),
5137 "languageModes", args
, 1);
5138 btn
= XtVaCreateManagedWidget("languageMode",
5139 xmToggleButtonGadgetClass
, menu
,
5140 XmNlabelString
, s1
=XmStringCreateSimple("Plain"),
5141 XmNuserData
, (void *)PLAIN_LANGUAGE_MODE
,
5142 XmNset
, window
->languageMode
==PLAIN_LANGUAGE_MODE
, NULL
);
5144 XtAddCallback(btn
, XmNvalueChangedCallback
, setLangModeCB
, window
);
5145 for (i
=0; i
<NLanguageModes
; i
++) {
5146 btn
= XtVaCreateManagedWidget("languageMode",
5147 xmToggleButtonGadgetClass
, menu
,
5148 XmNlabelString
, s1
=XmStringCreateSimple(LanguageModes
[i
]->name
),
5150 XmNuserData
, (void *)i
,
5151 XmNset
, window
->languageMode
==i
, NULL
);
5153 XtAddCallback(btn
, XmNvalueChangedCallback
, setLangModeCB
, window
);
5155 XtVaSetValues(window
->langModeCascade
, XmNsubMenuId
, menu
, NULL
);
5158 static void setLangModeCB(Widget w
, XtPointer clientData
, XtPointer callData
)
5160 WindowInfo
*window
= WidgetToWindow(MENU_WIDGET(w
));
5164 if (!XmToggleButtonGetState(w
))
5167 /* get name of language mode stored in userData field of menu item */
5168 XtVaGetValues(w
, XmNuserData
, &mode
, NULL
);
5170 /* If the mode didn't change, do nothing */
5171 if (window
->languageMode
== (int)mode
)
5174 /* redo syntax highlighting word delimiters, etc. */
5176 reapplyLanguageMode(window, (int)mode, False);
5178 params
[0] = (((int)mode
) == PLAIN_LANGUAGE_MODE
) ? "" : LanguageModes
[(int)mode
]->name
;
5179 XtCallActionProc(window
->textArea
, "set_language_mode", NULL
, params
, 1);
5183 ** Skip a delimiter and it's surrounding whitespace
5185 int SkipDelimiter(char **inPtr
, char **errMsg
)
5187 *inPtr
+= strspn(*inPtr
, " \t");
5188 if (**inPtr
!= ':') {
5189 *errMsg
= "syntax error";
5193 *inPtr
+= strspn(*inPtr
, " \t");
5198 ** Skip an optional separator and its surrounding whitespace
5199 ** return true if delimiter found
5201 int SkipOptSeparator(char separator
, char **inPtr
)
5203 *inPtr
+= strspn(*inPtr
, " \t");
5204 if (**inPtr
!= separator
) {
5208 *inPtr
+= strspn(*inPtr
, " \t");
5213 ** Short-hand error processing for language mode parsing errors, frees
5214 ** lm (if non-null), prints a formatted message explaining where the
5215 ** error is, and returns False;
5217 static int modeError(languageModeRec
*lm
, const char *stringStart
,
5218 const char *stoppedAt
, const char *message
)
5221 freeLanguageModeRec(lm
);
5222 return ParseError(NULL
, stringStart
, stoppedAt
,
5223 "language mode specification", message
);
5227 ** Report parsing errors in resource strings or macros, formatted nicely so
5228 ** the user can tell where things became botched. Errors can be sent either
5229 ** to stderr, or displayed in a dialog. For stderr, pass toDialog as NULL.
5230 ** For a dialog, pass the dialog parent in toDialog.
5232 int ParseError(Widget toDialog
, const char *stringStart
, const char *stoppedAt
,
5233 const char *errorIn
, const char *message
)
5235 int len
, nNonWhite
= 0;
5239 for (c
=stoppedAt
; c
>=stringStart
; c
--) {
5240 if (c
== stringStart
)
5242 else if (*c
== '\n' && nNonWhite
>= 5)
5244 else if (*c
!= ' ' && *c
!= '\t')
5247 len
= stoppedAt
- c
+ (*stoppedAt
== '\0' ? 0 : 1);
5248 errorLine
= XtMalloc(len
+4);
5249 strncpy(errorLine
, c
, len
);
5250 errorLine
[len
++] = '<';
5251 errorLine
[len
++] = '=';
5252 errorLine
[len
++] = '=';
5253 errorLine
[len
] = '\0';
5254 if (toDialog
== NULL
)
5256 fprintf(stderr
, "NEdit: %s in %s:\n%s\n", message
, errorIn
, errorLine
);
5259 DialogF(DF_WARN
, toDialog
, 1, "Parse Error", "%s in %s:\n%s", "OK",
5260 message
, errorIn
, errorLine
);
5267 ** Compare two strings which may be NULL
5269 int AllocatedStringsDiffer(const char *s1
, const char *s2
)
5271 if (s1
== NULL
&& s2
== NULL
)
5273 if (s1
== NULL
|| s2
== NULL
)
5275 return strcmp(s1
, s2
);
5278 static void updatePatternsTo5dot1(void)
5280 const char *htmlDefaultExpr
= "^[ \t]*HTML[ \t]*:[ \t]*Default[ \t]*$";
5281 const char *vhdlAnchorExpr
= "^[ \t]*VHDL:";
5283 /* Add new patterns if there aren't already existing patterns with
5284 the same name. If possible, insert before VHDL in language mode
5285 list. If not, just add to end */
5286 if (!regexFind(TempStringPrefs
.highlight
, "^[ \t]*PostScript:"))
5287 spliceString(&TempStringPrefs
.highlight
, "PostScript:Default",
5289 if (!regexFind(TempStringPrefs
.language
, "^[ \t]*PostScript:"))
5290 spliceString(&TempStringPrefs
.language
,
5291 "PostScript:.ps .PS .eps .EPS .epsf .epsi::::::",
5293 if (!regexFind(TempStringPrefs
.highlight
, "^[ \t]*Lex:"))
5294 spliceString(&TempStringPrefs
.highlight
, "Lex:Default",
5296 if (!regexFind(TempStringPrefs
.language
, "^[ \t]*Lex:"))
5297 spliceString(&TempStringPrefs
.language
, "Lex:.lex::::::",
5299 if (!regexFind(TempStringPrefs
.highlight
, "^[ \t]*SQL:"))
5300 spliceString(&TempStringPrefs
.highlight
, "SQL:Default",
5302 if (!regexFind(TempStringPrefs
.language
, "^[ \t]*SQL:"))
5303 spliceString(&TempStringPrefs
.language
, "SQL:.sql::::::",
5305 if (!regexFind(TempStringPrefs
.highlight
, "^[ \t]*Matlab:"))
5306 spliceString(&TempStringPrefs
.highlight
, "Matlab:Default",
5308 if (!regexFind(TempStringPrefs
.language
, "^[ \t]*Matlab:"))
5309 spliceString(&TempStringPrefs
.language
, "Matlab:..m .oct .sci::::::",
5311 if (!regexFind(TempStringPrefs
.smartIndent
, "^[ \t]*Matlab:"))
5312 spliceString(&TempStringPrefs
.smartIndent
, "Matlab:Default", NULL
);
5313 if (!regexFind(TempStringPrefs
.styles
, "^[ \t]*Label:"))
5314 spliceString(&TempStringPrefs
.styles
, "Label:red:Italic",
5316 if (!regexFind(TempStringPrefs
.styles
, "^[ \t]*Storage Type1:"))
5317 spliceString(&TempStringPrefs
.styles
, "Storage Type1:saddle brown:Bold",
5320 /* Replace html pattern with sgml html pattern, as long as there
5321 isn't an existing html pattern which will be overwritten */
5322 if (regexFind(TempStringPrefs
.highlight
, htmlDefaultExpr
)) {
5323 regexReplace(&TempStringPrefs
.highlight
, htmlDefaultExpr
,
5324 "SGML HTML:Default");
5325 if (!regexReplace(&TempStringPrefs
.language
, "^[ \t]*HTML:.*$",
5326 "SGML HTML:.sgml .sgm .html .htm:\"\\<(?ihtml)\\>\":::::\n")) {
5327 spliceString(&TempStringPrefs
.language
,
5328 "SGML HTML:.sgml .sgm .html .htm:\"\\<(?ihtml)\\>\":::::\n",
5334 static void updatePatternsTo5dot2(void)
5337 const char *cppLm5dot1
=
5338 "^[ \t]*C\\+\\+:\\.CC \\.HH \\.I::::::\"\\.,/\\\\`'!\\|@#%\\^&\\*\\(\\)-=\\+\\{\\}\\[\\]\"\":;\\<\\>\\?~\"";
5339 const char *perlLm5dot1
=
5340 "^[ \t]*Perl:\\.PL \\.PM \\.P5:\"\\^\\[ \\\\t\\]\\*#\\[ \\\\t\\]\\*!\\.\\*perl\":::::";
5341 const char *psLm5dot1
=
5342 "^[ \t]*PostScript:\\.ps \\.PS \\.eps \\.EPS \\.epsf \\.epsi:\"\\^%!\":::::\"/%\\(\\)\\{\\}\\[\\]\\<\\>\"";
5343 const char *tclLm5dot1
= "^[ \t]*Tcl:\\.TCL::::::";
5345 const char *cppLm5dot2
=
5346 "C++:.CC .HH .C .H .I .CXX .HXX .CPP::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\"";
5347 const char *perlLm5dot2
=
5348 "Perl:.PL .PM .P5:\"^[ \\t]*#[ \\t]*!.*perl\":Auto:None:::\".,/\\\\`'!$@#%^&*()-=+{}[]\"\":;<>?~|\"";
5349 const char *psLm5dot2
=
5350 "PostScript:.ps .PS .eps .EPS .epsf .epsi:\"^%!\":::::\"/%(){}[]<>\"";
5351 const char *tclLm5dot2
=
5352 "Tcl:.TCL::Smart:None:::";
5354 const char *cppLm5dot1
=
5355 "^[ \t]*C\\+\\+:\\.cc \\.hh \\.C \\.H \\.i \\.cxx \\.hxx::::::\"\\.,/\\\\`'!\\|@#%\\^&\\*\\(\\)-=\\+\\{\\}\\[\\]\"\":;\\<\\>\\?~\"";
5356 const char *perlLm5dot1
=
5357 "^[ \t]*Perl:\\.pl \\.pm \\.p5:\"\\^\\[ \\\\t\\]\\*#\\[ \\\\t\\]\\*!\\.\\*perl\":::::";
5358 const char *psLm5dot1
=
5359 "^[ \t]*PostScript:\\.ps \\.PS \\.eps \\.EPS \\.epsf \\.epsi:\"\\^%!\":::::\"/%\\(\\)\\{\\}\\[\\]\\<\\>\"";
5360 const char *shLm5dot1
=
5361 "^[ \t]*Sh Ksh Bash:\\.sh \\.bash \\.ksh \\.profile:\"\\^\\[ \\\\t\\]\\*#\\[ \\\\t\\]\\*!\\[ \\\\t\\]\\*/bin/\\(sh\\|ksh\\|bash\\)\":::::";
5362 const char *tclLm5dot1
= "^[ \t]*Tcl:\\.tcl::::::";
5364 const char *cppLm5dot2
=
5365 "C++:.cc .hh .C .H .i .cxx .hxx .cpp::::::\".,/\\`'!|@#%^&*()-=+{}[]\"\":;<>?~\"";
5366 const char *perlLm5dot2
=
5367 "Perl:.pl .pm .p5 .PL:\"^[ \\t]*#[ \\t]*!.*perl\":Auto:None:::\".,/\\\\`'!$@#%^&*()-=+{}[]\"\":;<>?~|\"";
5368 const char *psLm5dot2
=
5369 "PostScript:.ps .eps .epsf .epsi:\"^%!\":::::\"/%(){}[]<>\"";
5370 const char *shLm5dot2
=
5371 "Sh Ksh Bash:.sh .bash .ksh .profile .bashrc .bash_logout .bash_login .bash_profile:\"^[ \\t]*#[ \\t]*![ \\t]*/.*bin/(sh|ksh|bash)\":::::";
5372 const char *tclLm5dot2
=
5373 "Tcl:.tcl .tk .itcl .itk::Smart:None:::";
5376 const char *cssLm5dot2
=
5377 "CSS:css::Auto:None:::\".,/\\`'!|@#%^&*()=+{}[]\"\":;<>?~\"";
5378 const char *reLm5dot2
=
5379 "Regex:.reg .regex:\"\\(\\?[:#=!iInN].+\\)\":None:Continuous:::";
5380 const char *xmlLm5dot2
=
5381 "XML:.xml .xsl .dtd:\"\\<(?i\\?xml|!doctype)\"::None:::\"<>/=\"\"'()+*?|\"";
5383 const char *cssHl5dot2
= "CSS:Default";
5384 const char *reHl5dot2
= "Regex:Default";
5385 const char *xmlHl5dot2
= "XML:Default";
5387 const char *ptrStyle
= "Pointer:#660000:Bold";
5388 const char *reStyle
= "Regex:#009944:Bold";
5389 const char *wrnStyle
= "Warning:brown2:Italic";
5391 /* First upgrade modified language modes, only if the user hasn't
5392 altered the default 5.1 definitions. */
5393 if (regexFind(TempStringPrefs
.language
, cppLm5dot1
))
5394 regexReplace(&TempStringPrefs
.language
, cppLm5dot1
, cppLm5dot2
);
5395 if (regexFind(TempStringPrefs
.language
, perlLm5dot1
))
5396 regexReplace(&TempStringPrefs
.language
, perlLm5dot1
, perlLm5dot2
);
5397 if (regexFind(TempStringPrefs
.language
, psLm5dot1
))
5398 regexReplace(&TempStringPrefs
.language
, psLm5dot1
, psLm5dot2
);
5400 if (regexFind(TempStringPrefs
.language
, shLm5dot1
))
5401 regexReplace(&TempStringPrefs
.language
, shLm5dot1
, shLm5dot2
);
5403 if (regexFind(TempStringPrefs
.language
, tclLm5dot1
))
5404 regexReplace(&TempStringPrefs
.language
, tclLm5dot1
, tclLm5dot2
);
5406 /* Then append the new modes (trying to keep them in alphabetical order
5407 makes no sense, since 5.1 didn't use alphabetical order). */
5408 if (!regexFind(TempStringPrefs
.language
, "^[ \t]*CSS:"))
5409 spliceString(&TempStringPrefs
.language
, cssLm5dot2
, NULL
);
5410 if (!regexFind(TempStringPrefs
.language
, "^[ \t]*Regex:"))
5411 spliceString(&TempStringPrefs
.language
, reLm5dot2
, NULL
);
5412 if (!regexFind(TempStringPrefs
.language
, "^[ \t]*XML:"))
5413 spliceString(&TempStringPrefs
.language
, xmlLm5dot2
, NULL
);
5415 /* Enable default highlighting patterns for these modes, unless already
5417 if (!regexFind(TempStringPrefs
.highlight
, "^[ \t]*CSS:"))
5418 spliceString(&TempStringPrefs
.highlight
, cssHl5dot2
, NULL
);
5419 if (!regexFind(TempStringPrefs
.highlight
, "^[ \t]*Regex:"))
5420 spliceString(&TempStringPrefs
.highlight
, reHl5dot2
, NULL
);
5421 if (!regexFind(TempStringPrefs
.highlight
, "^[ \t]*XML:"))
5422 spliceString(&TempStringPrefs
.highlight
, xmlHl5dot2
, NULL
);
5424 /* Finally, append the new highlight styles */
5426 if (!regexFind(TempStringPrefs
.styles
, "^[ \t]*Warning:"))
5427 spliceString(&TempStringPrefs
.styles
, wrnStyle
, NULL
);
5428 if (!regexFind(TempStringPrefs
.styles
, "^[ \t]*Regex:"))
5429 spliceString(&TempStringPrefs
.styles
, reStyle
, "^[ \t]*Warning:");
5430 if (!regexFind(TempStringPrefs
.styles
, "^[ \t]*Pointer:"))
5431 spliceString(&TempStringPrefs
.styles
, ptrStyle
, "^[ \t]*Regex:");
5434 static void updatePatternsTo5dot3(void)
5436 /* This is a bogus function on non-VMS */
5438 const char *psLm5dot2
=
5439 "^[ \t]*PostScript:\\.ps \\.PS \\.eps \\.EPS \\.epsf \\.epsi:\"\\^%!\":::::\"/%\\(\\)\\{\\}\\[\\]\\<\\>\"";
5441 const char *psLm5dot3
=
5442 "PostScript:.ps .PS .eps .EPS .epsf .EPSF .epsi .EPSI:\"^%!\":::::\"/%(){}[]<>\"";
5444 /* Upgrade modified language modes, only if the user hasn't
5445 altered the default 5.2 definitions. */
5446 if (regexFind(TempStringPrefs
.language
, psLm5dot2
))
5447 regexReplace(&TempStringPrefs
.language
, psLm5dot2
, psLm5dot3
);
5451 static void updatePatternsTo5dot4(void)
5454 const char *pyLm5dot3
=
5455 "Python:\\.PY:\"\\^#!\\.\\*python\":Auto:None::::?\n";
5456 const char *xrLm5dot3
=
5457 "X Resources:\\.XRESOURCES \\.XDEFAULTS \\.NEDIT:\"\\^\\[!#\\]\\.\\*\\(\\[Aa\\]pp\\|\\[Xx\\]\\)\\.\\*\\[Dd\\]efaults\"::::::?\n";
5459 const char *pyLm5dot4
=
5460 "Python:.PY:\"^#!.*python\":Auto:None:::\"!\"\"#$%&'()*+,-./:;<=>?@[\\\\]^`{|}~\":\n";
5461 const char *xrLm5dot4
=
5462 "X Resources:.XRESOURCES .XDEFAULTS .NEDIT NEDIT.RC:\"^[!#].*([Aa]pp|[Xx]).*[Dd]efaults\"::::::\n";
5464 const char *pyLm5dot3
=
5465 "Python:\\.py:\"\\^#!\\.\\*python\":Auto:None::::?\n";
5466 const char *xrLm5dot3
=
5467 "X Resources:\\.Xresources \\.Xdefaults \\.nedit:\"\\^\\[!#\\]\\.\\*\\(\\[Aa\\]pp\\|\\[Xx\\]\\)\\.\\*\\[Dd\\]efaults\"::::::?\n";
5469 const char *pyLm5dot4
=
5470 "Python:.py:\"^#!.*python\":Auto:None:::\"!\"\"#$%&'()*+,-./:;<=>?@[\\\\]^`{|}~\":\n";
5471 const char *xrLm5dot4
=
5472 "X Resources:.Xresources .Xdefaults .nedit nedit.rc:\"^[!#].*([Aa]pp|[Xx]).*[Dd]efaults\"::::::\n";
5475 /* Upgrade modified language modes, only if the user hasn't
5476 altered the default 5.3 definitions. */
5477 if (regexFind(TempStringPrefs
.language
, pyLm5dot3
))
5478 regexReplace(&TempStringPrefs
.language
, pyLm5dot3
, pyLm5dot4
);
5479 if (regexFind(TempStringPrefs
.language
, xrLm5dot3
))
5480 regexReplace(&TempStringPrefs
.language
, xrLm5dot3
, xrLm5dot4
);
5482 /* Add new styles */
5483 if (!regexFind(TempStringPrefs
.styles
, "^[ \t]*Identifier2:"))
5484 spliceString(&TempStringPrefs
.styles
, "Identifier2:SteelBlue:Plain",
5485 "^[ \t]*Subroutine:");
5488 static void updatePatternsTo5dot6(void)
5490 const char *pats
[] = {
5492 "Csh:\\.csh \\.cshrc \\.login \\.logout:\"\\^\\[ \\\\t\\]\\*#\\[ \\\\t\\]\\*!\\[ \\\\t\\]\\*/bin/csh\"::::::\\n",
5493 "Csh:.csh .cshrc .tcshrc .login .logout:\"^[ \\t]*#[ \\t]*![ \\t]*/bin/t?csh\"::::::\n",
5494 "LaTeX:\\.tex \\.sty \\.cls \\.ltx \\.ins:::::::\\n",
5495 "LaTeX:.tex .sty .cls .ltx .ins .clo .fd:::::::\n",
5496 "X Resources:\\.Xresources \\.Xdefaults \\.nedit:\"\\^\\[!#\\]\\.\\*\\(\\[Aa\\]pp\\|\\[Xx\\]\\)\\.\\*\\[Dd\\]efaults\"::::::\\n",
5497 "X Resources:.Xresources .Xdefaults .nedit .pats nedit.rc:\"^[!#].*([Aa]pp|[Xx]).*[Dd]efaults\"::::::\n",
5499 "Csh:\\.csh \\.cshrc \\.login \\.logout:\"\\^\\[ \\\\t\\]\\*#\\[ \\\\t\\]\\*!\\[ \\\\t\\]\\*/bin/csh\"::::::\\n",
5500 "Csh:.CSH .CSHRC .TCSHRC .LOGIN .LOGOUT:\"^[ \\t]*#[ \\t]*![ \\t]*/bin/t?csh\"::::::\n",
5501 "LaTeX:\\.TEX \\.STY \\.CLS \\.LTX \\.INS:::::::\\n",
5502 "LaTeX:.TEX .STY .CLS .LTX .INS .CLO .FD:::::::\n",
5503 "Lex:\\.lex:::::::\\n",
5504 "Lex:.LEX:::::::\n",
5505 "Matlab:\\.m \\.oct \\.sci:::::::\\n",
5506 "Matlab:.M .OCT .SCI:::::::\n",
5507 "Regex:\\.reg \\.regex:\"\\\\\\(\\\\\\?\\[:#=!iInN\\]\\.\\+\\\\\\\)\":None:Continuous::::\\n",
5508 "Regex:.REG .REGEX:\"\\(\\?[:#=!iInN].+\\)\":None:Continuous::::\n",
5509 "SGML HTML:\\.sgml \\.sgm \\.html \\.htm:\"\\\\\\<\\[Hh\\]\\[Tt\\]\\[Mm\\]\\[Ll\\]\\\\\\>\"::::::\\n",
5510 "SGML HTML:.SGML .SGM .HTML .HTM:\"\\<[Hh][Tt][Mm][Ll]\\>\"::::::\n",
5511 "SQL:\\.sql:::::::\\n",
5512 "SQL:.SQL:::::::\n",
5513 "Sh Ksh Bash:\\.sh \\.bash \\.ksh \\.profile \\.bashrc \\.bash_logout \\.bash_login \\.bash_profile:\"\\^\\[ \\\\t\\]\\*#\\[ \\\\t\\]\\*!\\[ \\\\t\\]\\*/\\.\\*bin/\\(bash\\|ksh\\|sh\\|zsh\\)\"::::::\\n",
5514 "Sh Ksh Bash:.SH .BASH .KSH .PROFILE .BASHRC .BASH_LOGOUT .BASH_LOGIN .BASH_PROFILE:\"^[ \\t]*#[ \\t]*![ \\t]*/.*bin/(bash|ksh|sh|zsh)\"::::::\n",
5515 "XML:\\.xml \\.xsl \\.dtd:\"\\\\\\<\\(\\?i\\\\\\?xml\\|!doctype\\)\"::None:::\"\\<\\>/=\"\"'\\(\\)\\+\\*\\?\\|\":\\n",
5516 "XML:.XML .XSL .DTD:\"\\<(?i\\?xml|!doctype)\"::None:::\"<>/=\"\"'()+*?|\":\n",
5517 "X Resources:\\.XRESOURCES \\.XDEFAULTS \\.NEDIT:\"\\^\\[!#\\]\\.\\*\\(\\[Aa\\]pp\\|\\[Xx\\]\\)\\.\\*\\[Dd\\]efaults\"::::::\\n",
5518 "X Resources:.XRESOURCES .XDEFAULTS .NEDIT .PATS NEDIT.RC:\"^[!#].*([Aa]pp|[Xx]).*[Dd]efaults\"::::::\n",
5522 /* Upgrade modified language modes, only if the user hasn't
5523 altered the default 5.5 definitions. */
5525 for (i
= 0; pats
[i
]; i
+=2) {
5526 if (regexFind(TempStringPrefs
.language
, pats
[i
]))
5527 regexReplace(&TempStringPrefs
.language
, pats
[i
], pats
[i
+1]);
5530 /* Add new styles */
5531 if (!regexFind(TempStringPrefs
.styles
, "^[ \t]*Bracket:"))
5532 spliceString(&TempStringPrefs
.styles
, "Bracket:dark blue:Bold",
5533 "^[ \t]*Storage Type:");
5534 if (!regexFind(TempStringPrefs
.styles
, "^[ \t]*Operator:"))
5535 spliceString(&TempStringPrefs
.styles
, "Operator:dark blue:Bold",
5541 * We migrate a color from the X resources to the prefs if:
5542 * 1. The prefs entry is equal to the default entry
5543 * 2. The X resource is not equal to the default entry
5545 static void migrateColor(XrmDatabase prefDB
, XrmDatabase appDB
,
5546 char *class, char *name
, int color_index
, char *default_val
)
5548 char *type
, *valueString
;
5551 /* If this color has been customized in the color dialog then use
5553 if ( strcmp(default_val
, PrefData
.colorNames
[color_index
]) )
5556 /* Retrieve the value of the resource from the DB */
5557 if (XrmGetResource(prefDB
, name
, class, &type
, &rsrcValue
)) {
5558 if (strcmp(type
, XmRString
)) {
5559 fprintf(stderr
,"Internal Error: Unexpected resource type, %s\n",
5563 valueString
= rsrcValue
.addr
;
5564 } else if (XrmGetResource(appDB
, name
, class, &type
, &rsrcValue
)) {
5565 if (strcmp(type
, XmRString
)) {
5566 fprintf(stderr
,"Internal Error: Unexpected resource type, %s\n",
5570 valueString
= rsrcValue
.addr
;
5572 /* No resources set */
5575 /* An X resource is set. If it's non-default, update the prefs. */
5576 if ( strcmp(valueString
, default_val
) ) {
5577 strncpy(PrefData
.colorNames
[color_index
], valueString
,
5583 * In 5.4 we moved color preferences from X resources to a color dialog,
5584 * meaning they're in the normal prefs system. Users who have customized
5585 * their colors with X resources would probably prefer not to have to redo
5586 * the customization in the dialog, so we migrate them to the prefs for them.
5588 static void migrateColorResources(XrmDatabase prefDB
, XrmDatabase appDB
)
5590 migrateColor(prefDB
, appDB
, APP_CLASS
".Text.Foreground",
5591 APP_NAME
".text.foreground", TEXT_FG_COLOR
,
5593 migrateColor(prefDB
, appDB
, APP_CLASS
".Text.Background",
5594 APP_NAME
".text.background", TEXT_BG_COLOR
,
5595 NEDIT_DEFAULT_TEXT_BG
);
5596 migrateColor(prefDB
, appDB
, APP_CLASS
".Text.SelectForeground",
5597 APP_NAME
".text.selectForeground", SELECT_FG_COLOR
,
5598 NEDIT_DEFAULT_SEL_FG
);
5599 migrateColor(prefDB
, appDB
, APP_CLASS
".Text.SelectBackground",
5600 APP_NAME
".text.selectBackground", SELECT_BG_COLOR
,
5601 NEDIT_DEFAULT_SEL_BG
);
5602 migrateColor(prefDB
, appDB
, APP_CLASS
".Text.HighlightForeground",
5603 APP_NAME
".text.highlightForeground", HILITE_FG_COLOR
,
5604 NEDIT_DEFAULT_HI_FG
);
5605 migrateColor(prefDB
, appDB
, APP_CLASS
".Text.HighlightBackground",
5606 APP_NAME
".text.highlightBackground", HILITE_BG_COLOR
,
5607 NEDIT_DEFAULT_HI_BG
);
5608 migrateColor(prefDB
, appDB
, APP_CLASS
".Text.LineNumForeground",
5609 APP_NAME
".text.lineNumForeground", LINENO_FG_COLOR
,
5610 NEDIT_DEFAULT_LINENO_FG
);
5611 migrateColor(prefDB
, appDB
, APP_CLASS
".Text.CursorForeground",
5612 APP_NAME
".text.cursorForeground", CURSOR_FG_COLOR
,
5613 NEDIT_DEFAULT_CURSOR_FG
);
5617 ** Inserts a string into intoString, reallocating it with XtMalloc. If
5618 ** regular expression atExpr is found, inserts the string before atExpr
5619 ** followed by a newline. If atExpr is not found, inserts insertString
5620 ** at the end, PRECEDED by a newline.
5622 static void spliceString(char **intoString
, const char *insertString
, const char *atExpr
)
5624 int beginPos
, endPos
;
5625 int intoLen
= strlen(*intoString
);
5626 int insertLen
= strlen(insertString
);
5627 char *newString
= XtMalloc(intoLen
+ insertLen
+ 2);
5629 if (atExpr
!= NULL
&& SearchString(*intoString
, atExpr
,
5630 SEARCH_FORWARD
, SEARCH_REGEX
, False
, 0, &beginPos
, &endPos
,
5631 NULL
, NULL
, NULL
)) {
5632 strncpy(newString
, *intoString
, beginPos
);
5633 strncpy(&newString
[beginPos
], insertString
, insertLen
);
5634 newString
[beginPos
+insertLen
] = '\n';
5635 strncpy(&newString
[beginPos
+insertLen
+1],
5636 &((*intoString
)[beginPos
]), intoLen
- beginPos
);
5638 strncpy(newString
, *intoString
, intoLen
);
5639 newString
[intoLen
] = '\n';
5640 strncpy(&newString
[intoLen
+1], insertString
, insertLen
);
5642 newString
[intoLen
+ insertLen
+ 1] = '\0';
5643 XtFree(*intoString
);
5644 *intoString
= newString
;
5648 ** Simplified regular expression search routine which just returns true
5649 ** or false depending on whether inString matches expr
5651 static int regexFind(const char *inString
, const char *expr
)
5653 int beginPos
, endPos
;
5654 return SearchString(inString
, expr
, SEARCH_FORWARD
, SEARCH_REGEX
, False
,
5655 0, &beginPos
, &endPos
, NULL
, NULL
, NULL
);
5659 ** Simplified case-sensisitive string search routine which just
5660 ** returns true or false depending on whether inString matches expr
5662 static int caseFind(const char *inString
, const char *expr
)
5664 int beginPos
, endPos
;
5665 return SearchString(inString
, expr
, SEARCH_FORWARD
, SEARCH_CASE_SENSE
,
5666 False
, 0, &beginPos
, &endPos
, NULL
, NULL
, NULL
);
5670 ** Common implementation for simplified string replacement routines.
5672 static int stringReplace(char **inString
, const char *expr
,
5673 const char *replaceWith
, int searchType
,
5676 int beginPos
, endPos
, newLen
;
5678 int inLen
= strlen(*inString
);
5679 if (0 >= replaceLen
) replaceLen
= strlen(replaceWith
);
5680 if (!SearchString(*inString
, expr
, SEARCH_FORWARD
, searchType
, False
,
5681 0, &beginPos
, &endPos
, NULL
, NULL
, NULL
))
5683 newLen
= inLen
+ replaceLen
- (endPos
-beginPos
);
5684 newString
= XtMalloc(newLen
+ 1);
5685 strncpy(newString
, *inString
, beginPos
);
5686 strncpy(&newString
[beginPos
], replaceWith
, replaceLen
);
5687 strncpy(&newString
[beginPos
+replaceLen
],
5688 &((*inString
)[endPos
]), inLen
- endPos
);
5689 newString
[newLen
] = '\0';
5691 *inString
= newString
;
5696 ** Simplified regular expression replacement routine which replaces the
5697 ** first occurence of expr in inString with replaceWith, reallocating
5698 ** inString with XtMalloc. If expr is not found, does nothing and
5701 static int regexReplace(char **inString
, const char *expr
,
5702 const char *replaceWith
)
5704 return stringReplace(inString
, expr
, replaceWith
, SEARCH_REGEX
, -1);
5708 ** Simplified case-sensisitive string replacement routine which
5709 ** replaces the first occurence of expr in inString with replaceWith,
5710 ** reallocating inString with XtMalloc. If expr is not found, does nothing
5711 ** and returns false.
5713 static int caseReplace(char **inString
, const char *expr
,
5714 const char *replaceWith
, int replaceLen
)
5716 return stringReplace(inString
, expr
, replaceWith
, SEARCH_CASE_SENSE
,
5721 ** Looks for a (case-sensitive literal) match of an old macro text in a
5722 ** temporary macro commands buffer. If the text is found, it is replaced by
5723 ** a substring of the default macros, bounded by a given start and end pattern
5724 ** (inclusive). Returns the length of the replacement.
5726 static int replaceMacroIfUnchanged(const char* oldText
, const char* newStart
,
5729 if (caseFind(TempStringPrefs
.macroCmds
, oldText
)) {
5731 const char *start
= strstr(PrefDescrip
[1].defaultString
, newStart
);
5733 const char *start
= strstr(PrefDescrip
[2].defaultString
, newStart
);
5736 const char *end
= strstr(start
, newEnd
);
5738 int length
= (int)(end
-start
) + strlen(newEnd
);
5739 caseReplace(&TempStringPrefs
.macroCmds
, oldText
, start
, length
);
5749 ** Replace all '#' characters in shell commands by '##' to keep commands
5750 ** containing those working. '#' is a line number placeholder in 5.3 and
5751 ** had no special meaning before.
5753 static void updateShellCmdsTo5dot3(void)
5755 char *cOld
, *cNew
, *pCol
, *pNL
;
5759 if(!TempStringPrefs
.shellCmds
)
5762 /* Count number of '#'. If there are '#' characters in the non-command
5763 ** part of the definition we count too much and later allocate too much
5764 ** memory for the new string, but this doesn't hurt.
5766 for(cOld
=TempStringPrefs
.shellCmds
, nHash
=0; *cOld
; cOld
++)
5770 /* No '#' -> no conversion necessary. */
5774 newString
=XtMalloc(strlen(TempStringPrefs
.shellCmds
) + 1 + nHash
);
5776 cOld
= TempStringPrefs
.shellCmds
;
5782 /* Copy all characters from TempStringPrefs.shellCmds into newString
5783 ** and duplicate '#' in command parts. A simple check for really beeing
5784 ** inside a command part (starting with '\n', between the the two last
5785 ** '\n' a colon ':' must have been found) is preformed.
5788 /* actually every 2nd line is a command. We additionally
5789 ** check if there is a colon ':' in the previous line.
5792 if((pCol
> pNL
) && !isCmd
)
5799 if(!isCmd
&& *cOld
==':')
5802 /* Duplicate hashes if we're in a command part */
5803 if(isCmd
&& *cOld
=='#')
5806 /* Copy every character */
5811 /* Terminate new preferences string */
5814 /* free the old memory */
5815 XtFree(TempStringPrefs
.shellCmds
);
5817 /* exchange the string */
5818 TempStringPrefs
.shellCmds
= newString
;
5824 static void updateShellCmdsTo5dot3(void) {
5825 /* No shell commands in VMS ! */
5831 static void updateShellCmdsTo5dot4(void)
5833 #ifndef VMS /* No shell commands on VMS */
5836 const char* wc5dot3
=
5837 "^(\\s*)set wc=`wc`; echo \\$wc\\[1\\] \"words,\" \\$wc\\[2\\] \"lines,\" \\$wc\\[3\\] \"characters\"\\n";
5838 const char* wc5dot4
=
5839 "wc | awk '{print $2 \" lines, \" $1 \" words, \" $3 \" characters\"}'\n";
5841 const char* wc5dot3
=
5842 "^(\\s*)set wc=`wc`; echo \\$wc\\[1\\] \"lines,\" \\$wc\\[2\\] \"words,\" \\$wc\\[3\\] \"characters\"\\n";
5843 const char* wc5dot4
=
5844 "wc | awk '{print $1 \" lines, \" $2 \" words, \" $3 \" characters\"}'\n";
5845 #endif /* __FreeBSD__ */
5847 if (regexFind(TempStringPrefs
.shellCmds
, wc5dot3
))
5848 regexReplace(&TempStringPrefs
.shellCmds
, wc5dot3
, wc5dot4
);
5855 static void updateMacroCmdsTo5dot5(void)
5857 const char* uc5dot4
=
5858 "^(\\s*)if \\(substring\\(sel, keepEnd - 1, keepEnd == \" \"\\)\\)\\n";
5859 const char* uc5dot5
=
5860 " if (substring(sel, keepEnd - 1, keepEnd) == \" \")\n";
5861 if (regexFind(TempStringPrefs
.macroCmds
, uc5dot4
))
5862 regexReplace(&TempStringPrefs
.macroCmds
, uc5dot4
, uc5dot5
);
5867 static void updateMacroCmdsTo5dot6(void)
5870 This is ridiculous. Macros don't belong in the default preferences
5872 This code is also likely to break when the macro commands are upgraded
5873 again in a next release, because it looks for patterns in the default
5874 macro string (which may change).
5875 Using a "Default" mechanism, like we do for highlighting patterns
5876 would simplify upgrading A LOT in the future, but changing the way
5877 default macros are stored, is a lot of work too, unfortunately.
5879 const char *pats
[] = {
5880 "Complete Word:Alt+D::: {\n\
5881 # Tuning parameters\n\
5882 ScanDistance = 200\n\
5884 # Search back to a word boundary to find the word to complete\n\
5885 startScan = max(0, $cursor - ScanDistance)\n\
5886 endScan = min($text_length, $cursor + ScanDistance)\n\
5887 scanString = get_range(startScan, endScan)\n\
5888 keyEnd = $cursor-startScan\n\
5889 keyStart = search_string(scanString, \"<\", keyEnd, \"backward\", \"regex\")\n\
5890 if (keyStart == -1)\n\
5892 keyString = \"<\" substring(scanString, keyStart, keyEnd)\n\
5894 # search both forward and backward from the cursor position. Note that\n\
5895 # using a regex search can lead to incorrect results if any of the special\n\
5896 # regex characters is encountered, which is not considered a delimiter\n\
5897 backwardSearchResult = search_string(scanString, keyString, keyStart-1, \\\n\
5898 \"backward\", \"regex\")\n\
5899 forwardSearchResult = search_string(scanString, keyString, keyEnd, \"regex\")\n\
5900 if (backwardSearchResult == -1 && forwardSearchResult == -1) {\n\
5905 # if only one direction matched, use that, otherwise use the nearest\n\
5906 if (backwardSearchResult == -1)\n\
5907 matchStart = forwardSearchResult\n\
5908 else if (forwardSearchResult == -1)\n\
5909 matchStart = backwardSearchResult\n\
5911 if (keyStart - backwardSearchResult <= forwardSearchResult - keyEnd)\n\
5912 matchStart = backwardSearchResult\n\
5914 matchStart = forwardSearchResult\n\
5917 # find the complete word\n\
5918 matchEnd = search_string(scanString, \">\", matchStart, \"regex\")\n\
5919 completedWord = substring(scanString, matchStart, matchEnd)\n\
5921 # replace it in the window\n\
5922 replace_range(startScan + keyStart, $cursor, completedWord)\n\
5923 }", "Complete Word:", "\n\t}",
5924 "Fill Sel. w/Char:::R: {\n\
5925 if ($selection_start == -1) {\n\
5930 # Ask the user what character to fill with\n\
5931 fillChar = string_dialog(\"Fill selection with what character?\", \"OK\", \"Cancel\")\n\
5932 if ($string_dialog_button == 2 || $string_dialog_button == 0)\n\
5935 # Count the number of lines in the selection\n\
5937 for (i=$selection_start; i<$selection_end; i++)\n\
5938 if (get_character(i) == \"\\n\")\n\
5941 # Create the fill text\n\
5942 rectangular = $selection_left != -1\n\
5945 if (rectangular) {\n\
5946 for (i=0; i<$selection_right-$selection_left; i++)\n\
5947 line = line fillChar\n\
5948 for (i=0; i<nLines; i++)\n\
5949 fillText = fillText line \"\\n\"\n\
5950 fillText = fillText line\n\
5952 if (nLines == 0) {\n\
5953 for (i=$selection_start; i<$selection_end; i++)\n\
5954 fillText = fillText fillChar\n\
5957 for (i=$selection_start-1; i>=0 && get_character(i)!=\"\\n\"; i--)\n\
5959 for (i=0; i<$wrap_margin-startIndent; i++)\n\
5960 fillText = fillText fillChar\n\
5961 fillText = fillText \"\\n\"\n\
5962 for (i=0; i<$wrap_margin; i++)\n\
5963 line = line fillChar\n\
5964 for (i=0; i<nLines-1; i++)\n\
5965 fillText = fillText line \"\\n\"\n\
5966 for (i=$selection_end-1; i>=$selection_start && get_character(i)!=\"\\n\"; \\\n\
5968 fillText = fillText fillChar\n\
5972 # Replace the selection with the fill text\n\
5973 replace_selection(fillText)\n\
5974 }", "Fill Sel. w/Char:", "\n\t}",
5975 "Comments>/* Uncomment */@C@C++@Java@CSS@JavaScript@Lex:::R: {\n\
5976 sel = get_selection()\n\
5977 selStart = $selection_start\n\
5978 selEnd = $selection_end\n\
5979 commentStart = search_string(sel, \"/*\", 0)\n\
5980 if (substring(sel, commentStart + 2, commentStart + 3) == \" \")\n\
5981 keepStart = commentStart + 3\n\
5983 keepStart = commentStart + 2\n\
5984 keepEnd = search_string(sel, \"*/\", length(sel), \"backward\")\n\
5985 commentEnd = keepEnd + 2\n\
5986 if (substring(sel, keepEnd - 1, keepEnd) == \" \")\n\
5987 keepEnd = keepEnd - 1\n\
5988 replace_range(selStart + commentStart, selStart + commentEnd, \\\n\
5989 substring(sel, keepStart, keepEnd))\n\
5990 select(selStart, selEnd - (keepStart-commentStart) - \\\n\
5991 (commentEnd - keepEnd))\n\
5992 }", "Comments>/* Uncomment */", "\n\t}",
5993 "Comments>Bar Uncomment@C:::R: {\n\
5994 selStart = $selection_start\n\
5995 selEnd = $selection_end\n\
5996 newText = get_range(selStart+3, selEnd-4)\n\
5997 newText = replace_in_string(newText, \"^ \\\\* \", \"\", \"regex\")\n\
5998 replace_range(selStart, selEnd, newText)\n\
5999 select(selStart, selStart + length(newText))\n\
6000 }","Comments>Bar Uncomment@C:", "\n\t}",
6001 "Make C Prototypes@C@C++:::: {\n\
6002 if ($selection_start == -1) {\n\
6004 end = $text_length\n\
6006 start = $selection_start\n\
6007 end = $selection_end\n\
6009 string = get_range(start, end)\n\
6010 nDefs = 0", "Make C Prototypes@C@C++:", "\t\tnDefs = 0",
6013 for (i
= 0; pats
[i
]; i
+=3)
6014 replaceMacroIfUnchanged(pats
[i
], pats
[i
+1], pats
[i
+2]);
6020 ** Present the user a dialog for specifying whether or not a short
6021 ** menu mode preference should be applied toward the default setting.
6022 ** Return False (function value) if operation was canceled, return True
6023 ** in setDefault if requested to reset the default value.
6025 static int shortPrefToDefault(Widget parent
, const char *settingName
, int *setDefault
)
6029 if (!GetPrefShortMenus()) {
6030 *setDefault
= False
;
6034 sprintf(msg
, "%s\nSave as default for future windows as well?", settingName
);
6035 switch (DialogF (DF_QUES
, parent
, 3, "Save Default", msg
, "Yes", "No",
6042 *setDefault
= False
;
6044 case 3: /* cancel */
6047 return False
; /* not reached */
6051 /* Decref the default calltips file(s) for this window */
6052 void UnloadLanguageModeTipsFile(WindowInfo
*window
)
6056 mode
= window
->languageMode
;
6057 if (mode
!= PLAIN_LANGUAGE_MODE
&& LanguageModes
[mode
]->defTipsFile
) {
6058 DeleteTagsFile( LanguageModes
[mode
]->defTipsFile
, TIP
, False
);
6062 /******************************************************************************
6063 * The Color selection dialog
6064 ******************************************************************************/
6067 There are 8 colors: And 8 indices:
6068 textFg TEXT_FG_COLOR
6069 textBg TEXT_BG_COLOR
6070 selectFg SELECT_FG_COLOR
6071 selectBg SELECT_BG_COLOR
6072 hiliteFg HILITE_FG_COLOR
6073 hiliteBg HILITE_BG_COLOR
6074 lineNoFg LINENO_FG_COLOR
6075 cursorFg CURSOR_FG_COLOR
6078 #define MARGIN_SPACING 10
6081 * Callbacks for field modifications
6083 static void textFgModifiedCB(Widget w
, XtPointer clientData
,
6086 colorDialog
*cd
= (colorDialog
*)clientData
;
6087 showColorStatus(cd
, cd
->textFgW
, cd
->textFgErrW
);
6090 static void textBgModifiedCB(Widget w
, XtPointer clientData
,
6093 colorDialog
*cd
= (colorDialog
*)clientData
;
6094 showColorStatus(cd
, cd
->textBgW
, cd
->textBgErrW
);
6097 static void selectFgModifiedCB(Widget w
, XtPointer clientData
,
6100 colorDialog
*cd
= (colorDialog
*)clientData
;
6101 showColorStatus(cd
, cd
->selectFgW
, cd
->selectFgErrW
);
6104 static void selectBgModifiedCB(Widget w
, XtPointer clientData
,
6107 colorDialog
*cd
= (colorDialog
*)clientData
;
6108 showColorStatus(cd
, cd
->selectBgW
, cd
->selectBgErrW
);
6111 static void hiliteFgModifiedCB(Widget w
, XtPointer clientData
,
6114 colorDialog
*cd
= (colorDialog
*)clientData
;
6115 showColorStatus(cd
, cd
->hiliteFgW
, cd
->hiliteFgErrW
);
6118 static void hiliteBgModifiedCB(Widget w
, XtPointer clientData
,
6121 colorDialog
*cd
= (colorDialog
*)clientData
;
6122 showColorStatus(cd
, cd
->hiliteBgW
, cd
->hiliteBgErrW
);
6125 static void lineNoFgModifiedCB(Widget w
, XtPointer clientData
,
6128 colorDialog
*cd
= (colorDialog
*)clientData
;
6129 showColorStatus(cd
, cd
->lineNoFgW
, cd
->lineNoFgErrW
);
6132 static void cursorFgModifiedCB(Widget w
, XtPointer clientData
,
6135 colorDialog
*cd
= (colorDialog
*)clientData
;
6136 showColorStatus(cd
, cd
->cursorFgW
, cd
->cursorFgErrW
);
6141 * Helper functions for validating colors
6143 static int verifyAllColors(colorDialog
*cd
)
6145 /* Maybe just check for empty strings in error widgets instead? */
6146 return (checkColorStatus(cd
, cd
->textFgW
) &&
6147 checkColorStatus(cd
, cd
->textBgW
) &&
6148 checkColorStatus(cd
, cd
->selectFgW
) &&
6149 checkColorStatus(cd
, cd
->selectBgW
) &&
6150 checkColorStatus(cd
, cd
->hiliteFgW
) &&
6151 checkColorStatus(cd
, cd
->hiliteBgW
) &&
6152 checkColorStatus(cd
, cd
->lineNoFgW
) &&
6153 checkColorStatus(cd
, cd
->cursorFgW
) );
6156 /* Returns True if the color is valid, False if it's not */
6157 static Boolean
checkColorStatus(colorDialog
*cd
, Widget colorFieldW
)
6162 Display
*display
= XtDisplay(cd
->shell
);
6163 char *text
= XmTextGetString(colorFieldW
);
6164 XtVaGetValues(cd
->shell
, XtNcolormap
, &cMap
, NULL
);
6165 status
= XParseColor(display
, cMap
, text
, &colorDef
);
6167 return (status
!= 0);
6170 /* Show or hide errorLabelW depending on whether or not colorFieldW
6171 contains a valid color name. */
6172 static void showColorStatus(colorDialog
*cd
, Widget colorFieldW
,
6175 /* Should set the OK/Apply button sensitivity here, instead
6176 of leaving is sensitive and then complaining if an error. */
6177 XtSetMappedWhenManaged( errorLabelW
, !checkColorStatus(cd
, colorFieldW
) );
6180 /* Update the colors in the window or in the preferences */
6181 static void updateColors(colorDialog
*cd
)
6185 char *textFg
= XmTextGetString(cd
->textFgW
),
6186 *textBg
= XmTextGetString(cd
->textBgW
),
6187 *selectFg
= XmTextGetString(cd
->selectFgW
),
6188 *selectBg
= XmTextGetString(cd
->selectBgW
),
6189 *hiliteFg
= XmTextGetString(cd
->hiliteFgW
),
6190 *hiliteBg
= XmTextGetString(cd
->hiliteBgW
),
6191 *lineNoFg
= XmTextGetString(cd
->lineNoFgW
),
6192 *cursorFg
= XmTextGetString(cd
->cursorFgW
);
6194 for (window
= WindowList
; window
!= NULL
; window
= window
->next
)
6196 SetColors(window
, textFg
, textBg
, selectFg
, selectBg
, hiliteFg
,
6197 hiliteBg
, lineNoFg
, cursorFg
);
6200 SetPrefColorName(TEXT_FG_COLOR
, textFg
);
6201 SetPrefColorName(TEXT_BG_COLOR
, textBg
);
6202 SetPrefColorName(SELECT_FG_COLOR
, selectFg
);
6203 SetPrefColorName(SELECT_BG_COLOR
, selectBg
);
6204 SetPrefColorName(HILITE_FG_COLOR
, hiliteFg
);
6205 SetPrefColorName(HILITE_BG_COLOR
, hiliteBg
);
6206 SetPrefColorName(LINENO_FG_COLOR
, lineNoFg
);
6207 SetPrefColorName(CURSOR_FG_COLOR
, cursorFg
);
6221 * Dialog button callbacks
6224 static void colorDestroyCB(Widget w
, XtPointer clientData
, XtPointer callData
)
6226 colorDialog
*cd
= (colorDialog
*)clientData
;
6228 cd
->window
->colorDialog
= NULL
;
6232 static void colorOkCB(Widget w
, XtPointer clientData
, XtPointer callData
)
6234 colorDialog
*cd
= (colorDialog
*)clientData
;
6236 if(!verifyAllColors(cd
))
6238 DialogF(DF_ERR
, w
, 1, "Invalid Colors",
6239 "All colors must be valid to proceed.", "OK");
6244 /* pop down and destroy the dialog */
6245 XtDestroyWidget(cd
->shell
);
6248 static void colorApplyCB(Widget w
, XtPointer clientData
, XtPointer callData
)
6250 colorDialog
*cd
= (colorDialog
*)clientData
;
6252 if(!verifyAllColors(cd
))
6254 DialogF(DF_ERR
, w
, 1, "Invalid Colors",
6255 "All colors must be valid to be applied.", "OK");
6261 static void colorCloseCB(Widget w
, XtPointer clientData
, XtPointer callData
)
6263 colorDialog
*cd
= (colorDialog
*)clientData
;
6265 /* pop down and destroy the dialog */
6266 XtDestroyWidget(cd
->shell
);
6270 /* Add a label, error label, and text entry label with a validation
6272 static Widget
addColorGroup( Widget parent
, const char *name
, char mnemonic
,
6273 char *label
, Widget
*fieldW
, Widget
*errW
, Widget topWidget
,
6274 int leftPos
, int rightPos
, XtCallbackProc modCallback
,
6280 int nameLen
= strlen(name
);
6282 /* The label widget */
6283 longerName
= XtMalloc(nameLen
+7);
6284 strcpy(longerName
, name
);
6285 strcat(longerName
, "Lbl");
6286 lblW
= XtVaCreateManagedWidget(longerName
,
6287 xmLabelGadgetClass
, parent
,
6288 XmNlabelString
, s1
=XmStringCreateSimple( label
),
6289 XmNmnemonic
, mnemonic
,
6290 XmNtopAttachment
, XmATTACH_WIDGET
,
6291 XmNtopWidget
, topWidget
,
6292 XmNtopOffset
, MARGIN_SPACING
,
6293 XmNleftAttachment
, XmATTACH_POSITION
,
6294 XmNleftPosition
, leftPos
, NULL
);
6297 /* The error label widget */
6298 strcpy(&(longerName
[nameLen
]), "ErrLbl");
6299 *errW
= XtVaCreateManagedWidget(longerName
,
6300 xmLabelWidgetClass
, parent
,
6301 XmNlabelString
, s1
=XmStringCreateSimple("(Invalid!)"),
6302 XmNalignment
, XmALIGNMENT_END
,
6303 XmNtopAttachment
, XmATTACH_WIDGET
,
6304 XmNtopWidget
, topWidget
,
6305 XmNtopOffset
, MARGIN_SPACING
,
6306 XmNleftAttachment
, XmATTACH_WIDGET
,
6307 XmNleftWidget
, lblW
,
6308 XmNrightAttachment
, XmATTACH_POSITION
,
6309 XmNrightPosition
, rightPos
, NULL
);
6312 /* The text field entry widget */
6313 *fieldW
= XtVaCreateManagedWidget(name
, xmTextWidgetClass
,
6315 XmNcolumns
, MAX_COLOR_LEN
-1,
6316 XmNmaxLength
, MAX_COLOR_LEN
-1,
6317 XmNleftAttachment
, XmATTACH_POSITION
,
6318 XmNleftPosition
, leftPos
,
6319 XmNrightAttachment
, XmATTACH_POSITION
,
6320 XmNrightPosition
, rightPos
,
6321 XmNtopAttachment
, XmATTACH_WIDGET
,
6322 XmNtopWidget
, lblW
, NULL
);
6323 RemapDeleteKey(*fieldW
);
6324 XtAddCallback(*fieldW
, XmNvalueChangedCallback
,
6326 XtVaSetValues(lblW
, XmNuserData
, *fieldW
, NULL
);
6334 * Code for the dialog itself
6336 void ChooseColors(WindowInfo
*window
)
6338 Widget form
, tmpW
, topW
, infoLbl
;
6339 Widget okBtn
, applyBtn
, closeBtn
;
6345 /* if the dialog is already displayed, just pop it to the top and return */
6346 if (window
->colorDialog
!= NULL
) {
6347 RaiseDialogWindow(((colorDialog
*)window
->colorDialog
)->shell
);
6351 /* Create a structure for keeping track of dialog state */
6352 cd
= XtNew(colorDialog
);
6353 window
->colorDialog
= (void*)cd
;
6355 /* Create a form widget in a dialog shell */
6357 XtSetArg(args
[ac
], XmNautoUnmanage
, False
); ac
++;
6358 XtSetArg(args
[ac
], XmNresizePolicy
, XmRESIZE_NONE
); ac
++;
6359 form
= CreateFormDialog(window
->shell
, "choose colors", args
, ac
);
6360 XtVaSetValues(form
, XmNshadowThickness
, 0, NULL
);
6361 cd
->shell
= XtParent(form
);
6362 cd
->window
= window
;
6363 XtVaSetValues(cd
->shell
, XmNtitle
, "Colors", NULL
);
6364 AddMotifCloseCallback(XtParent(form
), colorCloseCB
, cd
);
6365 XtAddCallback(form
, XmNdestroyCallback
, colorDestroyCB
, cd
);
6367 /* Information label */
6368 infoLbl
= XtVaCreateManagedWidget("infoLbl",
6369 xmLabelGadgetClass
, form
,
6370 XmNtopAttachment
, XmATTACH_POSITION
,
6372 XmNleftAttachment
, XmATTACH_POSITION
,
6374 XmNrightAttachment
, XmATTACH_POSITION
,
6375 XmNrightPosition
, 99,
6376 XmNalignment
, XmALIGNMENT_CENTER
,
6377 XmNlabelString
, s1
= XmStringCreateLtoR(
6378 "Colors can be entered as names (e.g. red, blue) or "
6379 "as RGB triples\nin the format #RRGGBB, where each digit "
6380 "is in the range 0-f.", XmFONTLIST_DEFAULT_TAG
),
6386 /* The left column (foregrounds) of color entry groups */
6387 tmpW
= addColorGroup( form
, "textFg", 'P', "Plain Text Foreground",
6388 &(cd
->textFgW
), &(cd
->textFgErrW
), topW
, 1, 49,
6389 textFgModifiedCB
, cd
);
6390 tmpW
= addColorGroup( form
, "selectFg", 'S', "Selection Foreground",
6391 &(cd
->selectFgW
), &(cd
->selectFgErrW
), tmpW
, 1, 49,
6392 selectFgModifiedCB
, cd
);
6393 tmpW
= addColorGroup( form
, "hiliteFg", 'M', "Matching (..) Foreground",
6394 &(cd
->hiliteFgW
), &(cd
->hiliteFgErrW
), tmpW
, 1, 49,
6395 hiliteFgModifiedCB
, cd
);
6396 tmpW
= addColorGroup( form
, "lineNoFg", 'L', "Line Numbers",
6397 &(cd
->lineNoFgW
), &(cd
->lineNoFgErrW
), tmpW
, 1, 49,
6398 lineNoFgModifiedCB
, cd
);
6400 /* The right column (backgrounds) */
6401 tmpW
= addColorGroup( form
, "textBg", 'T', "Text Area Background",
6402 &(cd
->textBgW
), &(cd
->textBgErrW
), topW
, 51, 99,
6403 textBgModifiedCB
, cd
);
6404 tmpW
= addColorGroup( form
, "selectBg", 'B', "Selection Background",
6405 &(cd
->selectBgW
), &(cd
->selectBgErrW
), tmpW
, 51, 99,
6406 selectBgModifiedCB
, cd
);
6407 tmpW
= addColorGroup( form
, "hiliteBg", 'h', "Matching (..) Background",
6408 &(cd
->hiliteBgW
), &(cd
->hiliteBgErrW
), tmpW
, 51, 99,
6409 hiliteBgModifiedCB
, cd
);
6410 tmpW
= addColorGroup( form
, "cursorFg", 'C', "Cursor Color",
6411 &(cd
->cursorFgW
), &(cd
->cursorFgErrW
), tmpW
, 51, 99,
6412 cursorFgModifiedCB
, cd
);
6414 tmpW
= XtVaCreateManagedWidget("infoLbl",
6415 xmLabelGadgetClass
, form
,
6416 XmNtopAttachment
, XmATTACH_WIDGET
,
6418 XmNtopOffset
, MARGIN_SPACING
,
6419 XmNleftAttachment
, XmATTACH_POSITION
,
6421 XmNrightAttachment
, XmATTACH_POSITION
,
6422 XmNrightPosition
, 99,
6423 XmNalignment
, XmALIGNMENT_CENTER
,
6424 XmNlabelString
, s1
= XmStringCreateLtoR(
6425 "NOTE: Foreground colors only apply when syntax highlighting "
6426 "is DISABLED.\n", XmFONTLIST_DEFAULT_TAG
),
6430 tmpW
= XtVaCreateManagedWidget("sep",
6431 xmSeparatorGadgetClass
, form
,
6432 XmNtopAttachment
, XmATTACH_WIDGET
,
6434 XmNleftAttachment
, XmATTACH_FORM
,
6435 XmNrightAttachment
, XmATTACH_FORM
, NULL
);
6437 /* The OK, Apply, and Cancel buttons */
6438 okBtn
= XtVaCreateManagedWidget("ok",
6439 xmPushButtonWidgetClass
, form
,
6440 XmNlabelString
, s1
=XmStringCreateSimple("OK"),
6441 XmNmarginWidth
, BUTTON_WIDTH_MARGIN
,
6442 XmNtopAttachment
, XmATTACH_WIDGET
,
6444 XmNtopOffset
, MARGIN_SPACING
,
6445 XmNleftAttachment
, XmATTACH_POSITION
,
6446 XmNleftPosition
, 10,
6447 XmNrightAttachment
, XmATTACH_POSITION
,
6448 XmNrightPosition
, 30,
6450 XtAddCallback(okBtn
, XmNactivateCallback
, colorOkCB
, cd
);
6453 applyBtn
= XtVaCreateManagedWidget(
6454 "apply", xmPushButtonWidgetClass
, form
,
6455 XmNlabelString
, s1
=XmStringCreateSimple("Apply"),
6456 XmNtopAttachment
, XmATTACH_WIDGET
,
6458 XmNtopOffset
, MARGIN_SPACING
,
6460 XmNleftAttachment
, XmATTACH_POSITION
,
6461 XmNleftPosition
, 40,
6462 XmNrightAttachment
, XmATTACH_POSITION
,
6463 XmNrightPosition
, 60, NULL
);
6464 XtAddCallback(applyBtn
, XmNactivateCallback
, colorApplyCB
, cd
);
6467 closeBtn
= XtVaCreateManagedWidget("close",
6468 xmPushButtonWidgetClass
, form
,
6469 XmNlabelString
, s1
=XmStringCreateSimple("Close"),
6470 XmNtopAttachment
, XmATTACH_WIDGET
,
6472 XmNtopOffset
, MARGIN_SPACING
,
6473 XmNleftAttachment
, XmATTACH_POSITION
,
6474 XmNleftPosition
, 70,
6475 XmNrightAttachment
, XmATTACH_POSITION
,
6476 XmNrightPosition
, 90,
6478 XtAddCallback(closeBtn
, XmNactivateCallback
, colorCloseCB
, cd
);
6481 /* Set initial default button */
6482 XtVaSetValues(form
, XmNdefaultButton
, okBtn
, NULL
);
6483 XtVaSetValues(form
, XmNcancelButton
, closeBtn
, NULL
);
6485 /* Set initial values */
6486 XmTextSetString(cd
->textFgW
, GetPrefColorName(TEXT_FG_COLOR
));
6487 XmTextSetString(cd
->textBgW
, GetPrefColorName(TEXT_BG_COLOR
));
6488 XmTextSetString(cd
->selectFgW
, GetPrefColorName(SELECT_FG_COLOR
));
6489 XmTextSetString(cd
->selectBgW
, GetPrefColorName(SELECT_BG_COLOR
));
6490 XmTextSetString(cd
->hiliteFgW
, GetPrefColorName(HILITE_FG_COLOR
));
6491 XmTextSetString(cd
->hiliteBgW
, GetPrefColorName(HILITE_BG_COLOR
));
6492 XmTextSetString(cd
->lineNoFgW
, GetPrefColorName(LINENO_FG_COLOR
));
6493 XmTextSetString(cd
->cursorFgW
, GetPrefColorName(CURSOR_FG_COLOR
));
6495 /* Handle mnemonic selection of buttons and focus to dialog */
6496 AddDialogMnemonicHandler(form
, FALSE
);
6499 ManageDialogCenteredOnPointer(form
);
6503 ** This function passes up a pointer to the static name of the default
6504 ** shell, currently defined as the user's login shell.
6505 ** In case of errors, the fallback of "sh" will be returned.
6507 static const char* getDefaultShell(void)
6509 struct passwd
* passwdEntry
= NULL
;
6510 static char shellBuffer
[MAXPATHLEN
+ 1] = "sh";
6512 passwdEntry
= getpwuid(getuid()); /* getuid() never fails. */
6514 if (NULL
== passwdEntry
)
6516 /* Something bad happened! Do something, quick! */
6517 perror("nedit: Failed to get passwd entry (falling back to 'sh')");
6521 /* *passwdEntry may be overwritten */
6522 /* TODO: To make this and other function calling getpwuid() more robust,
6523 passwdEntry should be kept in a central position (Core->sysinfo?).
6524 That way, local code would always get a current copy of passwdEntry,
6525 but could still be kept lean. The obvious alternative of a central
6526 facility within NEdit to access passwdEntry would increase coupling
6527 and would have to cover a lot of assumptions. */
6528 strncpy(shellBuffer
, passwdEntry
->pw_shell
, MAXPATHLEN
);
6529 shellBuffer
[MAXPATHLEN
] = '\0';