From 08329dd5b707ff583606af0ec369814dae284de7 Mon Sep 17 00:00:00 2001 From: Edi61 <84682915+Edi61@users.noreply.github.com> Date: Fri, 17 Feb 2023 19:04:48 +0100 Subject: [PATCH 1/2] Merge 0.0.3 from WPF branch --- .../AntiDuplWPF/AntiDuplWPF.csproj | 240 ++- src/AntiDuplWPF/AntiDuplWPF/App.xaml | 9 +- src/AntiDuplWPF/AntiDuplWPF/App.xaml.cs | 30 +- .../AllowableCharactersTextBoxBehavior.cs | 114 ++ ...textMenuItemSourceBindingOnOpenBehavior.cs | 122 +- .../DataGridScrollIntoViewBehavior.cs | 53 + .../Behavior/FrameworkElementDropBehavior.cs | 2 +- .../Behavior/ImagePropertyBehavior.cs | 3 +- .../Behavior/MenuItemButtonGroupBehavior.cs | 118 ++ .../Behavior/MouseEnterBehaviour.cs | 71 + .../Behavior/WindowCloseOnEscBehavior.cs | 44 + .../Command/CalculateHistogramPeaksCommand.cs | 182 +++ .../Command/ConvertToDuplPairCommand.cs | 81 + .../Command/ConvertToGroupCommand.cs | 79 + .../AntiDuplWPF/Command/SearchDllCommand.cs | 44 +- .../AntiDuplWPF/Control/BrushExtender.cs | 119 ++ .../Control/ComplexProgressBar.xaml | 19 +- .../Control/ComplexProgressBar.xaml.cs | 28 +- .../AntiDuplWPF/Control/ImageInfoControl.xaml | 180 +++ .../Control/ImageInfoControl.xaml.cs | 153 ++ .../AntiDuplWPF/Control/RenameImageTextBox.cs | 1 - .../AntiDuplWPF/Control/SearchControl.cs | 122 ++ .../Control/SearchControlTheme.xaml | 70 + .../ColorToSolidColorBrushConverter.cs | 30 + .../DeleteBackgroundValueConverter.cs | 42 + .../Convertor/DifferenceValueConverter.cs | 31 + .../DuplResultMultiValueConverter.cs | 23 +- .../ImageBackgroundMultiValueConverter.cs | 77 + .../ListToBackgroundMultiValueConverter.cs | 80 +- .../AntiDuplWPF/Convertor/MaxProperty.cs | 5 +- .../Convertor/StringToVisibilityConverter.cs | 29 + .../ViewModeToVisibilityConverter.cs | 32 + .../AntiDuplWPF/Core/AdvancedOption.cs | 125 ++ .../AntiDuplWPF/Core/CompareOption.cs | 42 +- src/AntiDuplWPF/AntiDuplWPF/Core/CoreDll.cs | 119 +- src/AntiDuplWPF/AntiDuplWPF/Core/CoreLib.cs | 60 +- .../AntiDuplWPF/Core/DefectOption.cs | 114 ++ src/AntiDuplWPF/AntiDuplWPF/Core/ICoreLib.cs | 23 + src/AntiDuplWPF/AntiDuplWPF/Core/Location.cs | 2 +- .../AntiDuplWPF/Core/SearchOption.cs | 4 +- .../Helper/DataGridColumnChooserHelper.cs | 152 ++ .../AntiDuplWPF/Helper/DiffrenceHelper.cs | 41 + .../AntiDuplWPF/Helper/DirectoryHelper.cs | 23 + .../AntiDuplWPF/Helper/GroupHelper.cs | 12 +- .../AntiDuplWPF/Helper/PercentHelper.cs | 36 + .../AntiDuplWPF/Helper/SaatiHelper.cs | 127 +- .../AntiDuplWPF/Model/ConfigurationModel.cs | 40 +- .../AntiDuplWPF/Model/IConfigurationModel.cs | 4 + .../AntiDuplWPF/Model/IViewModeModel.cs | 15 + .../AntiDuplWPF/Model/LocationsModel.cs | 21 +- src/AntiDuplWPF/AntiDuplWPF/Model/Option.cs | 26 +- .../AntiDuplWPF/Model/ViewModeModel.cs | 24 + .../ObjectModel/ActionCondition.cs | 13 + .../ActionGenerator/AllBestGenerator.cs | 62 + .../BlockinesBluringGenerator.cs | 65 + .../ConfigurableActionGenerator.cs | 295 ++++ .../FileSizePeakBluringGenerator.cs | 71 + .../ActionGenerator/FileSizePeakGenerator.cs | 66 + .../LittleDifferenceGenerator.cs | 74 + .../LittleDifferenceGenerator2.cs | 75 + .../ObjectModel/ActionOnDuplPair.cs | 14 + .../ByImageProperty/BestConditionParametr.cs | 22 + ...ConditionOfSelectingBestImageByProperty.cs | 111 ++ .../SelectingBestImageByProperty.cs | 48 + .../ByPath/BestImageShouldBeInDirectory.cs | 28 + .../BestImageShouldHaveASmallerNumber.cs | 58 + .../ByPath/IBestSelectingByPath.cs | 17 + .../ConditionMode/EqualConditionMode.cs | 43 + .../ConditionMode/IConditionMode.cs | 16 + .../ConditionMode/LessConditionMode.cs | 43 + .../ConditionMode/MoreConditionMode.cs | 43 + .../ConfigurableAction/DeleteBadAction.cs | 44 + .../ConfigurableAction/DeleteOtherAction.cs | 70 + .../ConfigurableAction/IConfigurableAction.cs | 19 + .../ReplaceAndDeleteAction.cs | 86 + .../ReplaceBadImageAction.cs | 30 + .../ConfigurableAction/SkipAction.cs | 45 + .../AntiDuplWPF/ObjectModel/CriterionType.cs | 4 +- .../AnywhereDirectoryFilter.cs | 26 + .../DirectoryFilter/IDirectoryFilter.cs | 17 + .../OneImageInDir1OtherInDir2.cs | 27 + .../DirectoryFilter/SameDirectory.cs | 35 + .../AntiDuplWPF/ObjectModel/DuplicateGroup.cs | 4 + .../AntiDuplWPF/ObjectModel/EqualAction.cs | 15 + .../ObjectModel/FilterCondition.cs | 216 +++ .../ObjectModel/FilterConditionParametr.cs | 34 + .../GettingNumber/IGettingNumber.cs | 19 + .../NumberBeforeUnderlineGettingNumber.cs | 48 + .../AntiDuplWPF/ObjectModel/ImageInfoClass.cs | 126 +- .../AntiDuplWPF/ObjectModel/ViewMode.cs | 14 + .../AntiDuplWPF/Properties/AssemblyInfo.cs | 6 +- .../Properties/Resources.Designer.cs | 81 +- .../Properties/Settings.Designer.cs | 30 +- .../AntiDuplWPF/Resources/lang.ru-RU.xaml | 25 +- .../AntiDuplWPF/Resources/lang.xaml | 25 +- .../AntiDuplWPF/Service/IImageLoader.cs | 15 + .../AntiDuplWPF/Service/IThumbnailProvider.cs | 13 + .../AntiDuplWPF/Service/ImageLoader.cs | 241 +++ .../AntiDuplWPF/Service/LanguageService.cs | 4 +- .../AntiDuplWPF/Service/ThumbnailCache.cs | 6 +- .../AntiDuplWPF/Service/ThumbnailProvider.cs | 93 +- .../AntiDuplWPF/Style/Default.xaml | 41 + .../UndoRedo/AutoDeleteMultiPairCommand.cs | 1 + .../UndoRedo/DeleteCurrentImageCommand.cs | 87 + .../UndoRedo/DeleteImageCommand.cs | 67 + .../UndoRedo/DeleteMultiCommand.cs | 61 + .../UndoRedo/DeleteOtherCommand.cs | 64 + .../UndoRedo/DeleteOtherFromGroupCommand.cs | 12 - .../AntiDuplWPF/UndoRedo/IgnorePairCommand.cs | 16 +- .../AntiDuplWPF/UndoRedo/RenamedImage.cs | 21 + .../AntiDuplWPF/UndoRedo/Replace2Command.cs | 59 + .../AntiDuplWPF/UndoRedo/ReplaceCommand.cs | 102 ++ .../AntiDuplWPF/View/ColorWindow.xaml | 48 + .../AntiDuplWPF/View/ColorWindow.xaml.cs | 27 + .../AntiDuplWPF/View/ComparatorWindow.xaml | 56 +- .../View/ConfigurableActionWindow.xaml | 602 +++++++ .../View/ConfigurableActionWindow.xaml.cs | 27 + .../AntiDuplWPF/View/ConfigurationWindow.xaml | 301 +++- .../View/ConfigurationWindow.xaml.cs | 23 +- .../AntiDuplWPF/View/IWindowService.cs | 10 + .../AntiDuplWPF/View/MainWindow.xaml | 1415 +++++++++++++---- .../AntiDuplWPF/View/MainWindow.xaml.cs | 24 +- .../AntiDuplWPF/View/PathWindow.xaml | 20 +- .../AntiDuplWPF/View/PrioritiesWindow.xaml | 2 + .../AntiDuplWPF/View/ProgressDialog.xaml | 65 +- .../AntiDuplWPF/View/WindowService.cs | 87 +- .../AntiDuplWPF/ViewModel/BoolEventHandler.cs | 23 + .../ViewModel/CloseableViewModel.cs | 38 + .../AntiDuplWPF/ViewModel/ColorViewModel.cs | 130 ++ .../ViewModel/ComparatorViewModel.cs | 8 +- .../ViewModel/ConfigurableActionViewModel.cs | 353 ++++ .../ViewModel/ConfigurationViewModel.cs | 50 +- .../ViewModel/DuplPairViewModel.cs | 143 +- .../ViewModel/IClosingViewModel.cs | 13 + .../AntiDuplWPF/ViewModel/MainViewModel.cs | 884 +++++++++- .../AntiDuplWPF/ViewModel/PathViewModel.cs | 62 +- .../ViewModel/PrioritiesViewModel.cs | 119 +- .../ViewModel/ProgressDialogViewModel.cs | 7 +- src/AntiDuplWPF/AntiDuplWPF/packages.config | 3 +- 139 files changed, 9998 insertions(+), 898 deletions(-) create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Behavior/AllowableCharactersTextBoxBehavior.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Behavior/DataGridScrollIntoViewBehavior.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Behavior/MenuItemButtonGroupBehavior.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Behavior/MouseEnterBehaviour.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Behavior/WindowCloseOnEscBehavior.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Command/CalculateHistogramPeaksCommand.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Command/ConvertToDuplPairCommand.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Command/ConvertToGroupCommand.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Control/BrushExtender.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Control/ImageInfoControl.xaml create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Control/ImageInfoControl.xaml.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Control/SearchControl.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Control/SearchControlTheme.xaml create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Convertor/ColorToSolidColorBrushConverter.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Convertor/DeleteBackgroundValueConverter.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Convertor/DifferenceValueConverter.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Convertor/ImageBackgroundMultiValueConverter.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Convertor/StringToVisibilityConverter.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Convertor/ViewModeToVisibilityConverter.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Core/AdvancedOption.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Core/DefectOption.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Core/ICoreLib.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Helper/DataGridColumnChooserHelper.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Helper/DiffrenceHelper.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Helper/DirectoryHelper.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Helper/PercentHelper.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Model/IViewModeModel.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Model/ViewModeModel.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/ActionCondition.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/ActionGenerator/AllBestGenerator.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/ActionGenerator/BlockinesBluringGenerator.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/ActionGenerator/ConfigurableActionGenerator.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/ActionGenerator/FileSizePeakBluringGenerator.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/ActionGenerator/FileSizePeakGenerator.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/ActionGenerator/LittleDifferenceGenerator.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/ActionGenerator/LittleDifferenceGenerator2.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/ActionOnDuplPair.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/ByImageProperty/BestConditionParametr.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/ByImageProperty/ConditionOfSelectingBestImageByProperty.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/ByImageProperty/SelectingBestImageByProperty.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/ByPath/BestImageShouldBeInDirectory.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/ByPath/BestImageShouldHaveASmallerNumber.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/ByPath/IBestSelectingByPath.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/ConditionMode/EqualConditionMode.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/ConditionMode/IConditionMode.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/ConditionMode/LessConditionMode.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/ConditionMode/MoreConditionMode.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/ConfigurableAction/DeleteBadAction.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/ConfigurableAction/DeleteOtherAction.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/ConfigurableAction/IConfigurableAction.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/ConfigurableAction/ReplaceAndDeleteAction.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/ConfigurableAction/ReplaceBadImageAction.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/ConfigurableAction/SkipAction.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/DirectoryFilter/AnywhereDirectoryFilter.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/DirectoryFilter/IDirectoryFilter.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/DirectoryFilter/OneImageInDir1OtherInDir2.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/DirectoryFilter/SameDirectory.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/EqualAction.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/FilterCondition.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/FilterConditionParametr.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/GettingNumber/IGettingNumber.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/GettingNumber/NumberBeforeUnderlineGettingNumber.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ObjectModel/ViewMode.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Service/IImageLoader.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Service/IThumbnailProvider.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Service/ImageLoader.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/Style/Default.xaml create mode 100644 src/AntiDuplWPF/AntiDuplWPF/UndoRedo/DeleteCurrentImageCommand.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/UndoRedo/DeleteImageCommand.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/UndoRedo/DeleteMultiCommand.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/UndoRedo/DeleteOtherCommand.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/UndoRedo/RenamedImage.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/UndoRedo/Replace2Command.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/UndoRedo/ReplaceCommand.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/View/ColorWindow.xaml create mode 100644 src/AntiDuplWPF/AntiDuplWPF/View/ColorWindow.xaml.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/View/ConfigurableActionWindow.xaml create mode 100644 src/AntiDuplWPF/AntiDuplWPF/View/ConfigurableActionWindow.xaml.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ViewModel/BoolEventHandler.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ViewModel/CloseableViewModel.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ViewModel/ColorViewModel.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ViewModel/ConfigurableActionViewModel.cs create mode 100644 src/AntiDuplWPF/AntiDuplWPF/ViewModel/IClosingViewModel.cs diff --git a/src/AntiDuplWPF/AntiDuplWPF/AntiDuplWPF.csproj b/src/AntiDuplWPF/AntiDuplWPF/AntiDuplWPF.csproj index 3654d9a9..cdb416e1 100644 --- a/src/AntiDuplWPF/AntiDuplWPF/AntiDuplWPF.csproj +++ b/src/AntiDuplWPF/AntiDuplWPF/AntiDuplWPF.csproj @@ -1,6 +1,5 @@  - - + Debug @@ -69,40 +68,66 @@ MSBuild:Compile Designer + + + + + + + + + CgsImageViewer.xaml ComplexProgressBar.xaml + + ImageInfoControl.xaml + + + + + + + + + + + + + + + @@ -111,43 +136,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ColorWindow.xaml + ComparatorWindow.xaml + + ConfigurableActionWindow.xaml + ConfigurationWindow.xaml @@ -169,6 +252,14 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + Designer MSBuild:Compile @@ -181,14 +272,26 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile @@ -272,17 +375,146 @@ - + + + + + + + + + + + + + + False - Microsoft .NET Framework 4.8 %28x86 und x64%29 + Microsoft .NET Framework 4.5 %28x86 и x64%29 true + + False + Клиентский профиль .NET Framework 3.5 SP1 + false + False .NET Framework 3.5 SP1 false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/AntiDuplWPF/AntiDuplWPF/App.xaml.cs b/src/AntiDuplWPF/AntiDuplWPF/App.xaml.cs index 7e42d451..fbd2f722 100644 --- a/src/AntiDuplWPF/AntiDuplWPF/App.xaml.cs +++ b/src/AntiDuplWPF/AntiDuplWPF/App.xaml.cs @@ -1,11 +1,7 @@ using System; -using System.Collections.Generic; using System.ComponentModel; -using System.Configuration; -using System.Data; -using System.Linq; -using System.Threading.Tasks; using System.Windows; +using AntiDuplWPF.Core; using AntiDuplWPF.Model; using AntiDuplWPF.Service; using AntiDuplWPF.View; @@ -14,10 +10,7 @@ namespace AntiDuplWPF { - /// - /// Логика взаимодействия для App.xaml - /// - public partial class App : Application + public partial class App { public App() { @@ -34,13 +27,26 @@ private void Application_Startup(object sender, StartupEventArgs e) // Register config TinyIoCContainer.Current.Register(confModel); - LanguageService languageService = new LanguageService(confModel); - TinyIoCContainer.Current.Register(languageService); + ILanguageService languageService = new LanguageService(confModel); + TinyIoCContainer.Current.Register(languageService); - var viewModel = new MainViewModel(); + CoreLib core = new CoreLib(); + TinyIoC.TinyIoCContainer.Current.Register(core); + + ImageLoader imageLoader = new ImageLoader(core); + TinyIoC.TinyIoCContainer.Current.Register(imageLoader); + + ThumbnailProvider thumbnailProvider = new ThumbnailProvider(imageLoader); + TinyIoC.TinyIoCContainer.Current.Register(thumbnailProvider); + + //IWindowService windowService = new WindowService(); + MainViewModel viewModel = TinyIoCContainer.Current.Resolve(); + //var viewModel = new MainViewModel(languageService); var shell = new MainWindow(); + //windowService.MainWindow = shell; shell.DataContext = viewModel; + shell.Loaded += new RoutedEventHandler(viewModel.OnLoaded); shell.Closing += new CancelEventHandler(viewModel.OnClosing); shell.Show(); } diff --git a/src/AntiDuplWPF/AntiDuplWPF/Behavior/AllowableCharactersTextBoxBehavior.cs b/src/AntiDuplWPF/AntiDuplWPF/Behavior/AllowableCharactersTextBoxBehavior.cs new file mode 100644 index 00000000..dbd265c1 --- /dev/null +++ b/src/AntiDuplWPF/AntiDuplWPF/Behavior/AllowableCharactersTextBoxBehavior.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Interactivity; + +namespace AntiDuplWPF.Behavior +{ + public class AllowableCharactersTextBoxBehavior : Behavior + { + public static readonly DependencyProperty RegularExpressionProperty = + DependencyProperty.Register("RegularExpression", typeof(string), typeof(AllowableCharactersTextBoxBehavior), + new FrameworkPropertyMetadata(".*")); + public string RegularExpression + { + get + { + return (string)base.GetValue(RegularExpressionProperty); + } + set + { + base.SetValue(RegularExpressionProperty, value); + } + } + + public static readonly DependencyProperty MaxLengthProperty = + DependencyProperty.Register("MaxLength", typeof(int), typeof(AllowableCharactersTextBoxBehavior), + new FrameworkPropertyMetadata(int.MinValue)); + public int MaxLength + { + get + { + return (int)base.GetValue(MaxLengthProperty); + } + set + { + base.SetValue(MaxLengthProperty, value); + } + } + + protected override void OnAttached() + { + base.OnAttached(); + AssociatedObject.PreviewTextInput += OnPreviewTextInput; + DataObject.AddPastingHandler(AssociatedObject, OnPaste); + } + + private void OnPaste(object sender, DataObjectPastingEventArgs e) + { + if (e.DataObject.GetDataPresent(DataFormats.Text)) + { + string text = Convert.ToString(e.DataObject.GetData(DataFormats.Text)); + + if (!IsValid(text, true)) + { + e.CancelCommand(); + } + } + else + { + e.CancelCommand(); + } + } + + void OnPreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e) + { + e.Handled = !IsValid(e.Text, false); + } + + protected override void OnDetaching() + { + base.OnDetaching(); + AssociatedObject.PreviewTextInput -= OnPreviewTextInput; + DataObject.RemovePastingHandler(AssociatedObject, OnPaste); + } + + private bool IsValid(string newText, bool paste) + { + return !ExceedsMaxLength(newText, paste) && Regex.IsMatch(newText, RegularExpression); + } + + private bool ExceedsMaxLength(string newText, bool paste) + { + if (MaxLength == 0) return false; + + return LengthOfModifiedText(newText, paste) > MaxLength; + } + + private int LengthOfModifiedText(string newText, bool paste) + { + var countOfSelectedChars = this.AssociatedObject.SelectedText.Length; + var caretIndex = this.AssociatedObject.CaretIndex; + string text = this.AssociatedObject.Text; + + if (countOfSelectedChars > 0 || paste) + { + text = text.Remove(caretIndex, countOfSelectedChars); + return text.Length + newText.Length; + } + else + { + var insert = Keyboard.IsKeyToggled(Key.Insert); + + return insert && caretIndex < text.Length ? text.Length : text.Length + newText.Length; + } + } + } + +} diff --git a/src/AntiDuplWPF/AntiDuplWPF/Behavior/DataGridContextMenuItemSourceBindingOnOpenBehavior.cs b/src/AntiDuplWPF/AntiDuplWPF/Behavior/DataGridContextMenuItemSourceBindingOnOpenBehavior.cs index a922bf55..ad8543b9 100644 --- a/src/AntiDuplWPF/AntiDuplWPF/Behavior/DataGridContextMenuItemSourceBindingOnOpenBehavior.cs +++ b/src/AntiDuplWPF/AntiDuplWPF/Behavior/DataGridContextMenuItemSourceBindingOnOpenBehavior.cs @@ -8,8 +8,11 @@ using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; +using System.Windows.Data; +using System.Windows.Documents; using System.Windows.Input; -using Microsoft.Xaml.Behaviors; +using System.Windows.Interactivity; +using AntiDuplWPF.Helper; using AntiDuplWPF.ObjectModel; using AntiDuplWPF.ViewModel; @@ -30,7 +33,7 @@ public Func MenuGeneratorDuplPair set { SetValue(MenuGeneratorDuplPairProperty, value); } } - /* public static readonly DependencyProperty MenuGeneratorDuplGroupProperty = + public static readonly DependencyProperty MenuGeneratorDuplGroupProperty = DependencyProperty.Register("MenuGeneratorDuplGroup", typeof(Func), typeof(DataGridContextMenuItemSourceBindingOnOpenBehavior), @@ -40,7 +43,7 @@ public Func MenuGeneratorDuplGroup { get { return (Func)GetValue(MenuGeneratorDuplGroupProperty); } set { SetValue(MenuGeneratorDuplGroupProperty, value); } - }*/ + } public static readonly DependencyProperty MenuGeneratorMultiDuplPairProperty = DependencyProperty.Register("MenuGeneratorMultiDuplPair", @@ -75,42 +78,99 @@ protected override void OnAttached() void AssociatedObject_ContextMenuOpening(object sender, ContextMenuEventArgs e) { - var grid = sender as MultiSelector; - if (grid != null) + var grid = sender as DataGrid; + if (grid == null) + return; + + if (grid.ContextMenu == null) + return; + + grid.ContextMenu.ItemsSource = null; + grid.ContextMenu.Items.Clear(); + + var fe = e.OriginalSource as FrameworkElement; + if (fe != null) + { + if (HandleColumnHeadersMenuOpen(grid, grid.ContextMenu)) + return; + } + + if (grid.SelectedItems.Count > 1) { - if (grid.SelectedItems.Count > 1) + if (grid.SelectedItem is DuplPairViewModel) { - if (grid.SelectedItem is DuplPairViewModel) - { - IList viewResultsOfDupl = (IList)grid.SelectedItems; - if (MenuGeneratorMultiDuplPair != null) - grid.ContextMenu.ItemsSource = MenuGeneratorMultiDuplPair(viewResultsOfDupl); - } - /* else if (grid.SelectedItem is DuplicateGroup) - { - IList viewResults = (IList)grid.SelectedItems; - if (MenuGeneratorMultiDuplGroup != null) - grid.ContextMenu.ItemsSource = MenuGeneratorMultiDuplGroup(viewResults); - }*/ + IList viewResultsOfDupl = (IList)grid.SelectedItems; + if (MenuGeneratorMultiDuplPair != null) + grid.ContextMenu.ItemsSource = MenuGeneratorMultiDuplPair(viewResultsOfDupl); } - else + else if (grid.SelectedItem is DuplicateGroup) + { + IList viewResults = (IList)grid.SelectedItems; + if (MenuGeneratorMultiDuplGroup != null) + grid.ContextMenu.ItemsSource = MenuGeneratorMultiDuplGroup(viewResults); + } + } + else + { + if (grid.SelectedItem is DuplPairViewModel) + { + DuplPairViewModel viewResultOfDupl = (DuplPairViewModel)grid.SelectedItem; + if (MenuGeneratorDuplPair != null) + grid.ContextMenu.ItemsSource = MenuGeneratorDuplPair(viewResultOfDupl); + } + else if (grid.SelectedItem is DuplicateGroup) { - if (grid.SelectedItem is DuplPairViewModel) - { - DuplPairViewModel viewResultOfDupl = (DuplPairViewModel)grid.SelectedItem; - if (MenuGeneratorDuplPair != null) - grid.ContextMenu.ItemsSource = MenuGeneratorDuplPair(viewResultOfDupl); - } - /*else if (grid.SelectedItem is DuplicateGroup) - { - DuplicateGroup duplicateGroup = (DuplicateGroup)grid.SelectedItem; - if (MenuGeneratorDuplGroup != null) - grid.ContextMenu.ItemsSource = MenuGeneratorDuplGroup(duplicateGroup); - }*/ + DuplicateGroup duplicateGroup = (DuplicateGroup)grid.SelectedItem; + if (MenuGeneratorDuplGroup != null) + grid.ContextMenu.ItemsSource = MenuGeneratorDuplGroup(duplicateGroup); } } } + private static bool HandleColumnHeadersMenuOpen(DataGrid grid, ContextMenu menu) + { + var headersPresenter = VisualTreeHelperEx.FindVisualChildByType(grid); + if (headersPresenter == null) + return false; + + var currentPosition = Mouse.GetPosition(headersPresenter); + if (currentPosition.X < 0 || currentPosition.X > headersPresenter.ActualWidth || + currentPosition.Y < 0 || currentPosition.Y > headersPresenter.ActualHeight) + return false; + + var enabled = DataGridColumnChooserHelper.GetIsEnabled(grid); + if (!enabled) + return true; + + foreach (var col in grid.Columns.OrderBy(col => col.DisplayIndex)) + { + string title; + if (col.Header is TextBlock) + { + var tblock = (TextBlock) col.Header; + title = !string.IsNullOrEmpty(tblock.Text) + ? tblock.Text + : string.Join(string.Empty, tblock.Inlines.OfType().Select(i => i.Text)) + .Replace(Environment.NewLine, string.Empty); + } + else + title = (string) col.Header; + + var menuItem = new MenuItem {Header = title, IsCheckable = true}; + var binding = new Binding + { + Source = col, + Path = new PropertyPath(DataGridColumn.VisibilityProperty.Name), + Converter = new VisibilityToBoolConverter() + }; + BindingOperations.SetBinding(menuItem, MenuItem.IsCheckedProperty, binding); + menuItem.StaysOpenOnClick = true; + menu.Items.Add(menuItem); + } + + return true; + } + protected override void OnDetaching() { base.OnDetaching(); diff --git a/src/AntiDuplWPF/AntiDuplWPF/Behavior/DataGridScrollIntoViewBehavior.cs b/src/AntiDuplWPF/AntiDuplWPF/Behavior/DataGridScrollIntoViewBehavior.cs new file mode 100644 index 00000000..ce48d120 --- /dev/null +++ b/src/AntiDuplWPF/AntiDuplWPF/Behavior/DataGridScrollIntoViewBehavior.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Interactivity; + +namespace AntiDuplWPF.Behavior +{ + public class DataGridScrollIntoViewBehavior : Behavior + { + protected override void OnAttached() + { + AssociatedObject.Loaded += OnLoaded; + AssociatedObject.Unloaded += OnUnLoaded; + } + + protected override void OnDetaching() + { + AssociatedObject.Loaded -= OnLoaded; + AssociatedObject.Unloaded -= OnUnLoaded; + } + + private void OnLoaded(object sender, RoutedEventArgs e) + { + AssociatedObject.SelectionChanged += AssociatedObject_SelectionChanged; + } + + void AssociatedObject_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (AssociatedObject is DataGrid) + { + DataGrid grid = (DataGrid)AssociatedObject; + grid.Dispatcher.BeginInvoke((Action)(() => + { + grid.UpdateLayout(); + if (grid.SelectedItem != null) + grid.ScrollIntoView(grid.SelectedItem); + })); + } + } + + private void OnUnLoaded(object sender, RoutedEventArgs e) + { + AssociatedObject.SelectionChanged -= AssociatedObject_SelectionChanged; + } + + + } +} diff --git a/src/AntiDuplWPF/AntiDuplWPF/Behavior/FrameworkElementDropBehavior.cs b/src/AntiDuplWPF/AntiDuplWPF/Behavior/FrameworkElementDropBehavior.cs index 71f3807f..e1b93514 100644 --- a/src/AntiDuplWPF/AntiDuplWPF/Behavior/FrameworkElementDropBehavior.cs +++ b/src/AntiDuplWPF/AntiDuplWPF/Behavior/FrameworkElementDropBehavior.cs @@ -4,7 +4,7 @@ using System.Text; using System.Threading.Tasks; using System.Windows; -using Microsoft.Xaml.Behaviors; +using System.Windows.Interactivity; using AntiDuplWPF.DragDrop; namespace AntiDuplWPF.Behavior diff --git a/src/AntiDuplWPF/AntiDuplWPF/Behavior/ImagePropertyBehavior.cs b/src/AntiDuplWPF/AntiDuplWPF/Behavior/ImagePropertyBehavior.cs index 08f2bfa0..56ed0dfc 100644 --- a/src/AntiDuplWPF/AntiDuplWPF/Behavior/ImagePropertyBehavior.cs +++ b/src/AntiDuplWPF/AntiDuplWPF/Behavior/ImagePropertyBehavior.cs @@ -4,7 +4,7 @@ using System.Text; using System.Threading.Tasks; using System.Windows; -using Microsoft.Xaml.Behaviors; +using System.Windows.Interactivity; using System.Windows.Controls; using AntiDuplWPF.Helper; using TinyIoC; @@ -70,6 +70,7 @@ private void SetPropertyes() } } } + #endregion } } diff --git a/src/AntiDuplWPF/AntiDuplWPF/Behavior/MenuItemButtonGroupBehavior.cs b/src/AntiDuplWPF/AntiDuplWPF/Behavior/MenuItemButtonGroupBehavior.cs new file mode 100644 index 00000000..e97a8859 --- /dev/null +++ b/src/AntiDuplWPF/AntiDuplWPF/Behavior/MenuItemButtonGroupBehavior.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Interactivity; +using AntiDuplWPF.Model; +using AntiDuplWPF.ObjectModel; +using TinyIoC; + +namespace AntiDuplWPF.Behavior +{ + public class MenuItemButtonGroupBehavior : Behavior + { + private IViewModeModel _viewModeModel; + IEnumerable _menus; + + public MenuItemButtonGroupBehavior() + { + if (_viewModeModel == null) + { + _viewModeModel = TinyIoCContainer.Current.Resolve(); + } + + if (_viewModeModel == null) + { + throw new ArgumentNullException("No IViewModeModel is registered"); + } + + _viewModeModel.PropertyChanged += _viewModeModel_PropertyChanged; + } + + void _viewModeModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + { + _menus.ToList().ForEach(item => item.IsChecked = false); + SetCheck(_menus, _viewModeModel.ViewMode); + } + + protected override void OnAttached() + { + base.OnAttached(); + + _menus = GetCheckableSubMenuItems(AssociatedObject); + _menus.ToList() + .ForEach(item => item.Click += OnClick); + + SetCheck(_menus, _viewModeModel.ViewMode); + } + + protected override void OnDetaching() + { + base.OnDetaching(); + + //GetCheckableSubMenuItems(AssociatedObject) + _menus.ToList() + .ForEach(item => item.Click -= OnClick); + _viewModeModel.PropertyChanged -= _viewModeModel_PropertyChanged; + } + + private static IEnumerable GetCheckableSubMenuItems(ItemsControl menuItem) + { + var itemCollection = menuItem.Items; + return itemCollection.OfType().Where(menuItemCandidate => menuItemCandidate.IsCheckable); + } + + private void OnClick(object sender, RoutedEventArgs routedEventArgs) + { + var menuItem = (MenuItem)sender; + + if (!menuItem.IsChecked) + { + menuItem.IsChecked = true; + return; + } + + SetViewMode(menuItem); + + //GetCheckableSubMenuItems(AssociatedObject) + _menus.Where(item => item != menuItem) + .ToList() + .ForEach(item => item.IsChecked = false); + } + + private void SetCheck(IEnumerable menus, ViewMode viewMode) + { + if (viewMode == ObjectModel.ViewMode.Group) + { + var item = menus.First(m => m.Name == "toGroup"); + if (item != null) + item.IsChecked = true; + } + else if (viewMode == ObjectModel.ViewMode.Pair) + { + var item = menus.First(m => m.Name == "toDuplPair"); + if (item != null) + item.IsChecked = true; + } + } + + private void SetViewMode(MenuItem menuItem) + { + if (menuItem.Name == "toGroup") + { + _viewModeModel.PropertyChanged -= _viewModeModel_PropertyChanged; + _viewModeModel.ViewMode = ViewMode.Group; + _viewModeModel.PropertyChanged += _viewModeModel_PropertyChanged; + } + else if (menuItem.Name == "toDuplPair") + { + _viewModeModel.PropertyChanged -= _viewModeModel_PropertyChanged; + _viewModeModel.ViewMode = ViewMode.Pair; + _viewModeModel.PropertyChanged += _viewModeModel_PropertyChanged; + } + } + } +} diff --git a/src/AntiDuplWPF/AntiDuplWPF/Behavior/MouseEnterBehaviour.cs b/src/AntiDuplWPF/AntiDuplWPF/Behavior/MouseEnterBehaviour.cs new file mode 100644 index 00000000..a982ad8e --- /dev/null +++ b/src/AntiDuplWPF/AntiDuplWPF/Behavior/MouseEnterBehaviour.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Input; +using System.Windows.Interactivity; + +namespace AntiDuplWPF.Behavior +{ + public class MouseEnterBehaviour : Behavior + { + public static readonly DependencyProperty MouseEnterCommandProperty = + DependencyProperty.Register("MouseEnterCommand", + typeof(ICommand), + typeof(MouseEnterBehaviour), + new UIPropertyMetadata(null)); + + public ICommand MouseEnterCommand + { + get { return (ICommand)GetValue(MouseEnterCommandProperty); } + set { SetValue(MouseEnterCommandProperty, value); } + } + + public static readonly DependencyProperty MouseLeaveCommandProperty = + DependencyProperty.Register("MouseLeaveCommand", + typeof(ICommand), + typeof(MouseEnterBehaviour), + new UIPropertyMetadata(null)); + + public ICommand MouseLeaveCommand + { + get { return (ICommand)GetValue(MouseLeaveCommandProperty); } + set { SetValue(MouseLeaveCommandProperty, value); } + } + + protected override void OnAttached() + { + base.OnAttached(); + + AssociatedObject.MouseEnter += AssociatedObject_MouseEnter; + AssociatedObject.MouseLeave += AssociatedObject_MouseLeave; + } + + protected override void OnDetaching() + { + base.OnDetaching(); + + AssociatedObject.MouseEnter -= AssociatedObject_MouseEnter; + AssociatedObject.MouseLeave -= AssociatedObject_MouseLeave; + } + + void AssociatedObject_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e) + { + object[] parametrs = new object[0]; + if (MouseEnterCommand != null && MouseEnterCommand.CanExecute(parametrs)) + MouseEnterCommand.Execute(parametrs); + } + + + void AssociatedObject_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e) + { + object[] parametrs = new object[0]; + if (MouseLeaveCommand != null && MouseLeaveCommand.CanExecute(parametrs)) + MouseLeaveCommand.Execute(parametrs); + } + + + } +} diff --git a/src/AntiDuplWPF/AntiDuplWPF/Behavior/WindowCloseOnEscBehavior.cs b/src/AntiDuplWPF/AntiDuplWPF/Behavior/WindowCloseOnEscBehavior.cs new file mode 100644 index 00000000..7073cf3e --- /dev/null +++ b/src/AntiDuplWPF/AntiDuplWPF/Behavior/WindowCloseOnEscBehavior.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Input; +using System.Windows.Interactivity; + +namespace AntiDuplWPF.Behavior +{ + class WindowCloseOnEscBehavior : Behavior + { + protected override void OnAttached() + { + base.OnAttached(); + + AssociatedObject.PreviewKeyDown += AssociatedObject_PreviewKeyDown; + + //_undoRedoEngine = TinyIoCContainer.Current.Resolve(); + } + + void AssociatedObject_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e) + { + Window target = sender as Window; + + if (target != null) + { + if (e.Key == Key.Escape) + { + target.Close(); + } + } + } + + + protected override void OnDetaching() + { + base.OnDetaching(); + + AssociatedObject.PreviewKeyDown -= AssociatedObject_PreviewKeyDown; + } + } +} diff --git a/src/AntiDuplWPF/AntiDuplWPF/Command/CalculateHistogramPeaksCommand.cs b/src/AntiDuplWPF/AntiDuplWPF/Command/CalculateHistogramPeaksCommand.cs new file mode 100644 index 00000000..bb551294 --- /dev/null +++ b/src/AntiDuplWPF/AntiDuplWPF/Command/CalculateHistogramPeaksCommand.cs @@ -0,0 +1,182 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Input; +using System.Windows.Threading; +using AntiDuplWPF.Core; +using AntiDuplWPF.ViewModel; + +namespace AntiDuplWPF.Command +{ + class CalculateHistogramPeaksCommand : ICommand + { + private ViewModel.MainViewModel _mainViewModel; + private Core.ICoreLib _core; + private View.IWindowService _windowService; + //private IEnumerable _results; + System.Collections.ObjectModel.ObservableCollection _resultList; + ProgressDialogViewModel _progressDialogViewModel; + + CoreDll.adImageInfoW[] _arrayInfo; + + DispatcherTimer _timer = new DispatcherTimer(); + StateEnum _state = StateEnum.Start; + public enum StateEnum + { + Start, + Work, + Stopped, + Finish + } + + public CalculateHistogramPeaksCommand(ViewModel.MainViewModel mainViewModel, + Core.ICoreLib core, View.IWindowService windowService, + System.Collections.ObjectModel.ObservableCollection resultList) + { + _mainViewModel = mainViewModel; + _core = core; + this._windowService = windowService; + _resultList = resultList; + + if (_resultList == null) + throw new NullReferenceException("_results"); + + _resultList.CollectionChanged += _resultList_CollectionChanged; + + // установка таймера + _timer = new DispatcherTimer(); + _timer.Tick += OnTimerTick; + _timer.Interval = new TimeSpan(0, 0, 1); + } + + void _resultList_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) + { + if (CanExecuteChanged != null) + CanExecuteChanged(this, e); + } + + void OnTimerTick(object sender, EventArgs e) + { + if (_state == StateEnum.Finish + || _state == StateEnum.Stopped) + { + _timer.Stop(); + var closeProgressWindow = new Action(_windowService.CloseProgressWindow); + Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, closeProgressWindow); + + + //if (_arrayInfo.All(i => i.jpegPeaks == 0)) + // throw new Exception("All jpegPeaks == 0"); + + foreach (var result in _resultList) + { + var first = _arrayInfo.Single(i => i.path == result.FirstFile.Path); + var second = _arrayInfo.Single(i => i.path == result.SecondFile.Path); + + result.FirstFile.JpegPeaks = first.jpegPeaks; + result.SecondFile.JpegPeaks = second.jpegPeaks; + } + } + else + { + CoreStatus mainThreadStatus = _core.StatusGet(CoreDll.ThreadType.Main, 0); + if (mainThreadStatus != null) + { + + _progressDialogViewModel.ProgressMax = (uint)(mainThreadStatus.total); + _progressDialogViewModel.Progress = (uint)(mainThreadStatus.current); + // _progressDialogViewModel.CurrentSecond = (uint)currentSecond; + _progressDialogViewModel.ProgressMessage = mainThreadStatus.path; + } + + } + } + + /// + /// Method for ThreadStart delegate + /// + public void RunProcess() + { + _progressDialogViewModel.State = "Calculate DCT Histogram Peaks"; + + CoreDll.WorkProgressInteropNegotiator negotiator = new CoreDll.WorkProgressInteropNegotiator(); + negotiator.cancellationPending = new CoreDll.CancellationPendingCallback(() => { return _progressDialogViewModel.IsCancel; }); + + // Refer for details to + // "How to: Marshal Callbacks and Delegates Using C++ Interop" + // http://msdn.microsoft.com/en-us/library/367eeye0%28v=vs.100%29.aspx + GCHandle gch = GCHandle.Alloc(negotiator); + + _mainViewModel.Options.CopyToDll(); + _mainViewModel.LocationsModel.CopyToDll(); + + var array = _resultList.Select(r => r.FirstFile).Union(_resultList.Select(r2 => r2.SecondFile)); + var arrayDistinct = array.Distinct(); + _arrayInfo = arrayDistinct.Select(i => new CoreDll.adImageInfoW(i)).ToArray(); + //new CoreDll.adResultW(r)).ToArray(); + + //foreach (var item in arrayInfo) + //{ + // var sear = arrayInfo.Where(i => i.path == item.path).ToArray(); + // var first = arrayInfo.Single(i => i.path == item.path); + //} + + _core.CalculateHistogramPeaks(_arrayInfo, negotiator); + + // DuplPairViewModel[] result2 = _core.GetResult(); + + //if (result2.Any()) + // _mainViewModel.SetResult(result2); + + _state = StateEnum.Finish; + } + + + public event EventHandler CanExecuteChanged; + + public bool CanExecute(object parameter) + { + return _resultList.Any(); + //return true; + } + + public void Execute(object parameter) + { + // Initialize + _progressDialogViewModel = new ProgressDialogViewModel(); + // Set the view model's token source + _progressDialogViewModel.TokenSource = new CancellationTokenSource(); + //_progressDialogViewModel.TokenSource.Token.Register(() => OnCancel()); + + _state = StateEnum.Start; + + Thread thread = new Thread(new ThreadStart(RunProcess)); + thread.IsBackground = true; //make them a daemon - prevent thread callback issues + thread.Name = "CalculateHistogramPeaksThread"; + thread.Start(); + + _timer.Start(); + + Thread.Sleep(200); + + if (_state != StateEnum.Finish) + { + // Announce that work is starting + //_mainViewModel.RaiseWorkStartedEvent(); + _windowService.OpenProgressWindow(_progressDialogViewModel); + } + } + + + //private void OnCancel() + //{ + // _core.Stop(); + // _state = StateEnum.Stopped; + //} + } +} diff --git a/src/AntiDuplWPF/AntiDuplWPF/Command/ConvertToDuplPairCommand.cs b/src/AntiDuplWPF/AntiDuplWPF/Command/ConvertToDuplPairCommand.cs new file mode 100644 index 00000000..94968335 --- /dev/null +++ b/src/AntiDuplWPF/AntiDuplWPF/Command/ConvertToDuplPairCommand.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Data; +using System.Windows.Input; +using AntiDuplWPF.Helper; +using AntiDuplWPF.ViewModel; + +namespace AntiDuplWPF.Command +{ + class ConvertToDuplPairCommand : ICommand + { + public event EventHandler CanExecuteChanged; + private MainViewModel _mainViewModel; + private View.IWindowService _windowService; + public enum StateEnum + { + Start, + Finish + } + StateEnum _state = StateEnum.Start; + ProgressDialogViewModel _progressDialogViewModel; + + public ConvertToDuplPairCommand(MainViewModel mainViewModel, View.IWindowService _windowService) + { + this._mainViewModel = mainViewModel; + this._windowService = _windowService; + } + + public void Execute(object parameter) + { + // Initialize + _progressDialogViewModel = new ProgressDialogViewModel(); + + Thread thread = new Thread(new ThreadStart(RunProcess)); + thread.IsBackground = true; //make them a daemon - prevent thread callback issues + thread.Name = "ConvertToDuplPairThread"; + thread.Start(); + + Thread.Sleep(200); + + if (_state != StateEnum.Finish) + { + // Announce that work is starting + _windowService.OpenProgressWindow(_progressDialogViewModel); + } + } + + /// + /// Method for ThreadStart delegate + /// + public void RunProcess() + { + Application.Current.Dispatcher.Invoke(() => + { + _mainViewModel.ResultList.Clear(); + }); + GroupHelper.GroupToList(_mainViewModel.Groups, _mainViewModel.ResultList); + Application.Current.Dispatcher.Invoke(() => + { + var res = CollectionViewSource.GetDefaultView(_mainViewModel.ResultList); + _mainViewModel.Result = (IEditableCollectionView)res; + _mainViewModel.Groups.Clear(); + _mainViewModel.SelectedTabPageIndex = 0; + }); + + _state = StateEnum.Finish; + + } + + public bool CanExecute(object parameter) + { + return _mainViewModel.Groups != null && _mainViewModel.Groups.Any(); + } + } +} diff --git a/src/AntiDuplWPF/AntiDuplWPF/Command/ConvertToGroupCommand.cs b/src/AntiDuplWPF/AntiDuplWPF/Command/ConvertToGroupCommand.cs new file mode 100644 index 00000000..de3b1e7c --- /dev/null +++ b/src/AntiDuplWPF/AntiDuplWPF/Command/ConvertToGroupCommand.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Data; +using System.Windows.Input; +using System.Windows.Threading; +using AntiDuplWPF.Helper; +using AntiDuplWPF.ViewModel; + +namespace AntiDuplWPF.Command +{ + class ConvertToGroupCommand : ICommand + { + public event EventHandler CanExecuteChanged; + private MainViewModel _mainViewModel; + private View.IWindowService _windowService; + public enum StateEnum + { + Start, + Finish + } + StateEnum _state = StateEnum.Start; + ProgressDialogViewModel _progressDialogViewModel; + + public ConvertToGroupCommand(MainViewModel mainViewModel, View.IWindowService _windowService) + { + this._mainViewModel = mainViewModel; + this._windowService = _windowService; + } + + public void Execute(object parameter) + { + Thread thread = new Thread(new ThreadStart(RunProcess)); + thread.IsBackground = true; //make them a daemon - prevent thread callback issues + thread.Name = "ConvertToGroupThread"; + thread.Start(); + + Thread.Sleep(200); + + if (_state != StateEnum.Finish) + { + _progressDialogViewModel = new ProgressDialogViewModel(); + // Announce that work is starting + _windowService.OpenProgressWindow(_progressDialogViewModel); + } + } + + /// + /// Method for ThreadStart delegate + /// + public void RunProcess() + { + _mainViewModel.Groups.Clear(); + GroupHelper.ConvertToGroup(_mainViewModel.Groups, _mainViewModel.ResultList); + + Application.Current.Dispatcher.Invoke(() => + { + if (_mainViewModel.GroupsCollection == null) + _mainViewModel.GroupsCollection = CollectionViewSource.GetDefaultView(_mainViewModel.Groups); + _mainViewModel.ResultList.Clear(); + _mainViewModel.SelectedTabPageIndex = 1; + }); + + _state = StateEnum.Finish; + if (_progressDialogViewModel != null) + Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => _windowService.CloseProgressWindow())); + } + + public bool CanExecute(object parameter) + { + return _mainViewModel.ResultList != null && _mainViewModel.ResultList.Any(); + } + + } +} diff --git a/src/AntiDuplWPF/AntiDuplWPF/Command/SearchDllCommand.cs b/src/AntiDuplWPF/AntiDuplWPF/Command/SearchDllCommand.cs index ce14a535..1c900352 100644 --- a/src/AntiDuplWPF/AntiDuplWPF/Command/SearchDllCommand.cs +++ b/src/AntiDuplWPF/AntiDuplWPF/Command/SearchDllCommand.cs @@ -17,7 +17,7 @@ public class SearchDllCommand : ICommand { public event EventHandler CanExecuteChanged; private MainViewModel _mainViewModel; - private CoreLib _core; + private ICoreLib _core; private IWindowService _windowService; DispatcherTimer _timer; ProgressDialogViewModel _progressDialogViewModel; @@ -30,7 +30,7 @@ public enum StateEnum } StateEnum _state = StateEnum.Start; - public SearchDllCommand(MainViewModel mainViewModel, CoreLib core, IWindowService windowService) + public SearchDllCommand(MainViewModel mainViewModel, ICoreLib core, IWindowService windowService) { this._mainViewModel = mainViewModel; this._core = core; @@ -49,6 +49,16 @@ void OnTimerTick(object sender, EventArgs e) _timer.Stop(); var closeProgressWindow = new Action(_windowService.CloseProgressWindow); Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, closeProgressWindow); + + DuplPairViewModel[] result2 = _core.GetResult(); + + //if (result2.Any()) + _mainViewModel.SetResult(result2); + } + if (_state == StateEnum.Stopped) + { + _progressDialogViewModel.State = "Stopped"; + _progressDialogViewModel.ProgressMessage = "Stopped"; } else { @@ -102,7 +112,7 @@ void OnTimerTick(object sender, EventArgs e) _progressDialogViewModel.ProgressMax = (uint)(mainThreadStatus.total); _progressDialogViewModel.Progress = (uint)(currentFirst); _progressDialogViewModel.CurrentSecond = (uint)currentSecond; - //_progressDialogViewModel.ProgressMessage = status.path; + _progressDialogViewModel.ProgressMessage = path; } } @@ -117,6 +127,9 @@ public void Execute(object parameter) _progressDialogViewModel = new ProgressDialogViewModel(); // Set the view model's token source _progressDialogViewModel.TokenSource = new CancellationTokenSource(); + _progressDialogViewModel.TokenSource.Token.Register(() => OnCancel()); + + _state = StateEnum.Start; Thread thread = new Thread(new ThreadStart(RunProcess)); thread.IsBackground = true; //make them a daemon - prevent thread callback issues @@ -133,9 +146,6 @@ public void Execute(object parameter) //_mainViewModel.RaiseWorkStartedEvent(); _windowService.OpenProgressWindow(_progressDialogViewModel); } - else - { - } } /// @@ -143,29 +153,27 @@ public void Execute(object parameter) /// public void RunProcess() { - var progressDialogViewModel = _progressDialogViewModel; - - var watch = System.Diagnostics.Stopwatch.StartNew(); + //var watch = System.Diagnostics.Stopwatch.StartNew(); - progressDialogViewModel.State = "progressWindow_ComputeHashes2"; + _progressDialogViewModel.State = "Search"; _mainViewModel.Options.CopyToDll(); _mainViewModel.LocationsModel.CopyToDll(); var result = _core.Search(); - watch.Stop(); - var elapsedMs = watch.ElapsedMilliseconds; + //watch.Stop(); + //var elapsedMs = watch.ElapsedMilliseconds; //MessageBox.Show(elapsedMs.ToString()); - - DuplPairViewModel[] result2 = _core.GetResult(); - - if (result2.Any()) - _mainViewModel.SetResult(result2); - _state = StateEnum.Finish; } + private void OnCancel() + { + _core.Stop(); + _state = StateEnum.Stopped; + _progressDialogViewModel.IsCancelled = true; + } } } diff --git a/src/AntiDuplWPF/AntiDuplWPF/Control/BrushExtender.cs b/src/AntiDuplWPF/AntiDuplWPF/Control/BrushExtender.cs new file mode 100644 index 00000000..9619b5ca --- /dev/null +++ b/src/AntiDuplWPF/AntiDuplWPF/Control/BrushExtender.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Media; + +namespace AntiDuplWPF.Control +{ + public static class BrushExtender + { + public readonly static DependencyProperty BrushProperty = DependencyProperty.RegisterAttached("Brush", typeof(Brush), typeof(BrushExtender), new PropertyMetadata(Brushes.Black, DoBrushChanged)); + + public readonly static DependencyProperty RedChannelProperty = DependencyProperty.RegisterAttached("RedChannel", typeof(int), typeof(BrushExtender), new PropertyMetadata(DoColorChangedRed)); + + public readonly static DependencyProperty GreenChannelProperty = DependencyProperty.RegisterAttached("GreenChannel", typeof(int), typeof(BrushExtender), new PropertyMetadata(DoColorChangedGreen)); + + public readonly static DependencyProperty BlueChannelProperty = DependencyProperty.RegisterAttached("BlueChannel", typeof(int), typeof(BrushExtender), new PropertyMetadata(DoColorChangedBlue)); + + public readonly static DependencyProperty AlphaChannelProperty = DependencyProperty.RegisterAttached("AlphaChannel", typeof(int), typeof(BrushExtender), new PropertyMetadata(DoColorChangedAlpha)); + + public readonly static DependencyProperty ColourValueProperty = DependencyProperty.RegisterAttached("ColourValue", typeof(string), typeof(BrushExtender), new PropertyMetadata(DoValueChanged)); + + public static void SetRedChannel(DependencyObject o, int value) + { + o.SetValue(RedChannelProperty, value); + } + + public static void SetGreenChannel(DependencyObject o, int value) + { + o.SetValue(GreenChannelProperty, value); + } + + public static void SetBlueChannel(DependencyObject o, int value) + { + o.SetValue(BlueChannelProperty, value); + } + + public static void SetAlphaChannel(DependencyObject o, int value) + { + o.SetValue(AlphaChannelProperty, value); + } + + public static void SetBrush(DependencyObject o, SolidColorBrush brush) + { + o.SetValue(BrushProperty, brush); + } + + public static void SetColourValue(DependencyObject o, string value) + { + o.SetValue(ColourValueProperty, value); + } + + private static void DoColorChangedRed(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var color = ((SolidColorBrush)d.GetValue(BrushProperty)).Color; + DoColorChange(d, (int)e.NewValue, c => c.R, () => Color.FromArgb(color.A, ((byte)(int)e.NewValue), color.G, color.B)); + } + + private static void DoColorChangedGreen(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var color = ((SolidColorBrush)d.GetValue(BrushProperty)).Color; + DoColorChange(d, (int)e.NewValue, c => c.G, () => Color.FromArgb(color.A, color.R, ((byte)(int)e.NewValue), color.B)); + } + + private static void DoColorChangedBlue(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var color = ((SolidColorBrush)d.GetValue(BrushProperty)).Color; + DoColorChange(d, (int)e.NewValue, c => c.B, () => Color.FromArgb(color.A, color.R, color.G, (byte)(int)e.NewValue)); + } + + private static void DoColorChangedAlpha(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var color = ((SolidColorBrush)d.GetValue(BrushProperty)).Color; + DoColorChange(d, (int)e.NewValue, c => c.A, () => Color.FromArgb((byte)(int)e.NewValue, color.R, color.G, color.B)); + } + + private static void DoColorChange(DependencyObject d, int newValue, Func colorCompare, Func getColor) + { + var color = ((SolidColorBrush)d.GetValue(BrushProperty)).Color; + if (colorCompare(color) == newValue) + return; + var newBrush = new SolidColorBrush(getColor()); + d.SetValue(BrushProperty, newBrush); + d.SetValue(ColourValueProperty, newBrush.Color.ToString()); + } + + private static void DoValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var color = ((SolidColorBrush)d.GetValue(BrushProperty)).Color; + if (color.ToString() == (string)e.NewValue) + return; + Color? newColour = null; + try + { + newColour = (Color)ColorConverter.ConvertFromString((string)e.NewValue); + } + catch { } + if (newColour == null) + return; + var newBrush = new SolidColorBrush(newColour.Value); + d.SetValue(BrushProperty, newBrush); + } + + + private static void DoBrushChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (e.NewValue == e.OldValue) + return; + var colour = ((SolidColorBrush)e.NewValue).Color; + d.SetValue(RedChannelProperty, (int)colour.R); + d.SetValue(GreenChannelProperty, (int)colour.G); + d.SetValue(BlueChannelProperty, (int)colour.B); + d.SetValue(AlphaChannelProperty, (int)colour.A); + d.SetValue(ColourValueProperty, colour.ToString()); + } + } +} diff --git a/src/AntiDuplWPF/AntiDuplWPF/Control/ComplexProgressBar.xaml b/src/AntiDuplWPF/AntiDuplWPF/Control/ComplexProgressBar.xaml index 16205838..571c5b5c 100644 --- a/src/AntiDuplWPF/AntiDuplWPF/Control/ComplexProgressBar.xaml +++ b/src/AntiDuplWPF/AntiDuplWPF/Control/ComplexProgressBar.xaml @@ -11,22 +11,18 @@ - + - - - - + @@ -35,11 +31,7 @@ x:Name="ProgressBarForeground" HorizontalAlignment="Left"> - - - - + @@ -49,8 +41,7 @@ FontFamily="Times" Foreground="Black" x:Name="ProgressText" - Margin="2,2,2,2"> 0% - + Margin="2,2,2,2" /> diff --git a/src/AntiDuplWPF/AntiDuplWPF/Control/ComplexProgressBar.xaml.cs b/src/AntiDuplWPF/AntiDuplWPF/Control/ComplexProgressBar.xaml.cs index bd1a08d3..a2af1a0b 100644 --- a/src/AntiDuplWPF/AntiDuplWPF/Control/ComplexProgressBar.xaml.cs +++ b/src/AntiDuplWPF/AntiDuplWPF/Control/ComplexProgressBar.xaml.cs @@ -66,8 +66,22 @@ private static void OnCurrentFirstChanged(DependencyObject sender, DependencyPro //e.Property = (double)e.NewValue + 5; //myControl.imgCurrent.Source = ((ImageInfoClass)e.NewValue).Image; - myControl.ProgressBarForeground.Width = (myControl.ActualWidth - 2) * myControl.CurrentFirst / myControl.Maximum; + try + { + if (myControl.ActualWidth > 0) + myControl.ProgressBarForeground.Width = (myControl.ActualWidth - 2) * myControl.CurrentFirst / myControl.Maximum; + } + catch (Exception ex) + { + + throw; + } + // myControl.ProgressBarForeground2.Width = (myControl.ActualWidth - 2) * myControl. / myControl.Maximum; + if (myControl.Maximum > 0) + myControl.ProgressText.Text = (((double)myControl.CurrentFirst / (double)myControl.Maximum) * 100).ToString("F2") + "%"; + else + myControl.ProgressText.Text = ""; } public static readonly DependencyProperty CurrentSecondProperty = @@ -89,7 +103,17 @@ public uint CurrentSecond private static void OnCurrentSecondChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { ComplexProgressBar myControl = sender as ComplexProgressBar; - myControl.ProgressBarForeground2.Width = (myControl.ActualWidth - 2) * myControl.CurrentSecond / myControl.Maximum; + try + { + if (myControl.ActualWidth > 0) + myControl.ProgressBarForeground2.Width = (myControl.ActualWidth - 2) * myControl.CurrentSecond / myControl.Maximum; + } + catch (Exception ex) + { + + throw; + } + } } diff --git a/src/AntiDuplWPF/AntiDuplWPF/Control/ImageInfoControl.xaml b/src/AntiDuplWPF/AntiDuplWPF/Control/ImageInfoControl.xaml new file mode 100644 index 00000000..94455214 --- /dev/null +++ b/src/AntiDuplWPF/AntiDuplWPF/Control/ImageInfoControl.xaml @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/AntiDuplWPF/AntiDuplWPF/Control/ImageInfoControl.xaml.cs b/src/AntiDuplWPF/AntiDuplWPF/Control/ImageInfoControl.xaml.cs new file mode 100644 index 00000000..9b6044ac --- /dev/null +++ b/src/AntiDuplWPF/AntiDuplWPF/Control/ImageInfoControl.xaml.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using AntiDuplWPF.ObjectModel; + +namespace AntiDuplWPF.Control +{ + /// + /// Логика взаимодействия для ImageInfoControl.xaml + /// + public partial class ImageInfoControl : UserControl + { + public ImageInfoControl() + { + InitializeComponent(); + } + + public static readonly DependencyProperty MainImageProperty = + DependencyProperty.Register("MainImage", typeof(ImageInfoClass), typeof(ImageInfoControl), + new PropertyMetadata(null, OnCurrentImageChanged)); + + public ImageInfoClass MainImage + { + get + { + return (ImageInfoClass)GetValue(MainImageProperty); + } + set + { + SetValue(MainImageProperty, value); + } + } + + + public static readonly DependencyProperty AdditionalImageProperty = + DependencyProperty.Register("AdditionalImage", typeof(ImageInfoClass), typeof(ImageInfoControl), + new PropertyMetadata(null, null)); + + public ImageInfoClass AdditionalImage + { + get + { + return (ImageInfoClass)GetValue(AdditionalImageProperty); + } + set + { + SetValue(AdditionalImageProperty, value); + } + } + + private static void OnCurrentImageChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) + { + ImageInfoControl myControl = sender as ImageInfoControl; + // Gestion des synchonisations des colonnes + //double width = (double)sender; + + //e.Property = (double)e.NewValue + 5; + //myControl.imgCurrent.Source = ((ImageInfoClass)e.NewValue).Image; + } + + + public static readonly DependencyProperty EnableInfoProperty = + DependencyProperty.Register("EnableInfo", typeof(bool), typeof(ImageInfoControl), + new PropertyMetadata(true, null)); + + public bool EnableInfo + { + get + { + return (bool)GetValue(EnableInfoProperty); + } + set + { + SetValue(EnableInfoProperty, value); + } + } + + public static readonly DependencyProperty GoodColorProperty = + DependencyProperty.Register("GoodColor", typeof(Color), typeof(ImageInfoControl), + new PropertyMetadata(null)); + + public Color GoodColor + { + get + { + return (Color)GetValue(GoodColorProperty); + } + set + { + SetValue(GoodColorProperty, value); + } + } + + public static readonly DependencyProperty BadColorProperty = + DependencyProperty.Register("BadColor", typeof(Color), typeof(ImageInfoControl), + new PropertyMetadata(null)); + + public Color BadColor + { + get + { + return (Color)GetValue(BadColorProperty); + } + set + { + SetValue(BadColorProperty, value); + } + } + + public static readonly DependencyProperty OpenComparatorForDuplPairCommandProperty = + DependencyProperty.Register("OpenComparatorForDuplPairCommand", typeof(ICommand), typeof(ImageInfoControl), + new PropertyMetadata(null)); + + public ICommand OpenComparatorForDuplPairCommand + { + get + { + return (ICommand)GetValue(OpenComparatorForDuplPairCommandProperty); + } + set + { + SetValue(OpenComparatorForDuplPairCommandProperty, value); + } + } + + public static readonly DependencyProperty ShowFullImageProperty = + DependencyProperty.Register("ShowFullImage", typeof(bool), typeof(ImageInfoControl), + new PropertyMetadata(false)); + + public bool ShowFullImage + { + get + { + return (bool)GetValue(ShowFullImageProperty); + } + set + { + SetValue(ShowFullImageProperty, value); + } + } + } +} diff --git a/src/AntiDuplWPF/AntiDuplWPF/Control/RenameImageTextBox.cs b/src/AntiDuplWPF/AntiDuplWPF/Control/RenameImageTextBox.cs index 5c384c9a..b0782f1d 100644 --- a/src/AntiDuplWPF/AntiDuplWPF/Control/RenameImageTextBox.cs +++ b/src/AntiDuplWPF/AntiDuplWPF/Control/RenameImageTextBox.cs @@ -6,7 +6,6 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -using System.Windows.Forms; using AntiDuplWPF.UndoRedo; using TinyIoC; using System.Windows.Input; diff --git a/src/AntiDuplWPF/AntiDuplWPF/Control/SearchControl.cs b/src/AntiDuplWPF/AntiDuplWPF/Control/SearchControl.cs new file mode 100644 index 00000000..9613fc01 --- /dev/null +++ b/src/AntiDuplWPF/AntiDuplWPF/Control/SearchControl.cs @@ -0,0 +1,122 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace AntiDuplWPF.Control +{ + public class SearchControl : ContentControl + { + #region Поля + //private TextBox _filterNameTextBox; + //private ComboBox _filterTypeComboBox; + //private CheckBox _isSearchByType; + //private Button _selectType; + //private TextBox _filterReplacementTextBox; + #endregion + + #region Конструкторы + + static SearchControl() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(SearchControl), new FrameworkPropertyMetadata(typeof(SearchControl))); + } + + #endregion + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + //_filterNameTextBox = Template.FindName("PART_FilterName", this) as TextBox; + //_filterTypeComboBox = Template.FindName("PART_FilterType", this) as ComboBox; + //_isSearchByType = Template.FindName("PART_IsSearchByType", this) as CheckBox; + //_selectType = Template.FindName("PART_SelectType", this) as Button; + //_filterReplacementTextBox = Template.FindName("PART_FilterReplacement", this) as TextBox; + //_filterTypeComboBox.ItemsSource = MainViewModel.AvailableTypeOfTool; + } + + #region Свойства зависимостей + + //public string FilterName + //{ + // get { return (string)GetValue(FilterNameProperty); } + // set { SetValue(FilterNameProperty, value); } + //} + + //public static readonly DependencyProperty FilterNameProperty = DependencyProperty.Register("FilterName", + // typeof(string), typeof(SearchControl), new PropertyMetadata(default(string))); + + //public string FilterType + //{ + // get { return (string)GetValue(FilterTypeProperty); } + // set { SetValue(FilterTypeProperty, value); } + //} + + //public static readonly DependencyProperty FilterTypeProperty = DependencyProperty.Register("FilterType", + // typeof(string), typeof(FiltrationControl), new PropertyMetadata(default(string))); + + //public bool IsSearchByType + //{ + // get { return (bool)GetValue(IsSearchByTypeProperty); } + // set { SetValue(IsSearchByTypeProperty, value); } + //} + + public ICommand SearchCommand + { + get { return (ICommand)GetValue(SearchCommandProperty); } + set { SetValue(SearchCommandProperty, value); } + } + + public static readonly DependencyProperty SearchCommandProperty = DependencyProperty.Register("SearchCommand", + typeof(ICommand), typeof(SearchControl), new PropertyMetadata(null)); + + public ICommand ClearCommand + { + get { return (ICommand)GetValue(ClearCommandProperty); } + set { SetValue(ClearCommandProperty, value); } + } + + public static readonly DependencyProperty ClearCommandProperty = DependencyProperty.Register("ClearCommand", + typeof(ICommand), typeof(SearchControl), new PropertyMetadata(null)); + + + public string SearchText + { + get { return (string)GetValue(SearchTextProperty); } + set { SetValue(SearchTextProperty, value); } + } + + public static readonly DependencyProperty SearchTextProperty = DependencyProperty.Register("SearchText", + typeof(string), typeof(SearchControl), new PropertyMetadata("", OnSearchTextChanged)); + + static void OnSearchTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + SearchControl control = d as SearchControl; + if (String.IsNullOrEmpty((string)e.NewValue) && !String.IsNullOrEmpty((string)e.OldValue) + && d != null && control.ClearCommand != null) + control.ClearCommand.Execute(null); + } + + public string Watermark + { + get { return (string)GetValue(WatermarkProperty); } + set { SetValue(WatermarkProperty, value); } + } + + public static readonly DependencyProperty WatermarkProperty = DependencyProperty.Register("Watermark", + typeof(string), typeof(SearchControl), new PropertyMetadata("Поиск")); + + #endregion + + } +} diff --git a/src/AntiDuplWPF/AntiDuplWPF/Control/SearchControlTheme.xaml b/src/AntiDuplWPF/AntiDuplWPF/Control/SearchControlTheme.xaml new file mode 100644 index 00000000..2712e949 --- /dev/null +++ b/src/AntiDuplWPF/AntiDuplWPF/Control/SearchControlTheme.xaml @@ -0,0 +1,70 @@ + + + + + + \ No newline at end of file diff --git a/src/AntiDuplWPF/AntiDuplWPF/Convertor/ColorToSolidColorBrushConverter.cs b/src/AntiDuplWPF/AntiDuplWPF/Convertor/ColorToSolidColorBrushConverter.cs new file mode 100644 index 00000000..51b089d1 --- /dev/null +++ b/src/AntiDuplWPF/AntiDuplWPF/Convertor/ColorToSolidColorBrushConverter.cs @@ -0,0 +1,30 @@ +using System; +using System.Globalization; +using System.Windows.Data; +using System.Windows.Media; + +namespace AntiDuplWPF.Convertor +{ + public sealed class ColorToSolidColorBrushConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (!(value is Color)) + return value; + + var brush = new SolidColorBrush((Color) value); + brush.Freeze(); + + return brush; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + var brush = value as SolidColorBrush; + if (brush == null) + throw new Exception("Provided value is not brush"); + + return brush.Color; + } + } +} \ No newline at end of file diff --git a/src/AntiDuplWPF/AntiDuplWPF/Convertor/DeleteBackgroundValueConverter.cs b/src/AntiDuplWPF/AntiDuplWPF/Convertor/DeleteBackgroundValueConverter.cs new file mode 100644 index 00000000..e3d4446c --- /dev/null +++ b/src/AntiDuplWPF/AntiDuplWPF/Convertor/DeleteBackgroundValueConverter.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using System.Windows.Media; +using AntiDuplWPF.ObjectModel; +using AntiDuplWPF.ViewModel; + +namespace AntiDuplWPF.Convertor +{ + public class DeleteBackgroundValueConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + DuplPairViewModel result = value as DuplPairViewModel; + PositionInDuplPair position = (PositionInDuplPair)parameter; + if (result != null && position != null) + { + if (result.FirstFile.UtilityIndex > result.SecondFile.UtilityIndex) + { + if (position == PositionInDuplPair.Second) + return new SolidColorBrush(Colors.LightCoral); + } + else if (result.FirstFile.UtilityIndex < result.SecondFile.UtilityIndex) + { + if (position == PositionInDuplPair.First) + return new SolidColorBrush(Colors.LightCoral); + } + } + + return new SolidColorBrush(); + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/AntiDuplWPF/AntiDuplWPF/Convertor/DifferenceValueConverter.cs b/src/AntiDuplWPF/AntiDuplWPF/Convertor/DifferenceValueConverter.cs new file mode 100644 index 00000000..ca9ce6b9 --- /dev/null +++ b/src/AntiDuplWPF/AntiDuplWPF/Convertor/DifferenceValueConverter.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using System.Windows.Media; + +namespace AntiDuplWPF.Convertor +{ + public class DifferenceValueConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + double difference = (double)value; + if (difference != null) + { + if (difference == 0.0) + return new SolidColorBrush(Colors.LightGreen); + } + + return new SolidColorBrush(); + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/AntiDuplWPF/AntiDuplWPF/Convertor/DuplResultMultiValueConverter.cs b/src/AntiDuplWPF/AntiDuplWPF/Convertor/DuplResultMultiValueConverter.cs index 73eefae0..ce01588a 100644 --- a/src/AntiDuplWPF/AntiDuplWPF/Convertor/DuplResultMultiValueConverter.cs +++ b/src/AntiDuplWPF/AntiDuplWPF/Convertor/DuplResultMultiValueConverter.cs @@ -33,18 +33,27 @@ public object Convert(object[] values, Type targetType, object parameter, System return position == PositionInDuplPair.First ? new SolidColorBrush(badColor) : new SolidColorBrush(goodColor); else return position == PositionInDuplPair.Second ? new SolidColorBrush(badColor) : new SolidColorBrush(goodColor); - //чем выше JpegQuality тем лучше изображение - case MaxProperty.JpegQuality: - if (result.FirstFile.JpegQuality == result.SecondFile.JpegQuality) + //чем ниже Blockiness тем лучше изображение + case MaxProperty.Blockiness: + if (result.FirstFile.Blockiness == result.SecondFile.Blockiness) return new SolidColorBrush(); - if (result.FirstFile.JpegQuality < result.SecondFile.JpegQuality) + if (result.FirstFile.Blockiness > result.SecondFile.Blockiness) return position == PositionInDuplPair.First ? new SolidColorBrush(badColor) : new SolidColorBrush(goodColor); else return position == PositionInDuplPair.Second ? new SolidColorBrush(badColor) : new SolidColorBrush(goodColor); - case MaxProperty.Sharpness: - if (result.FirstFile.Sharpness == result.SecondFile.Sharpness) + //чем ниже Bluring тем лучше изображение + case MaxProperty.Bluring: + if (result.FirstFile.Bluring == result.SecondFile.Bluring) return new SolidColorBrush(); - if (result.FirstFile.Sharpness < result.SecondFile.Sharpness) + if (result.FirstFile.Bluring > result.SecondFile.Bluring) + return position == PositionInDuplPair.First ? new SolidColorBrush(badColor) : new SolidColorBrush(goodColor); + else + return position == PositionInDuplPair.Second ? new SolidColorBrush(badColor) : new SolidColorBrush(goodColor); + //чем меньше JpegPeaks, тем лучше изображение + case MaxProperty.JpegPeaks: + if (result.FirstFile.JpegPeaks == result.SecondFile.JpegPeaks) + return new SolidColorBrush(); + if (result.FirstFile.JpegPeaks > result.SecondFile.JpegPeaks) return position == PositionInDuplPair.First ? new SolidColorBrush(badColor) : new SolidColorBrush(goodColor); else return position == PositionInDuplPair.Second ? new SolidColorBrush(badColor) : new SolidColorBrush(goodColor); diff --git a/src/AntiDuplWPF/AntiDuplWPF/Convertor/ImageBackgroundMultiValueConverter.cs b/src/AntiDuplWPF/AntiDuplWPF/Convertor/ImageBackgroundMultiValueConverter.cs new file mode 100644 index 00000000..2f9b9102 --- /dev/null +++ b/src/AntiDuplWPF/AntiDuplWPF/Convertor/ImageBackgroundMultiValueConverter.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Data; +using System.Windows.Media; +using AntiDuplWPF.ObjectModel; + +namespace AntiDuplWPF.Convertor +{ + public class ImageBackgroundMultiValueConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + if (values[0] != null && values[0] is ImageInfoClass + && values[1] != null && values[1] is ImageInfoClass + && values[2] != DependencyProperty.UnsetValue + && values[3] != DependencyProperty.UnsetValue) + { + ImageInfoClass mainImage = values[0] as ImageInfoClass; + ImageInfoClass additionalImage = values[1] as ImageInfoClass; + System.Windows.Media.Color goodColor = (System.Windows.Media.Color)values[2]; + System.Windows.Media.Color badColor = (System.Windows.Media.Color)values[3]; + + switch ((MaxProperty)parameter) + { + //чем ниже Blockiness тем лучше изображение + case MaxProperty.Blockiness: + if (mainImage.Blockiness == additionalImage.Blockiness) + return new SolidColorBrush(); + if (mainImage.Blockiness < additionalImage.Blockiness) + return new SolidColorBrush(badColor); + break; + case MaxProperty.Bluring: + if (mainImage.Bluring == additionalImage.Bluring) + return new SolidColorBrush(); + if (mainImage.Bluring < additionalImage.Bluring) + return new SolidColorBrush(badColor); + break; + case MaxProperty.FileSize: + if (mainImage.FileSize == additionalImage.FileSize) + return new SolidColorBrush(); + if (mainImage.FileSize < additionalImage.FileSize) + return new SolidColorBrush(badColor); + break; + case MaxProperty.Resolution: + if (mainImage.Width * mainImage.Height == additionalImage.Width * additionalImage.Height) + return new SolidColorBrush(); + if (mainImage.Width * mainImage.Height < additionalImage.Width * additionalImage.Height) + return new SolidColorBrush(badColor); + break; + //case MaxProperty.EXIF: + // if (mainImage.EXIF.Equals(additionalImage.EXIF)) + // return new SolidColorBrush(); + // else + // return new SolidColorBrush(badColor); + case MaxProperty.UtilityIndex: + if (mainImage.UtilityIndex.Equals(additionalImage.UtilityIndex)) + return new SolidColorBrush(); + if (mainImage.UtilityIndex < additionalImage.UtilityIndex) + return new SolidColorBrush(badColor); + break; + } + return new SolidColorBrush(goodColor); + } + return new SolidColorBrush(); + } + + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/AntiDuplWPF/AntiDuplWPF/Convertor/ListToBackgroundMultiValueConverter.cs b/src/AntiDuplWPF/AntiDuplWPF/Convertor/ListToBackgroundMultiValueConverter.cs index ddc8b183..3f83a5b6 100644 --- a/src/AntiDuplWPF/AntiDuplWPF/Convertor/ListToBackgroundMultiValueConverter.cs +++ b/src/AntiDuplWPF/AntiDuplWPF/Convertor/ListToBackgroundMultiValueConverter.cs @@ -25,34 +25,68 @@ public object Convert(object[] values, Type targetType, object parameter, System System.Windows.Media.Color badColor = (System.Windows.Media.Color)values[3]; MaxProperty property = (MaxProperty)parameter; - ulong maxUint = 0; + uint maxUint = 0; double maxDouble = 0.0; decimal maxDecimal = 0; - //uint min = uint.MaxValue; + ulong maxUlong = 0UL; + + uint minUint = 0; + double minDouble = 0.0; + decimal minDecimal = 0; + ulong minUlong = 0UL; + foreach (ImageInfoClass info in (IEnumerable)values[0]) { switch (property) { case MaxProperty.FileSize: - if (info.FileSize > maxUint) - maxUint = info.FileSize; + if (info.FileSize > maxUlong) + maxUlong = info.FileSize; + if (minUlong == 0UL) + minUlong = info.FileSize; + else if (info.FileSize < minUlong) + minUlong = info.FileSize; + break; + case MaxProperty.Blockiness: + if (info.Blockiness > maxDouble) + maxDouble = info.Blockiness; + if (minDouble == 0.0) + minDouble = info.Blockiness; + else if (info.Blockiness < minDouble) + minDouble = info.Blockiness; break; - case MaxProperty.JpegQuality: - if (info.JpegQuality > maxDouble) - maxDouble = info.JpegQuality; + case MaxProperty.Bluring: + if (info.Bluring > maxDouble) + maxDouble = info.Bluring; + if (minDouble == 0.0) + minDouble = info.Bluring; + else if (info.Bluring < minDouble) + minDouble = info.Bluring; break; - case MaxProperty.Sharpness: - if (info.Sharpness > maxDouble) - maxDouble = info.Sharpness; + case MaxProperty.JpegPeaks: + if (info.JpegPeaks > maxUint) + maxUint = info.JpegPeaks; + if (minUint == 0.0) + minUint = info.JpegPeaks; + else if (info.JpegPeaks < minUint) + minUint = info.JpegPeaks; break; case MaxProperty.Resolution: if (info.Width * info.Height > maxUint) maxUint = info.Width * info.Height; + if (minUint == 0.0) + minUint = info.Width * info.Height; + else if (info.Width * info.Height < minUint) + minUint = info.Width * info.Height; break; case MaxProperty.UtilityIndex: if (info.UtilityIndex > maxDecimal) maxDecimal = info.UtilityIndex; + if (minDecimal == 0) + minDecimal = info.UtilityIndex; + else if (info.UtilityIndex < minDecimal) + minDecimal = info.UtilityIndex; break; } } @@ -60,22 +94,36 @@ public object Convert(object[] values, Type targetType, object parameter, System switch (property) { case MaxProperty.FileSize: - if ((uint)values[1] == maxUint - && maxUint != 0) + if (minUlong == maxUlong) + return new SolidColorBrush(); + if ((ulong)values[1] == maxUlong + && maxUlong != 0) + return new SolidColorBrush(goodColor); + break; + case MaxProperty.JpegPeaks: + if (maxUint == minUint) + return new SolidColorBrush(); + if ((uint)values[1] == minUint && minUint != 0) return new SolidColorBrush(goodColor); break; case MaxProperty.Resolution: + if (maxUint == minUint) + return new SolidColorBrush(); if ((uint)values[1] * (uint)values[4] == maxUint && maxUint != 0) return new SolidColorBrush(goodColor); break; - case MaxProperty.JpegQuality: - case MaxProperty.Sharpness: - if ((double)values[1] == maxDouble - && maxDouble != 0.0) + case MaxProperty.Blockiness: + case MaxProperty.Bluring: + if (maxDouble == minDouble) + return new SolidColorBrush(); + if ((double)values[1] == minDouble + && minDouble != 0.0) return new SolidColorBrush(goodColor); break; case MaxProperty.UtilityIndex: + if (maxDecimal == minDecimal) + return new SolidColorBrush(); if ((decimal)values[1] == maxDecimal && maxDecimal != 0) return new SolidColorBrush(goodColor); diff --git a/src/AntiDuplWPF/AntiDuplWPF/Convertor/MaxProperty.cs b/src/AntiDuplWPF/AntiDuplWPF/Convertor/MaxProperty.cs index c640a8b5..205f6526 100644 --- a/src/AntiDuplWPF/AntiDuplWPF/Convertor/MaxProperty.cs +++ b/src/AntiDuplWPF/AntiDuplWPF/Convertor/MaxProperty.cs @@ -8,8 +8,9 @@ namespace AntiDuplWPF.Convertor { public enum MaxProperty { - JpegQuality, - Sharpness, + Blockiness, + Bluring, + JpegPeaks, FileSize, Resolution, EXIF, diff --git a/src/AntiDuplWPF/AntiDuplWPF/Convertor/StringToVisibilityConverter.cs b/src/AntiDuplWPF/AntiDuplWPF/Convertor/StringToVisibilityConverter.cs new file mode 100644 index 00000000..a7b21866 --- /dev/null +++ b/src/AntiDuplWPF/AntiDuplWPF/Convertor/StringToVisibilityConverter.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Data; + +namespace AntiDuplWPF.Convertor +{ + [ValueConversion(typeof(string), typeof(Visibility))] + public class StringToVisibilityConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (!String.IsNullOrEmpty(value as string)) + { + return Visibility.Visible; + } + return Visibility.Collapsed; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/AntiDuplWPF/AntiDuplWPF/Convertor/ViewModeToVisibilityConverter.cs b/src/AntiDuplWPF/AntiDuplWPF/Convertor/ViewModeToVisibilityConverter.cs new file mode 100644 index 00000000..5637ca3d --- /dev/null +++ b/src/AntiDuplWPF/AntiDuplWPF/Convertor/ViewModeToVisibilityConverter.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Data; +using AntiDuplWPF.ObjectModel; + +namespace AntiDuplWPF.Convertor +{ + [ValueConversion(typeof(ViewMode), typeof(Visibility))] + public class ViewModeToVisibilityConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + var par = (ViewMode)parameter; + var viewMode = (ViewMode)value; + if (viewMode == par) + { + return Visibility.Visible; + } + return Visibility.Collapsed; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/AntiDuplWPF/AntiDuplWPF/Core/AdvancedOption.cs b/src/AntiDuplWPF/AntiDuplWPF/Core/AdvancedOption.cs new file mode 100644 index 00000000..a15f76be --- /dev/null +++ b/src/AntiDuplWPF/AntiDuplWPF/Core/AdvancedOption.cs @@ -0,0 +1,125 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace AntiDuplWPF.Core +{ + [Serializable] + [StructLayout(LayoutKind.Sequential)] + public class AdvancedOption : INotifyPropertyChanged + { + [MarshalAs(UnmanagedType.I4)] + int _ratioResolution; + [MarshalAs(UnmanagedType.I4)] + int _compareThreadCount; + [MarshalAs(UnmanagedType.I4)] + int _collectThreadCount; + [MarshalAs(UnmanagedType.I4)] + int _reducedImageSize; + [MarshalAs(UnmanagedType.I4)] + int _resultCountMax; + [MarshalAs(UnmanagedType.I4)] + int _ignoreFrameWidth; + [MarshalAs(UnmanagedType.U1)] + bool _useImageDataBase; + + public AdvancedOption() + { + _useImageDataBase = true; + _ratioResolution = 32; + _reducedImageSize = 32; + _resultCountMax = 100000; + _ignoreFrameWidth = 0; + _collectThreadCount = _compareThreadCount = Environment.ProcessorCount; + } + + public int RatioResolution + { + get { return _ratioResolution; } + set + { + _ratioResolution = value; + NotifyPropertyChanged("RatioResolution"); + } + } + + public int CompareThreadCount + { + get { return _compareThreadCount; } + set + { + _compareThreadCount = value; + NotifyPropertyChanged("CompareThreadCount"); + } + } + + public int CollectThreadCount + { + get { return _collectThreadCount; } + set + { + _collectThreadCount = value; + NotifyPropertyChanged("CollectThreadCount"); + } + } + + public int ReducedImageSize + { + get { return _reducedImageSize; } + set + { + _reducedImageSize = value; + NotifyPropertyChanged("ReducedImageSize"); + } + } + + public int ResultCountMax + { + get { return _resultCountMax; } + set + { + _resultCountMax = value; + NotifyPropertyChanged("ResultCountMax"); + } + } + + public int IgnoreFrameWidth + { + get { return _ignoreFrameWidth; } + set + { + _ignoreFrameWidth = value; + NotifyPropertyChanged("IgnoreFrameWidth"); + } + } + + public bool UseImageDataBase + { + get { return _useImageDataBase; } + set + { + _useImageDataBase = value; + NotifyPropertyChanged("UseImageDataBase"); + } + } + + #region Члены INotifyPropertyChanged + + public event PropertyChangedEventHandler PropertyChanged; + + // This method is called by the Set accessor of each property. + // The CallerMemberName attribute that is applied to the optional propertyName + // parameter causes the property name of the caller to be substituted as an argument. + private void NotifyPropertyChanged(string propertyName) + { + if (PropertyChanged != null) + PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } + + #endregion + } +} diff --git a/src/AntiDuplWPF/AntiDuplWPF/Core/CompareOption.cs b/src/AntiDuplWPF/AntiDuplWPF/Core/CompareOption.cs index 188812ea..935de71c 100644 --- a/src/AntiDuplWPF/AntiDuplWPF/Core/CompareOption.cs +++ b/src/AntiDuplWPF/AntiDuplWPF/Core/CompareOption.cs @@ -33,11 +33,21 @@ public class CompareOption : INotifyPropertyChanged [MarshalAs(UnmanagedType.U1)] bool _compareInsideOneSearchPath; [MarshalAs(UnmanagedType.I4)] - CoreDll.AlgorithmComparing _algorithmComparing; + AlgorithmComparing _algorithmComparing; public CompareOption() { _checkOnEquality = true; + _transformedImage = true; + _sizeControl = false; + _typeControl = false; + _ratioControl = false; + _thresholdDifference = 5; + _minimalImageSize = 64; + _maximalImageSize = 16328; + _compareInsideOneFolder = true; + _compareInsideOneSearchPath = true; + _algorithmComparing = Core.AlgorithmComparing.SquaredSum; } public bool CheckOnEquality @@ -120,6 +130,36 @@ public int MaximalImageSize } } + public bool CompareInsideOneFolder + { + get { return _compareInsideOneFolder; } + set + { + _compareInsideOneFolder = value; + NotifyPropertyChanged("CompareInsideOneFolder"); + } + } + + public bool CompareInsideOneSearchPath + { + get { return _compareInsideOneSearchPath; } + set + { + _compareInsideOneSearchPath = value; + NotifyPropertyChanged("CompareInsideOneSearchPath"); + } + } + + public AlgorithmComparing AlgorithmComparing + { + get { return _algorithmComparing; } + set + { + _algorithmComparing = value; + NotifyPropertyChanged("AlgorithmComparing"); + } + } + #region Члены INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged; diff --git a/src/AntiDuplWPF/AntiDuplWPF/Core/CoreDll.cs b/src/AntiDuplWPF/AntiDuplWPF/Core/CoreDll.cs index 5a03f576..2606b7bc 100644 --- a/src/AntiDuplWPF/AntiDuplWPF/Core/CoreDll.cs +++ b/src/AntiDuplWPF/AntiDuplWPF/Core/CoreDll.cs @@ -7,10 +7,17 @@ namespace AntiDuplWPF.Core { + //надо вынести из класса, иначе comboBox не увидит + public enum AlgorithmComparing : int + { + SquaredSum = 0, + SSIM = 1, + }; + public class CoreDll : DynamicModule { public CoreDll() - : base("AntiDupl64.dll") + : base(IntPtr.Size == 8 ? "AntiDupl64.dll" : "AntiDupl32.dll") { } @@ -137,14 +144,9 @@ public enum ImageType : int Psd = 11, Dds = 12, Tga = 13, + Webp = 14, } - public enum AlgorithmComparing : int - { - SquaredSum = 0, - SSIM = 1, - }; - public enum OptionsType : int { SetDefault = -1, @@ -154,6 +156,12 @@ public enum OptionsType : int Advanced = 3, } + public enum PixelFormatType : int + { + None = 0, + Argb32 = 1, + } + //-----------API structures-------------------------------------------- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] @@ -202,7 +210,23 @@ public struct adImageInfoW public uint height; public double blockiness; public double blurring; + public uint jpegPeaks; public adImageExifW exifInfo; + + public adImageInfoW(ObjectModel.ImageInfoClass i) + : this() + { + //id = IntPtr.Zero; + path = i.Path; + size = i.FileSize; + path = i.Path; + jpegPeaks = i.JpegPeaks; + blockiness = i.Blockiness; + blurring = i.Bluring; + width = i.Width; + height = i.Height; + type = i.Type; + } } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] @@ -219,14 +243,63 @@ public class adResultW public IntPtr group; public IntPtr groupSize; public HintType hint; + + //public adResultW(ViewModel.DuplPairViewModel d) + //{ + // difference = d.Difference; + // transform = d.Transform; + // type = d.Type; + + // first.path = d.FirstFile.Path; + // first.jpegPeaks = d.FirstFile.JpegPeaks; + // first.blockiness = d.FirstFile.Blockiness; + // first.blurring = d.FirstFile.Bluring; + // first.size = d.FirstFile.FileSize; + // first.width = d.FirstFile.Width; + // first.height = d.FirstFile.Height; + // first.type = d.FirstFile.Type; + + // second.path = d.SecondFile.Path; + // second.jpegPeaks = d.SecondFile.JpegPeaks; + // second.blockiness = d.SecondFile.Blockiness; + // second.blurring = d.SecondFile.Bluring; + // second.size = d.SecondFile.FileSize; + // second.width = d.SecondFile.Width; + // second.height = d.SecondFile.Height; + // second.type = d.SecondFile.Type; + //} + } + + [StructLayout(LayoutKind.Sequential)] + public struct adBitmap + { + public uint width; + public uint height; + public int stride; + public PixelFormatType format; + public IntPtr data; + } + + + public delegate bool CancellationPendingCallback(); + + [StructLayout(LayoutKind.Sequential)] + public class WorkProgressInteropNegotiator + { + public CancellationPendingCallback cancellationPending; + +#pragma warning disable 0649 + // C# does not see this member is set up in native code, we disable warning to avoid it. + public bool cancel; +#pragma warning restore 0649 } //-------------------API functions:------------------------------------ - [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)] - public delegate IntPtr adCreate_fn(string userPath); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void adCreate_fn(); [DynamicModuleApi] - public adCreate_fn adCreateW = null; + public adCreate_fn adCreate = null; [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)] public delegate Error adRelease_fn(); @@ -277,5 +350,31 @@ public class adResultW public delegate Error adSetSearchOptions_fn([In, Out] SearchOption options); [DynamicModuleApi] public adSetSearchOptions_fn adSetSearchOptions = null; + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate Error adSetAdvancedOptions_fn([In, Out] AdvancedOption options); + [DynamicModuleApi] + public adSetAdvancedOptions_fn adSetAdvancedOptions = null; + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate Error adSetCompareOption_fn([In, Out] CompareOption options); + [DynamicModuleApi] + public adSetCompareOption_fn adSetCompareOption = null; + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate Error adSetDefectOption_fn([In, Out] DefectOption options); + [DynamicModuleApi] + public adSetDefectOption_fn adSetDefectOption = null; + + [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)] + public delegate Error adLoadBitmapW_fn(string fileName, IntPtr pBitmap); + [DynamicModuleApi] + public adLoadBitmapW_fn adLoadBitmapW = null; + + [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)] + public delegate Error adCalculateMultiImageMetric_fn([In, Out] adImageInfoW[] fileArray, int size, [In, Out] WorkProgressInteropNegotiator negotiator); + [DynamicModuleApi] + public adCalculateMultiImageMetric_fn adCalculateMultiImageMetric = null; + } } diff --git a/src/AntiDuplWPF/AntiDuplWPF/Core/CoreLib.cs b/src/AntiDuplWPF/AntiDuplWPF/Core/CoreLib.cs index 23a6018e..8a9052eb 100644 --- a/src/AntiDuplWPF/AntiDuplWPF/Core/CoreLib.cs +++ b/src/AntiDuplWPF/AntiDuplWPF/Core/CoreLib.cs @@ -9,13 +9,13 @@ namespace AntiDuplWPF.Core { - public class CoreLib : IDisposable + public class CoreLib : AntiDuplWPF.Core.ICoreLib { private CoreDll _dll = null; //-----------Public functions---------------------------------------------- - public CoreLib(string userPath) + public CoreLib() { try { @@ -25,7 +25,7 @@ public CoreLib(string userPath) { throw new Exception("Can't load core library! " + Environment.NewLine + ex.Message); } - _dll.adCreateW(userPath); + _dll.adCreate(); } ~CoreLib() @@ -64,7 +64,16 @@ public bool Stop() public bool Search() { - return _dll.adSearch() == CoreDll.Error.Ok; + try + { + return _dll.adSearch() == CoreDll.Error.Ok; + } + catch (Exception) + { + + throw; + } + return false; } //public CoreDll.Status2 GetStatus() @@ -95,9 +104,12 @@ public CoreStatus StatusGet(CoreDll.ThreadType threadType, int threadId) public bool SetLocation(IEnumerable locations, CoreDll.PathType pathType) { _dll.adClearLocations(pathType); - foreach (Location item in locations) + foreach (Location location in locations) { - _dll.adAddLocations(pathType, item); + if (location.Path.Last() == '\\' + || location.Path.Last() == '/') + throw new Exception("Location end with slash!"); + _dll.adAddLocations(pathType, location); } return true; } @@ -115,7 +127,15 @@ public DuplPairViewModel[] GetResult() // Initialize unmanged memory to hold the struct. IntPtr ptr = Marshal.AllocHGlobal(elemSize); - _dll.adGetResult(ptr, i); + try + { + _dll.adGetResult(ptr, i); + } + catch (Exception) + { + throw; + } + CoreDll.adResultW dpExport = (CoreDll.adResultW)Marshal.PtrToStructure(ptr, typeof(CoreDll.adResultW)); result.Add(new DuplPairViewModel(dpExport)); @@ -137,5 +157,31 @@ public void SetSearchOptions(SearchOption options) { _dll.adSetSearchOptions(options); } + + public void SetAdvancedOptions(AdvancedOption options) + { + _dll.adSetAdvancedOptions(options); + } + + public void SetCompareOptions(CompareOption options) + { + _dll.adSetCompareOption(options); + } + + public void SetDefectOptions(DefectOption options) + { + _dll.adSetDefectOption(options); + } + + public bool LoadBitmap(string fileName, IntPtr pBitmap) + { + return _dll.adLoadBitmapW(fileName, pBitmap) == CoreDll.Error.Ok; + } + + + public void CalculateHistogramPeaks(CoreDll.adImageInfoW[] array, CoreDll.WorkProgressInteropNegotiator negotiator) + { + _dll.adCalculateMultiImageMetric(array, array.Length, negotiator); + } } } diff --git a/src/AntiDuplWPF/AntiDuplWPF/Core/DefectOption.cs b/src/AntiDuplWPF/AntiDuplWPF/Core/DefectOption.cs new file mode 100644 index 00000000..1da8b5f1 --- /dev/null +++ b/src/AntiDuplWPF/AntiDuplWPF/Core/DefectOption.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + + +namespace AntiDuplWPF.Core +{ + [Serializable] + [StructLayout(LayoutKind.Sequential)] + public class DefectOption : INotifyPropertyChanged + { + [MarshalAs(UnmanagedType.U1)] + bool _checkOnDefect; + [MarshalAs(UnmanagedType.U1)] + bool _checkOnBlockiness; + [MarshalAs(UnmanagedType.I4)] + int _blockinessThreshold; + [MarshalAs(UnmanagedType.U1)] + bool _checkOnBlockinessOnlyNotJpeg; + [MarshalAs(UnmanagedType.U1)] + bool _checkOnBlurring; + [MarshalAs(UnmanagedType.I4)] + int _blurringThreshold; + + public DefectOption() + { + _checkOnDefect = true; + _checkOnBlockiness = false; + _blockinessThreshold = 10; + _checkOnBlockinessOnlyNotJpeg = false; + _checkOnBlurring = false; + _blurringThreshold = 4; + } + + public bool CheckOnDefect + { + get { return _checkOnDefect; } + set + { + _checkOnDefect = value; + NotifyPropertyChanged("CheckOnDefect"); + } + } + + public bool CheckOnBlockiness + { + get { return _checkOnBlockiness; } + set + { + _checkOnBlockiness = value; + NotifyPropertyChanged("CheckOnBlockiness"); + } + } + + public int BlockinessThreshold + { + get { return _blockinessThreshold; } + set + { + _blockinessThreshold = value; + NotifyPropertyChanged("BlockinessThreshold"); + } + } + + public bool CheckOnBlockinessOnlyNotJpeg + { + get { return _checkOnBlockinessOnlyNotJpeg; } + set + { + _checkOnBlockinessOnlyNotJpeg = value; + NotifyPropertyChanged("CheckOnBlockinessOnlyNotJpeg"); + } + } + + public bool CheckOnBlurring + { + get { return _checkOnBlurring; } + set + { + _checkOnBlurring = value; + NotifyPropertyChanged("CheckOnBlurring"); + } + } + + public int BlurringThreshold + { + get { return _blurringThreshold; } + set + { + _blurringThreshold = value; + NotifyPropertyChanged("BlurringThreshold"); + } + } + + #region Члены INotifyPropertyChanged + + public event PropertyChangedEventHandler PropertyChanged; + + // This method is called by the Set accessor of each property. + // The CallerMemberName attribute that is applied to the optional propertyName + // parameter causes the property name of the caller to be substituted as an argument. + private void NotifyPropertyChanged(string propertyName) + { + if (PropertyChanged != null) + PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } + + #endregion + } +} diff --git a/src/AntiDuplWPF/AntiDuplWPF/Core/ICoreLib.cs b/src/AntiDuplWPF/AntiDuplWPF/Core/ICoreLib.cs new file mode 100644 index 00000000..d90720cc --- /dev/null +++ b/src/AntiDuplWPF/AntiDuplWPF/Core/ICoreLib.cs @@ -0,0 +1,23 @@ +using System; +namespace AntiDuplWPF.Core +{ + public interface ICoreLib : IDisposable + { + void Dispose(); + + bool LoadBitmap(string fileName, IntPtr pBitmap); + + AntiDuplWPF.ViewModel.DuplPairViewModel[] GetResult(); + void Release(); + bool Search(); + void SetAdvancedOptions(AdvancedOption options); + void SetCompareOptions(CompareOption options); + void SetDefectOptions(DefectOption options); + bool SetLocation(System.Collections.Generic.IEnumerable locations, CoreDll.PathType pathType); + void SetSearchOptions(SearchOption options); + CoreStatus StatusGet(CoreDll.ThreadType threadType, int threadId); + bool Stop(); + + void CalculateHistogramPeaks(CoreDll.adImageInfoW[] array, CoreDll.WorkProgressInteropNegotiator negotiator); + } +} diff --git a/src/AntiDuplWPF/AntiDuplWPF/Core/Location.cs b/src/AntiDuplWPF/AntiDuplWPF/Core/Location.cs index f56e5bdd..c1ce6ecf 100644 --- a/src/AntiDuplWPF/AntiDuplWPF/Core/Location.cs +++ b/src/AntiDuplWPF/AntiDuplWPF/Core/Location.cs @@ -84,7 +84,7 @@ public bool SetPath(string path, out string error) error = String.Empty; if (IOHelper.IsDirectory(path)) { - _path = path; + _path = path.TrimEnd(new [] { '\\', '/' }); _isDirectory = true; return true; } diff --git a/src/AntiDuplWPF/AntiDuplWPF/Core/SearchOption.cs b/src/AntiDuplWPF/AntiDuplWPF/Core/SearchOption.cs index 3f8b8e21..fda80d23 100644 --- a/src/AntiDuplWPF/AntiDuplWPF/Core/SearchOption.cs +++ b/src/AntiDuplWPF/AntiDuplWPF/Core/SearchOption.cs @@ -44,10 +44,12 @@ public class SearchOption : INotifyPropertyChanged bool DDS; [MarshalAs(UnmanagedType.U1)] bool TGA; + [MarshalAs(UnmanagedType.U1)] + bool WEBP; public SearchOption() { - JPEG = BMP = GIF = PNG = TIFF = EMF = WMF = EXIF = ICON = JP2 = PSD = DDS = TGA = true; + JPEG = BMP = GIF = PNG = TIFF = EMF = WMF = EXIF = ICON = JP2 = PSD = DDS = TGA = WEBP = true; } diff --git a/src/AntiDuplWPF/AntiDuplWPF/Helper/DataGridColumnChooserHelper.cs b/src/AntiDuplWPF/AntiDuplWPF/Helper/DataGridColumnChooserHelper.cs new file mode 100644 index 00000000..67b6122d --- /dev/null +++ b/src/AntiDuplWPF/AntiDuplWPF/Helper/DataGridColumnChooserHelper.cs @@ -0,0 +1,152 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; + +namespace AntiDuplWPF.Helper +{ + public sealed class ReferenceEqualityComparer : IEqualityComparer + { + public static readonly IEqualityComparer DefaultInstance = new ReferenceEqualityComparer(); + + public bool Equals(T x, T y) + { + return ReferenceEquals(x, y); + } + + public int GetHashCode(T obj) + { + return 0; + } + } + + public static class DataGridColumnChooserHelper + { + private static readonly Dictionary ms_Grids = new Dictionary(); + private static readonly Dictionary ms_Buttons = new Dictionary(ReferenceEqualityComparer - + CurrentImage="{Binding Image}"> + + + + + @@ -78,30 +95,45 @@ - - Blockiness + + + + + + + + + + + + + + ToolTip="Bluring"> + ConverterParameter="{x:Static convertor:MaxProperty.Bluring}" > - + - - JpegPeaks + + ToolTip="JpegPeaks"> + ConverterParameter="{x:Static convertor:MaxProperty.JpegPeaks}" > - + diff --git a/src/AntiDuplWPF/AntiDuplWPF/View/ConfigurableActionWindow.xaml b/src/AntiDuplWPF/AntiDuplWPF/View/ConfigurableActionWindow.xaml new file mode 100644 index 00000000..d35bcf3c --- /dev/null +++ b/src/AntiDuplWPF/AntiDuplWPF/View/ConfigurableActionWindow.xaml @@ -0,0 +1,602 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/AntiDuplWPF/AntiDuplWPF/View/ConfigurableActionWindow.xaml.cs b/src/AntiDuplWPF/AntiDuplWPF/View/ConfigurableActionWindow.xaml.cs new file mode 100644 index 00000000..4ac08247 --- /dev/null +++ b/src/AntiDuplWPF/AntiDuplWPF/View/ConfigurableActionWindow.xaml.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; + +namespace AntiDuplWPF.View +{ + /// + /// Логика взаимодействия для ConfigurableActionWindow.xaml + /// + public partial class ConfigurableActionWindow : Window + { + public ConfigurableActionWindow() + { + InitializeComponent(); + } + } +} diff --git a/src/AntiDuplWPF/AntiDuplWPF/View/ConfigurationWindow.xaml b/src/AntiDuplWPF/AntiDuplWPF/View/ConfigurationWindow.xaml index 134a31c0..0471d75a 100644 --- a/src/AntiDuplWPF/AntiDuplWPF/View/ConfigurationWindow.xaml +++ b/src/AntiDuplWPF/AntiDuplWPF/View/ConfigurationWindow.xaml @@ -1,29 +1,292 @@  - + xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" + xmlns:system="clr-namespace:System;assembly=mscorlib" + xmlns:behavior="clr-namespace:AntiDuplWPF.Behavior" + xmlns:core="clr-namespace:AntiDuplWPF.Core" + Title="ConfigurationWindow" + Height="400" Width="500" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:viewModel="clr-namespace:AntiDuplWPF.ViewModel" + xmlns:convertor="clr-namespace:AntiDuplWPF.Convertor" + mc:Ignorable="d" + d:DataContext="{d:DesignInstance viewModel:ConfigurationViewModel, IsDesignTimeCreatable=False}"> + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + - - - - - - - - - - - + + + + + + + + + + - - + + + - - - - - - + + + + + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + - - + - - - - - - - - - + + + + + + + + - - + - - - - - - - - - + + + + + + + + - - + - - - - - - - - + + + + + + + - - + - - - - - - - - - + + + + + + + + - - - - + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - + + + - - - - - - - - - - - - - + + + + + + + + + + + + - - - - + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + - - - - - - - - + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/AntiDuplWPF/AntiDuplWPF/View/MainWindow.xaml.cs b/src/AntiDuplWPF/AntiDuplWPF/View/MainWindow.xaml.cs index 6fae0ad3..18b29569 100644 --- a/src/AntiDuplWPF/AntiDuplWPF/View/MainWindow.xaml.cs +++ b/src/AntiDuplWPF/AntiDuplWPF/View/MainWindow.xaml.cs @@ -1,28 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; - -namespace AntiDuplWPF.View +namespace AntiDuplWPF.View { - /// - /// Логика взаимодействия для MainWindow.xaml - /// - public partial class MainWindow : Window + public partial class MainWindow { public MainWindow() { InitializeComponent(); } } -} +} \ No newline at end of file diff --git a/src/AntiDuplWPF/AntiDuplWPF/View/PathWindow.xaml b/src/AntiDuplWPF/AntiDuplWPF/View/PathWindow.xaml index 7e1ae874..9a0516dc 100644 --- a/src/AntiDuplWPF/AntiDuplWPF/View/PathWindow.xaml +++ b/src/AntiDuplWPF/AntiDuplWPF/View/PathWindow.xaml @@ -1,14 +1,22 @@  - + + + + + + + - @@ -47,6 +55,12 @@ + + + + diff --git a/src/AntiDuplWPF/AntiDuplWPF/View/PrioritiesWindow.xaml b/src/AntiDuplWPF/AntiDuplWPF/View/PrioritiesWindow.xaml index 4da57a56..af53e0ad 100644 --- a/src/AntiDuplWPF/AntiDuplWPF/View/PrioritiesWindow.xaml +++ b/src/AntiDuplWPF/AntiDuplWPF/View/PrioritiesWindow.xaml @@ -25,6 +25,8 @@ +