SF #1772468 - crash when pressing Insert in a help window
[nedit.git] / source / menu.c
blobe643f32b3ecdeae0774cdfee4c2355e73291c1dd
1 static const char CVSID[] = "$Id: menu.c,v 1.139 2007/08/12 18:13:10 tringali Exp $";
2 /*******************************************************************************
3 * *
4 * menu.c -- Nirvana Editor menus *
5 * *
6 * Copyright (C) 1999 Mark Edel *
7 * *
8 * This is free software; you can redistribute it and/or modify it under the *
9 * terms of the GNU General Public License as published by the Free Software *
10 * Foundation; either version 2 of the License, or (at your option) any later *
11 * version. In addition, you may distribute versions of this program linked to *
12 * Motif or Open Motif. See README for details. *
13 * *
14 * This software is distributed in the hope that it will be useful, but WITHOUT *
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
17 * for more details. *
18 * *
19 * You should have received a copy of the GNU General Public License along with *
20 * software; if not, write to the Free Software Foundation, Inc., 59 Temple *
21 * Place, Suite 330, Boston, MA 02111-1307 USA *
22 * *
23 * Nirvana Text Editor *
24 * May 10, 1991 *
25 * *
26 * Written by Mark Edel *
27 * *
28 *******************************************************************************/
30 #ifdef HAVE_CONFIG_H
31 #include "../config.h"
32 #endif
34 #include "menu.h"
35 #include "textBuf.h"
36 #include "text.h"
37 #include "nedit.h"
38 #include "file.h"
39 #include "window.h"
40 #include "search.h"
41 #include "selection.h"
42 #include "undo.h"
43 #include "shift.h"
44 #include "help.h"
45 #include "preferences.h"
46 #include "tags.h"
47 #include "userCmds.h"
48 #include "shell.h"
49 #include "macro.h"
50 #include "highlight.h"
51 #include "highlightData.h"
52 #include "interpret.h"
53 #include "smartIndent.h"
54 #include "windowTitle.h"
55 #include "../util/getfiles.h"
56 #include "../util/DialogF.h"
57 #include "../util/misc.h"
58 #include "../util/fileUtils.h"
59 #include "../util/utils.h"
60 #include "../Xlt/BubbleButton.h"
62 #include <ctype.h>
63 #include <errno.h>
64 #include <stdio.h>
65 #include <stdlib.h>
66 #include <string.h>
67 #include <unistd.h>
68 #include <sys/stat.h>
69 #include <sys/types.h>
71 #ifdef VMS
72 #include "../util/VMSparam.h"
73 #else
74 #ifndef __MVS__
75 #include <sys/param.h>
76 #endif
77 #endif /*VMS*/
79 #include <X11/X.h>
80 #include <Xm/Xm.h>
81 #include <Xm/CascadeB.h>
82 #include <Xm/PushB.h>
83 #include <Xm/ToggleB.h>
84 #include <Xm/Separator.h>
85 #include <Xm/RowColumn.h>
86 #include <Xm/MenuShell.h>
88 #ifdef HAVE_DEBUG_H
89 #include "../debug.h"
90 #endif
92 #if XmVersion >= 1002
93 #define MENU_WIDGET(w) (XmGetPostedFromWidget(XtParent(w)))
94 #else
95 #define MENU_WIDGET(w) (w)
96 #endif
98 /* Menu modes for SGI_CUSTOM short-menus feature */
99 enum menuModes {FULL, SHORT};
101 typedef void (*menuCallbackProc)();
103 extern void _XmDismissTearOff(Widget, XtPointer, XtPointer);
105 static void doActionCB(Widget w, XtPointer clientData, XtPointer callData);
106 static void doTabActionCB(Widget w, XtPointer clientData, XtPointer callData);
107 static void pasteColCB(Widget w, XtPointer clientData, XtPointer callData);
108 static void shiftLeftCB(Widget w, XtPointer clientData, XtPointer callData);
109 static void shiftRightCB(Widget w, XtPointer clientData, XtPointer callData);
110 static void findCB(Widget w, XtPointer clientData, XtPointer callData);
111 static void findSameCB(Widget w, XtPointer clientData, XtPointer callData);
112 static void findSelCB(Widget w, XtPointer clientData, XtPointer callData);
113 static void findIncrCB(Widget w, XtPointer clientData, XtPointer callData);
114 static void replaceCB(Widget w, XtPointer clientData, XtPointer callData);
115 static void replaceSameCB(Widget w, XtPointer clientData, XtPointer callData);
116 static void replaceFindSameCB(Widget w, XtPointer clientData, XtPointer callData);
117 static void markCB(Widget w, XtPointer clientData, XtPointer callData);
118 static void gotoMarkCB(Widget w, XtPointer clientData, XtPointer callData);
119 static void gotoMatchingCB(Widget w, XtPointer clientData, XtPointer callData);
120 static void autoIndentOffCB(Widget w, WindowInfo *window, caddr_t callData);
121 static void autoIndentCB(Widget w, WindowInfo *window, caddr_t callData);
122 static void smartIndentCB(Widget w, WindowInfo *window, caddr_t callData);
123 static void preserveCB(Widget w, WindowInfo *window, caddr_t callData);
124 static void autoSaveCB(Widget w, WindowInfo *window, caddr_t callData);
125 static void newlineWrapCB(Widget w, WindowInfo *window, caddr_t callData);
126 static void noWrapCB(Widget w, WindowInfo *window, caddr_t callData);
127 static void continuousWrapCB(Widget w, WindowInfo *window, caddr_t callData);
128 static void wrapMarginCB(Widget w, WindowInfo *window, caddr_t callData);
129 static void fontCB(Widget w, WindowInfo *window, caddr_t callData);
130 static void tabsCB(Widget w, WindowInfo *window, caddr_t callData);
131 static void backlightCharsCB(Widget w, WindowInfo *window, caddr_t callData);
132 static void showMatchingOffCB(Widget w, WindowInfo *window, caddr_t callData);
133 static void showMatchingDelimitCB(Widget w, WindowInfo *window, caddr_t callData);
134 static void showMatchingRangeCB(Widget w, WindowInfo *window, caddr_t callData);
135 static void matchSyntaxBasedCB(Widget w, WindowInfo *window, caddr_t callData);
136 static void statsCB(Widget w, WindowInfo *window, caddr_t callData);
137 static void autoIndentOffDefCB(Widget w, WindowInfo *window, caddr_t callData);
138 static void autoIndentDefCB(Widget w, WindowInfo *window, caddr_t callData);
139 static void smartIndentDefCB(Widget w, WindowInfo *window, caddr_t callData);
140 static void autoSaveDefCB(Widget w, WindowInfo *window, caddr_t callData);
141 static void preserveDefCB(Widget w, WindowInfo *window, caddr_t callData);
142 static void noWrapDefCB(Widget w, WindowInfo *window, caddr_t callData);
143 static void newlineWrapDefCB(Widget w, WindowInfo *window, caddr_t callData);
144 static void contWrapDefCB(Widget w, WindowInfo *window, caddr_t callData);
145 static void wrapMarginDefCB(Widget w, WindowInfo *window, caddr_t callData);
146 static void shellSelDefCB(Widget widget, WindowInfo* window, caddr_t callData);
147 static void openInTabDefCB(Widget w, WindowInfo *window, caddr_t callData);
148 static void tabBarDefCB(Widget w, WindowInfo *window, caddr_t callData);
149 static void tabBarHideDefCB(Widget w, WindowInfo *window, caddr_t callData);
150 static void tabSortDefCB(Widget w, WindowInfo *window, caddr_t callData);
151 static void toolTipsDefCB(Widget w, WindowInfo *window, caddr_t callData);
152 static void tabNavigateDefCB(Widget w, WindowInfo *window, caddr_t callData);
153 static void statsLineDefCB(Widget w, WindowInfo *window, caddr_t callData);
154 static void iSearchLineDefCB(Widget w, WindowInfo *window, caddr_t callData);
155 static void lineNumsDefCB(Widget w, WindowInfo *window, caddr_t callData);
156 static void pathInWindowsMenuDefCB(Widget w, WindowInfo *window, caddr_t callData);
157 static void customizeTitleDefCB(Widget w, WindowInfo *window, caddr_t callData);
158 static void tabsDefCB(Widget w, WindowInfo *window, caddr_t callData);
159 static void showMatchingOffDefCB(Widget w, WindowInfo *window, caddr_t callData);
160 static void showMatchingDelimitDefCB(Widget w, WindowInfo *window, caddr_t callData);
161 static void showMatchingRangeDefCB(Widget w, WindowInfo *window, caddr_t callData);
162 static void matchSyntaxBasedDefCB(Widget w, WindowInfo *window, caddr_t callData);
163 static void highlightOffDefCB(Widget w, WindowInfo *window, caddr_t callData);
164 static void highlightDefCB(Widget w, WindowInfo *window, caddr_t callData);
165 static void backlightCharsDefCB(Widget w, WindowInfo *window, caddr_t callData);
166 static void fontDefCB(Widget w, WindowInfo *window, caddr_t callData);
167 static void colorDefCB(Widget w, WindowInfo *window, caddr_t callData);
168 static void smartTagsDefCB(Widget parent, XtPointer client_data, XtPointer call_data);
169 static void showAllTagsDefCB(Widget parent, XtPointer client_data, XtPointer call_data);
170 static void languageDefCB(Widget w, WindowInfo *window, caddr_t callData);
171 static void highlightingDefCB(Widget w, WindowInfo *window, caddr_t callData);
172 static void smartMacrosDefCB(Widget w, WindowInfo *window, caddr_t callData);
173 static void stylesDefCB(Widget w, WindowInfo *window, caddr_t callData);
174 static void shellDefCB(Widget w, WindowInfo *window, caddr_t callData);
175 static void macroDefCB(Widget w, WindowInfo *window, caddr_t callData);
176 static void bgMenuDefCB(Widget w, WindowInfo *window, caddr_t callData);
177 static void searchDlogsDefCB(Widget w, WindowInfo *window, caddr_t callData);
178 static void beepOnSearchWrapDefCB(Widget w, WindowInfo *window, caddr_t callData);
179 static void keepSearchDlogsDefCB(Widget w, WindowInfo *window,
180 caddr_t callData);
181 static void searchWrapsDefCB(Widget w, WindowInfo *window, caddr_t callData);
182 static void appendLFCB(Widget w, WindowInfo* window, caddr_t callData);
183 static void sortOpenPrevDefCB(Widget w, WindowInfo *window, caddr_t callData);
184 static void reposDlogsDefCB(Widget w, WindowInfo *window, caddr_t callData);
185 static void autoScrollDefCB(Widget w, WindowInfo *window, caddr_t callData);
186 static void modWarnDefCB(Widget w, WindowInfo *window, caddr_t callData);
187 static void modWarnRealDefCB(Widget w, WindowInfo *window, caddr_t callData);
188 static void exitWarnDefCB(Widget w, WindowInfo *window, caddr_t callData);
189 static void searchLiteralCB(Widget w, WindowInfo *window, caddr_t callData);
190 static void searchCaseSenseCB(Widget w, WindowInfo *window, caddr_t callData);
191 static void searchLiteralWordCB(Widget w, WindowInfo *window, caddr_t callData);
192 static void searchCaseSenseWordCB(Widget w, WindowInfo *window, caddr_t callData);
193 static void searchRegexNoCaseCB(Widget w, WindowInfo *window, caddr_t callData);
194 static void searchRegexCB(Widget w, WindowInfo *window, caddr_t callData);
195 #ifdef REPLACE_SCOPE
196 static void replaceScopeWindowCB(Widget w, WindowInfo *window, caddr_t callData);
197 static void replaceScopeSelectionCB(Widget w, WindowInfo *window, caddr_t callData);
198 static void replaceScopeSmartCB(Widget w, WindowInfo *window, caddr_t callData);
199 #endif
200 static void size24x80CB(Widget w, WindowInfo *window, caddr_t callData);
201 static void size40x80CB(Widget w, WindowInfo *window, caddr_t callData);
202 static void size60x80CB(Widget w, WindowInfo *window, caddr_t callData);
203 static void size80x80CB(Widget w, WindowInfo *window, caddr_t callData);
204 static void sizeCustomCB(Widget w, WindowInfo *window, caddr_t callData);
205 static void savePrefCB(Widget w, WindowInfo *window, caddr_t callData);
206 static void formFeedCB(Widget w, XtPointer clientData, XtPointer callData);
207 static void cancelShellCB(Widget w, WindowInfo *window, XtPointer callData);
208 static void learnCB(Widget w, WindowInfo *window, caddr_t callData);
209 static void finishLearnCB(Widget w, WindowInfo *window, caddr_t callData);
210 static void cancelLearnCB(Widget w, WindowInfo *window, caddr_t callData);
211 static void replayCB(Widget w, WindowInfo *window, caddr_t callData);
212 static void windowMenuCB(Widget w, WindowInfo *window, caddr_t callData);
213 static void prevOpenMenuCB(Widget w, WindowInfo *window, caddr_t callData);
214 static void unloadTagsFileMenuCB(Widget w, WindowInfo *window,
215 caddr_t callData);
216 static void unloadTipsFileMenuCB(Widget w, WindowInfo *window,
217 caddr_t callData);
218 static void newAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
219 static void newOppositeAP(Widget w, XEvent *event, String *args,
220 Cardinal *nArgs);
221 static void newTabAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
222 static void openDialogAP(Widget w, XEvent *event, String *args,
223 Cardinal *nArgs);
224 static void openAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
225 static void openSelectedAP(Widget w, XEvent *event, String *args,
226 Cardinal *nArgs);
227 static void closeAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
228 static void saveAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
229 static void saveAsDialogAP(Widget w, XEvent *event, String *args,
230 Cardinal *nArgs);
231 static void saveAsAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
232 static void revertDialogAP(Widget w, XEvent *event, String *args,
233 Cardinal *nArgs);
234 static void revertAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
235 static void includeDialogAP(Widget w, XEvent *event, String *args,
236 Cardinal *nArgs);
237 static void includeAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
238 static void loadMacroDialogAP(Widget w, XEvent *event, String *args,
239 Cardinal *nArgs) ;
240 static void loadMacroAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
241 static void loadTagsDialogAP(Widget w, XEvent *event, String *args,
242 Cardinal *nArgs);
243 static void loadTagsAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
244 static void unloadTagsAP(Widget w, XEvent *event, String *args,
245 Cardinal *nArgs);
246 static void loadTipsDialogAP(Widget w, XEvent *event, String *args,
247 Cardinal *nArgs);
248 static void loadTipsAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
249 static void unloadTipsAP(Widget w, XEvent *event, String *args,
250 Cardinal *nArgs);
251 static void printAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
252 static void printSelAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
253 static void exitAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
254 static void undoAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
255 static void redoAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
256 static void clearAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
257 static void selAllAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
258 static void shiftLeftAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
259 static void shiftLeftTabAP(Widget w, XEvent *event, String *args,
260 Cardinal *nArgs);
261 static void shiftRightAP(Widget w, XEvent *event, String *args,
262 Cardinal *nArgs);
263 static void shiftRightTabAP(Widget w, XEvent *event, String *args,
264 Cardinal *nArgs);
265 static void findDialogAP(Widget w, XEvent *event, String *args,
266 Cardinal *nArgs);
267 static void findAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
268 static void findSameAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
269 static void findSelAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
270 static void findIncrAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
271 static void startIncrFindAP(Widget w, XEvent *event, String *args,
272 Cardinal *nArgs);
273 static void replaceDialogAP(Widget w, XEvent *event, String *args,
274 Cardinal *nArgs);
275 static void replaceAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
276 static void replaceAllAP(Widget w, XEvent *event, String *args,
277 Cardinal *nArgs);
278 static void replaceInSelAP(Widget w, XEvent *event, String *args,
279 Cardinal *nArgs);
280 static void replaceSameAP(Widget w, XEvent *event, String *args,
281 Cardinal *nArgs);
282 static void replaceFindAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
283 static void replaceFindSameAP(Widget w, XEvent *event, String *args,
284 Cardinal *nArgs);
285 static void gotoAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
286 static void gotoDialogAP(Widget w, XEvent *event, String *args,
287 Cardinal *nArgs);
288 static void gotoSelectedAP(Widget w, XEvent *event, String *args,
289 Cardinal *nArgs);
290 static void repeatDialogAP(Widget w, XEvent *event, String *args,
291 Cardinal *nArgs);
292 static void repeatMacroAP(Widget w, XEvent *event, String *args,
293 Cardinal *nArgs);
294 static void markAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
295 static void markDialogAP(Widget w, XEvent *event, String *args,
296 Cardinal *nArgs);
297 static void gotoMarkAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
298 static void gotoMarkDialogAP(Widget w, XEvent *event, String *args,
299 Cardinal *nArgs);
300 static void selectToMatchingAP(Widget w, XEvent *event, String *args,
301 Cardinal *nArgs);
302 static void gotoMatchingAP(Widget w, XEvent *event, String *args,
303 Cardinal *nArgs);
304 static void findDefAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
305 static void showTipAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
306 static void splitPaneAP(Widget w, XEvent *event, String *args,
307 Cardinal *nArgs);
308 static void detachDocumentDialogAP(Widget w, XEvent *event, String *args,
309 Cardinal *nArgs);
310 static void detachDocumentAP(Widget w, XEvent *event, String *args,
311 Cardinal *nArgs);
312 static void moveDocumentDialogAP(Widget w, XEvent *event, String *args,
313 Cardinal *nArgs);
314 static void nextDocumentAP(Widget w, XEvent *event, String *args,
315 Cardinal *nArgs);
316 static void prevDocumentAP(Widget w, XEvent *event, String *args,
317 Cardinal *nArgs);
318 static void lastDocumentAP(Widget w, XEvent *event, String *args,
319 Cardinal *nArgs);
320 static void closePaneAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
321 static void capitalizeAP(Widget w, XEvent *event, String *args,
322 Cardinal *nArgs);
323 static void lowercaseAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
324 static void fillAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
325 static void controlDialogAP(Widget w, XEvent *event, String *args,
326 Cardinal *nArgs);
327 #ifndef VMS
328 static void filterDialogAP(Widget w, XEvent *event, String *args,
329 Cardinal *nArgs);
330 static void shellFilterAP(Widget w, XEvent *event, String *args,
331 Cardinal *nArgs);
332 static void execDialogAP(Widget w, XEvent *event, String *args,
333 Cardinal *nArgs);
334 static void execAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
335 static void execLineAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
336 static void shellMenuAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
337 #endif
338 static void macroMenuAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
339 static void bgMenuAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
340 static void beginningOfSelectionAP(Widget w, XEvent *event, String *args,
341 Cardinal *nArgs);
342 static void endOfSelectionAP(Widget w, XEvent *event, String *args,
343 Cardinal *nArgs);
344 static Widget createMenu(Widget parent, char *name, char *label,
345 char mnemonic, Widget *cascadeBtn, int mode);
346 static Widget createMenuItem(Widget parent, char *name, char *label,
347 char mnemonic, menuCallbackProc callback, void *cbArg, int mode);
348 static Widget createFakeMenuItem(Widget parent, char *name,
349 menuCallbackProc callback, void *cbArg);
350 static Widget createMenuToggle(Widget parent, char *name, char *label,
351 char mnemonic, menuCallbackProc callback, void *cbArg, int set,
352 int mode);
353 static Widget createMenuRadioToggle(Widget parent, char *name, char *label,
354 char mnemonic, menuCallbackProc callback, void *cbArg, int set,
355 int mode);
356 static Widget createMenuSeparator(Widget parent, char *name, int mode);
357 static void invalidatePrevOpenMenus(void);
358 static void updateWindowMenu(const WindowInfo *window);
359 static void updatePrevOpenMenu(WindowInfo *window);
360 static void updateTagsFileMenu(WindowInfo *window);
361 static void updateTipsFileMenu(WindowInfo *window);
362 static int searchDirection(int ignoreArgs, String *args, Cardinal *nArgs);
363 static int searchWrap(int ignoreArgs, String *args, Cardinal *nArgs);
364 static int searchKeepDialogs(int ignoreArgs, String *args, Cardinal *nArgs);
365 static int searchType(int ignoreArgs, String *args, Cardinal *nArgs);
366 static char **shiftKeyToDir(XtPointer callData);
367 static void raiseCB(Widget w, WindowInfo *window, caddr_t callData);
368 static void openPrevCB(Widget w, char *name, caddr_t callData);
369 static void unloadTagsFileCB(Widget w, char *name, caddr_t callData);
370 static void unloadTipsFileCB(Widget w, char *name, caddr_t callData);
371 static int cmpStrPtr(const void *strA, const void *strB);
372 static void setWindowSizeDefault(int rows, int cols);
373 static void updateWindowSizeMenus(void);
374 static void updateWindowSizeMenu(WindowInfo *win);
375 static int strCaseCmp(const char *str1, const char *str2);
376 static int compareWindowNames(const void *windowA, const void *windowB);
377 static int compareWindowShell(const void *windowA, const void *windowB);
378 static void bgMenuPostAP(Widget w, XEvent *event, String *args,
379 Cardinal *nArgs);
380 static void tabMenuPostAP(Widget w, XEvent *event, String *args,
381 Cardinal *nArgs);
382 static void raiseWindowAP(Widget w, XEvent *event, String *args,
383 Cardinal *nArgs);
384 static void focusPaneAP(Widget w, XEvent *event, String *args,
385 Cardinal *nArgs);
386 static void setStatisticsLineAP(Widget w, XEvent *event, String *args,
387 Cardinal *nArgs);
388 static void setIncrementalSearchLineAP(Widget w, XEvent *event, String *args,
389 Cardinal *nArgs);
390 static void setShowLineNumbersAP(Widget w, XEvent *event, String *args,
391 Cardinal *nArgs);
392 static void setAutoIndentAP(Widget w, XEvent *event, String *args,
393 Cardinal *nArgs);
394 static void setWrapTextAP(Widget w, XEvent *event, String *args,
395 Cardinal *nArgs);
396 static void setWrapMarginAP(Widget w, XEvent *event, String *args,
397 Cardinal *nArgs);
398 static void setHighlightSyntaxAP(Widget w, XEvent *event, String *args,
399 Cardinal *nArgs);
400 static void setMakeBackupCopyAP(Widget w, XEvent *event, String *args,
401 Cardinal *nArgs);
402 static void setIncrementalBackupAP(Widget w, XEvent *event, String *args,
403 Cardinal *nArgs);
404 static void setShowMatchingAP(Widget w, XEvent *event, String *args,
405 Cardinal *nArgs);
406 static void setMatchSyntaxBasedAP(Widget w, XEvent *event, String *args,
407 Cardinal *nArgs);
408 static void setOvertypeModeAP(Widget w, XEvent *event, String *args,
409 Cardinal *nArgs);
410 static void setLockedAP(Widget w, XEvent *event, String *args,
411 Cardinal *nArgs);
412 static void setUseTabsAP(Widget w, XEvent *event, String *args,
413 Cardinal *nArgs);
414 static void setEmTabDistAP(Widget w, XEvent *event, String *args,
415 Cardinal *nArgs);
416 static void setTabDistAP(Widget w, XEvent *event, String *args,
417 Cardinal *nArgs);
418 static void setFontsAP(Widget w, XEvent *event, String *args,
419 Cardinal *nArgs);
420 static void setLanguageModeAP(Widget w, XEvent *event, String *args,
421 Cardinal *nArgs);
422 #ifdef SGI_CUSTOM
423 static void shortMenusCB(Widget w, WindowInfo *window, caddr_t callData);
424 static void addToToggleShortList(Widget w);
425 static int shortPrefAskDefault(Widget parent, Widget w, const char *settingName);
426 #endif
428 static HelpMenu * buildHelpMenu( Widget pane, HelpMenu * menu,
429 WindowInfo * window);
431 /* Application action table */
432 static XtActionsRec Actions[] = {
433 {"new", newAP},
434 {"new_opposite", newOppositeAP},
435 {"new_tab", newTabAP},
436 {"open", openAP},
437 {"open-dialog", openDialogAP},
438 {"open_dialog", openDialogAP},
439 {"open-selected", openSelectedAP},
440 {"open_selected", openSelectedAP},
441 {"close", closeAP},
442 {"save", saveAP},
443 {"save-as", saveAsAP},
444 {"save_as", saveAsAP},
445 {"save-as-dialog", saveAsDialogAP},
446 {"save_as_dialog", saveAsDialogAP},
447 {"revert-to-saved", revertAP},
448 {"revert_to_saved", revertAP},
449 {"revert_to_saved_dialog", revertDialogAP},
450 {"include-file", includeAP},
451 {"include_file", includeAP},
452 {"include-file-dialog", includeDialogAP},
453 {"include_file_dialog", includeDialogAP},
454 {"load-macro-file", loadMacroAP},
455 {"load_macro_file", loadMacroAP},
456 {"load-macro-file-dialog", loadMacroDialogAP},
457 {"load_macro_file_dialog", loadMacroDialogAP},
458 {"load-tags-file", loadTagsAP},
459 {"load_tags_file", loadTagsAP},
460 {"load-tags-file-dialog", loadTagsDialogAP},
461 {"load_tags_file_dialog", loadTagsDialogAP},
462 {"unload_tags_file", unloadTagsAP},
463 {"load_tips_file", loadTipsAP},
464 {"load_tips_file_dialog", loadTipsDialogAP},
465 {"unload_tips_file", unloadTipsAP},
466 {"print", printAP},
467 {"print-selection", printSelAP},
468 {"print_selection", printSelAP},
469 {"exit", exitAP},
470 {"undo", undoAP},
471 {"redo", redoAP},
472 {"delete", clearAP},
473 {"select-all", selAllAP},
474 {"select_all", selAllAP},
475 {"shift-left", shiftLeftAP},
476 {"shift_left", shiftLeftAP},
477 {"shift-left-by-tab", shiftLeftTabAP},
478 {"shift_left_by_tab", shiftLeftTabAP},
479 {"shift-right", shiftRightAP},
480 {"shift_right", shiftRightAP},
481 {"shift-right-by-tab", shiftRightTabAP},
482 {"shift_right_by_tab", shiftRightTabAP},
483 {"find", findAP},
484 {"find-dialog", findDialogAP},
485 {"find_dialog", findDialogAP},
486 {"find-again", findSameAP},
487 {"find_again", findSameAP},
488 {"find-selection", findSelAP},
489 {"find_selection", findSelAP},
490 {"find_incremental", findIncrAP},
491 {"start_incremental_find", startIncrFindAP},
492 {"replace", replaceAP},
493 {"replace-dialog", replaceDialogAP},
494 {"replace_dialog", replaceDialogAP},
495 {"replace-all", replaceAllAP},
496 {"replace_all", replaceAllAP},
497 {"replace-in-selection", replaceInSelAP},
498 {"replace_in_selection", replaceInSelAP},
499 {"replace-again", replaceSameAP},
500 {"replace_again", replaceSameAP},
501 {"replace_find", replaceFindAP},
502 {"replace_find_same", replaceFindSameAP},
503 {"replace_find_again", replaceFindSameAP},
504 {"goto-line-number", gotoAP},
505 {"goto_line_number", gotoAP},
506 {"goto-line-number-dialog", gotoDialogAP},
507 {"goto_line_number_dialog", gotoDialogAP},
508 {"goto-selected", gotoSelectedAP},
509 {"goto_selected", gotoSelectedAP},
510 {"mark", markAP},
511 {"mark-dialog", markDialogAP},
512 {"mark_dialog", markDialogAP},
513 {"goto-mark", gotoMarkAP},
514 {"goto_mark", gotoMarkAP},
515 {"goto-mark-dialog", gotoMarkDialogAP},
516 {"goto_mark_dialog", gotoMarkDialogAP},
517 {"match", selectToMatchingAP},
518 {"select_to_matching", selectToMatchingAP},
519 {"goto_matching", gotoMatchingAP},
520 {"find-definition", findDefAP},
521 {"find_definition", findDefAP},
522 {"show_tip", showTipAP},
523 {"split-pane", splitPaneAP},
524 {"split_pane", splitPaneAP},
525 {"close-pane", closePaneAP},
526 {"close_pane", closePaneAP},
527 {"detach_document", detachDocumentAP},
528 {"detach_document_dialog", detachDocumentDialogAP},
529 {"move_document_dialog", moveDocumentDialogAP},
530 {"next_document", nextDocumentAP},
531 {"previous_document", prevDocumentAP},
532 {"last_document", lastDocumentAP},
533 {"uppercase", capitalizeAP},
534 {"lowercase", lowercaseAP},
535 {"fill-paragraph", fillAP},
536 {"fill_paragraph", fillAP},
537 {"control-code-dialog", controlDialogAP},
538 {"control_code_dialog", controlDialogAP},
539 #ifndef VMS
540 {"filter-selection-dialog", filterDialogAP},
541 {"filter_selection_dialog", filterDialogAP},
542 {"filter-selection", shellFilterAP},
543 {"filter_selection", shellFilterAP},
544 {"execute-command", execAP},
545 {"execute_command", execAP},
546 {"execute-command-dialog", execDialogAP},
547 {"execute_command_dialog", execDialogAP},
548 {"execute-command-line", execLineAP},
549 {"execute_command_line", execLineAP},
550 {"shell-menu-command", shellMenuAP},
551 {"shell_menu_command", shellMenuAP},
552 #endif /*VMS*/
553 {"macro-menu-command", macroMenuAP},
554 {"macro_menu_command", macroMenuAP},
555 {"bg_menu_command", bgMenuAP},
556 {"post_window_bg_menu", bgMenuPostAP},
557 {"post_tab_context_menu", tabMenuPostAP},
558 {"beginning-of-selection", beginningOfSelectionAP},
559 {"beginning_of_selection", beginningOfSelectionAP},
560 {"end-of-selection", endOfSelectionAP},
561 {"end_of_selection", endOfSelectionAP},
562 {"repeat_macro", repeatMacroAP},
563 {"repeat_dialog", repeatDialogAP},
564 {"raise_window", raiseWindowAP},
565 {"focus_pane", focusPaneAP},
566 {"set_statistics_line", setStatisticsLineAP},
567 {"set_incremental_search_line", setIncrementalSearchLineAP},
568 {"set_show_line_numbers", setShowLineNumbersAP},
569 {"set_auto_indent", setAutoIndentAP},
570 {"set_wrap_text", setWrapTextAP},
571 {"set_wrap_margin", setWrapMarginAP},
572 {"set_highlight_syntax", setHighlightSyntaxAP},
573 #ifndef VMS
574 {"set_make_backup_copy", setMakeBackupCopyAP},
575 #endif
576 {"set_incremental_backup", setIncrementalBackupAP},
577 {"set_show_matching", setShowMatchingAP},
578 {"set_match_syntax_based", setMatchSyntaxBasedAP},
579 {"set_overtype_mode", setOvertypeModeAP},
580 {"set_locked", setLockedAP},
581 {"set_tab_dist", setTabDistAP},
582 {"set_em_tab_dist", setEmTabDistAP},
583 {"set_use_tabs", setUseTabsAP},
584 {"set_fonts", setFontsAP},
585 {"set_language_mode", setLanguageModeAP}
588 /* List of previously opened files for File menu */
589 static int NPrevOpen = 0;
590 static char** PrevOpen = NULL;
592 #ifdef SGI_CUSTOM
593 /* Window to receive items to be toggled on and off in short menus mode */
594 static WindowInfo *ShortMenuWindow;
595 #endif
597 void HidePointerOnKeyedEvent(Widget w, XEvent *event)
599 if (event && (event->type == KeyPress || event->type == KeyRelease)) {
600 ShowHidePointer((TextWidget)w, True);
605 ** Install actions for use in translation tables and macro recording, relating
606 ** to menu item commands
608 void InstallMenuActions(XtAppContext context)
610 XtAppAddActions(context, Actions, XtNumber(Actions));
614 ** Return the (statically allocated) action table for menu item actions.
616 XtActionsRec *GetMenuActions(int *nActions)
618 *nActions = XtNumber(Actions);
619 return Actions;
623 ** Create the menu bar
625 Widget CreateMenuBar(Widget parent, WindowInfo *window)
627 Widget menuBar, menuPane, btn, subPane, subSubPane, subSubSubPane, cascade;
630 ** cache user menus:
631 ** allocate user menu cache
633 window->userMenuCache = CreateUserMenuCache();
636 ** Create the menu bar (row column) widget
638 menuBar = XmCreateMenuBar(parent, "menuBar", NULL, 0);
640 #ifdef SGI_CUSTOM
642 ** Short menu mode is a special feature for the SGI system distribution
643 ** version of NEdit.
645 ** To make toggling short-menus mode faster (re-creating the menus was
646 ** too slow), a list is kept in the window data structure of items to
647 ** be turned on and off. Initialize that list and give the menu creation
648 ** routines a pointer to the window on which this list is kept. This is
649 ** (unfortunately) a global variable to keep the interface simple for
650 ** the mainstream case.
652 ShortMenuWindow = window;
653 window->nToggleShortItems = 0;
654 #endif
657 ** "File" pull down menu.
659 menuPane = createMenu(menuBar, "fileMenu", "File", 0, NULL, SHORT);
660 createMenuItem(menuPane, "new", "New", 'N', doActionCB, "new", SHORT);
661 if ( GetPrefOpenInTab() )
662 window->newOppositeItem = createMenuItem(menuPane, "newOpposite",
663 "New Window", 'W', doActionCB, "new_opposite", SHORT);
664 else
665 window->newOppositeItem = createMenuItem(menuPane, "newOpposite",
666 "New Tab", 'T', doActionCB, "new_opposite", SHORT);
667 createMenuItem(menuPane, "open", "Open...", 'O', doActionCB, "open_dialog",
668 SHORT);
669 window->openSelItem=createMenuItem(menuPane, "openSelected", "Open Selected", 'd',
670 doActionCB, "open_selected", FULL);
671 if (GetPrefMaxPrevOpenFiles() > 0) {
672 window->prevOpenMenuPane = createMenu(menuPane, "openPrevious",
673 "Open Previous", 'v', &window->prevOpenMenuItem, SHORT);
674 XtSetSensitive(window->prevOpenMenuItem, NPrevOpen != 0);
675 XtAddCallback(window->prevOpenMenuItem, XmNcascadingCallback,
676 (XtCallbackProc)prevOpenMenuCB, window);
678 createMenuSeparator(menuPane, "sep1", SHORT);
679 window->closeItem = createMenuItem(menuPane, "close", "Close", 'C',
680 doActionCB, "close", SHORT);
681 createMenuItem(menuPane, "save", "Save", 'S', doActionCB, "save", SHORT);
682 createMenuItem(menuPane, "saveAs", "Save As...", 'A', doActionCB,
683 "save_as_dialog", SHORT);
684 createMenuItem(menuPane, "revertToSaved", "Revert to Saved", 'R',
685 doActionCB, "revert_to_saved_dialog", SHORT);
686 createMenuSeparator(menuPane, "sep2", SHORT);
687 createMenuItem(menuPane, "includeFile", "Include File...", 'I',
688 doActionCB, "include_file_dialog", SHORT);
689 createMenuItem(menuPane, "loadMacroFile", "Load Macro File...", 'M',
690 doActionCB, "load_macro_file_dialog", FULL);
691 createMenuItem(menuPane, "loadTagsFile", "Load Tags File...", 'g',
692 doActionCB, "load_tags_file_dialog", FULL);
693 window->unloadTagsMenuPane = createMenu(menuPane, "unloadTagsFiles",
694 "Unload Tags File", 'U', &window->unloadTagsMenuItem, FULL);
695 XtSetSensitive(window->unloadTagsMenuItem, TagsFileList != NULL);
696 XtAddCallback(window->unloadTagsMenuItem, XmNcascadingCallback,
697 (XtCallbackProc)unloadTagsFileMenuCB, window);
698 createMenuItem(menuPane, "loadTipsFile", "Load Calltips File...", 'F',
699 doActionCB, "load_tips_file_dialog", FULL);
700 window->unloadTipsMenuPane = createMenu(menuPane, "unloadTipsFiles",
701 "Unload Calltips File", 'e', &window->unloadTipsMenuItem, FULL);
702 XtSetSensitive(window->unloadTipsMenuItem, TipsFileList != NULL);
703 XtAddCallback(window->unloadTipsMenuItem, XmNcascadingCallback,
704 (XtCallbackProc)unloadTipsFileMenuCB, window);
705 createMenuSeparator(menuPane, "sep3", SHORT);
706 createMenuItem(menuPane, "print", "Print...", 'P', doActionCB, "print",
707 SHORT);
708 window->printSelItem = createMenuItem(menuPane, "printSelection",
709 "Print Selection...", 'l', doActionCB, "print_selection",
710 SHORT);
711 XtSetSensitive(window->printSelItem, window->wasSelected);
712 createMenuSeparator(menuPane, "sep4", SHORT);
713 createMenuItem(menuPane, "exit", "Exit", 'x', doActionCB, "exit", SHORT);
714 CheckCloseDim();
717 ** "Edit" pull down menu.
719 menuPane = createMenu(menuBar, "editMenu", "Edit", 0, NULL, SHORT);
720 window->undoItem = createMenuItem(menuPane, "undo", "Undo", 'U',
721 doActionCB, "undo", SHORT);
722 XtSetSensitive(window->undoItem, False);
723 window->redoItem = createMenuItem(menuPane, "redo", "Redo", 'R',
724 doActionCB, "redo", SHORT);
725 XtSetSensitive(window->redoItem, False);
726 createMenuSeparator(menuPane, "sep1", SHORT);
727 window->cutItem = createMenuItem(menuPane, "cut", "Cut", 't', doActionCB,
728 "cut_clipboard", SHORT);
729 XtSetSensitive(window->cutItem, window->wasSelected);
730 window->copyItem = createMenuItem(menuPane, "copy", "Copy", 'C', doActionCB,
731 "copy_clipboard", SHORT);
732 XtSetSensitive(window->copyItem, window->wasSelected);
733 createMenuItem(menuPane, "paste", "Paste", 'P', doActionCB,
734 "paste_clipboard", SHORT);
735 createMenuItem(menuPane, "pasteColumn", "Paste Column", 's', pasteColCB,
736 window, SHORT);
737 window->delItem=createMenuItem(menuPane, "delete", "Delete", 'D', doActionCB, "delete_selection",
738 SHORT);
739 XtSetSensitive(window->delItem, window->wasSelected);
740 createMenuItem(menuPane, "selectAll", "Select All", 'A', doActionCB,
741 "select_all", SHORT);
742 createMenuSeparator(menuPane, "sep2", SHORT);
743 createMenuItem(menuPane, "shiftLeft", "Shift Left", 'L',
744 shiftLeftCB, window, SHORT);
745 createFakeMenuItem(menuPane, "shiftLeftShift", shiftLeftCB, window);
746 createMenuItem(menuPane, "shiftRight", "Shift Right", 'g',
747 shiftRightCB, window, SHORT);
748 createFakeMenuItem(menuPane, "shiftRightShift", shiftRightCB, window);
749 window->lowerItem=createMenuItem(menuPane, "lowerCase", "Lower-case", 'w',
750 doActionCB, "lowercase", SHORT);
751 window->upperItem=createMenuItem(menuPane, "upperCase", "Upper-case", 'e',
752 doActionCB, "uppercase", SHORT);
753 createMenuItem(menuPane, "fillParagraph", "Fill Paragraph", 'F',
754 doActionCB, "fill_paragraph", SHORT);
755 createMenuSeparator(menuPane, "sep3", FULL);
756 createMenuItem(menuPane, "insertFormFeed", "Insert Form Feed", 'I',
757 formFeedCB, window, FULL);
758 createMenuItem(menuPane, "insertCtrlCode", "Insert Ctrl Code...", 'n',
759 doActionCB, "control_code_dialog", FULL);
760 #ifdef SGI_CUSTOM
761 createMenuSeparator(menuPane, "sep4", SHORT);
762 window->overtypeModeItem = createMenuToggle(menuPane, "overtype", "Overtype", 'O',
763 doActionCB, "set_overtype_mode", False, SHORT);
764 window->readOnlyItem = createMenuToggle(menuPane, "readOnly", "Read Only",
765 'y', doActionCB, "set_locked", IS_USER_LOCKED(window->lockReasons), FULL);
766 #endif
769 ** "Search" pull down menu.
771 menuPane = createMenu(menuBar, "searchMenu", "Search", 0, NULL, SHORT);
772 createMenuItem(menuPane, "find", "Find...", 'F', findCB, window, SHORT);
773 createFakeMenuItem(menuPane, "findShift", findCB, window);
774 window->findAgainItem=createMenuItem(menuPane, "findAgain", "Find Again", 'i', findSameCB, window,
775 SHORT);
776 XtSetSensitive(window->findAgainItem, NHist);
777 createFakeMenuItem(menuPane, "findAgainShift", findSameCB, window);
778 window->findSelItem=createMenuItem(menuPane, "findSelection", "Find Selection", 'S',
779 findSelCB, window, SHORT);
780 createFakeMenuItem(menuPane, "findSelectionShift", findSelCB, window);
781 createMenuItem(menuPane, "findIncremental", "Find Incremental", 'n',
782 findIncrCB, window, SHORT);
783 createFakeMenuItem(menuPane, "findIncrementalShift", findIncrCB, window);
784 createMenuItem(menuPane, "replace", "Replace...", 'R', replaceCB, window,
785 SHORT);
786 createFakeMenuItem(menuPane, "replaceShift", replaceCB, window);
787 window->replaceFindAgainItem=createMenuItem(menuPane, "replaceFindAgain", "Replace Find Again", 'A',
788 replaceFindSameCB, window, SHORT);
789 XtSetSensitive(window->replaceFindAgainItem, NHist);
790 createFakeMenuItem(menuPane, "replaceFindAgainShift", replaceFindSameCB, window);
791 window->replaceAgainItem=createMenuItem(menuPane, "replaceAgain", "Replace Again", 'p',
792 replaceSameCB, window, SHORT);
793 XtSetSensitive(window->replaceAgainItem, NHist);
794 createFakeMenuItem(menuPane, "replaceAgainShift", replaceSameCB, window);
795 createMenuSeparator(menuPane, "sep1", FULL);
796 createMenuItem(menuPane, "gotoLineNumber", "Goto Line Number...", 'L',
797 doActionCB, "goto_line_number_dialog", FULL);
798 window->gotoSelItem=createMenuItem(menuPane, "gotoSelected", "Goto Selected", 'G',
799 doActionCB, "goto_selected", FULL);
800 createMenuSeparator(menuPane, "sep2", FULL);
801 createMenuItem(menuPane, "mark", "Mark", 'k', markCB, window, FULL);
802 createMenuItem(menuPane, "gotoMark", "Goto Mark", 'o', gotoMarkCB, window,
803 FULL);
804 createFakeMenuItem(menuPane, "gotoMarkShift", gotoMarkCB, window);
805 createMenuSeparator(menuPane, "sep3", FULL);
806 createMenuItem(menuPane, "gotoMatching", "Goto Matching (..)", 'M',
807 gotoMatchingCB, window, FULL);
808 createFakeMenuItem(menuPane, "gotoMatchingShift", gotoMatchingCB, window);
809 window->findDefItem = createMenuItem(menuPane, "findDefinition",
810 "Find Definition", 'D', doActionCB, "find_definition", FULL);
811 XtSetSensitive(window->findDefItem, TagsFileList != NULL);
812 window->showTipItem = createMenuItem(menuPane, "showCalltip",
813 "Show Calltip", 'C', doActionCB, "show_tip", FULL);
814 XtSetSensitive(window->showTipItem, (TagsFileList != NULL ||
815 TipsFileList != NULL) );
818 ** Preferences menu, Default Settings sub menu
820 menuPane = createMenu(menuBar, "preferencesMenu", "Preferences", 0, NULL,
821 SHORT);
822 subPane = createMenu(menuPane, "defaultSettings", "Default Settings", 'D',
823 NULL, FULL);
824 createMenuItem(subPane, "languageModes", "Language Modes...", 'L',
825 languageDefCB, window, FULL);
827 /* Auto Indent sub menu */
828 subSubPane = createMenu(subPane, "autoIndent", "Auto Indent", 'A',
829 NULL, FULL);
830 window->autoIndentOffDefItem = createMenuRadioToggle(subSubPane, "off",
831 "Off", 'O', autoIndentOffDefCB, window,
832 GetPrefAutoIndent(PLAIN_LANGUAGE_MODE) == NO_AUTO_INDENT, SHORT);
833 window->autoIndentDefItem = createMenuRadioToggle(subSubPane, "on",
834 "On", 'n', autoIndentDefCB, window,
835 GetPrefAutoIndent(PLAIN_LANGUAGE_MODE) == AUTO_INDENT, SHORT);
836 window->smartIndentDefItem = createMenuRadioToggle(subSubPane, "smart",
837 "Smart", 'S', smartIndentDefCB, window,
838 GetPrefAutoIndent(PLAIN_LANGUAGE_MODE) == SMART_INDENT, SHORT);
839 createMenuSeparator(subSubPane, "sep1", SHORT);
840 createMenuItem(subSubPane, "ProgramSmartIndent", "Program Smart Indent...",
841 'P', smartMacrosDefCB, window, FULL);
843 /* Wrap sub menu */
844 subSubPane = createMenu(subPane, "wrap", "Wrap", 'W', NULL, FULL);
845 window->noWrapDefItem = createMenuRadioToggle(subSubPane,
846 "none", "None", 'N', noWrapDefCB,
847 window, GetPrefWrap(PLAIN_LANGUAGE_MODE) == NO_WRAP, SHORT);
848 window->newlineWrapDefItem = createMenuRadioToggle(subSubPane,
849 "autoNewline", "Auto Newline", 'A', newlineWrapDefCB,
850 window, GetPrefWrap(PLAIN_LANGUAGE_MODE) == NEWLINE_WRAP, SHORT);
851 window->contWrapDefItem = createMenuRadioToggle(subSubPane, "continuous",
852 "Continuous", 'C', contWrapDefCB, window,
853 GetPrefWrap(PLAIN_LANGUAGE_MODE) == CONTINUOUS_WRAP, SHORT);
854 createMenuSeparator(subSubPane, "sep1", SHORT);
855 createMenuItem(subSubPane, "wrapMargin", "Wrap Margin...", 'W',
856 wrapMarginDefCB, window, SHORT);
858 /* Smart Tags sub menu */
859 subSubPane = createMenu(subPane, "smartTags", "Tag Collisions", 'l',
860 NULL, FULL);
861 window->allTagsDefItem = createMenuRadioToggle(subSubPane, "showall",
862 "Show All", 'A', showAllTagsDefCB, window, !GetPrefSmartTags(),
863 FULL);
864 window->smartTagsDefItem = createMenuRadioToggle(subSubPane, "smart",
865 "Smart", 'S', smartTagsDefCB, window, GetPrefSmartTags(), FULL);
867 createMenuItem(subPane, "shellSel", "Command Shell...", 's', shellSelDefCB,
868 window, SHORT);
869 createMenuItem(subPane, "tabDistance", "Tab Stops...", 'T', tabsDefCB, window,
870 SHORT);
871 createMenuItem(subPane, "textFont", "Text Fonts...", 'F', fontDefCB, window,
872 FULL);
873 createMenuItem(subPane, "colors", "Colors...", 'C', colorDefCB, window,
874 FULL);
876 /* Customize Menus sub menu */
877 subSubPane = createMenu(subPane, "customizeMenus", "Customize Menus",
878 'u', NULL, FULL);
879 #ifndef VMS
880 createMenuItem(subSubPane, "shellMenu", "Shell Menu...", 'S',
881 shellDefCB, window, FULL);
882 #endif
883 createMenuItem(subSubPane, "macroMenu", "Macro Menu...", 'M',
884 macroDefCB, window, FULL);
885 createMenuItem(subSubPane, "windowBackgroundMenu",
886 "Window Background Menu...", 'W', bgMenuDefCB, window, FULL);
887 createMenuSeparator(subSubPane, "sep1", SHORT);
888 window->sortOpenPrevDefItem = createMenuToggle(subSubPane, "sortOpenPrevMenu",
889 "Sort Open Prev. Menu", 'o', sortOpenPrevDefCB, window,
890 GetPrefSortOpenPrevMenu(), FULL);
891 window->pathInWindowsMenuDefItem = createMenuToggle(subSubPane, "pathInWindowsMenu",
892 "Show Path In Windows Menu", 'P', pathInWindowsMenuDefCB, window, GetPrefShowPathInWindowsMenu(),
893 SHORT);
895 createMenuItem(subPane, "custimizeTitle", "Customize Window Title...", 'd',
896 customizeTitleDefCB, window, FULL);
898 /* Search sub menu */
899 subSubPane = createMenu(subPane, "searching", "Searching",
900 'g', NULL, FULL);
901 window->searchDlogsDefItem = createMenuToggle(subSubPane, "verbose",
902 "Verbose", 'V', searchDlogsDefCB, window,
903 GetPrefSearchDlogs(), SHORT);
904 window->searchWrapsDefItem = createMenuToggle(subSubPane, "wrapAround",
905 "Wrap Around", 'W', searchWrapsDefCB, window,
906 GetPrefSearchWraps(), SHORT);
907 window->beepOnSearchWrapDefItem = createMenuToggle(subSubPane,
908 "beepOnSearchWrap", "Beep On Search Wrap", 'B',
909 beepOnSearchWrapDefCB, window, GetPrefBeepOnSearchWrap(), SHORT);
910 window->keepSearchDlogsDefItem = createMenuToggle(subSubPane,
911 "keepDialogsUp", "Keep Dialogs Up", 'K',
912 keepSearchDlogsDefCB, window, GetPrefKeepSearchDlogs(), SHORT);
913 subSubSubPane = createMenu(subSubPane, "defaultSearchStyle",
914 "Default Search Style", 'D', NULL, FULL);
915 XtVaSetValues(subSubSubPane, XmNradioBehavior, True, NULL);
916 window->searchLiteralDefItem = createMenuToggle(subSubSubPane, "literal",
917 "Literal", 'L', searchLiteralCB, window,
918 GetPrefSearch() == SEARCH_LITERAL, FULL);
919 window->searchCaseSenseDefItem = createMenuToggle(subSubSubPane,
920 "caseSensitive", "Literal, Case Sensitive", 'C', searchCaseSenseCB, window,
921 GetPrefSearch() == SEARCH_CASE_SENSE, FULL);
922 window->searchLiteralWordDefItem = createMenuToggle(subSubSubPane, "literalWord",
923 "Literal, Whole Word", 'W', searchLiteralWordCB, window,
924 GetPrefSearch() == SEARCH_LITERAL_WORD, FULL);
925 window->searchCaseSenseWordDefItem = createMenuToggle(subSubSubPane,
926 "caseSensitiveWord", "Literal, Case Sensitive, Whole Word", 't', searchCaseSenseWordCB, window,
927 GetPrefSearch() == SEARCH_CASE_SENSE_WORD, FULL);
928 window->searchRegexDefItem = createMenuToggle(subSubSubPane,
929 "regularExpression", "Regular Expression", 'R', searchRegexCB,
930 window, GetPrefSearch() == SEARCH_REGEX, FULL);
931 window->searchRegexNoCaseDefItem = createMenuToggle(subSubSubPane,
932 "regularExpressionNoCase", "Regular Expression, Case Insensitive", 'I', searchRegexNoCaseCB, window,
933 GetPrefSearch() == SEARCH_REGEX_NOCASE, FULL);
934 #ifdef REPLACE_SCOPE
935 subSubSubPane = createMenu(subSubPane, "defaultReplaceScope",
936 "Default Replace Scope", 'R', NULL, FULL);
937 XtVaSetValues(subSubSubPane, XmNradioBehavior, True, NULL);
938 window->replScopeWinDefItem = createMenuToggle(subSubSubPane, "window",
939 "In Window", 'W', replaceScopeWindowCB, window,
940 GetPrefReplaceDefScope() == REPL_DEF_SCOPE_WINDOW, FULL);
941 window->replScopeSelDefItem = createMenuToggle(subSubSubPane, "selection",
942 "In Selection", 'S', replaceScopeSelectionCB, window,
943 GetPrefReplaceDefScope() == REPL_DEF_SCOPE_SELECTION, FULL);
944 window->replScopeSmartDefItem = createMenuToggle(subSubSubPane, "window",
945 "Smart", 'm', replaceScopeSmartCB, window,
946 GetPrefReplaceDefScope() == REPL_DEF_SCOPE_SMART, FULL);
947 #endif
949 /* Syntax Highlighting sub menu */
950 subSubPane = createMenu(subPane, "syntaxHighlighting","Syntax Highlighting",
951 'H', NULL, FULL);
952 window->highlightOffDefItem = createMenuRadioToggle(subSubPane, "off","Off",
953 'O', highlightOffDefCB, window, !GetPrefHighlightSyntax(), FULL);
954 window->highlightDefItem = createMenuRadioToggle(subSubPane, "on",
955 "On", 'n', highlightDefCB, window, GetPrefHighlightSyntax(), FULL);
956 createMenuSeparator(subSubPane, "sep1", SHORT);
957 createMenuItem(subSubPane, "recognitionPatterns", "Recognition Patterns...",
958 'R', highlightingDefCB, window, FULL);
959 createMenuItem(subSubPane, "textDrawingStyles", "Text Drawing Styles...", 'T',
960 stylesDefCB, window, FULL);
961 window->backlightCharsDefItem = createMenuToggle(subPane,
962 "backlightChars", "Apply Backlighting", 'g', backlightCharsDefCB,
963 window, GetPrefBacklightChars(), FULL);
965 /* tabbed editing sub menu */
966 subSubPane = createMenu(subPane, "tabbedEditMenu", "Tabbed Editing", 0,
967 &cascade, SHORT);
968 window->openInTabDefItem = createMenuToggle(subSubPane, "openAsTab",
969 "Open File In New Tab", 'T', openInTabDefCB, window,
970 GetPrefOpenInTab(), FULL);
971 window->tabBarDefItem = createMenuToggle(subSubPane, "showTabBar",
972 "Show Tab Bar", 'B', tabBarDefCB, window,
973 GetPrefTabBar(), FULL);
974 window->tabBarHideDefItem = createMenuToggle(subSubPane,
975 "hideTabBar", "Hide Tab Bar When Only One Document is Open", 'H',
976 tabBarHideDefCB, window, GetPrefTabBarHideOne(), FULL);
977 window->tabNavigateDefItem = createMenuToggle(subSubPane, "tabNavigateDef",
978 "Next/Prev Tabs Across Windows", 'W', tabNavigateDefCB, window,
979 GetPrefGlobalTabNavigate(), FULL);
980 window->tabSortDefItem = createMenuToggle(subSubPane, "tabSortDef",
981 "Sort Tabs Alphabetically", 'S', tabSortDefCB, window,
982 GetPrefSortTabs(), FULL);
984 window->toolTipsDefItem = createMenuToggle(subPane, "showTooltips",
985 "Show Tooltips", 0, toolTipsDefCB, window, GetPrefToolTips(),
986 FULL);
987 window->statsLineDefItem = createMenuToggle(subPane, "statisticsLine",
988 "Statistics Line", 'S', statsLineDefCB, window, GetPrefStatsLine(),
989 SHORT);
990 window->iSearchLineDefItem = createMenuToggle(subPane,
991 "incrementalSearchLine", "Incremental Search Line", 'i',
992 iSearchLineDefCB, window, GetPrefISearchLine(), FULL);
993 window->lineNumsDefItem = createMenuToggle(subPane, "showLineNumbers",
994 "Show Line Numbers", 'N', lineNumsDefCB, window, GetPrefLineNums(),
995 SHORT);
996 window->saveLastDefItem = createMenuToggle(subPane, "preserveLastVersion",
997 "Make Backup Copy (*.bck)", 'e', preserveDefCB, window,
998 GetPrefSaveOldVersion(), SHORT);
999 window->autoSaveDefItem = createMenuToggle(subPane, "incrementalBackup",
1000 "Incremental Backup", 'B', autoSaveDefCB, window, GetPrefAutoSave(),
1001 SHORT);
1004 /* Show Matching sub menu */
1005 subSubPane = createMenu(subPane, "showMatching", "Show Matching (..)", 'M',
1006 NULL, FULL);
1007 window->showMatchingOffDefItem = createMenuRadioToggle(subSubPane, "off",
1008 "Off", 'O', showMatchingOffDefCB, window,
1009 GetPrefShowMatching() == NO_FLASH, SHORT);
1010 window->showMatchingDelimitDefItem = createMenuRadioToggle(subSubPane,
1011 "delimiter", "Delimiter", 'D', showMatchingDelimitDefCB, window,
1012 GetPrefShowMatching() == FLASH_DELIMIT, SHORT);
1013 window->showMatchingRangeDefItem = createMenuRadioToggle(subSubPane,
1014 "range", "Range", 'R', showMatchingRangeDefCB, window,
1015 GetPrefShowMatching() == FLASH_RANGE, SHORT);
1016 createMenuSeparator(subSubPane, "sep", SHORT);
1017 window->matchSyntaxBasedDefItem = createMenuToggle(subSubPane,
1018 "matchSyntax", "Syntax Based", 'S', matchSyntaxBasedDefCB, window,
1019 GetPrefMatchSyntaxBased(), SHORT);
1021 /* Append LF at end of files on save */
1022 window->appendLFItem = createMenuToggle(subPane, "appendLFItem",
1023 "Terminate with Line Break on Save", 'v', appendLFCB, NULL,
1024 GetPrefAppendLF(), FULL);
1026 window->reposDlogsDefItem = createMenuToggle(subPane, "popupsUnderPointer",
1027 "Popups Under Pointer", 'P', reposDlogsDefCB, window,
1028 GetPrefRepositionDialogs(), FULL);
1029 window->autoScrollDefItem = createMenuToggle(subPane, "autoScroll",
1030 "Auto Scroll Near Window Top/Bottom", 0, autoScrollDefCB, window,
1031 GetPrefAutoScroll(), FULL);
1032 subSubPane = createMenu(subPane, "warnings", "Warnings", 'r', NULL, FULL);
1033 window->modWarnDefItem = createMenuToggle(subSubPane,
1034 "filesModifiedExternally", "Files Modified Externally", 'F',
1035 modWarnDefCB, window, GetPrefWarnFileMods(), FULL);
1036 window->modWarnRealDefItem = createMenuToggle(subSubPane,
1037 "checkModifiedFileContents", "Check Modified File Contents", 'C',
1038 modWarnRealDefCB, window, GetPrefWarnRealFileMods(), FULL);
1039 XtSetSensitive(window->modWarnRealDefItem, GetPrefWarnFileMods());
1040 window->exitWarnDefItem = createMenuToggle(subSubPane, "onExit", "On Exit", 'O',
1041 exitWarnDefCB, window, GetPrefWarnExit(), FULL);
1043 /* Initial Window Size sub menu (simulates radioBehavior) */
1044 subSubPane = createMenu(subPane, "initialwindowSize",
1045 "Initial Window Size", 'z', NULL, FULL);
1046 /* XtVaSetValues(subSubPane, XmNradioBehavior, True, NULL); */
1047 window->size24x80DefItem = btn = createMenuToggle(subSubPane, "24X80",
1048 "24 x 80", '2', size24x80CB, window, False, SHORT);
1049 XtVaSetValues(btn, XmNindicatorType, XmONE_OF_MANY, NULL);
1050 window->size40x80DefItem = btn = createMenuToggle(subSubPane, "40X80",
1051 "40 x 80", '4', size40x80CB, window, False, SHORT);
1052 XtVaSetValues(btn, XmNindicatorType, XmONE_OF_MANY, NULL);
1053 window->size60x80DefItem = btn = createMenuToggle(subSubPane, "60X80",
1054 "60 x 80", '6', size60x80CB, window, False, SHORT);
1055 XtVaSetValues(btn, XmNindicatorType, XmONE_OF_MANY, NULL);
1056 window->size80x80DefItem = btn = createMenuToggle(subSubPane, "80X80",
1057 "80 x 80", '8', size80x80CB, window, False, SHORT);
1058 XtVaSetValues(btn, XmNindicatorType, XmONE_OF_MANY, NULL);
1059 window->sizeCustomDefItem = btn = createMenuToggle(subSubPane, "custom",
1060 "Custom...", 'C', sizeCustomCB, window, False, SHORT);
1061 XtVaSetValues(btn, XmNindicatorType, XmONE_OF_MANY, NULL);
1062 updateWindowSizeMenu(window);
1065 ** Remainder of Preferences menu
1067 createMenuItem(menuPane, "saveDefaults", "Save Defaults...", 'v',
1068 savePrefCB, window, FULL);
1069 #ifdef SGI_CUSTOM
1070 window->shortMenusDefItem = createMenuToggle(menuPane,
1071 "shortMenus", "Short Menus", 'h', shortMenusCB, window,
1072 GetPrefShortMenus(), SHORT);
1073 #endif
1074 createMenuSeparator(menuPane, "sep1", SHORT);
1075 window->statsLineItem = createMenuToggle(menuPane, "statisticsLine", "Statistics Line", 'S',
1076 statsCB, window, GetPrefStatsLine(), SHORT);
1077 window->iSearchLineItem = createMenuToggle(menuPane, "incrementalSearchLine","Incremental Search Line",
1078 'I', doActionCB, "set_incremental_search_line", GetPrefISearchLine(), FULL);
1079 window->lineNumsItem = createMenuToggle(menuPane, "lineNumbers", "Show Line Numbers", 'N',
1080 doActionCB, "set_show_line_numbers", GetPrefLineNums(), SHORT);
1081 CreateLanguageModeSubMenu(window, menuPane, "languageMode",
1082 "Language Mode", 'L');
1083 subPane = createMenu(menuPane, "autoIndent", "Auto Indent",
1084 'A', NULL, FULL);
1085 window->autoIndentOffItem = createMenuRadioToggle(subPane, "off", "Off",
1086 'O', autoIndentOffCB, window, window->indentStyle == NO_AUTO_INDENT,
1087 SHORT);
1088 window->autoIndentItem = createMenuRadioToggle(subPane, "on", "On", 'n',
1089 autoIndentCB, window, window->indentStyle == AUTO_INDENT, SHORT);
1090 window->smartIndentItem = createMenuRadioToggle(subPane, "smart", "Smart",
1091 'S', smartIndentCB, window, window->indentStyle == SMART_INDENT,
1092 SHORT);
1093 subPane = createMenu(menuPane, "wrap", "Wrap",
1094 'W', NULL, FULL);
1095 window->noWrapItem = createMenuRadioToggle(subPane, "none",
1096 "None", 'N', noWrapCB, window,
1097 window->wrapMode==NO_WRAP, SHORT);
1098 window->newlineWrapItem = createMenuRadioToggle(subPane, "autoNewlineWrap",
1099 "Auto Newline", 'A', newlineWrapCB, window,
1100 window->wrapMode==NEWLINE_WRAP, SHORT);
1101 window->continuousWrapItem = createMenuRadioToggle(subPane,
1102 "continuousWrap", "Continuous", 'C', continuousWrapCB, window,
1103 window->wrapMode==CONTINUOUS_WRAP, SHORT);
1104 createMenuSeparator(subPane, "sep1", SHORT);
1105 createMenuItem(subPane, "wrapMargin", "Wrap Margin...", 'W',
1106 wrapMarginCB, window, SHORT);
1107 createMenuItem(menuPane, "tabs", "Tab Stops...", 'T', tabsCB, window, SHORT);
1108 createMenuItem(menuPane, "textFont", "Text Fonts...", 'F', fontCB, window,
1109 FULL);
1110 window->highlightItem = createMenuToggle(menuPane, "highlightSyntax",
1111 "Highlight Syntax", 'H', doActionCB, "set_highlight_syntax",
1112 GetPrefHighlightSyntax(), SHORT);
1113 window->backlightCharsItem = createMenuToggle(menuPane, "backlightChars",
1114 "Apply Backlighting", 'g', backlightCharsCB, window,
1115 window->backlightChars, FULL);
1116 #ifndef VMS
1117 window->saveLastItem = createMenuToggle(menuPane, "makeBackupCopy",
1118 "Make Backup Copy (*.bck)", 'e', preserveCB, window,
1119 window->saveOldVersion, SHORT);
1120 #endif
1121 window->autoSaveItem = createMenuToggle(menuPane, "incrementalBackup",
1122 "Incremental Backup", 'B', autoSaveCB, window, window->autoSave,
1123 SHORT);
1125 subPane = createMenu(menuPane, "showMatching", "Show Matching (..)",
1126 'M', NULL, FULL);
1127 window->showMatchingOffItem = createMenuRadioToggle(subPane, "off", "Off",
1128 'O', showMatchingOffCB, window, window->showMatchingStyle == NO_FLASH,
1129 SHORT);
1130 window->showMatchingDelimitItem = createMenuRadioToggle(subPane,
1131 "delimiter", "Delimiter", 'D', showMatchingDelimitCB, window,
1132 window->showMatchingStyle == FLASH_DELIMIT, SHORT);
1133 window->showMatchingRangeItem = createMenuRadioToggle(subPane, "range",
1134 "Range", 'R', showMatchingRangeCB, window,
1135 window->showMatchingStyle == FLASH_RANGE, SHORT);
1136 createMenuSeparator(subPane, "sep", SHORT);
1137 window->matchSyntaxBasedItem = createMenuToggle(subPane, "matchSyntax",
1138 "Syntax Based", 'S', matchSyntaxBasedCB, window,
1139 window->matchSyntaxBased, SHORT);
1141 #ifndef SGI_CUSTOM
1142 createMenuSeparator(menuPane, "sep2", SHORT);
1143 window->overtypeModeItem = createMenuToggle(menuPane, "overtype", "Overtype", 'O',
1144 doActionCB, "set_overtype_mode", False, SHORT);
1145 window->readOnlyItem = createMenuToggle(menuPane, "readOnly", "Read Only",
1146 'y', doActionCB, "set_locked", IS_USER_LOCKED(window->lockReasons), FULL);
1147 #endif
1149 #ifndef VMS
1151 ** Create the Shell menu
1153 menuPane = window->shellMenuPane =
1154 createMenu(menuBar, "shellMenu", "Shell", 0, &cascade, FULL);
1155 btn = createMenuItem(menuPane, "executeCommand", "Execute Command...",
1156 'E', doActionCB, "execute_command_dialog", SHORT);
1157 XtVaSetValues(btn, XmNuserData, PERMANENT_MENU_ITEM, NULL);
1158 btn = createMenuItem(menuPane, "executeCommandLine", "Execute Command Line",
1159 'x', doActionCB, "execute_command_line", SHORT);
1160 XtVaSetValues(btn, XmNuserData, PERMANENT_MENU_ITEM, NULL);
1161 window->filterItem = createMenuItem(menuPane, "filterSelection",
1162 "Filter Selection...", 'F', doActionCB, "filter_selection_dialog",
1163 SHORT);
1164 XtVaSetValues(window->filterItem, XmNuserData, PERMANENT_MENU_ITEM,
1165 XmNsensitive, window->wasSelected, NULL);
1166 window->cancelShellItem = createMenuItem(menuPane, "cancelShellCommand",
1167 "Cancel Shell Command", 'C', cancelShellCB, window, SHORT);
1168 XtVaSetValues(window->cancelShellItem, XmNuserData, PERMANENT_MENU_ITEM,
1169 XmNsensitive, False, NULL);
1170 btn = createMenuSeparator(menuPane, "sep1", SHORT);
1171 XtVaSetValues(btn, XmNuserData, PERMANENT_MENU_ITEM, NULL);
1172 #endif
1175 ** Create the Macro menu
1177 menuPane = window->macroMenuPane =
1178 createMenu(menuBar, "macroMenu", "Macro", 0, &cascade, FULL);
1179 window->learnItem = createMenuItem(menuPane, "learnKeystrokes",
1180 "Learn Keystrokes", 'L', learnCB, window, SHORT);
1181 XtVaSetValues(window->learnItem , XmNuserData, PERMANENT_MENU_ITEM, NULL);
1182 window->finishLearnItem = createMenuItem(menuPane, "finishLearn",
1183 "Finish Learn", 'F', finishLearnCB, window, SHORT);
1184 XtVaSetValues(window->finishLearnItem , XmNuserData, PERMANENT_MENU_ITEM,
1185 XmNsensitive, False, NULL);
1186 window->cancelMacroItem = createMenuItem(menuPane, "cancelLearn",
1187 "Cancel Learn", 'C', cancelLearnCB, window, SHORT);
1188 XtVaSetValues(window->cancelMacroItem, XmNuserData, PERMANENT_MENU_ITEM,
1189 XmNsensitive, False, NULL);
1190 window->replayItem = createMenuItem(menuPane, "replayKeystrokes",
1191 "Replay Keystrokes", 'K', replayCB, window, SHORT);
1192 XtVaSetValues(window->replayItem, XmNuserData, PERMANENT_MENU_ITEM,
1193 XmNsensitive, GetReplayMacro() != NULL, NULL);
1194 window->repeatItem = createMenuItem(menuPane, "repeat",
1195 "Repeat...", 'R', doActionCB, "repeat_dialog", SHORT);
1196 XtVaSetValues(window->repeatItem, XmNuserData, PERMANENT_MENU_ITEM, NULL);
1197 btn = createMenuSeparator(menuPane, "sep1", SHORT);
1198 XtVaSetValues(btn, XmNuserData, PERMANENT_MENU_ITEM, NULL);
1201 ** Create the Windows menu
1203 menuPane = window->windowMenuPane = createMenu(menuBar, "windowsMenu",
1204 "Windows", 0, &cascade, FULL);
1205 XtAddCallback(cascade, XmNcascadingCallback, (XtCallbackProc)windowMenuCB,
1206 window);
1207 window->splitPaneItem = createMenuItem(menuPane, "splitPane",
1208 "Split Pane", 'S', doActionCB, "split_pane", SHORT);
1209 XtVaSetValues(window->splitPaneItem, XmNuserData, PERMANENT_MENU_ITEM,
1210 NULL);
1211 window->closePaneItem = createMenuItem(menuPane, "closePane",
1212 "Close Pane", 'C', doActionCB, "close_pane", SHORT);
1213 XtVaSetValues(window->closePaneItem, XmNuserData, PERMANENT_MENU_ITEM,NULL);
1214 XtSetSensitive(window->closePaneItem, False);
1216 btn = createMenuSeparator(menuPane, "sep01", SHORT);
1217 XtVaSetValues(btn, XmNuserData, PERMANENT_MENU_ITEM, NULL);
1218 window->detachDocumentItem = createMenuItem(menuPane, "detachBuffer",
1219 "Detach Tab", 'D', doActionCB, "detach_document", SHORT);
1220 XtSetSensitive(window->detachDocumentItem, False);
1222 window->moveDocumentItem = createMenuItem(menuPane, "moveDocument",
1223 "Move Tab To...", 'M', doActionCB, "move_document_dialog", SHORT);
1224 XtSetSensitive(window->moveDocumentItem, False);
1225 btn = createMenuSeparator(menuPane, "sep1", SHORT);
1226 XtVaSetValues(btn, XmNuserData, PERMANENT_MENU_ITEM, NULL);
1229 ** Create "Help" pull down menu.
1231 menuPane = createMenu(menuBar, "helpMenu", "Help", 0, &cascade, SHORT);
1232 XtVaSetValues(menuBar, XmNmenuHelpWidget, cascade, NULL);
1233 buildHelpMenu( menuPane, &H_M[0], window );
1235 return menuBar;
1238 /*----------------------------------------------------------------------------*/
1240 static Widget makeHelpMenuItem(
1242 Widget parent,
1243 char *name, /* to be assigned to the child widget */
1244 char *label, /* text to be displayed in menu */
1245 char mnemonic, /* letter in label to be underlined */
1246 menuCallbackProc callback, /* activated when menu item selected */
1247 void *cbArg, /* passed to activated call back */
1248 int mode, /* SGI_CUSTOM menu option */
1249 enum HelpTopic topic /* associated with this menu item */
1252 Widget menuItem =
1253 createMenuItem( parent, name, label, mnemonic, callback, cbArg, mode );
1255 XtVaSetValues( menuItem, XmNuserData, topic, 0 );
1256 return menuItem;
1259 /*----------------------------------------------------------------------------*/
1261 static void helpCB( Widget menuItem, XtPointer clientData, XtPointer callData )
1263 enum HelpTopic topic;
1265 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(menuItem))->lastFocus,
1266 ((XmAnyCallbackStruct *)callData)->event);
1267 XtVaGetValues( menuItem, XmNuserData, &topic, 0 );
1269 Help(topic);
1272 /*----------------------------------------------------------------------------*/
1274 #define NON_MENU_HELP 9
1276 static HelpMenu * buildHelpMenu(
1278 Widget pane, /* Menu pane on which to place new menu items */
1279 HelpMenu * menu, /* Data to drive building the help menu */
1280 WindowInfo * window /* Main NEdit window information */
1283 #ifdef VMS
1284 int hideIt = 1; /* All menu items matching this will be inaccessible */
1285 #else
1286 int hideIt = -1; /* This value should make all menu items accessible */
1287 #endif
1289 if( menu != NULL )
1291 int crntLevel = menu->level;
1293 /*-------------------------
1294 * For each menu element ...
1295 *-------------------------*/
1296 while( menu != NULL && menu->level == crntLevel )
1298 /*----------------------------------------------
1299 * ... see if dealing with a separator or submenu
1300 *----------------------------------------------*/
1301 if( menu->topic == HELP_none )
1303 if( menu->mnemonic == '-' )
1305 createMenuSeparator(pane, menu->wgtName, SHORT);
1306 menu = menu->next;
1308 else
1310 /*-------------------------------------------------------
1311 * Do not show any of the submenu when it is to be hidden.
1312 *-------------------------------------------------------*/
1313 if( menu->hideIt == hideIt || menu->hideIt == NON_MENU_HELP )
1315 do { menu = menu->next;
1316 } while( menu != NULL && menu->level > crntLevel );
1319 else
1321 Widget subPane =
1322 createMenu( pane, menu->wgtName, menu->subTitle,
1323 menu->mnemonic, NULL, FULL);
1325 menu = buildHelpMenu( subPane, menu->next, window );
1330 else
1332 /*---------------------------------------
1333 * Show menu item if not going to hide it.
1334 * This is the easy way out of hiding
1335 * menu items. When entire submenus want
1336 * to be hidden, either the entire branch
1337 * will have to be marked, or this algorithm
1338 * will have to become a lot smarter.
1339 *---------------------------------------*/
1340 if( menu->hideIt != hideIt && menu->hideIt != NON_MENU_HELP )
1341 makeHelpMenuItem(
1342 pane, menu->wgtName, HelpTitles[menu->topic],
1343 menu->mnemonic, helpCB, window, SHORT, menu->topic );
1345 menu = menu->next;
1350 return menu;
1353 /*----------------------------------------------------------------------------*/
1356 ** handle actions called from the context menus of tabs.
1358 static void doTabActionCB(Widget w, XtPointer clientData, XtPointer callData)
1360 Widget menu = MENU_WIDGET(w);
1361 WindowInfo *win, *window = WidgetToWindow(menu);
1363 /* extract the window to be acted upon, see comment in
1364 tabMenuPostAP() for detail */
1365 XtVaGetValues(window->tabMenuPane, XmNuserData, &win, NULL);
1367 HidePointerOnKeyedEvent(win->lastFocus,
1368 ((XmAnyCallbackStruct *)callData)->event);
1369 XtCallActionProc(win->lastFocus, (char *)clientData,
1370 ((XmAnyCallbackStruct *)callData)->event, NULL, 0);
1373 static void doActionCB(Widget w, XtPointer clientData, XtPointer callData)
1375 Widget menu = MENU_WIDGET(w);
1376 Widget widget = WidgetToWindow(menu)->lastFocus;
1377 String action = (String) clientData;
1378 XEvent* event = ((XmAnyCallbackStruct*) callData)->event;
1380 HidePointerOnKeyedEvent(widget, event);
1382 XtCallActionProc(widget, action, event, NULL, 0);
1385 static void pasteColCB(Widget w, XtPointer clientData, XtPointer callData)
1387 static char *params[1] = {"rect"};
1389 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
1390 ((XmAnyCallbackStruct *)callData)->event);
1391 XtCallActionProc(WidgetToWindow(MENU_WIDGET(w))->lastFocus, "paste_clipboard",
1392 ((XmAnyCallbackStruct *)callData)->event, params, 1);
1395 static void shiftLeftCB(Widget w, XtPointer clientData, XtPointer callData)
1397 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
1398 ((XmAnyCallbackStruct *)callData)->event);
1399 XtCallActionProc(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
1400 ((XmAnyCallbackStruct *)callData)->event->xbutton.state & ShiftMask
1401 ? "shift_left_by_tab" : "shift_left",
1402 ((XmAnyCallbackStruct *)callData)->event, NULL, 0);
1405 static void shiftRightCB(Widget w, XtPointer clientData, XtPointer callData)
1407 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
1408 ((XmAnyCallbackStruct *)callData)->event);
1409 XtCallActionProc(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
1410 ((XmAnyCallbackStruct *)callData)->event->xbutton.state & ShiftMask
1411 ? "shift_right_by_tab" : "shift_right",
1412 ((XmAnyCallbackStruct *)callData)->event, NULL, 0);
1415 static void findCB(Widget w, XtPointer clientData, XtPointer callData)
1417 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
1418 ((XmAnyCallbackStruct *)callData)->event);
1419 XtCallActionProc(WidgetToWindow(MENU_WIDGET(w))->lastFocus, "find_dialog",
1420 ((XmAnyCallbackStruct *)callData)->event,
1421 shiftKeyToDir(callData), 1);
1424 static void findSameCB(Widget w, XtPointer clientData, XtPointer callData)
1426 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
1427 ((XmAnyCallbackStruct *)callData)->event);
1428 XtCallActionProc(WidgetToWindow(MENU_WIDGET(w))->lastFocus, "find_again",
1429 ((XmAnyCallbackStruct *)callData)->event,
1430 shiftKeyToDir(callData), 1);
1433 static void findSelCB(Widget w, XtPointer clientData, XtPointer callData)
1435 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
1436 ((XmAnyCallbackStruct *)callData)->event);
1437 XtCallActionProc(WidgetToWindow(MENU_WIDGET(w))->lastFocus, "find_selection",
1438 ((XmAnyCallbackStruct *)callData)->event,
1439 shiftKeyToDir(callData), 1);
1442 static void findIncrCB(Widget w, XtPointer clientData, XtPointer callData)
1444 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
1445 ((XmAnyCallbackStruct *)callData)->event);
1446 XtCallActionProc(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
1447 "start_incremental_find", ((XmAnyCallbackStruct *)callData)->event,
1448 shiftKeyToDir(callData), 1);
1451 static void replaceCB(Widget w, XtPointer clientData, XtPointer callData)
1453 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
1454 ((XmAnyCallbackStruct *)callData)->event);
1455 XtCallActionProc(WidgetToWindow(MENU_WIDGET(w))->lastFocus, "replace_dialog",
1456 ((XmAnyCallbackStruct *)callData)->event,
1457 shiftKeyToDir(callData), 1);
1460 static void replaceSameCB(Widget w, XtPointer clientData, XtPointer callData)
1462 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
1463 ((XmAnyCallbackStruct *)callData)->event);
1464 XtCallActionProc(WidgetToWindow(MENU_WIDGET(w))->lastFocus, "replace_again",
1465 ((XmAnyCallbackStruct *)callData)->event,
1466 shiftKeyToDir(callData), 1);
1469 static void replaceFindSameCB(Widget w, XtPointer clientData, XtPointer callData)
1471 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
1472 ((XmAnyCallbackStruct *)callData)->event);
1473 XtCallActionProc(WidgetToWindow(MENU_WIDGET(w))->lastFocus, "replace_find_same",
1474 ((XmAnyCallbackStruct *)callData)->event,
1475 shiftKeyToDir(callData), 1);
1478 static void markCB(Widget w, XtPointer clientData, XtPointer callData)
1480 XEvent *event = ((XmAnyCallbackStruct *)callData)->event;
1481 WindowInfo *window = WidgetToWindow(MENU_WIDGET(w));
1483 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
1484 ((XmAnyCallbackStruct *)callData)->event);
1485 if (event->type == KeyPress || event->type == KeyRelease)
1486 BeginMarkCommand(window);
1487 else
1488 XtCallActionProc(window->lastFocus, "mark_dialog", event, NULL, 0);
1491 static void gotoMarkCB(Widget w, XtPointer clientData, XtPointer callData)
1493 XEvent *event = ((XmAnyCallbackStruct *)callData)->event;
1494 WindowInfo *window = WidgetToWindow(MENU_WIDGET(w));
1495 int extend = event->xbutton.state & ShiftMask;
1496 static char *params[1] = {"extend"};
1498 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
1499 ((XmAnyCallbackStruct *)callData)->event);
1500 if (event->type == KeyPress || event->type == KeyRelease)
1501 BeginGotoMarkCommand(window, extend);
1502 else
1503 XtCallActionProc(window->lastFocus, "goto_mark_dialog", event, params,
1504 extend ? 1 : 0);
1507 static void gotoMatchingCB(Widget w, XtPointer clientData, XtPointer callData)
1509 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
1510 ((XmAnyCallbackStruct *)callData)->event);
1511 XtCallActionProc(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
1512 ((XmAnyCallbackStruct *)callData)->event->xbutton.state & ShiftMask
1513 ? "select_to_matching" : "goto_matching",
1514 ((XmAnyCallbackStruct *)callData)->event, NULL, 0);
1517 static void autoIndentOffCB(Widget w, WindowInfo *window, caddr_t callData)
1519 static char *params[1] = {"off"};
1520 Widget menu = MENU_WIDGET(w);
1522 window = WidgetToWindow(menu);
1524 #ifdef SGI_CUSTOM
1525 if (shortPrefAskDefault(window->shell, w, "Auto Indent Off")) {
1526 autoIndentOffDefCB(w, window, callData);
1527 SaveNEditPrefs(window->shell, GetPrefShortMenus());
1529 #endif
1530 HidePointerOnKeyedEvent(WidgetToWindow(menu)->lastFocus,
1531 ((XmAnyCallbackStruct *)callData)->event);
1532 XtCallActionProc(WidgetToWindow(menu)->lastFocus, "set_auto_indent",
1533 ((XmAnyCallbackStruct *)callData)->event, params, 1);
1536 static void autoIndentCB(Widget w, WindowInfo *window, caddr_t callData)
1538 static char *params[1] = {"on"};
1539 Widget menu = MENU_WIDGET(w);
1541 window = WidgetToWindow(menu);
1543 #ifdef SGI_CUSTOM
1544 if (shortPrefAskDefault(window->shell, w, "Auto Indent")) {
1545 autoIndentDefCB(w, window, callData);
1546 SaveNEditPrefs(window->shell, GetPrefShortMenus());
1548 #endif
1549 HidePointerOnKeyedEvent(WidgetToWindow(menu)->lastFocus,
1550 ((XmAnyCallbackStruct *)callData)->event);
1551 XtCallActionProc(WidgetToWindow(menu)->lastFocus, "set_auto_indent",
1552 ((XmAnyCallbackStruct *)callData)->event, params, 1);
1555 static void smartIndentCB(Widget w, WindowInfo *window, caddr_t callData)
1557 static char *params[1] = {"smart"};
1558 Widget menu = MENU_WIDGET(w);
1560 window = WidgetToWindow(menu);
1562 #ifdef SGI_CUSTOM
1563 if (shortPrefAskDefault(window->shell, w, "Smart Indent")) {
1564 smartIndentDefCB(w, window, callData);
1565 SaveNEditPrefs(window->shell, GetPrefShortMenus());
1567 #endif
1568 HidePointerOnKeyedEvent(WidgetToWindow(menu)->lastFocus,
1569 ((XmAnyCallbackStruct *)callData)->event);
1570 XtCallActionProc(WidgetToWindow(menu)->lastFocus, "set_auto_indent",
1571 ((XmAnyCallbackStruct *)callData)->event, params, 1);
1574 static void autoSaveCB(Widget w, WindowInfo *window, caddr_t callData)
1576 Widget menu = MENU_WIDGET(w);
1578 window = WidgetToWindow(menu);
1580 #ifdef SGI_CUSTOM
1581 if (shortPrefAskDefault(window->shell, w, "Incremental Backup")) {
1582 autoSaveDefCB(w, window, callData);
1583 SaveNEditPrefs(window->shell, GetPrefShortMenus());
1585 #endif
1586 HidePointerOnKeyedEvent(WidgetToWindow(menu)->lastFocus,
1587 ((XmAnyCallbackStruct *)callData)->event);
1588 XtCallActionProc(WidgetToWindow(menu)->lastFocus, "set_incremental_backup",
1589 ((XmAnyCallbackStruct *)callData)->event, NULL, 0);
1592 static void preserveCB(Widget w, WindowInfo *window, caddr_t callData)
1594 Widget menu = MENU_WIDGET(w);
1596 window = WidgetToWindow(menu);
1598 #ifdef SGI_CUSTOM
1599 if (shortPrefAskDefault(window->shell, w, "Make Backup Copy")) {
1600 preserveDefCB(w, window, callData);
1601 SaveNEditPrefs(window->shell, GetPrefShortMenus());
1603 #endif
1604 HidePointerOnKeyedEvent(WidgetToWindow(menu)->lastFocus,
1605 ((XmAnyCallbackStruct *)callData)->event);
1606 XtCallActionProc(WidgetToWindow(menu)->lastFocus, "set_make_backup_copy",
1607 ((XmAnyCallbackStruct *)callData)->event, NULL, 0);
1610 static void showMatchingOffCB(Widget w, WindowInfo *window, caddr_t callData)
1612 static char *params[1] = {NO_FLASH_STRING};
1613 Widget menu = MENU_WIDGET(w);
1615 window = WidgetToWindow(menu);
1617 #ifdef SGI_CUSTOM
1618 if (shortPrefAskDefault(window->shell, w, "Show Matching Off")) {
1619 showMatchingOffDefCB(w, window, callData);
1620 SaveNEditPrefs(window->shell, GetPrefShortMenus());
1622 #endif
1623 HidePointerOnKeyedEvent(WidgetToWindow(menu)->lastFocus,
1624 ((XmAnyCallbackStruct *)callData)->event);
1625 XtCallActionProc(WidgetToWindow(menu)->lastFocus, "set_show_matching",
1626 ((XmAnyCallbackStruct *)callData)->event, params, 1);
1629 static void showMatchingDelimitCB(Widget w, WindowInfo *window, caddr_t callData)
1631 static char *params[1] = {FLASH_DELIMIT_STRING};
1632 Widget menu = MENU_WIDGET(w);
1634 window = WidgetToWindow(menu);
1636 #ifdef SGI_CUSTOM
1637 if (shortPrefAskDefault(window->shell, w, "Show Matching Delimiter")) {
1638 showMatchingDelimitDefCB(w, window, callData);
1639 SaveNEditPrefs(window->shell, GetPrefShortMenus());
1641 #endif
1642 HidePointerOnKeyedEvent(WidgetToWindow(menu)->lastFocus,
1643 ((XmAnyCallbackStruct *)callData)->event);
1644 XtCallActionProc(WidgetToWindow(menu)->lastFocus, "set_show_matching",
1645 ((XmAnyCallbackStruct *)callData)->event, params, 1);
1648 static void showMatchingRangeCB(Widget w, WindowInfo *window, caddr_t callData)
1650 static char *params[1] = {FLASH_RANGE_STRING};
1651 Widget menu = MENU_WIDGET(w);
1653 window = WidgetToWindow(menu);
1655 #ifdef SGI_CUSTOM
1656 if (shortPrefAskDefault(window->shell, w, "Show Matching Range")) {
1657 showMatchingRangeDefCB(w, window, callData);
1658 SaveNEditPrefs(window->shell, GetPrefShortMenus());
1660 #endif
1661 HidePointerOnKeyedEvent(WidgetToWindow(menu)->lastFocus,
1662 ((XmAnyCallbackStruct *)callData)->event);
1663 XtCallActionProc(WidgetToWindow(menu)->lastFocus, "set_show_matching",
1664 ((XmAnyCallbackStruct *)callData)->event, params, 1);
1667 static void matchSyntaxBasedCB(Widget w, WindowInfo *window, caddr_t callData)
1669 Widget menu = MENU_WIDGET(w);
1671 window = WidgetToWindow(menu);
1673 #ifdef SGI_CUSTOM
1674 if (shortPrefAskDefault(window->shell, w, "Match Syntax Based")) {
1675 matchSyntaxBasedDefCB(w, window, callData);
1676 SaveNEditPrefs(window->shell, GetPrefShortMenus());
1678 #endif
1679 HidePointerOnKeyedEvent(WidgetToWindow(menu)->lastFocus,
1680 ((XmAnyCallbackStruct *)callData)->event);
1681 XtCallActionProc(WidgetToWindow(menu)->lastFocus, "set_match_syntax_based",
1682 ((XmAnyCallbackStruct *)callData)->event, NULL, 0);
1685 static void fontCB(Widget w, WindowInfo *window, caddr_t callData)
1687 ChooseFonts(WidgetToWindow(MENU_WIDGET(w)), True);
1690 static void noWrapCB(Widget w, WindowInfo *window, caddr_t callData)
1692 static char *params[1] = {"none"};
1693 Widget menu = MENU_WIDGET(w);
1695 window = WidgetToWindow(menu);
1697 #ifdef SGI_CUSTOM
1698 if (shortPrefAskDefault(window->shell, w, "No Wrap")) {
1699 noWrapDefCB(w, window, callData);
1700 SaveNEditPrefs(window->shell, GetPrefShortMenus());
1702 #endif
1703 HidePointerOnKeyedEvent(WidgetToWindow(menu)->lastFocus,
1704 ((XmAnyCallbackStruct *)callData)->event);
1705 XtCallActionProc(WidgetToWindow(menu)->lastFocus, "set_wrap_text",
1706 ((XmAnyCallbackStruct *)callData)->event, params, 1);
1709 static void newlineWrapCB(Widget w, WindowInfo *window, caddr_t callData)
1711 static char *params[1] = {"auto"};
1712 Widget menu = MENU_WIDGET(w);
1714 window = WidgetToWindow(menu);
1716 #ifdef SGI_CUSTOM
1717 if (shortPrefAskDefault(window->shell, w, "Auto Newline Wrap")) {
1718 newlineWrapDefCB(w, window, callData);
1719 SaveNEditPrefs(window->shell, GetPrefShortMenus());
1721 #endif
1722 HidePointerOnKeyedEvent(WidgetToWindow(menu)->lastFocus,
1723 ((XmAnyCallbackStruct *)callData)->event);
1724 XtCallActionProc(WidgetToWindow(menu)->lastFocus, "set_wrap_text",
1725 ((XmAnyCallbackStruct *)callData)->event, params, 1);
1728 static void continuousWrapCB(Widget w, WindowInfo *window, caddr_t callData)
1730 static char *params[1] = {"continuous"};
1731 Widget menu = MENU_WIDGET(w);
1733 window = WidgetToWindow(menu);
1735 #ifdef SGI_CUSTOM
1736 if (shortPrefAskDefault(window->shell, w, "Continuous Wrap")) {
1737 contWrapDefCB(w, window, callData);
1738 SaveNEditPrefs(window->shell, GetPrefShortMenus());
1740 #endif
1741 HidePointerOnKeyedEvent(WidgetToWindow(menu)->lastFocus,
1742 ((XmAnyCallbackStruct *)callData)->event);
1743 XtCallActionProc(WidgetToWindow(menu)->lastFocus, "set_wrap_text",
1744 ((XmAnyCallbackStruct *)callData)->event, params, 1);
1747 static void wrapMarginCB(Widget w, WindowInfo *window, caddr_t callData)
1749 window = WidgetToWindow(MENU_WIDGET(w));
1751 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
1752 ((XmAnyCallbackStruct *)callData)->event);
1753 WrapMarginDialog(window->shell, window);
1756 static void backlightCharsCB(Widget w, WindowInfo *window, caddr_t callData)
1758 int applyBacklight = XmToggleButtonGetState(w);
1759 window = WidgetToWindow(MENU_WIDGET(w));
1760 SetBacklightChars(window, applyBacklight?GetPrefBacklightCharTypes():NULL);
1763 static void tabsCB(Widget w, WindowInfo *window, caddr_t callData)
1765 window = WidgetToWindow(MENU_WIDGET(w));
1767 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
1768 ((XmAnyCallbackStruct *)callData)->event);
1769 TabsPrefDialog(window->shell, window);
1772 static void statsCB(Widget w, WindowInfo *window, caddr_t callData)
1774 Widget menu = MENU_WIDGET(w);
1776 window = WidgetToWindow(menu);
1778 #ifdef SGI_CUSTOM
1779 if (shortPrefAskDefault(window->shell, w, "Statistics Line")) {
1780 statsLineDefCB(w, window, callData);
1781 SaveNEditPrefs(window->shell, GetPrefShortMenus());
1783 #endif
1784 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
1785 ((XmAnyCallbackStruct *)callData)->event);
1786 XtCallActionProc(WidgetToWindow(menu)->lastFocus, "set_statistics_line",
1787 ((XmAnyCallbackStruct *)callData)->event, NULL, 0);
1790 static void autoIndentOffDefCB(Widget w, WindowInfo *window, caddr_t callData)
1792 WindowInfo *win;
1794 /* Set the preference and make the other windows' menus agree */
1795 SetPrefAutoIndent(NO_AUTO_INDENT);
1796 for (win=WindowList; win!=NULL; win=win->next) {
1797 if (!IsTopDocument(win))
1798 continue;
1799 XmToggleButtonSetState(win->autoIndentOffDefItem, True, False);
1800 XmToggleButtonSetState(win->autoIndentDefItem, False, False);
1801 XmToggleButtonSetState(win->smartIndentDefItem, False, False);
1805 static void autoIndentDefCB(Widget w, WindowInfo *window, caddr_t callData)
1807 WindowInfo *win;
1809 /* Set the preference and make the other windows' menus agree */
1810 SetPrefAutoIndent(AUTO_INDENT);
1811 for (win=WindowList; win!=NULL; win=win->next) {
1812 if (!IsTopDocument(win))
1813 continue;
1814 XmToggleButtonSetState(win->autoIndentDefItem, True, False);
1815 XmToggleButtonSetState(win->autoIndentOffDefItem, False, False);
1816 XmToggleButtonSetState(win->smartIndentDefItem, False, False);
1820 static void smartIndentDefCB(Widget w, WindowInfo *window, caddr_t callData)
1822 WindowInfo *win;
1824 /* Set the preference and make the other windows' menus agree */
1825 SetPrefAutoIndent(SMART_INDENT);
1826 for (win=WindowList; win!=NULL; win=win->next) {
1827 if (!IsTopDocument(win))
1828 continue;
1829 XmToggleButtonSetState(win->smartIndentDefItem, True, False);
1830 XmToggleButtonSetState(win->autoIndentOffDefItem, False, False);
1831 XmToggleButtonSetState(win->autoIndentDefItem, False, False);
1835 static void autoSaveDefCB(Widget w, WindowInfo *window, caddr_t callData)
1837 WindowInfo *win;
1838 int state = XmToggleButtonGetState(w);
1840 /* Set the preference and make the other windows' menus agree */
1841 SetPrefAutoSave(state);
1842 for (win=WindowList; win!=NULL; win=win->next) {
1843 if (IsTopDocument(win))
1844 XmToggleButtonSetState(win->autoSaveDefItem, state, False);
1848 static void preserveDefCB(Widget w, WindowInfo *window, caddr_t callData)
1850 WindowInfo *win;
1851 int state = XmToggleButtonGetState(w);
1853 /* Set the preference and make the other windows' menus agree */
1854 SetPrefSaveOldVersion(state);
1855 for (win=WindowList; win!=NULL; win=win->next) {
1856 if (IsTopDocument(win))
1857 XmToggleButtonSetState(win->saveLastDefItem, state, False);
1861 static void fontDefCB(Widget w, WindowInfo *window, caddr_t callData)
1863 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
1864 ((XmAnyCallbackStruct *)callData)->event);
1865 ChooseFonts(WidgetToWindow(MENU_WIDGET(w)), False);
1868 static void colorDefCB(Widget w, WindowInfo *window, caddr_t callData)
1870 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
1871 ((XmAnyCallbackStruct *)callData)->event);
1872 ChooseColors(WidgetToWindow(MENU_WIDGET(w)));
1875 static void noWrapDefCB(Widget w, WindowInfo *window, caddr_t callData)
1877 WindowInfo *win;
1879 /* Set the preference and make the other windows' menus agree */
1880 SetPrefWrap(NO_WRAP);
1881 for (win=WindowList; win!=NULL; win=win->next) {
1882 if (!IsTopDocument(win))
1883 continue;
1884 XmToggleButtonSetState(win->noWrapDefItem, True, False);
1885 XmToggleButtonSetState(win->newlineWrapDefItem, False, False);
1886 XmToggleButtonSetState(win->contWrapDefItem, False, False);
1890 static void newlineWrapDefCB(Widget w, WindowInfo *window, caddr_t callData)
1892 WindowInfo *win;
1894 /* Set the preference and make the other windows' menus agree */
1895 SetPrefWrap(NEWLINE_WRAP);
1896 for (win=WindowList; win!=NULL; win=win->next) {
1897 if (!IsTopDocument(win))
1898 continue;
1899 XmToggleButtonSetState(win->newlineWrapDefItem, True, False);
1900 XmToggleButtonSetState(win->contWrapDefItem, False, False);
1901 XmToggleButtonSetState(win->noWrapDefItem, False, False);
1905 static void contWrapDefCB(Widget w, WindowInfo *window, caddr_t callData)
1907 WindowInfo *win;
1909 /* Set the preference and make the other windows' menus agree */
1910 SetPrefWrap(CONTINUOUS_WRAP);
1911 for (win=WindowList; win!=NULL; win=win->next) {
1912 if (!IsTopDocument(win))
1913 continue;
1914 XmToggleButtonSetState(win->contWrapDefItem, True, False);
1915 XmToggleButtonSetState(win->newlineWrapDefItem, False, False);
1916 XmToggleButtonSetState(win->noWrapDefItem, False, False);
1920 static void wrapMarginDefCB(Widget w, WindowInfo *window, caddr_t callData)
1922 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
1923 ((XmAnyCallbackStruct *)callData)->event);
1924 WrapMarginDialog(WidgetToWindow(MENU_WIDGET(w))->shell, NULL);
1927 static void smartTagsDefCB(Widget w, XtPointer client_data, XtPointer callData)
1929 WindowInfo *win;
1931 SetPrefSmartTags(True);
1932 for (win=WindowList; win!=NULL; win=win->next) {
1933 if (!IsTopDocument(win))
1934 continue;
1935 XmToggleButtonSetState(win->smartTagsDefItem, True, False);
1936 XmToggleButtonSetState(win->allTagsDefItem, False, False);
1940 static void showAllTagsDefCB(Widget w, XtPointer client_data, XtPointer callData)
1942 WindowInfo *win;
1944 SetPrefSmartTags(False);
1945 for (win=WindowList; win!=NULL; win=win->next) {
1946 if (!IsTopDocument(win))
1947 continue;
1948 XmToggleButtonSetState(win->smartTagsDefItem, False, False);
1949 XmToggleButtonSetState(win->allTagsDefItem, True, False);
1953 static void shellSelDefCB(Widget widget, WindowInfo* window, caddr_t callData)
1955 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(widget))->lastFocus,
1956 ((XmAnyCallbackStruct*) callData)->event);
1957 SelectShellDialog(WidgetToWindow(MENU_WIDGET(widget))->shell, NULL);
1960 static void tabsDefCB(Widget w, WindowInfo *window, caddr_t callData)
1962 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
1963 ((XmAnyCallbackStruct *)callData)->event);
1964 TabsPrefDialog(WidgetToWindow(MENU_WIDGET(w))->shell, NULL);
1967 static void showMatchingOffDefCB(Widget w, WindowInfo *window, caddr_t callData)
1969 WindowInfo *win;
1971 /* Set the preference and make the other windows' menus agree */
1972 SetPrefShowMatching(NO_FLASH);
1973 for (win=WindowList; win!=NULL; win=win->next) {
1974 if (!IsTopDocument(win))
1975 continue;
1976 XmToggleButtonSetState(win->showMatchingOffDefItem, True, False);
1977 XmToggleButtonSetState(win->showMatchingDelimitDefItem, False, False);
1978 XmToggleButtonSetState(win->showMatchingRangeDefItem, False, False);
1982 static void showMatchingDelimitDefCB(Widget w, WindowInfo *window, caddr_t callData)
1984 WindowInfo *win;
1986 /* Set the preference and make the other windows' menus agree */
1987 SetPrefShowMatching(FLASH_DELIMIT);
1988 for (win=WindowList; win!=NULL; win=win->next) {
1989 if (!IsTopDocument(win))
1990 continue;
1991 XmToggleButtonSetState(win->showMatchingOffDefItem, False, False);
1992 XmToggleButtonSetState(win->showMatchingDelimitDefItem, True, False);
1993 XmToggleButtonSetState(win->showMatchingRangeDefItem, False, False);
1997 static void showMatchingRangeDefCB(Widget w, WindowInfo *window, caddr_t callData)
1999 WindowInfo *win;
2001 /* Set the preference and make the other windows' menus agree */
2002 SetPrefShowMatching(FLASH_RANGE);
2003 for (win=WindowList; win!=NULL; win=win->next) {
2004 if (!IsTopDocument(win))
2005 continue;
2006 XmToggleButtonSetState(win->showMatchingOffDefItem, False, False);
2007 XmToggleButtonSetState(win->showMatchingDelimitDefItem, False, False);
2008 XmToggleButtonSetState(win->showMatchingRangeDefItem, True, False);
2012 static void matchSyntaxBasedDefCB(Widget w, WindowInfo *window, caddr_t callData)
2014 WindowInfo *win;
2016 int state = XmToggleButtonGetState(w);
2018 /* Set the preference and make the other windows' menus agree */
2019 SetPrefMatchSyntaxBased(state);
2020 for (win=WindowList; win!=NULL; win=win->next) {
2021 if (IsTopDocument(win))
2022 XmToggleButtonSetState(win->matchSyntaxBasedDefItem, state, False);
2026 static void backlightCharsDefCB(Widget w, WindowInfo *window, caddr_t callData)
2028 WindowInfo *win;
2029 int state = XmToggleButtonGetState(w);
2031 /* Set the preference and make the other windows' menus agree */
2032 SetPrefBacklightChars(state);
2033 for (win=WindowList; win!=NULL; win=win->next) {
2034 if (IsTopDocument(win))
2035 XmToggleButtonSetState(win->backlightCharsDefItem, state, False);
2039 static void highlightOffDefCB(Widget w, WindowInfo *window, caddr_t callData)
2041 WindowInfo *win;
2043 /* Set the preference and make the other windows' menus agree */
2044 SetPrefHighlightSyntax(False);
2045 for (win=WindowList; win!=NULL; win=win->next) {
2046 if (!IsTopDocument(win))
2047 continue;
2048 XmToggleButtonSetState(win->highlightOffDefItem, True, False);
2049 XmToggleButtonSetState(win->highlightDefItem, False, False);
2053 static void highlightDefCB(Widget w, WindowInfo *window, caddr_t callData)
2055 WindowInfo *win;
2057 /* Set the preference and make the other windows' menus agree */
2058 SetPrefHighlightSyntax(True);
2059 for (win=WindowList; win!=NULL; win=win->next) {
2060 if (!IsTopDocument(win))
2061 continue;
2062 XmToggleButtonSetState(win->highlightOffDefItem, False, False);
2063 XmToggleButtonSetState(win->highlightDefItem, True, False);
2067 static void highlightingDefCB(Widget w, WindowInfo *window, caddr_t callData)
2069 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
2070 ((XmAnyCallbackStruct *)callData)->event);
2071 EditHighlightPatterns(WidgetToWindow(MENU_WIDGET(w)));
2074 static void smartMacrosDefCB(Widget w, WindowInfo *window, caddr_t callData)
2076 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
2077 ((XmAnyCallbackStruct *)callData)->event);
2078 EditSmartIndentMacros(WidgetToWindow(MENU_WIDGET(w)));
2081 static void stylesDefCB(Widget w, WindowInfo *window, caddr_t callData)
2083 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
2084 ((XmAnyCallbackStruct *)callData)->event);
2085 EditHighlightStyles(NULL);
2088 static void languageDefCB(Widget w, WindowInfo *window, caddr_t callData)
2090 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
2091 ((XmAnyCallbackStruct *)callData)->event);
2092 EditLanguageModes();
2095 #ifndef VMS
2096 static void shellDefCB(Widget w, WindowInfo *window, caddr_t callData)
2098 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
2099 ((XmAnyCallbackStruct *)callData)->event);
2100 EditShellMenu(WidgetToWindow(MENU_WIDGET(w)));
2102 #endif /* VMS */
2104 static void macroDefCB(Widget w, WindowInfo *window, caddr_t callData)
2106 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
2107 ((XmAnyCallbackStruct *)callData)->event);
2108 EditMacroMenu(WidgetToWindow(MENU_WIDGET(w)));
2111 static void bgMenuDefCB(Widget w, WindowInfo *window, caddr_t callData)
2113 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
2114 ((XmAnyCallbackStruct *)callData)->event);
2115 EditBGMenu(WidgetToWindow(MENU_WIDGET(w)));
2118 static void customizeTitleDefCB(Widget w, WindowInfo *window, caddr_t callData)
2120 window = WidgetToWindow(MENU_WIDGET(w));
2122 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
2123 ((XmAnyCallbackStruct *)callData)->event);
2124 EditCustomTitleFormat(window);
2127 static void searchDlogsDefCB(Widget w, WindowInfo *window, caddr_t callData)
2129 WindowInfo *win;
2130 int state = XmToggleButtonGetState(w);
2132 /* Set the preference and make the other windows' menus agree */
2133 SetPrefSearchDlogs(state);
2134 for (win=WindowList; win!=NULL; win=win->next) {
2135 if (IsTopDocument(win))
2136 XmToggleButtonSetState(win->searchDlogsDefItem, state, False);
2140 static void beepOnSearchWrapDefCB(Widget w, WindowInfo *window, caddr_t callData)
2142 WindowInfo *win;
2143 int state = XmToggleButtonGetState(w);
2145 /* Set the preference and make the other windows' menus agree */
2146 SetPrefBeepOnSearchWrap(state);
2147 for (win=WindowList; win!=NULL; win=win->next) {
2148 if (IsTopDocument(win))
2149 XmToggleButtonSetState(win->beepOnSearchWrapDefItem, state, False);
2153 static void keepSearchDlogsDefCB(Widget w, WindowInfo *window, caddr_t callData)
2155 WindowInfo *win;
2156 int state = XmToggleButtonGetState(w);
2158 /* Set the preference and make the other windows' menus agree */
2159 SetPrefKeepSearchDlogs(state);
2160 for (win=WindowList; win!=NULL; win=win->next) {
2161 if (IsTopDocument(win))
2162 XmToggleButtonSetState(win->keepSearchDlogsDefItem, state, False);
2166 static void searchWrapsDefCB(Widget w, WindowInfo *window, caddr_t callData)
2168 WindowInfo *win;
2169 int state = XmToggleButtonGetState(w);
2171 /* Set the preference and make the other windows' menus agree */
2172 SetPrefSearchWraps(state);
2173 for (win=WindowList; win!=NULL; win=win->next) {
2174 if (IsTopDocument(win))
2175 XmToggleButtonSetState(win->searchWrapsDefItem, state, False);
2179 static void appendLFCB(Widget w, WindowInfo* window, caddr_t callData)
2181 WindowInfo *win;
2182 int state = XmToggleButtonGetState(w);
2184 SetPrefAppendLF(state);
2185 for (win = WindowList; win != NULL; win = win->next) {
2186 if (IsTopDocument(win))
2187 XmToggleButtonSetState(win->appendLFItem, state, False);
2191 static void sortOpenPrevDefCB(Widget w, WindowInfo *window, caddr_t callData)
2193 WindowInfo *win;
2194 int state = XmToggleButtonGetState(w);
2196 /* Set the preference, make the other windows' menus agree,
2197 and invalidate their Open Previous menus */
2198 SetPrefSortOpenPrevMenu(state);
2199 for (win=WindowList; win!=NULL; win=win->next) {
2200 if (IsTopDocument(win))
2201 XmToggleButtonSetState(win->sortOpenPrevDefItem, state, False);
2205 static void reposDlogsDefCB(Widget w, WindowInfo *window, caddr_t callData)
2207 WindowInfo *win;
2208 int state = XmToggleButtonGetState(w);
2210 /* Set the preference and make the other windows' menus agree */
2211 SetPrefRepositionDialogs(state);
2212 SetPointerCenteredDialogs(state);
2213 for (win=WindowList; win!=NULL; win=win->next) {
2214 if (IsTopDocument(win))
2215 XmToggleButtonSetState(win->reposDlogsDefItem, state, False);
2219 static void autoScrollDefCB(Widget w, WindowInfo *window, caddr_t callData)
2221 WindowInfo *win;
2222 int state = XmToggleButtonGetState(w);
2224 /* Set the preference and make the other windows' menus agree */
2225 SetPrefAutoScroll(state);
2226 /* XXX: Should we ensure auto-scroll now if needed? */
2227 for (win=WindowList; win!=NULL; win=win->next) {
2228 if (IsTopDocument(win))
2229 XmToggleButtonSetState(win->autoScrollDefItem, state, False);
2233 static void modWarnDefCB(Widget w, WindowInfo *window, caddr_t callData)
2235 WindowInfo *win;
2236 int state = XmToggleButtonGetState(w);
2238 /* Set the preference and make the other windows' menus agree */
2239 SetPrefWarnFileMods(state);
2240 for (win=WindowList; win!=NULL; win=win->next) {
2241 if (!IsTopDocument(win))
2242 continue;
2243 XmToggleButtonSetState(win->modWarnDefItem, state, False);
2244 XtSetSensitive(win->modWarnRealDefItem, state);
2248 static void modWarnRealDefCB(Widget w, WindowInfo *window, caddr_t callData)
2250 WindowInfo *win;
2251 int state = XmToggleButtonGetState(w);
2253 /* Set the preference and make the other windows' menus agree */
2254 SetPrefWarnRealFileMods(state);
2255 for (win=WindowList; win!=NULL; win=win->next) {
2256 if (IsTopDocument(win))
2257 XmToggleButtonSetState(win->modWarnRealDefItem, state, False);
2261 static void exitWarnDefCB(Widget w, WindowInfo *window, caddr_t callData)
2263 WindowInfo *win;
2264 int state = XmToggleButtonGetState(w);
2266 /* Set the preference and make the other windows' menus agree */
2267 SetPrefWarnExit(state);
2268 for (win=WindowList; win!=NULL; win=win->next) {
2269 if (IsTopDocument(win))
2270 XmToggleButtonSetState(win->exitWarnDefItem, state, False);
2274 static void openInTabDefCB(Widget w, WindowInfo *window, caddr_t callData)
2276 WindowInfo *win;
2277 int state = XmToggleButtonGetState(w);
2279 /* Set the preference and make the other windows' menus agree */
2280 SetPrefOpenInTab(state);
2281 for (win=WindowList; win!=NULL; win=win->next)
2282 XmToggleButtonSetState(win->openInTabDefItem, state, False);
2285 static void tabBarDefCB(Widget w, WindowInfo *window, caddr_t callData)
2287 WindowInfo *win;
2288 int state = XmToggleButtonGetState(w);
2290 /* Set the preference and make the other windows' menus agree */
2291 SetPrefTabBar(state);
2292 for (win=WindowList; win!=NULL; win=win->next) {
2293 if (!IsTopDocument(win))
2294 continue;
2295 XmToggleButtonSetState(win->tabBarDefItem, state, False);
2296 ShowWindowTabBar(win);
2300 static void tabBarHideDefCB(Widget w, WindowInfo *window, caddr_t callData)
2302 WindowInfo *win;
2303 int state = XmToggleButtonGetState(w);
2305 /* Set the preference and make the other windows' menus agree */
2306 SetPrefTabBarHideOne(state);
2307 for (win=WindowList; win!=NULL; win=win->next) {
2308 if (!IsTopDocument(win))
2309 continue;
2310 XmToggleButtonSetState(win->tabBarHideDefItem, state, False);
2311 ShowWindowTabBar(win);
2315 static void toolTipsDefCB(Widget w, WindowInfo *window, caddr_t callData)
2317 WindowInfo *win;
2318 int state = XmToggleButtonGetState(w);
2320 /* Set the preference and make the other windows' menus agree */
2321 SetPrefToolTips(state);
2322 for (win=WindowList; win!=NULL; win=win->next) {
2323 XtVaSetValues(win->tab, XltNshowBubble, GetPrefToolTips(), NULL);
2324 if (IsTopDocument(win))
2325 XmToggleButtonSetState(win->toolTipsDefItem, state, False);
2329 static void tabNavigateDefCB(Widget w, WindowInfo *window, caddr_t callData)
2331 WindowInfo *win;
2332 int state = XmToggleButtonGetState(w);
2334 /* Set the preference and make the other windows' menus agree */
2335 SetPrefGlobalTabNavigate(state);
2336 for (win=WindowList; win!=NULL; win=win->next) {
2337 if (IsTopDocument(win))
2338 XmToggleButtonSetState(win->tabNavigateDefItem, state, False);
2342 static void tabSortDefCB(Widget w, WindowInfo *window, caddr_t callData)
2344 WindowInfo *win;
2345 int state = XmToggleButtonGetState(w);
2347 /* Set the preference and make the other windows' menus agree */
2348 SetPrefSortTabs(state);
2349 for (win=WindowList; win!=NULL; win=win->next) {
2350 if (IsTopDocument(win))
2351 XmToggleButtonSetState(win->tabSortDefItem, state, False);
2354 /* If we just enabled sorting, sort all tabs. Note that this reorders
2355 the next pointers underneath us, which is scary, but SortTabBar never
2356 touches windows that are earlier in the WindowList so it's ok. */
2357 if (state) {
2358 Widget shell=(Widget)0;
2359 for (win=WindowList; win!=NULL; win=win->next) {
2360 if ( win->shell != shell ) {
2361 SortTabBar(win);
2362 shell = win->shell;
2368 static void statsLineDefCB(Widget w, WindowInfo *window, caddr_t callData)
2370 WindowInfo *win;
2371 int state = XmToggleButtonGetState(w);
2373 /* Set the preference and make the other windows' menus agree */
2374 SetPrefStatsLine(state);
2375 for (win=WindowList; win!=NULL; win=win->next) {
2376 if (IsTopDocument(win))
2377 XmToggleButtonSetState(win->statsLineDefItem, state, False);
2381 static void iSearchLineDefCB(Widget w, WindowInfo *window, caddr_t callData)
2383 WindowInfo *win;
2384 int state = XmToggleButtonGetState(w);
2386 /* Set the preference and make the other windows' menus agree */
2387 SetPrefISearchLine(state);
2388 for (win=WindowList; win!=NULL; win=win->next) {
2389 if (IsTopDocument(win))
2390 XmToggleButtonSetState(win->iSearchLineDefItem, state, False);
2394 static void lineNumsDefCB(Widget w, WindowInfo *window, caddr_t callData)
2396 WindowInfo *win;
2397 int state = XmToggleButtonGetState(w);
2399 /* Set the preference and make the other windows' menus agree */
2400 SetPrefLineNums(state);
2401 for (win=WindowList; win!=NULL; win=win->next) {
2402 if (IsTopDocument(win))
2403 XmToggleButtonSetState(win->lineNumsDefItem, state, False);
2407 static void pathInWindowsMenuDefCB(Widget w, WindowInfo *window, caddr_t callData)
2409 WindowInfo *win;
2410 int state = XmToggleButtonGetState(w);
2412 /* Set the preference and make the other windows' menus agree */
2413 SetPrefShowPathInWindowsMenu(state);
2414 for (win=WindowList; win!=NULL; win=win->next) {
2415 if (IsTopDocument(win))
2416 XmToggleButtonSetState(win->pathInWindowsMenuDefItem, state, False);
2418 InvalidateWindowMenus();
2421 static void searchLiteralCB(Widget w, WindowInfo *window, caddr_t callData)
2423 WindowInfo *win;
2425 /* Set the preference and make the other windows' menus agree */
2426 if (XmToggleButtonGetState(w)) {
2427 SetPrefSearch(SEARCH_LITERAL);
2428 for (win=WindowList; win!=NULL; win=win->next){
2429 if (!IsTopDocument(win))
2430 continue;
2431 XmToggleButtonSetState(win->searchLiteralDefItem, True, False);
2432 XmToggleButtonSetState(win->searchCaseSenseDefItem, False, False);
2433 XmToggleButtonSetState(win->searchLiteralWordDefItem, False, False);
2434 XmToggleButtonSetState(win->searchCaseSenseWordDefItem, False, False);
2435 XmToggleButtonSetState(win->searchRegexDefItem, False, False);
2436 XmToggleButtonSetState(win->searchRegexNoCaseDefItem, False, False);
2441 static void searchCaseSenseCB(Widget w, WindowInfo *window, caddr_t callData)
2443 WindowInfo *win;
2445 /* Set the preference and make the other windows' menus agree */
2446 if (XmToggleButtonGetState(w)) {
2447 SetPrefSearch(SEARCH_CASE_SENSE);
2448 for (win=WindowList; win!=NULL; win=win->next) {
2449 if (!IsTopDocument(win))
2450 continue;
2451 XmToggleButtonSetState(win->searchLiteralDefItem, False, False);
2452 XmToggleButtonSetState(win->searchCaseSenseDefItem, True, False);
2453 XmToggleButtonSetState(win->searchLiteralWordDefItem, False, False);
2454 XmToggleButtonSetState(win->searchCaseSenseWordDefItem, False, False);
2455 XmToggleButtonSetState(win->searchRegexDefItem, False, False);
2456 XmToggleButtonSetState(win->searchRegexNoCaseDefItem, False, False);
2461 static void searchLiteralWordCB(Widget w, WindowInfo *window, caddr_t callData)
2463 WindowInfo *win;
2465 /* Set the preference and make the other windows' menus agree */
2466 if (XmToggleButtonGetState(w)) {
2467 SetPrefSearch(SEARCH_LITERAL_WORD);
2468 for (win=WindowList; win!=NULL; win=win->next){
2469 if (!IsTopDocument(win))
2470 continue;
2471 XmToggleButtonSetState(win->searchLiteralDefItem, False, False);
2472 XmToggleButtonSetState(win->searchCaseSenseDefItem, False, False);
2473 XmToggleButtonSetState(win->searchLiteralWordDefItem, True, False);
2474 XmToggleButtonSetState(win->searchCaseSenseWordDefItem, False, False);
2475 XmToggleButtonSetState(win->searchRegexDefItem, False, False);
2476 XmToggleButtonSetState(win->searchRegexNoCaseDefItem, False, False);
2481 static void searchCaseSenseWordCB(Widget w, WindowInfo *window, caddr_t callData)
2483 WindowInfo *win;
2485 /* Set the preference and make the other windows' menus agree */
2486 if (XmToggleButtonGetState(w)) {
2487 SetPrefSearch(SEARCH_CASE_SENSE_WORD);
2488 for (win=WindowList; win!=NULL; win=win->next) {
2489 if (!IsTopDocument(win))
2490 continue;
2491 XmToggleButtonSetState(win->searchLiteralDefItem, False, False);
2492 XmToggleButtonSetState(win->searchCaseSenseDefItem, False, False);
2493 XmToggleButtonSetState(win->searchLiteralWordDefItem, False, False);
2494 XmToggleButtonSetState(win->searchCaseSenseWordDefItem, True, False);
2495 XmToggleButtonSetState(win->searchRegexDefItem, False, False);
2496 XmToggleButtonSetState(win->searchRegexNoCaseDefItem, False, False);
2501 static void searchRegexCB(Widget w, WindowInfo *window, caddr_t callData)
2503 WindowInfo *win;
2505 /* Set the preference and make the other windows' menus agree */
2506 if (XmToggleButtonGetState(w)) {
2507 SetPrefSearch(SEARCH_REGEX);
2508 for (win=WindowList; win!=NULL; win=win->next){
2509 if (!IsTopDocument(win))
2510 continue;
2511 XmToggleButtonSetState(win->searchLiteralDefItem, False, False);
2512 XmToggleButtonSetState(win->searchCaseSenseDefItem, False, False);
2513 XmToggleButtonSetState(win->searchLiteralWordDefItem, False, False);
2514 XmToggleButtonSetState(win->searchCaseSenseWordDefItem, False, False);
2515 XmToggleButtonSetState(win->searchRegexDefItem, True, False);
2516 XmToggleButtonSetState(win->searchRegexNoCaseDefItem, False, False);
2521 static void searchRegexNoCaseCB(Widget w, WindowInfo *window, caddr_t callData)
2523 WindowInfo *win;
2525 /* Set the preference and make the other windows' menus agree */
2526 if (XmToggleButtonGetState(w)) {
2527 SetPrefSearch(SEARCH_REGEX_NOCASE);
2528 for (win=WindowList; win!=NULL; win=win->next){
2529 if (!IsTopDocument(win))
2530 continue;
2531 XmToggleButtonSetState(win->searchLiteralDefItem, False, False);
2532 XmToggleButtonSetState(win->searchCaseSenseDefItem, False, False);
2533 XmToggleButtonSetState(win->searchLiteralWordDefItem, False, False);
2534 XmToggleButtonSetState(win->searchCaseSenseWordDefItem, False, False);
2535 XmToggleButtonSetState(win->searchRegexDefItem, False, False);
2536 XmToggleButtonSetState(win->searchRegexNoCaseDefItem, True, False);
2541 #ifdef REPLACE_SCOPE
2542 static void replaceScopeWindowCB(Widget w, WindowInfo *window, caddr_t callData)
2544 WindowInfo *win;
2546 /* Set the preference and make the other windows' menus agree */
2547 if (XmToggleButtonGetState(w)) {
2548 SetPrefReplaceDefScope(REPL_DEF_SCOPE_WINDOW);
2549 for (win=WindowList; win!=NULL; win=win->next){
2550 if (!IsTopDocument(win))
2551 continue;
2552 XmToggleButtonSetState(win->replScopeWinDefItem, True, False);
2553 XmToggleButtonSetState(win->replScopeSelDefItem, False, False);
2554 XmToggleButtonSetState(win->replScopeSmartDefItem, False, False);
2559 static void replaceScopeSelectionCB(Widget w, WindowInfo *window, caddr_t callData)
2561 WindowInfo *win;
2563 /* Set the preference and make the other windows' menus agree */
2564 if (XmToggleButtonGetState(w)) {
2565 SetPrefReplaceDefScope(REPL_DEF_SCOPE_SELECTION);
2566 for (win=WindowList; win!=NULL; win=win->next){
2567 if (!IsTopDocument(win))
2568 continue;
2569 XmToggleButtonSetState(win->replScopeWinDefItem, False, False);
2570 XmToggleButtonSetState(win->replScopeSelDefItem, True, False);
2571 XmToggleButtonSetState(win->replScopeSmartDefItem, False, False);
2576 static void replaceScopeSmartCB(Widget w, WindowInfo *window, caddr_t callData)
2578 WindowInfo *win;
2580 /* Set the preference and make the other windows' menus agree */
2581 if (XmToggleButtonGetState(w)) {
2582 SetPrefReplaceDefScope(REPL_DEF_SCOPE_SMART);
2583 for (win=WindowList; win!=NULL; win=win->next){
2584 if (!IsTopDocument(win))
2585 continue;
2586 XmToggleButtonSetState(win->replScopeWinDefItem, False, False);
2587 XmToggleButtonSetState(win->replScopeSelDefItem, False, False);
2588 XmToggleButtonSetState(win->replScopeSmartDefItem, True, False);
2592 #endif
2594 static void size24x80CB(Widget w, WindowInfo *window, caddr_t callData)
2596 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
2597 ((XmAnyCallbackStruct *)callData)->event);
2598 setWindowSizeDefault(24, 80);
2601 static void size40x80CB(Widget w, WindowInfo *window, caddr_t callData)
2603 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
2604 ((XmAnyCallbackStruct *)callData)->event);
2605 setWindowSizeDefault(40, 80);
2608 static void size60x80CB(Widget w, WindowInfo *window, caddr_t callData)
2610 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
2611 ((XmAnyCallbackStruct *)callData)->event);
2612 setWindowSizeDefault(60, 80);
2615 static void size80x80CB(Widget w, WindowInfo *window, caddr_t callData)
2617 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
2618 ((XmAnyCallbackStruct *)callData)->event);
2619 setWindowSizeDefault(80, 80);
2622 static void sizeCustomCB(Widget w, WindowInfo *window, caddr_t callData)
2624 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
2625 ((XmAnyCallbackStruct *)callData)->event);
2626 RowColumnPrefDialog(WidgetToWindow(MENU_WIDGET(w))->shell);
2627 updateWindowSizeMenus();
2630 static void savePrefCB(Widget w, WindowInfo *window, caddr_t callData)
2632 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
2633 ((XmAnyCallbackStruct *)callData)->event);
2634 SaveNEditPrefs(WidgetToWindow(MENU_WIDGET(w))->shell, False);
2637 static void formFeedCB(Widget w, XtPointer clientData, XtPointer callData)
2639 static char *params[1] = {"\f"};
2641 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
2642 ((XmAnyCallbackStruct *)callData)->event);
2643 XtCallActionProc(WidgetToWindow(MENU_WIDGET(w))->lastFocus, "insert_string",
2644 ((XmAnyCallbackStruct *)callData)->event, params, 1);
2647 static void cancelShellCB(Widget w, WindowInfo *window, XtPointer callData)
2649 #ifndef VMS
2650 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
2651 ((XmAnyCallbackStruct *)callData)->event);
2652 AbortShellCommand(WidgetToWindow(MENU_WIDGET(w)));
2653 #endif
2656 static void learnCB(Widget w, WindowInfo *window, caddr_t callData)
2658 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
2659 ((XmAnyCallbackStruct *)callData)->event);
2660 BeginLearn(WidgetToWindow(MENU_WIDGET(w)));
2663 static void finishLearnCB(Widget w, WindowInfo *window, caddr_t callData)
2665 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
2666 ((XmAnyCallbackStruct *)callData)->event);
2667 FinishLearn();
2670 static void cancelLearnCB(Widget w, WindowInfo *window, caddr_t callData)
2672 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
2673 ((XmAnyCallbackStruct *)callData)->event);
2674 CancelMacroOrLearn(WidgetToWindow(MENU_WIDGET(w)));
2677 static void replayCB(Widget w, WindowInfo *window, caddr_t callData)
2679 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
2680 ((XmAnyCallbackStruct *)callData)->event);
2681 Replay(WidgetToWindow(MENU_WIDGET(w)));
2684 static void windowMenuCB(Widget w, WindowInfo *window, caddr_t callData)
2686 window = WidgetToWindow(MENU_WIDGET(w));
2688 if (!window->windowMenuValid) {
2689 updateWindowMenu(window);
2690 window->windowMenuValid = True;
2694 static void prevOpenMenuCB(Widget w, WindowInfo *window, caddr_t callData)
2696 window = WidgetToWindow(MENU_WIDGET(w));
2698 updatePrevOpenMenu(window);
2701 static void unloadTagsFileMenuCB(Widget w, WindowInfo *window, caddr_t callData)
2703 updateTagsFileMenu(WidgetToWindow(MENU_WIDGET(w)));
2706 static void unloadTipsFileMenuCB(Widget w, WindowInfo *window, caddr_t callData)
2708 updateTipsFileMenu(WidgetToWindow(MENU_WIDGET(w)));
2712 ** open a new tab or window.
2714 static void newAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
2716 WindowInfo *window = WidgetToWindow(w);
2717 int openInTab = GetPrefOpenInTab();
2719 if (*nArgs > 0) {
2720 if (strcmp(args[0], "prefs") == 0) {
2721 /* accept default */;
2723 else if (strcmp(args[0], "tab") == 0) {
2724 openInTab = 1;
2726 else if (strcmp(args[0], "window") == 0) {
2727 openInTab = 0;
2729 else if (strcmp(args[0], "opposite") == 0) {
2730 openInTab = !openInTab;
2732 else {
2733 fprintf(stderr, "nedit: Unknown argument to action procedure \"new\": %s\n", args[0]);
2737 EditNewFile(openInTab? window : NULL, NULL, False, NULL, window->path);
2738 CheckCloseDim();
2742 ** These are just here because our techniques make it hard to bind a menu item
2743 ** to an action procedure that takes arguments. The user doesn't need to know
2744 ** about them -- they can use new( "opposite" ) or new( "tab" ).
2746 static void newOppositeAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
2748 WindowInfo *window = WidgetToWindow(w);
2750 EditNewFile(GetPrefOpenInTab()? NULL : window, NULL, False, NULL,
2751 window->path);
2752 CheckCloseDim();
2754 static void newTabAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
2756 WindowInfo *window = WidgetToWindow(w);
2758 EditNewFile(window, NULL, False, NULL, window->path);
2759 CheckCloseDim();
2762 static void openDialogAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
2764 WindowInfo *window = WidgetToWindow(w);
2765 char fullname[MAXPATHLEN], *params[2];
2766 int response;
2767 int n=1;
2769 response = PromptForExistingFile(window, "Open File", fullname);
2770 if (response != GFN_OK)
2771 return;
2772 params[0] = fullname;
2774 if (*nArgs>0 && !strcmp(args[0], "1"))
2775 params[n++] = "1";
2777 XtCallActionProc(window->lastFocus, "open", event, params, n);
2778 CheckCloseDim();
2781 static void openAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
2783 WindowInfo *window = WidgetToWindow(w);
2784 char filename[MAXPATHLEN], pathname[MAXPATHLEN];
2786 if (*nArgs == 0) {
2787 fprintf(stderr, "nedit: open action requires file argument\n");
2788 return;
2790 if (0 != ParseFilename(args[0], filename, pathname)
2791 || strlen(filename) + strlen(pathname) > MAXPATHLEN - 1) {
2792 fprintf(stderr, "nedit: invalid file name for open action: %s\n",
2793 args[0]);
2794 return;
2796 EditExistingFile(window, filename, pathname, 0, NULL, False,
2797 NULL, GetPrefOpenInTab(), False);
2798 CheckCloseDim();
2801 static void openSelectedAP(Widget w, XEvent *event, String *args,
2802 Cardinal *nArgs)
2804 OpenSelectedFile(WidgetToWindow(w), event->xbutton.time);
2805 CheckCloseDim();
2808 static void closeAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
2810 int preResponse = PROMPT_SBC_DIALOG_RESPONSE;
2812 if (*nArgs > 0) {
2813 if (strcmp(args[0], "prompt") == 0) {
2814 preResponse = PROMPT_SBC_DIALOG_RESPONSE;
2816 else if (strcmp(args[0], "save") == 0) {
2817 preResponse = YES_SBC_DIALOG_RESPONSE;
2819 else if (strcmp(args[0], "nosave") == 0) {
2820 preResponse = NO_SBC_DIALOG_RESPONSE;
2823 CloseFileAndWindow(WidgetToWindow(w), preResponse);
2824 CheckCloseDim();
2827 static void saveAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
2829 WindowInfo *window = WidgetToWindow(w);
2831 if (CheckReadOnly(window))
2832 return;
2833 SaveWindow(window);
2836 static void saveAsDialogAP(Widget w, XEvent *event, String *args,
2837 Cardinal *nArgs)
2839 WindowInfo *window = WidgetToWindow(w);
2840 int response, addWrap, fileFormat;
2841 char fullname[MAXPATHLEN], *params[2];
2843 response = PromptForNewFile(window, "Save File As", fullname,
2844 &fileFormat, &addWrap);
2845 if (response != GFN_OK)
2846 return;
2847 window->fileFormat = fileFormat;
2848 params[0] = fullname;
2849 params[1] = "wrapped";
2850 XtCallActionProc(window->lastFocus, "save_as", event, params, addWrap?2:1);
2853 static void saveAsAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
2855 if (*nArgs == 0) {
2856 fprintf(stderr, "nedit: save_as action requires file argument\n");
2857 return;
2859 SaveWindowAs(WidgetToWindow(w), args[0],
2860 *nArgs == 2 && !strCaseCmp(args[1], "wrapped"));
2863 static void revertDialogAP(Widget w, XEvent *event, String *args,
2864 Cardinal *nArgs)
2866 WindowInfo *window = WidgetToWindow(w);
2867 int b;
2869 /* re-reading file is irreversible, prompt the user first */
2870 if (window->fileChanged)
2872 b = DialogF(DF_QUES, window->shell, 2, "Discard Changes",
2873 "Discard changes to\n%s%s?", "OK", "Cancel", window->path,
2874 window->filename);
2875 } else
2877 b = DialogF(DF_QUES, window->shell, 2, "Reload File",
2878 "Re-load file\n%s%s?", "Re-read", "Cancel", window->path,
2879 window->filename);
2882 if (b != 1)
2884 return;
2886 XtCallActionProc(window->lastFocus, "revert_to_saved", event, NULL, 0);
2890 static void revertAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
2892 RevertToSaved(WidgetToWindow(w));
2895 static void includeDialogAP(Widget w, XEvent *event, String *args,
2896 Cardinal *nArgs)
2898 WindowInfo *window = WidgetToWindow(w);
2899 char filename[MAXPATHLEN], *params[1];
2900 int response;
2902 if (CheckReadOnly(window))
2903 return;
2904 response = PromptForExistingFile(window, "Include File", filename);
2905 if (response != GFN_OK)
2906 return;
2907 params[0] = filename;
2908 XtCallActionProc(window->lastFocus, "include_file", event, params, 1);
2911 static void includeAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
2913 WindowInfo *window = WidgetToWindow(w);
2915 if (CheckReadOnly(window))
2916 return;
2917 if (*nArgs == 0) {
2918 fprintf(stderr, "nedit: include action requires file argument\n");
2919 return;
2921 IncludeFile(WidgetToWindow(w), args[0]);
2924 static void loadMacroDialogAP(Widget w, XEvent *event, String *args,
2925 Cardinal *nArgs)
2927 WindowInfo *window = WidgetToWindow(w);
2928 char filename[MAXPATHLEN], *params[1];
2929 int response;
2931 response = PromptForExistingFile(window, "Load Macro File", filename);
2932 if (response != GFN_OK)
2933 return;
2934 params[0] = filename;
2935 XtCallActionProc(window->lastFocus, "load_macro_file", event, params, 1);
2938 static void loadMacroAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
2940 if (*nArgs == 0) {
2941 fprintf(stderr,"nedit: load_macro_file action requires file argument\n");
2942 return;
2944 ReadMacroFile(WidgetToWindow(w), args[0], True);
2947 static void loadTagsDialogAP(Widget w, XEvent *event, String *args,
2948 Cardinal *nArgs)
2950 WindowInfo *window = WidgetToWindow(w);
2951 char filename[MAXPATHLEN], *params[1];
2952 int response;
2954 response = PromptForExistingFile(window, "Load Tags File", filename);
2955 if (response != GFN_OK)
2956 return;
2957 params[0] = filename;
2958 XtCallActionProc(window->lastFocus, "load_tags_file", event, params, 1);
2961 static void loadTagsAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
2963 if (*nArgs == 0) {
2964 fprintf(stderr,"nedit: load_tags_file action requires file argument\n");
2965 return;
2968 if (!AddTagsFile(args[0], TAG))
2970 DialogF(DF_WARN, WidgetToWindow(w)->shell, 1, "Error Reading File",
2971 "Error reading ctags file:\n'%s'\ntags not loaded", "OK",
2972 args[0]);
2976 static void unloadTagsAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
2978 if (*nArgs == 0) {
2979 fprintf(stderr,
2980 "nedit: unload_tags_file action requires file argument\n");
2981 return;
2984 if (DeleteTagsFile(args[0], TAG, True)) {
2985 WindowInfo *win;
2987 /* refresh the "Unload Tags File" tear-offs after unloading, or
2988 close the tear-offs if all tags files have been unloaded */
2989 for (win=WindowList; win!=NULL; win=win->next) {
2990 if (IsTopDocument(win) &&
2991 !XmIsMenuShell(XtParent(win->unloadTagsMenuPane))) {
2992 if (XtIsSensitive(win->unloadTagsMenuItem))
2993 updateTagsFileMenu(win);
2994 else
2995 _XmDismissTearOff(XtParent(win->unloadTagsMenuPane),
2996 NULL, NULL);
3002 static void loadTipsDialogAP(Widget w, XEvent *event, String *args,
3003 Cardinal *nArgs)
3005 WindowInfo *window = WidgetToWindow(w);
3006 char filename[MAXPATHLEN], *params[1];
3007 int response;
3009 response = PromptForExistingFile(window, "Load Calltips File", filename);
3010 if (response != GFN_OK)
3011 return;
3012 params[0] = filename;
3013 XtCallActionProc(window->lastFocus, "load_tips_file", event, params, 1);
3016 static void loadTipsAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3018 if (*nArgs == 0) {
3019 fprintf(stderr,"nedit: load_tips_file action requires file argument\n");
3020 return;
3023 if (!AddTagsFile(args[0], TIP))
3025 DialogF(DF_WARN, WidgetToWindow(w)->shell, 1, "Error Reading File",
3026 "Error reading tips file:\n'%s'\ntips not loaded", "OK",
3027 args[0]);
3031 static void unloadTipsAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3033 if (*nArgs == 0) {
3034 fprintf(stderr,
3035 "nedit: unload_tips_file action requires file argument\n");
3036 return;
3038 /* refresh the "Unload Calltips File" tear-offs after unloading, or
3039 close the tear-offs if all tips files have been unloaded */
3040 if (DeleteTagsFile(args[0], TIP, True)) {
3041 WindowInfo *win;
3043 for (win=WindowList; win!=NULL; win=win->next) {
3044 if (IsTopDocument(win) &&
3045 !XmIsMenuShell(XtParent(win->unloadTipsMenuPane))) {
3046 if (XtIsSensitive(win->unloadTipsMenuItem))
3047 updateTipsFileMenu(win);
3048 else
3049 _XmDismissTearOff(XtParent(win->unloadTipsMenuPane),
3050 NULL, NULL);
3056 static void printAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3058 PrintWindow(WidgetToWindow(w), False);
3061 static void printSelAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3063 PrintWindow(WidgetToWindow(w), True);
3066 static void exitAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3068 WindowInfo *window = WidgetToWindow(w);
3070 if (!CheckPrefsChangesSaved(window->shell))
3071 return;
3073 /* If this is not the last window (more than one window is open),
3074 confirm with the user before exiting. */
3075 if (GetPrefWarnExit() && !(window == WindowList && window->next == NULL)) {
3076 int resp, titleLen, lineLen;
3077 char exitMsg[DF_MAX_MSG_LENGTH], *ptr, *title;
3078 char filename[MAXPATHLEN];
3079 WindowInfo *win;
3081 /* List the windows being edited and make sure the
3082 user really wants to exit */
3083 ptr = exitMsg;
3084 lineLen = 0;
3085 strcpy(ptr, "Editing: "); ptr += 9; lineLen += 9;
3086 for (win=WindowList; win!=NULL; win=win->next) {
3087 sprintf(filename, "%s%s", win->filename, win->fileChanged? "*": "");
3088 title = filename;
3089 titleLen = strlen(title);
3090 if (ptr - exitMsg + titleLen + 30 >= DF_MAX_MSG_LENGTH) {
3091 strcpy(ptr, "..."); ptr += 3;
3092 break;
3094 if (lineLen + titleLen + (win->next==NULL?5:2) > 50) {
3095 *ptr++ = '\n';
3096 lineLen = 0;
3098 if (win->next == NULL) {
3099 sprintf(ptr, "and %s.", title);
3100 ptr += 5 + titleLen;
3101 lineLen += 5 + titleLen;
3102 } else {
3103 sprintf(ptr, "%s, ", title);
3104 ptr += 2 + titleLen;
3105 lineLen += 2 + titleLen;
3108 sprintf(ptr, "\n\nExit NEdit?");
3109 resp = DialogF(DF_QUES, window->shell, 2, "Exit", "%s", "Exit",
3110 "Cancel", exitMsg);
3111 if (resp == 2)
3112 return;
3115 /* Close all files and exit when the last one is closed */
3116 if (CloseAllFilesAndWindows())
3117 exit(EXIT_SUCCESS);
3120 static void undoAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3122 WindowInfo *window = WidgetToWindow(w);
3124 if (CheckReadOnly(window))
3125 return;
3126 Undo(window);
3129 static void redoAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3131 WindowInfo *window = WidgetToWindow(w);
3133 if (CheckReadOnly(window))
3134 return;
3135 Redo(window);
3138 static void clearAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3140 WindowInfo *window = WidgetToWindow(w);
3142 if (CheckReadOnly(window))
3143 return;
3144 BufRemoveSelected(window->buffer);
3147 static void selAllAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3149 WindowInfo *window = WidgetToWindow(w);
3151 BufSelect(window->buffer, 0, window->buffer->length);
3154 static void shiftLeftAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3156 WindowInfo *window = WidgetToWindow(w);
3158 if (CheckReadOnly(window))
3159 return;
3160 ShiftSelection(window, SHIFT_LEFT, False);
3163 static void shiftLeftTabAP(Widget w, XEvent *event, String *args,
3164 Cardinal *nArgs)
3166 WindowInfo *window = WidgetToWindow(w);
3168 if (CheckReadOnly(window))
3169 return;
3170 ShiftSelection(window, SHIFT_LEFT, True);
3173 static void shiftRightAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3175 WindowInfo *window = WidgetToWindow(w);
3177 if (CheckReadOnly(window))
3178 return;
3179 ShiftSelection(window, SHIFT_RIGHT, False);
3182 static void shiftRightTabAP(Widget w, XEvent *event, String *args,
3183 Cardinal *nArgs)
3185 WindowInfo *window = WidgetToWindow(w);
3187 if (CheckReadOnly(window))
3188 return;
3189 ShiftSelection(window, SHIFT_RIGHT, True);
3192 static void findDialogAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3194 DoFindDlog(WidgetToWindow(w), searchDirection(0, args, nArgs),
3195 searchKeepDialogs(0, args, nArgs), searchType(0, args, nArgs),
3196 event->xbutton.time);
3199 static void findAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3201 if (*nArgs == 0) {
3202 fprintf(stderr, "nedit: find action requires search string argument\n");
3203 return;
3205 SearchAndSelect(WidgetToWindow(w), searchDirection(1, args, nArgs), args[0],
3206 searchType(1, args, nArgs), searchWrap(1, args, nArgs));
3209 static void findSameAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3211 SearchAndSelectSame(WidgetToWindow(w), searchDirection(0, args, nArgs),
3212 searchWrap(0, args, nArgs));
3215 static void findSelAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3217 SearchForSelected(WidgetToWindow(w), searchDirection(0, args, nArgs),
3218 searchType(0, args, nArgs), searchWrap(0, args, nArgs),
3219 event->xbutton.time);
3222 static void startIncrFindAP(Widget w, XEvent *event, String *args,
3223 Cardinal *nArgs)
3225 BeginISearch(WidgetToWindow(w), searchDirection(0, args, nArgs));
3228 static void findIncrAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3230 int i, continued = FALSE;
3231 if (*nArgs == 0) {
3232 fprintf(stderr, "nedit: find action requires search string argument\n");
3233 return;
3235 for (i=1; i<(int)*nArgs; i++)
3236 if (!strCaseCmp(args[i], "continued"))
3237 continued = TRUE;
3238 SearchAndSelectIncremental(WidgetToWindow(w),
3239 searchDirection(1, args, nArgs), args[0],
3240 searchType(1, args, nArgs), searchWrap(1, args, nArgs), continued);
3243 static void replaceDialogAP(Widget w, XEvent *event, String *args,
3244 Cardinal *nArgs)
3246 WindowInfo *window = WidgetToWindow(w);
3248 if (CheckReadOnly(window))
3249 return;
3250 DoFindReplaceDlog(window, searchDirection(0, args, nArgs),
3251 searchKeepDialogs(0, args, nArgs), searchType(0, args, nArgs),
3252 event->xbutton.time);
3255 static void replaceAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3257 WindowInfo *window = WidgetToWindow(w);
3259 if (CheckReadOnly(window))
3260 return;
3261 if (*nArgs < 2) {
3262 fprintf(stderr,
3263 "nedit: replace action requires search and replace string arguments\n");
3264 return;
3266 SearchAndReplace(window, searchDirection(2, args, nArgs),
3267 args[0], args[1], searchType(2, args, nArgs), searchWrap(2, args, nArgs));
3270 static void replaceAllAP(Widget w, XEvent *event, String *args,
3271 Cardinal *nArgs)
3273 WindowInfo *window = WidgetToWindow(w);
3275 if (CheckReadOnly(window))
3276 return;
3277 if (*nArgs < 2) {
3278 fprintf(stderr,
3279 "nedit: replace_all action requires search and replace string arguments\n");
3280 return;
3282 ReplaceAll(window, args[0], args[1], searchType(2, args, nArgs));
3285 static void replaceInSelAP(Widget w, XEvent *event, String *args,
3286 Cardinal *nArgs)
3288 WindowInfo *window = WidgetToWindow(w);
3290 if (CheckReadOnly(window))
3291 return;
3292 if (*nArgs < 2) {
3293 fprintf(stderr,
3294 "nedit: replace_in_selection requires search and replace string arguments\n");
3295 return;
3297 ReplaceInSelection(window, args[0], args[1],
3298 searchType(2, args, nArgs));
3301 static void replaceSameAP(Widget w, XEvent *event, String *args,
3302 Cardinal *nArgs)
3304 WindowInfo *window = WidgetToWindow(w);
3306 if (CheckReadOnly(window))
3307 return;
3308 ReplaceSame(window, searchDirection(0, args, nArgs), searchWrap(0, args, nArgs));
3311 static void replaceFindAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3313 WindowInfo *window = WidgetToWindow(w);
3315 if (CheckReadOnly(window))
3317 return;
3320 if (*nArgs < 2)
3322 DialogF(DF_WARN, window->shell, 1, "Error in replace_find",
3323 "replace_find action requires search and replace string arguments",
3324 "OK");
3325 return;
3328 ReplaceAndSearch(window, searchDirection(2, args, nArgs), args[0], args[1],
3329 searchType(2, args, nArgs), searchWrap(0, args, nArgs));
3332 static void replaceFindSameAP(Widget w, XEvent *event, String *args,
3333 Cardinal *nArgs)
3335 WindowInfo *window = WidgetToWindow(w);
3337 if (CheckReadOnly(window))
3338 return;
3339 ReplaceFindSame(window, searchDirection(0, args, nArgs), searchWrap(0, args, nArgs));
3342 static void gotoAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3344 int lineNum, column, position, curCol;
3346 /* Accept various formats:
3347 [line]:[column] (menu action)
3348 line (macro call)
3349 line, column (macro call) */
3350 if ( *nArgs == 0 ||
3351 *nArgs > 2 ||
3352 (*nArgs == 1 &&
3353 StringToLineAndCol( args[0], &lineNum, &column ) == -1) ||
3354 (*nArgs == 2 &&
3355 (!StringToNum(args[0], &lineNum) ||
3356 !StringToNum(args[1], &column)) ) ) {
3357 fprintf(stderr,"nedit: goto_line_number action requires line and/or column number\n");
3358 return;
3360 /* User specified column, but not line number */
3361 if ( lineNum == -1 ) {
3362 position = TextGetCursorPos(w);
3363 if (TextPosToLineAndCol(w, position, &lineNum,
3364 &curCol) == False) {
3365 return;
3368 /* User didn't specify a column */
3369 else if ( column == -1 ) {
3370 SelectNumberedLine(WidgetToWindow(w), lineNum);
3371 return;
3374 position = TextLineAndColToPos(w, lineNum, column );
3375 if ( position == -1 ) {
3376 return;
3378 TextSetCursorPos(w, position);
3379 return;
3382 static void gotoDialogAP(Widget w, XEvent *event, String *args,
3383 Cardinal *nArgs)
3385 GotoLineNumber(WidgetToWindow(w));
3388 static void gotoSelectedAP(Widget w, XEvent *event, String *args,
3389 Cardinal *nArgs)
3391 GotoSelectedLineNumber(WidgetToWindow(w), event->xbutton.time);
3394 static void repeatDialogAP(Widget w, XEvent *event, String *args,
3395 Cardinal *nArgs)
3397 RepeatDialog(WidgetToWindow(w));
3400 static void repeatMacroAP(Widget w, XEvent *event, String *args,
3401 Cardinal *nArgs)
3403 int how;
3405 if (*nArgs != 2) {
3406 fprintf(stderr, "nedit: repeat_macro requires two arguments\n");
3407 return;
3409 if (!strcmp(args[0], "in_selection"))
3410 how = REPEAT_IN_SEL;
3411 else if (!strcmp(args[0], "to_end"))
3412 how = REPEAT_TO_END;
3413 else if (sscanf(args[0], "%d", &how) != 1) {
3414 fprintf(stderr, "nedit: repeat_macro requires method/count\n");
3415 return;
3417 RepeatMacro(WidgetToWindow(w), args[1], how);
3420 static void markAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3422 if (*nArgs == 0 || strlen(args[0]) != 1 ||
3423 !isalnum((unsigned char)args[0][0])) {
3424 fprintf(stderr,"nedit: mark action requires a single-letter label\n");
3425 return;
3427 AddMark(WidgetToWindow(w), w, args[0][0]);
3430 static void markDialogAP(Widget w, XEvent *event, String *args,
3431 Cardinal *nArgs)
3433 MarkDialog(WidgetToWindow(w));
3436 static void gotoMarkAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3438 if (*nArgs == 0 || strlen(args[0]) != 1 ||
3439 !isalnum((unsigned char)args[0][0])) {
3440 fprintf(stderr,
3441 "nedit: goto_mark action requires a single-letter label\n");
3442 return;
3444 GotoMark(WidgetToWindow(w), w, args[0][0], *nArgs > 1 &&
3445 !strcmp(args[1], "extend"));
3448 static void gotoMarkDialogAP(Widget w, XEvent *event, String *args,
3449 Cardinal *nArgs)
3451 GotoMarkDialog(WidgetToWindow(w), *nArgs!=0 && !strcmp(args[0], "extend"));
3454 static void selectToMatchingAP(Widget w, XEvent *event, String *args,
3455 Cardinal *nArgs)
3457 SelectToMatchingCharacter(WidgetToWindow(w));
3460 static void gotoMatchingAP(Widget w, XEvent *event, String *args,
3461 Cardinal *nArgs)
3463 GotoMatchingCharacter(WidgetToWindow(w));
3466 static void findDefAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3468 FindDefinition(WidgetToWindow(w), event->xbutton.time,
3469 *nArgs == 0 ? NULL : args[0]);
3472 static void showTipAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3474 FindDefCalltip(WidgetToWindow(w), event->xbutton.time,
3475 *nArgs == 0 ? NULL : args[0]);
3478 static void splitPaneAP(Widget w, XEvent *event, String *args,
3479 Cardinal *nArgs)
3481 WindowInfo *window = WidgetToWindow(w);
3483 SplitPane(window);
3484 if (IsTopDocument(window)) {
3485 XtSetSensitive(window->splitPaneItem, window->nPanes < MAX_PANES);
3486 XtSetSensitive(window->closePaneItem, window->nPanes > 0);
3490 static void closePaneAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3492 WindowInfo *window = WidgetToWindow(w);
3494 ClosePane(window);
3495 if (IsTopDocument(window)) {
3496 XtSetSensitive(window->splitPaneItem, window->nPanes < MAX_PANES);
3497 XtSetSensitive(window->closePaneItem, window->nPanes > 0);
3501 static void detachDocumentDialogAP(Widget w, XEvent *event, String *args,
3502 Cardinal *nArgs)
3504 WindowInfo *window = WidgetToWindow(w);
3505 int resp;
3507 if (NDocuments(window) < 2)
3508 return;
3510 resp = DialogF(DF_QUES, window->shell, 2, "Detach %s?",
3511 "Detach", "Cancel", window->filename);
3513 if (resp == 1)
3514 DetachDocument(window);
3517 static void detachDocumentAP(Widget w, XEvent *event, String *args,
3518 Cardinal *nArgs)
3520 WindowInfo *window = WidgetToWindow(w);
3522 if (NDocuments(window) < 2)
3523 return;
3525 DetachDocument(window);
3528 static void moveDocumentDialogAP(Widget w, XEvent *event, String *args,
3529 Cardinal *nArgs)
3531 MoveDocumentDialog(WidgetToWindow(w));
3534 static void nextDocumentAP(Widget w, XEvent *event, String *args,
3535 Cardinal *nArgs)
3537 NextDocument(WidgetToWindow(w));
3540 static void prevDocumentAP(Widget w, XEvent *event, String *args,
3541 Cardinal *nArgs)
3543 PreviousDocument(WidgetToWindow(w));
3546 static void lastDocumentAP(Widget w, XEvent *event, String *args,
3547 Cardinal *nArgs)
3549 LastDocument(WidgetToWindow(w));
3552 static void capitalizeAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3554 WindowInfo *window = WidgetToWindow(w);
3556 if (CheckReadOnly(window))
3557 return;
3558 UpcaseSelection(window);
3561 static void lowercaseAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3563 WindowInfo *window = WidgetToWindow(w);
3565 if (CheckReadOnly(window))
3566 return;
3567 DowncaseSelection(window);
3570 static void fillAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3572 WindowInfo *window = WidgetToWindow(w);
3574 if (CheckReadOnly(window))
3575 return;
3576 FillSelection(window);
3579 static void controlDialogAP(Widget w, XEvent *event, String *args,
3580 Cardinal *nArgs)
3582 WindowInfo *window = WidgetToWindow(w);
3583 unsigned char charCodeString[2];
3584 char charCodeText[DF_MAX_PROMPT_LENGTH], dummy[DF_MAX_PROMPT_LENGTH];
3585 char *params[1];
3586 int charCode, nRead, response;
3588 if (CheckReadOnly(window))
3589 return;
3591 response = DialogF(DF_PROMPT, window->shell, 2, "Insert Ctrl Code",
3592 "ASCII Character Code:", charCodeText, "OK", "Cancel");
3594 if (response == 2)
3595 return;
3596 /* If we don't scan for a trailing string invalid input
3597 would be accepted sometimes. */
3598 nRead = sscanf(charCodeText, "%i%s", &charCode, dummy);
3599 if (nRead != 1 || charCode < 0 || charCode > 255) {
3600 XBell(TheDisplay, 0);
3601 return;
3603 charCodeString[0] = (unsigned char)charCode;
3604 charCodeString[1] = '\0';
3605 params[0] = (char *)charCodeString;
3607 if (!BufSubstituteNullChars((char *)charCodeString, 1, window->buffer))
3609 DialogF(DF_ERR, window->shell, 1, "Error", "Too much binary data",
3610 "OK");
3611 return;
3614 XtCallActionProc(w, "insert_string", event, params, 1);
3617 #ifndef VMS
3618 static void filterDialogAP(Widget w, XEvent *event, String *args,
3619 Cardinal *nArgs)
3621 WindowInfo *window = WidgetToWindow(w);
3622 char *params[1], cmdText[DF_MAX_PROMPT_LENGTH];
3623 int resp;
3624 static char **cmdHistory = NULL;
3625 static int nHistoryCmds = 0;
3627 if (CheckReadOnly(window))
3628 return;
3629 if (!window->buffer->primary.selected) {
3630 XBell(TheDisplay, 0);
3631 return;
3634 SetDialogFPromptHistory(cmdHistory, nHistoryCmds);
3636 resp = DialogF(DF_PROMPT, window->shell, 2, "Filter Selection",
3637 "Shell command: (use up arrow key to recall previous)",
3638 cmdText, "OK", "Cancel");
3640 if (resp == 2)
3641 return;
3642 AddToHistoryList(cmdText, &cmdHistory, &nHistoryCmds);
3643 params[0] = cmdText;
3644 XtCallActionProc(w, "filter_selection", event, params, 1);
3647 static void shellFilterAP(Widget w, XEvent *event, String *args,
3648 Cardinal *nArgs)
3650 WindowInfo *window = WidgetToWindow(w);
3652 if (CheckReadOnly(window))
3653 return;
3654 if (*nArgs == 0) {
3655 fprintf(stderr,
3656 "nedit: filter_selection requires shell command argument\n");
3657 return;
3659 FilterSelection(window, args[0],
3660 event->xany.send_event == MACRO_EVENT_MARKER);
3663 static void execDialogAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3665 WindowInfo *window = WidgetToWindow(w);
3666 char *params[1], cmdText[DF_MAX_PROMPT_LENGTH];
3667 int resp;
3668 static char **cmdHistory = NULL;
3669 static int nHistoryCmds = 0;
3671 if (CheckReadOnly(window))
3672 return;
3673 SetDialogFPromptHistory(cmdHistory, nHistoryCmds);
3675 resp = DialogF(DF_PROMPT, window->shell, 2, "Execute Command",
3676 "Shell command: (use up arrow key to recall previous;\n"
3677 "%% expands to current filename, # to line number)", cmdText, "OK",
3678 "Cancel");
3680 if (resp == 2)
3681 return;
3682 AddToHistoryList(cmdText, &cmdHistory, &nHistoryCmds);
3683 params[0] = cmdText;
3684 XtCallActionProc(w, "execute_command", event, params, 1);;
3687 static void execAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3689 WindowInfo *window = WidgetToWindow(w);
3691 if (CheckReadOnly(window))
3692 return;
3693 if (*nArgs == 0) {
3694 fprintf(stderr,
3695 "nedit: execute_command requires shell command argument\n");
3696 return;
3698 ExecShellCommand(window, args[0],
3699 event->xany.send_event == MACRO_EVENT_MARKER);
3702 static void execLineAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3704 WindowInfo *window = WidgetToWindow(w);
3706 if (CheckReadOnly(window))
3707 return;
3708 ExecCursorLine(window, event->xany.send_event == MACRO_EVENT_MARKER);
3711 static void shellMenuAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3713 if (*nArgs == 0) {
3714 fprintf(stderr,
3715 "nedit: shell_menu_command requires item-name argument\n");
3716 return;
3718 HidePointerOnKeyedEvent(w, event);
3719 DoNamedShellMenuCmd(WidgetToWindow(w), args[0],
3720 event->xany.send_event == MACRO_EVENT_MARKER);
3722 #endif
3724 static void macroMenuAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3726 if (*nArgs == 0) {
3727 fprintf(stderr,
3728 "nedit: macro_menu_command requires item-name argument\n");
3729 return;
3731 /* Don't allow users to execute a macro command from the menu (or accel)
3732 if there's already a macro command executing, UNLESS the macro is
3733 directly called from another one. NEdit can't handle
3734 running multiple, independent uncoordinated, macros in the same
3735 window. Macros may invoke macro menu commands recursively via the
3736 macro_menu_command action proc, which is important for being able to
3737 repeat any operation, and to embed macros within eachother at any
3738 level, however, a call here with a macro running means that THE USER
3739 is explicitly invoking another macro via the menu or an accelerator,
3740 UNLESS the macro event marker is set */
3741 if (event->xany.send_event != MACRO_EVENT_MARKER) {
3742 if (WidgetToWindow(w)->macroCmdData != NULL) {
3743 XBell(TheDisplay, 0);
3744 return;
3747 HidePointerOnKeyedEvent(w, event);
3748 DoNamedMacroMenuCmd(WidgetToWindow(w), args[0]);
3751 static void bgMenuAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3753 if (*nArgs == 0) {
3754 fprintf(stderr,
3755 "nedit: bg_menu_command requires item-name argument\n");
3756 return;
3758 /* Same remark as for macro menu commands (see above). */
3759 if (event->xany.send_event != MACRO_EVENT_MARKER) {
3760 if (WidgetToWindow(w)->macroCmdData != NULL) {
3761 XBell(TheDisplay, 0);
3762 return;
3765 HidePointerOnKeyedEvent(w, event);
3766 DoNamedBGMenuCmd(WidgetToWindow(w), args[0]);
3769 static void beginningOfSelectionAP(Widget w, XEvent *event, String *args,
3770 Cardinal *nArgs)
3772 textBuffer *buf = TextGetBuffer(w);
3773 int start, end, isRect, rectStart, rectEnd;
3775 if (!BufGetSelectionPos(buf, &start, &end, &isRect, &rectStart, &rectEnd))
3776 return;
3777 if (!isRect)
3778 TextSetCursorPos(w, start);
3779 else
3780 TextSetCursorPos(w, BufCountForwardDispChars(buf,
3781 BufStartOfLine(buf, start), rectStart));
3784 static void endOfSelectionAP(Widget w, XEvent *event, String *args,
3785 Cardinal *nArgs)
3787 textBuffer *buf = TextGetBuffer(w);
3788 int start, end, isRect, rectStart, rectEnd;
3790 if (!BufGetSelectionPos(buf, &start, &end, &isRect, &rectStart, &rectEnd))
3791 return;
3792 if (!isRect)
3793 TextSetCursorPos(w, end);
3794 else
3795 TextSetCursorPos(w, BufCountForwardDispChars(buf,
3796 BufStartOfLine(buf, end), rectEnd));
3799 static void raiseWindowAP(Widget w, XEvent *event, String *args,
3800 Cardinal *nArgs)
3802 WindowInfo *window = WidgetToWindow(w);
3803 WindowInfo *nextWindow;
3804 WindowInfo *tmpWindow;
3805 int windowIndex;
3806 Boolean focus = GetPrefFocusOnRaise();
3808 if (*nArgs > 0) {
3809 if (strcmp(args[0], "last") == 0) {
3810 window = WindowList;
3812 else if (strcmp(args[0], "first") == 0) {
3813 window = WindowList;
3814 if (window != NULL) {
3815 nextWindow = window->next;
3816 while (nextWindow != NULL) {
3817 window = nextWindow;
3818 nextWindow = nextWindow->next;
3822 else if (strcmp(args[0], "previous") == 0) {
3823 tmpWindow = window;
3824 window = WindowList;
3825 if (window != NULL) {
3826 nextWindow = window->next;
3827 while (nextWindow != NULL && nextWindow != tmpWindow) {
3828 window = nextWindow;
3829 nextWindow = nextWindow->next;
3831 if (nextWindow == NULL && tmpWindow != WindowList) {
3832 window = NULL;
3836 else if (strcmp(args[0], "next") == 0) {
3837 if (window != NULL) {
3838 window = window->next;
3839 if (window == NULL) {
3840 window = WindowList;
3844 else {
3845 if (sscanf(args[0], "%d", &windowIndex) == 1) {
3846 if (windowIndex > 0) {
3847 for (window = WindowList; window != NULL && windowIndex > 1;
3848 --windowIndex) {
3849 window = window->next;
3852 else if (windowIndex < 0) {
3853 for (window = WindowList; window != NULL;
3854 window = window->next) {
3855 ++windowIndex;
3857 if (windowIndex >= 0) {
3858 for (window = WindowList; window != NULL &&
3859 windowIndex > 0; window = window->next) {
3860 --windowIndex;
3863 else {
3864 window = NULL;
3867 else {
3868 window = NULL;
3871 else {
3872 window = NULL;
3876 if (*nArgs > 1) {
3877 if (strcmp(args[1], "focus") == 0) {
3878 focus = True;
3880 else if (strcmp(args[1], "nofocus") == 0) {
3881 focus = False;
3885 if (window != NULL) {
3886 RaiseFocusDocumentWindow(window, focus);
3888 else {
3889 XBell(TheDisplay, 0);
3893 static void focusPaneAP(Widget w, XEvent *event, String *args,
3894 Cardinal *nArgs)
3896 WindowInfo *window = WidgetToWindow(w);
3897 Widget newFocusPane = NULL;
3898 int paneIndex;
3900 if (*nArgs > 0) {
3901 if (strcmp(args[0], "first") == 0) {
3902 paneIndex = 0;
3904 else if (strcmp(args[0], "last") == 0) {
3905 paneIndex = window->nPanes;
3907 else if (strcmp(args[0], "next") == 0) {
3908 paneIndex = WidgetToPaneIndex(window, window->lastFocus) + 1;
3909 if (paneIndex > window->nPanes) {
3910 paneIndex = 0;
3913 else if (strcmp(args[0], "previous") == 0) {
3914 paneIndex = WidgetToPaneIndex(window, window->lastFocus) - 1;
3915 if (paneIndex < 0) {
3916 paneIndex = window->nPanes;
3919 else {
3920 if (sscanf(args[0], "%d", &paneIndex) == 1) {
3921 if (paneIndex > 0) {
3922 paneIndex = paneIndex - 1;
3924 else if (paneIndex < 0) {
3925 paneIndex = window->nPanes + (paneIndex + 1);
3927 else {
3928 paneIndex = -1;
3932 if (paneIndex >= 0 && paneIndex <= window->nPanes) {
3933 newFocusPane = GetPaneByIndex(window, paneIndex);
3935 if (newFocusPane != NULL) {
3936 window->lastFocus = newFocusPane;
3937 XmProcessTraversal(window->lastFocus, XmTRAVERSE_CURRENT);
3939 else {
3940 XBell(TheDisplay, 0);
3943 else {
3944 fprintf(stderr, "nedit: focus_pane requires argument\n");
3948 #define ACTION_BOOL_PARAM_OR_TOGGLE(newState, numArgs, argvVal, oValue, actionName) \
3949 if ((numArgs) > 0) { \
3950 int intState; \
3952 if (sscanf(argvVal[0], "%d", &intState) == 1) { \
3953 (newState) = (intState != 0); \
3955 else { \
3956 fprintf(stderr, "nedit: %s requires 0 or 1 argument\n", actionName); \
3957 return; \
3960 else { \
3961 (newState) = !(oValue); \
3964 static void setStatisticsLineAP(Widget w, XEvent *event, String *args,
3965 Cardinal *nArgs)
3967 WindowInfo *window = WidgetToWindow(w);
3968 Boolean newState;
3970 /* stats line is a shell-level item, so we toggle the button
3971 state regardless of it's 'topness' */
3972 ACTION_BOOL_PARAM_OR_TOGGLE(newState, *nArgs, args, window->showStats,
3973 "set_statistics_line");
3974 XmToggleButtonSetState(window->statsLineItem, newState, False);
3975 ShowStatsLine(window, newState);
3978 static void setIncrementalSearchLineAP(Widget w, XEvent *event, String *args,
3979 Cardinal *nArgs)
3981 WindowInfo *window = WidgetToWindow(w);
3982 Boolean newState;
3984 /* i-search line is a shell-level item, so we toggle the button
3985 state regardless of it's 'topness' */
3986 ACTION_BOOL_PARAM_OR_TOGGLE(newState, *nArgs, args,
3987 window->showISearchLine, "set_incremental_search_line");
3988 XmToggleButtonSetState(window->iSearchLineItem, newState, False);
3989 ShowISearchLine(window, newState);
3992 static void setShowLineNumbersAP(Widget w, XEvent *event, String *args,
3993 Cardinal *nArgs)
3995 WindowInfo *window = WidgetToWindow(w);
3996 Boolean newState;
3998 /* line numbers panel is a shell-level item, so we toggle the button
3999 state regardless of it's 'topness' */
4000 ACTION_BOOL_PARAM_OR_TOGGLE(newState, *nArgs, args,
4001 window->showLineNumbers, "set_show_line_numbers");
4002 XmToggleButtonSetState(window->lineNumsItem, newState, False);
4003 ShowLineNumbers(window, newState);
4006 static void setAutoIndentAP(Widget w, XEvent *event, String *args,
4007 Cardinal *nArgs)
4009 WindowInfo *window = WidgetToWindow(w);
4010 if (*nArgs > 0) {
4011 if (strcmp(args[0], "off") == 0) {
4012 SetAutoIndent(window, NO_AUTO_INDENT);
4014 else if (strcmp(args[0], "on") == 0) {
4015 SetAutoIndent(window, AUTO_INDENT);
4017 else if (strcmp(args[0], "smart") == 0) {
4018 SetAutoIndent(window, SMART_INDENT);
4020 else {
4021 fprintf(stderr, "nedit: set_auto_indent invalid argument\n");
4024 else {
4025 fprintf(stderr, "nedit: set_auto_indent requires argument\n");
4029 static void setWrapTextAP(Widget w, XEvent *event, String *args,
4030 Cardinal *nArgs)
4032 WindowInfo *window = WidgetToWindow(w);
4033 if (*nArgs > 0) {
4034 if (strcmp(args[0], "none") == 0) {
4035 SetAutoWrap(window, NO_WRAP);
4037 else if (strcmp(args[0], "auto") == 0) {
4038 SetAutoWrap(window, NEWLINE_WRAP);
4040 else if (strcmp(args[0], "continuous") == 0) {
4041 SetAutoWrap(window, CONTINUOUS_WRAP);
4043 else {
4044 fprintf(stderr, "nedit: set_wrap_text invalid argument\n");
4047 else {
4048 fprintf(stderr, "nedit: set_wrap_text requires argument\n");
4052 static void setWrapMarginAP(Widget w, XEvent *event, String *args,
4053 Cardinal *nArgs)
4055 WindowInfo *window = WidgetToWindow(w);
4057 if (*nArgs > 0) {
4058 int newMargin = 0;
4059 if (sscanf(args[0], "%d", &newMargin) == 1 &&
4060 newMargin >= 0 &&
4061 newMargin < 1000) {
4062 int i;
4064 XtVaSetValues(window->textArea, textNwrapMargin, newMargin, NULL);
4065 for (i = 0; i < window->nPanes; ++i) {
4066 XtVaSetValues(window->textPanes[i], textNwrapMargin, newMargin, NULL);
4069 else {
4070 fprintf(stderr,
4071 "nedit: set_wrap_margin requires integer argument >= 0 and < 1000\n");
4074 else {
4075 fprintf(stderr, "nedit: set_wrap_margin requires argument\n");
4079 static void setHighlightSyntaxAP(Widget w, XEvent *event, String *args,
4080 Cardinal *nArgs)
4082 WindowInfo *window = WidgetToWindow(w);
4083 Boolean newState;
4085 ACTION_BOOL_PARAM_OR_TOGGLE(newState, *nArgs, args, window->highlightSyntax, "set_highlight_syntax");
4087 if (IsTopDocument(window))
4088 XmToggleButtonSetState(window->highlightItem, newState, False);
4089 window->highlightSyntax = newState;
4090 if (window->highlightSyntax) {
4091 StartHighlighting(window, True);
4092 } else {
4093 StopHighlighting(window);
4097 static void setMakeBackupCopyAP(Widget w, XEvent *event, String *args,
4098 Cardinal *nArgs)
4100 WindowInfo *window = WidgetToWindow(w);
4101 Boolean newState;
4103 ACTION_BOOL_PARAM_OR_TOGGLE(newState, *nArgs, args, window->saveOldVersion, "set_make_backup_copy");
4105 #ifndef VMS
4106 if (IsTopDocument(window))
4107 XmToggleButtonSetState(window->saveLastItem, newState, False);
4108 #endif
4109 window->saveOldVersion = newState;
4112 static void setIncrementalBackupAP(Widget w, XEvent *event, String *args,
4113 Cardinal *nArgs)
4115 WindowInfo *window = WidgetToWindow(w);
4116 Boolean newState;
4118 ACTION_BOOL_PARAM_OR_TOGGLE(newState, *nArgs, args, window->autoSave, "set_incremental_backup");
4120 if (IsTopDocument(window))
4121 XmToggleButtonSetState(window->autoSaveItem, newState, False);
4122 window->autoSave = newState;
4125 static void setShowMatchingAP(Widget w, XEvent *event, String *args,
4126 Cardinal *nArgs)
4128 WindowInfo *window = WidgetToWindow(w);
4129 if (*nArgs > 0) {
4130 if (strcmp(args[0], NO_FLASH_STRING) == 0) {
4131 SetShowMatching(window, NO_FLASH);
4133 else if (strcmp(args[0], FLASH_DELIMIT_STRING) == 0) {
4134 SetShowMatching(window, FLASH_DELIMIT);
4136 else if (strcmp(args[0], FLASH_RANGE_STRING) == 0) {
4137 SetShowMatching(window, FLASH_RANGE);
4139 /* For backward compatibility with pre-5.2 versions, we also
4140 accept 0 and 1 as aliases for NO_FLASH and FLASH_DELIMIT.
4141 It is quite unlikely, though, that anyone ever used this
4142 action procedure via the macro language or a key binding,
4143 so this can probably be left out safely. */
4144 else if (strcmp(args[0], "0") == 0) {
4145 SetShowMatching(window, NO_FLASH);
4147 else if (strcmp(args[0], "1") == 0) {
4148 SetShowMatching(window, FLASH_DELIMIT);
4150 else {
4151 fprintf(stderr, "nedit: Invalid argument for set_show_matching\n");
4154 else {
4155 fprintf(stderr, "nedit: set_show_matching requires argument\n");
4159 static void setMatchSyntaxBasedAP(Widget w, XEvent *event, String *args,
4160 Cardinal *nArgs)
4162 WindowInfo *window = WidgetToWindow(w);
4163 Boolean newState;
4165 ACTION_BOOL_PARAM_OR_TOGGLE(newState, *nArgs, args, window->matchSyntaxBased, "set_match_syntax_based");
4167 if (IsTopDocument(window))
4168 XmToggleButtonSetState(window->matchSyntaxBasedItem, newState, False);
4169 window->matchSyntaxBased = newState;
4172 static void setOvertypeModeAP(Widget w, XEvent *event, String *args,
4173 Cardinal *nArgs)
4175 WindowInfo *window = WidgetToWindow(w);
4176 Boolean newState;
4178 if (window == NULL)
4179 return;
4181 ACTION_BOOL_PARAM_OR_TOGGLE(newState, *nArgs, args, window->overstrike, "set_overtype_mode");
4183 if (IsTopDocument(window))
4184 XmToggleButtonSetState(window->overtypeModeItem, newState, False);
4185 SetOverstrike(window, newState);
4188 static void setLockedAP(Widget w, XEvent *event, String *args,
4189 Cardinal *nArgs)
4191 WindowInfo *window = WidgetToWindow(w);
4192 Boolean newState;
4194 ACTION_BOOL_PARAM_OR_TOGGLE(newState, *nArgs, args, IS_USER_LOCKED(window->lockReasons), "set_locked");
4196 SET_USER_LOCKED(window->lockReasons, newState);
4197 if (IsTopDocument(window))
4198 XmToggleButtonSetState(window->readOnlyItem, IS_ANY_LOCKED(window->lockReasons), False);
4199 UpdateWindowTitle(window);
4200 UpdateWindowReadOnly(window);
4203 static void setTabDistAP(Widget w, XEvent *event, String *args,
4204 Cardinal *nArgs)
4206 WindowInfo *window = WidgetToWindow(w);
4208 if (*nArgs > 0) {
4209 int newTabDist = 0;
4210 if (sscanf(args[0], "%d", &newTabDist) == 1 &&
4211 newTabDist > 0 &&
4212 newTabDist <= MAX_EXP_CHAR_LEN) {
4213 SetTabDist(window, newTabDist);
4215 else {
4216 fprintf(stderr,
4217 "nedit: set_tab_dist requires integer argument > 0 and <= %d\n",
4218 MAX_EXP_CHAR_LEN);
4221 else {
4222 fprintf(stderr, "nedit: set_tab_dist requires argument\n");
4226 static void setEmTabDistAP(Widget w, XEvent *event, String *args,
4227 Cardinal *nArgs)
4229 WindowInfo *window = WidgetToWindow(w);
4231 if (*nArgs > 0) {
4232 int newEmTabDist = 0;
4233 if (sscanf(args[0], "%d", &newEmTabDist) == 1 &&
4234 newEmTabDist >= -1 &&
4235 newEmTabDist < 1000) {
4236 if (newEmTabDist < 0) {
4237 newEmTabDist = 0;
4239 SetEmTabDist(window, newEmTabDist);
4241 else {
4242 fprintf(stderr,
4243 "nedit: set_em_tab_dist requires integer argument >= -1 and < 1000\n");
4246 else {
4247 fprintf(stderr, "nedit: set_em_tab_dist requires argument\n");
4251 static void setUseTabsAP(Widget w, XEvent *event, String *args,
4252 Cardinal *nArgs)
4254 WindowInfo *window = WidgetToWindow(w);
4255 Boolean newState;
4257 ACTION_BOOL_PARAM_OR_TOGGLE(newState, *nArgs, args, window->buffer->useTabs, "set_use_tabs");
4259 window->buffer->useTabs = newState;
4262 static void setFontsAP(Widget w, XEvent *event, String *args,
4263 Cardinal *nArgs)
4265 WindowInfo *window = WidgetToWindow(w);
4266 if (*nArgs >= 4) {
4267 SetFonts(window, args[0], args[1], args[2], args[3]);
4269 else {
4270 fprintf(stderr, "nedit: set_fonts requires 4 arguments\n");
4274 static void setLanguageModeAP(Widget w, XEvent *event, String *args,
4275 Cardinal *nArgs)
4277 WindowInfo *window = WidgetToWindow(w);
4279 if (*nArgs > 0) {
4280 SetLanguageMode(window, FindLanguageMode(args[0]), FALSE);
4282 else {
4283 fprintf(stderr, "nedit: set_language_mode requires argument\n");
4288 ** Same as AddSubMenu from libNUtil.a but 1) mnemonic is optional (NEdit
4289 ** users like to be able to re-arrange the mnemonics so they can set Alt
4290 ** key combinations as accelerators), 2) supports the short/full option
4291 ** of SGI_CUSTOM mode, 3) optionally returns the cascade button widget
4292 ** in "cascadeBtn" if "cascadeBtn" is non-NULL.
4294 static Widget createMenu(Widget parent, char *name, char *label,
4295 char mnemonic, Widget *cascadeBtn, int mode)
4297 Widget menu, cascade;
4298 XmString st1;
4300 menu = CreatePulldownMenu(parent, name, NULL, 0);
4301 cascade = XtVaCreateWidget(name, xmCascadeButtonWidgetClass, parent,
4302 XmNlabelString, st1=XmStringCreateSimple(label),
4303 XmNsubMenuId, menu, NULL);
4304 XmStringFree(st1);
4305 if (mnemonic != 0)
4306 XtVaSetValues(cascade, XmNmnemonic, mnemonic, NULL);
4307 #ifdef SGI_CUSTOM
4308 if (mode == SHORT || !GetPrefShortMenus())
4309 XtManageChild(cascade);
4310 if (mode == FULL)
4311 addToToggleShortList(cascade);
4312 #else
4313 XtManageChild(cascade);
4314 #endif
4315 if (cascadeBtn != NULL)
4316 *cascadeBtn = cascade;
4317 return menu;
4321 ** Same as AddMenuItem from libNUtil.a without setting the accelerator
4322 ** (these are set in the fallback app-defaults so users can change them),
4323 ** and with the short/full option required in SGI_CUSTOM mode.
4325 static Widget createMenuItem(Widget parent, char *name, char *label,
4326 char mnemonic, menuCallbackProc callback, void *cbArg, int mode)
4328 Widget button;
4329 XmString st1;
4332 button = XtVaCreateWidget(name, xmPushButtonWidgetClass, parent,
4333 XmNlabelString, st1=XmStringCreateSimple(label),
4334 XmNmnemonic, mnemonic, NULL);
4335 XtAddCallback(button, XmNactivateCallback, (XtCallbackProc)callback, cbArg);
4336 XmStringFree(st1);
4337 #ifdef SGI_CUSTOM
4338 if (mode == SHORT || !GetPrefShortMenus())
4339 XtManageChild(button);
4340 if (mode == FULL)
4341 addToToggleShortList(button);
4342 XtVaSetValues(button, XmNuserData, PERMANENT_MENU_ITEM, NULL);
4343 #else
4344 XtManageChild(button);
4345 #endif
4346 return button;
4350 ** "fake" menu items allow accelerators to be attached, but don't show up
4351 ** in the menu. They are necessary to process the shifted menu items because
4352 ** Motif does not properly process the event descriptions in accelerator
4353 ** resources, and you can't specify "shift key is optional"
4355 static Widget createFakeMenuItem(Widget parent, char *name,
4356 menuCallbackProc callback, void *cbArg)
4358 Widget button;
4359 XmString st1;
4361 button = XtVaCreateManagedWidget(name, xmPushButtonWidgetClass, parent,
4362 XmNlabelString, st1=XmStringCreateSimple(""),
4363 XmNshadowThickness, 0,
4364 XmNmarginHeight, 0,
4365 XmNheight, 0, NULL);
4366 XtAddCallback(button, XmNactivateCallback, (XtCallbackProc)callback, cbArg);
4367 XmStringFree(st1);
4368 XtVaSetValues(button, XmNtraversalOn, False, NULL);
4370 return button;
4374 ** Add a toggle button item to an already established pull-down or pop-up
4375 ** menu, including mnemonics, accelerators and callbacks.
4377 static Widget createMenuToggle(Widget parent, char *name, char *label,
4378 char mnemonic, menuCallbackProc callback, void *cbArg, int set,
4379 int mode)
4381 Widget button;
4382 XmString st1;
4384 button = XtVaCreateWidget(name, xmToggleButtonWidgetClass, parent,
4385 XmNlabelString, st1=XmStringCreateSimple(label),
4386 XmNmnemonic, mnemonic,
4387 XmNset, set, NULL);
4388 XtAddCallback(button, XmNvalueChangedCallback, (XtCallbackProc)callback,
4389 cbArg);
4390 XmStringFree(st1);
4391 #ifdef SGI_CUSTOM
4392 if (mode == SHORT || !GetPrefShortMenus())
4393 XtManageChild(button);
4394 if (mode == FULL)
4395 addToToggleShortList(button);
4396 XtVaSetValues(button, XmNuserData, PERMANENT_MENU_ITEM, NULL);
4397 #else
4398 XtManageChild(button);
4399 #endif
4400 return button;
4404 ** Create a toggle button with a diamond (radio-style) appearance
4406 static Widget createMenuRadioToggle(Widget parent, char *name, char *label,
4407 char mnemonic, menuCallbackProc callback, void *cbArg, int set,
4408 int mode)
4410 Widget button;
4411 button = createMenuToggle(parent, name, label, mnemonic, callback, cbArg,
4412 set, mode);
4413 XtVaSetValues(button, XmNindicatorType, XmONE_OF_MANY, NULL);
4414 return button;
4417 static Widget createMenuSeparator(Widget parent, char *name, int mode)
4419 Widget button;
4421 button = XmCreateSeparator(parent, name, NULL, 0);
4422 #ifdef SGI_CUSTOM
4423 if (mode == SHORT || !GetPrefShortMenus())
4424 XtManageChild(button);
4425 if (mode == FULL)
4426 addToToggleShortList(button);
4427 XtVaSetValues(button, XmNuserData, PERMANENT_MENU_ITEM, NULL);
4428 #else
4429 XtManageChild(button);
4430 #endif
4431 return button;
4435 ** Make sure the close menu item is dimmed appropriately for the current
4436 ** set of windows. It should be dim only for the last Untitled, unmodified,
4437 ** editor window, and sensitive otherwise.
4439 void CheckCloseDim(void)
4441 WindowInfo *window;
4443 if (WindowList == NULL)
4444 return;
4445 if (WindowList->next==NULL &&
4446 !WindowList->filenameSet && !WindowList->fileChanged) {
4447 XtSetSensitive(WindowList->closeItem, FALSE);
4448 return;
4451 for (window=WindowList; window!=NULL; window=window->next) {
4452 if (!IsTopDocument(window))
4453 continue;
4454 XtSetSensitive(window->closeItem, True);
4459 ** Invalidate the Window menus of all NEdit windows to but don't change
4460 ** the menus until they're needed (Originally, this was "UpdateWindowMenus",
4461 ** but creating and destroying manu items for every window every time a
4462 ** new window was created or something changed, made things move very
4463 ** slowly with more than 10 or so windows).
4465 void InvalidateWindowMenus(void)
4467 WindowInfo *w;
4469 /* Mark the window menus invalid (to be updated when the user pulls one
4470 down), unless the menu is torn off, meaning it is visible to the user
4471 and should be updated immediately */
4472 for (w=WindowList; w!=NULL; w=w->next) {
4473 if (!XmIsMenuShell(XtParent(w->windowMenuPane)))
4474 updateWindowMenu(w);
4475 else
4476 w->windowMenuValid = False;
4481 ** Mark the Previously Opened Files menus of all NEdit windows as invalid.
4482 ** Since actually changing the menus is slow, they're just marked and updated
4483 ** when the user pulls one down.
4485 static void invalidatePrevOpenMenus(void)
4487 WindowInfo *w;
4489 /* Mark the menus invalid (to be updated when the user pulls one
4490 down), unless the menu is torn off, meaning it is visible to the user
4491 and should be updated immediately */
4492 for (w=WindowList; w!=NULL; w=w->next) {
4493 if (!XmIsMenuShell(XtParent(w->prevOpenMenuPane)))
4494 updatePrevOpenMenu(w);
4499 ** Add a file to the list of previously opened files for display in the
4500 ** File menu.
4502 void AddToPrevOpenMenu(const char *filename)
4504 int i;
4505 char *nameCopy;
4506 WindowInfo *w;
4508 /* If the Open Previous command is disabled, just return */
4509 if (GetPrefMaxPrevOpenFiles() < 1) {
4510 return;
4513 /* Refresh list of previously opened files to avoid Big Race Condition,
4514 where two sessions overwrite each other's changes in NEdit's
4515 history file.
4516 Of course there is still Little Race Condition, which occurs if a
4517 Session A reads the list, then Session B reads the list and writes
4518 it before Session A gets a chance to write. */
4519 ReadNEditDB();
4521 /* If the name is already in the list, move it to the start */
4522 for (i=0; i<NPrevOpen; i++) {
4523 if (!strcmp(filename, PrevOpen[i])) {
4524 nameCopy = PrevOpen[i];
4525 memmove(&PrevOpen[1], &PrevOpen[0], sizeof(char *) * i);
4526 PrevOpen[0] = nameCopy;
4527 invalidatePrevOpenMenus();
4528 WriteNEditDB();
4529 return;
4533 /* If the list is already full, make room */
4534 if (NPrevOpen >= GetPrefMaxPrevOpenFiles()) {
4535 /* This is only safe if GetPrefMaxPrevOpenFiles() > 0. */
4536 XtFree(PrevOpen[--NPrevOpen]);
4539 /* Add it to the list */
4540 nameCopy = XtMalloc(strlen(filename) + 1);
4541 strcpy(nameCopy, filename);
4542 memmove(&PrevOpen[1], &PrevOpen[0], sizeof(char *) * NPrevOpen);
4543 PrevOpen[0] = nameCopy;
4544 NPrevOpen++;
4546 /* Mark the Previously Opened Files menu as invalid in all windows */
4547 invalidatePrevOpenMenus();
4549 /* Undim the menu in all windows if it was previously empty */
4550 if (NPrevOpen > 0) {
4551 for (w=WindowList; w!=NULL; w=w->next) {
4552 if (!IsTopDocument(w))
4553 continue;
4554 XtSetSensitive(w->prevOpenMenuItem, True);
4558 /* Write the menu contents to disk to restore in later sessions */
4559 WriteNEditDB();
4562 static char* getWindowsMenuEntry(const WindowInfo* window)
4564 static char fullTitle[MAXPATHLEN * 2 + 3+ 1];
4566 sprintf(fullTitle, "%s%s", window->filename,
4567 window->fileChanged? "*" : "");
4569 if (GetPrefShowPathInWindowsMenu() && window->filenameSet)
4571 strcat(fullTitle, " - ");
4572 strcat(fullTitle, window->path);
4575 return(fullTitle);
4579 ** Update the Window menu of a single window to reflect the current state of
4580 ** all NEdit windows as determined by the global WindowList.
4582 static void updateWindowMenu(const WindowInfo *window)
4584 WindowInfo *w;
4585 WidgetList items;
4586 Cardinal nItems;
4587 int i, n, nWindows, windowIndex;
4588 WindowInfo **windows;
4590 if (!IsTopDocument(window))
4591 return;
4593 /* Make a sorted list of windows */
4594 /* windows = MakeSortedWindowArray();*/
4595 for (w=WindowList, nWindows=0; w!=NULL; w=w->next, nWindows++);
4596 windows = (WindowInfo **)XtMalloc(sizeof(WindowInfo *) * nWindows);
4597 for (w=WindowList, i=0; w!=NULL; w=w->next, i++)
4598 windows[i] = w;
4599 qsort(windows, nWindows, sizeof(WindowInfo *), compareWindowNames);
4601 /* if the menu is torn off, unmanage the menu pane
4602 before updating it to prevent the tear-off menu
4603 from shrinking/expanding as the menu entries
4604 are added */
4605 if (!XmIsMenuShell(XtParent(window->windowMenuPane)))
4606 XtUnmanageChild(window->windowMenuPane);
4608 /* While it is not possible on some systems (ibm at least) to substitute
4609 a new menu pane, it is possible to substitute menu items, as long as
4610 at least one remains in the menu at all times. This routine assumes
4611 that the menu contains permanent items marked with the value
4612 PERMANENT_MENU_ITEM in the userData resource, and adds and removes items
4613 which it marks with the value TEMPORARY_MENU_ITEM */
4615 /* Go thru all of the items in the menu and rename them to
4616 match the window list. Delete any extras */
4617 XtVaGetValues(window->windowMenuPane, XmNchildren, &items,
4618 XmNnumChildren, &nItems, NULL);
4619 windowIndex = 0;
4620 nWindows = NWindows();
4621 for (n=0; n<(int)nItems; n++) {
4622 XtPointer userData;
4623 XtVaGetValues(items[n], XmNuserData, &userData, NULL);
4624 if (userData == TEMPORARY_MENU_ITEM) {
4625 if (windowIndex >= nWindows) {
4626 /* unmanaging before destroying stops parent from displaying */
4627 XtUnmanageChild(items[n]);
4628 XtDestroyWidget(items[n]);
4629 } else {
4630 XmString st1;
4631 char* title = getWindowsMenuEntry(windows[windowIndex]);
4632 XtVaSetValues(items[n], XmNlabelString,
4633 st1=XmStringCreateSimple(title), NULL);
4634 XtRemoveAllCallbacks(items[n], XmNactivateCallback);
4635 XtAddCallback(items[n], XmNactivateCallback,
4636 (XtCallbackProc)raiseCB, windows[windowIndex]);
4637 XmStringFree(st1);
4638 windowIndex++;
4643 /* Add new items for the titles of the remaining windows to the menu */
4644 for (; windowIndex<nWindows; windowIndex++) {
4645 XmString st1;
4646 char* title = getWindowsMenuEntry(windows[windowIndex]);
4647 Widget btn = XtVaCreateManagedWidget("win", xmPushButtonWidgetClass,
4648 window->windowMenuPane,
4649 XmNlabelString, st1=XmStringCreateSimple(title),
4650 XmNmarginHeight, 0,
4651 XmNuserData, TEMPORARY_MENU_ITEM, NULL);
4652 XtAddCallback(btn, XmNactivateCallback, (XtCallbackProc)raiseCB,
4653 windows[windowIndex]);
4654 XmStringFree(st1);
4656 XtFree((char *)windows);
4658 /* if the menu is torn off, we need to manually adjust the
4659 dimension of the menuShell _before_ re-managing the menu
4660 pane, to either expose the hidden menu entries or remove
4661 the empty space */
4662 if (!XmIsMenuShell(XtParent(window->windowMenuPane))) {
4663 Dimension width, height;
4665 XtVaGetValues(window->windowMenuPane, XmNwidth, &width,
4666 XmNheight, &height, NULL);
4667 XtVaSetValues(XtParent(window->windowMenuPane), XmNwidth, width,
4668 XmNheight, height, NULL);
4669 XtManageChild(window->windowMenuPane);
4674 ** Update the Previously Opened Files menu of a single window to reflect the
4675 ** current state of the list as retrieved from FIXME.
4676 ** Thanks to Markus Schwarzenberg for the sorting part.
4678 static void updatePrevOpenMenu(WindowInfo *window)
4680 Widget btn;
4681 WidgetList items;
4682 Cardinal nItems;
4683 int n, index;
4684 XmString st1;
4685 char **prevOpenSorted;
4687 /* Read history file to get entries written by other sessions. */
4688 ReadNEditDB();
4690 /* Sort the previously opened file list if requested */
4691 prevOpenSorted = (char **)XtMalloc(NPrevOpen * sizeof(char*));
4692 memcpy(prevOpenSorted, PrevOpen, NPrevOpen * sizeof(char*));
4693 if (GetPrefSortOpenPrevMenu())
4694 qsort(prevOpenSorted, NPrevOpen, sizeof(char*), cmpStrPtr);
4696 /* Go thru all of the items in the menu and rename them to match the file
4697 list. In older Motifs (particularly ibm), it was dangerous to replace
4698 a whole menu pane, which would be much simpler. However, since the
4699 code was already written for the Windows menu and is well tested, I'll
4700 stick with this weird method of re-naming the items */
4701 XtVaGetValues(window->prevOpenMenuPane, XmNchildren, &items,
4702 XmNnumChildren, &nItems, NULL);
4703 index = 0;
4704 for (n=0; n<(int)nItems; n++) {
4705 if (index >= NPrevOpen) {
4706 /* unmanaging before destroying stops parent from displaying */
4707 XtUnmanageChild(items[n]);
4708 XtDestroyWidget(items[n]);
4709 } else {
4710 XtVaSetValues(items[n], XmNlabelString,
4711 st1=XmStringCreateSimple(prevOpenSorted[index]), NULL);
4712 XtRemoveAllCallbacks(items[n], XmNactivateCallback);
4713 XtAddCallback(items[n], XmNactivateCallback,
4714 (XtCallbackProc)openPrevCB, prevOpenSorted[index]);
4715 XmStringFree(st1);
4716 index++;
4720 /* Add new items for the remaining file names to the menu */
4721 for (; index<NPrevOpen; index++) {
4722 btn = XtVaCreateManagedWidget("win", xmPushButtonWidgetClass,
4723 window->prevOpenMenuPane,
4724 XmNlabelString, st1=XmStringCreateSimple(prevOpenSorted[index]),
4725 XmNmarginHeight, 0,
4726 XmNuserData, TEMPORARY_MENU_ITEM, NULL);
4727 XtAddCallback(btn, XmNactivateCallback, (XtCallbackProc)openPrevCB,
4728 prevOpenSorted[index]);
4729 XmStringFree(st1);
4732 XtFree((char*)prevOpenSorted);
4736 ** This function manages the display of the Tags File Menu, which is displayed
4737 ** when the user selects Un-load Tags File.
4739 static void updateTagsFileMenu(WindowInfo *window)
4741 tagFile *tf;
4742 Widget btn;
4743 WidgetList items;
4744 Cardinal nItems;
4745 int n;
4746 XmString st1;
4748 /* Go thru all of the items in the menu and rename them to match the file
4749 list. In older Motifs (particularly ibm), it was dangerous to replace
4750 a whole menu pane, which would be much simpler. However, since the
4751 code was already written for the Windows menu and is well tested, I'll
4752 stick with this weird method of re-naming the items */
4753 XtVaGetValues(window->unloadTagsMenuPane, XmNchildren, &items,
4754 XmNnumChildren, &nItems, NULL);
4755 tf = TagsFileList;
4756 for (n=0; n<(int)nItems; n++) {
4757 if (!tf) {
4758 /* unmanaging before destroying stops parent from displaying */
4759 XtUnmanageChild(items[n]);
4760 XtDestroyWidget(items[n]);
4761 } else {
4762 XtVaSetValues(items[n], XmNlabelString,
4763 st1=XmStringCreateSimple(tf->filename), NULL);
4764 XtRemoveAllCallbacks(items[n], XmNactivateCallback);
4765 XtAddCallback(items[n], XmNactivateCallback,
4766 (XtCallbackProc)unloadTagsFileCB, tf->filename);
4767 XmStringFree(st1);
4768 tf = tf->next;
4772 /* Add new items for the remaining file names to the menu */
4773 while (tf) {
4774 btn = XtVaCreateManagedWidget("win", xmPushButtonWidgetClass,
4775 window->unloadTagsMenuPane, XmNlabelString,
4776 st1=XmStringCreateSimple(tf->filename),XmNmarginHeight, 0,
4777 XmNuserData, TEMPORARY_MENU_ITEM, NULL);
4778 XtAddCallback(btn, XmNactivateCallback,
4779 (XtCallbackProc)unloadTagsFileCB, tf->filename);
4780 XmStringFree(st1);
4781 tf = tf->next;
4786 ** This function manages the display of the Tips File Menu, which is displayed
4787 ** when the user selects Un-load Calltips File.
4789 static void updateTipsFileMenu(WindowInfo *window)
4791 tagFile *tf;
4792 Widget btn;
4793 WidgetList items;
4794 Cardinal nItems;
4795 int n;
4796 XmString st1;
4798 /* Go thru all of the items in the menu and rename them to match the file
4799 list. In older Motifs (particularly ibm), it was dangerous to replace
4800 a whole menu pane, which would be much simpler. However, since the
4801 code was already written for the Windows menu and is well tested, I'll
4802 stick with this weird method of re-naming the items */
4803 XtVaGetValues(window->unloadTipsMenuPane, XmNchildren, &items,
4804 XmNnumChildren, &nItems, NULL);
4805 tf = TipsFileList;
4806 for (n=0; n<(int)nItems; n++) {
4807 if (!tf) {
4808 /* unmanaging before destroying stops parent from displaying */
4809 XtUnmanageChild(items[n]);
4810 XtDestroyWidget(items[n]);
4811 } else {
4812 XtVaSetValues(items[n], XmNlabelString,
4813 st1=XmStringCreateSimple(tf->filename), NULL);
4814 XtRemoveAllCallbacks(items[n], XmNactivateCallback);
4815 XtAddCallback(items[n], XmNactivateCallback,
4816 (XtCallbackProc)unloadTipsFileCB, tf->filename);
4817 XmStringFree(st1);
4818 tf = tf->next;
4822 /* Add new items for the remaining file names to the menu */
4823 while (tf) {
4824 btn = XtVaCreateManagedWidget("win", xmPushButtonWidgetClass,
4825 window->unloadTipsMenuPane, XmNlabelString,
4826 st1=XmStringCreateSimple(tf->filename),XmNmarginHeight, 0,
4827 XmNuserData, TEMPORARY_MENU_ITEM, NULL);
4828 XtAddCallback(btn, XmNactivateCallback,
4829 (XtCallbackProc)unloadTipsFileCB, tf->filename);
4830 XmStringFree(st1);
4831 tf = tf->next;
4836 ** Comparison function for sorting file names for the Open Previous submenu
4838 static int cmpStrPtr(const void *strA, const void *strB)
4840 return strcmp(*((char**)strA), *((char**)strB));
4843 #ifdef VMS
4844 static char neditDBBadFilenameChars[] = "\n\t*?(){}!@#%&' ";
4845 #else
4846 static char neditDBBadFilenameChars[] = "\n";
4847 #endif
4850 ** Write dynamic database of file names for "Open Previous". Eventually,
4851 ** this may hold window positions, and possibly file marks, in which case,
4852 ** it should be moved to a different module, but for now it's just a list
4853 ** of previously opened files.
4855 void WriteNEditDB(void)
4857 const char* fullName = GetRCFileName(NEDIT_HISTORY);
4858 FILE *fp;
4859 int i;
4860 static char fileHeader[] =
4861 "# File name database for NEdit Open Previous command\n";
4863 if (fullName == NULL) {
4864 /* GetRCFileName() might return NULL if an error occurs during
4865 creation of the preference file directory. */
4866 return;
4869 /* If the Open Previous command is disabled, just return */
4870 if (GetPrefMaxPrevOpenFiles() < 1) {
4871 return;
4874 /* open the file */
4875 if ((fp = fopen(fullName, "w")) == NULL) {
4876 #ifdef VMS
4877 /* When the version number, ";1" is specified as part of the file
4878 name, fopen(fullName, "w"), will only open for writing if the
4879 file does not exist. Using, fopen(fullName, "r+"), opens an
4880 existing file for "update" - read/write pointer is placed at the
4881 beginning of file.
4882 By calling ftruncate(), we discard the old contents and avoid
4883 trailing garbage in the file if the new contents is shorter. */
4884 if ((fp = fopen(fullName, "r+")) == NULL) {
4885 return;
4887 if (ftruncate(fileno(fp), 0) != 0) {
4888 fclose(fp);
4889 return;
4891 #else
4892 return;
4893 #endif
4896 /* write the file header text to the file */
4897 fprintf(fp, "%s", fileHeader);
4899 /* Write the list of file names */
4900 for (i = 0; i < NPrevOpen; ++i) {
4901 size_t lineLen = strlen(PrevOpen[i]);
4903 if (lineLen > 0 && PrevOpen[i][0] != '#' &&
4904 strcspn(PrevOpen[i], neditDBBadFilenameChars) == lineLen) {
4905 fprintf(fp, "%s\n", PrevOpen[i]);
4909 fclose(fp);
4913 ** Read database of file names for 'Open Previous' submenu.
4915 ** Eventually, this may hold window positions, and possibly file marks (in
4916 ** which case it should be moved to a different module) but for now it's
4917 ** just a list of previously opened files.
4919 ** This list is read once at startup and potentially refreshed before a
4920 ** new entry is about to be written to the file or before the menu is
4921 ** displayed. If the file is modified since the last read (or not read
4922 ** before), it is read in, otherwise nothing is done.
4924 void ReadNEditDB(void)
4926 const char *fullName = GetRCFileName(NEDIT_HISTORY);
4927 char line[MAXPATHLEN + 2];
4928 char *nameCopy;
4929 struct stat attribute;
4930 FILE *fp;
4931 size_t lineLen;
4932 static time_t lastNeditdbModTime = 0;
4934 /* If the Open Previous command is disabled or the user set the
4935 resource to an (invalid) negative value, just return. */
4936 if (GetPrefMaxPrevOpenFiles() < 1) {
4937 return;
4940 /* Initialize the files list and allocate a (permanent) block memory
4941 of the size prescribed by the maxPrevOpenFiles resource */
4942 if (!PrevOpen) {
4943 PrevOpen = (char**) XtMalloc(sizeof(char*) * GetPrefMaxPrevOpenFiles());
4944 NPrevOpen = 0;
4947 /* Don't move this check ahead of the previous statements. PrevOpen
4948 must be initialized at all times. */
4949 if (fullName == NULL)
4951 /* GetRCFileName() might return NULL if an error occurs during
4952 creation of the preference file directory. */
4953 return;
4956 /* Stat history file to see whether someone touched it after this
4957 session last changed it. */
4958 if (0 == stat(fullName, &attribute)) {
4959 if (lastNeditdbModTime >= attribute.st_mtime) {
4960 /* Do nothing, history file is unchanged. */
4961 return;
4962 } else {
4963 /* Memorize modtime to compare to next time. */
4964 lastNeditdbModTime = attribute.st_mtime;
4966 } else {
4967 /* stat() failed, probably for non-exiting history database. */
4968 if (ENOENT != errno)
4970 perror("nedit: Error reading history database");
4972 return;
4975 /* open the file */
4976 if ((fp = fopen(fullName, "r")) == NULL) {
4977 return;
4980 /* Clear previous list. */
4981 while (0 != NPrevOpen) {
4982 XtFree(PrevOpen[--NPrevOpen]);
4985 /* read lines of the file, lines beginning with # are considered to be
4986 comments and are thrown away. Lines are subject to cursory checking,
4987 then just copied to the Open Previous file menu list */
4988 while (True) {
4989 if (fgets(line, sizeof(line), fp) == NULL) {
4990 /* end of file */
4991 fclose(fp);
4992 return;
4994 if (line[0] == '#') {
4995 /* comment */
4996 continue;
4998 lineLen = strlen(line);
4999 if (lineLen == 0) {
5000 /* blank line */
5001 continue;
5003 if (line[lineLen - 1] != '\n') {
5004 /* no newline, probably truncated */
5005 fprintf(stderr, "nedit: Line too long in history file\n");
5006 while (fgets(line, sizeof(line), fp) != NULL) {
5007 lineLen = strlen(line);
5008 if (lineLen > 0 && line[lineLen - 1] == '\n') {
5009 break;
5012 continue;
5014 line[--lineLen] = '\0';
5015 if (strcspn(line, neditDBBadFilenameChars) != lineLen) {
5016 /* non-filename characters */
5017 fprintf(stderr, "nedit: History file may be corrupted\n");
5018 continue;
5020 nameCopy = XtMalloc(lineLen + 1);
5021 strcpy(nameCopy, line);
5022 PrevOpen[NPrevOpen++] = nameCopy;
5023 if (NPrevOpen >= GetPrefMaxPrevOpenFiles()) {
5024 /* too many entries */
5025 fclose(fp);
5026 return;
5031 static void setWindowSizeDefault(int rows, int cols)
5033 SetPrefRows(rows);
5034 SetPrefCols(cols);
5035 updateWindowSizeMenus();
5038 static void updateWindowSizeMenus(void)
5040 WindowInfo *win;
5042 for (win=WindowList; win!=NULL; win=win->next)
5043 updateWindowSizeMenu(win);
5046 static void updateWindowSizeMenu(WindowInfo *win)
5048 int rows = GetPrefRows(), cols = GetPrefCols();
5049 char title[50];
5050 XmString st1;
5052 if (!IsTopDocument(win))
5053 return;
5055 XmToggleButtonSetState(win->size24x80DefItem, rows==24&&cols==80,False);
5056 XmToggleButtonSetState(win->size40x80DefItem, rows==40&&cols==80,False);
5057 XmToggleButtonSetState(win->size60x80DefItem, rows==60&&cols==80,False);
5058 XmToggleButtonSetState(win->size80x80DefItem, rows==80&&cols==80,False);
5059 if ((rows!=24 && rows!=40 && rows!=60 && rows!=80) || cols!=80) {
5060 XmToggleButtonSetState(win->sizeCustomDefItem, True, False);
5061 sprintf(title, "Custom... (%d x %d)", rows, cols);
5062 XtVaSetValues(win->sizeCustomDefItem,
5063 XmNlabelString, st1=XmStringCreateSimple(title), NULL);
5064 XmStringFree(st1);
5065 } else {
5066 XmToggleButtonSetState(win->sizeCustomDefItem, False, False);
5067 XtVaSetValues(win->sizeCustomDefItem,
5068 XmNlabelString, st1=XmStringCreateSimple("Custom..."), NULL);
5069 XmStringFree(st1);
5074 ** Scans action argument list for arguments "forward" or "backward" to
5075 ** determine search direction for search and replace actions. "ignoreArgs"
5076 ** tells the routine how many required arguments there are to ignore before
5077 ** looking for keywords
5079 static int searchDirection(int ignoreArgs, String *args, Cardinal *nArgs)
5081 int i;
5083 for (i=ignoreArgs; i<(int)*nArgs; i++) {
5084 if (!strCaseCmp(args[i], "forward"))
5085 return SEARCH_FORWARD;
5086 if (!strCaseCmp(args[i], "backward"))
5087 return SEARCH_BACKWARD;
5089 return SEARCH_FORWARD;
5093 ** Scans action argument list for arguments "keep" or "nokeep" to
5094 ** determine whether to keep dialogs up for search and replace. "ignoreArgs"
5095 ** tells the routine how many required arguments there are to ignore before
5096 ** looking for keywords
5098 static int searchKeepDialogs(int ignoreArgs, String *args, Cardinal *nArgs)
5100 int i;
5102 for (i=ignoreArgs; i<(int)*nArgs; i++) {
5103 if (!strCaseCmp(args[i], "keep"))
5104 return TRUE;
5105 if (!strCaseCmp(args[i], "nokeep"))
5106 return FALSE;
5108 return GetPrefKeepSearchDlogs();
5112 ** Scans action argument list for arguments "wrap" or "nowrap" to
5113 ** determine search direction for search and replace actions. "ignoreArgs"
5114 ** tells the routine how many required arguments there are to ignore before
5115 ** looking for keywords
5117 static int searchWrap(int ignoreArgs, String *args, Cardinal *nArgs)
5119 int i;
5121 for (i=ignoreArgs; i<(int)*nArgs; i++) {
5122 if (!strCaseCmp(args[i], "wrap"))
5123 return(TRUE);
5124 if (!strCaseCmp(args[i], "nowrap"))
5125 return(FALSE);
5127 return GetPrefSearchWraps();
5131 ** Scans action argument list for arguments "literal", "case" or "regex" to
5132 ** determine search type for search and replace actions. "ignoreArgs"
5133 ** tells the routine how many required arguments there are to ignore before
5134 ** looking for keywords
5136 static int searchType(int ignoreArgs, String *args, Cardinal *nArgs)
5138 int i, tmpSearchType;
5140 for (i=ignoreArgs; i<(int)*nArgs; i++) {
5141 if (StringToSearchType(args[i], &tmpSearchType))
5142 return tmpSearchType;
5144 return GetPrefSearch();
5148 ** Return a pointer to the string describing search direction for search action
5149 ** routine parameters given a callback XmAnyCallbackStruct pointed to by
5150 ** "callData", by checking if the shift key is pressed (for search callbacks).
5152 static char **shiftKeyToDir(XtPointer callData)
5154 static char *backwardParam[1] = {"backward"};
5155 static char *forwardParam[1] = {"forward"};
5156 if (((XmAnyCallbackStruct *)callData)->event->xbutton.state & ShiftMask)
5157 return backwardParam;
5158 return forwardParam;
5161 static void raiseCB(Widget w, WindowInfo *window, caddr_t callData)
5163 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
5164 ((XmAnyCallbackStruct *)callData)->event);
5165 RaiseFocusDocumentWindow(window, True /* always focus */);
5168 static void openPrevCB(Widget w, char *name, caddr_t callData)
5170 char *params[1];
5171 Widget menu = MENU_WIDGET(w);
5173 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
5174 ((XmAnyCallbackStruct *)callData)->event);
5175 params[0] = name;
5176 XtCallActionProc(WidgetToWindow(menu)->lastFocus, "open",
5177 ((XmAnyCallbackStruct *)callData)->event, params, 1);
5178 CheckCloseDim();
5181 static void unloadTagsFileCB(Widget w, char *name, caddr_t callData)
5183 char *params[1];
5184 Widget menu = MENU_WIDGET(w);
5186 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
5187 ((XmAnyCallbackStruct *)callData)->event);
5188 params[0] = name;
5189 XtCallActionProc(WidgetToWindow(menu)->lastFocus, "unload_tags_file",
5190 ((XmAnyCallbackStruct *)callData)->event, params, 1);
5193 static void unloadTipsFileCB(Widget w, char *name, caddr_t callData)
5195 char *params[1];
5196 #if XmVersion >= 1002
5197 Widget menu = XmGetPostedFromWidget(XtParent(w)); /* If menu is torn off */
5198 #else
5199 Widget menu = w;
5200 #endif
5202 params[0] = name;
5203 XtCallActionProc(WidgetToWindow(menu)->lastFocus, "unload_tips_file",
5204 ((XmAnyCallbackStruct *)callData)->event, params, 1);
5208 ** strCaseCmp compares its arguments and returns 0 if the two strings
5209 ** are equal IGNORING case differences. Otherwise returns 1.
5211 static int strCaseCmp(const char *str1, const char *str2)
5213 const char *c1, *c2;
5215 for (c1=str1, c2=str2; *c1!='\0' && *c2!='\0'; c1++, c2++)
5216 if (toupper((unsigned char)*c1) != toupper((unsigned char)*c2))
5217 return 1;
5218 if (*c1 == *c2) {
5219 return(0);
5221 else {
5222 return(1);
5227 ** Comparison function for sorting windows by title for the window menu.
5228 ** Windows are sorted by Untitled and then alphabetically by filename and
5229 ** then alphabetically by path.
5231 static int compareWindowNames(const void *windowA, const void *windowB)
5233 int rc;
5234 const WindowInfo *a = *((WindowInfo**)windowA);
5235 const WindowInfo *b = *((WindowInfo**)windowB);
5236 /* Untitled first */
5237 rc = a->filenameSet == b->filenameSet ? 0 :
5238 a->filenameSet && !b->filenameSet ? 1 : -1;
5239 if (rc != 0)
5240 return rc;
5241 rc = strcmp(a->filename, b->filename);
5242 if (rc != 0)
5243 return rc;
5244 rc = strcmp(a->path, b->path);
5245 return rc;
5248 static int compareWindowShell(const void *windowA, const void *windowB)
5250 const WindowInfo *a = *((WindowInfo**)windowA);
5251 const WindowInfo *b = *((WindowInfo**)windowB);
5253 return a->shell > b->shell;
5257 ** create & return a sorted list of windows
5258 ** Windows are first sort by their filename then,
5259 ** if windows are tabbed, grouped by their shell windows
5261 ** Note: caller must XtFree the returned window list.
5263 WindowInfo **MakeSortedWindowArray(void)
5265 WindowInfo *w, **windows;
5266 int i, nWindows;
5268 /* Make a sorted list of windows */
5269 for (w=WindowList, nWindows=0; w!=NULL; w=w->next, nWindows++);
5270 windows = (WindowInfo **)XtMalloc(sizeof(WindowInfo *) * nWindows);
5271 for (w=WindowList, i=0; w!=NULL; w=w->next, i++)
5272 windows[i] = w;
5273 qsort(windows, nWindows, sizeof(WindowInfo *), compareWindowNames);
5275 /* group the documents together by their shell window */
5276 if (GetPrefOpenInTab())
5277 qsort(windows, nWindows, sizeof(WindowInfo *), compareWindowShell);
5279 return windows;
5283 ** Create popup for right button programmable menu
5285 Widget CreateBGMenu(WindowInfo *window)
5287 Arg args[1];
5289 /* There is still some mystery here. It's important to get the XmNmenuPost
5290 resource set to the correct menu button, or the menu will not post
5291 properly, but there's also some danger that it will take over the entire
5292 button and interfere with text widget translations which use the button
5293 with modifiers. I don't entirely understand why it works properly now
5294 when it failed often in development, and certainly ignores the ~ syntax
5295 in translation event specifications. */
5296 XtSetArg(args[0], XmNmenuPost, GetPrefBGMenuBtn());
5297 return CreatePopupMenu(window->textArea, "bgMenu", args, 1);
5301 ** Create context popup menu for tabs & tab bar
5303 Widget CreateTabContextMenu(Widget parent, WindowInfo *window)
5305 Widget menu;
5306 Arg args[8];
5307 int n;
5309 n = 0;
5310 XtSetArg(args[n], XmNtearOffModel, XmTEAR_OFF_DISABLED); n++;
5311 menu = CreatePopupMenu(parent, "tabContext", args, n);
5313 createMenuItem(menu, "new", "New Tab", 0, doTabActionCB, "new_tab", SHORT);
5314 createMenuItem(menu, "close", "Close Tab", 0, doTabActionCB, "close", SHORT);
5315 createMenuSeparator(menu, "sep1", SHORT);
5316 window->contextDetachDocumentItem = createMenuItem(menu, "detach",
5317 "Detach Tab", 0, doTabActionCB, "detach_document", SHORT);
5318 XtSetSensitive(window->contextDetachDocumentItem, False);
5319 window->contextMoveDocumentItem = createMenuItem(menu, "attach",
5320 "Move Tab To...", 0, doTabActionCB, "move_document_dialog", SHORT);
5322 return menu;
5326 ** Add a translation to the text widget to trigger the background menu using
5327 ** the mouse-button + modifier combination specified in the resource:
5328 ** nedit.bgMenuBtn.
5330 void AddBGMenuAction(Widget widget)
5332 static XtTranslations table = NULL;
5334 if (table == NULL) {
5335 char translations[MAX_ACCEL_LEN + 25];
5336 sprintf(translations, "%s: post_window_bg_menu()\n",GetPrefBGMenuBtn());
5337 table = XtParseTranslationTable(translations);
5339 XtOverrideTranslations(widget, table);
5342 static void bgMenuPostAP(Widget w, XEvent *event, String *args,
5343 Cardinal *nArgs)
5345 WindowInfo *window = WidgetToWindow(w);
5347 /* The Motif popup handling code BLOCKS events while the menu is posted,
5348 including the matching btn-up events which complete various dragging
5349 operations which it may interrupt. Cancel to head off problems */
5350 XtCallActionProc(window->lastFocus, "process_cancel", event, NULL, 0);
5352 /* Pop up the menu */
5353 XmMenuPosition(window->bgMenuPane, (XButtonPressedEvent *)event);
5354 XtManageChild(window->bgMenuPane);
5357 These statements have been here for a very long time, but seem
5358 unnecessary and are even dangerous: when any of the lock keys are on,
5359 Motif thinks it shouldn't display the background menu, but this
5360 callback is called anyway. When we then grab the focus and force the
5361 menu to be drawn, bad things can happen (like a total lockup of the X
5362 server).
5364 XtPopup(XtParent(window->bgMenuPane), XtGrabNonexclusive);
5365 XtMapWidget(XtParent(window->bgMenuPane));
5366 XtMapWidget(window->bgMenuPane);
5370 void AddTabContextMenuAction(Widget widget)
5372 static XtTranslations table = NULL;
5374 if (table == NULL) {
5375 char *translations = "<Btn3Down>: post_tab_context_menu()\n";
5376 table = XtParseTranslationTable(translations);
5378 XtOverrideTranslations(widget, table);
5382 ** action procedure for posting context menu of tabs
5384 static void tabMenuPostAP(Widget w, XEvent *event, String *args,
5385 Cardinal *nArgs)
5387 WindowInfo *window;
5388 XButtonPressedEvent *xbutton = (XButtonPressedEvent *)event;
5389 Widget wgt;
5391 /* Determine if the context menu was called from tabs or gutter,
5392 then stored the corresponding window info as userData of
5393 the popup menu pane, which will later be extracted by
5394 doTabActionCB() to act upon. When the context menu was called
5395 from the gutter, the active doc is assumed.
5397 Lesstif requires the action [to pupop the menu] to also be
5398 to the tabs, else nothing happed when right-click on tabs.
5399 Even so, the action procedure sometime appear to be called
5400 from the gutter even if users did right-click on the tabs.
5401 Here we try to cater for the uncertainty. */
5402 if (XtClass(w) == xrwsBubbleButtonWidgetClass)
5403 window = TabToWindow(w);
5404 else if (xbutton->subwindow) {
5405 wgt = XtWindowToWidget(XtDisplay(w), xbutton->subwindow);
5406 window = TabToWindow(wgt);
5408 else {
5409 window = WidgetToWindow(w);
5411 XtVaSetValues(window->tabMenuPane, XmNuserData, (XtPointer)window, NULL);
5413 /* The Motif popup handling code BLOCKS events while the menu is posted,
5414 including the matching btn-up events which complete various dragging
5415 operations which it may interrupt. Cancel to head off problems */
5416 XtCallActionProc(window->lastFocus, "process_cancel", event, NULL, 0);
5418 /* Pop up the menu */
5419 XmMenuPosition(window->tabMenuPane, (XButtonPressedEvent *)event);
5420 XtManageChild(window->tabMenuPane);
5424 ** Event handler for restoring the input hint of menu tearoffs
5425 ** previously disabled in ShowHiddenTearOff()
5427 static void tearoffMappedCB(Widget w, XtPointer clientData, XUnmapEvent *event)
5429 Widget shell = (Widget)clientData;
5430 XWMHints *wmHints;
5432 if (event->type != MapNotify)
5433 return;
5435 /* restore the input hint previously disabled in ShowHiddenTearOff() */
5436 wmHints = XGetWMHints(TheDisplay, XtWindow(shell));
5437 wmHints->input = True;
5438 wmHints->flags |= InputHint;
5439 XSetWMHints(TheDisplay, XtWindow(shell), wmHints);
5440 XFree(wmHints);
5442 /* we only need to do this only */
5443 XtRemoveEventHandler(shell, StructureNotifyMask, False,
5444 (XtEventHandler)tearoffMappedCB, shell);
5448 ** Redisplay (map) a hidden tearoff
5450 void ShowHiddenTearOff(Widget menuPane)
5452 Widget shell;
5454 if (!menuPane)
5455 return;
5457 shell = XtParent(menuPane);
5458 if (!XmIsMenuShell(shell)) {
5459 XWindowAttributes winAttr;
5461 XGetWindowAttributes(XtDisplay(shell), XtWindow(shell), &winAttr);
5462 if (winAttr.map_state == IsUnmapped) {
5463 XWMHints *wmHints;
5465 /* to workaround a problem where the remapped tearoffs
5466 always receive the input focus insteads of the text
5467 editing window, we disable the input hint of the
5468 tearoff shell temporarily. */
5469 wmHints = XGetWMHints(XtDisplay(shell), XtWindow(shell));
5470 wmHints->input = False;
5471 wmHints->flags |= InputHint;
5472 XSetWMHints(XtDisplay(shell), XtWindow(shell), wmHints);
5473 XFree(wmHints);
5475 /* show the tearoff */
5476 XtMapWidget(shell);
5478 /* the input hint will be restored when the tearoff
5479 is mapped */
5480 XtAddEventHandler(shell, StructureNotifyMask, False,
5481 (XtEventHandler)tearoffMappedCB, shell);
5486 #ifdef SGI_CUSTOM
5487 static void shortMenusCB(Widget w, WindowInfo *window, caddr_t callData)
5489 WindowInfo *win;
5490 int i, state = XmToggleButtonGetState(w);
5491 Widget parent;
5493 window = WidgetToWindow(w);
5495 HidePointerOnKeyedEvent(WidgetToWindow(MENU_WIDGET(w))->lastFocus,
5496 ((XmAnyCallbackStruct *)callData)->event);
5497 /* Set the preference */
5498 SetPrefShortMenus(state);
5500 /* Re-create the menus for all windows */
5501 for (win=WindowList; win!=NULL; win=win->next) {
5502 for (i=0; i<win->nToggleShortItems; i++) {
5503 if (state)
5504 XtUnmanageChild(win->toggleShortItems[i]);
5505 else
5506 XtManageChild(win->toggleShortItems[i]);
5509 if (GetPrefShortMenus())
5510 SaveNEditPrefs(window->shell, True);
5513 static void addToToggleShortList(Widget w)
5515 if (ShortMenuWindow->nToggleShortItems >= MAX_SHORTENED_ITEMS) {
5516 fprintf(stderr,"nedit, internal error: increase MAX_SHORTENED_ITEMS\n");
5517 return;
5519 ShortMenuWindow->toggleShortItems[ShortMenuWindow->nToggleShortItems++] = w;
5523 ** Present the user a dialog for specifying whether or not a short
5524 ** menu mode preference should be applied toward the default setting.
5525 ** Return True if user requested to reset and save the default value.
5526 ** If operation was canceled, will return toggle widget "w" to it's
5527 ** original (opposite) state.
5529 static int shortPrefAskDefault(Widget parent, Widget w, const char *settingName)
5531 char msg[100] = "";
5533 if (!GetPrefShortMenus()) {
5534 return False;
5537 sprintf(msg, "%s: %s\nSave as default for future windows as well?",
5538 settingName, XmToggleButtonGetState(w) ? "On" : "Off");
5539 switch (DialogF (DF_QUES, parent, 3, "Save Default", msg, "Yes", "No",
5540 "Cancel"))
5542 case 1: /* yes */
5543 return True;
5544 case 2: /* no */
5545 return False;
5546 case 3: /* cancel */
5547 XmToggleButtonSetState(w, !XmToggleButtonGetState(w), False);
5548 return False;
5550 return False; /* not reached */
5552 #endif