1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-18 20:10:29 +01:00
Files
wmaker/WPrefs.app/Menu.c
kojima dd2d71fc9b started Appearance update in WPrefs
added tabbed view
changed some callbacks to delegate like stuff (textfield and browser)
1999-05-15 17:38:05 +00:00

1495 lines
38 KiB
C

/* 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 <assert.h>
#include <ctype.h>
#include <X11/keysym.h>
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; i<PLGetNumberOfElements(menuList); i++) {
menuItem = PLGetArrayElement(menuList, i);
WMInsertBrowserItem(bPtr, column, -1, getItemTitle(menuItem),
isMenu(menuItem));
}
}
static void
changedItem(void *observerData, WMNotification *notification)
{
_Panel *panel = (_Panel*)observerData;
WMTextField *t = (WMTextField*)WMGetNotificationObject(notification);
proplist_t item = panel->editedItem;
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; i<PLGetNumberOfElements(pmenu); i++) {
item = PLGetArrayElement(pmenu, i);
if (isMenu(item)) {
PLInsertArrayElement(pmenu, preProcessMenu(item, hasWSMenu), i);
PLRemoveArrayElement(pmenu, i+1);
PLRelease(item);
} else if (strcmp(getItemCommand(item), "RESTART")==0) {
if (getItemShortcut(item)) {
if (PLGetNumberOfElements(item) == 4) {
changeItemCommand(item, "RESTARTW");
PLAppendArrayElement(item, PLMakeString(""));
}
} else {
if (PLGetNumberOfElements(item) == 2) {
changeItemCommand(item, "RESTARTW");
PLAppendArrayElement(item, PLMakeString(""));
}
}
} else {
if (strcmp(getItemCommand(item),"WORKSPACE_MENU")==0)
*hasWSMenu = 1;
if (getItemShortcut(item)) {
if (PLGetNumberOfElements(item) == 4)
PLAppendArrayElement(item, PLMakeString(""));
} else {
if (PLGetNumberOfElements(item) == 2)
PLAppendArrayElement(item, PLMakeString(""));
}
}
}
return pmenu;
}
static proplist_t
postProcessMenu(proplist_t menu)
{
proplist_t pmenu;
proplist_t item;
int i;
int count;
pmenu = PLDeepCopy(menu);
if (PLGetNumberOfElements(pmenu)==1) {
return pmenu;
}
count = PLGetNumberOfElements(pmenu);
for (i=1; i<count; i++) {
char *cmd;
item = PLGetArrayElement(pmenu, i);
if (isMenu(item)) {
PLInsertArrayElement(pmenu, postProcessMenu(item), i);
PLRemoveArrayElement(pmenu, i+1);
PLRelease(item);
} else {
cmd = getItemCommand(item);
if (strcmp(cmd, "RESTARTW")==0) {
changeItemCommand(item, "RESTART");
removeParameter(item);
} else if (strcmp(cmd, "EXEC")==0 || strcmp(cmd, "SHEXEC")==0 ||
strcmp(cmd, "OPEN_MENU")==0) {
/* do nothing */
} else if (strcmp(cmd, "RESTART")==0 || strcmp(cmd, "SHUTDOWN")==0
|| strcmp(cmd, "EXIT")==0) {
char *tmp = getItemParameter(item);
if (tmp && strlen(tmp)==0)
removeParameter(item);
} else {
removeParameter(item);
}
}
}
return pmenu;
}
static proplist_t
getDefaultMenu(_Panel *panel, int *hasWSMenu)
{
proplist_t menu, pmenu;
char *menuPath, *gspath;
gspath = wusergnusteppath();
menuPath = wmalloc(strlen(gspath)+128);
/* if there is a localized plmenu for the tongue put it's filename here */
sprintf(menuPath, _("%s/Library/WindowMaker/plmenu"), gspath);
menu = PLGetProplistWithPath(menuPath);
if (!menu) {
wwarning("%s:could not read property list menu", menuPath);
if (strcmp("%s/Library/WindowMaker/plmenu",
_("%s/Library/WindowMaker/plmenu"))!=0) {
sprintf(menuPath, "%s/Library/WindowMaker/plmenu", gspath);
menu = PLGetProplistWithPath(menuPath);
wwarning("%s:could not read property list menu", menuPath);
}
if (!menu) {
char buffer[512];
sprintf(buffer, _("Could not open default menu from '%s'"),
menuPath);
WMRunAlertPanel(WMWidgetScreen(panel->win), 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;
}