| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400 | 
							- using Aitex.Core.RT.Log;
 
- using Caliburn.Micro;
 
- using Caliburn.Micro.Core;
 
- using MECF.Framework.Common.CommonData;
 
- using MECF.Framework.Common.DataCenter;
 
- using MECF.Framework.UI.Client.CenterViews.Editors.Sequence;
 
- using MECF.Framework.UI.Client.ClientBase;
 
- using OpenSEMI.ClientBase;
 
- using OpenSEMI.ClientBase.Command;
 
- using RecipeEditorLib.DGExtension.CustomColumn;
 
- using RecipeEditorLib.RecipeModel.Params;
 
- using System;
 
- using System.Collections.Generic;
 
- using System.Collections.ObjectModel;
 
- using System.Linq;
 
- using System.Windows;
 
- using System.Windows.Controls;
 
- using System.Windows.Input;
 
- using System.Windows.Media;
 
- namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe
 
- {
 
-     public class ProcessTypeFileItem : NotifiableItem
 
-     {
 
-         public string ProcessType { get; set; }
 
-         public ObservableCollection<FileNode> FileListByProcessType { get; set; }
 
-         public ProcessTypeFileItem()
 
-         {
 
-             FileListByProcessType = new ObservableCollection<FileNode>();
 
-         }
 
-     }
 
-     public class ChamberTypeItem : NotifiableItem
 
-     {
 
-         public string ChamberType { get; set; }
 
-         public ObservableCollection<ProcessTypeFileItem> FileListByChamberType { get; set; }
 
-         public ChamberTypeItem()
 
-         {
 
-             FileListByChamberType = new ObservableCollection<ProcessTypeFileItem>();
 
-         }
 
-     }
 
-     public class RecipeEditorViewModel : BaseModel
 
-     {
 
-         public bool IsPermission { get => this.Permission == 3; }//&& RtStatus != "AutoRunning";
 
-         private ICommand _RenameFolderCommand;
 
-         public ICommand RenameFolderCommand
 
-         {
 
-             get
 
-             {
 
-                 if (this._RenameFolderCommand == null)
 
-                     this._RenameFolderCommand = new BaseCommand(() => this.RenameFolder());
 
-                 return this._RenameFolderCommand;
 
-             }
 
-         }
 
-         private ICommand _DeleteFolderCommand;
 
-         public ICommand DeleteFolderCommand
 
-         {
 
-             get
 
-             {
 
-                 if (this._DeleteFolderCommand == null)
 
-                     this._DeleteFolderCommand = new BaseCommand(() => this.DeleteFolder());
 
-                 return this._DeleteFolderCommand;
 
-             }
 
-         }
 
-         private ICommand _NewFolderCommand;
 
-         public ICommand NewFolderCommand
 
-         {
 
-             get
 
-             {
 
-                 if (this._NewFolderCommand == null)
 
-                     this._NewFolderCommand = new BaseCommand(() => this.NewFolder());
 
-                 return this._NewFolderCommand;
 
-             }
 
-         }
 
-         private ICommand _NewFolderRootCommand;
 
-         public ICommand NewFolderRootCommand
 
-         {
 
-             get
 
-             {
 
-                 if (this._NewFolderRootCommand == null)
 
-                     this._NewFolderRootCommand = new BaseCommand(() => this.NewFolderRoot());
 
-                 return this._NewFolderRootCommand;
 
-             }
 
-         }
 
-         private ICommand _NewRecipeCommand;
 
-         public ICommand NewRecipeCommand
 
-         {
 
-             get
 
-             {
 
-                 if (this._NewRecipeCommand == null)
 
-                     this._NewRecipeCommand = new BaseCommand(() => this.NewRecipe());
 
-                 return this._NewRecipeCommand;
 
-             }
 
-         }
 
-         private ICommand _NewRecipeRootCommand;
 
-         public ICommand NewRecipeRootCommand
 
-         {
 
-             get
 
-             {
 
-                 if (this._NewRecipeRootCommand == null)
 
-                     this._NewRecipeRootCommand = new BaseCommand(() => this.NewRecipeRoot());
 
-                 return this._NewRecipeRootCommand;
 
-             }
 
-         }
 
-         private ICommand _RenameRecipeCommand;
 
-         public ICommand RenameRecipeCommand
 
-         {
 
-             get
 
-             {
 
-                 if (this._RenameRecipeCommand == null)
 
-                     this._RenameRecipeCommand = new BaseCommand(() => this.RenameRecipe());
 
-                 return this._RenameRecipeCommand;
 
-             }
 
-         }
 
-         private ICommand _DeleteRecipeCommand;
 
-         public ICommand DeleteRecipeCommand
 
-         {
 
-             get
 
-             {
 
-                 if (this._DeleteRecipeCommand == null)
 
-                     this._DeleteRecipeCommand = new BaseCommand(() => this.DeleteRecipe());
 
-                 return this._DeleteRecipeCommand;
 
-             }
 
-         }
 
-         private ICommand _SaveAsRecipeCommand;
 
-         public ICommand SaveAsRecipeCommand
 
-         {
 
-             get
 
-             {
 
-                 if (this._SaveAsRecipeCommand == null)
 
-                     this._SaveAsRecipeCommand = new BaseCommand(() => this.SaveAsRecipe());
 
-                 return this._SaveAsRecipeCommand;
 
-             }
 
-         }
 
-         public ObservableCollection<ProcessTypeFileItem> ProcessTypeFileList { get; set; }
 
-         public RecipeData CurrentRecipe { get; private set; }
 
-         public FileNode CurrentFileNode { get; set; }
 
-         private bool IsChanged
 
-         {
 
-             get
 
-             {
 
-                 return editMode == EditMode.Edit || CurrentRecipe.IsChanged;
 
-             }
 
-         }
 
-         public ObservableCollection<EditorDataGridTemplateColumnBase> Columns { get; set; }
 
-         public Dictionary<string, ObservableCollection<Param>> PopSettingColumns { get; set; }
 
-         public ObservableCollection<EditorDataGridTemplateColumnBase> ColumnsTolerance { get; set; }
 
-         public Dictionary<string, ObservableCollection<EditorDataGridTemplateColumnBase>> DicColunms { get; set; }
 
-         public bool EnableNew { get; set; }
 
-         public bool EnableReName { get; set; }
 
-         public bool EnableCopy { get; set; }
 
-         public bool EnableDelete { get; set; }
 
-         public bool EnableSave { get; set; }
 
-         public bool EnableStep { get; set; }
 
-         public bool EnableReload { get; set; }
 
-         public bool EnableSaveToAll { get; set; }
 
-         public bool EnableSaveTo { get; set; }
 
-         private RecipeFormatBuilder _columnBuilder = new RecipeFormatBuilder();
 
-         private EditMode editMode;
 
-         private RecipeProvider _recipeProvider = new RecipeProvider();
 
-         public ObservableCollection<string> ChamberType { get; set; }
 
-         public int ChamberTypeIndexSelection { get; set; }
 
-         public int ProcessTypeIndexSelection { get; set; }
 
-         public string CurrentChamberType
 
-         {
 
-             get
 
-             {
 
-                 return ChamberType[ChamberTypeIndexSelection];
 
-             }
 
-         }
 
-         public string CurrentProcessType
 
-         {
 
-             get
 
-             {
 
-                 return ProcessTypeFileList[ProcessTypeIndexSelection].ProcessType;
 
-             }
 
-         }
 
-         public Visibility MultiChamberVisibility
 
-         {
 
-             get;
 
-             set;
 
-         }
 
-         public Visibility ToleranceVisibility
 
-         {
 
-             get;
 
-             set;
 
-         }
 
-         public ObservableCollection<string> Chambers { get; set; }
 
-         public string SelectedChamber { get; set; }
 
-         public object View { get; set; }
 
-         protected override void OnInitialize()
 
-         {
 
-             base.OnInitialize();
 
-             var chamberType = QueryDataClient.Instance.Service.GetConfig("System.Recipe.RecipeChamberType");
 
-             if (chamberType == null)
 
-             {
 
-                 ChamberType = new ObservableCollection<string>() { "Default" };
 
-             }
 
-             else
 
-             {
 
-                 ChamberType = new ObservableCollection<string>(((string)(chamberType)).Split(','));
 
-             }
 
-             ChamberTypeIndexSelection = 0;
 
-             //Etch:Process,Clean,Chuck,Dechuck;CVD:Process,Clean;
 
-             var processType = QueryDataClient.Instance.Service.GetConfig("System.Recipe.SupportedProcessType");
 
-             if (processType == null)
 
-             {
 
-                 processType = "Process";
 
-             }
 
-             ProcessTypeFileList = new ObservableCollection<ProcessTypeFileItem>();
 
-             string[] recipeProcessType = ((string)processType).Split(',');
 
-             for (int i = 0; i < recipeProcessType.Length; i++)
 
-             {
 
-                 var type = new ProcessTypeFileItem();
 
-                 type.ProcessType = recipeProcessType[i];
 
-                 var prefix = $"{ChamberType[ChamberTypeIndexSelection]}\\{recipeProcessType[i]}";
 
-                 // var recipes = _recipeProvider.GetXmlRecipeList(prefix);
 
-                 type.FileListByProcessType = RecipeSequenceTreeBuilder.GetFileNodeParameterList(prefix);//RecipeSequenceTreeBuilder.BuildFileNode(prefix, "", false, recipes)[0].Files;
 
-                 ProcessTypeFileList.Add(type);
 
-             }
 
-             DicColunms = new Dictionary<string, ObservableCollection<EditorDataGridTemplateColumnBase>>();
 
-             UpdateRecipeFormat();
 
-         }
 
-         protected override void OnActivate()
 
-         {
 
-             base.OnActivate();
 
-         }
 
-         protected override void OnDeactivate(bool close)
 
-         {
 
-             base.OnDeactivate(close);
 
-             if (this.IsChanged)
 
-             {
 
-                 if (DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No, DialogType.CONFIRM, $"Recipe {CurrentRecipe.Name} content is changed, do you want to save it?") == DialogButton.Yes)
 
-                 {
 
-                     this.SaveRecipe();
 
-                 }
 
-             }
 
-         }
 
-         protected override void OnViewLoaded(object view)
 
-         {
 
-             View = view;
 
-             base.OnViewLoaded(view);
 
-             RecipeFormatBuilder.ApplyTemplate((UserControl)view, this.Columns);
 
-             RecipeEditorView u = (RecipeEditorView)view;
 
-             u.dgCustom.Columns.Clear();
 
-             u.ToleranceGrid.Columns.Clear();
 
-             this.Columns.Apply((c) =>
 
-             {
 
-                 c.Header = c;
 
-                 u.dgCustom.Columns.Add(c);
 
-             });
 
-             RecipeFormatBuilder.ApplyTemplate((UserControl)view, this.ColumnsTolerance);
 
-             ColumnsTolerance.Apply((c) =>
 
-             {
 
-                 c.Header = c;
 
-                 u.ToleranceGrid.Columns.Add(c);
 
-             });
 
-             u.dgCustom.ItemsSource = this.CurrentRecipe.Steps;
 
-             u.ToleranceGrid.ItemsSource = this.CurrentRecipe.StepTolerances;
 
-         }
 
-         public void TabSelectionChanged()
 
-         {
 
-             UpdateRecipeFormat();
 
-             OnViewLoaded(View);
 
-         }
 
-         public void UpdateRecipeFormat()
 
-         {
 
-             if (DicColunms.Keys.Contains(CurrentProcessType))
 
-             {
 
-                 this.Columns = DicColunms[CurrentProcessType];
 
-             }
 
-             else
 
-             {
 
-                 this.Columns = this._columnBuilder.Build(CurrentProcessType);
 
-                 DicColunms[CurrentProcessType] = this.Columns;
 
-             }
 
-             int indexOthers = this.Columns.IndexOf(this.Columns.Where(x => x.DisplayName == "Others").FirstOrDefault());
 
-             ColumnsTolerance = new ObservableCollection<EditorDataGridTemplateColumnBase>(
 
-                 this.Columns.Take(indexOthers));
 
-             this.CurrentRecipe = new RecipeData();
 
-             CurrentRecipe.RecipeChamberType = _columnBuilder.RecipeChamberType;
 
-             CurrentRecipe.RecipeVersion = _columnBuilder.RecipeVersion;
 
-             this.PopSettingColumns = new Dictionary<string, ObservableCollection<Param>>();
 
-             this.PopSettingColumns.Add("Oes", _columnBuilder.OesConfig);
 
-             this.PopSettingColumns.Add("Vat", _columnBuilder.VatConfig);
 
-             this.PopSettingColumns.Add("FineTuning", _columnBuilder.FineTuningConfig);
 
-             CurrentRecipe.PopEnable.Add("Oes", _columnBuilder.OesConfig.Count > 0);
 
-             CurrentRecipe.PopEnable.Add("Vat", _columnBuilder.VatConfig.Count > 0);
 
-             CurrentRecipe.PopEnable.Add("FineTuning", _columnBuilder.FineTuningConfig.Count > 0);
 
-             CurrentRecipe.ToleranceEnable = Columns.FirstOrDefault(x => x.EnableTolerance) != null;
 
-             this.editMode = EditMode.None;
 
-             var chamber = QueryDataClient.Instance.Service.GetConfig("System.Recipe.ChamberModules");
 
-             if (chamber == null)
 
-             {
 
-                 chamber = "PM1";
 
-             }
 
-             Chambers = new ObservableCollection<string>(((string)chamber).Split(','));
 
-             SelectedChamber = Chambers[0];
 
-             MultiChamberVisibility = Chambers.Count > 1 ? Visibility.Visible : Visibility.Collapsed;
 
-             ToleranceVisibility = CurrentRecipe.ToleranceEnable ? Visibility.Visible : Visibility.Collapsed;
 
-         }
 
-         public void ChamberSelectionChanged()
 
-         {
 
-             if (IsChanged)
 
-             {
 
-                 var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No,
 
-                     DialogType.CONFIRM,
 
-                     $"Recipe {CurrentRecipe.Name} is changed, do you want to save it?");
 
-                 if (selection == DialogButton.Yes)
 
-                 {
 
-                     this.CurrentRecipe.Revisor = BaseApp.Instance.UserContext.LoginName;
 
-                     this.CurrentRecipe.ReviseTime = DateTime.Now;
 
-                     this.Save(this.CurrentRecipe, false);
 
-                 }
 
-             }
 
-             CurrentRecipe.ChangeChamber(Columns, PopSettingColumns
 
-                 , _columnBuilder.Configs, SelectedChamber);
 
-         }
 
