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.
27 #include <X11/keysym.h>
28 #include <X11/cursorfont.h>
45 #define MAX_SECTION_SIZE 4
47 typedef struct _Panel
{
53 CallbackRec callbacks
;
62 WMPixmap
*markerPix
[LastInfo
];
75 WMTextField
*commandT
; /* command to run */
77 WMButton
*xtermC
; /* inside xterm? */
88 WMButton
*plpipeCacheB
;
94 WMTextField
*dcommandT
;
110 Bool dontAsk
; /* whether to comfirm submenu remove */
115 /* about the currently selected item */
116 WEditMenuItem
*currentItem
;
117 InfoType currentType
;
118 WMWidget
*sections
[LastInfo
][MAX_SECTION_SIZE
];
148 static char *commandNames
[] = {
163 #define ICON_FILE "menus"
165 static void showData(_Panel
* panel
);
167 static void updateMenuItem(_Panel
* panel
, WEditMenuItem
* item
, WMWidget
* changedWidget
);
169 static void menuItemSelected(struct WEditMenuDelegate
*delegate
, WEditMenu
* menu
, WEditMenuItem
* item
);
171 static void menuItemDeselected(struct WEditMenuDelegate
*delegate
, WEditMenu
* menu
, WEditMenuItem
* item
);
173 static void menuItemCloned(struct WEditMenuDelegate
*delegate
, WEditMenu
* menu
,
174 WEditMenuItem
* origItem
, WEditMenuItem
* newItem
);
176 static void menuItemEdited(struct WEditMenuDelegate
*delegate
, WEditMenu
* menu
, WEditMenuItem
* item
);
178 static Bool
shouldRemoveItem(struct WEditMenuDelegate
*delegate
, WEditMenu
* menu
, WEditMenuItem
* item
);
180 static void freeItemData(ItemData
* data
);
183 static WEditMenuDelegate menuDelegate
= {
192 static void dataChanged(void *self
, WMNotification
* notif
)
194 _Panel
*panel
= (_Panel
*) self
;
195 WEditMenuItem
*item
= panel
->currentItem
;
196 WMWidget
*w
= (WMWidget
*) WMGetNotificationObject(notif
);
198 updateMenuItem(panel
, item
, w
);
201 static void buttonClicked(WMWidget
* w
, void *data
)
203 _Panel
*panel
= (_Panel
*) data
;
204 WEditMenuItem
*item
= panel
->currentItem
;
206 updateMenuItem(panel
, item
, w
);
209 static void icommandLClicked(WMWidget
* w
, void *data
)
211 _Panel
*panel
= (_Panel
*) data
;
214 cmd
= WMGetListSelectedItemRow(w
);
215 if (cmd
== 3 || cmd
== 4) {
216 WMMapWidget(panel
->quickB
);
218 WMUnmapWidget(panel
->quickB
);
221 WMMapWidget(panel
->paramF
);
223 WMUnmapWidget(panel
->paramF
);
227 static void browseForFile(WMWidget
* self
, void *clientData
)
229 _Panel
*panel
= (_Panel
*) clientData
;
230 WMFilePanel
*filePanel
;
231 char *text
, *oldprog
, *newprog
;
233 filePanel
= WMGetOpenPanel(WMWidgetScreen(self
));
234 text
= WMGetTextFieldText(panel
->commandT
);
236 oldprog
= wtrimspace(text
);
239 if (oldprog
[0] == 0 || oldprog
[0] != '/') {
241 oldprog
= wstrdup("/");
244 while (*ptr
&& !isspace(*ptr
))
249 WMSetFilePanelCanChooseDirectories(filePanel
, False
);
251 if (WMRunModalFilePanelForDirectory(filePanel
, panel
->parent
, oldprog
, _("Select Program"), NULL
) == True
) {
252 newprog
= WMGetFilePanelFileName(filePanel
);
253 WMSetTextFieldText(panel
->commandT
, newprog
);
254 updateMenuItem(panel
, panel
->currentItem
, panel
->commandT
);
261 static void sgrabClicked(WMWidget
* w
, void *data
)
263 _Panel
*panel
= (_Panel
*) data
;
264 Display
*dpy
= WMScreenDisplay(WMWidgetScreen(panel
->parent
));
267 if (w
== panel
->sclearB
) {
268 WMSetTextFieldText(panel
->shortT
, "");
269 updateMenuItem(panel
, panel
->currentItem
, panel
->shortT
);
273 if (!panel
->capturing
) {
274 panel
->capturing
= 1;
275 WMSetButtonText(w
, _("Cancel"));
276 XGrabKeyboard(dpy
, WMWidgetXID(panel
->parent
), True
, GrabModeAsync
, GrabModeAsync
, CurrentTime
);
277 shortcut
= capture_shortcut(dpy
, &panel
->capturing
, 0);
279 WMSetTextFieldText(panel
->shortT
, shortcut
);
280 updateMenuItem(panel
, panel
->currentItem
, panel
->shortT
);
284 panel
->capturing
= 0;
285 WMSetButtonText(w
, _("Capture"));
286 XUngrabKeyboard(dpy
, CurrentTime
);
289 static void changedItemPad(WMWidget
* w
, void *data
)
291 _Panel
*panel
= (_Panel
*) data
;
292 int padn
= WMGetPopUpButtonSelectedItem(w
);
296 WMUnmapWidget(panel
->itemPad
[panel
->currentPad
]);
297 WMMapWidget(panel
->itemPad
[padn
]);
299 panel
->currentPad
= padn
;
302 static WEditMenu
*putNewSubmenu(WEditMenu
* menu
, const char *title
)
307 item
= WAddMenuItemWithTitle(menu
, title
);
309 tmp
= WCreateEditMenu(WMWidgetScreen(menu
), title
);
310 WSetEditMenuAcceptsDrop(tmp
, True
);
311 WSetEditMenuDelegate(tmp
, &menuDelegate
);
312 WSetEditMenuSubmenu(menu
, item
, tmp
);
317 static ItemData
*putNewItem(_Panel
* panel
, WEditMenu
* menu
, int type
, const char *title
)
322 item
= WAddMenuItemWithTitle(menu
, title
);
324 data
= wmalloc(sizeof(ItemData
));
326 WSetEditMenuItemData(item
, data
, (WMCallback
*) freeItemData
);
327 WSetEditMenuItemImage(item
, panel
->markerPix
[type
]);
332 static WEditMenu
*makeFactoryMenu(WMWidget
* parent
, int width
)
336 pad
= WCreateEditMenuPad(parent
);
337 WMResizeWidget(pad
, width
, 10);
338 WSetEditMenuMinSize(pad
, wmksize(width
, 0));
339 WSetEditMenuMaxSize(pad
, wmksize(width
, 0));
340 WSetEditMenuSelectable(pad
, False
);
341 WSetEditMenuEditable(pad
, False
);
342 WSetEditMenuIsFactory(pad
, True
);
343 WSetEditMenuDelegate(pad
, &menuDelegate
);
348 static void createPanel(_Panel
* p
)
350 _Panel
*panel
= (_Panel
*) p
;
351 WMScreen
*scr
= WMWidgetScreen(panel
->parent
);
352 WMColor
*black
= WMBlackColor(scr
);
353 WMColor
*white
= WMWhiteColor(scr
);
354 WMColor
*gray
= WMGrayColor(scr
);
355 WMFont
*bold
= WMBoldSystemFontOfSize(scr
, 12);
356 WMFont
*font
= WMSystemFontOfSize(scr
, 12);
360 menuDelegate
.data
= panel
;
362 panel
->boldFont
= bold
;
363 panel
->normalFont
= font
;
365 panel
->black
= black
;
366 panel
->white
= white
;
371 Display
*dpy
= WMScreenDisplay(scr
);
375 pixm
= WMCreatePixmap(scr
, 7, 7, WMScreenDepth(scr
), True
);
377 pix
= WMGetPixmapXID(pixm
);
379 XDrawLine(dpy
, pix
, WMColorGC(black
), 0, 3, 6, 3);
380 XDrawLine(dpy
, pix
, WMColorGC(black
), 3, 0, 3, 6);
382 XDrawLine(dpy, pix, WMColorGC(black), 1, 0, 3, 3);
383 XDrawLine(dpy, pix, WMColorGC(black), 1, 6, 3, 3);
384 XDrawLine(dpy, pix, WMColorGC(black), 0, 0, 0, 6);
387 pix
= WMGetPixmapMaskXID(pixm
);
389 gc
= XCreateGC(dpy
, pix
, 0, NULL
);
391 XSetForeground(dpy
, gc
, 0);
392 XFillRectangle(dpy
, pix
, gc
, 0, 0, 7, 7);
394 XSetForeground(dpy
, gc
, 1);
395 XDrawLine(dpy
, pix
, gc
, 0, 3, 6, 3);
396 XDrawLine(dpy
, pix
, gc
, 3, 0, 3, 6);
398 panel
->markerPix
[ExternalInfo
] = pixm
;
399 panel
->markerPix
[PipeInfo
] = pixm
;
400 panel
->markerPix
[PLPipeInfo
] = pixm
;
401 panel
->markerPix
[DirectoryInfo
] = pixm
;
402 panel
->markerPix
[WSMenuInfo
] = pixm
;
403 panel
->markerPix
[WWindowListInfo
] = pixm
;
408 panel
->box
= WMCreateBox(panel
->parent
);
409 WMSetViewExpandsToParent(WMWidgetView(panel
->box
), 2, 2, 2, 2);
411 panel
->typeP
= WMCreatePopUpButton(panel
->box
);
412 WMResizeWidget(panel
->typeP
, 150, 20);
413 WMMoveWidget(panel
->typeP
, 10, 10);
415 WMAddPopUpButtonItem(panel
->typeP
, _("New Items"));
416 WMAddPopUpButtonItem(panel
->typeP
, _("Sample Commands"));
417 WMAddPopUpButtonItem(panel
->typeP
, _("Sample Submenus"));
419 WMSetPopUpButtonAction(panel
->typeP
, changedItemPad
, panel
);
421 WMSetPopUpButtonSelectedItem(panel
->typeP
, 0);
426 pad
= makeFactoryMenu(panel
->box
, 150);
427 WMMoveWidget(pad
, 10, 40);
429 putNewItem(panel
, pad
, ExecInfo
, _("Run Program"));
430 putNewItem(panel
, pad
, CommandInfo
, _("Internal Command"));
431 putNewSubmenu(pad
, _("Submenu"));
432 putNewItem(panel
, pad
, ExternalInfo
, _("External Submenu"));
433 putNewItem(panel
, pad
, PipeInfo
, _("Generated Submenu"));
434 putNewItem(panel
, pad
, PLPipeInfo
, _("Generated PL Menu"));
435 putNewItem(panel
, pad
, DirectoryInfo
, _("Directory Contents"));
436 putNewItem(panel
, pad
, WSMenuInfo
, _("Workspace Menu"));
437 putNewItem(panel
, pad
, WWindowListInfo
, _("Window List Menu"));
439 panel
->itemPad
[0] = pad
;
447 sview
= WMCreateScrollView(panel
->box
);
448 WMResizeWidget(sview
, 150, 180);
449 WMMoveWidget(sview
, 10, 40);
450 WMSetScrollViewHasVerticalScroller(sview
, True
);
452 pad
= makeFactoryMenu(panel
->box
, 130);
454 WMSetScrollViewContentView(sview
, WMWidgetView(pad
));
456 data
= putNewItem(panel
, pad
, ExecInfo
, _("XTerm"));
457 data
->param
.exec
.command
= "xterm -sb -sl 2000 -bg black -fg white";
459 data
= putNewItem(panel
, pad
, ExecInfo
, _("rxvt"));
460 data
->param
.exec
.command
= "rxvt";
462 data
= putNewItem(panel
, pad
, ExecInfo
, _("ETerm"));
463 data
->param
.exec
.command
= "eterm";
465 data
= putNewItem(panel
, pad
, ExecInfo
, _("Run..."));
466 data
->param
.exec
.command
= _("%A(Run,Type command to run)");
468 data
= putNewItem(panel
, pad
, ExecInfo
, _("Firefox"));
469 data
->param
.exec
.command
= "firefox";
471 data
= putNewItem(panel
, pad
, ExecInfo
, _("gimp"));
472 data
->param
.exec
.command
= "gimp";
474 data
= putNewItem(panel
, pad
, ExecInfo
, _("epic"));
475 data
->param
.exec
.command
= "xterm -e epic";
477 data
= putNewItem(panel
, pad
, ExecInfo
, _("ee"));
478 data
->param
.exec
.command
= "ee";
480 data
= putNewItem(panel
, pad
, ExecInfo
, _("xv"));
481 data
->param
.exec
.command
= "xv";
483 data
= putNewItem(panel
, pad
, ExecInfo
, _("Evince"));
484 data
->param
.exec
.command
= "evince";
486 data
= putNewItem(panel
, pad
, ExecInfo
, _("ghostview"));
487 data
->param
.exec
.command
= "gv";
489 data
= putNewItem(panel
, pad
, CommandInfo
, _("Exit Window Maker"));
490 data
->param
.command
.command
= 3;
494 panel
->itemPad
[1] = sview
;
498 WEditMenu
*pad
, *smenu
;
502 sview
= WMCreateScrollView(panel
->box
);
503 WMResizeWidget(sview
, 150, 180);
504 WMMoveWidget(sview
, 10, 40);
505 WMSetScrollViewHasVerticalScroller(sview
, True
);
507 pad
= makeFactoryMenu(panel
->box
, 130);
509 WMSetScrollViewContentView(sview
, WMWidgetView(pad
));
511 data
= putNewItem(panel
, pad
, ExternalInfo
, _("Debian Menu"));
512 data
->param
.pipe
.command
= "/etc/" GSUSER_SUBDIR
"/" DEFAULTS_SUBDIR
"/menu.hook";
514 data
= putNewItem(panel
, pad
, PipeInfo
, _("RedHat Menu"));
515 data
->param
.pipe
.command
= "wmconfig --output wmaker";
517 data
= putNewItem(panel
, pad
, PipeInfo
, _("Menu Conectiva"));
518 data
->param
.pipe
.command
= "wmconfig --output wmaker";
520 data
= putNewItem(panel
, pad
, DirectoryInfo
, _("Themes"));
521 data
->param
.directory
.command
= "setstyle";
522 data
->param
.directory
.directory
=
523 "/usr/share/" PACKAGE_TARNAME
"/Themes"
524 " /usr/local/share/" PACKAGE_TARNAME
"/Themes"
525 " $HOME/" GSUSER_SUBDIR
"/" USERDATA_SUBDIR
"/" PACKAGE_TARNAME
"/Themes";
526 data
->param
.directory
.stripExt
= 1;
528 data
= putNewItem(panel
, pad
, DirectoryInfo
, _("Bg Images (scale)"));
529 data
->param
.directory
.command
= "wmsetbg -u -s";
530 data
->param
.directory
.directory
=
531 "/opt/kde2/share/wallpapers"
532 " /usr/share/" PACKAGE_TARNAME
"/Backgrounds"
533 " $HOME/" GSUSER_SUBDIR
"/" USERDATA_SUBDIR
"/" PACKAGE_TARNAME
"/Backgrounds";
534 data
->param
.directory
.stripExt
= 1;
536 data
= putNewItem(panel
, pad
, DirectoryInfo
, _("Bg Images (tile)"));
537 data
->param
.directory
.command
= "wmsetbg -u -t";
538 data
->param
.directory
.directory
=
539 "/opt/kde2/share/wallpapers"
540 " /usr/share/" PACKAGE_TARNAME
"/Backgrounds"
541 " $HOME/" GSUSER_SUBDIR
"/" USERDATA_SUBDIR
"/" PACKAGE_TARNAME
"/Backgrounds";
542 data
->param
.directory
.stripExt
= 1;
544 smenu
= putNewSubmenu(pad
, _("Assorted XTerms"));
546 data
= putNewItem(panel
, smenu
, ExecInfo
, _("XTerm Yellow on Blue"));
547 data
->param
.exec
.command
= "xterm -sb -sl 2000 -bg midnightblue -fg yellow";
549 data
= putNewItem(panel
, smenu
, ExecInfo
, _("XTerm White on Black"));
550 data
->param
.exec
.command
= "xterm -sb -sl 2000 -bg black -fg white";
552 data
= putNewItem(panel
, smenu
, ExecInfo
, _("XTerm Black on White"));
553 data
->param
.exec
.command
= "xterm -sb -sl 2000 -bg white -fg black";
555 data
= putNewItem(panel
, smenu
, ExecInfo
, _("XTerm Black on Beige"));
556 data
->param
.exec
.command
= "xterm -sb -sl 2000 -bg '#bbbb99' -fg black";
558 data
= putNewItem(panel
, smenu
, ExecInfo
, _("XTerm White on Green"));
559 data
->param
.exec
.command
= "xterm -sb -sl 2000 -bg '#228822' -fg white";
561 data
= putNewItem(panel
, smenu
, ExecInfo
, _("XTerm White on Olive"));
562 data
->param
.exec
.command
= "xterm -sb -sl 2000 -bg '#335533' -fg white";
564 data
= putNewItem(panel
, smenu
, ExecInfo
, _("XTerm Blue on Blue"));
565 data
->param
.exec
.command
= "xterm -sb -sl 2000 -bg '#112244' -fg '#88aabb'";
567 data
= putNewItem(panel
, smenu
, ExecInfo
, _("XTerm BIG FONTS"));
568 data
->param
.exec
.command
= "xterm -sb -sl 2000 -bg black -fg white -fn 10x20";
572 panel
->itemPad
[2] = sview
;
575 width
= FRAME_WIDTH
- 20 - 150 - 10 - 2;
577 panel
->optionsF
= WMCreateFrame(panel
->box
);
578 WMResizeWidget(panel
->optionsF
, width
, FRAME_HEIGHT
- 15);
579 WMMoveWidget(panel
->optionsF
, 10 + 150 + 10, 5);
585 panel
->commandF
= WMCreateFrame(panel
->optionsF
);
586 WMResizeWidget(panel
->commandF
, width
, 50);
587 WMMoveWidget(panel
->commandF
, 10, 20);
588 WMSetFrameTitle(panel
->commandF
, _("Program to Run"));
589 WMSetFrameTitlePosition(panel
->commandF
, WTPAtTop
);
591 panel
->commandT
= WMCreateTextField(panel
->commandF
);
592 WMResizeWidget(panel
->commandT
, width
- 95, 20);
593 WMMoveWidget(panel
->commandT
, 10, 20);
595 panel
->browseB
= WMCreateCommandButton(panel
->commandF
);
596 WMResizeWidget(panel
->browseB
, 70, 24);
597 WMMoveWidget(panel
->browseB
, width
- 80, 18);
598 WMSetButtonText(panel
->browseB
, _("Browse"));
599 WMSetButtonAction(panel
->browseB
, browseForFile
, panel
);
601 WMAddNotificationObserver(dataChanged
, panel
, WMTextDidChangeNotification
, panel
->commandT
);
604 panel
->xtermC
= WMCreateSwitchButton(panel
->commandF
);
605 WMResizeWidget(panel
->xtermC
, width
- 20, 20);
606 WMMoveWidget(panel
->xtermC
, 10, 50);
607 WMSetButtonText(panel
->xtermC
, _("Run the program inside a Xterm"));
609 WMMapSubwidgets(panel
->commandF
);
613 panel
->pathF
= WMCreateFrame(panel
->optionsF
);
614 WMResizeWidget(panel
->pathF
, width
, 150);
615 WMMoveWidget(panel
->pathF
, 10, 40);
616 WMSetFrameTitle(panel
->pathF
, _("Path for Menu"));
618 panel
->pathT
= WMCreateTextField(panel
->pathF
);
619 WMResizeWidget(panel
->pathT
, width
- 20, 20);
620 WMMoveWidget(panel
->pathT
, 10, 20);
622 WMAddNotificationObserver(dataChanged
, panel
, WMTextDidChangeNotification
, panel
->pathT
);
624 label
= WMCreateLabel(panel
->pathF
);
625 WMResizeWidget(label
, width
- 20, 90);
626 WMMoveWidget(label
, 10, 50);
627 WMSetLabelText(label
, _("Enter the path for a file containing a menu\n"
628 "or a list of directories with the programs you\n"
629 "want to have listed in the menu. Ex:\n"
630 "~/" GSUSER_SUBDIR
"/" USERDATA_SUBDIR
"/" PACKAGE_TARNAME
"/menu\n"
631 "or\n" "/usr/bin ~/xbin"));
633 WMMapSubwidgets(panel
->pathF
);
637 panel
->pipeF
= WMCreateFrame(panel
->optionsF
);
638 WMResizeWidget(panel
->pipeF
, width
, 155);
639 WMMoveWidget(panel
->pipeF
, 10, 30);
640 WMSetFrameTitle(panel
->pipeF
, _("Command"));
642 panel
->pipeT
= WMCreateTextField(panel
->pipeF
);
643 WMResizeWidget(panel
->pipeT
, width
- 20, 20);
644 WMMoveWidget(panel
->pipeT
, 10, 20);
646 WMAddNotificationObserver(dataChanged
, panel
, WMTextDidChangeNotification
, panel
->pipeT
);
648 label
= WMCreateLabel(panel
->pipeF
);
649 WMResizeWidget(label
, width
- 20, 40);
650 WMMoveWidget(label
, 10, 50);
651 WMSetLabelText(label
, _("Enter a command that outputs a menu\n" "definition to stdout when invoked."));
653 panel
->pipeCacheB
= WMCreateSwitchButton(panel
->pipeF
);
654 WMResizeWidget(panel
->pipeCacheB
, width
- 20, 40);
655 WMMoveWidget(panel
->pipeCacheB
, 10, 110);
656 WMSetButtonText(panel
->pipeCacheB
, _("Cache menu contents after opening for\n" "the first time"));
658 WMMapSubwidgets(panel
->pipeF
);
662 panel
->plpipeF
= WMCreateFrame(panel
->optionsF
);
663 WMResizeWidget(panel
->plpipeF
, width
, 155);
664 WMMoveWidget(panel
->plpipeF
, 10, 30);
665 WMSetFrameTitle(panel
->plpipeF
, _("Command"));
667 panel
->plpipeT
= WMCreateTextField(panel
->plpipeF
);
668 WMResizeWidget(panel
->plpipeT
, width
- 20, 20);
669 WMMoveWidget(panel
->plpipeT
, 10, 20);
671 WMAddNotificationObserver(dataChanged
, panel
, WMTextDidChangeNotification
, panel
->plpipeT
);
673 label
= WMCreateLabel(panel
->plpipeF
);
674 WMResizeWidget(label
, width
- 20, 40);
675 WMMoveWidget(label
, 10, 50);
676 WMSetLabelText(label
, _("Enter a command that outputs a proplist menu\n" "definition to stdout when invoked."));
678 panel
->plpipeCacheB
= WMCreateSwitchButton(panel
->plpipeF
);
679 WMResizeWidget(panel
->plpipeCacheB
, width
- 20, 40);
680 WMMoveWidget(panel
->plpipeCacheB
, 10, 110);
681 WMSetButtonText(panel
->plpipeCacheB
, _("Cache menu contents after opening for\n" "the first time"));
683 WMMapSubwidgets(panel
->plpipeF
);
687 panel
->dcommandF
= WMCreateFrame(panel
->optionsF
);
688 WMResizeWidget(panel
->dcommandF
, width
, 90);
689 WMMoveWidget(panel
->dcommandF
, 10, 25);
690 WMSetFrameTitle(panel
->dcommandF
, _("Command to Open Files"));
692 panel
->dcommandT
= WMCreateTextField(panel
->dcommandF
);
693 WMResizeWidget(panel
->dcommandT
, width
- 20, 20);
694 WMMoveWidget(panel
->dcommandT
, 10, 20);
696 WMAddNotificationObserver(dataChanged
, panel
, WMTextDidChangeNotification
, panel
->dcommandT
);
698 label
= WMCreateLabel(panel
->dcommandF
);
699 WMResizeWidget(label
, width
- 20, 45);
700 WMMoveWidget(label
, 10, 40);
701 WMSetLabelText(label
, _("Enter the command you want to use to open the\n"
702 "files in the directories listed below."));
704 WMMapSubwidgets(panel
->dcommandF
);
706 panel
->dpathF
= WMCreateFrame(panel
->optionsF
);
707 WMResizeWidget(panel
->dpathF
, width
, 80);
708 WMMoveWidget(panel
->dpathF
, 10, 125);
709 WMSetFrameTitle(panel
->dpathF
, _("Directories with Files"));
711 panel
->dpathT
= WMCreateTextField(panel
->dpathF
);
712 WMResizeWidget(panel
->dpathT
, width
- 20, 20);
713 WMMoveWidget(panel
->dpathT
, 10, 20);
715 WMAddNotificationObserver(dataChanged
, panel
, WMTextDidChangeNotification
, panel
->dpathT
);
717 panel
->dstripB
= WMCreateSwitchButton(panel
->dpathF
);
718 WMResizeWidget(panel
->dstripB
, width
- 20, 20);
719 WMMoveWidget(panel
->dstripB
, 10, 50);
720 WMSetButtonText(panel
->dstripB
, _("Strip extensions from file names"));
722 WMSetButtonAction(panel
->dstripB
, buttonClicked
, panel
);
724 WMMapSubwidgets(panel
->dpathF
);
728 panel
->shortF
= WMCreateFrame(panel
->optionsF
);
729 WMResizeWidget(panel
->shortF
, width
, 50);
730 WMMoveWidget(panel
->shortF
, 10, 160);
731 WMSetFrameTitle(panel
->shortF
, _("Keyboard Shortcut"));
733 panel
->shortT
= WMCreateTextField(panel
->shortF
);
734 WMResizeWidget(panel
->shortT
, width
- 20 - 150, 20);
735 WMMoveWidget(panel
->shortT
, 10, 20);
737 WMAddNotificationObserver(dataChanged
, panel
, WMTextDidChangeNotification
, panel
->shortT
);
739 panel
->sgrabB
= WMCreateCommandButton(panel
->shortF
);
740 WMResizeWidget(panel
->sgrabB
, 70, 24);
741 WMMoveWidget(panel
->sgrabB
, width
- 80, 18);
742 WMSetButtonText(panel
->sgrabB
, _("Capture"));
743 WMSetButtonAction(panel
->sgrabB
, sgrabClicked
, panel
);
745 panel
->sclearB
= WMCreateCommandButton(panel
->shortF
);
746 WMResizeWidget(panel
->sclearB
, 70, 24);
747 WMMoveWidget(panel
->sclearB
, width
- 155, 18);
748 WMSetButtonText(panel
->sclearB
, _("Clear"));
749 WMSetButtonAction(panel
->sclearB
, sgrabClicked
, panel
);
751 WMMapSubwidgets(panel
->shortF
);
753 /* internal command */
755 panel
->icommandL
= WMCreateList(panel
->optionsF
);
756 WMResizeWidget(panel
->icommandL
, width
, 80);
757 WMMoveWidget(panel
->icommandL
, 10, 20);
759 WMSetListAction(panel
->icommandL
, icommandLClicked
, panel
);
761 WMAddNotificationObserver(dataChanged
, panel
, WMListSelectionDidChangeNotification
, panel
->icommandL
);
763 WMInsertListItem(panel
->icommandL
, 0, _("Arrange Icons"));
764 WMInsertListItem(panel
->icommandL
, 1, _("Hide All Windows Except For The Focused One"));
765 WMInsertListItem(panel
->icommandL
, 2, _("Show All Windows"));
767 WMInsertListItem(panel
->icommandL
, 3, _("Exit Window Maker"));
768 WMInsertListItem(panel
->icommandL
, 4, _("Exit X Session"));
769 WMInsertListItem(panel
->icommandL
, 5, _("Restart Window Maker"));
770 WMInsertListItem(panel
->icommandL
, 6, _("Start Another Window Manager : ("));
772 WMInsertListItem(panel
->icommandL
, 7, _("Save Current Session"));
773 WMInsertListItem(panel
->icommandL
, 8, _("Clear Saved Session"));
774 WMInsertListItem(panel
->icommandL
, 9, _("Refresh Screen"));
775 WMInsertListItem(panel
->icommandL
, 10, _("Open Info Panel"));
776 WMInsertListItem(panel
->icommandL
, 11, _("Open Copyright Panel"));
778 panel
->paramF
= WMCreateFrame(panel
->optionsF
);
779 WMResizeWidget(panel
->paramF
, width
, 50);
780 WMMoveWidget(panel
->paramF
, 10, 105);
781 WMSetFrameTitle(panel
->paramF
, _("Window Manager to Start"));
783 panel
->paramT
= WMCreateTextField(panel
->paramF
);
784 WMResizeWidget(panel
->paramT
, width
- 20, 20);
785 WMMoveWidget(panel
->paramT
, 10, 20);
787 WMAddNotificationObserver(dataChanged
, panel
, WMTextDidChangeNotification
, panel
->paramT
);
789 WMMapSubwidgets(panel
->paramF
);
791 panel
->quickB
= WMCreateSwitchButton(panel
->optionsF
);
792 WMResizeWidget(panel
->quickB
, width
, 20);
793 WMMoveWidget(panel
->quickB
, 10, 120);
794 WMSetButtonText(panel
->quickB
, _("Do not confirm action."));
795 WMSetButtonAction(panel
->quickB
, buttonClicked
, panel
);
797 label
= WMCreateLabel(panel
->optionsF
);
798 WMResizeWidget(label
, width
+ 5, FRAME_HEIGHT
- 50);
799 WMMoveWidget(label
, 7, 20);
800 WMSetLabelText(label
,
801 _("Instructions:\n\n"
802 " - drag items from the left to the menu to add new items\n"
803 " - drag items out of the menu to remove items\n"
804 " - drag items in menu to change their position\n"
805 " - drag items with Control pressed to copy them\n"
806 " - double click in a menu item to change the label\n"
807 " - click on a menu item to change related information"));
810 WMRealizeWidget(panel
->box
);
811 WMMapSubwidgets(panel
->box
);
812 WMMapWidget(panel
->box
);
816 for (i
= 0; i
< wlengthof(panel
->itemPad
); i
++)
817 WMUnmapWidget(panel
->itemPad
[i
]);
819 changedItemPad(panel
->typeP
, panel
);
821 panel
->sections
[NoInfo
][0] = label
;
823 panel
->sections
[ExecInfo
][0] = panel
->commandF
;
824 panel
->sections
[ExecInfo
][1] = panel
->shortF
;
826 panel
->sections
[CommandInfo
][0] = panel
->icommandL
;
827 panel
->sections
[CommandInfo
][1] = panel
->shortF
;
829 panel
->sections
[ExternalInfo
][0] = panel
->pathF
;
831 panel
->sections
[PipeInfo
][0] = panel
->pipeF
;
833 panel
->sections
[PLPipeInfo
][0] = panel
->plpipeF
;
835 panel
->sections
[DirectoryInfo
][0] = panel
->dpathF
;
836 panel
->sections
[DirectoryInfo
][1] = panel
->dcommandF
;
838 panel
->currentType
= NoInfo
;
845 pos
= WMGetViewScreenPosition(WMWidgetView(panel
->box
));
848 pos
.x
+= FRAME_WIDTH
+ 20;
853 pos
.y
= WMAX(pos
.y
- 100, 0);
856 WEditMenuShowAt(panel
->menu
, pos
.x
, pos
.y
);
860 static void freeItemData(ItemData
* data
)
862 #define CFREE(d) if (d) wfree(d)
865 switch (data
->type
) {
867 CFREE(data
->param
.command
.parameter
);
868 CFREE(data
->param
.command
.shortcut
);
872 CFREE(data
->param
.exec
.command
);
873 CFREE(data
->param
.exec
.shortcut
);
877 CFREE(data
->param
.pipe
.command
);
881 CFREE(data
->param
.pipe
.command
);
885 CFREE(data
->param
.external
.path
);
889 CFREE(data
->param
.directory
.command
);
890 CFREE(data
->param
.directory
.directory
);
901 static ItemData
*parseCommand(WMPropList
* item
)
903 ItemData
*data
= wmalloc(sizeof(ItemData
));
905 char *command
= NULL
;
906 char *parameter
= NULL
;
907 char *shortcut
= NULL
;
910 p
= WMGetFromPLArray(item
, i
++);
911 command
= WMGetFromPLString(p
);
912 if (strcmp(command
, "SHORTCUT") == 0) {
913 p
= WMGetFromPLArray(item
, i
++);
914 shortcut
= WMGetFromPLString(p
);
915 p
= WMGetFromPLArray(item
, i
++);
916 command
= WMGetFromPLString(p
);
918 p
= WMGetFromPLArray(item
, i
++);
920 parameter
= WMGetFromPLString(p
);
922 if (strcmp(command
, "EXEC") == 0 || strcmp(command
, "SHEXEC") == 0) {
924 data
->type
= ExecInfo
;
926 if (parameter
== NULL
) {
931 data
->param
.exec
.command
= wstrdup(parameter
);
933 data
->param
.exec
.shortcut
= wstrdup(shortcut
);
935 } else if (strcmp(command
, "OPEN_MENU") == 0) {
938 * dir menu, menu file
949 while (isspace(*p
) && *p
)
952 if (*(p
+ 1) == '|') {
954 data
->param
.pipe
.cached
= 0;
956 data
->param
.pipe
.cached
= 1;
958 data
->type
= PipeInfo
;
959 data
->param
.pipe
.command
= wtrimspace(p
+ 1);
965 s
= strstr(p
, "WITH");
972 data
->type
= DirectoryInfo
;
976 while (*s
&& isspace(*s
))
978 data
->param
.directory
.command
= wstrdup(s
);
980 wtokensplit(p
, &tokens
, &tokn
);
983 ctokens
= wmalloc(sizeof(char *) * tokn
);
985 for (i
= 0, j
= 0; i
< tokn
; i
++) {
986 if (strcmp(tokens
[i
], "-noext") == 0) {
987 data
->param
.directory
.stripExt
= 1;
989 ctokens
[j
++] = tokens
[i
];
992 data
->param
.directory
.directory
= wtokenjoin(ctokens
, j
);
995 wtokenfree(tokens
, tokn
);
997 data
->type
= ExternalInfo
;
998 data
->param
.external
.path
= p
;
1001 } else if (strcmp(command
, "OPEN_PLMENU") == 0) {
1005 while (isspace(*p
) && *p
)
1008 if (*(p
+ 1) == '|') {
1010 data
->param
.pipe
.cached
= 0;
1012 data
->param
.pipe
.cached
= 1;
1014 data
->type
= PLPipeInfo
;
1015 data
->param
.pipe
.command
= wtrimspace(p
+ 1);
1017 } else if (strcmp(command
, "WORKSPACE_MENU") == 0) {
1018 data
->type
= WSMenuInfo
;
1019 } else if (strcmp(command
, "WINDOWS_MENU") == 0) {
1020 data
->type
= WWindowListInfo
;
1024 if (strcmp(command
, "ARRANGE_ICONS") == 0) {
1026 } else if (strcmp(command
, "HIDE_OTHERS") == 0) {
1028 } else if (strcmp(command
, "SHOW_ALL") == 0) {
1030 } else if (strcmp(command
, "EXIT") == 0) {
1032 } else if (strcmp(command
, "SHUTDOWN") == 0) {
1034 } else if (strcmp(command
, "RESTART") == 0) {
1040 } else if (strcmp(command
, "SAVE_SESSION") == 0) {
1042 } else if (strcmp(command
, "CLEAR_SESSION") == 0) {
1044 } else if (strcmp(command
, "REFRESH") == 0) {
1046 } else if (strcmp(command
, "INFO_PANEL") == 0) {
1048 } else if (strcmp(command
, "LEGAL_PANEL") == 0) {
1051 wwarning(_("unknown command '%s' in menu"), command
);
1056 data
->type
= CommandInfo
;
1058 data
->param
.command
.command
= cmd
;
1060 data
->param
.command
.shortcut
= wstrdup(shortcut
);
1062 data
->param
.command
.parameter
= wstrdup(parameter
);
1068 static void updateFrameTitle(_Panel
* panel
, const char *title
, InfoType type
)
1070 if (type
!= NoInfo
) {
1075 tmp
= wstrconcat(title
, _(": Execute Program"));
1079 tmp
= wstrconcat(title
, _(": Perform Internal Command"));
1083 tmp
= wstrconcat(title
, _(": Open a Submenu"));
1087 tmp
= wstrconcat(title
, _(": Program Generated Submenu"));
1091 tmp
= wstrconcat(title
, _(": Program Generated Proplist Submenu"));
1095 tmp
= wstrconcat(title
, _(": Directory Contents Menu"));
1099 tmp
= wstrconcat(title
, _(": Open Workspaces Submenu"));
1102 case WWindowListInfo
:
1103 tmp
= wstrconcat(title
, _(": Open Window List Submenu"));
1110 WMSetFrameTitle(panel
->optionsF
, tmp
);
1113 WMSetFrameTitle(panel
->optionsF
, NULL
);
1117 static void changeInfoType(_Panel
* panel
, const char *title
, InfoType type
)
1121 if (panel
->currentType
!= type
) {
1123 w
= panel
->sections
[panel
->currentType
];
1129 WMUnmapWidget(panel
->paramF
);
1130 WMUnmapWidget(panel
->quickB
);
1132 w
= panel
->sections
[type
];
1140 updateFrameTitle(panel
, title
, type
);
1142 panel
->currentType
= type
;
1145 static void updateMenuItem(_Panel
* panel
, WEditMenuItem
* item
, WMWidget
* changedWidget
)
1147 ItemData
*data
= WGetEditMenuItemData(item
);
1149 assert(data
!= NULL
);
1151 #define REPLACE(v, d) if (v) wfree(v); v = d
1153 switch (data
->type
) {
1155 if (changedWidget
== panel
->commandT
) {
1156 REPLACE(data
->param
.exec
.command
, WMGetTextFieldText(panel
->commandT
));
1158 if (changedWidget
== panel
->shortT
) {
1159 REPLACE(data
->param
.exec
.shortcut
, WMGetTextFieldText(panel
->shortT
));
1164 if (changedWidget
== panel
->icommandL
) {
1165 data
->param
.command
.command
= WMGetListSelectedItemRow(panel
->icommandL
);
1167 switch (data
->param
.command
.command
) {
1170 if (changedWidget
== panel
->quickB
) {
1171 REPLACE(data
->param
.command
.parameter
, WMGetButtonSelected(panel
->quickB
)
1172 ? wstrdup("QUICK") : NULL
);
1177 if (changedWidget
== panel
->paramT
) {
1178 REPLACE(data
->param
.command
.parameter
, WMGetTextFieldText(panel
->paramT
));
1182 if (changedWidget
== panel
->shortT
) {
1183 REPLACE(data
->param
.command
.shortcut
, WMGetTextFieldText(panel
->shortT
));
1189 if (changedWidget
== panel
->pipeT
) {
1190 REPLACE(data
->param
.pipe
.command
, WMGetTextFieldText(panel
->pipeT
));
1192 if (changedWidget
== panel
->pipeCacheB
) {
1193 data
->param
.pipe
.cached
= WMGetButtonSelected(panel
->pipeCacheB
);
1198 if (changedWidget
== panel
->plpipeT
) {
1199 REPLACE(data
->param
.pipe
.command
, WMGetTextFieldText(panel
->plpipeT
));
1201 if (changedWidget
== panel
->plpipeCacheB
) {
1202 data
->param
.pipe
.cached
= WMGetButtonSelected(panel
->plpipeCacheB
);
1207 if (changedWidget
== panel
->pathT
) {
1208 REPLACE(data
->param
.external
.path
, WMGetTextFieldText(panel
->pathT
));
1213 if (changedWidget
== panel
->dpathT
) {
1214 REPLACE(data
->param
.directory
.directory
, WMGetTextFieldText(panel
->dpathT
));
1216 if (changedWidget
== panel
->dcommandT
) {
1217 REPLACE(data
->param
.directory
.command
, WMGetTextFieldText(panel
->dcommandT
));
1219 if (changedWidget
== panel
->dstripB
) {
1220 data
->param
.directory
.stripExt
= WMGetButtonSelected(panel
->dstripB
);
1233 menuItemCloned(WEditMenuDelegate
* delegate
, WEditMenu
* menu
, WEditMenuItem
* origItem
, WEditMenuItem
* newItem
)
1235 ItemData
*data
= WGetEditMenuItemData(origItem
);
1238 /* Parameter not used, but tell the compiler that it is ok */
1245 #define DUP(s) (s) ? wstrdup(s) : NULL
1247 newData
= wmalloc(sizeof(ItemData
));
1249 newData
->type
= data
->type
;
1251 switch (data
->type
) {
1253 newData
->param
.exec
.command
= DUP(data
->param
.exec
.command
);
1254 newData
->param
.exec
.shortcut
= DUP(data
->param
.exec
.shortcut
);
1258 newData
->param
.command
.command
= data
->param
.command
.command
;
1259 newData
->param
.command
.parameter
= DUP(data
->param
.command
.parameter
);
1260 newData
->param
.command
.shortcut
= DUP(data
->param
.command
.shortcut
);
1264 newData
->param
.pipe
.command
= DUP(data
->param
.pipe
.command
);
1265 newData
->param
.pipe
.cached
= data
->param
.pipe
.cached
;
1269 newData
->param
.pipe
.command
= DUP(data
->param
.pipe
.command
);
1270 newData
->param
.pipe
.cached
= data
->param
.pipe
.cached
;
1274 newData
->param
.external
.path
= DUP(data
->param
.external
.path
);
1278 newData
->param
.directory
.directory
= DUP(data
->param
.directory
.directory
);
1279 newData
->param
.directory
.command
= DUP(data
->param
.directory
.command
);
1280 newData
->param
.directory
.stripExt
= data
->param
.directory
.stripExt
;
1289 WSetEditMenuItemData(newItem
, newData
, (WMCallback
*) freeItemData
);
1292 static void menuItemEdited(struct WEditMenuDelegate
*delegate
, WEditMenu
* menu
, WEditMenuItem
* item
)
1294 _Panel
*panel
= (_Panel
*) delegate
->data
;
1297 /* Parameter not used, but tell the compiler it is ok */
1300 updateFrameTitle(panel
, WGetEditMenuItemTitle(item
), panel
->currentType
);
1302 submenu
= WGetEditMenuSubmenu(item
);
1304 WSetEditMenuTitle(submenu
, WGetEditMenuItemTitle(item
));
1308 static Bool
shouldRemoveItem(struct WEditMenuDelegate
*delegate
, WEditMenu
* menu
, WEditMenuItem
* item
)
1310 _Panel
*panel
= (_Panel
*) delegate
->data
;
1315 if (WGetEditMenuSubmenu(item
)) {
1318 res
= WMRunAlertPanel(WMWidgetScreen(menu
), NULL
,
1319 _("Remove Submenu"),
1320 _("Removing this item will destroy all items inside\n"
1321 "the submenu. Do you really want to do that?"),
1322 _("Yes"), _("No"), _("Yes, don't ask again"));
1329 panel
->dontAsk
= True
;
1336 static void menuItemDeselected(WEditMenuDelegate
* delegate
, WEditMenu
* menu
, WEditMenuItem
* item
)
1338 _Panel
*panel
= (_Panel
*) delegate
->data
;
1340 /* Parameter not used, but tell the compiler that it is ok */
1344 changeInfoType(panel
, NULL
, NoInfo
);
1347 static void menuItemSelected(WEditMenuDelegate
* delegate
, WEditMenu
* menu
, WEditMenuItem
* item
)
1349 ItemData
*data
= WGetEditMenuItemData(item
);
1350 _Panel
*panel
= (_Panel
*) delegate
->data
;
1352 /* Parameter not used, but tell the compiler that it is ok */
1355 panel
->currentItem
= item
;
1358 changeInfoType(panel
, WGetEditMenuItemTitle(item
), data
->type
);
1360 switch (data
->type
) {
1365 WMSetTextFieldText(panel
->commandT
, data
->param
.exec
.command
);
1366 WMSetTextFieldText(panel
->shortT
, data
->param
.exec
.shortcut
);
1370 WMSelectListItem(panel
->icommandL
, data
->param
.command
.command
);
1371 WMSetListPosition(panel
->icommandL
, data
->param
.command
.command
- 2);
1372 WMSetTextFieldText(panel
->shortT
, data
->param
.command
.shortcut
);
1374 switch (data
->param
.command
.command
) {
1377 WMSetButtonSelected(panel
->quickB
, data
->param
.command
.parameter
!= NULL
);
1380 WMSetTextFieldText(panel
->paramT
, data
->param
.command
.parameter
);
1384 icommandLClicked(panel
->icommandL
, panel
);
1388 WMSetTextFieldText(panel
->pipeT
, data
->param
.pipe
.command
);
1389 WMSetButtonSelected(panel
->pipeCacheB
, data
->param
.pipe
.cached
);
1393 WMSetTextFieldText(panel
->plpipeT
, data
->param
.pipe
.command
);
1394 WMSetButtonSelected(panel
->plpipeCacheB
, data
->param
.pipe
.cached
);
1398 WMSetTextFieldText(panel
->pathT
, data
->param
.external
.path
);
1402 WMSetTextFieldText(panel
->dpathT
, data
->param
.directory
.directory
);
1403 WMSetTextFieldText(panel
->dcommandT
, data
->param
.directory
.command
);
1404 WMSetButtonSelected(panel
->dstripB
, data
->param
.directory
.stripExt
);
1416 static WEditMenu
*buildSubmenu(_Panel
* panel
, WMPropList
* pl
)
1418 WMScreen
*scr
= WMWidgetScreen(panel
->parent
);
1420 WEditMenuItem
*item
;
1422 WMPropList
*tp
, *bp
;
1425 tp
= WMGetFromPLArray(pl
, 0);
1426 title
= WMGetFromPLString(tp
);
1428 menu
= WCreateEditMenu(scr
, title
);
1430 for (i
= 1; i
< WMGetPropListItemCount(pl
); i
++) {
1433 pi
= WMGetFromPLArray(pl
, i
);
1435 tp
= WMGetFromPLArray(pi
, 0);
1436 bp
= WMGetFromPLArray(pi
, 1);
1438 title
= WMGetFromPLString(tp
);
1440 if (!bp
|| WMIsPLArray(bp
)) { /* it's a submenu */
1443 submenu
= buildSubmenu(panel
, pi
);
1445 item
= WAddMenuItemWithTitle(menu
, title
);
1447 WSetEditMenuSubmenu(menu
, item
, submenu
);
1451 data
= parseCommand(pi
);
1454 item
= WAddMenuItemWithTitle(menu
, title
);
1455 if (panel
->markerPix
[data
->type
])
1456 WSetEditMenuItemImage(item
, panel
->markerPix
[data
->type
]);
1457 WSetEditMenuItemData(item
, data
, (WMCallback
*) freeItemData
);
1461 snprintf(buf
, sizeof(buf
), _("Invalid menu command \"%s\" with label \"%s\" cleared"),
1462 WMGetFromPLString(WMGetFromPLArray(pi
, 1)),
1463 WMGetFromPLString(WMGetFromPLArray(pi
, 0)));
1464 WMRunAlertPanel(scr
, panel
->parent
, _("Warning"), buf
, _("OK"), NULL
, NULL
);
1470 WSetEditMenuAcceptsDrop(menu
, True
);
1471 WSetEditMenuDelegate(menu
, &menuDelegate
);
1473 WMRealizeWidget(menu
);
1478 static void buildMenuFromPL(_Panel
* panel
, WMPropList
* pl
)
1480 panel
->menu
= buildSubmenu(panel
, pl
);
1483 static WMPropList
*getDefaultMenu(_Panel
* panel
)
1486 static const char menuPath
[] = WMAKER_RESOURCE_PATH
"/plmenu";
1488 menu
= WMReadPropListFromFile(menuPath
);
1492 msg
= _("Could not open default menu from '%s'");
1493 buffer
= wmalloc(strlen(msg
) + strlen(menuPath
) + 10);
1494 sprintf(buffer
, msg
, menuPath
);
1495 WMRunAlertPanel(WMWidgetScreen(panel
->parent
), panel
->parent
,
1496 _("Error"), buffer
, _("OK"), NULL
, NULL
);
1503 static void showData(_Panel
* panel
)
1505 char *menuPath
, *labelText
;
1509 menuPath
= wdefaultspathfordomain("WMRootMenu");
1511 pmenu
= WMReadPropListFromFile(menuPath
);
1513 /* check if WMRootMenu references another file, and if so,
1514 if that file is in proplist format */
1515 while (WMIsPLString(pmenu
)) {
1518 path
= wexpandpath(WMGetFromPLString(pmenu
));
1520 if (access(path
, F_OK
) < 0) {
1521 char *old_path
= path
;
1523 path
= wfindfile(DEF_CONFIG_PATHS
, path
);
1527 /* TODO: if needed, concatenate locale suffix to path.
1528 See getLocalizedMenuFile() in src/rootmenu.c. */
1533 if (access(path
, W_OK
) < 0) {
1534 snprintf(buf
, sizeof(buf
),
1535 _("The menu file \"%s\" referenced by "
1536 "WMRootMenu is read-only.\n"
1537 "You cannot use WPrefs to modify it."),
1539 WMRunAlertPanel(WMWidgetScreen(panel
->parent
),
1542 _("OK"), NULL
, NULL
);
1543 panel
->dontSave
= True
;
1548 pmenu
= WMReadPropListFromFile(path
);
1552 if (!pmenu
|| !WMIsPLArray(pmenu
)) {
1555 res
= WMRunAlertPanel(WMWidgetScreen(panel
->parent
), panel
->parent
,
1557 _("The menu file format currently in use is not supported\n"
1558 "by this tool. Do you want to discard the current menu\n"
1559 "to use this tool?"),
1560 _("Yes, Discard and Update"), _("No, Keep Current Menu"), NULL
);
1562 if (res
== WAPRDefault
) {
1563 pmenu
= getDefaultMenu(panel
);
1566 pmenu
= WMCreatePLArray(WMCreatePLString("Applications"), NULL
);
1569 panel
->dontSave
= True
;
1574 panel
->menuPath
= menuPath
;
1576 snprintf(buf
, sizeof(buf
),
1577 _("\n\nWhen saved, the menu will be written to the file\n\"%s\"."),
1579 labelText
= WMGetLabelText(panel
->sections
[NoInfo
][0]);
1580 labelText
= wstrconcat(labelText
, buf
);
1581 WMSetLabelText(panel
->sections
[NoInfo
][0], labelText
);
1584 buildMenuFromPL(panel
, pmenu
);
1586 WMReleasePropList(pmenu
);
1589 static Bool
notblank(const char *s
)
1600 static WMPropList
*processData(const char *title
, ItemData
* data
)
1604 static WMPropList
*pscut
= NULL
;
1605 static WMPropList
*pomenu
= NULL
;
1606 static WMPropList
*poplmenu
= NULL
;
1613 pscut
= WMCreatePLString("SHORTCUT");
1614 pomenu
= WMCreatePLString("OPEN_MENU");
1615 poplmenu
= WMCreatePLString("OPEN_PLMENU");
1618 item
= WMCreatePLArray(WMCreatePLString(title
), NULL
);
1620 switch (data
->type
) {
1622 if (data
->param
.exec
.command
== NULL
)
1625 if (strpbrk(data
->param
.exec
.command
, "&$*|><?`=;")) {
1631 if (notblank(data
->param
.exec
.shortcut
)) {
1632 WMAddToPLArray(item
, pscut
);
1633 WMAddToPLArray(item
, WMCreatePLString(data
->param
.exec
.shortcut
));
1636 WMAddToPLArray(item
, WMCreatePLString(s1
));
1637 WMAddToPLArray(item
, WMCreatePLString(data
->param
.exec
.command
));
1641 if (notblank(data
->param
.command
.shortcut
)) {
1642 WMAddToPLArray(item
, pscut
);
1643 WMAddToPLArray(item
, WMCreatePLString(data
->param
.command
.shortcut
));
1646 i
= data
->param
.command
.command
;
1648 WMAddToPLArray(item
, WMCreatePLString(commandNames
[i
]));
1653 if (data
->param
.command
.parameter
) {
1654 WMAddToPLArray(item
, WMCreatePLString(data
->param
.command
.parameter
));
1658 case 6: /* restart */
1659 if (data
->param
.command
.parameter
) {
1660 WMAddToPLArray(item
, WMCreatePLString(data
->param
.command
.parameter
));
1669 if (!data
->param
.pipe
.command
)
1671 if (data
->type
== PLPipeInfo
)
1672 WMAddToPLArray(item
, poplmenu
);
1674 WMAddToPLArray(item
, pomenu
);
1676 if (data
->param
.pipe
.cached
)
1677 s1
= wstrconcat("| ", data
->param
.pipe
.command
);
1679 s1
= wstrconcat("|| ", data
->param
.pipe
.command
);
1680 WMAddToPLArray(item
, WMCreatePLString(s1
));
1685 if (!data
->param
.external
.path
)
1687 WMAddToPLArray(item
, pomenu
);
1688 WMAddToPLArray(item
, WMCreatePLString(data
->param
.external
.path
));
1696 if (!data
->param
.directory
.directory
|| !data
->param
.directory
.command
)
1699 l
= strlen(data
->param
.directory
.directory
);
1700 l
+= strlen(data
->param
.directory
.command
);
1703 WMAddToPLArray(item
, pomenu
);
1706 sprintf(tmp
, "%s%s WITH %s",
1707 data
->param
.directory
.stripExt
? "-noext " : "",
1708 data
->param
.directory
.directory
, data
->param
.directory
.command
);
1710 WMAddToPLArray(item
, WMCreatePLString(tmp
));
1716 WMAddToPLArray(item
, WMCreatePLString("WORKSPACE_MENU"));
1719 case WWindowListInfo
:
1720 WMAddToPLArray(item
, WMCreatePLString("WINDOWS_MENU"));
1731 WMReleasePropList(item
);
1735 static WMPropList
*processSubmenu(WEditMenu
* menu
)
1737 WEditMenuItem
*item
;
1743 s
= WGetEditMenuTitle(menu
);
1744 pl
= WMCreatePLString(s
);
1746 pmenu
= WMCreatePLArray(pl
, NULL
);
1749 while ((item
= WGetEditMenuItem(menu
, i
++))) {
1752 s
= WGetEditMenuItemTitle(item
);
1754 submenu
= WGetEditMenuSubmenu(item
);
1756 pl
= processSubmenu(submenu
);
1758 pl
= processData(s
, WGetEditMenuItemData(item
));
1764 WMAddToPLArray(pmenu
, pl
);
1770 static WMPropList
*buildPLFromMenu(_Panel
* panel
)
1774 menu
= processSubmenu(panel
->menu
);
1779 static void storeData(_Panel
* panel
)
1783 if (panel
->dontSave
)
1786 menu
= buildPLFromMenu(panel
);
1788 WMWritePropListToFile(menu
, panel
->menuPath
);
1790 WMReleasePropList(menu
);
1793 static void showMenus(_Panel
* panel
)
1796 WEditMenuUnhide(panel
->menu
);
1799 static void hideMenus(_Panel
* panel
)
1802 WEditMenuHide(panel
->menu
);
1805 Panel
*InitMenu(WMWidget
*parent
)
1809 panel
= wmalloc(sizeof(_Panel
));
1811 panel
->sectionName
= _("Applications Menu Definition");
1813 panel
->description
= _("Edit the menu for launching applications.");
1815 panel
->parent
= parent
;
1817 panel
->callbacks
.createWidgets
= createPanel
;
1818 panel
->callbacks
.updateDomain
= storeData
;
1819 panel
->callbacks
.showPanel
= showMenus
;
1820 panel
->callbacks
.hidePanel
= hideMenus
;
1822 AddSection(panel
, ICON_FILE
);