From: Daniel C. \(kzu\) <dca...@us...> - 2005-10-31 09:31:32
|
Update of /cvsroot/mvp-xml/Design/v2/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29101/v2/src Added Files: .cvsignore AssemblyInfo.cs DebugUtils.cs DteHelper.cs ListViewEx.cs Mvp.Xml.Design.csproj Mvp.Xml.Design.sln ProjectInstaller.cs changelog.txt license.txt Log Message: Finished port to v2 of XGen and XsdGen. Removed XmlValidate as the new XML editor has built-in support for validation. --- NEW FILE: .cvsignore --- bin obj *.user *.suo --- NEW FILE: DteHelper.cs --- using System; using System.IO; using EnvDTE; using VSLangProj; using System.Collections; using System.Runtime.InteropServices; using System.Diagnostics; using System.ComponentModel.Design; using EnvDTE80; namespace Mvp.Xml.Design { /// <summary> /// Provides utility methods for working with the DTE. /// </summary> public sealed class DteHelper { #region BuildPath /// <summary> /// Builds a path to the element, detecting automatically the /// type of element and building an appropriate path to it. /// </summary> public static string BuildPath(object toElement) { if (toElement == null) { throw new ArgumentNullException("toElement"); } if (toElement is SelectedItem) { return BuildPath((SelectedItem)toElement); } else if (toElement is SolutionFolder) { return BuildPath(((SolutionFolder)toElement).Parent); } else if (toElement is Project) { return BuildPath((Project)toElement); } else if (toElement is ProjectItem) { return BuildPath((ProjectItem)toElement); } else { throw new NotSupportedException(toElement.ToString()); } } /// <summary> /// Gets an string representation from the current selected item in the solution explorer window. /// </summary> /// <param name="toSelectedItem"></param> /// <returns></returns> public static string BuildPath(SelectedItem toSelectedItem) { if (toSelectedItem == null) { throw new ArgumentNullException("toSelectedItem"); } if (toSelectedItem.ProjectItem != null) { return BuildPath(toSelectedItem.ProjectItem); } else if (toSelectedItem.Project != null) { return BuildPath(toSelectedItem.Project); } return toSelectedItem.Name; } /// <summary> /// Gets an string representatio from <paramref name="toProject"/> /// </summary> /// <param name="toProject"></param> /// <returns></returns> public static string BuildPath(Project toProject) { if (toProject == null) { throw new ArgumentNullException("toProject"); } string path = ""; // Solution folders are exposed with the same kind as solution items. // This eases compatibility with VS2003 in the future. if (toProject.Kind == EnvDTE.Constants.vsProjectKindSolutionItems) { string folder = ""; foreach (Project project in toProject.DTE.Solution.Projects) { folder = project.Name; // Only build the path if it's not the same top-level project. if (project == toProject) { break; } else if (BuildPathToFolder(project, toProject, ref folder)) { break; } } path = folder + path; } else { try { // Setup projects throw NotImplementedException when queried for ParentProjectItem :S if (toProject.ParentProjectItem == null) { return toProject.Name; } } catch (NotImplementedException) { } string folder = ""; foreach (Project project in toProject.DTE.Solution.Projects) { folder = project.Name; // Only build the path if it's not the same top-level project. if (project == toProject) { break; } else if (BuildPathToFolder(project, toProject, ref folder)) { break; } } path = folder + path; } return path; } /// <summary> /// Gets an string representation from <paramref name="toItem"/> /// </summary> /// <param name="toItem"></param> /// <returns></returns> public static string BuildPath(ProjectItem toItem) { if (toItem == null) { throw new ArgumentNullException("toItem"); } string path = ""; if (toItem.ContainingProject != null) { if (!BuildPathFromCollection(toItem.ContainingProject.ProjectItems, toItem, ref path)) { return ""; } else { path = BuildPath(toItem.ContainingProject) + path; } } else { path = toItem.Name; } return path; } private static bool BuildPathFromCollection(ProjectItems items, ProjectItem target, ref string path) { if (items == null) return false; foreach (ProjectItem item in items) { if (item == target) { path = path + Path.DirectorySeparatorChar + target.Name; return true; } else { string tmp = path + Path.DirectorySeparatorChar + item.Name; ProjectItems childitems = item.ProjectItems; if (childitems == null && item.Object is Project) childitems = ((Project)item.Object).ProjectItems; bool found = BuildPathFromCollection(childitems, target, ref tmp); if (found) { path = tmp; return true; } } } return false; } /// <summary> /// Recursively tries to build a path from the parent project to the child one. /// Returns true if the path can be built. /// </summary> private static bool BuildPathToFolder(Project parent, Project target, ref string path) { if (parent == null || parent.ProjectItems == null) return false; foreach (ProjectItem item in parent.ProjectItems) { try { if (item.Object == target) { path = path + Path.DirectorySeparatorChar + target.Name; return true; } else if (item.Kind == EnvDTE.Constants.vsProjectItemKindSolutionItems) { string tmp = path + Path.DirectorySeparatorChar + item.Name; bool found = BuildPathToFolder(item.Object as Project, target, ref tmp); if (found) { path = tmp; return true; } } } catch { // This is for safety. // Sometimes there may be invalid items laying around in the solution explorer. continue; } } return false; } #endregion BuildPath #region Find methods /// <summary> /// Finds a project in the solution, given its output assembly name. /// </summary> /// <returns>A <see cref="Project"/> reference or <see langword="null" /> if /// it doesn't exist. Project can be C# or VB.</returns> public static Project FindProjectByAssemblyName(_DTE vs, string name) { if (vs == null) { throw new ArgumentNullException("vs"); } if (name == null) { throw new ArgumentNullException("name"); } try { foreach (Project p in (Projects)vs.GetObject("CSharpProjects")) { if (p.Properties.Item("AssemblyName").Value.ToString() == name) return p; } } catch { } // Late-bound collection of "CSharpProject" throws if C# is not installed. try { foreach (Project p in (Projects)vs.GetObject("VBProjects")) { if (p.Properties.Item("AssemblyName").Value.ToString() == name) return p; } } catch { } // Late-bound collection of "VBProjects" throws if VB is not installed. return null; } /// <summary> /// Finds a project in the solution, given its name. /// </summary> /// <returns>A <see cref="Project"/> reference or <see langword="null" /> if /// it doesn't exist. Project can be C# or VB.</returns> public static Project FindProjectByName(_DTE vs, string name) { if (vs == null) { throw new ArgumentNullException("vs"); } if (name == null) { throw new ArgumentNullException("name"); } // Try the quick ones first. try { foreach (Project p in (Projects)vs.GetObject("CSharpProjects")) { if (p.Name == name) return p; } } catch { } // Late-bound collection of "CSharpProject" throws if C# is not installed. try { foreach (Project p in (Projects)vs.GetObject("VBProjects")) { if (p.Name == name) return p; } } catch { } // Late-bound collection of "VBProjects" throws if VB is not installed. // We've no option but to iterate everything now. foreach (Project p in vs.Solution.Projects) { if (p.Name == name) { return p; } else if (p.ProjectItems != null) { Project inner = FindProjectByName(p.ProjectItems, name); if (inner != null) { return inner; } } } return null; } private static Project FindProjectByName(ProjectItems items, string name) { foreach (ProjectItem item in items) { if (item.Object is Project && ((Project)item.Object).Name == name) { return item.Object as Project; } else if (item.ProjectItems != null) { Project p = FindProjectByName(item.ProjectItems, name); if (p != null) { return p; } } } return null; } /// <summary> /// Finds a solution folder in the solution hierarchy, given its /// folder-like location path. /// </summary> /// <returns>The solution folder or <see langword="null" /> if /// it doesn't exist.</returns> /// <remarks> /// Note that this method performs the same work as <see cref="FindProjectByPath"/>, /// but only returns an instance if the <see cref="Project.Object"/> is actually /// an <see cref="EnvDTE80.SolutionFolder"/>. This is because solution folders /// are represented as <see cref="Project"/> elements in Visual Studio. /// </remarks> public static EnvDTE80.SolutionFolder FindSolutionFolderByPath(Solution root, string path) { Project prj = FindProjectByPath(root, path); if (prj != null) { return prj.Object as EnvDTE80.SolutionFolder; } return null; } /// <summary> /// Finds a project in the solution hierarchy, given its /// folder-like location path. Note that solution folders will /// also be returned, as they are represented as <see cref="Project"/> elements /// in Visual Studio, and the actual folder can be retrieved by casting /// the returned project <see cref="Project.Object"/> property to /// <see cref="EnvDTE80.SolutionFolder"/>. /// </summary> /// <returns>The project or <see langword="null" /> if /// it doesn't exist.</returns> public static Project FindProjectByPath(Solution root, string path) { if (root == null) { throw new ArgumentNullException("root"); } if (path == null) { throw new ArgumentNullException("path"); } string[] allpaths = path.Split(System.IO.Path.DirectorySeparatorChar, System.IO.Path.AltDirectorySeparatorChar); // First path is the project/solution folder to look into. Project prj = null; foreach (Project p in root.Projects) { if (p.Name == allpaths[0]) { prj = p; break; } } if (prj == null) return null; string[] paths = new string[allpaths.Length - 1]; // If there are no child paths, we reached the end. if (paths.Length == 0) { return prj; } Array.Copy(allpaths, 1, paths, 0, paths.Length); ProjectItem item = FindInCollectionRecursive(prj.ProjectItems, paths, 0); if (item == null) { return null; } { return item.Object as Project; } } /// <summary> /// Finds a project item in the received collection, given its name. /// </summary> /// <param name="collection">The initial collection to start the search.</param> /// <param name="name">The name of the item to locate.</param> /// <param name="recursive">Specifies whether to search in items collections in turn.</param> /// <returns>A <see cref="Project"/> reference or <see langword="null" /> if /// it doesn't exist. Project can be C# or VB.</returns> public static ProjectItem FindItemByName(ProjectItems collection, string name, bool recursive) { foreach (ProjectItem item in collection) { if (item.Name == name) return item; // Recurse if specified. if (recursive) { ProjectItem child = FindItemByName(item.ProjectItems, name, recursive); if (child != null) return child; } } return null; } /// <summary> /// Finds a project item in the solution hierarchy, given its /// folder-like location path. /// </summary> /// <returns>The project item or <see langword="null" /> if /// it doesn't exist.</returns> /// <remarks> /// Note that even projects and solution folders are represented /// as project items, if they are not directly under the solution root, /// but this method checks for the <see cref="ProjectItem.Object"/> property /// to discard matches in this case. If the object to retrieve is a /// project (or solution folder, which is represented as a project too, /// and the folder is retrieved through the <see cref="Project.Object"/> property), /// the <see cref="FindProjectByPath"/> method must be used. /// </remarks> public static ProjectItem FindItemByPath(Solution root, string path) { if (root == null) { throw new ArgumentNullException("root"); } if (path == null) { throw new ArgumentNullException("path"); } string[] allpaths = path.Split(System.IO.Path.DirectorySeparatorChar, System.IO.Path.AltDirectorySeparatorChar); // First path is the project/solution folder to look into. Project prj = null; foreach (Project p in root.Projects) { if (p.Name == allpaths[0]) { prj = p; break; } } if (prj == null) { return null; } string[] paths = new string[allpaths.Length - 1]; // If there are no child paths, this is not an item but the project itself. if (paths.Length == 0) { return null; } Array.Copy(allpaths, 1, paths, 0, paths.Length); ProjectItem item = FindInCollectionRecursive(prj.ProjectItems, paths, 0); if ((item != null) && !(item.Object is Project || item.Object is EnvDTE80.SolutionFolder)) { // Only return the item if it's not a container for a Project or SolutionFolder. return item; } return null; } private static ProjectItem FindInCollectionRecursive(ProjectItems collection, string[] paths, int index) { foreach (ProjectItem item in collection) { if (item.Name == paths[index]) { if (index == paths.Length - 1) { // We reached the item we were looking for. return item; } else { // Otherwise, keep processing. // If item is a project/solution folder, cast before moving on. if (item.Object is Project) { return FindInCollectionRecursive( ((Project)item.Object).ProjectItems, paths, ++index); } else { return FindInCollectionRecursive(item.ProjectItems, paths, ++index); } } } } // Item wasn't found. return null; } #endregion Find methods #region Get methods /// <summary> /// Retrieves the currently selected target in the solution explorer. /// </summary> /// <remarks> /// If there's only one item selected, then the corresponding Solution, Project /// or ProjectItem element is returned. Otherwise, the <see cref="EnvDTE.SelectedItems"/> /// property is returned. /// </remarks> /// <exception cref="InvalidOperationException">There's no current selection in the solution explorer.</exception> /// <returns>The current selection.</returns> public static object GetTarget(_DTE vs) { if (vs.SelectedItems != null && vs.SelectedItems.Count > 0) { if (vs.SelectedItems.Count == 1) { IEnumerator enumerator = vs.SelectedItems.GetEnumerator(); enumerator.MoveNext(); EnvDTE.SelectedItem item = (EnvDTE.SelectedItem)enumerator.Current; // Determine target to load. if (item.Project != null) { return item.Project; } else if (item.ProjectItem != null) { return item.ProjectItem; } else if ( vs.Solution.Properties.Item("Name").Value.Equals(item.Name) ) { return vs.Solution; } return item; } else { //If more than one element is selected, then assert should deal with the DTE.SelectedItems object return vs.SelectedItems; } } throw new InvalidOperationException(Properties.Resources.DteHelper_NoSelection); } /// <summary> /// Retrieves the code file extension for the project. /// </summary> public static string GetDefaultExtension(Project project) { if (project == null) { throw new ArgumentNullException("project"); } if (project.Kind == PrjKind.prjKindCSharpProject) { return ".cs"; } else if (project.Kind == PrjKind.prjKindVBProject) { return ".vb"; } else { throw new NotSupportedException(String.Format( System.Globalization.CultureInfo.CurrentCulture, Properties.Resources.DteHelper_UnsupportedProjectKind, project.Name)); } } /// <summary> /// Retrieves a default namespace to use for project items. /// </summary> public static string GetProjectNamespace(Project project) { if (project == null) { throw new ArgumentNullException("project"); } string ns = project.Properties.Item("DefaultNamespace").Value.ToString(); if (string.IsNullOrEmpty(ns)) { ns = project.Properties.Item("RootNamespace").Value.ToString(); } if (string.IsNullOrEmpty(ns)) { ns = project.Properties.Item("AssemblyName").Value.ToString(); } return ns; } /// <summary> /// Retrieves the project currently selected, if any. /// </summary> public static Project GetSelectedProject(_DTE vs) { if (vs == null) { throw new ArgumentNullException("vs"); } foreach (object obj in (object[]) vs.ActiveSolutionProjects) { if (obj is Project) return obj as Project; } return null; } /// <summary> /// Returns the item file name relative to the containing solution. /// </summary> public static string GetFilePathRelative(ProjectItem item) { if (item == null) { throw new ArgumentNullException("item"); } return GetFilePathRelative(item.DTE, item.get_FileNames(1)); } /// <summary> /// Turns the file name received into a path relative to the containing solution. /// </summary> public static string GetFilePathRelative(_DTE vs, string file) { if (vs == null) { throw new ArgumentNullException("vs"); } if (file == null) { throw new ArgumentNullException("file"); } if (!file.StartsWith(Path.GetDirectoryName(vs.Solution.FullName))) { throw new ArgumentException(String.Format( System.Globalization.CultureInfo.CurrentCulture, Properties.Resources.DteHelper_PathNotRelativeToSln, file, vs.Solution.FullName)); } string relative = file.Replace(Path.GetDirectoryName(vs.Solution.FullName), ""); if (relative.StartsWith(Path.DirectorySeparatorChar.ToString())) { relative = relative.Substring(1); } return relative; } /// <summary> /// Turns the relative file name received into full path, based on the containing solution location. /// </summary> public static string GetPathFull(_DTE vs, string file) { if (vs == null) { throw new ArgumentNullException("vs"); } if (file == null) { throw new ArgumentNullException("file"); } if (Path.IsPathRooted(file) && !file.StartsWith(Path.GetDirectoryName(vs.Solution.FullName))) { throw new ArgumentException(String.Format( System.Globalization.CultureInfo.CurrentCulture, Properties.Resources.DteHelper_PathNotRelativeToSln, file, vs.Solution.FullName)); } return Path.Combine(Path.GetDirectoryName(vs.Solution.FullName), file); } #endregion Get methods #region Select methods /// <summary> /// Selects the solution in the solution explorer. /// </summary> /// <returns>Whether the selection was successful.</returns> public static bool SelectSolution(_DTE vs) { if (vs == null) { throw new ArgumentNullException("vs"); } // Select the parent folder to add the project to it. Window win = vs.Windows.Item(EnvDTE.Constants.vsWindowKindSolutionExplorer); if (win == null) { // Can't select as there's no solution explorer open. throw new InvalidOperationException(Properties.Resources.DteHelper_NoSolutionExplorer); } win.Activate(); win.SetFocus(); UIHierarchy hier = win.Object as UIHierarchy; UIHierarchyItem sol = hier.UIHierarchyItems.Item(1); if (sol == null) { // No solution is opened. return false; } sol.Select(vsUISelectionType.vsUISelectionTypeSelect); return true; } #region Removed feature - not working quite good /* /// <summary> /// Selects a project in the solution explorer. /// </summary> public static bool SelectProject(Project project) { if (project == null) { throw new ArgumentNullException("project"); } // Select the parent folder to add the project to it. Window win = project.DTE.Windows.Item(Constants.vsWindowKindSolutionExplorer); if (win == null) { // Can't select as there's no solution explorer open. throw new InvalidOperationException(Properties.Resources.DteHelper_NoSolutionExplorer); } win.Activate(); win.SetFocus(); UIHierarchy hier = win.Object as UIHierarchy; UIHierarchyItem sol = hier.UIHierarchyItems.Item(1); if (sol == null) { // No solution is opened. return false; } sol.Select(vsUISelectionType.vsUISelectionTypeSelect); // Remove project file name from path. string name = Path.GetDirectoryName(project.UniqueName); // Web projects can't be located through UniqueName. if (IsWebProject(project)) { // Locate by folder relative to solution one. // WARNING: this will not work if project is NOT inside solution! name = Path.GetDirectoryName(project.Properties.Item("FullPath").Value.ToString()); string slnpath = Path.GetDirectoryName(project.DTE.Solution.FullName); name = name.Substring(name.IndexOf(slnpath) + slnpath.Length + 1); } // Perform selection. UIHierarchyItem item = null; try { item = hier.GetItem(Path.Combine(sol.Name, name)); } catch (ArgumentException) { // Retry selection by name (much slower!) item = FindProjectByName(project.Name, hier.UIHierarchyItems); } if (item != null) { item.UIHierarchyItems.Expanded = true; item.Select(vsUISelectionType.vsUISelectionTypeSelect); return true; } else { return false; } } private static UIHierarchyItem FindProjectByName(string name, UIHierarchyItems items) { foreach (UIHierarchyItem item in items) { if (item.Name == name) { ProjectItem pi = item.Object as ProjectItem; // Check the project name or the subproject name (for ETP). if (pi.ContainingProject.Name == name || (pi.SubProject != null && pi.SubProject.Name == name)) return item; } if (item.UIHierarchyItems != null) { UIHierarchyItem uii = FindProjectByName(name, item.UIHierarchyItems); if (uii != null) return uii; } } return null; } */ #endregion Removed feature - not working quite good /// <summary> /// Selects a solution explorer item, based on /// its relative path with regards to the solution. /// </summary> /// <remarks> /// If selection fails, returned object will be null too. /// </remarks> public static UIHierarchyItem SelectItem(_DTE vs, string path) { if (vs == null) { throw new ArgumentNullException("vs"); } if (path == null) { throw new ArgumentNullException("path"); } // Select the parent folder to add the project to it. Window win = vs.Windows.Item(EnvDTE.Constants.vsWindowKindSolutionExplorer); if (win == null) { // Can't select as there's no solution explorer open. throw new InvalidOperationException(Properties.Resources.DteHelper_NoSolutionExplorer); } win.Activate(); win.SetFocus(); UIHierarchy hier = win.Object as UIHierarchy; UIHierarchyItem sol = hier.UIHierarchyItems.Item(1); if (sol == null) { // No solution is opened. throw new InvalidOperationException(Properties.Resources.DteHelper_NoSolutionExplorer); } sol.Select(vsUISelectionType.vsUISelectionTypeSelect); // Perform selection. UIHierarchyItem item = null; try { string slnpath = Path.Combine(sol.Name, path); item = hier.GetItem(slnpath); } catch (ArgumentException) { // Retry selection by name (slower) item = FindHierarchyItemByPath(sol.UIHierarchyItems, path.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar), 0); } if (item != null) { item.UIHierarchyItems.Expanded = true; item.Select(vsUISelectionType.vsUISelectionTypeSelect); } return item; } #region Find manually /// <summary> /// UIHierarchy.GetItem does not always work :S, so I do it by hand here. /// </summary> private static UIHierarchyItem FindHierarchyItemByPath(UIHierarchyItems items, string[] paths, int index) { // Expand everything as we go. items.Expanded = true; foreach (UIHierarchyItem item in items) { if (item.Name == paths[index]) { if (index == paths.Length - 1) { // We reached the item we were looking for. return item; } else { // Otherwise, keep processing. return FindHierarchyItemByPath(item.UIHierarchyItems, paths, ++index); } } } // Item wasn't found. return null; } #endregion Find manually #endregion Select methods #region IsXXX methods /// <summary> /// Determines whether the project is a web project. /// </summary> public static bool IsWebProject(Project project) { if (project == null) { throw new ArgumentNullException("project"); } try { return project.Properties.Item("WebServerVersion") != null && project.Properties.Item("WebServerVersion").Value != null && !string.IsNullOrEmpty(project.Properties.Item("WebServerVersion").Value.ToString()); } catch { return false; } } /// <summary> /// Determines if the project item is a web reference. /// </summary> public static bool IsWebReference(ProjectItem item) { if (item.ContainingProject.Object is VSProject) { ProjectItem webrefs = ((VSProject)item.ContainingProject.Object).WebReferencesFolder; if (webrefs != null && webrefs.ProjectItems != null) { foreach (ProjectItem webref in webrefs.ProjectItems) { if (webref == item) { return true; } } return false; } return false; } return false; } #endregion IsXXX methods } } --- NEW FILE: DebugUtils.cs --- using System; using System.CodeDom.Compiler; using System.Diagnostics; using System.IO; using EnvDTE; /// <summary> /// Utility methods for working with the IDE while debugging. /// </summary> internal class DebugUtils { public static void DumpUIHierarchy(UIHierarchy hierarchy) { StringWriter sw = new StringWriter(); IndentedTextWriter tw = new IndentedTextWriter(sw); DumpUIHierarchyItems(hierarchy.UIHierarchyItems, tw); tw.Flush(); System.Diagnostics.Debugger.Log(0, "Debug", sw.ToString()); } private static void DumpUIHierarchyItems(UIHierarchyItems items, IndentedTextWriter tw) { tw.Indent++; foreach (UIHierarchyItem item in items) { tw.Write(item.Name); if (item.Object is ProjectItem) tw.WriteLine(" (ProjectItem)"); else if (item.Object is Project) tw.WriteLine(" (Project)"); else tw.WriteLine(" (Unknown)"); if (item.UIHierarchyItems != null) DumpUIHierarchyItems(item.UIHierarchyItems, tw); } tw.Indent--; } public static void DumpProjectItems(DTE dte) { StringWriter sw = new StringWriter(); IndentedTextWriter tw = new IndentedTextWriter(sw); tw.WriteLine(dte.Solution.FullName); System.Collections.IEnumerator en = dte.Solution.GetEnumerator(); while (en.MoveNext()) { if (en.Current is ProjectItem) { tw.Indent++; tw.WriteLine(((ProjectItem)en.Current).Name); DumpProjectItems(((ProjectItem)en.Current).ProjectItems, tw); tw.Indent--; } else if (en.Current is Project) { Project p = en.Current as Project; tw.Indent++; tw.WriteLine(p.Name + " (" + p.Kind + ")"); DumpProjectItems(p.ProjectItems, tw); tw.Indent--; } } tw.Flush(); System.Diagnostics.Debugger.Log(0, "Debug", sw.ToString()); } private static void DumpProjectItems(ProjectItems items, IndentedTextWriter tw) { tw.Indent++; foreach (ProjectItem item in items) { tw.WriteLine(item.Name); // + "(" + item.Kind + ")"); if (item.Object is Project) { DumpProjectItems(((Project)item.Object).ProjectItems, tw); } // else if (item.Object is EnvDTE80.SolutionFolder) // { // tw.WriteLine("**** SolutionFolder ****"); // } else if (item.ProjectItems != null) { DumpProjectItems(item.ProjectItems, tw); } } tw.Indent--; } public static void DumpProperties(Properties props) { StringWriter sw = new StringWriter(); foreach (Property prop in props) sw.WriteLine("Name={0}, Value={1}", prop.Name, prop.Value.ToString()); System.Diagnostics.Debugger.Log(0, "Debug", sw.ToString()); } // public static void DumpCommandBars(DTE dte) // { // StringWriter sw = new StringWriter(); // IndentedTextWriter tw = new IndentedTextWriter(sw); // // CommandBars bars = (CommandBars) dte.CommandBars; // // foreach (CommandBar bar in bars) // { // DumpCommandBar(bar, tw); // } // // tw.Flush(); // System.Diagnostics.Debugger.Log(0, "Debug", sw.ToString()); // } // // public static void DumpCommandBar(CommandBar bar, IndentedTextWriter tw) // { // tw.WriteLine(bar.Name); // tw.Indent++; // DumpControls(bar.Controls, tw); // tw.Indent--; // } // // // public static void DumpControls(CommandBarControls controls, IndentedTextWriter tw) // { // foreach (CommandBarControl control in controls) // { // if (control is CommandBar) // { // tw.Indent++; // DumpCommandBar((CommandBar)control, tw); // tw.Indent--; // } // else // { // tw.WriteLine("[" + control.Caption + "]"); // } // } // } } --- NEW FILE: changelog.txt --- --------------------------------------------------------- October 31, 2005 Finished port to v2 of XGen and XsdGen. Removed XmlValidate as the new XML editor has built-in support for validation. --------------------------------------------------------- January 09, 2005 Added class picker to XGen tool, so that multiple target classes can be selected on a single file to be generated. --------------------------------------------------------- December 30, 2004 Added XmlValidate custom tool, that allows validation of the file against multiple schemas if necessary. --------------------------------------------------------- October 21, 2004 Renamed tool to XGen, added setup and test project. --------------------------------------------------------- October 10, 2004 Initial release of the SGen custom tool. --------------------------------------------------------- April 01, 2004 Initial setup. Folder contains main project source files. --- NEW FILE: Mvp.Xml.Design.csproj --- (This appears to be a binary file; contents omitted.) --- NEW FILE: AssemblyInfo.cs --- using System; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security.Permissions; [assembly: ComVisible(true)] [assembly: CLSCompliant(false)] [assembly: AssemblyTitle("Mvp.Xml.Design")] [assembly: AssemblyDescription("MVP XML Design Tools")] [assembly: AssemblyVersion(ThisAssembly.Version)] [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("")] [assembly: AssemblyKeyName("")] #if DEBUG [assembly: AssemblyConfiguration("DEBUG")] #else [assembly: AssemblyConfiguration("RELEASE")] #endif #region Security Permissions //[assembly: SecurityPermission(SecurityAction.RequestRefuse, UnmanagedCode=true)] #endregion Security Permissions internal class ThisAssembly { public const string Title = "Mvp.Xml.Design"; public const string Description = "MVP XML Design Tools"; public const string Version = "1.1.1.0"; } --- NEW FILE: Mvp.Xml.Design.sln --- Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mvp.Xml.Design", "Mvp.Xml.Design.csproj", "{A379C40D-C984-4E63-933A-BE96E9A599B7}" EndProject Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "Mvp.Xml.Design.Setup", "..\setup\setup.vdproj", "{0836E643-A9ED-421E-8426-1CB68F125B66}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Default = Debug|Default Release|Default = Release|Default EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {A379C40D-C984-4E63-933A-BE96E9A599B7}.Debug|Default.ActiveCfg = Debug|Any CPU {A379C40D-C984-4E63-933A-BE96E9A599B7}.Debug|Default.Build.0 = Debug|Any CPU {A379C40D-C984-4E63-933A-BE96E9A599B7}.Release|Default.ActiveCfg = Release|Any CPU {A379C40D-C984-4E63-933A-BE96E9A599B7}.Release|Default.Build.0 = Release|Any CPU {0836E643-A9ED-421E-8426-1CB68F125B66}.Debug|Default.ActiveCfg = Debug {0836E643-A9ED-421E-8426-1CB68F125B66}.Release|Default.ActiveCfg = Release EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal --- NEW FILE: ListViewEx.cs --- // Thanks mav.northwind // http://www.thecodeproject.com/cs/miscctrl/ListViewCellEditors.asp using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Data; using System.Windows.Forms; using System.Runtime.InteropServices; namespace Mvp.Xml.Design { /// <summary> /// Event Handler for SubItem events /// </summary> public delegate void SubItemEventHandler(object sender, SubItemEventArgs e); /// <summary> /// Event Handler for SubItemEndEditing events /// </summary> public delegate void SubItemEndEditingEventHandler(object sender, SubItemEndEditingEventArgs e); /// <summary> /// Event Args for SubItemClicked event /// </summary> public class SubItemEventArgs : EventArgs { public SubItemEventArgs(ListViewItem item, int subItem) { _subItemIndex = subItem; _item = item; } private int _subItemIndex = -1; private ListViewItem _item = null; public int SubItem { get { return _subItemIndex; } } public ListViewItem Item { get { return _item; } } } /// <summary> /// Event Args for SubItemEndEditingClicked event /// </summary> public class SubItemEndEditingEventArgs : SubItemEventArgs { private string _text = string.Empty; private bool _cancel = true; public SubItemEndEditingEventArgs(ListViewItem item, int subItem, string display, bool cancel) : base(item, subItem) { _text = display; _cancel = cancel; } public string DisplayText { get { return _text; } set { _text = value; } } public bool Cancel { get { return _cancel; } set { _cancel = value; } } } /// <summary> /// Inherited ListView to allow in-place editing of subitems /// </summary> public class ListViewEx : System.Windows.Forms.ListView { #region Interop structs, imports and constants /// <summary> /// MessageHeader for WM_NOTIFY /// </summary> private struct NMHDR { public IntPtr hwndFrom; public Int32 idFrom; public Int32 code; } [DllImport("user32.dll")] private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wPar, IntPtr lPar); [DllImport("user32.dll", CharSet=CharSet.Ansi)] private static extern IntPtr SendMessage(IntPtr hWnd, int msg, int len, ref int [] order); // ListView messages private const int LVM_FIRST = 0x1000; private const int LVM_GETCOLUMNORDERARRAY = (LVM_FIRST + 59); // Windows Messages that will abort editing private const int WM_HSCROLL = 0x114; private const int WM_VSCROLL = 0x115; private const int WM_SIZE = 0x05; private const int WM_NOTIFY = 0x4E; private const int HDN_FIRST = -300; private const int HDN_BEGINDRAG = (HDN_FIRST-10); private const int HDN_ITEMCHANGINGA = (HDN_FIRST-0); private const int HDN_ITEMCHANGINGW = (HDN_FIRST-20); #endregion /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.Container components = null; public event SubItemEventHandler SubItemClicked; public event SubItemEventHandler SubItemBeginEditing; public event SubItemEndEditingEventHandler SubItemEndEditing; public ListViewEx() { // This call is required by the Windows.Forms Form Designer. InitializeComponent(); base.FullRowSelect = true; base.View = View.Details; base.AllowColumnReorder = true; } /// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if( components != null ) components.Dispose(); } base.Dispose( disposing ); } #region Component Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { components = new System.ComponentModel.Container(); } #endregion private bool _doubleClickActivation = false; /// <summary> /// Is a double click required to start editing a cell? /// </summary> public bool DoubleClickActivation { get { return _doubleClickActivation; } set { _doubleClickActivation = value; } } /// <summary> /// Retrieve the order in which columns appear /// </summary> /// <returns>Current display order of column indices</returns> public int[] GetColumnOrder() { IntPtr lPar = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)) * Columns.Count); IntPtr res = SendMessage(Handle, LVM_GETCOLUMNORDERARRAY, new IntPtr(Columns.Count), lPar); if (res.ToInt32() == 0) // Something went wrong { Marshal.FreeHGlobal(lPar); return null; } int [] order = new int[Columns.Count]; Marshal.Copy(lPar, order, 0, Columns.Count); Marshal.FreeHGlobal(lPar); return order; } /// <summary> /// Find ListViewItem and SubItem Index at position (x,y) /// </summary> /// <param name="x">relative to ListView</param> /// <param name="y">relative to ListView</param> /// <param name="item">Item at position (x,y)</param> /// <returns>SubItem index</returns> public int GetSubItemAt(int x, int y, out ListViewItem item) { item = this.GetItemAt(x, y); if (item != null) { int[] order = GetColumnOrder(); Rectangle lviBounds; int subItemX; lviBounds = item.GetBounds(ItemBoundsPortion.Entire); subItemX = lviBounds.Left; for (int i=0; i<order.Length; i++) { ColumnHeader h = this.Columns[order[i]]; if (x < subItemX+h.Width) { return h.Index; } subItemX += h.Width; } } return -1; } /// <summary> /// Get bounds for a SubItem /// </summary> /// <param name="Item">Target ListViewItem</param> /// <param name="SubItem">Target SubItem index</param> /// <returns>Bounds of SubItem (relative to ListView)</returns> public Rectangle GetSubItemBounds(ListViewItem Item, int SubItem) { int[] order = GetColumnOrder(); Rectangle subItemRect = Rectangle.Empty; if (SubItem >= order.Length) throw new IndexOutOfRangeException("SubItem "+SubItem+" out of range"); if (Item == null) throw new ArgumentNullException("Item"); Rectangle lviBounds = Item.GetBounds(ItemBoundsPortion.Entire); int subItemX = lviBounds.Left; ColumnHeader col; int i; for (i=0; i<order.Length; i++) { col = this.Columns[order[i]]; if (col.Index == SubItem) break; subItemX += col.Width; } subItemRect = new Rectangle(subItemX, lviBounds.Top, this.Columns[order[i]].Width, lviBounds.Height); return subItemRect; } protected override void WndProc(ref Message msg) { switch (msg.Msg) { // Look for WM_VSCROLL,WM_HSCROLL or WM_SIZE messages. case WM_VSCROLL: case WM_HSCROLL: case WM_SIZE: EndEditing(false); break; case WM_NOTIFY: // Look for WM_NOTIFY of events that might also change the // editor's position/size: Column reordering or resizing NMHDR h = (NMHDR)Marshal.PtrToStructure(msg.LParam, typeof(NMHDR)); if (h.code == HDN_BEGINDRAG || h.code == HDN_ITEMCHANGINGA || h.code == HDN_ITEMCHANGINGW) EndEditing(false); break; } base.WndProc(ref msg); } #region Initialize editing depending of DoubleClickActivation property protected override void OnMouseUp(System.Windows.Forms.MouseEventArgs e) { base.OnMouseUp(e); if (DoubleClickActivation) { return; } EditSubitemAt(new Point(e.X, e.Y)); } protected override void OnDoubleClick(EventArgs e) { base.OnDoubleClick (e); if (!DoubleClickActivation) { return; } Point pt = this.PointToClient(Cursor.Position); EditSubitemAt(pt); } ///<summary> /// Fire SubItemClicked ///</summary> ///<param name="p">Point of click/doubleclick</param> private void EditSubitemAt(Point p) { ListViewItem item; int idx = GetSubItemAt(p.X, p.Y, out item); if (idx >= 0) { OnSubItemClicked(new SubItemEventArgs(item, idx)); } } #endregion #region In-place editing functions // The control performing the actual editing private Control _editingControl; // The LVI being edited private ListViewItem _editItem; // The SubItem being edited private int _editSubItem; protected void OnSubItemBeginEditing(SubItemEventArgs e) { if (SubItemBeginEditing != null) SubItemBeginEditing(this, e); } protected void OnSubItemEndEditing(SubItemEndEditingEventArgs e) { if (SubItemEndEditing != null) SubItemEndEditing(this, e); } protected void OnSubItemClicked(SubItemEventArgs e) { if (SubItemClicked != null) SubItemClicked(this, e); } /// <summary> /// Begin in-place editing of given cell /// </summary> /// <param name="c">Control used as cell editor</param> /// <param name="Item">ListViewItem to edit</param> /// <param name="SubItem">SubItem index to edit</param> public void StartEditing(Control c, ListViewItem Item, int SubItem) { OnSubItemBeginEditing(new SubItemEventArgs(Item, SubItem)); Rectangle rcSubItem = GetSubItemBounds(Item, SubItem); if (rcSubItem.X < 0) { // Left edge of SubItem not visible - adjust rectangle position and width rcSubItem.Width += rcSubItem.X; rcSubItem.X=0; } if (rcSubItem.X+rcSubItem.Width > this.Width) { // Right edge of SubItem not visible - adjust rectangle width rcSubItem.Width = this.Width-rcSubItem.Left; } // Subitem bounds are relative to the location of the ListView! rcSubItem.Offset(Left, Top); // In case the editing control and the listview are on different parents, // account for different origins Point origin = new Point(0,0); Point lvOrigin = this.Parent.PointToScreen(origin); Point ctlOrigin = c.Parent.PointToScreen(origin); rcSubItem.Offset(lvOrigin.X-ctlOrigin.X, lvOrigin.Y-ctlOrigin.Y); // Position and show editor c.Bounds = rcSubItem; c.Text = Item.SubItems[SubItem].Text; c.Visible = true; c.BringToFront(); c.Focus(); _editingControl = c; _editingControl.Leave += new EventHandler(_editControl_Leave); _editingControl.KeyPress += new KeyPressEventHandler(_editControl_KeyPress); _editItem = Item; _editSubItem = SubItem; } private void _editControl_Leave(object sender, EventArgs e) { // cell editor losing focus EndEditing(true); } private void _editControl_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e) { switch (e.KeyChar) { case (char)(int)Keys.Escape: { EndEditing(false); break; } case (char)(int)Keys.Enter: { EndEditing(true); break; } } } /// <summary> /// Accept or discard current value of cell editor control /// </summary> /// <param name="AcceptChanges">Use the _editingControl's Text as new SubItem text or discard changes?</param> public void EndEditing(bool AcceptChanges) { if (_editingControl == null) return; SubItemEndEditingEventArgs e = new SubItemEndEditingEventArgs( _editItem, // The item being edited _editSubItem, // The subitem index being edited AcceptChanges ? _editingControl.Text : // Use editControl text if changes are accepted _editItem.SubItems[_editSubItem].Text, // or the original subitem's text, if changes are discarded !AcceptChanges // Cancel? ); OnSubItemEndEditing(e); _editItem.SubItems[_editSubItem].Text = e.DisplayText; _editingControl.Leave -= new EventHandler(_editControl_Leave); _editingControl.KeyPress -= new KeyPressEventHandler(_editControl_KeyPress); _editingControl.Visible = false; _editingControl = null; _editItem = null; _editSubItem = -1; } #endregion } } --- NEW FILE: ProjectInstaller.cs --- using System; using System.Collections; using System.ComponentModel; using System.Configuration.Install; using System.Reflection; using System.Runtime.InteropServices; namespace Mvp.Xml.Design { /// <summary> /// Registers the project with COM. /// </summary> [RunInstaller(true)] [System.ComponentModel.DesignerCategory("Code")] public class ProjectInstaller : System.Configuration.Install.Installer { public override void Install(IDictionary stateSaver) { base.Install(stateSaver); new RegistrationServices().RegisterAssembly( Assembly.GetExecutingAssembly(), AssemblyRegistrationFlags.SetCodeBase); } public override void Rollback(IDictionary savedState) { base.Rollback (savedState); new RegistrationServices().UnregisterAssembly( Assembly.GetExecutingAssembly()); } public override void Uninstall(IDictionary savedState) { base.Uninstall (savedState); new RegistrationServices().UnregisterAssembly( Assembly.GetExecutingAssembly()); } } } --- NEW FILE: license.txt --- Common Public License Version 1.0 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties heret... [truncated message content] |