diff --git a/ExportDXF/Forms/DrawingSelectionForm.Designer.cs b/ExportDXF/Forms/DrawingSelectionForm.Designer.cs deleted file mode 100644 index 1a20ad6..0000000 --- a/ExportDXF/Forms/DrawingSelectionForm.Designer.cs +++ /dev/null @@ -1,283 +0,0 @@ -namespace ExportDXF.Forms -{ - partial class DrawingSelectionForm - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.equipmentLabel = new System.Windows.Forms.Label(); - this.equipmentComboBox = new System.Windows.Forms.ComboBox(); - this.drawingLabel = new System.Windows.Forms.Label(); - this.drawingComboBox = new System.Windows.Forms.ComboBox(); - this.newDrawingButton = new System.Windows.Forms.Button(); - this.newDrawingPanel = new System.Windows.Forms.Panel(); - this.qtyNumericUpDown = new System.Windows.Forms.NumericUpDown(); - this.qtyLabel = new System.Windows.Forms.Label(); - this.descriptionTextBox = new System.Windows.Forms.TextBox(); - this.descriptionLabel = new System.Windows.Forms.Label(); - this.drawingNumberTextBox = new System.Windows.Forms.TextBox(); - this.drawingNumberLabel = new System.Windows.Forms.Label(); - this.currentDrawingLabel = new System.Windows.Forms.Label(); - this.okButton = new System.Windows.Forms.Button(); - this.cancelButton = new System.Windows.Forms.Button(); - this.statusLabel = new System.Windows.Forms.Label(); - this.newDrawingPanel.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.qtyNumericUpDown)).BeginInit(); - this.SuspendLayout(); - // - // equipmentLabel - // - this.equipmentLabel.AutoSize = true; - this.equipmentLabel.Location = new System.Drawing.Point(12, 15); - this.equipmentLabel.Name = "equipmentLabel"; - this.equipmentLabel.Size = new System.Drawing.Size(82, 17); - this.equipmentLabel.TabIndex = 0; - this.equipmentLabel.Text = "Equipment #"; - // - // equipmentComboBox - // - this.equipmentComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.equipmentComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.equipmentComboBox.FormattingEnabled = true; - this.equipmentComboBox.Location = new System.Drawing.Point(100, 12); - this.equipmentComboBox.Name = "equipmentComboBox"; - this.equipmentComboBox.Size = new System.Drawing.Size(470, 25); - this.equipmentComboBox.TabIndex = 1; - this.equipmentComboBox.SelectedIndexChanged += new System.EventHandler(this.equipmentComboBox_SelectedIndexChanged); - // - // drawingLabel - // - this.drawingLabel.AutoSize = true; - this.drawingLabel.Location = new System.Drawing.Point(12, 48); - this.drawingLabel.Name = "drawingLabel"; - this.drawingLabel.Size = new System.Drawing.Size(68, 17); - this.drawingLabel.TabIndex = 2; - this.drawingLabel.Text = "Drawing #"; - // - // drawingComboBox - // - this.drawingComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.drawingComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.drawingComboBox.FormattingEnabled = true; - this.drawingComboBox.Location = new System.Drawing.Point(100, 45); - this.drawingComboBox.Name = "drawingComboBox"; - this.drawingComboBox.Size = new System.Drawing.Size(370, 25); - this.drawingComboBox.TabIndex = 3; - // - // newDrawingButton - // - this.newDrawingButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.newDrawingButton.Location = new System.Drawing.Point(476, 43); - this.newDrawingButton.Name = "newDrawingButton"; - this.newDrawingButton.Size = new System.Drawing.Size(94, 27); - this.newDrawingButton.TabIndex = 4; - this.newDrawingButton.Text = "New Drawing"; - this.newDrawingButton.UseVisualStyleBackColor = true; - this.newDrawingButton.Click += new System.EventHandler(this.newDrawingButton_Click); - // - // newDrawingPanel - // - this.newDrawingPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.newDrawingPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.newDrawingPanel.Controls.Add(this.qtyNumericUpDown); - this.newDrawingPanel.Controls.Add(this.qtyLabel); - this.newDrawingPanel.Controls.Add(this.descriptionTextBox); - this.newDrawingPanel.Controls.Add(this.descriptionLabel); - this.newDrawingPanel.Controls.Add(this.drawingNumberTextBox); - this.newDrawingPanel.Controls.Add(this.drawingNumberLabel); - this.newDrawingPanel.Location = new System.Drawing.Point(15, 85); - this.newDrawingPanel.Name = "newDrawingPanel"; - this.newDrawingPanel.Size = new System.Drawing.Size(555, 120); - this.newDrawingPanel.TabIndex = 5; - this.newDrawingPanel.Visible = false; - // - // qtyNumericUpDown - // - this.qtyNumericUpDown.Location = new System.Drawing.Point(124, 72); - this.qtyNumericUpDown.Maximum = new decimal(new int[] { - 10000, - 0, - 0, - 0}); - this.qtyNumericUpDown.Minimum = new decimal(new int[] { - 1, - 0, - 0, - 0}); - this.qtyNumericUpDown.Name = "qtyNumericUpDown"; - this.qtyNumericUpDown.Size = new System.Drawing.Size(100, 25); - this.qtyNumericUpDown.TabIndex = 5; - this.qtyNumericUpDown.Value = new decimal(new int[] { - 1, - 0, - 0, - 0}); - // - // qtyLabel - // - this.qtyLabel.AutoSize = true; - this.qtyLabel.Location = new System.Drawing.Point(10, 74); - this.qtyLabel.Name = "qtyLabel"; - this.qtyLabel.Size = new System.Drawing.Size(56, 17); - this.qtyLabel.TabIndex = 4; - this.qtyLabel.Text = "Quantity"; - // - // descriptionTextBox - // - this.descriptionTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.descriptionTextBox.Location = new System.Drawing.Point(124, 41); - this.descriptionTextBox.Name = "descriptionTextBox"; - this.descriptionTextBox.Size = new System.Drawing.Size(411, 25); - this.descriptionTextBox.TabIndex = 3; - // - // descriptionLabel - // - this.descriptionLabel.AutoSize = true; - this.descriptionLabel.Location = new System.Drawing.Point(10, 44); - this.descriptionLabel.Name = "descriptionLabel"; - this.descriptionLabel.Size = new System.Drawing.Size(74, 17); - this.descriptionLabel.TabIndex = 2; - this.descriptionLabel.Text = "Description"; - // - // drawingNumberTextBox - // - this.drawingNumberTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.drawingNumberTextBox.Location = new System.Drawing.Point(124, 10); - this.drawingNumberTextBox.Name = "drawingNumberTextBox"; - this.drawingNumberTextBox.Size = new System.Drawing.Size(411, 25); - this.drawingNumberTextBox.TabIndex = 1; - this.drawingNumberTextBox.TextChanged += new System.EventHandler(this.drawingNumberTextBox_TextChanged); - // - // drawingNumberLabel - // - this.drawingNumberLabel.AutoSize = true; - this.drawingNumberLabel.Location = new System.Drawing.Point(10, 13); - this.drawingNumberLabel.Name = "drawingNumberLabel"; - this.drawingNumberLabel.Size = new System.Drawing.Size(108, 17); - this.drawingNumberLabel.TabIndex = 0; - this.drawingNumberLabel.Text = "Drawing Number"; - // - // currentDrawingLabel - // - this.currentDrawingLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.currentDrawingLabel.AutoEllipsis = true; - this.currentDrawingLabel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.currentDrawingLabel.Location = new System.Drawing.Point(15, 217); - this.currentDrawingLabel.Name = "currentDrawingLabel"; - this.currentDrawingLabel.Size = new System.Drawing.Size(557, 41); - this.currentDrawingLabel.TabIndex = 9; - this.currentDrawingLabel.Text = "Loading active drawing..."; - // - // okButton - // - this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.okButton.Enabled = false; - this.okButton.Location = new System.Drawing.Point(414, 273); - this.okButton.Name = "okButton"; - this.okButton.Size = new System.Drawing.Size(75, 30); - this.okButton.TabIndex = 6; - this.okButton.Text = "OK"; - this.okButton.UseVisualStyleBackColor = true; - this.okButton.Click += new System.EventHandler(this.okButton_Click); - // - // cancelButton - // - this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.cancelButton.Location = new System.Drawing.Point(495, 273); - this.cancelButton.Name = "cancelButton"; - this.cancelButton.Size = new System.Drawing.Size(75, 30); - this.cancelButton.TabIndex = 7; - this.cancelButton.Text = "Cancel"; - this.cancelButton.UseVisualStyleBackColor = true; - this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click); - // - // statusLabel - // - this.statusLabel.AutoSize = true; - this.statusLabel.Location = new System.Drawing.Point(15, 280); - this.statusLabel.Name = "statusLabel"; - this.statusLabel.Size = new System.Drawing.Size(44, 17); - this.statusLabel.TabIndex = 8; - this.statusLabel.Text = "Ready"; - // - // DrawingSelectionForm - // - this.AcceptButton = this.okButton; - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; - this.CancelButton = this.cancelButton; - this.ClientSize = new System.Drawing.Size(584, 315); - this.Controls.Add(this.currentDrawingLabel); - this.Controls.Add(this.statusLabel); - this.Controls.Add(this.cancelButton); - this.Controls.Add(this.okButton); - this.Controls.Add(this.newDrawingPanel); - this.Controls.Add(this.newDrawingButton); - this.Controls.Add(this.drawingComboBox); - this.Controls.Add(this.drawingLabel); - this.Controls.Add(this.equipmentComboBox); - this.Controls.Add(this.equipmentLabel); - this.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "DrawingSelectionForm"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "Select Drawing - ExportDXF"; - this.newDrawingPanel.ResumeLayout(false); - this.newDrawingPanel.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.qtyNumericUpDown)).EndInit(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Label equipmentLabel; - private System.Windows.Forms.ComboBox equipmentComboBox; - private System.Windows.Forms.Label drawingLabel; - private System.Windows.Forms.ComboBox drawingComboBox; - private System.Windows.Forms.Button newDrawingButton; - private System.Windows.Forms.Panel newDrawingPanel; - private System.Windows.Forms.TextBox drawingNumberTextBox; - private System.Windows.Forms.Label drawingNumberLabel; - private System.Windows.Forms.TextBox descriptionTextBox; - private System.Windows.Forms.Label descriptionLabel; - private System.Windows.Forms.NumericUpDown qtyNumericUpDown; - private System.Windows.Forms.Label qtyLabel; - private System.Windows.Forms.Label currentDrawingLabel; - private System.Windows.Forms.Button okButton; - private System.Windows.Forms.Button cancelButton; - private System.Windows.Forms.Label statusLabel; - } -} diff --git a/ExportDXF/Forms/DrawingSelectionForm.cs b/ExportDXF/Forms/DrawingSelectionForm.cs deleted file mode 100644 index 11549d9..0000000 --- a/ExportDXF/Forms/DrawingSelectionForm.cs +++ /dev/null @@ -1,260 +0,0 @@ -using ExportDXF.Services; -using System; -using System.Drawing; -using System.Linq; -using System.Threading.Tasks; -using System.Windows.Forms; - -namespace ExportDXF.Forms -{ - public partial class DrawingSelectionForm : Form - { - private readonly ICutFabApiClient _apiClient; - private readonly ISolidWorksService _solidWorksService; - - public int? SelectedDrawingId { get; private set; } - public string SelectedDrawingNumber { get; private set; } - - public DrawingSelectionForm(ICutFabApiClient apiClient, ISolidWorksService solidWorksService) - { - _apiClient = apiClient ?? throw new ArgumentNullException(nameof(apiClient)); - _solidWorksService = solidWorksService ?? throw new ArgumentNullException(nameof(solidWorksService)); - _solidWorksService.ActiveDocumentChanged += (s, e) => DisplayActiveDrawing(); - InitializeComponent(); - } - - protected override async void OnLoad(EventArgs e) - { - base.OnLoad(e); - DisplayActiveDrawing(); - await LoadEquipmentAsync(); - } - - private void DisplayActiveDrawing() - { - try - { - var activeDoc = _solidWorksService.GetActiveDocument(); - if (activeDoc != null && activeDoc.DocumentType == Models.DocumentType.Drawing) - { - currentDrawingLabel.Text = $"Active Drawing: {activeDoc.Title}"; - currentDrawingLabel.ForeColor = Color.Green; - } - else if (activeDoc != null) - { - currentDrawingLabel.Text = $"Active Document: {activeDoc.Title} (Not a Drawing)"; - currentDrawingLabel.ForeColor = Color.Orange; - } - else - { - currentDrawingLabel.Text = "No active SolidWorks document"; - currentDrawingLabel.ForeColor = Color.Gray; - } - } - catch (Exception ex) - { - currentDrawingLabel.Text = $"Error getting active document: {ex.Message}"; - currentDrawingLabel.ForeColor = Color.Red; - } - } - - private async Task LoadEquipmentAsync() - { - try - { - statusLabel.Text = "Loading equipment..."; - statusLabel.ForeColor = Color.Black; - - var equipment = await _apiClient.GetEquipmentAsync(); - - equipmentComboBox.DisplayMember = nameof(CutFabApiClient.ApiEquipment.EquipmentNumber); - equipmentComboBox.ValueMember = nameof(CutFabApiClient.ApiEquipment.ID); - equipmentComboBox.DataSource = equipment; - - if (equipment.Count > 0) - { - equipmentComboBox.SelectedIndex = 0; - statusLabel.Text = $"Loaded {equipment.Count} equipment record(s)"; - statusLabel.ForeColor = Color.Green; - } - else - { - statusLabel.Text = "No equipment found"; - statusLabel.ForeColor = Color.Red; - } - } - catch (Exception ex) - { - statusLabel.Text = $"Error loading equipment: {ex.Message}"; - statusLabel.ForeColor = Color.Red; - MessageBox.Show($"Failed to load equipment: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - - private async void equipmentComboBox_SelectedIndexChanged(object sender, EventArgs e) - { - await LoadDrawingsAsync(); - } - - private async Task LoadDrawingsAsync() - { - try - { - var selectedEquipment = equipmentComboBox.SelectedItem as CutFabApiClient.ApiEquipment; - if (selectedEquipment == null) - { - drawingComboBox.DataSource = null; - return; - } - - statusLabel.Text = "Loading drawings..."; - statusLabel.ForeColor = Color.Black; - - var drawings = await _apiClient.GetDrawingsForEquipmentAsync(selectedEquipment.ID); - - drawingComboBox.DisplayMember = nameof(CutFabApiClient.ApiDrawingSummary.DrawingNumber); - drawingComboBox.ValueMember = nameof(CutFabApiClient.ApiDrawingSummary.ID); - drawingComboBox.DataSource = drawings; - - if (drawings.Count > 0) - { - statusLabel.Text = $"Loaded {drawings.Count} drawing(s)"; - statusLabel.ForeColor = Color.Green; - drawingComboBox.Enabled = true; - } - else - { - statusLabel.Text = "No drawings found for this equipment"; - statusLabel.ForeColor = Color.DarkBlue; - drawingComboBox.Enabled = false; - } - - UpdateOkButtonState(); - } - catch (Exception ex) - { - statusLabel.Text = $"Error loading drawings: {ex.Message}"; - statusLabel.ForeColor = Color.Red; - } - } - - private void newDrawingButton_Click(object sender, EventArgs e) - { - ToggleNewDrawingMode(!newDrawingPanel.Visible); - } - - private void ToggleNewDrawingMode(bool enabled) - { - newDrawingPanel.Visible = enabled; - drawingComboBox.Enabled = !enabled; - newDrawingButton.Text = enabled ? "Cancel New" : "New Drawing"; - - if (enabled) - { - drawingNumberTextBox.Focus(); - } - - UpdateOkButtonState(); - } - - private void drawingNumberTextBox_TextChanged(object sender, EventArgs e) - { - UpdateOkButtonState(); - } - - private void UpdateOkButtonState() - { - if (newDrawingPanel.Visible) - { - // Creating new drawing - require drawing number - okButton.Enabled = !string.IsNullOrWhiteSpace(drawingNumberTextBox.Text); - } - else - { - // Selecting existing drawing - okButton.Enabled = drawingComboBox.SelectedItem != null; - } - } - - private async void okButton_Click(object sender, EventArgs e) - { - try - { - okButton.Enabled = false; - statusLabel.Text = "Processing..."; - statusLabel.ForeColor = Color.Black; - - if (newDrawingPanel.Visible) - { - // Create new drawing - await CreateNewDrawingAsync(); - } - else - { - // Use existing drawing - var selectedDrawing = drawingComboBox.SelectedItem as CutFabApiClient.ApiDrawingSummary; - if (selectedDrawing != null) - { - SelectedDrawingId = selectedDrawing.ID; - SelectedDrawingNumber = selectedDrawing.DrawingNumber; - DialogResult = DialogResult.OK; - Close(); - } - } - } - catch (Exception ex) - { - statusLabel.Text = $"Error: {ex.Message}"; - statusLabel.ForeColor = Color.Red; - MessageBox.Show($"Operation failed: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - okButton.Enabled = true; - } - } - - private async Task CreateNewDrawingAsync() - { - var selectedEquipment = equipmentComboBox.SelectedItem as CutFabApiClient.ApiEquipment; - if (selectedEquipment == null) - { - MessageBox.Show("Please select equipment first.", "Validation Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); - return; - } - - var drawingNumber = drawingNumberTextBox.Text.Trim(); - if (string.IsNullOrWhiteSpace(drawingNumber)) - { - MessageBox.Show("Please enter a drawing number.", "Validation Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); - return; - } - - statusLabel.Text = "Creating new drawing..."; - statusLabel.ForeColor = Color.Black; - - var response = await _apiClient.CreateDrawingWithInfoAsync(selectedEquipment.ID, drawingNumber); - - if (response.Success && response.Data.HasValue) - { - SelectedDrawingId = response.Data.Value; - SelectedDrawingNumber = drawingNumber; - statusLabel.Text = "Drawing created successfully"; - statusLabel.ForeColor = Color.Green; - DialogResult = DialogResult.OK; - Close(); - } - else - { - var errorMsg = response.Error ?? "Unknown error occurred"; - statusLabel.Text = $"Failed to create drawing: {errorMsg}"; - statusLabel.ForeColor = Color.Red; - MessageBox.Show($"Failed to create drawing: {errorMsg}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - okButton.Enabled = true; - } - } - - private void cancelButton_Click(object sender, EventArgs e) - { - DialogResult = DialogResult.Cancel; - Close(); - } - } -} diff --git a/ExportDXF/Forms/DrawingSelectionForm.resx b/ExportDXF/Forms/DrawingSelectionForm.resx deleted file mode 100644 index d58980a..0000000 --- a/ExportDXF/Forms/DrawingSelectionForm.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/ExportDXF/Forms/MainForm.Designer.cs b/ExportDXF/Forms/MainForm.Designer.cs index 4e09823..302bbbd 100644 --- a/ExportDXF/Forms/MainForm.Designer.cs +++ b/ExportDXF/Forms/MainForm.Designer.cs @@ -1,4 +1,4 @@ -namespace ExportDXF.Forms +namespace ExportDXF.Forms { partial class MainForm { @@ -28,192 +28,169 @@ /// private void InitializeComponent() { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); - this.runButton = new System.Windows.Forms.Button(); - this.label3 = new System.Windows.Forms.Label(); - this.viewFlipDeciderBox = new System.Windows.Forms.ComboBox(); - this.mainTabControl = new System.Windows.Forms.TabControl(); - this.logEventsTab = new System.Windows.Forms.TabPage(); - this.logEventsDataGrid = new System.Windows.Forms.DataGridView(); - this.bomTab = new System.Windows.Forms.TabPage(); - this.bomDataGrid = new System.Windows.Forms.DataGridView(); - this.cutTemplatesTab = new System.Windows.Forms.TabPage(); - this.cutTemplatesDataGrid = new System.Windows.Forms.DataGridView(); - this.dwgDetailsTab = new System.Windows.Forms.TabPage(); - this.drawingPdfViewer = new AxAcroPDFLib.AxAcroPDF(); - this.mainTabControl.SuspendLayout(); - this.logEventsTab.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.logEventsDataGrid)).BeginInit(); - this.bomTab.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.bomDataGrid)).BeginInit(); - this.cutTemplatesTab.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.cutTemplatesDataGrid)).BeginInit(); - this.dwgDetailsTab.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.drawingPdfViewer)).BeginInit(); - this.SuspendLayout(); + runButton = new System.Windows.Forms.Button(); + label3 = new System.Windows.Forms.Label(); + viewFlipDeciderBox = new System.Windows.Forms.ComboBox(); + mainTabControl = new System.Windows.Forms.TabControl(); + logEventsTab = new System.Windows.Forms.TabPage(); + logEventsDataGrid = new System.Windows.Forms.DataGridView(); + bomTab = new System.Windows.Forms.TabPage(); + bomDataGrid = new System.Windows.Forms.DataGridView(); + equipmentBox = new System.Windows.Forms.ComboBox(); + label1 = new System.Windows.Forms.Label(); + label2 = new System.Windows.Forms.Label(); + drawingNoBox = new System.Windows.Forms.ComboBox(); + mainTabControl.SuspendLayout(); + logEventsTab.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)logEventsDataGrid).BeginInit(); + bomTab.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)bomDataGrid).BeginInit(); + SuspendLayout(); // // runButton // - this.runButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.runButton.Location = new System.Drawing.Point(790, 13); - this.runButton.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); - this.runButton.Name = "runButton"; - this.runButton.Size = new System.Drawing.Size(100, 30); - this.runButton.TabIndex = 11; - this.runButton.Text = "Start"; - this.runButton.UseVisualStyleBackColor = true; - this.runButton.Click += new System.EventHandler(this.button1_Click); + runButton.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right; + runButton.Location = new System.Drawing.Point(656, 13); + runButton.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + runButton.Name = "runButton"; + runButton.Size = new System.Drawing.Size(100, 30); + runButton.TabIndex = 11; + runButton.Text = "Start"; + runButton.UseVisualStyleBackColor = true; + runButton.Click += button1_Click; // // label3 // - this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(12, 20); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(112, 17); - this.label3.TabIndex = 2; - this.label3.Text = "View flip decider :"; + label3.AutoSize = true; + label3.Location = new System.Drawing.Point(26, 46); + label3.Name = "label3"; + label3.Size = new System.Drawing.Size(105, 17); + label3.TabIndex = 2; + label3.Text = "View flip decider"; // // viewFlipDeciderBox // - this.viewFlipDeciderBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.viewFlipDeciderBox.FormattingEnabled = true; - this.viewFlipDeciderBox.Location = new System.Drawing.Point(130, 17); - this.viewFlipDeciderBox.Name = "viewFlipDeciderBox"; - this.viewFlipDeciderBox.Size = new System.Drawing.Size(375, 25); - this.viewFlipDeciderBox.TabIndex = 3; + viewFlipDeciderBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + viewFlipDeciderBox.FormattingEnabled = true; + viewFlipDeciderBox.Location = new System.Drawing.Point(137, 43); + viewFlipDeciderBox.Name = "viewFlipDeciderBox"; + viewFlipDeciderBox.Size = new System.Drawing.Size(502, 25); + viewFlipDeciderBox.TabIndex = 3; // // mainTabControl // - this.mainTabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.mainTabControl.Controls.Add(this.logEventsTab); - this.mainTabControl.Controls.Add(this.bomTab); - this.mainTabControl.Controls.Add(this.cutTemplatesTab); - this.mainTabControl.Controls.Add(this.dwgDetailsTab); - this.mainTabControl.Location = new System.Drawing.Point(15, 50); - this.mainTabControl.Name = "mainTabControl"; - this.mainTabControl.Padding = new System.Drawing.Point(20, 5); - this.mainTabControl.SelectedIndex = 0; - this.mainTabControl.Size = new System.Drawing.Size(879, 594); - this.mainTabControl.TabIndex = 12; + mainTabControl.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right; + mainTabControl.Controls.Add(logEventsTab); + mainTabControl.Controls.Add(bomTab); + mainTabControl.Location = new System.Drawing.Point(15, 74); + mainTabControl.Name = "mainTabControl"; + mainTabControl.Padding = new System.Drawing.Point(20, 5); + mainTabControl.SelectedIndex = 0; + mainTabControl.Size = new System.Drawing.Size(741, 586); + mainTabControl.TabIndex = 12; // // logEventsTab // - this.logEventsTab.Controls.Add(this.logEventsDataGrid); - this.logEventsTab.Location = new System.Drawing.Point(4, 30); - this.logEventsTab.Name = "logEventsTab"; - this.logEventsTab.Padding = new System.Windows.Forms.Padding(3); - this.logEventsTab.Size = new System.Drawing.Size(871, 560); - this.logEventsTab.TabIndex = 0; - this.logEventsTab.Text = "Log Events"; - this.logEventsTab.UseVisualStyleBackColor = true; + logEventsTab.Controls.Add(logEventsDataGrid); + logEventsTab.Location = new System.Drawing.Point(4, 30); + logEventsTab.Name = "logEventsTab"; + logEventsTab.Padding = new System.Windows.Forms.Padding(3); + logEventsTab.Size = new System.Drawing.Size(733, 552); + logEventsTab.TabIndex = 0; + logEventsTab.Text = "Log Events"; + logEventsTab.UseVisualStyleBackColor = true; // // logEventsDataGrid // - this.logEventsDataGrid.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.logEventsDataGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - this.logEventsDataGrid.Location = new System.Drawing.Point(6, 6); - this.logEventsDataGrid.Name = "logEventsDataGrid"; - this.logEventsDataGrid.Size = new System.Drawing.Size(859, 548); - this.logEventsDataGrid.TabIndex = 0; + logEventsDataGrid.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right; + logEventsDataGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + logEventsDataGrid.GridColor = System.Drawing.Color.WhiteSmoke; + logEventsDataGrid.Location = new System.Drawing.Point(6, 6); + logEventsDataGrid.Name = "logEventsDataGrid"; + logEventsDataGrid.Size = new System.Drawing.Size(721, 540); + logEventsDataGrid.TabIndex = 0; // // bomTab // - this.bomTab.Controls.Add(this.bomDataGrid); - this.bomTab.Location = new System.Drawing.Point(4, 30); - this.bomTab.Name = "bomTab"; - this.bomTab.Padding = new System.Windows.Forms.Padding(3); - this.bomTab.Size = new System.Drawing.Size(871, 560); - this.bomTab.TabIndex = 1; - this.bomTab.Text = "Bill Of Materials"; - this.bomTab.UseVisualStyleBackColor = true; + bomTab.Controls.Add(bomDataGrid); + bomTab.Location = new System.Drawing.Point(4, 30); + bomTab.Name = "bomTab"; + bomTab.Padding = new System.Windows.Forms.Padding(3); + bomTab.Size = new System.Drawing.Size(733, 552); + bomTab.TabIndex = 1; + bomTab.Text = "Bill Of Materials"; + bomTab.UseVisualStyleBackColor = true; // // bomDataGrid // - this.bomDataGrid.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.bomDataGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - this.bomDataGrid.Location = new System.Drawing.Point(6, 6); - this.bomDataGrid.Name = "bomDataGrid"; - this.bomDataGrid.Size = new System.Drawing.Size(859, 548); - this.bomDataGrid.TabIndex = 1; + bomDataGrid.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right; + bomDataGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + bomDataGrid.GridColor = System.Drawing.Color.WhiteSmoke; + bomDataGrid.Location = new System.Drawing.Point(6, 6); + bomDataGrid.Name = "bomDataGrid"; + bomDataGrid.Size = new System.Drawing.Size(721, 540); + bomDataGrid.TabIndex = 1; // - // cutTemplatesTab + // equipmentBox // - this.cutTemplatesTab.Controls.Add(this.cutTemplatesDataGrid); - this.cutTemplatesTab.Location = new System.Drawing.Point(4, 30); - this.cutTemplatesTab.Name = "cutTemplatesTab"; - this.cutTemplatesTab.Padding = new System.Windows.Forms.Padding(3); - this.cutTemplatesTab.Size = new System.Drawing.Size(871, 560); - this.cutTemplatesTab.TabIndex = 3; - this.cutTemplatesTab.Text = "Cut Templates"; - this.cutTemplatesTab.UseVisualStyleBackColor = true; + equipmentBox.FormattingEnabled = true; + equipmentBox.Location = new System.Drawing.Point(137, 12); + equipmentBox.Name = "equipmentBox"; + equipmentBox.Size = new System.Drawing.Size(166, 25); + equipmentBox.TabIndex = 13; // - // cutTemplatesDataGrid + // label1 // - this.cutTemplatesDataGrid.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.cutTemplatesDataGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - this.cutTemplatesDataGrid.Location = new System.Drawing.Point(6, 6); - this.cutTemplatesDataGrid.Name = "cutTemplatesDataGrid"; - this.cutTemplatesDataGrid.Size = new System.Drawing.Size(859, 548); - this.cutTemplatesDataGrid.TabIndex = 2; + label1.AutoSize = true; + label1.Location = new System.Drawing.Point(61, 15); + label1.Name = "label1"; + label1.Size = new System.Drawing.Size(70, 17); + label1.TabIndex = 2; + label1.Text = "Equipment"; // - // dwgDetailsTab + // label2 // - this.dwgDetailsTab.Controls.Add(this.drawingPdfViewer); - this.dwgDetailsTab.Location = new System.Drawing.Point(4, 30); - this.dwgDetailsTab.Name = "dwgDetailsTab"; - this.dwgDetailsTab.Padding = new System.Windows.Forms.Padding(3); - this.dwgDetailsTab.Size = new System.Drawing.Size(871, 560); - this.dwgDetailsTab.TabIndex = 2; - this.dwgDetailsTab.Text = "Drawing Details"; - this.dwgDetailsTab.UseVisualStyleBackColor = true; + label2.AutoSize = true; + label2.Location = new System.Drawing.Point(354, 15); + label2.Name = "label2"; + label2.Size = new System.Drawing.Size(56, 17); + label2.TabIndex = 2; + label2.Text = "Drawing"; // - // drawingPdfViewer + // drawingNoBox // - this.drawingPdfViewer.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.drawingPdfViewer.Enabled = true; - this.drawingPdfViewer.Location = new System.Drawing.Point(6, 6); - this.drawingPdfViewer.Name = "drawingPdfViewer"; - this.drawingPdfViewer.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("drawingPdfViewer.OcxState"))); - this.drawingPdfViewer.Size = new System.Drawing.Size(859, 548); - this.drawingPdfViewer.TabIndex = 0; + drawingNoBox.FormattingEnabled = true; + drawingNoBox.Location = new System.Drawing.Point(416, 12); + drawingNoBox.Name = "drawingNoBox"; + drawingNoBox.Size = new System.Drawing.Size(223, 25); + drawingNoBox.TabIndex = 13; // // MainForm // - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; - this.ClientSize = new System.Drawing.Size(906, 656); - this.Controls.Add(this.mainTabControl); - this.Controls.Add(this.viewFlipDeciderBox); - this.Controls.Add(this.label3); - this.Controls.Add(this.runButton); - this.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); - this.MaximizeBox = false; - this.MinimumSize = new System.Drawing.Size(643, 355); - this.Name = "MainForm"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "ExportDXF"; - this.mainTabControl.ResumeLayout(false); - this.logEventsTab.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.logEventsDataGrid)).EndInit(); - this.bomTab.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.bomDataGrid)).EndInit(); - this.cutTemplatesTab.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.cutTemplatesDataGrid)).EndInit(); - this.dwgDetailsTab.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.drawingPdfViewer)).EndInit(); - this.ResumeLayout(false); - this.PerformLayout(); - + AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; + ClientSize = new System.Drawing.Size(768, 672); + Controls.Add(drawingNoBox); + Controls.Add(equipmentBox); + Controls.Add(mainTabControl); + Controls.Add(viewFlipDeciderBox); + Controls.Add(label2); + Controls.Add(label1); + Controls.Add(label3); + Controls.Add(runButton); + Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 0); + Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + MaximizeBox = false; + MinimumSize = new System.Drawing.Size(643, 355); + Name = "MainForm"; + StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + Text = "ExportDXF"; + mainTabControl.ResumeLayout(false); + logEventsTab.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)logEventsDataGrid).EndInit(); + bomTab.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)bomDataGrid).EndInit(); + ResumeLayout(false); + PerformLayout(); } #endregion @@ -224,12 +201,11 @@ private System.Windows.Forms.TabControl mainTabControl; private System.Windows.Forms.TabPage logEventsTab; private System.Windows.Forms.TabPage bomTab; - private System.Windows.Forms.TabPage dwgDetailsTab; private System.Windows.Forms.DataGridView logEventsDataGrid; - private AxAcroPDFLib.AxAcroPDF drawingPdfViewer; private System.Windows.Forms.DataGridView bomDataGrid; - private System.Windows.Forms.TabPage cutTemplatesTab; - private System.Windows.Forms.DataGridView cutTemplatesDataGrid; + private System.Windows.Forms.ComboBox equipmentBox; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.ComboBox drawingNoBox; } } - diff --git a/ExportDXF/Forms/MainForm.cs b/ExportDXF/Forms/MainForm.cs index 68b4c58..ba2ee81 100644 --- a/ExportDXF/Forms/MainForm.cs +++ b/ExportDXF/Forms/MainForm.cs @@ -1,47 +1,50 @@ +using ExportDXF.Data; using ExportDXF.Extensions; using ExportDXF.Models; using ExportDXF.Services; using ExportDXF.ViewFlipDeciders; using System; +using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; + namespace ExportDXF.Forms { public partial class MainForm : Form { private readonly ISolidWorksService _solidWorksService; private readonly IDxfExportService _exportService; - private readonly ICutFabApiClient _apiClient; + private readonly IFileExportService _fileExportService; + private readonly Func _dbContextFactory; private CancellationTokenSource _cancellationTokenSource; private readonly BindingList _logEvents; private readonly BindingList _bomItems; - private readonly BindingList _cutTemplates; - private readonly int _selectedDrawingId; - private readonly string _selectedDrawingNumber; + private List _allDrawings; - public MainForm(ISolidWorksService solidWorksService, IDxfExportService exportService, ICutFabApiClient apiClient, int selectedDrawingId, string selectedDrawingNumber) + public MainForm(ISolidWorksService solidWorksService, IDxfExportService exportService, IFileExportService fileExportService, Func dbContextFactory = null) { InitializeComponent(); _solidWorksService = solidWorksService ?? throw new ArgumentNullException(nameof(solidWorksService)); + _solidWorksService.ActiveDocumentChanged += OnActiveDocumentChanged; _exportService = exportService ?? throw new ArgumentNullException(nameof(exportService)); - _apiClient = apiClient ?? - throw new ArgumentNullException(nameof(apiClient)); - _selectedDrawingId = selectedDrawingId; - _selectedDrawingNumber = selectedDrawingNumber ?? throw new ArgumentNullException(nameof(selectedDrawingNumber)); + _fileExportService = fileExportService ?? + throw new ArgumentNullException(nameof(fileExportService)); + _dbContextFactory = dbContextFactory ?? (() => new ExportDxfDbContext()); _logEvents = new BindingList(); _bomItems = new BindingList(); - _cutTemplates = new BindingList(); + _allDrawings = new List(); InitializeViewFlipDeciders(); InitializeLogEventsGrid(); InitializeBomGrid(); - InitializeCutTemplatesGrid(); + InitializeDrawingDropdowns(); } + ~MainForm() { _cancellationTokenSource?.Dispose(); @@ -49,12 +52,14 @@ namespace ExportDXF.Forms components?.Dispose(); Dispose(false); } + protected override async void OnLoad(EventArgs e) { base.OnLoad(e); runButton.Enabled = false; await InitializeAsync(); } + private async Task InitializeAsync() { try @@ -62,87 +67,18 @@ namespace ExportDXF.Forms LogMessage("Connecting to SolidWorks, this may take a minute..."); await _solidWorksService.ConnectAsync(); _solidWorksService.ActiveDocumentChanged += OnActiveDocumentChanged; - LogMessage("Ready", Color.Green); + LogMessage($"Output folder: {_fileExportService.OutputFolder}"); + LogMessage("Ready"); UpdateActiveDocumentDisplay(); runButton.Enabled = true; - - // Load the selected drawing's BOM items - LogMessage($"Loading BOM items for drawing {_selectedDrawingNumber}..."); - await LoadBomItemsForDrawingAsync(_selectedDrawingId); - - // Load cut templates - await LoadCutTemplatesAsync(); } catch (Exception ex) { - LogMessage($"Failed to connect to SolidWorks: {ex.Message}", Color.Red); + LogMessage($"Failed to connect to SolidWorks: {ex.Message}", LogLevel.Error); MessageBox.Show("Failed to connect to SolidWorks.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); Application.Exit(); } } - private async Task LoadBomItemsForDrawingAsync(int drawingId) - { - try - { - _bomItems.Clear(); - - var apiBomItems = await _apiClient.GetBomItemsForDrawingAsync(drawingId); - - foreach (var apiItem in apiBomItems) - { - var bomItem = new BomItem - { - ID = apiItem.ID, - ItemNo = apiItem.ItemNo ?? "", - PartNo = apiItem.PartNo ?? "", - SortOrder = apiItem.SortOrder, - Qty = apiItem.Qty, - TotalQty = apiItem.TotalQty, - Description = apiItem.Description ?? "", - PartName = apiItem.PartName ?? "", - ConfigurationName = apiItem.ConfigurationName ?? "", - Material = apiItem.Material ?? "", - DrawingID = apiItem.DrawingID, - CutTemplateID = apiItem.CutTemplateID, - CutTemplateName = apiItem.CutTemplateName ?? "", - Thickness = apiItem.Thickness, - KFactor = apiItem.KFactor, - DefaultBendRadius = apiItem.DefaultBendRadius - }; - - _bomItems.Add(bomItem); - } - - LogMessage($"Loaded {apiBomItems.Count} BOM item(s)", Color.Green); - } - catch (Exception ex) - { - LogMessage($"Failed to load BOM items: {ex.Message}", Color.Red); - } - } - - private async Task LoadCutTemplatesAsync() - { - try - { - _cutTemplates.Clear(); - - LogMessage("Loading cut templates..."); - - var apiCutTemplates = await _apiClient.GetCutTemplatesAsync(); - - foreach (var template in apiCutTemplates) - { - _cutTemplates.Add(template); - } - - LogMessage($"Loaded {apiCutTemplates.Count} cut template(s)", Color.Green); - } - catch (Exception ex) - { - LogMessage($"Failed to load cut templates: {ex.Message}", Color.Red); - } - } private void InitializeViewFlipDeciders() { @@ -163,6 +99,7 @@ namespace ExportDXF.Forms viewFlipDeciderBox.DataSource = items; viewFlipDeciderBox.DisplayMember = "Name"; } + private void InitializeLogEventsGrid() { // Clear any existing columns first @@ -191,6 +128,13 @@ namespace ExportDXF.Forms Width = 70 }); + logEventsDataGrid.Columns.Add(new DataGridViewTextBoxColumn + { + DataPropertyName = nameof(LogEvent.Part), + HeaderText = "File", + Width = 180 + }); + logEventsDataGrid.Columns.Add(new DataGridViewTextBoxColumn { DataPropertyName = nameof(LogEvent.Message), @@ -198,6 +142,9 @@ namespace ExportDXF.Forms AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill }); + // Add row coloring based on log level + logEventsDataGrid.CellFormatting += LogEventsDataGrid_CellFormatting; + // Set the data source AFTER adding columns logEventsDataGrid.DataSource = _logEvents; } @@ -264,84 +211,85 @@ namespace ExportDXF.Forms Width = 120 }); - bomDataGrid.Columns.Add(new DataGridViewTextBoxColumn - { - DataPropertyName = nameof(BomItem.CutTemplateName), - HeaderText = "Cut Template", - Width = 120 - }); - // Set the data source AFTER adding columns bomDataGrid.DataSource = _bomItems; } - private void InitializeCutTemplatesGrid() + private void InitializeDrawingDropdowns() { - // Clear any existing columns first - cutTemplatesDataGrid.Columns.Clear(); - - // Configure grid settings - cutTemplatesDataGrid.AutoGenerateColumns = false; - cutTemplatesDataGrid.AllowUserToAddRows = false; - cutTemplatesDataGrid.AllowUserToDeleteRows = false; - cutTemplatesDataGrid.ReadOnly = true; - cutTemplatesDataGrid.SelectionMode = DataGridViewSelectionMode.FullRowSelect; - - // Add columns - cutTemplatesDataGrid.Columns.Add(new DataGridViewTextBoxColumn + try { - DataPropertyName = nameof(CutFabApiClient.ApiCutTemplate.Name), - HeaderText = "Name", - Width = 200 - }); + using (var db = _dbContextFactory()) + { + // Get all drawing numbers from the database + var drawingNumbers = db.ExportRecords + .Select(r => r.DrawingNumber) + .Where(d => !string.IsNullOrEmpty(d)) + .Distinct() + .ToList(); - cutTemplatesDataGrid.Columns.Add(new DataGridViewTextBoxColumn + // Parse into DrawingInfo objects + _allDrawings = drawingNumbers + .Select(DrawingInfo.Parse) + .Where(d => d != null) + .Distinct() + .OrderBy(d => d.EquipmentNo) + .ThenBy(d => d.DrawingNo) + .ToList(); + + // Get distinct equipment numbers + var equipmentNumbers = _allDrawings + .Select(d => d.EquipmentNo) + .Distinct() + .OrderBy(e => e) + .ToList(); + + // Populate equipment dropdown + equipmentBox.Items.Clear(); + equipmentBox.Items.Add(""); // Empty option for "all" + foreach (var eq in equipmentNumbers) + { + equipmentBox.Items.Add(eq); + } + + // Populate drawing dropdown with all drawings initially + UpdateDrawingDropdown(); + + // Wire up event handler for equipment selection change + equipmentBox.SelectedIndexChanged += EquipmentBox_SelectedIndexChanged; + } + } + catch (Exception ex) { - DataPropertyName = nameof(CutFabApiClient.ApiCutTemplate.Material), - HeaderText = "Material", - Width = 120 - }); + // Database might not exist yet - that's OK + System.Diagnostics.Debug.WriteLine($"Failed to load drawings from database: {ex.Message}"); + } + } - cutTemplatesDataGrid.Columns.Add(new DataGridViewTextBoxColumn + private void EquipmentBox_SelectedIndexChanged(object sender, EventArgs e) + { + UpdateDrawingDropdown(); + } + + private void UpdateDrawingDropdown() + { + var selectedEquipment = equipmentBox.SelectedItem?.ToString(); + + var filteredDrawings = string.IsNullOrEmpty(selectedEquipment) + ? _allDrawings + : _allDrawings.Where(d => d.EquipmentNo == selectedEquipment).ToList(); + + drawingNoBox.Items.Clear(); + drawingNoBox.Items.Add(""); // Empty option + foreach (var drawing in filteredDrawings) { - DataPropertyName = nameof(CutFabApiClient.ApiCutTemplate.Thickness), - HeaderText = "Thickness", - Width = 80, - DefaultCellStyle = new DataGridViewCellStyle { Format = "0.##" } - }); + drawingNoBox.Items.Add(drawing.DrawingNo); + } - cutTemplatesDataGrid.Columns.Add(new DataGridViewTextBoxColumn + if (drawingNoBox.Items.Count > 0) { - DataPropertyName = nameof(CutFabApiClient.ApiCutTemplate.KFactor), - HeaderText = "K-Factor", - Width = 80, - DefaultCellStyle = new DataGridViewCellStyle { Format = "0.####" } - }); - - cutTemplatesDataGrid.Columns.Add(new DataGridViewTextBoxColumn - { - DataPropertyName = nameof(CutFabApiClient.ApiCutTemplate.DefaultBendRadius), - HeaderText = "Bend Radius", - Width = 90, - DefaultCellStyle = new DataGridViewCellStyle { Format = "0.##" } - }); - - cutTemplatesDataGrid.Columns.Add(new DataGridViewTextBoxColumn - { - DataPropertyName = nameof(CutFabApiClient.ApiCutTemplate.Version), - HeaderText = "Version", - Width = 70 - }); - - cutTemplatesDataGrid.Columns.Add(new DataGridViewTextBoxColumn - { - DataPropertyName = nameof(CutFabApiClient.ApiCutTemplate.Description), - HeaderText = "Description", - AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill - }); - - // Set the data source AFTER adding columns - cutTemplatesDataGrid.DataSource = _cutTemplates; + drawingNoBox.SelectedIndex = 0; + } } private async void button1_Click(object sender, EventArgs e) @@ -355,6 +303,7 @@ namespace ExportDXF.Forms await StartExportAsync(); } } + private async Task StartExportAsync() { try @@ -362,33 +311,47 @@ namespace ExportDXF.Forms _cancellationTokenSource = new CancellationTokenSource(); var token = _cancellationTokenSource.Token; UpdateUIForExportStart(); + var activeDoc = _solidWorksService.GetActiveDocument(); if (activeDoc == null) { - LogMessage("No active document.", Color.Red); + LogMessage("No active document.", LogLevel.Error); return; } + + // Parse drawing number from active document title + var drawingInfo = DrawingInfo.Parse(activeDoc.Title); + var filePrefix = drawingInfo != null ? $"{drawingInfo.EquipmentNo} {drawingInfo.DrawingNo}" : activeDoc.Title; + var viewFlipDecider = GetSelectedViewFlipDecider(); var exportContext = new ExportContext { ActiveDocument = activeDoc, ViewFlipDecider = viewFlipDecider, - FilePrefix = _selectedDrawingNumber, - EquipmentId = null, // Not needed for export + FilePrefix = filePrefix, + EquipmentId = null, CancellationToken = token, - ProgressCallback = LogMessage + ProgressCallback = (msg, level, file) => LogMessage(msg, level, file), + BomItemCallback = AddBomItem }; + + // Clear previous BOM items + _bomItems.Clear(); + LogMessage($"Started at {DateTime.Now:t}"); + LogMessage($"Exporting to: {_fileExportService.OutputFolder}"); + await Task.Run(() => _exportService.Export(exportContext), token); - LogMessage("Done.", Color.Green); + + LogMessage("Done."); } catch (OperationCanceledException) { - LogMessage("Export canceled.", Color.Red); + LogMessage("Export canceled.", LogLevel.Error); } catch (Exception ex) { - LogMessage($"Export failed: {ex.Message}", Color.Red); + LogMessage($"Export failed: {ex.Message}", LogLevel.Error); MessageBox.Show($"Export failed: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally @@ -398,27 +361,32 @@ namespace ExportDXF.Forms _cancellationTokenSource = null; } } + private void CancelExport() { runButton.Enabled = false; _cancellationTokenSource?.Cancel(); } + private IViewFlipDecider GetSelectedViewFlipDecider() { var item = viewFlipDeciderBox.SelectedItem as ViewFlipDeciderComboboxItem; return item?.ViewFlipDecider; } + private void UpdateUIForExportStart() { viewFlipDeciderBox.Enabled = false; - runButton.Image = Properties.Resources.stop_alt; + runButton.Text = "Stop"; } + private void UpdateUIForExportComplete() { viewFlipDeciderBox.Enabled = true; - runButton.Image = Properties.Resources.play; + runButton.Text = "Start"; runButton.Enabled = true; } + private void OnActiveDocumentChanged(object sender, EventArgs e) { if (InvokeRequired) @@ -428,20 +396,17 @@ namespace ExportDXF.Forms } UpdateActiveDocumentDisplay(); } + private void UpdateActiveDocumentDisplay() { var activeDoc = _solidWorksService.GetActiveDocument(); var docTitle = activeDoc?.Title ?? "No Document Open"; this.Text = $"ExportDXF - {docTitle}"; } - private void LogMessage(string message, Color? color = null) - { - var level = color.HasValue && color.Value == Color.Red ? LogLevel.Error : - color.HasValue && color.Value == Color.Green ? LogLevel.Info : - color.HasValue && color.Value == Color.DarkBlue ? LogLevel.Warning : - LogLevel.Info; - AddLogEvent(level, LogAction.Start, message); + private void LogMessage(string message, LogLevel level = LogLevel.Info, string file = null) + { + AddLogEvent(level, LogAction.Start, message, part: file); } private void AddLogEvent(LogLevel level, LogAction action, string message, string equipment = "", string drawing = "", string part = "", string target = "", string result = "OK", int durationMs = 0) @@ -474,5 +439,40 @@ namespace ExportDXF.Forms logEventsDataGrid.FirstDisplayedScrollingRowIndex = logEventsDataGrid.Rows.Count - 1; } } + + public void AddBomItem(BomItem item) + { + if (InvokeRequired) + { + Invoke(new Action(() => AddBomItem(item))); + return; + } + _bomItems.Add(item); + } + + private void LogEventsDataGrid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) + { + if (e.RowIndex < 0 || e.RowIndex >= _logEvents.Count) + return; + + var logEvent = _logEvents[e.RowIndex]; + var row = logEventsDataGrid.Rows[e.RowIndex]; + + switch (logEvent.Level) + { + case LogLevel.Warning: + row.DefaultCellStyle.BackColor = Color.LightGoldenrodYellow; + row.DefaultCellStyle.ForeColor = Color.DarkOrange; + break; + case LogLevel.Error: + row.DefaultCellStyle.BackColor = Color.MistyRose; + row.DefaultCellStyle.ForeColor = Color.DarkRed; + break; + default: + row.DefaultCellStyle.BackColor = Color.White; + row.DefaultCellStyle.ForeColor = Color.Black; + break; + } + } } -} \ No newline at end of file +} diff --git a/ExportDXF/Forms/MainForm.resx b/ExportDXF/Forms/MainForm.resx index 27850f2..8b2ff64 100644 --- a/ExportDXF/Forms/MainForm.resx +++ b/ExportDXF/Forms/MainForm.resx @@ -1,17 +1,17 @@  - @@ -117,12 +117,4 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w - LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACFTeXN0 - ZW0uV2luZG93cy5Gb3Jtcy5BeEhvc3QrU3RhdGUBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAIQAAAAIB - AAAAAQAAAAAAAAAAAAAAAAwAAAAADgAASGsAANA3AAAL - - \ No newline at end of file diff --git a/ExportDXF/Models/BomItem.cs b/ExportDXF/Models/BomItem.cs index 3bd2a5b..16c7dc0 100644 --- a/ExportDXF/Models/BomItem.cs +++ b/ExportDXF/Models/BomItem.cs @@ -14,14 +14,29 @@ namespace ExportDXF.Models public string PartName { get; set; } = ""; public string ConfigurationName { get; set; } = ""; public string Material { get; set; } = ""; - public int DrawingID { get; set; } - public int? CutTemplateID { get; set; } public string CutTemplateName { get; set; } = ""; + public string DxfFilePath { get; set; } = ""; + + // Sheet metal properties + private double? _thickness; + public double? Thickness + { + get => _thickness; + set => _thickness = value.HasValue ? Math.Round(value.Value, 8) : null; + } - // Sheet metal properties from CutTemplate - public double? Thickness { get; set; } public double? KFactor { get; set; } - public double? DefaultBendRadius { get; set; } + + private double? _defaultBendRadius; + public double? DefaultBendRadius + { + get => _defaultBendRadius; + set => _defaultBendRadius = value.HasValue ? Math.Round(value.Value, 8) : null; + } + + // EF Core relationship to ExportRecord + public int ExportRecordId { get; set; } + public virtual ExportRecord ExportRecord { get; set; } } public struct Size diff --git a/ExportDXF/Models/ExportContext.cs b/ExportDXF/Models/ExportContext.cs index 66a8abb..837db04 100644 --- a/ExportDXF/Models/ExportContext.cs +++ b/ExportDXF/Models/ExportContext.cs @@ -1,8 +1,8 @@ -using ExportDXF.ViewFlipDeciders; +using ExportDXF.Models; +using ExportDXF.ViewFlipDeciders; using SolidWorks.Interop.sldworks; using SolidWorks.Interop.swconst; using System; -using System.Drawing; using System.IO; using System.Threading; using System.Windows.Forms; @@ -44,12 +44,18 @@ namespace ExportDXF.Services /// /// Callback for reporting progress and status messages. + /// Parameters: message, level, file (optional) /// - public Action ProgressCallback { get; set; } + public Action ProgressCallback { get; set; } - public void LogProgress(string message, Color? color = null) + /// + /// Callback for adding BOM items to the UI. + /// + public Action BomItemCallback { get; set; } + + public void LogProgress(string message, LogLevel level = LogLevel.Info, string file = null) { - ProgressCallback?.Invoke(message, color); + ProgressCallback?.Invoke(message, level, file); } public SldWorks SolidWorksApp { get; set; } @@ -90,7 +96,7 @@ namespace ExportDXF.Services if (SolidWorksApp == null) { - ProgressCallback?.Invoke("Warning: Cannot cleanup template drawing - SolidWorks app not available", Color.DarkBlue); + ProgressCallback?.Invoke("Warning: Cannot cleanup template drawing - SolidWorks app not available", LogLevel.Warning, null); TemplateDrawing = null; return; } @@ -104,7 +110,7 @@ namespace ExportDXF.Services { // Close the document without saving SolidWorksApp.CloseDoc(title); - ProgressCallback?.Invoke("Closed template drawing", null); + ProgressCallback?.Invoke("Closed template drawing", LogLevel.Info, null); } } @@ -113,7 +119,7 @@ namespace ExportDXF.Services } catch (Exception ex) { - ProgressCallback?.Invoke($"Failed to close template drawing: {ex.Message}", Color.Red); + ProgressCallback?.Invoke($"Failed to close template drawing: {ex.Message}", LogLevel.Error, null); // Still clear the reference to prevent further issues TemplateDrawing = null; diff --git a/ExportDXF/Program.cs b/ExportDXF/Program.cs index 882818d..4e68c80 100644 --- a/ExportDXF/Program.cs +++ b/ExportDXF/Program.cs @@ -1,8 +1,7 @@ -using ExportDXF.Forms; +using ExportDXF.Forms; using ExportDXF.Services; using System; using System.Configuration; -using System.Threading.Tasks; using System.Windows.Forms; namespace ExportDXF @@ -18,78 +17,40 @@ namespace ExportDXF Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - // Simple DI setup - could use a DI container like Microsoft.Extensions.DependencyInjection var container = new ServiceContainer(); - - // Show drawing selection dialog first - var drawingSelectionForm = container.ResolveDrawingSelectionAsync().GetAwaiter().GetResult(); - var result = drawingSelectionForm.ShowDialog(); - - if (result == DialogResult.OK && drawingSelectionForm.SelectedDrawingId.HasValue) - { - // User selected a drawing, proceed to main form - var mainForm = container.Resolve( - drawingSelectionForm.SelectedDrawingId.Value, - drawingSelectionForm.SelectedDrawingNumber); - - Application.Run(mainForm); - } - // If user cancelled, just exit + var mainForm = container.ResolveMainForm(); + Application.Run(mainForm); } } /// /// Simple dependency injection container. - /// For production, consider using Microsoft.Extensions.DependencyInjection or similar. /// public class ServiceContainer { - private readonly string _baseUrl; - private readonly CutFabApiClient _apiClient; + private readonly string _outputFolder; public ServiceContainer() { - _baseUrl = ConfigurationManager.AppSettings["CutFab.ApiBaseUrl"] ?? "http://localhost:7027"; - _apiClient = new CutFabApiClient(_baseUrl); + _outputFolder = ConfigurationManager.AppSettings["ExportOutputFolder"] ?? @"C:\ExportDXF\Output"; } - public async Task ResolveDrawingSelectionAsync() + public MainForm ResolveMainForm() { - // Connect to SolidWorks first var solidWorksService = new SolidWorksService(); - try - { - await solidWorksService.ConnectAsync(); - } - catch (Exception ex) - { - System.Windows.Forms.MessageBox.Show( - $"Warning: Could not connect to SolidWorks: {ex.Message}\n\nYou can still select a drawing, but the active document will not be displayed.", - "SolidWorks Connection Warning", - System.Windows.Forms.MessageBoxButtons.OK, - System.Windows.Forms.MessageBoxIcon.Warning); - } - - return new DrawingSelectionForm(_apiClient, solidWorksService); - } - - public MainForm Resolve(int selectedDrawingId, string selectedDrawingNumber) where T : MainForm - { - // Create the dependency tree - var solidWorksService = new SolidWorksService(); - var bomExtractor = new BomExtractor(); var partExporter = new PartExporter(); var drawingExporter = new DrawingExporter(); + var fileExportService = new FileExportService(_outputFolder); var exportService = new DxfExportService( solidWorksService, bomExtractor, partExporter, drawingExporter, - _apiClient); + fileExportService); - return new MainForm(solidWorksService, exportService, _apiClient, selectedDrawingId, selectedDrawingNumber); + return new MainForm(solidWorksService, exportService, fileExportService); } } } diff --git a/ExportDXF/Services/BomExtractor.cs b/ExportDXF/Services/BomExtractor.cs index ad11a5b..b2e0e98 100644 --- a/ExportDXF/Services/BomExtractor.cs +++ b/ExportDXF/Services/BomExtractor.cs @@ -1,9 +1,9 @@ using ExportDXF.Extensions; using ExportDXF.ItemExtractors; +using ExportDXF.Models; using SolidWorks.Interop.sldworks; using System; using System.Collections.Generic; -using System.Drawing; namespace ExportDXF.Services { @@ -16,14 +16,14 @@ namespace ExportDXF.Services /// Extracts items from all BOM tables in a drawing document. /// /// The drawing document containing BOM tables. - /// Optional callback for progress updates. + /// Optional callback for progress updates (message, level, file). /// A list of extracted items. - List ExtractFromDrawing(DrawingDoc drawing, Action progressCallback); + List ExtractFromDrawing(DrawingDoc drawing, Action progressCallback); } public class BomExtractor : IBomExtractor { - public List ExtractFromDrawing(DrawingDoc drawing, Action progressCallback) + public List ExtractFromDrawing(DrawingDoc drawing, Action progressCallback) { if (drawing == null) throw new ArgumentNullException(nameof(drawing)); @@ -32,11 +32,11 @@ namespace ExportDXF.Services if (bomTables.Count == 0) { - progressCallback?.Invoke("Error: Bill of materials not found.", Color.Red); + progressCallback?.Invoke("Error: Bill of materials not found.", LogLevel.Error, null); return new List(); } - progressCallback?.Invoke($"Found {bomTables.Count} BOM table(s)", null); + progressCallback?.Invoke($"Found {bomTables.Count} BOM table(s)", LogLevel.Info, null); var allItems = new List(); @@ -49,14 +49,14 @@ namespace ExportDXF.Services SkipHiddenRows = true }; - progressCallback?.Invoke($"Fetching components from {bom.BomFeature.Name}", null); + progressCallback?.Invoke($"Fetching components from {bom.BomFeature.Name}", LogLevel.Info, null); var items = extractor.GetItems(); allItems.AddRange(items); } catch (Exception ex) { - progressCallback?.Invoke($"Failed to extract from {bom.BomFeature.Name}: {ex.Message}", Color.Red); + progressCallback?.Invoke($"Failed to extract: {ex.Message}", LogLevel.Error, bom.BomFeature.Name); } } diff --git a/ExportDXF/Services/CutFabApiClient.cs b/ExportDXF/Services/CutFabApiClient.cs deleted file mode 100644 index e69cc4b..0000000 --- a/ExportDXF/Services/CutFabApiClient.cs +++ /dev/null @@ -1,468 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Configuration; -using System.IO; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Text; -using System.Threading.Tasks; -using System.Web.Script.Serialization; -using static ExportDXF.Services.CutFabApiClient; - -namespace ExportDXF.Services -{ - public interface ICutFabApiClient - { - string BaseUrl { get; } - Task ResolveDrawingIdAsync(string drawingNumber); - Task CreateDrawingAsync(int equipmentId, string drawingNumber); - Task> CreateDrawingWithInfoAsync(int equipmentId, string drawingNumber); - Task UploadDrawingPdfAsync(string drawingNumber, string pdfPath, string uploadedBy = null, string notes = null); - Task UploadDxfZipAsync( - int drawingId, - string zipPath, - double? thickness = null, - double? kfactor = null, - double? defaultBendRadius = null, - string material = null); - Task CreateBomItemAsync(object upsertBomItemDto); - Task AutoLinkTemplatesAsync(int drawingId); - Task> GetEquipmentAsync(); - Task> GetDrawingsForEquipmentAsync(int equipmentId); - Task> GetBomItemsForDrawingAsync(int drawingId); - Task> GetCutTemplatesAsync(); - } - - public class CutFabApiClient : ICutFabApiClient, IDisposable - { - private readonly HttpClient _http; - private readonly string _baseUrl; - public string BaseUrl => _baseUrl; - public class ApiResponse - { - public bool Success { get; set; } - public int StatusCode { get; set; } - public T Data { get; set; } - public string RawBody { get; set; } - public string Error { get; set; } - } - - public CutFabApiClient(string baseUrl) - { - _baseUrl = (baseUrl ?? string.Empty).TrimEnd('/'); - - if (string.IsNullOrWhiteSpace(_baseUrl)) - { - // Default to deployed API port from deployment script - _baseUrl = "http://localhost:7027"; - } - - _http = new HttpClient - { - Timeout = TimeSpan.FromSeconds(100) - }; - } - - public async Task ResolveDrawingIdAsync(string drawingNumber) - { - try - { - var url = $"{_baseUrl}/api/Drawings/resolve?drawingNumber={Uri.EscapeDataString(drawingNumber)}"; - var resp = await _http.GetAsync(url).ConfigureAwait(false); - if (!resp.IsSuccessStatusCode) return null; - var json = await resp.Content.ReadAsStringAsync().ConfigureAwait(false); - var dict = new JavaScriptSerializer().Deserialize>(json); - if (dict != null && dict.ContainsKey("ID")) - { - var idObj = dict["ID"]; // serializer returns int or double depending - if (idObj is int i) return i; - if (idObj is double d) return (int)d; - } - return null; - } - catch - { - return null; - } - } - - public async Task CreateDrawingAsync(int equipmentId, string drawingNumber) - { - var payload = new { DrawingNumber = drawingNumber, Description = (string)null, Qty = 1, EquipmentID = equipmentId }; - var json = new JavaScriptSerializer().Serialize(payload); - var content = new StringContent(json, Encoding.UTF8, "application/json"); - var resp = await _http.PostAsync($"{_baseUrl}/api/Drawings", content).ConfigureAwait(false); - if (!resp.IsSuccessStatusCode) return null; - var body = await resp.Content.ReadAsStringAsync().ConfigureAwait(false); - try - { - var dict = new JavaScriptSerializer().Deserialize>(body); - if (dict != null && dict.ContainsKey("ID")) - { - var idObj = dict["ID"]; if (idObj is int i) return i; if (idObj is double d) return (int)d; - } - } - catch { } - return null; - } - - public async Task> CreateDrawingWithInfoAsync(int equipmentId, string drawingNumber) - { - var result = new ApiResponse { Success = false, StatusCode = 0, Data = null, RawBody = null, Error = null }; - try - { - var payload = new { DrawingNumber = drawingNumber, Description = (string)null, Qty = 1, EquipmentID = equipmentId }; - var json = new JavaScriptSerializer().Serialize(payload); - var content = new StringContent(json, Encoding.UTF8, "application/json"); - var resp = await _http.PostAsync($"{_baseUrl}/api/Drawings", content).ConfigureAwait(false); - result.StatusCode = (int)resp.StatusCode; - result.Success = resp.IsSuccessStatusCode; - var body = await resp.Content.ReadAsStringAsync().ConfigureAwait(false); - result.RawBody = body; - if (!resp.IsSuccessStatusCode) - { - result.Error = "HTTP " + ((int)resp.StatusCode) + " " + resp.ReasonPhrase; - return result; - } - try - { - var dict = new JavaScriptSerializer().Deserialize>(body); - if (dict != null) - { - object v; - if (TryGetCI(dict, new[] { "ID", "id" }, out v)) - { - if (v is int i) { result.Data = i; return result; } - if (v is double d) { result.Data = (int)d; return result; } - int parsed; if (int.TryParse(Convert.ToString(v), out parsed)) { result.Data = parsed; return result; } - } - } - } - catch (Exception ex) - { - result.Error = ex.Message; - } - return result; - } - catch (Exception ex) - { - result.Error = ex.Message; - return result; - } - } - - public async Task UploadDrawingPdfAsync(string drawingNumber, string pdfPath, string uploadedBy = null, string notes = null) - { - if (!File.Exists(pdfPath)) return false; - using (var form = new MultipartFormDataContent()) - { - form.Add(new StringContent(drawingNumber ?? string.Empty), "drawingNumber"); - if (!string.IsNullOrWhiteSpace(uploadedBy)) form.Add(new StringContent(uploadedBy), "uploadedBy"); - if (!string.IsNullOrWhiteSpace(notes)) form.Add(new StringContent(notes), "notes"); - - var fileContent = new StreamContent(File.OpenRead(pdfPath)); - fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/pdf"); - var fileName = Path.GetFileName(pdfPath); - form.Add(fileContent, "file", fileName); - - var resp = await _http.PostAsync($"{_baseUrl}/api/DrawingRevisions/upload", form).ConfigureAwait(false); - return resp.IsSuccessStatusCode; - } - } - - public async Task UploadDxfZipAsync(int drawingId, string zipPath, double? thickness = null, double? kfactor = null, double? defaultBendRadius = null, string material = null) - { - if (!File.Exists(zipPath)) return false; - using (var form = new MultipartFormDataContent()) - { - var fileContent = new StreamContent(File.OpenRead(zipPath)); - fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/zip"); - var fileName = Path.GetFileName(zipPath); - form.Add(fileContent, "file", fileName); - - // Add thickness and kfactor if provided - if (thickness.HasValue) - form.Add(new StringContent(thickness.Value.ToString(System.Globalization.CultureInfo.InvariantCulture)), "thickness"); - if (kfactor.HasValue) - form.Add(new StringContent(kfactor.Value.ToString(System.Globalization.CultureInfo.InvariantCulture)), "kfactor"); - // Add default bend radius and material if provided - if (defaultBendRadius.HasValue) - form.Add(new StringContent(defaultBendRadius.Value.ToString(System.Globalization.CultureInfo.InvariantCulture)), "defaultBendRadius"); - if (!string.IsNullOrWhiteSpace(material)) - form.Add(new StringContent(material), "material"); - - var resp = await _http.PostAsync($"{_baseUrl}/api/Drawings/{drawingId}/upload-dxf-templates", form).ConfigureAwait(false); - return resp.IsSuccessStatusCode; - } - } - - public async Task CreateBomItemAsync(object upsertBomItemDto) - { - var json = new JavaScriptSerializer().Serialize(upsertBomItemDto); - var content = new StringContent(json, Encoding.UTF8, "application/json"); - var resp = await _http.PostAsync($"{_baseUrl}/api/BomItems", content).ConfigureAwait(false); - if (!resp.IsSuccessStatusCode) return null; - var body = await resp.Content.ReadAsStringAsync().ConfigureAwait(false); - try - { - var dict = new JavaScriptSerializer().Deserialize>(body); - if (dict != null) - { - object v; - if (TryGetCI(dict, new[] { "ID", "id" }, out v)) - { - if (v is int i) return i; - if (v is double d) return (int)d; - int parsed; if (int.TryParse(Convert.ToString(v), out parsed)) return parsed; - } - } - } - catch { } - // Successful HTTP with empty/minimal body: treat as success - return 0; - } - - public async Task AutoLinkTemplatesAsync(int drawingId) - { - var url = $"{_baseUrl}/api/Drawings/{drawingId}/auto-link-templates"; - var resp = await _http.PostAsync(url, new ByteArrayContent(new byte[0])).ConfigureAwait(false); - return resp.IsSuccessStatusCode; - } - - public async Task> GetBomItemsForDrawingAsync(int drawingId) - { - var url = $"{_baseUrl}/api/BomItems/drawing/{drawingId}"; - var resp = await _http.GetAsync(url).ConfigureAwait(false); - if (!resp.IsSuccessStatusCode) return new List(); - var json = await resp.Content.ReadAsStringAsync().ConfigureAwait(false); - var serializer = new JavaScriptSerializer(); - var raw = serializer.DeserializeObject(json); - var result = new List(); - - if (raw is System.Collections.IEnumerable enumerable && !(raw is string)) - { - foreach (var item in enumerable) - { - var dict = item as Dictionary; - if (dict == null) continue; - var bomItem = new ApiBomItem(); - object v; - if (TryGetCI(dict, new[] { "ID", "id" }, out v)) bomItem.ID = ToInt(v); - if (TryGetCI(dict, new[] { "ItemNo", "itemNo" }, out v)) bomItem.ItemNo = v?.ToString(); - if (TryGetCI(dict, new[] { "PartNo", "partNo" }, out v)) bomItem.PartNo = v?.ToString(); - if (TryGetCI(dict, new[] { "SortOrder", "sortOrder" }, out v)) bomItem.SortOrder = ToInt(v); - if (TryGetCI(dict, new[] { "Qty", "qty" }, out v)) bomItem.Qty = v != null ? (int?)ToInt(v) : null; - if (TryGetCI(dict, new[] { "TotalQty", "totalQty" }, out v)) bomItem.TotalQty = v != null ? (int?)ToInt(v) : null; - if (TryGetCI(dict, new[] { "Description", "description" }, out v)) bomItem.Description = v?.ToString(); - if (TryGetCI(dict, new[] { "PartName", "partName" }, out v)) bomItem.PartName = v?.ToString(); - if (TryGetCI(dict, new[] { "ConfigurationName", "configurationName" }, out v)) bomItem.ConfigurationName = v?.ToString(); - if (TryGetCI(dict, new[] { "Material", "material" }, out v)) bomItem.Material = v?.ToString(); - if (TryGetCI(dict, new[] { "DrawingID", "drawingID", "drawingId" }, out v)) bomItem.DrawingID = ToInt(v); - if (TryGetCI(dict, new[] { "CutTemplateID", "cutTemplateID", "cutTemplateId" }, out v)) bomItem.CutTemplateID = v != null ? (int?)ToInt(v) : null; - - // Try to get CutTemplate info if available - if (TryGetCI(dict, new[] { "CutTemplate", "cutTemplate" }, out v)) - { - var templateDict = v as Dictionary; - if (templateDict != null) - { - object tv; - if (TryGetCI(templateDict, new[] { "Name", "name" }, out tv)) bomItem.CutTemplateName = tv?.ToString(); - if (TryGetCI(templateDict, new[] { "Thickness", "thickness" }, out tv)) bomItem.Thickness = ToDouble(tv); - if (TryGetCI(templateDict, new[] { "KFactor", "kFactor", "kfactor" }, out tv)) bomItem.KFactor = ToDouble(tv); - if (TryGetCI(templateDict, new[] { "DefaultBendRadius", "defaultBendRadius" }, out tv)) bomItem.DefaultBendRadius = ToDouble(tv); - } - } - - result.Add(bomItem); - } - } - - return result; - } - - public async Task> GetCutTemplatesAsync() - { - var url = $"{_baseUrl}/api/CutTemplates"; - var resp = await _http.GetAsync(url).ConfigureAwait(false); - if (!resp.IsSuccessStatusCode) return new List(); - var json = await resp.Content.ReadAsStringAsync().ConfigureAwait(false); - var serializer = new JavaScriptSerializer(); - var raw = serializer.DeserializeObject(json); - var result = new List(); - - if (raw is System.Collections.IEnumerable enumerable && !(raw is string)) - { - foreach (var item in enumerable) - { - var dict = item as Dictionary; - if (dict == null) continue; - var template = new ApiCutTemplate(); - object v; - if (TryGetCI(dict, new[] { "ID", "id" }, out v)) template.ID = ToInt(v); - if (TryGetCI(dict, new[] { "Name", "name" }, out v)) template.Name = v?.ToString(); - if (TryGetCI(dict, new[] { "FilePath", "filePath" }, out v)) template.FilePath = v?.ToString(); - if (TryGetCI(dict, new[] { "Description", "description" }, out v)) template.Description = v?.ToString(); - if (TryGetCI(dict, new[] { "Material", "material" }, out v)) template.Material = v?.ToString(); - if (TryGetCI(dict, new[] { "Thickness", "thickness" }, out v)) template.Thickness = ToDouble(v); - if (TryGetCI(dict, new[] { "KFactor", "kFactor", "kfactor" }, out v)) template.KFactor = ToDouble(v); - if (TryGetCI(dict, new[] { "DefaultBendRadius", "defaultBendRadius" }, out v)) template.DefaultBendRadius = ToDouble(v); - if (TryGetCI(dict, new[] { "Version", "version" }, out v)) template.Version = ToInt(v); - result.Add(template); - } - } - - return result; - } - - public void Dispose() - { - _http?.Dispose(); - } - - // Lightweight DTOs for UI binding - public class ApiEquipment - { - public int ID { get; set; } - public string EquipmentNumber { get; set; } - public string Description { get; set; } - public override string ToString() => EquipmentNumber ?? base.ToString(); - } - - public class ApiDrawingSummary - { - public int ID { get; set; } - public string DrawingNumber { get; set; } - public string Description { get; set; } - public override string ToString() => DrawingNumber ?? base.ToString(); - } - - public class ApiBomItem - { - public int ID { get; set; } - public string ItemNo { get; set; } - public string PartNo { get; set; } - public int SortOrder { get; set; } - public int? Qty { get; set; } - public int? TotalQty { get; set; } - public string Description { get; set; } - public string PartName { get; set; } - public string ConfigurationName { get; set; } - public string Material { get; set; } - public int DrawingID { get; set; } - public int? CutTemplateID { get; set; } - public string CutTemplateName { get; set; } - public double? Thickness { get; set; } - public double? KFactor { get; set; } - public double? DefaultBendRadius { get; set; } - } - - public class ApiCutTemplate - { - public int ID { get; set; } - public string Name { get; set; } - public string FilePath { get; set; } - public string Description { get; set; } - public string Material { get; set; } - public double? Thickness { get; set; } - public double? KFactor { get; set; } - public double? DefaultBendRadius { get; set; } - public int Version { get; set; } - } - - public async Task> GetEquipmentAsync() - { - var url = $"{_baseUrl}/api/Equipment"; - var req = new HttpRequestMessage(HttpMethod.Get, url); - req.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - var resp = await _http.SendAsync(req).ConfigureAwait(false); - resp.EnsureSuccessStatusCode(); - var json = await resp.Content.ReadAsStringAsync().ConfigureAwait(false); - - var serializer = new JavaScriptSerializer(); - var raw = serializer.DeserializeObject(json); - var result = new List(); - - if (raw is System.Collections.IEnumerable enumerable && !(raw is string)) - { - foreach (var item in enumerable) - { - var dict = item as Dictionary; - if (dict == null) continue; - var eq = new ApiEquipment(); - object v; - if (TryGetCI(dict, new[] { "ID", "id" }, out v)) eq.ID = ToInt(v); - if (TryGetCI(dict, new[] { "EquipmentNumber", "equipmentNumber", "equipmentNo" }, out v)) eq.EquipmentNumber = v?.ToString(); - if (TryGetCI(dict, new[] { "Description", "description" }, out v)) eq.Description = v?.ToString(); - result.Add(eq); - } - } - - return result; - } - - public async Task> GetDrawingsForEquipmentAsync(int equipmentId) - { - var url = $"{_baseUrl}/api/Equipment/{equipmentId}"; - var resp = await _http.GetAsync(url).ConfigureAwait(false); - if (!resp.IsSuccessStatusCode) return new List(); - var json = await resp.Content.ReadAsStringAsync().ConfigureAwait(false); - var serializer = new JavaScriptSerializer(); - var root = serializer.DeserializeObject(json) as Dictionary; - var results = new List(); - if (root != null) - { - object dval; - if (!TryGetCI(root, new[] { "Drawings", "drawings" }, out dval)) return results; - if (dval is System.Collections.IEnumerable arr && !(dval is string)) - { - foreach (var item in arr) - { - var d = item as Dictionary; - if (d == null) continue; - var summary = new ApiDrawingSummary(); - object v; - if (TryGetCI(d, new[] { "ID", "id" }, out v)) summary.ID = ToInt(v); - if (TryGetCI(d, new[] { "DrawingNumber", "drawingNumber" }, out v)) summary.DrawingNumber = v?.ToString(); - if (TryGetCI(d, new[] { "Description", "description" }, out v)) summary.Description = v?.ToString(); - results.Add(summary); - } - } - } - return results; - } - - private static bool TryGetCI(Dictionary dict, IEnumerable keys, out object value) - { - foreach (var k in keys) - { - if (dict.ContainsKey(k)) { value = dict[k]; return true; } - foreach (var dk in dict.Keys) - { - if (string.Equals(dk, k, StringComparison.OrdinalIgnoreCase)) { value = dict[dk]; return true; } - } - } - value = null; return false; - } - - private static int ToInt(object v) - { - if (v == null) return 0; - if (v is int i) return i; - if (v is long l) return (int)l; - if (v is double d) return (int)d; - int parsed; if (int.TryParse(v.ToString(), out parsed)) return parsed; return 0; - } - - private static double? ToDouble(object v) - { - if (v == null) return null; - if (v is double d) return d; - if (v is int i) return (double)i; - if (v is long l) return (double)l; - if (v is float f) return (double)f; - double parsed; if (double.TryParse(v.ToString(), out parsed)) return parsed; - return null; - } - } -} diff --git a/ExportDXF/Services/DrawingExporter.cs b/ExportDXF/Services/DrawingExporter.cs index bd3aed6..4e5ccc4 100644 --- a/ExportDXF/Services/DrawingExporter.cs +++ b/ExportDXF/Services/DrawingExporter.cs @@ -1,7 +1,7 @@ -using SolidWorks.Interop.sldworks; +using ExportDXF.Models; +using SolidWorks.Interop.sldworks; using SolidWorks.Interop.swconst; using System; -using System.Drawing; using System.IO; namespace ExportDXF.Services @@ -57,7 +57,7 @@ namespace ExportDXF.Services (int)swExportDataSheetsToExport_e.swExportData_ExportAllSheets, drawing); - context.ProgressCallback?.Invoke($"Exporting drawing to PDF: \"{pdfFileName}\"", null); + context.ProgressCallback?.Invoke("Exporting drawing to PDF", LogLevel.Info, pdfFileName); int errors = 0; int warnings = 0; @@ -73,26 +73,26 @@ namespace ExportDXF.Services if (success && errors == 0) { - context.ProgressCallback?.Invoke($"Saved drawing to PDF: \"{pdfFileName}\"", Color.Green); + context.ProgressCallback?.Invoke("Saved drawing to PDF", LogLevel.Info, pdfFileName); } else if (success && warnings > 0) { context.ProgressCallback?.Invoke( $"PDF export completed with warnings: {warnings}", - Color.DarkBlue); + LogLevel.Warning, pdfFileName); } else { context.ProgressCallback?.Invoke( $"PDF export failed. Errors: {errors}, Warnings: {warnings}", - Color.Red); + LogLevel.Error, pdfFileName); throw new InvalidOperationException($"PDF export failed with {errors} errors and {warnings} warnings."); } } catch (Exception ex) { var errorMessage = $"Failed to export PDF: {ex.Message}"; - context.ProgressCallback?.Invoke(errorMessage, Color.Red); + context.ProgressCallback?.Invoke(errorMessage, LogLevel.Error, null); throw new InvalidOperationException(errorMessage, ex); } } diff --git a/ExportDXF/Services/DxfExportService.cs b/ExportDXF/Services/DxfExportService.cs index 409f342..77e54a5 100644 --- a/ExportDXF/Services/DxfExportService.cs +++ b/ExportDXF/Services/DxfExportService.cs @@ -1,17 +1,12 @@ +using ExportDXF.Data; using ExportDXF.Extensions; using ExportDXF.ItemExtractors; using ExportDXF.Models; using ExportDXF; using SolidWorks.Interop.sldworks; -using SolidWorks.Interop.swconst; using System; using System.Collections.Generic; -using System.Linq; -using System.Drawing; using System.IO; -using System.Windows.Forms; -using Environment = System.Environment; -using System.IO.Compression; namespace ExportDXF.Services { @@ -33,20 +28,23 @@ namespace ExportDXF.Services private readonly IBomExtractor _bomExtractor; private readonly IPartExporter _partExporter; private readonly IDrawingExporter _drawingExporter; - private readonly ICutFabApiClient _apiClient; + private readonly IFileExportService _fileExportService; + private readonly Func _dbContextFactory; public DxfExportService( ISolidWorksService solidWorksService, IBomExtractor bomExtractor, IPartExporter partExporter, IDrawingExporter drawingExporter, - ICutFabApiClient apiClient) + IFileExportService fileExportService, + Func dbContextFactory = null) { _solidWorksService = solidWorksService ?? throw new ArgumentNullException(nameof(solidWorksService)); _bomExtractor = bomExtractor ?? throw new ArgumentNullException(nameof(bomExtractor)); _partExporter = partExporter ?? throw new ArgumentNullException(nameof(partExporter)); _drawingExporter = drawingExporter ?? throw new ArgumentNullException(nameof(drawingExporter)); - _apiClient = apiClient ?? throw new ArgumentNullException(nameof(apiClient)); + _fileExportService = fileExportService ?? throw new ArgumentNullException(nameof(fileExportService)); + _dbContextFactory = dbContextFactory ?? (() => new ExportDxfDbContext()); } /// @@ -81,7 +79,7 @@ namespace ExportDXF.Services break; default: - LogProgress(context, "Unknown document type.", Color.Red); + LogProgress(context, "Unknown document type.", LogLevel.Error); break; } } @@ -91,7 +89,7 @@ namespace ExportDXF.Services _solidWorksService.EnableUserControl(true); var duration = DateTime.Now - startTime; - LogProgress(context, $"Run time: {duration.ToReadableFormat()}", null); + LogProgress(context, $"Run time: {duration.ToReadableFormat()}"); } } @@ -99,28 +97,28 @@ namespace ExportDXF.Services private void ExportPart(ExportContext context) { - LogProgress(context, "Active document is a Part", null); + LogProgress(context, "Active document is a Part"); var part = context.ActiveDocument.NativeDocument as PartDoc; if (part == null) { - LogProgress(context, "Failed to get part document.", Color.Red); + LogProgress(context, "Failed to get part document.", LogLevel.Error); return; } - var tempDir = CreateTempWorkDir(); - _partExporter.ExportSinglePart(part, tempDir, context); + // Export directly to the output folder + _partExporter.ExportSinglePart(part, _fileExportService.OutputFolder, context); } private void ExportAssembly(ExportContext context) { - LogProgress(context, "Active document is an Assembly", null); - LogProgress(context, "Fetching components...", null); + LogProgress(context, "Active document is an Assembly"); + LogProgress(context, "Fetching components..."); var assembly = context.ActiveDocument.NativeDocument as AssemblyDoc; if (assembly == null) { - LogProgress(context, "Failed to get assembly document.", Color.Red); + LogProgress(context, "Failed to get assembly document.", LogLevel.Error); return; } @@ -128,25 +126,25 @@ namespace ExportDXF.Services if (items == null || items.Count == 0) { - LogProgress(context, "No items found in assembly.", Color.DarkBlue); + LogProgress(context, "No items found in assembly.", LogLevel.Warning); return; } - LogProgress(context, $"Found {items.Count} item(s).", null); + LogProgress(context, $"Found {items.Count} item(s)."); - var tempDir = CreateTempWorkDir(); - ExportItems(items, tempDir, context, drawingId: null); + // Export directly to the output folder + ExportItems(items, _fileExportService.OutputFolder, context); } private void ExportDrawing(ExportContext context) { - LogProgress(context, "Active document is a Drawing", null); - LogProgress(context, "Finding BOM tables...", null); + LogProgress(context, "Active document is a Drawing"); + LogProgress(context, "Finding BOM tables..."); var drawing = context.ActiveDocument.NativeDocument as DrawingDoc; if (drawing == null) { - LogProgress(context, "Failed to get drawing document.", Color.Red); + LogProgress(context, "Failed to get drawing document.", LogLevel.Error); return; } @@ -154,126 +152,61 @@ namespace ExportDXF.Services if (items == null || items.Count == 0) { - LogProgress(context, "Error: Bill of materials not found.", Color.Red); + LogProgress(context, "Error: Bill of materials not found.", LogLevel.Error); return; } - LogProgress(context, $"Found {items.Count} component(s)", null); + LogProgress(context, $"Found {items.Count} component(s)"); - var tempDir = CreateTempWorkDir(); - - // Determine drawing number + // Determine drawing number for file naming var drawingNumber = ParseDrawingNumber(context); - if (string.IsNullOrWhiteSpace(drawingNumber)) + + // Export drawing to PDF + var tempDir = CreateTempWorkDir(); + _drawingExporter.ExportToPdf(drawing, tempDir, context); + + // Copy PDF to output folder + try { - LogProgress(context, "Warning: Could not determine drawing number for API upload.", Color.DarkBlue); + var pdfs = Directory.GetFiles(tempDir, "*.pdf"); + if (pdfs.Length > 0) + { + var savedPath = _fileExportService.SavePdfFile(pdfs[0], drawingNumber); + LogProgress(context, $"Saved PDF: {Path.GetFileName(savedPath)}", LogLevel.Info); + } + } + catch (Exception ex) + { + LogProgress(context, $"PDF save error: {ex.Message}", LogLevel.Error); } - // Resolve drawing ID if possible - int? drawingId = null; - if (!string.IsNullOrWhiteSpace(drawingNumber)) + // Create export record in database + ExportRecord exportRecord = null; + try { - drawingId = _apiClient.ResolveDrawingIdAsync(drawingNumber).GetAwaiter().GetResult(); - // Fallback: if resolve endpoint not available or failed, search equipment details - if (drawingId == null && context.EquipmentId.HasValue) + using (var db = _dbContextFactory()) { - try + db.Database.EnsureCreated(); + exportRecord = new ExportRecord { - var drawings = _apiClient.GetDrawingsForEquipmentAsync(context.EquipmentId.Value).GetAwaiter().GetResult(); - if (drawings != null) - { - // Match by exact DrawingNumber (case-insensitive, trimmed) - var match = drawings.FirstOrDefault(d => string.Equals(d.DrawingNumber?.Trim(), drawingNumber.Trim(), StringComparison.OrdinalIgnoreCase)); - if (match != null) drawingId = match.ID; - } - } - catch { } + DrawingNumber = drawingNumber ?? context.ActiveDocument.Title, + SourceFilePath = context.ActiveDocument.FilePath, + OutputFolder = _fileExportService.OutputFolder, + ExportedAt = DateTime.Now, + ExportedBy = System.Environment.UserName + }; + db.ExportRecords.Add(exportRecord); + db.SaveChanges(); + LogProgress(context, $"Created export record (ID: {exportRecord.Id})", LogLevel.Info); } - if (drawingId == null) - { - // If equipment is provided, create the drawing on the API - if (context.EquipmentId.HasValue) - { - var create = _apiClient.CreateDrawingWithInfoAsync(context.EquipmentId.Value, drawingNumber).GetAwaiter().GetResult(); - if (create != null && create.Success && create.Data.HasValue) - { - drawingId = create.Data; - LogProgress(context, "Created drawing '" + drawingNumber + "' (ID " + drawingId + ") for equipment " + context.EquipmentId, Color.Green); - } - else - { - var code = create != null ? create.StatusCode.ToString() : "?"; - var err = create != null ? (create.Error ?? create.RawBody) : null; - if (!string.IsNullOrWhiteSpace(err) && err.Length > 180) err = err.Substring(0, 180) + "..."; - LogProgress(context, "Warning: Could not create drawing '" + drawingNumber + "' on API (status " + code + "). " + (err ?? string.Empty), Color.DarkBlue); - } - } - else - { - LogProgress(context, $"Warning: Drawing '{drawingNumber}' not found in API; uploads will be skipped.", Color.DarkBlue); - } - } - - // Export drawing to PDF first - _drawingExporter.ExportToPdf(drawing, tempDir, context); - - // Upload PDF if we have a drawing number - try - { - if (!string.IsNullOrWhiteSpace(drawingNumber)) - { - var pdfs = Directory.GetFiles(tempDir, "*.pdf"); - var pdfName = pdfs.Length > 0 ? pdfs[0] : null; - if (pdfName != null) - { - var uploadedBy = Environment.UserName; - var ok = _apiClient.UploadDrawingPdfAsync(drawingNumber, pdfName, uploadedBy, null).GetAwaiter().GetResult(); - LogProgress(context, ok ? $"Uploaded PDF for '{drawingNumber}'" : $"Failed to upload PDF for '{drawingNumber}'", ok ? Color.Green : Color.Red); - } - } - } - catch (Exception ex) - { - LogProgress(context, $"PDF upload error: {ex.Message}", Color.Red); - } - - // If we still don't have an ID, resolve again after PDF upload (server may create on upload) - if (!drawingId.HasValue && !string.IsNullOrWhiteSpace(drawingNumber)) - { - var resolved = _apiClient.ResolveDrawingIdAsync(drawingNumber).GetAwaiter().GetResult(); - if (!resolved.HasValue && context.EquipmentId.HasValue) - { - try - { - var drawings = _apiClient.GetDrawingsForEquipmentAsync(context.EquipmentId.Value).GetAwaiter().GetResult(); - if (drawings != null) - { - var match = drawings.FirstOrDefault(d => string.Equals(d.DrawingNumber?.Trim(), drawingNumber.Trim(), StringComparison.OrdinalIgnoreCase)); - if (match != null) resolved = match.ID; - } - } - catch { } - } - if (resolved.HasValue) - { - drawingId = resolved; - LogProgress(context, $"Resolved drawing ID after PDF upload: {drawingId}", Color.Green); - } - } - - // Then export parts to DXF and upload per-file - ExportItems(items, tempDir, context, drawingId); - - // Attempt to auto-link templates at the end - try - { - if (drawingId.HasValue) - { - _apiClient.AutoLinkTemplatesAsync(drawingId.Value).GetAwaiter().GetResult(); - } - } - catch { } } + catch (Exception ex) + { + LogProgress(context, $"Database error creating export record: {ex.Message}", LogLevel.Error); + } + + // Export parts to DXF (directly to output folder) and save BOM items + ExportItems(items, _fileExportService.OutputFolder, context, exportRecord?.Id); } #endregion @@ -293,7 +226,7 @@ namespace ExportDXF.Services // Set up drawing template path context.TemplateDrawing = null; - LogProgress(context, "Export context initialized", null); + LogProgress(context, "Export context initialized"); } private void CleanupExportContext(ExportContext context) @@ -305,7 +238,7 @@ namespace ExportDXF.Services } catch (Exception ex) { - LogProgress(context, $"Warning: Failed to cleanup template drawing: {ex.Message}", Color.DarkBlue); + LogProgress(context, $"Warning: Failed to cleanup template drawing: {ex.Message}", LogLevel.Warning); // Don't throw - this is cleanup code } } @@ -327,23 +260,22 @@ namespace ExportDXF.Services } catch (Exception ex) { - LogProgress(context, $"Failed to extract items from assembly: {ex.Message}", Color.Red); + LogProgress(context, $"Failed to extract items from assembly: {ex.Message}", LogLevel.Error); return new List(); } } - private void ExportItems(List items, string saveDirectory, ExportContext context, int? drawingId) + private void ExportItems(List items, string saveDirectory, ExportContext context, int? exportRecordId = null) { - LogProgress(context, "", null); - int successCount = 0; int failureCount = 0; + int sortOrder = 0; foreach (var item in items) { if (context.CancellationToken.IsCancellationRequested) { - LogProgress(context, "Export canceled by user.", Color.DarkBlue); + LogProgress(context, "Export canceled by user.", LogLevel.Warning); return; } @@ -352,54 +284,49 @@ namespace ExportDXF.Services // PartExporter will handle template drawing creation through context _partExporter.ExportItem(item, saveDirectory, context); - // Always create BOM item first if we have a drawing - if (drawingId.HasValue) - { - var dto = new - { - DrawingID = drawingId.Value, - ItemNo = item.ItemNo, - PartNo = !string.IsNullOrEmpty(item.FileName) ? item.FileName : item.PartName, - Qty = (int?)item.Quantity, - Description = string.IsNullOrWhiteSpace(item.Description) ? null : item.Description, - PartName = string.IsNullOrWhiteSpace(item.PartName) ? null : item.PartName, - ConfigurationName = string.IsNullOrWhiteSpace(item.Configuration) ? null : item.Configuration, - Material = string.IsNullOrWhiteSpace(item.Material) ? null : item.Material, - SortOrder = 0, - CutTemplateID = (int?)null, - FormProgramID = (int?)null - }; - var bomId = _apiClient.CreateBomItemAsync(dto).GetAwaiter().GetResult(); - LogProgress(context, bomId.HasValue ? $"Created BOM item for {item.ItemNo ?? item.PartName}" : $"Failed to create BOM item for {item.ItemNo ?? item.PartName}", bomId.HasValue ? Color.Green : Color.Red); - } - if (!string.IsNullOrEmpty(item.FileName)) { successCount++; + LogProgress(context, $"Exported: {item.FileName}.dxf", LogLevel.Info); - // If we know the drawing, upload DXF - if (drawingId.HasValue) + // Create BOM item + var dxfPath = Path.Combine(saveDirectory, item.FileName + ".dxf"); + var bomItem = new BomItem { - var dxfPath = Path.Combine(saveDirectory, item.FileName + ".dxf"); - if (File.Exists(dxfPath)) + ExportRecordId = exportRecordId ?? 0, + ItemNo = item.ItemNo ?? "", + PartNo = item.FileName ?? item.PartName ?? "", + SortOrder = sortOrder++, + Qty = item.Quantity, + TotalQty = item.Quantity, + Description = item.Description ?? "", + PartName = item.PartName ?? "", + ConfigurationName = item.Configuration ?? "", + Material = item.Material ?? "", + Thickness = item.Thickness > 0 ? item.Thickness : null, + KFactor = item.KFactor > 0 ? item.KFactor : null, + DefaultBendRadius = item.BendRadius > 0 ? item.BendRadius : null, + DxfFilePath = dxfPath + }; + + // Add to UI + context.BomItemCallback?.Invoke(bomItem); + + // Save BOM item to database if we have an export record + if (exportRecordId.HasValue) + { + try { - // Zip just this file - string zipPath = CreateZipWithSingleFile(dxfPath); - try + using (var db = _dbContextFactory()) { - // Pass thickness, kfactor, default bend radius and material from the item - double? thickness = item.Thickness > 0 ? item.Thickness : (double?)null; - double? kfactor = item.KFactor > 0 ? item.KFactor : (double?)null; - double? defaultBendRadius = item.BendRadius > 0 ? item.BendRadius : (double?)null; - string material = string.IsNullOrWhiteSpace(item.Material) ? null : item.Material; - var okZip = _apiClient.UploadDxfZipAsync(drawingId.Value, zipPath, thickness, kfactor, defaultBendRadius, material).GetAwaiter().GetResult(); - LogProgress(context, okZip ? $"Uploaded DXF: {Path.GetFileName(dxfPath)}" : $"Failed to upload DXF: {Path.GetFileName(dxfPath)}", okZip ? Color.Green : Color.Red); - } - finally - { - try { if (File.Exists(zipPath)) File.Delete(zipPath); } catch { } + db.BomItems.Add(bomItem); + db.SaveChanges(); } } + catch (Exception dbEx) + { + LogProgress(context, $"Database error saving BOM item: {dbEx.Message}", LogLevel.Error); + } } } else @@ -409,20 +336,23 @@ namespace ExportDXF.Services } catch (Exception ex) { - LogProgress(context, $"Error exporting item {item.ItemNo}: {ex.Message}", Color.Red); + LogProgress(context, $"Error exporting item {item.ItemNo}: {ex.Message}", LogLevel.Error); failureCount++; } - - LogProgress(context, "", null); } LogProgress(context, $"Export complete: {successCount} succeeded, {failureCount} failed", - failureCount > 0 ? Color.DarkBlue : Color.Green); + failureCount > 0 ? LogLevel.Warning : LogLevel.Info); + + if (exportRecordId.HasValue) + { + LogProgress(context, $"BOM items saved to database (ExportRecord ID: {exportRecordId.Value})", LogLevel.Info); + } } #endregion - #region Temp + Upload Helpers + #region Helper Methods private string CreateTempWorkDir() { @@ -444,21 +374,6 @@ namespace ExportDXF.Services return info != null ? ($"{info.EquipmentNo} {info.DrawingNo}") : null; } - private string CreateZipWithSingleFile(string filePath) - { - var zipPath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath) + ".zip"); - if (File.Exists(zipPath)) File.Delete(zipPath); - using (var zip = System.IO.Compression.ZipFile.Open(zipPath, System.IO.Compression.ZipArchiveMode.Create)) - { - zip.CreateEntryFromFile(filePath, Path.GetFileName(filePath)); - } - return zipPath; - } - - #endregion - - #region Helper Methods - private void ValidateContext(ExportContext context) { if (context.ActiveDocument == null) @@ -468,15 +383,11 @@ namespace ExportDXF.Services throw new ArgumentException("ProgressCallback cannot be null.", nameof(context)); } - private void LogProgress(ExportContext context, string message, Color? color) + private void LogProgress(ExportContext context, string message, LogLevel level = LogLevel.Info, string file = null) { - context.ProgressCallback?.Invoke(message, color); + context.ProgressCallback?.Invoke(message, level, file); } - - #endregion } } - - diff --git a/ExportDXF/Services/PartExporter.cs b/ExportDXF/Services/PartExporter.cs index 9c4221e..405bdf5 100644 --- a/ExportDXF/Services/PartExporter.cs +++ b/ExportDXF/Services/PartExporter.cs @@ -1,9 +1,9 @@ using ExportDXF.Extensions; +using ExportDXF.Models; using ExportDXF.Utilities; using SolidWorks.Interop.sldworks; using SolidWorks.Interop.swconst; using System; -using System.Drawing; using System.IO; namespace ExportDXF.Services @@ -75,7 +75,7 @@ namespace ExportDXF.Services if (item?.Component == null) { - context.ProgressCallback?.Invoke($"Item {item?.ItemNo} - skipped, no component", Color.Yellow); + context.ProgressCallback?.Invoke("Skipped, no component", LogLevel.Warning, $"Item {item?.ItemNo}"); return; } @@ -88,7 +88,7 @@ namespace ExportDXF.Services if (part == null) { - context.ProgressCallback?.Invoke($"{item.ItemNo} - skipped, not a part document", null); + context.ProgressCallback?.Invoke("Skipped, not a part document", LogLevel.Info, item.PartName); return; } @@ -150,9 +150,11 @@ namespace ExportDXF.Services { var model = part as ModelDoc2; + var partTitle = model.GetTitle(); + if (!model.IsSheetMetal()) { - context.ProgressCallback?.Invoke($"{model.GetTitle()} - skipped, not sheet metal", null); + context.ProgressCallback?.Invoke("Skipped, not sheet metal", LogLevel.Info, partTitle); return false; } @@ -164,13 +166,13 @@ namespace ExportDXF.Services var modelName = Path.GetFileNameWithoutExtension(model.GetPathName()); sheet.SetName(modelName); - context.ProgressCallback?.Invoke($"{model.GetTitle()} - Creating flat pattern", null); + context.ProgressCallback?.Invoke("Creating flat pattern", LogLevel.Info, partTitle); var view = CreateFlatPatternView(templateDrawing, model, configName); if (view == null) { - context.ProgressCallback?.Invoke($"{model.GetTitle()} - Failed to create flat pattern", Color.Red); + context.ProgressCallback?.Invoke("Failed to create flat pattern", LogLevel.Error, partTitle); return false; } @@ -178,7 +180,7 @@ namespace ExportDXF.Services if (context.ViewFlipDecider?.ShouldFlip(view) == true) { - context.ProgressCallback?.Invoke($"{model.GetTitle()} - Flipped view", Color.Blue); + context.ProgressCallback?.Invoke("Flipped view", LogLevel.Info, partTitle); view.FlipView = true; } @@ -187,7 +189,7 @@ namespace ExportDXF.Services AddEtchLines(savePath); - context.ProgressCallback?.Invoke($"{model.GetTitle()} - Saved to \"{savePath}\"", Color.Green); + context.ProgressCallback?.Invoke($"Saved to \"{savePath}\"", LogLevel.Info, partTitle); DeleteView(drawingModel, view); @@ -195,7 +197,7 @@ namespace ExportDXF.Services } catch (Exception ex) { - context.ProgressCallback?.Invoke($"Export failed: {ex.Message}", Color.Red); + context.ProgressCallback?.Invoke($"Export failed: {ex.Message}", LogLevel.Error, null); return false; } } @@ -232,7 +234,8 @@ namespace ExportDXF.Services if (ViewHelper.HasSupressedBends(view)) { - context.ProgressCallback?.Invoke("A bend is suppressed, please check flat pattern", Color.Red); + var title = partModel.GetTitle(); + context.ProgressCallback?.Invoke("A bend is suppressed, please check flat pattern", LogLevel.Error, title); } if (ViewHelper.HideModelSketches(view)) @@ -297,14 +300,16 @@ namespace ExportDXF.Services if (desc.Contains("laser")) { context.ProgressCallback?.Invoke( - $"Failed to export item #{item.ItemNo} but description says it is laser cut.", - Color.Red); + "Export failed but description says it is laser cut", + LogLevel.Error, + item.PartName); } else if (desc.Contains("plasma")) { context.ProgressCallback?.Invoke( - $"Failed to export item #{item.ItemNo} but description says it is plasma cut.", - Color.Red); + "Export failed but description says it is plasma cut", + LogLevel.Error, + item.PartName); } } } diff --git a/ExportDXF/app.config b/ExportDXF/app.config index 8bfc0ef..f67a830 100644 --- a/ExportDXF/app.config +++ b/ExportDXF/app.config @@ -5,7 +5,11 @@ - - + + + +