672 lines
No EOL
18 KiB
C#
672 lines
No EOL
18 KiB
C#
/*
|
|
Copyright (c) 2018, Kevin Pope, John Lewin
|
|
All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions are met:
|
|
|
|
1. Redistributions of source code must retain the above copyright notice, this
|
|
list of conditions and the following disclaimer.
|
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
this list of conditions and the following disclaimer in the documentation
|
|
and/or other materials provided with the distribution.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
The views and conclusions contained in the software and documentation are those
|
|
of the authors and should not be interpreted as representing official policies,
|
|
either expressed or implied, of the FreeBSD Project.
|
|
*/
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text.RegularExpressions;
|
|
using CsvHelper;
|
|
using MatterHackers.Agg;
|
|
using MatterHackers.Agg.Platform;
|
|
using MatterHackers.Agg.UI;
|
|
using MatterHackers.Localizations;
|
|
using MatterHackers.MatterControl.CustomWidgets;
|
|
using MatterHackers.MatterControl.DataStorage;
|
|
using MatterHackers.MatterControl.PartPreviewWindow;
|
|
using MatterHackers.MatterControl.PrintQueue;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace MatterHackers.MatterControl.PrintHistory
|
|
{
|
|
public class PrintHistoryListItem : ListViewItemBase
|
|
{
|
|
private string[] qualityNames = new string[]
|
|
{
|
|
"Failed".Localize(),
|
|
"Terrible".Localize(),
|
|
"Bad".Localize(),
|
|
"Good".Localize(),
|
|
"Great".Localize(),
|
|
};
|
|
|
|
public PrintHistoryListItem(ListViewItem listViewItem, int thumbWidth, int thumbHeight, PrintTask printTask, ThemeConfig theme)
|
|
: base(listViewItem, thumbWidth, thumbHeight, theme)
|
|
{
|
|
this.HAnchor = HAnchor.Stretch;
|
|
this.VAnchor = VAnchor.Fit;
|
|
this.Padding = new BorderDouble(0);
|
|
this.Margin = new BorderDouble(6, 0, 6, 6);
|
|
this.printTask = printTask;
|
|
|
|
var mainContainer = new GuiWidget
|
|
{
|
|
HAnchor = HAnchor.Stretch,
|
|
VAnchor = VAnchor.Fit
|
|
};
|
|
{
|
|
indicator = new GuiWidget
|
|
{
|
|
VAnchor = VAnchor.Stretch,
|
|
Width = 15
|
|
};
|
|
|
|
SetIndicatorColor();
|
|
|
|
var middleColumn = new FlowLayoutWidget(FlowDirection.TopToBottom)
|
|
{
|
|
HAnchor = HAnchor.Stretch,
|
|
Padding = new BorderDouble(6, 3)
|
|
};
|
|
|
|
var labelContainer = new FlowLayoutWidget
|
|
{
|
|
HAnchor = HAnchor.Stretch
|
|
};
|
|
|
|
printInfoWidget = new TextWidget(GetPrintInfo(), pointSize: 15)
|
|
{
|
|
TextColor = Color.Black,
|
|
AutoExpandBoundsToText = true,
|
|
};
|
|
|
|
labelContainer.AddChild(printInfoWidget);
|
|
|
|
middleColumn.AddChild(labelContainer);
|
|
|
|
var timeTextColor = new Color(34, 34, 34);
|
|
|
|
var detailsRow = new FlowLayoutWidget
|
|
{
|
|
Margin = new BorderDouble(0),
|
|
HAnchor = HAnchor.Stretch
|
|
};
|
|
{
|
|
var timeLabel = new TextWidget("Time".Localize().ToUpper() + ": ", pointSize: 8)
|
|
{
|
|
TextColor = timeTextColor
|
|
};
|
|
|
|
TextWidget timeIndicator;
|
|
int minutes = printTask.PrintTimeMinutes;
|
|
if (minutes < 0)
|
|
{
|
|
timeIndicator = new TextWidget("Unknown".Localize());
|
|
}
|
|
else if (minutes > 60)
|
|
{
|
|
timeIndicator = new TextWidget("{0}hrs {1}min".FormatWith(printTask.PrintTimeMinutes / 60, printTask.PrintTimeMinutes % 60), pointSize: 12);
|
|
}
|
|
else
|
|
{
|
|
timeIndicator = new TextWidget(string.Format("{0}min", printTask.PrintTimeMinutes), pointSize: 12);
|
|
}
|
|
|
|
if (printTask.PercentDone > 0)
|
|
{
|
|
timeIndicator.AutoExpandBoundsToText = true;
|
|
timeIndicator.Text += $" ({printTask.PercentDone:0.0}%)";
|
|
|
|
if (printTask.RecoveryCount > 0)
|
|
{
|
|
if (printTask.RecoveryCount == 1)
|
|
{
|
|
timeIndicator.Text += " - " + "recovered once".Localize();
|
|
}
|
|
else
|
|
{
|
|
timeIndicator.Text += " - " + "recovered {0} times".FormatWith(printTask.RecoveryCount);
|
|
}
|
|
}
|
|
}
|
|
|
|
timeIndicator.Margin = new BorderDouble(right: 6);
|
|
timeIndicator.TextColor = timeTextColor;
|
|
|
|
detailsRow.AddChild(timeLabel);
|
|
detailsRow.AddChild(timeIndicator);
|
|
detailsRow.AddChild(new HorizontalSpacer());
|
|
middleColumn.AddChild(detailsRow);
|
|
}
|
|
|
|
var primaryContainer = new GuiWidget
|
|
{
|
|
HAnchor = HAnchor.Stretch,
|
|
VAnchor = VAnchor.Fit
|
|
};
|
|
|
|
var primaryFlow = new FlowLayoutWidget(FlowDirection.LeftToRight)
|
|
{
|
|
HAnchor = HAnchor.Stretch,
|
|
VAnchor = VAnchor.Fit
|
|
};
|
|
|
|
primaryFlow.AddChild(indicator);
|
|
primaryFlow.AddChild(middleColumn);
|
|
|
|
primaryContainer.AddChild(primaryFlow);
|
|
|
|
AddTimeStamp(printTask, timeTextColor, primaryFlow);
|
|
|
|
mainContainer.AddChild(primaryContainer);
|
|
|
|
this.AddChild(mainContainer);
|
|
}
|
|
|
|
this.BackgroundColor = new Color(255, 255, 255, 255);
|
|
}
|
|
|
|
private void SetIndicatorColor()
|
|
{
|
|
if (printTask.PrintComplete)
|
|
{
|
|
if (printTask.QualityWasSet && printTask.PrintQuality == 0)
|
|
{
|
|
indicator.BackgroundColor = new Color(252, 38, 51, 180);
|
|
}
|
|
else
|
|
{
|
|
indicator.BackgroundColor = new Color(38, 147, 51, 180);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
indicator.BackgroundColor = new Color(252, 209, 22, 180);
|
|
}
|
|
}
|
|
|
|
private string GetPrintInfo()
|
|
{
|
|
TextInfo textInfo = new CultureInfo("en-US", false).TextInfo;
|
|
|
|
var labelName = "";
|
|
if (!string.IsNullOrEmpty(printTask.PrinterName))
|
|
{
|
|
labelName = printTask.PrinterName + ":\n" + labelName;
|
|
}
|
|
|
|
labelName += textInfo.ToTitleCase(printTask.PrintName).Replace('_', ' ');
|
|
|
|
string groupNames = GetItemNamesFromMcx(printTask.PrintName);
|
|
if (!string.IsNullOrEmpty(groupNames))
|
|
{
|
|
labelName += "\n" + groupNames;
|
|
}
|
|
|
|
if (printTask.QualityWasSet)
|
|
{
|
|
labelName += "\n" + "Print Quality".Localize() + ": " + qualityNames[printTask.PrintQuality];
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(printTask.Note))
|
|
{
|
|
labelName += "\n" + printTask.Note;
|
|
}
|
|
|
|
return labelName;
|
|
}
|
|
|
|
protected override void OnClick(MouseEventArgs mouseEvent)
|
|
{
|
|
if (mouseEvent.Button == MouseButtons.Right)
|
|
{
|
|
var theme = ApplicationController.Instance.MenuTheme;
|
|
var printTasks = PrintHistoryData.Instance.GetHistoryItems(1000);
|
|
|
|
var popupMenu = new PopupMenu(theme);
|
|
AddQualityMenu(popupMenu);
|
|
AddNotesMenu(popupMenu, printTasks);
|
|
|
|
popupMenu.CreateSeparator();
|
|
|
|
AddExportMenu(popupMenu, printTasks);
|
|
|
|
popupMenu.CreateSeparator();
|
|
|
|
AddClearHistorMenu(popupMenu, printTasks);
|
|
|
|
popupMenu.ShowMenu(this, mouseEvent);
|
|
}
|
|
|
|
base.OnClick(mouseEvent);
|
|
}
|
|
|
|
private void AddNotesMenu(PopupMenu popupMenu, IEnumerable<PrintTask> printTasks)
|
|
{
|
|
var addNotest = popupMenu.CreateMenuItem(string.IsNullOrEmpty(printTask.Note) ? "Add Note...".Localize() : "Edit Note...".Localize());
|
|
addNotest.Enabled = printTasks.Any();
|
|
addNotest.Click += (s, e) =>
|
|
{
|
|
DialogWindow.Show(
|
|
new InputBoxPage(
|
|
"Print History Note".Localize(),
|
|
"Note".Localize(),
|
|
printTask.Note == null ? "" : printTask.Note,
|
|
"Enter Note Here".Localize(),
|
|
string.IsNullOrEmpty(printTask.Note) ? "Add Note".Localize() : "Update".Localize(),
|
|
(newNote) =>
|
|
{
|
|
printTask.Note = newNote;
|
|
printTask.Commit();
|
|
popupMenu.Unfocus();
|
|
printInfoWidget.Text = GetPrintInfo();
|
|
})
|
|
{
|
|
AllowEmpty = true,
|
|
});
|
|
};
|
|
}
|
|
|
|
private void AddQualityMenu(PopupMenu popupMenu)
|
|
{
|
|
var theme = ApplicationController.Instance.MenuTheme;
|
|
|
|
var content = new FlowLayoutWidget()
|
|
{
|
|
HAnchor = HAnchor.Fit | HAnchor.Stretch
|
|
};
|
|
|
|
var textWidget = new TextWidget("Print Quality".Localize() + ":", pointSize: theme.DefaultFontSize, textColor: theme.TextColor)
|
|
{
|
|
// Padding = MenuPadding,
|
|
VAnchor = VAnchor.Center
|
|
};
|
|
content.AddChild(textWidget);
|
|
|
|
content.AddChild(new HorizontalSpacer());
|
|
|
|
var siblings = new List<GuiWidget>();
|
|
|
|
for (int i = 0; i < qualityNames.Length; i++)
|
|
{
|
|
var button = new RadioButton(new TextWidget(i.ToString(), pointSize: theme.DefaultFontSize, textColor: theme.TextColor))
|
|
{
|
|
Enabled = printTask.PrintComplete,
|
|
Checked = printTask.QualityWasSet && printTask.PrintQuality == i,
|
|
ToolTipText = qualityNames[i],
|
|
Margin = 0,
|
|
Padding = 5,
|
|
HAnchor = HAnchor.Fit,
|
|
VAnchor = VAnchor.Fit,
|
|
};
|
|
|
|
siblings.Add(button);
|
|
|
|
if (button.Checked && button.Enabled)
|
|
{
|
|
button.BackgroundColor = theme.AccentMimimalOverlay;
|
|
}
|
|
|
|
button.SiblingRadioButtonList = siblings;
|
|
|
|
content.AddChild(button);
|
|
|
|
button.Click += (s, e) =>
|
|
{
|
|
printTask.PrintQuality = siblings.IndexOf((GuiWidget)s);
|
|
printTask.QualityWasSet = true;
|
|
printTask.Commit();
|
|
popupMenu.Unfocus();
|
|
|
|
printInfoWidget.Text = GetPrintInfo();
|
|
SetIndicatorColor();
|
|
};
|
|
}
|
|
|
|
var menuItem = new PopupMenu.MenuItem(content, theme)
|
|
{
|
|
HAnchor = HAnchor.Fit | HAnchor.Stretch,
|
|
VAnchor = VAnchor.Fit,
|
|
HoverColor = Color.Transparent,
|
|
};
|
|
popupMenu.AddChild(menuItem);
|
|
}
|
|
|
|
private void AddClearHistorMenu(PopupMenu popupMenu, IEnumerable<PrintTask> printTasks)
|
|
{
|
|
var clearPrintHistory = popupMenu.CreateMenuItem("Clear History".Localize());
|
|
clearPrintHistory.Enabled = printTasks.Any();
|
|
clearPrintHistory.Click += (s, e) =>
|
|
{
|
|
// clear history
|
|
StyledMessageBox.ShowMessageBox(
|
|
(clearHistory) =>
|
|
{
|
|
if (clearHistory)
|
|
{
|
|
PrintHistoryData.Instance.ClearHistory();
|
|
}
|
|
},
|
|
"Are you sure you want to clear your print history?".Localize(),
|
|
"Clear History?".Localize(),
|
|
StyledMessageBox.MessageType.YES_NO,
|
|
"Clear History".Localize());
|
|
};
|
|
}
|
|
|
|
private void AddExportMenu(PopupMenu popupMenu, IEnumerable<PrintTask> printTasks)
|
|
{
|
|
var exportPrintHistory = popupMenu.CreateMenuItem("Export History".Localize() + "...");
|
|
exportPrintHistory.Enabled = printTasks.Any();
|
|
exportPrintHistory.Click += (s, e) =>
|
|
{
|
|
if (ApplicationController.Instance.IsMatterControlPro())
|
|
{
|
|
ExportToCsv(printTasks);
|
|
}
|
|
else // upsell MatterControl Pro
|
|
{
|
|
string text = "Exporting print history is a MatterControl Pro feature. Upgrade to Pro to unlock MatterControl Pro.".Localize();
|
|
WebCache.RetrieveText(
|
|
"https://matterhackers.github.io/MatterControl-Docs/ProContent/Unlock_Export_Print_History.md",
|
|
(markDown) =>
|
|
{
|
|
// push the new text into the widget
|
|
text = markDown;
|
|
});
|
|
|
|
StyledMessageBox.ShowMessageBox(text,
|
|
"Upgrade to Pro".Localize(),
|
|
StyledMessageBox.MessageType.OK,
|
|
useMarkdown: true,
|
|
width: 540,
|
|
height: 400);
|
|
}
|
|
};
|
|
}
|
|
|
|
public class RowData
|
|
{
|
|
public string Printer { get; set; }
|
|
|
|
public string QualitySettingsName { get; set; }
|
|
|
|
public string MaterialSettingsName { get; set; }
|
|
|
|
public string Name { get; set; }
|
|
|
|
public DateTime Start { get; set; }
|
|
|
|
public DateTime End { get; set; }
|
|
|
|
public int Minutes { get; set; }
|
|
|
|
public bool Compleated { get; set; }
|
|
|
|
public double RecoveryCount { get; set; }
|
|
|
|
public string ItemsPrinted { get; set; }
|
|
|
|
public string Notes { get; set; }
|
|
|
|
public int PrintQuality { get; set; }
|
|
}
|
|
|
|
private static void ExportToCsv(IEnumerable<PrintTask> printTasks)
|
|
{
|
|
// right click success or fail
|
|
// user settings that are different
|
|
var records = new List<RowData>();
|
|
|
|
// do the export
|
|
foreach (var printTask in printTasks)
|
|
{
|
|
string groupNames = PrintHistoryListItem.GetItemNamesFromMcx(printTask.PrintName);
|
|
|
|
records.Add(new RowData()
|
|
{
|
|
Printer = printTask.PrinterName,
|
|
Name = printTask.PrintName,
|
|
Start = printTask.PrintStart,
|
|
End = printTask.PrintEnd,
|
|
Compleated = printTask.PrintComplete,
|
|
PrintQuality = printTask.PrintQuality,
|
|
ItemsPrinted = groupNames,
|
|
Minutes = printTask.PrintTimeMinutes,
|
|
RecoveryCount = printTask.RecoveryCount,
|
|
QualitySettingsName = printTask.QualitySettingsName,
|
|
MaterialSettingsName = printTask.MaterialSettingsName,
|
|
Notes = printTask.Note,
|
|
});
|
|
}
|
|
|
|
AggContext.FileDialogs.SaveFileDialog(
|
|
new SaveFileDialogParams("MatterControl Printer Export|*.printer", title: "Export Printer Settings")
|
|
{
|
|
FileName = "Pinter Histor.csv",
|
|
Filter = "CSV Files|*.csv"
|
|
},
|
|
(saveParams) =>
|
|
{
|
|
try
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(saveParams.FileName))
|
|
{
|
|
using (var writer = new StreamWriter(saveParams.FileName))
|
|
{
|
|
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
|
|
{
|
|
csv.WriteRecords(records);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e2)
|
|
{
|
|
UiThread.RunOnIdle(() =>
|
|
{
|
|
StyledMessageBox.ShowMessageBox(e2.Message, "Couldn't save file".Localize());
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
public static string GetItemNamesFromMcx(string mcxFileName)
|
|
{
|
|
// add in the cache path
|
|
mcxFileName = Path.Combine(ApplicationDataStorage.Instance.PlatingDirectory, mcxFileName);
|
|
if (File.Exists(mcxFileName))
|
|
{
|
|
var names = JsonConvert.DeserializeObject<McxDocument.McxNode>(File.ReadAllText(mcxFileName)).AllNames();
|
|
var grouped = names.GroupBy(n => n)
|
|
.Select(g =>
|
|
{
|
|
if (g.Count() > 1)
|
|
{
|
|
return g.Key + " (" + g.Count() + ")";
|
|
}
|
|
else
|
|
{
|
|
return g.Key;
|
|
}
|
|
})
|
|
.OrderBy(n => n);
|
|
var groupNames = string.Join(", ", grouped);
|
|
return groupNames;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private void AddTimeStamp(PrintTask printTask, Color timeTextColor, FlowLayoutWidget primaryFlow)
|
|
{
|
|
var timestampColumn = new FlowLayoutWidget(FlowDirection.TopToBottom)
|
|
{
|
|
VAnchor = VAnchor.Stretch,
|
|
BackgroundColor = Color.LightGray,
|
|
Padding = new BorderDouble(6, 0)
|
|
};
|
|
|
|
var startTimeContainer = new FlowLayoutWidget
|
|
{
|
|
HAnchor = HAnchor.Stretch,
|
|
Padding = new BorderDouble(0, 3)
|
|
};
|
|
|
|
string startLabelFull = "{0}:".FormatWith("Start".Localize().ToUpper());
|
|
var startLabel = new TextWidget(startLabelFull, pointSize: 8)
|
|
{
|
|
TextColor = timeTextColor
|
|
};
|
|
|
|
string startTimeString = printTask.PrintStart.ToString("MMM d yyyy h:mm ") + printTask.PrintStart.ToString("tt").ToLower();
|
|
var startDate = new TextWidget(startTimeString, pointSize: 12)
|
|
{
|
|
TextColor = timeTextColor
|
|
};
|
|
|
|
startTimeContainer.AddChild(startLabel);
|
|
startTimeContainer.AddChild(new HorizontalSpacer());
|
|
startTimeContainer.AddChild(startDate);
|
|
|
|
var endTimeContainer = new FlowLayoutWidget
|
|
{
|
|
HAnchor = HAnchor.Stretch,
|
|
Padding = new BorderDouble(0, 3)
|
|
};
|
|
|
|
string endLabelFull = "{0}:".FormatWith("End".Localize().ToUpper());
|
|
var endLabel = new TextWidget(endLabelFull, pointSize: 8)
|
|
{
|
|
TextColor = timeTextColor
|
|
};
|
|
|
|
string endTimeString;
|
|
if (printTask.PrintEnd != DateTime.MinValue)
|
|
{
|
|
endTimeString = printTask.PrintEnd.ToString("MMM d yyyy h:mm ") + printTask.PrintEnd.ToString("tt").ToLower();
|
|
}
|
|
else
|
|
{
|
|
endTimeString = "Unknown".Localize();
|
|
}
|
|
|
|
var endDate = new TextWidget(endTimeString, pointSize: 12)
|
|
{
|
|
TextColor = timeTextColor
|
|
};
|
|
|
|
endTimeContainer.AddChild(endLabel);
|
|
endTimeContainer.AddChild(new HorizontalSpacer());
|
|
endTimeContainer.AddChild(endDate);
|
|
|
|
var horizontalLine = new HorizontalLine
|
|
{
|
|
BackgroundColor = Color.Gray
|
|
};
|
|
|
|
timestampColumn.AddChild(endTimeContainer);
|
|
timestampColumn.AddChild(horizontalLine);
|
|
timestampColumn.AddChild(startTimeContainer);
|
|
|
|
timestampColumn.HAnchor = HAnchor.Stretch;
|
|
timestampColumn.Padding = new BorderDouble(5, 0, 15, 0);
|
|
|
|
primaryFlow.AddChild(timestampColumn);
|
|
}
|
|
|
|
public void ShowCantFindFileMessage(PrintItemWrapper printItemWrapper)
|
|
{
|
|
itemToRemove = printItemWrapper;
|
|
UiThread.RunOnIdle(() =>
|
|
{
|
|
string maxLengthName = printItemWrapper.FileLocation;
|
|
int maxLength = 43;
|
|
if (maxLengthName.Length > maxLength)
|
|
{
|
|
string start = maxLengthName.Substring(0, 15) + "...";
|
|
int amountRemaining = maxLength - start.Length;
|
|
string end = maxLengthName.Substring(maxLengthName.Length - amountRemaining, amountRemaining);
|
|
maxLengthName = start + end;
|
|
}
|
|
|
|
string notFoundMessage = "Oops! Could not find this file".Localize() + ":";
|
|
string message = "{0}:\n'{1}'".FormatWith(notFoundMessage, maxLengthName);
|
|
string titleLabel = "Item not Found".Localize();
|
|
StyledMessageBox.ShowMessageBox(OnConfirmRemove, message, titleLabel, StyledMessageBox.MessageType.OK);
|
|
});
|
|
}
|
|
|
|
private PrintItemWrapper itemToRemove;
|
|
private PrintTask printTask;
|
|
private GuiWidget indicator;
|
|
private TextWidget printInfoWidget;
|
|
|
|
private void OnConfirmRemove(bool messageBoxResponse)
|
|
{
|
|
if (messageBoxResponse)
|
|
{
|
|
int index = QueueData.Instance.GetIndex(itemToRemove);
|
|
UiThread.RunOnIdle(() => QueueData.Instance.RemoveAt(index));
|
|
}
|
|
}
|
|
}
|
|
|
|
public static class McxDocument
|
|
{
|
|
public class McxNode
|
|
{
|
|
public List<McxNode> Children { get; set; }
|
|
|
|
public string Name { get; set; }
|
|
|
|
public bool Visible { get; set; }
|
|
|
|
public string MeshPath { get; set; }
|
|
|
|
private static Regex fileNameNumberMatch = new Regex("\\(\\d+\\)\\s*$", RegexOptions.Compiled);
|
|
|
|
public IEnumerable<string> AllNames()
|
|
{
|
|
if (Children?.Count > 0)
|
|
{
|
|
foreach (var child in Children)
|
|
{
|
|
foreach (var name in child.AllNames())
|
|
{
|
|
yield return name;
|
|
}
|
|
}
|
|
}
|
|
else if (!string.IsNullOrWhiteSpace(Name))
|
|
{
|
|
if (Name.Contains("("))
|
|
{
|
|
yield return fileNameNumberMatch.Replace(Name, "").Trim();
|
|
}
|
|
else
|
|
{
|
|
yield return Name;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |