/// <summary>
 /// Initializes a new instance of the <see cref="ProjectInfo"/> class. 
 /// </summary>
 /// <param name="name">Name of the project.</param>
 /// <param name="projectId">Project ID.</param>
 /// <param name="priority">Project load priority.</param>
 /// <param name="parent">Parent project, if any.</param>
 public ProjectInfo(string name, Guid projectId, LoadPriority priority, ProjectInfo parent)
 {
     Name = name;
     ProjectId = projectId;
     Priority = priority;
     Parent = parent;
     Children = new List<ProjectInfo>();
 }
        public SolutionViewForm(ProjectInfo solution, ISettingsManager settingsManager)
        {
            InitializeComponent();
            projectsTreeView.TreeViewNodeSorter = new SolutionNodeComparer();

            _settingsManager = settingsManager;
            RootProject = solution;

            ReloadProfilesList();
            SelectProfile(_settingsManager.ActiveProfile);
        }
 private static Color GetPriorityColor(ProjectInfo info)
 {
     switch (info.Priority)
     {
         case LoadPriority.DemandLoad:
             return DemandLoadColor;
         case LoadPriority.BackgroundLoad:
             return BackgroundLoadColor;
         case LoadPriority.LoadIfNeeded:
             return LoadIfNeededColor;
         case LoadPriority.ExplicitLoadOnly:
             return ExplicitLoadOnlyColor;
         default:
             return Color.White;
     }
 }
 private void UpdateProjectLoadPriority(ProjectInfo project)
 {
     UpdateProjectLoadPriority(project.ProjectId, project.Priority);
 }
 private ProjectInfo UpdateEntireSolution()
 {
     _rootProject = null;
     //Get the solution service so we can traverse each project hierarchy contained within.
     var solution = (IVsSolution)GetService(typeof(SVsSolution));
     if (null != solution)
     {
         var solutionHierarchy = solution as IVsHierarchy;
         if (null != solutionHierarchy)
             EnumHierarchyItems(solutionHierarchy, VSConstants.VSITEMID_ROOT, 0, true, false);
     }
     return _rootProject;
 }
        private void ProcessHierarchyNode(IVsHierarchy hierarchy, uint itemid)
        {
            int hr;

            // Canonical Name
            string canonicalName;
            hr = hierarchy.GetCanonicalName(itemid, out canonicalName);

            // Project Name
            object projectName;
            ErrorHandler.ThrowOnFailure(hierarchy.GetProperty(itemid, (int)__VSHPROPID.VSHPROPID_Name, out projectName));

            // Project GUID
            Guid projectGuid;
            hr = hierarchy.GetGuidProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ProjectIDGuid, out projectGuid);
            if (Guid.Empty == projectGuid) // in case when project is unloaded
                _projectNames.TryGetValue(canonicalName, out projectGuid);

            // Project Icon
            var icon = RetrieveProjectIcon(hierarchy);

            // Load Priority
            var loadPriority = RetrieveProjectLoadPriority(projectGuid);

            if (null == _rootProject)
            {
                _rootProject = _lastProject = new ProjectInfo((String)projectName, projectGuid, loadPriority, null) { Icon = icon };
            }
            else
            {
                _lastProject = new ProjectInfo((String)projectName, projectGuid, loadPriority, _currentProject) { Icon = icon };
                _currentProject.Children.Add(_lastProject);
            }
        }
        /// <summary>
        /// Enumerates over the hierarchy items for the given hierarchy traversing into nested hierarchies.
        /// </summary>
        /// <param name="hierarchy">hierarchy to enmerate over.</param>
        /// <param name="itemid">item id of the hierarchy</param>
        /// <param name="recursionLevel">Depth of recursion. e.g. if recursion started with the Solution
        /// node, then : Level 0 -- Solution node, Level 1 -- children of Solution, etc.</param>
        /// <param name="hierIsSolution">true if hierarchy is Solution Node. This is needed to special
        /// case the children of the solution to work around a bug with VSHPROPID_FirstChild and 
        /// VSHPROPID_NextSibling implementation of the Solution.</param>
        /// <param name="visibleNodesOnly">true if only nodes visible in the Solution Explorer should
        /// be traversed. false if all project items should be traversed.</param>
        private void EnumHierarchyItems(IVsHierarchy hierarchy, uint itemid, int recursionLevel, bool hierIsSolution, bool visibleNodesOnly)
        {
            int hr;
            IntPtr nestedHierarchyObj;
            uint nestedItemId;
            Guid hierGuid = typeof(IVsHierarchy).GUID;

            // Check first if this node has a nested hierarchy. If so, then there really are two
            // identities for this node: 1. hierarchy/itemid 2. nestedHierarchy/nestedItemId.
            // We will recurse and call EnumHierarchyItems which will display this node using
            // the inner nestedHierarchy/nestedItemId identity.
            hr = hierarchy.GetNestedHierarchy(itemid, ref hierGuid, out nestedHierarchyObj, out nestedItemId);
            if (VSConstants.S_OK == hr && IntPtr.Zero != nestedHierarchyObj)
            {
                var nestedHierarchy = Marshal.GetObjectForIUnknown(nestedHierarchyObj) as IVsHierarchy;
                Marshal.Release(nestedHierarchyObj);    // we are responsible to release the refcount on the out IntPtr parameter
                if (nestedHierarchy != null)
                {
                    // Display name and type of the node in the Output Window
                    EnumHierarchyItems(nestedHierarchy, nestedItemId, recursionLevel, false, visibleNodesOnly);
                }
            }
            else
            {
                object pVar;

                ProcessHierarchyNode(hierarchy, itemid);
                if (!_projectGuids.Contains(_lastProject.ProjectId))
                {
                    recursionLevel++;

                    //Get the first child node of the current hierarchy being walked
                    // NOTE: to work around a bug with the Solution implementation of VSHPROPID_FirstChild,
                    // we keep track of the recursion level. If we are asking for the first child under
                    // the Solution, we use VSHPROPID_FirstVisibleChild instead of _FirstChild.
                    // In VS 2005 and earlier, the Solution improperly enumerates all nested projects
                    // in the Solution (at any depth) as if they are immediate children of the Solution.
                    // Its implementation _FirstVisibleChild is correct however, and given that there is
                    // not a feature to hide a SolutionFolder or a Project, thus _FirstVisibleChild is
                    // expected to return the identical results as _FirstChild.
                    hr = hierarchy.GetProperty(itemid, ((visibleNodesOnly || (hierIsSolution && recursionLevel == 1)
                                                        ? (int)__VSHPROPID.VSHPROPID_FirstVisibleChild
                                                        : (int)__VSHPROPID.VSHPROPID_FirstChild)), out pVar);
                    ErrorHandler.ThrowOnFailure(hr);
                    if (VSConstants.S_OK == hr)
                    {
                        _currentProject = _lastProject;

                        //We are using Depth first search so at each level we recurse to check if the node has any children
                        // and then look for siblings.
                        uint childId = GetItemId(pVar);
                        while (childId != VSConstants.VSITEMID_NIL)
                        {
                            EnumHierarchyItems(hierarchy, childId, recursionLevel, false, visibleNodesOnly);
                            // NOTE: to work around a bug with the Solution implementation of VSHPROPID_NextSibling,
                            // we keep track of the recursion level. If we are asking for the next sibling under
                            // the Solution, we use VSHPROPID_NextVisibleSibling instead of _NextSibling.
                            // In VS 2005 and earlier, the Solution improperly enumerates all nested projects
                            // in the Solution (at any depth) as if they are immediate children of the Solution.
                            // Its implementation   _NextVisibleSibling is correct however, and given that there is
                            // not a feature to hide a SolutionFolder or a Project, thus _NextVisibleSibling is
                            // expected to return the identical results as _NextSibling.
                            hr = hierarchy.GetProperty(childId, ((visibleNodesOnly || (hierIsSolution && recursionLevel == 1))
                                                                 ? (int)__VSHPROPID.VSHPROPID_NextVisibleSibling
                                                                 : (int)__VSHPROPID.VSHPROPID_NextSibling), out pVar);
                            if (VSConstants.S_OK == hr)
                            {
                                childId = GetItemId(pVar);
                            }
                            else
                            {
                                ErrorHandler.ThrowOnFailure(hr);
                                break;
                            }
                        }

                        _currentProject = _currentProject.Parent;
                    }
                }
            }
        }
        private void UpdateTree(ProjectInfo info)
        {
            projectsTreeView.BeginUpdate();
            projectsTreeView.Nodes.Clear();
            if (null != info)
            {
                var rootNode = CreateTreeNode(info);
                projectsTreeView.Nodes.Add(rootNode);
                projectsTreeView.Sort();

                rootNode.Expand();
            }
            projectsTreeView.EndUpdate();
        }
        private TreeNode CreateTreeNode(ProjectInfo info)
        {
            var node = new TreeNode(info.Name) {Tag = info};
            foreach (var child in info.Children)
                node.Nodes.Add(CreateTreeNode(child));

            // Show load priority only for projects
            if (0 == node.GetNodeCount(false))
                node.BackColor = GetPriorityColor(info);

            // Assign project icon
            if (null != info.Icon)
            {
                projectIcons.Images.Add(info.Icon);
                node.ImageIndex = node.SelectedImageIndex = projectIcons.Images.Count - 1;
            }

            return node;
        }
 public PriorityChangedEventArgs(ProjectInfo project)
 {
     Project = project;
 }