mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-19 12:28:22 +01:00
- Also tested the backward compatibility ability of the WINGs proplist code which seems to work quite well. Starting with this moment, Window Maker no longer needs libPropList and is now using the better and much more robust proplist code from WINGs. Also the WINGs based proplist code is actively maintained while the old libPropList code is practically dead and flawed by the fact that it borrowed concepts from the UserDefaults which conflicted with the retain/release mechanism, making some problems that libPropList had, practically unsolvable without a complete redesign (which can be found in the more robust WINGs code).
1848 lines
43 KiB
C
1848 lines
43 KiB
C
/* Menu.c- menu definition
|
|
*
|
|
* WPrefs - Window Maker Preferences Program
|
|
*
|
|
* Copyright (c) 2000 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>
|
|
#include <X11/cursorfont.h>
|
|
|
|
|
|
#include "editmenu.h"
|
|
|
|
|
|
typedef enum {
|
|
NoInfo,
|
|
ExecInfo,
|
|
CommandInfo,
|
|
ExternalInfo,
|
|
PipeInfo,
|
|
DirectoryInfo,
|
|
WSMenuInfo,
|
|
WWindowListInfo,
|
|
LastInfo
|
|
} InfoType;
|
|
|
|
#define MAX_SECTION_SIZE 4
|
|
|
|
typedef struct _Panel {
|
|
WMBox *box;
|
|
char *sectionName;
|
|
|
|
char *description;
|
|
|
|
CallbackRec callbacks;
|
|
WMWidget *parent;
|
|
|
|
|
|
WMFont *boldFont;
|
|
WMFont *normalFont;
|
|
WMColor *white;
|
|
WMColor *gray;
|
|
WMColor *black;
|
|
|
|
WMPixmap *markerPix[LastInfo];
|
|
|
|
WMPopUpButton *typeP;
|
|
|
|
WMWidget *itemPad[3];
|
|
int currentPad;
|
|
|
|
WEditMenu *menu;
|
|
char *menuPath;
|
|
|
|
WMFrame *optionsF;
|
|
|
|
WMFrame *commandF;
|
|
WMTextField *commandT; /* command to run */
|
|
WMButton *xtermC; /* inside xterm? */
|
|
|
|
WMFrame *pathF;
|
|
WMTextField *pathT;
|
|
|
|
WMFrame *pipeF;
|
|
WMTextField *pipeT;
|
|
|
|
WMFrame *dpathF;
|
|
WMTextField *dpathT;
|
|
|
|
WMFrame *dcommandF;
|
|
WMTextField *dcommandT;
|
|
|
|
WMButton *dstripB;
|
|
|
|
WMFrame *shortF;
|
|
WMTextField *shortT;
|
|
WMButton *sgrabB;
|
|
WMButton *sclearB;
|
|
|
|
WMList *icommandL;
|
|
|
|
WMFrame *paramF;
|
|
WMTextField *paramT;
|
|
|
|
WMButton *quickB;
|
|
|
|
Bool dontAsk; /* whether to comfirm submenu remove */
|
|
Bool dontSave;
|
|
|
|
Bool capturing;
|
|
|
|
|
|
/* about the currently selected item */
|
|
WEditMenuItem *currentItem;
|
|
InfoType currentType;
|
|
WMWidget *sections[LastInfo][MAX_SECTION_SIZE];
|
|
} _Panel;
|
|
|
|
|
|
typedef struct {
|
|
InfoType type;
|
|
union {
|
|
struct {
|
|
int command;
|
|
char *parameter;
|
|
char *shortcut;
|
|
} command;
|
|
struct {
|
|
char *command;
|
|
char *shortcut;
|
|
} exec;
|
|
struct {
|
|
char *path;
|
|
} external;
|
|
struct {
|
|
char *command;
|
|
} pipe;
|
|
struct {
|
|
char *directory;
|
|
char *command;
|
|
unsigned stripExt:1;
|
|
} directory;
|
|
} param;
|
|
} ItemData;
|
|
|
|
|
|
|
|
static char *commandNames[] = {
|
|
"ARRANGE_ICONS",
|
|
"HIDE_OTHERS",
|
|
"SHOW_ALL",
|
|
"EXIT",
|
|
"SHUTDOWN",
|
|
"RESTART",
|
|
"RESTART",
|
|
"SAVE_SESSION",
|
|
"CLEAR_SESSION",
|
|
"REFRESH",
|
|
"INFO_PANEL",
|
|
"LEGAL_PANEL"
|
|
};
|
|
|
|
|
|
|
|
#define NEW(type) memset(wmalloc(sizeof(type)), 0, sizeof(type))
|
|
|
|
|
|
#define ICON_FILE "menus"
|
|
|
|
|
|
|
|
static void showData(_Panel *panel);
|
|
|
|
|
|
static void updateMenuItem(_Panel *panel, WEditMenuItem *item,
|
|
WMWidget *changedWidget);
|
|
|
|
static void menuItemSelected(struct WEditMenuDelegate *delegate,
|
|
WEditMenu *menu, WEditMenuItem *item);
|
|
|
|
static void menuItemDeselected(struct WEditMenuDelegate *delegate,
|
|
WEditMenu *menu, WEditMenuItem *item);
|
|
|
|
static void menuItemCloned(struct WEditMenuDelegate *delegate, WEditMenu *menu,
|
|
WEditMenuItem *origItem, WEditMenuItem *newItem);
|
|
|
|
static void menuItemEdited(struct WEditMenuDelegate *delegate, WEditMenu *menu,
|
|
WEditMenuItem *item);
|
|
|
|
static Bool shouldRemoveItem(struct WEditMenuDelegate *delegate,
|
|
WEditMenu *menu, WEditMenuItem *item);
|
|
|
|
|
|
static void freeItemData(ItemData *data);
|
|
|
|
|
|
|
|
static WEditMenuDelegate menuDelegate = {
|
|
NULL,
|
|
menuItemCloned,
|
|
menuItemEdited,
|
|
menuItemSelected,
|
|
menuItemDeselected,
|
|
shouldRemoveItem
|
|
};
|
|
|
|
|
|
static void
|
|
dataChanged(void *self, WMNotification *notif)
|
|
{
|
|
_Panel *panel = (_Panel*)self;
|
|
WEditMenuItem *item = panel->currentItem;
|
|
WMWidget *w = (WMWidget*)WMGetNotificationObject(notif);
|
|
|
|
updateMenuItem(panel, item, w);
|
|
}
|
|
|
|
|
|
static void
|
|
buttonClicked(WMWidget *w, void *data)
|
|
{
|
|
_Panel *panel = (_Panel*)data;
|
|
WEditMenuItem *item = panel->currentItem;
|
|
|
|
updateMenuItem(panel, item, w);
|
|
}
|
|
|
|
|
|
static void
|
|
icommandLClicked(WMWidget *w, void *data)
|
|
{
|
|
_Panel *panel = (_Panel*)data;
|
|
int cmd;
|
|
|
|
cmd = WMGetListSelectedItemRow(w);
|
|
if (cmd == 3 || cmd == 4) {
|
|
WMMapWidget(panel->quickB);
|
|
} else {
|
|
WMUnmapWidget(panel->quickB);
|
|
}
|
|
if (cmd == 6) {
|
|
WMMapWidget(panel->paramF);
|
|
} else {
|
|
WMUnmapWidget(panel->paramF);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
sgrabClicked(WMWidget *w, void *data)
|
|
{
|
|
_Panel *panel = (_Panel*)data;
|
|
Display *dpy = WMScreenDisplay(WMWidgetScreen(panel->parent));
|
|
char *shortcut;
|
|
|
|
|
|
if (w == panel->sclearB) {
|
|
WMSetTextFieldText(panel->shortT, "");
|
|
updateMenuItem(panel, panel->currentItem, panel->shortT);
|
|
return;
|
|
}
|
|
|
|
if (!panel->capturing) {
|
|
panel->capturing = 1;
|
|
WMSetButtonText(w, _("Cancel"));
|
|
XGrabKeyboard(dpy, WMWidgetXID(panel->parent), True, GrabModeAsync,
|
|
GrabModeAsync, CurrentTime);
|
|
shortcut = captureShortcut(dpy, panel);
|
|
if (shortcut) {
|
|
WMSetTextFieldText(panel->shortT, shortcut);
|
|
updateMenuItem(panel, panel->currentItem, panel->shortT);
|
|
wfree(shortcut);
|
|
}
|
|
}
|
|
panel->capturing = 0;
|
|
WMSetButtonText(w, _("Capture"));
|
|
XUngrabKeyboard(dpy, CurrentTime);
|
|
}
|
|
|
|
|
|
static void
|
|
changedItemPad(WMWidget *w, void *data)
|
|
{
|
|
_Panel *panel = (_Panel*)data;
|
|
int padn = WMGetPopUpButtonSelectedItem(w);
|
|
|
|
WMUnmapWidget(panel->itemPad[panel->currentPad]);
|
|
WMMapWidget(panel->itemPad[padn]);
|
|
|
|
panel->currentPad = padn;
|
|
}
|
|
|
|
|
|
static WEditMenu*
|
|
putNewSubmenu(WEditMenu *menu, char *title)
|
|
{
|
|
WEditMenu *tmp;
|
|
WEditMenuItem *item;
|
|
|
|
item = WAddMenuItemWithTitle(menu, title);
|
|
|
|
tmp = WCreateEditMenu(WMWidgetScreen(menu), title);
|
|
WSetEditMenuAcceptsDrop(tmp, True);
|
|
WSetEditMenuDelegate(tmp, &menuDelegate);
|
|
WSetEditMenuSubmenu(menu, item, tmp);
|
|
|
|
return tmp;
|
|
}
|
|
|
|
|
|
static ItemData*
|
|
putNewItem(_Panel *panel, WEditMenu *menu, int type, char *title)
|
|
{
|
|
WEditMenuItem *item;
|
|
ItemData *data;
|
|
|
|
item = WAddMenuItemWithTitle(menu, title);
|
|
|
|
data = NEW(ItemData);
|
|
data->type = type;
|
|
WSetEditMenuItemData(item, data, (WMCallback*)freeItemData);
|
|
WSetEditMenuItemImage(item, panel->markerPix[type]);
|
|
|
|
return data;
|
|
}
|
|
|
|
|
|
static WEditMenu*
|
|
makeFactoryMenu(WMWidget *parent, int width)
|
|
{
|
|
WEditMenu *pad;
|
|
|
|
pad = WCreateEditMenuPad(parent);
|
|
WMResizeWidget(pad, width, 10);
|
|
WSetEditMenuMinSize(pad, wmksize(width, 0));
|
|
WSetEditMenuMaxSize(pad, wmksize(width, 0));
|
|
WSetEditMenuSelectable(pad, False);
|
|
WSetEditMenuEditable(pad, False);
|
|
WSetEditMenuIsFactory(pad, True);
|
|
WSetEditMenuDelegate(pad, &menuDelegate);
|
|
|
|
return pad;
|
|
}
|
|
|
|
|
|
static void
|
|
createPanel(_Panel *p)
|
|
{
|
|
_Panel *panel = (_Panel*)p;
|
|
WMScreen *scr = WMWidgetScreen(panel->parent);
|
|
WMColor *black = WMBlackColor(scr);
|
|
WMColor *white = WMWhiteColor(scr);
|
|
WMColor *gray = WMGrayColor(scr);
|
|
WMFont *bold = WMBoldSystemFontOfSize(scr, 12);
|
|
WMFont *font = WMSystemFontOfSize(scr, 12);
|
|
WMLabel *label;
|
|
int width;
|
|
|
|
|
|
menuDelegate.data = panel;
|
|
|
|
|
|
panel->boldFont = bold;
|
|
panel->normalFont = font;
|
|
|
|
panel->black = black;
|
|
panel->white = white;
|
|
panel->gray = gray;
|
|
|
|
{
|
|
Pixmap pix;
|
|
Display *dpy = WMScreenDisplay(scr);
|
|
GC gc;
|
|
WMPixmap *pixm;
|
|
|
|
pixm = WMCreatePixmap(scr, 7, 7, WMScreenDepth(scr), True);
|
|
|
|
pix = WMGetPixmapXID(pixm);
|
|
|
|
XDrawLine(dpy, pix, WMColorGC(black), 0, 3, 6, 3);
|
|
XDrawLine(dpy, pix, WMColorGC(black), 3, 0, 3, 6);
|
|
/*
|
|
XDrawLine(dpy, pix, WMColorGC(black), 1, 0, 3, 3);
|
|
XDrawLine(dpy, pix, WMColorGC(black), 1, 6, 3, 3);
|
|
XDrawLine(dpy, pix, WMColorGC(black), 0, 0, 0, 6);
|
|
*/
|
|
|
|
pix = WMGetPixmapMaskXID(pixm);
|
|
|
|
gc = XCreateGC(dpy, pix, 0, NULL);
|
|
|
|
XSetForeground(dpy, gc, 0);
|
|
XFillRectangle(dpy, pix, gc, 0, 0, 7, 7);
|
|
|
|
XSetForeground(dpy, gc, 1);
|
|
XDrawLine(dpy, pix, gc, 0, 3, 6, 3);
|
|
XDrawLine(dpy, pix, gc, 3, 0, 3, 6);
|
|
|
|
panel->markerPix[ExternalInfo] = pixm;
|
|
panel->markerPix[PipeInfo] = pixm;
|
|
panel->markerPix[DirectoryInfo] = pixm;
|
|
panel->markerPix[WSMenuInfo] = pixm;
|
|
panel->markerPix[WWindowListInfo] = pixm;
|
|
|
|
XFreeGC(dpy, gc);
|
|
}
|
|
|
|
panel->box = WMCreateBox(panel->parent);
|
|
WMSetViewExpandsToParent(WMWidgetView(panel->box), 2, 2, 2, 2);
|
|
|
|
panel->typeP = WMCreatePopUpButton(panel->box);
|
|
WMResizeWidget(panel->typeP, 150, 20);
|
|
WMMoveWidget(panel->typeP, 10, 10);
|
|
|
|
WMAddPopUpButtonItem(panel->typeP, _("New Items"));
|
|
WMAddPopUpButtonItem(panel->typeP, _("Sample Commands"));
|
|
WMAddPopUpButtonItem(panel->typeP, _("Sample Submenus"));
|
|
|
|
WMSetPopUpButtonAction(panel->typeP, changedItemPad, panel);
|
|
|
|
WMSetPopUpButtonSelectedItem(panel->typeP, 0);
|
|
|
|
{
|
|
WEditMenu *pad;
|
|
WEditMenu *smenu;
|
|
ItemData *data;
|
|
|
|
pad = makeFactoryMenu(panel->box, 150);
|
|
WMMoveWidget(pad, 10, 40);
|
|
|
|
data = putNewItem(panel, pad, ExecInfo, _("Run Program"));
|
|
data = putNewItem(panel, pad, CommandInfo, _("Internal Command"));
|
|
smenu = putNewSubmenu(pad, _("Submenu"));
|
|
data = putNewItem(panel, pad, ExternalInfo, _("External Submenu"));
|
|
data = putNewItem(panel, pad, PipeInfo, _("Generated Submenu"));
|
|
data = putNewItem(panel, pad, DirectoryInfo, _("Directory Contents"));
|
|
data = putNewItem(panel, pad, WSMenuInfo, _("Workspace Menu"));
|
|
data = putNewItem(panel, pad, WWindowListInfo, _("Window List Menu"));
|
|
|
|
panel->itemPad[0] = pad;
|
|
}
|
|
|
|
{
|
|
WEditMenu *pad;
|
|
ItemData *data;
|
|
WMScrollView *sview;
|
|
|
|
sview = WMCreateScrollView(panel->box);
|
|
WMResizeWidget(sview, 150, 180);
|
|
WMMoveWidget(sview, 10, 40);
|
|
WMSetScrollViewHasVerticalScroller(sview, True);
|
|
|
|
pad = makeFactoryMenu(panel->box, 130);
|
|
|
|
WMSetScrollViewContentView(sview, WMWidgetView(pad));
|
|
|
|
data = putNewItem(panel, pad, ExecInfo, _("XTerm"));
|
|
data->param.exec.command = "xterm -sb -sl 2000 -bg black -fg white";
|
|
|
|
data = putNewItem(panel, pad, ExecInfo, _("rxvt"));
|
|
data->param.exec.command = "rxvt";
|
|
|
|
data = putNewItem(panel, pad, ExecInfo, _("ETerm"));
|
|
data->param.exec.command = "eterm";
|
|
|
|
data = putNewItem(panel, pad, ExecInfo, _("Run..."));
|
|
data->param.exec.command = "%a(Run,Type command to run)";
|
|
|
|
data = putNewItem(panel, pad, ExecInfo, _("Netscape"));
|
|
data->param.exec.command = "netscape";
|
|
|
|
data = putNewItem(panel, pad, ExecInfo, _("gimp"));
|
|
data->param.exec.command = "gimp";
|
|
|
|
data = putNewItem(panel, pad, ExecInfo, _("epic"));
|
|
data->param.exec.command = "xterm -e epic";
|
|
|
|
data = putNewItem(panel, pad, ExecInfo, _("ee"));
|
|
data->param.exec.command = "ee";
|
|
|
|
data = putNewItem(panel, pad, ExecInfo, _("xv"));
|
|
data->param.exec.command = "xv";
|
|
|
|
data = putNewItem(panel, pad, ExecInfo, _("Acrobat Reader"));
|
|
data->param.exec.command = "acroread || /usr/local/Acrobat4/bin/acroread";
|
|
|
|
data = putNewItem(panel, pad, ExecInfo, _("ghostview"));
|
|
data->param.exec.command = "gv";
|
|
|
|
data = putNewItem(panel, pad, CommandInfo, _("Exit Window Maker"));
|
|
data->param.command.command = 3;
|
|
|
|
WMMapWidget(pad);
|
|
|
|
panel->itemPad[1] = sview;
|
|
}
|
|
|
|
|
|
{
|
|
WEditMenu *pad, *smenu;
|
|
ItemData *data;
|
|
WMScrollView *sview;
|
|
|
|
sview = WMCreateScrollView(panel->box);
|
|
WMResizeWidget(sview, 150, 180);
|
|
WMMoveWidget(sview, 10, 40);
|
|
WMSetScrollViewHasVerticalScroller(sview, True);
|
|
|
|
pad = makeFactoryMenu(panel->box, 130);
|
|
|
|
WMSetScrollViewContentView(sview, WMWidgetView(pad));
|
|
|
|
data = putNewItem(panel, pad, ExternalInfo, _("Debian Menu"));
|
|
data->param.pipe.command = "/etc/X11/WindowMaker/menu.hook";
|
|
|
|
data = putNewItem(panel, pad, PipeInfo, _("RedHat Menu"));
|
|
data->param.pipe.command = "wmconfig --output wmaker";
|
|
|
|
data = putNewItem(panel, pad, PipeInfo, _("Menu Conectiva"));
|
|
data->param.pipe.command = "wmconfig --output wmaker";
|
|
|
|
data = putNewItem(panel, pad, DirectoryInfo, _("Themes"));
|
|
data->param.directory.command = "setstyle";
|
|
data->param.directory.directory = "/usr/share/WindowMaker/Themes /usr/local/share/WindowMaker/Themes $HOME/GNUstep/Library/WindowMaker/Themes";
|
|
data->param.directory.stripExt = 1;
|
|
|
|
data = putNewItem(panel, pad, DirectoryInfo, _("Bg Images (scale)"));
|
|
data->param.directory.command = "wmsetbg -u -s";
|
|
data->param.directory.directory = "/opt/kde2/share/wallpapers /usr/share/WindowMaker/Backgrounds $HOME/GNUstep/Library/WindowMaker/Backgrounds";
|
|
data->param.directory.stripExt = 1;
|
|
|
|
data = putNewItem(panel, pad, DirectoryInfo, _("Bg Images (tile)"));
|
|
data->param.directory.command = "wmsetbg -u -t";
|
|
data->param.directory.directory = "/opt/kde2/share/wallpapers /usr/share/WindowMaker/Backgrounds $HOME/GNUstep/Library/WindowMaker/Backgrounds";
|
|
data->param.directory.stripExt = 1;
|
|
|
|
smenu = putNewSubmenu(pad, _("Assorted XTerms"));
|
|
|
|
data = putNewItem(panel, smenu, ExecInfo, _("XTerm Yellow on Blue"));
|
|
data->param.exec.command = "xterm -sb -sl 2000 -bg midnightblue -fg yellow";
|
|
|
|
data = putNewItem(panel, smenu, ExecInfo, _("XTerm White on Black"));
|
|
data->param.exec.command = "xterm -sb -sl 2000 -bg black -fg white";
|
|
|
|
data = putNewItem(panel, smenu, ExecInfo, _("XTerm Black on White"));
|
|
data->param.exec.command = "xterm -sb -sl 2000 -bg white -fg black";
|
|
|
|
data = putNewItem(panel, smenu, ExecInfo, _("XTerm Black on Beige"));
|
|
data->param.exec.command = "xterm -sb -sl 2000 -bg '#bbbb99' -fg black";
|
|
|
|
data = putNewItem(panel, smenu, ExecInfo, _("XTerm White on Green"));
|
|
data->param.exec.command = "xterm -sb -sl 2000 -bg '#228822' -fg white";
|
|
|
|
data = putNewItem(panel, smenu, ExecInfo, _("XTerm White on Olive"));
|
|
data->param.exec.command = "xterm -sb -sl 2000 -bg '#335533' -fg white";
|
|
|
|
data = putNewItem(panel, smenu, ExecInfo, _("XTerm Blue on Blue"));
|
|
data->param.exec.command = "xterm -sb -sl 2000 -bg '#112244' -fg '#88aabb'";
|
|
|
|
data = putNewItem(panel, smenu, ExecInfo, _("XTerm BIG FONTS"));
|
|
data->param.exec.command = "xterm -sb -sl 2000 -bg black -fg white -fn 10x20";
|
|
|
|
WMMapWidget(pad);
|
|
|
|
panel->itemPad[2] = sview;
|
|
}
|
|
|
|
|
|
width = FRAME_WIDTH - 20 - 150 - 10 - 2;
|
|
|
|
panel->optionsF = WMCreateFrame(panel->box);
|
|
WMResizeWidget(panel->optionsF, width, FRAME_HEIGHT - 15);
|
|
WMMoveWidget(panel->optionsF, 10 + 150 + 10, 5);
|
|
|
|
width -= 20;
|
|
|
|
/* command */
|
|
|
|
panel->commandF = WMCreateFrame(panel->optionsF);
|
|
WMResizeWidget(panel->commandF, width, 50);
|
|
WMMoveWidget(panel->commandF, 10, 20);
|
|
WMSetFrameTitle(panel->commandF, _("Program to Run"));
|
|
|
|
panel->commandT = WMCreateTextField(panel->commandF);
|
|
WMResizeWidget(panel->commandT, width - 20, 20);
|
|
WMMoveWidget(panel->commandT, 10, 20);
|
|
|
|
WMAddNotificationObserver(dataChanged, panel,
|
|
WMTextDidChangeNotification,
|
|
panel->commandT);
|
|
|
|
#if 0
|
|
panel->xtermC = WMCreateSwitchButton(panel->commandF);
|
|
WMResizeWidget(panel->xtermC, width - 20, 20);
|
|
WMMoveWidget(panel->xtermC, 10, 50);
|
|
WMSetButtonText(panel->xtermC, _("Run the program inside a Xterm"));
|
|
#endif
|
|
WMMapSubwidgets(panel->commandF);
|
|
|
|
|
|
/* path */
|
|
|
|
panel->pathF = WMCreateFrame(panel->optionsF);
|
|
WMResizeWidget(panel->pathF, width, 150);
|
|
WMMoveWidget(panel->pathF, 10, 40);
|
|
WMSetFrameTitle(panel->pathF, _("Path for Menu"));
|
|
|
|
panel->pathT = WMCreateTextField(panel->pathF);
|
|
WMResizeWidget(panel->pathT, width - 20, 20);
|
|
WMMoveWidget(panel->pathT, 10, 20);
|
|
|
|
WMAddNotificationObserver(dataChanged, panel,
|
|
WMTextDidChangeNotification,
|
|
panel->pathT);
|
|
|
|
label = WMCreateLabel(panel->pathF);
|
|
WMResizeWidget(label, width - 20, 80);
|
|
WMMoveWidget(label, 10, 50);
|
|
WMSetLabelText(label, _("Enter the path for a file containing a menu\n"
|
|
"or a list of directories with the programs you\n"
|
|
"want to have listed in the menu. Ex:\n"
|
|
"~/GNUstep/Library/WindowMaker/menu\n"
|
|
"or\n"
|
|
"/usr/X11R6/bin ~/xbin"));
|
|
|
|
WMMapSubwidgets(panel->pathF);
|
|
|
|
|
|
/* pipe */
|
|
|
|
panel->pipeF = WMCreateFrame(panel->optionsF);
|
|
WMResizeWidget(panel->pipeF, width, 100);
|
|
WMMoveWidget(panel->pipeF, 10, 50);
|
|
WMSetFrameTitle(panel->pipeF, _("Command"));
|
|
|
|
panel->pipeT = WMCreateTextField(panel->pipeF);
|
|
WMResizeWidget(panel->pipeT, width - 20, 20);
|
|
WMMoveWidget(panel->pipeT, 10, 20);
|
|
|
|
WMAddNotificationObserver(dataChanged, panel,
|
|
WMTextDidChangeNotification,
|
|
panel->pipeT);
|
|
|
|
|
|
label = WMCreateLabel(panel->pipeF);
|
|
WMResizeWidget(label, width - 20, 40);
|
|
WMMoveWidget(label, 10, 50);
|
|
WMSetLabelText(label, _("Enter a command that outputs a menu\n"
|
|
"definition to stdout when invoked."));
|
|
|
|
WMMapSubwidgets(panel->pipeF);
|
|
|
|
|
|
/* directory menu */
|
|
|
|
panel->dcommandF = WMCreateFrame(panel->optionsF);
|
|
WMResizeWidget(panel->dcommandF, width, 90);
|
|
WMMoveWidget(panel->dcommandF, 10, 25);
|
|
WMSetFrameTitle(panel->dcommandF, _("Command to Open Files"));
|
|
|
|
panel->dcommandT = WMCreateTextField(panel->dcommandF);
|
|
WMResizeWidget(panel->dcommandT, width - 20, 20);
|
|
WMMoveWidget(panel->dcommandT, 10, 20);
|
|
|
|
WMAddNotificationObserver(dataChanged, panel,
|
|
WMTextDidChangeNotification,
|
|
panel->dcommandT);
|
|
|
|
|
|
label = WMCreateLabel(panel->dcommandF);
|
|
WMResizeWidget(label, width - 20, 45);
|
|
WMMoveWidget(label, 10, 40);
|
|
WMSetLabelText(label, _("Enter the command you want to use to open the\n"
|
|
"files in the directories listed below."));
|
|
|
|
WMMapSubwidgets(panel->dcommandF);
|
|
|
|
|
|
panel->dpathF = WMCreateFrame(panel->optionsF);
|
|
WMResizeWidget(panel->dpathF, width, 80);
|
|
WMMoveWidget(panel->dpathF, 10, 125);
|
|
WMSetFrameTitle(panel->dpathF, _("Directories with Files"));
|
|
|
|
panel->dpathT = WMCreateTextField(panel->dpathF);
|
|
WMResizeWidget(panel->dpathT, width - 20, 20);
|
|
WMMoveWidget(panel->dpathT, 10, 20);
|
|
|
|
WMAddNotificationObserver(dataChanged, panel,
|
|
WMTextDidChangeNotification,
|
|
panel->dpathT);
|
|
|
|
panel->dstripB = WMCreateSwitchButton(panel->dpathF);
|
|
WMResizeWidget(panel->dstripB, width - 20, 20);
|
|
WMMoveWidget(panel->dstripB, 10, 50);
|
|
WMSetButtonText(panel->dstripB, _("Strip extensions from file names"));
|
|
|
|
WMSetButtonAction(panel->dstripB, buttonClicked, panel);
|
|
|
|
WMMapSubwidgets(panel->dpathF);
|
|
|
|
|
|
/* shortcut */
|
|
|
|
panel->shortF = WMCreateFrame(panel->optionsF);
|
|
WMResizeWidget(panel->shortF, width, 50);
|
|
WMMoveWidget(panel->shortF, 10, 160);
|
|
WMSetFrameTitle(panel->shortF, _("Keyboard Shortcut"));
|
|
|
|
panel->shortT = WMCreateTextField(panel->shortF);
|
|
WMResizeWidget(panel->shortT, width - 20 - 170, 20);
|
|
WMMoveWidget(panel->shortT, 10, 20);
|
|
|
|
WMAddNotificationObserver(dataChanged, panel,
|
|
WMTextDidChangeNotification,
|
|
panel->shortT);
|
|
|
|
panel->sgrabB = WMCreateCommandButton(panel->shortF);
|
|
WMResizeWidget(panel->sgrabB, 80, 24);
|
|
WMMoveWidget(panel->sgrabB, width - 90, 18);
|
|
WMSetButtonText(panel->sgrabB, _("Capture"));
|
|
WMSetButtonAction(panel->sgrabB, sgrabClicked, panel);
|
|
|
|
panel->sclearB = WMCreateCommandButton(panel->shortF);
|
|
WMResizeWidget(panel->sclearB, 80, 24);
|
|
WMMoveWidget(panel->sclearB, width - 175, 18);
|
|
WMSetButtonText(panel->sclearB, _("Clear"));
|
|
WMSetButtonAction(panel->sclearB, sgrabClicked, panel);
|
|
|
|
WMMapSubwidgets(panel->shortF);
|
|
|
|
/* internal command */
|
|
|
|
panel->icommandL = WMCreateList(panel->optionsF);
|
|
WMResizeWidget(panel->icommandL, width, 80);
|
|
WMMoveWidget(panel->icommandL, 10, 20);
|
|
|
|
WMSetListAction(panel->icommandL, icommandLClicked, panel);
|
|
|
|
WMAddNotificationObserver(dataChanged, panel,
|
|
WMListSelectionDidChangeNotification,
|
|
panel->icommandL);
|
|
|
|
WMInsertListItem(panel->icommandL, 0, _("Arrange Icons"));
|
|
WMInsertListItem(panel->icommandL, 1, _("Hide All Windows Except For The Focused One"));
|
|
WMInsertListItem(panel->icommandL, 2, _("Show All Windows"));
|
|
|
|
WMInsertListItem(panel->icommandL, 3, _("Exit Window Maker"));
|
|
WMInsertListItem(panel->icommandL, 4, _("Exit X Session"));
|
|
WMInsertListItem(panel->icommandL, 5, _("Restart Window Maker"));
|
|
WMInsertListItem(panel->icommandL, 6, _("Start Another Window Manager : ("));
|
|
|
|
WMInsertListItem(panel->icommandL, 7, _("Save Current Session"));
|
|
WMInsertListItem(panel->icommandL, 8, _("Clear Saved Session"));
|
|
WMInsertListItem(panel->icommandL, 9, _("Refresh Screen"));
|
|
WMInsertListItem(panel->icommandL, 10, _("Open Info Panel"));
|
|
WMInsertListItem(panel->icommandL, 11, _("Open Copyright Panel"));
|
|
|
|
|
|
panel->paramF = WMCreateFrame(panel->optionsF);
|
|
WMResizeWidget(panel->paramF, width, 50);
|
|
WMMoveWidget(panel->paramF, 10, 105);
|
|
WMSetFrameTitle(panel->paramF, _("Window Manager to Start"));
|
|
|
|
panel->paramT = WMCreateTextField(panel->paramF);
|
|
WMResizeWidget(panel->paramT, width - 20, 20);
|
|
WMMoveWidget(panel->paramT, 10, 20);
|
|
|
|
WMAddNotificationObserver(dataChanged, panel,
|
|
WMTextDidChangeNotification,
|
|
panel->paramT);
|
|
|
|
WMMapSubwidgets(panel->paramF);
|
|
|
|
|
|
panel->quickB = WMCreateSwitchButton(panel->optionsF);
|
|
WMResizeWidget(panel->quickB, width, 20);
|
|
WMMoveWidget(panel->quickB, 10, 120);
|
|
WMSetButtonText(panel->quickB, _("Do not confirm action."));
|
|
WMSetButtonAction(panel->quickB, buttonClicked, panel);
|
|
|
|
|
|
|
|
|
|
label = WMCreateLabel(panel->optionsF);
|
|
WMResizeWidget(label, width - 10, FRAME_HEIGHT - 50);
|
|
WMMoveWidget(label, 10, 20);
|
|
WMSetLabelText(label,
|
|
_("Instructions:\n\n"
|
|
" - drag items from the left to the menu to add new items\n"
|
|
" - drag items out of the menu to remove items\n"
|
|
" - drag items in menu to change their position\n"
|
|
" - drag items with Control pressed to copy them\n"
|
|
" - double click in a menu item to change the label\n"
|
|
" - click on a menu item to change related information"));
|
|
WMMapWidget(label);
|
|
|
|
WMRealizeWidget(panel->box);
|
|
WMMapSubwidgets(panel->box);
|
|
WMMapWidget(panel->box);
|
|
|
|
|
|
{
|
|
int i;
|
|
for (i = 0; i < 3; i++)
|
|
WMUnmapWidget(panel->itemPad[i]);
|
|
}
|
|
changedItemPad(panel->typeP, panel);
|
|
|
|
panel->sections[NoInfo][0] = label;
|
|
|
|
panel->sections[ExecInfo][0] = panel->commandF;
|
|
panel->sections[ExecInfo][1] = panel->shortF;
|
|
|
|
panel->sections[CommandInfo][0] = panel->icommandL;
|
|
panel->sections[CommandInfo][1] = panel->shortF;
|
|
|
|
panel->sections[ExternalInfo][0] = panel->pathF;
|
|
|
|
panel->sections[PipeInfo][0] = panel->pipeF;
|
|
|
|
panel->sections[DirectoryInfo][0] = panel->dpathF;
|
|
panel->sections[DirectoryInfo][1] = panel->dcommandF;
|
|
|
|
panel->currentType = NoInfo;
|
|
|
|
showData(panel);
|
|
|
|
{
|
|
WMPoint pos;
|
|
|
|
pos = WMGetViewScreenPosition(WMWidgetView(panel->box));
|
|
|
|
if (pos.x < 200) {
|
|
pos.x += FRAME_WIDTH + 20;
|
|
} else {
|
|
pos.x = 10;
|
|
}
|
|
|
|
pos.y = WMAX(pos.y - 100, 0);
|
|
|
|
WEditMenuShowAt(panel->menu, pos.x, pos.y);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
freeItemData(ItemData *data)
|
|
{
|
|
#define CFREE(d) if (d) wfree(d)
|
|
|
|
/* TODO */
|
|
switch (data->type) {
|
|
case CommandInfo:
|
|
CFREE(data->param.command.parameter);
|
|
CFREE(data->param.command.shortcut);
|
|
break;
|
|
|
|
case ExecInfo:
|
|
CFREE(data->param.exec.command);
|
|
CFREE(data->param.exec.shortcut);
|
|
break;
|
|
|
|
case PipeInfo:
|
|
CFREE(data->param.pipe.command);
|
|
break;
|
|
|
|
case ExternalInfo:
|
|
CFREE(data->param.external.path);
|
|
break;
|
|
|
|
case DirectoryInfo:
|
|
CFREE(data->param.directory.command);
|
|
CFREE(data->param.directory.directory);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
wfree(data);
|
|
#undef CFREE
|
|
}
|
|
|
|
|
|
static ItemData*
|
|
parseCommand(WMPropList *item)
|
|
{
|
|
ItemData *data = NEW(ItemData);
|
|
WMPropList *p;
|
|
char *command = NULL;
|
|
char *parameter = NULL;
|
|
char *shortcut = NULL;
|
|
int i = 1;
|
|
|
|
|
|
p = WMGetFromPLArray(item, i++);
|
|
command = WMGetFromPLString(p);
|
|
if (strcmp(command, "SHORTCUT") == 0) {
|
|
p = WMGetFromPLArray(item, i++);
|
|
shortcut = WMGetFromPLString(p);
|
|
p = WMGetFromPLArray(item, i++);
|
|
command = WMGetFromPLString(p);
|
|
}
|
|
p = WMGetFromPLArray(item, i++);
|
|
if (p)
|
|
parameter = WMGetFromPLString(p);
|
|
|
|
if (strcmp(command, "EXEC") == 0 || strcmp(command, "SHEXEC") == 0) {
|
|
|
|
data->type = ExecInfo;
|
|
|
|
data->param.exec.command = wstrdup(parameter);
|
|
if (shortcut)
|
|
data->param.exec.shortcut = wstrdup(shortcut);
|
|
|
|
} else if (strcmp(command, "OPEN_MENU") == 0) {
|
|
char *p;
|
|
/*
|
|
* dir menu, menu file
|
|
* dir WITH
|
|
* |pipe (TODO: ||pipe)
|
|
*/
|
|
p = parameter;
|
|
while (isspace(*p) && *p) p++;
|
|
if (*p == '|') {
|
|
data->type = PipeInfo;
|
|
data->param.pipe.command = wtrimspace(p+1);
|
|
} else {
|
|
char *s;
|
|
|
|
p = wstrdup(p);
|
|
|
|
s = strstr(p, "WITH");
|
|
if (s) {
|
|
char **tokens;
|
|
char **ctokens;
|
|
int tokn;
|
|
int i, j;
|
|
|
|
data->type = DirectoryInfo;
|
|
|
|
*s = '\0';
|
|
s += 5;
|
|
while (*s && isspace(*s)) s++;
|
|
data->param.directory.command = wstrdup(s);
|
|
|
|
wtokensplit(p, &tokens, &tokn);
|
|
wfree(p);
|
|
|
|
ctokens = wmalloc(sizeof(char*)*tokn);
|
|
|
|
for (i = 0, j = 0; i < tokn; i++) {
|
|
if (strcmp(tokens[i], "-noext") == 0) {
|
|
wfree(tokens[i]);
|
|
data->param.directory.stripExt = 1;
|
|
} else {
|
|
ctokens[j++] = tokens[i];
|
|
}
|
|
}
|
|
data->param.directory.directory = wtokenjoin(ctokens, j);
|
|
wfree(ctokens);
|
|
|
|
wtokenfree(tokens, tokn);
|
|
} else {
|
|
data->type = ExternalInfo;
|
|
data->param.external.path = p;
|
|
}
|
|
}
|
|
} else if (strcmp(command, "WORKSPACE_MENU") == 0) {
|
|
data->type = WSMenuInfo;
|
|
} else if (strcmp(command, "WINDOWS_MENU") == 0) {
|
|
data->type = WWindowListInfo;
|
|
} else {
|
|
int cmd;
|
|
|
|
if (strcmp(command, "ARRANGE_ICONS") == 0) {
|
|
cmd = 0;
|
|
} else if (strcmp(command, "HIDE_OTHERS") == 0) {
|
|
cmd = 1;
|
|
} else if (strcmp(command, "SHOW_ALL") == 0) {
|
|
cmd = 2;
|
|
} else if (strcmp(command, "EXIT") == 0) {
|
|
cmd = 3;
|
|
} else if (strcmp(command, "SHUTDOWN") == 0) {
|
|
cmd = 4;
|
|
} else if (strcmp(command, "RESTART") == 0) {
|
|
if (parameter) {
|
|
cmd = 6;
|
|
} else {
|
|
cmd = 5;
|
|
}
|
|
} else if (strcmp(command, "SAVE_SESSION") == 0) {
|
|
cmd = 7;
|
|
} else if (strcmp(command, "CLEAR_SESSION") == 0) {
|
|
cmd = 8;
|
|
} else if (strcmp(command, "REFRESH") == 0) {
|
|
cmd = 9;
|
|
} else if (strcmp(command, "INFO_PANEL") == 0) {
|
|
cmd = 10;
|
|
} else if (strcmp(command, "LEGAL_PANEL") == 0) {
|
|
cmd = 11;
|
|
} else {
|
|
wwarning(_("unknown command '%s' in menu"), command);
|
|
goto error;
|
|
}
|
|
|
|
data->type = CommandInfo;
|
|
|
|
data->param.command.command = cmd;
|
|
if (shortcut)
|
|
data->param.command.shortcut = wstrdup(shortcut);
|
|
if (parameter)
|
|
data->param.command.parameter = wstrdup(parameter);
|
|
}
|
|
|
|
return data;
|
|
|
|
error:
|
|
wfree(data);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
updateFrameTitle(_Panel *panel, char *title, InfoType type)
|
|
{
|
|
if (type != NoInfo) {
|
|
char *tmp;
|
|
|
|
switch (type) {
|
|
case ExecInfo:
|
|
tmp = wstrconcat(title, _(": Execute Program"));
|
|
break;
|
|
|
|
case CommandInfo:
|
|
tmp = wstrconcat(title, _(": Perform Internal Command"));
|
|
break;
|
|
|
|
case ExternalInfo:
|
|
tmp = wstrconcat(title, _(": Open a Submenu"));
|
|
break;
|
|
|
|
case PipeInfo:
|
|
tmp = wstrconcat(title, _(": Program Generated Submenu"));
|
|
break;
|
|
|
|
case DirectoryInfo:
|
|
tmp = wstrconcat(title, _(": Directory Contents Menu"));
|
|
break;
|
|
|
|
case WSMenuInfo:
|
|
tmp = wstrconcat(title, _(": Open Workspaces Submenu"));
|
|
break;
|
|
|
|
case WWindowListInfo:
|
|
tmp = wstrconcat(title, _(": Open Window List Submenu"));
|
|
break;
|
|
|
|
default:
|
|
tmp = NULL;
|
|
break;
|
|
}
|
|
WMSetFrameTitle(panel->optionsF, tmp);
|
|
wfree(tmp);
|
|
} else {
|
|
WMSetFrameTitle(panel->optionsF, NULL);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
changeInfoType(_Panel *panel, char *title, InfoType type)
|
|
{
|
|
WMWidget **w;
|
|
|
|
if (panel->currentType != type) {
|
|
|
|
w = panel->sections[panel->currentType];
|
|
|
|
while (*w) {
|
|
WMUnmapWidget(*w);
|
|
w++;
|
|
}
|
|
WMUnmapWidget(panel->paramF);
|
|
WMUnmapWidget(panel->quickB);
|
|
|
|
|
|
w = panel->sections[type];
|
|
|
|
while (*w) {
|
|
WMMapWidget(*w);
|
|
w++;
|
|
}
|
|
}
|
|
|
|
updateFrameTitle(panel, title, type);
|
|
|
|
panel->currentType = type;
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
updateMenuItem(_Panel *panel, WEditMenuItem *item, WMWidget *changedWidget)
|
|
{
|
|
ItemData *data = WGetEditMenuItemData(item);
|
|
|
|
assert(data != NULL);
|
|
|
|
#define REPLACE(v, d) if (v) wfree(v); v = d
|
|
|
|
switch (data->type) {
|
|
case ExecInfo:
|
|
if (changedWidget == panel->commandT) {
|
|
REPLACE(data->param.exec.command,
|
|
WMGetTextFieldText(panel->commandT));
|
|
}
|
|
if (changedWidget == panel->shortT) {
|
|
REPLACE(data->param.exec.shortcut,
|
|
WMGetTextFieldText(panel->shortT));
|
|
}
|
|
break;
|
|
|
|
case CommandInfo:
|
|
if (changedWidget == panel->icommandL) {
|
|
data->param.command.command =
|
|
WMGetListSelectedItemRow(panel->icommandL);
|
|
}
|
|
switch (data->param.command.command) {
|
|
case 3:
|
|
case 4:
|
|
if (changedWidget == panel->quickB) {
|
|
REPLACE(data->param.command.parameter,
|
|
WMGetButtonSelected(panel->quickB)
|
|
? wstrdup("QUICK") : NULL);
|
|
}
|
|
break;
|
|
|
|
case 6:
|
|
if (changedWidget == panel->paramT) {
|
|
REPLACE(data->param.command.parameter,
|
|
WMGetTextFieldText(panel->paramT));
|
|
}
|
|
break;
|
|
}
|
|
if (changedWidget == panel->shortT) {
|
|
REPLACE(data->param.command.shortcut,
|
|
WMGetTextFieldText(panel->shortT));
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
case PipeInfo:
|
|
if (changedWidget == panel->pipeT) {
|
|
REPLACE(data->param.pipe.command,
|
|
WMGetTextFieldText(panel->pipeT));
|
|
}
|
|
break;
|
|
|
|
case ExternalInfo:
|
|
if (changedWidget == panel->pathT) {
|
|
REPLACE(data->param.external.path,
|
|
WMGetTextFieldText(panel->pathT));
|
|
}
|
|
break;
|
|
|
|
case DirectoryInfo:
|
|
if (changedWidget == panel->dpathT) {
|
|
REPLACE(data->param.directory.directory,
|
|
WMGetTextFieldText(panel->dpathT));
|
|
}
|
|
if (changedWidget == panel->dcommandT) {
|
|
REPLACE(data->param.directory.command,
|
|
WMGetTextFieldText(panel->dcommandT));
|
|
}
|
|
if (changedWidget == panel->dstripB) {
|
|
data->param.directory.stripExt =
|
|
WMGetButtonSelected(panel->dstripB);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
assert(0);
|
|
break;
|
|
}
|
|
|
|
#undef REPLACE
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
menuItemCloned(WEditMenuDelegate *delegate, WEditMenu *menu,
|
|
WEditMenuItem *origItem, WEditMenuItem *newItem)
|
|
{
|
|
ItemData *data = WGetEditMenuItemData(origItem);
|
|
ItemData *newData;
|
|
|
|
if (!data)
|
|
return;
|
|
|
|
#define DUP(s) (s) ? wstrdup(s) : NULL
|
|
|
|
newData = NEW(ItemData);
|
|
|
|
newData->type = data->type;
|
|
|
|
switch (data->type) {
|
|
case ExecInfo:
|
|
newData->param.exec.command = DUP(data->param.exec.command);
|
|
newData->param.exec.shortcut = DUP(data->param.exec.shortcut);
|
|
break;
|
|
|
|
case CommandInfo:
|
|
newData->param.command.command = data->param.command.command;
|
|
newData->param.command.parameter = DUP(data->param.command.parameter);
|
|
newData->param.command.shortcut = DUP(data->param.command.shortcut);
|
|
break;
|
|
|
|
case PipeInfo:
|
|
newData->param.pipe.command = DUP(data->param.pipe.command);
|
|
break;
|
|
|
|
case ExternalInfo:
|
|
newData->param.external.path = DUP(data->param.external.path);
|
|
break;
|
|
|
|
case DirectoryInfo:
|
|
newData->param.directory.directory = DUP(data->param.directory.directory);
|
|
newData->param.directory.command = DUP(data->param.directory.command);
|
|
newData->param.directory.stripExt = data->param.directory.stripExt;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
#undef DUP
|
|
|
|
WSetEditMenuItemData(newItem, newData, (WMCallback*)freeItemData);
|
|
}
|
|
|
|
|
|
static void
|
|
menuItemEdited(struct WEditMenuDelegate *delegate, WEditMenu *menu,
|
|
WEditMenuItem *item)
|
|
{
|
|
_Panel *panel = (_Panel*)delegate->data;
|
|
WEditMenu *submenu;
|
|
|
|
updateFrameTitle(panel, WGetEditMenuItemTitle(item), panel->currentType);
|
|
|
|
submenu = WGetEditMenuSubmenu(menu, item);
|
|
if (submenu) {
|
|
WSetEditMenuTitle(submenu, WGetEditMenuItemTitle(item));
|
|
}
|
|
}
|
|
|
|
|
|
static Bool
|
|
shouldRemoveItem(struct WEditMenuDelegate *delegate, WEditMenu *menu,
|
|
WEditMenuItem *item)
|
|
{
|
|
_Panel *panel = (_Panel*)delegate->data;
|
|
|
|
if (panel->dontAsk)
|
|
return True;
|
|
|
|
if (WGetEditMenuSubmenu(menu, item)) {
|
|
int res;
|
|
|
|
res = WMRunAlertPanel(WMWidgetScreen(menu), NULL,
|
|
_("Remove Submenu"),
|
|
_("Removing this item will destroy all items inside\n"
|
|
"the submenu. Do you really want to do that?"),
|
|
_("Yes"), _("No"),
|
|
_("Yes, don't ask again."));
|
|
switch (res) {
|
|
case WAPRDefault:
|
|
return True;
|
|
case WAPRAlternate:
|
|
return False;
|
|
case WAPROther:
|
|
panel->dontAsk = True;
|
|
return True;
|
|
}
|
|
}
|
|
return True;
|
|
}
|
|
|
|
|
|
static void
|
|
menuItemDeselected(WEditMenuDelegate *delegate, WEditMenu *menu,
|
|
WEditMenuItem *item)
|
|
{
|
|
_Panel *panel = (_Panel*)delegate->data;
|
|
|
|
changeInfoType(panel, NULL, NoInfo);
|
|
}
|
|
|
|
|
|
static void
|
|
menuItemSelected(WEditMenuDelegate *delegate, WEditMenu *menu,
|
|
WEditMenuItem *item)
|
|
{
|
|
ItemData *data = WGetEditMenuItemData(item);
|
|
_Panel *panel = (_Panel*)delegate->data;
|
|
|
|
panel->currentItem = item;
|
|
|
|
if (data) {
|
|
changeInfoType(panel, WGetEditMenuItemTitle(item), data->type);
|
|
|
|
switch (data->type) {
|
|
case NoInfo:
|
|
break;
|
|
|
|
case ExecInfo:
|
|
WMSetTextFieldText(panel->commandT, data->param.exec.command);
|
|
WMSetTextFieldText(panel->shortT, data->param.exec.shortcut);
|
|
break;
|
|
|
|
case CommandInfo:
|
|
WMSelectListItem(panel->icommandL,
|
|
data->param.command.command);
|
|
WMSetListPosition(panel->icommandL,
|
|
data->param.command.command - 2);
|
|
WMSetTextFieldText(panel->shortT, data->param.command.shortcut);
|
|
|
|
switch (data->param.command.command) {
|
|
case 3:
|
|
case 4:
|
|
WMSetButtonSelected(panel->quickB,
|
|
data->param.command.parameter!=NULL);
|
|
break;
|
|
case 6:
|
|
WMSetTextFieldText(panel->paramT,
|
|
data->param.command.parameter);
|
|
break;
|
|
}
|
|
|
|
icommandLClicked(panel->icommandL, panel);
|
|
break;
|
|
|
|
case PipeInfo:
|
|
WMSetTextFieldText(panel->pipeT, data->param.pipe.command);
|
|
break;
|
|
|
|
case ExternalInfo:
|
|
WMSetTextFieldText(panel->pathT, data->param.external.path);
|
|
break;
|
|
|
|
case DirectoryInfo:
|
|
WMSetTextFieldText(panel->dpathT, data->param.directory.directory);
|
|
WMSetTextFieldText(panel->dcommandT, data->param.directory.command);
|
|
WMSetButtonSelected(panel->dstripB, data->param.directory.stripExt);
|
|
break;
|
|
|
|
case WSMenuInfo:
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static WEditMenu*
|
|
buildSubmenu(_Panel *panel, WMPropList *pl)
|
|
{
|
|
WMScreen *scr = WMWidgetScreen(panel->parent);
|
|
WEditMenu *menu;
|
|
WEditMenuItem *item;
|
|
char *title;
|
|
WMPropList *tp, *bp;
|
|
int i;
|
|
|
|
tp = WMGetFromPLArray(pl, 0);
|
|
title = WMGetFromPLString(tp);
|
|
|
|
menu = WCreateEditMenu(scr, title);
|
|
|
|
for (i = 1; i < WMGetPropListItemCount(pl); i++) {
|
|
WMPropList *pi;
|
|
|
|
pi = WMGetFromPLArray(pl, i);
|
|
|
|
tp = WMGetFromPLArray(pi, 0);
|
|
bp = WMGetFromPLArray(pi, 1);
|
|
|
|
title = WMGetFromPLString(tp);
|
|
|
|
if (!bp || WMIsPLArray(bp)) { /* it's a submenu */
|
|
WEditMenu *submenu;
|
|
|
|
submenu = buildSubmenu(panel, pi);
|
|
|
|
item = WAddMenuItemWithTitle(menu, title);
|
|
|
|
WSetEditMenuSubmenu(menu, item, submenu);
|
|
} else {
|
|
ItemData *data;
|
|
|
|
item = WAddMenuItemWithTitle(menu, title);
|
|
|
|
data = parseCommand(pi);
|
|
|
|
if (panel->markerPix[data->type])
|
|
WSetEditMenuItemImage(item, panel->markerPix[data->type]);
|
|
WSetEditMenuItemData(item, data, (WMCallback*)freeItemData);
|
|
}
|
|
}
|
|
|
|
WSetEditMenuAcceptsDrop(menu, True);
|
|
WSetEditMenuDelegate(menu, &menuDelegate);
|
|
|
|
WMRealizeWidget(menu);
|
|
|
|
return menu;
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
buildMenuFromPL(_Panel *panel, WMPropList *pl)
|
|
{
|
|
panel->menu = buildSubmenu(panel, pl);
|
|
}
|
|
|
|
|
|
|
|
static WMPropList*
|
|
getDefaultMenu(_Panel *panel)
|
|
{
|
|
WMPropList *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 = WMReadPropListFromFile(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 = WMReadPropListFromFile(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->parent), panel->parent,
|
|
_("Error"), buffer, _("OK"), NULL, NULL);
|
|
}
|
|
}
|
|
|
|
wfree(menuPath);
|
|
|
|
if (menu) {
|
|
pmenu = menu;
|
|
} else {
|
|
pmenu = NULL;
|
|
}
|
|
|
|
return pmenu;
|
|
}
|
|
|
|
|
|
static void
|
|
showData(_Panel *panel)
|
|
{
|
|
char *gspath;
|
|
char *menuPath;
|
|
WMPropList *pmenu;
|
|
|
|
gspath = wusergnusteppath();
|
|
|
|
menuPath = wmalloc(strlen(gspath)+32);
|
|
strcpy(menuPath, gspath);
|
|
strcat(menuPath, "/Defaults/WMRootMenu");
|
|
|
|
pmenu = WMReadPropListFromFile(menuPath);
|
|
|
|
if (!pmenu || !WMIsPLArray(pmenu)) {
|
|
int res;
|
|
|
|
res = WMRunAlertPanel(WMWidgetScreen(panel->parent), panel->parent,
|
|
_("Warning"),
|
|
_("The menu file format currently in use is not supported\n"
|
|
"by this tool. Do you want to discard the current menu\n"
|
|
"to use this tool?"),
|
|
_("Yes, Discard and Update"),
|
|
_("No, Keep Current Menu"), NULL);
|
|
|
|
if (res == WAPRDefault) {
|
|
pmenu = getDefaultMenu(panel);
|
|
|
|
if (!pmenu) {
|
|
pmenu = WMCreatePLArray(WMCreatePLString("Applications"),
|
|
NULL);
|
|
}
|
|
} else {
|
|
panel->dontSave = True;
|
|
return;
|
|
}
|
|
}
|
|
|
|
panel->menuPath = menuPath;
|
|
|
|
buildMenuFromPL(panel, pmenu);
|
|
|
|
WMReleasePropList(pmenu);
|
|
}
|
|
|
|
|
|
static Bool
|
|
notblank(char *s)
|
|
{
|
|
if (s) {
|
|
while (*s++) {
|
|
if (!isspace(*s))
|
|
return True;
|
|
}
|
|
}
|
|
return False;
|
|
}
|
|
|
|
|
|
static WMPropList*
|
|
processData(char *title, ItemData *data)
|
|
{
|
|
WMPropList *item;
|
|
char *s1;
|
|
static WMPropList *pscut = NULL;
|
|
static WMPropList *pomenu = NULL;
|
|
int i;
|
|
|
|
if (!pscut) {
|
|
pscut = WMCreatePLString("SHORTCUT");
|
|
pomenu = WMCreatePLString("OPEN_MENU");
|
|
}
|
|
|
|
item = WMCreatePLArray(WMCreatePLString(title), NULL);
|
|
|
|
|
|
switch (data->type) {
|
|
case ExecInfo:
|
|
if (data->param.exec.command == NULL)
|
|
return NULL;
|
|
#if 1
|
|
if (strpbrk(data->param.exec.command, "&$*|><?`=;")) {
|
|
s1 = "SHEXEC";
|
|
} else {
|
|
s1 = "EXEC";
|
|
}
|
|
#else
|
|
s1 = "SHEXEC";
|
|
#endif
|
|
|
|
if (notblank(data->param.exec.shortcut)) {
|
|
WMAddToPLArray(item, pscut);
|
|
WMAddToPLArray(item,
|
|
WMCreatePLString(data->param.exec.shortcut));
|
|
}
|
|
|
|
WMAddToPLArray(item, WMCreatePLString(s1));
|
|
WMAddToPLArray(item, WMCreatePLString(data->param.exec.command));
|
|
break;
|
|
|
|
case CommandInfo:
|
|
if (notblank(data->param.command.shortcut)) {
|
|
WMAddToPLArray(item, pscut);
|
|
WMAddToPLArray(item,
|
|
WMCreatePLString(data->param.command.shortcut));
|
|
}
|
|
|
|
i = data->param.command.command;
|
|
|
|
WMAddToPLArray(item, WMCreatePLString(commandNames[i]));
|
|
|
|
switch (i) {
|
|
case 3:
|
|
case 4:
|
|
if (data->param.command.parameter) {
|
|
WMAddToPLArray(item,
|
|
WMCreatePLString(data->param.command.parameter));
|
|
}
|
|
break;
|
|
|
|
case 6: /* restart */
|
|
if (data->param.command.parameter) {
|
|
WMAddToPLArray(item,
|
|
WMCreatePLString(data->param.command.parameter));
|
|
}
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case PipeInfo:
|
|
if (!data->param.pipe.command)
|
|
return NULL;
|
|
WMAddToPLArray(item, pomenu);
|
|
s1 = wstrconcat("| ", data->param.pipe.command);
|
|
WMAddToPLArray(item, WMCreatePLString(s1));
|
|
wfree(s1);
|
|
break;
|
|
|
|
case ExternalInfo:
|
|
if (!data->param.external.path)
|
|
return NULL;
|
|
WMAddToPLArray(item, pomenu);
|
|
WMAddToPLArray(item, WMCreatePLString(data->param.external.path));
|
|
break;
|
|
|
|
case DirectoryInfo:
|
|
if (!data->param.directory.directory
|
|
|| !data->param.directory.command)
|
|
return NULL;
|
|
{
|
|
int l;
|
|
char *tmp;
|
|
|
|
l = strlen(data->param.directory.directory);
|
|
l += strlen(data->param.directory.command);
|
|
l += 32;
|
|
|
|
WMAddToPLArray(item, pomenu);
|
|
|
|
tmp = wmalloc(l);
|
|
sprintf(tmp, "%s%s WITH %s",
|
|
data->param.directory.stripExt ? "-noext " : "",
|
|
data->param.directory.directory,
|
|
data->param.directory.command);
|
|
|
|
WMAddToPLArray(item, WMCreatePLString(tmp));
|
|
wfree(tmp);
|
|
}
|
|
break;
|
|
|
|
case WSMenuInfo:
|
|
WMAddToPLArray(item, WMCreatePLString("WORKSPACE_MENU"));
|
|
break;
|
|
|
|
case WWindowListInfo:
|
|
WMAddToPLArray(item, WMCreatePLString("WINDOWS_MENU"));
|
|
break;
|
|
|
|
default:
|
|
assert(0);
|
|
break;
|
|
}
|
|
|
|
return item;
|
|
}
|
|
|
|
|
|
static WMPropList*
|
|
processSubmenu(WEditMenu *menu)
|
|
{
|
|
WEditMenuItem *item;
|
|
WMPropList *pmenu;
|
|
WMPropList *pl;
|
|
char *s;
|
|
int i;
|
|
|
|
|
|
s = WGetEditMenuTitle(menu);
|
|
pl = WMCreatePLString(s);
|
|
|
|
pmenu = WMCreatePLArray(pl, NULL);
|
|
|
|
i = 0;
|
|
while ((item = WGetEditMenuItem(menu, i++))) {
|
|
WEditMenu *submenu;
|
|
|
|
s = WGetEditMenuItemTitle(item);
|
|
|
|
submenu = WGetEditMenuSubmenu(menu, item);
|
|
if (submenu) {
|
|
pl = processSubmenu(submenu);
|
|
} else {
|
|
pl = processData(s, WGetEditMenuItemData(item));
|
|
}
|
|
|
|
if (!pl)
|
|
continue;
|
|
|
|
WMAddToPLArray(pmenu, pl);
|
|
}
|
|
|
|
return pmenu;
|
|
}
|
|
|
|
|
|
|
|
static WMPropList*
|
|
buildPLFromMenu(_Panel *panel)
|
|
{
|
|
WMPropList *menu;
|
|
|
|
menu = processSubmenu(panel->menu);
|
|
|
|
return menu;
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
storeData(_Panel *panel)
|
|
{
|
|
WMPropList *menu;
|
|
|
|
if (panel->dontSave)
|
|
return;
|
|
|
|
menu = buildPLFromMenu(panel);
|
|
|
|
WMWritePropListToFile(menu, panel->menuPath, True);
|
|
|
|
WMReleasePropList(menu);
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
showMenus(_Panel *panel)
|
|
{
|
|
WEditMenuUnhide(panel->menu);
|
|
}
|
|
|
|
|
|
static void
|
|
hideMenus(_Panel *panel)
|
|
{
|
|
WEditMenuHide(panel->menu);
|
|
}
|
|
|
|
|
|
|
|
|
|
Panel*
|
|
InitMenu(WMScreen *scr, WMWidget *parent)
|
|
{
|
|
_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->parent = parent;
|
|
|
|
panel->callbacks.createWidgets = createPanel;
|
|
panel->callbacks.updateDomain = storeData;
|
|
panel->callbacks.showPanel = showMenus;
|
|
panel->callbacks.hidePanel = hideMenus;
|
|
|
|
|
|
AddSection(panel, ICON_FILE);
|
|
|
|
return panel;
|
|
}
|
|
|