1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #ifdef HAVE_CONFIG_H
30 #include "../config.h"
31 #endif
32
33 #include "userCmds.h"
34 #include "textBuf.h"
35 #include "text.h"
36 #include "nedit.h"
37 #include "preferences.h"
38 #include "window.h"
39 #include "menu.h"
40 #include "shell.h"
41 #include "macro.h"
42 #include "file.h"
43 #include "interpret.h"
44 #include "parse.h"
45 #include "../util/DialogF.h"
46 #include "../util/misc.h"
47 #include "../util/managedList.h"
48 #include "../util/nedit_malloc.h"
49
50 #include <stdio.h>
51 #include <stdlib.h>
52 #include <string.h>
53 #include <ctype.h>
54 #include <sys/param.h>
55
56 #include <Xm/Xm.h>
57 #include <X11/keysym.h>
58 #include <X11/IntrinsicP.h>
59 #include <Xm/Text.h>
60 #include <Xm/Form.h>
61 #include <Xm/List.h>
62 #include <Xm/LabelG.h>
63 #include <Xm/PushB.h>
64 #include <Xm/ToggleB.h>
65 #include <Xm/SelectioB.h>
66 #include <Xm/RowColumn.h>
67 #include <Xm/CascadeB.h>
68 #include <Xm/MenuShell.h>
69
70 #include <inttypes.h>
71
72 #ifdef HAVE_DEBUG_H
73 #include "../debug.h"
74 #endif
75
76 #if XmVersion >=
1002
77 #define MENU_WIDGET(w) (XmGetPostedFromWidget(XtParent(w)))
78 #else
79 #define MENU_WIDGET(w) (w)
80 #endif
81
82 extern void _XmDismissTearOff(Widget w, XtPointer call, XtPointer x);
83
84
85
86 #define MAX_ITEMS_PER_MENU 400
87
88
89
90 #define UNKNOWN_LANGUAGE_MODE -
2
91
92
93 #define LEFT_MARGIN_POS 1
94 #define RIGHT_MARGIN_POS 99
95 #define LIST_RIGHT 45
96 #define SHELL_CMD_TOP 70
97 #define MACRO_CMD_TOP 40
98
99
100 enum dialogTypes {
SHELL_CMDS,
MACRO_CMDS,
BG_MENU_CMDS};
101
102
103 typedef struct {
104 char *name;
105 unsigned int modifiers;
106 KeySym keysym;
107 char mnemonic;
108 char input;
109 char output;
110 char repInput;
111 char saveFirst;
112 char loadAfter;
113 char *cmd;
114 } menuItemRec;
115
116
117
118 typedef struct {
119 int dialogType;
120 WindowInfo *window;
121 Widget nameTextW, accTextW, mneTextW, cmdTextW, saveFirstBtn;
122 Widget loadAfterBtn, selInpBtn, winInpBtn, eitherInpBtn, noInpBtn;
123 Widget repInpBtn, sameOutBtn, dlogOutBtn, winOutBtn, dlogShell;
124 Widget managedList;
125 menuItemRec **menuItemsList;
126 int nMenuItems;
127 } userCmdDialog;
128
129
130
131 typedef struct {
132 char *name;
133 Widget menuPane;
134 } menuTreeItem;
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159 typedef struct {
160 char *usmiName;
161 int *usmiId;
162 int usmiIdLen;
163 } userSubMenuInfo;
164
165
166 typedef struct {
167 int usmcNbrOfMainMenuItems;
168 int usmcNbrOfSubMenus;
169 userSubMenuInfo *usmcInfo;
170 } userSubMenuCache;
171
172
173
174
175
176
177
178
179
180
181 typedef struct {
182 char *umiName;
183
184 int *umiId;
185 int umiIdLen;
186 Boolean umiIsDefault;
187 int umiNbrOfLanguageModes;
188
189 int *umiLanguageMode;
190 int umiDefaultIndex;
191
192
193 Boolean umiToBeManaged;
194
195 } userMenuInfo;
196
197
198
199 typedef struct {
200 int sumType;
201
202 Widget sumMenuPane;
203 int sumNbrOfListItems;
204 menuItemRec **sumItemList;
205 userMenuInfo **sumInfoList;
206 userSubMenuCache *sumSubMenus;
207 UserMenuList *sumMainMenuList;
208 Boolean *sumMenuCreated;
209
210 } selectedUserMenu;
211
212
213
214 static menuItemRec *ShellMenuItems[
MAX_ITEMS_PER_MENU];
215 static userMenuInfo *ShellMenuInfo[
MAX_ITEMS_PER_MENU];
216 static userSubMenuCache ShellSubMenus;
217 static int NShellMenuItems =
0;
218 static menuItemRec *MacroMenuItems[
MAX_ITEMS_PER_MENU];
219 static userMenuInfo *MacroMenuInfo[
MAX_ITEMS_PER_MENU];
220 static userSubMenuCache MacroSubMenus;
221 static int NMacroMenuItems =
0;
222 static menuItemRec *BGMenuItems[
MAX_ITEMS_PER_MENU];
223 static userMenuInfo *BGMenuInfo[
MAX_ITEMS_PER_MENU];
224 static userSubMenuCache BGSubMenus;
225 static int NBGMenuItems =
0;
226
227
228 static Widget ShellCmdDialog =
NULL;
229 static Widget MacroCmdDialog =
NULL;
230 static Widget BGMenuCmdDialog =
NULL;
231
232
233
234 static Widget MacroPasteReplayBtn =
NULL;
235 static Widget BGMenuPasteReplayBtn =
NULL;
236
237 static void editMacroOrBGMenu(WindowInfo *window,
int dialogType);
238 static void dimSelDepItemsInMenu(Widget menuPane, menuItemRec **menuList,
239 int nMenuItems,
int sensitive);
240 static void rebuildMenuOfAllWindows(
int menuType);
241 static void rebuildMenu(WindowInfo *window,
int menuType);
242 static Widget findInMenuTree(menuTreeItem *menuTree,
int nTreeEntries,
243 const char *hierName);
244 static char *copySubstring(
const char *string,
int length);
245 static Widget createUserMenuItem(Widget menuPane,
char *name, menuItemRec *f,
246 int index, XtCallbackProc cbRtn, XtPointer cbArg);
247 static Widget createUserSubMenu(Widget parent,
char *label, Widget *menuItem);
248 static void deleteMenuItems(Widget menuPane);
249 static void selectUserMenu(WindowInfo *window,
int menuType, selectedUserMenu *menu);
250 static void updateMenu(WindowInfo *window,
int menuType);
251 static void manageTearOffMenu(Widget menuPane);
252 static void resetManageMode(UserMenuList *list);
253 static void manageAllSubMenuWidgets(UserMenuListElement *subMenu);
254 static void unmanageAllSubMenuWidgets(UserMenuListElement *subMenu);
255 static void manageMenuWidgets(UserMenuList *list);
256 static void removeAccelFromMenuWidgets(UserMenuList *menuList);
257 static void assignAccelToMenuWidgets(UserMenuList *menuList, WindowInfo *window);
258 static void manageUserMenu(selectedUserMenu *menu, WindowInfo *window);
259 static void createMenuItems(WindowInfo *window, selectedUserMenu *menu);
260 static void okCB(Widget w, XtPointer clientData, XtPointer callData);
261 static void applyCB(Widget w, XtPointer clientData, XtPointer callData);
262 static void checkCB(Widget w, XtPointer clientData, XtPointer callData);
263 static int checkMacro(userCmdDialog *ucd);
264 static int checkMacroText(
char *macro, Widget errorParent, Widget errFocus);
265 static int applyDialogChanges(userCmdDialog *ucd);
266 static void closeCB(Widget w, XtPointer clientData, XtPointer callData);
267 static void pasteReplayCB(Widget w, XtPointer clientData, XtPointer callData);
268 static void destroyCB(Widget w, XtPointer clientData, XtPointer callData);
269 static void accKeyCB(Widget w, XtPointer clientData, XKeyEvent *event);
270 static void sameOutCB(Widget w, XtPointer clientData, XtPointer callData);
271 static void shellMenuCB(Widget w, WindowInfo *window, XtPointer callData);
272 static void macroMenuCB(Widget w, WindowInfo *window, XtPointer callData);
273 static void bgMenuCB(Widget w, WindowInfo *window, XtPointer callData) ;
274 static void accFocusCB(Widget w, XtPointer clientData, XtPointer callData);
275 static void accLoseFocusCB(Widget w, XtPointer clientData,
276 XtPointer callData);
277 static void updateDialogFields(menuItemRec *f, userCmdDialog *ucd);
278 static menuItemRec *readDialogFields(userCmdDialog *ucd,
int silent);
279 static menuItemRec *copyMenuItemRec(menuItemRec *item);
280 static void freeMenuItemRec(menuItemRec *item);
281 static void *getDialogDataCB(
void *oldItem,
int explicitRequest,
int *abort,
282 void *cbArg);
283 static void setDialogDataCB(
void *item,
void *cbArg);
284 static void freeItemCB(
void *item);
285 static int dialogFieldsAreEmpty(userCmdDialog *ucd);
286 static void disableTextW(Widget textW);
287 static char *writeMenuItemString(menuItemRec **menuItems,
int nItems,
288 int listType);
289 static int loadMenuItemString(
char *inString, menuItemRec **menuItems,
290 int *nItems,
int listType);
291 static void generateAcceleratorString(
char *text,
unsigned int modifiers,
292 KeySym keysym);
293 static void genAccelEventName(
char *text,
unsigned int modifiers,
294 KeySym keysym);
295 static int parseAcceleratorString(
const char *string,
unsigned int *modifiers,
296 KeySym *keysym);
297 static int parseError(
const char *message);
298 static char *copyMacroToEnd(
char **inPtr);
299 static void addTerminatingNewline(
char **string);
300 static void parseMenuItemList(menuItemRec **itemList,
int nbrOfItems,
301 userMenuInfo **infoList, userSubMenuCache *subMenus);
302 static int getSubMenuDepth(
const char *menuName);
303 static userMenuInfo *parseMenuItemRec(menuItemRec *item);
304 static void parseMenuItemName(
char *menuItemName, userMenuInfo *info);
305 static void generateUserMenuId(userMenuInfo *info, userSubMenuCache *subMenus);
306 static userSubMenuInfo *findSubMenuInfo(userSubMenuCache *subMenus,
307 const char *hierName);
308 static char *stripLanguageMode(
const char *menuItemName);
309 static void setDefaultIndex(userMenuInfo **infoList,
int nbrOfItems,
310 int defaultIdx);
311 static void applyLangModeToUserMenuInfo(userMenuInfo **infoList,
int nbrOfItems,
312 int languageMode);
313 static int doesLanguageModeMatch(userMenuInfo *info,
int languageMode);
314 static void freeUserMenuInfoList(userMenuInfo **infoList,
int nbrOfItems);
315 static void freeUserMenuInfo(userMenuInfo *info);
316 static void allocSubMenuCache(userSubMenuCache *subMenus,
int nbrOfItems);
317 static void freeSubMenuCache(userSubMenuCache *subMenus);
318 static void allocUserMenuList(UserMenuList *list,
int nbrOfItems);
319 static void freeUserMenuList(UserMenuList *list);
320 static UserMenuListElement *allocUserMenuListElement(Widget menuItem,
char *accKeys);
321 static void freeUserMenuListElement(UserMenuListElement *element);
322 static UserMenuList *allocUserSubMenuList(
int nbrOfItems);
323 static void freeUserSubMenuList(UserMenuList *list);
324
325
326
327
328 void EditShellMenu(WindowInfo *window)
329 {
330 Widget form, accLabel, inpLabel, inpBox, outBox, outLabel;
331 Widget nameLabel, cmdLabel, okBtn, applyBtn, closeBtn;
332 userCmdDialog *ucd;
333 XmString s1;
334 int ac, i;
335 Arg args[
20];
336
337
338 if (ShellCmdDialog !=
NULL) {
339 RaiseDialogWindow(ShellCmdDialog);
340 return;
341 }
342
343
344 ucd = (userCmdDialog *)NEditMalloc(
sizeof(userCmdDialog));
345 ucd->window = window;
346
347
348 ucd->menuItemsList = (menuItemRec **)NEditMalloc(
sizeof(menuItemRec *) *
349 MAX_ITEMS_PER_MENU);
350 for (i=
0; i<NShellMenuItems; i++)
351 ucd->menuItemsList[i] = copyMenuItemRec(ShellMenuItems[i]);
352 ucd->nMenuItems = NShellMenuItems;
353 ucd->dialogType =
SHELL_CMDS;
354
355 ac =
0;
356 XtSetArg(args[ac], XmNdeleteResponse, XmDO_NOTHING); ac++;
357 XtSetArg(args[ac], XmNiconName,
"XNEdit Shell Menu"); ac++;
358 XtSetArg(args[ac], XmNtitle,
"Shell Menu"); ac++;
359 ucd->dlogShell = CreateWidget(TheAppShell,
"shellCommands",
360 topLevelShellWidgetClass, args, ac);
361 AddSmallIcon(ucd->dlogShell);
362 form = XtVaCreateManagedWidget(
"editShellCommands", xmFormWidgetClass,
363 ucd->dlogShell, XmNautoUnmanage, False,
364 XmNresizePolicy, XmRESIZE_NONE,
NULL);
365 ShellCmdDialog = ucd->dlogShell;
366 XtAddCallback(form, XmNdestroyCallback, destroyCB, ucd);
367 AddMotifCloseCallback(ucd->dlogShell, closeCB, ucd);
368
369 ac =
0;
370 XtSetArg(args[ac], XmNtopAttachment, XmATTACH_POSITION); ac++;
371 XtSetArg(args[ac], XmNtopPosition,
2); ac++;
372 XtSetArg(args[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
373 XtSetArg(args[ac], XmNleftPosition,
LEFT_MARGIN_POS); ac++;
374 XtSetArg(args[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
375 XtSetArg(args[ac], XmNrightPosition,
LIST_RIGHT-
1); ac++;
376 XtSetArg(args[ac], XmNbottomAttachment, XmATTACH_POSITION); ac++;
377 XtSetArg(args[ac], XmNbottomPosition,
SHELL_CMD_TOP); ac++;
378 ucd->managedList = CreateManagedList(form,
"list", args, ac,
379 (
void **)ucd->menuItemsList, &ucd->nMenuItems,
MAX_ITEMS_PER_MENU,
380 20, getDialogDataCB, ucd, setDialogDataCB, ucd, freeItemCB);
381
382 ucd->loadAfterBtn = XtVaCreateManagedWidget(
"loadAfterBtn",
383 xmToggleButtonWidgetClass, form,
384 XmNlabelString, s1=
MKSTRING(
"Re-load file after executing command"),
385 XmNmnemonic,
'R',
386 XmNalignment, XmALIGNMENT_BEGINNING,
387 XmNset, False,
388 XmNleftAttachment, XmATTACH_POSITION,
389 XmNleftPosition,
LIST_RIGHT,
390 XmNrightAttachment, XmATTACH_POSITION,
391 XmNrightPosition,
RIGHT_MARGIN_POS,
392 XmNbottomAttachment, XmATTACH_POSITION,
393 XmNbottomPosition,
SHELL_CMD_TOP,
NULL);
394 XmStringFree(s1);
395 ucd->saveFirstBtn = XtVaCreateManagedWidget(
"saveFirstBtn",
396 xmToggleButtonWidgetClass, form,
397 XmNlabelString, s1=
MKSTRING(
"Save file before executing command"),
398 XmNmnemonic,
'f',
399 XmNalignment, XmALIGNMENT_BEGINNING,
400 XmNset, False,
401 XmNleftAttachment, XmATTACH_POSITION,
402 XmNleftPosition,
LIST_RIGHT,
403 XmNrightAttachment, XmATTACH_POSITION,
404 XmNrightPosition,
RIGHT_MARGIN_POS,
405 XmNbottomAttachment, XmATTACH_WIDGET,
406 XmNbottomWidget, ucd->loadAfterBtn,
NULL);
407 XmStringFree(s1);
408 ucd->repInpBtn = XtVaCreateManagedWidget(
"repInpBtn",
409 xmToggleButtonWidgetClass, form,
410 XmNlabelString, s1=
MKSTRING(
"Output replaces input"),
411 XmNmnemonic,
'f',
412 XmNalignment, XmALIGNMENT_BEGINNING,
413 XmNset, False,
414 XmNleftAttachment, XmATTACH_POSITION,
415 XmNleftPosition,
LIST_RIGHT,
416 XmNrightAttachment, XmATTACH_POSITION,
417 XmNrightPosition,
RIGHT_MARGIN_POS,
418 XmNbottomAttachment, XmATTACH_WIDGET,
419 XmNbottomWidget, ucd->saveFirstBtn,
NULL);
420 XmStringFree(s1);
421 outBox = XtVaCreateManagedWidget(
"outBox", xmRowColumnWidgetClass, form,
422 XmNpacking, XmPACK_TIGHT,
423 XmNorientation, XmHORIZONTAL,
424 XmNradioBehavior, True,
425 XmNradioAlwaysOne, True,
426 XmNleftAttachment, XmATTACH_POSITION,
427 XmNleftPosition,
LIST_RIGHT +
2,
428 XmNrightAttachment, XmATTACH_POSITION,
429 XmNrightPosition,
RIGHT_MARGIN_POS,
430 XmNbottomAttachment, XmATTACH_WIDGET,
431 XmNbottomWidget, ucd->repInpBtn,
432 XmNbottomOffset,
4,
NULL);
433 ucd->sameOutBtn = XtVaCreateManagedWidget(
"sameOutBtn",
434 xmToggleButtonWidgetClass, outBox,
435 XmNlabelString, s1=
MKSTRING(
"same document"),
436 XmNmnemonic,
'm',
437 XmNalignment, XmALIGNMENT_BEGINNING,
438 XmNmarginHeight,
0,
439 XmNset, True,
NULL);
440 XmStringFree(s1);
441 XtAddCallback(ucd->sameOutBtn, XmNvalueChangedCallback, sameOutCB, ucd);
442 ucd->dlogOutBtn = XtVaCreateManagedWidget(
"dlogOutBtn",
443 xmToggleButtonWidgetClass, outBox,
444 XmNlabelString, s1=
MKSTRING(
"dialog"),
445 XmNmnemonic,
'g',
446 XmNalignment, XmALIGNMENT_BEGINNING,
447 XmNmarginHeight,
0,
448 XmNset, False,
NULL);
449 XmStringFree(s1);
450 ucd->winOutBtn = XtVaCreateManagedWidget(
"winOutBtn", xmToggleButtonWidgetClass,
451 outBox,
452 XmNlabelString, s1=
MKSTRING(
"new document"),
453 XmNmnemonic,
'n',
454 XmNalignment, XmALIGNMENT_BEGINNING,
455 XmNmarginHeight,
0,
456 XmNset, False,
NULL);
457 XmStringFree(s1);
458 outLabel = XtVaCreateManagedWidget(
"outLabel", xmLabelGadgetClass, form,
459 XmNlabelString, s1=
MKSTRING(
"Command Output (stdout/stderr):"),
460 XmNalignment, XmALIGNMENT_BEGINNING,
461 XmNmarginTop,
5,
462 XmNleftAttachment, XmATTACH_POSITION,
463 XmNleftPosition,
LIST_RIGHT,
464 XmNrightAttachment, XmATTACH_POSITION,
465 XmNrightPosition,
RIGHT_MARGIN_POS,
466 XmNbottomAttachment, XmATTACH_WIDGET,
467 XmNbottomWidget, outBox,
NULL);
468 XmStringFree(s1);
469
470 inpBox = XtVaCreateManagedWidget(
"inpBox", xmRowColumnWidgetClass, form,
471 XmNpacking, XmPACK_TIGHT,
472 XmNorientation, XmHORIZONTAL,
473 XmNradioBehavior, True,
474 XmNradioAlwaysOne, True,
475 XmNleftAttachment, XmATTACH_POSITION,
476 XmNleftPosition,
LIST_RIGHT +
2,
477 XmNrightAttachment, XmATTACH_POSITION,
478 XmNrightPosition,
RIGHT_MARGIN_POS,
479 XmNbottomAttachment, XmATTACH_WIDGET,
480 XmNbottomWidget, outLabel,
NULL);
481 ucd->selInpBtn = XtVaCreateManagedWidget(
"selInpBtn", xmToggleButtonWidgetClass,
482 inpBox,
483 XmNlabelString, s1=
MKSTRING(
"selection"),
484 XmNmnemonic,
's',
485 XmNalignment, XmALIGNMENT_BEGINNING,
486 XmNmarginHeight,
0,
487 XmNset, True,
NULL);
488 XmStringFree(s1);
489 ucd->winInpBtn = XtVaCreateManagedWidget(
"winInpBtn",
490 xmToggleButtonWidgetClass, inpBox,
491 XmNlabelString, s1=
MKSTRING(
"document"),
492 XmNmnemonic,
'w',
493 XmNalignment, XmALIGNMENT_BEGINNING,
494 XmNmarginHeight,
0,
495 XmNset, False,
NULL);
496 XmStringFree(s1);
497 ucd->eitherInpBtn = XtVaCreateManagedWidget(
"eitherInpBtn",
498 xmToggleButtonWidgetClass, inpBox,
499 XmNlabelString, s1=
MKSTRING(
"either"),
500 XmNmnemonic,
't',
501 XmNalignment, XmALIGNMENT_BEGINNING,
502 XmNmarginHeight,
0,
503 XmNset, False,
NULL);
504 XmStringFree(s1);
505 ucd->noInpBtn = XtVaCreateManagedWidget(
"noInpBtn",
506 xmToggleButtonWidgetClass, inpBox,
507 XmNlabelString, s1=
MKSTRING(
"none"),
508 XmNmnemonic,
'o',
509 XmNalignment, XmALIGNMENT_BEGINNING,
510 XmNmarginHeight,
0,
511 XmNset, False,
NULL);
512 XmStringFree(s1);
513 inpLabel = XtVaCreateManagedWidget(
"inpLabel", xmLabelGadgetClass, form,
514 XmNlabelString, s1=
MKSTRING(
"Command Input (stdin):"),
515 XmNalignment, XmALIGNMENT_BEGINNING,
516 XmNmarginTop,
5,
517 XmNleftAttachment, XmATTACH_POSITION,
518 XmNleftPosition,
LIST_RIGHT,
519 XmNrightAttachment, XmATTACH_POSITION,
520 XmNrightPosition,
RIGHT_MARGIN_POS,
521 XmNbottomAttachment, XmATTACH_WIDGET,
522 XmNbottomWidget, inpBox,
NULL);
523 XmStringFree(s1);
524
525 ucd->mneTextW = XtVaCreateManagedWidget(
"mne", xmTextWidgetClass, form,
526 XmNcolumns,
1,
527 XmNmaxLength,
1,
528 XmNleftAttachment, XmATTACH_POSITION,
529 XmNleftPosition,
RIGHT_MARGIN_POS-
10,
530 XmNrightAttachment, XmATTACH_POSITION,
531 XmNrightPosition,
RIGHT_MARGIN_POS,
532 XmNbottomAttachment, XmATTACH_WIDGET,
533 XmNbottomWidget, inpLabel,
NULL);
534 RemapDeleteKey(ucd->mneTextW);
535
536 ucd->accTextW = XtVaCreateManagedWidget(
"acc", xmTextWidgetClass, form,
537 XmNcolumns,
12,
538 XmNmaxLength,
MAX_ACCEL_LEN-
1,
539 XmNcursorPositionVisible, False,
540 XmNleftAttachment, XmATTACH_POSITION,
541 XmNleftPosition,
LIST_RIGHT,
542 XmNrightAttachment, XmATTACH_POSITION,
543 XmNrightPosition,
RIGHT_MARGIN_POS-
15,
544 XmNbottomAttachment, XmATTACH_WIDGET,
545 XmNbottomWidget, inpLabel,
NULL);
546 XtAddEventHandler(ucd->accTextW, KeyPressMask, False,
547 (XtEventHandler)accKeyCB, ucd);
548 XtAddCallback(ucd->accTextW, XmNfocusCallback, accFocusCB, ucd);
549 XtAddCallback(ucd->accTextW, XmNlosingFocusCallback, accLoseFocusCB, ucd);
550 accLabel = XtVaCreateManagedWidget(
"accLabel", xmLabelGadgetClass, form,
551 XmNlabelString, s1=
MKSTRING(
"Accelerator"),
552 XmNmnemonic,
'l',
553 XmNuserData, ucd->accTextW,
554 XmNalignment, XmALIGNMENT_BEGINNING,
555 XmNmarginTop,
5,
556 XmNleftAttachment, XmATTACH_POSITION,
557 XmNleftPosition,
LIST_RIGHT,
558 XmNrightAttachment, XmATTACH_POSITION,
559 XmNrightPosition,
LIST_RIGHT +
24,
560 XmNbottomAttachment, XmATTACH_WIDGET,
561 XmNbottomWidget, ucd->mneTextW,
NULL);
562 XmStringFree(s1);
563
564 XtVaCreateManagedWidget(
"mneLabel", xmLabelGadgetClass, form,
565 XmNlabelString, s1=
MKSTRING(
"Mnemonic"),
566 XmNmnemonic,
'i',
567 XmNuserData, ucd->mneTextW,
568 XmNalignment, XmALIGNMENT_END,
569 XmNmarginTop,
5,
570 XmNleftAttachment, XmATTACH_POSITION,
571 XmNleftPosition,
LIST_RIGHT +
24,
572 XmNrightAttachment, XmATTACH_POSITION,
573 XmNrightPosition,
RIGHT_MARGIN_POS,
574 XmNbottomAttachment, XmATTACH_WIDGET,
575 XmNbottomWidget, ucd->mneTextW,
NULL);
576 XmStringFree(s1);
577
578 ucd->nameTextW = XtVaCreateManagedWidget(
"name", xmTextWidgetClass, form,
579 XmNleftAttachment, XmATTACH_POSITION,
580 XmNleftPosition,
LIST_RIGHT,
581 XmNrightAttachment, XmATTACH_POSITION,
582 XmNrightPosition,
RIGHT_MARGIN_POS,
583 XmNbottomAttachment, XmATTACH_WIDGET,
584 XmNbottomWidget, accLabel,
NULL);
585 RemapDeleteKey(ucd->nameTextW);
586
587 nameLabel = XtVaCreateManagedWidget(
"nameLabel", xmLabelGadgetClass, form,
588 XmNlabelString, s1=
MKSTRING(
"Menu Entry"),
589 XmNmnemonic,
'y',
590 XmNuserData, ucd->nameTextW,
591 XmNalignment, XmALIGNMENT_BEGINNING,
592 XmNmarginTop,
5,
593 XmNleftAttachment, XmATTACH_POSITION,
594 XmNleftPosition,
LIST_RIGHT,
595 XmNbottomAttachment, XmATTACH_WIDGET,
596 XmNbottomWidget, ucd->nameTextW,
NULL);
597 XmStringFree(s1);
598
599 XtVaCreateManagedWidget(
"nameNotes", xmLabelGadgetClass, form,
600 XmNlabelString, s1=
MKSTRING(
"(> for sub-menu, @ language mode)"),
601 XmNalignment, XmALIGNMENT_END,
602 XmNmarginTop,
5,
603 XmNleftAttachment, XmATTACH_WIDGET,
604 XmNleftWidget, nameLabel,
605 XmNrightAttachment, XmATTACH_POSITION,
606 XmNrightPosition,
RIGHT_MARGIN_POS,
607 XmNbottomAttachment, XmATTACH_WIDGET,
608 XmNbottomWidget, ucd->nameTextW,
NULL);
609 XmStringFree(s1);
610
611 XtVaCreateManagedWidget(
"topLabel", xmLabelGadgetClass, form,
612 XmNlabelString, s1=
MKSTRING(
613 "Select a shell menu item from the list at left.\n\
614 Select \"New\" to add a new command to the menu."),
615 XmNtopAttachment, XmATTACH_POSITION,
616 XmNtopPosition,
2,
617 XmNleftAttachment, XmATTACH_POSITION,
618 XmNleftPosition,
LIST_RIGHT,
619 XmNrightAttachment, XmATTACH_POSITION,
620 XmNrightPosition,
RIGHT_MARGIN_POS,
621 XmNbottomAttachment, XmATTACH_WIDGET,
622 XmNbottomWidget, nameLabel,
NULL);
623 XmStringFree(s1);
624
625 cmdLabel = XtVaCreateManagedWidget(
"cmdLabel", xmLabelGadgetClass, form,
626 XmNlabelString, s1=
MKSTRING(
"Shell Command to Execute"),
627 XmNmnemonic,
'x',
628 XmNalignment, XmALIGNMENT_BEGINNING,
629 XmNmarginTop,
5,
630 XmNtopAttachment, XmATTACH_POSITION,
631 XmNtopPosition,
SHELL_CMD_TOP,
632 XmNleftAttachment, XmATTACH_POSITION,
633 XmNleftPosition,
LEFT_MARGIN_POS,
NULL);
634 XmStringFree(s1);
635 XtVaCreateManagedWidget(
"cmdLabel", xmLabelGadgetClass, form,
636 XmNlabelString, s1=
MKSTRING(
"(% expands to current filename, # to line number)"),
637 XmNalignment, XmALIGNMENT_END,
638 XmNmarginTop,
5,
639 XmNtopAttachment, XmATTACH_POSITION,
640 XmNtopPosition,
SHELL_CMD_TOP,
641 XmNleftAttachment, XmATTACH_WIDGET,
642 XmNleftWidget, cmdLabel,
643 XmNrightAttachment, XmATTACH_POSITION,
644 XmNrightPosition,
RIGHT_MARGIN_POS,
NULL);
645 XmStringFree(s1);
646
647 okBtn = XtVaCreateManagedWidget(
"ok",xmPushButtonWidgetClass,form,
648 XmNlabelString, s1=
MKSTRING(
"OK"),
649 XmNmarginWidth,
BUTTON_WIDTH_MARGIN,
650 XmNleftAttachment, XmATTACH_POSITION,
651 XmNleftPosition,
13,
652 XmNrightAttachment, XmATTACH_POSITION,
653 XmNrightPosition,
29,
654 XmNbottomAttachment, XmATTACH_POSITION,
655 XmNbottomPosition,
99,
NULL);
656 XtAddCallback(okBtn, XmNactivateCallback, okCB, ucd);
657 XmStringFree(s1);
658
659 applyBtn = XtVaCreateManagedWidget(
"apply",xmPushButtonWidgetClass,form,
660 XmNlabelString, s1=
MKSTRING(
"Apply"),
661 XmNmnemonic,
'A',
662 XmNleftAttachment, XmATTACH_POSITION,
663 XmNleftPosition,
42,
664 XmNrightAttachment, XmATTACH_POSITION,
665 XmNrightPosition,
58,
666 XmNbottomAttachment, XmATTACH_POSITION,
667 XmNbottomPosition,
99,
NULL);
668 XtAddCallback(applyBtn, XmNactivateCallback, applyCB, ucd);
669 XmStringFree(s1);
670
671 closeBtn = XtVaCreateManagedWidget(
"close",
672 xmPushButtonWidgetClass, form,
673 XmNlabelString, s1=
MKSTRING(
"Close"),
674 XmNleftAttachment, XmATTACH_POSITION,
675 XmNleftPosition,
71,
676 XmNrightAttachment, XmATTACH_POSITION,
677 XmNrightPosition,
87,
678 XmNbottomAttachment, XmATTACH_POSITION,
679 XmNbottomPosition,
99,
680 NULL);
681 XtAddCallback(closeBtn, XmNactivateCallback, closeCB, ucd);
682 XmStringFree(s1);
683
684 ac =
0;
685 XtSetArg(args[ac], XmNeditMode, XmMULTI_LINE_EDIT); ac++;
686 XtSetArg(args[ac], XmNscrollHorizontal, False); ac++;
687 XtSetArg(args[ac], XmNwordWrap, True); ac++;
688 XtSetArg(args[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
689 XtSetArg(args[ac], XmNtopWidget, cmdLabel); ac++;
690 XtSetArg(args[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
691 XtSetArg(args[ac], XmNleftPosition,
LEFT_MARGIN_POS); ac++;
692 XtSetArg(args[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
693 XtSetArg(args[ac], XmNrightPosition,
RIGHT_MARGIN_POS); ac++;
694 XtSetArg(args[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
695 XtSetArg(args[ac], XmNbottomWidget, okBtn); ac++;
696 XtSetArg(args[ac], XmNbottomOffset,
5); ac++;
697 ucd->cmdTextW = XmCreateScrolledText(form,
"name", args, ac);
698 AddMouseWheelSupport(ucd->cmdTextW);
699 XtManageChild(ucd->cmdTextW);
700 MakeSingleLineTextW(ucd->cmdTextW);
701 RemapDeleteKey(ucd->cmdTextW);
702 XtVaSetValues(cmdLabel, XmNuserData, ucd->cmdTextW,
NULL);
703
704
705
706 disableTextW(ucd->accTextW);
707
708
709 updateDialogFields(
NULL, ucd);
710
711
712 XtVaSetValues(form, XmNdefaultButton, okBtn,
NULL);
713 XtVaSetValues(form, XmNcancelButton, closeBtn,
NULL);
714
715
716 AddDialogMnemonicHandler(form,
FALSE);
717
718
719 RealizeWithoutForcingPosition(ucd->dlogShell);
720 }
721
722
723
724
725
726 void EditMacroMenu(WindowInfo *window)
727 {
728 editMacroOrBGMenu(window,
MACRO_CMDS);
729 }
730 void EditBGMenu(WindowInfo *window)
731 {
732 editMacroOrBGMenu(window,
BG_MENU_CMDS);
733 }
734
735 static void editMacroOrBGMenu(WindowInfo *window,
int dialogType)
736 {
737 Widget form, accLabel, pasteReplayBtn;
738 Widget nameLabel, cmdLabel, okBtn, applyBtn, closeBtn;
739 userCmdDialog *ucd;
740 char *title;
741 XmString s1;
742 int ac, i;
743 Arg args[
20];
744
745
746 if (dialogType ==
MACRO_CMDS && MacroCmdDialog !=
NULL) {
747 RaiseDialogWindow(MacroCmdDialog);
748 return;
749 }
750 if (dialogType ==
BG_MENU_CMDS && BGMenuCmdDialog !=
NULL) {
751 RaiseDialogWindow(BGMenuCmdDialog);
752 return;
753 }
754
755
756 ucd = (userCmdDialog *)NEditMalloc(
sizeof(userCmdDialog));
757 ucd->window = window;
758
759
760 ucd->menuItemsList = (menuItemRec **)NEditMalloc(
sizeof(menuItemRec **) *
761 MAX_ITEMS_PER_MENU);
762 if (dialogType ==
MACRO_CMDS) {
763 for (i=
0; i<NMacroMenuItems; i++)
764 ucd->menuItemsList[i] = copyMenuItemRec(MacroMenuItems[i]);
765 ucd->nMenuItems = NMacroMenuItems;
766 }
else {
767 for (i=
0; i<NBGMenuItems; i++)
768 ucd->menuItemsList[i] = copyMenuItemRec(BGMenuItems[i]);
769 ucd->nMenuItems = NBGMenuItems;
770 }
771 ucd->dialogType = dialogType;
772
773 title = dialogType ==
MACRO_CMDS ?
"Macro Commands" :
774 "Window Background Menu";
775 ac =
0;
776 XtSetArg(args[ac], XmNdeleteResponse, XmDO_NOTHING); ac++;
777 XtSetArg(args[ac], XmNiconName, title); ac++;
778 XtSetArg(args[ac], XmNtitle, title); ac++;
779 ucd->dlogShell = CreateWidget(TheAppShell,
"macros",
780 topLevelShellWidgetClass, args, ac);
781 AddSmallIcon(ucd->dlogShell);
782 form = XtVaCreateManagedWidget(
"editMacroCommands", xmFormWidgetClass,
783 ucd->dlogShell, XmNautoUnmanage, False,
784 XmNresizePolicy, XmRESIZE_NONE,
NULL);
785 XtAddCallback(form, XmNdestroyCallback, destroyCB, ucd);
786 AddMotifCloseCallback(ucd->dlogShell, closeCB, ucd);
787
788 ac =
0;
789 XtSetArg(args[ac], XmNtopAttachment, XmATTACH_POSITION); ac++;
790 XtSetArg(args[ac], XmNtopPosition,
2); ac++;
791 XtSetArg(args[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
792 XtSetArg(args[ac], XmNleftPosition,
LEFT_MARGIN_POS); ac++;
793 XtSetArg(args[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
794 XtSetArg(args[ac], XmNrightPosition,
LIST_RIGHT-
1); ac++;
795 XtSetArg(args[ac], XmNbottomAttachment, XmATTACH_POSITION); ac++;
796 XtSetArg(args[ac], XmNbottomPosition,
MACRO_CMD_TOP); ac++;
797 ucd->managedList = CreateManagedList(form,
"list", args, ac,
798 (
void **)ucd->menuItemsList, &ucd->nMenuItems,
MAX_ITEMS_PER_MENU,
20,
799 getDialogDataCB, ucd, setDialogDataCB, ucd, freeItemCB);
800
801 ucd->selInpBtn = XtVaCreateManagedWidget(
"selInpBtn",
802 xmToggleButtonWidgetClass, form,
803 XmNlabelString, s1=
MKSTRING(
"Requires Selection"),
804 XmNmnemonic,
'R',
805 XmNalignment, XmALIGNMENT_BEGINNING,
806 XmNmarginHeight,
0,
807 XmNset, False,
808 XmNleftAttachment, XmATTACH_POSITION,
809 XmNleftPosition,
LIST_RIGHT,
810 XmNbottomAttachment, XmATTACH_POSITION,
811 XmNbottomPosition,
MACRO_CMD_TOP,
NULL);
812 XmStringFree(s1);
813
814 ucd->mneTextW = XtVaCreateManagedWidget(
"mne", xmTextWidgetClass, form,
815 XmNcolumns,
1,
816 XmNmaxLength,
1,
817 XmNleftAttachment, XmATTACH_POSITION,
818 XmNleftPosition,
RIGHT_MARGIN_POS-
21-
5,
819 XmNrightAttachment, XmATTACH_POSITION,
820 XmNrightPosition,
RIGHT_MARGIN_POS-
21,
821 XmNbottomAttachment, XmATTACH_WIDGET,
822 XmNbottomWidget, ucd->selInpBtn,
823 XmNbottomOffset,
5,
NULL);
824 RemapDeleteKey(ucd->mneTextW);
825
826 ucd->accTextW = XtVaCreateManagedWidget(
"acc", xmTextWidgetClass, form,
827 XmNcolumns,
12,
828 XmNmaxLength,
MAX_ACCEL_LEN-
1,
829 XmNcursorPositionVisible, False,
830 XmNleftAttachment, XmATTACH_POSITION,
831 XmNleftPosition,
LIST_RIGHT,
832 XmNrightAttachment, XmATTACH_POSITION,
833 XmNrightPosition,
RIGHT_MARGIN_POS-
20-
10,
834 XmNbottomAttachment, XmATTACH_WIDGET,
835 XmNbottomWidget, ucd->selInpBtn,
836 XmNbottomOffset,
5,
NULL);
837 XtAddEventHandler(ucd->accTextW, KeyPressMask, False,
838 (XtEventHandler)accKeyCB, ucd);
839 XtAddCallback(ucd->accTextW, XmNfocusCallback, accFocusCB, ucd);
840 XtAddCallback(ucd->accTextW, XmNlosingFocusCallback, accLoseFocusCB, ucd);
841
842 accLabel = XtVaCreateManagedWidget(
"accLabel", xmLabelGadgetClass, form,
843 XmNlabelString, s1=
MKSTRING(
"Accelerator"),
844 XmNmnemonic,
'l',
845 XmNuserData, ucd->accTextW,
846 XmNalignment, XmALIGNMENT_BEGINNING,
847 XmNmarginTop,
5,
848 XmNleftAttachment, XmATTACH_POSITION,
849 XmNleftPosition,
LIST_RIGHT,
850 XmNrightAttachment, XmATTACH_POSITION,
851 XmNrightPosition,
LIST_RIGHT +
22,
852 XmNbottomAttachment, XmATTACH_WIDGET,
853 XmNbottomWidget, ucd->mneTextW,
NULL);
854 XmStringFree(s1);
855
856 XtVaCreateManagedWidget(
"mneLabel", xmLabelGadgetClass, form,
857 XmNlabelString, s1=
MKSTRING(
"Mnemonic"),
858 XmNmnemonic,
'i',
859 XmNuserData, ucd->mneTextW,
860 XmNalignment, XmALIGNMENT_END,
861 XmNmarginTop,
5,
862 XmNleftAttachment, XmATTACH_POSITION,
863 XmNleftPosition,
LIST_RIGHT +
22,
864 XmNrightAttachment, XmATTACH_POSITION,
865 XmNrightPosition,
RIGHT_MARGIN_POS-
21,
866 XmNbottomAttachment, XmATTACH_WIDGET,
867 XmNbottomWidget, ucd->mneTextW,
NULL);
868 XmStringFree(s1);
869
870 pasteReplayBtn = XtVaCreateManagedWidget(
"pasteReplay",
871 xmPushButtonWidgetClass, form,
872 XmNlabelString, s1=
MKSTRING(
"Paste Learn/\nReplay Macro"),
873 XmNmnemonic,
'P',
874 XmNsensitive, GetReplayMacro() !=
NULL,
875 XmNleftAttachment, XmATTACH_POSITION,
876 XmNleftPosition,
RIGHT_MARGIN_POS-
20,
877 XmNrightAttachment, XmATTACH_POSITION,
878 XmNrightPosition,
RIGHT_MARGIN_POS,
879 XmNbottomAttachment, XmATTACH_POSITION,
880 XmNbottomPosition,
MACRO_CMD_TOP,
NULL);
881 XtAddCallback(pasteReplayBtn, XmNactivateCallback,
882 pasteReplayCB, ucd);
883 XmStringFree(s1);
884
885 ucd->nameTextW = XtVaCreateManagedWidget(
"name", xmTextWidgetClass, form,
886 XmNleftAttachment, XmATTACH_POSITION,
887 XmNleftPosition,
LIST_RIGHT,
888 XmNrightAttachment, XmATTACH_POSITION,
889 XmNrightPosition,
RIGHT_MARGIN_POS,
890 XmNbottomAttachment, XmATTACH_WIDGET,
891 XmNbottomWidget, accLabel,
NULL);
892 RemapDeleteKey(ucd->nameTextW);
893
894 nameLabel = XtVaCreateManagedWidget(
"nameLabel", xmLabelGadgetClass, form,
895 XmNlabelString, s1=
MKSTRING(
"Menu Entry"),
896 XmNmnemonic,
'y',
897 XmNuserData, ucd->nameTextW,
898 XmNalignment, XmALIGNMENT_BEGINNING,
899 XmNmarginTop,
5,
900 XmNleftAttachment, XmATTACH_POSITION,
901 XmNleftPosition,
LIST_RIGHT,
902 XmNbottomAttachment, XmATTACH_WIDGET,
903 XmNbottomWidget, ucd->nameTextW,
NULL);
904 XmStringFree(s1);
905
906 XtVaCreateManagedWidget(
"nameNotes", xmLabelGadgetClass, form,
907 XmNlabelString, s1=
MKSTRING(
"(> for sub-menu, @ language mode)"),
908 XmNalignment, XmALIGNMENT_END,
909 XmNmarginTop,
5,
910 XmNleftAttachment, XmATTACH_WIDGET,
911 XmNleftWidget, nameLabel,
912 XmNrightAttachment, XmATTACH_POSITION,
913 XmNrightPosition,
RIGHT_MARGIN_POS,
914 XmNbottomAttachment, XmATTACH_WIDGET,
915 XmNbottomWidget, ucd->nameTextW,
NULL);
916 XmStringFree(s1);
917
918 XtVaCreateManagedWidget(
"topLabel", xmLabelGadgetClass, form,
919 XmNlabelString, s1=
MKSTRING(
920 "Select a macro menu item from the list at left.\n\
921 Select \"New\" to add a new command to the menu."),
922 XmNtopAttachment, XmATTACH_POSITION,
923 XmNtopPosition,
2,
924 XmNleftAttachment, XmATTACH_POSITION,
925 XmNleftPosition,
LIST_RIGHT,
926 XmNrightAttachment, XmATTACH_POSITION,
927 XmNrightPosition,
RIGHT_MARGIN_POS,
928 XmNbottomAttachment, XmATTACH_WIDGET,
929 XmNbottomWidget, nameLabel,
NULL);
930 XmStringFree(s1);
931
932 cmdLabel = XtVaCreateManagedWidget(
"cmdLabel", xmLabelGadgetClass, form,
933 XmNlabelString, s1=
MKSTRING(
"Macro Command to Execute"),
934 XmNmnemonic,
'x',
935 XmNalignment, XmALIGNMENT_BEGINNING,
936 XmNmarginTop,
5,
937 XmNtopAttachment, XmATTACH_POSITION,
938 XmNtopPosition,
MACRO_CMD_TOP,
939 XmNleftAttachment, XmATTACH_POSITION,
940 XmNleftPosition,
LEFT_MARGIN_POS,
NULL);
941 XmStringFree(s1);
942
943 okBtn = XtVaCreateManagedWidget(
"ok",xmPushButtonWidgetClass,form,
944 XmNlabelString, s1=
MKSTRING(
"OK"),
945 XmNmarginWidth,
BUTTON_WIDTH_MARGIN,
946 XmNleftAttachment, XmATTACH_POSITION,
947 XmNleftPosition,
8,
948 XmNrightAttachment, XmATTACH_POSITION,
949 XmNrightPosition,
23,
950 XmNbottomAttachment, XmATTACH_POSITION,
951 XmNbottomPosition,
99,
NULL);
952 XtAddCallback(okBtn, XmNactivateCallback, okCB, ucd);
953 XmStringFree(s1);
954
955 applyBtn = XtVaCreateManagedWidget(
"apply",xmPushButtonWidgetClass,form,
956 XmNlabelString, s1=
MKSTRING(
"Apply"),
957 XmNmnemonic,
'A',
958 XmNleftAttachment, XmATTACH_POSITION,
959 XmNleftPosition,
31,
960 XmNrightAttachment, XmATTACH_POSITION,
961 XmNrightPosition,
46,
962 XmNbottomAttachment, XmATTACH_POSITION,
963 XmNbottomPosition,
99,
NULL);
964 XtAddCallback(applyBtn, XmNactivateCallback, applyCB, ucd);
965 XmStringFree(s1);
966
967 applyBtn = XtVaCreateManagedWidget(
"check",xmPushButtonWidgetClass,form,
968 XmNlabelString, s1=
MKSTRING(
"Check"),
969 XmNmnemonic,
'C',
970 XmNleftAttachment, XmATTACH_POSITION,
971 XmNleftPosition,
54,
972 XmNrightAttachment, XmATTACH_POSITION,
973 XmNrightPosition,
69,
974 XmNbottomAttachment, XmATTACH_POSITION,
975 XmNbottomPosition,
99,
NULL);
976 XtAddCallback(applyBtn, XmNactivateCallback, checkCB, ucd);
977 XmStringFree(s1);
978
979 closeBtn = XtVaCreateManagedWidget(
"close",
980 xmPushButtonWidgetClass, form,
981 XmNlabelString, s1=
MKSTRING(
"Close"),
982 XmNleftAttachment, XmATTACH_POSITION,
983 XmNleftPosition,
77,
984 XmNrightAttachment, XmATTACH_POSITION,
985 XmNrightPosition,
92,
986 XmNbottomAttachment, XmATTACH_POSITION,
987 XmNbottomPosition,
99,
988 NULL);
989 XtAddCallback(closeBtn, XmNactivateCallback, closeCB, ucd);
990 XmStringFree(s1);
991
992 ac =
0;
993 XtSetArg(args[ac], XmNeditMode, XmMULTI_LINE_EDIT); ac++;
994 XtSetArg(args[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
995 XtSetArg(args[ac], XmNtopWidget, cmdLabel); ac++;
996 XtSetArg(args[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
997 XtSetArg(args[ac], XmNleftPosition,
LEFT_MARGIN_POS); ac++;
998 XtSetArg(args[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
999 XtSetArg(args[ac], XmNrightPosition,
RIGHT_MARGIN_POS); ac++;
1000 XtSetArg(args[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
1001 XtSetArg(args[ac], XmNbottomWidget, okBtn); ac++;
1002 XtSetArg(args[ac], XmNbottomOffset,
5); ac++;
1003 ucd->cmdTextW = XmCreateScrolledText(form,
"name", args, ac);
1004 AddMouseWheelSupport(ucd->cmdTextW);
1005 XtManageChild(ucd->cmdTextW);
1006 RemapDeleteKey(ucd->cmdTextW);
1007 XtVaSetValues(cmdLabel, XmNuserData, ucd->cmdTextW,
NULL);
1008
1009
1010
1011 disableTextW(ucd->accTextW);
1012
1013
1014 updateDialogFields(
NULL, ucd);
1015
1016
1017 XtVaSetValues(form, XmNdefaultButton, okBtn,
NULL);
1018 XtVaSetValues(form, XmNcancelButton, closeBtn,
NULL);
1019
1020
1021 AddDialogMnemonicHandler(form,
FALSE);
1022
1023
1024
1025 if (dialogType ==
MACRO_CMDS) {
1026 MacroCmdDialog = ucd->dlogShell;
1027 MacroPasteReplayBtn = pasteReplayBtn;
1028 }
else {
1029 BGMenuCmdDialog = ucd->dlogShell;
1030 BGMenuPasteReplayBtn = pasteReplayBtn;
1031 }
1032
1033
1034 RealizeWithoutForcingPosition(ucd->dlogShell);
1035 }
1036
1037
1038
1039
1040
1041 void UpdateUserMenus(WindowInfo *window)
1042 {
1043 if (!IsTopDocument(window))
1044 return;
1045
1046
1047
1048 if (window->userMenuCache->umcLanguageMode != window->languageMode) {
1049 updateMenu(window,
SHELL_CMDS);
1050 updateMenu(window,
MACRO_CMDS);
1051
1052
1053 window->userMenuCache->umcLanguageMode = window->languageMode;
1054 }
1055
1056
1057
1058 if (window->userBGMenuCache.ubmcLanguageMode != window->languageMode) {
1059 updateMenu(window,
BG_MENU_CMDS);
1060
1061
1062 window->userBGMenuCache.ubmcLanguageMode = window->languageMode;
1063 }
1064 }
1065
1066
1067
1068
1069 void DimPasteReplayBtns(
int sensitive)
1070 {
1071 if (MacroCmdDialog !=
NULL)
1072 XtSetSensitive(MacroPasteReplayBtn, sensitive);
1073 if (BGMenuCmdDialog !=
NULL)
1074 XtSetSensitive(BGMenuPasteReplayBtn, sensitive);
1075 }
1076
1077
1078
1079
1080
1081 void DimSelectionDepUserMenuItems(WindowInfo *window,
int sensitive)
1082 {
1083 if (!IsTopDocument(window))
1084 return;
1085
1086 dimSelDepItemsInMenu(window->shellMenuPane, ShellMenuItems,
1087 NShellMenuItems, sensitive);
1088 dimSelDepItemsInMenu(window->macroMenuPane, MacroMenuItems,
1089 NMacroMenuItems, sensitive);
1090 dimSelDepItemsInMenu(window->bgMenuPane, BGMenuItems,
1091 NBGMenuItems, sensitive);
1092 }
1093
1094 static void dimSelDepItemsInMenu(Widget menuPane, menuItemRec **menuList,
1095 int nMenuItems,
int sensitive)
1096 {
1097 WidgetList items;
1098 Widget subMenu;
1099 XtPointer userData;
1100 int n, index;
1101 Cardinal nItems;
1102
1103 XtVaGetValues(menuPane, XmNchildren, &items, XmNnumChildren, &nItems,
NULL);
1104 for (n=
0; n<(
int)nItems; n++) {
1105 XtVaGetValues(items[n], XmNuserData, &userData,
NULL);
1106 if (userData != (XtPointer)
PERMANENT_MENU_ITEM) {
1107 if (XtClass(items[n]) == xmCascadeButtonWidgetClass) {
1108 XtVaGetValues(items[n], XmNsubMenuId, &subMenu,
NULL);
1109 dimSelDepItemsInMenu(subMenu, menuList, nMenuItems, sensitive);
1110 }
else {
1111 index = (
int)(
intptr_t)userData -
10;
1112 if (index <
0 || index >= nMenuItems)
1113 return;
1114 if (menuList[index]->input ==
FROM_SELECTION)
1115 XtSetSensitive(items[n], sensitive);
1116 }
1117 }
1118 }
1119 }
1120
1121
1122
1123
1124
1125
1126 void SetBGMenuUndoSensitivity(WindowInfo *window,
int sensitive)
1127 {
1128 if (window->bgMenuUndoItem !=
NULL)
1129 SetSensitive(window, window->bgMenuUndoItem, sensitive);
1130 }
1131 void SetBGMenuRedoSensitivity(WindowInfo *window,
int sensitive)
1132 {
1133 if (window->bgMenuRedoItem !=
NULL)
1134 SetSensitive(window, window->bgMenuRedoItem, sensitive);
1135 }
1136
1137
1138
1139
1140
1141
1142
1143 char *WriteShellCmdsString(
void)
1144 {
1145 return writeMenuItemString(ShellMenuItems, NShellMenuItems,
1146 SHELL_CMDS);
1147 }
1148
1149
1150
1151
1152
1153
1154
1155
1156 char *WriteMacroCmdsString(
void)
1157 {
1158 return writeMenuItemString(MacroMenuItems, NMacroMenuItems,
MACRO_CMDS);
1159 }
1160
1161 char *WriteBGMenuCmdsString(
void)
1162 {
1163 return writeMenuItemString(BGMenuItems, NBGMenuItems,
BG_MENU_CMDS);
1164 }
1165
1166
1167
1168
1169
1170 int LoadShellCmdsString(
char *inString)
1171 {
1172 return loadMenuItemString(inString, ShellMenuItems, &NShellMenuItems,
1173 SHELL_CMDS);
1174 }
1175
1176
1177
1178
1179
1180 int LoadMacroCmdsString(
char *inString)
1181 {
1182 return loadMenuItemString(inString, MacroMenuItems, &NMacroMenuItems,
1183 MACRO_CMDS);
1184 }
1185
1186 int LoadBGMenuCmdsString(
char *inString)
1187 {
1188 return loadMenuItemString(inString, BGMenuItems, &NBGMenuItems,
1189 BG_MENU_CMDS);
1190 }
1191
1192
1193
1194
1195
1196
1197
1198 void SetupUserMenuInfo(
void)
1199 {
1200 parseMenuItemList(ShellMenuItems, NShellMenuItems, ShellMenuInfo, &ShellSubMenus);
1201 parseMenuItemList(MacroMenuItems, NMacroMenuItems, MacroMenuInfo, &MacroSubMenus);
1202 parseMenuItemList(BGMenuItems , NBGMenuItems , BGMenuInfo , &BGSubMenus);
1203 }
1204
1205
1206
1207
1208
1209
1210 void UpdateUserMenuInfo(
void)
1211 {
1212 freeUserMenuInfoList(ShellMenuInfo, NShellMenuItems);
1213 freeSubMenuCache(&ShellSubMenus);
1214 parseMenuItemList(ShellMenuItems, NShellMenuItems, ShellMenuInfo, &ShellSubMenus);
1215
1216 freeUserMenuInfoList(MacroMenuInfo, NMacroMenuItems);
1217 freeSubMenuCache(&MacroSubMenus);
1218 parseMenuItemList(MacroMenuItems, NMacroMenuItems, MacroMenuInfo, &MacroSubMenus);
1219
1220 freeUserMenuInfoList(BGMenuInfo, NBGMenuItems);
1221 freeSubMenuCache(&BGSubMenus);
1222 parseMenuItemList(BGMenuItems, NBGMenuItems, BGMenuInfo, &BGSubMenus);
1223 }
1224
1225
1226
1227
1228
1229 int DoNamedShellMenuCmd(WindowInfo *window,
const char *itemName,
int fromMacro)
1230 {
1231 int i;
1232
1233 for (i=
0; i<NShellMenuItems; i++) {
1234 if (!strcmp(ShellMenuItems[i]->name, itemName)) {
1235 if (ShellMenuItems[i]->output ==
TO_SAME_WINDOW &&
1236 CheckReadOnly(window))
1237 return False;
1238 DoShellMenuCmd(window, ShellMenuItems[i]->cmd,
1239 ShellMenuItems[i]->input, ShellMenuItems[i]->output,
1240 ShellMenuItems[i]->repInput, ShellMenuItems[i]->saveFirst,
1241 ShellMenuItems[i]->loadAfter, fromMacro);
1242 return True;
1243 }
1244 }
1245 return False;
1246 }
1247
1248
1249
1250
1251
1252
1253 int DoNamedMacroMenuCmd(WindowInfo *window,
const char *itemName)
1254 {
1255 int i;
1256
1257 for (i=
0; i<NMacroMenuItems; i++) {
1258 if (!strcmp(MacroMenuItems[i]->name, itemName)) {
1259 DoMacro(window, MacroMenuItems[i]->cmd,
"macro menu command");
1260 return True;
1261 }
1262 }
1263 return False;
1264 }
1265
1266 int DoNamedBGMenuCmd(WindowInfo *window,
const char *itemName)
1267 {
1268 int i;
1269
1270 for (i=
0; i<NBGMenuItems; i++) {
1271 if (!strcmp(BGMenuItems[i]->name, itemName)) {
1272 DoMacro(window, BGMenuItems[i]->cmd,
"background menu macro");
1273 return True;
1274 }
1275 }
1276 return False;
1277 }
1278
1279
1280
1281
1282
1283 void RebuildAllMenus(WindowInfo *window)
1284 {
1285 rebuildMenu(window,
SHELL_CMDS);
1286 rebuildMenu(window,
MACRO_CMDS);
1287 rebuildMenu(window,
BG_MENU_CMDS);
1288 }
1289
1290
1291
1292
1293
1294 static void rebuildMenuOfAllWindows(
int menuType)
1295 {
1296 WindowInfo *w;
1297
1298 for (w=WindowList; w!=
NULL; w=w->next)
1299 rebuildMenu(w, menuType);
1300 }
1301
1302
1303
1304
1305
1306
1307
1308
1309 static void rebuildMenu(WindowInfo *window,
int menuType)
1310 {
1311 selectedUserMenu menu;
1312
1313
1314
1315
1316 if (menuType !=
BG_MENU_CMDS && !IsTopDocument(window))
1317 return;
1318
1319
1320 selectUserMenu(window, menuType, &menu);
1321
1322
1323
1324
1325
1326
1327
1328
1329 if (!XmIsMenuShell(XtParent(menu.sumMenuPane)))
1330 _XmDismissTearOff(XtParent(menu.sumMenuPane),
NULL,
NULL);
1331
1332
1333 deleteMenuItems(menu.sumMenuPane);
1334
1335
1336 freeUserMenuList(menu.sumMainMenuList);
1337 *menu.sumMenuCreated = False;
1338
1339
1340 updateMenu(window, menuType);
1341 }
1342
1343
1344
1345
1346 static void selectUserMenu(WindowInfo *window,
int menuType, selectedUserMenu *menu)
1347 {
1348 if (menuType ==
SHELL_CMDS) {
1349 menu->sumMenuPane = window->shellMenuPane;
1350 menu->sumNbrOfListItems = NShellMenuItems;
1351 menu->sumItemList = ShellMenuItems;
1352 menu->sumInfoList = ShellMenuInfo;
1353 menu->sumSubMenus = &ShellSubMenus;
1354 menu->sumMainMenuList = &window->userMenuCache->umcShellMenuList;
1355 menu->sumMenuCreated = &window->userMenuCache->umcShellMenuCreated;
1356 }
else if (menuType ==
MACRO_CMDS) {
1357 menu->sumMenuPane = window->macroMenuPane;
1358 menu->sumNbrOfListItems = NMacroMenuItems;
1359 menu->sumItemList = MacroMenuItems;
1360 menu->sumInfoList = MacroMenuInfo;
1361 menu->sumSubMenus = &MacroSubMenus;
1362 menu->sumMainMenuList = &window->userMenuCache->umcMacroMenuList;
1363 menu->sumMenuCreated = &window->userMenuCache->umcMacroMenuCreated;
1364 }
else {
1365 menu->sumMenuPane = window->bgMenuPane;
1366 menu->sumNbrOfListItems = NBGMenuItems;
1367 menu->sumItemList = BGMenuItems;
1368 menu->sumInfoList = BGMenuInfo;
1369 menu->sumSubMenus = &BGSubMenus;
1370 menu->sumMainMenuList = &window->userBGMenuCache.ubmcMenuList;
1371 menu->sumMenuCreated = &window->userBGMenuCache.ubmcMenuCreated;
1372 }
1373 menu->sumType = menuType;
1374 }
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386 static void updateMenu(WindowInfo *window,
int menuType)
1387 {
1388 selectedUserMenu menu;
1389
1390 EnableWindowResourceDB(window);
1391
1392
1393 selectUserMenu(window, menuType, &menu);
1394
1395
1396 applyLangModeToUserMenuInfo(menu.sumInfoList, menu.sumNbrOfListItems,
1397 window->languageMode);
1398
1399
1400 if (!*menu.sumMenuCreated)
1401 createMenuItems(window, &menu);
1402
1403
1404 manageUserMenu(&menu, window);
1405
1406 if (menuType ==
BG_MENU_CMDS) {
1407
1408 SetBGMenuUndoSensitivity(window, XtIsSensitive(window->undoItem));
1409 SetBGMenuRedoSensitivity(window, XtIsSensitive(window->redoItem));
1410 }
1411
1412 DimSelectionDepUserMenuItems(window, window->buffer->primary.selected);
1413
1414
1415 EnableDefaultColorProfileResourceDB(XtDisplay(window->mainWin));
1416 }
1417
1418
1419
1420
1421
1422
1423 static void manageTearOffMenu(Widget menuPane)
1424 {
1425 Dimension width, height, border;
1426
1427
1428
1429
1430
1431 XtVaGetValues(XtParent(menuPane), XmNborderWidth, &border,
NULL);
1432 XtVaGetValues(menuPane, XmNwidth, &width, XmNheight, &height,
NULL);
1433 XtResizeWidget(XtParent(menuPane), width, height, border);
1434
1435 XtManageChild(menuPane);
1436 }
1437
1438
1439
1440
1441
1442 static void resetManageMode(UserMenuList *list)
1443 {
1444 int i;
1445 UserMenuListElement *element;
1446
1447 for (i=
0; i<list->umlNbrItems; i ++) {
1448 element = list->umlItems[i];
1449
1450
1451
1452 element->umlePrevManageMode = element->umleManageMode;
1453 element->umleManageMode =
UMMM_UNMANAGE;
1454
1455
1456 if (element->umleSubMenuList !=
NULL)
1457 resetManageMode(element->umleSubMenuList);
1458 }
1459 }
1460
1461
1462
1463
1464
1465 static void manageAllSubMenuWidgets(UserMenuListElement *subMenu)
1466 {
1467 int i;
1468 UserMenuList *subMenuList;
1469 UserMenuListElement *element;
1470 WidgetList widgetList;
1471 Cardinal nWidgetListItems;
1472
1473
1474
1475
1476
1477 if (!XmIsMenuShell(XtParent(subMenu->umleSubMenuPane))) {
1478 XtUnmanageChild(subMenu->umleSubMenuPane);
1479 }
1480
1481
1482 XtVaGetValues(subMenu->umleSubMenuPane,
1483 XmNchildren, &widgetList,
1484 XmNnumChildren, &nWidgetListItems,
1485 NULL);
1486 XtManageChildren(widgetList, nWidgetListItems);
1487
1488
1489
1490 subMenuList = subMenu->umleSubMenuList;
1491
1492 for (i=
0; i<subMenuList->umlNbrItems; i ++) {
1493 element = subMenuList->umlItems[i];
1494
1495 if (element->umleSubMenuList !=
NULL) {
1496
1497
1498 manageAllSubMenuWidgets(element);
1499 }
1500 }
1501
1502
1503 XtManageChild(subMenu->umleMenuItem);
1504
1505
1506 if (!XmIsMenuShell(XtParent(subMenu->umleSubMenuPane))) {
1507 manageTearOffMenu(subMenu->umleSubMenuPane);
1508 }
1509
1510
1511
1512 ShowHiddenTearOff(subMenu->umleSubMenuPane);
1513 }
1514
1515
1516
1517
1518
1519 static void unmanageAllSubMenuWidgets(UserMenuListElement *subMenu)
1520 {
1521 int i;
1522 Widget shell;
1523 UserMenuList *subMenuList;
1524 UserMenuListElement *element;
1525 WidgetList widgetList;
1526 Cardinal nWidgetListItems;
1527
1528
1529
1530 shell = XtParent(subMenu->umleSubMenuPane);
1531 if (!XmIsMenuShell(shell)) {
1532 XtUnmapWidget(shell);
1533 }
1534
1535
1536 XtVaGetValues(subMenu->umleSubMenuPane,
1537 XmNchildren, &widgetList,
1538 XmNnumChildren, &nWidgetListItems,
1539 NULL);
1540 XtUnmanageChildren(widgetList, nWidgetListItems);
1541
1542
1543
1544 subMenuList = subMenu->umleSubMenuList;
1545
1546 for (i=
0; i<subMenuList->umlNbrItems; i ++) {
1547 element = subMenuList->umlItems[i];
1548
1549 if (element->umleSubMenuList !=
NULL) {
1550
1551
1552 unmanageAllSubMenuWidgets(element);
1553 }
1554 }
1555
1556
1557 XtUnmanageChild(subMenu->umleMenuItem);
1558 }
1559
1560
1561
1562
1563
1564 static void manageMenuWidgets(UserMenuList *list)
1565 {
1566 int i;
1567 UserMenuListElement *element;
1568
1569
1570 for (i=
0; i<list->umlNbrItems; i ++) {
1571 element = list->umlItems[i];
1572
1573 if (element->umlePrevManageMode != element->umleManageMode ||
1574 element->umleManageMode ==
UMMM_MANAGE) {
1575
1576
1577
1578 if (element->umleManageMode ==
UMMM_MANAGE_ALL) {
1579
1580
1581 manageAllSubMenuWidgets(element);
1582 }
else if (element->umleManageMode ==
UMMM_MANAGE) {
1583 if (element->umlePrevManageMode ==
UMMM_UNMANAGE ||
1584 element->umlePrevManageMode ==
UMMM_UNMANAGE_ALL) {
1585
1586
1587 XtManageChild(element->umleMenuItem);
1588 }
1589
1590
1591
1592 if (element->umleSubMenuList !=
NULL) {
1593
1594
1595
1596
1597 if (!XmIsMenuShell(XtParent(element->umleSubMenuPane))) {
1598 XtUnmanageChild(element->umleSubMenuPane);
1599 }
1600
1601
1602 manageMenuWidgets(element->umleSubMenuList);
1603
1604
1605 if (!XmIsMenuShell(XtParent(element->umleSubMenuPane))) {
1606 manageTearOffMenu(element->umleSubMenuPane);
1607 }
1608
1609
1610 ShowHiddenTearOff(element->umleSubMenuPane);
1611 }
1612 }
else if (element->umleManageMode ==
UMMM_UNMANAGE_ALL){
1613
1614
1615 unmanageAllSubMenuWidgets(element);
1616 }
else {
1617
1618
1619
1620 XtUnmanageChild(element->umleMenuItem);
1621 }
1622 }
1623 }
1624 }
1625
1626
1627
1628
1629
1630 static void removeAccelFromMenuWidgets(UserMenuList *menuList)
1631 {
1632 int i;
1633 UserMenuListElement *element;
1634
1635
1636 for (i=
0; i<menuList->umlNbrItems; i ++) {
1637 element = menuList->umlItems[i];
1638
1639 if (element->umleSubMenuList !=
NULL) {
1640
1641
1642 removeAccelFromMenuWidgets(element->umleSubMenuList);
1643 }
else if (element->umleAccKeys !=
NULL &&
1644 element->umleManageMode ==
UMMM_UNMANAGE &&
1645 element->umlePrevManageMode ==
UMMM_MANAGE) {
1646
1647 XtVaSetValues(element->umleMenuItem, XmNaccelerator,
NULL,
NULL);
1648 }
1649 }
1650 }
1651
1652
1653
1654
1655
1656 static void assignAccelToMenuWidgets(UserMenuList *menuList, WindowInfo *window)
1657 {
1658 int i;
1659 UserMenuListElement *element;
1660
1661
1662 for (i=
0; i<menuList->umlNbrItems; i ++) {
1663 element = menuList->umlItems[i];
1664
1665 if (element->umleSubMenuList !=
NULL) {
1666
1667
1668 assignAccelToMenuWidgets(element->umleSubMenuList, window);
1669 }
else if (element->umleAccKeys !=
NULL &&
1670 element->umleManageMode ==
UMMM_MANAGE &&
1671 element->umlePrevManageMode ==
UMMM_UNMANAGE) {
1672
1673 XtVaSetValues(element->umleMenuItem, XmNaccelerator,
1674 element->umleAccKeys,
NULL);
1675 if (!element->umleAccLockPatchApplied) {
1676 UpdateAccelLockPatch(window->splitPane, element->umleMenuItem);
1677 element->umleAccLockPatchApplied = True;
1678 }
1679 }
1680 }
1681 }
1682
1683
1684
1685
1686
1687 static void manageUserMenu(selectedUserMenu *menu, WindowInfo *window)
1688 {
1689 int n, i;
1690 int *id;
1691 Boolean currentLEisSubMenu;
1692 userMenuInfo *info;
1693 UserMenuList *menuList;
1694 UserMenuListElement *currentLE;
1695 UserMenuManageMode *mode;
1696
1697
1698 resetManageMode(menu->sumMainMenuList);
1699
1700
1701
1702 for (n=
0; n<menu->sumNbrOfListItems; n++) {
1703 info = menu->sumInfoList[n];
1704
1705 menuList = menu->sumMainMenuList;
1706 id = info->umiId;
1707
1708
1709
1710
1711 for (i=
0; i<info->umiIdLen; i ++) {
1712 currentLE = menuList->umlItems[*id];
1713 mode = ¤tLE->umleManageMode;
1714 currentLEisSubMenu = (currentLE->umleSubMenuList !=
NULL);
1715
1716 if (info->umiToBeManaged) {
1717
1718 if (*mode ==
UMMM_UNMANAGE) {
1719
1720
1721
1722
1723
1724 if (currentLEisSubMenu) {
1725 *mode =
UMMM_MANAGE_ALL;
1726 }
else {
1727 *mode =
UMMM_MANAGE;
1728 }
1729 }
else if (*mode ==
UMMM_UNMANAGE_ALL) {
1730
1731
1732
1733
1734
1735 *mode =
UMMM_MANAGE;
1736 }
1737 }
else {
1738
1739 if (*mode ==
UMMM_UNMANAGE) {
1740
1741
1742
1743
1744 if (currentLEisSubMenu) {
1745 *mode =
UMMM_UNMANAGE_ALL;
1746 }
1747 }
else if (*mode ==
UMMM_MANAGE_ALL) {
1748
1749
1750
1751
1752
1753 *mode =
UMMM_MANAGE;
1754 }
1755 }
1756
1757 menuList = currentLE->umleSubMenuList;
1758
1759 id ++;
1760 }
1761 }
1762
1763
1764
1765
1766
1767 if (!XmIsMenuShell(XtParent(menu->sumMenuPane)))
1768 XtUnmanageChild(menu->sumMenuPane);
1769
1770
1771
1772 manageMenuWidgets(menu->sumMainMenuList);
1773
1774
1775
1776
1777
1778 removeAccelFromMenuWidgets(menu->sumMainMenuList);
1779
1780 assignAccelToMenuWidgets(menu->sumMainMenuList, window);
1781
1782
1783 if (!XmIsMenuShell(XtParent(menu->sumMenuPane)))
1784 manageTearOffMenu(menu->sumMenuPane);
1785 }
1786
1787
1788
1789
1790
1791 static void createMenuItems(WindowInfo *window, selectedUserMenu *menu)
1792 {
1793 Widget btn, subPane, newSubPane;
1794 int n;
1795 menuItemRec *item;
1796 menuTreeItem *menuTree;
1797 int i, nTreeEntries, size;
1798 char *hierName, *namePtr, *subMenuName, *subSep, *fullName;
1799 int menuType = menu->sumType;
1800 userMenuInfo *info;
1801 userSubMenuCache *subMenus = menu->sumSubMenus;
1802 userSubMenuInfo *subMenuInfo;
1803 UserMenuList *menuList;
1804 UserMenuListElement *currentLE;
1805 int subMenuDepth;
1806 char accKeysBuf[
MAX_ACCEL_LEN+
5];
1807 char *accKeys;
1808
1809
1810 size =
sizeof(menuTreeItem) * menu->sumNbrOfListItems;
1811 menuTree = (menuTreeItem *)NEditMalloc(size);
1812 nTreeEntries =
0;
1813
1814
1815
1816 window->bgMenuUndoItem =
NULL;
1817 window->bgMenuRedoItem =
NULL;
1818
1819
1820
1821
1822
1823 allocUserMenuList(menu->sumMainMenuList, subMenus->usmcNbrOfMainMenuItems);
1824 for (n=
0; n<menu->sumNbrOfListItems; n++) {
1825 item = menu->sumItemList[n];
1826 info = menu->sumInfoList[n];
1827 menuList = menu->sumMainMenuList;
1828 subMenuDepth =
0;
1829
1830 fullName = info->umiName;
1831
1832
1833
1834 namePtr = fullName;
1835 subPane = menu->sumMenuPane;
1836 for (;;) {
1837 subSep = strchr(namePtr,
'>');
1838 if (subSep ==
NULL) {
1839 btn = createUserMenuItem(subPane, namePtr, item, n,
1840 (XtCallbackProc)(menuType ==
SHELL_CMDS ? shellMenuCB :
1841 (menuType ==
MACRO_CMDS ? macroMenuCB : bgMenuCB)),
1842 (XtPointer)window);
1843 if (menuType ==
BG_MENU_CMDS && !strcmp(item->cmd,
"undo()\n"))
1844 window->bgMenuUndoItem = btn;
1845 else if (menuType ==
BG_MENU_CMDS && !strcmp(item->cmd,
"redo()\n"))
1846 window->bgMenuRedoItem = btn;
1847
1848 genAccelEventName(accKeysBuf, item->modifiers, item->keysym);
1849 accKeys = item->keysym == NoSymbol ?
NULL : NEditStrdup(accKeysBuf);
1850
1851 menuList->umlItems[menuList->umlNbrItems ++] =
1852 allocUserMenuListElement(btn, accKeys);
1853 break;
1854 }
1855 hierName = copySubstring(fullName, subSep - fullName);
1856 subMenuInfo = findSubMenuInfo(subMenus, hierName);
1857 newSubPane = findInMenuTree(menuTree, nTreeEntries, hierName);
1858 if (newSubPane ==
NULL) {
1859 subMenuName = copySubstring(namePtr, subSep - namePtr);
1860 newSubPane = createUserSubMenu(subPane, subMenuName, &btn);
1861 NEditFree(subMenuName);
1862 menuTree[nTreeEntries].name = hierName;
1863 menuTree[nTreeEntries++].menuPane = newSubPane;
1864
1865 currentLE = allocUserMenuListElement(btn,
NULL);
1866 menuList->umlItems[menuList->umlNbrItems ++] = currentLE;
1867 currentLE->umleSubMenuPane = newSubPane;
1868 currentLE->umleSubMenuList =
1869 allocUserSubMenuList(subMenuInfo->usmiId[subMenuInfo->usmiIdLen]);
1870 }
else {
1871 currentLE = menuList->umlItems[subMenuInfo->usmiId[subMenuDepth]];
1872 NEditFree(hierName);
1873 }
1874 subPane = newSubPane;
1875 menuList = currentLE->umleSubMenuList;
1876 subMenuDepth ++;
1877 namePtr = subSep +
1;
1878 }
1879 }
1880
1881 *menu->sumMenuCreated = True;
1882
1883
1884 for (i=
0; i<nTreeEntries; i++)
1885 NEditFree(menuTree[i].name);
1886 NEditFree(menuTree);
1887 }
1888
1889
1890
1891
1892 static Widget findInMenuTree(menuTreeItem *menuTree,
int nTreeEntries,
1893 const char *hierName)
1894 {
1895 int i;
1896
1897 for (i=
0; i<nTreeEntries; i++)
1898 if (!strcmp(hierName, menuTree[i].name))
1899 return menuTree[i].menuPane;
1900 return NULL;
1901 }
1902
1903 static char *copySubstring(
const char *string,
int length)
1904 {
1905 char *retStr = (
char*)NEditMalloc(length +
1);
1906
1907 strncpy(retStr, string, length);
1908 retStr[length] =
'\0';
1909 return retStr;
1910 }
1911
1912 static Widget createUserMenuItem(Widget menuPane,
char *name, menuItemRec *f,
1913 int index, XtCallbackProc cbRtn, XtPointer cbArg)
1914 {
1915 XmString st1, st2;
1916 char accText[
MAX_ACCEL_LEN];
1917 Widget btn;
1918
1919 generateAcceleratorString(accText, f->modifiers, f->keysym);
1920 st1=XmStringCreateSimple(name);
1921 st2=XmStringCreateSimple(accText);
1922 btn = XtVaCreateWidget(
"cmd", xmPushButtonWidgetClass, menuPane,
1923 XmNlabelString, st1,
1924 XmNacceleratorText, st2,
1925 XmNmnemonic, f->mnemonic,
1926 XmNuserData, (XtPointer)(
intptr_t)(index+
10),
NULL);
1927 XtAddCallback(btn, XmNactivateCallback, cbRtn, cbArg);
1928 XmStringFree(st1);
1929 XmStringFree(st2);
1930 return btn;
1931 }
1932
1933
1934
1935
1936
1937
1938
1939 static Widget createUserSubMenu(Widget parent,
char *label, Widget *menuItem)
1940 {
1941 Widget menuPane;
1942 XmString st1;
1943 static Arg args[
1] = {{XmNuserData, (XtArgVal)
TEMPORARY_MENU_ITEM}};
1944
1945 menuPane = CreatePulldownMenu(parent,
"userPulldown", args,
1);
1946 *menuItem = XtVaCreateWidget(
"userCascade", xmCascadeButtonWidgetClass, parent,
1947 XmNlabelString, st1=XmStringCreateSimple(label),
1948 XmNsubMenuId, menuPane, XmNuserData,
TEMPORARY_MENU_ITEM,
1949 NULL);
1950 XmStringFree(st1);
1951 return menuPane;
1952 }
1953
1954
1955
1956
1957
1958 static void deleteMenuItems(Widget menuPane)
1959 {
1960 WidgetList itemList, items;
1961 Cardinal nItems;
1962 Widget subMenuID;
1963 XtPointer userData;
1964 int n;
1965
1966
1967 XtVaGetValues(menuPane, XmNchildren, &itemList,
1968 XmNnumChildren, &nItems,
NULL);
1969
1970
1971 items = (WidgetList)NEditMalloc(
sizeof(Widget) * nItems);
1972 memcpy(items, itemList,
sizeof(Widget) * nItems);
1973
1974
1975 for (n=
0; n<(
int)nItems; n++) {
1976 XtVaGetValues(items[n], XmNuserData, &userData,
NULL);
1977 if (userData != (XtPointer)
PERMANENT_MENU_ITEM) {
1978 if (XtClass(items[n]) == xmCascadeButtonWidgetClass) {
1979 XtVaGetValues(items[n], XmNsubMenuId, &subMenuID,
NULL);
1980
1981
1982 if (!XmIsMenuShell(XtParent(subMenuID)))
1983 _XmDismissTearOff(XtParent(subMenuID),
NULL,
NULL);
1984
1985 deleteMenuItems(subMenuID);
1986 #if XmVersion <
2000
1987
1988
1989
1990
1991
1992
1993 XtDestroyWidget(subMenuID);
1994 #endif
1995 }
else {
1996
1997 XtVaSetValues(items[n], XmNaccelerator,
NULL,
NULL);
1998 }
1999 XtDestroyWidget(items[n]);
2000 }
2001 }
2002 NEditFree(items);
2003 }
2004
2005 static void closeCB(Widget w, XtPointer clientData, XtPointer callData)
2006 {
2007 userCmdDialog *ucd = (userCmdDialog *)clientData;
2008
2009
2010 if (ucd->dialogType ==
SHELL_CMDS)
2011 ShellCmdDialog =
NULL;
2012 else if (ucd->dialogType ==
MACRO_CMDS)
2013 MacroCmdDialog =
NULL;
2014 else
2015 BGMenuCmdDialog =
NULL;
2016
2017
2018
2019 XtDestroyWidget(ucd->dlogShell);
2020 }
2021
2022 static void okCB(Widget w, XtPointer clientData, XtPointer callData)
2023 {
2024 userCmdDialog *ucd = (userCmdDialog *)clientData;
2025
2026
2027 if (!applyDialogChanges(ucd))
2028 return;
2029
2030
2031 if (ucd->dialogType ==
SHELL_CMDS)
2032 ShellCmdDialog =
NULL;
2033 else if (ucd->dialogType ==
MACRO_CMDS)
2034 MacroCmdDialog =
NULL;
2035 else
2036 BGMenuCmdDialog =
NULL;
2037
2038
2039
2040 XtDestroyWidget(ucd->dlogShell);
2041 }
2042
2043 static void applyCB(Widget w, XtPointer clientData, XtPointer callData)
2044 {
2045 applyDialogChanges((userCmdDialog *)clientData);
2046 }
2047
2048 static void checkCB(Widget w, XtPointer clientData, XtPointer callData)
2049 {
2050 userCmdDialog *ucd = (userCmdDialog *)clientData;
2051
2052 if (checkMacro(ucd))
2053 {
2054 DialogF(
DF_INF, ucd->dlogShell,
1,
"Macro",
2055 "Macro compiled without error",
"OK");
2056 }
2057 }
2058
2059 static int checkMacro(userCmdDialog *ucd)
2060 {
2061 menuItemRec *f;
2062
2063 f = readDialogFields(ucd, False);
2064 if (f ==
NULL)
2065 return False;
2066 if (!checkMacroText(f->cmd, ucd->dlogShell, ucd->cmdTextW)) {
2067 freeMenuItemRec(f);
2068 return False;
2069 }
2070 return True;
2071 }
2072
2073 static int checkMacroText(
char *macro, Widget errorParent, Widget errFocus)
2074 {
2075 Program *prog;
2076 char *errMsg, *stoppedAt;
2077
2078 prog = ParseMacro(macro, &errMsg, &stoppedAt);
2079 if (prog ==
NULL) {
2080 if (errorParent !=
NULL) {
2081 ParseError(errorParent, macro, stoppedAt,
"macro", errMsg);
2082 XmTextSetInsertionPosition(errFocus, stoppedAt - macro);
2083 XmProcessTraversal(errFocus, XmTRAVERSE_CURRENT);
2084 }
2085 return False;
2086 }
2087 FreeProgram(prog);
2088 if (*stoppedAt !=
'\0') {
2089 if (errorParent !=
NULL) {
2090 ParseError(errorParent, macro, stoppedAt,
"macro",
"syntax error");
2091 XmTextSetInsertionPosition(errFocus, stoppedAt - macro);
2092 XmProcessTraversal(errFocus, XmTRAVERSE_CURRENT);
2093 }
2094 return False;
2095 }
2096 return True;
2097 }
2098
2099 static int applyDialogChanges(userCmdDialog *ucd)
2100 {
2101 int i;
2102
2103
2104 if (!UpdateManagedList(ucd->managedList, True))
2105 return False;
2106
2107
2108 if (ucd->dialogType ==
MACRO_CMDS)
2109 if (!checkMacro(ucd))
2110 return False;
2111
2112
2113 if (ucd->dialogType ==
SHELL_CMDS) {
2114 for (i=
0; i<NShellMenuItems; i++)
2115 freeMenuItemRec(ShellMenuItems[i]);
2116 freeUserMenuInfoList(ShellMenuInfo, NShellMenuItems);
2117 freeSubMenuCache(&ShellSubMenus);
2118 for (i=
0; i<ucd->nMenuItems; i++)
2119 ShellMenuItems[i] = copyMenuItemRec(ucd->menuItemsList[i]);
2120 NShellMenuItems = ucd->nMenuItems;
2121 parseMenuItemList(ShellMenuItems, NShellMenuItems, ShellMenuInfo, &ShellSubMenus);
2122 }
else if (ucd->dialogType ==
MACRO_CMDS) {
2123 for (i=
0; i<NMacroMenuItems; i++)
2124 freeMenuItemRec(MacroMenuItems[i]);
2125 freeUserMenuInfoList(MacroMenuInfo, NMacroMenuItems);
2126 freeSubMenuCache(&MacroSubMenus);
2127 for (i=
0; i<ucd->nMenuItems; i++)
2128 MacroMenuItems[i] = copyMenuItemRec(ucd->menuItemsList[i]);
2129 NMacroMenuItems = ucd->nMenuItems;
2130 parseMenuItemList(MacroMenuItems, NMacroMenuItems, MacroMenuInfo, &MacroSubMenus);
2131 }
else {
2132 for (i=
0; i<NBGMenuItems; i++)
2133 freeMenuItemRec(BGMenuItems[i]);
2134 freeUserMenuInfoList(BGMenuInfo, NBGMenuItems);
2135 freeSubMenuCache(&BGSubMenus);
2136 for (i=
0; i<ucd->nMenuItems; i++)
2137 BGMenuItems[i] = copyMenuItemRec(ucd->menuItemsList[i]);
2138 NBGMenuItems = ucd->nMenuItems;
2139 parseMenuItemList(BGMenuItems, NBGMenuItems, BGMenuInfo, &BGSubMenus);
2140 }
2141
2142
2143 rebuildMenuOfAllWindows(ucd->dialogType);
2144
2145
2146 MarkPrefsChanged();
2147 return True;
2148 }
2149
2150 static void pasteReplayCB(Widget w, XtPointer clientData, XtPointer callData)
2151 {
2152 userCmdDialog *ucd = (userCmdDialog *)clientData;
2153
2154 if (GetReplayMacro() ==
NULL)
2155 return;
2156
2157 XmTextInsert(ucd->cmdTextW, XmTextGetInsertionPosition(ucd->cmdTextW),
2158 GetReplayMacro());
2159 }
2160
2161 static void destroyCB(Widget w, XtPointer clientData, XtPointer callData)
2162 {
2163 userCmdDialog *ucd = (userCmdDialog *)clientData;
2164 int i;
2165
2166 for (i=
0; i<ucd->nMenuItems; i++)
2167 freeMenuItemRec(ucd->menuItemsList[i]);
2168 NEditFree(ucd->menuItemsList);
2169 NEditFree(ucd);
2170 }
2171
2172 static void accFocusCB(Widget w, XtPointer clientData, XtPointer callData)
2173 {
2174 userCmdDialog *ucd = (userCmdDialog *)clientData;
2175
2176 RemoveDialogMnemonicHandler(XtParent(ucd->accTextW));
2177 }
2178
2179 static void accLoseFocusCB(Widget w, XtPointer clientData, XtPointer callData)
2180 {
2181 userCmdDialog *ucd = (userCmdDialog *)clientData;
2182
2183 AddDialogMnemonicHandler(XtParent(ucd->accTextW),
FALSE);
2184 }
2185
2186 static void accKeyCB(Widget w, XtPointer clientData, XKeyEvent *event)
2187 {
2188 userCmdDialog *ucd = (userCmdDialog *)clientData;
2189 KeySym keysym = XLookupKeysym(event,
0);
2190 char outStr[
MAX_ACCEL_LEN];
2191
2192
2193 if (IsModifierKey(keysym))
2194 return;
2195
2196
2197 if (keysym == XK_Tab)
2198 return;
2199
2200
2201 if (event->state & ~(ShiftMask | LockMask | ControlMask | Mod1Mask |
2202 Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask)) {
2203 XBell(TheDisplay,
0);
2204 return;
2205 }
2206
2207
2208 if (keysym == XK_Delete || keysym == XK_BackSpace) {
2209 XmTextSetString(ucd->accTextW,
"");
2210 return;
2211 }
2212
2213
2214 generateAcceleratorString(outStr, event->state, keysym);
2215
2216
2217
2218
2219
2220 if (strlen(outStr) ==
1) {
2221 XBell(TheDisplay,
0);
2222 return;
2223 }
2224
2225
2226 XmTextSetString(ucd->accTextW, outStr);
2227 }
2228
2229 static void sameOutCB(Widget w, XtPointer clientData, XtPointer callData)
2230 {
2231 XtSetSensitive(((userCmdDialog *)clientData)->repInpBtn,
2232 XmToggleButtonGetState(w));
2233 }
2234
2235 static void shellMenuCB(Widget w, WindowInfo *window, XtPointer callData)
2236 {
2237 XtArgVal userData;
2238 int index;
2239 char *params[
1];
2240
2241 window = WidgetToWindow(
MENU_WIDGET(w));
2242
2243
2244 XtVaGetValues(w, XmNuserData, &userData,
NULL);
2245 index = (
int)userData -
10;
2246 if (index <
0 || index >= NShellMenuItems)
2247 return;
2248
2249 params[
0] = ShellMenuItems[index]->name;
2250 XtCallActionProc(window->lastFocus,
"shell_menu_command",
2251 ((XmAnyCallbackStruct *)callData)->event, params,
1);
2252 }
2253
2254 static void macroMenuCB(Widget w, WindowInfo *window, XtPointer callData)
2255 {
2256 XtArgVal userData;
2257 int index;
2258 char *params[
1];
2259
2260 window = WidgetToWindow(
MENU_WIDGET(w));
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270 if (window->macroCmdData !=
NULL) {
2271 XBell(TheDisplay,
0);
2272 return;
2273 }
2274
2275
2276 XtVaGetValues(w, XmNuserData, &userData,
NULL);
2277 index = (
int)userData -
10;
2278 if (index <
0 || index >= NMacroMenuItems)
2279 return;
2280
2281 params[
0] = MacroMenuItems[index]->name;
2282 XtCallActionProc(window->lastFocus,
"macro_menu_command",
2283 ((XmAnyCallbackStruct *)callData)->event, params,
1);
2284 }
2285
2286 static void bgMenuCB(Widget w, WindowInfo *window, XtPointer callData)
2287 {
2288 XtArgVal userData;
2289 int index;
2290 char *params[
1];
2291
2292
2293 if (window->macroCmdData !=
NULL) {
2294 XBell(TheDisplay,
0);
2295 return;
2296 }
2297
2298
2299 XtVaGetValues(w, XmNuserData, &userData,
NULL);
2300 index = (
int)userData -
10;
2301 if (index <
0 || index >= NBGMenuItems)
2302 return;
2303
2304 params[
0] = BGMenuItems[index]->name;
2305 XtCallActionProc(window->lastFocus,
"bg_menu_command",
2306 ((XmAnyCallbackStruct *)callData)->event, params,
1);
2307 }
2308
2309
2310
2311
2312
2313
2314 static void updateDialogFields(menuItemRec *f, userCmdDialog *ucd)
2315 {
2316 char mneString[
2], accString[
MAX_ACCEL_LEN];
2317
2318
2319
2320 if (f ==
NULL) {
2321 XmTextSetString(ucd->nameTextW,
"");
2322 XmTextSetString(ucd->cmdTextW,
"");
2323 XmTextSetString(ucd->accTextW,
"");
2324 XmTextSetString(ucd->mneTextW,
"");
2325 if (ucd->dialogType ==
SHELL_CMDS) {
2326 RadioButtonChangeState(ucd->selInpBtn, True, True);
2327 RadioButtonChangeState(ucd->sameOutBtn, True, True);
2328 RadioButtonChangeState(ucd->repInpBtn, False, False);
2329 XtSetSensitive(ucd->repInpBtn, True);
2330 RadioButtonChangeState(ucd->saveFirstBtn, False, False);
2331 RadioButtonChangeState(ucd->loadAfterBtn, False, False);
2332 }
2333 }
else {
2334 mneString[
0] = f->mnemonic;
2335 mneString[
1] =
'\0';
2336 generateAcceleratorString(accString, f->modifiers, f->keysym);
2337 XmTextSetString(ucd->nameTextW, f->name);
2338 XmTextSetString(ucd->cmdTextW, f->cmd);
2339 XmTextSetString(ucd->accTextW, accString);
2340 XmTextSetString(ucd->mneTextW, mneString);
2341 RadioButtonChangeState(ucd->selInpBtn, f->input==
FROM_SELECTION, False);
2342 if (ucd->dialogType ==
SHELL_CMDS) {
2343 RadioButtonChangeState(ucd->winInpBtn, f->input ==
FROM_WINDOW,
2344 False);
2345 RadioButtonChangeState(ucd->eitherInpBtn, f->input ==
FROM_EITHER,
2346 False);
2347 RadioButtonChangeState(ucd->noInpBtn, f->input ==
FROM_NONE,
2348 False);
2349 RadioButtonChangeState(ucd->sameOutBtn, f->output==
TO_SAME_WINDOW,
2350 False);
2351 RadioButtonChangeState(ucd->winOutBtn, f->output==
TO_NEW_WINDOW,
2352 False);
2353 RadioButtonChangeState(ucd->dlogOutBtn, f->output==
TO_DIALOG,
2354 False);
2355 RadioButtonChangeState(ucd->repInpBtn, f->repInput, False);
2356 XtSetSensitive(ucd->repInpBtn, f->output==
TO_SAME_WINDOW);
2357 RadioButtonChangeState(ucd->saveFirstBtn, f->saveFirst, False);
2358 RadioButtonChangeState(ucd->loadAfterBtn, f->loadAfter, False);
2359 }
2360 }
2361 }
2362
2363
2364
2365
2366
2367
2368
2369 static menuItemRec *readDialogFields(userCmdDialog *ucd,
int silent)
2370 {
2371 char *nameText, *cmdText, *mneText, *accText;
2372 menuItemRec *f;
2373
2374 nameText = XmTextGetString(ucd->nameTextW);
2375 if (*nameText ==
'\0')
2376 {
2377 if (!silent)
2378 {
2379 DialogF(
DF_WARN, ucd->dlogShell,
1,
"Menu Entry",
2380 "Please specify a name\nfor the menu item",
"OK");
2381 XmProcessTraversal(ucd->nameTextW, XmTRAVERSE_CURRENT);
2382 }
2383 NEditFree(nameText);
2384 return NULL;
2385 }
2386
2387 if (strchr(nameText,
':'))
2388 {
2389 if (!silent)
2390 {
2391 DialogF(
DF_WARN, ucd->dlogShell,
1,
"Menu Entry",
2392 "Menu item names may not\ncontain colon (:) characters",
2393 "OK");
2394 XmProcessTraversal(ucd->nameTextW, XmTRAVERSE_CURRENT);
2395 }
2396 NEditFree(nameText);
2397 return NULL;
2398 }
2399
2400 cmdText = XmTextGetString(ucd->cmdTextW);
2401 if (cmdText ==
NULL || *cmdText ==
'\0')
2402 {
2403 if (!silent)
2404 {
2405 DialogF(
DF_WARN, ucd->dlogShell,
1,
"Command to Execute",
2406 "Please specify %s to execute",
"OK",
2407 ucd->dialogType ==
SHELL_CMDS
2408 ?
"shell command"
2409 :
"macro command(s)");
2410 XmProcessTraversal(ucd->cmdTextW, XmTRAVERSE_CURRENT);
2411 }
2412 NEditFree(nameText);
2413 NEditFree(cmdText);
2414
2415 return NULL;
2416 }
2417
2418 if (ucd->dialogType ==
MACRO_CMDS || ucd->dialogType ==
BG_MENU_CMDS) {
2419 addTerminatingNewline(&cmdText);
2420 if (!checkMacroText(cmdText, silent ?
NULL : ucd->dlogShell,
2421 ucd->cmdTextW)) {
2422 NEditFree(nameText);
2423 NEditFree(cmdText);
2424 return NULL;
2425 }
2426 }
2427 f = (menuItemRec *)NEditMalloc(
sizeof(menuItemRec));
2428 f->name = nameText;
2429 f->cmd = cmdText;
2430 if ((mneText = XmTextGetString(ucd->mneTextW)) !=
NULL) {
2431 f->mnemonic = mneText==
NULL ?
'\0' : mneText[
0];
2432 NEditFree(mneText);
2433 if (f->mnemonic ==
':')
2434 f->mnemonic =
'\0';
2435 }
2436 if ((accText = XmTextGetString(ucd->accTextW)) !=
NULL) {
2437 parseAcceleratorString(accText, &f->modifiers, &f->keysym);
2438 NEditFree(accText);
2439 }
2440 if (ucd->dialogType ==
SHELL_CMDS) {
2441 if (XmToggleButtonGetState(ucd->selInpBtn))
2442 f->input =
FROM_SELECTION;
2443 else if (XmToggleButtonGetState(ucd->winInpBtn))
2444 f->input =
FROM_WINDOW;
2445 else if (XmToggleButtonGetState(ucd->eitherInpBtn))
2446 f->input =
FROM_EITHER;
2447 else
2448 f->input =
FROM_NONE;
2449 if (XmToggleButtonGetState(ucd->winOutBtn))
2450 f->output =
TO_NEW_WINDOW;
2451 else if (XmToggleButtonGetState(ucd->dlogOutBtn))
2452 f->output =
TO_DIALOG;
2453 else
2454 f->output =
TO_SAME_WINDOW;
2455 f->repInput = XmToggleButtonGetState(ucd->repInpBtn);
2456 f->saveFirst = XmToggleButtonGetState(ucd->saveFirstBtn);
2457 f->loadAfter = XmToggleButtonGetState(ucd->loadAfterBtn);
2458 }
else {
2459 f->input = XmToggleButtonGetState(ucd->selInpBtn) ?
FROM_SELECTION :
2460 FROM_NONE;
2461 f->output =
TO_SAME_WINDOW;
2462 f->repInput = False;
2463 f->saveFirst = False;
2464 f->loadAfter = False;
2465 }
2466 return f;
2467 }
2468
2469
2470
2471
2472 static menuItemRec *copyMenuItemRec(menuItemRec *item)
2473 {
2474 menuItemRec *newItem;
2475
2476 newItem = (menuItemRec *)NEditMalloc(
sizeof(menuItemRec));
2477 *newItem = *item;
2478 newItem->name = (
char*)NEditMalloc(strlen(item->name)+
1);
2479 strcpy(newItem->name, item->name);
2480 newItem->cmd = (
char*)NEditMalloc(strlen(item->cmd)+
1);
2481 strcpy(newItem->cmd, item->cmd);
2482 return newItem;
2483 }
2484
2485
2486
2487
2488 static void freeMenuItemRec(menuItemRec *item)
2489 {
2490 NEditFree(item->name);
2491 NEditFree(item->cmd);
2492 NEditFree(item);
2493 }
2494
2495
2496
2497
2498 static void *getDialogDataCB(
void *oldItem,
int explicitRequest,
int *abort,
2499 void *cbArg)
2500 {
2501 userCmdDialog *ucd = (userCmdDialog *)cbArg;
2502 menuItemRec *currentFields;
2503
2504
2505
2506 if (oldItem ==
NULL && dialogFieldsAreEmpty(ucd))
2507 return NULL;
2508
2509
2510 currentFields = readDialogFields(ucd, True);
2511 if (currentFields !=
NULL)
2512 return (
void *)currentFields;
2513
2514
2515 if (!explicitRequest)
2516 {
2517 if (DialogF(
DF_WARN, ucd->dlogShell,
2,
"Discard Entry",
2518 "Discard incomplete entry\nfor current menu item?",
"Keep",
2519 "Discard") ==
2)
2520 {
2521 return oldItem ==
NULL
2522 ?
NULL
2523 : (
void *)copyMenuItemRec((menuItemRec *)oldItem);
2524 }
2525 }
2526
2527
2528 readDialogFields(ucd, False);
2529 *abort = True;
2530 return NULL;
2531 }
2532
2533
2534 static void setDialogDataCB(
void *item,
void *cbArg)
2535 {
2536 updateDialogFields((menuItemRec *)item, (userCmdDialog *)cbArg);
2537 }
2538
2539 static int dialogFieldsAreEmpty(userCmdDialog *ucd)
2540 {
2541 return TextWidgetIsBlank(ucd->nameTextW) &&
2542 TextWidgetIsBlank(ucd->cmdTextW) &&
2543 TextWidgetIsBlank(ucd->accTextW) &&
2544 TextWidgetIsBlank(ucd->mneTextW) &&
2545 (ucd->dialogType !=
SHELL_CMDS || (
2546 XmToggleButtonGetState(ucd->selInpBtn) &&
2547 XmToggleButtonGetState(ucd->sameOutBtn) &&
2548 !XmToggleButtonGetState(ucd->repInpBtn) &&
2549 !XmToggleButtonGetState(ucd->saveFirstBtn) &&
2550 !XmToggleButtonGetState(ucd->loadAfterBtn)));
2551 }
2552
2553 static void freeItemCB(
void *item)
2554 {
2555 freeMenuItemRec((menuItemRec *)item);
2556 }
2557
2558
2559
2560
2561 static void disableTextW(Widget textW)
2562 {
2563 static XtTranslations emptyTable =
NULL;
2564 static char *emptyTranslations =
"\
2565 <EnterWindow>: enter()\n\
2566 <Btn1Down>: grab-focus()\n\
2567 <Btn1Motion>: extend-adjust()\n\
2568 <Btn1Up>: extend-end()\n\
2569 Shift<Key>Tab: prev-tab-group()\n\
2570 Ctrl<Key>Tab: next-tab-group()\n\
2571 <Key>Tab: next-tab-group()\n\
2572 <LeaveWindow>: leave()\n\
2573 <FocusIn>: focusIn()\n\
2574 <FocusOut>: focusOut()\n\
2575 <Unmap>: unmap()\n";
2576
2577
2578 if (emptyTable ==
NULL)
2579 emptyTable = XtParseTranslationTable(emptyTranslations);
2580 XtVaSetValues(textW, XmNtranslations, emptyTable,
NULL);
2581 }
2582
2583 static char *writeMenuItemString(menuItemRec **menuItems,
int nItems,
2584 int listType)
2585 {
2586 char *outStr, *outPtr, *c, accStr[
MAX_ACCEL_LEN];
2587 menuItemRec *f;
2588 int i, length;
2589
2590
2591
2592 length =
0;
2593 for (i=
0; i<nItems; i++) {
2594 f = menuItems[i];
2595 generateAcceleratorString(accStr, f->modifiers, f->keysym);
2596 length += strlen(f->name) *
2;
2597 length += strlen(accStr);
2598 length += strlen(f->cmd) *
6;
2599 length +=
21;
2600 }
2601 length++;
2602 outStr = (
char*)NEditMalloc(length);
2603
2604
2605 outPtr = outStr;
2606 *outPtr++ =
'\\';
2607 *outPtr++ =
'\n';
2608 for (i=
0; i<nItems; i++) {
2609 f = menuItems[i];
2610 generateAcceleratorString(accStr, f->modifiers, f->keysym);
2611 *outPtr++ =
'\t';
2612 for (c=f->name; *c!=
'\0'; ++c) {
2613 if (*c ==
'\\') {
2614 *outPtr++ =
'\\';
2615 *outPtr++ =
'\\';
2616 }
else if (*c ==
'\n') {
2617 *outPtr++ =
'\\';
2618 *outPtr++ =
'n';
2619 }
else {
2620 *outPtr++ = *c;
2621 }
2622 }
2623 *outPtr++ =
':';
2624 strcpy(outPtr, accStr);
2625 outPtr += strlen(accStr);
2626 *outPtr++ =
':';
2627 if (f->mnemonic !=
'\0')
2628 *outPtr++ = f->mnemonic;
2629 *outPtr++ =
':';
2630 if (listType ==
SHELL_CMDS) {
2631 if (f->input ==
FROM_SELECTION)
2632 *outPtr++ =
'I';
2633 else if (f->input ==
FROM_WINDOW)
2634 *outPtr++ =
'A';
2635 else if (f->input ==
FROM_EITHER)
2636 *outPtr++ =
'E';
2637 if (f->output ==
TO_DIALOG)
2638 *outPtr++ =
'D';
2639 else if (f->output ==
TO_NEW_WINDOW)
2640 *outPtr++ =
'W';
2641 if (f->repInput)
2642 *outPtr++ =
'X';
2643 if (f->saveFirst)
2644 *outPtr++ =
'S';
2645 if (f->loadAfter)
2646 *outPtr++ =
'L';
2647 *outPtr++ =
':';
2648 }
else {
2649 if (f->input ==
FROM_SELECTION)
2650 *outPtr++ =
'R';
2651 *outPtr++ =
':';
2652 *outPtr++ =
' ';
2653 *outPtr++ =
'{';
2654 }
2655 *outPtr++ =
'\\';
2656 *outPtr++ =
'n';
2657 *outPtr++ =
'\\';
2658 *outPtr++ =
'\n';
2659 *outPtr++ =
'\t';
2660 *outPtr++ =
'\t';
2661 for (c=f->cmd; *c!=
'\0'; c++) {
2662 if (*c ==
'\\') {
2663 *outPtr++ =
'\\';
2664 *outPtr++ =
'\\';
2665 }
else if (*c ==
'\n') {
2666 *outPtr++ =
'\\';
2667 *outPtr++ =
'n';
2668 *outPtr++ =
'\\';
2669 *outPtr++ =
'\n';
2670 *outPtr++ =
'\t';
2671 *outPtr++ =
'\t';
2672 }
else
2673 *outPtr++ = *c;
2674 }
2675 if (listType ==
MACRO_CMDS || listType ==
BG_MENU_CMDS) {
2676 if (*(outPtr-
1) ==
'\t') outPtr--;
2677 *outPtr++ =
'}';
2678 }
2679 *outPtr++ =
'\\';
2680 *outPtr++ =
'n';
2681 *outPtr++ =
'\\';
2682 *outPtr++ =
'\n';
2683 }
2684 --outPtr;
2685 *--outPtr =
'\0';
2686 return outStr;
2687 }
2688
2689 static int loadMenuItemString(
char *inString, menuItemRec **menuItems,
2690 int *nItems,
int listType)
2691 {
2692 menuItemRec *f;
2693 char *cmdStr;
2694 char *inPtr = inString;
2695 char *nameStr, accStr[
MAX_ACCEL_LEN], mneChar;
2696 KeySym keysym;
2697 unsigned int modifiers;
2698 int i, input, output, saveFirst, loadAfter, repInput;
2699 int nameLen, accLen, mneLen, cmdLen;
2700
2701 for (;;) {
2702
2703
2704 while (*inPtr ==
' ' || *inPtr ==
'\t')
2705 inPtr++;
2706
2707
2708 if (*inPtr ==
'\0') {
2709 return True;
2710 }
2711
2712
2713 nameLen = strcspn(inPtr,
":");
2714 if (nameLen ==
0)
2715 return parseError(
"no name field");
2716 nameStr = (
char*)NEditMalloc(nameLen+
1);
2717 strncpy(nameStr, inPtr, nameLen);
2718 nameStr[nameLen] =
'\0';
2719 inPtr += nameLen;
2720 if (*inPtr ==
'\0')
2721 return parseError(
"end not expected");
2722 inPtr++;
2723
2724
2725 accLen = strcspn(inPtr,
":");
2726 if (accLen >=
MAX_ACCEL_LEN)
2727 return parseError(
"accelerator field too long");
2728 strncpy(accStr, inPtr, accLen);
2729 accStr[accLen] =
'\0';
2730 inPtr += accLen;
2731 if (*inPtr ==
'\0')
2732 return parseError(
"end not expected");
2733 inPtr++;
2734
2735
2736 mneLen = strcspn(inPtr,
":");
2737 if (mneLen >
1)
2738 return parseError(
"mnemonic field too long");
2739 if (mneLen ==
1)
2740 mneChar = *inPtr++;
2741 else
2742 mneChar =
'\0';
2743 inPtr++;
2744 if (*inPtr ==
'\0')
2745 return parseError(
"end not expected");
2746
2747
2748 input =
FROM_NONE;
2749 output =
TO_SAME_WINDOW;
2750 repInput = False;
2751 saveFirst = False;
2752 loadAfter = False;
2753 for (; *inPtr !=
':'; inPtr++) {
2754 if (listType ==
SHELL_CMDS) {
2755 if (*inPtr ==
'I')
2756 input =
FROM_SELECTION;
2757 else if (*inPtr ==
'A')
2758 input =
FROM_WINDOW;
2759 else if (*inPtr ==
'E')
2760 input =
FROM_EITHER;
2761 else if (*inPtr ==
'W')
2762 output =
TO_NEW_WINDOW;
2763 else if (*inPtr ==
'D')
2764 output =
TO_DIALOG;
2765 else if (*inPtr ==
'X')
2766 repInput = True;
2767 else if (*inPtr ==
'S')
2768 saveFirst = True;
2769 else if (*inPtr ==
'L')
2770 loadAfter = True;
2771 else
2772 return parseError(
"unreadable flag field");
2773 }
else {
2774 if (*inPtr ==
'R')
2775 input =
FROM_SELECTION;
2776 else
2777 return parseError(
"unreadable flag field");
2778 }
2779 }
2780 inPtr++;
2781
2782
2783 if (listType ==
SHELL_CMDS) {
2784 if (*inPtr++ !=
'\n')
2785 return parseError(
"command must begin with newline");
2786 while (*inPtr ==
' ' || *inPtr ==
'\t')
2787 inPtr++;
2788 cmdLen = strcspn(inPtr,
"\n");
2789 if (cmdLen ==
0)
2790 return parseError(
"shell command field is empty");
2791 cmdStr = (
char*)NEditMalloc(cmdLen+
1);
2792 strncpy(cmdStr, inPtr, cmdLen);
2793 cmdStr[cmdLen] =
'\0';
2794 inPtr += cmdLen;
2795 }
else {
2796 cmdStr = copyMacroToEnd(&inPtr);
2797 if (cmdStr ==
NULL)
2798 return False;
2799 }
2800 while (*inPtr ==
' ' || *inPtr ==
'\t' || *inPtr ==
'\n')
2801 inPtr++;
2802
2803
2804 if (!parseAcceleratorString(accStr, &modifiers, &keysym))
2805 return parseError(
"couldn''t read accelerator field");
2806
2807
2808 f = (menuItemRec *)NEditMalloc(
sizeof(menuItemRec));
2809 f->name = nameStr;
2810 f->cmd = cmdStr;
2811 f->mnemonic = mneChar;
2812 f->modifiers = modifiers;
2813 f->input = input;
2814 f->output = output;
2815 f->repInput = repInput;
2816 f->saveFirst = saveFirst;
2817 f->loadAfter = loadAfter;
2818 f->keysym = keysym;
2819
2820
2821 for (i=
0; i < *nItems; i++) {
2822 if (!strcmp(menuItems[i]->name, f->name)) {
2823 freeMenuItemRec(menuItems[i]);
2824 menuItems[i] = f;
2825 break;
2826 }
2827 }
2828 if (i == *nItems)
2829 menuItems[(*nItems)++] = f;
2830
2831 }
2832 }
2833
2834 static int parseError(
const char *message)
2835 {
2836 fprintf(stderr,
"XNEdit: Parse error in user defined menu item, %s\n",
2837 message);
2838 return False;
2839 }
2840
2841
2842
2843
2844
2845 static void generateAcceleratorString(
char *text,
unsigned int modifiers,
2846 KeySym keysym)
2847 {
2848 char *shiftStr =
"", *ctrlStr =
"", *altStr =
"";
2849 char *mod2Str =
"", *mod3Str =
"", *mod4Str =
"", *mod5Str =
"";
2850 char keyName[
20];
2851 Modifiers numLockMask = GetNumLockModMask(TheDisplay);
2852
2853
2854 if (keysym == NoSymbol) {
2855 *text =
'\0';
2856 return;
2857 }
2858
2859
2860
2861
2862
2863 if (modifiers & ShiftMask)
2864 shiftStr =
"Shift+";
2865 if (modifiers & ControlMask)
2866 ctrlStr =
"Ctrl+";
2867 if (modifiers & Mod1Mask)
2868 altStr =
"Alt+";
2869 if ((modifiers & Mod2Mask) && (Mod2Mask != numLockMask))
2870 mod2Str =
"Mod2+";
2871 if ((modifiers & Mod3Mask) && (Mod3Mask != numLockMask))
2872 mod3Str =
"Mod3+";
2873 if ((modifiers & Mod4Mask) && (Mod4Mask != numLockMask))
2874 mod4Str =
"Mod4+";
2875 if ((modifiers & Mod5Mask) && (Mod5Mask != numLockMask))
2876 mod5Str =
"Mod5+";
2877
2878
2879
2880 strcpy(keyName, XKeysymToString(keysym));
2881 *keyName = toupper(*keyName);
2882
2883
2884 sprintf(text,
"%s%s%s%s%s%s%s%s", shiftStr, ctrlStr, altStr,
2885 mod2Str, mod3Str, mod4Str, mod5Str, keyName);
2886 }
2887
2888
2889
2890
2891
2892 static void genAccelEventName(
char *text,
unsigned int modifiers,
2893 KeySym keysym)
2894 {
2895 char *shiftStr =
"", *lockStr =
"", *ctrlStr =
"", *altStr =
"";
2896 char *mod2Str =
"", *mod3Str =
"", *mod4Str =
"", *mod5Str =
"";
2897
2898
2899 if (keysym == NoSymbol) {
2900 *text =
'\0';
2901 return;
2902 }
2903
2904
2905 if (modifiers & ShiftMask)
2906 shiftStr =
"Shift ";
2907 if (modifiers & LockMask)
2908 lockStr =
"Lock ";
2909 if (modifiers & ControlMask)
2910 ctrlStr =
"Ctrl ";
2911 if (modifiers & Mod1Mask)
2912 altStr =
"Alt ";
2913 if (modifiers & Mod2Mask)
2914 mod2Str =
"Mod2 ";
2915 if (modifiers & Mod3Mask)
2916 mod3Str =
"Mod3 ";
2917 if (modifiers & Mod4Mask)
2918 mod4Str =
"Mod4 ";
2919 if (modifiers & Mod5Mask)
2920 mod5Str =
"Mod5 ";
2921
2922
2923 sprintf(text,
"%s%s%s%s%s%s%s%s<Key>%s",
2924 shiftStr, lockStr, ctrlStr, altStr,
2925 mod2Str, mod3Str, mod4Str, mod5Str,
2926 XKeysymToString(keysym));
2927 }
2928
2929
2930
2931
2932
2933
2934 static int parseAcceleratorString(
const char *string,
unsigned int *modifiers,
2935 KeySym *keysym)
2936 {
2937 int i, nFields, inputLength = strlen(string);
2938 char fields[
10][
MAX_ACCEL_LEN];
2939
2940
2941 if (inputLength ==
0) {
2942 *modifiers =
0;
2943 *keysym = NoSymbol;
2944 return True;
2945 }
2946
2947
2948 if (inputLength >
MAX_ACCEL_LEN)
2949 return False;
2950
2951
2952 nFields = sscanf(string,
"%[^+]+%[^+]+%[^+]+%[^+]+%[^+]+%[^+]+%[^+]+%[^+]+%[^+]+%[^+]",
2953 fields[
0], fields[
1], fields[
2], fields[
3], fields[
4], fields[
5],
2954 fields[
6], fields[
7], fields[
8], fields[
9]);
2955 if (nFields ==
0)
2956 return False;
2957
2958
2959
2960
2961 *keysym = XStringToKeysym(fields[nFields-
1]);
2962 if (*keysym == NoSymbol) {
2963 *fields[nFields-
1] = tolower(*fields[nFields-
1]);
2964 *keysym = XStringToKeysym(fields[nFields-
1]);
2965 if (*keysym == NoSymbol)
2966 return False;
2967 }
2968
2969
2970 *modifiers =
0;
2971 for (i=
0; i<nFields-
1; i++) {
2972 if (!strcmp(fields[i],
"Shift"))
2973 *modifiers |= ShiftMask;
2974 else if (!strcmp(fields[i],
"Lock"))
2975 *modifiers |= LockMask;
2976 else if (!strcmp(fields[i],
"Ctrl"))
2977 *modifiers |= ControlMask;
2978
2979 else if (!strcmp(fields[i],
"Alt"))
2980 *modifiers |= Mod1Mask;
2981 else if (!strcmp(fields[i],
"Mod2"))
2982 *modifiers |= Mod2Mask;
2983 else if (!strcmp(fields[i],
"Mod3"))
2984 *modifiers |= Mod3Mask;
2985 else if (!strcmp(fields[i],
"Mod4"))
2986 *modifiers |= Mod4Mask;
2987 else if (!strcmp(fields[i],
"Mod5"))
2988 *modifiers |= Mod5Mask;
2989 else
2990 return False;
2991 }
2992
2993
2994 return True;
2995 }
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005 static char *copyMacroToEnd(
char **inPtr)
3006 {
3007 char *retStr, *errMsg, *stoppedAt, *p, *retPtr;
3008 Program *prog;
3009
3010
3011
3012 *inPtr += strspn(*inPtr,
" \t\n");
3013 if (**inPtr !=
'{') {
3014 ParseError(
NULL, *inPtr, *inPtr-
1,
"macro menu item",
"expecting ''{''");
3015 return NULL;
3016 }
3017
3018
3019 prog = ParseMacro(*inPtr, &errMsg, &stoppedAt);
3020 if (prog ==
NULL) {
3021 ParseError(
NULL, *inPtr, stoppedAt,
"macro menu item", errMsg);
3022 return NULL;
3023 }
3024 FreeProgram(prog);
3025
3026
3027
3028 (*inPtr)++;
3029 *inPtr += strspn(*inPtr,
" \t");
3030 if (**inPtr ==
'\n') (*inPtr)++;
3031 if (**inPtr ==
'\t') (*inPtr)++;
3032 if (**inPtr ==
'\t') (*inPtr)++;
3033 retPtr = retStr = (
char*)NEditMalloc(stoppedAt - *inPtr +
1);
3034 for (p = *inPtr; p < stoppedAt -
1; p++) {
3035 if (!strncmp(p,
"\n\t\t",
3)) {
3036 *retPtr++ =
'\n';
3037 p +=
2;
3038 }
else
3039 *retPtr++ = *p;
3040 }
3041 if (*(retPtr-
1) ==
'\t') retPtr--;
3042 *retPtr =
'\0';
3043 *inPtr = stoppedAt;
3044 return retStr;
3045 }
3046
3047
3048
3049
3050
3051
3052
3053 static void addTerminatingNewline(
char **string)
3054 {
3055 char *newString;
3056 int length;
3057
3058 length = strlen(*string);
3059 if ((*string)[length-
1] !=
'\n') {
3060 newString = (
char*)NEditMalloc(length +
2);
3061 strcpy(newString, *string);
3062 newString[length] =
'\n';
3063 newString[length+
1] =
'\0';
3064 NEditFree(*string);
3065 *string = newString;
3066 }
3067 }
3068
3069
3070
3071
3072
3073 UserMenuCache *CreateUserMenuCache(
void)
3074 {
3075
3076 UserMenuCache *cache = (UserMenuCache *)NEditMalloc(
sizeof(UserMenuCache));
3077
3078 cache->umcLanguageMode = -
2;
3079 cache->umcShellMenuCreated = False;
3080 cache->umcMacroMenuCreated = False;
3081 cache->umcShellMenuList.umlNbrItems =
0;
3082 cache->umcShellMenuList.umlItems =
NULL;
3083 cache->umcMacroMenuList.umlNbrItems =
0;
3084 cache->umcMacroMenuList.umlItems =
NULL;
3085
3086 return cache;
3087 }
3088
3089 void FreeUserMenuCache(UserMenuCache *cache)
3090 {
3091 freeUserMenuList(&cache->umcShellMenuList);
3092 freeUserMenuList(&cache->umcMacroMenuList);
3093
3094 NEditFree(cache);
3095 }
3096
3097
3098
3099
3100
3101 void InitUserBGMenuCache(UserBGMenuCache *cache)
3102 {
3103 cache->ubmcLanguageMode = -
2;
3104 cache->ubmcMenuCreated = False;
3105 cache->ubmcMenuList.umlNbrItems =
0;
3106 cache->ubmcMenuList.umlItems =
NULL;
3107 }
3108
3109 void FreeUserBGMenuCache(UserBGMenuCache *cache)
3110 {
3111 freeUserMenuList(&cache->ubmcMenuList);
3112 }
3113
3114
3115
3116
3117
3118
3119 static void parseMenuItemList(menuItemRec **itemList,
int nbrOfItems,
3120 userMenuInfo **infoList, userSubMenuCache *subMenus)
3121 {
3122 int i;
3123 userMenuInfo *info;
3124
3125
3126 allocSubMenuCache(subMenus, nbrOfItems);
3127
3128
3129
3130 for (i=
0; i<nbrOfItems; i++) {
3131 infoList[i] = parseMenuItemRec(itemList[i]);
3132 generateUserMenuId(infoList[i], subMenus);
3133 }
3134
3135
3136 for (i=
0; i<nbrOfItems; i++) {
3137 info = infoList[i];
3138
3139
3140
3141
3142
3143 if (info->umiIsDefault) {
3144 setDefaultIndex(infoList, nbrOfItems, i);
3145 }
3146 }
3147 }
3148
3149
3150
3151
3152
3153 static int getSubMenuDepth(
const char *menuName)
3154 {
3155 const char *subSep;
3156 int depth =
0;
3157
3158
3159 subSep = menuName;
3160 while ((subSep = strchr(subSep,
'>')) !=
NULL ) {
3161 depth ++;
3162 subSep ++;
3163 }
3164
3165 return depth;
3166 }
3167
3168
3169
3170
3171
3172
3173 static userMenuInfo *parseMenuItemRec(menuItemRec *item)
3174 {
3175 userMenuInfo *newInfo;
3176 int subMenuDepth;
3177 int idSize;
3178
3179
3180 newInfo = (userMenuInfo *)NEditMalloc(
sizeof(userMenuInfo));
3181
3182
3183
3184 newInfo->umiName = stripLanguageMode(item->name);
3185
3186 subMenuDepth = getSubMenuDepth(newInfo->umiName);
3187 idSize =
sizeof(
int)*(subMenuDepth+
1);
3188
3189 newInfo->umiId = (
int *)NEditMalloc(idSize);
3190 memset(newInfo->umiId,
0,idSize);
3191
3192
3193 newInfo->umiIdLen =
0;
3194 newInfo->umiIsDefault = False;
3195 newInfo->umiNbrOfLanguageModes =
0;
3196 newInfo->umiLanguageMode =
NULL;
3197 newInfo->umiDefaultIndex = -
1;
3198 newInfo->umiToBeManaged = False;
3199
3200
3201 parseMenuItemName(item->name, newInfo);
3202
3203 return newInfo;
3204 }
3205
3206
3207
3208
3209
3210
3211 static void parseMenuItemName(
char *menuItemName, userMenuInfo *info)
3212 {
3213 char *atPtr, *firstAtPtr, *endPtr;
3214 char c;
3215 int languageMode;
3216 int langModes[
MAX_LANGUAGE_MODES];
3217 int nbrLM =
0;
3218 int size;
3219
3220 atPtr = firstAtPtr = strchr(menuItemName,
'@');
3221 if (atPtr !=
NULL) {
3222 if (!strcmp(atPtr+
1,
"*")) {
3223
3224
3225 info->umiIsDefault = True;
3226 return;
3227 }
3228
3229
3230 while (atPtr !=
NULL) {
3231
3232 for(endPtr=atPtr+
1; isalnum((
unsigned char)*endPtr) || *endPtr==
'_' ||
3233 *endPtr==
'-' || *endPtr==
' ' || *endPtr==
'+' || *endPtr==
'$' ||
3234 *endPtr==
'#'; endPtr++);
3235
3236
3237
3238
3239 c = *endPtr;
3240 *endPtr =
'\0';
3241 languageMode = FindLanguageMode(atPtr+
1);
3242 if (languageMode ==
PLAIN_LANGUAGE_MODE) {
3243 langModes[nbrLM] =
UNKNOWN_LANGUAGE_MODE;
3244 }
else {
3245 langModes[nbrLM] = languageMode;
3246 }
3247 nbrLM ++;
3248 *endPtr = c;
3249
3250
3251 atPtr = strchr(endPtr,
'@');
3252 }
3253
3254 if (nbrLM !=
0) {
3255 info->umiNbrOfLanguageModes = nbrLM;
3256 size =
sizeof(
int)*nbrLM;
3257 info->umiLanguageMode = (
int *)NEditMalloc(size);
3258 memcpy(info->umiLanguageMode, langModes, size);
3259 }
3260 }
3261 }
3262
3263
3264
3265
3266
3267
3268
3269
3270 static void generateUserMenuId(userMenuInfo *info, userSubMenuCache *subMenus)
3271 {
3272 int idSize;
3273 char *hierName, *subSep;
3274 int subMenuDepth =
0;
3275 int *menuIdx = &subMenus->usmcNbrOfMainMenuItems;
3276 userSubMenuInfo *curSubMenu;
3277
3278
3279
3280 subSep = info->umiName;
3281 while ((subSep = strchr(subSep,
'>')) !=
NULL) {
3282 hierName = copySubstring(info->umiName, subSep - info->umiName);
3283 curSubMenu = findSubMenuInfo(subMenus, hierName);
3284 if (curSubMenu ==
NULL) {
3285
3286
3287 info->umiId[subMenuDepth] = *menuIdx;
3288 (*menuIdx) ++;
3289
3290
3291
3292
3293 curSubMenu = &subMenus->usmcInfo[subMenus->usmcNbrOfSubMenus];
3294 subMenus->usmcNbrOfSubMenus ++;
3295 curSubMenu->usmiName = hierName;
3296 idSize =
sizeof(
int)*(subMenuDepth+
2);
3297 curSubMenu->usmiId = (
int *)NEditMalloc(idSize);
3298 memcpy(curSubMenu->usmiId, info->umiId, idSize);
3299 curSubMenu->usmiIdLen = subMenuDepth+
1;
3300 }
else {
3301
3302
3303 NEditFree(hierName);
3304 info->umiId[subMenuDepth] = curSubMenu->usmiId[subMenuDepth];
3305 }
3306
3307 subMenuDepth ++;
3308 menuIdx = &curSubMenu->usmiId[subMenuDepth];
3309
3310 subSep ++;
3311 }
3312
3313
3314 info->umiId[subMenuDepth] = *menuIdx;
3315 info->umiIdLen = subMenuDepth +
1;
3316 (*menuIdx) ++;
3317 }
3318
3319
3320
3321
3322
3323 static userSubMenuInfo *findSubMenuInfo(userSubMenuCache *subMenus,
3324 const char *hierName)
3325 {
3326 int i;
3327
3328 for (i=
0; i<subMenus->usmcNbrOfSubMenus; i++)
3329 if (!strcmp(hierName, subMenus->usmcInfo[i].usmiName))
3330 return &subMenus->usmcInfo[i];
3331 return NULL;
3332 }
3333
3334
3335
3336
3337
3338
3339 static char *stripLanguageMode(
const char *menuItemName)
3340 {
3341 char *firstAtPtr;
3342
3343 firstAtPtr = strchr(menuItemName,
'@');
3344 if (firstAtPtr ==
NULL)
3345 return NEditStrdup(menuItemName);
3346 else
3347 return copySubstring(menuItemName, firstAtPtr-menuItemName);
3348 }
3349
3350 static void setDefaultIndex(userMenuInfo **infoList,
int nbrOfItems,
3351 int defaultIdx)
3352 {
3353 char *defaultMenuName = infoList[defaultIdx]->umiName;
3354 int i;
3355 userMenuInfo *info;
3356
3357
3358
3359
3360 for (i=
0; i<nbrOfItems; i++) {
3361 info = infoList[i];
3362
3363 if (!info->umiIsDefault && strcmp(info->umiName, defaultMenuName)==
0) {
3364 info->umiDefaultIndex = defaultIdx;
3365 }
3366 }
3367 }
3368
3369
3370
3371
3372
3373
3374 static void applyLangModeToUserMenuInfo(userMenuInfo **infoList,
int nbrOfItems,
3375 int languageMode)
3376 {
3377 int i;
3378 userMenuInfo *info;
3379
3380
3381
3382 for (i=
0; i<nbrOfItems; i++) {
3383 info = infoList[i];
3384
3385 info->umiToBeManaged =
3386 (info->umiNbrOfLanguageModes ==
0 || info->umiIsDefault);
3387 }
3388
3389
3390
3391
3392 for (i=
0; i<nbrOfItems; i++) {
3393 info = infoList[i];
3394
3395 if (info->umiNbrOfLanguageModes !=
0) {
3396 if (doesLanguageModeMatch(info, languageMode)) {
3397 info->umiToBeManaged = True;
3398
3399 if (info->umiDefaultIndex != -
1)
3400 infoList[info->umiDefaultIndex]->umiToBeManaged = False;
3401 }
3402 }
3403 }
3404 }
3405
3406
3407
3408
3409 static int doesLanguageModeMatch(userMenuInfo *info,
int languageMode)
3410 {
3411 int i;
3412
3413 for (i=
0; i<info->umiNbrOfLanguageModes; i++) {
3414 if (info->umiLanguageMode[i] == languageMode)
3415 return True;
3416 }
3417
3418 return False;
3419 }
3420
3421 static void freeUserMenuInfoList(userMenuInfo **infoList,
int nbrOfItems)
3422 {
3423 int i;
3424
3425 for (i=
0; i<nbrOfItems; i++) {
3426 freeUserMenuInfo(infoList[i]);
3427 }
3428 }
3429
3430 static void freeUserMenuInfo(userMenuInfo *info)
3431 {
3432 NEditFree(info->umiName);
3433
3434 NEditFree(info->umiId);
3435
3436 if (info->umiNbrOfLanguageModes !=
0)
3437 NEditFree(info->umiLanguageMode);
3438
3439 NEditFree(info);
3440 }
3441
3442
3443
3444
3445
3446 static void allocSubMenuCache(userSubMenuCache *subMenus,
int nbrOfItems)
3447 {
3448 int size =
sizeof(userSubMenuInfo) * nbrOfItems;
3449
3450 subMenus->usmcNbrOfMainMenuItems =
0;
3451 subMenus->usmcNbrOfSubMenus =
0;
3452 subMenus->usmcInfo = (userSubMenuInfo *)NEditMalloc(size);
3453 }
3454
3455 static void freeSubMenuCache(userSubMenuCache *subMenus)
3456 {
3457 int i;
3458
3459 for (i=
0; i<subMenus->usmcNbrOfSubMenus; i++) {
3460 NEditFree(subMenus->usmcInfo[i].usmiName);
3461 NEditFree(subMenus->usmcInfo[i].usmiId);
3462 }
3463
3464 NEditFree(subMenus->usmcInfo);
3465 }
3466
3467 static void allocUserMenuList(UserMenuList *list,
int nbrOfItems)
3468 {
3469 int size =
sizeof(UserMenuListElement *) * nbrOfItems;
3470
3471 list->umlNbrItems =
0;
3472 list->umlItems = (UserMenuListElement **)NEditMalloc(size);
3473 }
3474
3475 static void freeUserMenuList(UserMenuList *list)
3476 {
3477 int i;
3478
3479 for (i=
0; i<list->umlNbrItems; i++)
3480 freeUserMenuListElement(list->umlItems[i]);
3481
3482 list->umlNbrItems =
0;
3483
3484 NEditFree(list->umlItems);
3485 list->umlItems =
NULL;
3486 }
3487
3488 static UserMenuListElement *allocUserMenuListElement(Widget menuItem,
char *accKeys)
3489 {
3490 UserMenuListElement *element;
3491
3492 element = (UserMenuListElement *)NEditMalloc(
sizeof(UserMenuListElement));
3493
3494 element->umleManageMode =
UMMM_UNMANAGE;
3495 element->umlePrevManageMode =
UMMM_UNMANAGE;
3496 element->umleAccKeys = accKeys;
3497 element->umleAccLockPatchApplied = False;
3498 element->umleMenuItem = menuItem;
3499 element->umleSubMenuPane =
NULL;
3500 element->umleSubMenuList =
NULL;
3501
3502 return element;
3503 }
3504
3505 static void freeUserMenuListElement(UserMenuListElement *element)
3506 {
3507 if (element->umleSubMenuList !=
NULL)
3508 freeUserSubMenuList(element->umleSubMenuList);
3509
3510 NEditFree(element->umleAccKeys);
3511 NEditFree(element);
3512 }
3513
3514 static UserMenuList *allocUserSubMenuList(
int nbrOfItems)
3515 {
3516 UserMenuList *list;
3517
3518 list = (UserMenuList *)NEditMalloc(
sizeof(UserMenuList));
3519
3520 allocUserMenuList(list, nbrOfItems);
3521
3522 return list;
3523 }
3524
3525 static void freeUserSubMenuList(UserMenuList *list)
3526 {
3527 freeUserMenuList(list);
3528
3529 NEditFree(list);
3530 }
3531