/// <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)); } } } }
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); }