diff --git a/Pf2eDataScrapper/ImportApplication.cs b/Pf2eDataScrapper/ImportApplication.cs
index 61d9763..ee1c1f5 100644
--- a/Pf2eDataScrapper/ImportApplication.cs
+++ b/Pf2eDataScrapper/ImportApplication.cs
@@ -25,8 +25,8 @@ internal sealed class ImportApplication : Application
Settings = settings;
Processors = processors;
- //CurrentStage = ApplicationStage.InitialSettings;
- CurrentStage = ApplicationStage.Viewer;
+ CurrentStage = ApplicationStage.InitialSettings;
+ //CurrentStage = ApplicationStage.Viewer;
}
#region "Поля"
diff --git a/Pf2eDataScrapper/WPF/EntityViewer/Component/ViewControl.xaml b/Pf2eDataScrapper/WPF/EntityViewer/Component/ViewControl.xaml
index 89257ff..32ff84b 100644
--- a/Pf2eDataScrapper/WPF/EntityViewer/Component/ViewControl.xaml
+++ b/Pf2eDataScrapper/WPF/EntityViewer/Component/ViewControl.xaml
@@ -6,6 +6,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:fa="http://schemas.awesome.incremented/wpf/xaml/fontawesome.sharp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:struct="clr-namespace:Pf2eDataScrapper.WPF.EntityViewer.EntityViewStructure"
xmlns:viewmodel="clr-namespace:Pf2eDataScrapper.WPF.EntityViewer.ViewModel"
x:Name="_this"
d:DataContext="{d:DesignInstance Type=viewmodel:ViewViewModel}"
@@ -17,15 +18,15 @@
/FontAwesome.Sharp;component/fonts/#Font Awesome 6 Free Solid
+
+
@@ -52,6 +63,14 @@
TargetType="Button">
+
+
@@ -63,7 +82,7 @@
-
+
@@ -72,7 +91,11 @@
-
+
+
@@ -86,13 +109,15 @@
Ladder="{Binding Ladder}" />
+ Visibility="{Binding ButtonVisibility}">
+
+
-
+ Text="{Binding Type}">
+
+
+
+
+
+
+ Text="{Binding Value}"
+ TextTrimming="CharacterEllipsis">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Pf2eDataScrapper/WPF/EntityViewer/EntityForm.xaml b/Pf2eDataScrapper/WPF/EntityViewer/EntityForm.xaml
index 79774ab..e1055bb 100644
--- a/Pf2eDataScrapper/WPF/EntityViewer/EntityForm.xaml
+++ b/Pf2eDataScrapper/WPF/EntityViewer/EntityForm.xaml
@@ -5,16 +5,18 @@
xmlns:component="clr-namespace:Pf2eDataScrapper.WPF.EntityViewer.Component"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:viewmodel="clr-namespace:Pf2eDataScrapper.WPF.EntityViewer.ViewModel"
Title="EntityForm"
Width="1400"
Height="800"
+ d:DataContext="{d:DesignInstance Type=viewmodel:EntityFormViewModel}"
x:ClassModifier="internal"
Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
Loaded="Window_Loaded"
mc:Ignorable="d">
-
+
@@ -47,6 +49,11 @@
Cursor="SizeNS"
ResizeDirection="Rows" />
+
+
diff --git a/Pf2eDataScrapper/WPF/EntityViewer/EntityForm.xaml.cs b/Pf2eDataScrapper/WPF/EntityViewer/EntityForm.xaml.cs
index 93d9c5d..ed9fc02 100644
--- a/Pf2eDataScrapper/WPF/EntityViewer/EntityForm.xaml.cs
+++ b/Pf2eDataScrapper/WPF/EntityViewer/EntityForm.xaml.cs
@@ -12,11 +12,7 @@ internal partial class EntityForm : Window
public Pf2eDbContext Context { get; }
public EntityFormViewModel ViewModel { get; }
- public EntityForm(
- Pf2eDbContext context,
- EntityFormViewModel viewModel,
- ViewViewModel entityViewViewModel
- )
+ public EntityForm(Pf2eDbContext context, EntityFormViewModel viewModel)
{
Context = context;
ViewModel = viewModel;
@@ -31,4 +27,9 @@ internal partial class EntityForm : Window
}
private void Window_Loaded(object sender, RoutedEventArgs e) { }
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+ (Application.Current as ImportApplication)!.CurrentStage = ApplicationStage.InitialSettings;
+ }
}
diff --git a/Pf2eDataScrapper/WPF/EntityViewer/EntityViewStructure/StructureBuilder.cs b/Pf2eDataScrapper/WPF/EntityViewer/EntityViewStructure/StructureBuilder.cs
index 60257a7..8396114 100644
--- a/Pf2eDataScrapper/WPF/EntityViewer/EntityViewStructure/StructureBuilder.cs
+++ b/Pf2eDataScrapper/WPF/EntityViewer/EntityViewStructure/StructureBuilder.cs
@@ -103,12 +103,7 @@ internal class StructureBuilder
return Create(name, value!, depth);
}
- StructureFieldReference reference = new StructureFieldReference(
- this,
- name,
- null,
- depth
- );
+ StructureFieldReference reference = new(this, name, null, depth);
processed.AddReference(reference);
return reference;
}
diff --git a/Pf2eDataScrapper/WPF/EntityViewer/EntityViewStructure/StructureField.cs b/Pf2eDataScrapper/WPF/EntityViewer/EntityViewStructure/StructureField.cs
index 46bb6df..b77b066 100644
--- a/Pf2eDataScrapper/WPF/EntityViewer/EntityViewStructure/StructureField.cs
+++ b/Pf2eDataScrapper/WPF/EntityViewer/EntityViewStructure/StructureField.cs
@@ -12,7 +12,8 @@ namespace Pf2eDataScrapper.WPF.EntityViewer.EntityViewStructure;
/// Класс построения структуры данных.
/// Название поля.
/// Глубина поля.
-internal abstract class StructureField(StructureBuilder builder, string name, int depth) : INotifyPropertyChanged
+internal abstract class StructureField(StructureBuilder builder, string name, int depth)
+ : INotifyPropertyChanged
{
///
/// Название поля.
@@ -216,3 +217,32 @@ internal class StructureFieldReference(
///
public override string GetValueString() => "";
}
+
+///
+/// Поле структуры пропускаемого объекта.
+///
+/// Класс построения структуры данных.
+/// Название поля.
+/// Ссылка на объект.
+/// Глубина поля.
+internal class StructureFieldIgnored(
+ StructureBuilder builder,
+ string name,
+ StructureFieldComplex? reference,
+ int depth
+) : StructureField(builder, name, depth)
+{
+ ///
+ /// Ссылка на объект.
+ ///
+ public StructureFieldComplex? Reference = reference;
+
+ ///
+ public override StructureFieldType FieldType => StructureFieldType.Reference;
+
+ ///
+ public override string GetTypeString() => Reference?.GetTypeString() ?? "???";
+
+ ///
+ public override string GetValueString() => "";
+}
diff --git a/Pf2eDataScrapper/WPF/EntityViewer/EntityViewStructure/StructureFieldComplex.cs b/Pf2eDataScrapper/WPF/EntityViewer/EntityViewStructure/StructureFieldComplex.cs
index a03adc2..04ebf9a 100644
--- a/Pf2eDataScrapper/WPF/EntityViewer/EntityViewStructure/StructureFieldComplex.cs
+++ b/Pf2eDataScrapper/WPF/EntityViewer/EntityViewStructure/StructureFieldComplex.cs
@@ -41,6 +41,19 @@ internal class StructureFieldComplex : StructureField
}
private bool _collapsed;
+ ///
+ /// Флаг, указывающий, что у этот элемент можно свернуть.
+ ///
+ public bool Collapsable
+ {
+ get => Fields.Count > 0;
+ }
+
+ ///
+ /// Значение поля идентификатора элемента.
+ ///
+ public string? IdValue { get; private set; }
+
///
public override bool Visible
{
@@ -118,14 +131,20 @@ internal class StructureFieldComplex : StructureField
Type type = value.GetType();
PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
- SetFieldsFromRecords(
- properties
- .Where(property =>
- property.GetAttribute() is null
- )
- .Select(property => new FieldRecord(property.Name, property.GetValue(value, null)))
- .ToList()
- );
+ var records = properties
+ .Where(property => property.GetAttribute() is null)
+ .Select(property => new FieldRecord(property.Name, property.GetValue(value, null)))
+ .ToList();
+
+ var idRecord = records.FirstOrDefault(record => record.Name == "Id");
+
+ if (idRecord is not null && idRecord.Value is not null)
+ {
+ records.Remove(idRecord);
+ IdValue = idRecord.Value.ToString();
+ }
+
+ SetFieldsFromRecords(records);
}
///
@@ -203,6 +222,12 @@ internal class StructureFieldComplex : StructureField
{
return Fields.Count.ToString() + (Fields.Count == 1 ? " item" : " items");
}
+
+ if (IdValue is not null)
+ {
+ return $"#{IdValue}";
+ }
+
return "";
}
diff --git a/Pf2eDataScrapper/WPF/EntityViewer/EntityViewStructure/StructureRow.cs b/Pf2eDataScrapper/WPF/EntityViewer/EntityViewStructure/StructureRow.cs
index aabb7a2..e1a8665 100644
--- a/Pf2eDataScrapper/WPF/EntityViewer/EntityViewStructure/StructureRow.cs
+++ b/Pf2eDataScrapper/WPF/EntityViewer/EntityViewStructure/StructureRow.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
+using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Runtime.CompilerServices;
@@ -9,6 +10,9 @@ using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using FontAwesome.Sharp;
+using static System.Runtime.InteropServices.JavaScript.JSType;
+using static LinqToDB.Sql;
+using Color = System.Windows.Media.Color;
namespace Pf2eDataScrapper.WPF.EntityViewer.EntityViewStructure;
@@ -27,7 +31,8 @@ internal class StructureRow : INotifyPropertyChanged
///
/// Флаг наличия кнопки.
///
- public bool HasButton => Field.FieldType == StructureFieldType.Complex;
+ public bool HasButton =>
+ Field.FieldType == StructureFieldType.Complex && ((StructureFieldComplex)Field).Collapsable;
///
/// Флаг, указывающий, отображается ли строка.
@@ -47,7 +52,10 @@ internal class StructureRow : INotifyPropertyChanged
///
/// Иконка кнопки.
///
- public string ButtonIcon => HasButton && !((StructureFieldComplex)Field).Collapsed ? IconChar.PlusSquare.ToChar() : IconChar.MinusSquare.ToChar();
+ public string ButtonIcon =>
+ HasButton && !((StructureFieldComplex)Field).Collapsed
+ ? IconChar.PlusSquare.ToChar()
+ : IconChar.MinusSquare.ToChar();
///
/// Глубина отображения поля.
@@ -78,7 +86,26 @@ internal class StructureRow : INotifyPropertyChanged
///
/// Строковое представление значения поля.
///
- public string Value => Field.GetValueString();
+ public string Value => Field.GetValueString().Replace("\r", "").Replace("\n", "");
+
+ ///
+ /// Цвет значения
+ ///
+ public Color? AccentColor =>
+ Field switch
+ {
+ StructureFieldPrimitive primitive => System.Type.GetTypeCode(primitive.Type) switch
+ {
+ TypeCode.Boolean => Colors.DarkGoldenrod,
+ TypeCode.Int32 => Colors.Blue,
+ TypeCode.Double => Colors.Aqua,
+ TypeCode.String => Colors.Green,
+ _ => null,
+ },
+ StructureFieldEnum => Colors.Red,
+ StructureFieldNull => Colors.Transparent,
+ _ => null,
+ };
///
/// Команда переключения.
@@ -91,14 +118,14 @@ internal class StructureRow : INotifyPropertyChanged
/// Поле.
public StructureRow(StructureField field)
{
- Field = field;
+ Field = field;
CollapseCommand = new CollapseCommand(this);
Field.PropertyChanged += Field_PropertyChanged;
}
///
- ///
+ ///
///
///
private void Field_PropertyChanged(object? sender, PropertyChangedEventArgs e)
@@ -147,3 +174,59 @@ internal class CollapseCommand(StructureRow structureRow) : ICommand
field.Collapsed = !field.Collapsed;
}
}
+
+public class ColorAdapterConverter : IMultiValueConverter
+{
+ private byte Mix(byte a, byte b, double rate) =>
+ System.Convert.ToByte(Math.Round(a * rate + b * (1 - rate)));
+
+ public object? Convert(object[] value, Type targetType, object parameter, CultureInfo culture)
+ {
+ Color textColor = System.Windows.SystemColors.WindowTextColor;
+ double a = textColor.A;
+ double r = textColor.R;
+ double g = textColor.G;
+ double b = textColor.B;
+ int n = 1 + value.Length;
+
+ foreach (var item in value)
+ {
+ if (item == null || item is not Color)
+ {
+ n--;
+ continue;
+ }
+
+ Color color = (Color)item;
+
+ a += color.A;
+ r += color.R;
+ g += color.G;
+ b += color.B;
+ }
+
+ Color resultColor = Color.FromArgb(
+ System.Convert.ToByte(Math.Round(a / n)),
+ System.Convert.ToByte(Math.Round(r / n)),
+ System.Convert.ToByte(Math.Round(g / n)),
+ System.Convert.ToByte(Math.Round(b / n))
+ );
+
+ var @switch = new Dictionary>
+ {
+ { typeof(System.Windows.Media.Brush), () => new SolidColorBrush(resultColor) },
+ };
+
+ return @switch.TryGetValue(targetType, out var action) ? action() : null;
+ }
+
+ public object[] ConvertBack(
+ object value,
+ Type[] targetType,
+ object parameter,
+ CultureInfo culture
+ )
+ {
+ throw new NotImplementedException();
+ }
+}
diff --git a/Pf2eDataScrapper/WPF/EntityViewer/Stores/SelectedEntityStore.cs b/Pf2eDataScrapper/WPF/EntityViewer/Stores/SelectedEntityStore.cs
index 3d63aad..f8d262d 100644
--- a/Pf2eDataScrapper/WPF/EntityViewer/Stores/SelectedEntityStore.cs
+++ b/Pf2eDataScrapper/WPF/EntityViewer/Stores/SelectedEntityStore.cs
@@ -13,9 +13,9 @@ public class SelectedEntityStore
set
{
_selectedEntity = value;
- SelectedEntityTypeChanged?.Invoke(SelectedEntity);
+ SelectedEntityChanged?.Invoke(SelectedEntity);
}
}
- public event Action? SelectedEntityTypeChanged;
+ public event Action? SelectedEntityChanged;
}
diff --git a/Pf2eDataScrapper/WPF/EntityViewer/ViewModel/EntityFormViewModel.cs b/Pf2eDataScrapper/WPF/EntityViewer/ViewModel/EntityFormViewModel.cs
index 0f3ca3e..d587fa7 100644
--- a/Pf2eDataScrapper/WPF/EntityViewer/ViewModel/EntityFormViewModel.cs
+++ b/Pf2eDataScrapper/WPF/EntityViewer/ViewModel/EntityFormViewModel.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using Pf2eDataScrapper.WPF.EntityViewer.Stores;
using Pf2eModel;
+using Pf2eModel.Model.Base;
using Pf2eModel.Model.Enum;
namespace Pf2eDataScrapper.WPF.EntityViewer.ViewModel;
@@ -16,13 +17,15 @@ internal class EntityFormViewModel : ViewModelBase
public EntityListViewModel DbEntityListViewModel { get; }
public ViewViewModel ViewViewModel { get; }
public SelectedEntityTypeStore SelectedEntityTypeStore { get; }
+ public SelectedEntityStore SelectedEntityStore { get; }
public EntityFormViewModel(
IServiceProvider serviceProvider,
Pf2eDbContext context,
EntityListViewModel entityListViewModel,
ViewViewModel viewViewModel,
- SelectedEntityTypeStore selectedEntityTypeStore
+ SelectedEntityTypeStore selectedEntityTypeStore,
+ SelectedEntityStore selectedEntityStore
)
{
ServiceProvider = serviceProvider;
@@ -30,7 +33,11 @@ internal class EntityFormViewModel : ViewModelBase
DbEntityListViewModel = entityListViewModel;
ViewViewModel = viewViewModel;
SelectedEntityTypeStore = selectedEntityTypeStore;
+ SelectedEntityStore = selectedEntityStore;
+
Update();
+
+ SelectedEntityStore.SelectedEntityChanged += SelectedEntityStore_SelectedEntityChanged;
}
public void Update()
@@ -64,5 +71,19 @@ internal class EntityFormViewModel : ViewModelBase
#endregion
+ #region "Текущий элемент"
+
+ public string SelectedEntityDescription
+ {
+ get => SelectedEntityStore.SelectedEntity?.Description ?? "";
+ }
+
+ private void SelectedEntityStore_SelectedEntityChanged(Entity? obj)
+ {
+ OnPropertyChanged(nameof(SelectedEntityDescription));
+ }
+
+ #endregion
+
public string TestText => SelectedEntityType?.ToString() ?? "null";
}
diff --git a/Pf2eDataScrapper/WPF/EntityViewer/ViewModel/EntityListViewModel.cs b/Pf2eDataScrapper/WPF/EntityViewer/ViewModel/EntityListViewModel.cs
index 8c4f79c..8a42d3f 100644
--- a/Pf2eDataScrapper/WPF/EntityViewer/ViewModel/EntityListViewModel.cs
+++ b/Pf2eDataScrapper/WPF/EntityViewer/ViewModel/EntityListViewModel.cs
@@ -87,6 +87,7 @@ internal class EntityListViewModel : ViewModelBase
set
{
_entities = [.. value];
+ SelectedEntity = Entities.FirstOrDefault();
OnPropertyChanged();
}
}
@@ -144,55 +145,24 @@ internal class EntityListViewModel : ViewModelBase
#region "Запросы"
- ///
- /// Поток, в котором будет выполняться запрос к базе данных.
- ///
- private Thread? _queryThread;
-
- public void Reload()
- {
- Abort();
- _queryThread = new(PerformQuery);
- _queryThread.Start();
- }
-
- ///
- /// Прерывает выполнение потока, если он ещё не завершён.
- ///
- public void Abort()
- {
- _queryThread?.Interrupt();
- _queryThread = null;
- }
-
///
/// Выполняет запрос к базе данных и обрабатывает результаты.
///
- private void PerformQuery()
+ public void Reload()
{
- try
- {
- Pf2eDbContext dbContext = new();
+ Pf2eDbContext dbContext = new();
- IQueryable query =
- Search == ""
- ? dbContext.Entities.Where(e => e.Type == SelectedEntityType)
- :
- // ReSharper disable once EntityFramework.UnsupportedServerSideFunctionCall
- dbContext.Entities.Where(e =>
- e.Type == SelectedEntityType && Pf2eDbContext.LocaleSearch(e.Name, Search)
- );
+ IQueryable query =
+ Search == ""
+ ? dbContext.Entities.Where(e => e.Type == SelectedEntityType)
+ :
+ // ReSharper disable once EntityFramework.UnsupportedServerSideFunctionCall
+ dbContext.Entities.Where(e =>
+ e.Type == SelectedEntityType && Pf2eDbContext.LocaleSearch(e.Name, Search)
+ );
- EntitiesCount = query.Count();
- Entities =
- [
- .. query.OrderBy(e => e.Id).Skip((Page - 1) * PerPage).Take(PerPage).ToList(),
- ];
- }
- catch (ThreadInterruptedException)
- {
- // Ignore
- }
+ EntitiesCount = query.Count();
+ Entities = [.. query.OrderBy(e => e.Id).Skip((Page - 1) * PerPage).Take(PerPage).ToList()];
}
#endregion
diff --git a/Pf2eDataScrapper/WPF/EntityViewer/ViewModel/ViewViewModel.cs b/Pf2eDataScrapper/WPF/EntityViewer/ViewModel/ViewViewModel.cs
index 5667c4c..f4f7f68 100644
--- a/Pf2eDataScrapper/WPF/EntityViewer/ViewModel/ViewViewModel.cs
+++ b/Pf2eDataScrapper/WPF/EntityViewer/ViewModel/ViewViewModel.cs
@@ -31,7 +31,6 @@ internal class ViewViewModel : ViewModelBase
{
_rows = value;
OnPropertyChanged();
-
}
}
private ObservableCollection _rows = [];
@@ -45,14 +44,12 @@ internal class ViewViewModel : ViewModelBase
Context = context;
SelectedEntityStore = selectedEntityStore;
- SelectedEntityStore.SelectedEntityTypeChanged +=
- SelectedEntityStore_SelectedEntityTypeChanged;
+ SelectedEntityStore.SelectedEntityChanged += SelectedEntityStore_SelectedEntityTypeChanged;
}
~ViewViewModel()
{
- SelectedEntityStore.SelectedEntityTypeChanged -=
- SelectedEntityStore_SelectedEntityTypeChanged;
+ SelectedEntityStore.SelectedEntityChanged -= SelectedEntityStore_SelectedEntityTypeChanged;
}
private void SelectedEntityStore_SelectedEntityTypeChanged(Pf2eModel.Model.Base.Entity? entity)