diff --git a/PettingZoo.Benchmark/Program.cs b/PettingZoo.Benchmark/Program.cs index 9579ed5..7d27337 100644 --- a/PettingZoo.Benchmark/Program.cs +++ b/PettingZoo.Benchmark/Program.cs @@ -73,7 +73,7 @@ namespace PettingZoo.Benchmark [Benchmark] - public string? TestReaderWriter() + public string TestReaderWriter() { using var stringReader = new StringReader(testJson); using var jsonTextReader = new JsonTextReader(stringReader); diff --git a/PettingZoo.Core/ExportImport/Publisher/PublisherMessage.cs b/PettingZoo.Core/ExportImport/Publisher/PublisherMessage.cs new file mode 100644 index 0000000..a680d5d --- /dev/null +++ b/PettingZoo.Core/ExportImport/Publisher/PublisherMessage.cs @@ -0,0 +1,58 @@ +using System.Collections.Generic; +using PettingZoo.Core.Connection; + +namespace PettingZoo.Core.ExportImport.Publisher +{ + public enum PublisherMessageType + { + Raw, + Tapeti + } + + + + public class PublisherMessage + { + public PublisherMessageType MessageType { get; set; } + public bool SendToExchange { get; set; } + public string? Exchange { get; set; } + public string? RoutingKey { get; set; } + public string? Queue { get; set; } + public bool ReplyToNewSubscriber { get; set; } + public string? ReplyTo { get; set; } + + public RawPublisherMessage? RawPublisherMessage { get; set; } + public TapetiPublisherMessage? TapetiPublisherMessage { get; set; } + } + + + public class RawPublisherMessage + { + public MessageDeliveryMode DeliveryMode { get; set; } + + public string? ContentType { get; set; } + public string? CorrelationId { get; set; } + public string? AppId { get; set; } + public string? ContentEncoding { get; set; } + public string? Expiration { get; set; } + public string? MessageId { get; set; } + public string? Priority { get; set; } + public string? Timestamp { get; set; } + public string? TypeProperty { get; set; } + public string? UserId { get; set; } + public string? Payload { get; set; } + public bool EnableMacros { get; set; } + + public Dictionary? Headers { get; set; } + } + + + public class TapetiPublisherMessage + { + public string? CorrelationId { get; set; } + public string? Payload { get; set; } + public bool EnableMacros { get; set; } + public string? ClassName { get; set; } + public string? AssemblyName { get; set; } + } +} diff --git a/PettingZoo.Core/ExportImport/BaseProgressDecorator.cs b/PettingZoo.Core/ExportImport/Subscriber/BaseProgressDecorator.cs similarity index 95% rename from PettingZoo.Core/ExportImport/BaseProgressDecorator.cs rename to PettingZoo.Core/ExportImport/Subscriber/BaseProgressDecorator.cs index 8e02cc4..89dcf3f 100644 --- a/PettingZoo.Core/ExportImport/BaseProgressDecorator.cs +++ b/PettingZoo.Core/ExportImport/Subscriber/BaseProgressDecorator.cs @@ -1,6 +1,6 @@ using System; -namespace PettingZoo.Core.ExportImport +namespace PettingZoo.Core.ExportImport.Subscriber { public abstract class BaseProgressDecorator { diff --git a/PettingZoo.Core/ExportImport/ExportImportFormatProvider.cs b/PettingZoo.Core/ExportImport/Subscriber/ExportImportFormatProvider.cs similarity index 93% rename from PettingZoo.Core/ExportImport/ExportImportFormatProvider.cs rename to PettingZoo.Core/ExportImport/Subscriber/ExportImportFormatProvider.cs index 1482bf2..190a18c 100644 --- a/PettingZoo.Core/ExportImport/ExportImportFormatProvider.cs +++ b/PettingZoo.Core/ExportImport/Subscriber/ExportImportFormatProvider.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.Linq; -namespace PettingZoo.Core.ExportImport +namespace PettingZoo.Core.ExportImport.Subscriber { public class ExportImportFormatProvider : IExportImportFormatProvider { diff --git a/PettingZoo.Core/ExportImport/IExportImportFormat.cs b/PettingZoo.Core/ExportImport/Subscriber/IExportImportFormat.cs similarity index 92% rename from PettingZoo.Core/ExportImport/IExportImportFormat.cs rename to PettingZoo.Core/ExportImport/Subscriber/IExportImportFormat.cs index e586348..d7b9c94 100644 --- a/PettingZoo.Core/ExportImport/IExportImportFormat.cs +++ b/PettingZoo.Core/ExportImport/Subscriber/IExportImportFormat.cs @@ -4,7 +4,7 @@ using System.Threading; using System.Threading.Tasks; using PettingZoo.Core.Connection; -namespace PettingZoo.Core.ExportImport +namespace PettingZoo.Core.ExportImport.Subscriber { public interface IExportImportFormat { diff --git a/PettingZoo.Core/ExportImport/IExportImportFormatProvider.cs b/PettingZoo.Core/ExportImport/Subscriber/IExportImportFormatProvider.cs similarity index 82% rename from PettingZoo.Core/ExportImport/IExportImportFormatProvider.cs rename to PettingZoo.Core/ExportImport/Subscriber/IExportImportFormatProvider.cs index 1991668..55ab49a 100644 --- a/PettingZoo.Core/ExportImport/IExportImportFormatProvider.cs +++ b/PettingZoo.Core/ExportImport/Subscriber/IExportImportFormatProvider.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace PettingZoo.Core.ExportImport +namespace PettingZoo.Core.ExportImport.Subscriber { public interface IExportImportFormatProvider { diff --git a/PettingZoo.Core/ExportImport/ImportSubscriber.cs b/PettingZoo.Core/ExportImport/Subscriber/ImportSubscriber.cs similarity index 95% rename from PettingZoo.Core/ExportImport/ImportSubscriber.cs rename to PettingZoo.Core/ExportImport/Subscriber/ImportSubscriber.cs index 49ffaca..dbfc831 100644 --- a/PettingZoo.Core/ExportImport/ImportSubscriber.cs +++ b/PettingZoo.Core/ExportImport/Subscriber/ImportSubscriber.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.IO; using PettingZoo.Core.Connection; -namespace PettingZoo.Core.ExportImport +namespace PettingZoo.Core.ExportImport.Subscriber { public class ImportSubscriber : ISubscriber { diff --git a/PettingZoo.Core/ExportImport/ListEnumerableProgressDecorator.cs b/PettingZoo.Core/ExportImport/Subscriber/ListEnumerableProgressDecorator.cs similarity index 98% rename from PettingZoo.Core/ExportImport/ListEnumerableProgressDecorator.cs rename to PettingZoo.Core/ExportImport/Subscriber/ListEnumerableProgressDecorator.cs index d74425a..4c63f66 100644 --- a/PettingZoo.Core/ExportImport/ListEnumerableProgressDecorator.cs +++ b/PettingZoo.Core/ExportImport/Subscriber/ListEnumerableProgressDecorator.cs @@ -2,7 +2,7 @@ using System.Collections; using System.Collections.Generic; -namespace PettingZoo.Core.ExportImport +namespace PettingZoo.Core.ExportImport.Subscriber { public class ListEnumerableProgressDecorator : BaseProgressDecorator, IEnumerable { diff --git a/PettingZoo.Core/ExportImport/StreamProgressDecorator.cs b/PettingZoo.Core/ExportImport/Subscriber/StreamProgressDecorator.cs similarity index 99% rename from PettingZoo.Core/ExportImport/StreamProgressDecorator.cs rename to PettingZoo.Core/ExportImport/Subscriber/StreamProgressDecorator.cs index b2abeaa..16eebe8 100644 --- a/PettingZoo.Core/ExportImport/StreamProgressDecorator.cs +++ b/PettingZoo.Core/ExportImport/Subscriber/StreamProgressDecorator.cs @@ -3,7 +3,7 @@ using System.IO; using System.Threading; using System.Threading.Tasks; -namespace PettingZoo.Core.ExportImport +namespace PettingZoo.Core.ExportImport.Subscriber { public class StreamProgressDecorator : BaseProgressDecorator { diff --git a/PettingZoo.Core/Rendering/MessageBodyRenderer.cs b/PettingZoo.Core/Rendering/MessageBodyRenderer.cs index b126f00..f184fa0 100644 --- a/PettingZoo.Core/Rendering/MessageBodyRenderer.cs +++ b/PettingZoo.Core/Rendering/MessageBodyRenderer.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.IO; using System.Text; using Newtonsoft.Json; -using Newtonsoft.Json.Linq; namespace PettingZoo.Core.Rendering { diff --git a/PettingZoo.Core/Settings/IPublisherMessagesRepository.cs b/PettingZoo.Core/Settings/IPublisherMessagesRepository.cs new file mode 100644 index 0000000..51d438c --- /dev/null +++ b/PettingZoo.Core/Settings/IPublisherMessagesRepository.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using PettingZoo.Core.ExportImport.Publisher; + +namespace PettingZoo.Core.Settings +{ + public interface IPublisherMessagesRepository + { + // For now read everything into memory, you need quite a few and/or huge messsages before that becomes an issue + Task> GetStored(); + + Task Add(string displayName, PublisherMessage message); + Task Update(Guid id, string displayName, PublisherMessage message); + Task Delete(Guid id); + } + + + public class StoredPublisherMessage + { + public Guid Id { get; } + public string DisplayName { get; } + public PublisherMessage Message { get; } + + + public StoredPublisherMessage(Guid id, string displayName, PublisherMessage message) + { + Id = id; + DisplayName = displayName; + Message = message; + } + } +} \ No newline at end of file diff --git a/PettingZoo.Settings.LiteDB/LiteDBPublisherMessagesRepository.cs b/PettingZoo.Settings.LiteDB/LiteDBPublisherMessagesRepository.cs new file mode 100644 index 0000000..81c766e --- /dev/null +++ b/PettingZoo.Settings.LiteDB/LiteDBPublisherMessagesRepository.cs @@ -0,0 +1,80 @@ +using PettingZoo.Core.ExportImport.Publisher; +using PettingZoo.Core.Settings; + +namespace PettingZoo.Settings.LiteDB +{ + public class LiteDBPublisherMessagesRepository : BaseLiteDBRepository, IPublisherMessagesRepository + { + private const string CollectionMessages = "messages"; + + + public LiteDBPublisherMessagesRepository() : base(@"publisherMessages") + { + } + + + public async Task> GetStored() + { + using var database = GetDatabase(); + var collection = database.GetCollection(CollectionMessages); + + return (await collection.FindAllAsync()) + .Select(r => new StoredPublisherMessage(r.Id, r.DisplayName, r.Message)) + .ToArray(); + } + + + public async Task Add(string displayName, PublisherMessage message) + { + using var database = GetDatabase(); + var collection = database.GetCollection(CollectionMessages); + + var id = Guid.NewGuid(); + await collection.InsertAsync(PublisherMessageRecord.FromPublisherMessage(id, displayName, message)); + + return new StoredPublisherMessage(id, displayName, message); + } + + + public async Task Update(Guid id, string displayName, PublisherMessage message) + { + using var database = GetDatabase(); + var collection = database.GetCollection(CollectionMessages); + + await collection.UpdateAsync(PublisherMessageRecord.FromPublisherMessage(id, displayName, message)); + return new StoredPublisherMessage(id, displayName, message); + } + + + public async Task Delete(Guid id) + { + using var database = GetDatabase(); + var collection = database.GetCollection(CollectionMessages); + + await collection.DeleteAsync(id); + } + + + // ReSharper disable MemberCanBePrivate.Local - for LiteDB + // ReSharper disable PropertyCanBeMadeInitOnly.Local + private class PublisherMessageRecord + { + public Guid Id { get; set; } + public string DisplayName { get; set; } = null!; + public PublisherMessage Message { get; set; } = null!; + + + public static PublisherMessageRecord FromPublisherMessage(Guid id, string displayName, PublisherMessage message) + { + return new PublisherMessageRecord + { + Id = id, + DisplayName = displayName, + Message = message + }; + } + } + // ReSharper restore PropertyCanBeMadeInitOnly.Local + // ReSharper restore MemberCanBePrivate.Local + } +} \ No newline at end of file diff --git a/PettingZoo.Tapeti/Export/BaseTapetiCmdExportImportFormat.cs b/PettingZoo.Tapeti/Export/BaseTapetiCmdExportImportFormat.cs index 6bfd721..1262c8a 100644 --- a/PettingZoo.Tapeti/Export/BaseTapetiCmdExportImportFormat.cs +++ b/PettingZoo.Tapeti/Export/BaseTapetiCmdExportImportFormat.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; using Newtonsoft.Json.Linq; -using PettingZoo.Core.ExportImport; +using PettingZoo.Core.ExportImport.Subscriber; namespace PettingZoo.Tapeti.Export { diff --git a/PettingZoo.Tapeti/Export/TapetiCmdExportFormat.cs b/PettingZoo.Tapeti/Export/TapetiCmdExportFormat.cs index 7967827..ebc83d8 100644 --- a/PettingZoo.Tapeti/Export/TapetiCmdExportFormat.cs +++ b/PettingZoo.Tapeti/Export/TapetiCmdExportFormat.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using PettingZoo.Core.Connection; -using PettingZoo.Core.ExportImport; +using PettingZoo.Core.ExportImport.Subscriber; namespace PettingZoo.Tapeti.Export diff --git a/PettingZoo.Tapeti/Export/TapetiCmdImportFormat.cs b/PettingZoo.Tapeti/Export/TapetiCmdImportFormat.cs index 58f88d4..00cf5d2 100644 --- a/PettingZoo.Tapeti/Export/TapetiCmdImportFormat.cs +++ b/PettingZoo.Tapeti/Export/TapetiCmdImportFormat.cs @@ -7,7 +7,7 @@ using System.Threading; using System.Threading.Tasks; using Newtonsoft.Json; using PettingZoo.Core.Connection; -using PettingZoo.Core.ExportImport; +using PettingZoo.Core.ExportImport.Subscriber; namespace PettingZoo.Tapeti.Export { diff --git a/PettingZoo.WPF/Controls/NoOverflowToolbar.cs b/PettingZoo.WPF/Controls/NoOverflowToolbar.cs new file mode 100644 index 0000000..09c9061 --- /dev/null +++ b/PettingZoo.WPF/Controls/NoOverflowToolbar.cs @@ -0,0 +1,21 @@ +using System.Windows; +using System.Windows.Controls; + +namespace PettingZoo.WPF.Controls +{ + public class NoOverflowToolbar : ToolBar + { + public NoOverflowToolbar() + { + Loaded += (_, _) => + { + // Hide arrow on the right side of the toolbar + if (Template.FindName("OverflowGrid", this) is FrameworkElement overflowGrid) + overflowGrid.Visibility = Visibility.Collapsed; + + if (Template.FindName("MainPanelBorder", this) is FrameworkElement mainPanelBorder) + mainPanelBorder.Margin = new Thickness(0); + }; + } + } +} diff --git a/PettingZoo.WPF/ValueConverters/SameReferenceConverter.cs b/PettingZoo.WPF/ValueConverters/SameReferenceConverter.cs new file mode 100644 index 0000000..ea0ff70 --- /dev/null +++ b/PettingZoo.WPF/ValueConverters/SameReferenceConverter.cs @@ -0,0 +1,20 @@ +using System; +using System.Globalization; +using System.Windows.Data; + +namespace PettingZoo.WPF.ValueConverters +{ + public class SameReferenceConverter : IMultiValueConverter + { + public object Convert(object?[] values, Type targetType, object parameter, CultureInfo culture) + { + return ReferenceEquals(values[0], values[1]); + } + + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + throw new NotSupportedException(); + } + } +} diff --git a/PettingZoo/Images/Delete.svg b/PettingZoo/Images/Delete.svg new file mode 100644 index 0000000..557bc3c --- /dev/null +++ b/PettingZoo/Images/Delete.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/PettingZoo/Images/Publish.svg b/PettingZoo/Images/Publish.svg index 1702435..67cd318 100644 --- a/PettingZoo/Images/Publish.svg +++ b/PettingZoo/Images/Publish.svg @@ -1,32 +1,53 @@ - - - - - - - - - - - - - - - - - - + + + + + + - - - + + + - - + + diff --git a/PettingZoo/Images/Save.svg b/PettingZoo/Images/Save.svg new file mode 100644 index 0000000..65b293b --- /dev/null +++ b/PettingZoo/Images/Save.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/PettingZoo/Images/SaveAs.svg b/PettingZoo/Images/SaveAs.svg new file mode 100644 index 0000000..f0630c9 --- /dev/null +++ b/PettingZoo/Images/SaveAs.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/PettingZoo/Images/Subscribe.svg b/PettingZoo/Images/Subscribe.svg index 0654459..c518099 100644 --- a/PettingZoo/Images/Subscribe.svg +++ b/PettingZoo/Images/Subscribe.svg @@ -1,32 +1,29 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + diff --git a/PettingZoo/PettingZoo.csproj b/PettingZoo/PettingZoo.csproj index cc761d5..fb0c52b 100644 --- a/PettingZoo/PettingZoo.csproj +++ b/PettingZoo/PettingZoo.csproj @@ -20,6 +20,7 @@ + @@ -29,6 +30,8 @@ + + @@ -36,6 +39,7 @@ + @@ -47,6 +51,8 @@ + + @@ -75,10 +81,10 @@ - + True True - ConnectionDisplayNameStrings.resx + InputDialogStrings.resx ConnectionWindowStrings.resx @@ -100,6 +106,11 @@ True PayloadEditorStrings.resx + + True + True + StoredPublisherMessagesStrings.resx + TapetiPublisherViewStrings.resx True @@ -131,9 +142,9 @@ - + PublicResXFileCodeGenerator - ConnectionDisplayNameStrings.Designer.cs + InputDialogStrings.Designer.cs ConnectionWindowStrings.Designer.cs @@ -151,6 +162,10 @@ PublicResXFileCodeGenerator PayloadEditorStrings.Designer.cs + + ResXFileCodeGenerator + StoredPublisherMessagesStrings.Designer.cs + TapetiPublisherViewStrings.Designer.cs PublicResXFileCodeGenerator diff --git a/PettingZoo/Program.cs b/PettingZoo/Program.cs index f0f717a..bdc95f3 100644 --- a/PettingZoo/Program.cs +++ b/PettingZoo/Program.cs @@ -4,7 +4,7 @@ using System.IO; using System.Windows; using System.Windows.Markup; using PettingZoo.Core.Connection; -using PettingZoo.Core.ExportImport; +using PettingZoo.Core.ExportImport.Subscriber; using PettingZoo.Core.Generator; using PettingZoo.Core.Macros; using PettingZoo.Core.Settings; @@ -16,6 +16,7 @@ using PettingZoo.UI.Connection; using PettingZoo.UI.Main; using PettingZoo.UI.Subscribe; using PettingZoo.UI.Tab; +using PettingZoo.UI.Tab.Publisher; using Serilog; using SimpleInjector; @@ -82,10 +83,12 @@ namespace PettingZoo container.Register(); container.Register(); container.Register(); + container.RegisterSingleton(); container.Register(); container.RegisterSingleton(); container.Register(); container.RegisterSingleton(); + container.RegisterSingleton(); container.RegisterInstance(new ExportImportFormatProvider( new TapetiCmdExportFormat(), diff --git a/PettingZoo/TODO.md b/PettingZoo/TODO.md index f0312f5..e9f26ef 100644 --- a/PettingZoo/TODO.md +++ b/PettingZoo/TODO.md @@ -8,5 +8,4 @@ Should-have Nice-to-have ------------ -- Save / load publisher messages (either as templates or to disk) - Tapeti: fetch NuGet dependencies to improve the chances of succesfully loading the assembly, instead of the current "extraAssembliesPaths" workaround diff --git a/PettingZoo/UI/Connection/ConnectionViewModel.cs b/PettingZoo/UI/Connection/ConnectionViewModel.cs index 0e9e445..05db2f4 100644 --- a/PettingZoo/UI/Connection/ConnectionViewModel.cs +++ b/PettingZoo/UI/Connection/ConnectionViewModel.cs @@ -262,7 +262,7 @@ namespace PettingZoo.UI.Connection // TODO create and enforce unique name? var displayName = SelectedStoredConnection != null && SelectedStoredConnection.Id != Guid.Empty ? SelectedStoredConnection.DisplayName : ""; - if (!ConnectionDisplayNameDialog.Execute(ref displayName)) + if (!InputDialog.Execute(ref displayName, ConnectionWindowStrings.ProfileNameDialogTitle)) return; var storedConnectionSettings = await connectionSettingsRepository.Add(displayName, StorePassword, ToModel()); diff --git a/PettingZoo/UI/Connection/ConnectionWindowStrings.Designer.cs b/PettingZoo/UI/Connection/ConnectionWindowStrings.Designer.cs index 2101f00..4288696 100644 --- a/PettingZoo/UI/Connection/ConnectionWindowStrings.Designer.cs +++ b/PettingZoo/UI/Connection/ConnectionWindowStrings.Designer.cs @@ -213,6 +213,15 @@ namespace PettingZoo.UI.Connection { } } + /// + /// Looks up a localized string similar to Profile name. + /// + public static string ProfileNameDialogTitle { + get { + return ResourceManager.GetString("ProfileNameDialogTitle", resourceCulture); + } + } + /// /// Looks up a localized string similar to Connection parameters. /// diff --git a/PettingZoo/UI/Connection/ConnectionWindowStrings.resx b/PettingZoo/UI/Connection/ConnectionWindowStrings.resx index 5b739e5..b9d96c5 100644 --- a/PettingZoo/UI/Connection/ConnectionWindowStrings.resx +++ b/PettingZoo/UI/Connection/ConnectionWindowStrings.resx @@ -112,10 +112,10 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Cancel @@ -168,6 +168,9 @@ <New connection> + + Profile name + Connection parameters diff --git a/PettingZoo/UI/Connection/ConnectionDisplayNameDialog.xaml b/PettingZoo/UI/InputDialog.xaml similarity index 52% rename from PettingZoo/UI/Connection/ConnectionDisplayNameDialog.xaml rename to PettingZoo/UI/InputDialog.xaml index e76c9de..b7feb2e 100644 --- a/PettingZoo/UI/Connection/ConnectionDisplayNameDialog.xaml +++ b/PettingZoo/UI/InputDialog.xaml @@ -1,9 +1,9 @@ - + d:DataContext="{d:DesignInstance local:InputDialogViewModel}"> - + - - + + diff --git a/PettingZoo/UI/Connection/ConnectionDisplayNameDialog.xaml.cs b/PettingZoo/UI/InputDialog.xaml.cs similarity index 55% rename from PettingZoo/UI/Connection/ConnectionDisplayNameDialog.xaml.cs rename to PettingZoo/UI/InputDialog.xaml.cs index 000287e..1d6c9ba 100644 --- a/PettingZoo/UI/Connection/ConnectionDisplayNameDialog.xaml.cs +++ b/PettingZoo/UI/InputDialog.xaml.cs @@ -1,18 +1,19 @@ using System.Linq; using System.Windows; -namespace PettingZoo.UI.Connection +namespace PettingZoo.UI { /// - /// Interaction logic for ConnectionDisplayNameDialog.xaml + /// Interaction logic for InputDialog.xaml /// - public partial class ConnectionDisplayNameDialog + public partial class InputDialog { - public static bool Execute(ref string displayName) + public static bool Execute(ref string value, string title) { - var viewModel = new ConnectionDisplayNameViewModel + var viewModel = new InputDialogViewModel { - DisplayName = displayName + Value = value, + Title = title }; @@ -20,7 +21,7 @@ namespace PettingZoo.UI.Connection .Cast() .FirstOrDefault(applicationWindow => applicationWindow.IsActive); - var window = new ConnectionDisplayNameDialog(viewModel) + var window = new InputDialog(viewModel) { Owner = activeWindow ?? Application.Current.MainWindow }; @@ -28,12 +29,12 @@ namespace PettingZoo.UI.Connection if (!window.ShowDialog().GetValueOrDefault()) return false; - displayName = viewModel.DisplayName; + value = viewModel.Value; return true; } - public ConnectionDisplayNameDialog(ConnectionDisplayNameViewModel viewModel) + public InputDialog(InputDialogViewModel viewModel) { viewModel.OkClick += (_, _) => { @@ -43,7 +44,7 @@ namespace PettingZoo.UI.Connection DataContext = viewModel; InitializeComponent(); - DisplayNameTextBox.CaretIndex = DisplayNameTextBox.Text.Length; + ValueTextBox.CaretIndex = ValueTextBox.Text.Length; } } } diff --git a/PettingZoo/UI/Connection/ConnectionDisplayNameStrings.Designer.cs b/PettingZoo/UI/InputDialogStrings.Designer.cs similarity index 86% rename from PettingZoo/UI/Connection/ConnectionDisplayNameStrings.Designer.cs rename to PettingZoo/UI/InputDialogStrings.Designer.cs index de2828b..a89015e 100644 --- a/PettingZoo/UI/Connection/ConnectionDisplayNameStrings.Designer.cs +++ b/PettingZoo/UI/InputDialogStrings.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace PettingZoo.UI.Connection { +namespace PettingZoo.UI { using System; @@ -22,14 +22,14 @@ namespace PettingZoo.UI.Connection { [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - public class ConnectionDisplayNameStrings { + public class InputDialogStrings { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal ConnectionDisplayNameStrings() { + internal InputDialogStrings() { } /// @@ -39,7 +39,7 @@ namespace PettingZoo.UI.Connection { public static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PettingZoo.UI.Connection.ConnectionDisplayNameStrings", typeof(ConnectionDisplayNameStrings).Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PettingZoo.UI.InputDialogStrings", typeof(InputDialogStrings).Assembly); resourceMan = temp; } return resourceMan; @@ -77,14 +77,5 @@ namespace PettingZoo.UI.Connection { return ResourceManager.GetString("ButtonOK", resourceCulture); } } - - /// - /// Looks up a localized string similar to Profile name. - /// - public static string WindowTitle { - get { - return ResourceManager.GetString("WindowTitle", resourceCulture); - } - } } } diff --git a/PettingZoo/UI/Connection/ConnectionDisplayNameStrings.resx b/PettingZoo/UI/InputDialogStrings.resx similarity index 96% rename from PettingZoo/UI/Connection/ConnectionDisplayNameStrings.resx rename to PettingZoo/UI/InputDialogStrings.resx index bc89e48..73ce2f1 100644 --- a/PettingZoo/UI/Connection/ConnectionDisplayNameStrings.resx +++ b/PettingZoo/UI/InputDialogStrings.resx @@ -112,10 +112,10 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Cancel @@ -123,7 +123,4 @@ OK - - Profile name - \ No newline at end of file diff --git a/PettingZoo/UI/Connection/ConnectionDisplayNameViewModel.cs b/PettingZoo/UI/InputDialogViewModel.cs similarity index 50% rename from PettingZoo/UI/Connection/ConnectionDisplayNameViewModel.cs rename to PettingZoo/UI/InputDialogViewModel.cs index 9594bfb..b5d1903 100644 --- a/PettingZoo/UI/Connection/ConnectionDisplayNameViewModel.cs +++ b/PettingZoo/UI/InputDialogViewModel.cs @@ -2,27 +2,36 @@ using System.Windows.Input; using PettingZoo.WPF.ViewModel; -namespace PettingZoo.UI.Connection +namespace PettingZoo.UI { - public class ConnectionDisplayNameViewModel : BaseViewModel + public class InputDialogViewModel : BaseViewModel { - private string displayName = ""; + private string title = ""; + private string value = ""; private readonly DelegateCommand okCommand; - public string DisplayName + public string Title { - get => displayName; - set => SetField(ref displayName, value, delegateCommandsChanged: new [] { okCommand }); + get => title; + set => SetField(ref title, value); } + + public string Value + { + get => value; + set => SetField(ref this.value, value, delegateCommandsChanged: new [] { okCommand }); + } + + public ICommand OkCommand => okCommand; public event EventHandler? OkClick; - public ConnectionDisplayNameViewModel() + public InputDialogViewModel() { okCommand = new DelegateCommand(OkExecute, OkCanExecute); } @@ -36,7 +45,7 @@ namespace PettingZoo.UI.Connection private bool OkCanExecute() { - return !string.IsNullOrWhiteSpace(DisplayName); + return !string.IsNullOrWhiteSpace(Value); } } } diff --git a/PettingZoo/UI/Main/MainWindow.xaml b/PettingZoo/UI/Main/MainWindow.xaml index 3ea2195..07f9873 100644 --- a/PettingZoo/UI/Main/MainWindow.xaml +++ b/PettingZoo/UI/Main/MainWindow.xaml @@ -7,6 +7,7 @@ xmlns:tab="clr-namespace:PettingZoo.UI.Tab" xmlns:svgc="http://sharpvectors.codeplex.com/svgc/" xmlns:ui="clr-namespace:PettingZoo.UI" + xmlns:controls="clr-namespace:PettingZoo.WPF.Controls;assembly=PettingZoo.WPF" mc:Ignorable="d" d:DataContext="{d:DesignInstance main:DesignTimeMainWindowViewModel, IsDesignTimeCreatable=True}" Width="800" @@ -24,7 +25,7 @@ - + + diff --git a/PettingZoo/UI/Main/MainWindow.xaml.cs b/PettingZoo/UI/Main/MainWindow.xaml.cs index 84e4e90..a769730 100644 --- a/PettingZoo/UI/Main/MainWindow.xaml.cs +++ b/PettingZoo/UI/Main/MainWindow.xaml.cs @@ -5,7 +5,7 @@ using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using PettingZoo.Core.Connection; -using PettingZoo.Core.ExportImport; +using PettingZoo.Core.ExportImport.Subscriber; using PettingZoo.UI.Connection; using PettingZoo.UI.Subscribe; using PettingZoo.UI.Tab; @@ -139,18 +139,6 @@ namespace PettingZoo.UI.Main public double TabWidth => SubscriberTabs.ActualWidth; public double TabHeight => SubscriberTabs.ActualHeight; - - private void Toolbar_Loaded(object sender, RoutedEventArgs e) - { - // Hide arrow on the right side of the toolbar - var toolBar = sender as ToolBar; - - if (toolBar?.Template.FindName("OverflowGrid", toolBar) is FrameworkElement overflowGrid) - overflowGrid.Visibility = Visibility.Collapsed; - - if (toolBar?.Template.FindName("MainPanelBorder", toolBar) is FrameworkElement mainPanelBorder) - mainPanelBorder.Margin = new Thickness(0); - } } #pragma warning restore CA1001 } diff --git a/PettingZoo/UI/Main/MainWindowViewModel.cs b/PettingZoo/UI/Main/MainWindowViewModel.cs index e7c190a..9aaa4f4 100644 --- a/PettingZoo/UI/Main/MainWindowViewModel.cs +++ b/PettingZoo/UI/Main/MainWindowViewModel.cs @@ -9,7 +9,7 @@ using System.Windows; using System.Windows.Forms; using System.Windows.Input; using PettingZoo.Core.Connection; -using PettingZoo.Core.ExportImport; +using PettingZoo.Core.ExportImport.Subscriber; using PettingZoo.UI.Connection; using PettingZoo.UI.Subscribe; using PettingZoo.UI.Tab; diff --git a/PettingZoo/UI/Tab/Publisher/PublisherView.xaml b/PettingZoo/UI/Tab/Publisher/PublisherView.xaml index 03ba2aa..964dff0 100644 --- a/PettingZoo/UI/Tab/Publisher/PublisherView.xaml +++ b/PettingZoo/UI/Tab/Publisher/PublisherView.xaml @@ -6,73 +6,153 @@ xmlns:res="clr-namespace:PettingZoo.UI.Tab.Publisher" xmlns:controls="clr-namespace:PettingZoo.WPF.Controls;assembly=PettingZoo.WPF" xmlns:svgc="http://sharpvectors.codeplex.com/svgc/" + xmlns:valueConverters="clr-namespace:PettingZoo.WPF.ValueConverters;assembly=PettingZoo.WPF" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance res:DesignTimePublisherViewModel, IsDesignTimeCreatable=True}" Background="White"> - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + - - - - - - + + + + + - + + - + + + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + diff --git a/PettingZoo/UI/Tab/Publisher/PublisherViewModel.cs b/PettingZoo/UI/Tab/Publisher/PublisherViewModel.cs index a8dbc2f..d63898f 100644 --- a/PettingZoo/UI/Tab/Publisher/PublisherViewModel.cs +++ b/PettingZoo/UI/Tab/Publisher/PublisherViewModel.cs @@ -1,27 +1,25 @@ using System; using System.Collections.Generic; +using System.Diagnostics; +using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using PettingZoo.Core.Connection; +using PettingZoo.Core.ExportImport.Publisher; using PettingZoo.Core.Generator; using PettingZoo.Core.Macros; +using PettingZoo.Core.Settings; using PettingZoo.WPF.ViewModel; namespace PettingZoo.UI.Tab.Publisher { - public enum MessageType - { - Raw, - Tapeti - } - - public class PublisherViewModel : BaseViewModel, ITabToolbarCommands, ITabHostWindowNotify, IPublishDestination { private readonly IConnection connection; private readonly IExampleGenerator exampleGenerator; private readonly IPayloadMacroProcessor payloadMacroProcessor; + private readonly StoredPublisherMessagesViewModel storedPublisherMessagesViewModel; private readonly ITabFactory tabFactory; private bool sendToExchange = true; @@ -29,16 +27,27 @@ namespace PettingZoo.UI.Tab.Publisher private string routingKey = ""; private string queue = ""; private string replyTo = ""; - private bool replyToSpecified = true; + private bool replyToNewSubscriber; - private MessageType messageType; + private StoredPublisherMessage? selectedStoredMessage; + private StoredPublisherMessage? activeStoredMessage; + + private PublisherMessageType messageType; private UserControl? messageTypeControl; private ICommand? messageTypePublishCommand; + private RawPublisherViewModel? rawPublisherViewModel; private UserControl? rawPublisherView; + + private TapetiPublisherViewModel? tapetiPublisherViewModel; private UserControl? tapetiPublisherView; private readonly DelegateCommand publishCommand; + private readonly DelegateCommand saveCommand; + private readonly DelegateCommand saveAsCommand; + private readonly DelegateCommand deleteCommand; + private readonly DelegateCommand loadStoredMessage; + private readonly TabToolbarCommand[] toolbarCommands; private Window? tabHostWindow; @@ -46,9 +55,10 @@ namespace PettingZoo.UI.Tab.Publisher public bool SendToExchange { get => sendToExchange; - set => SetField(ref sendToExchange, value, - delegateCommandsChanged: new [] { publishCommand }, - otherPropertiesChanged: new[] { nameof(SendToQueue), nameof(ExchangeVisibility), nameof(QueueVisibility), nameof(Title) }); + set => SetField(ref sendToExchange, value, + delegateCommandsChanged: new[] { publishCommand }, + otherPropertiesChanged: new[] + { nameof(SendToQueue), nameof(ExchangeVisibility), nameof(QueueVisibility), nameof(Title) }); } @@ -69,14 +79,16 @@ namespace PettingZoo.UI.Tab.Publisher public string RoutingKey { get => routingKey; - set => SetField(ref routingKey, value, delegateCommandsChanged: new[] { publishCommand }, otherPropertiesChanged: new[] { nameof(Title) }); + set => SetField(ref routingKey, value, delegateCommandsChanged: new[] { publishCommand }, + otherPropertiesChanged: new[] { nameof(Title) }); } public string Queue { get => queue; - set => SetField(ref queue, value, delegateCommandsChanged: new[] { publishCommand }, otherPropertiesChanged: new[] { nameof(Title) }); + set => SetField(ref queue, value, delegateCommandsChanged: new[] { publishCommand }, + otherPropertiesChanged: new[] { nameof(Title) }); } @@ -89,15 +101,16 @@ namespace PettingZoo.UI.Tab.Publisher public bool ReplyToSpecified { - get => replyToSpecified; - set => SetField(ref replyToSpecified, value, otherPropertiesChanged: new[] { nameof(ReplyToNewSubscriber) }); + get => !ReplyToNewSubscriber; + set => ReplyToNewSubscriber = !value; } public bool ReplyToNewSubscriber { - get => !ReplyToSpecified; - set => ReplyToSpecified = !value; + get => replyToNewSubscriber; + set => SetField(ref replyToNewSubscriber, value, + otherPropertiesChanged: new[] { nameof(ReplyToSpecified) }); } @@ -105,17 +118,17 @@ namespace PettingZoo.UI.Tab.Publisher public virtual Visibility QueueVisibility => SendToQueue ? Visibility.Visible : Visibility.Collapsed; - public MessageType MessageType + public PublisherMessageType MessageType { get => messageType; set { if (SetField(ref messageType, value, - otherPropertiesChanged: new[] - { - nameof(MessageTypeRaw), - nameof(MessageTypeTapeti) - })) + otherPropertiesChanged: new[] + { + nameof(MessageTypeRaw), + nameof(MessageTypeTapeti) + })) { SetMessageTypeControl(value); } @@ -124,14 +137,20 @@ namespace PettingZoo.UI.Tab.Publisher public bool MessageTypeRaw { - get => MessageType == MessageType.Raw; - set { if (value) MessageType = MessageType.Raw; } + get => MessageType == PublisherMessageType.Raw; + set + { + if (value) MessageType = PublisherMessageType.Raw; + } } public bool MessageTypeTapeti { - get => MessageType == MessageType.Tapeti; - set { if (value) MessageType = MessageType.Tapeti; } + get => MessageType == PublisherMessageType.Tapeti; + set + { + if (value) MessageType = PublisherMessageType.Tapeti; + } } @@ -142,12 +161,38 @@ namespace PettingZoo.UI.Tab.Publisher } + public ObservableCollectionEx StoredMessages => + storedPublisherMessagesViewModel.StoredMessages; + + public StoredPublisherMessage? SelectedStoredMessage + { + get => selectedStoredMessage; + set => SetField(ref selectedStoredMessage, value, delegateCommandsChanged: new[] { deleteCommand }); + } + + + // TODO detect changes from ActiveStoredMessage and show indication in the UI + + public StoredPublisherMessage? ActiveStoredMessage + { + get => activeStoredMessage; + set => SetField(ref activeStoredMessage, value); + } + + public ICommand PublishCommand => publishCommand; + public ICommand SaveCommand => saveCommand; + public ICommand SaveAsCommand => saveAsCommand; + public ICommand DeleteCommand => deleteCommand; + public ICommand LoadStoredMessage => loadStoredMessage; public string Title => SendToQueue - ? string.IsNullOrWhiteSpace(Queue) ? PublisherViewStrings.TabTitleEmpty : string.Format(PublisherViewStrings.TabTitle, Queue) - : string.IsNullOrWhiteSpace(RoutingKey) ? PublisherViewStrings.TabTitleEmpty : string.Format(PublisherViewStrings.TabTitle, RoutingKey); + ? string.IsNullOrWhiteSpace(Queue) ? PublisherViewStrings.TabTitleEmpty : + string.Format(PublisherViewStrings.TabTitle, Queue) + : string.IsNullOrWhiteSpace(RoutingKey) + ? PublisherViewStrings.TabTitleEmpty + : string.Format(PublisherViewStrings.TabTitle, RoutingKey); public IEnumerable ToolbarCommands => toolbarCommands; @@ -157,24 +202,33 @@ namespace PettingZoo.UI.Tab.Publisher string IPublishDestination.RoutingKey => SendToExchange ? RoutingKey : Queue; - public PublisherViewModel(ITabFactory tabFactory, IConnection connection, IExampleGenerator exampleGenerator, IPayloadMacroProcessor payloadMacroProcessor, ReceivedMessageInfo? fromReceivedMessage = null) + public PublisherViewModel(ITabFactory tabFactory, IConnection connection, IExampleGenerator exampleGenerator, + IPayloadMacroProcessor payloadMacroProcessor, + StoredPublisherMessagesViewModel storedPublisherMessagesViewModel, + ReceivedMessageInfo? fromReceivedMessage = null) { this.connection = connection; this.exampleGenerator = exampleGenerator; this.payloadMacroProcessor = payloadMacroProcessor; + this.storedPublisherMessagesViewModel = storedPublisherMessagesViewModel; this.tabFactory = tabFactory; publishCommand = new DelegateCommand(PublishExecute, PublishCanExecute); + saveCommand = new DelegateCommand(SaveExecute); + saveAsCommand = new DelegateCommand(SaveAsExecute); + deleteCommand = new DelegateCommand(DeleteExecute, DeleteCanExecute); + loadStoredMessage = new DelegateCommand(LoadStoredMessageExecute, LoadStoredMessageCanExecute); toolbarCommands = new[] { - new TabToolbarCommand(PublishCommand, PublisherViewStrings.CommandPublish, SvgIconHelper.LoadFromResource("/Images/PublishSend.svg")) + new TabToolbarCommand(PublishCommand, PublisherViewStrings.CommandPublish, + SvgIconHelper.LoadFromResource("/Images/PublishSend.svg")) }; if (fromReceivedMessage != null) SetMessageTypeControl(fromReceivedMessage); else - SetMessageTypeControl(MessageType.Raw); + SetMessageTypeControl(PublisherMessageType.Raw); } @@ -201,13 +255,11 @@ namespace PettingZoo.UI.Tab.Publisher } - private void SetMessageTypeControl(MessageType value) + private void SetMessageTypeControl(PublisherMessageType value) { switch (value) { - case MessageType.Raw: - RawPublisherViewModel rawPublisherViewModel; - + case PublisherMessageType.Raw: if (rawPublisherView == null) { rawPublisherViewModel = new RawPublisherViewModel(connection, this, payloadMacroProcessor); @@ -216,19 +268,17 @@ namespace PettingZoo.UI.Tab.Publisher publishCommand.RaiseCanExecuteChanged(); }; - rawPublisherView ??= new RawPublisherView(rawPublisherViewModel); + rawPublisherView = new RawPublisherView(rawPublisherViewModel); } else - rawPublisherViewModel = (RawPublisherViewModel)rawPublisherView.DataContext; + Debug.Assert(rawPublisherViewModel != null); MessageTypeControl = rawPublisherView; messageTypePublishCommand = rawPublisherViewModel.PublishCommand; break; - - case MessageType.Tapeti: - TapetiPublisherViewModel tapetiPublisherViewModel; + case PublisherMessageType.Tapeti: if (tapetiPublisherView == null) { tapetiPublisherViewModel = new TapetiPublisherViewModel(connection, this, exampleGenerator, payloadMacroProcessor); @@ -237,19 +287,19 @@ namespace PettingZoo.UI.Tab.Publisher publishCommand.RaiseCanExecuteChanged(); }; - tapetiPublisherView ??= new TapetiPublisherView(tapetiPublisherViewModel); + tapetiPublisherView = new TapetiPublisherView(tapetiPublisherViewModel); if (tabHostWindow != null) tapetiPublisherViewModel.HostWindowChanged(tabHostWindow); } else - tapetiPublisherViewModel = (TapetiPublisherViewModel)tapetiPublisherView.DataContext; + Debug.Assert(tapetiPublisherViewModel != null); MessageTypeControl = tapetiPublisherView; messageTypePublishCommand = tapetiPublisherViewModel.PublishCommand; break; - + default: throw new ArgumentException($@"Unknown message type: {value}", nameof(value)); } @@ -266,17 +316,17 @@ namespace PettingZoo.UI.Tab.Publisher if (TapetiPublisherViewModel.IsTapetiMessage(fromReceivedMessage)) { - var tapetiPublisherViewModel = new TapetiPublisherViewModel(connection, this, exampleGenerator, payloadMacroProcessor, fromReceivedMessage); + tapetiPublisherViewModel = new TapetiPublisherViewModel(connection, this, exampleGenerator, payloadMacroProcessor, fromReceivedMessage); tapetiPublisherView = new TapetiPublisherView(tapetiPublisherViewModel); - MessageType = MessageType.Tapeti; + MessageType = PublisherMessageType.Tapeti; } else { - var rawPublisherViewModel = new RawPublisherViewModel(connection, this, payloadMacroProcessor, fromReceivedMessage); + rawPublisherViewModel = new RawPublisherViewModel(connection, this, payloadMacroProcessor, fromReceivedMessage); rawPublisherView = new RawPublisherView(rawPublisherViewModel); - MessageType = MessageType.Raw; + MessageType = PublisherMessageType.Raw; } } @@ -304,16 +354,160 @@ namespace PettingZoo.UI.Tab.Publisher (tapetiPublisherView?.DataContext as TapetiPublisherViewModel)?.HostWindowChanged(hostWindow); } + + + private void SaveExecute() + { + storedPublisherMessagesViewModel.Save(SelectedStoredMessage, GetPublisherMessage(), message => + { + ActiveStoredMessage = message; + SelectedStoredMessage = message; + }); + } + + + private void SaveAsExecute() + { + storedPublisherMessagesViewModel.SaveAs(GetPublisherMessage(), SelectedStoredMessage?.DisplayName, message => + { + ActiveStoredMessage = message; + SelectedStoredMessage = message; + }); + } + + + private void DeleteExecute() + { + if (SelectedStoredMessage == null) + return; + + var message = SelectedStoredMessage; + + storedPublisherMessagesViewModel.Delete(message, () => + { + if (SelectedStoredMessage == message) + SelectedStoredMessage = null; + + if (ActiveStoredMessage == message) + ActiveStoredMessage = null; + }); + } + + + private bool DeleteCanExecute() + { + return SelectedStoredMessage != null; + } + + + private void LoadStoredMessageExecute() + { + if (SelectedStoredMessage == null) + return; + + var message = SelectedStoredMessage.Message; + + MessageType = message.MessageType; + SendToExchange = message.SendToExchange; + Exchange = message.Exchange ?? ""; + RoutingKey = message.RoutingKey ?? ""; + Queue = message.Queue ?? ""; + ReplyToNewSubscriber = message.ReplyToNewSubscriber; + ReplyTo = message.ReplyTo ?? ""; + + // ReSharper disable once SwitchStatementHandlesSomeKnownEnumValuesWithDefault + switch (message.MessageType) + { + case PublisherMessageType.Raw: + if (message.RawPublisherMessage != null) + rawPublisherViewModel?.LoadPublisherMessage(message.RawPublisherMessage); + + break; + + case PublisherMessageType.Tapeti: + if (message.TapetiPublisherMessage != null) + tapetiPublisherViewModel?.LoadPublisherMessage(message.TapetiPublisherMessage); + + break; + } + + ActiveStoredMessage = SelectedStoredMessage; + } + + + private bool LoadStoredMessageCanExecute() + { + return SelectedStoredMessage != null; + } + + + private PublisherMessage GetPublisherMessage() + { + return new PublisherMessage + { + MessageType = MessageType, + SendToExchange = SendToExchange, + Exchange = Exchange, + RoutingKey = RoutingKey, + Queue = Queue, + ReplyToNewSubscriber = ReplyToNewSubscriber, + ReplyTo = ReplyTo, + + RawPublisherMessage = MessageType == PublisherMessageType.Raw + ? rawPublisherViewModel?.GetPublisherMessage() + : null, + + TapetiPublisherMessage = MessageType == PublisherMessageType.Tapeti + ? tapetiPublisherViewModel?.GetPublisherMessage() + : null + }; + } } public class DesignTimePublisherViewModel : PublisherViewModel { - public DesignTimePublisherViewModel() : base(null!, null!, null!, null!) + public DesignTimePublisherViewModel() : base(null!, null!, null!, null!, new StoredPublisherMessagesViewModel(new DesignTimePublisherMessagesRepository())) { + StoredMessages.CollectionChanged += (_, _) => + { + if (StoredMessages.Count < 2) + return; + + SelectedStoredMessage = StoredMessages[0]; + ActiveStoredMessage = StoredMessages[1]; + }; } public override Visibility ExchangeVisibility => Visibility.Visible; public override Visibility QueueVisibility => Visibility.Visible; + + + private class DesignTimePublisherMessagesRepository : IPublisherMessagesRepository + { + public Task> GetStored() + { + return Task.FromResult(new StoredPublisherMessage[] + { + new(new Guid("16fdf930-2e4c-48f4-ae21-68dac9ca62e6"), "Design-time message 1", new PublisherMessage()), + new(new Guid("01d2671b-4426-4c1c-bcbc-61689d14796e"), "Design-time message 2", new PublisherMessage()) + } as IEnumerable); + } + + public Task Add(string displayName, PublisherMessage message) + { + throw new NotSupportedException(); + } + + public Task Update(Guid id, string displayName, PublisherMessage message) + { + throw new NotSupportedException(); + } + + public Task Delete(Guid id) + { + throw new NotSupportedException(); + } + } } } diff --git a/PettingZoo/UI/Tab/Publisher/PublisherViewStrings.Designer.cs b/PettingZoo/UI/Tab/Publisher/PublisherViewStrings.Designer.cs index 99ff390..c9df135 100644 --- a/PettingZoo/UI/Tab/Publisher/PublisherViewStrings.Designer.cs +++ b/PettingZoo/UI/Tab/Publisher/PublisherViewStrings.Designer.cs @@ -168,6 +168,15 @@ namespace PettingZoo.UI.Tab.Publisher { } } + /// + /// Looks up a localized string similar to Saved messages. + /// + public static string PanelTitleMessages { + get { + return ResourceManager.GetString("PanelTitleMessages", resourceCulture); + } + } + /// /// Looks up a localized string similar to Re: . /// @@ -194,5 +203,32 @@ namespace PettingZoo.UI.Tab.Publisher { return ResourceManager.GetString("TabTitleEmpty", resourceCulture); } } + + /// + /// Looks up a localized string similar to Delete. + /// + public static string ToolbarDelete { + get { + return ResourceManager.GetString("ToolbarDelete", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save. + /// + public static string ToolbarSave { + get { + return ResourceManager.GetString("ToolbarSave", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save as.... + /// + public static string ToolbarSaveAs { + get { + return ResourceManager.GetString("ToolbarSaveAs", resourceCulture); + } + } } } diff --git a/PettingZoo/UI/Tab/Publisher/PublisherViewStrings.resx b/PettingZoo/UI/Tab/Publisher/PublisherViewStrings.resx index 9c10050..b6b91e7 100644 --- a/PettingZoo/UI/Tab/Publisher/PublisherViewStrings.resx +++ b/PettingZoo/UI/Tab/Publisher/PublisherViewStrings.resx @@ -153,6 +153,9 @@ Tapeti message + + Saved messages + Re: @@ -162,4 +165,13 @@ Publish + + Delete + + + Save + + + Save as... + \ No newline at end of file diff --git a/PettingZoo/UI/Tab/Publisher/RawPublisherView.xaml.cs b/PettingZoo/UI/Tab/Publisher/RawPublisherView.xaml.cs index bf5baf3..d07ddf1 100644 --- a/PettingZoo/UI/Tab/Publisher/RawPublisherView.xaml.cs +++ b/PettingZoo/UI/Tab/Publisher/RawPublisherView.xaml.cs @@ -3,7 +3,6 @@ using System.Linq; using System.Windows; using System.Windows.Input; using System.Windows.Threading; -using PettingZoo.Core.Macros; namespace PettingZoo.UI.Tab.Publisher { diff --git a/PettingZoo/UI/Tab/Publisher/RawPublisherViewModel.cs b/PettingZoo/UI/Tab/Publisher/RawPublisherViewModel.cs index d36525a..f66602b 100644 --- a/PettingZoo/UI/Tab/Publisher/RawPublisherViewModel.cs +++ b/PettingZoo/UI/Tab/Publisher/RawPublisherViewModel.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Linq; @@ -7,6 +6,7 @@ using System.Text; using System.Windows; using System.Windows.Input; using PettingZoo.Core.Connection; +using PettingZoo.Core.ExportImport.Publisher; using PettingZoo.Core.Macros; using PettingZoo.WPF.ViewModel; @@ -37,10 +37,17 @@ namespace PettingZoo.UI.Tab.Publisher + public MessageDeliveryMode DeliveryMode + { + get => deliveryMode; + set => SetField(ref deliveryMode, value, otherPropertiesChanged: new[] { nameof(DeliveryModeIndex) }); + } + + public int DeliveryModeIndex { - get => deliveryMode == MessageDeliveryMode.Persistent ? 1 : 0; - set => SetField(ref deliveryMode, value == 1 ? MessageDeliveryMode.Persistent : MessageDeliveryMode.NonPersistent); + get => DeliveryMode == MessageDeliveryMode.Persistent ? 1 : 0; + set => DeliveryMode = value == 1 ? MessageDeliveryMode.Persistent : MessageDeliveryMode.NonPersistent; } @@ -127,7 +134,7 @@ namespace PettingZoo.UI.Tab.Publisher } - public ObservableCollection
Headers { get; } = new(); + public ObservableCollectionEx
Headers { get; } = new(); public ICommand PublishCommand => publishCommand; @@ -194,6 +201,56 @@ namespace PettingZoo.UI.Tab.Publisher } + public RawPublisherMessage GetPublisherMessage() + { + return new RawPublisherMessage + { + DeliveryMode = DeliveryMode, + ContentType = ContentType, + CorrelationId = CorrelationId, + AppId = AppId, + ContentEncoding = ContentEncoding, + Expiration = Expiration, + MessageId = MessageId, + Priority = Priority, + Timestamp = Timestamp, + TypeProperty = TypeProperty, + UserId = UserId, + Payload = Payload, + EnableMacros = EnableMacros, + + Headers = Headers.Count > 0 + ? Headers.ToDictionary(h => h.Key, h => h.Value) + : null + }; + } + + + public void LoadPublisherMessage(RawPublisherMessage message) + { + DeliveryMode = message.DeliveryMode; + ContentType = message.ContentType ?? ""; + CorrelationId = message.CorrelationId ?? ""; + AppId = message.AppId ?? ""; + ContentEncoding = message.ContentEncoding ?? ""; + Expiration = message.Expiration ?? ""; + MessageId = message.MessageId ?? ""; + Priority = message.Priority ?? ""; + Timestamp = message.Timestamp ?? ""; + TypeProperty = message.TypeProperty ?? ""; + UserId = message.UserId ?? ""; + Payload = message.Payload ?? ""; + EnableMacros = message.EnableMacros; + + if (message.Headers != null) + Headers.ReplaceAll(message.Headers.Select(p => new Header + { + Key = p.Key, + Value = p.Value + })); + } + + private static bool AnyNotEmpty(params string?[] values) { return values.Any(s => !string.IsNullOrEmpty(s)); diff --git a/PettingZoo/UI/Tab/Publisher/StoredPublisherMessagesStrings.Designer.cs b/PettingZoo/UI/Tab/Publisher/StoredPublisherMessagesStrings.Designer.cs new file mode 100644 index 0000000..468dd12 --- /dev/null +++ b/PettingZoo/UI/Tab/Publisher/StoredPublisherMessagesStrings.Designer.cs @@ -0,0 +1,90 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace PettingZoo.UI.Tab.Publisher { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class StoredPublisherMessagesStrings { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal StoredPublisherMessagesStrings() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PettingZoo.UI.Tab.Publisher.StoredPublisherMessagesStrings", typeof(StoredPublisherMessagesStrings).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Do you want to delete the saved message '{0}'?. + /// + internal static string DeleteConfirmation { + get { + return ResourceManager.GetString("DeleteConfirmation", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete message. + /// + internal static string DeleteConfirmationTitle { + get { + return ResourceManager.GetString("DeleteConfirmationTitle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save as.... + /// + internal static string DisplayNameDialogTitle { + get { + return ResourceManager.GetString("DisplayNameDialogTitle", resourceCulture); + } + } + } +} diff --git a/PettingZoo/UI/Tab/Publisher/StoredPublisherMessagesStrings.resx b/PettingZoo/UI/Tab/Publisher/StoredPublisherMessagesStrings.resx new file mode 100644 index 0000000..11e1170 --- /dev/null +++ b/PettingZoo/UI/Tab/Publisher/StoredPublisherMessagesStrings.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Do you want to delete the saved message '{0}'? + + + Delete message + + + Save as... + + \ No newline at end of file diff --git a/PettingZoo/UI/Tab/Publisher/StoredPublisherMessagesViewModel.cs b/PettingZoo/UI/Tab/Publisher/StoredPublisherMessagesViewModel.cs new file mode 100644 index 0000000..273f366 --- /dev/null +++ b/PettingZoo/UI/Tab/Publisher/StoredPublisherMessagesViewModel.cs @@ -0,0 +1,103 @@ +using System; +using System.Threading.Tasks; +using System.Windows; +using PettingZoo.Core.ExportImport.Publisher; +using PettingZoo.Core.Settings; +using PettingZoo.WPF.ViewModel; + +namespace PettingZoo.UI.Tab.Publisher +{ + public class StoredPublisherMessagesViewModel + { + private readonly IPublisherMessagesRepository publisherMessagesRepository; + + + public ObservableCollectionEx StoredMessages { get; } = new(); + + + public StoredPublisherMessagesViewModel(IPublisherMessagesRepository publisherMessagesRepository) + { + this.publisherMessagesRepository = publisherMessagesRepository; + + + Task.Run(async () => + { + var messages = await publisherMessagesRepository.GetStored(); + + await Application.Current.Dispatcher.BeginInvoke(() => + { + StoredMessages.ReplaceAll(messages); + }); + }); + } + + + public void Save(StoredPublisherMessage? selectedMessage, PublisherMessage message, Action onSaved) + { + if (selectedMessage == null) + { + SaveAs(message, null, onSaved); + return; + } + + Task.Run(async () => + { + var updatedMessage = await publisherMessagesRepository.Update(selectedMessage.Id, selectedMessage.DisplayName, message); + + await Application.Current.Dispatcher.BeginInvoke(() => + { + var index = StoredMessages.IndexOf(selectedMessage); + if (index >= 0) + StoredMessages[index] = updatedMessage; + else + // Should not occur, but might as well handle it gracefully + StoredMessages.Add(updatedMessage); + + onSaved(updatedMessage); + }); + }); + } + + + public void SaveAs(PublisherMessage message, string? originalDisplayName, Action onSaved) + { + var displayName = originalDisplayName ?? ""; + if (!InputDialog.Execute(ref displayName, StoredPublisherMessagesStrings.DisplayNameDialogTitle)) + return; + + Task.Run(async () => + { + var storedMessage = await publisherMessagesRepository.Add(displayName, message); + + await Application.Current.Dispatcher.BeginInvoke(() => + { + StoredMessages.Add(storedMessage); + onSaved(storedMessage); + }); + }); + + } + + + public void Delete(StoredPublisherMessage message, Action onDeleted) + { + if (MessageBox.Show( + string.Format(StoredPublisherMessagesStrings.DeleteConfirmation, message.DisplayName), + StoredPublisherMessagesStrings.DeleteConfirmationTitle, + MessageBoxButton.YesNo, + MessageBoxImage.Question) != MessageBoxResult.Yes) + return; + + Task.Run(async () => + { + await publisherMessagesRepository.Delete(message.Id); + + await Application.Current.Dispatcher.BeginInvoke(() => + { + StoredMessages.Remove(message); + onDeleted(); + }); + }); + } + } +} diff --git a/PettingZoo/UI/Tab/Publisher/TapetiPublisherView.xaml.cs b/PettingZoo/UI/Tab/Publisher/TapetiPublisherView.xaml.cs index db4468b..72e81aa 100644 --- a/PettingZoo/UI/Tab/Publisher/TapetiPublisherView.xaml.cs +++ b/PettingZoo/UI/Tab/Publisher/TapetiPublisherView.xaml.cs @@ -1,6 +1,5 @@ using System.Windows; using System.Windows.Controls; -using PettingZoo.Core.Macros; namespace PettingZoo.UI.Tab.Publisher { diff --git a/PettingZoo/UI/Tab/Publisher/TapetiPublisherViewModel.cs b/PettingZoo/UI/Tab/Publisher/TapetiPublisherViewModel.cs index b310820..6c2e1eb 100644 --- a/PettingZoo/UI/Tab/Publisher/TapetiPublisherViewModel.cs +++ b/PettingZoo/UI/Tab/Publisher/TapetiPublisherViewModel.cs @@ -3,6 +3,7 @@ using System.Text; using System.Windows; using System.Windows.Input; using PettingZoo.Core.Connection; +using PettingZoo.Core.ExportImport.Publisher; using PettingZoo.Core.Generator; using PettingZoo.Core.Macros; using PettingZoo.Core.Validation; @@ -132,6 +133,29 @@ namespace PettingZoo.UI.Tab.Publisher } + public TapetiPublisherMessage GetPublisherMessage() + { + return new TapetiPublisherMessage + { + CorrelationId = CorrelationId, + Payload = Payload, + EnableMacros = EnableMacros, + ClassName = ClassName, + AssemblyName = AssemblyName + }; + } + + + public void LoadPublisherMessage(TapetiPublisherMessage message) + { + CorrelationId = message.CorrelationId ?? ""; + Payload = message.Payload ?? ""; + EnableMacros = message.EnableMacros; + ClassName = message.ClassName ?? ""; + AssemblyName = message.AssemblyName ?? ""; + } + + private void BrowseClassExecute() { exampleGenerator.Select(tabHostWindow, example => diff --git a/PettingZoo/UI/Tab/Subscriber/SubscriberView.xaml b/PettingZoo/UI/Tab/Subscriber/SubscriberView.xaml index a6b3016..c8e5185 100644 --- a/PettingZoo/UI/Tab/Subscriber/SubscriberView.xaml +++ b/PettingZoo/UI/Tab/Subscriber/SubscriberView.xaml @@ -8,6 +8,7 @@ xmlns:svgc="http://sharpvectors.codeplex.com/svgc/" xmlns:avalonedit="http://icsharpcode.net/sharpdevelop/avalonedit" xmlns:connection="clr-namespace:PettingZoo.Core.Connection;assembly=PettingZoo.Core" + xmlns:controls="clr-namespace:PettingZoo.WPF.Controls;assembly=PettingZoo.WPF" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800" @@ -82,14 +83,14 @@ - + - + diff --git a/PettingZoo/UI/Tab/Subscriber/SubscriberView.xaml.cs b/PettingZoo/UI/Tab/Subscriber/SubscriberView.xaml.cs index f07a3b3..ef9c949 100644 --- a/PettingZoo/UI/Tab/Subscriber/SubscriberView.xaml.cs +++ b/PettingZoo/UI/Tab/Subscriber/SubscriberView.xaml.cs @@ -1,6 +1,4 @@ -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; +using System.Windows.Media; using ICSharpCode.AvalonEdit.Highlighting; namespace PettingZoo.UI.Tab.Subscriber @@ -35,17 +33,5 @@ namespace PettingZoo.UI.Tab.Subscriber if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this)) Background = Brushes.Transparent; } - - private void Toolbar_Loaded(object sender, RoutedEventArgs e) - { - // Hide arrow on the right side of the toolbar - var toolBar = sender as ToolBar; - - if (toolBar?.Template.FindName("OverflowGrid", toolBar) is FrameworkElement overflowGrid) - overflowGrid.Visibility = Visibility.Collapsed; - - if (toolBar?.Template.FindName("MainPanelBorder", toolBar) is FrameworkElement mainPanelBorder) - mainPanelBorder.Margin = new Thickness(0); - } } } diff --git a/PettingZoo/UI/Tab/Subscriber/SubscriberViewModel.cs b/PettingZoo/UI/Tab/Subscriber/SubscriberViewModel.cs index b2e7044..b2e0376 100644 --- a/PettingZoo/UI/Tab/Subscriber/SubscriberViewModel.cs +++ b/PettingZoo/UI/Tab/Subscriber/SubscriberViewModel.cs @@ -9,7 +9,7 @@ using System.Windows; using System.Windows.Forms; using System.Windows.Input; using PettingZoo.Core.Connection; -using PettingZoo.Core.ExportImport; +using PettingZoo.Core.ExportImport.Subscriber; using PettingZoo.Core.Rendering; using PettingZoo.WPF.ProgressWindow; using PettingZoo.WPF.ViewModel; diff --git a/PettingZoo/UI/Tab/Undocked/UndockedTabHostWindow.xaml b/PettingZoo/UI/Tab/Undocked/UndockedTabHostWindow.xaml index 2b9b461..76c9516 100644 --- a/PettingZoo/UI/Tab/Undocked/UndockedTabHostWindow.xaml +++ b/PettingZoo/UI/Tab/Undocked/UndockedTabHostWindow.xaml @@ -5,6 +5,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:undocked="clr-namespace:PettingZoo.UI.Tab.Undocked" xmlns:svgc="http://sharpvectors.codeplex.com/svgc/" + xmlns:controls="clr-namespace:PettingZoo.WPF.Controls;assembly=PettingZoo.WPF" mc:Ignorable="d" d:DataContext="{d:DesignInstance undocked:DesignTimeUndockedTabHostViewModel, IsDesignTimeCreatable=True}" Title="{Binding Title}" @@ -12,7 +13,7 @@ Width="800" WindowStyle="ThreeDBorderWindow"> - + + diff --git a/PettingZoo/UI/Tab/Undocked/UndockedTabHostWindow.xaml.cs b/PettingZoo/UI/Tab/Undocked/UndockedTabHostWindow.xaml.cs index d6fcdcb..8484260 100644 --- a/PettingZoo/UI/Tab/Undocked/UndockedTabHostWindow.xaml.cs +++ b/PettingZoo/UI/Tab/Undocked/UndockedTabHostWindow.xaml.cs @@ -1,7 +1,4 @@ -using System.Windows; -using System.Windows.Controls; - -namespace PettingZoo.UI.Tab.Undocked +namespace PettingZoo.UI.Tab.Undocked { /// /// Interaction logic for UndockedTabHostWindow.xaml @@ -41,17 +38,5 @@ namespace PettingZoo.UI.Tab.Undocked viewModel.Deactivate(); }; } - - private void Toolbar_Loaded(object sender, RoutedEventArgs e) - { - // Hide arrow on the right side of the toolbar - var toolBar = sender as ToolBar; - - if (toolBar?.Template.FindName("OverflowGrid", toolBar) is FrameworkElement overflowGrid) - overflowGrid.Visibility = Visibility.Collapsed; - - if (toolBar?.Template.FindName("MainPanelBorder", toolBar) is FrameworkElement mainPanelBorder) - mainPanelBorder.Margin = new Thickness(0); - } } } diff --git a/PettingZoo/UI/Tab/ViewTabFactory.cs b/PettingZoo/UI/Tab/ViewTabFactory.cs index 2e118f8..f5c3c07 100644 --- a/PettingZoo/UI/Tab/ViewTabFactory.cs +++ b/PettingZoo/UI/Tab/ViewTabFactory.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using PettingZoo.Core.Connection; -using PettingZoo.Core.ExportImport; +using PettingZoo.Core.ExportImport.Subscriber; using PettingZoo.Core.Generator; using PettingZoo.Core.Macros; using PettingZoo.UI.Tab.Publisher; @@ -17,6 +17,7 @@ namespace PettingZoo.UI.Tab private readonly IExampleGenerator exampleGenerator; private readonly IExportImportFormatProvider exportImportFormatProvider; private readonly IPayloadMacroProcessor payloadMacroProcessor; + private readonly StoredPublisherMessagesViewModel storedPublisherMessagesViewModel; // Not the cleanest way, but this factory itself can't be singleton without (justifyable) upsetting SimpleInjector private static ISubscriber? replySubscriber; @@ -24,13 +25,14 @@ namespace PettingZoo.UI.Tab public ViewTabFactory(ILogger logger, ITabHostProvider tabHostProvider, IExampleGenerator exampleGenerator, IExportImportFormatProvider exportImportFormatProvider, - IPayloadMacroProcessor payloadMacroProcessor) + IPayloadMacroProcessor payloadMacroProcessor, StoredPublisherMessagesViewModel storedPublisherMessagesViewModel) { this.logger = logger; this.tabHostProvider = tabHostProvider; this.exampleGenerator = exampleGenerator; this.exportImportFormatProvider = exportImportFormatProvider; this.payloadMacroProcessor = payloadMacroProcessor; + this.storedPublisherMessagesViewModel = storedPublisherMessagesViewModel; } @@ -63,7 +65,7 @@ namespace PettingZoo.UI.Tab public void CreatePublisherTab(IConnection connection, ReceivedMessageInfo? fromReceivedMessage = null) { - var viewModel = new PublisherViewModel(this, connection, exampleGenerator, payloadMacroProcessor, fromReceivedMessage); + var viewModel = new PublisherViewModel(this, connection, exampleGenerator, payloadMacroProcessor, storedPublisherMessagesViewModel, fromReceivedMessage); var tab = new ViewTab( new PublisherView(viewModel), viewModel,