Files
PDFPatcher/App/Functions/AutoBookmarkControl.cs
T
2021-12-24 20:35:03 +08:00

337 lines
13 KiB
C#

using System;
using System.ComponentModel;
using System.IO;
using System.Windows.Forms;
using PDFPatcher.Common;
using PDFPatcher.Model;
namespace PDFPatcher.Functions
{
[ToolboxItem (false)]
public partial class AutoBookmarkControl : FunctionControl, IResettableControl
{
AutoBookmarkOptions _options;
static AutoBookmarkOptions.LevelAdjustmentOption[] _copiedLevelAdjustments;
public override string FunctionName {
get { return "自动生成书签"; }
}
public override System.Drawing.Bitmap IconImage {
get { return Properties.Resources.AutoBookmark; }
}
public override Button DefaultButton {
get { return _ExportBookmarkButton; }
}
public AutoBookmarkControl () {
InitializeComponent ();
//this.Icon = FormHelper.ToIcon (Properties.Resources.ExportInfoFile);
AppContext.MainForm.SetTooltip (_SourceFileControl.FileList, "需要识别标题为书签的 PDF 源文件路径");
AppContext.MainForm.SetTooltip (_BookmarkControl.FileList, "指定识别书签后生成的信息文件或简易文本书签文件路径");
AppContext.MainForm.SetTooltip (_ExportBookmarkButton, "点击此按钮识别 PDF 文件的标题为信息文件");
AppContext.MainForm.SetTooltip (_TitleSizeThresholdBox, "指定标题文本的最小尺寸,小于此尺寸的文本将被忽略");
AppContext.MainForm.SetTooltip (_AutoHierarchicleArrangementBox, "根据标题文本的尺寸级别生成多层次的书签");
AppContext.MainForm.SetTooltip (_YOffsetBox, "将标题的定位位置向上偏移的行距");
AppContext.MainForm.SetTooltip (_MergeAdjacentTitlesBox, "将连续出现的标题合并为一个标题");
AppContext.MainForm.SetTooltip (_MergeDifferentSizeTitlesBox, "合并不同尺寸的相邻标题");
AppContext.MainForm.SetTooltip (_GoToPageTopLevelBox, "小于指定层数的标题定位到页首,而非所在精确位置");
AppContext.MainForm.SetTooltip (_IgnoreOverlappedTextBox, "忽略用于制作粗体、阴影等效果的重叠文本");
AppContext.MainForm.SetTooltip (_CreateBookmarkForFirstPageBox, "生成一个书签指向文档的第一页,书签文本为 PDF 文件的名称");
AppContext.MainForm.SetTooltip (_PageRangeBox, Messages.PageRanges);
int i = 0;
foreach (var item in EditAdjustmentForm.FilterNames) {
_AddFilterMenu.Items.Add (item).Name = EditAdjustmentForm.FilterIDs[i++];
}
_LevelAdjustmentBox.BeforeSorting += (object sender, BrightIdeasSoftware.BeforeSortingEventArgs e) => {
e.Canceled = true;
};
_LevelAdjustmentBox.DropSink = new BrightIdeasSoftware.RearrangingDropSink (false);
_AdvancedFilterColumn.AspectGetter = (object x) => {
var f = x as AutoBookmarkOptions.LevelAdjustmentOption;
if (f == null) {
return null;
}
return f.Condition.Description;
};
_AdjustmentLevelColumn.AspectGetter = (object x) => {
var f = x as AutoBookmarkOptions.LevelAdjustmentOption;
return f == null ? 0 : f.AdjustmentLevel;
};
_AdjustmentLevelColumn.AspectPutter = (object x, object value) => {
var f = x as AutoBookmarkOptions.LevelAdjustmentOption;
if (f == null) {
return;
}
if ((value ?? "0").ToString().TryParse(out float a)) {
f.AdjustmentLevel = a;
}
};
_RelativeAdjustmentColumn.AspectGetter = (object x) => (x as AutoBookmarkOptions.LevelAdjustmentOption)?.RelativeAdjustment == true;
_RelativeAdjustmentColumn.AspectPutter = (object x, object value) => {
var f = x as AutoBookmarkOptions.LevelAdjustmentOption;
if (f == null) {
return;
}
f.RelativeAdjustment = value is bool b && b;
};
_FilterBeforeMergeColumn.AspectGetter = (object x) => ((x as AutoBookmarkOptions.LevelAdjustmentOption)?.FilterBeforeMergeTitle) ?? false;
_FilterBeforeMergeColumn.AspectPutter = (object x, object value) => {
if (x is AutoBookmarkOptions.LevelAdjustmentOption f) {
f.FilterBeforeMergeTitle = value is bool b && b;
}
};
Reload ();
var d = _BookmarkControl.FileDialog;
d.CheckFileExists = false;
d.CheckPathExists = false;
var sd = d as SaveFileDialog;
if (sd != null) {
sd.OverwritePrompt = false;
}
}
public void Reset () {
AppContext.AutoBookmarker = new AutoBookmarkOptions ();
Reload ();
}
public void Reload () {
_options = AppContext.AutoBookmarker;
_CreateBookmarkForFirstPageBox.Checked = _options.CreateBookmarkForFirstPage;
_MergeAdjacentTitlesBox.Checked = _options.MergeAdjacentTitles;
_MergeDifferentSizeTitlesBox.Checked = _options.MergeDifferentSizeTitles;
_AutoHierarchicleArrangementBox.Checked = _options.AutoHierarchicalArrangement;
_IgnoreNumericTitleBox.Checked = _options.IgnoreNumericTitle;
_IgnoreOverlappedTextBox.Checked = _options.IgnoreOverlappedText;
_IgnoreSingleCharacterTitleBox.Checked = _options.IgnoreSingleCharacterTitle;
_ShowAllFontsBox.Checked = _options.DisplayAllFonts;
_DisplayFontStatisticsBox.Checked = _options.DisplayFontStatistics;
_WritingDirectionBox.SelectedIndex = (int)_options.WritingDirection;
_MergeDifferentFontTitlesBox.Checked = _options.MergeDifferentFontTitles;
_TitleSizeThresholdBox .SetValue (_options.TitleThreshold);
_YOffsetBox.SetValue (_options.YOffset);
_MaxDistanceBetweenLinesBox.SetValue (_options.MaxDistanceBetweenLines);
_FirstLineAsTitleBox.Checked = _options.FirstLineAsTitle;
for (int i = _options.LevelAdjustment.Count - 1; i >= 0; i--) {
if (_options.LevelAdjustment[i].Condition == null) {
_options.LevelAdjustment.RemoveAt (i);
}
}
_LevelAdjustmentBox.SetObjects (_options.LevelAdjustment);
_IgnorePatternsBox.Rows.Clear ();
foreach (var item in _options.IgnorePatterns) {
if (String.IsNullOrEmpty (item.Text)) {
continue;
}
_IgnorePatternsBox.Rows.Add (item.Text, item.MatchCase, item.FullMatch, item.UseRegularExpression);
}
}
private void _ExportBookmarkButton_Click (object sender, EventArgs e) {
if (File.Exists (_SourceFileControl.FirstFile) == false) {
FormHelper.ErrorBox (Messages.SourceFileNotFound);
return;
}
else if (String.IsNullOrEmpty (_BookmarkControl.Text)) {
FormHelper.ErrorBox (Messages.InfoDocNotSpecified);
return;
}
AppContext.SourceFiles = _SourceFileControl.Files;
AppContext.BookmarkFile = _BookmarkControl.Text;
if (_SourceFileControl.Files.Length == 1) {
_SourceFileControl.FileList.AddHistoryItem ();
_BookmarkControl.FileList.AddHistoryItem ();
}
AppContext.MainForm.ResetWorker ();
AppContext.MainForm.GetWorker ().DoWork += new DoWorkEventHandler (ExportControl_DoWork);
SyncOptions ();
AppContext.MainForm.GetWorker ().RunWorkerAsync (new object[] {
AppContext.SourceFiles,
AppContext.BookmarkFile,
_options
});
}
private void SyncOptions () {
_options.CreateBookmarkForFirstPage = _CreateBookmarkForFirstPageBox.Checked;
_options.PageRanges = _PageRangeBox.Text;
_options.TitleThreshold = (float)_TitleSizeThresholdBox.Value;
_options.MergeAdjacentTitles = _MergeAdjacentTitlesBox.Checked;
_options.IgnoreNumericTitle = _IgnoreNumericTitleBox.Checked;
_options.IgnoreOverlappedText = _IgnoreOverlappedTextBox.Checked;
_options.IgnoreSingleCharacterTitle = _IgnoreSingleCharacterTitleBox.Checked;
_options.MergeDifferentSizeTitles = _MergeDifferentSizeTitlesBox.Checked;
_options.MergeDifferentFontTitles = _MergeDifferentFontTitlesBox.Checked;
_options.YOffset = (float)_YOffsetBox.Value;
_options.ExportTextCoordinates = _ExportTextCoordinateBox.Checked;
_options.PageTopForLevel = (int)_GoToPageTopLevelBox.Value;
_options.AutoHierarchicalArrangement = _AutoHierarchicleArrangementBox.Checked;
_options.DisplayFontStatistics = _DisplayFontStatisticsBox.Checked;
_options.DisplayAllFonts = _ShowAllFontsBox.Checked;
_options.WritingDirection = (WritingDirection)_WritingDirectionBox.SelectedIndex;
_options.MaxDistanceBetweenLines = (float)_MaxDistanceBetweenLinesBox.Value;
_options.FirstLineAsTitle = _FirstLineAsTitleBox.Checked;
_options.IgnorePatterns.Clear ();
foreach (DataGridViewRow item in _IgnorePatternsBox.Rows) {
if (item.IsNewRow) {
continue;
}
var cells = item.Cells;
if (cells[0].Value == null) {
continue;
}
_options.IgnorePatterns.Add (new PDFPatcher.Model.MatchPattern (
cells[0].Value.ToString (),
(bool)(cells[_MatchCaseColumn.Index].Value ?? false),
(bool)(cells[_FullMatchColumn.Index].Value ?? false),
(bool)(cells[_PatternTypeColumn.Index].Value ?? false)));
}
_options.LevelAdjustment.Clear ();
if (_LevelAdjustmentBox.Items.Count > 0) {
foreach (ListViewItem item in _LevelAdjustmentBox.Items) {
_options.LevelAdjustment.Add (_LevelAdjustmentBox.GetModelObject (item.Index) as AutoBookmarkOptions.LevelAdjustmentOption);
}
}
}
void ExportControl_DoWork (object sender, DoWorkEventArgs e) {
var a = e.Argument as object[];
var files = a[0] as string[];
var b = a[1] as string;
var options = a[2] as AutoBookmarkOptions;
if (files.Length > 1) {
var p = Path.GetDirectoryName (b);
var ext = Path.GetExtension (b);
foreach (var file in files) {
Processor.Worker.CreateBookmark (file, FileHelper.CombinePath (p, Path.GetFileNameWithoutExtension (file) + ext), options);
if (AppContext.Abort) {
return;
}
}
}
else {
Processor.Worker.CreateBookmark (files[0], b, options);
}
}
private void _IgnorePatternsBox_CellContentClick (object sender, DataGridViewCellEventArgs e) {
if (e.ColumnIndex == _RemovePatternColumn.Index) {
_IgnorePatternsBox.Rows.RemoveAt (e.RowIndex);
}
}
private void _ImportLink_LinkClicked (object sender, LinkLabelLinkClickedEventArgs e) {
AppContext.MainForm.SelectFunctionList (Function.Patcher);
}
private void ControlEvent (object sender, EventArgs e) {
if (sender == _DeleteAdjustmentButton && _LevelAdjustmentBox.Items.Count > 0 && FormHelper.YesNoBox ("是否删除选中的项?") == DialogResult.Yes) {
_LevelAdjustmentBox.RemoveObjects (_LevelAdjustmentBox.SelectedObjects);
}
else if (sender == _ClearTextFiltersButton && _IgnorePatternsBox.Rows.Count > 0 && FormHelper.YesNoBox ("是否清空文本过滤列表?") == DialogResult.Yes) {
_IgnorePatternsBox.Rows.Clear ();
}
else if (sender == _CopyFilterButton) {
var si = _LevelAdjustmentBox.SelectedObjects;
if (si.Count == 0) {
return;
}
_copiedLevelAdjustments = new AutoBookmarkOptions.LevelAdjustmentOption[si.Count];
for (int i = 0; i < _copiedLevelAdjustments.Length; i++) {
var item = si[i] as AutoBookmarkOptions.LevelAdjustmentOption;
_copiedLevelAdjustments[i] = item;
}
}
else if (sender == _PasteButton) {
//var s = Clipboard.GetText ();
//if (String.IsNullOrEmpty (s) == false && s.Length < 100) {
// _LevelAdjustmentBox.AddObject (new AutoBookmarkOptions.LevelAdjustmentOption () {
// Condition = new AutoBookmarkCondition.FontNameCondition (s, false)
// });
// return;
//}
if (_copiedLevelAdjustments.HasContent () == false) {
return;
}
foreach (var item in _copiedLevelAdjustments) {
_LevelAdjustmentBox.AddObject (item.Clone ());
}
}
else if (sender == _AddFilterFromInfoFileButton) {
if (String.IsNullOrEmpty (_BookmarkControl.Text)) {
if (_BookmarkControl.FileDialog.ShowDialog () != DialogResult.OK) {
FormHelper.InfoBox ("请先指定信息文件的路径。");
return;
}
_BookmarkControl.Text = _BookmarkControl.FileDialog.FileName;
}
var doc = new System.Xml.XmlDocument ();
System.Xml.XmlNode fontInfo;
try {
doc.Load (_BookmarkControl.Text);
fontInfo = doc.SelectSingleNode (Constants.PdfInfo + "/" + Constants.Font.DocumentFont);
}
catch (Exception ex) {
FormHelper.ErrorBox ("无法从信息文件加载字体信息。" + ex.Message);
return;
}
if (fontInfo == null) {
FormHelper.ErrorBox ("无法从信息文件加载字体信息。");
return;
}
using (var f = new FontFilterForm (fontInfo)) {
if (f.ShowDialog () == DialogResult.OK && f.FilterConditions != null) {
foreach (var item in f.FilterConditions) {
_LevelAdjustmentBox.AddObject (new AutoBookmarkOptions.LevelAdjustmentOption ()
{
Condition = item,
AdjustmentLevel = 0,
RelativeAdjustment = false
});
}
}
}
}
}
private void _LevelAdjustmentBox_ItemActivate (object sender, EventArgs e) {
if (_LevelAdjustmentBox.FocusedItem == null) {
return;
}
var fi = _LevelAdjustmentBox.FocusedItem;
var i = fi.Index;
var o = _LevelAdjustmentBox.GetModelObject (i) as AutoBookmarkOptions.LevelAdjustmentOption;
using (var dialog = new EditAdjustmentForm (o)) {
if (dialog.ShowDialog () == DialogResult.OK) {
if (dialog.Filter.Condition != null) {
_LevelAdjustmentBox.InsertObjects (i, new AutoBookmarkOptions.LevelAdjustmentOption[] { dialog.Filter });
_LevelAdjustmentBox.SelectedIndex = i;
}
_LevelAdjustmentBox.RemoveObject (o);
}
}
}
private void _AddFilterMenu_ItemClicked (object sender, ToolStripItemClickedEventArgs e) {
var c = EditAdjustmentForm.CreateCondition (e.ClickedItem.Name);
if (c != null) {
using (var dialog = new EditAdjustmentForm (new AutoBookmarkOptions.LevelAdjustmentOption { Condition = c })) {
if (dialog.ShowDialog () == DialogResult.OK && dialog.Filter.Condition != null) {
_LevelAdjustmentBox.AddObject (dialog.Filter);
}
}
}
}
}
}