"finished" new menu editor
[wmaker-crm.git] / WPrefs.app / Menu.c
blobe1d71023cf12961cd63e671bae92fc3bb20d8d34
1 /* Menu.c- menu definition
2 *
3 * WPrefs - Window Maker Preferences Program
4 *
5 * Copyright (c) 2000 Alfredo K. Kojima
6 *
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
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20 * USA.
24 #include "WPrefs.h"
25 #include <assert.h>
26 #include <ctype.h>
28 #include <X11/keysym.h>
29 #include <X11/cursorfont.h>
32 #include "editmenu.h"
35 typedef enum {
36 NoInfo,
37 ExecInfo,
38 CommandInfo,
39 ExternalInfo,
40 PipeInfo,
41 DirectoryInfo,
42 WSMenuInfo,
43 LastInfo
44 } InfoType;
46 #define MAX_SECTION_SIZE 4
48 typedef struct _Panel {
49 WMFrame *frame;
50 char *sectionName;
52 char *description;
54 CallbackRec callbacks;
55 WMWindow *win;
58 WMFont *boldFont;
59 WMFont *normalFont;
60 WMColor *white;
61 WMColor *gray;
62 WMColor *black;
64 WMPixmap *markerPix[LastInfo];
66 WMPopUpButton *typeP;
68 WMWidget *itemPad[3];
69 int currentPad;
71 WEditMenu *menu;
72 char *menuPath;
74 WMFrame *optionsF;
76 WMFrame *commandF;
77 WMTextField *commandT; /* command to run */
78 WMButton *xtermC; /* inside xterm? */
80 WMFrame *pathF;
81 WMTextField *pathT;
83 WMFrame *pipeF;
84 WMTextField *pipeT;
86 WMFrame *dpathF;
87 WMTextField *dpathT;
89 WMFrame *dcommandF;
90 WMTextField *dcommandT;
92 WMButton *dstripB;
94 WMFrame *shortF;
95 WMTextField *shortT;
96 WMButton *sgrabB;
97 WMButton *sclearB;
99 WMList *icommandL;
101 WMFrame *paramF;
102 WMTextField *paramT;
104 WMButton *quickB;
106 Bool dontAsk; /* whether to comfirm submenu remove */
107 Bool dontSave;
109 Bool capturing;
111 /* about the currently selected item */
112 WEditMenuItem *currentItem;
113 InfoType currentType;
114 WMWidget *sections[LastInfo][MAX_SECTION_SIZE];
115 } _Panel;
118 typedef struct {
119 InfoType type;
120 union {
121 struct {
122 int command;
123 char *parameter;
124 char *shortcut;
125 } command;
126 struct {
127 char *command;
128 char *shortcut;
129 } exec;
130 struct {
131 char *path;
132 } external;
133 struct {
134 char *command;
135 } pipe;
136 struct {
137 char *directory;
138 char *command;
139 unsigned stripExt:1;
140 } directory;
141 } param;
142 } ItemData;
146 static char *commandNames[] = {
147 "ARRANGE_ICONS",
148 "HIDE_OTHERS",
149 "SHOW_ALL",
150 "EXIT",
151 "SHUTDOWN",
152 "RESTART",
153 "RESTART",
154 "SAVE_SESSION",
155 "CLEAR_SESSION",
156 "REFRESH",
157 "INFO_PANEL",
158 "LEGAL_PANEL"
163 #define NEW(type) memset(wmalloc(sizeof(type)), 0, sizeof(type))
166 #define ICON_FILE "menus"
170 static void showData(_Panel *panel);
173 static void updateMenuItem(_Panel *panel, WEditMenuItem *item,
174 WMWidget *changedWidget);
176 static void menuItemSelected(struct WEditMenuDelegate *delegate,
177 WEditMenu *menu, WEditMenuItem *item);
179 static void menuItemDeselected(struct WEditMenuDelegate *delegate,
180 WEditMenu *menu, WEditMenuItem *item);
182 static void menuItemCloned(struct WEditMenuDelegate *delegate, WEditMenu *menu,
183 WEditMenuItem *origItem, WEditMenuItem *newItem);
185 static void menuItemEdited(struct WEditMenuDelegate *delegate, WEditMenu *menu,
186 WEditMenuItem *item);
188 static Bool shouldRemoveItem(struct WEditMenuDelegate *delegate,
189 WEditMenu *menu, WEditMenuItem *item);
192 static void freeItemData(ItemData *data);
196 static WEditMenuDelegate menuDelegate = {
197 NULL,
198 menuItemCloned,
199 menuItemEdited,
200 menuItemSelected,
201 menuItemDeselected,
202 shouldRemoveItem
206 static void
207 dataChanged(void *self, WMNotification *notif)
209 _Panel *panel = (_Panel*)self;
210 WEditMenuItem *item = panel->currentItem;
211 WMWidget *w = (WMWidget*)WMGetNotificationObject(notif);
213 updateMenuItem(panel, item, w);
217 static void
218 buttonClicked(WMWidget *w, void *data)
220 _Panel *panel = (_Panel*)data;
221 WEditMenuItem *item = panel->currentItem;
223 updateMenuItem(panel, item, w);
227 static void
228 icommandLClicked(WMWidget *w, void *data)
230 _Panel *panel = (_Panel*)data;
231 int cmd;
233 cmd = WMGetListSelectedItemRow(w);
234 if (cmd == 3 || cmd == 4) {
235 WMMapWidget(panel->quickB);
236 } else {
237 WMUnmapWidget(panel->quickB);
239 if (cmd == 6) {
240 WMMapWidget(panel->paramF);
241 } else {
242 WMUnmapWidget(panel->paramF);
254 static char*
255 captureShortcut(Display *dpy, _Panel *panel)
257 XEvent ev;
258 KeySym ksym;
259 char buffer[64];
260 char *key = NULL;
262 while (panel->capturing) {
263 XAllowEvents(dpy, AsyncKeyboard, CurrentTime);
264 WMNextEvent(dpy, &ev);
265 if (ev.type==KeyPress && ev.xkey.keycode!=0) {
266 ksym = XKeycodeToKeysym(dpy, ev.xkey.keycode, 0);
267 if (!IsModifierKey(ksym)) {
268 key=XKeysymToString(ksym);
269 panel->capturing = 0;
270 break;
273 WMHandleEvent(&ev);
276 if (!key)
277 return NULL;
279 buffer[0] = 0;
281 if (ev.xkey.state & ControlMask) {
282 strcat(buffer, "Control+");
284 if (ev.xkey.state & ShiftMask) {
285 strcat(buffer, "Shift+");
287 if (ev.xkey.state & Mod1Mask) {
288 strcat(buffer, "Mod1+");
290 if (ev.xkey.state & Mod2Mask) {
291 strcat(buffer, "Mod2+");
293 if (ev.xkey.state & Mod3Mask) {
294 strcat(buffer, "Mod3+");
296 if (ev.xkey.state & Mod4Mask) {
297 strcat(buffer, "Mod4+");
299 if (ev.xkey.state & Mod5Mask) {
300 strcat(buffer, "Mod5+");
302 strcat(buffer, key);
304 return wstrdup(buffer);
309 static void
310 sgrabClicked(WMWidget *w, void *data)
312 _Panel *panel = (_Panel*)data;
313 Display *dpy = WMScreenDisplay(WMWidgetScreen(panel->win));
314 char *shortcut;
317 if (w == panel->sclearB) {
318 WMSetTextFieldText(panel->shortT, "");
319 updateMenuItem(panel, panel->currentItem, panel->shortT);
320 return;
323 if (!panel->capturing) {
324 panel->capturing = 1;
325 WMSetButtonText(w, _("Cancel"));
326 XGrabKeyboard(dpy, WMWidgetXID(panel->win), True, GrabModeAsync,
327 GrabModeAsync, CurrentTime);
328 shortcut = captureShortcut(dpy, panel);
329 if (shortcut) {
330 WMSetTextFieldText(panel->shortT, shortcut);
331 updateMenuItem(panel, panel->currentItem, panel->shortT);
332 free(shortcut);
335 panel->capturing = 0;
336 WMSetButtonText(w, _("Capture"));
337 XUngrabKeyboard(dpy, CurrentTime);
341 static void
342 changedItemPad(WMWidget *w, void *data)
344 _Panel *panel = (_Panel*)data;
345 int padn = WMGetPopUpButtonSelectedItem(w);
347 WMUnmapWidget(panel->itemPad[panel->currentPad]);
348 WMMapWidget(panel->itemPad[padn]);
350 panel->currentPad = padn;
354 static WEditMenu*
355 putNewSubmenu(WEditMenu *menu, char *title)
357 WEditMenu *tmp;
358 WEditMenuItem *item;
360 item = WAddMenuItemWithTitle(menu, title);
362 tmp = WCreateEditMenu(WMWidgetScreen(menu), title);
363 WSetEditMenuAcceptsDrop(tmp, True);
364 WSetEditMenuDelegate(tmp, &menuDelegate);
365 WSetEditMenuSubmenu(menu, item, tmp);
367 return tmp;
371 static ItemData*
372 putNewItem(_Panel *panel, WEditMenu *menu, int type, char *title)
374 WEditMenuItem *item;
375 ItemData *data;
377 item = WAddMenuItemWithTitle(menu, title);
379 data = NEW(ItemData);
380 data->type = type;
381 WSetEditMenuItemData(item, data, (WMCallback*)freeItemData);
382 WSetEditMenuItemImage(item, panel->markerPix[type]);
384 return data;
388 static WEditMenu*
389 makeFactoryMenu(WMWidget *parent, int width)
391 WEditMenu *pad;
393 pad = WCreateEditMenuPad(parent);
394 WMResizeWidget(pad, width, 10);
395 WSetEditMenuMinSize(pad, wmksize(width, 0));
396 WSetEditMenuMaxSize(pad, wmksize(width, 0));
397 WSetEditMenuSelectable(pad, False);
398 WSetEditMenuEditable(pad, False);
399 WSetEditMenuIsFactory(pad, True);
400 WSetEditMenuDelegate(pad, &menuDelegate);
402 return pad;
406 static void
407 createPanel(_Panel *p)
409 _Panel *panel = (_Panel*)p;
410 WMScreen *scr = WMWidgetScreen(panel->win);
411 WMColor *black = WMBlackColor(scr);
412 WMColor *white = WMWhiteColor(scr);
413 WMColor *gray = WMGrayColor(scr);
414 WMFont *bold = WMBoldSystemFontOfSize(scr, 12);
415 WMFont *font = WMSystemFontOfSize(scr, 12);
416 WMLabel *label;
417 int width;
420 menuDelegate.data = panel;
423 panel->boldFont = bold;
424 panel->normalFont = font;
426 panel->black = black;
427 panel->white = white;
428 panel->gray = gray;
431 Pixmap pix;
432 Display *dpy = WMScreenDisplay(scr);
433 GC gc;
434 WMPixmap *pixm;
436 pixm = WMCreatePixmap(scr, 7, 7, WMScreenDepth(scr), True);
438 pix = WMGetPixmapXID(pixm);
440 XDrawLine(dpy, pix, WMColorGC(black), 1, 0, 6, 3);
441 XDrawLine(dpy, pix, WMColorGC(black), 1, 6, 6, 3);
442 XDrawLine(dpy, pix, WMColorGC(black), 1, 0, 3, 3);
443 XDrawLine(dpy, pix, WMColorGC(black), 1, 6, 3, 3);
444 XDrawLine(dpy, pix, WMColorGC(black), 0, 0, 0, 6);
447 pix = WMGetPixmapMaskXID(pixm);
449 gc = XCreateGC(dpy, pix, 0, NULL);
451 XSetForeground(dpy, gc, 0);
452 XFillRectangle(dpy, pix, gc, 0, 0, 7, 7);
454 XSetForeground(dpy, gc, 1);
455 XDrawLine(dpy, pix, gc, 1, 0, 6, 3);
456 XDrawLine(dpy, pix, gc, 1, 6, 6, 3);
457 XDrawLine(dpy, pix, gc, 1, 0, 3, 3);
458 XDrawLine(dpy, pix, gc, 1, 6, 3, 3);
459 XDrawLine(dpy, pix, gc, 0, 0, 0, 6);
461 panel->markerPix[ExternalInfo] = pixm;
462 panel->markerPix[PipeInfo] = pixm;
463 panel->markerPix[DirectoryInfo] = pixm;
464 panel->markerPix[WSMenuInfo] = pixm;
466 XFreeGC(dpy, gc);
470 panel->frame = WMCreateFrame(panel->win);
471 WMResizeWidget(panel->frame, FRAME_WIDTH, FRAME_HEIGHT);
472 WMMoveWidget(panel->frame, FRAME_LEFT, FRAME_TOP);
474 panel->typeP = WMCreatePopUpButton(panel->frame);
475 WMResizeWidget(panel->typeP, 150, 20);
476 WMMoveWidget(panel->typeP, 10, 10);
478 WMAddPopUpButtonItem(panel->typeP, _("New Items"));
479 WMAddPopUpButtonItem(panel->typeP, _("Sample Commands"));
480 WMAddPopUpButtonItem(panel->typeP, _("Sample Submenus"));
482 WMSetPopUpButtonAction(panel->typeP, changedItemPad, panel);
484 WMSetPopUpButtonSelectedItem(panel->typeP, 0);
487 WEditMenu *pad;
488 WEditMenu *smenu;
489 ItemData *data;
491 pad = makeFactoryMenu(panel->frame, 150);
492 WMMoveWidget(pad, 10, 40);
494 data = putNewItem(panel, pad, ExecInfo, "Run Program");
495 data = putNewItem(panel, pad, CommandInfo, "Internal Command");
496 smenu = putNewSubmenu(pad, "Submenu");
497 data = putNewItem(panel, pad, ExternalInfo, "External Submenu");
498 data = putNewItem(panel, pad, PipeInfo, "Generated Submenu");
499 data = putNewItem(panel, pad, DirectoryInfo, "Directory Contents");
500 data = putNewItem(panel, pad, WSMenuInfo, "Workspace Menu");
502 panel->itemPad[0] = pad;
506 WEditMenu *pad;
507 ItemData *data;
508 WMScrollView *sview;
510 sview = WMCreateScrollView(panel->frame);
511 WMResizeWidget(sview, 150, 180);
512 WMMoveWidget(sview, 10, 40);
513 WMSetScrollViewHasVerticalScroller(sview, True);
515 pad = makeFactoryMenu(panel->frame, 130);
517 WMSetScrollViewContentView(sview, WMWidgetView(pad));
519 data = putNewItem(panel, pad, ExecInfo, _("XTerm"));
520 data->param.exec.command = "xterm -sb -sl 2000 -bg black -fg white";
522 data = putNewItem(panel, pad, ExecInfo, _("rxvt"));
523 data->param.exec.command = "rxvt";
525 data = putNewItem(panel, pad, ExecInfo, _("ETerm"));
526 data->param.exec.command = "eterm";
528 data = putNewItem(panel, pad, ExecInfo, _("Run..."));
529 data->param.exec.command = "%a(Run,Type command to run)";
531 data = putNewItem(panel, pad, ExecInfo, _("Netscape"));
532 data->param.exec.command = "netscape";
534 data = putNewItem(panel, pad, ExecInfo, _("gimp"));
535 data->param.exec.command = "gimp";
537 data = putNewItem(panel, pad, ExecInfo, _("epic"));
538 data->param.exec.command = "xterm -e epic";
540 data = putNewItem(panel, pad, ExecInfo, _("ee"));
541 data->param.exec.command = "ee";
543 data = putNewItem(panel, pad, ExecInfo, _("xv"));
544 data->param.exec.command = "xv";
546 data = putNewItem(panel, pad, ExecInfo, _("Acrobat Reader"));
547 data->param.exec.command = "acroread || /usr/local/Acrobat4/bin/acroread";
549 data = putNewItem(panel, pad, ExecInfo, _("ghostview"));
550 data->param.exec.command = "gv";
552 data = putNewItem(panel, pad, CommandInfo, _("Exit Window Maker"));
553 data->param.command.command = 3;
555 WMMapWidget(pad);
557 panel->itemPad[1] = sview;
562 WEditMenu *pad, *smenu;
563 ItemData *data;
564 WMScrollView *sview;
566 sview = WMCreateScrollView(panel->frame);
567 WMResizeWidget(sview, 150, 180);
568 WMMoveWidget(sview, 10, 40);
569 WMSetScrollViewHasVerticalScroller(sview, True);
571 pad = makeFactoryMenu(panel->frame, 130);
573 WMSetScrollViewContentView(sview, WMWidgetView(pad));
575 /* data = putNewItem(panel, pad, ExternalInfo, _("Debian Menu"));
576 data->param.pipe.command = "/etc/X11/WindowMaker/menu.hook";
578 data = putNewItem(panel, pad, PipeInfo, _("RedHat Menu"));
579 data->param.pipe.command = "wmconfig --output wmaker";
581 data = putNewItem(panel, pad, PipeInfo, _("Menu Conectiva"));
582 data->param.pipe.command = "wmconfig --output wmaker";
584 data = putNewItem(panel, pad, DirectoryInfo, _("Themes"));
585 data->param.directory.directory = "/usr/share/WindowMaker/Themes /usr/local/share/WindowMaker/Themes $HOME/GNUstep/Library/WindowMaker/Themes";
586 data->param.directory.stripExt = 1;
588 data = putNewItem(panel, pad, DirectoryInfo, _("Bg Images (scale)"));
589 data->param.directory.command = "wmsetbg -u -s";
590 data->param.directory.directory = "/opt/kde2/share/wallpapers /usr/share/WindowMaker/Backgrounds $HOME/GNUstep/Library/WindowMaker/Backgrounds";
591 data->param.directory.stripExt = 1;
593 data = putNewItem(panel, pad, DirectoryInfo, _("Bg Images (tile)"));
594 data->param.directory.command = "wmsetbg -u -t";
595 data->param.directory.directory = "/opt/kde2/share/wallpapers /usr/share/WindowMaker/Backgrounds $HOME/GNUstep/Library/WindowMaker/Backgrounds";
596 data->param.directory.stripExt = 1;
598 smenu = putNewSubmenu(pad, _("Assorted XTerms"));
600 data = putNewItem(panel, smenu, ExecInfo, _("XTerm Yellow on Blue"));
601 data->param.exec.command = "xterm -sb -sl 2000 -bg midnightblue -fg yellow";
603 data = putNewItem(panel, smenu, ExecInfo, _("XTerm White on Black"));
604 data->param.exec.command = "xterm -sb -sl 2000 -bg black -fg white";
606 data = putNewItem(panel, smenu, ExecInfo, _("XTerm Black on White"));
607 data->param.exec.command = "xterm -sb -sl 2000 -bg white -fg black";
609 data = putNewItem(panel, smenu, ExecInfo, _("XTerm Black on Beige"));
610 data->param.exec.command = "xterm -sb -sl 2000 -bg '#bbbb99' -fg black";
612 data = putNewItem(panel, smenu, ExecInfo, _("XTerm White on Green"));
613 data->param.exec.command = "xterm -sb -sl 2000 -bg '#228822' -fg white";
615 data = putNewItem(panel, smenu, ExecInfo, _("XTerm White on Olive"));
616 data->param.exec.command = "xterm -sb -sl 2000 -bg '#335533' -fg white";
618 data = putNewItem(panel, smenu, ExecInfo, _("XTerm Blue on Blue"));
619 data->param.exec.command = "xterm -sb -sl 2000 -bg '#112244' -fg '#88aabb'";
621 data = putNewItem(panel, smenu, ExecInfo, _("XTerm BIG FONTS"));
622 data->param.exec.command = "xterm -sb -sl 2000 -bg black -fg white -fn 10x20";
624 WMMapWidget(pad);
626 panel->itemPad[2] = sview;
630 width = FRAME_WIDTH - 20 - 150 - 10;
632 panel->optionsF = WMCreateFrame(panel->frame);
633 WMResizeWidget(panel->optionsF, width, FRAME_HEIGHT - 15);
634 WMMoveWidget(panel->optionsF, 10 + 150 + 10, 5);
636 width -= 20;
638 /* command */
640 panel->commandF = WMCreateFrame(panel->optionsF);
641 WMResizeWidget(panel->commandF, width, 50);
642 WMMoveWidget(panel->commandF, 10, 20);
643 WMSetFrameTitle(panel->commandF, _("Program to Run"));
645 panel->commandT = WMCreateTextField(panel->commandF);
646 WMResizeWidget(panel->commandT, width - 20, 20);
647 WMMoveWidget(panel->commandT, 10, 20);
649 WMAddNotificationObserver(dataChanged, panel,
650 WMTextDidChangeNotification,
651 panel->commandT);
653 #if 0
654 panel->xtermC = WMCreateSwitchButton(panel->commandF);
655 WMResizeWidget(panel->xtermC, width - 20, 20);
656 WMMoveWidget(panel->xtermC, 10, 50);
657 WMSetButtonText(panel->xtermC, _("Run the program inside a Xterm"));
658 #endif
659 WMMapSubwidgets(panel->commandF);
662 /* path */
664 panel->pathF = WMCreateFrame(panel->optionsF);
665 WMResizeWidget(panel->pathF, width, 150);
666 WMMoveWidget(panel->pathF, 10, 40);
667 WMSetFrameTitle(panel->pathF, _("Path for Menu"));
669 panel->pathT = WMCreateTextField(panel->pathF);
670 WMResizeWidget(panel->pathT, width - 20, 20);
671 WMMoveWidget(panel->pathT, 10, 20);
673 WMAddNotificationObserver(dataChanged, panel,
674 WMTextDidChangeNotification,
675 panel->pathT);
677 label = WMCreateLabel(panel->pathF);
678 WMResizeWidget(label, width - 20, 80);
679 WMMoveWidget(label, 10, 50);
680 WMSetLabelText(label, _("Enter the path for a file containing a menu\n"
681 "or a list of directories with the programs you\n"
682 "want to have listed in the menu. Ex:\n"
683 "~/GNUstep/Library/WindowMaker/menu\n"
684 "or\n"
685 "/usr/X11R6/bin ~/xbin"));
687 WMMapSubwidgets(panel->pathF);
690 /* pipe */
692 panel->pipeF = WMCreateFrame(panel->optionsF);
693 WMResizeWidget(panel->pipeF, width, 100);
694 WMMoveWidget(panel->pipeF, 10, 50);
695 WMSetFrameTitle(panel->pipeF, _("Command"));
697 panel->pipeT = WMCreateTextField(panel->pipeF);
698 WMResizeWidget(panel->pipeT, width - 20, 20);
699 WMMoveWidget(panel->pipeT, 10, 20);
701 WMAddNotificationObserver(dataChanged, panel,
702 WMTextDidChangeNotification,
703 panel->pipeT);
706 label = WMCreateLabel(panel->pipeF);
707 WMResizeWidget(label, width - 20, 40);
708 WMMoveWidget(label, 10, 50);
709 WMSetLabelText(label, _("Enter a command that outputs a menu\n"
710 "definition to stdout when invoked."));
712 WMMapSubwidgets(panel->pipeF);
715 /* directory menu */
717 panel->dcommandF = WMCreateFrame(panel->optionsF);
718 WMResizeWidget(panel->dcommandF, width, 90);
719 WMMoveWidget(panel->dcommandF, 10, 25);
720 WMSetFrameTitle(panel->dcommandF, _("Command to Open Files"));
722 panel->dcommandT = WMCreateTextField(panel->dcommandF);
723 WMResizeWidget(panel->dcommandT, width - 20, 20);
724 WMMoveWidget(panel->dcommandT, 10, 20);
726 WMAddNotificationObserver(dataChanged, panel,
727 WMTextDidChangeNotification,
728 panel->dcommandT);
731 label = WMCreateLabel(panel->dcommandF);
732 WMResizeWidget(label, width - 20, 45);
733 WMMoveWidget(label, 10, 40);
734 WMSetLabelText(label, _("Enter the command you want to use to open the\n"
735 "files in the directories listed below."));
737 WMMapSubwidgets(panel->dcommandF);
740 panel->dpathF = WMCreateFrame(panel->optionsF);
741 WMResizeWidget(panel->dpathF, width, 80);
742 WMMoveWidget(panel->dpathF, 10, 125);
743 WMSetFrameTitle(panel->dpathF, _("Directories with Files"));
745 panel->dpathT = WMCreateTextField(panel->dpathF);
746 WMResizeWidget(panel->dpathT, width - 20, 20);
747 WMMoveWidget(panel->dpathT, 10, 20);
749 WMAddNotificationObserver(dataChanged, panel,
750 WMTextDidChangeNotification,
751 panel->dpathT);
753 panel->dstripB = WMCreateSwitchButton(panel->dpathF);
754 WMResizeWidget(panel->dstripB, width - 20, 20);
755 WMMoveWidget(panel->dstripB, 10, 50);
756 WMSetButtonText(panel->dstripB, _("Strip extensions from file names"));
758 WMSetButtonAction(panel->dstripB, buttonClicked, panel);
760 WMMapSubwidgets(panel->dpathF);
763 /* shortcut */
765 panel->shortF = WMCreateFrame(panel->optionsF);
766 WMResizeWidget(panel->shortF, width, 50);
767 WMMoveWidget(panel->shortF, 10, 160);
768 WMSetFrameTitle(panel->shortF, _("Keyboard Shortcut"));
770 panel->shortT = WMCreateTextField(panel->shortF);
771 WMResizeWidget(panel->shortT, width - 20 - 170, 20);
772 WMMoveWidget(panel->shortT, 10, 20);
774 WMAddNotificationObserver(dataChanged, panel,
775 WMTextDidChangeNotification,
776 panel->shortT);
778 panel->sgrabB = WMCreateCommandButton(panel->shortF);
779 WMResizeWidget(panel->sgrabB, 80, 24);
780 WMMoveWidget(panel->sgrabB, width - 90, 18);
781 WMSetButtonText(panel->sgrabB, _("Capture"));
782 WMSetButtonAction(panel->sgrabB, sgrabClicked, panel);
784 panel->sclearB = WMCreateCommandButton(panel->shortF);
785 WMResizeWidget(panel->sclearB, 80, 24);
786 WMMoveWidget(panel->sclearB, width - 175, 18);
787 WMSetButtonText(panel->sclearB, _("Clear"));
788 WMSetButtonAction(panel->sclearB, sgrabClicked, panel);
790 WMMapSubwidgets(panel->shortF);
792 /* internal command */
794 panel->icommandL = WMCreateList(panel->optionsF);
795 WMResizeWidget(panel->icommandL, width, 80);
796 WMMoveWidget(panel->icommandL, 10, 20);
798 WMSetListAction(panel->icommandL, icommandLClicked, panel);
800 WMAddNotificationObserver(dataChanged, panel,
801 WMListSelectionDidChangeNotification,
802 panel->icommandL);
804 WMInsertListItem(panel->icommandL, 0, _("Arrange Icons"));
805 WMInsertListItem(panel->icommandL, 1, _("Hide All Windows Except For The Focused One"));
806 WMInsertListItem(panel->icommandL, 2, _("Show All Windows"));
808 WMInsertListItem(panel->icommandL, 3, _("Exit Window Maker"));
809 WMInsertListItem(panel->icommandL, 4, _("Exit X Session"));
810 WMInsertListItem(panel->icommandL, 5, _("Restart Window Maker"));
811 WMInsertListItem(panel->icommandL, 6, _("Start Another Window Manager : ("));
813 WMInsertListItem(panel->icommandL, 7, _("Save Current Session"));
814 WMInsertListItem(panel->icommandL, 8, _("Clear Saved Session"));
815 WMInsertListItem(panel->icommandL, 9, _("Refresh Screen"));
816 WMInsertListItem(panel->icommandL, 10, _("Open Info Panel"));
817 WMInsertListItem(panel->icommandL, 11, _("Open Copyright Panel"));
820 panel->paramF = WMCreateFrame(panel->optionsF);
821 WMResizeWidget(panel->paramF, width, 50);
822 WMMoveWidget(panel->paramF, 10, 105);
823 WMSetFrameTitle(panel->paramF, _("Window Manager to Start"));
825 panel->paramT = WMCreateTextField(panel->paramF);
826 WMResizeWidget(panel->paramT, width - 20, 20);
827 WMMoveWidget(panel->paramT, 10, 20);
829 WMAddNotificationObserver(dataChanged, panel,
830 WMTextDidChangeNotification,
831 panel->paramT);
833 WMMapSubwidgets(panel->paramF);
836 panel->quickB = WMCreateSwitchButton(panel->optionsF);
837 WMResizeWidget(panel->quickB, width, 20);
838 WMMoveWidget(panel->quickB, 10, 120);
839 WMSetButtonText(panel->quickB, _("Do not confirm action."));
840 WMSetButtonAction(panel->quickB, buttonClicked, panel);
842 WMRealizeWidget(panel->frame);
843 WMMapSubwidgets(panel->frame);
844 WMMapWidget(panel->frame);
848 int i;
849 for (i = 0; i < 3; i++)
850 WMUnmapWidget(panel->itemPad[i]);
852 changedItemPad(panel->typeP, panel);
855 panel->sections[ExecInfo][0] = panel->commandF;
856 panel->sections[ExecInfo][1] = panel->shortF;
858 panel->sections[CommandInfo][0] = panel->icommandL;
859 panel->sections[CommandInfo][1] = label;
860 panel->sections[CommandInfo][2] = panel->shortF;
862 panel->sections[ExternalInfo][0] = panel->pathF;
864 panel->sections[PipeInfo][0] = panel->pipeF;
866 panel->sections[DirectoryInfo][0] = panel->dpathF;
867 panel->sections[DirectoryInfo][1] = panel->dcommandF;
869 panel->currentType = NoInfo;
871 showData(panel);
877 static void
878 freeItemData(ItemData *data)
880 #define CFREE(d) if (d) free(d)
882 /* TODO */
883 switch (data->type) {
884 case CommandInfo:
885 CFREE(data->param.command.parameter);
886 CFREE(data->param.command.shortcut);
887 break;
889 case ExecInfo:
890 CFREE(data->param.exec.command);
891 CFREE(data->param.exec.shortcut);
892 break;
894 case PipeInfo:
895 CFREE(data->param.pipe.command);
896 break;
898 case ExternalInfo:
899 CFREE(data->param.external.path);
900 break;
902 case DirectoryInfo:
903 CFREE(data->param.directory.command);
904 CFREE(data->param.directory.directory);
905 break;
907 default:
908 break;
911 free(data);
912 #undef CFREE
916 static ItemData*
917 parseCommand(proplist_t item)
919 ItemData *data = NEW(ItemData);
920 proplist_t p;
921 char *command = NULL;
922 char *parameter = NULL;
923 char *shortcut = NULL;
924 int i = 1;
927 p = PLGetArrayElement(item, i++);
928 command = PLGetString(p);
929 if (strcmp(command, "SHORTCUT") == 0) {
930 p = PLGetArrayElement(item, i++);
931 shortcut = PLGetString(p);
932 p = PLGetArrayElement(item, i++);
933 command = PLGetString(p);
935 p = PLGetArrayElement(item, i++);
936 if (p)
937 parameter = PLGetString(p);
939 if (strcmp(command, "EXEC") == 0 || strcmp(command, "SHEXEC") == 0) {
941 data->type = ExecInfo;
943 data->param.exec.command = wstrdup(parameter);
944 if (shortcut)
945 data->param.exec.shortcut = wstrdup(shortcut);
947 } else if (strcmp(command, "OPEN_MENU") == 0) {
948 char *p;
950 * dir menu, menu file
951 * dir WITH
952 * |pipe (TODO: ||pipe)
954 p = parameter;
955 while (isspace(*p) && *p) p++;
956 if (*p == '|') {
957 data->type = PipeInfo;
958 data->param.pipe.command = wtrimspace(p+1);
959 } else {
960 char *s;
962 p = wstrdup(p);
964 s = strstr(p, "WITH");
965 if (s) {
966 char **tokens;
967 char **ctokens;
968 int tokn;
969 int i, j;
971 data->type = DirectoryInfo;
973 *s = '\0';
974 s += 5;
975 while (*s && isspace(*s)) s++;
976 data->param.directory.command = wstrdup(s);
978 wtokensplit(p, &tokens, &tokn);
979 free(p);
981 ctokens = wmalloc(sizeof(char*)*tokn);
983 for (i = 0, j = 0; i < tokn; i++) {
984 if (strcmp(tokens[i], "-noext") == 0) {
985 free(tokens[i]);
986 data->param.directory.stripExt = 1;
987 } else {
988 ctokens[j++] = tokens[i];
991 data->param.directory.directory = wtokenjoin(ctokens, j);
992 free(ctokens);
994 wtokenfree(tokens, tokn);
995 } else {
996 data->type = ExternalInfo;
997 data->param.external.path = p;
1000 } else if (strcmp(command, "WORKSPACE_MENU") == 0) {
1001 data->type = WSMenuInfo;
1002 } else {
1003 int cmd;
1005 if (strcmp(command, "ARRANGE_ICONS") == 0) {
1006 cmd = 0;
1007 } else if (strcmp(command, "HIDE_OTHERS") == 0) {
1008 cmd = 1;
1009 } else if (strcmp(command, "SHOW_ALL") == 0) {
1010 cmd = 2;
1011 } else if (strcmp(command, "EXIT") == 0) {
1012 cmd = 3;
1013 } else if (strcmp(command, "SHUTDOWN") == 0) {
1014 cmd = 4;
1015 } else if (strcmp(command, "RESTART") == 0) {
1016 if (parameter) {
1017 cmd = 6;
1018 } else {
1019 cmd = 5;
1021 } else if (strcmp(command, "SAVE_SESSION") == 0) {
1022 cmd = 7;
1023 } else if (strcmp(command, "CLEAR_SESSION") == 0) {
1024 cmd = 8;
1025 } else if (strcmp(command, "REFRESH") == 0) {
1026 cmd = 9;
1027 } else if (strcmp(command, "INFO_PANEL") == 0) {
1028 cmd = 10;
1029 } else if (strcmp(command, "LEGAL_PANEL") == 0) {
1030 cmd = 11;
1031 } else {
1032 wwarning(_("unknown command '%s' in menu"), command);
1033 goto error;
1036 data->type = CommandInfo;
1038 data->param.command.command = cmd;
1039 if (shortcut)
1040 data->param.command.shortcut = wstrdup(shortcut);
1041 if (parameter)
1042 data->param.command.parameter = wstrdup(parameter);
1045 return data;
1047 error:
1048 free(data);
1050 return NULL;
1056 static void
1057 updateFrameTitle(_Panel *panel, char *title, InfoType type)
1059 if (type != NoInfo) {
1060 char *tmp;
1062 switch (type) {
1063 case ExecInfo:
1064 tmp = wstrappend(title, _(": Execute Program"));
1065 break;
1067 case CommandInfo:
1068 tmp = wstrappend(title, _(": Perform Internal Command"));
1069 break;
1071 case ExternalInfo:
1072 tmp = wstrappend(title, _(": Open a Submenu"));
1073 break;
1075 case PipeInfo:
1076 tmp = wstrappend(title, _(": Program Generated Submenu"));
1077 break;
1079 case DirectoryInfo:
1080 tmp = wstrappend(title, _(": Directory Contents Menu"));
1081 break;
1083 case WSMenuInfo:
1084 tmp = wstrappend(title, _(": Open Workspaces Submenu"));
1085 break;
1087 default:
1088 tmp = NULL;
1089 break;
1091 WMSetFrameTitle(panel->optionsF, tmp);
1092 free(tmp);
1093 } else {
1094 WMSetFrameTitle(panel->optionsF, NULL);
1100 static void
1101 changeInfoType(_Panel *panel, char *title, InfoType type)
1103 WMWidget **w;
1105 if (panel->currentType != type) {
1107 if (panel->currentType != NoInfo) {
1108 w = panel->sections[panel->currentType];
1110 while (*w) {
1111 WMUnmapWidget(*w);
1112 w++;
1114 WMUnmapWidget(panel->paramF);
1115 WMUnmapWidget(panel->quickB);
1118 if (type != NoInfo) {
1119 w = panel->sections[type];
1121 while (*w) {
1122 WMMapWidget(*w);
1123 w++;
1128 updateFrameTitle(panel, title, type);
1130 panel->currentType = type;
1136 static void
1137 updateMenuItem(_Panel *panel, WEditMenuItem *item, WMWidget *changedWidget)
1139 ItemData *data = WGetEditMenuItemData(item);
1141 assert(data != NULL);
1143 #define REPLACE(v, d) if (v) free(v); v = d
1145 switch (data->type) {
1146 case ExecInfo:
1147 if (changedWidget == panel->commandT) {
1148 REPLACE(data->param.exec.command,
1149 WMGetTextFieldText(panel->commandT));
1151 if (changedWidget == panel->shortT) {
1152 REPLACE(data->param.exec.shortcut,
1153 WMGetTextFieldText(panel->shortT));
1155 break;
1157 case CommandInfo:
1158 if (changedWidget == panel->icommandL) {
1159 data->param.command.command =
1160 WMGetListSelectedItemRow(panel->icommandL);
1162 switch (data->param.command.command) {
1163 case 3:
1164 case 4:
1165 if (changedWidget == panel->quickB) {
1166 REPLACE(data->param.command.parameter,
1167 WMGetButtonSelected(panel->quickB)
1168 ? wstrdup("QUICK") : NULL);
1170 break;
1172 case 6:
1173 if (changedWidget == panel->paramT) {
1174 REPLACE(data->param.command.parameter,
1175 WMGetTextFieldText(panel->paramT));
1177 break;
1179 if (changedWidget == panel->shortT) {
1180 REPLACE(data->param.command.shortcut,
1181 WMGetTextFieldText(panel->shortT));
1185 break;
1187 case PipeInfo:
1188 if (changedWidget == panel->pipeT) {
1189 REPLACE(data->param.pipe.command,
1190 WMGetTextFieldText(panel->pipeT));
1192 break;
1194 case ExternalInfo:
1195 if (changedWidget == panel->pathT) {
1196 REPLACE(data->param.external.path,
1197 WMGetTextFieldText(panel->pathT));
1199 break;
1201 case DirectoryInfo:
1202 if (changedWidget == panel->dpathT) {
1203 REPLACE(data->param.directory.directory,
1204 WMGetTextFieldText(panel->dpathT));
1206 if (changedWidget == panel->dcommandT) {
1207 REPLACE(data->param.directory.command,
1208 WMGetTextFieldText(panel->dcommandT));
1210 if (changedWidget == panel->dstripB) {
1211 data->param.directory.stripExt =
1212 WMGetButtonSelected(panel->dstripB);
1214 break;
1216 default:
1217 assert(0);
1218 break;
1221 #undef REPLACE
1226 static void
1227 menuItemCloned(WEditMenuDelegate *delegate, WEditMenu *menu,
1228 WEditMenuItem *origItem, WEditMenuItem *newItem)
1230 ItemData *data = WGetEditMenuItemData(origItem);
1231 ItemData *newData;
1233 if (!data)
1234 return;
1236 #define DUP(s) (s) ? wstrdup(s) : NULL
1238 newData = NEW(ItemData);
1240 newData->type = data->type;
1242 switch (data->type) {
1243 case ExecInfo:
1244 newData->param.exec.command = DUP(data->param.exec.command);
1245 newData->param.exec.shortcut = DUP(data->param.exec.shortcut);
1246 break;
1248 case CommandInfo:
1249 newData->param.command.command = data->param.command.command;
1250 newData->param.command.parameter = DUP(data->param.command.parameter);
1251 newData->param.command.shortcut = DUP(data->param.command.shortcut);
1252 break;
1254 case PipeInfo:
1255 newData->param.pipe.command = DUP(data->param.pipe.command);
1256 break;
1258 case ExternalInfo:
1259 newData->param.external.path = DUP(data->param.external.path);
1260 break;
1262 case DirectoryInfo:
1263 newData->param.directory.directory = DUP(data->param.directory.directory);
1264 newData->param.directory.command = DUP(data->param.directory.command);
1265 newData->param.directory.stripExt = data->param.directory.stripExt;
1266 break;
1268 default:
1269 break;
1272 #undef DUP
1274 WSetEditMenuItemData(newItem, newData, (WMCallback*)freeItemData);
1280 static void menuItemEdited(struct WEditMenuDelegate *delegate, WEditMenu *menu,
1281 WEditMenuItem *item)
1283 _Panel *panel = (_Panel*)delegate->data;
1285 updateFrameTitle(panel, WGetEditMenuItemTitle(item), panel->currentType);
1292 static Bool shouldRemoveItem(struct WEditMenuDelegate *delegate,
1293 WEditMenu *menu, WEditMenuItem *item)
1295 _Panel *panel = (_Panel*)delegate->data;
1297 if (panel->dontAsk)
1298 return True;
1300 if (WGetEditMenuSubmenu(menu, item)) {
1301 int res;
1303 res = WMRunAlertPanel(WMWidgetScreen(menu), NULL,
1304 _("Remove Submenu"),
1305 _("Removing this item will destroy all items inside\n"
1306 "the submenu. Do you really want to do that?"),
1307 _("Yes"), _("No"),
1308 _("Yes, don't ask again."));
1309 switch (res) {
1310 case WAPRDefault:
1311 return True;
1312 case WAPRAlternate:
1313 return False;
1314 case WAPROther:
1315 panel->dontAsk = True;
1316 return True;
1319 return True;
1323 static void
1324 menuItemDeselected(WEditMenuDelegate *delegate, WEditMenu *menu,
1325 WEditMenuItem *item)
1327 _Panel *panel = (_Panel*)delegate->data;
1329 changeInfoType(panel, NULL, NoInfo);
1333 static void
1334 menuItemSelected(WEditMenuDelegate *delegate, WEditMenu *menu,
1335 WEditMenuItem *item)
1337 ItemData *data = WGetEditMenuItemData(item);
1338 _Panel *panel = (_Panel*)delegate->data;
1340 panel->currentItem = item;
1342 if (data) {
1343 changeInfoType(panel, WGetEditMenuItemTitle(item), data->type);
1345 switch (data->type) {
1346 case NoInfo:
1347 break;
1349 case ExecInfo:
1350 WMSetTextFieldText(panel->commandT, data->param.exec.command);
1351 WMSetTextFieldText(panel->shortT, data->param.exec.shortcut);
1352 break;
1354 case CommandInfo:
1355 WMSelectListItem(panel->icommandL,
1356 data->param.command.command);
1357 WMSetListPosition(panel->icommandL,
1358 data->param.command.command - 2);
1359 WMSetTextFieldText(panel->shortT, data->param.command.shortcut);
1361 switch (data->param.command.command) {
1362 case 3:
1363 case 4:
1364 WMSetButtonSelected(panel->quickB,
1365 data->param.command.parameter!=NULL);
1366 break;
1367 case 6:
1368 WMSetTextFieldText(panel->paramT,
1369 data->param.command.parameter);
1370 break;
1373 icommandLClicked(panel->icommandL, panel);
1374 break;
1376 case PipeInfo:
1377 WMSetTextFieldText(panel->pipeT, data->param.pipe.command);
1378 break;
1380 case ExternalInfo:
1381 WMSetTextFieldText(panel->pathT, data->param.external.path);
1382 break;
1384 case DirectoryInfo:
1385 WMSetTextFieldText(panel->dpathT, data->param.directory.directory);
1386 WMSetTextFieldText(panel->dcommandT, data->param.directory.command);
1387 WMSetButtonSelected(panel->dstripB, data->param.directory.stripExt);
1388 break;
1390 case WSMenuInfo:
1391 break;
1393 default:
1394 break;
1401 static WEditMenu*
1402 buildSubmenu(_Panel *panel, proplist_t pl)
1404 WMScreen *scr = WMWidgetScreen(panel->win);
1405 WEditMenu *menu;
1406 WEditMenuItem *item;
1407 char *title;
1408 proplist_t tp, bp;
1409 int i;
1411 tp = PLGetArrayElement(pl, 0);
1412 title = PLGetString(tp);
1414 menu = WCreateEditMenu(scr, title);
1416 for (i = 1; i < PLGetNumberOfElements(pl); i++) {
1417 proplist_t pi;
1419 pi = PLGetArrayElement(pl, i);
1421 tp = PLGetArrayElement(pi, 0);
1422 bp = PLGetArrayElement(pi, 1);
1424 title = PLGetString(tp);
1426 if (PLIsArray(bp)) { /* it's a submenu */
1427 WEditMenu *submenu;
1429 submenu = buildSubmenu(panel, pi);
1431 item = WAddMenuItemWithTitle(menu, title);
1433 WSetEditMenuSubmenu(menu, item, submenu);
1434 } else {
1435 ItemData *data;
1437 item = WAddMenuItemWithTitle(menu, title);
1439 data = parseCommand(pi);
1441 if (panel->markerPix[data->type])
1442 WSetEditMenuItemImage(item, panel->markerPix[data->type]);
1443 WSetEditMenuItemData(item, data, (WMCallback*)freeItemData);
1447 WSetEditMenuAcceptsDrop(menu, True);
1448 WSetEditMenuDelegate(menu, &menuDelegate);
1450 WMRealizeWidget(menu);
1452 return menu;
1457 static void
1458 buildMenuFromPL(_Panel *panel, proplist_t pl)
1460 panel->menu = buildSubmenu(panel, pl);
1461 WMMapWidget(panel->menu);
1466 static proplist_t
1467 getDefaultMenu(_Panel *panel)
1469 proplist_t menu, pmenu;
1470 char *menuPath, *gspath;
1472 gspath = wusergnusteppath();
1474 menuPath = wmalloc(strlen(gspath)+128);
1475 /* if there is a localized plmenu for the tongue put it's filename here */
1476 sprintf(menuPath, _("%s/Library/WindowMaker/plmenu"), gspath);
1478 menu = PLGetProplistWithPath(menuPath);
1479 if (!menu) {
1480 wwarning("%s:could not read property list menu", menuPath);
1482 if (strcmp("%s/Library/WindowMaker/plmenu",
1483 _("%s/Library/WindowMaker/plmenu"))!=0) {
1485 sprintf(menuPath, "%s/Library/WindowMaker/plmenu", gspath);
1486 menu = PLGetProplistWithPath(menuPath);
1487 wwarning("%s:could not read property list menu", menuPath);
1489 if (!menu) {
1490 char buffer[512];
1492 sprintf(buffer, _("Could not open default menu from '%s'"),
1493 menuPath);
1494 WMRunAlertPanel(WMWidgetScreen(panel->win), panel->win,
1495 _("Error"), buffer, _("OK"), NULL, NULL);
1499 free(menuPath);
1501 if (menu) {
1502 pmenu = menu;
1503 } else {
1504 pmenu = NULL;
1507 return pmenu;
1511 static void
1512 showData(_Panel *panel)
1514 char *gspath;
1515 char *menuPath;
1516 proplist_t pmenu;
1518 gspath = wusergnusteppath();
1520 menuPath = wmalloc(strlen(gspath)+32);
1521 strcpy(menuPath, gspath);
1522 strcat(menuPath, "/Defaults/WMRootMenu");
1524 pmenu = PLGetProplistWithPath(menuPath);
1526 if (!pmenu || !PLIsArray(pmenu)) {
1527 int res;
1529 res = WMRunAlertPanel(WMWidgetScreen(panel->win), panel->win,
1530 _("Warning"),
1531 _("The menu file format currently in use is not supported\n"
1532 "by this tool. Do you want to discard the current menu\n"
1533 "to use this tool?"),
1534 _("Yes, Discard and Update"),
1535 _("No, Keep Current Menu"), NULL);
1537 if (res == WAPRDefault) {
1538 pmenu = getDefaultMenu(panel);
1540 if (!pmenu) {
1541 pmenu = PLMakeArrayFromElements(PLMakeString("Applications"),
1542 NULL);
1544 } else {
1545 panel->dontSave = True;
1546 return;
1550 panel->menuPath = menuPath;
1552 buildMenuFromPL(panel, pmenu);
1554 PLRelease(pmenu);
1558 static Bool
1559 notblank(char *s)
1561 if (s) {
1562 while (*s++) {
1563 if (!isspace(*s))
1564 return True;
1567 return False;
1571 static proplist_t
1572 processData(char *title, ItemData *data)
1574 proplist_t item;
1575 char *s1;
1576 static char *pscut = NULL;
1577 static char *pomenu = NULL;
1578 int i;
1580 if (!pscut) {
1581 pscut = PLMakeString("SHORTCUT");
1582 pomenu = PLMakeString("OPEN_MENU");
1585 item = PLMakeArrayFromElements(PLMakeString(title), NULL);
1588 switch (data->type) {
1589 case ExecInfo:
1590 #if 1
1591 if (strpbrk(data->param.exec.command, "&$*|><?`")) {
1592 s1 = "SHEXEC";
1593 } else {
1594 s1 = "EXEC";
1596 #else
1597 s1 = "SHEXEC";
1598 #endif
1600 if (notblank(data->param.exec.shortcut)) {
1601 PLAppendArrayElement(item, pscut);
1602 PLAppendArrayElement(item,
1603 PLMakeString(data->param.exec.shortcut));
1606 PLAppendArrayElement(item, PLMakeString(s1));
1607 PLAppendArrayElement(item, PLMakeString(data->param.exec.command));
1608 break;
1610 case CommandInfo:
1611 if (notblank(data->param.command.shortcut)) {
1612 PLAppendArrayElement(item, pscut);
1613 PLAppendArrayElement(item,
1614 PLMakeString(data->param.command.shortcut));
1617 i = data->param.command.command;
1619 PLAppendArrayElement(item, PLMakeString(commandNames[i]));
1621 switch (i) {
1622 case 3:
1623 case 4:
1624 if (data->param.command.parameter)
1625 PLAppendArrayElement(item,
1626 PLMakeString(data->param.command.parameter));
1627 break;
1629 case 7: /* restart */
1630 if (data->param.command.parameter)
1631 PLAppendArrayElement(item,
1632 PLMakeString(data->param.command.parameter));
1633 break;
1636 break;
1638 case PipeInfo:
1639 PLAppendArrayElement(item, pomenu);
1640 s1 = wstrappend("| ", data->param.pipe.command);
1641 PLAppendArrayElement(item, PLMakeString(s1));
1642 free(s1);
1643 break;
1645 case ExternalInfo:
1646 PLAppendArrayElement(item, pomenu);
1647 PLAppendArrayElement(item, PLMakeString(data->param.external.path));
1648 break;
1650 case DirectoryInfo:
1652 int l;
1653 char *tmp;
1655 l = strlen(data->param.directory.directory);
1656 l += strlen(data->param.directory.command);
1657 l += 32;
1659 PLAppendArrayElement(item, pomenu);
1661 tmp = wmalloc(l);
1662 sprintf(tmp, "%s%s WITH %s",
1663 data->param.directory.stripExt ? "-noext " : "",
1664 data->param.directory.directory,
1665 data->param.directory.command);
1667 PLAppendArrayElement(item, PLMakeString(tmp));
1668 free(tmp);
1670 break;
1672 case WSMenuInfo:
1673 PLAppendArrayElement(item, PLMakeString("WORKSPACE_MENU"));
1674 break;
1676 default:
1677 assert(0);
1678 break;
1681 return item;
1685 static proplist_t
1686 processSubmenu(WEditMenu *menu)
1688 WEditMenuItem *item;
1689 proplist_t pmenu;
1690 proplist_t pl;
1691 char *s;
1692 int i;
1695 s = WGetEditMenuTitle(menu);
1696 pl = PLMakeString(s);
1698 pmenu = PLMakeArrayFromElements(pl, NULL);
1700 i = 0;
1701 while ((item = WGetEditMenuItem(menu, i++))) {
1702 WEditMenu *submenu;
1704 s = WGetEditMenuItemTitle(item);
1706 submenu = WGetEditMenuSubmenu(menu, item);
1707 if (submenu) {
1708 pl = processSubmenu(submenu);
1709 } else {
1710 pl = processData(s, WGetEditMenuItemData(item));
1713 PLAppendArrayElement(pmenu, pl);
1716 return pmenu;
1721 static proplist_t
1722 buildPLFromMenu(_Panel *panel)
1724 proplist_t menu;
1726 menu = processSubmenu(panel->menu);
1728 return menu;
1734 static void
1735 storeData(_Panel *panel)
1737 proplist_t menu;
1739 if (panel->dontSave)
1740 return;
1742 menu = buildPLFromMenu(panel);
1744 PLSetFilename(menu, PLMakeString(panel->menuPath));
1746 PLSave(menu, YES);
1748 PLRelease(menu);
1752 Panel*
1753 InitMenu(WMScreen *scr, WMWindow *win)
1755 _Panel *panel;
1757 panel = wmalloc(sizeof(_Panel));
1758 memset(panel, 0, sizeof(_Panel));
1760 panel->sectionName = _("Applications Menu Definition");
1762 panel->description = _("Edit the menu for launching applications.");
1764 panel->win = win;
1766 panel->callbacks.createWidgets = createPanel;
1767 panel->callbacks.updateDomain = storeData;
1769 AddSection(panel, ICON_FILE);
1771 return panel;