Files
PDFPatcher/App/Model/AutoBookmarkCondition.cs
2024-10-07 16:17:27 +08:00

353 lines
8.7 KiB
C#

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Xml.Serialization;
using PDFPatcher.Common;
using PDFPatcher.Processor;
using PowerJson;
namespace PDFPatcher.Model
{
public abstract class AutoBookmarkCondition : ICloneable
{
[XmlAttribute(Constants.AutoBookmark.IsInclusive)]
public bool IsInclusive { get; set; }
public abstract string Description { get; }
public abstract string Name { get; }
public abstract object Clone();
internal abstract AutoBookmarkFilter CreateFilter();
internal abstract bool IsTextLineFilter { get; }
[JsonTypeAlias(ThisName)]
public class MultiCondition : AutoBookmarkCondition
{
internal const string ThisName = "条件组";
readonly Collection<AutoBookmarkCondition> _Conditions = new Collection<AutoBookmarkCondition>();
[XmlElement(FontNameCondition.ThisName, typeof(FontNameCondition))]
[XmlElement(TextSizeCondition.ThisName, typeof(TextSizeCondition))]
[XmlElement(PageRangeCondition.ThisName, typeof(PageRangeCondition))]
[XmlElement(TextCondition.ThisName, typeof(TextCondition))]
[JsonField("条件")]
public Collection<AutoBookmarkCondition> Conditions => _Conditions;
public MultiCondition() { }
public MultiCondition(AutoBookmarkCondition condition) {
if (condition is MultiCondition m) {
foreach (var item in m.Conditions) {
Conditions.Add(item.Clone() as AutoBookmarkCondition);
}
}
else {
Conditions.Add(condition);
}
}
public override string Description {
get {
var s = new string[Conditions.Count];
for (int i = 0; i < s.Length; i++) {
s[i] = _Conditions[i].Description;
}
return String.Join(";", s);
}
}
public override string Name => "多条件组合";
internal override bool IsTextLineFilter {
get {
foreach (var item in Conditions) {
if (item.IsTextLineFilter) {
return true;
}
}
return false;
}
}
public override object Clone() {
var m = new MultiCondition();
foreach (var item in Conditions) {
m.Conditions.Add(item.Clone() as AutoBookmarkCondition);
}
return m;
}
internal override AutoBookmarkFilter CreateFilter() {
return new MultiConditionFilter(this);
}
}
[JsonTypeAlias(ThisName)]
public class FontNameCondition : AutoBookmarkCondition
{
internal const string ThisName = "字体名称";
/// <summary>
/// 需要调整级别的字体名称。
/// </summary>
[XmlAttribute(ThisName)]
public string FontName { get; set; }
/// <summary>
/// 是否匹配字体全名。
/// </summary>
[XmlAttribute("匹配字体全名")]
public bool MatchFullName { get; set; }
public override string Description => String.Concat(ThisName, (MatchFullName ? "为" : "包含"), "“", FontName, "”");
public override string Name => ThisName;
internal override bool IsTextLineFilter => false;
public FontNameCondition() { }
internal FontNameCondition(string fontName, bool matchFullName) {
FontName = fontName;
MatchFullName = matchFullName;
}
internal override AutoBookmarkFilter CreateFilter() {
return new FontNameFilter(FontName, MatchFullName);
}
public override object Clone() {
return new FontNameCondition(FontName, MatchFullName);
}
}
[JsonTypeAlias(ThisName)]
public class TextSizeCondition : AutoBookmarkCondition
{
internal const string ThisName = "字体尺寸";
float _minSize, _maxSize;
string _description;
[XmlAttribute("最小尺寸")]
[DefaultValue(0)]
public float MinSize {
get => _minSize;
set {
_minSize = value;
_description = null;
}
}
[XmlAttribute("最大尺寸")]
[DefaultValue(0)]
public float MaxSize {
get => _maxSize;
set {
_maxSize = value;
_description = null;
}
}
public override string Description {
get {
if (_description == null) {
UpdateRangeDescription();
}
return _description;
}
}
public override string Name => ThisName;
internal override bool IsTextLineFilter => false;
public TextSizeCondition() { }
internal TextSizeCondition(float size) {
SetRange(size, size);
}
internal TextSizeCondition(float minSize, float maxSize) {
SetRange(minSize, maxSize);
}
private void UpdateRangeDescription() {
_description = ThisName + (_minSize == _maxSize ? "等于" + _minSize.ToText() : "介于" + _minSize.ToText() + "和" + _maxSize.ToText());
}
public override object Clone() {
var f = new TextSizeCondition() { _minSize = _minSize, _maxSize = _maxSize };
f.UpdateRangeDescription();
return f;
}
internal void SetRange(float a, float b) {
if (a > b) {
_minSize = b;
_maxSize = a;
}
else {
_minSize = a;
_maxSize = b;
}
_description = null;
}
internal override AutoBookmarkFilter CreateFilter() {
return new TextSizeFilter(_minSize, _maxSize);
}
}
[JsonTypeAlias(ThisName)]
public class TextPositionCondition : AutoBookmarkCondition
{
internal const string ThisName = "文本坐标";
byte _position;
float _minValue, _maxValue;
string _description;
[XmlAttribute("坐标值")]
[DefaultValue(0)]
public byte Position {
get => _position;
set {
_position = value;
_description = null;
}
}
[XmlAttribute("坐标最小值")]
[DefaultValue(0)]
public float MinValue {
get => _minValue;
set {
_minValue = value;
_description = null;
}
}
[XmlAttribute("坐标最大值")]
[DefaultValue(0)]
public float MaxValue {
get => _maxValue;
set {
_maxValue = value;
_description = null;
}
}
public override string Description {
get {
if (_description == null) {
UpdateRangeDescription();
}
return _description;
}
}
public override string Name => ThisName;
internal override bool IsTextLineFilter => false;
public TextPositionCondition() { }
internal TextPositionCondition(byte position, float value) {
SetRange(position, value, value);
}
internal TextPositionCondition(byte position, float value1, float value2) {
SetRange(position, value1, value2);
}
private void UpdateRangeDescription() {
_description = String.Concat(ThisName,
_position == 1 ? "上" : _position == 2 ? "下" : _position == 3 ? "左" : _position == 4 ? "右" : String.Empty,
"坐标",
_minValue == _maxValue
? "等于" + ValueHelper.ToText(_minValue)
: "介于" + ValueHelper.ToText(_minValue) + "和" + _maxValue
);
}
public override object Clone() {
var f = new TextPositionCondition() {
_position = _position,
_minValue = _minValue,
_maxValue = _maxValue
};
f.UpdateRangeDescription();
return f;
}
internal void SetRange(byte position, float value1, float value2) {
_position = position;
if (value1 > value2) {
_minValue = value2;
_maxValue = value1;
}
else {
_minValue = value1;
_maxValue = value2;
}
_description = null;
}
internal override AutoBookmarkFilter CreateFilter() {
return new TextPositionFilter(_position, _minValue, _maxValue);
}
}
[JsonTypeAlias(ThisName)]
public class PageRangeCondition : AutoBookmarkCondition
{
internal const string ThisName = "页码范围";
[XmlAttribute(ThisName)]
public string PageRange { get; set; }
public override string Description => "页码范围为“" + PageRange + "”";
public override string Name => ThisName;
internal override bool IsTextLineFilter => false;
public override object Clone() {
return new PageRangeCondition() { PageRange = PageRange };
}
internal override AutoBookmarkFilter CreateFilter() {
return new PageRangeFilter(PageRange);
}
}
[JsonTypeAlias(ThisName)]
public class TextCondition : AutoBookmarkCondition
{
internal const string ThisName = "文本内容";
[XmlElement("文本模式")]
public MatchPattern Pattern { get; set; }
public override string Description => String.Concat(ThisName,
Pattern.MatchCase ? "区分大小写" : String.Empty,
Pattern.FullMatch ? "完全匹配" : "符合",
Pattern.UseRegularExpression ? "正则表达式" : String.Empty,
Pattern.Text);
public override string Name => ThisName;
internal override bool IsTextLineFilter => true;
public override object Clone() {
return new TextCondition(Pattern);
}
internal override AutoBookmarkFilter CreateFilter() {
return new TextFilter(Pattern);
}
public TextCondition() {
Pattern = new MatchPattern();
}
private TextCondition(MatchPattern pattern) {
Pattern = pattern.Clone() as MatchPattern;
}
}
}
}