/// <summary>
        /// Add a new item, or resurrect a deleted one.
        /// </summary>
        /// <param name="generator">The generator to add.</param>
        /// <param name="currentGeneratorNames">The current generator names. Note that if this is a
        /// toggle that adds a new generator for the same format, then the current names may
        /// include format modifiers that are not available from the generator itself.</param>
        private void AddPseudoItem(IORMGenerator generator, string currentGeneratorNames)
        {
            Dictionary <string, PseudoBuildItem> items = _pseudoItemsByOutputFormat;
            string          outputFormat      = generator.ProvidesOutputFormat;
            string          generatedFileName = generator.GetOutputFileDefaultName(_sourceFileName);
            PseudoBuildItem pseudoItem;

            if (items.TryGetValue(outputFormat, out pseudoItem))
            {
                pseudoItem.CurrentGeneratorNames    = currentGeneratorNames;
                pseudoItem.DefaultGeneratedFileName = generatedFileName;
            }
            else
            {
                pseudoItem = new PseudoBuildItem(null, generatedFileName);
                pseudoItem.CurrentGeneratorNames = currentGeneratorNames;
                items[outputFormat] = pseudoItem;
            }
        }
        public ORMGeneratorSelectionControl(EnvDTE.ProjectItem projectItem, IServiceProvider serviceProvider)
            : this()
        {
            _projectItem     = projectItem;
            _serviceProvider = serviceProvider;
#if VISUALSTUDIO_10_0
            ProjectRootElement project         = ProjectRootElement.TryOpen(projectItem.ContainingProject.FullName);
            string             projectFullPath = project.FullPath;
#else // VISUALSTUDIO_10_0
            Microsoft.Build.BuildEngine.Project project = Engine.GlobalEngine.GetLoadedProject(projectItem.ContainingProject.FullName);
            string projectFullPath = project.FullFileName;
#endif // VISUALSTUDIO_10_0
            _project = project;

            string projectItemRelativePath = (string)projectItem.Properties.Item("LocalPath").Value;
            projectItemRelativePath  = (new Uri(projectFullPath)).MakeRelativeUri(new Uri(projectItemRelativePath)).ToString();
            _projectItemRelativePath = projectItemRelativePath;

#if VISUALSTUDIO_10_0
            ProjectItemGroupElement originalItemGroup = ORMCustomTool.GetItemGroup(project, projectItemRelativePath);
#else // VISUALSTUDIO_10_0
            BuildItemGroup originalItemGroup = ORMCustomTool.GetItemGroup(project, projectItemRelativePath);
#endif // VISUALSTUDIO_10_0
            _originalItemGroup = originalItemGroup;

            string sourceFileName = projectItem.Name;
            _sourceFileName = sourceFileName;
            this.textBox_ORMFileName.Text = sourceFileName;

            this.button_SaveChanges.Click += new EventHandler(this.SaveChanges);
            this.button_Cancel.Click      += new EventHandler(this.Cancel);

            ITree tree = (ITree)(this.virtualTreeControl.MultiColumnTree = new MultiColumnTree(2));
            this.virtualTreeControl.SetColumnHeaders(new VirtualTreeColumnHeader[]
            {
                // TODO: Localize these.
                new VirtualTreeColumnHeader("Generated File Format", 0.30f, VirtualTreeColumnHeaderStyles.ColumnPositionLocked | VirtualTreeColumnHeaderStyles.DragDisabled),
                new VirtualTreeColumnHeader("Generated File Name", 1f, VirtualTreeColumnHeaderStyles.ColumnPositionLocked | VirtualTreeColumnHeaderStyles.DragDisabled)
            }, true);
            MainBranch mainBranch = this._mainBranch = new MainBranch(this
#if VISUALSTUDIO_15_0
                                                                      , serviceProvider
#endif
                                                                      );
            int   totalCount     = mainBranch.VisibleItemCount;
            int[] primaryIndices = new int[totalCount];
            for (int i = 0; i < totalCount; ++i)
            {
                if (mainBranch.IsPrimaryDisplayItem(i))
                {
                    primaryIndices[i] = i - totalCount;
                }
                else
                {
                    primaryIndices[i] = i + 1;
                }
            }
            Array.Sort <int>(primaryIndices);
            int lastPrimary = -1;
            for (int i = 0; i < totalCount; ++i)
            {
                int modifiedIndex = primaryIndices[i];
                if (modifiedIndex < 0)
                {
                    primaryIndices[i] = modifiedIndex + totalCount;
                }
                else
                {
                    if (lastPrimary == -1)
                    {
                        lastPrimary = i - 1;
                    }
                    primaryIndices[i] = modifiedIndex - 1;
                }
            }
            int modifierCount = totalCount - mainBranch.Branches.Count;
            tree.Root = (lastPrimary == -1) ? (IBranch)mainBranch : new BranchPartition(
                mainBranch,
                primaryIndices,
                new BranchPartitionSection(0, lastPrimary + 1),
                new BranchPartitionSection(totalCount - modifierCount, modifierCount, "Generated File Modifiers", false),
                new BranchPartitionSection(lastPrimary + 1, totalCount - lastPrimary - modifierCount - 1, "Intermediate and Secondary Files", true));                 // UNDONE: Localize Header
            this.virtualTreeControl.ShowToolTips   = true;
            this.virtualTreeControl.FullCellSelect = true;

            Dictionary <string, PseudoBuildItem> pseudoItemsByOutputFormat = new Dictionary <string, PseudoBuildItem>(StringComparer.OrdinalIgnoreCase);
            _pseudoItemsByOutputFormat = pseudoItemsByOutputFormat;
            IDictionary <string, IORMGenerator> generators =
#if VISUALSTUDIO_15_0
                ORMCustomTool.GetORMGenerators(serviceProvider);
#else
                ORMCustomTool.ORMGenerators;
#endif
            if (originalItemGroup != null)
            {
#if VISUALSTUDIO_10_0
                foreach (ProjectItemElement buildItem in originalItemGroup.Items)
#else // VISUALSTUDIO_10_0
                foreach (BuildItem buildItem in originalItemGroup)
#endif // VISUALSTUDIO_10_0
                {
                    // Do this very defensively so that the dialog can still be opened if a project is out
                    // of step with the generators registered on a specific machine.
                    string        generatorNameData;
                    string[]      generatorNames;                // The first string is the primary generator, others are the format modifiers
                    int           generatorNameCount;
                    IORMGenerator primaryGenerator;
                    MainBranch.OutputFormatBranch primaryFormatBranch;
                    if (!string.IsNullOrEmpty(generatorNameData = buildItem.GetEvaluatedMetadata(ITEMMETADATA_ORMGENERATOR)) &&
                        !string.IsNullOrEmpty(generatorNameData = generatorNameData.Trim()) &&
                        string.Equals(buildItem.GetEvaluatedMetadata(ITEMMETADATA_DEPENDENTUPON), sourceFileName, StringComparison.OrdinalIgnoreCase) &&
                        null != (generatorNames = generatorNameData.Split((char[])null, StringSplitOptions.RemoveEmptyEntries)) &&
                        0 != (generatorNameCount = generatorNames.Length) &&
                        // This assumes that each generator target of the same type has all of the same options.
                        // This is currently the result of this dialog, and we're not considering hand edits
                        // to the project file at this point.
                        generators.TryGetValue(generatorNames[0], out primaryGenerator) &&
                        mainBranch.Branches.TryGetValue(primaryGenerator.ProvidesOutputFormat, out primaryFormatBranch))
                    {
                        PseudoBuildItem pseudoItem;
                        string          outputFormat = primaryGenerator.ProvidesOutputFormat;

                        if (!pseudoItemsByOutputFormat.TryGetValue(outputFormat, out pseudoItem))
                        {
                            // Note that we can't use the build item file name here as it might be decorated with
                            // target names. Go back to the generator to get an undecorated default name.
                            pseudoItem = new PseudoBuildItem(generatorNameData, primaryGenerator.GetOutputFileDefaultName(sourceFileName));
                            pseudoItemsByOutputFormat.Add(outputFormat, pseudoItem);

                            if (primaryFormatBranch.SelectedORMGenerator == null)
                            {
                                primaryFormatBranch.SelectedORMGenerator = primaryGenerator;
                            }

                            // Format modifiers are attached to the end of the list
                            for (int i = 1; i < generatorNameCount; ++i)
                            {
                                MainBranch.OutputFormatBranch modifierBranch = primaryFormatBranch.NextModifier;
                                string findName = generatorNames[i];
                                while (modifierBranch != null)
                                {
                                    IORMGenerator testGenerator = modifierBranch.ORMGenerators[0];
                                    if (testGenerator.OfficialName == findName)
                                    {
                                        modifierBranch.SelectedORMGenerator = testGenerator;
                                        break;
                                    }
                                    modifierBranch = modifierBranch.NextModifier;
                                }
                            }
                        }

                        pseudoItem.AddOriginalInstance(generatorNameData, ORMCustomToolUtility.GeneratorTargetsFromBuildItem(buildItem));
                    }
                }
            }
        }
