/* Menu.c- menu definition * * WPrefs - Window Maker Preferences Program * * Copyright (c) 1998 Alfredo K. Kojima * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ #include "WPrefs.h" #include #include #include typedef struct _Panel { WMFrame *frame; char *sectionName; char *description; CallbackRec callbacks; WMWindow *win; WMPopUpButton *cmd1P; WMPopUpButton *cmd2P; WMTextField *tit1T; WMTextField *tit2T; WMBrowser *browser; WMFrame *labF; WMTextField *labT; WMFrame *cmdF; WMPopUpButton *cmdP; WMButton *noconfirmB; WMFrame *proF; WMTextField *proT; WMLabel *infoL; WMFrame *pathF; WMTextField *pathT; WMLabel *pathL; WMFrame *shoF; WMTextField *shoT; WMButton *shoB; WMButton *guruB; /**/ proplist_t menu; proplist_t editedItem; proplist_t itemClipboard; /* for copy/paste */ char capturing; /* shortcut capture */ char unsaved; /* if there are unsaved changes */ char dontSave; } _Panel; #define ICON_FILE "menus" extern char *OpenMenuGuru(WMWindow *mainWindow); extern Bool AskMenuCopy(WMWindow *wwin); /* must match the indexes of the commands popup */ enum { CAddCommand = 0, CAddSubmenu = 1, CAddExternal = 2, CAddWorkspace = 3, CRemove = 4, CCut = 5, CCopy = 6, CPaste = 7 }; enum { CpExec = 0, CpShExec = 1, CpArrange = 2, CpHide = 3, CpShow = 4, CpExit = 5, CpShutdown = 6, CpRestart = 7, CpRestartWM = 8, CpSaveSession = 9, CpClearSession = 10, CpRefresh = 11, CpInfo = 12, CpLegal = 13 }; enum { TNothing, TExec, TShExec, TSimpleCommand, TRestart, TRestartWM, TExit, TExternalMenu, TWSMenu }; static void showData(_Panel *panel); static void fillBrowser(WMBrowserDelegate *self, WMBrowser *bPtr, int column, WMList *list); static void scrolledBrowser(WMBrowserDelegate *self, WMBrowser *sender); static WMBrowserDelegate browserDelegate = { NULL, /* data */ fillBrowser, /* createRowsForColumn */ NULL, /* titleOfColumn */ scrolledBrowser, /* didScroll */ NULL /* willScroll */ }; static Bool isMenu(proplist_t item) { if (PLGetNumberOfElements(item)==1) return True; return PLIsArray(PLGetArrayElement(item, 1)); } static void splitOpenMenuParameter(char *str, char **dirs, char **prog) { char *p; if (!(p = strstr(str, " WITH "))) { *dirs = wstrdup(str); *prog = NULL; } else { int i, j; i = strlen(str); j = strlen(p); *dirs = wmalloc(i-j+1); strncpy(*dirs, str, i-j+1); (*dirs)[i-j] = 0; p += 6; while (isspace(*p)) p++; if (*p!=0) { *prog = wmalloc(j); strcpy(*prog, p); } else { *prog = NULL; } } } static void changeItemTitle(proplist_t item, char *title) { proplist_t tmp; tmp = PLGetArrayElement(item, 0); PLRelease(tmp); PLRemoveArrayElement(item, 0); PLInsertArrayElement(item, title?PLMakeString(title):PLMakeString(""), 0); } static void removeParameter(proplist_t item) { proplist_t tmp; int index; if (strcmp(PLGetString(PLGetArrayElement(item, 1)), "SHORTCUT")==0) { index = 4; } else { index = 2; } tmp = PLGetArrayElement(item, index); PLRemoveArrayElement(item, index); if (tmp) PLRelease(tmp); } static void changeItemParameter(proplist_t item, char *param) { proplist_t tmp; int index; if (strcmp(PLGetString(PLGetArrayElement(item, 1)), "SHORTCUT")==0) { index = 4; } else { index = 2; } tmp = PLGetArrayElement(item, index); PLRemoveArrayElement(item, index); PLRelease(tmp); tmp = param?PLMakeString(param):PLMakeString(""); PLInsertArrayElement(item, tmp, index); } static void changeItemShortcut(proplist_t item, char *shortcut) { proplist_t tmp; if (strcmp(PLGetString(PLGetArrayElement(item, 1)), "SHORTCUT")==0) { if (shortcut) { tmp = PLGetArrayElement(item, 2); PLRemoveArrayElement(item, 2); PLRelease(tmp); PLInsertArrayElement(item, PLMakeString(shortcut), 2); } else { /* remove SHORTCUT keyword */ tmp = PLGetArrayElement(item, 1); PLRemoveArrayElement(item, 1); PLRelease(tmp); /* remove the shortcut */ tmp = PLGetArrayElement(item, 1); PLRemoveArrayElement(item, 1); PLRelease(tmp); } } else { if (shortcut) { PLInsertArrayElement(item, PLMakeString("SHORTCUT"), 1); PLInsertArrayElement(item, PLMakeString(shortcut), 2); } else { /* do nothing */ } } } static void changeItemCommand(proplist_t item, char *command) { proplist_t tmp; tmp = PLGetArrayElement(item, 1); if (strcmp(PLGetString(tmp), "SHORTCUT")==0) { PLRelease(tmp); PLRemoveArrayElement(item, 3); PLInsertArrayElement(item, PLMakeString(command), 3); } else { PLRelease(tmp); PLRemoveArrayElement(item, 1); PLInsertArrayElement(item, PLMakeString(command), 1); } } static char* getItemTitle(proplist_t item) { return PLGetString(PLGetArrayElement(item, 0)); } static char* getItemParameter(proplist_t item) { proplist_t tmp; tmp = PLGetArrayElement(item, 1); if (strcmp(PLGetString(tmp), "SHORTCUT")==0) { tmp = PLGetArrayElement(item, 4); return tmp ? PLGetString(tmp) : NULL; } else { tmp = PLGetArrayElement(item, 2); return tmp ? PLGetString(tmp) : NULL; } } static char* getItemShortcut(proplist_t item) { proplist_t tmp; tmp = PLGetArrayElement(item, 1); if (strcmp(PLGetString(tmp), "SHORTCUT")==0) { return PLGetString(PLGetArrayElement(item, 2)); } else { return NULL; } } static char* getItemCommand(proplist_t item) { proplist_t tmp; char *str; tmp = PLGetArrayElement(item, 1); if (!tmp) return ""; if (strcmp(PLGetString(tmp), "SHORTCUT")==0) { str = PLGetString(PLGetArrayElement(item,3)); } else { str = PLGetString(tmp); } return str; } static proplist_t getSubmenuInColumn(_Panel *panel, int column) { proplist_t parent; proplist_t submenu; WMList *list; int r; if (column == 0) { return panel->menu; } if (column >= WMGetBrowserNumberOfColumns(panel->browser)) return NULL; list = WMGetBrowserListInColumn(panel->browser, column - 1); assert(list != NULL); r = WMGetListSelectedItemRow(list); parent = getSubmenuInColumn(panel, column - 1); assert(parent != NULL); submenu = PLGetArrayElement(parent, r + 1); return submenu; } static void updateForItemType(_Panel *panel, int type) { if (type==TNothing) { WMUnmapWidget(panel->labF); } else { WMMapWidget(panel->labF); } if (type==TExternalMenu || type==TNothing) { WMUnmapWidget(panel->cmdF); } else { WMMapWidget(panel->cmdF); } if (type==TNothing || type==TWSMenu || type==TExternalMenu) { WMUnmapWidget(panel->shoF); } else { WMMapWidget(panel->shoF); } if (type==TExec || type == TShExec || type==TRestart || type==TExternalMenu) { WMMapWidget(panel->proF); } else { WMUnmapWidget(panel->proF); } if (type==TExternalMenu) { WMMapWidget(panel->pathF); } else { WMUnmapWidget(panel->pathF); } if (type==TExit) { WMMapWidget(panel->noconfirmB); } else { WMUnmapWidget(panel->noconfirmB); } if (type==TWSMenu) { WMMapWidget(panel->infoL); } else { WMUnmapWidget(panel->infoL); } if (type==TExternalMenu) { WMMapWidget(panel->guruB); } else { WMUnmapWidget(panel->guruB); } if (type == TRestart) { WMSetFrameTitle(panel->proF, _("Window Manager")); } else if (type == TExternalMenu) { WMSetFrameTitle(panel->proF, _("Program to Open Files")); } else if (type == TShExec) { WMSetFrameTitle(panel->proF, _("Command to Execute")); } else { WMSetFrameTitle(panel->proF, _("Program to Run")); } } proplist_t getItemOfSelectedEntry(WMBrowser *bPtr) { proplist_t item; proplist_t menu; int i; i = WMGetBrowserSelectedColumn(bPtr); menu = getSubmenuInColumn((_Panel*)WMGetHangedData(bPtr), i); i = WMGetBrowserSelectedRowInColumn(bPtr, i); item = PLGetArrayElement(menu, i+1); return item; } static void performCommand(WMWidget *w, void *data) { _Panel *panel = (_Panel*)data; WMPopUpButton *pop = (WMPopUpButton*)w; proplist_t menuItem = NULL; proplist_t menu; int column; int row; static int cmdIndex=0; char *title = NULL; Bool removed = False; column = WMGetBrowserFirstVisibleColumn(panel->browser); if (pop == panel->cmd2P) { column++; } if (column >= WMGetBrowserNumberOfColumns(panel->browser)) return; menu = getSubmenuInColumn(panel, column); row = WMGetBrowserSelectedRowInColumn(panel->browser, column); switch (WMGetPopUpButtonSelectedItem(pop)) { case CAddCommand: title = wmalloc(strlen(_("New Command %i"))+6); sprintf(title, _("New Command %i"), cmdIndex++); menuItem = PLMakeArrayFromElements(PLMakeString(title), PLMakeString("EXEC"), PLMakeString(""), NULL); break; case CAddSubmenu: title = wstrdup(_("New Submenu")); menuItem = PLMakeArrayFromElements(PLMakeString(title), NULL); break; case CAddExternal: title = wstrdup(_("External Menu")); menuItem = PLMakeArrayFromElements(PLMakeString(title), PLMakeString("OPEN_MENU"), PLMakeString(""), NULL); break; case CAddWorkspace: title = wstrdup(_("Workspaces")); menuItem = PLMakeArrayFromElements(PLMakeString(title), PLMakeString("WORKSPACE_MENU"), NULL); WMSetPopUpButtonItemEnabled(panel->cmd1P, CAddWorkspace, False); WMSetPopUpButtonItemEnabled(panel->cmd2P, CAddWorkspace, False); break; case CRemove: if (row < 0) return; WMRemoveBrowserItem(panel->browser, column, row); menuItem = PLGetArrayElement(menu, row+1); if (strcmp(getItemCommand(menuItem), "WORKSPACE_MENU")==0) { WMSetPopUpButtonItemEnabled(panel->cmd1P, CAddWorkspace, True); WMSetPopUpButtonItemEnabled(panel->cmd2P, CAddWorkspace, True); } PLRemoveArrayElement(menu, row+1); PLRelease(menuItem); updateForItemType(panel, TNothing); panel->editedItem = NULL; panel->unsaved = 1; if (pop == panel->cmd1P) { WMSetTextFieldText(panel->tit2T, NULL); } removed = True; return; case CCut: if (row < 0) return; if (panel->itemClipboard && strcmp(getItemCommand(panel->itemClipboard), "WORKSPACE_MENU")==0){ WMSetPopUpButtonItemEnabled(panel->cmd1P, CAddWorkspace, True); WMSetPopUpButtonItemEnabled(panel->cmd2P, CAddWorkspace, True); } if (panel->itemClipboard) PLRelease(panel->itemClipboard); WMRemoveBrowserItem(panel->browser, column, row); menuItem = PLGetArrayElement(menu, row+1); PLRemoveArrayElement(menu, row+1); updateForItemType(panel, TNothing); panel->itemClipboard = menuItem; WMSetPopUpButtonItemEnabled(panel->cmd1P, CPaste, True); WMSetPopUpButtonItemEnabled(panel->cmd2P, CPaste, True); panel->unsaved = 1; removed = True; return; case CCopy: if (row < 0) return; if (panel->itemClipboard && strcmp(getItemCommand(panel->itemClipboard), "WORKSPACE_MENU")==0){ WMSetPopUpButtonItemEnabled(panel->cmd1P, CAddWorkspace, True); WMSetPopUpButtonItemEnabled(panel->cmd2P, CAddWorkspace, True); } if (panel->itemClipboard) PLRelease(panel->itemClipboard); panel->itemClipboard = NULL; menuItem = PLGetArrayElement(menu, row+1); if (strcmp(getItemCommand(menuItem), "WORKSPACE_MENU")==0) return; panel->itemClipboard = PLDeepCopy(menuItem); WMSetPopUpButtonItemEnabled(panel->cmd1P, CPaste, True); WMSetPopUpButtonItemEnabled(panel->cmd2P, CPaste, True); return; case CPaste: menuItem = panel->itemClipboard; title = wstrdup(getItemTitle(menuItem)); panel->itemClipboard = NULL; WMSetPopUpButtonItemEnabled(panel->cmd1P, CPaste, False); WMSetPopUpButtonItemEnabled(panel->cmd2P, CPaste, False); break; } if (row>=0) row++; WMInsertBrowserItem(panel->browser, column, row, title, isMenu(menuItem)); if (row<0) PLAppendArrayElement(menu, menuItem); else PLInsertArrayElement(menu, menuItem, row+1); free(title); panel->unsaved = 1; if (removed) { if (pop == panel->cmd1P) { WMSetTextFieldText(panel->tit2T, NULL); } } } static void browserClick(WMWidget *w, void *data) { _Panel *panel = (_Panel*)data; proplist_t item; char *command; /* stop shortcut capture */ panel->capturing = 0; item = getItemOfSelectedEntry(panel->browser); panel->editedItem = item; /* set title */ WMSetTextFieldText(panel->labT, getItemTitle(item)); if (isMenu(item)) { updateForItemType(panel, TNothing); WMSetPopUpButtonEnabled(panel->cmd2P, True); return; } else { int column = WMGetBrowserSelectedColumn(panel->browser); if (column == WMGetBrowserNumberOfColumns(panel->browser)-1 && column > 0) WMSetPopUpButtonEnabled(panel->cmd2P, True); else WMSetPopUpButtonEnabled(panel->cmd2P, False); if (column==WMGetBrowserFirstVisibleColumn(panel->browser)) { /* second column is empty, because selected item is not a submenu */ WMSetTextFieldText(panel->tit2T, NULL); } } command = getItemCommand(item); WMSetTextFieldText(panel->shoT, getItemShortcut(item)); if (strcmp(command, "OPEN_MENU")==0) { char *p, *c; splitOpenMenuParameter(getItemParameter(item), &p, &c); WMSetTextFieldText(panel->pathT, p); WMSetTextFieldText(panel->proT, c); if (p) free(p); if (c) free(c); updateForItemType(panel, TExternalMenu); } else if (strcmp(command, "EXEC")==0) { WMSetTextFieldText(panel->proT, getItemParameter(item)); WMSetPopUpButtonSelectedItem(panel->cmdP, CpExec); updateForItemType(panel, TExec); } else if (strcmp(command, "SHEXEC")==0) { WMSetTextFieldText(panel->proT, getItemParameter(item)); WMSetPopUpButtonSelectedItem(panel->cmdP, CpShExec); updateForItemType(panel, TShExec); } else if (strcmp(command, "WORKSPACE_MENU")==0) { updateForItemType(panel, TWSMenu); } else if (strcmp(command, "EXIT")==0) { WMSetPopUpButtonSelectedItem(panel->cmdP, CpExit); updateForItemType(panel, TExit); } else if (strcmp(command, "SHUTDOWN")==0) { WMSetPopUpButtonSelectedItem(panel->cmdP, CpShutdown); updateForItemType(panel, TExit); } else if (strcmp(command, "RESTARTW")==0) { WMSetPopUpButtonSelectedItem(panel->cmdP, CpRestartWM); updateForItemType(panel, TRestartWM); } else if (strcmp(command, "RESTART")==0) { WMSetPopUpButtonSelectedItem(panel->cmdP, CpRestart); WMSetTextFieldText(panel->proT, getItemParameter(item)); updateForItemType(panel, TRestart); } else { /* simple commands */ if (strcmp(command, "ARRANGE_ICONS")==0) WMSetPopUpButtonSelectedItem(panel->cmdP, CpArrange); else if (strcmp(command, "HIDE_OTHERS")==0) WMSetPopUpButtonSelectedItem(panel->cmdP, CpHide); else if (strcmp(command, "SHOW_ALL")==0) WMSetPopUpButtonSelectedItem(panel->cmdP, CpShow); else if (strcmp(command, "SAVE_SESSION")==0) WMSetPopUpButtonSelectedItem(panel->cmdP, CpSaveSession); else if (strcmp(command, "CLEAR_SESSION")==0) WMSetPopUpButtonSelectedItem(panel->cmdP, CpClearSession); else if (strcmp(command, "REFRESH")==0) WMSetPopUpButtonSelectedItem(panel->cmdP, CpRefresh); else if (strcmp(command, "INFO_PANEL")==0) WMSetPopUpButtonSelectedItem(panel->cmdP, CpInfo); else if (strcmp(command, "LEGAL_PANEL")==0) WMSetPopUpButtonSelectedItem(panel->cmdP, CpLegal); updateForItemType(panel, TSimpleCommand); } } static void fillBrowser(WMBrowserDelegate *self, WMBrowser *bPtr, int column, WMList *list) { _Panel *panel = (_Panel*)WMGetHangedData(bPtr); proplist_t menuItem; proplist_t menuList = NULL; int i; menuList = getSubmenuInColumn(panel, column); assert(menuList != NULL); if (column > WMGetBrowserFirstVisibleColumn(bPtr)) { WMSetTextFieldText(panel->tit2T, getItemTitle(menuList)); } else { WMSetTextFieldText(panel->tit1T, getItemTitle(menuList)); } for (i=1; ieditedItem; WMList *list; WMListItem *litem; char *command; char *str; if (!item) return; panel->unsaved = 1; if (!isMenu(item)) { command = getItemCommand(item); if (t == panel->shoT) { str = WMGetTextFieldText(t); if (strlen(str)==0) { free(str); str = NULL; } changeItemShortcut(item, str); if (str) free(str); } else if (t == panel->labT) { int column; str = WMGetTextFieldText(t); if (!str) str = wstrdup(""); changeItemTitle(item, str); column = WMGetBrowserSelectedColumn(panel->browser); list = WMGetBrowserListInColumn(panel->browser, column); litem = WMGetListSelectedItem(list); free(litem->text); litem->text = str; WMRedisplayWidget(list); } else if (strcmp(command, "EXEC")==0 || strcmp(command, "SHEXEC")==0 || strcmp(command, "RESTART")==0) { if (t == panel->proT) { str = WMGetTextFieldText(t); changeItemParameter(item, str); free(str); } } else if (strcmp(command, "OPEN_MENU")==0) { char *text; char *str2; str = WMGetTextFieldText(panel->pathT); str2 = WMGetTextFieldText(panel->proT); text = wmalloc(strlen(str)+strlen(str2)+16); strcpy(text, str); free(str); if (strlen(str2)>0) { strcat(text, " WITH "); strcat(text, str2); } free(str2); changeItemParameter(item, text); free(text); } } } static void changedTitle(void *observerData, WMNotification *notification) { _Panel *panel = (_Panel*)observerData; WMTextField *t = (WMTextField*)WMGetNotificationObject(notification); proplist_t menu; WMList *list; int column; char *txt; column = WMGetBrowserFirstVisibleColumn(panel->browser); if (panel->tit2T == t) column++; menu = getSubmenuInColumn(panel, column); if (!menu) return; txt = WMGetTextFieldText(t); changeItemTitle(menu, txt); if (column > 0) { WMListItem *litem; list = WMGetBrowserListInColumn(panel->browser, column-1); litem = WMGetListSelectedItem(list); free(litem->text); litem->text = txt; WMRedisplayWidget(list); } else { free(txt); } panel->unsaved = 1; } static void changedCommand(WMWidget *w, void *data) { _Panel *panel = (_Panel*)data; int i; char *tmp; panel->unsaved = 1; i = WMGetPopUpButtonSelectedItem(panel->cmdP); changeItemParameter(panel->editedItem, ""); switch (i) { case CpExec: if (strcmp(getItemCommand(panel->editedItem), "EXEC")!=0) { changeItemCommand(panel->editedItem, "EXEC"); tmp = WMGetTextFieldText(panel->proT); changeItemParameter(panel->editedItem, tmp); free(tmp); updateForItemType(panel, TExec); } break; case CpShExec: if (strcmp(getItemCommand(panel->editedItem), "SHEXEC")!=0) { changeItemCommand(panel->editedItem, "SHEXEC"); tmp = WMGetTextFieldText(panel->proT); changeItemParameter(panel->editedItem, tmp); free(tmp); updateForItemType(panel, TShExec); } break; case CpArrange: if (strcmp(getItemCommand(panel->editedItem), "ARRANGE_ICONS")!=0) { changeItemCommand(panel->editedItem, "ARRANGE_ICONS"); updateForItemType(panel, TSimpleCommand); } break; case CpHide: if (strcmp(getItemCommand(panel->editedItem), "HIDE_OTHERS")!=0) { changeItemCommand(panel->editedItem, "HIDE_OTHERS"); updateForItemType(panel, TSimpleCommand); } break; case CpShow: if (strcmp(getItemCommand(panel->editedItem), "SHOW_ALL")!=0) { changeItemCommand(panel->editedItem, "SHOW_ALL"); updateForItemType(panel, TSimpleCommand); } break; case CpExit: if (strcmp(getItemCommand(panel->editedItem), "EXIT")!=0) { changeItemCommand(panel->editedItem, "EXIT"); updateForItemType(panel, TExit); } if (WMGetButtonSelected(panel->noconfirmB)) changeItemParameter(panel->editedItem, "QUICK"); else changeItemParameter(panel->editedItem, ""); break; case CpShutdown: if (strcmp(getItemCommand(panel->editedItem), "SHUTDOWN")!=0) { changeItemCommand(panel->editedItem, "SHUTDOWN"); updateForItemType(panel, TExit); } if (WMGetButtonSelected(panel->noconfirmB)) changeItemParameter(panel->editedItem, "QUICK"); else changeItemParameter(panel->editedItem, ""); break; case CpRestartWM: changeItemCommand(panel->editedItem, "RESTARTW"); updateForItemType(panel, TRestartWM); break; case CpRestart: changeItemCommand(panel->editedItem, "RESTART"); updateForItemType(panel, TRestart); tmp = WMGetTextFieldText(panel->proT); changeItemParameter(panel->editedItem, tmp); free(tmp); break; case CpSaveSession: if (strcmp(getItemCommand(panel->editedItem), "SAVE_SESSION")!=0) { changeItemCommand(panel->editedItem, "SAVE_SESSION"); updateForItemType(panel, TSimpleCommand); } break; case CpClearSession: if (strcmp(getItemCommand(panel->editedItem), "CLEAR_SESSION")!=0) { changeItemCommand(panel->editedItem, "CLEAR_SESSION"); updateForItemType(panel, TSimpleCommand); } break; case CpRefresh: if (strcmp(getItemCommand(panel->editedItem), "REFRESH")!=0) { changeItemCommand(panel->editedItem, "REFRESH"); updateForItemType(panel, TSimpleCommand); } break; case CpInfo: if (strcmp(getItemCommand(panel->editedItem), "INFO_PANEL")!=0) { changeItemCommand(panel->editedItem, "INFO_PANEL"); updateForItemType(panel, TSimpleCommand); } break; case CpLegal: if (strcmp(getItemCommand(panel->editedItem), "LEGAL_PANEL")!=0) { changeItemCommand(panel->editedItem, "LEGAL_PANEL"); updateForItemType(panel, TSimpleCommand); } break; } } static char* captureShortcut(Display *dpy, _Panel *panel) { XEvent ev; KeySym ksym; char buffer[64]; char *key = NULL; while (panel->capturing) { XAllowEvents(dpy, AsyncKeyboard, CurrentTime); WMNextEvent(dpy, &ev); if (ev.type==KeyPress && ev.xkey.keycode!=0) { ksym = XKeycodeToKeysym(dpy, ev.xkey.keycode, 0); if (!IsModifierKey(ksym)) { key=XKeysymToString(ksym); panel->capturing = 0; break; } } WMHandleEvent(&ev); } if (!key) return NULL; buffer[0] = 0; if (ev.xkey.state & ControlMask) { strcat(buffer, "Control+"); } if (ev.xkey.state & ShiftMask) { strcat(buffer, "Shift+"); } if (ev.xkey.state & Mod1Mask) { strcat(buffer, "Mod1+"); } if (ev.xkey.state & Mod2Mask) { strcat(buffer, "Mod2+"); } if (ev.xkey.state & Mod3Mask) { strcat(buffer, "Mod3+"); } if (ev.xkey.state & Mod4Mask) { strcat(buffer, "Mod4+"); } if (ev.xkey.state & Mod5Mask) { strcat(buffer, "Mod5+"); } strcat(buffer, key); return wstrdup(buffer); } static void captureClick(WMWidget *w, void *data) { _Panel *panel = (_Panel*)data; Display *dpy = WMScreenDisplay(WMWidgetScreen(panel->win)); char *shortcut; if (!panel->capturing) { panel->capturing = 1; WMSetButtonText(w, _("Cancel")); XGrabKeyboard(dpy, WMWidgetXID(panel->win), True, GrabModeAsync, GrabModeAsync, CurrentTime); shortcut = captureShortcut(dpy, panel); if (shortcut) { WMSetTextFieldText(panel->shoT, shortcut); changeItemShortcut(panel->editedItem, shortcut); panel->unsaved = 1; } free(shortcut); } panel->capturing = 0; WMSetButtonText(w, _("Capture")); XUngrabKeyboard(dpy, CurrentTime); } static void scrolledBrowser(WMBrowserDelegate *self, WMBrowser *sender) { _Panel *panel = (_Panel*)self->data; int column; proplist_t item; column = WMGetBrowserFirstVisibleColumn(sender); item = getSubmenuInColumn(panel, column); WMSetTextFieldText(panel->tit1T, getItemTitle(item)); item = getSubmenuInColumn(panel, column + 1); if (item) WMSetTextFieldText(panel->tit2T, getItemTitle(item)); } static void confirmClicked(WMWidget *w, void *data) { _Panel *panel = (_Panel*)data; if (WMGetButtonSelected(panel->noconfirmB)) { changeItemParameter(panel->editedItem, "QUICK"); } else { changeItemParameter(panel->editedItem, ""); } panel->unsaved = 1; } static void openGuru(WMWidget *w, void *data) { _Panel *panel = (_Panel*)data; char *def; char *path, *cmd; def = OpenMenuGuru(GetWindow(panel)); if (def) { changeItemParameter(panel->editedItem, def); splitOpenMenuParameter(def, &path, &cmd); free(def); WMSetTextFieldText(panel->pathT, path); if (path) free(path); WMSetTextFieldText(panel->proT, cmd); if (cmd) free(cmd); panel->unsaved = 1; } } static void createPanel(_Panel *p) { _Panel *panel = (_Panel*)p; panel->frame = WMCreateFrame(panel->win); WMResizeWidget(panel->frame, FRAME_WIDTH, FRAME_HEIGHT); WMMoveWidget(panel->frame, FRAME_LEFT, FRAME_TOP); panel->cmd1P = WMCreatePopUpButton(panel->frame); WMSetPopUpButtonAction(panel->cmd1P, performCommand, panel); WMResizeWidget(panel->cmd1P, 144, 20); WMMoveWidget(panel->cmd1P, 15, 15); WMSetPopUpButtonPullsDown(panel->cmd1P, True); WMSetPopUpButtonText(panel->cmd1P, _("Commands")); WMAddPopUpButtonItem(panel->cmd1P, _("Add Command")); WMAddPopUpButtonItem(panel->cmd1P, _("Add Submenu")); WMAddPopUpButtonItem(panel->cmd1P, _("Add External Menu")); WMAddPopUpButtonItem(panel->cmd1P, _("Add Workspace Menu")); WMAddPopUpButtonItem(panel->cmd1P, _("Remove Item")); WMAddPopUpButtonItem(panel->cmd1P, _("Cut Item")); WMAddPopUpButtonItem(panel->cmd1P, _("Copy Item")); WMAddPopUpButtonItem(panel->cmd1P, _("Paste Item")); panel->cmd2P = WMCreatePopUpButton(panel->frame); WMSetPopUpButtonAction(panel->cmd2P, performCommand, panel); WMResizeWidget(panel->cmd2P, 144, 20); WMMoveWidget(panel->cmd2P, 164, 15); WMSetPopUpButtonPullsDown(panel->cmd2P, True); WMSetPopUpButtonText(panel->cmd2P, _("Commands")); WMAddPopUpButtonItem(panel->cmd2P, _("Add Command")); WMAddPopUpButtonItem(panel->cmd2P, _("Add Submenu")); WMAddPopUpButtonItem(panel->cmd2P, _("Add External Menu")); WMAddPopUpButtonItem(panel->cmd2P, _("Add Workspace Menu")); WMAddPopUpButtonItem(panel->cmd2P, _("Remove Item")); WMAddPopUpButtonItem(panel->cmd2P, _("Cut Item")); WMAddPopUpButtonItem(panel->cmd2P, _("Copy Item")); WMAddPopUpButtonItem(panel->cmd2P, _("Paste Item")); panel->tit1T = WMCreateTextField(panel->frame); WMResizeWidget(panel->tit1T, 144, 20); WMMoveWidget(panel->tit1T, 15, 40); WMAddNotificationObserver(changedTitle, panel, WMTextDidChangeNotification, panel->tit1T); panel->tit2T = WMCreateTextField(panel->frame); WMResizeWidget(panel->tit2T, 144, 20); WMMoveWidget(panel->tit2T, 164, 40); WMAddNotificationObserver(changedTitle, panel, WMTextDidChangeNotification, panel->tit2T); panel->browser = WMCreateBrowser(panel->frame); WMSetBrowserTitled(panel->browser, False); WMResizeWidget(panel->browser, 295, 160); WMMoveWidget(panel->browser, 15, 65); WMSetBrowserDelegate(panel->browser, &browserDelegate); WMHangData(panel->browser, panel); WMSetBrowserPathSeparator(panel->browser, "\r"); WMSetBrowserAction(panel->browser, browserClick, panel); /**/ panel->labF = WMCreateFrame(panel->frame); WMResizeWidget(panel->labF, 190, 50); WMMoveWidget(panel->labF, 320, 10); WMSetFrameTitle(panel->labF, _("Label")); panel->labT = WMCreateTextField(panel->labF); WMResizeWidget(panel->labT, 170, 20); WMMoveWidget(panel->labT, 10, 20); WMAddNotificationObserver(changedItem, panel, WMTextDidChangeNotification, panel->labT); WMMapSubwidgets(panel->labF); panel->cmdF = WMCreateFrame(panel->frame); WMResizeWidget(panel->cmdF, 190, 50); WMMoveWidget(panel->cmdF, 320, 65); WMSetFrameTitle(panel->cmdF, _("Command")); panel->cmdP = WMCreatePopUpButton(panel->cmdF); WMResizeWidget(panel->cmdP, 170, 20); WMMoveWidget(panel->cmdP, 10, 20); WMAddPopUpButtonItem(panel->cmdP, _("Run Program")); WMAddPopUpButtonItem(panel->cmdP, _("Execute Shell Command")); WMAddPopUpButtonItem(panel->cmdP, _("Arrange Icons")); WMAddPopUpButtonItem(panel->cmdP, _("Hide Others")); WMAddPopUpButtonItem(panel->cmdP, _("Show All Windows")); WMAddPopUpButtonItem(panel->cmdP, _("Exit WindowMaker")); WMAddPopUpButtonItem(panel->cmdP, _("Exit X Session")); WMAddPopUpButtonItem(panel->cmdP, _("Start Window Manager")); WMAddPopUpButtonItem(panel->cmdP, _("Restart WindowMaker")); WMAddPopUpButtonItem(panel->cmdP, _("Save Session")); WMAddPopUpButtonItem(panel->cmdP, _("Clear Session")); WMAddPopUpButtonItem(panel->cmdP, _("Refresh Screen")); WMAddPopUpButtonItem(panel->cmdP, _("Info Panel")); WMAddPopUpButtonItem(panel->cmdP, _("Legal Panel")); WMSetPopUpButtonAction(panel->cmdP, changedCommand, panel); WMMapSubwidgets(panel->cmdF); panel->infoL = WMCreateLabel(panel->frame); WMResizeWidget(panel->infoL, 190, 50); WMMoveWidget(panel->infoL, 320, 65); WMSetLabelText(panel->infoL, _("Open workspace menu")); WMSetLabelRelief(panel->infoL, WRGroove); WMSetLabelTextAlignment(panel->infoL, WACenter); panel->noconfirmB = WMCreateSwitchButton(panel->frame); WMResizeWidget(panel->noconfirmB, 190, 50); WMMoveWidget(panel->noconfirmB, 320, 120); WMSetButtonText(panel->noconfirmB, _("No confirmation panel")); WMSetButtonAction(panel->noconfirmB, confirmClicked, panel); panel->pathF = WMCreateFrame(panel->frame); WMResizeWidget(panel->pathF, 190, 50); WMMoveWidget(panel->pathF, 320, 65); WMSetFrameTitle(panel->pathF, _("Menu Path/Directory List")); panel->pathT = WMCreateTextField(panel->pathF); WMResizeWidget(panel->pathT, 170, 20); WMMoveWidget(panel->pathT, 10, 20); WMAddNotificationObserver(changedItem, panel, WMTextDidChangeNotification, panel->pathT); WMMapSubwidgets(panel->pathF); panel->proF = WMCreateFrame(panel->frame); WMResizeWidget(panel->proF, 190, 50); WMMoveWidget(panel->proF, 320, 120); WMSetFrameTitle(panel->proF, _("Program to Run")); panel->proT = WMCreateTextField(panel->proF); WMResizeWidget(panel->proT, 170, 20); WMMoveWidget(panel->proT, 10, 20); WMAddNotificationObserver(changedItem, panel, WMTextDidChangeNotification, panel->proT); WMMapSubwidgets(panel->proF); panel->shoF = WMCreateFrame(panel->frame); WMResizeWidget(panel->shoF, 190, 50); WMMoveWidget(panel->shoF, 320, 175); WMSetFrameTitle(panel->shoF, _("Shortcut")); panel->shoT = WMCreateTextField(panel->shoF); WMResizeWidget(panel->shoT, 95, 20); WMMoveWidget(panel->shoT, 10, 20); WMAddNotificationObserver(changedItem, panel, WMTextDidChangeNotification, panel->shoT); panel->shoB = WMCreateCommandButton(panel->shoF); WMResizeWidget(panel->shoB, 70, 24); WMMoveWidget(panel->shoB, 110, 18); WMSetButtonText(panel->shoB, _("Capture")); WMSetButtonAction(panel->shoB, captureClick, panel); WMMapSubwidgets(panel->shoF); panel->guruB = WMCreateCommandButton(panel->frame); WMResizeWidget(panel->guruB, 180, 24); WMMoveWidget(panel->guruB, 325, 190); WMSetButtonText(panel->guruB, _("Ask help to the Guru")); WMSetButtonAction(panel->guruB, openGuru, panel); WMRealizeWidget(panel->frame); WMMapSubwidgets(panel->frame); showData(panel); } static proplist_t preProcessMenu(proplist_t menu, int *hasWSMenu) { proplist_t pmenu; proplist_t item; int i; pmenu = PLDeepCopy(menu); if (PLGetNumberOfElements(pmenu)==1) { return pmenu; } for (i=1; iwin), panel->win, _("Error"), buffer, _("OK"), NULL, NULL); } } free(menuPath); if (menu) { pmenu = preProcessMenu(menu, hasWSMenu); PLRelease(menu); } else { pmenu = NULL; } return pmenu; } static void showData(_Panel *panel) { char *gspath; char *menuPath; proplist_t menu, pmenu, plPath; int hasWSMenu = 0; gspath = wusergnusteppath(); menuPath = wmalloc(strlen(gspath)+32); strcpy(menuPath, gspath); strcat(menuPath, "/Defaults/WMRootMenu"); menu = PLGetProplistWithPath(menuPath); pmenu = NULL; if (!menu || !PLIsArray(menu)) { if (AskMenuCopy(panel->win)) { panel->dontSave = 0; panel->unsaved = 1; pmenu = getDefaultMenu(panel, &hasWSMenu); } else { WMSetPopUpButtonEnabled(panel->cmd1P, False); WMSetPopUpButtonEnabled(panel->cmd2P, False); panel->dontSave = 1; } if (!pmenu) { pmenu = PLMakeArrayFromElements(PLMakeString("Applications"), NULL); } } else { pmenu = preProcessMenu(menu, &hasWSMenu); } plPath = PLMakeString(menuPath); free(menuPath); PLSetFilename(pmenu, plPath); PLRelease(plPath); if (menu) PLRelease(menu); if (panel->itemClipboard) { PLRelease(panel->itemClipboard); panel->itemClipboard = NULL; } panel->menu = pmenu; panel->editedItem = NULL; panel->capturing = 0; WMSetPopUpButtonItemEnabled(panel->cmd1P, CPaste, False); WMSetPopUpButtonItemEnabled(panel->cmd2P, CPaste, False); if (hasWSMenu) { WMSetPopUpButtonItemEnabled(panel->cmd1P, CAddWorkspace, False); WMSetPopUpButtonItemEnabled(panel->cmd2P, CAddWorkspace, False); } WMLoadBrowserColumnZero(panel->browser); updateForItemType(panel, TNothing); } static void storeData(_Panel *panel) { proplist_t menu; if (!panel->unsaved || panel->dontSave) return; panel->unsaved = 0; menu = postProcessMenu(panel->menu); PLSetFilename(menu, PLGetFilename(panel->menu)); PLSave(menu, YES); PLRelease(menu); } Panel* InitMenu(WMScreen *scr, WMWindow *win) { _Panel *panel; panel = wmalloc(sizeof(_Panel)); memset(panel, 0, sizeof(_Panel)); panel->sectionName = _("Applications Menu Definition"); panel->description = _("Edit the menu for launching applications."); panel->win = win; panel->callbacks.createWidgets = createPanel; panel->callbacks.updateDomain = storeData; AddSection(panel, ICON_FILE); return panel; }