-         public void TreeSelectChanged(FileNode node)
 
-         {
 
-             if (IsChanged)
 
-             {
 
-                 var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No,
 
-                     DialogType.CONFIRM,
 
-                     $"Recipe {CurrentRecipe.Name} is changed, do you want to save it?");
 
-                 if (selection == DialogButton.Yes)
 
-                 {
 
-                     this.CurrentRecipe.Revisor = BaseApp.Instance.UserContext.LoginName;
 
-                     this.CurrentRecipe.ReviseTime = DateTime.Now;
 
-                     this.Save(this.CurrentRecipe, false);
 
-                 }
 
-             }
 
-             CurrentFileNode = node;
 
-             if (node != null && node.IsFile)
 
-             {
 
-                 this.LoadData(node.PrefixPath, node.FullPath);
 
-             }
 
-             else
 
-             {
 
-                 this.ClearData();
 
-                 this.editMode = EditMode.None;
 
-             }
 
-             this.UpdateView();
 
-         }
 
-         #region folder
 
-         public void NewFolder()
 
-         {
 
-             if (IsChanged)
 
-             {
 
-                 var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No | DialogButton.Cancel, DialogType.CONFIRM, $"Recipe {CurrentRecipe.Name} is changed, do you want to save it?");
 
-                 if (selection == DialogButton.Cancel)
 
-                     return;
 
-                 if (selection == DialogButton.Yes)
 
-                 {
 
-                     this.CurrentRecipe.Revisor = BaseApp.Instance.UserContext.LoginName;
 
-                     this.CurrentRecipe.ReviseTime = DateTime.Now;
 
-                     this.Save(this.CurrentRecipe, false);
 
-                 }
 
-             }
 
-             InputFileNameDialogViewModel dialog = new InputFileNameDialogViewModel("Input New Folder Name");
 
-             dialog.FileName = "new folder";
 
-             WindowManager wm = new WindowManager();
 
-             bool? dialogReturn = wm.ShowDialog(dialog);
 
-             if (!dialogReturn.HasValue || !dialogReturn.Value)
 
-                 return;
 
-             string name = dialog.FileName.Trim();
 
-             if (string.IsNullOrEmpty(name))
 
-             {
 
-                 DialogBox.ShowWarning("Folder name should not be empty");
 
-                 return;
 
-             }
 
-             string prefix = ChamberType[ChamberTypeIndexSelection] + "\\" + ProcessTypeFileList[ProcessTypeIndexSelection].ProcessType;
 
-             string processType = string.Empty;
 
-             string newFolder = string.Empty;
 
-             if (CurrentFileNode != null)
 
-             {
 
-                 prefix = CurrentFileNode.PrefixPath;
 
-                 string folder = CurrentFileNode.FullPath;
 
-                 if (CurrentFileNode.IsFile)
 
-                 {
 
-                     folder = folder.Substring(0, folder.LastIndexOf("\\") + 1);
 
-                     if (!string.IsNullOrEmpty(folder))
 
-                         newFolder = folder;
 
-                 }
 
-                 else
 
-                 {
 
-                     newFolder = folder + "\\";
 
-                 }
 
-             }
 
-             newFolder = newFolder + name;
 
-             if (IsExist(newFolder, false))
 
-             {
 
-                 DialogBox.ShowWarning($"Can not create folder {newFolder}, Folder with the same name already exist.");
 
-                 return;
 
-             }
 
-             if (newFolder.Length > 200)
 
-             {
 
-                 DialogBox.ShowWarning($"Can not create folder {newFolder}, Folder name too long, should be less 200.");
 
-                 return;
 
-             }
 
-             _recipeProvider.CreateRecipeFolder(prefix, newFolder);
 
-             ReloadRecipeFileList(CurrentChamberType, CurrentProcessType, newFolder, true);
 
-         }
 
-         public void NewFolderRoot()
 
-         {
 
-             if (IsChanged)
 
-             {
 
-                 var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No | DialogButton.Cancel, DialogType.CONFIRM, $"Recipe {CurrentRecipe.Name} is changed, do you want to save it?");
 
-                 if (selection == DialogButton.Cancel)
 
-                     return;
 
-                 if (selection == DialogButton.Yes)
 
-                 {
 
-                     this.CurrentRecipe.Revisor = BaseApp.Instance.UserContext.LoginName;
 
-                     this.CurrentRecipe.ReviseTime = DateTime.Now;
 
-                     this.Save(this.CurrentRecipe, false);
 
-                 }
 
-             }
 
-             InputFileNameDialogViewModel dialog = new InputFileNameDialogViewModel("Input New Folder Name");
 
-             dialog.FileName = "new folder";
 
-             WindowManager wm = new WindowManager();
 
-             bool? dialogReturn = wm.ShowDialog(dialog);
 
-             if (!dialogReturn.HasValue || !dialogReturn.Value)
 
-                 return;
 
-             string name = dialog.FileName.Trim();
 
-             if (string.IsNullOrEmpty(name))
 
-             {
 
-                 DialogBox.ShowWarning("Folder name should not be empty");
 
-                 return;
 
-             }
 
-             if (IsExist(name, false))
 
-             {
 
-                 DialogBox.ShowWarning($"Can not create folder {name}, Folder with the same name already exist.");
 
-                 return;
 
-             }
 
-             if (name.Length > 200)
 
-             {
 
-                 DialogBox.ShowWarning($"Can not create folder {name}, Folder name too long, should be less 200.");
 
-                 return;
 
-             }
 
-             string prefix = ChamberType[ChamberTypeIndexSelection] + "\\" + ProcessTypeFileList[ProcessTypeIndexSelection].ProcessType;
 
-             _recipeProvider.CreateRecipeFolder(prefix, name);
 
-             ReloadRecipeFileList(CurrentChamberType, CurrentProcessType, name, true);
 
-         }
 
-         public void DeleteFolder()
 
-         {
 
-             if (CurrentFileNode == null || CurrentFileNode.IsFile)
 
-                 return;
 
-             if (CurrentFileNode.Files.Count > 0)
 
-             {
 
-                 DialogBox.ShowWarning($"Can not delete non-empty folder, Remove the files or folders under \r\n{CurrentFileNode.FullPath}.");
 
-                 return;
 
-             }
 
-             var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No, DialogType.CONFIRM,
 
-                 $"Are you sure you want to delete \r\n {CurrentFileNode.FullPath}?");
 
-             if (selection == DialogButton.No)
 
-                 return;
 
-             string nextFocus = CurrentFileNode.Parent.FullPath;
 
-             bool isFolder = true;
 
-             if (CurrentFileNode.Parent.Files.Count > 1)
 
-             {
 
-                 for (int i = 0; i < CurrentFileNode.Parent.Files.Count; i++)
 
-                 {
 
-                     if (CurrentFileNode.Parent.Files[i] == CurrentFileNode)
 
-                     {
 
-                         if (i == 0)
 
-                         {
 
-                             nextFocus = CurrentFileNode.Parent.Files[i + 1].FullPath;
 
-                             isFolder = !CurrentFileNode.Parent.Files[i + 1].IsFile;
 
-                         }
 
-                         else
 
-                         {
 
-                             nextFocus = CurrentFileNode.Parent.Files[i - 1].FullPath;
 
-                             isFolder = !CurrentFileNode.Parent.Files[i - 1].IsFile;
 
-                         }
 
-                     }
 
-                 }
 
-             }
 
-             _recipeProvider.DeleteRecipeFolder(CurrentFileNode.PrefixPath, CurrentFileNode.FullPath);
 
-             ReloadRecipeFileList(CurrentChamberType, CurrentProcessType, nextFocus, isFolder);
 
-         }
 
-         public void RenameFolder()
 
-         {
 
-             if (CurrentFileNode == null || CurrentFileNode.IsFile)
 
-                 return;
 
-             InputFileNameDialogViewModel dialog = new InputFileNameDialogViewModel("Input New Folder Name");
 
-             dialog.FileName = CurrentFileNode.Name;
 
-             WindowManager wm = new WindowManager();
 
-             bool? dialogReturn = wm.ShowDialog(dialog);
 
-             if (!dialogReturn.HasValue || !dialogReturn.Value)
 
-                 return;
 
-             string name = dialog.FileName.Trim();
 
-             if (string.IsNullOrEmpty(name))
 
-                 return;
 
-             string newFolder = CurrentFileNode.FullPath.Substring(0, CurrentFileNode.FullPath.LastIndexOf("\\") + 1);
 
-             if (!string.IsNullOrEmpty(newFolder))
 
-                 newFolder = newFolder + name;
 
-             else
 
-                 newFolder = name;
 
-             if (newFolder == CurrentFileNode.FullPath)
 
-                 return;
 
-             if (IsExist(newFolder, false))
 
-             {
 
-                 DialogBox.ShowWarning($"Can not rename to {newFolder}, Folder with the same name already exist.");
 
-                 return;
 
-             }
 
-             if (newFolder.Length > 200)
 
-             {
 
-                 DialogBox.ShowWarning($"Can not create folder {newFolder}, Folder name too long, should be less 200.");
 
-                 return;
 
-             }
 
-             _recipeProvider.RenameFolder(CurrentFileNode.PrefixPath, CurrentFileNode.FullPath, newFolder);
 
-             ReloadRecipeFileList(CurrentChamberType, CurrentProcessType, newFolder, true);
 
-         }
 
-         #endregion
 
-         #region recipe
 
-         public void NewRecipe()
 
-         {
 
-             if (IsChanged)
 
-             {
 
-                 var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No | DialogButton.Cancel, DialogType.CONFIRM, $"Recipe {CurrentRecipe.Name} is changed, do you want to save it?");
 
-                 if (selection == DialogButton.Cancel)
 
-                     return;
 
-                 if (selection == DialogButton.Yes)
 
-                 {
 
-                     this.CurrentRecipe.Revisor = BaseApp.Instance.UserContext.LoginName;
 
-                     this.CurrentRecipe.ReviseTime = DateTime.Now;
 
-                     this.Save(this.CurrentRecipe, false);
 
-                 }
 
-             }
 
-             InputFileNameDialogViewModel dialog = new InputFileNameDialogViewModel("Input New Recipe Name");
 
-             dialog.FileName = "new recipe";
 
-             WindowManager wm = new WindowManager();
 
-             bool? dialogReturn = wm.ShowDialog(dialog);
 
-             if (!dialogReturn.HasValue || !dialogReturn.Value)
 
-                 return;
 
-             string recipeName = dialog.FileName.Trim();
 
-             if (string.IsNullOrEmpty(dialog.FileName))
 
-             {
 
-                 DialogBox.ShowWarning("Recipe file name should not be empty");
 
-                 return;
 
-             }
 
-             string prefix = CurrentChamberType + "\\" + CurrentProcessType;
 
-             string processType = string.Empty;
 
-             if (CurrentFileNode != null)
 
-             {
 
-                 string folder = CurrentFileNode.FullPath;
 
-                 if (CurrentFileNode.IsFile)
 
-                 {
 
-                     folder = folder.Substring(0, folder.LastIndexOf("\\") + 1);
 
-                     //if (!string.IsNullOrEmpty(folder))
 
-                     //    folder = folder;
 
-                 }
 
-                 else
 
-                 {
 
-                     folder = folder + "\\";
 
-                 }
 
-                 recipeName = folder + recipeName;
 
-             }
 
-             if (IsExist(recipeName, true))
 
-             {
 
-                 DialogBox.ShowWarning($"Can not create {recipeName}, Recipe with the same name already exist.");
 
-                 return;
 
-             }
 
-             if (recipeName.Length > 200)
 
-             {
 
-                 DialogBox.ShowWarning($"Can not create folder {recipeName}, Folder name too long, should be less 200.");
 
-                 return;
 
-             }
 
-             RecipeData recipe = new RecipeData();
 
-             recipe.Name = recipeName;
 
-             recipe.PrefixPath = prefix;
 
-             recipe.Creator = BaseApp.Instance.UserContext.LoginName;
 
-             recipe.CreateTime = DateTime.Now;
 
-             recipe.Revisor = BaseApp.Instance.UserContext.LoginName;
 
-             recipe.ReviseTime = DateTime.Now;
 
-             recipe.Description = string.Empty;
 
-             if (!Save(recipe, true))
 
-                 return;
 
-             var types = prefix.Split('\\');
 
-             ReloadRecipeFileList(types[0], types[1], recipeName, false);
 
-         }
 
-         public void NewRecipeRoot()
 
-         {
 
-             if (IsChanged)
 
-             {
 
-                 var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No | DialogButton.Cancel, DialogType.CONFIRM, $"Recipe {CurrentRecipe.Name} is changed, do you want to save it?");
 
-                 if (selection == DialogButton.Cancel)
 
-                     return;
 
-                 if (selection == DialogButton.Yes)
 
-                 {
 
-                     this.CurrentRecipe.Revisor = BaseApp.Instance.UserContext.LoginName;
 
-                     this.CurrentRecipe.ReviseTime = DateTime.Now;
 
-                     this.Save(this.CurrentRecipe, false);
 
-                 }
 
-             }
 
-             InputFileNameDialogViewModel dialog = new InputFileNameDialogViewModel("Input New Recipe Name");
 
-             dialog.FileName = "new recipe";
 
-             WindowManager wm = new WindowManager();
 
-             bool? dialogReturn = wm.ShowDialog(dialog);
 
-             if (!dialogReturn.HasValue || !dialogReturn.Value)
 
-                 return;
 
-             string recipeName = dialog.FileName.Trim();
 
-             if (string.IsNullOrEmpty(dialog.FileName))
 
-             {
 
-                 DialogBox.ShowWarning("Recipe file name should not be empty");
 
-                 return;
 
-             }
 
-             if (IsExist(recipeName, true))
 
-             {
 
-                 DialogBox.ShowWarning($"Can not create {recipeName}, Recipe with the same name already exist.");
 
-                 return;
 
-             }
 
-             if (recipeName.Length > 200)
 
-             {
 
-                 DialogBox.ShowWarning($"Can not create folder {recipeName}, Folder name too long, should be less 200.");
 
-                 return;
 
-             }
 
-             RecipeData recipe = new RecipeData();
 
-             recipe.Name = recipeName;
 
-             recipe.PrefixPath = CurrentChamberType + "\\" + CurrentProcessType;
 
-             recipe.Creator = BaseApp.Instance.UserContext.LoginName;
 
-             recipe.CreateTime = DateTime.Now;
 
-             recipe.Revisor = BaseApp.Instance.UserContext.LoginName;
 
-             recipe.ReviseTime = DateTime.Now;
 
-             recipe.Description = string.Empty;
 
-             if (!Save(recipe, true))
 
-                 return;
 
-             ReloadRecipeFileList(CurrentChamberType, CurrentProcessType, recipeName, false);
 
-         }
 
-         private void ReloadRecipeFileList(string chamberType, string processType, string selectedFile, bool selectionIsFolder)
 
-         {
 
-             ProcessTypeFileItem item = ProcessTypeFileList.FirstOrDefault(x => x.ProcessType == processType);
 
-             if (item == null)
 
-             {
 
-                 LOG.Write("error reload recipe file list, type = " + processType);
 
-             }
 
-             var prefix = $"{ChamberType[ChamberTypeIndexSelection]}\\{item.ProcessType}";
 
-             var recipes = _recipeProvider.GetXmlRecipeList(prefix);
 
-             item.FileListByProcessType = RecipeSequenceTreeBuilder.BuildFileNode(prefix, selectedFile, selectionIsFolder, recipes)[0].Files;
 
-             item.InvokePropertyChanged();
 
-         }
 
-         private bool IsExist(string fullPath, bool isFile)
 
-         {
 
-             for (int i = 0; i < ProcessTypeFileList.Count; i++)
 
-             {
 
-                 if (ProcessTypeFileList[i].ProcessType == CurrentProcessType)
 
-                 {
 
-                     if (ProcessTypeFileList[i].FileListByProcessType.Count == 0)
 
-                         return false;
 
-                     return FindFile(fullPath, ProcessTypeFileList[i].FileListByProcessType[0].Parent, isFile);
 
-                 }
 
-             }
 
-             return true;
 
-         }
 
-         private bool FindFile(string path, FileNode root, bool isFile)
 
-         {
 
-             if (root.FullPath == path && !isFile)
 
-             {
 
-                 return true;
 
-             }
 
-             foreach (var node in root.Files)
 
-             {
 
-                 if (isFile && node.IsFile && node.FullPath == path)
 
-                     return true;
 
-                 if (!node.IsFile && FindFile(path, node, isFile))
 
-                     return true;
 
-             }
 
-             return false;
 
-         }
 
-         public void SaveAsRecipe()
 
-         {
 
-             if (CurrentFileNode == null || !CurrentFileNode.IsFile)
 
-                 return;
 
-             if (IsChanged)
 
-             {
 
-                 var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No | DialogButton.Cancel, DialogType.CONFIRM, $"Recipe {CurrentRecipe.Name} is changed, do you want to save it?");
 
-                 if (selection == DialogButton.Cancel)
 
-                     return;
 
-                 if (selection == DialogButton.Yes)
 
-                 {
 
-                     this.CurrentRecipe.Revisor = BaseApp.Instance.UserContext.LoginName;
 
-                     this.CurrentRecipe.ReviseTime = DateTime.Now;
 
-                     this.Save(this.CurrentRecipe, false);
 
-                 }
 
-             }
 
-             InputFileNameDialogViewModel dialog = new InputFileNameDialogViewModel("Input New Recipe Name");
 
-             dialog.FileName = CurrentFileNode.Name;
 
-             WindowManager wm = new WindowManager();
 
-             bool? dialogReturn = wm.ShowDialog(dialog);
 
-             if (!dialogReturn.HasValue || !dialogReturn.Value)
 
-                 return;
 
-             string recipeName = dialog.FileName.Trim();
 
-             if (string.IsNullOrEmpty(dialog.FileName))
 
-             {
 
-                 DialogBox.ShowWarning("Recipe file name should not be empty");
 
-                 return;
 
-             }
 
-             string prefix = CurrentChamberType + "\\" + CurrentProcessType;
 
-             string processType = string.Empty;
 
-             string folder = CurrentFileNode.FullPath;
 
-             if (CurrentFileNode.IsFile)
 
-             {
 
-                 folder = folder.Substring(0, folder.LastIndexOf("\\") + 1);
 
-             }
 
-             if (!string.IsNullOrEmpty(folder))
 
-                 recipeName = folder + "\\" + recipeName;
 
-             if (CurrentFileNode.FullPath == recipeName)
 
-                 return;
 
-             if (IsExist(recipeName, true))
 
-             {
 
-                 DialogBox.ShowWarning($"Can not copy to {recipeName}, Recipe with the same name already exist.");
 
-                 return;
 
-             }
 
-             if (recipeName.Length > 200)
 
-             {
 
-                 DialogBox.ShowWarning($"Can not create folder {recipeName}, Folder name too long, should be less 200.");
 
-                 return;
 
-             }
 
-             CurrentRecipe.Creator = BaseApp.Instance.UserContext.LoginName;
 
-             CurrentRecipe.CreateTime = DateTime.Now;
 
-             CurrentRecipe.Revisor = BaseApp.Instance.UserContext.LoginName;
 
-             CurrentRecipe.ReviseTime = DateTime.Now;
 
-             CurrentRecipe.Description = CurrentRecipe.Description + ". Renamed from " + CurrentFileNode.Name;
 
-             _recipeProvider.SaveAsRecipe(prefix, recipeName, CurrentRecipe.GetXmlString());
 
-             ReloadRecipeFileList(CurrentChamberType, CurrentProcessType, recipeName, false);
 
-         }
 
-         public void RenameRecipe()
 
-         {
 
-             if (CurrentFileNode == null || !CurrentFileNode.IsFile)
 
-                 return;
 
-             if (IsChanged)
 
-             {
 
-                 var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No | DialogButton.Cancel, DialogType.CONFIRM, $"Recipe {CurrentRecipe.Name} is changed, do you want to save it?");
 
-                 if (selection == DialogButton.Cancel)
 
-                     return;
 
-                 if (selection == DialogButton.Yes)
 
-                 {
 
-                     this.CurrentRecipe.Revisor = BaseApp.Instance.UserContext.LoginName;
 
-                     this.CurrentRecipe.ReviseTime = DateTime.Now;
 
-                     this.Save(this.CurrentRecipe, false);
 
-                 }
 
-             }
 
-             InputFileNameDialogViewModel dialog = new InputFileNameDialogViewModel("Input New Recipe Name");
 
-             dialog.FileName = CurrentFileNode.Name;
 
-             WindowManager wm = new WindowManager();
 
-             bool? dialogReturn = wm.ShowDialog(dialog);
 
-             if (!dialogReturn.HasValue || !dialogReturn.Value)
 
-                 return;
 
-             string recipeName = dialog.FileName.Trim();
 
-             if (string.IsNullOrEmpty(dialog.FileName))
 
-             {
 
-                 DialogBox.ShowWarning("Recipe file name should not be empty");
 
-                 return;
 
-             }
 
-             string prefix = CurrentChamberType + "\\" + CurrentProcessType;
 
-             string processType = string.Empty;
 
-             string newName = CurrentFileNode.FullPath.Substring(0, CurrentFileNode.FullPath.LastIndexOf("\\") + 1);
 
-             if (!string.IsNullOrEmpty(newName))
 
-                 newName = newName + recipeName;
 
-             else
 
-                 newName = recipeName;
 
-             if (newName == CurrentFileNode.FullPath)
 
-                 return;
 
-             if (IsExist(newName, true))
 
-             {
 
-                 DialogBox.ShowWarning($"Can not rename to {newName}, Recipe with the same name already exist.");
 
-                 return;
 
-             }
 
-             if (newName.Length > 200)
 
-             {
 
-                 DialogBox.ShowWarning($"Can not create folder {newName}, Folder name too long, should be less 200.");
 
-                 return;
 
-             }
 
-             _recipeProvider.RenameRecipe(prefix, CurrentFileNode.FullPath, newName);
 
-             ReloadRecipeFileList(CurrentChamberType, CurrentProcessType, newName, false);
 
-         }
 
-         public void DeleteRecipe()
 
-         {
 
-             if (CurrentFileNode == null || !CurrentFileNode.IsFile)
 
-                 return;
 
-             var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No, DialogType.CONFIRM,
 
-                 $"Are you sure you want to delete \r\n {CurrentFileNode.FullPath}?");
 
-             if (selection == DialogButton.No)
 
-                 return;
 
-             string nextFocus = CurrentFileNode.Parent.FullPath;
 
-             bool isFolder = true;
 
-             if (CurrentFileNode.Parent.Files.Count > 1)
 
-             {
 
-                 for (int i = 0; i < CurrentFileNode.Parent.Files.Count; i++)
 
-                 {
 
-                     if (CurrentFileNode.Parent.Files[i] == CurrentFileNode)
 
-                     {
 
-                         if (i == 0)
 
-                         {
 
-                             nextFocus = CurrentFileNode.Parent.Files[i + 1].FullPath;
 
-                             isFolder = !CurrentFileNode.Parent.Files[i + 1].IsFile;
 
-                         }
 
-                         else
 
-                         {
 
-                             nextFocus = CurrentFileNode.Parent.Files[i - 1].FullPath;
 
-                             isFolder = !CurrentFileNode.Parent.Files[i - 1].IsFile;
 
-                         }
 
-                     }
 
-                 }
 
-             }
 
-             _recipeProvider.DeleteRecipe(CurrentFileNode.PrefixPath, CurrentFileNode.FullPath);
 
-             ReloadRecipeFileList(CurrentChamberType, CurrentProcessType, nextFocus, isFolder);
 
-         }
 
-         public void ReloadRecipe()
 
-         {
 
-             if (this.editMode == EditMode.Normal || this.editMode == EditMode.Edit)
 
-             {
 
-                 this.LoadData(CurrentRecipe.PrefixPath, CurrentRecipe.Name);
 
-                 this.UpdateView();
 
-             }
 
-         }
 
-         public void SaveToAll()
 
-         {
 
-             if (!CurrentRecipe.IsCompatibleWithCurrentFormat)
 
-             {
 
-                 DialogBox.ShowWarning($"Save failed, {CurrentRecipe.Name} is not a valid recipe file");
 
-                 return;
 
-             }
 
-             var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No,
 
-                 DialogType.CONFIRM, $"Do you want to save to all? \r\n This will replace all the other chamber recipe content");
 
-             if (selection == DialogButton.No)
 
-                 return;
 
-             CurrentRecipe.SaveTo(Chambers.ToArray());
 
-             Save(this.CurrentRecipe, false);
 
-         }
 
-         public void SaveTo()
 
-         {
 
-             if (!CurrentRecipe.IsCompatibleWithCurrentFormat)
 
-             {
 
-                 DialogBox.ShowWarning($"Save failed, {CurrentRecipe.Name} is not a valid recipe file");
 
-                 return;
 
-             }
 
-             SaveToDialogViewModel dialog = new SaveToDialogViewModel("Select which chamber to copy to", SelectedChamber, Chambers.ToList());
 
-             WindowManager wm = new WindowManager();
 
-             bool? dialogReturn = wm.ShowDialog(dialog);
 
-             if (!dialogReturn.HasValue || !dialogReturn.Value)
 
-                 return;
 
-             List<string> chambers = new List<string>();
 
-             foreach (var dialogChamber in dialog.Chambers)
 
-             {
 
-                 if (dialogChamber.IsEnabled && dialogChamber.IsChecked)
 
-                     chambers.Add(dialogChamber.Name);
 
-             }
 
-             if (chambers.Count == 0)
 
-                 return;
 
-             CurrentRecipe.SaveTo(chambers.ToArray());
 
-             Save(this.CurrentRecipe, false);
 
-         }
 
-         #endregion
 
-         #region Steps
 
-         public void ParamsExpanded(ExpanderColumn col)
 
-         {
 
-             int index = this.Columns.IndexOf(col);
 
-             for (var i = index + 1; i < this.Columns.Count; i++)
 
-             {
 
-                 if (this.Columns[i] is ExpanderColumn)
 
-                     break;
 
-                 this.Columns[i].Visibility = Visibility.Visible;
 
-             }
 
-         }
 
-         public void ParamsCollapsed(ExpanderColumn col)
 
-         {
 
-             int index = this.Columns.IndexOf(col);
 
-             for (var i = index + 1; i < this.Columns.Count; i++)
 
-             {
 
-                 if (this.Columns[i] is ExpanderColumn)
 
-                     break;
 
-                 this.Columns[i].Visibility = Visibility.Collapsed;
 
-             }
 
-         }
 
-         public void SaveRecipe()
 
-         {
 
-             if (this.IsChanged)
 
-             {
 
-                 this.Save(this.CurrentRecipe, false);
 
-             }
 
-         }
 
-         public void PopSetting(string controlName, Param paramData)
 
-         {
 
-             int stepNum = Convert.ToInt32(((StepParam)paramData.Parent[1]).Value);
 
-             PublicPopSettingDialogViewModel dialog = new PublicPopSettingDialogViewModel();
 
-             dialog.DisplayName = paramData.DisplayName;
 
-             ObservableCollection<Param> Parameters = new ObservableCollection<Param>();
 
-             Parameters = this.CurrentRecipe.PopSettingSteps[controlName][stepNum - 1];
 
-             ObservableCollection<Param> ControlParameters = new ObservableCollection<Param>();
 
-             ObservableCollection<BandParam> BrandParameters = new ObservableCollection<BandParam>();
 
-             foreach (var item in Parameters)
 
-             {
 
-                 if (item.Name.Contains("Band"))
 
-                 {
 
-                     string name = item.Name.Replace("Wavelength", "").Replace("Bandwidth", "");
 
-                     string displayName = item.DisplayName.Replace("Wavelength", "").Replace("Bandwidth", "");
 
-                     if (BrandParameters.Where(x => x.Name == name).Count() == 0)
 
-                     {
 
-                         BrandParameters.Add(new BandParam()
 
-                         {
 
-                             Name = name,
 
-                             DisplayName = displayName
 
-                         });
 
-                     }
 
-                     if (item.Name.Contains("Wavelength"))
 
-                     {
 
-                         BrandParameters.First(x => x.Name == name).WavelengthDoubleParam = item;
 
-                     }
 
-                     else if (item.Name.Contains("Bandwidth"))
 
-                     {
 
-                         BrandParameters.First(x => x.Name == name).BandwidthDoubleParam = item;
 
-                     }
 
-                 }
 
-                 else
 
-                     ControlParameters.Add(item);
 
-             }
 
-             dialog.Parameters = Parameters;
 
-             dialog.ControlParameters = ControlParameters;
 
-             dialog.BandParameters = BrandParameters;
 
-             WindowManager wm = new WindowManager();
 
-             bool? bret = wm.ShowDialog(dialog);
 
-             if ((bool)bret)
 
-             {
 
-                 this.CurrentRecipe.PopSettingSteps[controlName][stepNum - 1] = dialog.Parameters;
 
-             }
 
-         }
 
-         public bool Save(RecipeData recipe, bool createNew)
 
-         {
 
-             bool result = false;
 
-             if (string.IsNullOrEmpty(recipe.Name))
 
-             {
 
-                 MessageBox.Show("Recipe name can't be empty");
 
-                 return false;
 
-             }
 
-             recipe.Revisor = BaseApp.Instance.UserContext.LoginName;
 
-             recipe.ReviseTime = DateTime.Now;
 
-             result = this._recipeProvider.SaveRecipe(recipe.PrefixPath, recipe.Name, recipe.GetXmlString());
 
-             if (result)
 
-             {
 
-                 recipe.DataSaved();
 
-                 this.editMode = EditMode.Normal;
 
-                 this.UpdateView();
 
-                 CurrentRecipe.ChangeChamber(Columns, PopSettingColumns, _columnBuilder.Configs, SelectedChamber);
 
-             }
 
-             else
 
-             {
 
-                 MessageBox.Show("Save failed!");
 
-             }
 
-             return result;
 
-         }
 
-         public void AddStep()
 
-         {
 
-             this.CurrentRecipe.Steps.Add(this.CurrentRecipe.CreateStep(this.Columns));
 
-             foreach (string key in PopSettingColumns.Keys)
 
-             {
 
-                 if (!this.CurrentRecipe.PopSettingSteps.ContainsKey(key))
 
-                 {
 
-                     this.CurrentRecipe.PopSettingSteps.Add(key, new ObservableCollection<ObservableCollection<Param>>());
 
-                 }
 
-                 this.CurrentRecipe.PopSettingSteps[key].Add(this.PopSettingColumns[key]);
 
-             }
 
-             if (this.editMode != EditMode.New && this.editMode != EditMode.ReName)
 
-                 this.editMode = EditMode.Edit;
 
-             int index = 1;
 
-             foreach (ObservableCollection<Param> parameters in this.CurrentRecipe.Steps)
 
-             {
 
-                 (parameters[1] as StepParam).Value = index.ToString();
 
-                 index++;
 
-             }
 
-             this.UpdateView();
 
-         }
 
-         public void AppendStep()
 
-         {
 
-             int index = -1;
 
-             bool found = false;
 
-             for (var i = 0; i < this.CurrentRecipe.Steps.Count; i++)
 
-             {
 
-                 if (this.CurrentRecipe.Steps[i][1] is StepParam && ((StepParam)this.CurrentRecipe.Steps[i][1]).Checked)
 
-                 {
 
-                     index = i;
 
-                     found = true;
 
-                     break;
 
-                 }
 
-             }
 
-             if (found)
 
-             {
 
-                 if (this.editMode != EditMode.New && this.editMode != EditMode.ReName)
 
-                     this.editMode = EditMode.Edit;
 
-                 this.CurrentRecipe.Steps.Insert(index, this.CurrentRecipe.CreateStep(this.Columns));
 
-                 if (this.CurrentRecipe.PopSettingSteps.Count != 0)
 
-                 {
 
-                     foreach (string key in PopSettingColumns.Keys)
 
-                     {
 
-                         this.CurrentRecipe.PopSettingSteps[key].Insert(index, this.PopSettingColumns[key]);
 
-                     }
 
-                 }
 
-                 index = 1;
 
-                 foreach (ObservableCollection<Param> parameters in this.CurrentRecipe.Steps)
 
-                 {
 
-                     (parameters[1] as StepParam).Value = index.ToString();
 
-                     index++;
 
-                 }
 
-             }
 
-         }
 
-         private ObservableCollection<ObservableCollection<Param>> copySteps = new ObservableCollection<ObservableCollection<Param>>();
 
-         private Dictionary<string, ObservableCollection<ObservableCollection<Param>>> popCopySteps = new Dictionary<string, ObservableCollection<ObservableCollection<Param>>>();
 
-         public void CopyStep()
 
-         {
 
-             this.copySteps.Clear();
 
-             this.popCopySteps.Clear();
 
-             for (var i = 0; i < this.CurrentRecipe.Steps.Count; i++)
 
-             {
 
-                 if (this.CurrentRecipe.Steps[i][1] is StepParam && ((StepParam)this.CurrentRecipe.Steps[i][1]).Checked)
 
-                 {
 
-                     this.copySteps.Add(this.CurrentRecipe.CloneStep(this.Columns, this.CurrentRecipe.Steps[i]));
 
-                     foreach (string key in PopSettingColumns.Keys)
 
-                     {
 
-                         if (!this.popCopySteps.ContainsKey(key))
 
-                         {
 
-                             this.popCopySteps.Add(key, new ObservableCollection<ObservableCollection<Param>>());
 
-                         }
 
-                         if (this.CurrentRecipe.PopSettingSteps.Count != 0)
 
-                         {
 
-                             this.popCopySteps[key].Add(this.CurrentRecipe.PopSettingSteps[key][i]);
 
-                         }
 
-                     }
 
-                 }
 
-             }
 
-             CurrentRecipe.ValidLoopData();
 
-         }
 
-         public void PasteStep()
 
-         {
 
-             if (this.copySteps.Count > 0)
 
-             {
 
-                 if (this.editMode != EditMode.New && this.editMode != EditMode.ReName)
 
-                     this.editMode = EditMode.Edit;
 
-                 for (var i = 0; i < this.CurrentRecipe.Steps.Count; i++)
 
-                 {
 
-                     if (this.CurrentRecipe.Steps[i][1] is StepParam && ((StepParam)this.CurrentRecipe.Steps[i][1]).Checked)
 
-                     {
 
-                         for (var copyindex = 0; copyindex < this.copySteps.Count; copyindex++)
 
-                         {
 
-                             this.CurrentRecipe.Steps.Insert(i, this.CurrentRecipe.CloneStep(this.Columns, this.copySteps[copyindex]));
 
-                             if (this.CurrentRecipe.PopSettingSteps.Count != 0)
 
-                             {
 
-                                 foreach (string key in PopSettingColumns.Keys)
 
-                                 {
 
-                                     this.CurrentRecipe.PopSettingSteps[key].Insert(i, this.popCopySteps[key][copyindex]);
 
-                                 }
 
-                             }
 
-                             i++;
 
-                         }
 
-                         break;
 
-                     }
 
-                 }
 
-                 int index = 1;
 
-                 foreach (ObservableCollection<Param> parameters in this.CurrentRecipe.Steps)
 
-                 {
 
-                     (parameters[1] as StepParam).Value = index.ToString();
 
-                     index++;
 
-                 }
 
-                 CurrentRecipe.ValidLoopData();
 
-                 this.UpdateView();
 
-             }
 
-         }
 
-         public void DeleteStep()
 
-         {
 
-             if (this.editMode != EditMode.New && this.editMode != EditMode.ReName)
 
-                 this.editMode = EditMode.Edit;
 
-             List<ObservableCollection<Param>> steps = this.CurrentRecipe.Steps.ToList();
 
-             for (var i = 0; i < steps.Count; i++)
 
-             {
 
-                 if (steps[i][1] is StepParam && ((StepParam)steps[i][1]).Checked)
 
-                 {
 
-                     this.CurrentRecipe.Steps.Remove(steps[i]);
 
-                     foreach (string key in PopSettingColumns.Keys)
 
-                     {
 
-                         if (CurrentRecipe.PopSettingSteps.ContainsKey(key) && CurrentRecipe.PopSettingSteps[key].Count > i)
 
-                             CurrentRecipe.PopSettingSteps[key].Remove(this.CurrentRecipe.PopSettingSteps[key][i]);
 
-                     }
 
-                 }
 
-             }
 
-             int index = 1;
 
-             foreach (ObservableCollection<Param> parameters in this.CurrentRecipe.Steps)
 
-             {
 
-                 (parameters[1] as StepParam).Value = index.ToString();
 
-                 index++;
 
-             }
 
-         }
 
-         private TreeViewItem GetParentObjectEx<TreeViewItem>(DependencyObject obj) where TreeViewItem : FrameworkElement
 
-         {
 
-             DependencyObject parent = VisualTreeHelper.GetParent(obj);
 
-             while (parent != null)
 
-             {
 
-                 if (parent is TreeViewItem)
 
-                 {
 
-                     return (TreeViewItem)parent;
 
-                 }
 
-                 parent = VisualTreeHelper.GetParent(parent);
 
-             }
 
-             return null;
 
-         }
 
-         public void TreeRightMouseDown(MouseButtonEventArgs e)
 
-         {
 
-             var item = GetParentObjectEx<TreeViewItem>(e.OriginalSource as DependencyObject) as TreeViewItem;
 
-             if (item != null)
 
-             {
 
-                 item.Focus();
 
-             }
 
-         }
 
-         #endregion
 
-         private void ClearData()
 
-         {
 
-             this.editMode = EditMode.None;
 
-             this.CurrentRecipe.Clear();
 
-             this.CurrentRecipe.Name = string.Empty;
 
-             this.CurrentRecipe.Description = string.Empty;
 
-         }
 
-         private void LoadData(string prefixPath, string recipeName)
 
-         {
 
-             CurrentRecipe.Clear();
 
-             var recipeContent = _recipeProvider.LoadRecipe(prefixPath, recipeName);
 
-             if (string.IsNullOrEmpty(recipeContent))
 
-             {
 
-                 MessageBox.Show($"{prefixPath}\\{recipeName} is empty, please confirm the file is valid.");
 
-                 return;
 
-             }
 
-             CurrentRecipe.RecipeChamberType = _columnBuilder.RecipeChamberType;
 
-             CurrentRecipe.RecipeVersion = _columnBuilder.RecipeVersion;
 
-             CurrentRecipe.InitData(prefixPath, recipeName, recipeContent, Columns, PopSettingColumns, _columnBuilder.Configs, SelectedChamber);
 
-             this.editMode = EditMode.Normal;
 
-         }
 
-         private void UpdateView()
 
-         {
 
-             bool isFileSelected = CurrentFileNode != null && CurrentFileNode.IsFile;
 
-             this.EnableNew = isFileSelected;
 
-             this.EnableReName = isFileSelected;
 
-             this.EnableCopy = isFileSelected;
 
-             this.EnableDelete = isFileSelected;
 
-             this.EnableSave = isFileSelected;
 
-             this.EnableStep = isFileSelected;
 
-             EnableSaveTo = isFileSelected;
 
-             EnableSaveToAll = isFileSelected;
 
-             EnableReload = isFileSelected;
 
-             if (this.editMode == EditMode.None)
 
-             {
 
-                 this.EnableNew = true;
 
-                 this.EnableReName = false;
 
-                 this.EnableCopy = false;
 
-                 this.EnableDelete = false;
 
-                 this.EnableStep = false;
 
-                 this.EnableSave = false;
 
-             }
 
-             this.NotifyOfPropertyChange("EnableNew");
 
-             this.NotifyOfPropertyChange("EnableReName");
 
-             this.NotifyOfPropertyChange("EnableCopy");
 
-             this.NotifyOfPropertyChange("EnableDelete");
 
-             this.NotifyOfPropertyChange("EnableSave");
 
-             this.NotifyOfPropertyChange("EnableStep");
 
-             this.NotifyOfPropertyChange("EnableSaveTo");
 
-             this.NotifyOfPropertyChange("EnableSaveToAll");
 
-             this.NotifyOfPropertyChange("EnableReload");
 
-             this.NotifyOfPropertyChange("CurrentRecipe");
 
-         }
 
-     }
 
- }
 
 
  |