Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions SolidDna/CADBooster.SolidDna/Errors/SolidDnaErrorCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,11 @@ public enum SolidDnaErrorCode
/// </summary>
SolidWorksCommandItemPositionError = 12010,

/// <summary>
/// There was an error while trying to activate a Context Menu Item that was already activated
/// </summary>
SolidWorksCommandContextMenuItemReActivateError = 12011,

#endregion

#region Export Data (13,000)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ public class CommandManager : SolidDnaObject<ICommandManager>
/// </summary>
private readonly List<CommandManagerFlyout> mCommandFlyouts = new List<CommandManagerFlyout>();

/// <summary>
/// A list of all created command context menu items
/// </summary>
private readonly List<ICommandCreated> mCommandContextItems = new List<ICommandCreated>();

/// <summary>
/// Unique ID for flyouts (just increment every time we add one)
/// </summary>
Expand Down Expand Up @@ -76,6 +81,16 @@ public CommandManagerGroup CreateCommandTab(string title, int id, List<ICommandM
#pragma warning restore CS0618
}

/// <summary>
/// Creates context menu items from the provided collection of <see cref="ICommandCreatable"/> objects
/// </summary>
/// <param name="commandItems">The collection of command items to create</param>
public void CreateContextMenuItems(IEnumerable<ICommandCreatable> commandItems)
{
foreach (var item in commandItems)
mCommandContextItems.AddRange(item.Create());
}

