From 11ec9e8f456efe52ce0acae22c0a07c9195cc64e Mon Sep 17 00:00:00 2001 From: CodeStack Date: Sat, 3 Aug 2019 12:08:21 +1000 Subject: [PATCH 1/6] Removed unused pre build event --- Installer/Addin11.wxs | 27 --------------------------- Installer/Installer.wixproj | 2 +- 2 files changed, 1 insertion(+), 28 deletions(-) delete mode 100644 Installer/Addin11.wxs diff --git a/Installer/Addin11.wxs b/Installer/Addin11.wxs deleted file mode 100644 index b8a2f68..0000000 --- a/Installer/Addin11.wxs +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Installer/Installer.wixproj b/Installer/Installer.wixproj index 7c232cd..6a1d630 100644 --- a/Installer/Installer.wixproj +++ b/Installer/Installer.wixproj @@ -55,6 +55,6 @@ - "%25Wix%25bin\heat" file "$(SolutionDir)Build\CodeStack.Sw.MyToolbar.dll" -gg -srd -sfrag -template fragment -cg AddinComponents -var var.SourceOutDir -dr INSTALLFOLDER -out "$(ProjectDir)Addin11.wxs" + \ No newline at end of file From 0561d3e6b9b159abafc447f4ae2f69a535ecf13d Mon Sep 17 00:00:00 2001 From: CodeStack Date: Mon, 7 Oct 2019 11:27:39 +1100 Subject: [PATCH 2/6] Updated the SwEx libraries Added the EnumComboBox control --- CodeMaid.config | 24 --- MyToolbar.Tests/MyToolbar.Tests.csproj | 28 +-- MyToolbar.Tests/UITests.cs | 4 +- MyToolbar.Tests/app.config | 12 ++ MyToolbar.Tests/packages.config | 5 +- MyToolbar/MyToolbar.csproj | 32 +-- MyToolbar/Properties/AssemblyInfo.cs | 1 + MyToolbar/Themes/Generic.xaml | 27 +++ MyToolbar/UI/Controls/EnumComboBox.cs | 247 ++++++++++++++++++++++ MyToolbar/UI/ViewModels/CommandMacroVM.cs | 28 +++ MyToolbar/UI/Views/CommandMacroView.xaml | 6 + MyToolbar/packages.config | 4 +- 12 files changed, 361 insertions(+), 57 deletions(-) delete mode 100644 CodeMaid.config create mode 100644 MyToolbar/Themes/Generic.xaml create mode 100644 MyToolbar/UI/Controls/EnumComboBox.cs diff --git a/CodeMaid.config b/CodeMaid.config deleted file mode 100644 index cf6d626..0000000 --- a/CodeMaid.config +++ /dev/null @@ -1,24 +0,0 @@ - - - - -
- - - - - - //********************** -//MyToolbar - Custom toolbar manager -//Copyright(C) 2019 www.codestack.net -//License: https://github.com/codestack-net-dev/my-toolbar/blob/master/LICENSE -//Product URL: https://www.codestack.net/labs/solidworks/my-toolbar/ -//********************** - - - - False - - - - \ No newline at end of file diff --git a/MyToolbar.Tests/MyToolbar.Tests.csproj b/MyToolbar.Tests/MyToolbar.Tests.csproj index e2f2409..9ea21ba 100644 --- a/MyToolbar.Tests/MyToolbar.Tests.csproj +++ b/MyToolbar.Tests/MyToolbar.Tests.csproj @@ -43,35 +43,35 @@ ..\packages\Castle.Core.4.4.0\lib\net45\Castle.Core.dll True - - ..\packages\CodeStack.SwEx.AddIn.0.7.0\lib\net40\CodeStack.SwEx.AddIn.dll - True + + ..\packages\CodeStack.SwEx.AddIn.0.8.1\lib\net40\CodeStack.SwEx.AddIn.dll - - ..\packages\CodeStack.SwEx.Common.0.9.6\lib\net40\CodeStack.SwEx.Common.dll - True + + ..\packages\CodeStack.SwEx.Common.0.9.9\lib\net40\CodeStack.SwEx.Common.dll ..\packages\Moq.4.11.0\lib\net45\Moq.dll True + + ..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll + - - ..\packages\CodeStack.SwEx.Common.0.9.6\lib\net40\SolidWorks.Interop.sldworks.dll + + ..\packages\CodeStack.SwEx.Common.0.9.9\lib\net40\SolidWorks.Interop.sldworks.dll False - - ..\packages\CodeStack.SwEx.Common.0.9.6\lib\net40\SolidWorks.Interop.swconst.dll + + ..\packages\CodeStack.SwEx.Common.0.9.9\lib\net40\SolidWorks.Interop.swconst.dll False - - ..\packages\CodeStack.SwEx.Common.0.9.6\lib\net40\SolidWorks.Interop.swpublished.dll + + ..\packages\CodeStack.SwEx.Common.0.9.9\lib\net40\SolidWorks.Interop.swpublished.dll False - ..\packages\CodeStack.SwEx.Common.0.9.6\lib\net40\SolidWorksTools.dll - True + ..\packages\CodeStack.SwEx.Common.0.9.9\lib\net40\SolidWorksTools.dll diff --git a/MyToolbar.Tests/UITests.cs b/MyToolbar.Tests/UITests.cs index 8e7b551..d322e9f 100644 --- a/MyToolbar.Tests/UITests.cs +++ b/MyToolbar.Tests/UITests.cs @@ -13,6 +13,8 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using System; +using System.Collections.Generic; +using System.Linq; namespace MyToolbar.Tests { @@ -34,7 +36,7 @@ public void Setup() appMock.Object, new Mock().Object); } - + [TestMethod] public void DisplayCommandManagerView() { diff --git a/MyToolbar.Tests/app.config b/MyToolbar.Tests/app.config index 0fe8f22..7fe3349 100644 --- a/MyToolbar.Tests/app.config +++ b/MyToolbar.Tests/app.config @@ -10,6 +10,18 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/MyToolbar.Tests/packages.config b/MyToolbar.Tests/packages.config index 71d4b92..e96e5a5 100644 --- a/MyToolbar.Tests/packages.config +++ b/MyToolbar.Tests/packages.config @@ -1,9 +1,10 @@  - - + + + \ No newline at end of file diff --git a/MyToolbar/MyToolbar.csproj b/MyToolbar/MyToolbar.csproj index 6c9ef16..889dc3d 100644 --- a/MyToolbar/MyToolbar.csproj +++ b/MyToolbar/MyToolbar.csproj @@ -5,6 +5,7 @@ 8.0.50727 2.0 {7ACEDAA9-2DE8-4485-837A-E7D58812A6DC} + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} Debug AnyCPU @@ -96,13 +97,11 @@ false - - ..\packages\CodeStack.SwEx.AddIn.0.7.0\lib\net40\CodeStack.SwEx.AddIn.dll - True + + ..\packages\CodeStack.SwEx.AddIn.0.8.1\lib\net40\CodeStack.SwEx.AddIn.dll - - ..\packages\CodeStack.SwEx.Common.0.9.6\lib\net40\CodeStack.SwEx.Common.dll - True + + ..\packages\CodeStack.SwEx.Common.0.9.9\lib\net40\CodeStack.SwEx.Common.dll ..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll @@ -110,21 +109,20 @@ - - ..\packages\CodeStack.SwEx.Common.0.9.6\lib\net40\SolidWorks.Interop.sldworks.dll + + ..\packages\CodeStack.SwEx.Common.0.9.9\lib\net40\SolidWorks.Interop.sldworks.dll False - - ..\packages\CodeStack.SwEx.Common.0.9.6\lib\net40\SolidWorks.Interop.swconst.dll + + ..\packages\CodeStack.SwEx.Common.0.9.9\lib\net40\SolidWorks.Interop.swconst.dll False - - ..\packages\CodeStack.SwEx.Common.0.9.6\lib\net40\SolidWorks.Interop.swpublished.dll + + ..\packages\CodeStack.SwEx.Common.0.9.9\lib\net40\SolidWorks.Interop.swpublished.dll False - ..\packages\CodeStack.SwEx.Common.0.9.6\lib\net40\SolidWorksTools.dll - True + ..\packages\CodeStack.SwEx.Common.0.9.9\lib\net40\SolidWorksTools.dll System @@ -212,6 +210,7 @@ + @@ -274,6 +273,10 @@ + + MSBuild:Compile + Designer + Designer MSBuild:Compile @@ -315,6 +318,7 @@ + diff --git a/MyToolbar/Properties/AssemblyInfo.cs b/MyToolbar/Properties/AssemblyInfo.cs index d725019..d73fe4e 100644 --- a/MyToolbar/Properties/AssemblyInfo.cs +++ b/MyToolbar/Properties/AssemblyInfo.cs @@ -12,6 +12,7 @@ using Xarial.AppLaunchKit.Attributes; using Xarial.AppLaunchKit.Services.Attributes; +[assembly: System.Windows.ThemeInfo(System.Windows.ResourceDictionaryLocation.None, System.Windows.ResourceDictionaryLocation.SourceAssembly)] [assembly: AssemblyTitle("MyToolbar")] [assembly: AssemblyDescription("Add-in to manage custom toolbars in SOLIDWORKS")] [assembly: AssemblyConfiguration("")] diff --git a/MyToolbar/Themes/Generic.xaml b/MyToolbar/Themes/Generic.xaml new file mode 100644 index 0000000..8f36248 --- /dev/null +++ b/MyToolbar/Themes/Generic.xaml @@ -0,0 +1,27 @@ + + + + + diff --git a/MyToolbar/UI/Controls/EnumComboBox.cs b/MyToolbar/UI/Controls/EnumComboBox.cs new file mode 100644 index 0000000..e669606 --- /dev/null +++ b/MyToolbar/UI/Controls/EnumComboBox.cs @@ -0,0 +1,247 @@ +//********************** +//MyToolbar - Custom toolbar manager +//Copyright(C) 2019 www.codestack.net +//License: https://github.com/codestack-net-dev/my-toolbar/blob/master/LICENSE +//Product URL: https://www.codestack.net/labs/solidworks/my-toolbar/ +//********************** + +using CodeStack.Sw.MyToolbar.UI.Base; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; + +namespace CodeStack.Sw.MyToolbar.UI.Controls +{ + public class EnumValueToHeaderConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + var enumVal = value as Enum; + return enumVal.ToString(); + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } + + public class EnumComboBoxItemTemplateSelector : DataTemplateSelector + { + public DataTemplate Item { get; set; } + public DataTemplate Header { get; set; } + + public override DataTemplate SelectTemplate(object item, DependencyObject container) + { + var elem = container as FrameworkElement; + + if (elem?.TemplatedParent is EnumComboBox) + { + return Header; + } + else + { + return Item; + } + } + } + + public class EnumComboBox : ComboBox + { + public enum EnumItemType_e + { + Default, + Combined, + None + } + + public class EnumComboBoxItem : NotifyPropertyChanged + { + private readonly EnumComboBox m_Parent; + private readonly Enum m_Value; + private readonly Enum[] m_AffectedFlags; + + internal EnumComboBoxItem(EnumComboBox parent, Enum value, Enum[] affectedFlags) + { + m_Parent = parent; + m_Parent.ValueChanged += OnValueChanged; + m_Value = value; + m_AffectedFlags = affectedFlags; + + if (m_AffectedFlags.Length > 1) + { + Type = EnumItemType_e.Combined; + } + else if (m_AffectedFlags.Length == 0) + { + Type = EnumItemType_e.None; + } + else + { + Type = EnumItemType_e.Default; + } + } + + public EnumItemType_e Type { get; private set; } + + public bool IsSelected + { + get + { + if (Type == EnumItemType_e.None) + { + return IsNone(m_Parent.Value); + } + else + { + return m_Parent.Value.HasFlag(m_Value); + } + } + set + { + if (Type == EnumItemType_e.None) + { + m_Parent.Value = (Enum)Enum.ToObject(m_Value.GetType(), 0); + } + else + { + int val = Convert.ToInt32(m_Parent.Value); + + if (value) + { + foreach (var flag in m_AffectedFlags) + { + if (!m_Parent.Value.HasFlag(flag)) + { + val += Convert.ToInt32(flag); + } + } + } + else + { + foreach (var flag in m_AffectedFlags) + { + if (m_Parent.Value.HasFlag(flag)) + { + val -= Convert.ToInt32(flag); + } + } + } + + m_Parent.Value = (Enum)Enum.ToObject(m_Value.GetType(), val); + } + + NotifyChanged(); + } + } + + private void OnValueChanged(Enum value) + { + NotifyChanged(nameof(IsSelected)); + } + + private bool IsNone(Enum val) + { + return Convert.ToInt32(val) == 0; + } + + public override string ToString() + { + return m_Value.ToString(); + } + } + + internal event Action ValueChanged; + + private Type m_CurBoundType; + private Enum[] m_CurFlags; + + static EnumComboBox() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(EnumComboBox), + new FrameworkPropertyMetadata(typeof(EnumComboBox))); + } + + public static readonly DependencyProperty ValueProperty = + DependencyProperty.Register(nameof(Value), typeof(Enum), + typeof(EnumComboBox), new FrameworkPropertyMetadata( + null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnValueChanged)); + + public Enum Value + { + get { return (Enum)GetValue(ValueProperty); } + set { SetValue(ValueProperty, value); } + } + + private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var cmb = d as EnumComboBox; + + var val = e.NewValue as Enum; + + if (val != null) + { + var enumType = val.GetType(); + + if (enumType != cmb.m_CurBoundType) + { + cmb.m_CurFlags = GetFlags(enumType); + + cmb.Items.Clear(); + + cmb.m_CurBoundType = enumType; + + var items = Enum.GetValues(enumType); + + foreach (Enum item in items) + { + cmb.Items.Add(new EnumComboBoxItem(cmb, item, + cmb.m_CurFlags.Where(f => item.HasFlag(f)).ToArray())); + } + + UpdateHeader(cmb); + } + } + + cmb.ValueChanged?.Invoke(val); + } + + private static Enum[] GetFlags(Type enumType) + { + var flags = new List(); + + var flag = 0x1; + + foreach (Enum value in Enum.GetValues(enumType)) + { + var bits = Convert.ToInt32(value); + + if (bits != 0) + { + while (flag < bits) + { + flag <<= 1; + } + if (flag == bits) + { + flags.Add(value); + } + } + } + + return flags.ToArray(); + } + + private static void UpdateHeader(EnumComboBox cmb) + { + if (cmb.Items.Count > 0) + { + cmb.SelectedIndex = 0; + } + } + } +} diff --git a/MyToolbar/UI/ViewModels/CommandMacroVM.cs b/MyToolbar/UI/ViewModels/CommandMacroVM.cs index 3221bcc..72e3311 100644 --- a/MyToolbar/UI/ViewModels/CommandMacroVM.cs +++ b/MyToolbar/UI/ViewModels/CommandMacroVM.cs @@ -8,10 +8,23 @@ using CodeStack.Sw.MyToolbar.Helpers; using CodeStack.Sw.MyToolbar.Structs; using CodeStack.Sw.MyToolbar.UI.Base; +using System; using System.Windows.Input; namespace CodeStack.Sw.MyToolbar.UI.ViewModels { + [Flags] + public enum MacroScope_e + { + None = 0, + Application = 1, + Part = 2, + Assembly = 4, + Drawing = 8, + AllDocuments = Part | Assembly | Drawing, + All = Application | AllDocuments + } + public class CommandMacroVM : CommandVM { private ICommand m_BrowseMacroPathCommand; @@ -67,6 +80,21 @@ public ICommand BrowseMacroPathCommand } } + private MacroScope_e m_Scope = MacroScope_e.Application | MacroScope_e.Part | MacroScope_e.Assembly | MacroScope_e.Drawing; + + public MacroScope_e Scope + { + get + { + return m_Scope; + } + set + { + m_Scope = value; + NotifyChanged(); + } + } + public CommandMacroVM() : this(new CommandMacroInfo()) { } diff --git a/MyToolbar/UI/Views/CommandMacroView.xaml b/MyToolbar/UI/Views/CommandMacroView.xaml index c12638f..479dc51 100644 --- a/MyToolbar/UI/Views/CommandMacroView.xaml +++ b/MyToolbar/UI/Views/CommandMacroView.xaml @@ -4,6 +4,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:CodeStack.Sw.MyToolbar.UI.Views" + xmlns:ctrls="clr-namespace:CodeStack.Sw.MyToolbar.UI.Controls" xmlns:conv="clr-namespace:CodeStack.Sw.MyToolbar.UI.Converters" xmlns:vm="clr-namespace:CodeStack.Sw.MyToolbar.UI.ViewModels" mc:Ignorable="d" @@ -24,6 +25,7 @@ + @@ -43,6 +45,10 @@ Grid.Column="1" Grid.Row="1" Margin="2" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Path=MacroPath, Converter={StaticResource macroPathToEntryPtsConv}}" /> + + + + \ No newline at end of file diff --git a/MyToolbar/packages.config b/MyToolbar/packages.config index abccd89..f5cd9fa 100644 --- a/MyToolbar/packages.config +++ b/MyToolbar/packages.config @@ -1,7 +1,7 @@  - - + + From b7a7a9846c593684fa3c9ac5181f2f6feec9d0ee Mon Sep 17 00:00:00 2001 From: CodeStack Date: Mon, 7 Oct 2019 14:23:23 +1100 Subject: [PATCH 3/6] Implemented events handlers Added the local settings handler --- MyToolbar/Base/CommandGroupInfoSpec.cs | 8 +- MyToolbar/Base/CommandItemInfoSpec.cs | 20 ++- MyToolbar/Base/MacroButtonIcon.cs | 24 +-- MyToolbar/Enums/MacroScope_e.cs | 26 +++ MyToolbar/Enums/Triggers_e.cs | 28 ++++ MyToolbar/Helpers/EnumHelper.cs | 38 +++++ MyToolbar/Helpers/MacroScopeHelper.cs | 35 ++++ MyToolbar/MyToolbar.csproj | 6 + MyToolbar/MyToolbarSwAddin.cs | 168 +++++++++++++++++++- MyToolbar/Services/LocalSettingsProvider.cs | 51 ++++++ MyToolbar/ServicesContainer.cs | 3 + MyToolbar/Structs/CommandMacroInfo.cs | 4 + MyToolbar/Structs/CustomToolbarInfo.cs | 2 +- MyToolbar/Structs/ToolbarLocalSettings.cs | 18 +++ MyToolbar/Themes/Generic.xaml | 5 +- MyToolbar/ToolbarInfoVersionConverter.cs | 15 ++ MyToolbar/UI/Controls/EnumComboBox.cs | 74 +++++---- MyToolbar/UI/ViewModels/CommandMacroVM.cs | 33 ++-- MyToolbar/UI/Views/CommandMacroView.xaml | 4 + 19 files changed, 486 insertions(+), 76 deletions(-) create mode 100644 MyToolbar/Enums/MacroScope_e.cs create mode 100644 MyToolbar/Enums/Triggers_e.cs create mode 100644 MyToolbar/Helpers/EnumHelper.cs create mode 100644 MyToolbar/Helpers/MacroScopeHelper.cs create mode 100644 MyToolbar/Services/LocalSettingsProvider.cs create mode 100644 MyToolbar/Structs/ToolbarLocalSettings.cs diff --git a/MyToolbar/Base/CommandGroupInfoSpec.cs b/MyToolbar/Base/CommandGroupInfoSpec.cs index 92060aa..a2e8f02 100644 --- a/MyToolbar/Base/CommandGroupInfoSpec.cs +++ b/MyToolbar/Base/CommandGroupInfoSpec.cs @@ -5,8 +5,10 @@ //Product URL: https://www.codestack.net/labs/solidworks/my-toolbar/ //********************** +using CodeStack.Sw.MyToolbar.Enums; using CodeStack.Sw.MyToolbar.Structs; using CodeStack.SwEx.AddIn.Core; +using SolidWorks.Interop.sldworks; using System; using System.Linq; @@ -16,7 +18,7 @@ internal class CommandGroupInfoSpec : CommandGroupSpec { public event Action MacroCommandClick; - internal CommandGroupInfoSpec(CommandGroupInfo info) + internal CommandGroupInfoSpec(CommandGroupInfo info, ISldWorks app) { Id = info.Id; Title = info.Title; @@ -25,10 +27,10 @@ internal CommandGroupInfoSpec(CommandGroupInfo info) if (info.Commands != null) { - Commands = info.Commands.Select( + Commands = info.Commands.Where(c => c.Triggers.HasFlag(Triggers_e.Button)).Select( c => { - var spec = new CommandItemInfoSpec(c); + var spec = new CommandItemInfoSpec(c, app); spec.MacroCommandClick += OnMacroCommandClick; return spec; }).ToArray(); diff --git a/MyToolbar/Base/CommandItemInfoSpec.cs b/MyToolbar/Base/CommandItemInfoSpec.cs index c735e71..aa52d63 100644 --- a/MyToolbar/Base/CommandItemInfoSpec.cs +++ b/MyToolbar/Base/CommandItemInfoSpec.cs @@ -5,8 +5,11 @@ //Product URL: https://www.codestack.net/labs/solidworks/my-toolbar/ //********************** +using CodeStack.Sw.MyToolbar.Helpers; using CodeStack.Sw.MyToolbar.Structs; using CodeStack.SwEx.AddIn.Core; +using CodeStack.SwEx.AddIn.Enums; +using SolidWorks.Interop.sldworks; using System; namespace CodeStack.Sw.MyToolbar.Base @@ -16,10 +19,13 @@ internal class CommandItemInfoSpec : CommandSpec public event Action MacroCommandClick; private readonly CommandMacroInfo m_Info; + private readonly ISldWorks m_App; - internal CommandItemInfoSpec(CommandMacroInfo info) + internal CommandItemInfoSpec(CommandMacroInfo info, ISldWorks app) { m_Info = info; + m_App = app; + UserId = info.Id; Title = info.Title; Tooltip = info.Description; @@ -32,5 +38,17 @@ public override void OnClick() { MacroCommandClick?.Invoke(m_Info); } + + public override CommandItemEnableState_e OnEnable() + { + if (m_Info.Scope.IsInScope(m_App)) + { + return CommandItemEnableState_e.DeselectEnable; + } + else + { + return CommandItemEnableState_e.DeselectDisable; + } + } } } \ No newline at end of file diff --git a/MyToolbar/Base/MacroButtonIcon.cs b/MyToolbar/Base/MacroButtonIcon.cs index 79c57b0..913ccd8 100644 --- a/MyToolbar/Base/MacroButtonIcon.cs +++ b/MyToolbar/Base/MacroButtonIcon.cs @@ -9,30 +9,10 @@ namespace CodeStack.Sw.MyToolbar.Base { - public class MacroButtonIcon : CommandGroupIcon + public class MacroButtonIcon : MasterIcon { - private readonly Image m_Icon; - - //TODO: once MasterIcon constructor in SwEx.AddIn is made to protected internal call it from here and remove all overloads - internal MacroButtonIcon(Image icon) - { - m_Icon = icon; - } - - public override IEnumerable GetHighResolutionIconSizes() - { - yield return new IconSizeInfo(m_Icon, new Size(20, 20)); - yield return new IconSizeInfo(m_Icon, new Size(32, 32)); - yield return new IconSizeInfo(m_Icon, new Size(40, 40)); - yield return new IconSizeInfo(m_Icon, new Size(64, 64)); - yield return new IconSizeInfo(m_Icon, new Size(96, 96)); - yield return new IconSizeInfo(m_Icon, new Size(128, 128)); - } - - public override IEnumerable GetIconSizes() + internal MacroButtonIcon(Image icon) : base(icon) { - yield return new IconSizeInfo(m_Icon, new Size(16, 16)); - yield return new IconSizeInfo(m_Icon, new Size(24, 24)); } } } diff --git a/MyToolbar/Enums/MacroScope_e.cs b/MyToolbar/Enums/MacroScope_e.cs new file mode 100644 index 0000000..47394fa --- /dev/null +++ b/MyToolbar/Enums/MacroScope_e.cs @@ -0,0 +1,26 @@ +using CodeStack.SwEx.Common.Attributes; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CodeStack.Sw.MyToolbar.Enums +{ + [Flags] + public enum MacroScope_e + { + [Summary("No Open Documents")] + Application = 1, + + Part = 2, + Assembly = 4, + Drawing = 8, + + [Title("All Documents")] + [Summary("All Documents (Part, Assembly, Drawing)")] + AllDocuments = Part | Assembly | Drawing, + + All = Application | AllDocuments + } +} diff --git a/MyToolbar/Enums/Triggers_e.cs b/MyToolbar/Enums/Triggers_e.cs new file mode 100644 index 0000000..5ffc80c --- /dev/null +++ b/MyToolbar/Enums/Triggers_e.cs @@ -0,0 +1,28 @@ +using CodeStack.SwEx.Common.Attributes; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CodeStack.Sw.MyToolbar.Enums +{ + [Flags] + public enum Triggers_e + { + [Summary("Disabled command")] + None = 0, + + [Summary("Invoked by clicking button in the toolbar")] + Button = 1 << 0, + + ApplicationStart = 1 << 1, + ApplicationClose = 1 << 2, + DocumentOpen = 1 << 3, + DocumentSave = 1 << 4, + DocumentClose = 1 << 5, + NewSelection = 1 << 6, + ConfigurationChange = 1 << 7, + Rebuild = 1 << 8, + } +} diff --git a/MyToolbar/Helpers/EnumHelper.cs b/MyToolbar/Helpers/EnumHelper.cs new file mode 100644 index 0000000..fd7ba6b --- /dev/null +++ b/MyToolbar/Helpers/EnumHelper.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CodeStack.Sw.MyToolbar.Helpers +{ + internal static class EnumHelper + { + //TODO: move to the framework + internal static Enum[] GetFlags(Type enumType) + { + var flags = new List(); + + var flag = 0x1; + + foreach (Enum value in Enum.GetValues(enumType)) + { + var bits = Convert.ToInt32(value); + + if (bits != 0) + { + while (flag < bits) + { + flag <<= 1; + } + if (flag == bits) + { + flags.Add(value); + } + } + } + + return flags.ToArray(); + } + } +} diff --git a/MyToolbar/Helpers/MacroScopeHelper.cs b/MyToolbar/Helpers/MacroScopeHelper.cs new file mode 100644 index 0000000..6978860 --- /dev/null +++ b/MyToolbar/Helpers/MacroScopeHelper.cs @@ -0,0 +1,35 @@ +using CodeStack.Sw.MyToolbar.Enums; +using SolidWorks.Interop.sldworks; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CodeStack.Sw.MyToolbar.Helpers +{ + public static class MacroScopeHelper + { + public static bool IsInScope(this MacroScope_e scope, ISldWorks app) + { + if (app.IActiveDoc2 == null && scope.HasFlag(MacroScope_e.Application)) + { + return true; + } + else if (app.IActiveDoc2 is IPartDoc && scope.HasFlag(MacroScope_e.Part)) + { + return true; + } + else if (app.IActiveDoc2 is IAssemblyDoc && scope.HasFlag(MacroScope_e.Assembly)) + { + return true; + } + else if (app.IActiveDoc2 is IDrawingDoc && scope.HasFlag(MacroScope_e.Drawing)) + { + return true; + } + + return false; + } + } +} diff --git a/MyToolbar/MyToolbar.csproj b/MyToolbar/MyToolbar.csproj index 889dc3d..45ab62e 100644 --- a/MyToolbar/MyToolbar.csproj +++ b/MyToolbar/MyToolbar.csproj @@ -170,17 +170,23 @@ + + + + + + Code diff --git a/MyToolbar/MyToolbarSwAddin.cs b/MyToolbar/MyToolbarSwAddin.cs index de847aa..1eb7c62 100644 --- a/MyToolbar/MyToolbarSwAddin.cs +++ b/MyToolbar/MyToolbarSwAddin.cs @@ -6,6 +6,7 @@ //********************** using CodeStack.Sw.MyToolbar.Base; +using CodeStack.Sw.MyToolbar.Enums; using CodeStack.Sw.MyToolbar.Exceptions; using CodeStack.Sw.MyToolbar.Helpers; using CodeStack.Sw.MyToolbar.Services; @@ -14,8 +15,12 @@ using CodeStack.Sw.MyToolbar.UI.ViewModels; using CodeStack.SwEx.AddIn; using CodeStack.SwEx.AddIn.Attributes; +using CodeStack.SwEx.AddIn.Base; +using CodeStack.SwEx.AddIn.Core; using Newtonsoft.Json.Linq; using System; +using System.Collections.Generic; +using System.Linq; using System.Runtime.InteropServices; using System.Windows.Threading; using Xarial.AppLaunchKit.Base.Services; @@ -28,6 +33,10 @@ public class MyToolbarSwAddin : SwAddInEx { private ServicesContainer m_Services; + private Dictionary m_Triggers; + + private IDocumentsHandler m_DocHandler; + public override bool OnConnect() { try @@ -40,10 +49,20 @@ public override bool OnConnect() AppDomain.CurrentDomain.UnhandledException += OnDomainUnhandledException; m_Services = new ServicesContainer(App, Logger); - ExceptionHelper.ExecuteUserCommand(LoadUserToolbar, e => "Failed to load toolbar specification"); + CustomToolbarInfo toolbarInfo = null; + ExceptionHelper.ExecuteUserCommand(() => toolbarInfo = LoadUserToolbar(), + e => "Failed to load toolbar specification"); + + ExceptionHelper.ExecuteUserCommand(() => LoadTriggers(toolbarInfo), + e => "Failed to load toolbar specification"); AddCommandGroup(OnButtonClick); + m_DocHandler = CreateDocumentsHandler(); + m_DocHandler.HandlerCreated += OnDocumentHandlerCreated; + + InvokeTrigger(Triggers_e.ApplicationStart); + return true; } catch (Exception ex) @@ -54,6 +73,93 @@ public override bool OnConnect() } } + public override bool OnDisconnect() + { + InvokeTrigger(Triggers_e.ApplicationClose); + + m_DocHandler.HandlerCreated -= OnDocumentHandlerCreated; + + return true; + } + + private void OnDocumentHandlerCreated(DocumentHandler doc) + { + if (doc.Model == App.IActiveDoc2) + { + InvokeTrigger(Triggers_e.DocumentOpen); + } + + foreach (var trigger in m_Triggers.Keys) + { + switch (trigger) + { + case Triggers_e.DocumentSave: + doc.Save += OnSave; + break; + case Triggers_e.NewSelection: + doc.Selection += OnSelection; + break; + case Triggers_e.ConfigurationChange: + doc.ConfigurationChange += OnConfigurationChange; + break; + case Triggers_e.Rebuild: + doc.Rebuild += OnRebuild; + break; + } + } + + doc.Destroyed += OnDestroyed; + } + + private bool OnSave(DocumentHandler docHandler, string fileName, SwEx.AddIn.Enums.SaveState_e state) + { + if (state == SwEx.AddIn.Enums.SaveState_e.PreSave) + { + InvokeTrigger(Triggers_e.DocumentSave); + } + + return true; + } + + private bool OnSelection(DocumentHandler docHandler, SolidWorks.Interop.swconst.swSelectType_e selType, SwEx.AddIn.Enums.SelectionState_e state) + { + if (state == SwEx.AddIn.Enums.SelectionState_e.NewSelection) + { + InvokeTrigger(Triggers_e.NewSelection); + } + + return true; + } + + private void OnConfigurationChange(DocumentHandler docHandler, SwEx.AddIn.Enums.ConfigurationChangeState_e state, string confName) + { + if (state == SwEx.AddIn.Enums.ConfigurationChangeState_e.PostActivate) + { + InvokeTrigger(Triggers_e.ConfigurationChange); + } + } + + private bool OnRebuild(DocumentHandler docHandler, SwEx.AddIn.Enums.RebuildState_e state) + { + if (state == SwEx.AddIn.Enums.RebuildState_e.PostRebuild) + { + InvokeTrigger(Triggers_e.Rebuild); + } + + return true; + } + + private void OnDestroyed(DocumentHandler docHandler) + { + InvokeTrigger(Triggers_e.DocumentClose); + + docHandler.Save -= OnSave; + docHandler.Selection -= OnSelection; + docHandler.ConfigurationChange -= OnConfigurationChange; + docHandler.Rebuild -= OnRebuild; + docHandler.Destroyed -= OnDestroyed; + } + private void OnDomainUnhandledException(object sender, UnhandledExceptionEventArgs e) { Logger.Log(e.ExceptionObject as Exception); @@ -67,7 +173,7 @@ private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledEx MessageService.ShowMessage("Unknown dispatcher error", MessageType_e.Error); } - private void LoadUserToolbar() + private CustomToolbarInfo LoadUserToolbar() { bool isReadOnly; var toolbarInfo = ToolbarProvider.GetToolbar(out isReadOnly, @@ -75,13 +181,43 @@ private void LoadUserToolbar() if (toolbarInfo?.Groups != null) { - foreach (var grp in toolbarInfo.Groups) + foreach (var grp in toolbarInfo.Groups + .Where(g => g.Commands?.Any(c => c.Triggers.HasFlag(Triggers_e.Button)) == true)) { - var cmdGrp = new CommandGroupInfoSpec(grp); + var cmdGrp = new CommandGroupInfoSpec(grp, App); cmdGrp.MacroCommandClick += OnMacroCommandClick; + + Logger.Log($"Adding command group: {cmdGrp.Title} [{cmdGrp.Id}]. Commands: {string.Join(", ", cmdGrp.Commands.Select(c => $"{c.Title} [{c.UserId}]").ToArray())}"); + AddCommandGroup(cmdGrp); } } + + return toolbarInfo; + } + + private void LoadTriggers(CustomToolbarInfo toolbarInfo) + { + m_Triggers = new Dictionary(); + + var allCmds = toolbarInfo.Groups?.SelectMany(g => g.Commands); + + if (allCmds == null) + { + return; + } + + var triggers = EnumHelper.GetFlags(typeof(Triggers_e)).Where(e => !e.Equals(Triggers_e.Button)); + + foreach (Triggers_e trigger in triggers) + { + var cmds = allCmds.Where(c => c.Scope.HasFlag(trigger)); + + if (cmds.Any()) + { + m_Triggers.Add(trigger, cmds.ToArray()); + } + } } private void OnMacroCommandClick(CommandMacroInfo cmd) @@ -89,6 +225,26 @@ private void OnMacroCommandClick(CommandMacroInfo cmd) RunMacroCommand(cmd); } + private void InvokeTrigger(Triggers_e trigger) + { + CommandMacroInfo[] cmds; + + if (m_Triggers.TryGetValue(trigger, out cmds)) + { + cmds = cmds.Where(c => c.Scope.IsInScope(App)).ToArray(); + + if (cmds != null && cmds.Any()) + { + Logger.Log($"Invoking {cmds.Length} command(s) for the trigger {trigger}"); + + foreach (var cmd in cmds) + { + RunMacroCommand(cmd); + } + } + } + } + private void RunMacroCommand(CommandMacroInfo cmd) { ExceptionHelper.ExecuteUserCommand(() => m_Services.GetService().RunMacro(cmd.MacroPath, cmd.EntryPoint), @@ -160,6 +316,10 @@ private void SaveSettingChanges(ToolbarSettings toolbarSets, CustomToolbarInfo t { toolbarConfProvider.SaveToolbar(toolbarConf, toolbarSets.SpecificationFile); } + else + { + Logger.Log("Skipped saving of read-only toolbar settings"); + } } } diff --git a/MyToolbar/Services/LocalSettingsProvider.cs b/MyToolbar/Services/LocalSettingsProvider.cs new file mode 100644 index 0000000..a61b3b2 --- /dev/null +++ b/MyToolbar/Services/LocalSettingsProvider.cs @@ -0,0 +1,51 @@ +//********************** +//MyToolbar - Custom toolbar manager +//Copyright(C) 2019 www.codestack.net +//License: https://github.com/codestack-net-dev/my-toolbar/blob/master/LICENSE +//Product URL: https://www.codestack.net/labs/solidworks/my-toolbar/ +//********************** + +using CodeStack.Sw.MyToolbar.Properties; +using CodeStack.Sw.MyToolbar.Structs; +using System.IO; +using Xarial.AppLaunchKit.Base.Services; + +namespace CodeStack.Sw.MyToolbar.Services +{ + public interface ILocalSettingsProvider + { + ToolbarLocalSettings GetLocalSettings(); + void SaveLocalSettings(ToolbarLocalSettings localSetts); + } + + public class LocalSettingsProvider : ILocalSettingsProvider + { + private readonly IUserSettingsService m_UserSettsSrv; + + public LocalSettingsProvider(IUserSettingsService userSettsSrv) + { + m_UserSettsSrv = userSettsSrv; + } + + public ToolbarLocalSettings GetLocalSettings() + { + ToolbarLocalSettings localSetts; + + try + { + localSetts = m_UserSettsSrv.ReadSettings(Settings.Default.SettingsStoreName); + } + catch + { + localSetts = new ToolbarLocalSettings(); + } + + return localSetts; + } + + public void SaveLocalSettings(ToolbarLocalSettings localSetts) + { + m_UserSettsSrv.StoreSettings(localSetts, Settings.Default.SettingsStoreName); + } + } +} \ No newline at end of file diff --git a/MyToolbar/ServicesContainer.cs b/MyToolbar/ServicesContainer.cs index 4f39d57..607b36d 100644 --- a/MyToolbar/ServicesContainer.cs +++ b/MyToolbar/ServicesContainer.cs @@ -56,6 +56,9 @@ public ServicesContainer(ISldWorks app, ILogger logger) m_Container.RegisterType( new ContainerControlledLifetimeManager()); + m_Container.RegisterType( + new ContainerControlledLifetimeManager()); + m_Container.RegisterType( new ContainerControlledLifetimeManager()); diff --git a/MyToolbar/Structs/CommandMacroInfo.cs b/MyToolbar/Structs/CommandMacroInfo.cs index 312ffcb..bb697d0 100644 --- a/MyToolbar/Structs/CommandMacroInfo.cs +++ b/MyToolbar/Structs/CommandMacroInfo.cs @@ -5,11 +5,15 @@ //Product URL: https://www.codestack.net/labs/solidworks/my-toolbar/ //********************** +using CodeStack.Sw.MyToolbar.Enums; + namespace CodeStack.Sw.MyToolbar.Structs { public class CommandMacroInfo : CommandItemInfo { public string MacroPath { get; set; } public MacroEntryPoint EntryPoint { get; set; } + public MacroScope_e Scope { get; set; } = MacroScope_e.All; + public Triggers_e Triggers { get; set; } = Triggers_e.Button; } } \ No newline at end of file diff --git a/MyToolbar/Structs/CustomToolbarInfo.cs b/MyToolbar/Structs/CustomToolbarInfo.cs index 094842d..b430ccd 100644 --- a/MyToolbar/Structs/CustomToolbarInfo.cs +++ b/MyToolbar/Structs/CustomToolbarInfo.cs @@ -9,7 +9,7 @@ namespace CodeStack.Sw.MyToolbar.Structs { - [UserSettingVersion("1.0")] + [UserSettingVersion("2.0")] public class CustomToolbarInfo { public CommandGroupInfo[] Groups { get; set; } diff --git a/MyToolbar/Structs/ToolbarLocalSettings.cs b/MyToolbar/Structs/ToolbarLocalSettings.cs new file mode 100644 index 0000000..eb92774 --- /dev/null +++ b/MyToolbar/Structs/ToolbarLocalSettings.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CodeStack.Sw.MyToolbar.Structs +{ + public class ToolbarLocalSettings + { + public Dictionary CommandUserIds { get; private set; } + + public ToolbarLocalSettings() + { + CommandUserIds = new Dictionary(); + } + } +} diff --git a/MyToolbar/Themes/Generic.xaml b/MyToolbar/Themes/Generic.xaml index 8f36248..c29f250 100644 --- a/MyToolbar/Themes/Generic.xaml +++ b/MyToolbar/Themes/Generic.xaml @@ -4,6 +4,8 @@ xmlns:local="clr-namespace:CodeStack.Sw.MyToolbar.UI.Controls"> + +