// -------------------------------------------------------------------------------------------- /// <summary> /// Obtains the menu information for a command handler method. /// </summary> /// <param name="idAttr">CommandID attribute belonging to the command.</param> /// <param name="method">Method information to scan for attributes.</param> /// <param name="defaultGuid"> /// Default GUID to be used if not defined with the command handler. /// </param> /// <returns>MenuCommandInfo instance about the method.</returns> // -------------------------------------------------------------------------------------------- private static MenuCommandInfo ObtainCommandMethodAttributes(CommandIdAttribute idAttr, MethodInfo method, Guid defaultGuid) { var menuInfo = new MenuCommandInfo(); bool commandAttrFound = false; foreach (var attr in method.GetCustomAttributes(true)) { // --- Check for command method attributes var cmdAttr = attr as CommandMethodAttribute; if (cmdAttr != null) { if (commandAttrFound) { VsDebug.Fail(String.Format("Only one CommandMethodAttribute is allowed for {0}.{1}", method.DeclaringType.Name, method.Name)); continue; } commandAttrFound = true; if (cmdAttr is CommandStatusMethodAttribute) { menuInfo.QueryStatusMethod = method; } else if (cmdAttr is CommandExecMethodAttribute) { menuInfo.ExecMethod = method; } else if (cmdAttr is CommandChangeMethodAttribute) { menuInfo.ChangeMethod = method; } } // --- Check command action var actionAttr = attr as ActionAttribute; if (actionAttr != null) { menuInfo.Action = actionAttr; } // --- Check promote flag var promoteAttr = attr as PromoteAttribute; if (promoteAttr != null) { menuInfo.Promote = true; } // --- Set command ID and handle the defaultvalue of the command GUID menuInfo.Guid = idAttr.Guid == Guid.Empty ? defaultGuid : idAttr.Guid; menuInfo.Id = idAttr.Id; } return(menuInfo); }
// -------------------------------------------------------------------------------------------- /// <summary> /// Merges menu information with the specified target information. /// </summary> /// <param name="target">Target to merge the menu into.</param> /// <param name="info">Menu command information to merge.</param> // -------------------------------------------------------------------------------------------- private static void MergeCommandMethodInfo(CommandTargetInfo target, MenuCommandInfo info) { // --- Apply mappings foreach (var mapping in target.Mappings) { // --- Check for mapping GUID if ((mapping.Guid == Guid.Empty && info.Guid == target.DefaultGuid) || mapping.Guid != info.Guid) { // --- Mapping GUID matches, check for ID range if (info.Id >= mapping.IdFrom && info.Id <= mapping.IdTo) { // --- ID in the mapping range, apply offset info.Id = (uint)((int)info.Id + mapping.Offset); break; } } } // --- Actual merging starts here Dictionary <uint, MenuCommandInfo> commandsForGroup; if (!target.TryGetValue(info.Guid, out commandsForGroup)) { // --- No item exists for the command group. commandsForGroup = new Dictionary <uint, MenuCommandInfo> { { info.Id, info } }; target.Add(info.Guid, commandsForGroup); return; } MenuCommandInfo mergedInfo; if (!commandsForGroup.TryGetValue(info.Id, out mergedInfo)) { // --- No item with info.id in the command group. commandsForGroup.Add(info.Id, info); return; } // --- Merge with the former items mergedInfo.Promote |= info.Promote; if (info.ChangeMethod != null) { if (mergedInfo.ChangeMethod == null) { mergedInfo.ChangeMethod = info.ChangeMethod; } else { throw new InvalidOperationException(Resources.CommandDispatcher_DuplicateChange); } } if (info.ExecMethod != null) { if (mergedInfo.ExecMethod == null) { mergedInfo.ExecMethod = info.ExecMethod; mergedInfo.Action = info.Action; } else { throw new InvalidOperationException(Resources.CommandDispatcher_DuplicateExec); } } if (info.QueryStatusMethod != null) { if (mergedInfo.QueryStatusMethod == null) { mergedInfo.QueryStatusMethod = info.QueryStatusMethod; } else { throw new InvalidOperationException(Resources.CommandDispatcher_DuplicateStatus); } } }