mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-06-07 15:37:14 +02:00
If a menu item is bound to ':action', the corresponding NSMenuItem has that action set as its action message (instead of the default 'vimMenuItemAction:').
git-svn-id: http://macvim.googlecode.com/svn/trunk@73 96c4425d-ca35-0410-94e5-3396d5c13a8f
This commit is contained in:
+2
-1
@@ -73,7 +73,8 @@
|
||||
atIndex:(int)index;
|
||||
- (void)addMenuItemWithTag:(int)tag parent:(int)parentTag name:(char *)name
|
||||
tip:(char *)tip icon:(char *)icon
|
||||
keyEquivalent:(int)key modifiers:(int)mods atIndex:(int)index;
|
||||
keyEquivalent:(int)key modifiers:(int)mods
|
||||
action:(NSString *)action atIndex:(int)index;
|
||||
- (void)removeMenuItemWithTag:(int)tag;
|
||||
- (void)enableMenuItemWithTag:(int)tag state:(int)enabled;
|
||||
- (void)showToolbar:(int)enable flags:(int)flags;
|
||||
|
||||
+5
-1
@@ -569,7 +569,8 @@ static int specialKeyToNSKey(int key);
|
||||
|
||||
- (void)addMenuItemWithTag:(int)tag parent:(int)parentTag name:(char *)name
|
||||
tip:(char *)tip icon:(char *)icon
|
||||
keyEquivalent:(int)key modifiers:(int)mods atIndex:(int)index
|
||||
keyEquivalent:(int)key modifiers:(int)mods
|
||||
action:(NSString *)action atIndex:(int)index
|
||||
{
|
||||
//NSLog(@"addMenuItemWithTag:%d parent:%d name:%s tip:%s atIndex:%d", tag,
|
||||
// parentTag, name, tip, index);
|
||||
@@ -578,6 +579,7 @@ static int specialKeyToNSKey(int key);
|
||||
int tiplen = tip ? strlen(tip) : 0;
|
||||
int iconlen = icon ? strlen(icon) : 0;
|
||||
int eventFlags = vimModMaskToEventModifierFlags(mods);
|
||||
int actionlen = [action lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
|
||||
key = specialKeyToNSKey(key);
|
||||
@@ -590,6 +592,8 @@ static int specialKeyToNSKey(int key);
|
||||
if (tiplen > 0) [data appendBytes:tip length:tiplen];
|
||||
[data appendBytes:&iconlen length:sizeof(int)];
|
||||
if (iconlen > 0) [data appendBytes:icon length:iconlen];
|
||||
[data appendBytes:&actionlen length:sizeof(int)];
|
||||
if (actionlen > 0) [data appendBytes:[action UTF8String] length:actionlen];
|
||||
[data appendBytes:&index length:sizeof(int)];
|
||||
[data appendBytes:&key length:sizeof(int)];
|
||||
[data appendBytes:&eventFlags length:sizeof(int)];
|
||||
|
||||
+19
-7
@@ -30,7 +30,8 @@ static NSString *DefaultToolbarImageName = @"Attention";
|
||||
atIndex:(int)idx;
|
||||
- (void)addMenuItemWithTag:(int)tag parent:(NSMenu *)parent
|
||||
title:(NSString *)title tip:(NSString *)tip
|
||||
keyEquivalent:(int)key modifiers:(int)mask atIndex:(int)idx;
|
||||
keyEquivalent:(int)key modifiers:(int)mask
|
||||
action:(NSString *)action atIndex:(int)idx;
|
||||
- (void)updateMainMenu;
|
||||
- (NSToolbarItem *)toolbarItemForTag:(int)tag index:(int *)index;
|
||||
- (IBAction)toolbarAction:(id)sender;
|
||||
@@ -569,7 +570,7 @@ static NSMenuItem *findMenuItemWithTagInMenu(NSMenu *root, int tag)
|
||||
|
||||
[title release];
|
||||
} else if (AddMenuItemMsgID == msgid) {
|
||||
NSString *title = nil, *tip = nil, *icon = nil;
|
||||
NSString *title = nil, *tip = nil, *icon = nil, *action = nil;
|
||||
const void *bytes = [data bytes];
|
||||
int tag = *((int*)bytes); bytes += sizeof(int);
|
||||
int parentTag = *((int*)bytes); bytes += sizeof(int);
|
||||
@@ -591,6 +592,13 @@ static NSMenuItem *findMenuItemWithTagInMenu(NSMenu *root, int tag)
|
||||
encoding:NSUTF8StringEncoding];
|
||||
bytes += iconlen;
|
||||
}
|
||||
int actionlen = *((int*)bytes); bytes += sizeof(int);
|
||||
if (actionlen > 0) {
|
||||
action = [[NSString alloc] initWithBytes:(void*)bytes
|
||||
length:actionlen
|
||||
encoding:NSUTF8StringEncoding];
|
||||
bytes += actionlen;
|
||||
}
|
||||
int idx = *((int*)bytes); bytes += sizeof(int);
|
||||
if (idx < 0) idx = 0;
|
||||
int key = *((int*)bytes); bytes += sizeof(int);
|
||||
@@ -604,12 +612,14 @@ static NSMenuItem *findMenuItemWithTagInMenu(NSMenu *root, int tag)
|
||||
} else {
|
||||
NSMenu *parent = [self menuForTag:parentTag];
|
||||
[self addMenuItemWithTag:tag parent:parent title:title tip:tip
|
||||
keyEquivalent:key modifiers:mask atIndex:idx];
|
||||
keyEquivalent:key modifiers:mask action:action
|
||||
atIndex:idx];
|
||||
}
|
||||
|
||||
[title release];
|
||||
[tip release];
|
||||
[icon release];
|
||||
[action release];
|
||||
} else if (RemoveMenuItemMsgID == msgid) {
|
||||
const void *bytes = [data bytes];
|
||||
int tag = *((int*)bytes); bytes += sizeof(int);
|
||||
@@ -891,21 +901,23 @@ static NSMenuItem *findMenuItemWithTagInMenu(NSMenu *root, int tag)
|
||||
|
||||
- (void)addMenuItemWithTag:(int)tag parent:(NSMenu *)parent
|
||||
title:(NSString *)title tip:(NSString *)tip
|
||||
keyEquivalent:(int)key modifiers:(int)mask atIndex:(int)idx
|
||||
keyEquivalent:(int)key modifiers:(int)mask
|
||||
action:(NSString *)action atIndex:(int)idx
|
||||
{
|
||||
if (parent) {
|
||||
NSMenuItem *item = nil;
|
||||
if (title) {
|
||||
item = [[[NSMenuItem alloc] init] autorelease];
|
||||
[item setTitle:title];
|
||||
[item setAction:@selector(vimMenuItemAction:)];
|
||||
// TODO: Check that 'action' is a valid action (nothing will happen
|
||||
// if it isn't, but it would be nice with a warning).
|
||||
if (action) [item setAction:NSSelectorFromString(action)];
|
||||
else [item setAction:@selector(vimMenuItemAction:)];
|
||||
if (tip) [item setToolTip:tip];
|
||||
|
||||
if (key != 0) {
|
||||
NSString *keyString =
|
||||
[NSString stringWithFormat:@"%C", key];
|
||||
//NSLog(@"Set key equivalent %@ (code=0x%x, mods=%d)",
|
||||
// keyString, key, mask);
|
||||
[item setKeyEquivalent:keyString];
|
||||
[item setKeyEquivalentModifierMask:mask];
|
||||
}
|
||||
|
||||
+46
-16
@@ -14,6 +14,8 @@
|
||||
#import "vim.h"
|
||||
|
||||
|
||||
static BOOL gui_cocoa_is_valid_action(NSString *action);
|
||||
|
||||
|
||||
// -- Initialization --------------------------------------------------------
|
||||
|
||||
@@ -582,6 +584,26 @@ gui_mch_add_menu_item(vimmenu_T *menu, int idx)
|
||||
char *tip = menu->strings[MENU_INDEX_TIP]
|
||||
? (char*)menu->strings[MENU_INDEX_TIP] : (char*)menu->actext;
|
||||
|
||||
// HACK! Check if menu is mapped to ':action actionName:'; if so, pass the
|
||||
// action along so that MacVim can bind the menu item to this action. This
|
||||
// means that if a menu item maps to an action in normal mode, then all
|
||||
// other modes will also use the same action.
|
||||
NSString *action = nil;
|
||||
char_u *map_str = menu->strings[MENU_INDEX_NORMAL];
|
||||
if (map_str) {
|
||||
NSString *mapping = [NSString stringWithCString:(char*)map_str
|
||||
encoding:NSUTF8StringEncoding];
|
||||
NSArray *parts = [mapping componentsSeparatedByString:@" "];
|
||||
if ([parts count] >=2
|
||||
&& [[parts objectAtIndex:0] isEqual:@":action"]) {
|
||||
action = [parts objectAtIndex:1];
|
||||
action = [action stringByTrimmingCharactersInSet:
|
||||
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
||||
if (!gui_cocoa_is_valid_action(action))
|
||||
action = nil;
|
||||
}
|
||||
}
|
||||
|
||||
[[MMBackend sharedInstance]
|
||||
addMenuItemWithTag:(int)menu
|
||||
parent:(int)menu->parent
|
||||
@@ -590,6 +612,7 @@ gui_mch_add_menu_item(vimmenu_T *menu, int idx)
|
||||
icon:(char*)icon
|
||||
keyEquivalent:menu->ke_key
|
||||
modifiers:menu->ke_mods
|
||||
action:action
|
||||
atIndex:idx];
|
||||
}
|
||||
|
||||
@@ -861,29 +884,14 @@ gui_mch_set_scrollbar_thumb(
|
||||
ex_action(eap)
|
||||
exarg_T *eap;
|
||||
{
|
||||
static NSDictionary *actionDict = nil;
|
||||
|
||||
if (!gui.in_use) {
|
||||
EMSG(_("E???: Command only available in GUI mode"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!actionDict) {
|
||||
NSBundle *mainBundle = [NSBundle mainBundle];
|
||||
NSString *path = [mainBundle pathForResource:@"Actions"
|
||||
ofType:@"plist"];
|
||||
if (path) {
|
||||
actionDict = [[NSDictionary alloc] initWithContentsOfFile:path];
|
||||
} else {
|
||||
// Allocate bogus dictionary so that error only pops up once.
|
||||
actionDict = [NSDictionary new];
|
||||
EMSG(_("E???: Failed to load action dictionary"));
|
||||
}
|
||||
}
|
||||
|
||||
NSString *name = [NSString stringWithCString:(char*)eap->arg
|
||||
encoding:NSUTF8StringEncoding];
|
||||
if ([actionDict objectForKey:name]) {
|
||||
if (gui_cocoa_is_valid_action(name)) {
|
||||
[[MMBackend sharedInstance] executeActionWithName:name];
|
||||
} else {
|
||||
EMSG2(_("E???: \"%s\" is not a valid action"), eap->arg);
|
||||
@@ -1244,3 +1252,25 @@ gui_mch_toggle_tearoffs(int enable)
|
||||
mch_set_mouse_shape(int shape)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static BOOL
|
||||
gui_cocoa_is_valid_action(NSString *action)
|
||||
{
|
||||
static NSDictionary *actionDict = nil;
|
||||
|
||||
if (!actionDict) {
|
||||
NSBundle *mainBundle = [NSBundle mainBundle];
|
||||
NSString *path = [mainBundle pathForResource:@"Actions"
|
||||
ofType:@"plist"];
|
||||
if (path) {
|
||||
actionDict = [[NSDictionary alloc] initWithContentsOfFile:path];
|
||||
} else {
|
||||
// Allocate bogus dictionary so that error only pops up once.
|
||||
actionDict = [NSDictionary new];
|
||||
EMSG(_("E???: Failed to load action dictionary"));
|
||||
}
|
||||
}
|
||||
|
||||
return [actionDict objectForKey:action] != nil;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user