Глобальное обновление #1

Merged
kozhilya merged 33 commits from dev into master 2025-06-01 22:28:15 +04:00
88 changed files with 209 additions and 3889 deletions
Showing only changes of commit 03a644624f - Show all commits
+4 -1
View File
@@ -1,4 +1,7 @@
namespace Pf2eDataScrapper.App; using System;
using System.Collections.Generic;
namespace Pf2eDataScrapper.App;
/// <summary> /// <summary>
/// Общий аттрибут обработчика. /// Общий аттрибут обработчика.
+4 -1
View File
@@ -1,4 +1,7 @@
using System.Reflection; using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Pf2eDataScrapper.Processors; using Pf2eDataScrapper.Processors;
namespace Pf2eDataScrapper.App; namespace Pf2eDataScrapper.App;
+2 -1
View File
@@ -1,4 +1,5 @@
using System.ComponentModel; using System;
using System.ComponentModel;
using System.IO; using System.IO;
using dotenv.net; using dotenv.net;
using dotenv.net.Utilities; using dotenv.net.Utilities;
@@ -1,22 +0,0 @@
namespace Pf2eDataScrapper.Forms.Controls;
/// <summary>
/// Элемент управления прокрутки страниц
/// </summary>
internal sealed class CoreBindingNavigator : BindingNavigator
{
public CoreBindingNavigator()
{
AddStandardItems();
if (DeleteItem != null)
{
DeleteItem.Visible = false;
}
if (AddNewItem != null)
{
AddNewItem.Visible = false;
}
}
}
@@ -1,130 +0,0 @@
using System.Collections.Concurrent;
using Pf2eModel;
using Pf2eModel.Model.Base;
using Pf2eModel.Model.Enum;
namespace Pf2eDataScrapper.Forms.Controls.DatabaseViewer;
/// <summary>
/// Класс, выполняющий страничные запросы к базе данных.
/// </summary>
internal class DatabaseQueryPerformer
{
/// <summary>
/// Тип сущностей, которую необходимо получить.
/// </summary>
public required EntityType Type;
/// <summary>
/// Номер страницы, которую необходимо получить.
/// </summary>
public required int Page;
/// <summary>
/// Количество элементов на странице.
/// </summary>
public required int PerPage;
/// <summary>
/// Поисковая строка, по которой будет производиться фильтрация.
/// </summary>
public required string Search = "";
/// <summary>
/// Поток, в котором будет выполняться запрос к базе данных.
/// </summary>
private readonly Thread _queryThread;
/// <summary>
/// Конструктор класса, который инициализирует поток для выполнения запроса к базе данных.
/// </summary>
public DatabaseQueryPerformer()
{
_queryThread = new(PerformQuery);
}
/// <summary>
/// Запускает поток для выполнения запроса к базе данных.
/// </summary>
public void Query()
{
_queryThread.Start();
}
/// <summary>
/// Прерывает выполнение потока, если он ещё не завершён.
/// </summary>
public void Abort()
{
_queryThread.Interrupt();
}
/// <summary>
/// Выполняет запрос к базе данных и обрабатывает результаты.
/// </summary>
private void PerformQuery()
{
try
{
Pf2eDbContext dbContext = new();
IQueryable<Entity> query =
Search == ""
? dbContext.Entities.Where(e => e.Type == Type)
:
// ReSharper disable once EntityFramework.UnsupportedServerSideFunctionCall
dbContext.Entities.Where(e =>
e.Type == Type && Pf2eDbContext.LocaleSearch(e.Name, Search)
);
int count = query.Count();
List<Entity> entities = query
.OrderBy(e => e.Id)
.Skip((Page - 1) * PerPage)
.Take(PerPage)
.ToList();
DatabaseQueryResult result = new(count, entities);
OnQueryCompleted?.Invoke(this, result);
}
catch (ThreadInterruptedException)
{
// Ignore
}
}
/// <summary>
/// Делегат, который будет вызван по завершении выполнения запроса к базе данных.
/// </summary>
/// <param name="sender">Объект класса, выполневшего запрос.</param>
/// <param name="result">Результат запроса.</param>
public delegate void DatabaseQueryPerformerDelegate(
DatabaseQueryPerformer sender,
DatabaseQueryResult result
);
/// <summary>
/// Событие, которое будет вызвано по завершении выполнения запроса к базе данных.
/// </summary>
public event DatabaseQueryPerformerDelegate? OnQueryCompleted;
}
/// <summary>
/// Класс, который содержит результат выполнения запроса к базе данных.
/// </summary>
/// <param name="count">Общее количество найденных сущностей.</param>
/// <param name="entities">Набор найденных сущностей.</param>
internal class DatabaseQueryResult(int count, ICollection<Entity> entities)
{
/// <summary>
/// Общее количество найденных сущностей.
/// </summary>
public int Count { get; } = count;
/// <summary>
/// Набор найденных сущностей.
/// </summary>
public ConcurrentBag<Entity> Entities { get; } = new(entities);
}
@@ -1,148 +0,0 @@
namespace Pf2eDataScrapper.Forms.Controls.DatabaseViewer;
partial class DatabaseViewerControl
{
/// <summary>
/// Обязательная переменная конструктора.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором компонентов
/// <summary>
/// Требуемый метод для поддержки конструктора — не изменяйте
/// содержимое этого метода с помощью редактора кода.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
BindingNavigator = new CoreBindingNavigator();
SearchTextBox = new TextBox();
DataGridView = new DataGridView();
DbBindingSource = new BindingSource(components);
PagesBindingSource = new BindingSource(components);
Id = new DataGridViewTextBoxColumn();
EntityName = new DataGridViewTextBoxColumn();
Rarity = new DataGridViewTextBoxColumn();
(BindingNavigator).BeginInit();
((System.ComponentModel.ISupportInitialize)DataGridView).BeginInit();
((System.ComponentModel.ISupportInitialize)DbBindingSource).BeginInit();
((System.ComponentModel.ISupportInitialize)PagesBindingSource).BeginInit();
SuspendLayout();
//
// BindingNavigator
//
BindingNavigator.AddNewItem = null;
BindingNavigator.DeleteItem = null;
BindingNavigator.ImeMode = ImeMode.NoControl;
BindingNavigator.LayoutStyle = ToolStripLayoutStyle.HorizontalStackWithOverflow;
BindingNavigator.Location = new Point(0, 0);
BindingNavigator.Name = "BindingNavigator";
BindingNavigator.Size = new Size(345, 25);
BindingNavigator.Stretch = true;
BindingNavigator.TabIndex = 1;
BindingNavigator.Text = "coreBindingNavigator1";
BindingNavigator.RefreshItems += BindingNavigator_RefreshItems;
//
// SearchTextBox
//
SearchTextBox.Dock = DockStyle.Top;
SearchTextBox.Location = new Point(0, 25);
SearchTextBox.Name = "SearchTextBox";
SearchTextBox.PlaceholderText = "Поиск";
SearchTextBox.Size = new Size(345, 23);
SearchTextBox.TabIndex = 3;
SearchTextBox.TextChanged += SearchTextBox_TextChanged;
SearchTextBox.Leave += SearchTextBox_Leave;
//
// DataGridView
//
DataGridView.AllowUserToAddRows = false;
DataGridView.AllowUserToDeleteRows = false;
DataGridView.AutoGenerateColumns = false;
DataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader;
DataGridView.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCellsExceptHeaders;
DataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
DataGridView.Columns.AddRange(new DataGridViewColumn[] { Id, EntityName, Rarity });
DataGridView.DataSource = DbBindingSource;
DataGridView.Dock = DockStyle.Fill;
DataGridView.Location = new Point(0, 48);
DataGridView.MultiSelect = false;
DataGridView.Name = "DataGridView";
DataGridView.ReadOnly = true;
DataGridView.RowHeadersVisible = false;
DataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
DataGridView.Size = new Size(345, 345);
DataGridView.TabIndex = 4;
DataGridView.RowStateChanged += DataGridView_RowStateChanged;
//
// Id
//
Id.DataPropertyName = "Id";
Id.HeaderText = "Id";
Id.Name = "Id";
Id.ReadOnly = true;
Id.Resizable = DataGridViewTriState.False;
Id.SortMode = DataGridViewColumnSortMode.NotSortable;
Id.Width = 5;
//
// EntityName
//
EntityName.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
EntityName.DataPropertyName = "Name";
EntityName.HeaderText = "Name";
EntityName.Name = "EntityName";
EntityName.ReadOnly = true;
EntityName.Resizable = DataGridViewTriState.False;
EntityName.SortMode = DataGridViewColumnSortMode.NotSortable;
//
// Rarity
//
Rarity.DataPropertyName = "Rarity";
Rarity.HeaderText = "Rarity";
Rarity.Name = "Rarity";
Rarity.ReadOnly = true;
Rarity.Resizable = DataGridViewTriState.False;
Rarity.SortMode = DataGridViewColumnSortMode.NotSortable;
Rarity.Width = 5;
//
// DatabaseViewerControl
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
Controls.Add(DataGridView);
Controls.Add(SearchTextBox);
Controls.Add(BindingNavigator);
Name = "DatabaseViewerControl";
Size = new Size(345, 393);
(BindingNavigator).EndInit();
((System.ComponentModel.ISupportInitialize)DataGridView).EndInit();
((System.ComponentModel.ISupportInitialize)DbBindingSource).EndInit();
((System.ComponentModel.ISupportInitialize)PagesBindingSource).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private CoreBindingNavigator BindingNavigator;
private TextBox SearchTextBox;
private DataGridView DataGridView;
private BindingSource DbBindingSource;
private BindingSource PagesBindingSource;
private DataGridViewTextBoxColumn Id;
private DataGridViewTextBoxColumn EntityName;
private DataGridViewTextBoxColumn Rarity;
}
@@ -1,391 +0,0 @@
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using Pf2eDataScrapper.Helpers;
using Pf2eModel;
using Pf2eModel.Model.Base;
using Pf2eModel.Model.Common.I18n;
using Pf2eModel.Model.Enum;
using Timer = System.Windows.Forms.Timer;
namespace Pf2eDataScrapper.Forms.Controls.DatabaseViewer;
/// <summary>
/// Класс элемента управления, который отображает сущности в виде таблицы.
/// </summary>
public partial class DatabaseViewerControl : UserControl
{
#region "Поля и свойства"
/// <summary>
/// Контекст базы данных, который используется для получения сущностей.
/// </summary>
public readonly Pf2eDbContext Context = new();
/// <summary>
/// Количество элементов на странице.
/// </summary>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int PerPage
{
get => _perPage;
set
{
_perPage = value;
UpdateView();
}
}
private int _perPage = 30;
/// <summary>
/// Номер страницы, которую необходимо отобразить.
/// </summary>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int Page
{
get => _page;
set
{
_page = value;
UpdateView();
}
}
private int _page = 1;
/// <summary>
/// Тип сущности, которую необходимо отобразить.
/// </summary>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public EntityType Type
{
get => _type;
set
{
_page = 1;
_type = value;
UpdateView();
}
}
private EntityType _type;
/// <summary>
/// Количество элементов, которые были получены из базы данных.
/// </summary>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int Count { get; private set; }
/// <summary>
/// Номер последней страницы, которая может быть отображена.
/// </summary>
public int MaxPage => Convert.ToInt32(Math.Ceiling(1.0 * Count / PerPage));
/// <summary>
/// Выбранная в элементе управления сущность.
/// </summary>
[AllowNull]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public EntityView CurrentEntity { get; private set; }
/// <summary>
/// Флаг, указывающий, что элемент управления занят выполнением запроса к базе данных.
/// </summary>
private bool _isBusy;
/// <summary>
/// Объект, который выполняет запрос к базе данных.
/// </summary>
private DatabaseQueryPerformer? _performer;
/// <summary>
/// Таймер, который используется для задержки обработки события изменения текста в поле поиска.
/// </summary>
private Timer? _typingTimer;
/// <summary>
/// Строка, которая хранит последнее значение, введенное в поле поиска.
/// </summary>
private string _lastSearch = "";
#endregion
/// <summary>
/// Конструктор класса, который инициализирует элемент управления и связывает его с источником данных.
/// </summary>
public DatabaseViewerControl()
{
InitializeComponent();
BindingNavigator.BindingSource = DbBindingSource;
//DataGridView.AutoGenerateColumns = true;
DataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
_isBusy = false;
}
#region "События элемента управления"
/// <summary>
/// Обработчик события, который вызывается при изменении текущей страницы в элементе управления.
/// </summary>
/// <param name="sender">Источник события.</param>
/// <param name="e">Объект, содержащий данные события.</param>
private void BindingNavigator_RefreshItems(object sender, EventArgs e)
{
if (_isBusy)
{
return;
}
Page = (int)(BindingNavigator?.BindingSource?.Current ?? 1);
UpdateView();
}
/// <summary>
/// Обработчик события, который вызывается при изменении выделенной строки в элементе управления DataGridView.
/// </summary>
/// <param name="sender">Источник события.</param>
/// <param name="e">Объект, содержащий данные события.</param>
private void DataGridView_RowStateChanged(object sender, DataGridViewRowStateChangedEventArgs e)
{
if (_isBusy)
{
return;
}
UpdateEntity();
}
/// <summary>
/// Обработчик события, который вызывается когда поле поиска теряет фокус.
/// </summary>
/// <param name="sender">Источник события.</param>
/// <param name="e">Объект, содержащий данные события.</param>
private void SearchTextBox_Leave(object sender, EventArgs e)
{
if (_isBusy || SearchTextBox.Text == _lastSearch)
{
return;
}
UpdateView();
}
/// <summary>
/// Обработчик события, который вызывается при изменении текста в поле поиска.
/// </summary>
/// <param name="sender">Источник события.</param>
/// <param name="e">Объект, содержащий данные события.</param>
private void SearchTextBox_TextChanged(object sender, EventArgs e)
{
if (_isBusy)
{
return;
}
if (_typingTimer == null)
{
_typingTimer = new();
_typingTimer.Interval = 3000;
_typingTimer.Tick += HandleTypingTimerTimeout;
}
_typingTimer.Stop(); // Resets the timer
_typingTimer.Tag = (sender as TextBox)!.Text; // This should be done with EventArgs
_typingTimer.Start();
}
/// <summary>
/// Обработчик события, который вызывается при истечении времени таймера ввода текста.
/// </summary>
/// <param name="sender">Источник события.</param>
/// <param name="e">Объект, содержащий данные события.</param>
private void HandleTypingTimerTimeout(object? sender, EventArgs e)
{
if (_isBusy || sender is not Timer timer)
{
return;
}
UpdateView();
timer.Stop();
}
#endregion
#region "Обновление данных"
/// <summary>
/// Устанавливает статус занятости элемента управления.
/// </summary>
/// <param name="busy">Новый статус занятости.</param>
private void SetBusyStatus(bool busy)
{
if (InvokeRequired)
{
Invoke(SetBusyStatus, busy);
return;
}
_isBusy = busy;
BindingNavigator.Enabled = !busy;
DataGridView.Enabled = !busy;
SearchTextBox.Enabled = !busy;
DataGridView.ColumnHeadersHeightSizeMode = !busy
? DataGridViewColumnHeadersHeightSizeMode.AutoSize
: DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
}
/// <summary>
/// Обновляет данные в элементе управления.
/// </summary>
/// <param name="force">Проигнорировать флаг занятости.</param>
public void UpdateView(bool force = false)
{
if (_isBusy && !force)
{
return;
}
SetBusyStatus(true);
_performer?.Abort();
_performer = new()
{
Type = Type,
Page = Page,
PerPage = PerPage,
Search = SearchTextBox.Text,
};
_performer.OnQueryCompleted += HandleQueryCompleted;
_performer.Query();
}
/// <summary>
/// Обработчик события, который вызывается по завершении выполнения запроса к базе данных.
/// </summary>
/// <param name="sender">Источник события.</param>
/// <param name="result">Результат выполнения события</param>
private void HandleQueryCompleted(DatabaseQueryPerformer sender, DatabaseQueryResult result)
{
if (sender != _performer)
{
return;
}
Count = result.Count;
_lastSearch = SearchTextBox.Text;
InvokeControl(
BindingNavigator,
b =>
{
PagesBindingSource.DataSource = Enumerable.Range(1, MaxPage).ToList();
b.BindingSource = PagesBindingSource;
}
);
InvokeControl(
DataGridView,
view =>
{
view.DataSource = result
.Entities.Select(e => new EntityGridRow(e))
.OrderBy(r => r.Id)
.ToList();
SetBusyStatus(false);
if (view.Rows.Count > 0)
{
view.Rows[0].Selected = true;
UpdateEntity();
}
}
);
}
/// <summary>
/// Вызывает действие на указанном элементе управления в нужном потоке , если это необходимо.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="control"></param>
/// <param name="action"></param>
private void InvokeControl<T>(T control, Action<T> action)
where T : Control
{
if (control.InvokeRequired)
{
control.Invoke(action, control);
}
else
{
action(control);
}
}
/// <summary>
/// Обновить сущность, которая была выбрана в элементе управления DataGridView.
/// </summary>
private void UpdateEntity()
{
if (DataGridView.SelectedRows.Count == 0)
{
return;
}
EntityGridRow? data = (EntityGridRow?)DataGridView.SelectedRows[0].DataBoundItem;
try
{
CurrentEntity = data is not null ? new(Context, Type, data.Id) : null;
}
catch (Exception)
{
// ignored
}
EntityChange?.Invoke(CurrentEntity);
}
#endregion
#region Output events
/// <summary>
/// Делегат, который будет вызван при изменении выбранной сущности.
/// </summary>
/// <param name="newEntity">Новая выбранная сущность.</param>
public delegate void EntityChangeHandler(EntityView newEntity);
/// <summary>
/// Событие, которое вызывается при изменении выбранной сущности.
/// </summary>
public event EntityChangeHandler? EntityChange;
#endregion
/// <summary>
/// Класс, который представляет строку в таблице сущностей.
/// </summary>
/// <param name="entity">Сущность, связанная со строкой</param>
internal class EntityGridRow(Entity entity)
{
/// <summary>
/// Идентификатор сущности.
/// </summary>
public int Id { get; set; } = entity.Id;
/// <summary>
/// Название сущности.
/// </summary>
public string Name { get; set; } = entity.Name[LocaleType.English];
/// <summary>
/// Редкость сущности.
/// </summary>
public EntityRarity Rarity { get; set; } = entity.Rarity;
}
}
@@ -1,132 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="Id.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Rarity.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="DbBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="PagesBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>163, 17</value>
</metadata>
</root>
@@ -1,60 +0,0 @@
namespace Pf2eDataScrapper.Forms.Controls.EntityTreeViewer;
sealed partial class EntityTreeViewerControl
{
/// <summary>
/// Обязательная переменная конструктора.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором компонентов
/// <summary>
/// Требуемый метод для поддержки конструктора — не изменяйте
/// содержимое этого метода с помощью редактора кода.
/// </summary>
private void InitializeComponent()
{
ContentPanel = new PictureBox();
((System.ComponentModel.ISupportInitialize)ContentPanel).BeginInit();
SuspendLayout();
//
// ContentPanel
//
ContentPanel.Location = new Point(0, 0);
ContentPanel.Name = "ContentPanel";
ContentPanel.Size = new Size(400, 500);
ContentPanel.TabIndex = 0;
ContentPanel.TabStop = false;
ContentPanel.MouseMove += ContentPanel_MouseMove;
//
// EntityTreeViewerControl
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
AutoScroll = true;
Controls.Add(ContentPanel);
Name = "EntityTreeViewerControl";
Size = new Size(400, 500);
Resize += EntityTreeViewerControl_Resize;
((System.ComponentModel.ISupportInitialize)ContentPanel).EndInit();
ResumeLayout(false);
}
#endregion
public PictureBox ContentPanel;
}
@@ -1,407 +0,0 @@
using System.ComponentModel;
using Pf2eDataScrapper.Helpers;
using Pf2eDataScrapper.WPF.ViewModels.EntityViewStructure;
namespace Pf2eDataScrapper.Forms.Controls.EntityTreeViewer;
/// <summary>
/// Элемент управления для отображения структуры сущности.
/// </summary>
public sealed partial class EntityTreeViewerControl : UserControl
{
#region "Поля элемента управления"
/// <summary>
/// Высота строки поля структуры.
/// </summary>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[Category("Entity Render")]
[Description("The height of each item in the tree view.")]
public int ItemHeight
{
get => _itemHeight;
set
{
_itemHeight = value;
UpdateView();
}
}
private int _itemHeight = 20;
/// <summary>
/// Сущность, которая будет отображаться в элементе управления.
/// </summary>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public EntityView? EntityView
{
get => _entityView;
set
{
_entityView = value;
UpdateData();
}
}
private EntityView? _entityView;
/// <summary>
/// Ширина отступа глубины.
/// </summary>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[Category("Entity Render")]
[Description("The size of tab.")]
public int DepthSize
{
get => _depthSize;
set
{
_depthSize = value;
UpdateView();
}
}
private int _depthSize = 20;
/// <summary>
/// Размер шрифта типа поля сущности.
/// </summary>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[Category("Entity Render")]
[Description("The size of tab.")]
public float TypeFontSize
{
get => _typeFontSize;
set
{
_typeFontSize = value;
UpdateView();
}
}
private float _typeFontSize = 9.5f;
/// <summary>
/// Размер кнопки плюс/минус.
/// </summary>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[Category("Entity Render")]
[Description("The size of plus/minus button.")]
public int ButtonSize
{
get => _buttonSize;
set
{
_buttonSize = value;
UpdateView();
}
}
private int _buttonSize = 20;
/// <summary>
/// Ширина имени поля сущности.
/// </summary>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public int NameWidth { get; private set; } = 200;
/// <summary>
/// Цвет фона строки поля при наведении на элемент управления.
/// </summary>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[Category("Entity Render")]
[Description("Color on item hover.")]
public Color HoverColor
{
get => _hoverColor;
set
{
_hoverColor = value;
UpdateView();
}
}
private Color _hoverColor = SystemColors.ControlDark;
/// <summary>
/// Изображение, используемое для отображения содержимого элемента управления.
/// </summary>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public Bitmap ContentImage { get; set; }
#endregion
#region "Вычисляемые поля"
/// <summary>
/// Ширина области содержимого элемента управления.
/// </summary>
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public int ContentWidth => Width - SystemInformation.VerticalScrollBarWidth - 2;
#endregion
#region "Приватные поля"
/// <summary>
/// Коллекция полей структуры.
/// </summary>
private readonly List<StructureField> _rows = [];
/// <summary>
/// Коллекция строк полей структуры, которые будут отображаться в элементе управления.
/// </summary>
private List<EntityTreeViewerControlRow> _viewerRows = [];
/// <summary>
/// Флаг, указывающий, что элемент управления в данный момент перерисовывается.
/// </summary>
private bool _rendering;
#endregion
/// <summary>
/// Конструктор класса <see cref="EntityTreeViewerControl"/>.
/// </summary>
public EntityTreeViewerControl()
{
InitializeComponent();
ContentImage = new(ContentWidth, Height);
DoubleBuffered = true;
VerticalScroll.Visible = true;
HorizontalScroll.Visible = false;
ContentPanel.MouseWheel += ContentPanel_MouseWheel;
}
#region "Методы обновления"
/// <summary>
/// Обновление данных в элементе управления.
/// </summary>
public void UpdateData()
{
if (EntityView?.Entity is null)
{
return;
}
_rows.Clear();
ContentPanel.Controls.Clear();
StructureBuilder builder = new();
_rows.Add(builder.Create("Entity", EntityView.Entity));
if (EntityView.SubEntity is not null)
{
string typeName = EntityView.SubEntity.GetType().Name;
_rows.Add(builder.Create(typeName, EntityView.SubEntity));
}
_viewerRows = _rows
.SelectMany(r => r.GetRows(row => new EntityTreeViewerControlRow(this, row)))
.ToList();
UpdateRenders();
}
/// <summary>
/// Обновление отрисовок в элементе управления.
/// </summary>
public void UpdateRenders()
{
if (EntityView?.Entity is null)
{
return;
}
int maxNameWidth = -1;
foreach (EntityTreeViewerControlRow row in _viewerRows)
{
int nameWidth = row.NameWidth + row.Item.Depth * DepthSize;
maxNameWidth = Math.Max(maxNameWidth, nameWidth);
}
NameWidth = maxNameWidth + 3;
// Debug.WriteLine($@"Height Inner {ContentWidth} / Outer {Width}");
// Debug.WriteLine($@"Name {NameWidth} / Full {ContentWidth}");
foreach (EntityTreeViewerControlRow row in _viewerRows)
{
row.UpdateCache();
}
UpdateView();
}
/// <summary>
/// Обновление отображения в элементе управления.
/// </summary>
public void UpdateView()
{
if (EntityView?.Entity is null)
{
return;
}
_viewerRows.ForEach(row => row.UpdateButton());
List<EntityTreeViewerControlRow> rows = _viewerRows.Where(r => r.Item.Visible).ToList();
if (rows.Count == 0)
{
return;
}
BuildLadder(rows);
_rendering = true;
ContentImage = new(ContentWidth, rows.Count * ItemHeight);
Graphics g = Graphics.FromImage(ContentImage);
int viewRow = 0;
foreach (EntityTreeViewerControlRow row in rows)
{
row.ViewIndex = viewRow++;
row.Invalidate(g);
}
g.Save();
ContentPanel.Image = ContentImage;
ContentPanel.Width = ContentImage.Width;
ContentPanel.Height = ContentImage.Height;
_rendering = false;
}
#endregion
#region "Вспомогательные методы"
/// <summary>
/// Построение лестницы для строк полей структуры.
/// </summary>
/// <param name="rows">Набор строк полей структуры.</param>
private void BuildLadder(List<EntityTreeViewerControlRow> rows)
{
List<LadderType> lastLadder = [];
for (int i = rows.Count - 1; i >= 0; i--)
{
EntityTreeViewerControlRow row = rows[i];
List<LadderType> ladder;
if (row.Depth == 0)
{
ladder = [];
}
else if (row.Depth < lastLadder.Count)
{
ladder =
[
.. lastLadder[..(row.Depth - 1)],
lastLadder[row.Depth - 1] == LadderType.Empty
? LadderType.Last
: LadderType.Through,
];
}
else if (row.Depth == lastLadder.Count)
{
ladder = lastLadder;
}
else
{
ladder =
[
.. lastLadder,
.. Enumerable.Repeat(LadderType.Empty, row.Depth - lastLadder.Count - 1),
LadderType.Last,
];
}
row.Ladder = ladder;
lastLadder = ladder
.Select(l => (l == LadderType.Last) ? LadderType.Through : l)
.ToList();
}
}
#endregion
#region "События элемента управления"
/// <summary>
/// Обработчик события изменения размера элемента управления.
/// </summary>
/// <param name="sender">Источник события.</param>
/// <param name="e">Объект события.</param>
private void EntityTreeViewerControl_Resize(object sender, EventArgs e)
{
if (_rendering)
{
return;
}
ContentPanel.Width = Width;
UpdateRenders();
}
/// <summary>
/// Обработчик события прокрутки элемента управления.
/// </summary>
/// <param name="sender">Источник события.</param>
/// <param name="e">Объект события.</param>
private void ContentPanel_MouseWheel(object? sender, MouseEventArgs e)
{
/*
int initValue = VerticalScroll.Value;
int delta = -e.Delta / 120;
VerticalScroll.Value = Math.Clamp(
initValue + delta,
VerticalScrollBar.Minimum,
VerticalScrollBar.Maximum - VerticalScrollBar.LargeChange + 1
);
if (VerticalScrollBar.Value != initValue)
{
ContentPanel.Invalidate();
}
*/
}
/// <summary>
/// Обработчик события движения мыши над элементом управления.
/// </summary>
/// <param name="sender">Источник события.</param>
/// <param name="e">Объект события.</param>
private void ContentPanel_MouseMove(object sender, MouseEventArgs e)
{
PointF p = new(e.X, e.Y);
foreach (EntityTreeViewerControlRow row in _viewerRows)
{
bool contained = row.Target.Contains(p);
if (contained != row.Hovered)
{
Rectangle r = new();
row.RealTarget.Intersect(r);
ContentPanel.Invalidate(r);
}
row.Hovered = contained;
}
}
#endregion
}
@@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
@@ -1,607 +0,0 @@
using FontAwesome.Sharp;
using Pf2eDataScrapper.WPF.ViewModels.EntityViewStructure;
using Font = System.Drawing.Font;
using FontStyle = System.Drawing.FontStyle;
using Image = System.Drawing.Image;
namespace Pf2eDataScrapper.Forms.Controls.EntityTreeViewer;
/// <summary>
/// Элемент управления для отображения строки поля сущности.
/// </summary>
internal class EntityTreeViewerControlRow
{
/// <summary>
/// Элемент управления, которому принадлежит эта строка.
/// </summary>
public readonly EntityTreeViewerControl ParentControl;
/// <summary>
/// Отображаемая строка поля сущности.
/// </summary>
public readonly StructureField Item;
#region "Поля строки"
/// <summary>
/// Кэш изображения строки.
/// </summary>
public Image Cache
{
get
{
if (_cache == null)
{
UpdateCache();
}
return _cache!;
}
set => _cache = value;
}
private Image? _cache;
/// <summary>
/// Кэш изображения строки при наведении.
/// </summary>
public Image HoveredCache
{
get
{
if (_hoveredCache == null)
{
UpdateCache();
}
return _hoveredCache!;
}
set => _hoveredCache = value;
}
private Image? _hoveredCache;
/// <summary>
/// Список типов лестницы.
/// </summary>
public List<LadderType> Ladder
{
get => _ladder;
set
{
_ladder = value;
_cache = null;
}
}
private List<LadderType> _ladder = [];
/// <summary>
/// Проверяет, находится ли курсор над строкой.
/// </summary>
public bool Hovered
{
get => _hovered;
set
{
if (value != _hovered)
{
_hovered = value;
Invalidate();
}
}
}
private bool _hovered;
/// <summary>
/// Индекс строки в представлении.
/// </summary>
public int ViewIndex { get; set; } // = -1;
/// <summary>
/// Кнопка раскрытия/сворачивания.
/// </summary>
public IconButton? Button { get; set; }
#endregion
#region "Поля для рендеринга"
/// <inheritdoc cref="EntityTreeViewerControl.Font"/>
public Font Font
{
get => ParentControl.Font;
set => ParentControl.Font = value;
}
/// <inheritdoc cref="EntityTreeViewerControl.ForeColor"/>
public Color ForeColor
{
get => ParentControl.ForeColor;
set => ParentControl.ForeColor = value;
}
/// <inheritdoc cref="EntityTreeViewerControl.BackColor"/>
public Color BackColor
{
get => ParentControl.BackColor;
set => ParentControl.BackColor = value;
}
/// <inheritdoc cref="EntityTreeViewerControl.HoverColor"/>
public Color HoverColor
{
get => ParentControl.HoverColor;
set => ParentControl.HoverColor = value;
}
/// <inheritdoc cref="EntityTreeViewerControl.ItemHeight"/>
public int ItemHeight
{
get => ParentControl.ItemHeight;
set => ParentControl.ItemHeight = value;
}
/// <inheritdoc cref="EntityTreeViewerControl.DepthSize"/>
public int DepthSize
{
get => ParentControl.DepthSize;
set => ParentControl.DepthSize = value;
}
/// <inheritdoc cref="EntityTreeViewerControl.ButtonSize"/>
public int ButtonSize
{
get => ParentControl.ButtonSize;
set => ParentControl.ButtonSize = value;
}
/// <inheritdoc cref="EntityTreeViewerControl.TypeFontSize"/>
public float TypeFontSize
{
get => ParentControl.TypeFontSize;
set => ParentControl.TypeFontSize = value;
}
#endregion
#region "Вычисляемые поля"
/// <summary>
/// Ширина строки.
/// </summary>
public int Width => ParentControl.ContentWidth;
/// <summary>
/// Высота строки.
/// </summary>
public int Height => ItemHeight;
/// <summary>
/// Флаг наличия кнопки.
/// </summary>
public bool HasButton => Item.FieldType == StructureFieldType.Complex;
/// <summary>
/// Глубина отображения строки.
/// </summary>
public int Depth => Item.Depth;
/// <summary>
/// Ширина имени в строке.
/// </summary>
public int NameWidth
{
get
{
Graphics g = Graphics.FromImage(Cache);
return Convert.ToInt32(g.MeasureString(Item.Name, Font).Width + DepthSize);
}
}
/// <summary>
/// Строковое представление типа поля.
/// </summary>
public string TypeText
{
get
{
string result = Item.GetTypeString();
if (result != "")
{
result = $@"({result})";
}
return result;
}
}
/// <summary>
/// Шрифт для отображения типа поля.
/// </summary>
public Font TypeFont => new(Font.FontFamily, TypeFontSize);
/// <summary>
/// Строковое представление значения поля.
/// </summary>
public string ValueText => Item.GetValueString();
/// <summary>
/// Шрифт для отображения значения поля.
/// </summary>
public Font ValueFont =>
new(
Font.FontFamily,
Font.Size,
Item.FieldType == StructureFieldType.Complex ? FontStyle.Italic : FontStyle.Regular
);
/// <summary>
/// Прямоугольник, занимаемый строкой в представлении.
/// </summary>
public RectangleF Target => new(0, ViewIndex * Height, Width, Height);
/// <summary>
/// Прямоугольник, занимаемый строкой в родительском представлении.
/// </summary>
public RectangleF RealTarget =>
new(0, ViewIndex * Height - ParentControl.VerticalScroll.Value, Width, Height);
#endregion
/// <summary>
/// Список данных для рендеринга строк.
/// </summary>
private readonly List<StringRenderData> _renderData = [];
#region "Основные методы"
/// <summary>
/// Создание элемента управления строки поля сущности.
/// </summary>
/// <param name="parent">Родительский элемент управления.</param>
/// <param name="item">Строка поля структуры объекта.</param>
public EntityTreeViewerControlRow(EntityTreeViewerControl parent, StructureField item)
{
ParentControl = parent;
Item = item;
ApplyItem();
UpdateCache();
UpdateButton();
}
/// <summary>
/// Применение свойств к элементу управления.
/// </summary>
private void ApplyItem()
{
_renderData.Clear();
_renderData.Add(new(Item.Name, Font, ForeColor));
_renderData.Add(new(TypeText, TypeFont, GetValueColor()));
_renderData.Add(
new(ValueText.Replace("\r", "").Replace('\n', ' '), ValueFont, GetValueColor())
);
if (HasButton)
{
Button = new()
{
Width = ButtonSize,
Height = ButtonSize,
IconSize = ButtonSize,
IconChar = IconChar.MinusSquare,
ImageAlign = ContentAlignment.MiddleCenter,
TextAlign = ContentAlignment.MiddleCenter,
Visible = false,
};
Button.Click += Button_Click;
ParentControl.ContentPanel.Controls.Add(Button);
}
}
/// <summary>
/// Обновление кэша изображения строки.
/// </summary>
public void UpdateCache()
{
Cache = RenderCache(BackColor);
HoveredCache = RenderCache(HoverColor);
}
/// <summary>
/// Создание кэша изображения строки.
/// </summary>
/// <param name="backColor">Цвет заднего фона.</param>
/// <returns>Кеш изображения строки.</returns>
private Image RenderCache(Color backColor)
{
Image cache = new Bitmap(Width, Height);
Graphics g = Graphics.FromImage(cache);
g.FillRectangle(new SolidBrush(backColor), 0, 0, Width, Height);
RenderLadder(g);
RenderContent(g);
g.Save();
return cache;
}
/// <summary>
/// Запрос на перерисовку строки.
/// </summary>
/// <param name="g">Графический объект.</param>
public void Invalidate(Graphics? g = null)
{
g ??= Graphics.FromImage(ParentControl.ContentImage);
g.DrawImage(Hovered ? HoveredCache : Cache, Target);
UpdateButton();
}
#endregion
#region "Кнопка"
/// <summary>
/// Обновление кнопки раскрытия/сворачивания.
/// </summary>
public void UpdateButton()
{
if (Button is null)
{
return;
}
int cx = Convert.ToInt32((0.5 + Depth) * DepthSize - 0.5 * ButtonSize);
int cy = Convert.ToInt32((0.5 + ViewIndex) * ItemHeight - 0.5 * ButtonSize);
Button.Left = cx;
Button.Top = cy;
Button!.IconChar = ((StructureFieldComplex)Item).Collapsed
? IconChar.PlusSquare
: IconChar.MinusSquare;
Button.Visible = Item.Visible;
}
/// <summary>
/// Событие нажатия кнопки раскрытия/сворачивания.
/// </summary>
/// <param name="sender">Источник события.</param>
/// <param name="e">Событие нажатие кнопки</param>
private void Button_Click(object? sender, EventArgs e)
{
if (Item is StructureFieldComplex complex)
{
complex.Collapsed = !complex.Collapsed;
ParentControl.UpdateView();
}
}
#endregion
#region "Отрисовка"
/// <summary>
/// Отрисовка лестницы.
/// </summary>
/// <param name="g">Графический объект.</param>
private void RenderLadder(Graphics g)
{
int n = Depth;
int h = ItemHeight;
int w = DepthSize;
if (_ladder.Count < Depth)
{
return;
}
Pen pen = new(Color.FromArgb(127, ForeColor.R, ForeColor.G, ForeColor.B), 1);
pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
float cy = 0.5f * h;
for (int i = 0; i < n; i++)
{
float cx = (i + 1.5f) * w;
switch (_ladder[i])
{
case LadderType.Last:
g.DrawLine(pen, cx, 0, cx, cy);
break;
case LadderType.Through:
g.DrawLine(pen, cx, 0, cx, h);
break;
case LadderType.Empty:
default:
break;
}
if (i == n - 1)
{
g.DrawLine(pen, cx, cy, (i + 2) * w, cy);
}
}
}
/// <summary>
/// Отрисовка содержимого строки.
/// </summary>
/// <param name="g">Графический объект.</param>
private void RenderContent(Graphics g)
{
float[] xs =
[
DepthSize * (Item.Depth + 1),
ParentControl.NameWidth,
ParentControl.NameWidth + g.MeasureString(TypeText, TypeFont).Width + 3,
Width,
];
Pen _ = new(Color.Aqua, 1);
for (int i = 0; i < 3; i++)
{
StringRenderData item = _renderData[i];
item.Left = xs[i];
item.Width = xs[i + 1] - xs[i];
item.Height = ItemHeight;
// g.DrawRectangle(p, item.Rect);
item.Draw(g);
}
}
#endregion
#region Функции-помощники в отрисовке
/// <summary>
/// Смешивание цвета с цветом текста.
/// </summary>
/// <param name="color">Цвет оттенка.</param>
/// <param name="rate">Степень смешения.</param>
/// <returns>Смешенный цвет.</returns>
private Color BlendColor(Color color, double rate = 0.5)
{
return BlendColor(ForeColor, color, rate);
}
/// <summary>
/// Смешивание цветов.
/// </summary>
/// <param name="color1">Первый смешиваемый цвет.</param>
/// <param name="color2">Второй смешиваемый цвет.</param>
/// <param name="rate">Степень смешения.</param>
/// <returns>Смешенный цвет.</returns>
private Color BlendColor(Color color1, Color color2, double rate)
{
return Color.FromArgb(
Mix(color1.A, color2.A),
Mix(color1.R, color2.R),
Mix(color1.G, color2.G),
Mix(color1.B, color2.B)
);
int Mix(int a, int b) => Convert.ToInt32(Math.Round(a * rate + b * (1 - rate)));
}
/// <summary>
/// Получение цвета текста по типу значения поля.
/// </summary>
/// <returns>Цвет текста.</returns>
public Color GetValueColor()
{
return Item switch
{
StructureFieldPrimitive primitive => Type.GetTypeCode(primitive.Type) switch
{
TypeCode.Boolean => BlendColor(Color.DarkGoldenrod),
TypeCode.Int32 => BlendColor(Color.Blue),
TypeCode.Double => BlendColor(Color.Aqua),
TypeCode.String => BlendColor(Color.Green),
_ => ForeColor,
},
StructureFieldEnum => BlendColor(Color.Red),
StructureFieldNull => BlendColor(BackColor),
_ => ForeColor,
};
}
#endregion
/// <summary>
/// Класс для хранения данных рендеринга строки.
/// </summary>
/// <param name="text">Текст отображаемой строки.</param>
/// <param name="font">Шрифт отображаемой строки.</param>
/// <param name="color">Цвет отображаемой строки.</param>
private class StringRenderData(string text, Font font, Color color)
{
/// <summary>
/// Текст отображаемой строки.
/// </summary>
public string Text { get; } = text;
/// <summary>
/// Шрифт отображаемой строки.
/// </summary>
public Font Font { get; } = font;
/// <summary>
/// Цвет отображаемой строки.
/// </summary>
public Color Color { get; } = color;
/// <summary>
/// Левый край отображаемой строки.
/// </summary>
public float Left { get; set; }
/// <summary>
/// Ширина отображаемой строки.
/// </summary>
public float Width { get; set; }
/// <summary>
/// Высота отображаемой строки.
/// </summary>
public float Height { get; set; }
/// <summary>
/// Прямоугольник, занимаемый строкой.
/// </summary>
public RectangleF Rect => new(Left, 0, Width, Height);
/// <summary>
/// Уместить строку в занимаемый прямоугольник.
/// </summary>
/// <param name="g">Элемент графики.</param>
/// <param name="rect">Занимаемый прямоугольник</param>
/// <param name="filler">Строка, на которую будет заканчиваться значнеие при переполнении.</param>
/// <returns></returns>
private string Fit(Graphics g, RectangleF rect, string filler = "…")
{
if (Text.Length == 0 || g.MeasureString(Text, Font).Width <= rect.Width)
{
return Text;
}
string txt = Text.Length > 100 ? Text[..100] : Text;
int i = txt.Length;
while (g.MeasureString(txt + filler, Font).Width > rect.Width)
{
txt = txt[..--i];
if (i == 0)
break;
}
return txt + filler;
}
/// <summary>
/// Отрисовка строки.
/// </summary>
/// <param name="g">Элемент графики.</param>
public void Draw(Graphics g)
{
g.DrawString(
Fit(g, Rect),
Font,
new SolidBrush(Color),
Rect,
new StringFormat
{
Alignment = StringAlignment.Near,
LineAlignment = StringAlignment.Center,
FormatFlags = StringFormatFlags.NoWrap,
}
);
}
}
}
@@ -1,36 +0,0 @@
namespace Pf2eDataScrapper.Forms.Controls.EntityTreeViewer;
partial class EntityViewerControl
{
/// <summary>
/// Обязательная переменная конструктора.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором компонентов
/// <summary>
/// Требуемый метод для поддержки конструктора — не изменяйте
/// содержимое этого метода с помощью редактора кода.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
}
#endregion
}
@@ -1,18 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Pf2eDataScrapper.Forms.Controls.EntityTreeViewer;
public partial class EntityViewerControl : UserControl
{
public EntityViewerControl()
{
InitializeComponent();
}
}
@@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
@@ -1,60 +0,0 @@
namespace Pf2eDataScrapper.Forms.Controls;
partial class ProcessorCollectionControl
{
/// <summary>
/// Обязательная переменная конструктора.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором компонентов
/// <summary>
/// Требуемый метод для поддержки конструктора — не изменяйте
/// содержимое этого метода с помощью редактора кода.
/// </summary>
private void InitializeComponent()
{
RootFlowLayoutPanel = new FlowLayoutPanel();
SuspendLayout();
//
// RootFlowLayoutPanel
//
RootFlowLayoutPanel.AutoScroll = true;
RootFlowLayoutPanel.BackColor = SystemColors.Window;
RootFlowLayoutPanel.BorderStyle = BorderStyle.FixedSingle;
RootFlowLayoutPanel.Dock = DockStyle.Fill;
RootFlowLayoutPanel.FlowDirection = FlowDirection.TopDown;
RootFlowLayoutPanel.Location = new Point(0, 0);
RootFlowLayoutPanel.Name = "RootFlowLayoutPanel";
RootFlowLayoutPanel.Size = new Size(432, 406);
RootFlowLayoutPanel.TabIndex = 0;
RootFlowLayoutPanel.WrapContents = false;
//
// ProcessorCollectionControl
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
Controls.Add(RootFlowLayoutPanel);
Name = "ProcessorCollectionControl";
Size = new Size(432, 406);
ResumeLayout(false);
}
#endregion
private FlowLayoutPanel RootFlowLayoutPanel;
}
@@ -1,173 +0,0 @@
using System.ComponentModel;
using Pf2eDataScrapper.App;
namespace Pf2eDataScrapper.Forms.Controls;
internal partial class ProcessorCollectionControl : UserControl
{
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public ProcessorCollection Collection
{
get => _collection;
set
{
_collection = value;
SetContent();
}
}
private ProcessorCollection _collection = null!;
public ProcessorCollectionControl()
{
InitializeComponent();
}
private Dictionary<ProcessorGroupEnum, CheckBox> GroupCheckBoxes { get; } = [];
private Dictionary<ProcessorGroupEnum, FlowLayoutPanel> GroupFlowLayoutPanels { get; } = [];
private Dictionary<string, CheckBox> ItemCheckBoxes { get; } = [];
private void SetContent()
{
RootFlowLayoutPanel.Controls.Clear();
foreach (ProcessorGroupEnum group in Enum.GetValues<ProcessorGroupEnum>())
{
GroupCheckBoxes[group] = new()
{
Text = group.GetDescription(),
Tag = group,
Dock = DockStyle.Fill,
ThreeState = true,
Checked = true,
AutoCheck = false,
CheckAlign = ContentAlignment.TopLeft,
};
GroupCheckBoxes[group].Click += GroupCheckBox_Click;
GroupFlowLayoutPanels[group] = new()
{
AutoSize = true,
Dock = DockStyle.Fill,
FlowDirection = FlowDirection.LeftToRight,
WrapContents = true,
BorderStyle = BorderStyle.FixedSingle,
Margin = new(10, 0, 10, 15),
};
RootFlowLayoutPanel.Controls.Add(GroupCheckBoxes[group]);
RootFlowLayoutPanel.Controls.Add(GroupFlowLayoutPanels[group]);
}
foreach (ProcessorCollectionItem item in Collection.AllItems)
{
ItemCheckBoxes[item.Name] = new()
{
Text = item.Description,
Tag = item,
AutoSize = true,
// Dock = DockStyle.Fill,
// MaximumSize = new Size(Width, 20),
// Width = 200,
Checked = item.Active,
CheckAlign = ContentAlignment.TopLeft,
};
ItemCheckBoxes[item.Name].CheckedChanged += ItemCheckBox_CheckedChanged;
GroupFlowLayoutPanels[item.Group].Controls.Add(ItemCheckBoxes[item.Name]);
}
UpdateContent();
}
private void UpdateContent()
{
Dictionary<ProcessorGroupEnum, CheckState> checkStates = [];
List<string> checkedItems = [];
foreach ((string key, CheckBox checkBox) in ItemCheckBoxes)
{
ProcessorCollectionItem item = Collection[key];
if (checkStates.TryGetValue(item.Group, out CheckState state))
{
/*
* | Checked | Unchecked | Indeterminate
* -------+---------------+---------------+---------------
* true | Checked | Indeterminate | Indeterminate
* false | Indeterminate | Unchecked | Indeterminate
*/
checkStates[item.Group] =
checkBox.Checked && state == CheckState.Checked ? CheckState.Checked
: !checkBox.Checked && state == CheckState.Unchecked ? CheckState.Unchecked
: CheckState.Indeterminate;
}
else
{
checkStates[item.Group] = checkBox.Checked
? CheckState.Checked
: CheckState.Unchecked;
}
if (checkBox.Checked)
{
checkedItems.Add(key);
}
}
foreach ((ProcessorGroupEnum groupEnum, CheckBox checkBox) in GroupCheckBoxes)
{
checkBox.CheckState = checkStates.GetValueOrDefault(
groupEnum,
CheckState.Indeterminate
);
}
Collection.FilterProcessors(checkedItems);
}
private void GroupCheckBox_Click(object? sender, EventArgs e)
{
if (sender is null)
{
return;
}
CheckBox groupCheckBox = (CheckBox)sender;
ProcessorGroupEnum groupEnum = GroupCheckBoxes
.First(pair => pair.Value == groupCheckBox)
.Key;
CheckState nextState = groupCheckBox.CheckState switch
{
CheckState.Unchecked => CheckState.Checked,
CheckState.Checked => CheckState.Unchecked,
CheckState.Indeterminate => CheckState.Checked,
_ => throw new ArgumentOutOfRangeException(
$"Неизвестное состояние {groupCheckBox.CheckState}"
),
};
groupCheckBox.CheckState = nextState;
foreach (
(string _, CheckBox checkBox) in ItemCheckBoxes.Where(pair =>
((ProcessorCollectionItem?)pair.Value.Tag)?.Group == groupEnum
)
)
{
checkBox.Checked = nextState == CheckState.Checked;
}
UpdateContent();
}
private void ItemCheckBox_CheckedChanged(object? sender, EventArgs e)
{
UpdateContent();
}
}
@@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
-240
View File
@@ -1,240 +0,0 @@
using Pf2eDataScrapper.Forms.Controls.DatabaseViewer;
using Pf2eDataScrapper.Forms.Controls.EntityTreeViewer;
namespace Pf2eDataScrapper.Forms;
partial class EntityViewForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
RootSplitContainer = new SplitContainer();
InnerSplitContainer = new SplitContainer();
TypesListBox = new ListBox();
ResultSplitContainer = new SplitContainer();
DescriptionTextBox = new TextBox();
DatabaseViewer = new DatabaseViewerControl();
_entityTreeViewerCntrl = new EntityTreeViewerControl();
MenuStrip = new MenuStrip();
FileToolStripMenuItem = new ToolStripMenuItem();
ExitToolStripMenuItem = new ToolStripMenuItem();
WindowsToolStripMenuItem = new ToolStripMenuItem();
ImportSettingsWindowsToolStripMenuItem = new ToolStripMenuItem();
EntityViewWindowToolStripMenuItem = new ToolStripMenuItem();
((System.ComponentModel.ISupportInitialize)RootSplitContainer).BeginInit();
RootSplitContainer.Panel1.SuspendLayout();
RootSplitContainer.Panel2.SuspendLayout();
RootSplitContainer.SuspendLayout();
((System.ComponentModel.ISupportInitialize)InnerSplitContainer).BeginInit();
InnerSplitContainer.Panel1.SuspendLayout();
InnerSplitContainer.SuspendLayout();
((System.ComponentModel.ISupportInitialize)ResultSplitContainer).BeginInit();
ResultSplitContainer.Panel2.SuspendLayout();
ResultSplitContainer.SuspendLayout();
MenuStrip.SuspendLayout();
SuspendLayout();
//
// RootSplitContainer
//
RootSplitContainer.Dock = DockStyle.Fill;
RootSplitContainer.Location = new Point(0, 24);
RootSplitContainer.Name = "RootSplitContainer";
//
// RootSplitContainer.Panel1
//
RootSplitContainer.Panel1.Controls.Add(InnerSplitContainer);
RootSplitContainer.Panel1MinSize = 200;
//
// RootSplitContainer.Panel2
//
RootSplitContainer.Panel2.Controls.Add(ResultSplitContainer);
RootSplitContainer.Panel2MinSize = 400;
RootSplitContainer.Size = new Size(1384, 837);
RootSplitContainer.SplitterDistance = 322;
RootSplitContainer.TabIndex = 0;
//
// InnerSplitContainer
//
InnerSplitContainer.Dock = DockStyle.Fill;
InnerSplitContainer.Location = new Point(0, 0);
InnerSplitContainer.Name = "InnerSplitContainer";
InnerSplitContainer.Orientation = Orientation.Horizontal;
//
// InnerSplitContainer.Panel1
//
InnerSplitContainer.Panel1.Controls.Add(TypesListBox);
//
// InnerSplitContainer.Panel2
//
InnerSplitContainer.Panel2.Controls.Add(DatabaseViewer);
InnerSplitContainer.Size = new Size(322, 861);
InnerSplitContainer.SplitterDistance = 126;
InnerSplitContainer.TabIndex = 1;
//
// TypesListBox
//
TypesListBox.Dock = DockStyle.Fill;
TypesListBox.FormattingEnabled = true;
TypesListBox.Location = new Point(0, 0);
TypesListBox.Name = "TypesListBox";
TypesListBox.Size = new Size(322, 122);
TypesListBox.TabIndex = 0;
TypesListBox.SelectedIndexChanged += TypesListBox_SelectedIndexChanged;
//
// ResultSplitContainer
//
ResultSplitContainer.Dock = DockStyle.Fill;
ResultSplitContainer.Location = new Point(0, 0);
ResultSplitContainer.Name = "ResultSplitContainer";
//
// ResultSplitContainer.Panel2
//
ResultSplitContainer.Panel2.Controls.Add(DescriptionTextBox);
ResultSplitContainer.Size = new Size(1058, 837);
ResultSplitContainer.SplitterDistance = 582;
ResultSplitContainer.TabIndex = 1;
//
// DescriptionTextBox
//
DescriptionTextBox.Dock = DockStyle.Fill;
DescriptionTextBox.Font = new Font("Consolas", 9F);
DescriptionTextBox.Location = new Point(0, 0);
DescriptionTextBox.Multiline = true;
DescriptionTextBox.Name = "DescriptionTextBox";
DescriptionTextBox.ReadOnly = true;
DescriptionTextBox.ScrollBars = ScrollBars.Vertical;
DescriptionTextBox.Size = new Size(472, 837);
DescriptionTextBox.TabIndex = 0;
//
// DatabaseViewer
//
DatabaseViewer.Dock = DockStyle.Fill;
DatabaseViewer.Location = new Point(0, 0);
DatabaseViewer.Name = "DatabaseViewer";
DatabaseViewer.Size = new Size(322, 731);
DatabaseViewer.TabIndex = 1;
//
// _entityTreeViewerCntrl
//
_entityTreeViewerCntrl.AutoScroll = true;
_entityTreeViewerCntrl.ButtonSize = 15;
_entityTreeViewerCntrl.DepthSize = 15;
_entityTreeViewerCntrl.Dock = DockStyle.Fill;
_entityTreeViewerCntrl.Font = new Font("Consolas", 9F);
_entityTreeViewerCntrl.HoverColor = SystemColors.ControlDark;
_entityTreeViewerCntrl.ItemHeight = 20;
_entityTreeViewerCntrl.Location = new Point(0, 0);
_entityTreeViewerCntrl.Name = "_entityTreeViewerCntrl";
_entityTreeViewerCntrl.Size = new Size(582, 861);
_entityTreeViewerCntrl.TabIndex = 0;
_entityTreeViewerCntrl.TypeFontSize = 7F;
//
// MenuStrip
//
MenuStrip.Items.AddRange(new ToolStripItem[] { FileToolStripMenuItem, WindowsToolStripMenuItem });
MenuStrip.Location = new Point(0, 0);
MenuStrip.Name = "MainMenuStrip";
MenuStrip.Size = new Size(1384, 24);
MenuStrip.TabIndex = 1;
MenuStrip.Text = "menuStrip1";
//
// FileToolStripMenuItem
//
FileToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { ExitToolStripMenuItem });
FileToolStripMenuItem.Name = "FileToolStripMenuItem";
FileToolStripMenuItem.Size = new Size(48, 20);
FileToolStripMenuItem.Text = "Файл";
//
// ExitToolStripMenuItem
//
ExitToolStripMenuItem.Name = "ExitToolStripMenuItem";
ExitToolStripMenuItem.Size = new Size(109, 22);
ExitToolStripMenuItem.Text = "Выход";
ExitToolStripMenuItem.Click += ExitToolStripMenuItem_Click;
//
// WindowsToolStripMenuItem
//
WindowsToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { ImportSettingsWindowsToolStripMenuItem, EntityViewWindowToolStripMenuItem });
WindowsToolStripMenuItem.Name = "WindowsToolStripMenuItem";
WindowsToolStripMenuItem.Size = new Size(47, 20);
WindowsToolStripMenuItem.Text = "Окна";
//
// ImportSettingsWindowsToolStripMenuItem
//
ImportSettingsWindowsToolStripMenuItem.Name = "ImportSettingsWindowsToolStripMenuItem";
ImportSettingsWindowsToolStripMenuItem.Size = new Size(228, 22);
ImportSettingsWindowsToolStripMenuItem.Text = "Настройка импорта данных";
ImportSettingsWindowsToolStripMenuItem.Click += ImportSettingsWindowsToolStripMenuItem_Click;
//
// EntityViewWindowToolStripMenuItem
//
EntityViewWindowToolStripMenuItem.Enabled = false;
EntityViewWindowToolStripMenuItem.Name = "EntityViewWindowToolStripMenuItem";
EntityViewWindowToolStripMenuItem.Size = new Size(228, 22);
EntityViewWindowToolStripMenuItem.Text = "Просмотр сущностей";
//
// EntityViewForm
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1384, 861);
Controls.Add(RootSplitContainer);
Controls.Add(MenuStrip);
Name = "EntityViewForm";
Text = "DataBaseViewer";
RootSplitContainer.Panel1.ResumeLayout(false);
RootSplitContainer.Panel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)RootSplitContainer).EndInit();
RootSplitContainer.ResumeLayout(false);
InnerSplitContainer.Panel1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)InnerSplitContainer).EndInit();
InnerSplitContainer.ResumeLayout(false);
ResultSplitContainer.Panel2.ResumeLayout(false);
ResultSplitContainer.Panel2.PerformLayout();
((System.ComponentModel.ISupportInitialize)ResultSplitContainer).EndInit();
ResultSplitContainer.ResumeLayout(false);
MenuStrip.ResumeLayout(false);
MenuStrip.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
#endregion
private SplitContainer RootSplitContainer;
private SplitContainer InnerSplitContainer;
private ListBox TypesListBox;
private SplitContainer ResultSplitContainer;
private TextBox DescriptionTextBox;
private EntityTreeViewerControl _entityTreeViewerCntrl;
private DatabaseViewerControl DatabaseViewer;
private MenuStrip MenuStrip;
private ToolStripMenuItem FileToolStripMenuItem;
private ToolStripMenuItem ExitToolStripMenuItem;
private ToolStripMenuItem WindowsToolStripMenuItem;
private ToolStripMenuItem ImportSettingsWindowsToolStripMenuItem;
private ToolStripMenuItem EntityViewWindowToolStripMenuItem;
}
-99
View File
@@ -1,99 +0,0 @@
using System.ComponentModel;
using Pf2eDataScrapper.Helpers;
using Pf2eModel;
using Pf2eModel.Model.Enum;
namespace Pf2eDataScrapper.Forms;
/// <summary>
/// Основная форма приложения.
/// </summary>
internal partial class EntityViewForm : Form
{
public Pf2eDbContext Context { get; }
/// <summary>
/// Элемент управления для отображения дерева сущностей.
/// </summary>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public EntityView? CurrentView
{
get => _entityTreeViewerCntrl.EntityView;
set
{
_entityTreeViewerCntrl.EntityView = value;
Application.DoEvents();
}
}
/// <summary>
/// Конструктор класса <see cref="EntityViewForm"/>.
/// </summary>
public EntityViewForm(Pf2eDbContext context)
{
Context = context;
InitializeComponent();
DatabaseViewer.EntityChange += DatabaseViewer_EntityChange;
Reset();
}
/// <summary>
/// Сброс состояния формы.
/// </summary>
public void Reset()
{
TypesListBox.DataSource = Context
.Entities.Select(e => e.Type)
.Distinct()
.OrderBy(t => t.ToString())
.ToList();
if (TypesListBox.Items.Count > 0)
{
TypesListBox.SelectedIndex = 0;
}
}
/// <summary>
/// Обработчик события изменения выбранного элемента в списке типов сущностей.
/// </summary>
/// <param name="sender">Источник события.</param>
/// <param name="_">Данные события.</param>
private void TypesListBox_SelectedIndexChanged(object sender, EventArgs _)
{
if (TypesListBox.SelectedItem is null)
{
return;
}
CurrentView = null;
DatabaseViewer.Type = (EntityType)TypesListBox.SelectedItem;
}
/// <summary>
/// Обработчик события изменения выбранной сущности в дереве сущностей.
/// </summary>
/// <param name="newEntity">Новая выбранная сущность.</param>
private void DatabaseViewer_EntityChange(EntityView newEntity)
{
CurrentView = newEntity;
DescriptionTextBox.Text = newEntity.Entity!.Description;
}
private void ExitToolStripMenuItem_Click(object sender, EventArgs e)
{
Close();
}
private void ImportSettingsWindowsToolStripMenuItem_Click(object sender, EventArgs e)
{
ApplicationStateChange?.Invoke(this, ApplicationStage.InitialSettings);
}
public event ImportApplication.ApplicationStateChangeDelegate? ApplicationStateChange;
}
-126
View File
@@ -1,126 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="MenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>51</value>
</metadata>
</root>
-128
View File
@@ -1,128 +0,0 @@
namespace Pf2eDataScrapper.Forms;
partial class ProgressForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
ProcessorsProgressBar = new ProgressBar();
ProcessorsLabel = new Label();
LocalLabel = new Label();
LocalProgressBar = new ProgressBar();
MessageListView = new ListView();
TimeColumnHeader = new ColumnHeader();
TypeColumnHeader = new ColumnHeader();
MessageColumnHeader = new ColumnHeader();
SuspendLayout();
//
// ProcessorsProgressBar
//
ProcessorsProgressBar.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
ProcessorsProgressBar.Location = new Point(12, 27);
ProcessorsProgressBar.Name = "ProcessorsProgressBar";
ProcessorsProgressBar.Size = new Size(537, 23);
ProcessorsProgressBar.TabIndex = 0;
//
// ProcessorsLabel
//
ProcessorsLabel.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
ProcessorsLabel.Location = new Point(12, 9);
ProcessorsLabel.Name = "ProcessorsLabel";
ProcessorsLabel.Size = new Size(537, 15);
ProcessorsLabel.TabIndex = 1;
ProcessorsLabel.Text = "ProcessorsLabel";
//
// LocalLabel
//
LocalLabel.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
LocalLabel.Location = new Point(12, 59);
LocalLabel.Name = "LocalLabel";
LocalLabel.Size = new Size(537, 15);
LocalLabel.TabIndex = 2;
LocalLabel.Text = "LocalLabel";
//
// LocalProgressBar
//
LocalProgressBar.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
LocalProgressBar.Location = new Point(12, 77);
LocalProgressBar.Name = "LocalProgressBar";
LocalProgressBar.Size = new Size(537, 23);
LocalProgressBar.TabIndex = 3;
//
// MessageListView
//
MessageListView.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
MessageListView.Columns.AddRange(new ColumnHeader[] { TimeColumnHeader, TypeColumnHeader, MessageColumnHeader });
MessageListView.GridLines = true;
MessageListView.HeaderStyle = ColumnHeaderStyle.Nonclickable;
MessageListView.Location = new Point(12, 114);
MessageListView.Name = "MessageListView";
MessageListView.Size = new Size(537, 450);
MessageListView.TabIndex = 4;
MessageListView.UseCompatibleStateImageBehavior = false;
MessageListView.View = View.Details;
//
// TimeColumnHeader
//
TimeColumnHeader.Text = "Время";
TimeColumnHeader.Width = 80;
//
// TypeColumnHeader
//
TypeColumnHeader.Text = "Тип";
TypeColumnHeader.Width = 80;
//
// MessageColumnHeader
//
MessageColumnHeader.Text = "Сообщение";
MessageColumnHeader.Width = 2000;
//
// ProgressForm
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(561, 576);
Controls.Add(MessageListView);
Controls.Add(LocalProgressBar);
Controls.Add(LocalLabel);
Controls.Add(ProcessorsLabel);
Controls.Add(ProcessorsProgressBar);
Name = "ProgressForm";
Text = "ProgressForm";
ResumeLayout(false);
}
#endregion
private ProgressBar ProcessorsProgressBar;
private Label ProcessorsLabel;
private Label LocalLabel;
private ProgressBar LocalProgressBar;
private ListView MessageListView;
private ColumnHeader TimeColumnHeader;
private ColumnHeader TypeColumnHeader;
private ColumnHeader MessageColumnHeader;
}
-72
View File
@@ -1,72 +0,0 @@
using Pf2eDataScrapper.Helpers;
namespace Pf2eDataScrapper.Forms;
internal partial class ProgressForm : Form
{
public ProcessProgress Progress { get; }
public ProgressForm(ProcessProgress progress)
{
Progress = progress;
InitializeComponent();
Progress.ProgressUpdate += Progress_ProgressUpdate;
Progress.ProgressMessage += Progress_ProgressMessage;
MessageListView
.GetType()
.GetProperty(
"DoubleBuffered",
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic
)!
.SetValue(MessageListView, true, null);
}
private void Progress_ProgressUpdate(ProcessProgress sender)
{
if (InvokeRequired)
{
Invoke(Progress_ProgressUpdate, sender);
return;
}
ProcessorsLabel.Text = sender.Processors.ToString();
ProcessorsProgressBar.Maximum = sender.Processors.Count;
ProcessorsProgressBar.Value = sender.Processors.Current;
LocalLabel.Text = sender.Local.ToString();
LocalProgressBar.Maximum = sender.Local.Count;
LocalProgressBar.Value = sender.Local.Current;
Application.DoEvents();
}
private void Progress_ProgressMessage(ProcessProgress sender, LogLevel level, string message)
{
if (InvokeRequired)
{
Invoke(Progress_ProgressMessage, sender, level, message);
return;
}
ListViewItem item = new([DateTime.Now.ToString("HH:mm:ss.fff"), level.ToString(), message])
{
BackColor = level switch
{
LogLevel.Important => Color.Salmon,
LogLevel.Warning => Color.Khaki,
LogLevel.Information => Color.White,
LogLevel.Progress => Color.LightGray,
_ => Color.White,
},
};
MessageListView.Items.Add(item);
//MessageListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
//MessageListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
Application.DoEvents();
}
}
-120
View File
@@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
-236
View File
@@ -1,236 +0,0 @@
namespace Pf2eDataScrapper.Forms;
partial class StartForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
MainSplitContainer = new SplitContainer();
PropertiesGroupBox = new GroupBox();
SettingsPropertyGrid = new PropertyGrid();
ProcessorsGroupBox = new GroupBox();
ProcessorCollectionControl = new Pf2eDataScrapper.Forms.Controls.ProcessorCollectionControl();
SelectAllButton = new Button();
DeselectAllButton = new Button();
StartButton = new Button();
MenuStrip = new MenuStrip();
FileToolStripMenuItem = new ToolStripMenuItem();
ExitToolStripMenuItem = new ToolStripMenuItem();
WindowsToolStripMenuItem = new ToolStripMenuItem();
ImportSettingsWindowsToolStripMenuItem = new ToolStripMenuItem();
EntityViewWindowToolStripMenuItem = new ToolStripMenuItem();
StartToolStripMenuItem = new ToolStripMenuItem();
((System.ComponentModel.ISupportInitialize)MainSplitContainer).BeginInit();
MainSplitContainer.Panel1.SuspendLayout();
MainSplitContainer.Panel2.SuspendLayout();
MainSplitContainer.SuspendLayout();
PropertiesGroupBox.SuspendLayout();
ProcessorsGroupBox.SuspendLayout();
MenuStrip.SuspendLayout();
SuspendLayout();
//
// MainSplitContainer
//
MainSplitContainer.Dock = DockStyle.Fill;
MainSplitContainer.Location = new Point(0, 24);
MainSplitContainer.Name = "MainSplitContainer";
//
// MainSplitContainer.Panel1
//
MainSplitContainer.Panel1.Controls.Add(PropertiesGroupBox);
MainSplitContainer.Panel1MinSize = 300;
//
// MainSplitContainer.Panel2
//
MainSplitContainer.Panel2.Controls.Add(ProcessorsGroupBox);
MainSplitContainer.Panel2.Controls.Add(StartButton);
MainSplitContainer.Panel2MinSize = 300;
MainSplitContainer.Size = new Size(931, 653);
MainSplitContainer.SplitterDistance = 300;
MainSplitContainer.TabIndex = 0;
//
// PropertiesGroupBox
//
PropertiesGroupBox.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
PropertiesGroupBox.Controls.Add(SettingsPropertyGrid);
PropertiesGroupBox.Location = new Point(3, 3);
PropertiesGroupBox.Name = "PropertiesGroupBox";
PropertiesGroupBox.Size = new Size(294, 647);
PropertiesGroupBox.TabIndex = 0;
PropertiesGroupBox.TabStop = false;
PropertiesGroupBox.Text = "Свойства";
//
// SettingsPropertyGrid
//
SettingsPropertyGrid.BackColor = SystemColors.Control;
SettingsPropertyGrid.Dock = DockStyle.Fill;
SettingsPropertyGrid.Location = new Point(3, 19);
SettingsPropertyGrid.Name = "SettingsPropertyGrid";
SettingsPropertyGrid.Size = new Size(288, 625);
SettingsPropertyGrid.TabIndex = 0;
//
// ProcessorsGroupBox
//
ProcessorsGroupBox.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
ProcessorsGroupBox.Controls.Add(ProcessorCollectionControl);
ProcessorsGroupBox.Controls.Add(SelectAllButton);
ProcessorsGroupBox.Controls.Add(DeselectAllButton);
ProcessorsGroupBox.Location = new Point(3, 3);
ProcessorsGroupBox.Name = "ProcessorsGroupBox";
ProcessorsGroupBox.Size = new Size(621, 578);
ProcessorsGroupBox.TabIndex = 1;
ProcessorsGroupBox.TabStop = false;
ProcessorsGroupBox.Text = "Обработчики";
//
// ProcessorCollectionControl
//
ProcessorCollectionControl.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
ProcessorCollectionControl.Location = new Point(6, 48);
ProcessorCollectionControl.Name = "ProcessorCollectionControl";
ProcessorCollectionControl.Size = new Size(609, 524);
ProcessorCollectionControl.TabIndex = 2;
//
// SelectAllButton
//
SelectAllButton.Location = new Point(149, 19);
SelectAllButton.Name = "SelectAllButton";
SelectAllButton.Size = new Size(137, 23);
SelectAllButton.TabIndex = 1;
SelectAllButton.Text = "Выделить все";
SelectAllButton.UseVisualStyleBackColor = true;
//
// DeselectAllButton
//
DeselectAllButton.Location = new Point(6, 19);
DeselectAllButton.Name = "DeselectAllButton";
DeselectAllButton.Size = new Size(137, 23);
DeselectAllButton.TabIndex = 0;
DeselectAllButton.Text = "Снять выделение всех";
DeselectAllButton.UseVisualStyleBackColor = true;
//
// StartButton
//
StartButton.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
StartButton.Font = new Font("Segoe UI", 18F, FontStyle.Bold);
StartButton.Location = new Point(3, 587);
StartButton.Name = "StartButton";
StartButton.Size = new Size(621, 63);
StartButton.TabIndex = 0;
StartButton.Text = "Запуск";
StartButton.UseVisualStyleBackColor = true;
StartButton.Click += StartButton_Click;
//
// MenuStrip
//
MenuStrip.Items.AddRange(new ToolStripItem[] { FileToolStripMenuItem, WindowsToolStripMenuItem, StartToolStripMenuItem });
MenuStrip.Location = new Point(0, 0);
MenuStrip.Name = "MenuStrip";
MenuStrip.Size = new Size(931, 24);
MenuStrip.TabIndex = 1;
MenuStrip.Text = "menuStrip1";
//
// FileToolStripMenuItem
//
FileToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { ExitToolStripMenuItem });
FileToolStripMenuItem.Name = "FileToolStripMenuItem";
FileToolStripMenuItem.Size = new Size(48, 20);
FileToolStripMenuItem.Text = "Файл";
//
// ExitToolStripMenuItem
//
ExitToolStripMenuItem.Name = "ExitToolStripMenuItem";
ExitToolStripMenuItem.Size = new Size(109, 22);
ExitToolStripMenuItem.Text = "Выход";
ExitToolStripMenuItem.Click += ExitToolStripMenuItem_Click;
//
// WindowsToolStripMenuItem
//
WindowsToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { ImportSettingsWindowsToolStripMenuItem, EntityViewWindowToolStripMenuItem });
WindowsToolStripMenuItem.Name = "WindowsToolStripMenuItem";
WindowsToolStripMenuItem.Size = new Size(47, 20);
WindowsToolStripMenuItem.Text = "Окна";
//
// ImportSettingsWindowsToolStripMenuItem
//
ImportSettingsWindowsToolStripMenuItem.Enabled = false;
ImportSettingsWindowsToolStripMenuItem.Name = "ImportSettingsWindowsToolStripMenuItem";
ImportSettingsWindowsToolStripMenuItem.Size = new Size(228, 22);
ImportSettingsWindowsToolStripMenuItem.Text = "Настройка импорта данных";
//
// EntityViewWindowToolStripMenuItem
//
EntityViewWindowToolStripMenuItem.Name = "EntityViewWindowToolStripMenuItem";
EntityViewWindowToolStripMenuItem.Size = new Size(228, 22);
EntityViewWindowToolStripMenuItem.Text = "Просмотр сущностей";
EntityViewWindowToolStripMenuItem.Click += EntityViewWindowToolStripMenuItem_Click;
//
// StartToolStripMenuItem
//
StartToolStripMenuItem.Name = "StartToolStripMenuItem";
StartToolStripMenuItem.Size = new Size(108, 20);
StartToolStripMenuItem.Text = "Запуск импорта";
StartToolStripMenuItem.Click += StartToolStripMenuItem_Click;
//
// StartForm
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(931, 677);
Controls.Add(MainSplitContainer);
Controls.Add(MenuStrip);
Name = "StartForm";
Text = "Настройки импорта данных";
Load += StartForm_Load;
MainSplitContainer.Panel1.ResumeLayout(false);
MainSplitContainer.Panel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)MainSplitContainer).EndInit();
MainSplitContainer.ResumeLayout(false);
PropertiesGroupBox.ResumeLayout(false);
ProcessorsGroupBox.ResumeLayout(false);
MenuStrip.ResumeLayout(false);
MenuStrip.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
#endregion
private SplitContainer MainSplitContainer;
private GroupBox PropertiesGroupBox;
private PropertyGrid SettingsPropertyGrid;
private Button StartButton;
private GroupBox ProcessorsGroupBox;
private Button SelectAllButton;
private Button DeselectAllButton;
private Controls.ProcessorCollectionControl ProcessorCollectionControl;
private MenuStrip MenuStrip;
private ToolStripMenuItem FileToolStripMenuItem;
private ToolStripMenuItem ExitToolStripMenuItem;
private ToolStripMenuItem WindowsToolStripMenuItem;
private ToolStripMenuItem ImportSettingsWindowsToolStripMenuItem;
private ToolStripMenuItem EntityViewWindowToolStripMenuItem;
private ToolStripMenuItem StartToolStripMenuItem;
}
-107
View File
@@ -1,107 +0,0 @@
using Pf2eDataScrapper.App;
namespace Pf2eDataScrapper.Forms;
internal partial class StartForm : Form
{
private ProcessorCollection ProcessorCollection { get; }
public ApplicationSettings Settings { get; }
public StartForm(ProcessorCollection processorCollection, ApplicationSettings settings)
{
ProcessorCollection = processorCollection;
Settings = settings;
InitializeComponent();
}
private void StartForm_Load(object sender, EventArgs e)
{
ProcessorCollectionControl.Collection = ProcessorCollection;
SettingsPropertyGrid.SelectedObject = Settings;
}
/*
private void PopulateListView()
{
Dictionary<ProcessorGroupEnum, List<ProcessorCollectionItem>> items = [];
foreach (ProcessorCollectionItem item in ProcessorCollection.AllItems)
{
items.TryAdd(item.Group, []);
items[item.Group].Add(item);
}
ProcessorsListView.Groups.Clear();
foreach (ProcessorGroupEnum group in Enum.GetValues<ProcessorGroupEnum>())
{
if (!items.TryGetValue(group, out List<ProcessorCollectionItem>? list))
{
continue;
}
ListViewGroup listViewGroup = new(group.GetDescription())
{
TaskLink = "Выбрать/снять все",
};
ProcessorsListView.Groups.Add(listViewGroup);
foreach (ProcessorCollectionItem item in list)
{
ListViewItem listViewItem = new()
{
Group = listViewGroup,
Text = item.Description,
Checked = true,
ToolTipText = item.Name,
};
ProcessorsListView.Items.Add(listViewItem);
}
}
}
private void ProcessorsListView_GroupTaskLinkClick(object sender, ListViewGroupEventArgs e)
{
ListViewGroup group = ProcessorsListView.Groups[e.GroupIndex];
bool allSelected = group.Items.Cast<ListViewItem>().All(item => item.Checked);
foreach (ListViewItem item in group.Items.Cast<ListViewItem>())
{
item.Checked = !allSelected;
}
}
*/
#region "Кнопка старта"
private void StartButton_Click(object sender, EventArgs e)
{
ApplicationStateChange?.Invoke(this, ApplicationStage.ImportProcess);
}
#endregion
#region "Основное меню"
private void ExitToolStripMenuItem_Click(object sender, EventArgs e)
{
Close();
}
private void EntityViewWindowToolStripMenuItem_Click(object sender, EventArgs e)
{
ApplicationStateChange?.Invoke(this, ApplicationStage.Viewer);
}
private void StartToolStripMenuItem_Click(object sender, EventArgs e)
{
ApplicationStateChange?.Invoke(this, ApplicationStage.ImportProcess);
}
public event ImportApplication.ApplicationStateChangeDelegate? ApplicationStateChange;
#endregion
}
-123
View File
@@ -1,123 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="MenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>
+2 -1
View File
@@ -1,4 +1,5 @@
using Pf2eModel; using System.Linq;
using Pf2eModel;
using Slugify; using Slugify;
namespace Pf2eDataScrapper.Helpers; namespace Pf2eDataScrapper.Helpers;
+4 -1
View File
@@ -1,4 +1,7 @@
using Microsoft.EntityFrameworkCore; using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Pf2eModel; using Pf2eModel;
using Pf2eModel.Model; using Pf2eModel.Model;
using Pf2eModel.Model.Base; using Pf2eModel.Model.Base;
+5 -9
View File
@@ -1,6 +1,6 @@
using System.ComponentModel; using System;
using System.ComponentModel;
using System.Windows; using System.Windows;
using System.Windows.Forms.Integration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Pf2eDataScrapper.App; using Pf2eDataScrapper.App;
using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Helpers;
@@ -9,11 +9,10 @@ using Pf2eDataScrapper.WPF;
using Pf2eDataScrapper.WPF.Views; using Pf2eDataScrapper.WPF.Views;
using Pf2eModel; using Pf2eModel;
using Slugify; using Slugify;
using StartForm = Pf2eDataScrapper.WPF.Views.StartForm;
namespace Pf2eDataScrapper; namespace Pf2eDataScrapper;
internal sealed class ImportApplication : ApplicationContext internal sealed class ImportApplication : Application
{ {
public ImportApplication( public ImportApplication(
IServiceProvider serviceProvider, IServiceProvider serviceProvider,
@@ -82,7 +81,6 @@ internal sealed class ImportApplication : ApplicationContext
_startFormWpf.ApplicationStateChange += ApplicationStateChange; _startFormWpf.ApplicationStateChange += ApplicationStateChange;
_startFormWpf.Show(); _startFormWpf.Show();
ElementHost.EnableModelessKeyboardInterop(_startFormWpf);
CurrentWpfForm = _startFormWpf; CurrentWpfForm = _startFormWpf;
break; break;
@@ -99,7 +97,6 @@ internal sealed class ImportApplication : ApplicationContext
_progressFormWpf.ApplicationStateChange += ApplicationStateChange; _progressFormWpf.ApplicationStateChange += ApplicationStateChange;
_progressFormWpf.Show(); _progressFormWpf.Show();
ElementHost.EnableModelessKeyboardInterop(_progressFormWpf);
CurrentWpfForm = _progressFormWpf; CurrentWpfForm = _progressFormWpf;
executor.Start(); executor.Start();
@@ -112,7 +109,6 @@ internal sealed class ImportApplication : ApplicationContext
//_entityForm.ApplicationStateChange += ApplicationStateChange; //_entityForm.ApplicationStateChange += ApplicationStateChange;
_entityForm.Show(); _entityForm.Show();
ElementHost.EnableModelessKeyboardInterop(_entityForm);
CurrentWpfForm = _entityForm; CurrentWpfForm = _entityForm;
break; break;
@@ -147,7 +143,7 @@ internal sealed class ImportApplication : ApplicationContext
break; break;
default: default:
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException(nameof(stage));
} }
} }
@@ -167,7 +163,7 @@ internal sealed class ImportApplication : ApplicationContext
{ {
if (sender?.Equals(CurrentWpfForm) ?? false) if (sender?.Equals(CurrentWpfForm) ?? false)
{ {
ExitThread(); Shutdown();
} }
else else
{ {
@@ -1,4 +1,6 @@
using Newtonsoft.Json.Linq; using System;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using Pf2eDataScrapper.Importers.Repositories; using Pf2eDataScrapper.Importers.Repositories;
namespace Pf2eDataScrapper.Importers; namespace Pf2eDataScrapper.Importers;
@@ -1,5 +1,8 @@
using System.IO; using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http; using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Helpers;
using Pf2eDataScrapper.Importers.Repositories; using Pf2eDataScrapper.Importers.Repositories;
@@ -1,5 +1,8 @@
using System.Collections.Concurrent; using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Compendium; namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Compendium;
@@ -1,4 +1,5 @@
using Pf2eModel.Model.Base.Targets; using System.Collections.Generic;
using Pf2eModel.Model.Base.Targets;
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers;
@@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection; using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using Pf2eDataScrapper.Processors; using Pf2eDataScrapper.Processors;
using Pf2eModel.Model.Enum; using Pf2eModel.Model.Enum;
@@ -1,4 +1,7 @@
using System.IO; using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Pf2eModel.Model.Base.Source; using Pf2eModel.Model.Base.Source;
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers;
@@ -1,4 +1,6 @@
using System.Text.RegularExpressions; using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers;
@@ -1,4 +1,6 @@
using Newtonsoft.Json; using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Pf2eDataScrapper.App; using Pf2eDataScrapper.App;
using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Helpers;
@@ -1,4 +1,5 @@
using Pf2eDataScrapper.App; using System.Linq;
using Pf2eDataScrapper.App;
using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Helpers;
using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers;
using Pf2eDataScrapper.Processors; using Pf2eDataScrapper.Processors;
@@ -1,4 +1,5 @@
using Pf2eDataScrapper.App; using System;
using Pf2eDataScrapper.App;
using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers;
using Pf2eDataScrapper.Processors; using Pf2eDataScrapper.Processors;
using Pf2eModel; using Pf2eModel;
@@ -1,4 +1,6 @@
using Microsoft.EntityFrameworkCore; using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Pf2eDataScrapper.App; using Pf2eDataScrapper.App;
using Pf2eDataScrapper.Processors; using Pf2eDataScrapper.Processors;
@@ -1,4 +1,7 @@
using System.IO; using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Pf2eDataScrapper.App; using Pf2eDataScrapper.App;
using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Helpers;
using Pf2eDataScrapper.Importers.Implementations.Aonprd.Compendium; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Compendium;
@@ -1,4 +1,6 @@
using Pf2eDataScrapper.App; using System.Collections.Generic;
using System.Linq;
using Pf2eDataScrapper.App;
using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Helpers;
using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers;
using Pf2eDataScrapper.Processors; using Pf2eDataScrapper.Processors;
@@ -1,4 +1,7 @@
using Newtonsoft.Json.Linq; using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
using Pf2eDataScrapper.App; using Pf2eDataScrapper.App;
using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Helpers;
using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers;
@@ -1,4 +1,7 @@
using System.Text.RegularExpressions; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Pf2eDataScrapper.App; using Pf2eDataScrapper.App;
using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Helpers;
@@ -1,4 +1,5 @@
using Newtonsoft.Json.Linq; using System.Linq;
using Newtonsoft.Json.Linq;
using Pf2eDataScrapper.App; using Pf2eDataScrapper.App;
using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Helpers;
using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers;
@@ -1,4 +1,7 @@
using System.Text.RegularExpressions; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Pf2eDataScrapper.App; using Pf2eDataScrapper.App;
using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Helpers;
@@ -1,4 +1,5 @@
using Newtonsoft.Json.Linq; using System.Linq;
using Newtonsoft.Json.Linq;
using Pf2eDataScrapper.App; using Pf2eDataScrapper.App;
using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Helpers;
using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers;
@@ -5,6 +5,8 @@
// так что ставить порядок ВСЕХ правил в архиве не получится, только тех, что есть в содержании. // так что ставить порядок ВСЕХ правил в архиве не получится, только тех, что есть в содержании.
// Ну а пока просто расставляем родительские и дочерние элементы. // Ну а пока просто расставляем родительские и дочерние элементы.
using System.Collections.Generic;
using System.Linq;
using Pf2eDataScrapper.App; using Pf2eDataScrapper.App;
using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers;
using Pf2eDataScrapper.Processors; using Pf2eDataScrapper.Processors;
@@ -1,4 +1,5 @@
using System.Text.RegularExpressions; using System.Linq;
using System.Text.RegularExpressions;
using System.Web; using System.Web;
using AngleSharp; using AngleSharp;
using AngleSharp.Dom; using AngleSharp.Dom;
@@ -1,4 +1,6 @@
using Newtonsoft.Json.Linq; using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
using Pf2eDataScrapper.App; using Pf2eDataScrapper.App;
using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Helpers;
using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers;
@@ -1,4 +1,5 @@
using Newtonsoft.Json.Linq; using System;
using Newtonsoft.Json.Linq;
namespace Pf2eDataScrapper.Importers.Implementations.FoundryEn.Compendium; namespace Pf2eDataScrapper.Importers.Implementations.FoundryEn.Compendium;
@@ -1,4 +1,7 @@
namespace Pf2eDataScrapper.Importers.Implementations.FoundryEn.Compendium; using System.Collections.Generic;
using System.Linq;
namespace Pf2eDataScrapper.Importers.Implementations.FoundryEn.Compendium;
/// <summary> /// <summary>
/// Коллекция папок компендиума /// Коллекция папок компендиума
@@ -1,5 +1,8 @@
using System.Collections.Concurrent; using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
namespace Pf2eDataScrapper.Importers.Implementations.FoundryEn.Compendium; namespace Pf2eDataScrapper.Importers.Implementations.FoundryEn.Compendium;
@@ -1,4 +1,7 @@
using System.Security.Cryptography; using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text; using System.Text;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
@@ -1,4 +1,6 @@
using System.IO; using System.Collections.Generic;
using System.IO;
using System.Linq;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Pf2eDataScrapper.App; using Pf2eDataScrapper.App;
using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Helpers;
@@ -1,4 +1,7 @@
using System.IO; using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Pf2eDataScrapper.App; using Pf2eDataScrapper.App;
using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Helpers;
using Pf2eDataScrapper.Importers.Implementations.FoundryEn.Compendium; using Pf2eDataScrapper.Importers.Implementations.FoundryEn.Compendium;
@@ -1,4 +1,5 @@
using Newtonsoft.Json.Linq; using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using Pf2eDataScrapper.SchemaBuilder; using Pf2eDataScrapper.SchemaBuilder;
using Pf2eDataScrapper.SchemaBuilder.Types; using Pf2eDataScrapper.SchemaBuilder.Types;
+2 -16
View File
@@ -3,8 +3,8 @@
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>net9.0-windows7.0</TargetFramework> <TargetFramework>net9.0-windows7.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms> <UseWindowsForms>False</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>disable</ImplicitUsings>
<UseWPF>True</UseWPF> <UseWPF>True</UseWPF>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -39,18 +39,4 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Compile Update="Forms\Controls\CoreBindingNavigator.cs">
<SubType>Component</SubType>
</Compile>
<Compile Update="Forms\Controls\DatabaseViewer\DatabaseViewerControl.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Update="Forms\Controls\EntityTreeViewer\EntityTreeViewerControl.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Update="Forms\EntityViewForm.cs">
<SubType>Form</SubType>
</Compile>
</ItemGroup>
</Project> </Project>
@@ -1,4 +1,7 @@
using System.ComponentModel; using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Pf2eDataScrapper.App; using Pf2eDataScrapper.App;
@@ -49,7 +52,10 @@ internal sealed class ProcessorExecutor(
{ {
Parallel.ForEach( Parallel.ForEach(
IterateProcessors(item), IterateProcessors(item),
new() { MaxDegreeOfParallelism = item.Parallel ? Settings.MaxThreads : 1 }, new ParallelOptions()
{
MaxDegreeOfParallelism = item.Parallel ? Settings.MaxThreads : 1,
},
RunProcessor RunProcessor
); );
}; };
@@ -1,4 +1,7 @@
using System.Security.Cryptography; using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text; using System.Text;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using NpgsqlTypes; using NpgsqlTypes;
+6 -3
View File
@@ -1,4 +1,6 @@
using Microsoft.Extensions.DependencyInjection; using System;
using System.Windows;
using Microsoft.Extensions.DependencyInjection;
using Pf2eDataScrapper.Importers.Implementations.Aonprd; using Pf2eDataScrapper.Importers.Implementations.Aonprd;
using Pf2eDataScrapper.Importers.Implementations.FoundryEn; using Pf2eDataScrapper.Importers.Implementations.FoundryEn;
using Pf2eDataScrapper.WPF; using Pf2eDataScrapper.WPF;
@@ -17,7 +19,7 @@ internal static class Program
// see https://aka.ms/applicationconfiguration. // see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize(); ApplicationConfiguration.Initialize();
Application.SetHighDpiMode(HighDpiMode.SystemAware); // Application.SetHighDpiMode(HighDpiMode.SystemAware);
/* /*
#pragma warning disable WFO5001 #pragma warning disable WFO5001
Application.SetColorMode(SystemColorMode.System); Application.SetColorMode(SystemColorMode.System);
@@ -31,7 +33,8 @@ internal static class Program
serviceProvider serviceProvider
); );
Application.Run(app); app.Run();
// Application.Run(app);
} }
private static IServiceCollection RegisterServices() private static IServiceCollection RegisterServices()
@@ -1,4 +1,6 @@
using System.IO; using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Helpers;
using Pf2eDataScrapper.Importers; using Pf2eDataScrapper.Importers;
+3 -1
View File
@@ -1,4 +1,6 @@
using Newtonsoft.Json.Linq; using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
using Pf2eDataScrapper.SchemaBuilder.Types; using Pf2eDataScrapper.SchemaBuilder.Types;
namespace Pf2eDataScrapper.SchemaBuilder; namespace Pf2eDataScrapper.SchemaBuilder;
@@ -1,4 +1,7 @@
using Newtonsoft.Json.Linq; using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
using Pf2eDataScrapper.SchemaBuilder.Types; using Pf2eDataScrapper.SchemaBuilder.Types;
namespace Pf2eDataScrapper.SchemaBuilder; namespace Pf2eDataScrapper.SchemaBuilder;
@@ -1,4 +1,5 @@
using Newtonsoft.Json.Linq; using System.Collections.Generic;
using Newtonsoft.Json.Linq;
namespace Pf2eDataScrapper.SchemaBuilder.Types; namespace Pf2eDataScrapper.SchemaBuilder.Types;
@@ -1,4 +1,6 @@
using Newtonsoft.Json.Linq; using System;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
namespace Pf2eDataScrapper.SchemaBuilder.Types; namespace Pf2eDataScrapper.SchemaBuilder.Types;
@@ -1,4 +1,5 @@
using Newtonsoft.Json.Linq; using System.Collections.Generic;
using Newtonsoft.Json.Linq;
namespace Pf2eDataScrapper.SchemaBuilder.Types; namespace Pf2eDataScrapper.SchemaBuilder.Types;
@@ -1,4 +1,5 @@
using Newtonsoft.Json.Linq; using System.Collections.Generic;
using Newtonsoft.Json.Linq;
namespace Pf2eDataScrapper.SchemaBuilder.Types; namespace Pf2eDataScrapper.SchemaBuilder.Types;
@@ -1,4 +1,7 @@
using Newtonsoft.Json.Linq; using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
namespace Pf2eDataScrapper.SchemaBuilder.Types; namespace Pf2eDataScrapper.SchemaBuilder.Types;
@@ -1,4 +1,6 @@
using Newtonsoft.Json.Linq; using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
namespace Pf2eDataScrapper.SchemaBuilder.Types; namespace Pf2eDataScrapper.SchemaBuilder.Types;
@@ -62,7 +62,6 @@
<Button.Resources> <Button.Resources>
<Style TargetType="Border"> <Style TargetType="Border">
<Setter Property="CornerRadius" Value="3" /> <Setter Property="CornerRadius" Value="3" />
<Setter Property="LineHeight" Value="15" />
</Style> </Style>
</Button.Resources> </Button.Resources>
<!--<Button.Width> <!--<Button.Width>
@@ -13,7 +13,6 @@ using System.Windows.Media;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using System.Windows.Navigation; using System.Windows.Navigation;
using System.Windows.Shapes; using System.Windows.Shapes;
using Pf2eDataScrapper.Forms.Controls.EntityTreeViewer;
using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Helpers;
using Pf2eDataScrapper.WPF.ViewModels; using Pf2eDataScrapper.WPF.ViewModels;
using Pf2eDataScrapper.WPF.ViewModels.EntityViewStructure; using Pf2eDataScrapper.WPF.ViewModels.EntityViewStructure;
@@ -1,4 +1,7 @@
using System.ComponentModel; using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows; using System.Windows;
using Pf2eDataScrapper.App; using Pf2eDataScrapper.App;
using CheckBox = System.Windows.Controls.CheckBox; using CheckBox = System.Windows.Controls.CheckBox;
@@ -1,4 +1,5 @@
using Pf2eModel.Model.Base; using System;
using Pf2eModel.Model.Base;
namespace Pf2eDataScrapper.WPF.Stores; namespace Pf2eDataScrapper.WPF.Stores;
@@ -1,4 +1,5 @@
using Pf2eModel.Model.Enum; using System;
using Pf2eModel.Model.Enum;
namespace Pf2eDataScrapper.WPF.Stores; namespace Pf2eDataScrapper.WPF.Stores;
+2 -1
View File
@@ -1,4 +1,5 @@
using System.ComponentModel; using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
namespace Pf2eDataScrapper.WPF; namespace Pf2eDataScrapper.WPF;
@@ -1,4 +1,8 @@
using System.Collections.ObjectModel; using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading;
using AngleSharp.Browser; using AngleSharp.Browser;
using LinqToDB.DataProvider.Access; using LinqToDB.DataProvider.Access;
using Pf2eDataScrapper.WPF.Stores; using Pf2eDataScrapper.WPF.Stores;
@@ -1,4 +1,7 @@
using Pf2eDataScrapper.WPF.Stores; using System;
using System.Collections.Generic;
using System.Linq;
using Pf2eDataScrapper.WPF.Stores;
using Pf2eModel; using Pf2eModel;
using Pf2eModel.Model.Enum; using Pf2eModel.Model.Enum;
@@ -1,4 +1,8 @@
namespace Pf2eDataScrapper.WPF.ViewModels.EntityViewStructure; using System;
using System.Collections.Generic;
using System.Linq;
namespace Pf2eDataScrapper.WPF.ViewModels.EntityViewStructure;
/// <summary> /// <summary>
/// Класс для построения структуры данных класса. /// Класс для построения структуры данных класса.
@@ -1,4 +1,8 @@
namespace Pf2eDataScrapper.WPF.ViewModels.EntityViewStructure; using System;
using System.Collections.Generic;
using System.Linq;
namespace Pf2eDataScrapper.WPF.ViewModels.EntityViewStructure;
/// <summary> /// <summary>
/// Базовый класс для полей структуры. /// Базовый класс для полей структуры.
@@ -1,4 +1,7 @@
using System.Collections; using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection; using System.Reflection;
using LinqToDB.Extensions; using LinqToDB.Extensions;
using Pf2eModel.Model.Common.I18n; using Pf2eModel.Model.Common.I18n;
@@ -1,4 +1,6 @@
namespace Pf2eDataScrapper.WPF.ViewModels.EntityViewStructure; using System;
namespace Pf2eDataScrapper.WPF.ViewModels.EntityViewStructure;
/// <summary> /// <summary>
/// Поле структуры с перечислением. /// Поле структуры с перечислением.
@@ -1,4 +1,6 @@
namespace Pf2eDataScrapper.WPF.ViewModels.EntityViewStructure; using System;
namespace Pf2eDataScrapper.WPF.ViewModels.EntityViewStructure;
/// <summary> /// <summary>
/// Простое поле структуры. /// Простое поле структуры.
@@ -1,4 +1,6 @@
namespace Pf2eDataScrapper.WPF.ViewModels.EntityViewStructure; using System.Collections.Generic;
namespace Pf2eDataScrapper.WPF.ViewModels.EntityViewStructure;
/// <summary> /// <summary>
/// Класс для хранения обработанного объекта. /// Класс для хранения обработанного объекта.
@@ -1,4 +1,7 @@
using System.Globalization; using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Windows; using System.Windows;
using System.Windows.Data; using System.Windows.Data;
using System.Windows.Media; using System.Windows.Media;
@@ -1,4 +1,6 @@
using System.Collections.ObjectModel; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Helpers;
using Pf2eDataScrapper.WPF.Stores; using Pf2eDataScrapper.WPF.Stores;
using Pf2eDataScrapper.WPF.ViewModels.EntityViewStructure; using Pf2eDataScrapper.WPF.ViewModels.EntityViewStructure;
@@ -1,4 +1,6 @@
using System.Collections.ObjectModel; using System;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Windows; using System.Windows;
using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Helpers;