WPrefs: Update translations
[wmaker-crm.git] / WPrefs.app / Menu.c
blob4a8cc94e07522c59e191e315e517d05f6465a9cd
1 /* Menu.c- menu definition
3 * WPrefs - Window Maker Preferences Program
5 * Copyright (c) 2000-2003 Alfredo K. Kojima
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "WPrefs.h"
23 #include <assert.h>
24 #include <ctype.h>
26 #include <X11/keysym.h>
27 #include <X11/cursorfont.h>
29 #include "editmenu.h"
31 typedef enum {
32 NoInfo,
33 ExecInfo,
34 CommandInfo,
35 ExternalInfo,
36 PipeInfo,
37 DirectoryInfo,
38 WSMenuInfo,
39 WWindowListInfo,
40 LastInfo
41 } InfoType;
43 #define MAX_SECTION_SIZE 4
44 #define PATH_LEN 256
46 typedef struct _Panel {
47 WMBox *box;
48 char *sectionName;
50 char *description;
52 CallbackRec callbacks;
53 WMWidget *parent;
55 WMFont *boldFont;
56 WMFont *normalFont;
57 WMColor *white;
58 WMColor *gray;
59 WMColor *black;
61 WMPixmap *markerPix[LastInfo];
63 WMPopUpButton *typeP;
65 WMWidget *itemPad[3];
66 int currentPad;
68 WEditMenu *menu;
69 char *menuPath;
71 WMFrame *optionsF;
73 WMFrame *commandF;
74 WMTextField *commandT; /* command to run */
75 WMButton *browseB;
76 WMButton *xtermC; /* inside xterm? */
78 WMFrame *pathF;
79 WMTextField *pathT;
81 WMFrame *pipeF;
82 WMTextField *pipeT;
83 WMButton *pipeCacheB;
85 WMFrame *dpathF;
86 WMTextField *dpathT;
88 WMFrame *dcommandF;
89 WMTextField *dcommandT;
91 WMButton *dstripB;
93 WMFrame *shortF;
94 WMTextField *shortT;
95 WMButton *sgrabB;
96 WMButton *sclearB;
98 WMList *icommandL;
100 WMFrame *paramF;
101 WMTextField *paramT;
103 WMButton *quickB;
105 Bool dontAsk; /* whether to comfirm submenu remove */
106 Bool dontSave;
108 Bool capturing;
110 /* about the currently selected item */
111 WEditMenuItem *currentItem;
112 InfoType currentType;
113 WMWidget *sections[LastInfo][MAX_SECTION_SIZE];
114 } _Panel;
116 typedef struct {
117 InfoType type;
118 union {
119 struct {
120 int command;
121 char *parameter;
122 char *shortcut;
123 } command;
124 struct {
125 char *command;
126 char *shortcut;
127 } exec;
128 struct {
129 char *path;
130 } external;
131 struct {
132 char *command;
133 unsigned cached:1;
134 } pipe;
135 struct {
136 char *directory;
137 char *command;
138 unsigned stripExt:1;
139 } directory;
140 } param;
141 } ItemData;
143 static char *commandNames[] = {
144 "ARRANGE_ICONS",
145 "HIDE_OTHERS",
146 "SHOW_ALL",
147 "EXIT",
148 "SHUTDOWN",
149 "RESTART",
150 "RESTART",
151 "SAVE_SESSION",
152 "CLEAR_SESSION",
153 "REFRESH",
154 "INFO_PANEL",
155 "LEGAL_PANEL"
158 #define ICON_FILE "menus"
160 static void showData(_Panel * panel);
162 static void updateMenuItem(_Panel * panel, WEditMenuItem * item, WMWidget * changedWidget);
164 static void menuItemSelected(struct WEditMenuDelegate *delegate, WEditMenu * menu, WEditMenuItem * item);
166 static void menuItemDeselected(struct WEditMenuDelegate *delegate, WEditMenu * menu, WEditMenuItem * item);
168 static void menuItemCloned(struct WEditMenuDelegate *delegate, WEditMenu * menu,
169 WEditMenuItem * origItem, WEditMenuItem * newItem);
171 static void menuItemEdited(struct WEditMenuDelegate *delegate, WEditMenu * menu, WEditMenuItem * item);
173 static Bool shouldRemoveItem(struct WEditMenuDelegate *delegate, WEditMenu * menu, WEditMenuItem * item);
175 static void freeItemData(ItemData * data);
177 extern char *capture_shortcut(Display *dpy, Bool *capturing, Bool convert_case);
179 static WEditMenuDelegate menuDelegate = {
180 NULL,
181 menuItemCloned,
182 menuItemEdited,
183 menuItemSelected,
184 menuItemDeselected,
185 shouldRemoveItem
188 static void dataChanged(void *self, WMNotification * notif)
190 _Panel *panel = (_Panel *) self;
191 WEditMenuItem *item = panel->currentItem;
192 WMWidget *w = (WMWidget *) WMGetNotificationObject(notif);
194 updateMenuItem(panel, item, w);
197 static void buttonClicked(WMWidget * w, void *data)
199 _Panel *panel = (_Panel *) data;
200 WEditMenuItem *item = panel->currentItem;
202 updateMenuItem(panel, item, w);
205 static void icommandLClicked(WMWidget * w, void *data)
207 _Panel *panel = (_Panel *) data;
208 int cmd;
210 cmd = WMGetListSelectedItemRow(w);
211 if (cmd == 3 || cmd == 4) {
212 WMMapWidget(panel->quickB);
213 } else {
214 WMUnmapWidget(panel->quickB);
216 if (cmd == 6) {
217 WMMapWidget(panel->paramF);
218 } else {
219 WMUnmapWidget(panel->paramF);
223 static void browseForFile(WMWidget * self, void *clientData)
225 _Panel *panel = (_Panel *) clientData;
226 WMFilePanel *filePanel;
227 char *text, *oldprog, *newprog;
229 filePanel = WMGetOpenPanel(WMWidgetScreen(self));
230 text = WMGetTextFieldText(panel->commandT);
232 oldprog = wtrimspace(text);
233 wfree(text);
235 if (oldprog[0] == 0 || oldprog[0] != '/') {
236 wfree(oldprog);
237 oldprog = wstrdup("/");
238 } else {
239 char *ptr = oldprog;
240 while (*ptr && !isspace(*ptr))
241 ptr++;
242 *ptr = 0;
245 WMSetFilePanelCanChooseDirectories(filePanel, False);
247 if (WMRunModalFilePanelForDirectory(filePanel, panel->parent, oldprog, _("Select Program"), NULL) == True) {
248 newprog = WMGetFilePanelFileName(filePanel);
249 WMSetTextFieldText(panel->commandT, newprog);
250 updateMenuItem(panel, panel->currentItem, panel->commandT);
251 wfree(newprog);
254 wfree(oldprog);
257 static void sgrabClicked(WMWidget * w, void *data)
259 _Panel *panel = (_Panel *) data;
260 Display *dpy = WMScreenDisplay(WMWidgetScreen(panel->parent));
261 char *shortcut;
263 if (w == panel->sclearB) {
264 WMSetTextFieldText(panel->shortT, "");
265 updateMenuItem(panel, panel->currentItem, panel->shortT);
266 return;
269 if (!panel->capturing) {
270 panel->capturing = 1;
271 WMSetButtonText(w, _("Cancel"));
272 XGrabKeyboard(dpy, WMWidgetXID(panel->parent), True, GrabModeAsync, GrabModeAsync, CurrentTime);
273 shortcut = capture_shortcut(dpy, &panel->capturing, 0);
274 if (shortcut) {
275 WMSetTextFieldText(panel->shortT, shortcut);
276 updateMenuItem(panel, panel->currentItem, panel->shortT);
277 wfree(shortcut);
280 panel->capturing = 0;
281 WMSetButtonText(w, _("Capture"));
282 XUngrabKeyboard(dpy, CurrentTime);
285 static void changedItemPad(WMWidget * w, void *data)
287 _Panel *panel = (_Panel *) data;
288 int padn = WMGetPopUpButtonSelectedItem(w);
290 WMUnmapWidget(panel->itemPad[panel->currentPad]);
291 WMMapWidget(panel->itemPad[padn]);
293 panel->currentPad = padn;
296 static WEditMenu *putNewSubmenu(WEditMenu * menu, char *title)
298 WEditMenu *tmp;
299 WEditMenuItem *item;
301 item = WAddMenuItemWithTitle(menu, title);
303 tmp = WCreateEditMenu(WMWidgetScreen(menu), title);
304 WSetEditMenuAcceptsDrop(tmp, True);
305 WSetEditMenuDelegate(tmp, &menuDelegate);
306 WSetEditMenuSubmenu(menu, item, tmp);
308 return tmp;
311 static ItemData *putNewItem(_Panel * panel, WEditMenu * menu, int type, char *title)
313 WEditMenuItem *item;
314 ItemData *data;
316 item = WAddMenuItemWithTitle(menu, title);
318 data = wmalloc(sizeof(ItemData));
319 data->type = type;
320 WSetEditMenuItemData(item, data, (WMCallback *) freeItemData);
321 WSetEditMenuItemImage(item, panel->markerPix[type]);
323 return data;
326 static WEditMenu *makeFactoryMenu(WMWidget * parent, int width)
328 WEditMenu *pad;
330 pad = WCreateEditMenuPad(parent);
331 WMResizeWidget(pad, width, 10);
332 WSetEditMenuMinSize(pad, wmksize(width, 0));
333 WSetEditMenuMaxSize(pad, wmksize(width, 0));
334 WSetEditMenuSelectable(pad, False);
335 WSetEditMenuEditable(pad, False);
336 WSetEditMenuIsFactory(pad, True);
337 WSetEditMenuDelegate(pad, &menuDelegate);
339 return pad;
342 static void createPanel(_Panel * p)
344 _Panel *panel = (_Panel *) p;
345 WMScreen *scr = WMWidgetScreen(panel->parent);
346 WMColor *black = WMBlackColor(scr);
347 WMColor *white = WMWhiteColor(scr);
348 WMColor *gray = WMGrayColor(scr);
349 WMFont *bold = WMBoldSystemFontOfSize(scr, 12);
350 WMFont *font = WMSystemFontOfSize(scr, 12);
351 WMLabel *label;
352 int width;
354 menuDelegate.data = panel;
356 panel->boldFont = bold;
357 panel->normalFont = font;
359 panel->black = black;
360 panel->white = white;
361 panel->gray = gray;
364 Pixmap pix;
365 Display *dpy = WMScreenDisplay(scr);
366 GC gc;
367 WMPixmap *pixm;
369 pixm = WMCreatePixmap(scr, 7, 7, WMScreenDepth(scr), True);
371 pix = WMGetPixmapXID(pixm);
373 XDrawLine(dpy, pix, WMColorGC(black), 0, 3, 6, 3);
374 XDrawLine(dpy, pix, WMColorGC(black), 3, 0, 3, 6);
376 XDrawLine(dpy, pix, WMColorGC(black), 1, 0, 3, 3);
377 XDrawLine(dpy, pix, WMColorGC(black), 1, 6, 3, 3);
378 XDrawLine(dpy, pix, WMColorGC(black), 0, 0, 0, 6);
381 pix = WMGetPixmapMaskXID(pixm);
383 gc = XCreateGC(dpy, pix, 0, NULL);
385 XSetForeground(dpy, gc, 0);
386 XFillRectangle(dpy, pix, gc, 0, 0, 7, 7);
388 XSetForeground(dpy, gc, 1);
389 XDrawLine(dpy, pix, gc, 0, 3, 6, 3);
390 XDrawLine(dpy, pix, gc, 3, 0, 3, 6);
392 panel->markerPix[ExternalInfo] = pixm;
393 panel->markerPix[PipeInfo] = pixm;
394 panel->markerPix[DirectoryInfo] = pixm;
395 panel->markerPix[WSMenuInfo] = pixm;
396 panel->markerPix[WWindowListInfo] = pixm;
398 XFreeGC(dpy, gc);
401 panel->box = WMCreateBox(panel->parent);
402 WMSetViewExpandsToParent(WMWidgetView(panel->box), 2, 2, 2, 2);
404 panel->typeP = WMCreatePopUpButton(panel->box);
405 WMResizeWidget(panel->typeP, 150, 20);
406 WMMoveWidget(panel->typeP, 10, 10);
408 WMAddPopUpButtonItem(panel->typeP, _("New Items"));
409 WMAddPopUpButtonItem(panel->typeP, _("Sample Commands"));
410 WMAddPopUpButtonItem(panel->typeP, _("Sample Submenus"));
412 WMSetPopUpButtonAction(panel->typeP, changedItemPad, panel);
414 WMSetPopUpButtonSelectedItem(panel->typeP, 0);
417 WEditMenu *pad;
419 pad = makeFactoryMenu(panel->box, 150);
420 WMMoveWidget(pad, 10, 40);
422 putNewItem(panel, pad, ExecInfo, _("Run Program"));
423 putNewItem(panel, pad, CommandInfo, _("Internal Command"));
424 putNewSubmenu(pad, _("Submenu"));
425 putNewItem(panel, pad, ExternalInfo, _("External Submenu"));
426 putNewItem(panel, pad, PipeInfo, _("Generated Submenu"));
427 putNewItem(panel, pad, DirectoryInfo, _("Directory Contents"));
428 putNewItem(panel, pad, WSMenuInfo, _("Workspace Menu"));
429 putNewItem(panel, pad, WWindowListInfo, _("Window List Menu"));
431 panel->itemPad[0] = pad;
435 WEditMenu *pad;
436 ItemData *data;
437 WMScrollView *sview;
439 sview = WMCreateScrollView(panel->box);
440 WMResizeWidget(sview, 150, 180);
441 WMMoveWidget(sview, 10, 40);
442 WMSetScrollViewHasVerticalScroller(sview, True);
444 pad = makeFactoryMenu(panel->box, 130);
446 WMSetScrollViewContentView(sview, WMWidgetView(pad));
448 data = putNewItem(panel, pad, ExecInfo, _("XTerm"));
449 data->param.exec.command = "xterm -sb -sl 2000 -bg black -fg white";
451 data = putNewItem(panel, pad, ExecInfo, _("rxvt"));
452 data->param.exec.command = "rxvt";
454 data = putNewItem(panel, pad, ExecInfo, _("ETerm"));
455 data->param.exec.command = "eterm";
457 data = putNewItem(panel, pad, ExecInfo, _("Run..."));
458 data->param.exec.command = _("%A(Run,Type command to run)");
460 data = putNewItem(panel, pad, ExecInfo, _("Firefox"));
461 data->param.exec.command = "firefox";
463 data = putNewItem(panel, pad, ExecInfo, _("gimp"));
464 data->param.exec.command = "gimp";
466 data = putNewItem(panel, pad, ExecInfo, _("epic"));
467 data->param.exec.command = "xterm -e epic";
469 data = putNewItem(panel, pad, ExecInfo, _("ee"));
470 data->param.exec.command = "ee";
472 data = putNewItem(panel, pad, ExecInfo, _("xv"));
473 data->param.exec.command = "xv";
475 data = putNewItem(panel, pad, ExecInfo, _("Evince"));
476 data->param.exec.command = "evince";
478 data = putNewItem(panel, pad, ExecInfo, _("ghostview"));
479 data->param.exec.command = "gv";
481 data = putNewItem(panel, pad, CommandInfo, _("Exit Window Maker"));
482 data->param.command.command = 3;
484 WMMapWidget(pad);
486 panel->itemPad[1] = sview;
490 WEditMenu *pad, *smenu;
491 ItemData *data;
492 WMScrollView *sview;
494 sview = WMCreateScrollView(panel->box);
495 WMResizeWidget(sview, 150, 180);
496 WMMoveWidget(sview, 10, 40);
497 WMSetScrollViewHasVerticalScroller(sview, True);
499 pad = makeFactoryMenu(panel->box, 130);
501 WMSetScrollViewContentView(sview, WMWidgetView(pad));
503 data = putNewItem(panel, pad, ExternalInfo, _("Debian Menu"));
504 data->param.pipe.command = "/etc/X11/WindowMaker/menu.hook";
506 data = putNewItem(panel, pad, PipeInfo, _("RedHat Menu"));
507 data->param.pipe.command = "wmconfig --output wmaker";
509 data = putNewItem(panel, pad, PipeInfo, _("Menu Conectiva"));
510 data->param.pipe.command = "wmconfig --output wmaker";
512 data = putNewItem(panel, pad, DirectoryInfo, _("Themes"));
513 data->param.directory.command = "setstyle";
514 data->param.directory.directory =
515 "/usr/share/WindowMaker/Themes /usr/local/share/WindowMaker/Themes $HOME/GNUstep/Library/WindowMaker/Themes";
516 data->param.directory.stripExt = 1;
518 data = putNewItem(panel, pad, DirectoryInfo, _("Bg Images (scale)"));
519 data->param.directory.command = "wmsetbg -u -s";
520 data->param.directory.directory =
521 "/opt/kde2/share/wallpapers /usr/share/WindowMaker/Backgrounds $HOME/GNUstep/Library/WindowMaker/Backgrounds";
522 data->param.directory.stripExt = 1;
524 data = putNewItem(panel, pad, DirectoryInfo, _("Bg Images (tile)"));
525 data->param.directory.command = "wmsetbg -u -t";
526 data->param.directory.directory =
527 "/opt/kde2/share/wallpapers /usr/share/WindowMaker/Backgrounds $HOME/GNUstep/Library/WindowMaker/Backgrounds";
528 data->param.directory.stripExt = 1;
530 smenu = putNewSubmenu(pad, _("Assorted XTerms"));
532 data = putNewItem(panel, smenu, ExecInfo, _("XTerm Yellow on Blue"));
533 data->param.exec.command = "xterm -sb -sl 2000 -bg midnightblue -fg yellow";
535 data = putNewItem(panel, smenu, ExecInfo, _("XTerm White on Black"));
536 data->param.exec.command = "xterm -sb -sl 2000 -bg black -fg white";
538 data = putNewItem(panel, smenu, ExecInfo, _("XTerm Black on White"));
539 data->param.exec.command = "xterm -sb -sl 2000 -bg white -fg black";
541 data = putNewItem(panel, smenu, ExecInfo, _("XTerm Black on Beige"));
542 data->param.exec.command = "xterm -sb -sl 2000 -bg '#bbbb99' -fg black";
544 data = putNewItem(panel, smenu, ExecInfo, _("XTerm White on Green"));
545 data->param.exec.command = "xterm -sb -sl 2000 -bg '#228822' -fg white";
547 data = putNewItem(panel, smenu, ExecInfo, _("XTerm White on Olive"));
548 data->param.exec.command = "xterm -sb -sl 2000 -bg '#335533' -fg white";
550 data = putNewItem(panel, smenu, ExecInfo, _("XTerm Blue on Blue"));
551 data->param.exec.command = "xterm -sb -sl 2000 -bg '#112244' -fg '#88aabb'";
553 data = putNewItem(panel, smenu, ExecInfo, _("XTerm BIG FONTS"));
554 data->param.exec.command = "xterm -sb -sl 2000 -bg black -fg white -fn 10x20";
556 WMMapWidget(pad);
558 panel->itemPad[2] = sview;
561 width = FRAME_WIDTH - 20 - 150 - 10 - 2;
563 panel->optionsF = WMCreateFrame(panel->box);
564 WMResizeWidget(panel->optionsF, width, FRAME_HEIGHT - 15);
565 WMMoveWidget(panel->optionsF, 10 + 150 + 10, 5);
567 width -= 20;
569 /* command */
571 panel->commandF = WMCreateFrame(panel->optionsF);
572 WMResizeWidget(panel->commandF, width, 50);
573 WMMoveWidget(panel->commandF, 10, 20);
574 WMSetFrameTitle(panel->commandF, _("Program to Run"));
575 WMSetFrameTitlePosition(panel->commandF, WTPAtTop);
577 panel->commandT = WMCreateTextField(panel->commandF);
578 WMResizeWidget(panel->commandT, width - 95, 20);
579 WMMoveWidget(panel->commandT, 10, 20);
581 panel->browseB = WMCreateCommandButton(panel->commandF);
582 WMResizeWidget(panel->browseB, 70, 24);
583 WMMoveWidget(panel->browseB, width - 80, 18);
584 WMSetButtonText(panel->browseB, _("Browse"));
585 WMSetButtonAction(panel->browseB, browseForFile, panel);
587 WMAddNotificationObserver(dataChanged, panel, WMTextDidChangeNotification, panel->commandT);
589 #if 0
590 panel->xtermC = WMCreateSwitchButton(panel->commandF);
591 WMResizeWidget(panel->xtermC, width - 20, 20);
592 WMMoveWidget(panel->xtermC, 10, 50);
593 WMSetButtonText(panel->xtermC, _("Run the program inside a Xterm"));
594 #endif
595 WMMapSubwidgets(panel->commandF);
597 /* path */
599 panel->pathF = WMCreateFrame(panel->optionsF);
600 WMResizeWidget(panel->pathF, width, 150);
601 WMMoveWidget(panel->pathF, 10, 40);
602 WMSetFrameTitle(panel->pathF, _("Path for Menu"));
604 panel->pathT = WMCreateTextField(panel->pathF);
605 WMResizeWidget(panel->pathT, width - 20, 20);
606 WMMoveWidget(panel->pathT, 10, 20);
608 WMAddNotificationObserver(dataChanged, panel, WMTextDidChangeNotification, panel->pathT);
610 label = WMCreateLabel(panel->pathF);
611 WMResizeWidget(label, width - 20, 80);
612 WMMoveWidget(label, 10, 50);
613 WMSetLabelText(label, _("Enter the path for a file containing a menu\n"
614 "or a list of directories with the programs you\n"
615 "want to have listed in the menu. Ex:\n"
616 "~/GNUstep/Library/WindowMaker/menu\n" "or\n" "/usr/bin ~/xbin"));
618 WMMapSubwidgets(panel->pathF);
620 /* pipe */
622 panel->pipeF = WMCreateFrame(panel->optionsF);
623 WMResizeWidget(panel->pipeF, width, 155);
624 WMMoveWidget(panel->pipeF, 10, 30);
625 WMSetFrameTitle(panel->pipeF, _("Command"));
627 panel->pipeT = WMCreateTextField(panel->pipeF);
628 WMResizeWidget(panel->pipeT, width - 20, 20);
629 WMMoveWidget(panel->pipeT, 10, 20);
631 WMAddNotificationObserver(dataChanged, panel, WMTextDidChangeNotification, panel->pipeT);
633 label = WMCreateLabel(panel->pipeF);
634 WMResizeWidget(label, width - 20, 40);
635 WMMoveWidget(label, 10, 50);
636 WMSetLabelText(label, _("Enter a command that outputs a menu\n" "definition to stdout when invoked."));
638 panel->pipeCacheB = WMCreateSwitchButton(panel->pipeF);
639 WMResizeWidget(panel->pipeCacheB, width - 20, 40);
640 WMMoveWidget(panel->pipeCacheB, 10, 110);
641 WMSetButtonText(panel->pipeCacheB, _("Cache menu contents after opening for\n" "the first time"));
643 WMMapSubwidgets(panel->pipeF);
645 /* directory menu */
647 panel->dcommandF = WMCreateFrame(panel->optionsF);
648 WMResizeWidget(panel->dcommandF, width, 90);
649 WMMoveWidget(panel->dcommandF, 10, 25);
650 WMSetFrameTitle(panel->dcommandF, _("Command to Open Files"));
652 panel->dcommandT = WMCreateTextField(panel->dcommandF);
653 WMResizeWidget(panel->dcommandT, width - 20, 20);
654 WMMoveWidget(panel->dcommandT, 10, 20);
656 WMAddNotificationObserver(dataChanged, panel, WMTextDidChangeNotification, panel->dcommandT);
658 label = WMCreateLabel(panel->dcommandF);
659 WMResizeWidget(label, width - 20, 45);
660 WMMoveWidget(label, 10, 40);
661 WMSetLabelText(label, _("Enter the command you want to use to open the\n"
662 "files in the directories listed below."));
664 WMMapSubwidgets(panel->dcommandF);
666 panel->dpathF = WMCreateFrame(panel->optionsF);
667 WMResizeWidget(panel->dpathF, width, 80);
668 WMMoveWidget(panel->dpathF, 10, 125);
669 WMSetFrameTitle(panel->dpathF, _("Directories with Files"));
671 panel->dpathT = WMCreateTextField(panel->dpathF);
672 WMResizeWidget(panel->dpathT, width - 20, 20);
673 WMMoveWidget(panel->dpathT, 10, 20);
675 WMAddNotificationObserver(dataChanged, panel, WMTextDidChangeNotification, panel->dpathT);
677 panel->dstripB = WMCreateSwitchButton(panel->dpathF);
678 WMResizeWidget(panel->dstripB, width - 20, 20);
679 WMMoveWidget(panel->dstripB, 10, 50);
680 WMSetButtonText(panel->dstripB, _("Strip extensions from file names"));
682 WMSetButtonAction(panel->dstripB, buttonClicked, panel);
684 WMMapSubwidgets(panel->dpathF);
686 /* shortcut */
688 panel->shortF = WMCreateFrame(panel->optionsF);
689 WMResizeWidget(panel->shortF, width, 50);
690 WMMoveWidget(panel->shortF, 10, 160);
691 WMSetFrameTitle(panel->shortF, _("Keyboard Shortcut"));
693 panel->shortT = WMCreateTextField(panel->shortF);
694 WMResizeWidget(panel->shortT, width - 20 - 150, 20);
695 WMMoveWidget(panel->shortT, 10, 20);
697 WMAddNotificationObserver(dataChanged, panel, WMTextDidChangeNotification, panel->shortT);
699 panel->sgrabB = WMCreateCommandButton(panel->shortF);
700 WMResizeWidget(panel->sgrabB, 70, 24);
701 WMMoveWidget(panel->sgrabB, width - 80, 18);
702 WMSetButtonText(panel->sgrabB, _("Capture"));
703 WMSetButtonAction(panel->sgrabB, sgrabClicked, panel);
705 panel->sclearB = WMCreateCommandButton(panel->shortF);
706 WMResizeWidget(panel->sclearB, 70, 24);
707 WMMoveWidget(panel->sclearB, width - 155, 18);
708 WMSetButtonText(panel->sclearB, _("Clear"));
709 WMSetButtonAction(panel->sclearB, sgrabClicked, panel);
711 WMMapSubwidgets(panel->shortF);
713 /* internal command */
715 panel->icommandL = WMCreateList(panel->optionsF);
716 WMResizeWidget(panel->icommandL, width, 80);
717 WMMoveWidget(panel->icommandL, 10, 20);
719 WMSetListAction(panel->icommandL, icommandLClicked, panel);
721 WMAddNotificationObserver(dataChanged, panel, WMListSelectionDidChangeNotification, panel->icommandL);
723 WMInsertListItem(panel->icommandL, 0, _("Arrange Icons"));
724 WMInsertListItem(panel->icommandL, 1, _("Hide All Windows Except For The Focused One"));
725 WMInsertListItem(panel->icommandL, 2, _("Show All Windows"));
727 WMInsertListItem(panel->icommandL, 3, _("Exit Window Maker"));
728 WMInsertListItem(panel->icommandL, 4, _("Exit X Session"));
729 WMInsertListItem(panel->icommandL, 5, _("Restart Window Maker"));
730 WMInsertListItem(panel->icommandL, 6, _("Start Another Window Manager : ("));
732 WMInsertListItem(panel->icommandL, 7, _("Save Current Session"));
733 WMInsertListItem(panel->icommandL, 8, _("Clear Saved Session"));
734 WMInsertListItem(panel->icommandL, 9, _("Refresh Screen"));
735 WMInsertListItem(panel->icommandL, 10, _("Open Info Panel"));
736 WMInsertListItem(panel->icommandL, 11, _("Open Copyright Panel"));
738 panel->paramF = WMCreateFrame(panel->optionsF);
739 WMResizeWidget(panel->paramF, width, 50);
740 WMMoveWidget(panel->paramF, 10, 105);
741 WMSetFrameTitle(panel->paramF, _("Window Manager to Start"));
743 panel->paramT = WMCreateTextField(panel->paramF);
744 WMResizeWidget(panel->paramT, width - 20, 20);
745 WMMoveWidget(panel->paramT, 10, 20);
747 WMAddNotificationObserver(dataChanged, panel, WMTextDidChangeNotification, panel->paramT);
749 WMMapSubwidgets(panel->paramF);
751 panel->quickB = WMCreateSwitchButton(panel->optionsF);
752 WMResizeWidget(panel->quickB, width, 20);
753 WMMoveWidget(panel->quickB, 10, 120);
754 WMSetButtonText(panel->quickB, _("Do not confirm action."));
755 WMSetButtonAction(panel->quickB, buttonClicked, panel);
757 label = WMCreateLabel(panel->optionsF);
758 WMResizeWidget(label, width + 5, FRAME_HEIGHT - 50);
759 WMMoveWidget(label, 7, 20);
760 WMSetLabelText(label,
761 _("Instructions:\n\n"
762 " - drag items from the left to the menu to add new items\n"
763 " - drag items out of the menu to remove items\n"
764 " - drag items in menu to change their position\n"
765 " - drag items with Control pressed to copy them\n"
766 " - double click in a menu item to change the label\n"
767 " - click on a menu item to change related information"));
768 WMMapWidget(label);
770 WMRealizeWidget(panel->box);
771 WMMapSubwidgets(panel->box);
772 WMMapWidget(panel->box);
775 int i;
776 for (i = 0; i < 3; i++)
777 WMUnmapWidget(panel->itemPad[i]);
779 changedItemPad(panel->typeP, panel);
781 panel->sections[NoInfo][0] = label;
783 panel->sections[ExecInfo][0] = panel->commandF;
784 panel->sections[ExecInfo][1] = panel->shortF;
786 panel->sections[CommandInfo][0] = panel->icommandL;
787 panel->sections[CommandInfo][1] = panel->shortF;
789 panel->sections[ExternalInfo][0] = panel->pathF;
791 panel->sections[PipeInfo][0] = panel->pipeF;
793 panel->sections[DirectoryInfo][0] = panel->dpathF;
794 panel->sections[DirectoryInfo][1] = panel->dcommandF;
796 panel->currentType = NoInfo;
798 showData(panel);
801 WMPoint pos;
803 pos = WMGetViewScreenPosition(WMWidgetView(panel->box));
805 if (pos.x < 200) {
806 pos.x += FRAME_WIDTH + 20;
807 } else {
808 pos.x = 10;
811 pos.y = WMAX(pos.y - 100, 0);
813 if (panel->menu)
814 WEditMenuShowAt(panel->menu, pos.x, pos.y);
818 static void freeItemData(ItemData * data)
820 #define CFREE(d) if (d) wfree(d)
822 /* TODO */
823 switch (data->type) {
824 case CommandInfo:
825 CFREE(data->param.command.parameter);
826 CFREE(data->param.command.shortcut);
827 break;
829 case ExecInfo:
830 CFREE(data->param.exec.command);
831 CFREE(data->param.exec.shortcut);
832 break;
834 case PipeInfo:
835 CFREE(data->param.pipe.command);
836 break;
838 case ExternalInfo:
839 CFREE(data->param.external.path);
840 break;
842 case DirectoryInfo:
843 CFREE(data->param.directory.command);
844 CFREE(data->param.directory.directory);
845 break;
847 default:
848 break;
851 wfree(data);
852 #undef CFREE
855 static ItemData *parseCommand(WMPropList * item)
857 ItemData *data = wmalloc(sizeof(ItemData));
858 WMPropList *p;
859 char *command = NULL;
860 char *parameter = NULL;
861 char *shortcut = NULL;
862 int i = 1;
864 p = WMGetFromPLArray(item, i++);
865 command = WMGetFromPLString(p);
866 if (strcmp(command, "SHORTCUT") == 0) {
867 p = WMGetFromPLArray(item, i++);
868 shortcut = WMGetFromPLString(p);
869 p = WMGetFromPLArray(item, i++);
870 command = WMGetFromPLString(p);
872 p = WMGetFromPLArray(item, i++);
873 if (p)
874 parameter = WMGetFromPLString(p);
876 if (strcmp(command, "EXEC") == 0 || strcmp(command, "SHEXEC") == 0) {
878 data->type = ExecInfo;
880 data->param.exec.command = wstrdup(parameter);
881 if (shortcut)
882 data->param.exec.shortcut = wstrdup(shortcut);
884 } else if (strcmp(command, "OPEN_MENU") == 0) {
885 char *p;
887 * dir menu, menu file
888 * dir WITH
889 * |pipe
891 p = parameter;
892 while (isspace(*p) && *p)
893 p++;
894 if (*p == '|') {
895 if (*(p + 1) == '|') {
896 p++;
897 data->param.pipe.cached = 0;
898 } else {
899 data->param.pipe.cached = 1;
901 data->type = PipeInfo;
902 data->param.pipe.command = wtrimspace(p + 1);
903 } else {
904 char *s;
906 p = wstrdup(p);
908 s = strstr(p, "WITH");
909 if (s) {
910 char **tokens;
911 char **ctokens;
912 int tokn;
913 int i, j;
915 data->type = DirectoryInfo;
917 *s = '\0';
918 s += 5;
919 while (*s && isspace(*s))
920 s++;
921 data->param.directory.command = wstrdup(s);
923 wtokensplit(p, &tokens, &tokn);
924 wfree(p);
926 ctokens = wmalloc(sizeof(char *) * tokn);
928 for (i = 0, j = 0; i < tokn; i++) {
929 if (strcmp(tokens[i], "-noext") == 0) {
930 data->param.directory.stripExt = 1;
931 } else {
932 ctokens[j++] = tokens[i];
935 data->param.directory.directory = wtokenjoin(ctokens, j);
936 wfree(ctokens);
938 wtokenfree(tokens, tokn);
939 } else {
940 data->type = ExternalInfo;
941 data->param.external.path = p;
944 } else if (strcmp(command, "WORKSPACE_MENU") == 0) {
945 data->type = WSMenuInfo;
946 } else if (strcmp(command, "WINDOWS_MENU") == 0) {
947 data->type = WWindowListInfo;
948 } else {
949 int cmd;
951 if (strcmp(command, "ARRANGE_ICONS") == 0) {
952 cmd = 0;
953 } else if (strcmp(command, "HIDE_OTHERS") == 0) {
954 cmd = 1;
955 } else if (strcmp(command, "SHOW_ALL") == 0) {
956 cmd = 2;
957 } else if (strcmp(command, "EXIT") == 0) {
958 cmd = 3;
959 } else if (strcmp(command, "SHUTDOWN") == 0) {
960 cmd = 4;
961 } else if (strcmp(command, "RESTART") == 0) {
962 if (parameter) {
963 cmd = 6;
964 } else {
965 cmd = 5;
967 } else if (strcmp(command, "SAVE_SESSION") == 0) {
968 cmd = 7;
969 } else if (strcmp(command, "CLEAR_SESSION") == 0) {
970 cmd = 8;
971 } else if (strcmp(command, "REFRESH") == 0) {
972 cmd = 9;
973 } else if (strcmp(command, "INFO_PANEL") == 0) {
974 cmd = 10;
975 } else if (strcmp(command, "LEGAL_PANEL") == 0) {
976 cmd = 11;
977 } else {
978 wwarning(_("unknown command '%s' in menu"), command);
979 wfree(data);
980 return NULL;
983 data->type = CommandInfo;
985 data->param.command.command = cmd;
986 if (shortcut)
987 data->param.command.shortcut = wstrdup(shortcut);
988 if (parameter)
989 data->param.command.parameter = wstrdup(parameter);
992 return data;
995 static void updateFrameTitle(_Panel * panel, char *title, InfoType type)
997 if (type != NoInfo) {
998 char *tmp;
1000 switch (type) {
1001 case ExecInfo:
1002 tmp = wstrconcat(title, _(": Execute Program"));
1003 break;
1005 case CommandInfo:
1006 tmp = wstrconcat(title, _(": Perform Internal Command"));
1007 break;
1009 case ExternalInfo:
1010 tmp = wstrconcat(title, _(": Open a Submenu"));
1011 break;
1013 case PipeInfo:
1014 tmp = wstrconcat(title, _(": Program Generated Submenu"));
1015 break;
1017 case DirectoryInfo:
1018 tmp = wstrconcat(title, _(": Directory Contents Menu"));
1019 break;
1021 case WSMenuInfo:
1022 tmp = wstrconcat(title, _(": Open Workspaces Submenu"));
1023 break;
1025 case WWindowListInfo:
1026 tmp = wstrconcat(title, _(": Open Window List Submenu"));
1027 break;
1029 default:
1030 tmp = NULL;
1031 break;
1033 WMSetFrameTitle(panel->optionsF, tmp);
1034 wfree(tmp);
1035 } else {
1036 WMSetFrameTitle(panel->optionsF, NULL);
1040 static void changeInfoType(_Panel * panel, char *title, InfoType type)
1042 WMWidget **w;
1044 if (panel->currentType != type) {
1046 w = panel->sections[panel->currentType];
1048 while (*w) {
1049 WMUnmapWidget(*w);
1050 w++;
1052 WMUnmapWidget(panel->paramF);
1053 WMUnmapWidget(panel->quickB);
1055 w = panel->sections[type];
1057 while (*w) {
1058 WMMapWidget(*w);
1059 w++;
1063 updateFrameTitle(panel, title, type);
1065 panel->currentType = type;
1068 static void updateMenuItem(_Panel * panel, WEditMenuItem * item, WMWidget * changedWidget)
1070 ItemData *data = WGetEditMenuItemData(item);
1072 assert(data != NULL);
1074 #define REPLACE(v, d) if (v) wfree(v); v = d
1076 switch (data->type) {
1077 case ExecInfo:
1078 if (changedWidget == panel->commandT) {
1079 REPLACE(data->param.exec.command, WMGetTextFieldText(panel->commandT));
1081 if (changedWidget == panel->shortT) {
1082 REPLACE(data->param.exec.shortcut, WMGetTextFieldText(panel->shortT));
1084 break;
1086 case CommandInfo:
1087 if (changedWidget == panel->icommandL) {
1088 data->param.command.command = WMGetListSelectedItemRow(panel->icommandL);
1090 switch (data->param.command.command) {
1091 case 3:
1092 case 4:
1093 if (changedWidget == panel->quickB) {
1094 REPLACE(data->param.command.parameter, WMGetButtonSelected(panel->quickB)
1095 ? wstrdup("QUICK") : NULL);
1097 break;
1099 case 6:
1100 if (changedWidget == panel->paramT) {
1101 REPLACE(data->param.command.parameter, WMGetTextFieldText(panel->paramT));
1103 break;
1105 if (changedWidget == panel->shortT) {
1106 REPLACE(data->param.command.shortcut, WMGetTextFieldText(panel->shortT));
1109 break;
1111 case PipeInfo:
1112 if (changedWidget == panel->pipeT) {
1113 REPLACE(data->param.pipe.command, WMGetTextFieldText(panel->pipeT));
1115 if (changedWidget == panel->pipeCacheB) {
1116 data->param.pipe.cached = WMGetButtonSelected(panel->pipeCacheB);
1118 break;
1120 case ExternalInfo:
1121 if (changedWidget == panel->pathT) {
1122 REPLACE(data->param.external.path, WMGetTextFieldText(panel->pathT));
1124 break;
1126 case DirectoryInfo:
1127 if (changedWidget == panel->dpathT) {
1128 REPLACE(data->param.directory.directory, WMGetTextFieldText(panel->dpathT));
1130 if (changedWidget == panel->dcommandT) {
1131 REPLACE(data->param.directory.command, WMGetTextFieldText(panel->dcommandT));
1133 if (changedWidget == panel->dstripB) {
1134 data->param.directory.stripExt = WMGetButtonSelected(panel->dstripB);
1136 break;
1138 default:
1139 assert(0);
1140 break;
1143 #undef REPLACE
1146 static void
1147 menuItemCloned(WEditMenuDelegate * delegate, WEditMenu * menu, WEditMenuItem * origItem, WEditMenuItem * newItem)
1149 ItemData *data = WGetEditMenuItemData(origItem);
1150 ItemData *newData;
1152 if (!data)
1153 return;
1155 #define DUP(s) (s) ? wstrdup(s) : NULL
1157 newData = wmalloc(sizeof(ItemData));
1159 newData->type = data->type;
1161 switch (data->type) {
1162 case ExecInfo:
1163 newData->param.exec.command = DUP(data->param.exec.command);
1164 newData->param.exec.shortcut = DUP(data->param.exec.shortcut);
1165 break;
1167 case CommandInfo:
1168 newData->param.command.command = data->param.command.command;
1169 newData->param.command.parameter = DUP(data->param.command.parameter);
1170 newData->param.command.shortcut = DUP(data->param.command.shortcut);
1171 break;
1173 case PipeInfo:
1174 newData->param.pipe.command = DUP(data->param.pipe.command);
1175 newData->param.pipe.cached = data->param.pipe.cached;
1176 break;
1178 case ExternalInfo:
1179 newData->param.external.path = DUP(data->param.external.path);
1180 break;
1182 case DirectoryInfo:
1183 newData->param.directory.directory = DUP(data->param.directory.directory);
1184 newData->param.directory.command = DUP(data->param.directory.command);
1185 newData->param.directory.stripExt = data->param.directory.stripExt;
1186 break;
1188 default:
1189 break;
1192 #undef DUP
1194 WSetEditMenuItemData(newItem, newData, (WMCallback *) freeItemData);
1197 static void menuItemEdited(struct WEditMenuDelegate *delegate, WEditMenu * menu, WEditMenuItem * item)
1199 _Panel *panel = (_Panel *) delegate->data;
1200 WEditMenu *submenu;
1202 updateFrameTitle(panel, WGetEditMenuItemTitle(item), panel->currentType);
1204 submenu = WGetEditMenuSubmenu(menu, item);
1205 if (submenu) {
1206 WSetEditMenuTitle(submenu, WGetEditMenuItemTitle(item));
1210 static Bool shouldRemoveItem(struct WEditMenuDelegate *delegate, WEditMenu * menu, WEditMenuItem * item)
1212 _Panel *panel = (_Panel *) delegate->data;
1214 if (panel->dontAsk)
1215 return True;
1217 if (WGetEditMenuSubmenu(menu, item)) {
1218 int res;
1220 res = WMRunAlertPanel(WMWidgetScreen(menu), NULL,
1221 _("Remove Submenu"),
1222 _("Removing this item will destroy all items inside\n"
1223 "the submenu. Do you really want to do that?"),
1224 _("Yes"), _("No"), _("Yes, don't ask again."));
1225 switch (res) {
1226 case WAPRDefault:
1227 return True;
1228 case WAPRAlternate:
1229 return False;
1230 case WAPROther:
1231 panel->dontAsk = True;
1232 return True;
1235 return True;
1238 static void menuItemDeselected(WEditMenuDelegate * delegate, WEditMenu * menu, WEditMenuItem * item)
1240 _Panel *panel = (_Panel *) delegate->data;
1242 changeInfoType(panel, NULL, NoInfo);
1245 static void menuItemSelected(WEditMenuDelegate * delegate, WEditMenu * menu, WEditMenuItem * item)
1247 ItemData *data = WGetEditMenuItemData(item);
1248 _Panel *panel = (_Panel *) delegate->data;
1250 panel->currentItem = item;
1252 if (data) {
1253 changeInfoType(panel, WGetEditMenuItemTitle(item), data->type);
1255 switch (data->type) {
1256 case NoInfo:
1257 break;
1259 case ExecInfo:
1260 WMSetTextFieldText(panel->commandT, data->param.exec.command);
1261 WMSetTextFieldText(panel->shortT, data->param.exec.shortcut);
1262 break;
1264 case CommandInfo:
1265 WMSelectListItem(panel->icommandL, data->param.command.command);
1266 WMSetListPosition(panel->icommandL, data->param.command.command - 2);
1267 WMSetTextFieldText(panel->shortT, data->param.command.shortcut);
1269 switch (data->param.command.command) {
1270 case 3:
1271 case 4:
1272 WMSetButtonSelected(panel->quickB, data->param.command.parameter != NULL);
1273 break;
1274 case 6:
1275 WMSetTextFieldText(panel->paramT, data->param.command.parameter);
1276 break;
1279 icommandLClicked(panel->icommandL, panel);
1280 break;
1282 case PipeInfo:
1283 WMSetTextFieldText(panel->pipeT, data->param.pipe.command);
1284 WMSetButtonSelected(panel->pipeCacheB, data->param.pipe.cached);
1285 break;
1287 case ExternalInfo:
1288 WMSetTextFieldText(panel->pathT, data->param.external.path);
1289 break;
1291 case DirectoryInfo:
1292 WMSetTextFieldText(panel->dpathT, data->param.directory.directory);
1293 WMSetTextFieldText(panel->dcommandT, data->param.directory.command);
1294 WMSetButtonSelected(panel->dstripB, data->param.directory.stripExt);
1295 break;
1297 case WSMenuInfo:
1298 break;
1300 default:
1301 break;
1306 static WEditMenu *buildSubmenu(_Panel * panel, WMPropList * pl)
1308 WMScreen *scr = WMWidgetScreen(panel->parent);
1309 WEditMenu *menu;
1310 WEditMenuItem *item;
1311 char *title;
1312 WMPropList *tp, *bp;
1313 int i;
1315 tp = WMGetFromPLArray(pl, 0);
1316 title = WMGetFromPLString(tp);
1318 menu = WCreateEditMenu(scr, title);
1320 for (i = 1; i < WMGetPropListItemCount(pl); i++) {
1321 WMPropList *pi;
1323 pi = WMGetFromPLArray(pl, i);
1325 tp = WMGetFromPLArray(pi, 0);
1326 bp = WMGetFromPLArray(pi, 1);
1328 title = WMGetFromPLString(tp);
1330 if (!bp || WMIsPLArray(bp)) { /* it's a submenu */
1331 WEditMenu *submenu;
1333 submenu = buildSubmenu(panel, pi);
1335 item = WAddMenuItemWithTitle(menu, title);
1337 WSetEditMenuSubmenu(menu, item, submenu);
1338 } else {
1339 ItemData *data;
1341 data = parseCommand(pi);
1343 if (data != NULL) {
1344 item = WAddMenuItemWithTitle(menu, title);
1345 if (panel->markerPix[data->type])
1346 WSetEditMenuItemImage(item, panel->markerPix[data->type]);
1347 WSetEditMenuItemData(item, data, (WMCallback *) freeItemData);
1348 } else {
1349 char *buf = wmalloc(1024);
1350 snprintf(buf, 1024, _("Invalid menu command \"%s\" with label \"%s\" cleared"),
1351 WMGetFromPLString(WMGetFromPLArray(pi, 1)),
1352 WMGetFromPLString(WMGetFromPLArray(pi, 0)));
1353 WMRunAlertPanel(scr, panel->parent, _("Warning"), buf, _("OK"), NULL, NULL);
1354 wfree(buf);
1360 WSetEditMenuAcceptsDrop(menu, True);
1361 WSetEditMenuDelegate(menu, &menuDelegate);
1363 WMRealizeWidget(menu);
1365 return menu;
1368 static void buildMenuFromPL(_Panel * panel, WMPropList * pl)
1370 panel->menu = buildSubmenu(panel, pl);
1373 static WMPropList *getDefaultMenu(_Panel * panel)
1375 WMPropList *menu;
1376 char *menuPath, *gspath;
1378 gspath = wstrdup(WMAKER_RESOURCE_PATH);
1380 menuPath = wmalloc(strlen(gspath) + 128);
1381 sprintf(menuPath, "%s/plmenu", gspath);
1383 menu = WMReadPropListFromFile(menuPath);
1385 if (!menu) {
1386 char *buffer, *msg;
1388 msg = _("Could not open default menu from '%s'");
1389 buffer = wmalloc(strlen(msg) + strlen(menuPath) + 10);
1390 sprintf(buffer, msg, menuPath);
1391 WMRunAlertPanel(WMWidgetScreen(panel->parent), panel->parent,
1392 _("Error"), buffer, _("OK"), NULL, NULL);
1393 wfree(buffer);
1396 wfree(gspath);
1397 wfree(menuPath);
1399 return menu;
1402 static void showData(_Panel * panel)
1404 char *gspath;
1405 char *menuPath;
1406 WMPropList *pmenu;
1408 gspath = wusergnusteppath();
1410 menuPath = wmalloc(strlen(gspath) + 32);
1411 strcpy(menuPath, gspath);
1412 strcat(menuPath, "/Defaults/WMRootMenu");
1414 pmenu = WMReadPropListFromFile(menuPath);
1416 if (!pmenu || !WMIsPLArray(pmenu)) {
1417 int res;
1419 res = WMRunAlertPanel(WMWidgetScreen(panel->parent), panel->parent,
1420 _("Warning"),
1421 _("The menu file format currently in use is not supported\n"
1422 "by this tool. Do you want to discard the current menu\n"
1423 "to use this tool?"),
1424 _("Yes, Discard and Update"), _("No, Keep Current Menu"), NULL);
1426 if (res == WAPRDefault) {
1427 pmenu = getDefaultMenu(panel);
1429 if (!pmenu) {
1430 pmenu = WMCreatePLArray(WMCreatePLString("Applications"), NULL);
1432 } else {
1433 panel->dontSave = True;
1434 return;
1438 panel->menuPath = menuPath;
1440 buildMenuFromPL(panel, pmenu);
1442 WMReleasePropList(pmenu);
1445 static Bool notblank(char *s)
1447 if (s) {
1448 while (*s++) {
1449 if (!isspace(*s))
1450 return True;
1453 return False;
1456 static WMPropList *processData(char *title, ItemData * data)
1458 WMPropList *item;
1459 char *s1;
1460 static WMPropList *pscut = NULL;
1461 static WMPropList *pomenu = NULL;
1462 int i;
1464 if (data == NULL)
1465 return NULL;
1467 if (!pscut) {
1468 pscut = WMCreatePLString("SHORTCUT");
1469 pomenu = WMCreatePLString("OPEN_MENU");
1472 item = WMCreatePLArray(WMCreatePLString(title), NULL);
1474 switch (data->type) {
1475 case ExecInfo:
1476 if (data->param.exec.command == NULL)
1477 return NULL;
1478 #if 1
1479 if (strpbrk(data->param.exec.command, "&$*|><?`=;")) {
1480 s1 = "SHEXEC";
1481 } else {
1482 s1 = "EXEC";
1484 #else
1485 s1 = "SHEXEC";
1486 #endif
1488 if (notblank(data->param.exec.shortcut)) {
1489 WMAddToPLArray(item, pscut);
1490 WMAddToPLArray(item, WMCreatePLString(data->param.exec.shortcut));
1493 WMAddToPLArray(item, WMCreatePLString(s1));
1494 WMAddToPLArray(item, WMCreatePLString(data->param.exec.command));
1495 break;
1497 case CommandInfo:
1498 if (notblank(data->param.command.shortcut)) {
1499 WMAddToPLArray(item, pscut);
1500 WMAddToPLArray(item, WMCreatePLString(data->param.command.shortcut));
1503 i = data->param.command.command;
1505 WMAddToPLArray(item, WMCreatePLString(commandNames[i]));
1507 switch (i) {
1508 case 3:
1509 case 4:
1510 if (data->param.command.parameter) {
1511 WMAddToPLArray(item, WMCreatePLString(data->param.command.parameter));
1513 break;
1515 case 6: /* restart */
1516 if (data->param.command.parameter) {
1517 WMAddToPLArray(item, WMCreatePLString(data->param.command.parameter));
1519 break;
1522 break;
1524 case PipeInfo:
1525 if (!data->param.pipe.command)
1526 return NULL;
1527 WMAddToPLArray(item, pomenu);
1528 if (data->param.pipe.cached)
1529 s1 = wstrconcat("| ", data->param.pipe.command);
1530 else
1531 s1 = wstrconcat("|| ", data->param.pipe.command);
1532 WMAddToPLArray(item, WMCreatePLString(s1));
1533 wfree(s1);
1534 break;
1536 case ExternalInfo:
1537 if (!data->param.external.path)
1538 return NULL;
1539 WMAddToPLArray(item, pomenu);
1540 WMAddToPLArray(item, WMCreatePLString(data->param.external.path));
1541 break;
1543 case DirectoryInfo:
1544 if (!data->param.directory.directory || !data->param.directory.command)
1545 return NULL;
1547 int l;
1548 char *tmp;
1550 l = strlen(data->param.directory.directory);
1551 l += strlen(data->param.directory.command);
1552 l += 32;
1554 WMAddToPLArray(item, pomenu);
1556 tmp = wmalloc(l);
1557 sprintf(tmp, "%s%s WITH %s",
1558 data->param.directory.stripExt ? "-noext " : "",
1559 data->param.directory.directory, data->param.directory.command);
1561 WMAddToPLArray(item, WMCreatePLString(tmp));
1562 wfree(tmp);
1564 break;
1566 case WSMenuInfo:
1567 WMAddToPLArray(item, WMCreatePLString("WORKSPACE_MENU"));
1568 break;
1570 case WWindowListInfo:
1571 WMAddToPLArray(item, WMCreatePLString("WINDOWS_MENU"));
1572 break;
1574 default:
1575 assert(0);
1576 break;
1579 return item;
1582 static WMPropList *processSubmenu(WEditMenu * menu)
1584 WEditMenuItem *item;
1585 WMPropList *pmenu;
1586 WMPropList *pl;
1587 char *s;
1588 int i;
1590 s = WGetEditMenuTitle(menu);
1591 pl = WMCreatePLString(s);
1593 pmenu = WMCreatePLArray(pl, NULL);
1595 i = 0;
1596 while ((item = WGetEditMenuItem(menu, i++))) {
1597 WEditMenu *submenu;
1599 s = WGetEditMenuItemTitle(item);
1601 submenu = WGetEditMenuSubmenu(menu, item);
1602 if (submenu) {
1603 pl = processSubmenu(submenu);
1604 } else {
1605 pl = processData(s, WGetEditMenuItemData(item));
1608 if (!pl)
1609 continue;
1611 WMAddToPLArray(pmenu, pl);
1614 return pmenu;
1617 static WMPropList *buildPLFromMenu(_Panel * panel)
1619 WMPropList *menu;
1621 menu = processSubmenu(panel->menu);
1623 return menu;
1626 static void storeData(_Panel * panel)
1628 WMPropList *menu;
1630 if (panel->dontSave)
1631 return;
1633 menu = buildPLFromMenu(panel);
1635 WMWritePropListToFile(menu, panel->menuPath);
1637 WMReleasePropList(menu);
1640 static void showMenus(_Panel * panel)
1642 if (panel->menu)
1643 WEditMenuUnhide(panel->menu);
1646 static void hideMenus(_Panel * panel)
1648 if (panel->menu)
1649 WEditMenuHide(panel->menu);
1652 Panel *InitMenu(WMScreen * scr, WMWidget * parent)
1654 _Panel *panel;
1656 panel = wmalloc(sizeof(_Panel));
1658 panel->sectionName = _("Applications Menu Definition");
1660 panel->description = _("Edit the menu for launching applications.");
1662 panel->parent = parent;
1664 panel->callbacks.createWidgets = createPanel;
1665 panel->callbacks.updateDomain = storeData;
1666 panel->callbacks.showPanel = showMenus;
1667 panel->callbacks.hidePanel = hideMenus;
1669 AddSection(panel, ICON_FILE);
1671 return panel;