diff --git a/Source/App.axaml b/Source/App.axaml
index ef11874..a6f44eb 100644
--- a/Source/App.axaml
+++ b/Source/App.axaml
@@ -8,6 +8,15 @@
+
+ Ubuntu Mono,Lucida Console,SF Mono,Courier New
+
#2200EE00
12
@@ -18,9 +27,9 @@
-
-
-
+
+
+
diff --git a/Source/App.axaml.cs b/Source/App.axaml.cs
index 881cb5b..269a064 100644
--- a/Source/App.axaml.cs
+++ b/Source/App.axaml.cs
@@ -2,6 +2,7 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
+using Avalonia.Styling;
using Microsoft.Extensions.DependencyInjection;
using mqttMultimeter.Common;
using mqttMultimeter.Controls;
@@ -64,6 +65,8 @@ public override void Initialize()
public override void OnFrameworkInitializationCompleted()
{
+ Current!.RequestedThemeVariant = ThemeVariant.Dark;
+
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
var mainWindow = new MainWindow
diff --git a/Source/Assets/VectorIcons.axaml b/Source/Assets/VectorIcons.axaml
index bc8422e..f0f5adf 100644
--- a/Source/Assets/VectorIcons.axaml
+++ b/Source/Assets/VectorIcons.axaml
@@ -56,4 +56,7 @@
M2.75 5C2.33579 5 2 5.33579 2 5.75C2 6.16421 2.33579 6.5 2.75 6.5H21.25C21.6642 6.5 22 6.16421 22 5.75C22 5.33579 21.6642 5 21.25 5H2.75Z M2.75 11.5C2.33579 11.5 2 11.8358 2 12.25C2 12.6642 2.33579 13 2.75 13H19C20.3807 13 21.5 14.1193 21.5 15.5C21.5 16.8807 20.3807 18 19 18H14.5607L15.2803 17.2803C15.5732 16.9874 15.5732 16.5126 15.2803 16.2197C14.9874 15.9268 14.5126 15.9268 14.2197 16.2197L12.2197 18.2197C11.9268 18.5126 11.9268 18.9874 12.2197 19.2803L14.2197 21.2803C14.5126 21.5732 14.9874 21.5732 15.2803 21.2803C15.5732 20.9874 15.5732 20.5126 15.2803 20.2197L14.5607 19.5H19C21.2091 19.5 23 17.7091 23 15.5C23 13.2909 21.2091 11.5 19 11.5H2.75Z M2 18.75C2 18.3358 2.33579 18 2.75 18H9.25C9.66421 18 10 18.3358 10 18.75C10 19.1642 9.66421 19.5 9.25 19.5H2.75C2.33579 19.5 2 19.1642 2 18.75Z
M10.9093922,2.78216375 C11.9491636,2.20625071 13.2471955,2.54089334 13.8850247,3.52240345 L13.9678229,3.66023048 L21.7267791,17.6684928 C21.9115773,18.0021332 22.0085303,18.3772743 22.0085303,18.7586748 C22.0085303,19.9495388 21.0833687,20.9243197 19.9125791,21.003484 L19.7585303,21.0086748 L4.24277801,21.0086748 C3.86146742,21.0086748 3.48641186,20.9117674 3.15282824,20.7270522 C2.11298886,20.1512618 1.7079483,18.8734454 2.20150311,17.8120352 L2.27440063,17.668725 L10.0311968,3.66046274 C10.2357246,3.291099 10.5400526,2.98673515 10.9093922,2.78216375 Z M20.4146132,18.3952808 L12.6556571,4.3870185 C12.4549601,4.02467391 11.9985248,3.89363262 11.6361802,4.09432959 C11.5438453,4.14547244 11.4637001,4.21532637 11.4006367,4.29899869 L11.3434484,4.38709592 L3.58665221,18.3953582 C3.385998,18.7577265 3.51709315,19.2141464 3.87946142,19.4148006 C3.96285732,19.4609794 4.05402922,19.4906942 4.14802472,19.5026655 L4.24277801,19.5086748 L19.7585303,19.5086748 C20.1727439,19.5086748 20.5085303,19.1728883 20.5085303,18.7586748 C20.5085303,18.6633247 20.4903516,18.5691482 20.455275,18.4811011 L20.4146132,18.3952808 L12.6556571,4.3870185 L20.4146132,18.3952808 Z M12.0004478,16.0017852 C12.5519939,16.0017852 12.9991104,16.4489016 12.9991104,17.0004478 C12.9991104,17.5519939 12.5519939,17.9991104 12.0004478,17.9991104 C11.4489016,17.9991104 11.0017852,17.5519939 11.0017852,17.0004478 C11.0017852,16.4489016 11.4489016,16.0017852 12.0004478,16.0017852 Z M11.9962476,8.49954934 C12.3759432,8.49924613 12.689964,8.78114897 12.7399193,9.14718469 L12.7468472,9.24894974 L12.750448,13.7505438 C12.7507788,14.1647572 12.4152611,14.5008121 12.0010476,14.5011439 C11.621352,14.5014471 11.3073312,14.2195442 11.257376,13.8535085 L11.250448,13.7517435 L11.2468472,9.25014944 C11.2465164,8.83593601 11.5820341,8.49988112 11.9962476,8.49954934 Z
+
+ M10,2.75 C14.0041,2.75 17.25,5.99594 17.25,10 C17.25,11.6236562 16.7162402,13.1225957 15.8146692,14.3310347 L15.6295,14.5688 L20.5303,19.4697 C20.8232,19.7626 20.8232,20.2374 20.5303,20.5303 C20.2936778,20.7670111 19.938142,20.8124333 19.6558506,20.6665667 L19.5538,20.6029 L19.4697,20.5303 L14.5688,15.6295 C13.3219,16.6427 11.7319,17.25 10,17.25 C5.99593,17.25 2.75,14.0041 2.75,10 C2.75,5.99594 5.99593,2.75 10,2.75 Z M10,4.25 C6.82436,4.25 4.25,6.82436 4.25,10 C4.25,13.1756 6.82436,15.75 10,15.75 C13.1756,15.75 15.75,13.1756 15.75,10 C15.75,6.82436 13.1756,4.25 10,4.25 Z M12.75,9.25 C13.1642,9.25 13.5,9.58579 13.5,10 C13.5,10.4142 13.1642,10.75 12.75,10.75 L7.25,10.75 C6.83578,10.75 6.5,10.4142 6.5,10 C6.5,9.58579 6.83578,9.25 7.25,9.25 L12.75,9.25 Z
+ M10,2.75 C14.0041,2.75 17.25,5.99594 17.25,10 C17.25,11.7319 16.6427,13.3219 15.6295,14.5688 L20.5303,19.4697 C20.8232,19.7626 20.8232,20.2374 20.5303,20.5303 C20.2641,20.7966 19.8474,20.8208 19.5538,20.6029 L19.4697,20.5303 L14.5688,15.6295 C13.3219,16.6427 11.7319,17.25 10,17.25 C5.99593,17.25 2.75,14.0041 2.75,10 C2.75,5.99594 5.99593,2.75 10,2.75 Z M10,4.25 C6.82436,4.25 4.25,6.82436 4.25,10 C4.25,13.1756 6.82436,15.75 10,15.75 C13.1756,15.75 15.75,13.1756 15.75,10 C15.75,6.82436 13.1756,4.25 10,4.25 Z M10,6.5 C10.3796833,6.5 10.6934889,6.78215687 10.7431531,7.14823019 L10.75,7.25 L10.75,9.25 L12.75,9.25 C13.1642,9.25 13.5,9.58579 13.5,10 C13.5,10.3796833 13.2178347,10.6934889 12.8517677,10.7431531 L12.75,10.75 L10.75,10.75 L10.75,12.75 C10.75,13.1642 10.4142,13.5 10,13.5 C9.62029833,13.5 9.30650806,13.2178347 9.25684649,12.8517677 L9.25,12.75 L9.25,10.75 L7.25,10.75 C6.83578,10.75 6.5,10.4142 6.5,10 C6.5,9.6203075 6.78214847,9.30650958 7.14822809,9.25684668 L7.25,9.25 L9.25,9.25 L9.25,7.25 C9.25,6.83579 9.58578,6.5 10,6.5 Z
\ No newline at end of file
diff --git a/Source/Common/ViewLocator.cs b/Source/Common/ViewLocator.cs
index 28ade58..ccc1410 100644
--- a/Source/Common/ViewLocator.cs
+++ b/Source/Common/ViewLocator.cs
@@ -9,8 +9,13 @@ sealed class ViewLocator : IDataTemplate
{
readonly Dictionary _viewTypeCache = new();
- public IControl Build(object viewModel)
+ public Control Build(object? viewModel)
{
+ if (viewModel == null)
+ {
+ return new TextBlock();
+ }
+
var viewModelTypeName = viewModel.GetType().FullName!;
if (!_viewTypeCache.TryGetValue(viewModelTypeName, out var viewType))
@@ -43,7 +48,7 @@ public IControl Build(object viewModel)
};
}
- public bool Match(object data)
+ public bool Match(object? data)
{
return data is BaseViewModel;
}
diff --git a/Source/Controls/AutoGrid.cs b/Source/Controls/AutoGrid.cs
index d4fd69c..ae60c1c 100644
--- a/Source/Controls/AutoGrid.cs
+++ b/Source/Controls/AutoGrid.cs
@@ -24,7 +24,7 @@ public static void SetIsNextRow(AvaloniaObject element, bool value)
element.SetValue(IsNextRowProperty, value);
}
- protected override void ChildrenChanged(object sender, NotifyCollectionChangedEventArgs e)
+ protected override void ChildrenChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
base.ChildrenChanged(sender, e);
diff --git a/Source/Controls/BufferEditor/BufferEditor.axaml b/Source/Controls/BufferEditor/BufferEditor.axaml
index c2e59e8..0965dd0 100644
--- a/Source/Controls/BufferEditor/BufferEditor.axaml
+++ b/Source/Controls/BufferEditor/BufferEditor.axaml
@@ -23,20 +23,12 @@
-
-
-
-
-
+
-
-
-
-
-
+ Classes="tool_bar"
+ ColumnDefinitions="Auto,*,Auto">
@@ -47,9 +39,14 @@
-
-
-
+
+
+
+
-
-
-
+
+
+
+
+
-
+
+
+
+
+
diff --git a/Source/Controls/BufferEditor/BufferEditor.axaml.cs b/Source/Controls/BufferEditor/BufferEditor.axaml.cs
index 25b7491..5717ab9 100644
--- a/Source/Controls/BufferEditor/BufferEditor.axaml.cs
+++ b/Source/Controls/BufferEditor/BufferEditor.axaml.cs
@@ -1,50 +1,52 @@
using System;
using System.Collections.Generic;
using System.IO;
-using System.Linq;
-using System.Threading;
using System.Xml.Linq;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Interactivity;
+using Avalonia.Platform.Storage;
using Avalonia.Threading;
using AvaloniaEdit;
using AvaloniaEdit.TextMate;
-using AvaloniaEdit.TextMate.Grammars;
using mqttMultimeter.Extensions;
-using mqttMultimeter.Main;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
+using TextMateSharp.Grammars;
namespace mqttMultimeter.Controls;
public sealed class BufferEditor : TemplatedControl
{
- static readonly List FileDialogFilters = new()
+ static readonly List FileDialogFilters = new()
{
- new FileDialogFilter
+ new FilePickerFileType("JSON files")
{
- Name = "Text files",
- Extensions = new List
+ Patterns = new List
{
- "txt"
+ "*.json"
}
},
- new FileDialogFilter
+ new FilePickerFileType("Text files")
{
- Name = "JSON files",
- Extensions = new List
+ Patterns = new List
{
- "json"
+ "*.txt"
}
},
- new FileDialogFilter
+ new FilePickerFileType("XML files")
{
- Name = "XML files",
- Extensions = new List
+ Patterns = new List
{
- "xml"
+ "*.xml"
+ }
+ },
+ new FilePickerFileType("All files")
+ {
+ Patterns = new List
+ {
+ "*"
}
}
};
@@ -141,12 +143,24 @@ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
_reformatButton = (Button)this.GetTemplateChild("ReformatButton");
_reformatButton.Click += OnReformat;
+ var increaseFontSizeButton = (Button)this.GetTemplateChild("IncreaseFontSizeButton");
+ increaseFontSizeButton.Click += (_, __) =>
+ {
+ _textEditor.FontSize += 0.5;
+ };
+
+ var decreaseFontSizeButton = (Button)this.GetTemplateChild("DecreaseFontSizeButton");
+ decreaseFontSizeButton.Click += (_, __) =>
+ {
+ _textEditor.FontSize -= 0.5;
+ };
+
SyncText();
SyncGrammar();
SyncBufferFormat();
}
- protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
+ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
@@ -172,7 +186,8 @@ void OnCopyToClipboard(object? sender, RoutedEventArgs e)
{
if (!string.IsNullOrEmpty(Buffer))
{
- Application.Current?.Clipboard?.SetTextAsync(Buffer);
+ var clipboard = TopLevel.GetTopLevel(this)?.Clipboard;
+ _ = clipboard?.SetTextAsync(Buffer);
}
}
@@ -180,25 +195,32 @@ void OnLoadFromFile(object? sender, RoutedEventArgs e)
{
Dispatcher.UIThread.InvokeAsync(async () =>
{
- var openFileDialog = new OpenFileDialog();
- openFileDialog.Filters!.AddRange(FileDialogFilters);
+ var filePickerOptions = new FilePickerOpenOptions
+ {
+ FileTypeFilter = FileDialogFilters
+ };
- var fileName = (await openFileDialog.ShowAsync(MainWindow.Instance))?.FirstOrDefault();
- if (!string.IsNullOrEmpty(fileName))
+ var files = await TopLevel.GetTopLevel(this)!.StorageProvider.OpenFilePickerAsync(filePickerOptions);
+ if (files.Count == 0)
{
- try
- {
- Buffer = await File.ReadAllTextAsync(fileName, CancellationToken.None);
- }
- catch (FileNotFoundException)
- {
- // Ignore this case!
- }
- catch (Exception exception)
+ return;
+ }
+
+ try
+ {
+ using (var stream = new StreamReader(await files[0].OpenReadAsync()))
{
- App.ShowException(exception);
+ Buffer = await stream.ReadToEndAsync();
}
}
+ catch (FileNotFoundException)
+ {
+ // Ignore this case!
+ }
+ catch (Exception exception)
+ {
+ App.ShowException(exception);
+ }
});
}
@@ -230,29 +252,47 @@ void OnReformat(object? sender, RoutedEventArgs e)
void OnSaveToFile(object? sender, RoutedEventArgs e)
{
- var saveFileDialog = new SaveFileDialog();
- saveFileDialog.Filters!.AddRange(FileDialogFilters);
-
- // TODO: Not working!
- if (IsJson)
- {
- saveFileDialog.DefaultExtension = ".json";
- }
- else if (IsXml)
- {
- saveFileDialog.DefaultExtension = ".xml";
- }
- else
- {
- saveFileDialog.DefaultExtension = ".txt";
- }
-
Dispatcher.UIThread.InvokeAsync(async () =>
{
- var fileName = await saveFileDialog.ShowAsync(MainWindow.Instance);
- if (!string.IsNullOrEmpty(fileName))
+ try
+ {
+ var filePickerOptions = new FilePickerSaveOptions
+ {
+ FileTypeChoices = FileDialogFilters
+ };
+
+ // TODO: Not working!
+ if (IsJson)
+ {
+ filePickerOptions.DefaultExtension = ".json";
+ }
+ else if (IsXml)
+ {
+ filePickerOptions.DefaultExtension = ".xml";
+ }
+ else
+ {
+ filePickerOptions.DefaultExtension = ".txt";
+ }
+
+ var file = await TopLevel.GetTopLevel(this)!.StorageProvider.SaveFilePickerAsync(filePickerOptions);
+ if (file == null)
+ {
+ return;
+ }
+
+ await using (var stream = new StreamWriter(await file.OpenWriteAsync()))
+ {
+ await stream.WriteAsync(Buffer ?? string.Empty);
+ }
+ }
+ catch (FileNotFoundException)
+ {
+ // Ignore this case!
+ }
+ catch (Exception exception)
{
- await File.WriteAllTextAsync(fileName, Buffer ?? string.Empty, CancellationToken.None);
+ App.ShowException(exception);
}
});
}
diff --git a/Source/Controls/BufferPreview/BufferPreviewView.axaml b/Source/Controls/BufferPreview/BufferPreviewView.axaml
index 395f826..2b7e835 100644
--- a/Source/Controls/BufferPreview/BufferPreviewView.axaml
+++ b/Source/Controls/BufferPreview/BufferPreviewView.axaml
@@ -60,7 +60,7 @@
diff --git a/Source/Controls/BufferPreview/BufferPreviewView.axaml.cs b/Source/Controls/BufferPreview/BufferPreviewView.axaml.cs
index f1e4856..e1b99f7 100644
--- a/Source/Controls/BufferPreview/BufferPreviewView.axaml.cs
+++ b/Source/Controls/BufferPreview/BufferPreviewView.axaml.cs
@@ -6,21 +6,20 @@
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
-using System.Threading;
using System.Xml.Linq;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Interactivity;
+using Avalonia.Platform.Storage;
using Avalonia.Threading;
using AvaloniaEdit;
using AvaloniaEdit.TextMate;
-using AvaloniaEdit.TextMate.Grammars;
using MessagePack;
using mqttMultimeter.Extensions;
-using mqttMultimeter.Main;
using mqttMultimeter.Services.Data;
using mqttMultimeter.Text;
+using TextMateSharp.Grammars;
namespace mqttMultimeter.Controls;
@@ -138,7 +137,7 @@ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
ReadBuffer();
}
- protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
+ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
@@ -162,28 +161,49 @@ void OnCopyToClipboard(object? sender, RoutedEventArgs e)
{
if (!string.IsNullOrEmpty(_content))
{
- Application.Current?.Clipboard?.SetTextAsync(_content);
+ var clipboard = TopLevel.GetTopLevel(this)?.Clipboard;
+ _ = clipboard?.SetTextAsync(_content);
}
}
void OnSaveToFile(object? sender, RoutedEventArgs e)
{
- var saveFileDialog = new SaveFileDialog();
- saveFileDialog.Filters!.Add(new FileDialogFilter
+ Dispatcher.UIThread.InvokeAsync(async () =>
{
- Name = "Binary files",
- Extensions = new List
+ try
{
- "bin"
+ var filePickerOptions = new FilePickerSaveOptions
+ {
+ FileTypeChoices = new List
+ {
+ new("Binary files")
+ {
+ Patterns = new[]
+ {
+ "*.bin"
+ }
+ }
+ }
+ };
+
+ var file = await TopLevel.GetTopLevel(this)!.StorageProvider.SaveFilePickerAsync(filePickerOptions);
+ if (file == null)
+ {
+ return;
+ }
+
+ await using (var stream = await file.OpenWriteAsync())
+ {
+ await stream.WriteAsync(Buffer ?? Array.Empty());
+ }
}
- });
-
- Dispatcher.UIThread.InvokeAsync(async () =>
- {
- var fileName = await saveFileDialog.ShowAsync(MainWindow.Instance);
- if (!string.IsNullOrEmpty(fileName))
+ catch (FileNotFoundException)
+ {
+ // Ignore this case!
+ }
+ catch (Exception exception)
{
- await File.WriteAllBytesAsync(fileName, Buffer ?? Array.Empty(), CancellationToken.None);
+ App.ShowException(exception);
}
});
}
diff --git a/Source/Controls/CertificatePicker/CertificatePicker.axaml.cs b/Source/Controls/CertificatePicker/CertificatePicker.axaml.cs
index f053c05..96fa088 100644
--- a/Source/Controls/CertificatePicker/CertificatePicker.axaml.cs
+++ b/Source/Controls/CertificatePicker/CertificatePicker.axaml.cs
@@ -1,13 +1,11 @@
-using System.Collections.Generic;
-using System.Linq;
-using Avalonia;
+using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Data;
using Avalonia.Interactivity;
+using Avalonia.Platform.Storage;
using Avalonia.Threading;
using mqttMultimeter.Extensions;
-using mqttMultimeter.Main;
namespace mqttMultimeter.Controls;
@@ -39,9 +37,8 @@ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
_pickButton = (Button)this.GetTemplateChild("PART_PickButton");
_pickButton.Click += OnPickButtonClicked;
}
-
-
- protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
+
+ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
@@ -52,31 +49,30 @@ void OnPickButtonClicked(object? sender, RoutedEventArgs e)
{
Dispatcher.UIThread.InvokeAsync(async () =>
{
- var openFileDialog = new OpenFileDialog
+ var filePickerOptions = new FilePickerOpenOptions
{
- Title = "Choose certificate",
- Filters = new List
+ AllowMultiple = false,
+ FileTypeFilter = new[]
{
- new()
+ new FilePickerFileType("Certificates")
{
- Extensions =
+ Patterns = new[]
{
- "pem",
- "crt",
- "pfx"
- },
- Name = "Certificates"
+ "*.pem",
+ "*.crt",
+ "*.pfx"
+ }
}
}
};
-
- var filenames = await openFileDialog.ShowAsync(MainWindow.Instance);
- if (filenames?.Length == 0)
+
+ var files = await TopLevel.GetTopLevel(this)!.StorageProvider.OpenFilePickerAsync(filePickerOptions);
+ if (files.Count == 0)
{
return;
}
- Path = filenames?.FirstOrDefault() ?? string.Empty;
+ Path = files[0].Path.LocalPath;
});
}
}
\ No newline at end of file
diff --git a/Source/Controls/ErrorBox/ErrorBox.axaml b/Source/Controls/ErrorBox/ErrorBox.axaml
index c0e4005..33b1e96 100644
--- a/Source/Controls/ErrorBox/ErrorBox.axaml
+++ b/Source/Controls/ErrorBox/ErrorBox.axaml
@@ -1,15 +1,14 @@
+ x:Class="mqttMultimeter.Controls.ErrorBox">
+
+
+
@@ -28,6 +27,8 @@
MessageProperty = AvaloniaProperty.Register(nameof(Message));
@@ -35,6 +35,6 @@ void OnButtonCloseClicked(object? sender, RoutedEventArgs e)
void OnButtonCopyClicked(object? sender, RoutedEventArgs e)
{
- _ = Application.Current?.Clipboard?.SetTextAsync(Message);
+ //_ = Application.Current?.Clipboard?.SetTextAsync(Message);
}
}
\ No newline at end of file
diff --git a/Source/Controls/HexBox.axaml b/Source/Controls/HexBox.axaml
index 3c4552f..bc07a15 100644
--- a/Source/Controls/HexBox.axaml
+++ b/Source/Controls/HexBox.axaml
@@ -12,12 +12,13 @@
-
+
-
+
+ Foreground="{StaticResource SystemAccentColor}" />
+ Foreground="{StaticResource SystemAccentColor}" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source/Controls/HexBox.axaml.cs b/Source/Controls/HexBox.axaml.cs
index 8c65c65..412d1fe 100644
--- a/Source/Controls/HexBox.axaml.cs
+++ b/Source/Controls/HexBox.axaml.cs
@@ -49,7 +49,7 @@ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
UpdateValues();
}
- protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
+ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
@@ -90,7 +90,7 @@ void Dump()
contentBuilder.Append(byteHex);
- if (@byte > 0x0020 && @byte < 0x007F)
+ if (@byte is > 0x0020 and < 0x007F)
{
previewBuilder.Append((char)@byte);
}
@@ -144,13 +144,15 @@ static string GetBits(byte @byte)
void SetValue(string textBoxName, byte[] buffer, int bufferMinLength, Func valueProvider)
{
var textBox = (TextBox)this.GetTemplateChild(textBoxName);
+
if (buffer.Length < bufferMinLength)
{
textBox.Text = string.Empty;
- return;
}
-
- textBox.Text = valueProvider(buffer);
+ else
+ {
+ textBox.Text = valueProvider(buffer);
+ }
}
void SetValue(string textBoxName, object value)
@@ -161,7 +163,7 @@ void SetValue(string textBoxName, object value)
void UpdateValues()
{
- var lineBreaks = Regex.Matches(_contentTextBox?.Text?.Substring(0, CaretIndex) ?? "", Environment.NewLine).Count;
+ var lineBreaks = Regex.Matches(_contentTextBox?.Text?[..CaretIndex] ?? string.Empty, Environment.NewLine).Count;
var offset = (CaretIndex - lineBreaks) / 3;
var length = Value?.Length ?? 0;
@@ -173,8 +175,10 @@ void UpdateValues()
var buffer = Value?.Skip(offset).ToArray() ?? Array.Empty();
+ SetValue("Length", length.ToString(CultureInfo.InvariantCulture));
SetValue("ValueOffset", offset.ToString(CultureInfo.InvariantCulture));
SetValue("ValueRemaining", remaining.ToString(CultureInfo.InvariantCulture));
+ SetValue("ValueHex", buffer, 1, b => BitConverter.ToString(b, 0, 1));
SetValue("Value8Bit", buffer, 1, b => GetBits(b[0]));
SetValue("ValueBoolean", buffer, 1, b => (b[0] > 0).ToString(CultureInfo.InvariantCulture));
SetValue("ValueInt8", buffer, 1, b => b[0].ToString(CultureInfo.InvariantCulture));
diff --git a/Source/Controls/ProgressIndicator/ProgressIndicatorView.axaml b/Source/Controls/ProgressIndicator/ProgressIndicatorView.axaml
index 954b693..c210031 100644
--- a/Source/Controls/ProgressIndicator/ProgressIndicatorView.axaml
+++ b/Source/Controls/ProgressIndicator/ProgressIndicatorView.axaml
@@ -1,13 +1,13 @@
+
+
+
+
diff --git a/Source/Controls/ProgressIndicator/ProgressIndicatorView.axaml.cs b/Source/Controls/ProgressIndicator/ProgressIndicatorView.axaml.cs
index a64f51c..eac55a0 100644
--- a/Source/Controls/ProgressIndicator/ProgressIndicatorView.axaml.cs
+++ b/Source/Controls/ProgressIndicator/ProgressIndicatorView.axaml.cs
@@ -3,7 +3,7 @@
namespace mqttMultimeter.Controls;
-public class ProgressIndicatorView : UserControl
+public sealed partial class ProgressIndicatorView : UserControl
{
public ProgressIndicatorView()
{
diff --git a/Source/Controls/QualityOfServiceLevel/QualityOfServiceLevelSelectorView.axaml b/Source/Controls/QualityOfServiceLevel/QualityOfServiceLevelSelectorView.axaml
index 44cfcd5..d9f78bc 100644
--- a/Source/Controls/QualityOfServiceLevel/QualityOfServiceLevelSelectorView.axaml
+++ b/Source/Controls/QualityOfServiceLevel/QualityOfServiceLevelSelectorView.axaml
@@ -1,13 +1,13 @@
+
+
+
+
-
+
\ No newline at end of file
diff --git a/Source/Controls/QualityOfServiceLevel/QualityOfServiceLevelSelectorView.axaml.cs b/Source/Controls/QualityOfServiceLevel/QualityOfServiceLevelSelectorView.axaml.cs
index 3e0afcb..4a591a5 100644
--- a/Source/Controls/QualityOfServiceLevel/QualityOfServiceLevelSelectorView.axaml.cs
+++ b/Source/Controls/QualityOfServiceLevel/QualityOfServiceLevelSelectorView.axaml.cs
@@ -3,7 +3,7 @@
namespace mqttMultimeter.Controls;
-public sealed class QualityOfServiceLevelSelectorView : UserControl
+public sealed partial class QualityOfServiceLevelSelectorView : UserControl
{
public QualityOfServiceLevelSelectorView()
{
diff --git a/Source/Controls/RetainHandling/RetainHandlingSelectorView.axaml b/Source/Controls/RetainHandling/RetainHandlingSelectorView.axaml
index 10cab2f..6d5918b 100644
--- a/Source/Controls/RetainHandling/RetainHandlingSelectorView.axaml
+++ b/Source/Controls/RetainHandling/RetainHandlingSelectorView.axaml
@@ -1,13 +1,13 @@
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
@@ -44,7 +31,7 @@
-
+
+
diff --git a/Source/Controls/UserProperties/UserPropertiesView.axaml.cs b/Source/Controls/UserProperties/UserPropertiesView.axaml.cs
index a0e3d76..6d70506 100644
--- a/Source/Controls/UserProperties/UserPropertiesView.axaml.cs
+++ b/Source/Controls/UserProperties/UserPropertiesView.axaml.cs
@@ -3,7 +3,7 @@
namespace mqttMultimeter.Controls;
-public sealed class UserPropertiesView : UserControl
+public sealed partial class UserPropertiesView : UserControl
{
public UserPropertiesView()
{
diff --git a/Source/Extensions/TemplatedControlExtensions.cs b/Source/Extensions/TemplatedControlExtensions.cs
index 761b349..fdc40e1 100644
--- a/Source/Extensions/TemplatedControlExtensions.cs
+++ b/Source/Extensions/TemplatedControlExtensions.cs
@@ -10,7 +10,7 @@ namespace mqttMultimeter.Extensions;
public static class TemplatedControlExtensions
{
- public static StyledElement? FindVisualChild(this IVisual visual, string name)
+ public static StyledElement? FindVisualChild(this Visual visual, string name)
{
if (visual == null)
{
@@ -39,7 +39,7 @@ public static class TemplatedControlExtensions
return null;
}
- public static IControl GetTemplateChild(this TemplatedControl templatedControl, string name)
+ public static Control GetTemplateChild(this TemplatedControl templatedControl, string name)
{
if (templatedControl == null)
{
diff --git a/Source/Main/MainView.axaml b/Source/Main/MainView.axaml
index 4eeee3d..807a454 100644
--- a/Source/Main/MainView.axaml
+++ b/Source/Main/MainView.axaml
@@ -1,14 +1,14 @@
+ Design.Height="450"
+ Design.Width="800">
+
+
+
+
+
+
-
@@ -25,7 +30,7 @@
Orientation="Horizontal">
@@ -35,7 +40,7 @@
@@ -54,7 +59,7 @@
Content="MQTT protocol version" />
@@ -70,7 +75,7 @@
Content="{Binding ServerOptions.SelectedTransport.HostDisplayValue}" />
+ Classes="value code_text" />
-
@@ -152,8 +157,7 @@
-
+
diff --git a/Source/Pages/Connection/ConnectionOptionsView.axaml.cs b/Source/Pages/Connection/ConnectionOptionsView.axaml.cs
index e8bd0e6..849542f 100644
--- a/Source/Pages/Connection/ConnectionOptionsView.axaml.cs
+++ b/Source/Pages/Connection/ConnectionOptionsView.axaml.cs
@@ -3,7 +3,7 @@
namespace mqttMultimeter.Pages.Connection;
-public class ConnectionOptionsView : UserControl
+public sealed partial class ConnectionOptionsView : UserControl
{
public ConnectionOptionsView()
{
diff --git a/Source/Pages/Connection/ConnectionPageView.axaml b/Source/Pages/Connection/ConnectionPageView.axaml
index ba6a4be..65f4ba5 100644
--- a/Source/Pages/Connection/ConnectionPageView.axaml
+++ b/Source/Pages/Connection/ConnectionPageView.axaml
@@ -1,14 +1,13 @@
+
+
+
@@ -23,7 +22,8 @@
-
+
diff --git a/Source/Pages/Connection/ConnectionPageView.axaml.cs b/Source/Pages/Connection/ConnectionPageView.axaml.cs
index 003cd01..c744f89 100644
--- a/Source/Pages/Connection/ConnectionPageView.axaml.cs
+++ b/Source/Pages/Connection/ConnectionPageView.axaml.cs
@@ -3,7 +3,7 @@
namespace mqttMultimeter.Pages.Connection;
-public sealed class ConnectionPageView : UserControl
+public sealed partial class ConnectionPageView : UserControl
{
public ConnectionPageView()
{
diff --git a/Source/Pages/Inflight/InflightPageItemView.axaml b/Source/Pages/Inflight/InflightPageItemView.axaml
index 144ca8c..48fea49 100644
--- a/Source/Pages/Inflight/InflightPageItemView.axaml
+++ b/Source/Pages/Inflight/InflightPageItemView.axaml
@@ -1,15 +1,15 @@
+
+
+
+
diff --git a/Source/Pages/Inflight/InflightPageItemView.axaml.cs b/Source/Pages/Inflight/InflightPageItemView.axaml.cs
index 8cd57e0..87104a0 100644
--- a/Source/Pages/Inflight/InflightPageItemView.axaml.cs
+++ b/Source/Pages/Inflight/InflightPageItemView.axaml.cs
@@ -3,7 +3,7 @@
namespace mqttMultimeter.Pages.Inflight;
-public sealed class InflightPageItemView : UserControl
+public sealed partial class InflightPageItemView : UserControl
{
public InflightPageItemView()
{
diff --git a/Source/Pages/Inflight/InflightPageView.axaml b/Source/Pages/Inflight/InflightPageView.axaml
index 074d865..3bd7f1a 100644
--- a/Source/Pages/Inflight/InflightPageView.axaml
+++ b/Source/Pages/Inflight/InflightPageView.axaml
@@ -1,14 +1,13 @@
+
+
+
@@ -38,13 +37,13 @@
@@ -64,11 +63,10 @@
+ ItemsSource="{Binding Items}">
@@ -82,7 +80,6 @@
@@ -95,7 +92,6 @@
@@ -113,7 +109,6 @@
@@ -128,7 +123,8 @@
-
+
ExportDialogFilter = new()
+ {
+ new FilePickerFileType("MQTT Inflight item exports")
+ {
+ Patterns = new[]
+ {
+ "*.mqtt_inflight"
+ }
+ }
+ };
+
public InflightPageView()
{
InitializeComponent();
@@ -14,4 +33,67 @@ void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
+
+ void OnExportItems(object? _, RoutedEventArgs __)
+ {
+ Dispatcher.UIThread.InvokeAsync(async () =>
+ {
+ try
+ {
+ var filePickerOptions = new FilePickerSaveOptions
+ {
+ Title = ExportDialogTitle,
+ FileTypeChoices = ExportDialogFilter
+ };
+
+ var file = await TopLevel.GetTopLevel(this)!.StorageProvider.SaveFilePickerAsync(filePickerOptions);
+ if (file == null)
+ {
+ return;
+ }
+
+ await ((InflightPageViewModel)DataContext!).ExportItems(file.Path.LocalPath);
+ }
+ catch (FileNotFoundException)
+ {
+ // Ignore this case!
+ }
+ catch (Exception exception)
+ {
+ App.ShowException(exception);
+ }
+ });
+ }
+
+ void OnImportItems(object? _, RoutedEventArgs __)
+ {
+ Dispatcher.UIThread.InvokeAsync(async () =>
+ {
+ try
+ {
+ var filePickerOptions = new FilePickerOpenOptions
+ {
+ AllowMultiple = false,
+ Title = ExportDialogTitle,
+ FileTypeFilter = ExportDialogFilter
+ };
+
+ var files = await TopLevel.GetTopLevel(this)!.StorageProvider.OpenFilePickerAsync(filePickerOptions);
+ if (files.Count == 0)
+ {
+ return;
+ }
+
+ await ((InflightPageViewModel)DataContext!).ImportItems(files[0].Path.LocalPath);
+ }
+ catch (FileNotFoundException)
+ {
+ // Ignore this case!
+ }
+ catch (Exception exception)
+ {
+ App.ShowException(exception);
+ }
+ });
+ }
}
\ No newline at end of file
diff --git a/Source/Pages/Inflight/InflightPageViewModel.cs b/Source/Pages/Inflight/InflightPageViewModel.cs
index aa93776..8267979 100644
--- a/Source/Pages/Inflight/InflightPageViewModel.cs
+++ b/Source/Pages/Inflight/InflightPageViewModel.cs
@@ -1,17 +1,13 @@
using System;
-using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
-using System.Linq;
using System.Reactive.Linq;
using System.Threading;
using System.Threading.Tasks;
-using Avalonia.Controls;
using Avalonia.Threading;
using DynamicData;
using mqttMultimeter.Common;
using mqttMultimeter.Controls;
-using mqttMultimeter.Main;
using mqttMultimeter.Pages.Inflight.Export;
using mqttMultimeter.Services.Mqtt;
using MQTTnet;
@@ -22,17 +18,6 @@ namespace mqttMultimeter.Pages.Inflight;
public sealed class InflightPageViewModel : BasePageViewModel
{
- const string ExportDialogTitle = "Export Inflight items";
-
- static readonly FileDialogFilter ExportDialogFilter = new()
- {
- Name = "MQTT Inflight item exports",
- Extensions = new List
- {
- "mqtt_inflight"
- }
- };
-
readonly InflightPageItemExportService _exportService;
readonly ReadOnlyObservableCollection _items;
readonly SourceList _itemsSource = new();
@@ -91,15 +76,16 @@ public Task AppendMessage(MqttApplicationMessage message)
var newItem = CreateItemViewModel(message);
return Dispatcher.UIThread.InvokeAsync(() =>
- {
- _itemsSource.Add(newItem);
-
- // TODO: Move to configuration.
- if (_itemsSource.Count > 1000)
{
- _itemsSource.RemoveAt(0);
- }
- });
+ _itemsSource.Add(newItem);
+
+ // TODO: Move to configuration.
+ if (_itemsSource.Count > 1000)
+ {
+ _itemsSource.RemoveAt(0);
+ }
+ })
+ .GetTask();
}
public void ClearItems()
@@ -107,45 +93,19 @@ public void ClearItems()
_itemsSource.Clear();
}
- public async Task ExportItems()
+ public Task ExportItems(string path)
{
- var saveFileDialog = new SaveFileDialog
- {
- Title = ExportDialogTitle
- };
-
- saveFileDialog.Filters?.Add(ExportDialogFilter);
-
- var fileName = await saveFileDialog.ShowAsync(MainWindow.Instance);
- if (string.IsNullOrEmpty(fileName))
- {
- return;
- }
-
- await _exportService.Export(this, fileName);
+ return _exportService.Export(this, path);
}
- public async Task ImportItems()
+ public Task ImportItems(string path)
{
- var openFileDialog = new OpenFileDialog
- {
- Title = ExportDialogTitle
- };
-
- openFileDialog.Filters?.Add(ExportDialogFilter);
-
- var fileName = (await openFileDialog.ShowAsync(MainWindow.Instance))?.FirstOrDefault();
- if (string.IsNullOrEmpty(fileName))
- {
- return;
- }
-
- if (!File.Exists(fileName))
+ if (!File.Exists(path))
{
- return;
+ return Task.CompletedTask;
}
- await _exportService.Import(this, fileName);
+ return _exportService.Import(this, path);
}
Func BuildFilter(string? searchText)
diff --git a/Source/Pages/Info/InfoPageView.axaml b/Source/Pages/Info/InfoPageView.axaml
index bca9141..87e57c3 100644
--- a/Source/Pages/Info/InfoPageView.axaml
+++ b/Source/Pages/Info/InfoPageView.axaml
@@ -1,20 +1,24 @@
+
+
+
+
-
+
+
-
-
@@ -100,51 +104,51 @@
ColumnDefinitions="Auto,Auto,Auto"
RowDefinitions="Auto,Auto,Auto,Auto">
-
-
+
-
-
+
-
-
+
-
-
+
-
-
@@ -153,7 +157,7 @@
+ Content="Used libraries" />
diff --git a/Source/Pages/Info/InfoPageView.axaml.cs b/Source/Pages/Info/InfoPageView.axaml.cs
index 08cdbf9..4fba280 100644
--- a/Source/Pages/Info/InfoPageView.axaml.cs
+++ b/Source/Pages/Info/InfoPageView.axaml.cs
@@ -8,7 +8,7 @@
namespace mqttMultimeter.Pages.Info;
-public sealed class InfoPageView : UserControl
+public sealed partial class InfoPageView : UserControl
{
public InfoPageView()
{
@@ -19,7 +19,7 @@ void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
- var licenses = this.FindControl("Licenses");
+ var licenses = this.FindControl("Licenses")!;
licenses.Text = ReadEmbeddedMarkdown();
}
diff --git a/Source/Pages/Log/LogPageView.axaml b/Source/Pages/Log/LogPageView.axaml
index d29d501..ff67564 100644
--- a/Source/Pages/Log/LogPageView.axaml
+++ b/Source/Pages/Log/LogPageView.axaml
@@ -1,13 +1,13 @@
+
+
+
+
@@ -32,7 +32,7 @@
+ ItemsSource="{Binding Items}">
@@ -124,7 +122,7 @@
@@ -136,7 +134,7 @@
-
+
diff --git a/Source/Pages/TopicExplorer/TopicExplorerPageView.axaml.cs b/Source/Pages/TopicExplorer/TopicExplorerPageView.axaml.cs
index e24309d..5df6e00 100644
--- a/Source/Pages/TopicExplorer/TopicExplorerPageView.axaml.cs
+++ b/Source/Pages/TopicExplorer/TopicExplorerPageView.axaml.cs
@@ -3,7 +3,7 @@
namespace mqttMultimeter.Pages.TopicExplorer;
-public class TopicExplorerPageView : UserControl
+public sealed partial class TopicExplorerPageView : UserControl
{
public TopicExplorerPageView()
{
diff --git a/Source/Pages/TopicExplorer/TopicExplorerPageViewModel.cs b/Source/Pages/TopicExplorer/TopicExplorerPageViewModel.cs
index 8f79e64..c68103d 100644
--- a/Source/Pages/TopicExplorer/TopicExplorerPageViewModel.cs
+++ b/Source/Pages/TopicExplorer/TopicExplorerPageViewModel.cs
@@ -181,7 +181,7 @@ Task OnMqttMessageReceived(MqttApplicationMessageReceivedEventArgs arguments)
var topic = arguments.ApplicationMessage.Topic;
var path = topic.Split("/");
- return Dispatcher.UIThread.InvokeAsync(() => InsertNode(path, arguments.ApplicationMessage));
+ return Dispatcher.UIThread.InvokeAsync(() => InsertNode(path, arguments.ApplicationMessage)).GetTask();
}
static void SetExpandedState(TopicExplorerTreeNodeViewModel node, bool value)
diff --git a/Source/Pages/TopicExplorer/TopicExplorerTreeNodeView.axaml b/Source/Pages/TopicExplorer/TopicExplorerTreeNodeView.axaml
index 3d0d15c..c907891 100644
--- a/Source/Pages/TopicExplorer/TopicExplorerTreeNodeView.axaml
+++ b/Source/Pages/TopicExplorer/TopicExplorerTreeNodeView.axaml
@@ -1,13 +1,12 @@
+
+
+
-
+
();
-
if (control == null)
{
break;
}
}
-
if (control != null)
{
var viewModel = (TopicExplorerTreeNodeViewModel)control.DataContext!;
diff --git a/Source/Services/Mqtt/MqttClientService.cs b/Source/Services/Mqtt/MqttClientService.cs
index cfdd813..8d1bcec 100644
--- a/Source/Services/Mqtt/MqttClientService.cs
+++ b/Source/Services/Mqtt/MqttClientService.cs
@@ -7,7 +7,6 @@
using System.Text;
using System.Threading;
using System.Threading.Tasks;
-using Avalonia.Controls;
using Avalonia.Threading;
using mqttMultimeter.Controls;
using mqttMultimeter.Pages.Connection;
@@ -69,7 +68,7 @@ public async Task Connect(ConnectionItemViewModel item)
.WithRequestProblemInformation(item.SessionOptions.RequestProblemInformation)
.WithRequestResponseInformation(item.SessionOptions.RequestResponseInformation)
.WithKeepAlivePeriod(TimeSpan.FromSeconds(item.SessionOptions.KeepAliveInterval))
- .WithoutPacketFragmentation(); // There is no need for performance optimization in this MQTT debugging app.
+ .WithoutPacketFragmentation(); // We do not need this optimization is this type of client. It will also increase compatibility.
if (item.SessionOptions.SessionExpiryInterval > 0)
{
@@ -92,12 +91,12 @@ public async Task Connect(ConnectionItemViewModel item)
if (item.ServerOptions.SelectedTlsVersion.Value != SslProtocols.None)
{
- clientOptionsBuilder.WithTls(o =>
+ clientOptionsBuilder.WithTlsOptions(o =>
{
- o.SslProtocol = item.ServerOptions.SelectedTlsVersion.Value;
- o.IgnoreCertificateChainErrors = item.ServerOptions.IgnoreCertificateErrors;
- o.IgnoreCertificateRevocationErrors = item.ServerOptions.IgnoreCertificateErrors;
- o.CertificateValidationHandler = item.ServerOptions.IgnoreCertificateErrors ? _ => true : null;
+ o.WithSslProtocols(item.ServerOptions.SelectedTlsVersion.Value);
+ o.WithIgnoreCertificateChainErrors(item.ServerOptions.IgnoreCertificateErrors);
+ o.WithIgnoreCertificateRevocationErrors(item.ServerOptions.IgnoreCertificateErrors);
+ o.WithCertificateValidationHandler(item.ServerOptions.IgnoreCertificateErrors ? _ => true : null);
if (!string.IsNullOrEmpty(item.SessionOptions.CertificatePath))
{
@@ -112,12 +111,8 @@ public async Task Connect(ConnectionItemViewModel item)
certificates.Add(new X509Certificate2(item.SessionOptions.CertificatePath, item.SessionOptions.CertificatePassword));
}
- o.Certificates = certificates;
- o.ApplicationProtocols = new List
- {
- // TODO: Consider exposing this in the UI.
- new("mqtt")
- };
+ o.WithClientCertificates(certificates);
+ o.WithApplicationProtocols([new SslApplicationProtocol("mqtt")]);
}
});
}
diff --git a/Source/Services/State/StateService.cs b/Source/Services/State/StateService.cs
index 8d2aa68..ede0c17 100644
--- a/Source/Services/State/StateService.cs
+++ b/Source/Services/State/StateService.cs
@@ -58,7 +58,6 @@ public bool TryGet(string key, out TData? data)
}
catch (Exception exception)
{
- // TODO: Use proper logging framework.
Debug.WriteLine(exception);
}
@@ -84,7 +83,7 @@ public async Task Write()
static string GeneratePath()
{
var path = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
-
+
// We use ".MQTTnetApp" instead of ".mqttMultimeter" because the app name was changed
// and the state should be still working when starting the app with the new name!
path = Path.Combine(path, ".MQTTnetApp", "State");
diff --git a/Source/Styles/Badges.axaml b/Source/Styles/Badges.axaml
index 23383db..e51296f 100644
--- a/Source/Styles/Badges.axaml
+++ b/Source/Styles/Badges.axaml
@@ -19,7 +19,7 @@
+ Value="{StaticResource MonospaceFontFamily}" />
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/Styles/Sidebar.axaml b/Source/Styles/Sidebar.axaml
index 4dd9160..8b92392 100644
--- a/Source/Styles/Sidebar.axaml
+++ b/Source/Styles/Sidebar.axaml
@@ -16,10 +16,7 @@
RowDefinitions="*">
-
+
+ Value="{StaticResource MonospaceFontFamily}" />
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/Styles/ToolBar.axaml b/Source/Styles/ToolBar.axaml
index 894a084..92a20dd 100644
--- a/Source/Styles/ToolBar.axaml
+++ b/Source/Styles/ToolBar.axaml
@@ -102,6 +102,7 @@