Implemented exporting and import of publisher messages
This commit is contained in:
parent
b3c432d629
commit
d6b9970d51
@ -1,4 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using PettingZoo.Core.Connection;
|
||||
|
||||
namespace PettingZoo.Core.ExportImport.Publisher
|
||||
@ -11,48 +13,189 @@ namespace PettingZoo.Core.ExportImport.Publisher
|
||||
|
||||
|
||||
|
||||
public class PublisherMessage
|
||||
public class PublisherMessage : IEquatable<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 PublisherMessageType MessageType { get; init; }
|
||||
public bool SendToExchange { get; init; }
|
||||
public string? Exchange { get; init; }
|
||||
public string? RoutingKey { get; init; }
|
||||
public string? Queue { get; init; }
|
||||
public bool ReplyToNewSubscriber { get; init; }
|
||||
public string? ReplyTo { get; init; }
|
||||
|
||||
public RawPublisherMessage? RawPublisherMessage { get; set; }
|
||||
public TapetiPublisherMessage? TapetiPublisherMessage { get; set; }
|
||||
}
|
||||
public RawPublisherMessage? RawPublisherMessage { get; init; }
|
||||
public TapetiPublisherMessage? TapetiPublisherMessage { get; init; }
|
||||
|
||||
|
||||
public class RawPublisherMessage
|
||||
public bool Equals(PublisherMessage? other)
|
||||
{
|
||||
public MessageDeliveryMode DeliveryMode { get; set; }
|
||||
if (other == null) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
|
||||
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<string, string>? Headers { get; set; }
|
||||
return MessageType == other.MessageType &&
|
||||
SendToExchange == other.SendToExchange &&
|
||||
Exchange == other.Exchange &&
|
||||
RoutingKey == other.RoutingKey &&
|
||||
Queue == other.Queue &&
|
||||
ReplyToNewSubscriber == other.ReplyToNewSubscriber &&
|
||||
ReplyTo == other.ReplyTo &&
|
||||
Equals(RawPublisherMessage, other.RawPublisherMessage) &&
|
||||
Equals(TapetiPublisherMessage, other.TapetiPublisherMessage);
|
||||
}
|
||||
|
||||
|
||||
public class TapetiPublisherMessage
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
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; }
|
||||
if (obj == null) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
|
||||
return obj is PublisherMessage publisherMessage && Equals(publisherMessage);
|
||||
}
|
||||
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
var hashCode = new HashCode();
|
||||
hashCode.Add((int)MessageType);
|
||||
hashCode.Add(SendToExchange);
|
||||
hashCode.Add(Exchange);
|
||||
hashCode.Add(RoutingKey);
|
||||
hashCode.Add(Queue);
|
||||
hashCode.Add(ReplyToNewSubscriber);
|
||||
hashCode.Add(ReplyTo);
|
||||
hashCode.Add(RawPublisherMessage);
|
||||
hashCode.Add(TapetiPublisherMessage);
|
||||
return hashCode.ToHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class RawPublisherMessage : IEquatable<RawPublisherMessage>
|
||||
{
|
||||
public MessageDeliveryMode DeliveryMode { get; init; }
|
||||
|
||||
public string? ContentType { get; init; }
|
||||
public string? CorrelationId { get; init; }
|
||||
public string? AppId { get; init; }
|
||||
public string? ContentEncoding { get; init; }
|
||||
public string? Expiration { get; init; }
|
||||
public string? MessageId { get; init; }
|
||||
public string? Priority { get; init; }
|
||||
public string? Timestamp { get; init; }
|
||||
public string? TypeProperty { get; init; }
|
||||
public string? UserId { get; init; }
|
||||
public string? Payload { get; init; }
|
||||
public bool EnableMacros { get; init; }
|
||||
|
||||
public Dictionary<string, string>? Headers { get; init; }
|
||||
|
||||
|
||||
public bool Equals(RawPublisherMessage? other)
|
||||
{
|
||||
if (other == null) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
|
||||
return DeliveryMode == other.DeliveryMode &&
|
||||
ContentType == other.ContentType &&
|
||||
CorrelationId == other.CorrelationId &&
|
||||
AppId == other.AppId &&
|
||||
ContentEncoding == other.ContentEncoding &&
|
||||
Expiration == other.Expiration &&
|
||||
MessageId == other.MessageId &&
|
||||
Priority == other.Priority &&
|
||||
Timestamp == other.Timestamp &&
|
||||
TypeProperty == other.TypeProperty &&
|
||||
UserId == other.UserId &&
|
||||
Payload == other.Payload &&
|
||||
EnableMacros == other.EnableMacros &&
|
||||
HeadersEquals(other.Headers);
|
||||
}
|
||||
|
||||
|
||||
private bool HeadersEquals(Dictionary<string, string>? other)
|
||||
{
|
||||
if (other == null)
|
||||
return Headers == null || Headers.Count == 0;
|
||||
|
||||
if (Headers == null)
|
||||
return other.Count == 0;
|
||||
|
||||
return other.OrderBy(h => h.Key).SequenceEqual(Headers.OrderBy(h => h.Key));
|
||||
}
|
||||
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (obj == null) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
|
||||
return obj is RawPublisherMessage rawPublisherMessage && Equals(rawPublisherMessage);
|
||||
}
|
||||
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
var hashCode = new HashCode();
|
||||
hashCode.Add((int)DeliveryMode);
|
||||
hashCode.Add(ContentType);
|
||||
hashCode.Add(CorrelationId);
|
||||
hashCode.Add(AppId);
|
||||
hashCode.Add(ContentEncoding);
|
||||
hashCode.Add(Expiration);
|
||||
hashCode.Add(MessageId);
|
||||
hashCode.Add(Priority);
|
||||
hashCode.Add(Timestamp);
|
||||
hashCode.Add(TypeProperty);
|
||||
hashCode.Add(UserId);
|
||||
hashCode.Add(Payload);
|
||||
hashCode.Add(EnableMacros);
|
||||
|
||||
if (Headers != null)
|
||||
foreach (var (key, value) in Headers)
|
||||
{
|
||||
hashCode.Add(key);
|
||||
hashCode.Add(value);
|
||||
}
|
||||
|
||||
return hashCode.ToHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class TapetiPublisherMessage : IEquatable<TapetiPublisherMessage>
|
||||
{
|
||||
public string? CorrelationId { get; init; }
|
||||
public string? Payload { get; init; }
|
||||
public bool EnableMacros { get; init; }
|
||||
public string? ClassName { get; init; }
|
||||
public string? AssemblyName { get; init; }
|
||||
|
||||
|
||||
public bool Equals(TapetiPublisherMessage? other)
|
||||
{
|
||||
if (other == null) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
|
||||
return CorrelationId == other.CorrelationId &&
|
||||
Payload == other.Payload &&
|
||||
EnableMacros == other.EnableMacros &&
|
||||
ClassName == other.ClassName &&
|
||||
AssemblyName == other.AssemblyName;
|
||||
}
|
||||
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (obj == null) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
|
||||
return obj is TapetiPublisherMessage tapetiPublisherMessage && Equals(tapetiPublisherMessage);
|
||||
}
|
||||
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(CorrelationId, Payload, EnableMacros, ClassName, AssemblyName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PettingZoo.Core.ExportImport.Subscriber;
|
||||
|
||||
namespace PettingZoo.Tapeti.Export
|
||||
namespace PettingZoo.Tapeti.ExportImport
|
||||
{
|
||||
public abstract class BaseTapetiCmdExportImportFormat : IExportImportFormat
|
||||
{
|
@ -10,8 +10,7 @@ using Newtonsoft.Json.Linq;
|
||||
using PettingZoo.Core.Connection;
|
||||
using PettingZoo.Core.ExportImport.Subscriber;
|
||||
|
||||
|
||||
namespace PettingZoo.Tapeti.Export
|
||||
namespace PettingZoo.Tapeti.ExportImport
|
||||
{
|
||||
public class TapetiCmdExportFormat : BaseTapetiCmdExportImportFormat, IExportFormat
|
||||
{
|
@ -8,7 +8,7 @@
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace PettingZoo.Tapeti.Export {
|
||||
namespace PettingZoo.Tapeti.ExportImport {
|
||||
using System;
|
||||
|
||||
|
||||
@ -39,7 +39,7 @@ namespace PettingZoo.Tapeti.Export {
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PettingZoo.Tapeti.Export.TapetiCmdImportExportStrings", typeof(TapetiCmdImportExportStrings).Assembly);
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PettingZoo.Tapeti.ExportImport.TapetiCmdImportExportStrings", typeof(TapetiCmdImportExportStrings).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
@ -9,7 +9,7 @@ using Newtonsoft.Json;
|
||||
using PettingZoo.Core.Connection;
|
||||
using PettingZoo.Core.ExportImport.Subscriber;
|
||||
|
||||
namespace PettingZoo.Tapeti.Export
|
||||
namespace PettingZoo.Tapeti.ExportImport
|
||||
{
|
||||
public class TapetiCmdImportFormat : BaseTapetiCmdExportImportFormat, IImportFormat
|
||||
{
|
@ -33,7 +33,7 @@
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>AssemblyParserStrings.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Export\TapetiCmdImportExportStrings.Designer.cs">
|
||||
<Compile Update="ExportImport\TapetiCmdImportExportStrings.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>TapetiCmdImportExportStrings.resx</DependentUpon>
|
||||
@ -60,7 +60,7 @@
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>AssemblyParserStrings.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Export\TapetiCmdImportExportStrings.resx">
|
||||
<EmbeddedResource Update="ExportImport\TapetiCmdImportExportStrings.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>TapetiCmdImportExportStrings.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
|
26
PettingZoo.WPF/Controls/AutoOverflowToolBar.cs
Normal file
26
PettingZoo.WPF/Controls/AutoOverflowToolBar.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace PettingZoo.WPF.Controls
|
||||
{
|
||||
public class AutoOverflowToolBar : ToolBar
|
||||
{
|
||||
public AutoOverflowToolBar()
|
||||
{
|
||||
Loaded += (_, _) =>
|
||||
{
|
||||
// Hide overflow arrow on the right side of the toolbar when not required
|
||||
if (Template.FindName("OverflowButton", this) is not FrameworkElement overflowButton)
|
||||
return;
|
||||
|
||||
if (!overflowButton.IsEnabled)
|
||||
overflowButton.Visibility = Visibility.Hidden;
|
||||
|
||||
overflowButton.IsEnabledChanged += (_, _) =>
|
||||
{
|
||||
overflowButton.Visibility = overflowButton.IsEnabled ? Visibility.Visible : Visibility.Hidden;
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
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);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@ using PettingZoo.Core.Settings;
|
||||
using PettingZoo.RabbitMQ;
|
||||
using PettingZoo.Settings.LiteDB;
|
||||
using PettingZoo.Tapeti;
|
||||
using PettingZoo.Tapeti.Export;
|
||||
using PettingZoo.Tapeti.ExportImport;
|
||||
using PettingZoo.UI.Connection;
|
||||
using PettingZoo.UI.Main;
|
||||
using PettingZoo.UI.Subscribe;
|
||||
|
@ -12,7 +12,7 @@
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Style="{StaticResource WindowStyle}"
|
||||
Title="{Binding Title}"
|
||||
FocusManager.FocusedElement="{Binding ElementName=DisplayNameTextBox}"
|
||||
FocusManager.FocusedElement="{Binding ElementName=ValueTextBox}"
|
||||
d:DataContext="{d:DesignInstance local:InputDialogViewModel}">
|
||||
<StackPanel Margin="8">
|
||||
<TextBox Name="ValueTextBox" Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}" />
|
||||
|
@ -25,7 +25,7 @@
|
||||
<ui:BindingProxy x:Key="ContextMenuProxy" Data="{Binding}" />
|
||||
</Window.Resources>
|
||||
<DockPanel>
|
||||
<controls:NoOverflowToolbar DockPanel.Dock="Top" ToolBarTray.IsLocked="True">
|
||||
<controls:AutoOverflowToolBar DockPanel.Dock="Top" ToolBarTray.IsLocked="True">
|
||||
<Button Command="{Binding ConnectCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Source="{svgc:SvgImage Source=/Images/Connect.svg, AppName=PettingZoo}" Width="16" Height="16" Style="{StaticResource ToolbarIcon}"/>
|
||||
@ -83,7 +83,7 @@
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</controls:NoOverflowToolbar>
|
||||
</controls:AutoOverflowToolBar>
|
||||
<StatusBar DockPanel.Dock="Bottom">
|
||||
<StatusBarItem>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
|
@ -16,7 +16,7 @@
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="300" />
|
||||
<ColumnDefinition Width="350" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<ScrollViewer Grid.Column="0" VerticalScrollBarVisibility="Auto">
|
||||
@ -95,7 +95,7 @@
|
||||
|
||||
<Label Grid.Row="0" Style="{StaticResource HeaderLabel}" Content="{x:Static res:PublisherViewStrings.PanelTitleMessages}"/>
|
||||
|
||||
<controls:NoOverflowToolbar Grid.Row="1" ToolBarTray.IsLocked="True" Margin="0,0,0,4">
|
||||
<controls:AutoOverflowToolBar Grid.Row="1" ToolBarTray.IsLocked="True" Margin="0,0,0,4">
|
||||
<!-- TODO load button in addition to double-click. I don't like hidden-only functionality -->
|
||||
<Button Command="{Binding SaveCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
@ -116,8 +116,21 @@
|
||||
<TextBlock Margin="3,0,0,0" Text="{x:Static res:PublisherViewStrings.ToolbarDelete}" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Separator Style="{StaticResource {x:Static ToolBar.SeparatorStyleKey}}" />
|
||||
<Button Command="{Binding ExportCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Source="{svgc:SvgImage Source=/Images/Export.svg, AppName=PettingZoo}" Width="16" Height="16" Style="{StaticResource ToolbarIcon}"/>
|
||||
<TextBlock Margin="3,0,0,0" Text="{x:Static res:PublisherViewStrings.ToolbarExport}" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Command="{Binding ImportCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Source="{svgc:SvgImage Source=/Images/Import.svg, AppName=PettingZoo}" Width="16" Height="16" Style="{StaticResource ToolbarIcon}"/>
|
||||
<TextBlock Margin="3,0,0,0" Text="{x:Static res:PublisherViewStrings.ToolbarImport}" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<!-- TODO export / import -->
|
||||
</controls:NoOverflowToolbar>
|
||||
</controls:AutoOverflowToolBar>
|
||||
|
||||
<ListBox Grid.Row="2" ItemsSource="{Binding StoredMessages}" SelectedValue="{Binding SelectedStoredMessage}">
|
||||
<ListBox.Resources>
|
||||
@ -147,7 +160,7 @@
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
<TextBlock.InputBindings>
|
||||
<MouseBinding MouseAction="LeftDoubleClick" Command="{Binding DataContext.LoadStoredMessage, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}" />
|
||||
<MouseBinding MouseAction="LeftDoubleClick" Command="{Binding DataContext.LoadStoredMessageCommand, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}" />
|
||||
</TextBlock.InputBindings>
|
||||
</TextBlock>
|
||||
</DataTemplate>
|
||||
|
@ -1,16 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
using Accessibility;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
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;
|
||||
using UserControl = System.Windows.Controls.UserControl;
|
||||
|
||||
namespace PettingZoo.UI.Tab.Publisher
|
||||
{
|
||||
@ -46,10 +53,13 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
private readonly DelegateCommand saveCommand;
|
||||
private readonly DelegateCommand saveAsCommand;
|
||||
private readonly DelegateCommand deleteCommand;
|
||||
private readonly DelegateCommand loadStoredMessage;
|
||||
private readonly DelegateCommand loadStoredMessageCommand;
|
||||
private readonly DelegateCommand exportCommand;
|
||||
private readonly DelegateCommand importCommand;
|
||||
|
||||
private readonly TabToolbarCommand[] toolbarCommands;
|
||||
private Window? tabHostWindow;
|
||||
private bool disableCheckCanSave;
|
||||
|
||||
|
||||
public bool SendToExchange
|
||||
@ -167,12 +177,10 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
public StoredPublisherMessage? SelectedStoredMessage
|
||||
{
|
||||
get => selectedStoredMessage;
|
||||
set => SetField(ref selectedStoredMessage, value, delegateCommandsChanged: new[] { deleteCommand });
|
||||
set => SetField(ref selectedStoredMessage, value, delegateCommandsChanged: new[] { loadStoredMessageCommand, deleteCommand, exportCommand });
|
||||
}
|
||||
|
||||
|
||||
// TODO detect changes from ActiveStoredMessage and show indication in the UI
|
||||
|
||||
public StoredPublisherMessage? ActiveStoredMessage
|
||||
{
|
||||
get => activeStoredMessage;
|
||||
@ -184,7 +192,9 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
public ICommand SaveCommand => saveCommand;
|
||||
public ICommand SaveAsCommand => saveAsCommand;
|
||||
public ICommand DeleteCommand => deleteCommand;
|
||||
public ICommand LoadStoredMessage => loadStoredMessage;
|
||||
public ICommand LoadStoredMessageCommand => loadStoredMessageCommand;
|
||||
public ICommand ExportCommand => exportCommand;
|
||||
public ICommand ImportCommand => importCommand;
|
||||
|
||||
|
||||
public string Title => SendToQueue
|
||||
@ -214,10 +224,12 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
this.tabFactory = tabFactory;
|
||||
|
||||
publishCommand = new DelegateCommand(PublishExecute, PublishCanExecute);
|
||||
saveCommand = new DelegateCommand(SaveExecute);
|
||||
saveCommand = new DelegateCommand(SaveExecute, SaveCanExecute);
|
||||
saveAsCommand = new DelegateCommand(SaveAsExecute);
|
||||
deleteCommand = new DelegateCommand(DeleteExecute, DeleteCanExecute);
|
||||
loadStoredMessage = new DelegateCommand(LoadStoredMessageExecute, LoadStoredMessageCanExecute);
|
||||
deleteCommand = new DelegateCommand(DeleteExecute, SelectedMessageCanExecute);
|
||||
loadStoredMessageCommand = new DelegateCommand(LoadStoredMessageExecute, SelectedMessageCanExecute);
|
||||
exportCommand = new DelegateCommand(ExportExecute, SelectedMessageCanExecute);
|
||||
importCommand = new DelegateCommand(ImportExecute);
|
||||
|
||||
toolbarCommands = new[]
|
||||
{
|
||||
@ -229,6 +241,9 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
SetMessageTypeControl(fromReceivedMessage);
|
||||
else
|
||||
SetMessageTypeControl(PublisherMessageType.Raw);
|
||||
|
||||
|
||||
PropertyChanged += (_, _) => { saveCommand.RaiseCanExecuteChanged(); };
|
||||
}
|
||||
|
||||
|
||||
@ -268,6 +283,11 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
publishCommand.RaiseCanExecuteChanged();
|
||||
};
|
||||
|
||||
// This is becoming a bit messy, find a cleaner way...
|
||||
// TODO monitor header changes as well, instead of only the collection
|
||||
rawPublisherViewModel.PropertyChanged += (_, _) => { saveCommand.RaiseCanExecuteChanged(); };
|
||||
rawPublisherViewModel.Headers.CollectionChanged += (_, _) => { saveCommand.RaiseCanExecuteChanged(); };
|
||||
|
||||
rawPublisherView = new RawPublisherView(rawPublisherViewModel);
|
||||
}
|
||||
else
|
||||
@ -287,6 +307,8 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
publishCommand.RaiseCanExecuteChanged();
|
||||
};
|
||||
|
||||
tapetiPublisherViewModel.PropertyChanged += (_, _) => { saveCommand.RaiseCanExecuteChanged(); };
|
||||
|
||||
tapetiPublisherView = new TapetiPublisherView(tapetiPublisherViewModel);
|
||||
|
||||
if (tabHostWindow != null)
|
||||
@ -356,19 +378,33 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
}
|
||||
|
||||
|
||||
private bool SaveCanExecute()
|
||||
{
|
||||
if (disableCheckCanSave)
|
||||
return false;
|
||||
|
||||
return ActiveStoredMessage != null && !GetPublisherMessage().Equals(ActiveStoredMessage.Message);
|
||||
}
|
||||
|
||||
|
||||
private void SaveExecute()
|
||||
{
|
||||
storedPublisherMessagesViewModel.Save(SelectedStoredMessage, GetPublisherMessage(), message =>
|
||||
if (ActiveStoredMessage == null)
|
||||
return;
|
||||
|
||||
storedPublisherMessagesViewModel.Save(ActiveStoredMessage, GetPublisherMessage(), message =>
|
||||
{
|
||||
ActiveStoredMessage = message;
|
||||
SelectedStoredMessage = message;
|
||||
|
||||
saveCommand.RaiseCanExecuteChanged();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void SaveAsExecute()
|
||||
{
|
||||
storedPublisherMessagesViewModel.SaveAs(GetPublisherMessage(), SelectedStoredMessage?.DisplayName, message =>
|
||||
storedPublisherMessagesViewModel.SaveAs(GetPublisherMessage(), ActiveStoredMessage?.DisplayName, message =>
|
||||
{
|
||||
ActiveStoredMessage = message;
|
||||
SelectedStoredMessage = message;
|
||||
@ -394,7 +430,7 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
}
|
||||
|
||||
|
||||
private bool DeleteCanExecute()
|
||||
private bool SelectedMessageCanExecute()
|
||||
{
|
||||
return SelectedStoredMessage != null;
|
||||
}
|
||||
@ -407,6 +443,9 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
|
||||
var message = SelectedStoredMessage.Message;
|
||||
|
||||
disableCheckCanSave = true;
|
||||
try
|
||||
{
|
||||
MessageType = message.MessageType;
|
||||
SendToExchange = message.SendToExchange;
|
||||
Exchange = message.Exchange ?? "";
|
||||
@ -433,11 +472,66 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
|
||||
ActiveStoredMessage = SelectedStoredMessage;
|
||||
}
|
||||
|
||||
|
||||
private bool LoadStoredMessageCanExecute()
|
||||
finally
|
||||
{
|
||||
return SelectedStoredMessage != null;
|
||||
disableCheckCanSave = false;
|
||||
saveCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static readonly JsonSerializerSettings ExportImportSettings = new()
|
||||
{
|
||||
Converters = new List<JsonConverter> { new StringEnumConverter() }
|
||||
};
|
||||
|
||||
|
||||
|
||||
private void ExportExecute()
|
||||
{
|
||||
if (SelectedStoredMessage == null)
|
||||
return;
|
||||
|
||||
var invalidChars = Regex.Escape(new string(Path.GetInvalidFileNameChars()));
|
||||
var invalidRegStr = string.Format(@"([{0}]*\.+$)|([{0}]+)", invalidChars);
|
||||
var suggestedFilename = Regex.Replace(SelectedStoredMessage.DisplayName, invalidRegStr, "_");
|
||||
|
||||
var dialog = new SaveFileDialog
|
||||
{
|
||||
Filter = PublisherViewStrings.StoredMessagesExportImportFilter,
|
||||
FileName = suggestedFilename
|
||||
};
|
||||
|
||||
if (dialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
File.WriteAllText(dialog.FileName, JsonConvert.SerializeObject(SelectedStoredMessage.Message, ExportImportSettings), Encoding.UTF8);
|
||||
}
|
||||
|
||||
|
||||
private void ImportExecute()
|
||||
{
|
||||
var dialog = new OpenFileDialog
|
||||
{
|
||||
Filter = PublisherViewStrings.StoredMessagesExportImportFilter
|
||||
};
|
||||
|
||||
if (dialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var fileContents = File.ReadAllText(dialog.FileName, Encoding.UTF8);
|
||||
var message = JsonConvert.DeserializeObject<PublisherMessage>(fileContents, ExportImportSettings);
|
||||
if (message == null)
|
||||
return;
|
||||
|
||||
var displayName = dialog.FileName.EndsWith(".pubmsg.json")
|
||||
? Path.GetFileName(dialog.FileName)[..^".pubmsg.json".Length]
|
||||
: Path.GetFileNameWithoutExtension(dialog.FileName);
|
||||
|
||||
storedPublisherMessagesViewModel.SaveAs(message, displayName, storedMessage =>
|
||||
{
|
||||
SelectedStoredMessage = storedMessage;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -186,6 +186,15 @@ namespace PettingZoo.UI.Tab.Publisher {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to PettingZoo message (*.pubmsg.json)|*.pubmsg.json.
|
||||
/// </summary>
|
||||
public static string StoredMessagesExportImportFilter {
|
||||
get {
|
||||
return ResourceManager.GetString("StoredMessagesExportImportFilter", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Publish: {0}.
|
||||
/// </summary>
|
||||
@ -213,6 +222,24 @@ namespace PettingZoo.UI.Tab.Publisher {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Export....
|
||||
/// </summary>
|
||||
public static string ToolbarExport {
|
||||
get {
|
||||
return ResourceManager.GetString("ToolbarExport", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Import....
|
||||
/// </summary>
|
||||
public static string ToolbarImport {
|
||||
get {
|
||||
return ResourceManager.GetString("ToolbarImport", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Save.
|
||||
/// </summary>
|
||||
|
@ -159,6 +159,9 @@
|
||||
<data name="ReplyToCorrelationIdPrefix" xml:space="preserve">
|
||||
<value>Re: </value>
|
||||
</data>
|
||||
<data name="StoredMessagesExportImportFilter" xml:space="preserve">
|
||||
<value>PettingZoo message (*.pubmsg.json)|*.pubmsg.json</value>
|
||||
</data>
|
||||
<data name="TabTitle" xml:space="preserve">
|
||||
<value>Publish: {0}</value>
|
||||
</data>
|
||||
@ -168,6 +171,12 @@
|
||||
<data name="ToolbarDelete" xml:space="preserve">
|
||||
<value>Delete</value>
|
||||
</data>
|
||||
<data name="ToolbarExport" xml:space="preserve">
|
||||
<value>Export...</value>
|
||||
</data>
|
||||
<data name="ToolbarImport" xml:space="preserve">
|
||||
<value>Import...</value>
|
||||
</data>
|
||||
<data name="ToolbarSave" xml:space="preserve">
|
||||
<value>Save</value>
|
||||
</data>
|
||||
|
@ -219,9 +219,7 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
Payload = Payload,
|
||||
EnableMacros = EnableMacros,
|
||||
|
||||
Headers = Headers.Count > 0
|
||||
? Headers.ToDictionary(h => h.Key, h => h.Value)
|
||||
: null
|
||||
Headers = Headers.Where(h => !h.IsEmpty()).ToDictionary(h => h.Key, h => h.Value)
|
||||
};
|
||||
}
|
||||
|
||||
@ -243,12 +241,18 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
EnableMacros = message.EnableMacros;
|
||||
|
||||
if (message.Headers != null)
|
||||
{
|
||||
Headers.ReplaceAll(message.Headers.Select(p => new Header
|
||||
{
|
||||
Key = p.Key,
|
||||
Value = p.Value
|
||||
}));
|
||||
}
|
||||
else
|
||||
Headers.Clear();
|
||||
|
||||
AddHeader();
|
||||
}
|
||||
|
||||
|
||||
private static bool AnyNotEmpty(params string?[] values)
|
||||
|
@ -32,21 +32,15 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
}
|
||||
|
||||
|
||||
public void Save(StoredPublisherMessage? selectedMessage, PublisherMessage message, Action<StoredPublisherMessage> onSaved)
|
||||
public void Save(StoredPublisherMessage overwriteMessage, PublisherMessage message, Action<StoredPublisherMessage> onSaved)
|
||||
{
|
||||
if (selectedMessage == null)
|
||||
{
|
||||
SaveAs(message, null, onSaved);
|
||||
return;
|
||||
}
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var updatedMessage = await publisherMessagesRepository.Update(selectedMessage.Id, selectedMessage.DisplayName, message);
|
||||
var updatedMessage = await publisherMessagesRepository.Update(overwriteMessage.Id, overwriteMessage.DisplayName, message);
|
||||
|
||||
await Application.Current.Dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
var index = StoredMessages.IndexOf(selectedMessage);
|
||||
var index = StoredMessages.IndexOf(overwriteMessage);
|
||||
if (index >= 0)
|
||||
StoredMessages[index] = updatedMessage;
|
||||
else
|
||||
@ -75,7 +69,6 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
onSaved(storedMessage);
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -83,14 +83,14 @@
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="200"/>
|
||||
</Grid.RowDefinitions>
|
||||
<controls:NoOverflowToolbar Grid.Column="0" Grid.Row="0" ToolBarTray.IsLocked="True" Margin="0,0,0,4" Background="Transparent">
|
||||
<controls:AutoOverflowToolBar Grid.Column="0" Grid.Row="0" ToolBarTray.IsLocked="True" Margin="0,0,0,4" Background="Transparent">
|
||||
<Button Command="{Binding CreatePublisherCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Source="{svgc:SvgImage Source=/Images/Publish.svg, AppName=PettingZoo}" Width="16" Height="16" Style="{StaticResource ToolbarIcon}"/>
|
||||
<TextBlock Margin="3,0,0,0" Text="{x:Static res:SubscriberViewStrings.ContextPublish}" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</controls:NoOverflowToolbar>
|
||||
</controls:AutoOverflowToolBar>
|
||||
|
||||
<Border Grid.Column="0" Grid.Row="1" Style="{StaticResource SidePanel}">
|
||||
<DockPanel>
|
||||
|
@ -13,7 +13,7 @@
|
||||
Width="800"
|
||||
WindowStyle="ThreeDBorderWindow">
|
||||
<DockPanel>
|
||||
<controls:NoOverflowToolbar DockPanel.Dock="Top" ToolBarTray.IsLocked="True">
|
||||
<controls:AutoOverflowToolBar DockPanel.Dock="Top" ToolBarTray.IsLocked="True">
|
||||
<Button Command="{Binding DockCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Source="{svgc:SvgImage Source=/Images/Dock.svg, AppName=PettingZoo}" Width="16" Height="16" Style="{StaticResource ToolbarIcon}"/>
|
||||
@ -38,7 +38,7 @@
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</controls:NoOverflowToolbar>
|
||||
</controls:AutoOverflowToolBar>
|
||||
|
||||
<ContentControl Content="{Binding Content}" />
|
||||
</DockPanel>
|
||||
|
Loading…
Reference in New Issue
Block a user