Beispiel #1
0
        // --------------------------------------------------------------------------------------------
        /// <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);
                }
            }
        }
Beispiel #2
0
        // --------------------------------------------------------------------------------------------
        /// <summary>
        /// Scans through all the methods of the EventTarget's type to collect information about
        /// command handler methods.
        /// </summary>
        // --------------------------------------------------------------------------------------------
        private void ScanDispatchInfo()
        {
            Type targetType = EventTarget.GetType();

            lock (_Targets)
            {
                // --- We scan only the type info, if we have not scanned it yet.
                if (_Targets.ContainsKey(targetType))
                {
                    return;
                }

                var target = new CommandTargetInfo();

                // --- Obtain the default command Guid for the event target
                var  defaultGuidAttr = targetType.GetAttribute <DefaultCommandGroupAttribute>();
                Guid defaultGuid     = defaultGuidAttr == null
          ? (GuidProvider == null ? targetType.GUID : GuidProvider.CommandGuid)
          : defaultGuidAttr.Value.GUID;
                target.DefaultGuid = defaultGuid;

                // --- Obtain command mapping information
                var mappings = targetType.AttributesOfType <CommandMapAttribute>();
                foreach (var attr in mappings)
                {
                    target.Mappings.Add(attr);
                }

                // --- Obtain all methods that can be used as command methods
                var commandMethods =
                    from method in targetType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic |
                                                         BindingFlags.Instance | BindingFlags.Static)
                    where method.ReturnType == typeof(void) &&
                    (
                        // --- void MyCommandExec()
                        method.GetParameters().Count() == 0 &&
                        Attribute.IsDefined(method, typeof(CommandExecMethodAttribute))
                        ||
                        // --- void MyCommandExec(CommandContext)
                        method.GetParameters().Count() == 1 &&
                        (
                            method.GetParameters()[0].ParameterType == typeof(CommandContext) ||
                            method.GetParameters()[0].ParameterType.IsSubclassOf(typeof(CommandContext))
                        ) &&
                        Attribute.IsDefined(method, typeof(CommandExecMethodAttribute))
                        ||
                        // --- void MyCommandMethod(OleMenuCommand)
                        method.GetParameters().Count() == 1 &&
                        method.GetParameters()[0].ParameterType == typeof(OleMenuCommand) &&
                        Attribute.IsDefined(method, typeof(CommandMethodAttribute))
                        ||
                        // --- void MyCommandMethod(OleMenuCommand, CommandExec)
                        method.GetParameters().Count() == 2 &&
                        method.GetParameters()[0].ParameterType == typeof(OleMenuCommand) &&
                        (
                            method.GetParameters()[1].ParameterType == typeof(CommandContext) ||
                            method.GetParameters()[1].ParameterType.IsSubclassOf(typeof(CommandContext))
                        ) &&
                        Attribute.IsDefined(method, typeof(CommandMethodAttribute))
                    ) &&
                    Attribute.IsDefined(method, typeof(CommandIdAttribute))
                    select method;
                foreach (var method in commandMethods)
                {
                    foreach (CommandIdAttribute idAttr in
                             method.GetCustomAttributes(typeof(CommandIdAttribute), false))
                    {
                        var menuInfo = ObtainCommandMethodAttributes(idAttr, method, defaultGuid);
                        MergeCommandMethodInfo(target, menuInfo);
                    }
                }
                _Targets.Add(targetType, target);
            }
        }