Exemplo n.º 3
0
            private StateRefreshChanges ToggleOnRequiredBranches(OutputFormatBranch formatBranch, int branchGeneratorIndex, bool testToggleOff)
            {
                StateRefreshChanges retVal = StateRefreshChanges.None;

                if (formatBranch.IsModifier)
                {
                    if (formatBranch.SelectedORMGenerator == null)
                    {
                        // The build item is associated primarily with the output format for
                        // the primary generator, not the modifier. We need to make sure that
                        // the primary generator is turned on.
                        IORMGenerator      modifierGenerator = formatBranch.ORMGenerators[0];
                        OutputFormatBranch primaryBranch     = _branches[modifierGenerator.ProvidesOutputFormat];
                        IORMGenerator      primaryGenerator  = primaryBranch.SelectedORMGenerator;
                        if (primaryGenerator == null)
                        {
                            if (StateRefreshChanges.None != ToggleOnRequiredBranches(primaryBranch, 0, false))
                            {
                                retVal = StateRefreshChanges.Entire;
                            }
                            primaryGenerator = primaryBranch.SelectedORMGenerator;
                            if (primaryGenerator == null)
                            {
                                return(StateRefreshChanges.None);
                            }
                        }
                        formatBranch.SelectedORMGenerator = modifierGenerator;
                        PseudoBuildItem pseudoItem = _parent.PseudoItemsByOutputFormat[primaryGenerator.ProvidesOutputFormat];
                        pseudoItem.CurrentGeneratorNames = primaryBranch.SelectedGeneratorOfficialNames;
                        retVal |= StateRefreshChanges.Children | StateRefreshChanges.Children;
                    }
                    else if (testToggleOff)
                    {
                        // Note that we can always remove a modifier, do not call CanRemoveGenerator
                        RemoveGenerator(formatBranch);
                        retVal |= StateRefreshChanges.Current | StateRefreshChanges.Children;
                    }
                }
                else if (formatBranch.SelectedORMGenerator == null)
                {
                    IORMGenerator generator = formatBranch.ORMGenerators[branchGeneratorIndex];
                    retVal = StateRefreshChanges.Current | StateRefreshChanges.Children;
                    formatBranch.SelectedORMGenerator = generator;
                    _parent.AddPseudoItem(generator, formatBranch.SelectedGeneratorOfficialNames);

                    // Notify related generator branches
                    IList <string> requiredFormats = generator.RequiresInputFormats; int requiredFormatCount = requiredFormats.Count;
                    IList <string> companionFormats     = generator.RequiresCompanionFormats;
                    int            companionFormatCount = companionFormats.Count;
                    int            totalCount           = requiredFormatCount + companionFormatCount;
                    for (int i = 0; i < totalCount; ++i)
                    {
                        OutputFormatBranch requiredBranch;
                        if (_branches.TryGetValue(i < requiredFormatCount ? requiredFormats[i] : companionFormats[i - requiredFormatCount], out requiredBranch))
                        {
                            if (StateRefreshChanges.None != ToggleOnRequiredBranches(requiredBranch, 0, false))
                            {
                                retVal = StateRefreshChanges.Entire;
                            }
                        }
                    }
                }
                else if (testToggleOff && CanRemoveGenerator(formatBranch))
                {
                    RemoveGenerator(formatBranch);
                    retVal = StateRefreshChanges.Current | StateRefreshChanges.Children;
                }
                return(retVal);
            }