/// <summary>
/// Create a command group from a list of <see cref="CommandManagerItem"/> items. Uses a single list of items, separators and flyouts.
/// NOTE: If you set <paramref name="ignorePreviousVersion"/> to false, you should pick a new ID every time you change your tab.
Expand Down Expand Up @@ -119,7 +134,7 @@ public CommandManagerGroup CreateCommandGroupAndTabs(string title, int id, List<

// Track all flyouts for all add-ins that use SolidDNA
mCommandFlyouts.AddRange(commandManagerItems.OfType<CommandManagerFlyout>());

// Create the group
group.Create(this, title);

Expand Down Expand Up @@ -251,7 +266,10 @@ private CommandManagerGroup CreateCommandGroup(string title, int id, List<IComma
private void RemoveCommandFlyout(CommandManagerFlyout flyout)
{
lock (mCommandFlyouts)
{
BaseObject.RemoveFlyoutGroup(flyout.UserId);
mCommandFlyouts.Remove(flyout);
}
}

/// <summary>
Expand All @@ -262,7 +280,10 @@ private void RemoveCommandFlyout(CommandManagerFlyout flyout)
private void RemoveCommandGroup(CommandManagerGroup group, bool runtimeOnly = false)
{
lock (mCommandGroups)
{
BaseObject.RemoveCommandGroup2(group.UserId, runtimeOnly);
mCommandGroups.Remove(group);
}
}

/// <summary>
Expand Down Expand Up @@ -318,6 +339,10 @@ public override void Dispose()
// Remove all command flyouts
mCommandFlyouts?.ForEach(RemoveCommandFlyout);

// Dispose all command context menu items
mCommandContextItems?.ForEach(x => x.Dispose());
mCommandContextItems.Clear();

base.Dispose();
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using SolidWorks.Interop.swconst;
using System;
using System.Collections.Generic;
using System.Linq;

namespace CADBooster.SolidDna
{
/// <summary>
/// Provides extension methods for converting <see cref="CommandManagerItem"/> objects to <see cref="ICommandCreatable"/>
/// </summary>
public static class CommandManagerItemExtensions
{
/// <summary>
/// Converts a collection of <see cref="CommandManagerItem"/> objects to <see cref="ICommandCreatable"/> objects
/// </summary>
/// <param name="items">The collection of <see cref="CommandManagerItem"/> objects to convert</param>
/// <param name="selectTypeSelector">An optional function to determine the selection type for each item</param>
/// <returns>A collection of <see cref="ICommandCreatable"/> objects</returns>
public static IEnumerable<ICommandCreatable> AsCommandCreatable(this IEnumerable<CommandManagerItem> items,
Func<CommandManagerItem, SelectionType> selectTypeSelector = null)
=> items.Select(x =>
x.AsCommandCreatable(
selectTypeSelector is null
? SelectionType.Everything
: selectTypeSelector.Invoke(x)));

/// <summary>
/// Converts a single <see cref="CommandManagerItem"/> object to an <see cref="ICommandCreatable"/> object
/// </summary>
/// <param name="item">The <see cref="CommandManagerItem"/> object to convert</param>
/// <returns>An <see cref="ICommandCreatable"/> object</returns>
public static ICommandCreatable AsCommandCreatable(this CommandManagerItem item)
=> item.AsCommandCreatable(SelectionType.Everything);

/// <summary>
/// Converts a single <see cref="CommandManagerItem"/> object to an <see cref="ICommandCreatable"/> object
/// </summary>
/// <param name="item">The <see cref="CommandManagerItem"/> object to convert</param>
/// <param name="selectType">The selection type for the item (defaults to <see cref="SelectionType.Everything"/>)</param>
/// <returns>An <see cref="ICommandCreatable"/> object</returns>
public static ICommandCreatable AsCommandCreatable(this CommandManagerItem item, SelectionType selectType)
=> new CommandContextItem()
{
Name = item.Name,
Hint = item.Hint,
OnClick = item.OnClick,
OnStateCheck = item.OnStateCheck,
SelectionType = selectType,
VisibleForAssemblies = item.VisibleForAssemblies,
VisibleForDrawings = item.VisibleForDrawings,
VisibleForParts = item.VisibleForParts
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using SolidWorks.Interop.swconst;
using System;
using System.Collections.Generic;
using System.Linq;

namespace CADBooster.SolidDna
{
/// <summary>
/// A command context menu item base class
/// </summary>
public abstract class CommandContextBase
{

private bool _isCreated;

#region Public Properties

/// <summary>
/// The help text for this item.
/// </summary>
public string Hint { get; set; }

/// <summary>
/// True to show this item in the context menu when an assembly is open.
/// </summary>
public bool VisibleForAssemblies { get; set; } = true;

/// <summary>
/// True to show this item in the context menu when a drawing is open.
/// </summary>
public bool VisibleForDrawings { get; set; } = true;

/// <summary>
/// True to show this item in the context menu when a part is open.
/// </summary>
public bool VisibleForParts { get; set; } = true;

/// <summary>
/// The action to call when the item is clicked
/// </summary>
public Action OnClick { get; set; }

/// <summary>
/// The action to call when the item state requested
/// </summary>
public Action<CommandManagerItemStateCheckArgs> OnStateCheck { get; set; }

/// <summary>
/// The selection type that determines where the context menu will be shown
/// </summary>
public SelectionType SelectionType { get; set; } = SelectionType.Everything;

#endregion

/// <summary>
/// Creates the command context item for the specified document types
/// </summary>
/// <param name="path">The path to use for hierarchical naming. If empty, the item's name is used</param>
/// <returns>A list of created command context items</returns>
/// <exception cref="SolidDnaException">Thrown if the item has already been created</exception>
public virtual IEnumerable<ICommandCreated> Create(string path = "")
{
if (_isCreated)
throw new SolidDnaException(
SolidDnaErrors.CreateError(SolidDnaErrorTypeCode.SolidWorksCommandManager,
SolidDnaErrorCode.SolidWorksCommandContextMenuItemReActivateError));

_isCreated = true;

return Enumerable.Empty<ICommandCreated>();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
using SolidWorks.Interop.swconst;
using System;

namespace CADBooster.SolidDna
{
internal abstract class CommandContextCreatedBase : ICommandCreated, ICommandItem
{
/// <summary>
/// Gets the unique callback ID for this command context item
/// </summary>
public string CallbackId { get; } = Guid.NewGuid().ToString("N");

/// <summary>
/// Gets the name of this command context item
/// </summary>
public abstract string Name { get; }

/// <summary>
/// Gets the hint text for this command context item
/// </summary>
public string Hint { get; }

/// <summary>
/// Gets the selection type that determines where this item is shown
/// </summary>
public SelectionType SelectionType { get; }

/// <summary>
/// Gets the document type (Assembly, Part, or Drawing) for which this item is created
/// </summary>
public DocumentType DocumentType { get; }

/// <summary>
/// Gets the action to call when this item is clicked
/// </summary>
public Action OnClick { get; }

/// <summary>
/// Gets the action to call when the state of this item is checked
/// </summary>
public Action<CommandManagerItemStateCheckArgs> OnStateCheck { get; private set; }

/// <summary>
/// Initializes a new instance of the <see cref="CommandContextItemCreated"/> class
/// </summary>
/// <param name="commandContextItem">The command context item to create</param>
/// <param name="fullName">The full name of the item, including its hierarchical path</param>
/// <param name="documentType">The document type (Assembly, Part, or Drawing) for which this item is created</param>
public CommandContextCreatedBase(CommandContextBase commandContextBase, DocumentType documentType)
{
Hint = commandContextBase.Hint;
OnClick = commandContextBase.OnClick;
OnStateCheck = commandContextBase.OnStateCheck;
SelectionType = commandContextBase.SelectionType;
DocumentType = documentType;

// Listen out for callbacks
PlugInIntegration.CallbackFired += PlugInIntegration_CallbackFired;

// Listen out for EnableMethod
PlugInIntegration.ItemStateCheckFired += PlugInIntegration_EnableMethodFired;

Logger.LogDebugSource("Context menu item created");
}

/// <summary>
/// Fired when a SolidWorks callback is fired
/// </summary>
/// <param name="name">The name of the callback that was fired</param>
private void PlugInIntegration_CallbackFired(string name)
{
if (CallbackId != name)
return;

// Call the action
OnClick?.Invoke();
}

/// <summary>
/// Fired when a SolidWorks UpdateCallbackFunction is fired
/// </summary>
/// <param name="args">The arguments for user handling</param>
private void PlugInIntegration_EnableMethodFired(CommandManagerItemStateCheckArgs args)
{
if (CallbackId != args.CallbackId)
return;

// Call the action
OnStateCheck?.Invoke(args);
}

/// <summary>
/// Disposing
/// </summary>
public void Dispose()
{
/// I can't find the way to remove the item

/// It always returns false, and the item isn't removed.
//var removeMenuPopupItemResult = AddInIntegration.SolidWorks.UnsafeObject.RemoveMenuPopupItem2(
// (int)DocumentType,
// SolidWorksEnvironment.Application.SolidWorksCookie,
// (int)SelectionType,
// FullName,
// $"{nameof(SolidAddIn.Callback)}({CallbackId})",
// $"{nameof(SolidAddIn.ItemStateCheck)}({CallbackId})",
// Hint,
// string.Empty
//);

/// It always returns true, but the item isn't removed.
//var removeFromPopupMenuResult = AddInIntegration.SolidWorks.UnsafeObject.RemoveFromPopupMenu(
// CommandId,
// (int)DocumentType,
// (int)SelectionType,
// true
//);

/// Besides, the user can hide it using <see cref="ICommandItem.OnStateCheck"/>.

// Stop listening out for callbacks
PlugInIntegration.CallbackFired -= PlugInIntegration_CallbackFired;
PlugInIntegration.ItemStateCheckFired -= PlugInIntegration_EnableMethodFired;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System.Collections.Generic;

namespace CADBooster.SolidDna
{
/// <summary>
/// Represents a context icon in SolidWorks
/// </summary>
public class CommandContextIcon : CommandContextBase, ICommandCreatable
{
/// <summary>
/// Gets or sets the icon formatted path
/// </summary>
public string Icon { get; set; }

/// <summary>
/// Gets the name of the command (implementing ICommandCreatable interface)
/// </summary>
string ICommandCreatable.Name => Hint;

/// <summary>
/// Creates the command context icon for the specified document types
/// </summary>
/// <param name="path">Not used for icon</param>
/// <returns>A list of created command context icons</returns>
/// <exception cref="SolidDnaException">Thrown if the item has already been created</exception>
public sealed override IEnumerable<ICommandCreated> Create(string _s = "")
{
_ = base.Create();

var created = new List<CommandContextIconCreated>();

if (VisibleForAssemblies)
created.Add(new CommandContextIconCreated(this, DocumentType.Assembly));
if (VisibleForDrawings)
created.Add(new CommandContextIconCreated(this, DocumentType.Drawing));
if (VisibleForParts)
created.Add(new CommandContextIconCreated(this, DocumentType.Part));

return created;
}
}
}
Loading