1 /* Menu.c- menu definition
3 * WPrefs - Window Maker Preferences Program
5 * Copyright (c) 2000 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
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
28 #include <X11/keysym.h>
29 #include <X11/cursorfont.h>
46 #define MAX_SECTION_SIZE 4
48 typedef struct _Panel
{
54 CallbackRec callbacks
;
76 WMTextField
*commandT
; /* command to run */
77 WMButton
*xtermC
; /* inside xterm? */
89 WMTextField
*dcommandT
;
103 Bool dontAsk
; /* whether to comfirm submenu remove */
106 /* about the currently selected item */
107 WEditMenuItem
*currentItem
;
108 InfoType currentType
;
109 WMWidget
*sections
[LastInfo
][MAX_SECTION_SIZE
];
141 static char *commandNames
[] = {
158 #define NEW(type) memset(wmalloc(sizeof(type)), 0, sizeof(type))
161 #define ICON_FILE "menus"
165 static void showData(_Panel
*panel
);
168 static void updateMenuItem(_Panel
*panel
, WEditMenuItem
*item
,
169 WMWidget
*changedWidget
);
171 static void menuItemSelected(struct WEditMenuDelegate
*delegate
,
172 WEditMenu
*menu
, WEditMenuItem
*item
);
174 static void menuItemDeselected(struct WEditMenuDelegate
*delegate
,
175 WEditMenu
*menu
, WEditMenuItem
*item
);
177 static void menuItemCloned(struct WEditMenuDelegate
*delegate
, WEditMenu
*menu
,
178 WEditMenuItem
*origItem
, WEditMenuItem
*newItem
);
180 static void menuItemEdited(struct WEditMenuDelegate
*delegate
, WEditMenu
*menu
,
181 WEditMenuItem
*item
);
183 static Bool
shouldRemoveItem(struct WEditMenuDelegate
*delegate
,
184 WEditMenu
*menu
, WEditMenuItem
*item
);
187 static void freeItemData(ItemData
*data
);
191 static WEditMenuDelegate menuDelegate
= {
202 dataChanged(void *self
, WMNotification
*notif
)
204 _Panel
*panel
= (_Panel
*)self
;
205 WEditMenuItem
*item
= panel
->currentItem
;
206 WMWidget
*w
= (WMWidget
*)WMGetNotificationObject(notif
);
208 updateMenuItem(panel
, item
, w
);
213 stripClicked(WMWidget
*w
, void *data
)
215 _Panel
*panel
= (_Panel
*)data
;
216 WEditMenuItem
*item
= panel
->currentItem
;
218 updateMenuItem(panel
, item
, w
);
223 icommandLClicked(WMWidget
*w
, void *data
)
225 _Panel
*panel
= (_Panel
*)data
;
227 switch (WMGetListSelectedItemRow(w
)) {
229 WMMapWidget(panel
->paramF
);
232 WMUnmapWidget(panel
->paramF
);
239 createPanel(_Panel
*p
)
241 _Panel
*panel
= (_Panel
*)p
;
242 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
243 WMColor
*black
= WMBlackColor(scr
);
244 WMColor
*white
= WMWhiteColor(scr
);
245 WMColor
*gray
= WMGrayColor(scr
);
246 WMFont
*bold
= WMBoldSystemFontOfSize(scr
, 12);
247 WMFont
*font
= WMSystemFontOfSize(scr
, 12);
252 menuDelegate
.data
= panel
;
255 panel
->boldFont
= bold
;
256 panel
->normalFont
= font
;
258 panel
->black
= black
;
259 panel
->white
= white
;
264 Display
*dpy
= WMScreenDisplay(scr
);
267 panel
->markerPix
= WMCreatePixmap(scr
, 7, 7, WMScreenDepth(scr
), True
);
269 pix
= WMGetPixmapXID(panel
->markerPix
);
271 XDrawLine(dpy
, pix
, WMColorGC(black
), 1, 0, 6, 3);
272 XDrawLine(dpy
, pix
, WMColorGC(black
), 1, 6, 6, 3);
273 XDrawLine(dpy
, pix
, WMColorGC(black
), 1, 0, 3, 3);
274 XDrawLine(dpy
, pix
, WMColorGC(black
), 1, 6, 3, 3);
275 XDrawLine(dpy
, pix
, WMColorGC(black
), 0, 0, 0, 6);
278 pix
= WMGetPixmapMaskXID(panel
->markerPix
);
280 gc
= XCreateGC(dpy
, pix
, 0, NULL
);
282 XSetForeground(dpy
, gc
, 0);
283 XFillRectangle(dpy
, pix
, gc
, 0, 0, 7, 7);
285 XSetForeground(dpy
, gc
, 1);
286 XDrawLine(dpy
, pix
, gc
, 1, 0, 6, 3);
287 XDrawLine(dpy
, pix
, gc
, 1, 6, 6, 3);
288 XDrawLine(dpy
, pix
, gc
, 1, 0, 3, 3);
289 XDrawLine(dpy
, pix
, gc
, 1, 6, 3, 3);
290 XDrawLine(dpy
, pix
, gc
, 0, 0, 0, 6);
296 panel
->frame
= WMCreateFrame(panel
->win
);
297 WMResizeWidget(panel
->frame
, FRAME_WIDTH
, FRAME_HEIGHT
);
298 WMMoveWidget(panel
->frame
, FRAME_LEFT
, FRAME_TOP
);
300 panel
->typeP
= WMCreatePopUpButton(panel
->frame
);
301 WMResizeWidget(panel
->typeP
, 150, 20);
302 WMMoveWidget(panel
->typeP
, 10, 10);
304 WMAddPopUpButtonItem(panel
->typeP
, _("Items"));
305 WMAddPopUpButtonItem(panel
->typeP
, _("Sample Commands"));
306 WMAddPopUpButtonItem(panel
->typeP
, _("Sample Submenus"));
308 WMSetPopUpButtonSelectedItem(panel
->typeP
, 0);
316 pad
= WCreateEditMenuPad(panel
->frame
);
317 WMResizeWidget(pad
, 150, 180);
318 WMMoveWidget(pad
, 10, 40);
319 WSetEditMenuMinSize(pad
, wmksize(150, 180));
320 WSetEditMenuMaxSize(pad
, wmksize(150, 180));
321 WSetEditMenuSelectable(pad
, False
);
322 WSetEditMenuEditable(pad
, False
);
323 WSetEditMenuIsFactory(pad
, True
);
324 WSetEditMenuDelegate(pad
, &menuDelegate
);
326 item
= WInsertMenuItemWithTitle(pad
, 0, "Run Program");
327 data
= NEW(ItemData
);
328 data
->type
= ExecInfo
;
329 WSetEditMenuItemData(item
, data
, (WMCallback
*)freeItemData
);
331 item
= WInsertMenuItemWithTitle(pad
, 1, "Internal Command");
332 data
= NEW(ItemData
);
333 data
->type
= CommandInfo
;
334 WSetEditMenuItemData(item
, data
, (WMCallback
*)freeItemData
);
336 item
= WInsertMenuItemWithTitle(pad
, 2, "Submenu");
337 tmp
= WCreateEditMenu(scr
, "Submenu");
338 WSetEditMenuAcceptsDrop(tmp
, True
);
339 WSetEditMenuDelegate(tmp
, &menuDelegate
);
340 WSetEditMenuSubmenu(pad
, item
, tmp
);
342 item
= WInsertMenuItemWithTitle(pad
, 3, "External Submenu");
343 WSetEditMenuItemImage(item
, panel
->markerPix
);
344 data
= NEW(ItemData
);
345 data
->type
= ExternalInfo
;
346 WSetEditMenuItemData(item
, data
, (WMCallback
*)freeItemData
);
348 item
= WInsertMenuItemWithTitle(pad
, 4, "Generated Submenu");
349 WSetEditMenuItemImage(item
, panel
->markerPix
);
350 data
= NEW(ItemData
);
351 data
->type
= PipeInfo
;
352 WSetEditMenuItemData(item
, data
, (WMCallback
*)freeItemData
);
354 item
= WInsertMenuItemWithTitle(pad
, 5, "Directory Contents");
355 WSetEditMenuItemImage(item
, panel
->markerPix
);
356 data
= NEW(ItemData
);
357 data
->type
= DirectoryInfo
;
358 WSetEditMenuItemData(item
, data
, (WMCallback
*)freeItemData
);
360 item
= WInsertMenuItemWithTitle(pad
, 6, "Workspace Menu");
361 WSetEditMenuItemImage(item
, panel
->markerPix
);
362 data
= NEW(ItemData
);
363 data
->type
= WSMenuInfo
;
364 WSetEditMenuItemData(item
, data
, (WMCallback
*)freeItemData
);
366 panel
->itemPad
= pad
;
369 width
= FRAME_WIDTH
- 20 - 150 - 10;
371 panel
->optionsF
= WMCreateFrame(panel
->frame
);
372 WMResizeWidget(panel
->optionsF
, width
, FRAME_HEIGHT
- 15);
373 WMMoveWidget(panel
->optionsF
, 10 + 150 + 10, 5);
379 panel
->commandF
= WMCreateFrame(panel
->optionsF
);
380 WMResizeWidget(panel
->commandF
, width
, 50);
381 WMMoveWidget(panel
->commandF
, 10, 20);
382 WMSetFrameTitle(panel
->commandF
, _("Program to Run"));
384 panel
->commandT
= WMCreateTextField(panel
->commandF
);
385 WMResizeWidget(panel
->commandT
, width
- 20, 20);
386 WMMoveWidget(panel
->commandT
, 10, 20);
388 WMAddNotificationObserver(dataChanged
, panel
,
389 WMTextDidChangeNotification
,
393 panel
->xtermC
= WMCreateSwitchButton(panel
->commandF
);
394 WMResizeWidget(panel
->xtermC
, width
- 20, 20);
395 WMMoveWidget(panel
->xtermC
, 10, 50);
396 WMSetButtonText(panel
->xtermC
, _("Run the program inside a Xterm"));
398 WMMapSubwidgets(panel
->commandF
);
403 panel
->pathF
= WMCreateFrame(panel
->optionsF
);
404 WMResizeWidget(panel
->pathF
, width
, 150);
405 WMMoveWidget(panel
->pathF
, 10, 40);
406 WMSetFrameTitle(panel
->pathF
, _("Path for Menu"));
408 panel
->pathT
= WMCreateTextField(panel
->pathF
);
409 WMResizeWidget(panel
->pathT
, width
- 20, 20);
410 WMMoveWidget(panel
->pathT
, 10, 20);
412 WMAddNotificationObserver(dataChanged
, panel
,
413 WMTextDidChangeNotification
,
416 label
= WMCreateLabel(panel
->pathF
);
417 WMResizeWidget(label
, width
- 20, 80);
418 WMMoveWidget(label
, 10, 50);
419 WMSetLabelText(label
, _("Enter the path for a file containing a menu\n"
420 "or a list of directories with the programs you\n"
421 "want to have listed in the menu. Ex:\n"
422 "~/GNUstep/Library/WindowMaker/menu\n"
424 "/usr/X11R6/bin ~/xbin"));
426 WMMapSubwidgets(panel
->pathF
);
431 panel
->pipeF
= WMCreateFrame(panel
->optionsF
);
432 WMResizeWidget(panel
->pipeF
, width
, 100);
433 WMMoveWidget(panel
->pipeF
, 10, 50);
434 WMSetFrameTitle(panel
->pipeF
, _("Command"));
436 panel
->pipeT
= WMCreateTextField(panel
->pipeF
);
437 WMResizeWidget(panel
->pipeT
, width
- 20, 20);
438 WMMoveWidget(panel
->pipeT
, 10, 20);
440 WMAddNotificationObserver(dataChanged
, panel
,
441 WMTextDidChangeNotification
,
445 label
= WMCreateLabel(panel
->pipeF
);
446 WMResizeWidget(label
, width
- 20, 40);
447 WMMoveWidget(label
, 10, 50);
448 WMSetLabelText(label
, _("Enter a command that outputs a menu\n"
449 "definition to stdout when invoked."));
451 WMMapSubwidgets(panel
->pipeF
);
456 panel
->dcommandF
= WMCreateFrame(panel
->optionsF
);
457 WMResizeWidget(panel
->dcommandF
, width
, 90);
458 WMMoveWidget(panel
->dcommandF
, 10, 25);
459 WMSetFrameTitle(panel
->dcommandF
, _("Command to Open Files"));
461 panel
->dcommandT
= WMCreateTextField(panel
->dcommandF
);
462 WMResizeWidget(panel
->dcommandT
, width
- 20, 20);
463 WMMoveWidget(panel
->dcommandT
, 10, 20);
465 WMAddNotificationObserver(dataChanged
, panel
,
466 WMTextDidChangeNotification
,
470 label
= WMCreateLabel(panel
->dcommandF
);
471 WMResizeWidget(label
, width
- 20, 45);
472 WMMoveWidget(label
, 10, 40);
473 WMSetLabelText(label
, _("Enter the command you want to use to open the\n"
474 "files in the directories listed below."));
476 WMMapSubwidgets(panel
->dcommandF
);
479 panel
->dpathF
= WMCreateFrame(panel
->optionsF
);
480 WMResizeWidget(panel
->dpathF
, width
, 80);
481 WMMoveWidget(panel
->dpathF
, 10, 125);
482 WMSetFrameTitle(panel
->dpathF
, _("Directories with Files"));
484 panel
->dpathT
= WMCreateTextField(panel
->dpathF
);
485 WMResizeWidget(panel
->dpathT
, width
- 20, 20);
486 WMMoveWidget(panel
->dpathT
, 10, 20);
488 WMAddNotificationObserver(dataChanged
, panel
,
489 WMTextDidChangeNotification
,
492 panel
->dstripB
= WMCreateSwitchButton(panel
->dpathF
);
493 WMResizeWidget(panel
->dstripB
, width
- 20, 20);
494 WMMoveWidget(panel
->dstripB
, 10, 50);
495 WMSetButtonText(panel
->dstripB
, _("Strip extensions from file names"));
497 WMSetButtonAction(panel
->dstripB
, stripClicked
, panel
);
499 WMMapSubwidgets(panel
->dpathF
);
504 panel
->shortF
= WMCreateFrame(panel
->optionsF
);
505 WMResizeWidget(panel
->shortF
, width
, 50);
506 WMMoveWidget(panel
->shortF
, 10, 160);
507 WMSetFrameTitle(panel
->shortF
, _("Keyboard Shortcut"));
509 panel
->shortT
= WMCreateTextField(panel
->shortF
);
510 WMResizeWidget(panel
->shortT
, width
- 20 - 170, 20);
511 WMMoveWidget(panel
->shortT
, 10, 20);
513 WMAddNotificationObserver(dataChanged
, panel
,
514 WMTextDidChangeNotification
,
517 panel
->sgrabB
= WMCreateCommandButton(panel
->shortF
);
518 WMResizeWidget(panel
->sgrabB
, 80, 24);
519 WMMoveWidget(panel
->sgrabB
, width
- 90, 18);
520 WMSetButtonText(panel
->sgrabB
, _("Capture"));
522 panel
->sclearB
= WMCreateCommandButton(panel
->shortF
);
523 WMResizeWidget(panel
->sclearB
, 80, 24);
524 WMMoveWidget(panel
->sclearB
, width
- 175, 18);
525 WMSetButtonText(panel
->sclearB
, _("Clear"));
527 WMMapSubwidgets(panel
->shortF
);
529 /* internal command */
531 panel
->icommandL
= WMCreateList(panel
->optionsF
);
532 WMResizeWidget(panel
->icommandL
, width
, 80);
533 WMMoveWidget(panel
->icommandL
, 10, 20);
535 WMSetListAction(panel
->icommandL
, icommandLClicked
, panel
);
537 WMAddNotificationObserver(dataChanged
, panel
,
538 WMListSelectionDidChangeNotification
,
541 WMInsertListItem(panel
->icommandL
, 0, _("Arrange Icons"));
542 WMInsertListItem(panel
->icommandL
, 1, _("Hide All Windows Except For The Focused One"));
543 WMInsertListItem(panel
->icommandL
, 2, _("Show All Windows"));
545 WMInsertListItem(panel
->icommandL
, 3, _("Exit Window Maker"));
546 WMInsertListItem(panel
->icommandL
, 4, _("Exit X Session"));
547 WMInsertListItem(panel
->icommandL
, 5, _("Restart Window Maker"));
548 WMInsertListItem(panel
->icommandL
, 6, _("Start Another Window Manager : ("));
550 WMInsertListItem(panel
->icommandL
, 7, _("Save Current Session"));
551 WMInsertListItem(panel
->icommandL
, 8, _("Clear Saved Session"));
552 WMInsertListItem(panel
->icommandL
, 9, _("Refresh Screen"));
553 WMInsertListItem(panel
->icommandL
, 10, _("Open Info Panel"));
554 WMInsertListItem(panel
->icommandL
, 11, _("Open Copyright Panel"));
557 panel
->paramF
= WMCreateFrame(panel
->optionsF
);
558 WMResizeWidget(panel
->paramF
, width
, 50);
559 WMMoveWidget(panel
->paramF
, 10, 105);
560 WMSetFrameTitle(panel
->paramF
, _("Window Manager to Start"));
562 panel
->paramT
= WMCreateTextField(panel
->paramF
);
563 WMResizeWidget(panel
->paramT
, width
- 20, 20);
564 WMMoveWidget(panel
->paramT
, 10, 20);
566 WMMapSubwidgets(panel
->paramF
);
568 WMRealizeWidget(panel
->frame
);
569 WMMapSubwidgets(panel
->frame
);
570 WMMapWidget(panel
->frame
);
574 panel
->sections
[ExecInfo
][0] = panel
->commandF
;
575 panel
->sections
[ExecInfo
][1] = panel
->shortF
;
577 panel
->sections
[CommandInfo
][0] = panel
->icommandL
;
578 panel
->sections
[CommandInfo
][1] = label
;
579 panel
->sections
[CommandInfo
][2] = panel
->shortF
;
581 panel
->sections
[ExternalInfo
][0] = panel
->pathF
;
583 panel
->sections
[PipeInfo
][0] = panel
->pipeF
;
585 panel
->sections
[DirectoryInfo
][0] = panel
->dpathF
;
586 panel
->sections
[DirectoryInfo
][1] = panel
->dcommandF
;
588 panel
->currentType
= NoInfo
;
597 freeItemData(ItemData
*data
)
599 #define CFREE(d) if (d) free(d)
602 switch (data
->type
) {
604 CFREE(data
->param
.command
.parameter
);
605 CFREE(data
->param
.command
.shortcut
);
609 CFREE(data
->param
.exec
.command
);
610 CFREE(data
->param
.exec
.shortcut
);
614 CFREE(data
->param
.pipe
.command
);
618 CFREE(data
->param
.external
.path
);
622 CFREE(data
->param
.directory
.command
);
623 CFREE(data
->param
.directory
.directory
);
636 parseCommand(proplist_t item
)
638 ItemData
*data
= NEW(ItemData
);
640 char *command
= NULL
;
641 char *parameter
= NULL
;
642 char *shortcut
= NULL
;
646 p
= PLGetArrayElement(item
, i
++);
647 command
= PLGetString(p
);
648 if (strcmp(command
, "SHORTCUT") == 0) {
649 p
= PLGetArrayElement(item
, i
++);
650 shortcut
= PLGetString(p
);
651 p
= PLGetArrayElement(item
, i
++);
652 command
= PLGetString(p
);
654 p
= PLGetArrayElement(item
, i
++);
656 parameter
= PLGetString(p
);
658 if (strcmp(command
, "EXEC") == 0
659 || strcmp(command
, "SHEXEC") == 0) {
661 data
->type
= ExecInfo
;
663 data
->param
.exec
.command
= wstrdup(parameter
);
665 data
->param
.exec
.shortcut
= wstrdup(shortcut
);
667 } else if (strcmp(command
, "OPEN_MENU") == 0) {
670 * dir menu, menu file
672 * |pipe (TODO: ||pipe)
675 while (isspace(*p
) && *p
) p
++;
677 data
->type
= PipeInfo
;
678 data
->param
.pipe
.command
= wtrimspace(p
+1);
684 s
= strstr(p
, "WITH");
691 data
->type
= DirectoryInfo
;
695 while (*s
&& isspace(*s
)) s
++;
696 data
->param
.directory
.command
= wstrdup(s
);
698 wtokensplit(p
, &tokens
, &tokn
);
701 ctokens
= wmalloc(sizeof(char*)*tokn
);
703 for (i
= 0, j
= 0; i
< tokn
; i
++) {
704 if (strcmp(tokens
[i
], "-noext") == 0) {
706 data
->param
.directory
.stripExt
= 1;
708 ctokens
[j
++] = tokens
[i
];
711 data
->param
.directory
.directory
= wtokenjoin(ctokens
, j
);
714 wtokenfree(tokens
, tokn
);
716 data
->type
= ExternalInfo
;
717 data
->param
.external
.path
= p
;
720 } else if (strcmp(command
, "WORKSPACE_MENU") == 0) {
721 data
->type
= WSMenuInfo
;
725 if (strcmp(command
, "ARRANGE_ICONS") == 0) {
727 } else if (strcmp(command
, "HIDE_OTHERS") == 0) {
729 } else if (strcmp(command
, "SHOW_ALL") == 0) {
731 } else if (strcmp(command
, "EXIT") == 0) {
733 } else if (strcmp(command
, "SHUTDOWN") == 0) {
735 } else if (strcmp(command
, "RESTART") == 0) {
741 } else if (strcmp(command
, "SAVE_SESSION") == 0) {
743 } else if (strcmp(command
, "CLEAR_SESSION") == 0) {
745 } else if (strcmp(command
, "REFRESH") == 0) {
747 } else if (strcmp(command
, "INFO_PANEL") == 0) {
749 } else if (strcmp(command
, "LEGAL_PANEL") == 0) {
752 wwarning(_("unknown command '%s' in menu"), command
);
756 data
->type
= CommandInfo
;
758 data
->param
.command
.command
= cmd
;
760 data
->param
.command
.shortcut
= wstrdup(shortcut
);
762 data
->param
.command
.parameter
= wstrdup(parameter
);
777 updateFrameTitle(_Panel
*panel
, char *title
, InfoType type
)
779 if (type
!= NoInfo
) {
784 tmp
= wstrappend(title
, _(": Execute Program"));
788 tmp
= wstrappend(title
, _(": Perform Internal Command"));
792 tmp
= wstrappend(title
, _(": Open a Submenu"));
796 tmp
= wstrappend(title
, _(": Program Generated Submenu"));
800 tmp
= wstrappend(title
, _(": Directory Contents Menu"));
804 tmp
= wstrappend(title
, _(": Open Workspaces Submenu"));
811 WMSetFrameTitle(panel
->optionsF
, tmp
);
814 WMSetFrameTitle(panel
->optionsF
, NULL
);
821 changeInfoType(_Panel
*panel
, char *title
, InfoType type
)
825 if (panel
->currentType
!= NoInfo
) {
826 w
= panel
->sections
[panel
->currentType
];
834 if (type
!= NoInfo
) {
835 w
= panel
->sections
[type
];
843 updateFrameTitle(panel
, title
, type
);
845 panel
->currentType
= type
;
852 updateMenuItem(_Panel
*panel
, WEditMenuItem
*item
, WMWidget
*changedWidget
)
854 ItemData
*data
= WGetEditMenuItemData(item
);
856 assert(data
!= NULL
);
858 #define REPLACE(v, d) if (v) free(v); v = d
860 switch (data
->type
) {
862 if (changedWidget
== panel
->commandT
) {
863 REPLACE(data
->param
.exec
.command
,
864 WMGetTextFieldText(panel
->commandT
));
866 if (changedWidget
== panel
->shortT
) {
867 REPLACE(data
->param
.exec
.shortcut
,
868 WMGetTextFieldText(panel
->shortT
));
873 if (changedWidget
== panel
->icommandL
) {
874 data
->param
.command
.command
=
875 WMGetListSelectedItemRow(panel
->icommandL
);
877 switch (data
->param
.command
.command
) {
879 data
->param
.command
.parameter
=
880 WMGetTextFieldText(panel
->paramT
);
884 if (changedWidget
== panel
->shortT
) {
885 REPLACE(data
->param
.command
.shortcut
,
886 WMGetTextFieldText(panel
->shortT
));
891 if (changedWidget
== panel
->pipeT
) {
892 REPLACE(data
->param
.pipe
.command
,
893 WMGetTextFieldText(panel
->pipeT
));
898 if (changedWidget
== panel
->pathT
) {
899 REPLACE(data
->param
.external
.path
,
900 WMGetTextFieldText(panel
->pathT
));
905 if (changedWidget
== panel
->dpathT
) {
906 REPLACE(data
->param
.directory
.directory
,
907 WMGetTextFieldText(panel
->dpathT
));
909 if (changedWidget
== panel
->dcommandT
) {
910 REPLACE(data
->param
.directory
.command
,
911 WMGetTextFieldText(panel
->dcommandT
));
913 if (changedWidget
== panel
->dstripB
) {
914 data
->param
.directory
.stripExt
=
915 WMGetButtonSelected(panel
->dstripB
);
930 menuItemCloned(WEditMenuDelegate
*delegate
, WEditMenu
*menu
,
931 WEditMenuItem
*origItem
, WEditMenuItem
*newItem
)
933 ItemData
*data
= WGetEditMenuItemData(origItem
);
939 #define DUP(s) (s) ? wstrdup(s) : NULL
941 newData
= NEW(ItemData
);
943 newData
->type
= data
->type
;
945 switch (data
->type
) {
947 data
->param
.exec
.command
= DUP(data
->param
.exec
.command
);
948 data
->param
.exec
.shortcut
= DUP(data
->param
.exec
.shortcut
);
952 data
->param
.command
.parameter
= DUP(data
->param
.command
.parameter
);
953 data
->param
.command
.shortcut
= DUP(data
->param
.command
.shortcut
);
957 data
->param
.pipe
.command
= DUP(data
->param
.pipe
.command
);
961 data
->param
.external
.path
= DUP(data
->param
.external
.path
);
965 data
->param
.directory
.directory
= DUP(data
->param
.directory
.directory
);
966 data
->param
.directory
.command
= DUP(data
->param
.directory
.command
);
975 WSetEditMenuItemData(newItem
, newData
, (WMCallback
*)freeItemData
);
981 static void menuItemEdited(struct WEditMenuDelegate
*delegate
, WEditMenu
*menu
,
984 _Panel
*panel
= (_Panel
*)delegate
->data
;
986 updateFrameTitle(panel
, WGetEditMenuItemTitle(item
), panel
->currentType
);
993 static Bool
shouldRemoveItem(struct WEditMenuDelegate
*delegate
,
994 WEditMenu
*menu
, WEditMenuItem
*item
)
996 _Panel
*panel
= (_Panel
*)delegate
->data
;
1001 if (WGetEditMenuSubmenu(menu
, item
)) {
1004 res
= WMRunAlertPanel(WMWidgetScreen(menu
), NULL
,
1005 _("Remove Submenu"),
1006 _("Removing this item will destroy all items inside\n"
1007 "the submenu. Do you really want to do that?"),
1009 _("Yes, don't ask again."));
1016 panel
->dontAsk
= True
;
1025 menuItemDeselected(WEditMenuDelegate
*delegate
, WEditMenu
*menu
,
1026 WEditMenuItem
*item
)
1028 _Panel
*panel
= (_Panel
*)delegate
->data
;
1030 changeInfoType(panel
, NULL
, NoInfo
);
1035 menuItemSelected(WEditMenuDelegate
*delegate
, WEditMenu
*menu
,
1036 WEditMenuItem
*item
)
1038 ItemData
*data
= WGetEditMenuItemData(item
);
1039 _Panel
*panel
= (_Panel
*)delegate
->data
;
1041 panel
->currentItem
= item
;
1044 changeInfoType(panel
, WGetEditMenuItemTitle(item
), data
->type
);
1046 switch (data
->type
) {
1051 WMSetTextFieldText(panel
->commandT
, data
->param
.exec
.command
);
1052 WMSetTextFieldText(panel
->shortT
, data
->param
.exec
.shortcut
);
1056 WMSelectListItem(panel
->icommandL
,
1057 data
->param
.command
.command
);
1058 WMSetListPosition(panel
->icommandL
,
1059 data
->param
.command
.command
- 2);
1060 WMSetTextFieldText(panel
->shortT
, data
->param
.command
.shortcut
);
1062 switch (data
->param
.command
.command
) {
1064 WMSetTextFieldText(panel
->paramT
,
1065 data
->param
.command
.parameter
);
1069 icommandLClicked(panel
->icommandL
, panel
);
1073 WMSetTextFieldText(panel
->pipeT
, data
->param
.pipe
.command
);
1077 WMSetTextFieldText(panel
->pathT
, data
->param
.external
.path
);
1081 WMSetTextFieldText(panel
->dpathT
, data
->param
.directory
.directory
);
1082 WMSetTextFieldText(panel
->dcommandT
, data
->param
.directory
.command
);
1083 WMSetButtonSelected(panel
->dstripB
, data
->param
.directory
.stripExt
);
1098 buildSubmenu(WMScreen
*scr
, proplist_t pl
)
1101 WEditMenuItem
*item
;
1106 tp
= PLGetArrayElement(pl
, 0);
1107 title
= PLGetString(tp
);
1109 menu
= WCreateEditMenu(scr
, title
);
1111 for (i
= 1; i
< PLGetNumberOfElements(pl
); i
++) {
1114 pi
= PLGetArrayElement(pl
, i
);
1116 tp
= PLGetArrayElement(pi
, 0);
1117 bp
= PLGetArrayElement(pi
, 1);
1119 title
= PLGetString(tp
);
1121 if (PLIsArray(bp
)) { /* it's a submenu */
1124 submenu
= buildSubmenu(scr
, pi
);
1126 item
= WAddMenuItemWithTitle(menu
, title
);
1128 WSetEditMenuSubmenu(menu
, item
, submenu
);
1132 item
= WAddMenuItemWithTitle(menu
, title
);
1134 data
= parseCommand(pi
);
1136 WSetEditMenuItemData(item
, data
, (WMCallback
*)freeItemData
);
1140 WSetEditMenuAcceptsDrop(menu
, True
);
1141 WSetEditMenuDelegate(menu
, &menuDelegate
);
1143 WMRealizeWidget(menu
);
1151 buildMenuFromPL(_Panel
*panel
, proplist_t pl
)
1153 panel
->menu
= buildSubmenu(WMWidgetScreen(panel
->win
), pl
);
1154 WMMapWidget(panel
->menu
);
1160 getDefaultMenu(_Panel
*panel
)
1162 proplist_t menu
, pmenu
;
1163 char *menuPath
, *gspath
;
1165 gspath
= wusergnusteppath();
1167 menuPath
= wmalloc(strlen(gspath
)+128);
1168 /* if there is a localized plmenu for the tongue put it's filename here */
1169 sprintf(menuPath
, _("%s/Library/WindowMaker/plmenu"), gspath
);
1171 menu
= PLGetProplistWithPath(menuPath
);
1173 wwarning("%s:could not read property list menu", menuPath
);
1175 if (strcmp("%s/Library/WindowMaker/plmenu",
1176 _("%s/Library/WindowMaker/plmenu"))!=0) {
1178 sprintf(menuPath
, "%s/Library/WindowMaker/plmenu", gspath
);
1179 menu
= PLGetProplistWithPath(menuPath
);
1180 wwarning("%s:could not read property list menu", menuPath
);
1185 sprintf(buffer
, _("Could not open default menu from '%s'"),
1187 WMRunAlertPanel(WMWidgetScreen(panel
->win
), panel
->win
,
1188 _("Error"), buffer
, _("OK"), NULL
, NULL
);
1205 showData(_Panel
*panel
)
1211 gspath
= wusergnusteppath();
1213 menuPath
= wmalloc(strlen(gspath
)+32);
1214 strcpy(menuPath
, gspath
);
1215 strcat(menuPath
, "/Defaults/WMRootMenu");
1217 pmenu
= PLGetProplistWithPath(menuPath
);
1219 if (!pmenu
|| !PLIsArray(pmenu
)) {
1222 res
= WMRunAlertPanel(WMWidgetScreen(panel
->win
), panel
->win
,
1224 _("The menu file format currently in use is not supported\n"
1225 "by this tool. Do you want to discard the current menu\n"
1226 "to use this tool?"),
1227 _("Yes, Discard and Update"),
1228 _("No, Keep Current Menu"), NULL
);
1230 if (res
== WAPRDefault
) {
1231 pmenu
= getDefaultMenu(panel
);
1234 pmenu
= PLMakeArrayFromElements(PLMakeString("Applications"),
1238 panel
->dontSave
= True
;
1243 panel
->menuPath
= menuPath
;
1245 buildMenuFromPL(panel
, pmenu
);
1265 processData(char *title
, ItemData
*data
)
1269 static char *pscut
= NULL
;
1270 static char *pomenu
= NULL
;
1274 pscut
= PLMakeString("SHORTCUT");
1275 pomenu
= PLMakeString("OPEN_MENU");
1278 item
= PLMakeArrayFromElements(PLMakeString(title
), NULL
);
1281 switch (data
->type
) {
1284 if (strpbrk(data
->param
.exec
.command
, "&$*|><?")) {
1293 if (notblank(data
->param
.exec
.shortcut
)) {
1294 PLAppendArrayElement(item
, pscut
);
1295 PLAppendArrayElement(item
,
1296 PLMakeString(data
->param
.exec
.shortcut
));
1299 PLAppendArrayElement(item
, PLMakeString(s1
));
1300 PLAppendArrayElement(item
, PLMakeString(data
->param
.exec
.command
));
1304 if (notblank(data
->param
.command
.shortcut
)) {
1305 PLAppendArrayElement(item
, pscut
);
1306 PLAppendArrayElement(item
,
1307 PLMakeString(data
->param
.command
.shortcut
));
1310 i
= data
->param
.command
.command
;
1312 PLAppendArrayElement(item
, PLMakeString(commandNames
[i
]));
1315 case 7: /* restart */
1316 if (data
->param
.command
.parameter
)
1317 PLAppendArrayElement(item
,
1318 PLMakeString(data
->param
.command
.parameter
));
1321 /* SHUTDOWN, QUIT QUICK */
1327 PLAppendArrayElement(item
, pomenu
);
1328 s1
= wstrappend("| ", data
->param
.pipe
.command
);
1329 PLAppendArrayElement(item
, PLMakeString(s1
));
1334 PLAppendArrayElement(item
, pomenu
);
1335 PLAppendArrayElement(item
, PLMakeString(data
->param
.external
.path
));
1343 l
= strlen(data
->param
.directory
.directory
);
1344 l
+= strlen(data
->param
.directory
.command
);
1347 PLAppendArrayElement(item
, pomenu
);
1350 sprintf(tmp
, "%s%s WITH %s",
1351 data
->param
.directory
.stripExt
? "-noext " : "",
1352 data
->param
.directory
.directory
,
1353 data
->param
.directory
.command
);
1355 PLAppendArrayElement(item
, PLMakeString(tmp
));
1361 PLAppendArrayElement(item
, PLMakeString("WORKSPACE_MENU"));
1374 processSubmenu(WEditMenu
*menu
)
1376 WEditMenuItem
*item
;
1383 s
= WGetEditMenuTitle(menu
);
1384 pl
= PLMakeString(s
);
1386 pmenu
= PLMakeArrayFromElements(pl
, NULL
);
1389 while ((item
= WGetEditMenuItem(menu
, i
++))) {
1392 s
= WGetEditMenuItemTitle(item
);
1394 submenu
= WGetEditMenuSubmenu(menu
, item
);
1396 pl
= processSubmenu(submenu
);
1398 pl
= processData(s
, WGetEditMenuItemData(item
));
1401 PLAppendArrayElement(pmenu
, pl
);
1410 buildPLFromMenu(_Panel
*panel
)
1414 menu
= processSubmenu(panel
->menu
);
1423 storeData(_Panel
*panel
)
1427 if (panel
->dontSave
)
1430 menu
= buildPLFromMenu(panel
);
1432 PLSetFilename(menu
, PLMakeString(panel
->menuPath
));
1441 InitMenu(WMScreen
*scr
, WMWindow
*win
)
1445 panel
= wmalloc(sizeof(_Panel
));
1446 memset(panel
, 0, sizeof(_Panel
));
1448 panel
->sectionName
= _("Applications Menu Definition");
1450 panel
->description
= _("Edit the menu for launching applications.");
1454 panel
->callbacks
.createWidgets
= createPanel
;
1455 panel
->callbacks
.updateDomain
= storeData
;
1457 AddSection(panel
, ICON_FILE
);