Konstantin Koch 8287c54432 Included the Visual Studio extension and made the necessary changes to make it run.
Replaced the old VS templates with ones that offer more flexiblity.
Started replacing the Content Project for the samples with our custom project type.
Inlcuded a basic not yet working AssimpImporter.
2015-04-08 14:50:03 +02:00

407 lines
15 KiB
C#

/* ****************************************************************************
*
* Copyright (c) Microsoft Corporation.
*
* This source code is subject to terms and conditions of the Apache License, Version 2.0. A
* copy of the license can be found in the License.html file at the root of this distribution. If
* you cannot locate the Apache License, Version 2.0, please send an email to
* vspython@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
* by the terms of the Apache License, Version 2.0.
*
* You must not remove this notice, or any other, from this software.
*
* ***************************************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Threading;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using VSConstants = Microsoft.VisualStudio.VSConstants;
namespace Microsoft.VisualStudio.Navigation {
/// <summary>
/// Single node inside the tree of the libraries in the object browser or class view.
/// </summary>
public class LibraryNode : SimpleObjectList<LibraryNode>, IVsNavInfoNode, ISimpleObject {
private string _name, _fullname;
private LibraryNodeCapabilities _capabilities;
private readonly LibraryNodeType _type;
private readonly CommandID _contextMenuID;
private readonly string _tooltip;
private readonly Dictionary<LibraryNodeType, LibraryNode> _filteredView;
private readonly Dictionary<string, LibraryNode[]> _childrenByName;
private bool _duplicatedByName;
public LibraryNode(string name, string fullname, LibraryNodeType type)
: this(name, fullname, type, LibraryNodeCapabilities.None, null) { }
public LibraryNode(string name, string fullname, LibraryNodeType type, LibraryNodeCapabilities capabilities, CommandID contextMenuID) {
Debug.Assert(name != null);
_capabilities = capabilities;
_contextMenuID = contextMenuID;
_name = name;
_fullname = fullname;
_tooltip = name;
_type = type;
_filteredView = new Dictionary<LibraryNodeType, LibraryNode>();
_childrenByName = new Dictionary<string, LibraryNode[]>();
}
protected LibraryNode(LibraryNode node)
: this(node, node.FullName) {
}
protected LibraryNode(LibraryNode node, string newFullName) {
_capabilities = node._capabilities;
_contextMenuID = node._contextMenuID;
_name = node._name;
_tooltip = node._tooltip;
_type = node._type;
_fullname = newFullName;
Children.AddRange(node.Children);
_childrenByName = new Dictionary<string, LibraryNode[]>(node._childrenByName);
_filteredView = new Dictionary<LibraryNodeType, LibraryNode>();
}
protected void SetCapabilityFlag(LibraryNodeCapabilities flag, bool value) {
if (value) {
_capabilities |= flag;
} else {
_capabilities &= ~flag;
}
}
/// <summary>
/// Get or Set if the node can be deleted.
/// </summary>
public bool CanDelete {
get { return (0 != (_capabilities & LibraryNodeCapabilities.AllowDelete)); }
set { SetCapabilityFlag(LibraryNodeCapabilities.AllowDelete, value); }
}
/// <summary>
/// Get or Set if the node can be associated with some source code.
/// </summary>
public bool CanGoToSource {
get { return (0 != (_capabilities & LibraryNodeCapabilities.HasSourceContext)); }
set { SetCapabilityFlag(LibraryNodeCapabilities.HasSourceContext, value); }
}
/// <summary>
/// Get or Set if the node can be renamed.
/// </summary>
public bool CanRename {
get { return (0 != (_capabilities & LibraryNodeCapabilities.AllowRename)); }
set { SetCapabilityFlag(LibraryNodeCapabilities.AllowRename, value); }
}
/// <summary>
///
/// </summary>
public override uint Capabilities { get { return (uint)_capabilities; } }
public string TooltipText {
get { return _tooltip; }
}
public void AddNode(LibraryNode node) {
lock (Children) {
Children.Add(node);
LibraryNode[] nodes;
if (!_childrenByName.TryGetValue(node.Name, out nodes)) {
// common case, no duplicates by name
_childrenByName[node.Name] = new[] { node };
} else {
// uncommon case, duplicated by name
_childrenByName[node.Name] = nodes = nodes.Append(node);
foreach (var dupNode in nodes) {
dupNode.DuplicatedByName = true;
}
}
}
Update();
}
public void RemoveNode(LibraryNode node) {
if (node != null) {
lock (Children) {
Children.Remove(node);
LibraryNode[] items;
if (_childrenByName.TryGetValue(node.Name, out items)) {
if (items.Length == 1) {
System.Diagnostics.Debug.Assert(items[0] == node);
_childrenByName.Remove(node.Name);
} else {
var newItems = new LibraryNode[items.Length - 1];
for (int i = 0, write = 0; i < items.Length; i++) {
if (items[i] != node) {
newItems[write++] = items[i];
}
}
_childrenByName[node.Name] = newItems;
}
}
}
Update();
}
}
public virtual object BrowseObject {
get { return null; }
}
public override uint CategoryField(LIB_CATEGORY category) {
uint fieldValue = 0;
switch (category) {
case (LIB_CATEGORY)_LIB_CATEGORY2.LC_PHYSICALCONTAINERTYPE:
fieldValue = (uint)_LIBCAT_PHYSICALCONTAINERTYPE.LCPT_PROJECT;
break;
case LIB_CATEGORY.LC_NODETYPE:
fieldValue = (uint)_LIBCAT_NODETYPE.LCNT_HIERARCHY;
break;
case LIB_CATEGORY.LC_LISTTYPE: {
LibraryNodeType subTypes = LibraryNodeType.None;
foreach (LibraryNode node in Children) {
subTypes |= node._type;
}
fieldValue = (uint)subTypes;
}
break;
case (LIB_CATEGORY)_LIB_CATEGORY2.LC_HIERARCHYTYPE:
fieldValue = (uint)_LIBCAT_HIERARCHYTYPE.LCHT_UNKNOWN;
break;
default:
throw new NotImplementedException();
}
return fieldValue;
}
public virtual LibraryNode Clone() {
return new LibraryNode(this);
}
public virtual LibraryNode Clone(string newFullName) {
return new LibraryNode(this, newFullName);
}
/// <summary>
/// Performs the operations needed to delete this node.
/// </summary>
public virtual void Delete() {
}
/// <summary>
/// Perform a Drag and Drop operation on this node.
/// </summary>
public virtual void DoDragDrop(OleDataObject dataObject, uint keyState, uint effect) {
}
public virtual uint EnumClipboardFormats(_VSOBJCFFLAGS flags, VSOBJCLIPFORMAT[] formats) {
return 0;
}
public virtual void FillDescription(_VSOBJDESCOPTIONS flags, IVsObjectBrowserDescription3 description) {
description.ClearDescriptionText();
description.AddDescriptionText3(_name, VSOBDESCRIPTIONSECTION.OBDS_NAME, null);
}
public IVsSimpleObjectList2 FilterView(uint filterType) {
var libraryNodeType = (LibraryNodeType)filterType;
LibraryNode filtered = null;
if (_filteredView.TryGetValue(libraryNodeType, out filtered)) {
return filtered as IVsSimpleObjectList2;
}
filtered = this.Clone();
for (int i = 0; i < filtered.Children.Count; ) {
if (0 == (filtered.Children[i]._type & libraryNodeType)) {
filtered.Children.RemoveAt(i);
} else {
i += 1;
}
}
_filteredView.Add(libraryNodeType, filtered);
return filtered as IVsSimpleObjectList2;
}
public virtual void GotoSource(VSOBJGOTOSRCTYPE gotoType) {
// Do nothing.
}
public virtual string Name {
get {
return _name;
}
}
public virtual string GetTextRepresentation(VSTREETEXTOPTIONS options) {
return Name;
}
public LibraryNodeType NodeType {
get { return _type; }
}
/// <summary>
/// Finds the source files associated with this node.
/// </summary>
/// <param name="hierarchy">The hierarchy containing the items.</param>
/// <param name="itemId">The item id of the item.</param>
/// <param name="itemsCount">Number of items.</param>
public virtual void SourceItems(out IVsHierarchy hierarchy, out uint itemId, out uint itemsCount) {
hierarchy = null;
itemId = 0;
itemsCount = 0;
}
public virtual void Rename(string newName, uint flags) {
this._name = newName;
}
public virtual string UniqueName {
get { return Name; }
}
public string FullName {
get {
return _fullname;
}
}
public CommandID ContextMenuID {
get {
return _contextMenuID;
}
}
public virtual StandardGlyphGroup GlyphType {
get {
return StandardGlyphGroup.GlyphGroupModule;
}
}
public VSTREEDISPLAYDATA DisplayData {
get {
var res = new VSTREEDISPLAYDATA();
res.Image = res.SelectedImage = (ushort)GlyphType;
return res;
}
}
public virtual IVsSimpleObjectList2 DoSearch(VSOBSEARCHCRITERIA2 criteria) {
return null;
}
/// <summary>
/// Visit this node and its children.
/// </summary>
/// <param name="visitor">Visitor to invoke methods on when visiting the nodes.</param>
public void Visit(ILibraryNodeVisitor visitor, CancellationToken ct = default(CancellationToken)) {
if (ct.IsCancellationRequested) {
visitor.LeaveNode(this, ct);
return;
}
if (visitor.EnterNode(this, ct)) {
lock (Children) {
foreach (var child in Children) {
if (ct.IsCancellationRequested) {
visitor.LeaveNode(this, ct);
return;
}
child.Visit(visitor, ct);
}
}
}
visitor.LeaveNode(this, ct);
}
#region IVsNavInfoNode Members
int IVsNavInfoNode.get_Name(out string pbstrName) {
pbstrName = UniqueName;
return VSConstants.S_OK;
}
int IVsNavInfoNode.get_Type(out uint pllt) {
pllt = (uint)_type;
return VSConstants.S_OK;
}
#endregion
/// <summary>
/// Enumeration of the capabilities of a node. It is possible to combine different values
/// to support more capabilities.
/// This enumeration is a copy of _LIB_LISTCAPABILITIES with the Flags attribute set.
/// </summary>
[Flags()]
public enum LibraryNodeCapabilities {
None = _LIB_LISTCAPABILITIES.LLC_NONE,
HasBrowseObject = _LIB_LISTCAPABILITIES.LLC_HASBROWSEOBJ,
HasDescriptionPane = _LIB_LISTCAPABILITIES.LLC_HASDESCPANE,
HasSourceContext = _LIB_LISTCAPABILITIES.LLC_HASSOURCECONTEXT,
HasCommands = _LIB_LISTCAPABILITIES.LLC_HASCOMMANDS,
AllowDragDrop = _LIB_LISTCAPABILITIES.LLC_ALLOWDRAGDROP,
AllowRename = _LIB_LISTCAPABILITIES.LLC_ALLOWRENAME,
AllowDelete = _LIB_LISTCAPABILITIES.LLC_ALLOWDELETE,
AllowSourceControl = _LIB_LISTCAPABILITIES.LLC_ALLOWSCCOPS,
}
public bool DuplicatedByName { get { return _duplicatedByName; } private set { _duplicatedByName = value; } }
}
/// <summary>
/// Enumeration of the possible types of node. The type of a node can be the combination
/// of one of more of these values.
/// This is actually a copy of the _LIB_LISTTYPE enumeration with the difference that the
/// Flags attribute is set so that it is possible to specify more than one value.
/// </summary>
[Flags()]
public enum LibraryNodeType {
None = 0,
Hierarchy = _LIB_LISTTYPE.LLT_HIERARCHY,
Namespaces = _LIB_LISTTYPE.LLT_NAMESPACES,
Classes = _LIB_LISTTYPE.LLT_CLASSES,
Members = _LIB_LISTTYPE.LLT_MEMBERS,
Package = _LIB_LISTTYPE.LLT_PACKAGE,
PhysicalContainer = _LIB_LISTTYPE.LLT_PHYSICALCONTAINERS,
Containment = _LIB_LISTTYPE.LLT_CONTAINMENT,
ContainedBy = _LIB_LISTTYPE.LLT_CONTAINEDBY,
UsesClasses = _LIB_LISTTYPE.LLT_USESCLASSES,
UsedByClasses = _LIB_LISTTYPE.LLT_USEDBYCLASSES,
NestedClasses = _LIB_LISTTYPE.LLT_NESTEDCLASSES,
InheritedInterface = _LIB_LISTTYPE.LLT_INHERITEDINTERFACES,
InterfaceUsedByClasses = _LIB_LISTTYPE.LLT_INTERFACEUSEDBYCLASSES,
Definitions = _LIB_LISTTYPE.LLT_DEFINITIONS,
References = _LIB_LISTTYPE.LLT_REFERENCES,
DeferExpansion = _LIB_LISTTYPE.LLT_DEFEREXPANSION,
}
/// <summary>
/// Visitor interface used to enumerate all <see cref="LibraryNode"/>s in the library.
/// </summary>
public interface ILibraryNodeVisitor {
/// <summary>
/// Called on each node before any of its child nodes are visited.
/// </summary>
/// <param name="node">The node that is being visited.</param>
/// <returns><c>true</c> if children of this node should be visited, otherwise <c>false</c>.</returns>
bool EnterNode(LibraryNode node, CancellationToken ct);
/// <summary>
/// Called on each node after all its child nodes were visited.
/// </summary>
/// <param name="node">The node that was being visited.</param>
void LeaveNode(LibraryNode node, CancellationToken ct);
}
}