Add startup drill tape parameter cleanup

This commit is contained in:
2026-05-21 12:49:19 +08:00
parent 21fc6d4c4c
commit 951486202e
4 changed files with 212 additions and 5 deletions

View File

@@ -34,7 +34,8 @@ namespace DrillTools
// 防止选择窗口关闭后触发 OnLastWindowClose 导致应用退出
ShutdownMode = ShutdownMode.OnExplicitShutdown;
var selectionWindow = new StartupSelectionWindow(filePath);
bool canClearParameters = CanClearDrillTapeParameters(filePath);
var selectionWindow = new StartupSelectionWindow(filePath, canClearParameters);
selectionWindow.ShowDialog();
switch (selectionWindow.SelectedAction)
@@ -47,6 +48,10 @@ namespace DrillTools
PerformHeadlessExport(filePath);
Shutdown();
break;
case StartupAction.ClearParameters:
PerformParameterCleanup(filePath);
Shutdown();
break;
default:
Shutdown();
break;
@@ -97,6 +102,37 @@ namespace DrillTools
}
}
private static bool CanClearDrillTapeParameters(string filePath)
{
try
{
string content = CommandTypeFileReader.ReadAllText(filePath);
return DrillTapeParameterCleaner.CanClearParameters(content);
}
catch
{
return false;
}
}
private static void PerformParameterCleanup(string filePath)
{
try
{
DrillTapeParameterCleaner.ClearParametersAndSave(filePath);
System.Windows.MessageBox.Show(
$"参数已清空,原文件已备份为:\n{Path.GetFileName(filePath)}.bak",
"清空参数完成",
MessageBoxButton.OK,
MessageBoxImage.Information);
}
catch (Exception ex)
{
System.Windows.MessageBox.Show($"清空参数失败:\n{ex.Message}",
"错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
/// <summary>
/// 验证是否为有效的钻带文件
/// </summary>

View File

@@ -0,0 +1,162 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
namespace DrillTools
{
internal static class DrillTapeParameterCleaner
{
private const int Gb2312CodePage = 936;
private static readonly char[] LineEndChars = { '\r', '\n' };
private static readonly Regex HeaderToolDefinitionStartPattern = new(
@"^T\d+C",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex ToolDefinitionPattern = new(
@"^(?<prefix>\s*T\d+C\d+(?:\.\d+)?)(?<parameters>H.+)$",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
public static bool CanClearParameters(string drillTapeContent)
{
var lines = SplitLines(drillTapeContent);
if (lines.Count < 2)
return false;
string secondLine = lines[1].Text.Trim();
if (!secondLine.StartsWith(";") || secondLine.Length == 1)
return false;
var toolDefinitionLines = GetHeaderToolDefinitionLines(lines);
if (toolDefinitionLines.Count == 0)
return false;
foreach (var line in toolDefinitionLines)
{
if (!ToolDefinitionPattern.IsMatch(line.Text.TrimEnd()))
return false;
}
return true;
}
public static string ClearParameters(string drillTapeContent)
{
if (!CanClearParameters(drillTapeContent))
throw new InvalidOperationException("钻带文件不符合清空参数条件");
var lines = SplitLines(drillTapeContent);
var builder = new StringBuilder(drillTapeContent.Length);
for (int i = 0; i < lines.Count; i++)
{
if (i == 1)
continue;
string text = lines[i].Text;
var match = ToolDefinitionPattern.Match(text.TrimEnd());
if (match.Success && IsBeforeHeaderEnd(lines, i))
{
int trailingWhitespaceLength = text.Length - text.TrimEnd().Length;
string trailingWhitespace = trailingWhitespaceLength > 0 ? text[^trailingWhitespaceLength..] : string.Empty;
text = match.Groups["prefix"].Value + trailingWhitespace;
}
builder.Append(text);
builder.Append(lines[i].LineEnding);
}
return builder.ToString();
}
public static void ClearParametersAndSave(string filePath)
{
string content = CommandTypeFileReader.ReadAllText(filePath);
string cleanedContent = ClearParameters(content);
string backupFilePath = filePath + ".bak";
File.Copy(filePath, backupFilePath, true);
using var writer = new StreamWriter(filePath, false, CreateAnsiEncoding());
writer.Write(cleanedContent);
}
private static List<DrillTapeLine> SplitLines(string content)
{
var lines = new List<DrillTapeLine>();
int index = 0;
while (index < content.Length)
{
int lineEndIndex = content.IndexOfAny(LineEndChars, index);
if (lineEndIndex < 0)
{
lines.Add(new DrillTapeLine(content[index..], string.Empty));
return lines;
}
string text = content[index..lineEndIndex];
string lineEnding;
if (content[lineEndIndex] == '\r' && lineEndIndex + 1 < content.Length && content[lineEndIndex + 1] == '\n')
{
lineEnding = "\r\n";
index = lineEndIndex + 2;
}
else
{
lineEnding = content[lineEndIndex].ToString();
index = lineEndIndex + 1;
}
lines.Add(new DrillTapeLine(text, lineEnding));
}
if (content.Length == 0)
lines.Add(new DrillTapeLine(string.Empty, string.Empty));
return lines;
}
private static List<DrillTapeLine> GetHeaderToolDefinitionLines(IReadOnlyList<DrillTapeLine> lines)
{
var toolDefinitionLines = new List<DrillTapeLine>();
foreach (var line in lines)
{
string trimmedLine = line.Text.Trim();
if (trimmedLine == "%")
break;
if (HeaderToolDefinitionStartPattern.IsMatch(trimmedLine))
toolDefinitionLines.Add(line);
}
return toolDefinitionLines;
}
private static bool IsBeforeHeaderEnd(IReadOnlyList<DrillTapeLine> lines, int lineIndex)
{
for (int i = 0; i < lineIndex; i++)
{
if (lines[i].Text.Trim() == "%")
return false;
}
return true;
}
private static Encoding CreateAnsiEncoding()
{
try
{
return Encoding.GetEncoding(Gb2312CodePage);
}
catch
{
return Encoding.Default;
}
}
private readonly record struct DrillTapeLine(string Text, string LineEnding);
}
}

View File

@@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="选择功能"
Width="300"
Width="430"
SizeToContent="Height"
ResizeMode="NoResize"
WindowStartupLocation="CenterScreen">
@@ -18,7 +18,8 @@
<StackPanel Grid.Row="2" HorizontalAlignment="Center" Orientation="Horizontal">
<Button Width="120" Height="30" Content="调整刀序" Margin="0,0,15,0" Click="AdjustToolOrder_Click"/>
<Button Width="120" Height="30" Content="导出孔数" Click="ExportHoleCount_Click"/>
<Button Width="120" Height="30" Content="导出孔数" Margin="0,0,15,0" Click="ExportHoleCount_Click"/>
<Button Name="ClearParametersButton" Width="120" Height="30" Content="清空参数" Click="ClearParameters_Click"/>
</StackPanel>
</Grid>
</Window>

View File

@@ -7,17 +7,19 @@ namespace DrillTools
{
None,
AdjustToolOrder,
ExportHoleCount
ExportHoleCount,
ClearParameters
}
public partial class StartupSelectionWindow : Window
{
public StartupAction SelectedAction { get; private set; } = StartupAction.None;
public StartupSelectionWindow(string filePath)
public StartupSelectionWindow(string filePath, bool canClearParameters = false)
{
InitializeComponent();
DataContext = new { FileName = Path.GetFileName(filePath) };
ClearParametersButton.Visibility = canClearParameters ? Visibility.Visible : Visibility.Collapsed;
}
private void AdjustToolOrder_Click(object sender, RoutedEventArgs e)
@@ -31,5 +33,11 @@ namespace DrillTools
SelectedAction = StartupAction.ExportHoleCount;
Close();
}
private void ClearParameters_Click(object sender, RoutedEventArgs e)
{
SelectedAction = StartupAction.ClearParameters;
Close();
}
}
}