12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357 |
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.ComponentModel;
- using System.Diagnostics;
- using System.IO;
- using System.Linq;
- using System.Reflection;
- using System.Text.RegularExpressions;
- using System.Threading.Tasks;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Data;
- using System.Windows.Input;
- using System.Windows.Media;
- using System.Xml;
- using Aitex.UI.RecipeEditor.Core;
- using Aitex.UI.RecipeEditor.View;
- using ExcelLibrary.SpreadSheet;
- using Microsoft.Win32;
- using Xceed.Wpf.DataGrid;
- namespace Aitex.UI.RecipeEditor
- {
- public class RecipeEditorControlViewModel : INotifyPropertyChanged
- {
- public List<Tuple<string, string, ObservableCollection<RecipeRow>, Guid>> UndoList { get; set; }
- public List<Tuple<string, string, ObservableCollection<RecipeRow>, Guid>> RedoList { get; set; }
- public bool IsUndoEnabled { get { return UndoList != null && UndoList.Count > 0; } }
- public bool IsRedoEnabled { get { return RedoList != null && RedoList.Count > 0; } }
- public ObservableCollection<RecipeRow> RecipeRows { get; set; }
- private ObservableCollection<RecipeRow> _previousRecipeRows { get; set; }
- private string _valueBeforeEditing { get; set; }
- private string _currentRecipeVariationName = string.Empty;
- private SmartCellData _currentEditingCellData { get; set; }
- public List<Tuple<int/*row no*/, int/*col no*/, string/*var name*/, string/*reason*/>> Errors { get; set; }
- public List<Tuple<string, string>> CreateRecipeList { get; set; }
- public List<Tuple<string, string>> OpenRecipeList { get; set; }
- public DataGridControl DataGridControl { get; set; }
- public int CurrentRunningStepNo { get; set; }
- public Visibility SingleAppElementVisibility { get; set; }
- public Visibility RecipeInfoTextVisibility { get; set; }
- public ICommand ShowDetailedErrInfoCommand { get; set; }
- public ICommand EditRecipeInfoCommand { get; set; }
- //public ICommand CellContentChangedCommand { get; set; }
- public ICommand RightClickCommand { get; set; }
- public ICommand OpenLocalRecipeCommand { get; set; }
- public ICommand ExpandGroupCommand { get; set; }
- public ICommand CollapseGroupCommand { get; set; }
- public ICommand SaveRecipeCommand { get; set; }
- public ICommand RecipeHelpDocCommand { get; set; }
- public ICommand RecipeExport2ExcelCommand { get; set; }
- public ICommand ToggleHideSameCommand { get; set; }
- public ICommand UndoCommand { get; set; }
- public ICommand RedoCommand { get; set; }
- public ICommand SmartCellEditorLoadedCommand { get; set; }
- public ICommand SmartCellEditorUnloadedCommand { get; set; }
- public RecipeHead RecipeHead { get; set; }
- public bool IsBusy { get; set; }
- public bool IsHideSameContent { get; set; }
- public string RecipeInfo { get; set; }
- public HashSet<string> MaskedTechNames { get; set; }
- public HashSet<string> MaskedCatalogNames { get; set; }
- public event EventHandler OnSaveRecipeFile;
- public event EventHandler OnLocalRecipeOpened;
- public event EventHandler OnLoadRecipeContent;
- public bool IsRecipeModified { get; set; }
- public string UserName { set; get; }
- //private List<Tuple<string, string, string>> SourceDilteInjectRestrictions { get; set; }
- private Dictionary<string, string> _preDefinedRecipeVars { get; set; }
- private List<Tuple<string/*varName*/, string/*check condition*/, string/*message*/>> _validationRules { get; set; }
- private List<string> _checkVariables { get; set; }
- private Dictionary<string, int> RowVarNameDic { get; set; }
- private Dictionary<int, List<SmartCellData>> _copiedColumnDatas = new Dictionary<int, List<SmartCellData>>();
- private Dictionary<string/*CatalogName*/, Dictionary<string/*GroupName*/, List<RecipeVariableDefine/*StepList*/>>> _recipeReadingFormat;
- private Dictionary<string/*ModuleName*/, List<string>/*each item's control name*/> _recipeSavingFormat;
- private string _currentRecipeFormatContent;
- public bool IsBarcodeEnabled
- {
- get; set;
- }
- public Visibility IsBarcodeVisibility
- {
- get
- {
- return IsBarcodeEnabled ? Visibility.Visible : Visibility.Hidden;
- }
- }
- private string _defaultEndPointValue { get; set; }
- /// <summary>
- /// class construction
- /// </summary>
- public RecipeEditorControlViewModel()
- {
- UndoList = new List<Tuple<string, string, ObservableCollection<RecipeRow>, Guid>>();
- RedoList = new List<Tuple<string, string, ObservableCollection<RecipeRow>, Guid>>();
- //if(SingleAppElementVisibility
- CreateRecipeList = new List<Tuple<string, string>>();
- OpenRecipeList = new List<Tuple<string, string>>();
- foreach (var item in GetDefinedRecipeVariations())
- {
- CreateRecipeList.Add(new Tuple<string, string>("配置:" + item, item));
- OpenRecipeList.Add(new Tuple<string, string>("转换为配置:" + item, item));
- }
- RecipeInfoTextVisibility = Visibility.Collapsed;
- SingleAppElementVisibility = Visibility.Collapsed;
- RightClickCommand = new DelegatedCommand((o) => true, (o) => RightClickAction());
- ExpandGroupCommand = new DelegatedCommand((o) => true, (o) => ExpandGroups());
- CollapseGroupCommand = new DelegatedCommand((o) => true, (o) => CollapseGroups());
- SaveRecipeCommand = new DelegatedCommand((o) => true, (o) => SaveRecipeFile());
- OpenLocalRecipeCommand = new DelegatedCommand((o) => true, (o) => OpenLocalRecipe());
- ShowDetailedErrInfoCommand = new DelegatedCommand((o) => true, (o) => ShowDetailedErrInformation());
- EditRecipeInfoCommand = new DelegatedCommand((o) => true, (o) => EditRecipeInformation());
- RecipeHelpDocCommand = new DelegatedCommand((o) => true, (o) => ShowHelpDocView());
- RecipeExport2ExcelCommand = new DelegatedCommand((o) => true, (o) => Export2Excel());
- ToggleHideSameCommand = new DelegatedCommand((o) => true, (o) => ToggleHideSameContent());
- UndoCommand = new DelegatedCommand((o) => true, (o) => UndoOperation(o));
- RedoCommand = new DelegatedCommand((o) => true, (o) => RedoOperation(o));
- SmartCellEditorLoadedCommand = new DelegatedCommand((o) => true, (o) => SmartCellEditorLoaded(o));
- SmartCellEditorUnloadedCommand = new DelegatedCommand((o) => true, (o) => SmartCellEditorUnloaded(o));
- }
- /// <summary>
- /// When smart cell editor loaded
- /// </summary>
- /// <param name="obj"></param>
- private void SmartCellEditorLoaded(object obj)
- {
- _currentEditingCellData = obj as SmartCellData;
- if (_currentEditingCellData == null) return;
- _valueBeforeEditing = _currentEditingCellData.Value;
- _previousRecipeRows = CloneRecipeRowData(RecipeRows);
- }
- /// <summary>
- /// make a clone of current recipe row data
- /// </summary>
- /// <returns></returns>
- private ObservableCollection<RecipeRow> CloneRecipeRowData(ObservableCollection<RecipeRow> oldData)
- {
- ObservableCollection<RecipeRow> newRecipeRows = new ObservableCollection<RecipeRow>();
- foreach (var item in oldData)
- {
- var newRecipeRow = new RecipeRow() { CatalogName = item.CatalogName, FriendlyName = item.FriendlyName, TechnicalName = item.TechnicalName, RecipeItems = new ObservableCollection<SmartCellData>() };
- newRecipeRows.Add(newRecipeRow);
- foreach (var item2 in item.RecipeItems)
- {
- var newRecipeItem = new SmartCellData() { Background = item2.Background, ErrInfo = item2.ErrInfo, FontWeight = item2.FontWeight, Foreground = item2.Foreground, IsHidden = item2.IsHidden, IsMasked = item2.IsMasked, IsRunning = item2.IsRunning, RecipeVariableDefine = item2.RecipeVariableDefine, Value = item2.Value };
- newRecipeRow.RecipeItems.Add(newRecipeItem);
- }
- }
- return newRecipeRows;
- }
- /// <summary>
- /// When smart cell editor unloaded
- /// </summary>
- /// <param name="obj"></param>
- private void SmartCellEditorUnloaded(object obj)
- {
- if (_currentEditingCellData != null && _currentEditingCellData.Value != _valueBeforeEditing)
- {
- IsRecipeModified = true;
- var ret = OverrideSelectedCellsData();
- if (ret < 2)
- AddUndoHistory(string.Format("第{0}步({1})",
- _currentEditingCellData.ColIndex + 1,
- _currentEditingCellData.RecipeVariableDefine.CatalogName + _currentEditingCellData.RecipeVariableDefine.FriendlyName), _previousRecipeRows);
- else
- AddUndoHistory(string.Format("第{0}步({1})等{2}个单元格数据",
- _currentEditingCellData.ColIndex + 1,
- _currentEditingCellData.RecipeVariableDefine.CatalogName + _currentEditingCellData.RecipeVariableDefine.FriendlyName, ret), _previousRecipeRows);
- }
- RefreshCellsDisplay(false);
- }
- /// <summary>
- /// Adding undo history
- /// </summary>
- /// <param name="description"></param>
- /// <param name="recipeRows"></param>
- private void AddUndoHistory(string description, ObservableCollection<RecipeRow> recipeRows)
- {
- System.Diagnostics.Debug.WriteLine(description);
- if (recipeRows == null)
- return;
- string shortDesc = "";
- if (description.Length > 50)
- {
- shortDesc = description.Substring(0, 50);
- shortDesc += "...";
- }
- else
- {
- shortDesc = description;
- }
- UndoList.Insert(0, new Tuple<string, string, ObservableCollection<RecipeRow>, Guid>(shortDesc, description, recipeRows, Guid.NewGuid()));
- UndoList = new List<Tuple<string, string, ObservableCollection<RecipeRow>, Guid>>(UndoList.ToList());
- RedoList = new List<Tuple<string, string, ObservableCollection<RecipeRow>, Guid>>();
- InvokePropertyChanged("UndoList");
- InvokePropertyChanged("RedoList");
- InvokePropertyChanged("IsUndoEnabled");
- InvokePropertyChanged("IsRedoEnabled");
- }
- /// <summary>
- /// Redo something here
- /// </summary>
- private void RedoOperation(object obj)
- {
- try
- {
- if (RedoList == null || RedoList.Count == 0)
- return;
- Guid redoId = Guid.Empty;
- if (obj == null)
- redoId = RedoList[0].Item4;
- else
- redoId = (Guid)obj;
- var itemIndex = RedoList.FindIndex((o) => o.Item4 == redoId);
- if (itemIndex < 0)
- return;
- UndoList.Reverse();
- for (int i = 0; i <= itemIndex; i++)
- {
- if (i == 0)
- UndoList.Add(new Tuple<string, string, ObservableCollection<RecipeRow>, Guid>(RedoList[i].Item1, RedoList[i].Item2, CloneRecipeRowData(RecipeRows), RedoList[i].Item4));
- else
- UndoList.Add(new Tuple<string, string, ObservableCollection<RecipeRow>, Guid>(RedoList[i].Item1, RedoList[i].Item2, RedoList[i - 1].Item3, RedoList[i].Item4));
- }
- UndoList.Reverse();
- UndoList = new List<Tuple<string, string, ObservableCollection<RecipeRow>, Guid>>(UndoList.ToList());
- RecipeRows = RedoList[itemIndex].Item3;
- RedoList.RemoveRange(0, itemIndex + 1);
- RedoList = new List<Tuple<string, string, ObservableCollection<RecipeRow>, Guid>>(RedoList.ToList());
- RefreshDataGrid();
- RefreshCellsDisplay(false);
- InvokePropertyChanged("UndoList");
- InvokePropertyChanged("RedoList");
- InvokePropertyChanged("IsUndoEnabled");
- InvokePropertyChanged("IsRedoEnabled");
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- MessageBox.Show("恢复动作失败!\r\n\r\n" + ex.Message, "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
- }
- }
- /// <summary>
- /// Undo something here
- /// </summary>
- private void UndoOperation(object obj)
- {
- try
- {
- if (UndoList == null || UndoList.Count == 0)
- return;
- Guid undoId = Guid.Empty;
- if (obj == null)
- undoId = UndoList[0].Item4;
- else
- undoId = (Guid)obj;
- var itemIndex = UndoList.FindIndex((o) => o.Item4 == undoId);
- if (itemIndex < 0)
- return;
- RedoList.Reverse();
- for (int i = 0; i <= itemIndex; i++)
- {
- if (i == 0)
- RedoList.Add(new Tuple<string, string, ObservableCollection<RecipeRow>, Guid>(UndoList[i].Item1, UndoList[i].Item2, CloneRecipeRowData(RecipeRows), UndoList[i].Item4));
- else
- RedoList.Add(new Tuple<string, string, ObservableCollection<RecipeRow>, Guid>(UndoList[i].Item1, UndoList[i].Item2, UndoList[i - 1].Item3, UndoList[i].Item4));
- }
- RedoList.Reverse();
- RedoList = new List<Tuple<string, string, ObservableCollection<RecipeRow>, Guid>>(RedoList.ToList());
- RecipeRows = UndoList[itemIndex].Item3;
- UndoList.RemoveRange(0, itemIndex + 1);
- UndoList = new List<Tuple<string, string, ObservableCollection<RecipeRow>, Guid>>(UndoList.ToList());
- RefreshDataGrid();
- RefreshCellsDisplay(false);
- InvokePropertyChanged("UndoList");
- InvokePropertyChanged("RedoList");
- InvokePropertyChanged("IsUndoEnabled");
- InvokePropertyChanged("IsRedoEnabled");
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- MessageBox.Show("撤销动作失败!\r\n\r\n" + ex.Message, "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
- }
- }
- /// <summary>
- /// hide or show same content before and after one step
- /// </summary>
- private void ToggleHideSameContent()
- {
- IsHideSameContent = !IsHideSameContent;
- RefreshCellsDisplay(false);
- }
- /// <summary>
- /// get recipe variations
- /// </summary>
- /// <returns></returns>
- public List<string> GetDefinedRecipeVariations()
- {
- var list1 = new List<string>();
- var dir = new System.IO.FileInfo(Process.GetCurrentProcess().MainModule.FileName).Directory;
- string cfgPath = dir + "\\Config\\";
- var di = new System.IO.DirectoryInfo(cfgPath);
- if (di.Exists)
- {
- foreach (var item in di.GetFiles("*.xml"))
- {
- list1.Add(item.Name.Substring(0, item.Name.Length - item.Extension.Length));
- }
- }
- return list1;
- }
- /// <summary>
- /// Export to excel
- /// </summary>
- private void Export2Excel()
- {
- try
- {
- if (RecipeRows == null) return;
- var dlg = new SaveFileDialog();
- dlg.DefaultExt = ".xls";
- dlg.Filter = "Excel文件 (.xls)|*.xls|所有文件 (*.*)|*.*";
- if (dlg.ShowDialog() == true)
- {
- if (File.Exists(dlg.FileName))
- File.Delete(dlg.FileName);
- Workbook workbook = new Workbook();
- Worksheet worksheet = new Worksheet("First Sheet");
- XmlDocument doc = new XmlDocument();
- doc.LoadXml(_currentRecipeFormatContent);
- var catalogNodes = doc.SelectNodes("TableRecipeFormat/Catalog");
- int groupRowIndex = 0;
- int stepRowIndex = 0;
- int catalogRowIndex = 0;
- foreach (XmlElement cNode in catalogNodes)
- {
- XmlNodeList sNodes = cNode.SelectNodes("Group/Step");
- string catalogHeader = cNode.Attributes["DisplayName"].Value;
- worksheet.Cells[catalogRowIndex, 0] = new ExcelLibrary.SpreadSheet.Cell(catalogHeader);
- catalogRowIndex += sNodes.Count;
- XmlNodeList gNodes = cNode.SelectNodes("Group");
- foreach (XmlElement gNode in gNodes)
- {
- XmlNodeList stepNodes = gNode.SelectNodes("Step");
- string groupHeader = gNode.Attributes["DisplayName"].Value;
- worksheet.Cells[groupRowIndex, 1] = new ExcelLibrary.SpreadSheet.Cell(groupHeader);
- groupRowIndex += stepNodes.Count;
- foreach (XmlElement nd in stepNodes)
- {
- string stepHeader = nd.Attributes["DisplayName"].Value;
- worksheet.Cells[stepRowIndex, 2] = new ExcelLibrary.SpreadSheet.Cell(stepHeader);
- stepRowIndex++;
- }
- }
- }
- string recipeContent = GetRecipeContentString();
- XmlDocument rcp = new XmlDocument();
- rcp.LoadXml(recipeContent);
- XmlNodeList stepNodeList = rcp.SelectNodes("/TableRecipeData/Step");
- for (int stepNo = 0; stepNo < stepNodeList.Count; stepNo++)
- {
- var dataDic = new Dictionary<string, string>();
- foreach (XmlAttribute att in (stepNodeList[stepNo] as XmlElement).Attributes)
- {
- dataDic.Add(att.Name, att.Value);
- }
- //fill sub node's attributes
- foreach (XmlElement subStep in stepNodeList[stepNo].ChildNodes)
- {
- foreach (XmlAttribute att in subStep.Attributes)
- {
- dataDic.Add(att.Name, att.Value);
- }
- foreach (XmlElement subsubStep in subStep.ChildNodes)
- {
- foreach (XmlAttribute att2 in subsubStep.Attributes)
- {
- dataDic.Add(att2.Name, att2.Value);
- }
- }
- }
- long length = dataDic.LongCount();
- int step = 0;
- foreach (string key in dataDic.Keys)
- {
- worksheet.Cells.ColumnWidth[(ushort)step] = 4000;
- var cellContent = dataDic[key];
- double v;
- if (double.TryParse(cellContent, out v))
- {
- worksheet.Cells[step, stepNo + 3] = new ExcelLibrary.SpreadSheet.Cell(v);
- }
- else
- {
- worksheet.Cells[step, stepNo + 3] = new ExcelLibrary.SpreadSheet.Cell(cellContent);
- }
- step++;
- }
- }
- workbook.Worksheets.Add(worksheet);
- workbook.Save(dlg.FileName);
- MessageBox.Show(string.Format("成功导出到Excel文件!\r\n\r\n{0}", dlg.FileName), "导出", MessageBoxButton.OK, MessageBoxImage.Information);
- }
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- MessageBox.Show("导出Excel文件发生异常!\r\n\r\n" + ex.Message, "导出", MessageBoxButton.OK, MessageBoxImage.Error);
- }
- }
- /// <summary>
- /// Show recipe information
- /// </summary>
- private void ShowHelpDocView()
- {
- var view = RecipeHelpView.Instance;
- view.Owner = Application.Current.MainWindow;
- view.DataContext = this;
- if (view.Visibility == Visibility.Visible)
- view.Hide();
- else
- view.Show();
- }
- /// <summary>
- /// Edit recipe information
- /// </summary>
- private void EditRecipeInformation()
- {
- RecipeInfoEditor editor = new RecipeInfoEditor() { RecipeHead = this.RecipeHead, Owner = Application.Current.MainWindow };
- editor.ShowDialog();
- InvokePropertyChanged("RecipeHead");
- }
- public void EnableBarcode(bool enable)
- {
- IsBarcodeEnabled = enable;
- InvokePropertyChanged("IsBarcodeVisibility");
- }
- public void SetCurrentUser(string user)
- {
- UserName = user;
- InvokePropertyChanged("UserName");
- }
- public void SetEndPointDefaultValue(string defaultValue)
- {
- _defaultEndPointValue = defaultValue;
- }
- /// <summary>
- /// Show recipe information
- /// </summary>
- private void ShowDetailedErrInformation()
- {
- var view = ErrorInformationDetailsView.Instance;
- view.Owner = Application.Current.MainWindow;
- view.DataContext = this;
- if (view.Visibility == Visibility.Visible)
- view.Hide();
- else
- view.ShowDialog();
- }
- /// <summary>
- /// Update selected cells data
- /// </summary>
- /// <returns>overrided cells number</returns>
- private int OverrideSelectedCellsData()
- {
- int overridedCellsNum = 0;
- if (_currentEditingCellData != null)
- {
- var finalCellData = _currentEditingCellData;
- bool containsEditingCell = false;
- foreach (var item in DataGridControl.SelectedCellRanges)
- {
- int startColIndex = Math.Min(item.ColumnRange.StartIndex, item.ColumnRange.EndIndex);
- int endColIndex = Math.Max(item.ColumnRange.StartIndex, item.ColumnRange.EndIndex);
- int startRowIndex = Math.Min(item.ItemRange.StartIndex, item.ItemRange.EndIndex);
- int endRowIndex = Math.Max(item.ItemRange.StartIndex, item.ItemRange.EndIndex);
- if (startColIndex > 0 && startColIndex <= RecipeRows[0].RecipeItems.Count &&
- endColIndex > 0 && endColIndex <= RecipeRows[0].RecipeItems.Count &&
- startRowIndex >= 0 && startRowIndex < RecipeRows.Count &&
- endRowIndex >= 0 && endRowIndex < RecipeRows.Count)
- {
- for (int m = startRowIndex; m <= endRowIndex; m++)
- {
- for (int n = startColIndex; n <= endColIndex; n++)
- {
- int rowIndex = m;
- int colIndex = n - 1;
- if (RecipeRows[rowIndex].RecipeItems[colIndex] == _currentEditingCellData)
- {
- containsEditingCell = true;
- break;
- }
- }
- }
- }
- }
- if (containsEditingCell)
- {
- foreach (var item in DataGridControl.SelectedCellRanges)
- {
- int startColIndex = Math.Min(item.ColumnRange.StartIndex, item.ColumnRange.EndIndex);
- int endColIndex = Math.Max(item.ColumnRange.StartIndex, item.ColumnRange.EndIndex);
- int startRowIndex = Math.Min(item.ItemRange.StartIndex, item.ItemRange.EndIndex);
- int endRowIndex = Math.Max(item.ItemRange.StartIndex, item.ItemRange.EndIndex);
- if (startColIndex > 0 && startColIndex <= RecipeRows[0].RecipeItems.Count &&
- endColIndex > 0 && endColIndex <= RecipeRows[0].RecipeItems.Count &&
- startRowIndex >= 0 && startRowIndex < RecipeRows.Count &&
- endRowIndex >= 0 && endRowIndex < RecipeRows.Count)
- {
- for (int m = startRowIndex; m <= endRowIndex; m++)
- {
- for (int n = startColIndex; n <= endColIndex; n++)
- {
- int rowIndex = m;
- int colIndex = n - 1;
- if (RecipeRows[rowIndex].RecipeItems[colIndex].RecipeVariableDefine.CellType == finalCellData.RecipeVariableDefine.CellType)
- {
- overridedCellsNum++;
- RecipeRows[rowIndex].RecipeItems[colIndex].Value = finalCellData.Value;
- RecipeRows[rowIndex].RecipeItems[colIndex].InvokePropertyChanged();
- }
- }
- }
- }
- }
- }
- }
- return overridedCellsNum;
- }
- /// <summary>
- /// Open local recipe operation
- /// </summary>
- /// <param name="recipeDefineFilePath"></param>
- public void OpenLocalRecipe(string recipeVariationName = "")
- {
- var dlg = new OpenFileDialog();
- dlg.DefaultExt = ".rcp";
- dlg.Filter = "Recipe File (.rcp)|*.rcp|All (*.*)|*.*";
- if (dlg.ShowDialog() == true)
- {
- try
- {
- XmlDocument rcpDoc = new XmlDocument();
- rcpDoc.Load(dlg.FileName);
- string recipeVariation = recipeVariationName;
- if (string.IsNullOrEmpty(recipeVariation))
- {
- var root = rcpDoc.SelectSingleNode("/TableRecipeData") as XmlElement;
- recipeVariation = root.Attributes["RecipeVersion"].Value;
- }
- var startupPath = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
- string dir = System.IO.Path.GetDirectoryName(startupPath);
- List<Aitex.Controls.RecipeCompare.Item> map = CustomXmlSerializer.Deserialize<List<Aitex.Controls.RecipeCompare.Item>>(new System.IO.FileInfo(System.IO.Path.Combine(dir, "map.xml")));
- Func<Aitex.Controls.RecipeCompare.Item, bool> predicate = item => item.Name.Equals(recipeVariation);
- System.IO.FileInfo fi = new System.IO.FileInfo(string.Format("{0}\\config\\{1}.xml", dir, map.Any(predicate) ? map.Single(predicate).No : recipeVariation));
- if (fi.Exists)
- {
- XmlDocument doc = new XmlDocument();
- doc.Load(fi.FullName);
- string formatXml = doc.SelectSingleNode("/Aitex/TableRecipeFormat").OuterXml;
- string recipeXml = rcpDoc.SelectSingleNode("/TableRecipeData").OuterXml;
- LoadRecipe(formatXml, recipeXml);
- if (OnLocalRecipeOpened != null)
- OnLocalRecipeOpened.Invoke(new Tuple<string, string>(recipeVariation, dlg.FileName), null);
- }
- else
- {
- MessageBox.Show(string.Format("工艺程序版本{0}的描述文件不存在,无法正确识别该版本的工艺程序文件。", recipeVariation), "工艺程序打开失败",
- MessageBoxButton.OK, MessageBoxImage.Error);
- }
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- MessageBox.Show(string.Format("open recipe {0} failed,please confirm the recipe file is exist and valid。\r\n{1}", dlg.FileName, ex.Message), "Open recipe failed",
- MessageBoxButton.OK, MessageBoxImage.Error);
- }
- }
- }
- /// <summary>
- /// Save recipe file
- /// </summary>
- private void SaveRecipeFile()
- {
- try
- {
- if (Errors != null && Errors.Count > 0)
- {
- var ret = MessageBox.Show(string.Format("Recipe have {0} error,continue save?", Errors.Count), "Save", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
- if (ret != MessageBoxResult.Yes)
- return;
- }
- if (OnSaveRecipeFile != null)
- {
- IsRecipeModified = false;
- OnSaveRecipeFile.Invoke(GetRecipeContentString(), null);
- }
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- MessageBox.Show("save recipe failed!\r\n\r\n" + ex.Message, "Save", MessageBoxButton.OK, MessageBoxImage.Warning);
- }
- }
- /// <summary>
- /// get string typed recipe content
- /// </summary>
- /// <returns></returns>
- public string GetRecipeContentString()
- {
- if (string.IsNullOrEmpty(UserName))
- {
- var dlg1 = new Aitex.UI.RecipeEditor.UserNameInput() { Owner = Application.Current.MainWindow };
- var ret = dlg1.ShowDialog();
- if (ret.HasValue && ret.Value)
- {
- UserName = dlg1.UserName;
- }
- }
- RecipeHead.LastRevisionTime = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss");
- RecipeHead.LastModifiedBy = UserName;
- InvokePropertyChanged("RecipeHead");
- if (RecipeRows == null || RecipeRows.Count == 0 || RecipeRows[0].RecipeItems == null || RecipeRows[0].RecipeItems.Count == 0)
- return string.Empty;
- //Dictionary<string/*CatalogName*/, Dictionary<string/*GroupName*/, List<RecipeVariableDefine/*StepList*/>>> _recipeReadingFormat;
- XmlDocument doc = new XmlDocument();
- var rootNode = doc.CreateElement("TableRecipeData");
- rootNode.SetAttribute("RecipeVersion", RecipeHead.RecipeVariation);
- rootNode.SetAttribute("CreatedBy", RecipeHead.CreatedBy);
- rootNode.SetAttribute("CreationTime", RecipeHead.CreationTime);
- rootNode.SetAttribute("LastRevisedBy", RecipeHead.LastModifiedBy);
- rootNode.SetAttribute("LastRevisionTime", RecipeHead.LastRevisionTime);
- if (!string.IsNullOrEmpty(RecipeHead.PressureMode))
- {
- rootNode.SetAttribute("PressureMode", RecipeHead.PressureMode);
- }
- if (!string.IsNullOrEmpty(RecipeHead.BasePressure))
- {
- rootNode.SetAttribute("BasePressure", RecipeHead.BasePressure);
- }
- if (!string.IsNullOrEmpty(RecipeHead.SubstrateTemp))
- {
- rootNode.SetAttribute("SubstrateTemp", RecipeHead.SubstrateTemp);
- }
- if (!string.IsNullOrEmpty(RecipeHead.PumpingPinState))
- {
- rootNode.SetAttribute("PumpingPinState", RecipeHead.PumpingPinState);
- }
- if(!string.IsNullOrEmpty(RecipeHead.VentingPinState))
- {
- rootNode.SetAttribute("VentingPinState", RecipeHead.VentingPinState);
- }
- if(!string.IsNullOrEmpty(RecipeHead.PinDownPressure))
- {
- rootNode.SetAttribute("PinDownPressure", RecipeHead.PinDownPressure);
- }
- if (!string.IsNullOrEmpty(RecipeHead.PumpDownLimit))
- {
- rootNode.SetAttribute("PumpDownLimit", RecipeHead.PumpDownLimit);
- }
- if (!string.IsNullOrEmpty(RecipeHead.PurgeActive))
- {
- rootNode.SetAttribute("PurgeActive", RecipeHead.PurgeActive);
- }
- if (!string.IsNullOrEmpty(RecipeHead.NotToPurgeOrVent))
- {
- rootNode.SetAttribute("NotToPurgeOrVent", RecipeHead.NotToPurgeOrVent);
- }
- rootNode.SetAttribute("Barcode", RecipeHead.Barcode);
- rootNode.SetAttribute("Description", RecipeHead.Description);
- doc.AppendChild(rootNode);
- for (int stepIndex/* 0-> */ = 0; stepIndex < RecipeRows[0].RecipeItems.Count; stepIndex++)
- {
- var stepNode = doc.CreateElement("Step");
- rootNode.AppendChild(stepNode);
- foreach (var module in _recipeSavingFormat)
- {
- var moduleName = module.Key;
- XmlElement subNode = stepNode;
- if (!string.IsNullOrEmpty(moduleName))
- {
- string[] pathArr = moduleName.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
- for (int i = 0; i < pathArr.Length; i++)
- {
- var snd = subNode.SelectSingleNode(pathArr[i]) as XmlElement;
- if (snd == null)
- {
- var nd = doc.CreateElement(pathArr[i]);
- subNode.AppendChild(nd);
- subNode = nd;
- }
- else
- {
- subNode = snd;
- }
- }
- }
- foreach (var controlName in module.Value)
- {
- if (controlName == "StepNo")
- {
- subNode.SetAttribute(controlName, string.Format("第{0}步", stepIndex + 1));
- }
- else
- {
- var recipeRow = RecipeRows.First((o) => o.TechnicalName == controlName);
- if (recipeRow == null) continue;
- /*to compatiable with old recipe editor, always fill 'black space' to loop step*/
- if (controlName == "Loop" && string.IsNullOrEmpty(recipeRow.RecipeItems[stepIndex].Value))
- subNode.SetAttribute(controlName, " ");
- else
- {
- subNode.SetAttribute(controlName, recipeRow.RecipeItems[stepIndex].Value);
- //bool isJump = recipeRow.RecipeItems[stepIndex].IsJump;
- //if (isJump)
- //{
- // string deviceType = recipeRow.RecipeItems[stepIndex].RecipeVariableDefine.DeviceType;
- // if (deviceType == "MFC" || deviceType == "PC")
- // subNode.SetAttribute(controlName + ".IsJump", isJump.ToString());
- //}
- }
- }
- }
- }
- }
- return doc.OuterXml;
- }
- /// <summary>
- /// expand groups
- /// </summary>
- private void ExpandGroups()
- {
- try
- {
- foreach (CollectionViewGroup item in DataGridControl.Items.Groups)
- {
- DataGridControl.ExpandGroup(item);
- }
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- }
- }
- /// <summary>
- /// collapse groups
- /// </summary>
- private void CollapseGroups()
- {
- try
- {
- foreach (CollectionViewGroup item in DataGridControl.Items.Groups)
- {
- DataGridControl.CollapseGroup(item);
- }
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- }
- }
- /// <summary>
- /// right click context menu
- /// </summary>
- private void RightClickAction()
- {
- DataGridControl.ContextMenu = null;
- //get selected column information
- List<int> selectedColumns = new List<int>();
- foreach (var item in DataGridControl.SelectedCellRanges)
- {
- bool dir = item.ColumnRange.StartIndex <= item.ColumnRange.EndIndex;
- if (dir)
- {
- for (int i = item.ColumnRange.StartIndex; i <= item.ColumnRange.EndIndex; i++)
- {
- if (i > 0)
- if (!selectedColumns.Contains(i)) selectedColumns.Add(i);
- }
- }
- else
- {
- for (int i = item.ColumnRange.StartIndex; i >= item.ColumnRange.EndIndex; i--)
- {
- if (i > 0)
- if (!selectedColumns.Contains(i)) selectedColumns.Add(i);
- }
- }
- }
- selectedColumns.Sort();
- //debug only
- /*
- string s = "";
- foreach (var item in selectedColumns)
- {
- s += "," + item;
- }
- MessageBox.Show(s);
- * */
- //generate context menu
- ContextMenu cms = new ContextMenu();
- if (selectedColumns.Count > 0)
- {
- string colStrings = "";
- foreach (var item in selectedColumns)
- {
- if (string.IsNullOrEmpty(colStrings))
- colStrings = item.ToString();
- else
- colStrings += "," + item.ToString();
- }
- MenuItem mi;
- cms.Items.Add(new MenuItem() { Header = string.Format(" 当前选中第{0}步", colStrings), FontFamily = new FontFamily("Arial,SimSun"), IsEnabled = false, Background = Brushes.Gray, Foreground = Brushes.White });
- //copy
- mi = new MenuItem() { Header = " 复制", FontFamily = new FontFamily("Arial,SimSun"), Tag = selectedColumns.ToList() };
- mi.Click += (s, e) =>
- {
- try
- {
- var list = (s as MenuItem).Tag as List<int>;
- _copiedColumnDatas.Clear();
- foreach (var colId in list)
- {
- _copiedColumnDatas.Add(colId/*index from 1*/, new List<SmartCellData>());
- for (int i = 0; i < RecipeRows.Count; i++)
- {
- var oldCellData = RecipeRows[i].RecipeItems[colId - 1];
- var newCellData = new SmartCellData() { Value = oldCellData.Value, RecipeVariableDefine = oldCellData.RecipeVariableDefine };
- _copiedColumnDatas[colId].Add(newCellData);
- }
- }
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- }
- };
- cms.Items.Add(mi);
- if (selectedColumns.Count < RecipeRows[0].RecipeItems.Count)
- {
- mi = new MenuItem() { Header = " 剪切", FontFamily = new FontFamily("Arial,SimSun"), Tag = selectedColumns.ToList() };
- mi.Click += (s, e) =>
- {
- try
- {
- AddUndoHistory("剪切", CloneRecipeRowData(RecipeRows));
- var list = (s as MenuItem).Tag as List<int>;
- _copiedColumnDatas.Clear();
- foreach (var colId in list)
- {
- _copiedColumnDatas.Add(colId/*index from 1*/, new List<SmartCellData>());
- for (int i = 0; i < RecipeRows.Count; i++)
- {
- var oldCellData = RecipeRows[i].RecipeItems[colId - 1];
- var newCellData = new SmartCellData() { Value = oldCellData.Value, RecipeVariableDefine = oldCellData.RecipeVariableDefine };
- _copiedColumnDatas[colId].Add(newCellData);
- }
- }
- foreach (var item in RecipeRows)
- {
- var collection = new ObservableCollection<SmartCellData>();
- for (int index = 0; index < item.RecipeItems.Count; index++)
- {
- if (list.Contains(index + 1))
- continue;
- collection.Add(item.RecipeItems[index]);
- }
- item.RecipeItems = collection;
- }
- RefreshDataGrid();
- RefreshCellsDisplay(false);
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- }
- };
- cms.Items.Add(mi);
- mi = new MenuItem() { Header = " 删除", FontFamily = new FontFamily("Arial,SimSun"), Tag = selectedColumns.ToList() };
- mi.Click += (s, e) =>
- {
- try
- {
- AddUndoHistory("删除", CloneRecipeRowData(RecipeRows));
- var list = (s as MenuItem).Tag as List<int>;
- foreach (var item in RecipeRows)
- {
- var collection = new ObservableCollection<SmartCellData>();
- for (int index = 0; index < item.RecipeItems.Count; index++)
- {
- if (list.Contains(index + 1))
- continue;
- collection.Add(item.RecipeItems[index]);
- }
- item.RecipeItems = collection;
- }
- RefreshDataGrid();
- RefreshCellsDisplay(false);
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- }
- };
- cms.Items.Add(mi);
- }
- if (selectedColumns.Count == 1 && _copiedColumnDatas.Count > 0)
- {
- mi = new MenuItem() { Header = string.Format(" 插入第{0}步后", selectedColumns[0]/*, _copiedColumnDatas.Count*/), FontFamily = new FontFamily("Arial,SimSun"), Tag = selectedColumns[0] };
- mi.Click += (s, e) =>
- {
- try
- {
- AddUndoHistory("插入", CloneRecipeRowData(RecipeRows));
- int insertColId = (int)(s as MenuItem).Tag;
- for (int rowIndex = 0; rowIndex < RecipeRows.Count; rowIndex++)
- {
- var collection = new ObservableCollection<SmartCellData>();
- for (int index = 0; index < insertColId; index++)
- {
- collection.Add(RecipeRows[rowIndex].RecipeItems[index]);
- }
- foreach (var col in _copiedColumnDatas)
- {
- collection.Add(new SmartCellData() { Value = col.Value[rowIndex].Value, RecipeVariableDefine = col.Value[rowIndex].RecipeVariableDefine });
- }
- for (int index = insertColId; index < RecipeRows[rowIndex].RecipeItems.Count; index++)
- {
- collection.Add(RecipeRows[rowIndex].RecipeItems[index]);
- }
- RecipeRows[rowIndex].RecipeItems = collection;
- }
- RefreshDataGrid();
- RefreshCellsDisplay(false);
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- }
- };
- cms.Items.Add(mi);
- }
- }
- //show context menu
- DataGridControl.ContextMenu = cms;
- cms.Visibility = Visibility.Visible;
- }
- /// <summary>
- /// Parse recipe content with recipe format
- /// </summary>
- /// <param name="recipeFormat"></param>
- /// <param name="recipeContent"></param>
- /// <param name="selectedStepNo"></param>
- public void LoadRecipe(string recipeFormat, string recipeContent, int selectedStepNo = -1)
- {
- CurrentRunningStepNo = selectedStepNo;
- IsHideSameContent = false;
- IsRecipeModified = false;
- RecipeHead = new RecipeEditor.RecipeHead();
- DataGridControl.ContextMenu = null;
- RecipeInfo = "";
- IsBusy = true;
- InvokePropertyChanged("IsBusy");
- UndoList.Clear();
- RedoList.Clear();
- InvokePropertyChanged("UndoList");
- InvokePropertyChanged("RedoList");
- InvokePropertyChanged("IsUndoEnabled");
- InvokePropertyChanged("IsRedoEnabled");
- try
- {
- RecipeRows = new ObservableCollection<RecipeRow>();
- _recipeReadingFormat = new Dictionary<string, Dictionary<string, List<RecipeVariableDefine>>>();
- _recipeSavingFormat = new Dictionary<string, List<string>>();
- //parse recipe format
- XmlDocument formatXml = new XmlDocument();
- formatXml.LoadXml(recipeFormat);
- _currentRecipeFormatContent = formatXml.OuterXml;
- //reading recipe variation
- string recipeVariationName = formatXml.SelectSingleNode("TableRecipeFormat").Attributes["RecipeVersion"].Value;
- if (String.Compare(recipeVariationName, _currentRecipeVariationName) != 0)
- {
- //if variation name is different from previous loaded recipe -> clear all previous copied recipe columns
- _copiedColumnDatas.Clear();
- }
- _currentRecipeVariationName = recipeVariationName;
- //reading recipe validation releated parameters
- _preDefinedRecipeVars = new Dictionary<string, string>();
- foreach (XmlElement nd in formatXml.SelectNodes("/TableRecipeFormat/Validation/Predefine/Item"))
- {
- _preDefinedRecipeVars.Add(nd.Attributes["VarName"].Value, nd.Attributes["Value"].Value);
- }
- //reading check variables
- _checkVariables = new List<string>();
- foreach (XmlElement nd in formatXml.SelectNodes("/TableRecipeFormat/Validation/CheckVariable/Var"))
- {
- string varName = nd.Attributes["Name"].Value;
- _checkVariables.Add(varName);
- }
- //reading validation rules
- _validationRules = new List<Tuple<string, string, string>>();
- foreach (XmlElement nd in formatXml.SelectNodes("/TableRecipeFormat/Validation/Restriction/Rule"))
- {
- string varName = nd.Attributes["VarName"].Value;
- string checkCondition = nd.Attributes["CheckCondition"].Value.Replace("<", "<").Replace(">", ">");
- string message = nd.Attributes["Message"].Value.Replace("'", "\"");
- _validationRules.Add(new Tuple<string, string, string>(varName, checkCondition, message));
- }
- //parsing recipe format xml file
- foreach (XmlElement catalogNode in formatXml.SelectNodes("/TableRecipeFormat/Catalog"))
- {
- string catalogName = catalogNode.Attributes["DisplayName"].Value;
- _recipeReadingFormat.Add(catalogName, new Dictionary<string, List<RecipeVariableDefine>>());
- foreach (XmlElement groupNode in catalogNode.SelectNodes("Group"))
- {
- string groupName = groupNode.Attributes["DisplayName"].Value;
- _recipeReadingFormat[catalogName].Add(groupName, new List<RecipeVariableDefine>());
- foreach (XmlElement stepNode in groupNode.SelectNodes("Step"))
- {
- string stepModuleName = stepNode.Attributes["ModuleName"].Value;
- string stepDeviceType = stepNode.Attributes["DeviceType"].Value;
- string stepDisplayName = stepNode.Attributes["DisplayName"].Value;
- string stepControlName = stepNode.Attributes["ControlName"].Value;
- string stepInputType = stepNode.Attributes["InputType"].Value;
- string stepDescription = stepNode.HasAttribute("Desc") ? stepNode.Attributes["Desc"].Value : "";
- double stepMin = double.Parse(stepNode.HasAttribute("Min") ? stepNode.Attributes["Min"].Value : "0");
- double stepMax = double.Parse(stepNode.HasAttribute("Max") ? stepNode.Attributes["Max"].Value : "0");
- var selectionList = new List<Tuple<string, string>>();
- foreach (XmlElement selectionNode in stepNode.SelectNodes("Item"))
- {
- selectionList.Add(new Tuple<string, string>(selectionNode.Attributes["ControlName"].Value, selectionNode.Attributes["DisplayName"].Value));
- }
- if (!_recipeSavingFormat.ContainsKey(stepModuleName)) _recipeSavingFormat.Add(stepModuleName, new List<string>());
- _recipeSavingFormat[stepModuleName].Add(stepControlName);
- if (stepControlName == "StepNo")
- continue;
- _recipeReadingFormat[catalogName][groupName].Add(new RecipeVariableDefine()
- {
- CellType = (CellType)Enum.Parse(typeof(CellType), stepInputType),
- Description = stepDescription,
- DeviceType = stepDeviceType,
- DropdownItemList = selectionList,
- MaxValue = stepMax,
- //MinValue = stepDeviceType.Equals("MFC",StringComparison.InvariantCultureIgnoreCase)? stepMax*2.0/100: stepMin,
- MinValue = stepMin,
- GroupName = groupName,
- CatalogName = catalogName,
- TechnicalName = stepControlName,
- FriendlyName = stepDisplayName
- });
- }
- }
- }
- //parse recipe content
- XmlDocument contentXml = new XmlDocument();
- contentXml.LoadXml(recipeContent);
- contentXml.DocumentElement.SetAttribute("RecipeVersion", _currentRecipeVariationName);
- //read recipe head
- //em. RecipeVersion="Ace" CreatedBy="tech" CreationTime="2013-02-02T12:36:02" LastRevisedBy="Peter" LastRevisionTime="2013-10-22T13:30:29" Description="5e46af80-49f9-4b4f-b04b-bc911fb292f8"
- RecipeHead.CreatedBy = contentXml.DocumentElement.HasAttribute("CreatedBy") ? contentXml.DocumentElement.Attributes["CreatedBy"].Value : "(无)";
- RecipeHead.CreationTime = contentXml.DocumentElement.HasAttribute("CreationTime") ? contentXml.DocumentElement.Attributes["CreationTime"].Value : "(无)";
- RecipeHead.LastModifiedBy = contentXml.DocumentElement.HasAttribute("LastRevisedBy") ? contentXml.DocumentElement.Attributes["LastRevisedBy"].Value : "(无)";
- RecipeHead.LastRevisionTime = contentXml.DocumentElement.HasAttribute("LastRevisionTime") ? contentXml.DocumentElement.Attributes["LastRevisionTime"].Value : "(无)";
- if (contentXml.DocumentElement.HasAttribute("PressureMode"))
- {
- RecipeHead.PressureMode = contentXml.DocumentElement.Attributes["PressureMode"].Value;
- }
- if (contentXml.DocumentElement.HasAttribute("BasePressure"))
- {
- RecipeHead.BasePressure = contentXml.DocumentElement.Attributes["BasePressure"].Value;
- }
- if (contentXml.DocumentElement.HasAttribute("PumpDownLimit"))
- {
- RecipeHead.PumpDownLimit = contentXml.DocumentElement.Attributes["PumpDownLimit"].Value;
- }
-
- if (contentXml.DocumentElement.HasAttribute("SubstrateTemp"))
- {
- RecipeHead.SubstrateTemp = contentXml.DocumentElement.Attributes["SubstrateTemp"].Value;
- }
- if (contentXml.DocumentElement.HasAttribute("PumpingPinState"))
- {
- RecipeHead.PumpingPinState = contentXml.DocumentElement.Attributes["PumpingPinState"].Value;
- }
- if(contentXml.DocumentElement.HasAttribute("PinDownPressure"))
- {
- RecipeHead.PinDownPressure = contentXml.DocumentElement.Attributes["PinDownPressure"].Value;
- }
- if(contentXml.DocumentElement.HasAttribute("VentingPinState"))
- {
- RecipeHead.VentingPinState = contentXml.DocumentElement.Attributes["VentingPinState"].Value;
- }
- if (contentXml.DocumentElement.HasAttribute("PurgeActive"))
- {
- RecipeHead.PurgeActive = contentXml.DocumentElement.Attributes["PurgeActive"].Value;
- }
- if (contentXml.DocumentElement.HasAttribute("NotToPurgeOrVent"))
- {
- RecipeHead.NotToPurgeOrVent = contentXml.DocumentElement.Attributes["NotToPurgeOrVent"].Value;
- }
- if (contentXml.DocumentElement.HasAttribute("Barcode"))
- {
- RecipeHead.Barcode = contentXml.DocumentElement.Attributes["Barcode"].Value;
- }
- RecipeHead.RecipeVariation = contentXml.DocumentElement.HasAttribute("RecipeVersion") ? contentXml.DocumentElement.Attributes["RecipeVersion"].Value : "(NULL)";
- RecipeHead.Description = contentXml.DocumentElement.HasAttribute("Description") ? contentXml.DocumentElement.Attributes["Description"].Value : "(NULL)";
- var allRecipeItems = new List<Dictionary<string, string>>();
- foreach (XmlElement stepNode in contentXml.SelectNodes("/TableRecipeData/Step"))
- {
- var stepDic = new Dictionary<string, string>();
- allRecipeItems.Add(stepDic);
- foreach (XmlAttribute att in stepNode.Attributes)
- {
- stepDic.Add(att.Name, att.Value);
- }
- foreach (XmlElement innerStep in stepNode.ChildNodes)
- {
- foreach (XmlAttribute att in innerStep.Attributes)
- {
- stepDic.Add(att.Name, att.Value);
- }
- foreach (XmlElement innerInnerStep in innerStep.ChildNodes)
- {
- foreach (XmlAttribute att in innerInnerStep.Attributes)
- {
- stepDic.Add(att.Name, att.Value);
- }
- }
- }
- }
- //generate view model
- RowVarNameDic = new Dictionary<string, int>();
- int rowIndex = 0;
- foreach (var catalog in _recipeReadingFormat.Keys)
- {
- foreach (var group in _recipeReadingFormat[catalog].Keys)
- {
- foreach (var var1 in _recipeReadingFormat[catalog][group])
- {
- var singleRow = new RecipeRow() { CatalogName = catalog, FriendlyName = /*group + */var1.FriendlyName, TechnicalName = var1.TechnicalName };
- for (int stepNo = 0; stepNo < allRecipeItems.Count; stepNo++)
- {
- var stepCell = new SmartCellData() { RecipeVariableDefine = var1 };
- if (allRecipeItems[stepNo].ContainsKey(var1.TechnicalName))
- {
- stepCell.Value = allRecipeItems[stepNo][var1.TechnicalName];
- //stepCell.ShowsJumpControl = false;
- //if (var1.CellType == CellType.NumInput)
- //{
- // if (var1.DeviceType == "MFC" || var1.DeviceType == "PC")
- // {
- // string jumpString = var1.TechnicalName + ".IsJump";
- // stepCell.IsJump = allRecipeItems[stepNo].ContainsKey(jumpString) ? bool.Parse(allRecipeItems[stepNo][jumpString]) : false;
- // stepCell.ShowsJumpControl = true;
- // }
- //}
- }
- else
- stepCell.Value = "n/a";
- singleRow.RecipeItems.Add(stepCell);
- }
- RecipeRows.Add(singleRow);
- RowVarNameDic.Add(var1.TechnicalName, rowIndex++);
- }
- }
- }
- //refresh datagrid
- RefreshDataGrid();
- //refresh recipe information
- RefreshCellsDisplay();
- if (OnLoadRecipeContent != null)
- OnLoadRecipeContent.Invoke(recipeContent, null);
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- //LOG.Write("", ex);
- }
- IsBusy = false;
- InvokePropertyChanged("IsBusy");
- }
- /// <summary>
- /// 检查变量ramp rate
- /// </summary>
- /// <param name="stepNo"></param>
- /// <param name="rampEnable"></param>
- /// <param name="varName"></param>
- /// <param name="rampTime"></param>
- /// <param name="maxRampUpRate"></param>
- /// <param name="maxRampDownRate"></param>
- /// <returns>False:check ok, True: check failed</returns>
- public bool CheckRampRate(int stepNo, string rampEnable, string varName, string rampTime, double maxRampUpRate, double maxRampDownRate)
- {
- try
- {
- if (stepNo <= 0) return false;
- int rowIndex = RowVarNameDic[varName];
- double currentValue = double.Parse(RecipeRows[rowIndex].RecipeItems[stepNo].Value);
- //if (varName == "AZone.Setpoint" || varName == "BZone.Setpoint" || varName == "CZone.Setpoint" || varName == "DZone.Setpoint")
- //{
- // int heatControlModeIndex = RowVarNameDic["Heater.Mode"];
- // string curStepHeatCtrlMode = RecipeRows[heatControlModeIndex].RecipeItems[stepNo].Value;
- // string lastStepHeatCtrlMode = RecipeRows[heatControlModeIndex].RecipeItems[stepNo - 1].Value;
- // if (curStepHeatCtrlMode != lastStepHeatCtrlMode)
- // {
- // if (!(lastStepHeatCtrlMode.Equals("CurrentControl") && curStepHeatCtrlMode.Equals("PyroTempControl")))
- // return false;
- // int endbyIndex = RowVarNameDic["EndBy"];
- // int endValueIndex = RowVarNameDic["EndValue"];
- // string endby = RecipeRows[endbyIndex].RecipeItems[stepNo - 1].Value;
- // EndByCondition endbyEnum;
- // if (!Enum.TryParse(endby, out endbyEnum)) return false;
- // if (endbyEnum != EndByCondition.PmTempGt && endbyEnum != EndByCondition.PmTempLt) return false;
- // string end = RecipeRows[endValueIndex].RecipeItems[stepNo - 1].Value;
- // double endValue;
- // if (!double.TryParse(end, out endValue)) return false;
- // return CheckRampRate(rampEnable, rampTime, maxRampUpRate, maxRampDownRate, endValue, currentValue);
- // }
- //}
- double prevValue = double.Parse(RecipeRows[rowIndex].RecipeItems[stepNo - 1].Value);
- return CheckRampRate(rampEnable, rampTime, maxRampUpRate, maxRampDownRate, prevValue, currentValue);
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- return true;
- }
- }
- bool CheckRampRate(string rampEnable, string rampTime, double maxRampUpRate, double maxRampDownRate, double prevValue, double currentValue)
- {
- bool isRampEnable = bool.Parse(rampEnable);
- //string[] timeStr = rampTime.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
- //string tt = string.Join(":", timeStr);
- TimeSpan timeSpan;
- TimeSpan.TryParse(rampTime, out timeSpan);
- double totalTimeSec = timeSpan.TotalSeconds;
- double diff = currentValue - prevValue;
- if (!isRampEnable || totalTimeSec <= 0)
- {
- if (diff != 0) return true;
- return false;
- }
- else
- {
- double rampRate = diff / totalTimeSec;
- return (rampRate > 0 && rampRate >= maxRampUpRate) || (rampRate < 0 && rampRate <= -maxRampDownRate);
- }
- }
- /// <summary>
- /// Refresh datagrid cell data display
- /// </summary>
- /// <param name="moving2RunningStepPosition">True: moving to current running step position</param>
- public void RefreshCellsDisplay(bool moving2RunningStepPosition = true)
- {
- try
- {
- if (RecipeRows == null || RecipeRows.Count < 2)
- return;
- Errors = new List<Tuple<int, int, string, string>>();
- Dictionary<int, string> dicEndby = new Dictionary<int, string>();
- Dictionary<int, string> dicPressureMode = new Dictionary<int, string>();
- Dictionary<int, string> dicRfMode = new Dictionary<int, string>();
- Dictionary<int, string> dicRfMatchProcessMode = new Dictionary<int, string>();
- Dictionary<int, string> dicSetMatchPositionC1 = new Dictionary<int, string>();
- Dictionary<int, string> dicSetMatchPositionC2 = new Dictionary<int, string>();
- for (int i = 0; i < RecipeRows.Count; i++)
- {
- for (int j = 0; j < RecipeRows[i].RecipeItems.Count; j++)
- {
- var cell = RecipeRows[i].RecipeItems[j];
- cell.RowIndex = i;
- cell.ColIndex = j;
- cell.ErrInfo = string.Empty;
- bool logicEnable = true;
- if (cell.RecipeVariableDefine.TechnicalName == "EndBy")
- dicEndby[j] = cell.Value;
- if (cell.RecipeVariableDefine.TechnicalName == "ThrottleValve.SetMode")
- {
- dicPressureMode[j] = cell.Value;
- }
- if (cell.RecipeVariableDefine.TechnicalName == "PressureControl.SetTVMode")
- {
- dicPressureMode[j] = cell.Value;
- }
- if (cell.RecipeVariableDefine.TechnicalName == "Rf.SetMode")
- dicRfMode[j] = cell.Value;
- if (cell.RecipeVariableDefine.TechnicalName == "Match.SetMatchProcessMode")
- dicRfMatchProcessMode[j] = cell.Value;
- if (cell.RecipeVariableDefine.TechnicalName == "Match.SetMatchPositionC1")
- dicSetMatchPositionC1[j] = cell.Value;
- if (cell.RecipeVariableDefine.TechnicalName == "Match.SetMatchPositionC2")
- dicSetMatchPositionC2[j] = cell.Value;
- if (cell.RecipeVariableDefine.TechnicalName == "Time")
- {
- logicEnable = dicEndby.ContainsKey(j) && (dicEndby[j] == "EndByStepTime" ||
- dicEndby[j] == "EndByHeatUp" ||
- dicEndby[j] == "EndByEndPoint");
- }
- if (cell.RecipeVariableDefine.TechnicalName == "ThrottleValve.SetPosition")
- {
- logicEnable = dicPressureMode.ContainsKey(j) && dicPressureMode[j] == "TVPositionCtrl";
- }
- if (cell.RecipeVariableDefine.TechnicalName == "ThrottleValve.SetPressure")
- {
- logicEnable = dicPressureMode.ContainsKey(j) && dicPressureMode[j] == "TVPressureCtrl";
- }
- if (cell.RecipeVariableDefine.TechnicalName == "PressureControl.SetTVPosition")
- {
- logicEnable = dicPressureMode.ContainsKey(j) && dicPressureMode[j] == "TVPositionCtrl";
- }
- if (cell.RecipeVariableDefine.TechnicalName == "PressureControl.SetTVPressure")
- {
- logicEnable = dicPressureMode.ContainsKey(j) && dicPressureMode[j] == "TVPressureCtrl";
- }
- if (cell.RecipeVariableDefine.TechnicalName == "Rf.SetPulsingFrequency")
- {
- logicEnable = dicRfMode.ContainsKey(j) && dicRfMode[j] == "PulsingMode";
- }
- if (cell.RecipeVariableDefine.TechnicalName == "Rf.SetPulsingDuty")
- {
- logicEnable = dicRfMode.ContainsKey(j) && dicRfMode[j] == "PulsingMode";
- }
- if (cell.RecipeVariableDefine.TechnicalName == "Rf.SetPowerOnTime")
- {
- logicEnable = dicEndby.ContainsKey(j) && dicEndby[j] == "EndByRfTime";
- }
- if (cell.RecipeVariableDefine.TechnicalName == "EPD.SetConfig")
- {
- logicEnable = dicEndby.ContainsKey(j) && dicEndby[j] == "EndByEndPoint";
- if (string.IsNullOrEmpty(cell.Value) || cell.Value.StartsWith("n/a"))
- cell.Value = _defaultEndPointValue;
- }
-
- if (cell.RecipeVariableDefine.TechnicalName == "Match.SetMatchProcessMode")
- {
- logicEnable = dicRfMatchProcessMode.ContainsKey(j);// && dicRfMatchProcessMode[j] == "TritonPresetMode";
- }
- if (cell.RecipeVariableDefine.TechnicalName == "Match.SetMatchPositionC1")
- {
- logicEnable = dicSetMatchPositionC1.ContainsKey(j);// && dicRfMatchProcessMode[j] == "TritonPresetMode";
- }
- if (cell.RecipeVariableDefine.TechnicalName == "Match.SetMatchPositionC2")
- {
- logicEnable = dicSetMatchPositionC2.ContainsKey(j);// && dicRfMatchProcessMode[j] == "TritonPresetMode";
- }
- cell.IsMasked = !logicEnable;
- //update diff variable numbers
- if (cell.RecipeVariableDefine.TechnicalName == "Ramp")
- {
- //更新当前步骤中Ramp的变量数据
- if (j == 0)
- {
- cell.Tag = 0;
- }
- else
- {
- int rampNum = 0;
- for (int s1 = 0; s1 < RecipeRows.Count; s1++)
- {
- if (RecipeRows[s1].CatalogName == "StepInfo")// RecipeRows[s1].RecipeItems[j].RecipeVariableDefine.CellType == CellType.ReadOnly)
- continue;
- string preValue = RecipeRows[s1].RecipeItems[j - 1].Value;
- string curValue = RecipeRows[s1].RecipeItems[j].Value;
- if (RecipeRows[s1].RecipeItems[j].RecipeVariableDefine.CellType == CellType.NumInput)
- {
- double pd, cd;
- if (double.TryParse(preValue, out pd) && double.TryParse(curValue, out cd))
- if (pd != cd) rampNum++;
- }
- else if (String.Compare(preValue, curValue, false) != 0)
- {
- rampNum++;
- }
- }
- cell.Tag = rampNum;
- }
- cell.InvokePropertyChanged();
- }
- #region mask (hide or show cell content)
- if ((MaskedTechNames != null && MaskedTechNames.Contains(cell.RecipeVariableDefine.TechnicalName)) ||
- (MaskedCatalogNames != null && MaskedCatalogNames.Contains(cell.RecipeVariableDefine.CatalogName)) || !logicEnable)
- cell.IsMasked = true;
- else
- cell.IsMasked = false;
- #endregion mask (hide or show cell content)
- #region check cell data range
- switch (cell.RecipeVariableDefine.CellType)
- {
- case CellType.CheckBox:
- {
- if (string.Compare(cell.Value, "true", true) == 0 || string.Compare(cell.Value, "false", true) == 0)
- {
- cell.ErrInfo = "";
- cell.Background = Brushes.Transparent;
- }
- else
- {
- string reason = string.Format("Value '{0}' not valid", cell.Value);
- Errors.Add(new Tuple<int, int, string, string>(i, j, cell.RecipeVariableDefine.FriendlyName, reason));
- cell.ErrInfo = reason;
- cell.Background = Brushes.Pink;
- }
- }
- break;
- case CellType.EditableSelection:
- {
- cell.ErrInfo = "";
- cell.Background = Brushes.Transparent;
- }
- break;
- case CellType.NumInput:
- {
- double min = cell.RecipeVariableDefine.MinValue;
- double max = cell.RecipeVariableDefine.MaxValue;
- double v;
- if (!double.TryParse(cell.Value, out v))
- {
- string reason = string.Format("Value '{0}' not valid", cell.Value);
- Errors.Add(new Tuple<int, int, string, string>(i, j, cell.RecipeVariableDefine.FriendlyName, reason));
- cell.ErrInfo = reason;
- cell.Background = Brushes.Pink;
- }
- else if (v > max || v < 0 || (v < min && v > max * 0.1 / 100))
- {
- string reason = string.Format("Value'{0}',Out of Range {1}~{2}", cell.Value, min, max);
- Errors.Add(new Tuple<int, int, string, string>(i, j, cell.RecipeVariableDefine.FriendlyName, reason));
- cell.ErrInfo = reason;
- cell.Background = Brushes.Pink;
- }
- else
- {
- cell.ErrInfo = "";
- cell.Background = Brushes.Transparent;
- }
- }
- break;
- case CellType.ReadOnlySelection:
- {
- if (cell.RecipeVariableDefine.DropdownItemList != null && cell.RecipeVariableDefine.DropdownItemList.Find((o) => o.Item1 == cell.Value) != null)
- {
- cell.ErrInfo = "";
- cell.Background = Brushes.Transparent;
- }
- else
- {
- string reason = string.Format("Value'{0}' is not valid", cell.Value);
- Errors.Add(new Tuple<int, int, string, string>(i, j, cell.RecipeVariableDefine.FriendlyName, reason));
- cell.ErrInfo = reason;
- cell.Background = Brushes.Pink;
- }
- }
- break;
- case CellType.ReadOnly:
- case CellType.TextInput:
- cell.ErrInfo = "";
- cell.Background = Brushes.Transparent;
- break;
- case CellType.TimeInput:
- {
- string[] arr = cell.Value.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
- int h, mi, s;
- if (arr.Length == 3 && int.TryParse(arr[0], out h) && int.TryParse(arr[1], out mi) && int.TryParse(arr[2], out s) && h >= 0 && mi >= 0 && mi <= 59 && s >= 0 && s <= 59)
- {
- cell.ErrInfo = "";
- cell.Background = Brushes.Transparent;
- }
- else
- {
- string reason = string.Format("value'{0}' is not valid", cell.Value);
- Errors.Add(new Tuple<int, int, string, string>(i, j, cell.RecipeVariableDefine.FriendlyName, reason));
- cell.ErrInfo = reason;
- cell.Background = Brushes.Pink;
- }
- }
- break;
- }
- #endregion check cell data range
- #region mark data trend / hide same content
- if (j == 0) //step one
- {
- cell.Foreground = Brushes.Black;
- cell.FontWeight = FontWeights.Normal;
- cell.IsHidden = false;
- cell.InvokePropertyChanged();
- cell.IsMasked = !logicEnable;
- continue;
- }
- var preCell = RecipeRows[i].RecipeItems[j - 1];
- if (cell.RecipeVariableDefine.CellType == CellType.NumInput)
- {
- double preValue = 0;
- double.TryParse(preCell.Value.ToString(), out preValue);
- double curValue = 0;
- double.TryParse(cell.Value.ToString(), out curValue);
- if (curValue > preValue)
- {
- cell.Foreground = Brushes.Red;
- cell.FontWeight = FontWeights.Bold;
- }
- else if (curValue < preValue)
- {
- cell.Foreground = Brushes.Blue;
- cell.FontWeight = FontWeights.Bold;
- }
- else
- {
- cell.Foreground = Brushes.Black;
- cell.FontWeight = FontWeights.Normal;
- }
- }
- else
- {
- //not number type
- cell.Foreground = Brushes.Black;
- cell.FontWeight = FontWeights.Normal;
- }
- if (IsHideSameContent && cell.Value == preCell.Value)
- cell.IsHidden = true;
- else
- cell.IsHidden = false;
- //!logicEnable;
- cell.IsMasked = !logicEnable;
- //if (!logicEnable)
- //{
- // cell.Background = Brushes.DarkGray;
- // cell.IsMasked = true;
- //}
- #endregion mark data trend / hide same content
- cell.InvokePropertyChanged();
- }
- }
- #region check loop
- int loopRowId = -1;
- for (int i = 0; i < RecipeRows.Count; i++)
- {
- if (RecipeRows[i].TechnicalName == "Loop")
- {
- loopRowId = i;
- break;
- }
- }
- for (int j = 0; j < RecipeRows[loopRowId].RecipeItems.Count; j++)
- {
- var cell = RecipeRows[loopRowId].RecipeItems[j];
- bool isLoopStart = Regex.IsMatch(cell.Value, @"^Loop\x20\d+$");
- bool isLoopEnd = Regex.IsMatch(cell.Value, @"^Loop End$");
- bool isNullOrEmpty = string.IsNullOrWhiteSpace(cell.Value);
- if (!isLoopEnd && !isLoopStart && !isNullOrEmpty)
- {
- string reason = string.Format("Value '{0}' not valid", cell.Value);
- cell.ErrInfo = reason;
- cell.Background = Brushes.Pink;
- Errors.Add(new Tuple<int, int, string, string>(loopRowId, j, cell.RecipeVariableDefine.FriendlyName, reason));
- }
- if (isLoopEnd)
- {
- string reason = "Loop Start 缺失";
- cell.ErrInfo = reason;
- cell.Background = Brushes.Pink;
- Errors.Add(new Tuple<int, int, string, string>(loopRowId, j, cell.RecipeVariableDefine.FriendlyName, reason));
- }
- else if (isLoopStart)
- {
- for (int k = j + 1; k < RecipeRows[loopRowId].RecipeItems.Count; k++)
- {
- cell = RecipeRows[loopRowId].RecipeItems[k];
- bool isCurStepLoopStart = Regex.IsMatch(cell.Value, @"^Loop\x20\d+$");
- bool isCurStepLoopEnd = Regex.IsMatch(cell.Value, @"^Loop End$");
- isNullOrEmpty = string.IsNullOrWhiteSpace(cell.Value);
- if (!isCurStepLoopEnd && !isCurStepLoopStart && !isNullOrEmpty)
- {
- string reason = string.Format("Value '{0}' not valid", cell.Value);
- cell.ErrInfo = reason;
- cell.Background = Brushes.Pink;
- Errors.Add(new Tuple<int, int, string, string>(loopRowId, k, cell.RecipeVariableDefine.FriendlyName, reason));
- }
- else if (isCurStepLoopStart)
- {
- string reason = "前面循环没有结束,不能设置新的Loop Start标志";
- cell.ErrInfo = reason;
- cell.Background = Brushes.Pink;
- Errors.Add(new Tuple<int, int, string, string>(loopRowId, k, cell.RecipeVariableDefine.FriendlyName, reason));
- }
- else if (isCurStepLoopEnd)
- {
- //mark loop steps with blue background
- for (int m1 = j; m1 <= k; m1++)
- {
- var curCell = RecipeRows[loopRowId].RecipeItems[m1];
- if (curCell.Background == Brushes.Transparent)
- curCell.Background = Brushes.LightGreen;
- curCell.InvokePropertyChanged();
- }
- j = k;
- break;
- }
- if (k == RecipeRows[loopRowId].RecipeItems.Count - 1)
- {
- j = k;
- string reason = "Loop End 缺失";
- cell.ErrInfo = reason;
- cell.Background = Brushes.Pink;
- Errors.Add(new Tuple<int, int, string, string>(loopRowId, k, cell.RecipeVariableDefine.FriendlyName, reason));
- }
- }
- }
- }
- #endregion check loop
- #region recipe parameter validation
- //using (var lua = new LuaInterface.Lua())
- //{
- // //is special recipe?
- // //bool IsSpecialRecipe = true;
- // //{
- // // int heaterModeRowIndex = RowVarNameDic["Heater.Mode"];
- // // int aZoneSetpointIndex = RowVarNameDic["AZone.Setpoint"];
- // // int bZoneSetpointIndex = RowVarNameDic["BZone.Setpoint"];
- // // int cZoneSetpointIndex = RowVarNameDic["CZone.Setpoint"];
- // // int dZoneSetpointIndex = RowVarNameDic.ContainsKey("DZone.Setpoint") ? RowVarNameDic["DZone.Setpoint"] : aZoneSetpointIndex;
- // // for (int stepIndex = 0; stepIndex < RecipeRows[0].RecipeItems.Count; stepIndex++)
- // // {
- // // if (RecipeRows[heaterModeRowIndex].RecipeItems[stepIndex].Value != "CurrentControl" ||
- // // RecipeRows[aZoneSetpointIndex].RecipeItems[stepIndex].Value != "0" ||
- // // RecipeRows[bZoneSetpointIndex].RecipeItems[stepIndex].Value != "0" ||
- // // RecipeRows[cZoneSetpointIndex].RecipeItems[stepIndex].Value != "0" ||
- // // RecipeRows[dZoneSetpointIndex].RecipeItems[stepIndex].Value != "0")
- // // {
- // // IsSpecialRecipe = false;
- // // break;
- // // }
- // // }
- // //}
- // ////set get ramp rate function
- // //lua.RegisterFunction("CheckRampRate", this, GetType().GetMethod("CheckRampRate"));
- // //lua.DoString(string.Format("IsProductionRecipe={0};",(!IsSpecialRecipe).ToString().ToLower()));
- // for (int stepIndex = 0; stepIndex < RecipeRows[0].RecipeItems.Count; stepIndex++)
- // {
- // //set stepNo
- // lua.DoString(string.Format("StepNo={0};", stepIndex));
- // //reading var from current recipe step
- // foreach (var checkVar in _checkVariables)
- // {
- // if (!RowVarNameDic.ContainsKey(checkVar))
- // {
- // System.Diagnostics.Debug.WriteLine("检查不到变量定义," + checkVar);
- // continue;
- // }
- // try
- // {
- // int varId = RowVarNameDic[checkVar];
- // if (RecipeRows[varId].RecipeItems[stepIndex].RecipeVariableDefine.CellType == CellType.NumInput)
- // lua.DoString(string.Format("{0}={1};", RecipeRows[varId].RecipeItems[stepIndex].RecipeVariableDefine.TechnicalName.Replace(".", "_"), RecipeRows[varId].RecipeItems[stepIndex].Value));
- // else
- // lua.DoString(string.Format("{0}=\"{1}\";", RecipeRows[varId].RecipeItems[stepIndex].RecipeVariableDefine.TechnicalName.Replace(".", "_"), RecipeRows[varId].RecipeItems[stepIndex].Value));
- // }
- // catch (Exception ex)
- // {
- // System.Diagnostics.Debug.WriteLine("校验异常," + ex);
- // }
- // }
- // //reading from recipe format file
- // foreach (string key in _preDefinedRecipeVars.Keys)
- // {
- // string varValueString = _preDefinedRecipeVars[key];
- // double varValue;
- // if (double.TryParse(varValueString, out varValue))
- // lua.DoString(string.Format("{0}={1};", key, varValue));
- // else
- // lua.DoString(string.Format("{0}=\"{1}\";", key, varValueString));
- // }
- // //do valation
- // foreach (var rule in _validationRules)
- // {
- // lua.DoString(string.Format("if {0} then hasErr=1 else hasErr=0 end", rule.Item2));
- // bool hasError = ((int)lua.GetNumber("hasErr")) == 1;
- // if (hasError)
- // {
- // lua.DoString(string.Format("message=string.format({0});", rule.Item3));
- // string reason = lua.GetString("message");
- // var rowId = RowVarNameDic[rule.Item1];
- // var cell = RecipeRows[rowId].RecipeItems[stepIndex];
- // cell.ErrInfo = reason;
- // cell.Background = Brushes.Pink;
- // Errors.Add(new Tuple<int, int, string, string>(rowId, stepIndex, cell.RecipeVariableDefine.FriendlyName, reason));
- // cell.InvokePropertyChanged();
- // }
- // }
- // }
- //}
- #endregion recipe parameter validation
- #region update material cell data
- int materialRowId = -1;
- for (int colId = 0; colId < RecipeRows[0].RecipeItems.Count; colId++)
- {
- string materialName = "";
- for (int rowId = 0; rowId < RecipeRows.Count; rowId++)
- {
- string curMo = "";
- if (materialRowId == -1 && RecipeRows[rowId].RecipeItems[colId].RecipeVariableDefine.TechnicalName == "Material")
- {
- materialRowId = rowId;
- }
- var cell = RecipeRows[rowId].RecipeItems[colId];
- if (cell.RecipeVariableDefine.CellType == CellType.ReadOnlySelection && String.Compare(cell.Value, "flow", true) == 0)
- {
- string moName = cell.RecipeVariableDefine.TechnicalName.Split('.')[0].ToLower();
- string displayName = cell.RecipeVariableDefine.FriendlyName.Replace("_", ".").Split('.')[0].ToLower();
- if (moName.Contains("cp2mg_1") || displayName.Contains("cp2mg_1")) curMo = "Mg1";
- else if (moName.Contains("cp2mg_2") || displayName.Contains("cp2mg_2")) curMo = "Mg2";
- else if (moName.Contains("cp2mg_3") || displayName.Contains("cp2mg_3")) curMo = "Mg3";
- else if (moName.Contains("cp2mg_4") || displayName.Contains("cp2mg_4")) curMo = "Mg4";
- else if (moName.Contains("cp2mg") || displayName.Contains("cp2mg")) curMo = "Mg";
- else if (moName.Contains("tmin") || displayName.Contains("tmin")) curMo = "In";
- else if (moName.Contains("tmin_1") || displayName.Contains("tmin_1")) curMo = "In1";
- else if (moName.Contains("tmin_2") || displayName.Contains("tmin_2")) curMo = "In2";
- else if (moName.Contains("tmin_3") || displayName.Contains("tmin_3")) curMo = "In3";
- else if (moName.Contains("tmin_4") || displayName.Contains("tmin_4")) curMo = "In4";
- else if (moName.Contains("tmga") || displayName.Contains("tmga")) curMo = "TMG";
- else if (moName.Contains("tmga_1") || displayName.Contains("tmga_1")) curMo = "TMG1";
- else if (moName.Contains("tmga_2") || displayName.Contains("tmga_2")) curMo = "TMG2";
- else if (moName.Contains("tmga_3") || displayName.Contains("tmga_3")) curMo = "TMG3";
- else if (moName.Contains("tmga_4") || displayName.Contains("tmga_4")) curMo = "TMG4";
- else if (moName.Contains("tega") || displayName.Contains("tega")) curMo = "TEG";
- else if (moName.Contains("tega_1") || displayName.Contains("tega_1")) curMo = "TEG1";
- else if (moName.Contains("tega_2") || displayName.Contains("tega_2")) curMo = "TEG2";
- else if (moName.Contains("tega_3") || displayName.Contains("tega_3")) curMo = "TEG3";
- else if (moName.Contains("tega_4") || displayName.Contains("tega_4")) curMo = "TEG4";
- else if (moName.Contains("tmal") || displayName.Contains("tmal")) curMo = "TAl";
- else if (moName.Contains("tmal_1") || displayName.Contains("tmal_1")) curMo = "TAl1";
- else if (moName.Contains("tmal_2") || displayName.Contains("tmal_2")) curMo = "TAl2";
- else if (moName.Contains("tmal_3") || displayName.Contains("tmal_3")) curMo = "TAl3";
- else if (moName.Contains("tmal_4") || displayName.Contains("tmal_4")) curMo = "TAl4";
- else if (moName.Contains("nh3source") || displayName.Contains("nh3source")) curMo = "NH3";
- else if (moName.Contains("si")) curMo = "Si";
- if (!string.IsNullOrEmpty(curMo))
- {
- if (string.IsNullOrEmpty(materialName))
- materialName = curMo;
- else
- materialName += "|" + curMo;
- }
- }
- }
- if (materialRowId >= 0)
- {
- RecipeRows[materialRowId].RecipeItems[colId].Value = materialName;
- RecipeRows[materialRowId].RecipeItems[colId].InvokePropertyChanged();
- }
- }
- #endregion update material cell data
- #region update column header
- if (DataGridControl.Columns.Count - 1 == RecipeRows[0].RecipeItems.Count)
- {
- var redColHeader = (DataTemplate)DataGridControl.FindResource("columnRedTitleTemplate");
- var blackColHeader = (DataTemplate)DataGridControl.FindResource("columnBlackTitleTemplate");
- for (int j = 0; j < RecipeRows[0].RecipeItems.Count; j++)
- {
- DataGridControl.Columns[j + 1].Title = string.Format("{0}|{2}\r\n{1}", j + 1, RecipeRows[0].RecipeItems[j].Value, RecipeRows[2].RecipeItems[j].Value);
- if (Errors.Find((o) => o.Item2 == j) != null)
- DataGridControl.Columns[j + 1].TitleTemplate = redColHeader;
- else
- DataGridControl.Columns[j + 1].TitleTemplate = blackColHeader;
- }
- }
- #endregion update column header
- #region if running state, highlight current running step, move horizontal bar to current running step
- if (CurrentRunningStepNo > 0 && DataGridControl.Columns.Count > 2)
- {
- for (int rowId = 0; rowId < RecipeRows.Count; rowId++)
- {
- for (int colId = 0; colId < RecipeRows[0].RecipeItems.Count; colId++)
- {
- var cell = RecipeRows[rowId].RecipeItems[colId];
- if (colId + 1 == CurrentRunningStepNo)
- {
- cell.IsRunning = true;
- }
- else
- {
- cell.IsRunning = false;
- }
- cell.InvokePropertyChanged("IsRunning");
- }
- }
- if (moving2RunningStepPosition)
- {
- Task.Factory.StartNew(() =>
- {
- System.Threading.Thread.Sleep(200);
- DataGridControl.Dispatcher.Invoke(new Action(() =>
- {
- double singleWidth = DataGridControl.Columns[1].Width;
- double horizontalOffset = (CurrentRunningStepNo - 2) * singleWidth;
- if (DataGridControl.ScrollViewer != null)
- {
- if (horizontalOffset > DataGridControl.ScrollViewer.ScrollableWidth)
- horizontalOffset = DataGridControl.ScrollViewer.ScrollableWidth;
- if (horizontalOffset < 0)
- horizontalOffset = 0;
- DataGridControl.ScrollViewer.ScrollToHorizontalOffset(horizontalOffset);
- }
- }));
- });
- }
- }
- #endregion if running state, highlight current running step, move horizontal bar to current running step
- //calc recipe time
- CalcRecipeTime();
- //invoke property
- InvokePropertyChanged("Errors");
- }
- catch (Exception ex)
- {
- MessageBox.Show("工艺程序校验出错!\r\n\r\n" + ex.Message, "出错", MessageBoxButton.OK, MessageBoxImage.Error);
- System.Diagnostics.Debug.WriteLine(ex.Message);
- }
- }
- /// <summary>
- /// reload datagrid content
- /// </summary>
- private void RefreshDataGrid()
- {
- try
- {
- //generate columns in Grid
- DataGridControl.CurrentColumn = null;
- if (DataGridControl.Columns.Count > 0)
- DataGridControl.Columns.Clear();
- var template = (DataTemplate)DataGridControl.FindResource("CustomTemplate");
- var rowTemplate = (DataTemplate)DataGridControl.FindResource("RowHeadTemplate");
- DataGridControl.Columns.Add(new Xceed.Wpf.DataGrid.Column()
- {
- Width = 140,
- Title = " ",
- FieldName = ".",
- CellContentTemplate = rowTemplate
- });
- var cellEditor = DataGridControl.DefaultCellEditors[typeof(SmartCellData)];// DefaultCellEditorSelector.SelectCellEditor(typeof(SmartCellData));
- for (int index = 0; index < RecipeRows[0].RecipeItems.Count; index++)
- {
- //var col = new Xceed.Wpf.DataGrid.Column();
- DataGridControl.Columns.Add(new Xceed.Wpf.DataGrid.Column()
- {
- Title = string.Format("【{0}】\r\n{1}", index + 1, RecipeRows[0].RecipeItems[index].Value),
- FieldName = string.Format("RecipeItems[{0}]", index),
- CellContentTemplate = template,
- AllowSort = false,
- Width = 120,
- MaxWidth = 120,
- CellEditor = cellEditor
- });
- }
- InvokePropertyChanged("RecipeRows");
- InvokePropertyChanged("RecipeHead");
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- }
- }
- /// <summary>
- /// calc recipe total time
- /// </summary>
- private void CalcRecipeTime()
- {
- int timeStepRowId = -1;
- int loopStepRowId = -1;
- for (int i = 0; i < RecipeRows.Count; i++)
- {
- if (RecipeRows[i].TechnicalName == "Time")
- timeStepRowId = i;
- if (RecipeRows[i].TechnicalName == "Loop")
- loopStepRowId = i;
- if (loopStepRowId != -1 && timeStepRowId != -1)
- break;
- }
- TimeSpan tspan = new TimeSpan();
- for (int stepNo = 0; stepNo < RecipeRows[timeStepRowId].RecipeItems.Count; stepNo++)
- {
- string loopStr = RecipeRows[loopStepRowId].RecipeItems[stepNo].Value;
- bool isLoopStart = Regex.IsMatch(loopStr, @"^Loop\x20\d+$");
- if (isLoopStart)
- {
- int loopNum = int.Parse(loopStr.ToLower().Replace("loop", "").Replace(" ", ""));
- TimeSpan ts = new TimeSpan();
- for (int innerStepNo = stepNo; innerStepNo < RecipeRows[timeStepRowId].RecipeItems.Count; innerStepNo++)
- {
- loopStr = RecipeRows[loopStepRowId].RecipeItems[innerStepNo].Value;
- stepNo = innerStepNo;
- string timeDuration = RecipeRows[timeStepRowId].RecipeItems[innerStepNo].Value;
- string[] timeArr = timeDuration.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
- if (timeArr.Length == 3)
- {
- int h, mi, s;
- if (int.TryParse(timeArr[0], out h) && int.TryParse(timeArr[1], out mi) && int.TryParse(timeArr[2], out s))
- {
- var tt = new TimeSpan(h, mi, s);
- ts += tt;
- }
- }
- bool isLoopEnd = Regex.IsMatch(loopStr, @"^Loop End$");
- if (isLoopEnd)
- {
- tspan += new TimeSpan(ts.Ticks * loopNum);
- break;
- }
- }
- }
- else
- {
- string timeDuration = RecipeRows[timeStepRowId].RecipeItems[stepNo].Value;
- string[] timeArr = timeDuration.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
- if (timeArr.Length == 3)
- {
- int h, mi, s;
- if (int.TryParse(timeArr[0], out h) && int.TryParse(timeArr[1], out mi) && int.TryParse(timeArr[2], out s))
- {
- var ts = new TimeSpan(h, mi, s);
- tspan += ts;
- }
- }
- }
- }
- RecipeInfo = string.Format("共{0}步,总时间{1}:{2}:{3}", RecipeRows[0].RecipeItems.Count, (int)tspan.TotalHours, tspan.Minutes.ToString("00"), tspan.Seconds.ToString("00"));
- InvokePropertyChanged("RecipeInfo");
- }
- #region INotifyPropertyChanged
- public event PropertyChangedEventHandler PropertyChanged;
- public void InvokePropertyChanged(string propertyName)
- {
- if (PropertyChanged != null)
- {
- PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
- }
- #endregion INotifyPropertyChanged
- }
- public class RecipeRow
- {
- private ObservableCollection<SmartCellData> _recipeItems = new ObservableCollection<SmartCellData>();
- public RecipeRow(params SmartCellData[] vars)
- {
- foreach (var var in vars)
- _recipeItems.Add(var);
- }
- public string CatalogName { get; set; }
- public string FriendlyName { get; set; }
- public string TechnicalName { get; set; }
- public ObservableCollection<SmartCellData> RecipeItems
- {
- get { return _recipeItems; }
- set { _recipeItems = value; }
- }
- }
- /// <summary>
- /// Recipe head
- /// </summary>
- public class RecipeHead
- {
- public string RecipeVariation { get; set; }
- public string CreationTime { get; set; }
- public string LastRevisionTime { get; set; }
- public string CreatedBy { get; set; }
- public string LastModifiedBy { get; set; }
- public string PressureMode { get; set; }
- public string Description { get; set; }
- public string BasePressure
- {
- get; set;
- }
- public string PumpDownLimit
- {
- get; set;
- }
- public string PurgeActive
- {
- get; set;
- }
- public string NotToPurgeOrVent
- {
- get; set;
- }
- public string Barcode
- {
- get; set;
- }
- public string SubstrateTemp
- {
- get; set;
- }
- public string PumpingPinState
- {
- get; set;
- }
- public string VentingPinState
- {
- get; set;
- }
- public string PinDownPressure
- {
- get; set;
- }
- }
- public class EndPointConfigItem : INotifyPropertyChanged
- {
- public event PropertyChangedEventHandler PropertyChanged;
- public void InvokePropertyChanged(string propertyName)
- {
- if (PropertyChanged != null)
- {
- PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
- }
- public string ExposureTime { get; set; }
- public string WaveLengthA { get; set; }
- public string BinningA { get; set; }
- public string WaveLengthB { get; set; }
- public string BinningB { get; set; }
- public string WaveLengthC { get; set; }
- public string BinningC { get; set; }
- public string WaveLengthD { get; set; }
- public string BinningD { get; set; }
- public string Fd { get; set; }
- public string PrefilterTime { get; set; }
- public string PostfilterTime { get; set; }
- public string AlgorithmType { get; set; }
- public string Criteria { get; set; }
- public string DelayTime { get; set; }
- public string ValidationTime { get; set; }
- public string ValidationValue { get; set; }
- public string TimeWindow { get; set; }
- public string MinimalTime { get; set; }
- public string PostponeTime { get; set; }
- public bool Control { get; set; }
- public bool Normalization { get; set; }
- public bool EnablePostponePercent { get; set; }
- public bool EnableCriterialPercent { get; set; }
- public bool EnableEventTrigger { get; set; }
- public bool IsFaultIfNoTrigger { get; set; }
- public string ToValue()
- {
- return
- $@"ExposureTime={ExposureTime};WaveLengthA={WaveLengthA};BinningA={BinningA};WaveLengthB={WaveLengthB};" +
- $@"BinningB={BinningB};WaveLengthC={WaveLengthC};BinningC={BinningC};WaveLengthD={WaveLengthD};BinningD={BinningD};Fd={Fd};" +
- $@"PrefilterTime={PrefilterTime};PostfilterTime={PostfilterTime};AlgorithmType={AlgorithmType};Criteria={Criteria};DelayTime={DelayTime};ValidationTime={ValidationTime};" +
- $@"ValidationValue={ValidationValue};TimeWindow={TimeWindow};MinimalTime={MinimalTime};PostponeTime={PostponeTime};Control={Control};Normalization={Normalization};" +
- $@"EnablePostponePercent={EnablePostponePercent};EnableCriterialPercent={EnableCriterialPercent};EnableEventTrigger={EnableEventTrigger};IsFaultIfNoTrigger={IsFaultIfNoTrigger};"
- ;
- }
- public void SetValue(string config)
- {
- if (string.IsNullOrEmpty(config))
- return;
- string[] items = config.Split(';');
- foreach (var item in items)
- {
- if (string.IsNullOrEmpty(item))
- continue;
- string[] pairs = item.Split('=');
- if (pairs.Length != 2)
- continue;
- Parallel.ForEach(this.GetType().GetProperties(),
- property =>
- {
- PropertyInfo pi = (PropertyInfo) property;
- if (pi.Name == pairs[0])
- {
- try
- {
- var convertedValue = Convert.ChangeType(pairs[1], pi.PropertyType);
- var originValue = Convert.ChangeType(pi.GetValue(this, null), pi.PropertyType);
- if (originValue != convertedValue)
- {
- pi.SetValue(this, convertedValue, null);
- }
- }
- catch (Exception)
- {
- }
- }
- });
- }
- }
- }
- }
|