diff --git a/App.xaml.cs b/App.xaml.cs index e41972d..138c7a7 100644 --- a/App.xaml.cs +++ b/App.xaml.cs @@ -48,6 +48,8 @@ namespace DrillTools bool canClearParameters = DrillTapeParameterCleaner.CanClearParameters(content); bool canGeneratePpDrillTape = viewModel.CanGeneratePpDrillTape; + string extension = Path.GetExtension(filePath).ToLowerInvariant(); + bool canScaleDrillTape = extension == ".dr2" || extension == ".dpin"; double minDrill = viewModel.MinDrillDiameter; double minSlot = viewModel.MinSlotDiameter; double minEA = viewModel.MinEADiameter; @@ -62,6 +64,7 @@ namespace DrillTools filePath, canClearParameters, canGeneratePpDrillTape, + canScaleDrillTape, minDrill, minSlot, minEA, @@ -91,6 +94,10 @@ namespace DrillTools PerformPpDrillTapeGeneration(filePath); Shutdown(); break; + case StartupAction.ScaleDrillTape: + PerformDrillScaling(filePath); + Shutdown(); + break; default: Shutdown(); break; @@ -191,6 +198,42 @@ namespace DrillTools } } + private static void PerformDrillScaling(string filePath) + { + try + { + var scalingWindow = new DrillScalingWindow(); + scalingWindow.ShowDialog(); + + if (scalingWindow.ScalingResult == null) + return; + + var (kx, ky) = scalingWindow.ScalingResult.Value; + + string content = CommandTypeFileReader.ReadAllText(filePath); + string scaledContent = Integration.ExcellonScaler.Scale(content, kx, ky); + + // 备份原文件 + string backupFilePath = filePath + ".bak"; + File.Copy(filePath, backupFilePath, true); + + // 写入缩放后的内容 + using var writer = new StreamWriter(filePath, false, Encoding.GetEncoding(936)); + writer.Write(scaledContent); + + 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); + } + } + private static void RegisterShellContextMenu() { try diff --git a/DrillScalingViewModel.cs b/DrillScalingViewModel.cs new file mode 100644 index 0000000..534f6e6 --- /dev/null +++ b/DrillScalingViewModel.cs @@ -0,0 +1,145 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace DrillTools +{ + /// + /// 涨缩参数输入模式 + /// + public enum ScalingMode + { + /// 倍率模式 + Ratio, + /// PPM 模式 + Ppm + } + + /// + /// 钻带涨缩窗口视图模型 + /// + public class DrillScalingViewModel : INotifyPropertyChanged + { + private ScalingMode _mode = ScalingMode.Ratio; + private string _inputX = "1.0"; + private string _inputY = "1.0"; + + /// + /// 缩放模式(倍率 / PPM) + /// + public ScalingMode Mode + { + get => _mode; + set + { + if (SetProperty(ref _mode, value)) + { + OnPropertyChanged(nameof(ModeLabelX)); + OnPropertyChanged(nameof(ModeLabelY)); + OnPropertyChanged(nameof(ModeDescription)); + } + } + } + + /// + /// X 方向输入值(原始字符串) + /// + public string InputX + { + get => _inputX; + set => SetProperty(ref _inputX, value); + } + + /// + /// Y 方向输入值(原始字符串) + /// + public string InputY + { + get => _inputY; + set => SetProperty(ref _inputY, value); + } + + /// + /// X 方向标签文本(根据模式变化) + /// + public string ModeLabelX => Mode == ScalingMode.Ratio ? "倍率 X" : "PPM X"; + + /// + /// Y 方向标签文本(根据模式变化) + /// + public string ModeLabelY => Mode == ScalingMode.Ratio ? "倍率 Y" : "PPM Y"; + + /// + /// 模式说明文本 + /// + public string ModeDescription => Mode == ScalingMode.Ratio + ? "倍率模式:直接输入缩放倍率(如 1.0005)" + : "PPM 模式:输入百万分率(如 500 表示 +500ppm)"; + + /// + /// 计算后的 X 方向实际缩放倍率 + /// + public double Kx + { + get + { + if (!double.TryParse(_inputX, out double value)) + return 1.0; + return Mode == ScalingMode.Ratio ? value : 1.0 + value / 1e6; + } + } + + /// + /// 计算后的 Y 方向实际缩放倍率 + /// + public double Ky + { + get + { + if (!double.TryParse(_inputY, out double value)) + return 1.0; + return Mode == ScalingMode.Ratio ? value : 1.0 + value / 1e6; + } + } + + /// + /// 验证输入是否有效 + /// + /// 验证结果,null 表示有效,非 null 为错误消息 + public string? Validate() + { + if (!double.TryParse(_inputX, out double xVal)) + return "X 值不是有效的数字"; + if (!double.TryParse(_inputY, out double yVal)) + return "Y 值不是有效的数字"; + + if (Mode == ScalingMode.Ratio) + { + if (xVal <= 0) + return "倍率 X 必须大于 0"; + if (yVal <= 0) + return "倍率 Y 必须大于 0"; + } + + return null; + } + + public event PropertyChangedEventHandler? PropertyChanged; + + protected bool SetProperty(ref T field, T value, [CallerMemberName] string? propertyName = null) + { + if (EqualityComparer.Default.Equals(field, value)) + return false; + + field = value; + OnPropertyChanged(propertyName); + return true; + } + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + } +} diff --git a/DrillScalingWindow.xaml b/DrillScalingWindow.xaml new file mode 100644 index 0000000..e425789 --- /dev/null +++ b/DrillScalingWindow.xaml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +