Compare commits

...
3 Commits
34 changed files with 400 additions and 276 deletions
@@ -36,9 +36,16 @@ internal class ProcessProgress : AbstractLogger
ProgressMessage?.Invoke(this, level, message); ProgressMessage?.Invoke(this, level, message);
} }
public void Complete()
{
ProgressComplete?.Invoke(this);
}
public delegate void ProgressUpdateDelegate(ProcessProgress sender); public delegate void ProgressUpdateDelegate(ProcessProgress sender);
public event ProgressUpdateDelegate? ProgressUpdate; public event ProgressUpdateDelegate? ProgressUpdate;
public event ProgressUpdateDelegate? ProgressComplete;
public delegate void ProgressMessageDelegate( public delegate void ProgressMessageDelegate(
ProcessProgress sender, ProcessProgress sender,
LogLevel level, LogLevel level,
+8 -8
View File
@@ -7,7 +7,8 @@ using Pf2eDataScrapper.Helpers;
using Pf2eDataScrapper.Processors; using Pf2eDataScrapper.Processors;
using Pf2eDataScrapper.WPF; using Pf2eDataScrapper.WPF;
using Pf2eDataScrapper.WPF.EntityViewer; using Pf2eDataScrapper.WPF.EntityViewer;
using Pf2eDataScrapper.WPF.Views; using Pf2eDataScrapper.WPF.ProgressForm;
using Pf2eDataScrapper.WPF.StartForm;
using Pf2eModel; using Pf2eModel;
using Slugify; using Slugify;
@@ -25,8 +26,8 @@ internal sealed class ImportApplication : Application
Settings = settings; Settings = settings;
Processors = processors; Processors = processors;
//CurrentStage = ApplicationStage.InitialSettings; CurrentStage = ApplicationStage.InitialSettings;
CurrentStage = ApplicationStage.Viewer; //CurrentStage = ApplicationStage.Viewer;
} }
#region "Поля" #region "Поля"
@@ -50,7 +51,7 @@ internal sealed class ImportApplication : Application
#endregion #endregion
#region "Формы" #region "Жизненный цикл"
private StartForm? _startFormWpf; private StartForm? _startFormWpf;
@@ -58,10 +59,6 @@ internal sealed class ImportApplication : Application
private EntityForm? _entityForm; private EntityForm? _entityForm;
#endregion
#region "Жизненный цикл"
private Window? CurrentWpfForm { get; set; } private Window? CurrentWpfForm { get; set; }
public delegate void ApplicationStateChangeDelegate(object sender, ApplicationStage nextStage); public delegate void ApplicationStateChangeDelegate(object sender, ApplicationStage nextStage);
@@ -133,6 +130,9 @@ internal sealed class ImportApplication : Application
break; break;
case ApplicationStage.ImportProcess: case ApplicationStage.ImportProcess:
_progressFormWpf!.Hide();
_progressFormWpf!.Close();
_progressFormWpf = null;
break; break;
case ApplicationStage.Viewer: case ApplicationStage.Viewer:
@@ -59,14 +59,14 @@ internal partial class StringHelper
} }
/// <summary> /// <summary>
/// Извлечение информации о названии источника. /// Извлечение суффикса из описания источника.
/// </summary> /// </summary>
/// <param name="input">Исходная строка.</param> /// <param name="input">Исходная строка.</param>
/// <returns>Название источника.</returns> /// <returns>Суффикс.</returns>
public string ResolveSource(string input) public string ResolveSourceSuffix(string input)
{ {
Match match = SourceSuffixRegex().Match(input); Match match = SourceSuffixRegex().Match(input);
return match.Captures.Count > 0 ? match.Captures[0].Value : ""; return match.Captures.Count > 0 ? match.Groups[1].Value : "";
} }
/// <summary> /// <summary>
@@ -173,7 +173,9 @@ internal abstract class AbstractEntityProcessor(
{ {
Entity = Entity, Entity = Entity,
SourceId = Globals.SourceIds[sourceName], SourceId = Globals.SourceIds[sourceName],
Suffix = StringHelper.ResolveSource(Input.GetRequired<string>("source_markdown")), Suffix = StringHelper.ResolveSourceSuffix(
Input.GetRequired<string>("source_markdown")
),
IsRemaster = Input.GetOptional<JArray>("legacy_id") is not null, IsRemaster = Input.GetOptional<JArray>("legacy_id") is not null,
}; };
@@ -195,6 +197,7 @@ internal abstract class AbstractEntityProcessor(
Md5 = Input.Md5(), Md5 = Input.Md5(),
}; };
Entity.Externals.Add(external);
Context.EntityExternals.Add(external); Context.EntityExternals.Add(external);
} }
@@ -33,16 +33,17 @@ internal class LegacyRemasterProcessors(ProcessorInput input) : AbstractInputPro
{ {
Context.LegacyRemasters.Add(new() { LegacyId = entityId, RemasterId = remasterId }); Context.LegacyRemasters.Add(new() { LegacyId = entityId, RemasterId = remasterId });
} }
/*
foreach (int legacyId in GetEntityIds("legacy_id")) foreach (int legacyId in GetEntityIds("legacy_id"))
{ {
Context.LegacyRemasters.Add(new() { LegacyId = legacyId, RemasterId = entityId }); Context.LegacyRemasters.Add(new() { LegacyId = legacyId, RemasterId = entityId });
} }
*/
} }
protected List<int> GetEntityIds(string path) protected List<int> GetEntityIds(string path)
{ {
List<string> aonprdIds = (Input.GetOptional<JArray>("path") ?? []) List<string> aonprdIds = (Input.GetOptional<JArray>(path) ?? [])
.Select(token => token.ToString()) .Select(token => token.ToString())
.ToList(); .ToList();
@@ -109,6 +109,10 @@ internal class SpellProcessor(
{ {
A(new() { Spell = Object, Type = SpellAreaType.Square }); A(new() { Spell = Object, Type = SpellAreaType.Square });
} }
if (areaDetails.Contains("fungi"))
{
areaDetails = [areaDetails[0] + " or " + areaDetails[1]];
}
if (areaTypes.Count != areaDetails.Count) if (areaTypes.Count != areaDetails.Count)
{ {
@@ -94,6 +94,7 @@ internal sealed class ProcessorExecutor(
else else
{ {
Progress.Processors.Complete(); Progress.Processors.Complete();
Progress.Complete();
} }
} }
@@ -3,7 +3,6 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Pf2eDataScrapper.WPF.Components"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewmodel="clr-namespace:Pf2eDataScrapper.WPF.EntityViewer.ViewModel" xmlns:viewmodel="clr-namespace:Pf2eDataScrapper.WPF.EntityViewer.ViewModel"
Padding="3,3,3,3" Padding="3,3,3,3"
@@ -6,6 +6,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:fa="http://schemas.awesome.incremented/wpf/xaml/fontawesome.sharp" xmlns:fa="http://schemas.awesome.incremented/wpf/xaml/fontawesome.sharp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 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" xmlns:viewmodel="clr-namespace:Pf2eDataScrapper.WPF.EntityViewer.ViewModel"
x:Name="_this" x:Name="_this"
d:DataContext="{d:DesignInstance Type=viewmodel:ViewViewModel}" d:DataContext="{d:DesignInstance Type=viewmodel:ViewViewModel}"
@@ -17,15 +18,15 @@
<UserControl.Resources> <UserControl.Resources>
<FontFamily x:Key="FontAwesome">/FontAwesome.Sharp;component/fonts/#Font Awesome 6 Free Solid</FontFamily> <FontFamily x:Key="FontAwesome">/FontAwesome.Sharp;component/fonts/#Font Awesome 6 Free Solid</FontFamily>
<struct:ColorAdapterConverter x:Key="ColorAdapterConverter" />
<Style x:Key="ButtonStyle" TargetType="Button"> <Style x:Key="ButtonStyle" TargetType="Button">
<Setter Property="FontSize" Value="{Binding ButtonSize, ElementName=_this}" /> <Setter Property="FontSize" Value="{Binding ButtonSize, ElementName=_this}" />
<Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Center" /> <Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="Margin" Value="0" />
<Setter Property="Padding" Value="0" />
<Setter Property="Width" Value="{Binding ButtonSize, ElementName=_this}" /> <Setter Property="Width" Value="{Binding ButtonSize, ElementName=_this}" />
<Setter Property="Height" Value="{Binding ButtonSize, ElementName=_this}" /> <Setter Property="Height" Value="{Binding ButtonSize, ElementName=_this}" />
<Setter Property="BorderThickness" Value="1" /> <Setter Property="BorderThickness" Value="2,2,1,1" />
<Setter Property="Background"> <Setter Property="Background">
<Setter.Value> <Setter.Value>
@@ -41,7 +42,17 @@
<Setter Property="Foreground" Value="Black" /> <Setter Property="Foreground" Value="Black" />
<Style.Triggers> <Style.Triggers>
<Trigger Property="IsMouseOver" Value="True"> <Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="DarkGray" /> <Setter Property="Foreground" Value="DarkSlateGray" />
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="Transparent" />
</Setter.Value>
</Setter>
<Setter Property="BorderBrush">
<Setter.Value>
<SolidColorBrush Color="Transparent" />
</Setter.Value>
</Setter>
</Trigger> </Trigger>
</Style.Triggers> </Style.Triggers>
</Style> </Style>
@@ -52,6 +63,14 @@
TargetType="Button"> TargetType="Button">
<Setter Property="FontFamily" Value="{StaticResource FontAwesome}" /> <Setter Property="FontFamily" Value="{StaticResource FontAwesome}" />
</Style> </Style>
<Style x:Key="HoverRow" TargetType="Grid">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrush}}" />
</Trigger>
</Style.Triggers>
</Style>
</UserControl.Resources> </UserControl.Resources>
<UserControl.BorderBrush> <UserControl.BorderBrush>
@@ -63,7 +82,7 @@
</UserControl.Background> </UserControl.Background>
<ScrollViewer> <ScrollViewer>
<ItemsControl ItemsSource="{Binding Rows}"> <ItemsControl AlternationCount="2" ItemsSource="{Binding Rows}">
<ItemsControl.ItemsPanel> <ItemsControl.ItemsPanel>
<ItemsPanelTemplate> <ItemsPanelTemplate>
<StackPanel Grid.IsSharedSizeScope="True" /> <StackPanel Grid.IsSharedSizeScope="True" />
@@ -72,7 +91,11 @@
<ItemsControl.ItemTemplate> <ItemsControl.ItemTemplate>
<DataTemplate> <DataTemplate>
<Grid Height="{Binding ItemHeight, ElementName=_this}" Visibility="{Binding ItemVisibility}"> <Grid
x:Name="FooBar"
Height="{Binding ItemHeight, ElementName=_this}"
Visibility="{Binding ItemVisibility}">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="ColumnOne" /> <ColumnDefinition SharedSizeGroup="ColumnOne" />
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
@@ -86,13 +109,15 @@
Ladder="{Binding Ladder}" /> Ladder="{Binding Ladder}" />
<Button <Button
Margin="-22,0,0,0" Margin="-20,0,0,0"
Padding="0"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center" VerticalAlignment="Center"
Command="{Binding CollapseCommand}" Command="{Binding CollapseCommand}"
Content="{Binding ButtonIcon}"
Style="{StaticResource FaButtonStyle}" Style="{StaticResource FaButtonStyle}"
Visibility="{Binding ButtonVisibility}" /> Visibility="{Binding ButtonVisibility}">
<TextBlock Margin="-3,-3,0,0" Text="{Binding ButtonIcon}" />
</Button>
<TextBlock <TextBlock
Margin="2,0,10,0" Margin="2,0,10,0"
@@ -108,14 +133,35 @@
VerticalAlignment="Center" VerticalAlignment="Center"
FontSize="{Binding TypeFontSize, ElementName=_this}" FontSize="{Binding TypeFontSize, ElementName=_this}"
FontStyle="Italic" FontStyle="Italic"
Text="{Binding Type}" /> Text="{Binding Type}">
<TextBlock.Foreground>
<MultiBinding Converter="{StaticResource ColorAdapterConverter}">
<Binding Path="AccentColor" />
</MultiBinding>
</TextBlock.Foreground>
</TextBlock>
<TextBlock <TextBlock
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center" VerticalAlignment="Center"
Text="{Binding Value}" /> Text="{Binding Value}"
TextTrimming="CharacterEllipsis">
<TextBlock.Foreground>
<MultiBinding Converter="{StaticResource ColorAdapterConverter}">
<Binding Path="AccentColor" />
</MultiBinding>
</TextBlock.Foreground>
</TextBlock>
</StackPanel> </StackPanel>
</Grid> </Grid>
<DataTemplate.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter TargetName="FooBar" Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrush}}" />
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter TargetName="FooBar" Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrush}}" />
</Trigger>
</DataTemplate.Triggers>
</DataTemplate> </DataTemplate>
</ItemsControl.ItemTemplate> </ItemsControl.ItemTemplate>
</ItemsControl> </ItemsControl>
@@ -5,16 +5,18 @@
xmlns:component="clr-namespace:Pf2eDataScrapper.WPF.EntityViewer.Component" xmlns:component="clr-namespace:Pf2eDataScrapper.WPF.EntityViewer.Component"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewmodel="clr-namespace:Pf2eDataScrapper.WPF.EntityViewer.ViewModel"
Title="EntityForm" Title="EntityForm"
Width="1400" Width="1400"
Height="800" Height="800"
d:DataContext="{d:DesignInstance Type=viewmodel:EntityFormViewModel}"
x:ClassModifier="internal" x:ClassModifier="internal"
Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
Loaded="Window_Loaded" Loaded="Window_Loaded"
mc:Ignorable="d"> mc:Ignorable="d">
<Grid ClipToBounds="True"> <Grid ClipToBounds="True">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="20" /> <RowDefinition Height="25" />
<RowDefinition Height="150" /> <RowDefinition Height="150" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="*" /> <RowDefinition Height="*" />
@@ -47,6 +49,11 @@
Cursor="SizeNS" Cursor="SizeNS"
ResizeDirection="Rows" /> ResizeDirection="Rows" />
<Button
Margin="3,4,0,0"
Click="Button_Click"
Content="&lt;&lt;&lt; Вернуться в начало" />
<ListBox <ListBox
x:Name="EntityTypeListBox" x:Name="EntityTypeListBox"
Grid.Row="1" Grid.Row="1"
@@ -75,7 +82,7 @@
Grid.RowSpan="4" Grid.RowSpan="4"
Grid.Column="4" Grid.Column="4"
IsReadOnly="True" IsReadOnly="True"
Text="{Binding TestText, Mode=OneWay}" Text="{Binding SelectedEntityDescription, Mode=OneWay}"
TextWrapping="Wrap" /> TextWrapping="Wrap" />
</Grid> </Grid>
</Window> </Window>
@@ -1,6 +1,5 @@
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Windows; using System.Windows;
using Pf2eDataScrapper.WPF.Components;
using Pf2eDataScrapper.WPF.EntityViewer.ViewModel; using Pf2eDataScrapper.WPF.EntityViewer.ViewModel;
using Pf2eModel; using Pf2eModel;
using Pf2eModel.Model.Enum; using Pf2eModel.Model.Enum;
@@ -12,11 +11,7 @@ internal partial class EntityForm : Window
public Pf2eDbContext Context { get; } public Pf2eDbContext Context { get; }
public EntityFormViewModel ViewModel { get; } public EntityFormViewModel ViewModel { get; }
public EntityForm( public EntityForm(Pf2eDbContext context, EntityFormViewModel viewModel)
Pf2eDbContext context,
EntityFormViewModel viewModel,
ViewViewModel entityViewViewModel
)
{ {
Context = context; Context = context;
ViewModel = viewModel; ViewModel = viewModel;
@@ -31,4 +26,9 @@ internal partial class EntityForm : Window
} }
private void Window_Loaded(object sender, RoutedEventArgs e) { } private void Window_Loaded(object sender, RoutedEventArgs e) { }
private void Button_Click(object sender, RoutedEventArgs e)
{
(Application.Current as ImportApplication)!.CurrentStage = ApplicationStage.InitialSettings;
}
} }
@@ -103,12 +103,7 @@ internal class StructureBuilder
return Create(name, value!, depth); return Create(name, value!, depth);
} }
StructureFieldReference reference = new StructureFieldReference( StructureFieldReference reference = new(this, name, null, depth);
this,
name,
null,
depth
);
processed.AddReference(reference); processed.AddReference(reference);
return reference; return reference;
} }
@@ -12,7 +12,8 @@ namespace Pf2eDataScrapper.WPF.EntityViewer.EntityViewStructure;
/// <param name="builder">Класс построения структуры данных.</param> /// <param name="builder">Класс построения структуры данных.</param>
/// <param name="name">Название поля.</param> /// <param name="name">Название поля.</param>
/// <param name="depth">Глубина поля.</param> /// <param name="depth">Глубина поля.</param>
internal abstract class StructureField(StructureBuilder builder, string name, int depth) : INotifyPropertyChanged internal abstract class StructureField(StructureBuilder builder, string name, int depth)
: INotifyPropertyChanged
{ {
/// <summary> /// <summary>
/// Название поля. /// Название поля.
@@ -216,3 +217,32 @@ internal class StructureFieldReference(
/// <inheritdoc/> /// <inheritdoc/>
public override string GetValueString() => "<Reference>"; public override string GetValueString() => "<Reference>";
} }
/// <summary>
/// Поле структуры пропускаемого объекта.
/// </summary>
/// <param name="builder">Класс построения структуры данных.</param>
/// <param name="name">Название поля.</param>
/// <param name="reference">Ссылка на объект.</param>
/// <param name="depth">Глубина поля.</param>
internal class StructureFieldIgnored(
StructureBuilder builder,
string name,
StructureFieldComplex? reference,
int depth
) : StructureField(builder, name, depth)
{
/// <summary>
/// Ссылка на объект.
/// </summary>
public StructureFieldComplex? Reference = reference;
/// <inheritdoc/>
public override StructureFieldType FieldType => StructureFieldType.Reference;
/// <inheritdoc/>
public override string GetTypeString() => Reference?.GetTypeString() ?? "???";
/// <inheritdoc/>
public override string GetValueString() => "<Ignored>";
}
@@ -41,6 +41,19 @@ internal class StructureFieldComplex : StructureField
} }
private bool _collapsed; private bool _collapsed;
/// <summary>
/// Флаг, указывающий, что у этот элемент можно свернуть.
/// </summary>
public bool Collapsable
{
get => Fields.Count > 0;
}
/// <summary>
/// Значение поля идентификатора элемента.
/// </summary>
public string? IdValue { get; private set; }
/// <inheritdoc/> /// <inheritdoc/>
public override bool Visible public override bool Visible
{ {
@@ -118,14 +131,20 @@ internal class StructureFieldComplex : StructureField
Type type = value.GetType(); Type type = value.GetType();
PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
SetFieldsFromRecords( var records = properties
properties .Where(property => property.GetAttribute<Newtonsoft.Json.JsonIgnoreAttribute>() is null)
.Where(property => .Select(property => new FieldRecord(property.Name, property.GetValue(value, null)))
property.GetAttribute<Newtonsoft.Json.JsonIgnoreAttribute>() is null .ToList();
)
.Select(property => new FieldRecord(property.Name, property.GetValue(value, null))) var idRecord = records.FirstOrDefault(record => record.Name == "Id");
.ToList()
); if (idRecord is not null && idRecord.Value is not null)
{
records.Remove(idRecord);
IdValue = idRecord.Value.ToString();
}
SetFieldsFromRecords(records);
} }
/// <summary> /// <summary>
@@ -203,6 +222,12 @@ internal class StructureFieldComplex : StructureField
{ {
return Fields.Count.ToString() + (Fields.Count == 1 ? " item" : " items"); return Fields.Count.ToString() + (Fields.Count == 1 ? " item" : " items");
} }
if (IdValue is not null)
{
return $"#{IdValue}";
}
return ""; return "";
} }
@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Drawing;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
@@ -9,6 +10,9 @@ using System.Windows.Data;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using FontAwesome.Sharp; 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; namespace Pf2eDataScrapper.WPF.EntityViewer.EntityViewStructure;
@@ -27,7 +31,8 @@ internal class StructureRow : INotifyPropertyChanged
/// <summary> /// <summary>
/// Флаг наличия кнопки. /// Флаг наличия кнопки.
/// </summary> /// </summary>
public bool HasButton => Field.FieldType == StructureFieldType.Complex; public bool HasButton =>
Field.FieldType == StructureFieldType.Complex && ((StructureFieldComplex)Field).Collapsable;
/// <summary> /// <summary>
/// Флаг, указывающий, отображается ли строка. /// Флаг, указывающий, отображается ли строка.
@@ -47,7 +52,10 @@ internal class StructureRow : INotifyPropertyChanged
/// <summary> /// <summary>
/// Иконка кнопки. /// Иконка кнопки.
/// </summary> /// </summary>
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();
/// <summary> /// <summary>
/// Глубина отображения поля. /// Глубина отображения поля.
@@ -78,7 +86,26 @@ internal class StructureRow : INotifyPropertyChanged
/// <summary> /// <summary>
/// Строковое представление значения поля. /// Строковое представление значения поля.
/// </summary> /// </summary>
public string Value => Field.GetValueString(); public string Value => Field.GetValueString().Replace("\r", "").Replace("\n", "");
/// <summary>
/// Цвет значения
/// </summary>
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,
};
/// <summary> /// <summary>
/// Команда переключения. /// Команда переключения.
@@ -91,14 +118,14 @@ internal class StructureRow : INotifyPropertyChanged
/// <param name="field">Поле.</param> /// <param name="field">Поле.</param>
public StructureRow(StructureField field) public StructureRow(StructureField field)
{ {
Field = field; Field = field;
CollapseCommand = new CollapseCommand(this); CollapseCommand = new CollapseCommand(this);
Field.PropertyChanged += Field_PropertyChanged; Field.PropertyChanged += Field_PropertyChanged;
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="obj"></param> /// <param name="obj"></param>
private void Field_PropertyChanged(object? sender, PropertyChangedEventArgs e) private void Field_PropertyChanged(object? sender, PropertyChangedEventArgs e)
@@ -147,3 +174,59 @@ internal class CollapseCommand(StructureRow structureRow) : ICommand
field.Collapsed = !field.Collapsed; 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<Type, Func<object>>
{
{ 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();
}
}
@@ -13,9 +13,9 @@ public class SelectedEntityStore
set set
{ {
_selectedEntity = value; _selectedEntity = value;
SelectedEntityTypeChanged?.Invoke(SelectedEntity); SelectedEntityChanged?.Invoke(SelectedEntity);
} }
} }
public event Action<Entity?>? SelectedEntityTypeChanged; public event Action<Entity?>? SelectedEntityChanged;
} }
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using Pf2eDataScrapper.WPF.EntityViewer.Stores; using Pf2eDataScrapper.WPF.EntityViewer.Stores;
using Pf2eModel; using Pf2eModel;
using Pf2eModel.Model.Base;
using Pf2eModel.Model.Enum; using Pf2eModel.Model.Enum;
namespace Pf2eDataScrapper.WPF.EntityViewer.ViewModel; namespace Pf2eDataScrapper.WPF.EntityViewer.ViewModel;
@@ -16,13 +17,15 @@ internal class EntityFormViewModel : ViewModelBase
public EntityListViewModel DbEntityListViewModel { get; } public EntityListViewModel DbEntityListViewModel { get; }
public ViewViewModel ViewViewModel { get; } public ViewViewModel ViewViewModel { get; }
public SelectedEntityTypeStore SelectedEntityTypeStore { get; } public SelectedEntityTypeStore SelectedEntityTypeStore { get; }
public SelectedEntityStore SelectedEntityStore { get; }
public EntityFormViewModel( public EntityFormViewModel(
IServiceProvider serviceProvider, IServiceProvider serviceProvider,
Pf2eDbContext context, Pf2eDbContext context,
EntityListViewModel entityListViewModel, EntityListViewModel entityListViewModel,
ViewViewModel viewViewModel, ViewViewModel viewViewModel,
SelectedEntityTypeStore selectedEntityTypeStore SelectedEntityTypeStore selectedEntityTypeStore,
SelectedEntityStore selectedEntityStore
) )
{ {
ServiceProvider = serviceProvider; ServiceProvider = serviceProvider;
@@ -30,7 +33,11 @@ internal class EntityFormViewModel : ViewModelBase
DbEntityListViewModel = entityListViewModel; DbEntityListViewModel = entityListViewModel;
ViewViewModel = viewViewModel; ViewViewModel = viewViewModel;
SelectedEntityTypeStore = selectedEntityTypeStore; SelectedEntityTypeStore = selectedEntityTypeStore;
SelectedEntityStore = selectedEntityStore;
Update(); Update();
SelectedEntityStore.SelectedEntityChanged += SelectedEntityStore_SelectedEntityChanged;
} }
public void Update() public void Update()
@@ -64,5 +71,19 @@ internal class EntityFormViewModel : ViewModelBase
#endregion #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"; public string TestText => SelectedEntityType?.ToString() ?? "null";
} }
@@ -87,6 +87,7 @@ internal class EntityListViewModel : ViewModelBase
set set
{ {
_entities = [.. value]; _entities = [.. value];
SelectedEntity = Entities.FirstOrDefault();
OnPropertyChanged(); OnPropertyChanged();
} }
} }
@@ -144,55 +145,24 @@ internal class EntityListViewModel : ViewModelBase
#region "Запросы" #region "Запросы"
/// <summary>
/// Поток, в котором будет выполняться запрос к базе данных.
/// </summary>
private Thread? _queryThread;
public void Reload()
{
Abort();
_queryThread = new(PerformQuery);
_queryThread.Start();
}
/// <summary>
/// Прерывает выполнение потока, если он ещё не завершён.
/// </summary>
public void Abort()
{
_queryThread?.Interrupt();
_queryThread = null;
}
/// <summary> /// <summary>
/// Выполняет запрос к базе данных и обрабатывает результаты. /// Выполняет запрос к базе данных и обрабатывает результаты.
/// </summary> /// </summary>
private void PerformQuery() public void Reload()
{ {
try Pf2eDbContext dbContext = new();
{
Pf2eDbContext dbContext = new();
IQueryable<Entity> query = IQueryable<Entity> query =
Search == "" Search == ""
? dbContext.Entities.Where(e => e.Type == SelectedEntityType) ? dbContext.Entities.Where(e => e.Type == SelectedEntityType)
: :
// ReSharper disable once EntityFramework.UnsupportedServerSideFunctionCall // ReSharper disable once EntityFramework.UnsupportedServerSideFunctionCall
dbContext.Entities.Where(e => dbContext.Entities.Where(e =>
e.Type == SelectedEntityType && Pf2eDbContext.LocaleSearch(e.Name, Search) e.Type == SelectedEntityType && Pf2eDbContext.LocaleSearch(e.Name, Search)
); );
EntitiesCount = query.Count(); EntitiesCount = query.Count();
Entities = Entities = [.. query.OrderBy(e => e.Id).Skip((Page - 1) * PerPage).Take(PerPage).ToList()];
[
.. query.OrderBy(e => e.Id).Skip((Page - 1) * PerPage).Take(PerPage).ToList(),
];
}
catch (ThreadInterruptedException)
{
// Ignore
}
} }
#endregion #endregion
@@ -31,7 +31,6 @@ internal class ViewViewModel : ViewModelBase
{ {
_rows = value; _rows = value;
OnPropertyChanged(); OnPropertyChanged();
} }
} }
private ObservableCollection<StructureRow> _rows = []; private ObservableCollection<StructureRow> _rows = [];
@@ -45,14 +44,12 @@ internal class ViewViewModel : ViewModelBase
Context = context; Context = context;
SelectedEntityStore = selectedEntityStore; SelectedEntityStore = selectedEntityStore;
SelectedEntityStore.SelectedEntityTypeChanged += SelectedEntityStore.SelectedEntityChanged += SelectedEntityStore_SelectedEntityTypeChanged;
SelectedEntityStore_SelectedEntityTypeChanged;
} }
~ViewViewModel() ~ViewViewModel()
{ {
SelectedEntityStore.SelectedEntityTypeChanged -= SelectedEntityStore.SelectedEntityChanged -= SelectedEntityStore_SelectedEntityTypeChanged;
SelectedEntityStore_SelectedEntityTypeChanged;
} }
private void SelectedEntityStore_SelectedEntityTypeChanged(Pf2eModel.Model.Base.Entity? entity) private void SelectedEntityStore_SelectedEntityTypeChanged(Pf2eModel.Model.Base.Entity? entity)
@@ -1,16 +1,17 @@
<Window <Window
x:Class="Pf2eDataScrapper.WPF.ProgressForm" x:Class="Pf2eDataScrapper.WPF.ProgressForm.ProgressForm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Pf2eDataScrapper.WPF" xmlns:local="clr-namespace:Pf2eDataScrapper.WPF.ProgressForm"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="ProgressWindow" x:Name="_this"
Title="Выполняется обработка..." Title="Выполняется обработка..."
Width="400" Width="400"
Height="500" Height="500"
x:ClassModifier="internal" x:ClassModifier="internal"
mc:Ignorable="d"> mc:Ignorable="d">
<Grid Margin="3,3,3,3"> <Grid Margin="3,3,3,3">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
@@ -42,40 +43,52 @@
<ListView <ListView
x:Name="MessageListView" x:Name="MessageListView"
Grid.Row="5" Grid.Row="5"
ItemsSource="{Binding ViewRows}" ItemsSource="{Binding ViewRows, ElementName=_this}"
ScrollViewer.CanContentScroll="True"> ScrollViewer.CanContentScroll="True">
<ListView.Resources>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="Margin" Value="0" />
<Setter Property="Padding" Value="0" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Foreground" Value="Black" />
<Style.Triggers>
<DataTrigger Binding="{Binding Level}" Value="Progress">
<Setter Property="Background" Value="LightGray" />
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.Resources>
<ListView.View> <ListView.View>
<GridView> <GridView>
<GridViewColumn Width="Auto" Header="Время" /> <GridViewColumn
<GridViewColumn Width="Auto" Header="Тип" /> Width="Auto"
<GridViewColumn Width="Auto" Header="Сообщение" /> DisplayMemberBinding="{Binding Time}"
Header="Время" />
<GridViewColumn
Width="Auto"
DisplayMemberBinding="{Binding Level}"
Header="Тип" />
<GridViewColumn DisplayMemberBinding="{Binding Message}" Header="Сообщение" />
</GridView> </GridView>
</ListView.View> </ListView.View>
<ListView.ItemTemplate> <ListView.ItemTemplate>
<DataTemplate DataType="{x:Type local:ListViewRow}"> <DataTemplate>
<Grid> <Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70" />
<ColumnDefinition Width="70" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<TextBlock <TextBlock
Grid.Column="0" Grid.Column="0"
HorizontalAlignment="Left" HorizontalAlignment="Left"
Background="{Binding Path=Color}" Background="{Binding Path=Color}" />
Text="{Binding Path=Time}" />
<TextBlock <TextBlock
Grid.Column="1" Grid.Column="1"
HorizontalAlignment="Left" HorizontalAlignment="Left"
Background="{Binding Path=Color}" Background="{Binding Path=Color}" />
Text="{Binding Path=Level}" />
<TextBlock <TextBlock
Grid.Column="2" Grid.Column="2"
HorizontalAlignment="Left" HorizontalAlignment="Left"
Background="{Binding Path=Color}" Background="{Binding Path=Color}" />
Text="{Binding Path=Message}" />
</Grid> </Grid>
</DataTemplate> </DataTemplate>
</ListView.ItemTemplate> </ListView.ItemTemplate>
@@ -4,7 +4,7 @@ using System.Drawing;
using System.Windows; using System.Windows;
using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Helpers;
namespace Pf2eDataScrapper.WPF; namespace Pf2eDataScrapper.WPF.ProgressForm;
/// <summary> /// <summary>
/// Логика взаимодействия для ProgressFormWpf.xaml /// Логика взаимодействия для ProgressFormWpf.xaml
@@ -23,8 +23,10 @@ internal partial class ProgressForm : Window
Progress.ProgressUpdate += Progress_ProgressUpdate; Progress.ProgressUpdate += Progress_ProgressUpdate;
Progress.ProgressMessage += Progress_ProgressMessage; Progress.ProgressMessage += Progress_ProgressMessage;
Progress.ProgressComplete += Progress_ProgressComplete;
} }
private void Progress_ProgressUpdate(ProcessProgress sender) private void Progress_ProgressUpdate(ProcessProgress sender)
{ {
if (!Dispatcher.CheckAccess()) if (!Dispatcher.CheckAccess())
@@ -53,6 +55,12 @@ internal partial class ProgressForm : Window
ListViewRow item = new(level, message) { IsVisible = true }; ListViewRow item = new(level, message) { IsVisible = true };
ViewRows.Add(item); ViewRows.Add(item);
MessageListView.ScrollIntoView(item);
}
private void Progress_ProgressComplete(ProcessProgress sender)
{
//(Application.Current as ImportApplication)!.CurrentStage = ApplicationStage.Viewer;
} }
public event ImportApplication.ApplicationStateChangeDelegate? ApplicationStateChange; public event ImportApplication.ApplicationStateChangeDelegate? ApplicationStateChange;
@@ -1,5 +1,5 @@
<UserControl <UserControl
x:Class="Pf2eDataScrapper.WPF.Components.ProcessorCollectionControl" x:Class="Pf2eDataScrapper.WPF.StartForm.Components.ProcessorCollectionControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
@@ -6,7 +6,7 @@ using System.Windows;
using Pf2eDataScrapper.App; using Pf2eDataScrapper.App;
using CheckBox = System.Windows.Controls.CheckBox; using CheckBox = System.Windows.Controls.CheckBox;
namespace Pf2eDataScrapper.WPF.Components; namespace Pf2eDataScrapper.WPF.StartForm.Components;
/// <summary> /// <summary>
/// Логика взаимодействия для ProcessorCollectionControl.xaml /// Логика взаимодействия для ProcessorCollectionControl.xaml
@@ -1,8 +1,8 @@
<Window <Window
x:Class="Pf2eDataScrapper.WPF.Views.StartForm" x:Class="Pf2eDataScrapper.WPF.StartForm.StartForm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:components="clr-namespace:Pf2eDataScrapper.WPF.Components" xmlns:comp="clr-namespace:Pf2eDataScrapper.WPF.StartForm.Components"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Pf2eDataScrapper.WPF" xmlns:local="clr-namespace:Pf2eDataScrapper.WPF"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@@ -52,10 +52,11 @@
Width="5" Width="5"
HorizontalAlignment="Stretch" /> HorizontalAlignment="Stretch" />
<components:ProcessorCollectionControl <comp:ProcessorCollectionControl
x:Name="ProcessorCollectionControl" x:Name="ProcessorCollectionControl"
Grid.Row="0" Grid.Row="0"
Grid.RowSpan="2" Grid.RowSpan="2"
Grid.Column="2" /> Grid.Column="2" />
</Grid> </Grid>
</Window> </Window>
@@ -1,11 +1,8 @@
using System.Windows; using System.Windows;
using Pf2eDataScrapper.App; using Pf2eDataScrapper.App;
namespace Pf2eDataScrapper.WPF.Views; namespace Pf2eDataScrapper.WPF.StartForm;
/// <summary>
/// Логика взаимодействия для StartForm.xaml
/// </summary>
internal partial class StartForm : Window internal partial class StartForm : Window
{ {
public ProcessorCollection Collection { get; } public ProcessorCollection Collection { get; }
@@ -1,5 +1,4 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Pf2eDataScrapper.WPF.Components;
using Pf2eDataScrapper.WPF.EntityViewer.Stores; using Pf2eDataScrapper.WPF.EntityViewer.Stores;
using Pf2eDataScrapper.WPF.EntityViewer.ViewModel; using Pf2eDataScrapper.WPF.EntityViewer.ViewModel;
@@ -13,7 +13,7 @@ using Pf2eModel.Model.Enum;
namespace Pf2eModel.Migrations namespace Pf2eModel.Migrations
{ {
[DbContext(typeof(Pf2eDbContext))] [DbContext(typeof(Pf2eDbContext))]
[Migration("20250516162158_1")] [Migration("20250521102908_1")]
partial class _1 partial class _1
{ {
/// <inheritdoc /> /// <inheritdoc />
@@ -288,36 +288,11 @@ namespace Pf2eModel.Migrations
.HasColumnOrder(2) .HasColumnOrder(2)
.HasComment("Идентификатор цели"); .HasComment("Идентификатор цели");
b.Property<int>("LegacyEntitiesId")
.HasColumnType("integer")
.HasColumnName("legacy_entities_id");
b.Property<int>("LegacyEntityId")
.HasColumnType("integer")
.HasColumnName("legacy_entity_id");
b.Property<int>("RemasterEntitiesId")
.HasColumnType("integer")
.HasColumnName("remaster_entities_id");
b.Property<int>("RemasterEntityId")
.HasColumnType("integer")
.HasColumnName("remaster_entity_id");
b.HasKey("LegacyId", "RemasterId") b.HasKey("LegacyId", "RemasterId")
.HasName("pk_legacy_remasters"); .HasName("pk_legacy_remasters");
b.HasIndex("LegacyEntitiesId") b.HasIndex("RemasterId")
.HasDatabaseName("ix_legacy_remasters_legacy_entities_id"); .HasDatabaseName("ix_legacy_remasters_remaster_id");
b.HasIndex("LegacyEntityId")
.HasDatabaseName("ix_legacy_remasters_legacy_entity_id");
b.HasIndex("RemasterEntitiesId")
.HasDatabaseName("ix_legacy_remasters_remaster_entities_id");
b.HasIndex("RemasterEntityId")
.HasDatabaseName("ix_legacy_remasters_remaster_entity_id");
b.ToTable("legacy_remasters", (string)null); b.ToTable("legacy_remasters", (string)null);
}); });
@@ -1973,33 +1948,19 @@ namespace Pf2eModel.Migrations
modelBuilder.Entity("Pf2eModel.Model.Base.LegacyRemaster", b => modelBuilder.Entity("Pf2eModel.Model.Base.LegacyRemaster", b =>
{ {
b.HasOne("Pf2eModel.Model.Base.Entity", null)
.WithMany()
.HasForeignKey("LegacyEntitiesId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_legacy_remasters_entities_legacy_entities_id");
b.HasOne("Pf2eModel.Model.Base.Entity", "LegacyEntity") b.HasOne("Pf2eModel.Model.Base.Entity", "LegacyEntity")
.WithMany() .WithMany("LegacyTransferEntities")
.HasForeignKey("LegacyEntityId") .HasForeignKey("LegacyId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired() .IsRequired()
.HasConstraintName("fk_legacy_remasters_entities_legacy_entity_id"); .HasConstraintName("fk_legacy_remasters_entities_legacy_id");
b.HasOne("Pf2eModel.Model.Base.Entity", null)
.WithMany()
.HasForeignKey("RemasterEntitiesId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_legacy_remasters_entities_remaster_entities_id");
b.HasOne("Pf2eModel.Model.Base.Entity", "RemasterEntity") b.HasOne("Pf2eModel.Model.Base.Entity", "RemasterEntity")
.WithMany() .WithMany("RemasterTransferEntities")
.HasForeignKey("RemasterEntityId") .HasForeignKey("RemasterId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired() .IsRequired()
.HasConstraintName("fk_legacy_remasters_entities_remaster_entity_id"); .HasConstraintName("fk_legacy_remasters_entities_remaster_id");
b.Navigation("LegacyEntity"); b.Navigation("LegacyEntity");
@@ -2638,6 +2599,10 @@ namespace Pf2eModel.Migrations
b.Navigation("Externals"); b.Navigation("Externals");
b.Navigation("LegacyTransferEntities");
b.Navigation("RemasterTransferEntities");
b.Navigation("Sources"); b.Navigation("Sources");
}); });
@@ -316,36 +316,20 @@ namespace Pf2eModel.Migrations
columns: table => new columns: table => new
{ {
legacy_id = table.Column<int>(type: "integer", nullable: false, comment: "Идентификатор сущности"), legacy_id = table.Column<int>(type: "integer", nullable: false, comment: "Идентификатор сущности"),
remaster_id = table.Column<int>(type: "integer", nullable: false, comment: "Идентификатор цели"), remaster_id = table.Column<int>(type: "integer", nullable: false, comment: "Идентификатор цели")
legacy_entity_id = table.Column<int>(type: "integer", nullable: false),
remaster_entity_id = table.Column<int>(type: "integer", nullable: false),
legacy_entities_id = table.Column<int>(type: "integer", nullable: false),
remaster_entities_id = table.Column<int>(type: "integer", nullable: false)
}, },
constraints: table => constraints: table =>
{ {
table.PrimaryKey("pk_legacy_remasters", x => new { x.legacy_id, x.remaster_id }); table.PrimaryKey("pk_legacy_remasters", x => new { x.legacy_id, x.remaster_id });
table.ForeignKey( table.ForeignKey(
name: "fk_legacy_remasters_entities_legacy_entities_id", name: "fk_legacy_remasters_entities_legacy_id",
column: x => x.legacy_entities_id, column: x => x.legacy_id,
principalTable: "entities", principalTable: "entities",
principalColumn: "id", principalColumn: "id",
onDelete: ReferentialAction.Cascade); onDelete: ReferentialAction.Cascade);
table.ForeignKey( table.ForeignKey(
name: "fk_legacy_remasters_entities_legacy_entity_id", name: "fk_legacy_remasters_entities_remaster_id",
column: x => x.legacy_entity_id, column: x => x.remaster_id,
principalTable: "entities",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "fk_legacy_remasters_entities_remaster_entities_id",
column: x => x.remaster_entities_id,
principalTable: "entities",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "fk_legacy_remasters_entities_remaster_entity_id",
column: x => x.remaster_entity_id,
principalTable: "entities", principalTable: "entities",
principalColumn: "id", principalColumn: "id",
onDelete: ReferentialAction.Cascade); onDelete: ReferentialAction.Cascade);
@@ -1362,24 +1346,9 @@ namespace Pf2eModel.Migrations
column: "entity_id"); column: "entity_id");
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "ix_legacy_remasters_legacy_entities_id", name: "ix_legacy_remasters_remaster_id",
table: "legacy_remasters", table: "legacy_remasters",
column: "legacy_entities_id"); column: "remaster_id");
migrationBuilder.CreateIndex(
name: "ix_legacy_remasters_legacy_entity_id",
table: "legacy_remasters",
column: "legacy_entity_id");
migrationBuilder.CreateIndex(
name: "ix_legacy_remasters_remaster_entities_id",
table: "legacy_remasters",
column: "remaster_entities_id");
migrationBuilder.CreateIndex(
name: "ix_legacy_remasters_remaster_entity_id",
table: "legacy_remasters",
column: "remaster_entity_id");
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "ix_ritual_checks_ritual_id", name: "ix_ritual_checks_ritual_id",
@@ -285,36 +285,11 @@ namespace Pf2eModel.Migrations
.HasColumnOrder(2) .HasColumnOrder(2)
.HasComment("Идентификатор цели"); .HasComment("Идентификатор цели");
b.Property<int>("LegacyEntitiesId")
.HasColumnType("integer")
.HasColumnName("legacy_entities_id");
b.Property<int>("LegacyEntityId")
.HasColumnType("integer")
.HasColumnName("legacy_entity_id");
b.Property<int>("RemasterEntitiesId")
.HasColumnType("integer")
.HasColumnName("remaster_entities_id");
b.Property<int>("RemasterEntityId")
.HasColumnType("integer")
.HasColumnName("remaster_entity_id");
b.HasKey("LegacyId", "RemasterId") b.HasKey("LegacyId", "RemasterId")
.HasName("pk_legacy_remasters"); .HasName("pk_legacy_remasters");
b.HasIndex("LegacyEntitiesId") b.HasIndex("RemasterId")
.HasDatabaseName("ix_legacy_remasters_legacy_entities_id"); .HasDatabaseName("ix_legacy_remasters_remaster_id");
b.HasIndex("LegacyEntityId")
.HasDatabaseName("ix_legacy_remasters_legacy_entity_id");
b.HasIndex("RemasterEntitiesId")
.HasDatabaseName("ix_legacy_remasters_remaster_entities_id");
b.HasIndex("RemasterEntityId")
.HasDatabaseName("ix_legacy_remasters_remaster_entity_id");
b.ToTable("legacy_remasters", (string)null); b.ToTable("legacy_remasters", (string)null);
}); });
@@ -1970,33 +1945,19 @@ namespace Pf2eModel.Migrations
modelBuilder.Entity("Pf2eModel.Model.Base.LegacyRemaster", b => modelBuilder.Entity("Pf2eModel.Model.Base.LegacyRemaster", b =>
{ {
b.HasOne("Pf2eModel.Model.Base.Entity", null)
.WithMany()
.HasForeignKey("LegacyEntitiesId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_legacy_remasters_entities_legacy_entities_id");
b.HasOne("Pf2eModel.Model.Base.Entity", "LegacyEntity") b.HasOne("Pf2eModel.Model.Base.Entity", "LegacyEntity")
.WithMany() .WithMany("LegacyTransferEntities")
.HasForeignKey("LegacyEntityId") .HasForeignKey("LegacyId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired() .IsRequired()
.HasConstraintName("fk_legacy_remasters_entities_legacy_entity_id"); .HasConstraintName("fk_legacy_remasters_entities_legacy_id");
b.HasOne("Pf2eModel.Model.Base.Entity", null)
.WithMany()
.HasForeignKey("RemasterEntitiesId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_legacy_remasters_entities_remaster_entities_id");
b.HasOne("Pf2eModel.Model.Base.Entity", "RemasterEntity") b.HasOne("Pf2eModel.Model.Base.Entity", "RemasterEntity")
.WithMany() .WithMany("RemasterTransferEntities")
.HasForeignKey("RemasterEntityId") .HasForeignKey("RemasterId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired() .IsRequired()
.HasConstraintName("fk_legacy_remasters_entities_remaster_entity_id"); .HasConstraintName("fk_legacy_remasters_entities_remaster_id");
b.Navigation("LegacyEntity"); b.Navigation("LegacyEntity");
@@ -2635,6 +2596,10 @@ namespace Pf2eModel.Migrations
b.Navigation("Externals"); b.Navigation("Externals");
b.Navigation("LegacyTransferEntities");
b.Navigation("RemasterTransferEntities");
b.Navigation("Sources"); b.Navigation("Sources");
}); });
+10
View File
@@ -110,8 +110,18 @@ public class Entity
/// </summary> /// </summary>
public ICollection<Entity> LegacyEntities { get; set; } = []; public ICollection<Entity> LegacyEntities { get; set; } = [];
/// <summary>
/// Коллекция переходных объектов для устаревших сущностей.
/// </summary>
public ICollection<LegacyRemaster> LegacyTransferEntities { get; set; } = [];
/// <summary> /// <summary>
/// Коллекция обновлённых сущностей. /// Коллекция обновлённых сущностей.
/// </summary> /// </summary>
public ICollection<Entity> RemasterEntities { get; set; } = []; public ICollection<Entity> RemasterEntities { get; set; } = [];
/// <summary>
/// Коллекция переходных объектов для обновлённых сущностей.
/// </summary>
public ICollection<LegacyRemaster> RemasterTransferEntities { get; set; } = [];
} }
@@ -1,6 +1,7 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
namespace Pf2eModel.Model.Base.Source; namespace Pf2eModel.Model.Base.Source;
@@ -50,6 +51,7 @@ public class EntitySource
/// <summary> /// <summary>
/// Сущность, к которой относится источник. /// Сущность, к которой относится источник.
/// </summary> /// </summary>
[JsonIgnore]
public Entity Entity { get; set; } = null!; public Entity Entity { get; set; } = null!;
/// <summary> /// <summary>
+2
View File
@@ -1,6 +1,7 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using Pf2eModel.Model.Enum; using Pf2eModel.Model.Enum;
namespace Pf2eModel.Model.Base.Source; namespace Pf2eModel.Model.Base.Source;
@@ -44,5 +45,6 @@ public class Source
/// <summary> /// <summary>
/// Связанные сущности. /// Связанные сущности.
/// </summary> /// </summary>
[JsonIgnore]
public ICollection<EntitySource> EntitySources { get; set; } = []; public ICollection<EntitySource> EntitySources { get; set; } = [];
} }
@@ -1,6 +1,7 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
namespace Pf2eModel.Model.Base.Targets; namespace Pf2eModel.Model.Base.Targets;
@@ -45,5 +46,6 @@ public class ExternalTarget
/// <summary> /// <summary>
/// Коллекция сущностей, которые ссылаются на эту цель. /// Коллекция сущностей, которые ссылаются на эту цель.
/// </summary> /// </summary>
[JsonIgnore]
public ICollection<EntityExternal> EntityExternals { get; set; } = []; public ICollection<EntityExternal> EntityExternals { get; set; } = [];
} }
+8 -6
View File
@@ -123,12 +123,14 @@ public partial class Pf2eDbContext
.HasMany(e => e.LegacyEntities) .HasMany(e => e.LegacyEntities)
.WithMany(e => e.RemasterEntities) .WithMany(e => e.RemasterEntities)
.UsingEntity<LegacyRemaster>( .UsingEntity<LegacyRemaster>(
//l => l =>
// l.HasOne(lr => lr.LegacyEntity).WithMany().HasForeignKey(lr => lr.LegacyId), l.HasOne(lr => lr.LegacyEntity)
//r => .WithMany(e => e.LegacyTransferEntities)
// r.HasOne(lr => lr.RemasterEntity) .HasForeignKey(lr => lr.LegacyId),
// .WithMany() r =>
// .HasForeignKey(lr => lr.RemasterId) r.HasOne(lr => lr.RemasterEntity)
.WithMany(e => e.RemasterTransferEntities)
.HasForeignKey(lr => lr.RemasterId)
); );
}); });