diff --git a/src/LacmusApp.csproj b/src/LacmusApp.csproj index 46cf50c..27395a5 100644 --- a/src/LacmusApp.csproj +++ b/src/LacmusApp.csproj @@ -3,8 +3,8 @@ Exe netcoreapp3.1 Lacmus Foundation - 0.4.2.0 - 0.4.2.0 + 0.4.3.0 + 0.4.3.0 @@ -14,26 +14,29 @@ Designer + + Designer + - + - + - - - + + + - + - - + + - - - + + + diff --git a/src/Services/LocalizationContext.cs b/src/Services/LocalizationContext.cs index 34a1169..dd4de5f 100644 --- a/src/Services/LocalizationContext.cs +++ b/src/Services/LocalizationContext.cs @@ -63,6 +63,12 @@ [Reactive] public string ModelManager get { return _modelManager; } set { this.RaiseAndSetIfChanged(ref _modelManager, value); } } + private string _bugReport; + [Reactive] public string BugReport + { + get { return _bugReport; } + set { this.RaiseAndSetIfChanged(ref _bugReport, value); } + } private string _image; [Reactive] public string Image { @@ -807,6 +813,29 @@ [Reactive] public string SettingsBatchSize #endregion + #region BUG REPORT WINDOW + + private string _labelingWindowCapture; + [Reactive] public string LabelingWindowCapture + { + get { return _labelingWindowCapture; } + set { this.RaiseAndSetIfChanged(ref _labelingWindowCapture, value); } + } + private string _labelingWindowFalsePositive; + [Reactive] public string LabelingWindowFalsePositive + { + get { return _labelingWindowFalsePositive; } + set { this.RaiseAndSetIfChanged(ref _labelingWindowFalsePositive, value); } + } + private string _labelingWindowFalseNegative; + [Reactive] public string LabelingWindowFalseNegative + { + get { return _labelingWindowFalseNegative; } + set { this.RaiseAndSetIfChanged(ref _labelingWindowFalseNegative, value); } + } + + #endregion + public LocalizationContext() { this.WhenAnyValue(vm=>vm.Language).Subscribe(_=>UpdateText()); @@ -836,6 +865,7 @@ private void UpdateText() LoadModel="Load model"; UpdateModel="Update model"; ModelManager="Model manager..."; + BugReport = "Send bug report..."; //Image Image="Image"; PredictAll="Predict All"; @@ -969,6 +999,11 @@ private void UpdateText() //ModelManagerApplyButton = "Apply"; //ModelManagerCloseButton = "Close"; + //BugReportWindow + LabelingWindowCapture = "By submitting reports on neural network errors, you improve our recognition algorithm. Thank you for helping us develop!\n\nPlease select an error type:"; + LabelingWindowFalsePositive = "No person found in the photo (False Negative)."; + LabelingWindowFalseNegative = "An object was found in the photo but it is not a person (False Positive)."; + OsErrorMesageGPU = "Your OS is not support this ml model type."; break; } @@ -990,6 +1025,7 @@ private void UpdateText() LoadModel="Загрузить"; UpdateModel="Обновить"; ModelManager="Менеджер моделей..."; + BugReport = "Сообщить об ошибке..."; //Image Image="Изображение"; PredictAll="Обработать все"; @@ -1109,6 +1145,11 @@ private void UpdateText() SettingsPort = "Порт:"; SettingsJWT = "Внешнее использование (включить JVT шифрование)"; SettingsBatchSize = "Число потоков"; + + //BugReportWindow + LabelingWindowCapture = "Отправляя нам отчеты об ошибках в работе нейронной сети, вы обучаете и улучшаете наш алгоритм распознования! Спасибо что используете Lacmus и помогаете нам развиваться!\n\nПожалуйста выбирете тип ошибки:"; + LabelingWindowFalsePositive = "На фото не найден человек (False Negative)."; + LabelingWindowFalseNegative = "На фото обнаружен объект, но это не человек (False Positive)."; //Erroes OsErrorMesageGPU = "Ваша операционная система не поддерживает этот тип ml моделей."; diff --git a/src/ViewModels/BugReportViewModel.cs b/src/ViewModels/BugReportViewModel.cs new file mode 100644 index 0000000..287edf0 --- /dev/null +++ b/src/ViewModels/BugReportViewModel.cs @@ -0,0 +1,62 @@ +using System; +using System.Diagnostics; +using System.Reactive; +using System.Runtime.InteropServices; +using Avalonia.Controls; +using LacmusApp.Services; +using ReactiveUI; +using ReactiveUI.Fody.Helpers; +using Serilog; + +namespace LacmusApp.ViewModels +{ + public class BugReportViewModel : ReactiveObject + { + public BugReportViewModel(Window window, LocalizationContext localizationContext) + { + LocalizationContext = localizationContext; + OpenFalseNegativeCommand = ReactiveCommand.Create(OpenFalseNegative); + OpenFalsePositiveCommand = ReactiveCommand.Create(OpenFalsePositive); + } + [Reactive] public LocalizationContext LocalizationContext { get; set; } + public ReactiveCommand OpenFalseNegativeCommand { get; set; } + public ReactiveCommand OpenFalsePositiveCommand { get; set; } + + public void OpenFalseNegative() + { + OpenUrl("https://forms.gle/QbJaqcYvozC1dqTg7"); + } + public void OpenFalsePositive() + { + OpenUrl("https://forms.gle/FAGyGsSiFooVt5L89"); + } + private void OpenUrl(string url) + { + try + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + //https://stackoverflow.com/a/2796367/241446 + using (Process proc = new Process {StartInfo = {UseShellExecute = true, FileName = url}}) + { + proc.Start(); + } + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + Process.Start("x-www-browser", url); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + Process.Start("open", url); + } + else + throw new Exception(); + } + catch (Exception e) + { + Log.Error(e,$"Unable to ope url {url}."); + } + } + } +} \ No newline at end of file diff --git a/src/ViewModels/MainWindowViewModel.cs b/src/ViewModels/MainWindowViewModel.cs index 0921849..31b01d5 100644 --- a/src/ViewModels/MainWindowViewModel.cs +++ b/src/ViewModels/MainWindowViewModel.cs @@ -130,6 +130,7 @@ private void SetupCommand(IObservable canExecute, IObservable canSwi LoadModelCommand = ReactiveCommand.Create(LoadModel, canExecute); UpdateModelCommand = ReactiveCommand.Create(UpdateModel, canExecute); OpenModelManagerCommand = ReactiveCommand.Create(OpenModelManager, canExecute); + OpenBugReportCommand = ReactiveCommand.Create(OpenBugReport, canExecute); NextPageCommand = ReactiveCommand.Create(ShowNextPage); PreviousPageCommand = ReactiveCommand.Create(ShowPreviousPage); @@ -184,6 +185,7 @@ [Reactive] public int TotalPages public ReactiveCommand LoadModelCommand { get; set; } public ReactiveCommand UpdateModelCommand { get; set; } public ReactiveCommand OpenModelManagerCommand { get; set; } + public ReactiveCommand OpenBugReportCommand { get; set; } public ReactiveCommand SaveAsCommand { get; set; } public ReactiveCommand FirstPageCommand { get; set; } public ReactiveCommand PreviousPageCommand { get; set; } @@ -336,6 +338,14 @@ public async void OpenModelManager() _appConfig = await window.ShowResult(); } + public async void OpenBugReport() + { + BugReportWindow window = new BugReportWindow(_themeManager); + var context = new BugReportViewModel(window, LocalizationContext); + window.DataContext = context; + window.Show(); + } + /// /// /// @@ -568,7 +578,10 @@ private void OpenUrl(string url) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - Process.Start("cmd", $"/C start {url}"); + using (Process proc = new Process {StartInfo = {UseShellExecute = true, FileName = url}}) + { + proc.Start(); + } } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { diff --git a/src/ViewModels/MetadataViewModel.cs b/src/ViewModels/MetadataViewModel.cs index 360e0af..86cd2ac 100644 --- a/src/ViewModels/MetadataViewModel.cs +++ b/src/ViewModels/MetadataViewModel.cs @@ -116,7 +116,10 @@ private void OpenUrl(string url) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - Process.Start("cmd", $"/C start {url}"); + using (Process proc = new Process {StartInfo = {UseShellExecute = true, FileName = url}}) + { + proc.Start(); + } } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { diff --git a/src/ViewModels/SettingsWindowViewModel.cs b/src/ViewModels/SettingsWindowViewModel.cs index 1aeffc8..e3f5b0e 100644 --- a/src/ViewModels/SettingsWindowViewModel.cs +++ b/src/ViewModels/SettingsWindowViewModel.cs @@ -48,6 +48,7 @@ public SettingsWindowViewModel(SettingsWindow window, LocalizationContext contex _config = config; _newConfig = AppConfig.DeepCopy(_config); _applicationStatusManager = manager; + InitView(); this.WhenAnyValue(x => x.ThemeIndex) .Skip(1) @@ -80,6 +81,38 @@ private void SetupCommands() UpdateModelStatusCommand = ReactiveCommand.Create(UpdateModelStatus); OpenModelMnagerCommand = ReactiveCommand.Create(OpenModelManager); } + + private void InitView() + { + switch (LocalizationContext.Language) + { + case Language.English: + LanguageIndex = 0; + break; + case Language.Russian: + LanguageIndex = 1; + break; + } + + switch (_settingsThemeManager.CurrentTheme) + { + case ThemeManager.Theme.Citrus: + ThemeIndex = 0; + break; + case ThemeManager.Theme.Rust: + ThemeIndex = 1; + break; + case ThemeManager.Theme.Sea: + ThemeIndex = 2; + break; + case ThemeManager.Theme.Candy: + ThemeIndex = 3; + break; + case ThemeManager.Theme.Magma: + ThemeIndex = 4; + break; + } + } private async void Apply() { diff --git a/src/Views/BugReportWindow.xaml b/src/Views/BugReportWindow.xaml new file mode 100644 index 0000000..a5a83d7 --- /dev/null +++ b/src/Views/BugReportWindow.xaml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + +