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; using MECF.Framework.UI.Client.CenterViews.Editors.Recipe; using MECF.Framework.UI.Client.CenterViews.Editors.Sequence; using MECF.Framework.UI.Client.ClientBase; using OpenSEMI.ClientBase; using OpenSEMI.ClientBase.Command; 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; using FurnaceUI.Models; using FurnaceUI.Views.Editors; using FurnaceUI.Views.Recipes; using ProcessTypeFileItem = FurnaceUI.Views.Recipes.ProcessTypeFileItem; using MECF.Framework.UI.Client.CenterViews.Parameter; using MECF.Framework.Common.OperationCenter; namespace FurnaceUI.Views.Parameter { public class EditViewModel : FurnaceUIViewModelBase { 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 _NewParameterCommand; public ICommand NewParameterCommand { get { if (this._NewParameterCommand == null) this._NewParameterCommand = new BaseCommand(() => this.NewParameter()); return this._NewParameterCommand; } } private ICommand _RenameParameterCommand; public ICommand RenameParameterCommand { get { if (this._RenameParameterCommand == null) this._RenameParameterCommand = new BaseCommand(() => this.RenameParameter()); return this._RenameParameterCommand; } } private ICommand _DeleteParameterCommand; public ICommand DeleteParameterCommand { get { if (this._DeleteParameterCommand == null) this._DeleteParameterCommand = new BaseCommand(() => this.DeleteParameter()); return this._DeleteParameterCommand; } } private ICommand _SaveAsParameterCommand; public ICommand SaveAsParameterCommand { get { if (this._SaveAsParameterCommand == null) this._SaveAsParameterCommand = new BaseCommand(() => this.SaveAsRecipe()); return this._SaveAsParameterCommand; } } private ICommand _EditParameterCommand; public ICommand EditParameterCommand { get { if (this._EditParameterCommand == null) this._EditParameterCommand = new BaseCommand(() => this.EditParameter()); return this._EditParameterCommand; } } private ICommand _SetDefaultFileCommand; public ICommand SetDefaultFileCommand { get { if (this._SetDefaultFileCommand == null) this._SetDefaultFileCommand = new BaseCommand(() => this.SetDefaultFile()); return this._SetDefaultFileCommand; } } private ICommand _ViewParameterCommand; public ICommand ViewParameterCommand { get { if (this._ViewParameterCommand == null) this._ViewParameterCommand = new BaseCommand(() => this.ViewParameter()); return this._ViewParameterCommand; } } private ICommand _ChangePermission; public ICommand ChangePermission { get { if (this._ChangePermission == null) this._ChangePermission = new BaseCommand(() => this.SavePermission()); return this._ChangePermission; } } public ObservableCollection ParameterTypeFileList { get; set; } public ParameterDataBase CurrentParameter { get; private set; } public FileNode CurrentFileNode { get; set; } public bool IsCurrentNodePath { get => CurrentFileNode != null && !CurrentFileNode.IsFile; } public bool IsCurrentNodeFile { get => CurrentFileNode != null && CurrentFileNode.IsFile; } private bool _isReadAndWritePermission; public bool IsReadAndWritePermission { get { _isReadAndWritePermission = IsSelectPermission && CurrentFileNode.Permission != "Read"; return _isReadAndWritePermission; } set { _isReadAndWritePermission = value; } } private bool _isFreePermission; public bool IsFreePermission { get { //_isFreePermission = IsSelectPermission && CurrentFileNode.Permission == "Free"; _isFreePermission = IsSelectPermission; return _isFreePermission; } set { _isFreePermission = value; } } private bool _isSelectPermission; public bool IsSelectPermission { get { _isSelectPermission = LevelDisplay != "LEVEL1" && IsCurrentNodeFile; return _isSelectPermission; } set { _isSelectPermission = value; } } private bool IsChanged { get { return editMode == EditMode.Edit || CurrentParameter.IsChanged; } } // private ParameterFormatBuilder _columnBuilder = new ParameterFormatBuilder(); private EditMode editMode; private ParameterProvider _parameterProvider = new ParameterProvider(); public ObservableCollection ChamberType { get; set; } public int ChamberTypeIndexSelection { get; set; } private int _ParameterTypeIndexSelection; public int ParameterTypeIndexSelection { get { return _ParameterTypeIndexSelection; } set { _ParameterTypeIndexSelection = value; NotifyOfPropertyChange(nameof(ParameterTypeIndexSelection)); } } public string CurrentChamberType { get { return ChamberType[ChamberTypeIndexSelection]; } } public string CurrentParameterType { get { return ParameterTypeFileList[ParameterTypeIndexSelection].ProcessType; } } public Visibility MultiChamberVisibility { get; set; } public Visibility ToleranceVisibility { get; set; } public ObservableCollection Chambers { get; set; } public string SelectedChamber { get; set; } public object View { get; set; } private string _SelectRecipeTypeName; public string SelectRecipeTypeName { get { return _SelectRecipeTypeName; } set { _SelectRecipeTypeName = value; NotifyOfPropertyChange("SelectRecipeTypeName"); } } public EditViewModel() { SystemName = "System"; } protected override void OnInitialize() { base.OnInitialize(); var chamberType = QueryDataClient.Instance.Service.GetConfig("System.EditParameter.EditChamberType"); if (chamberType == null) { ChamberType = new ObservableCollection() { "Parameter" }; } else { ChamberType = new ObservableCollection(((string)(chamberType)).Split(',')); } ChamberTypeIndexSelection = 0; var processType = QueryDataClient.Instance.Service.GetConfig($"System.EditParameter.EditParameterType"); if (processType == null) { processType = "AlarmCondition"; } ParameterTypeFileList = new ObservableCollection(); 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 parameters = _parameterProvider.GetXmlParameterList(prefix); type.FileListByProcessType = ParameterTreeBuilder.GetFileNodeParameterList(prefix);//ParameterTreeBuilder.BuildFileNode(prefix, "", false, parameters)[0].Files; ParameterTypeFileList.Add(type); } if (ParameterTypeFileList[0].FileListByProcessType.Count > 0) CurrentFileNode = ParameterTypeFileList[0].FileListByProcessType[ParameterTypeFileList[0].FileListByProcessType.Count - 1]; SelectRecipeTypeName = (string)processType ; UpdateParameterFormat(); if (CurrentFileNode != null && CurrentFileNode.IsFile) { this.LoadData(CurrentFileNode.PrefixPath, CurrentFileNode.FullPath); } } 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 {CurrentParameter.Name} content is changed, do you want to save it?") == DialogButton.Yes) { this.SaveParameter(); } } } public void TabSelectionChanged() { UpdateParameterFormat(); OnViewLoaded(View); } public void UpdateParameterFormat() { this.CurrentParameter = new ParameterDataBase(); CurrentParameter.ChamberType = CurrentChamberType; // CurrentParameter.RecipeVersion = _columnBuilder.ParameterVersion; this.editMode = EditMode.None; var chamber = QueryDataClient.Instance.Service.GetConfig("System.Parameter.ChamberModules"); if (chamber == null) { chamber = "Parameter"; } Chambers = new ObservableCollection(((string)chamber).Split(',')); SelectedChamber = Chambers[0]; MultiChamberVisibility = Chambers.Count > 1 ? Visibility.Visible : Visibility.Collapsed; ToleranceVisibility = CurrentParameter.ToleranceEnable ? Visibility.Visible : Visibility.Collapsed; } public void TreeSelectChanged(FileNode node) { if (IsChanged) { var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No, DialogType.CONFIRM, $"Recipe {CurrentParameter.Name} is changed, do you want to save it?"); if (selection == DialogButton.Yes) { this.CurrentParameter.Revisor = BaseApp.Instance.UserContext.LoginName; this.CurrentParameter.ReviseTime = DateTime.Now; this.Save(this.CurrentParameter, false); } } CurrentFileNode = node; NotifyOfPropertyChange(nameof(IsCurrentNodeFile)); NotifyOfPropertyChange(nameof(IsCurrentNodePath)); NotifyOfPropertyChange(nameof(IsSelectPermission)); NotifyOfPropertyChange(nameof(IsReadAndWritePermission)); NotifyOfPropertyChange(nameof(IsFreePermission)); if (node != null && node.IsFile) { this.LoadData(node.PrefixPath, node.FullPath); } else { this.ClearData(); this.editMode = EditMode.None; } this.UpdateView(); } #region folder public void SetDefaultFile() { if (CurrentFileNode == null || !CurrentFileNode.IsFile) { DialogBox.ShowWarning($"Can not select file"); return; } switch (CurrentParameterType) { case "TempPID": InvokeClient.Instance.Service.DoOperation($"{SystemName}.SetConfig", "PM1.TempPID", $"{CurrentFileNode.PrefixPath}\\{CurrentFileNode.FullPath}"); break; case "TempCorrection": InvokeClient.Instance.Service.DoOperation($"{SystemName}.SetConfig", "PM1.TempCorrection", $"{CurrentFileNode.PrefixPath}\\{CurrentFileNode.FullPath}"); break; case "TempProfile": InvokeClient.Instance.Service.DoOperation($"{SystemName}.SetConfig", "PM1.TempProfile", $"{CurrentFileNode.PrefixPath}\\{CurrentFileNode.FullPath}"); break; case "LeakCheckCondition": InvokeClient.Instance.Service.DoOperation($"{SystemName}.SetConfig", "PM1.LeakCheckCondition", $"{CurrentFileNode.PrefixPath}\\{CurrentFileNode.FullPath}"); break; case "APCPID": InvokeClient.Instance.Service.DoOperation($"{SystemName}.SetConfig", "PM1.APCPID", $"{CurrentFileNode.PrefixPath}\\{CurrentFileNode.FullPath}"); break; case "TempAutoPID": InvokeClient.Instance.Service.DoOperation($"{SystemName}.SetConfig", "PM1.TempAutoPID", $"{CurrentFileNode.PrefixPath}\\{CurrentFileNode.FullPath}"); break; case "AlarmCondition": InvokeClient.Instance.Service.DoOperation($"{SystemName}.SetConfig", "PM1.AlarmCondition", $"{CurrentFileNode.PrefixPath}\\{CurrentFileNode.FullPath}"); break; default: break; } DialogBox.ShowInfo($"Save file is ok!"); //var windowManager = IoC.Get(); //RecipeSelectRecipeTypeViewModel recipeSelectRecipeTypeViewModel = new RecipeSelectRecipeTypeViewModel(); //(windowManager as WindowManager)?.ShowDialogWithTitle(recipeSelectRecipeTypeViewModel, null, "Select Recipe Type"); //if (recipeSelectRecipeTypeViewModel.SelectRecipeType != null) //{ // var selectRecipeType = recipeSelectRecipeTypeViewModel.SelectRecipeType; // var processType = QueryDataClient.Instance.Service.GetConfig($"System.Recipe.{selectRecipeType}"); // if (processType == null) // { // processType = selectRecipeType; // } // ParameterTypeFileList = new ObservableCollection(); // 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 = _parameterProvider.GetXmlParameterList(prefix); // type.FileListByProcessType = RecipeSequenceTreeBuilder.BuildFileNode(prefix, "", false, recipes)[0].Files; // ParameterTypeFileList.Add(type); // } // SelectRecipeTypeName = (string)processType; // this.NotifyOfPropertyChange("ProcessTypeFileList"); // if (ParameterTypeFileList[0].FileListByProcessType.Count > 0) // CurrentFileNode = ParameterTypeFileList[0].FileListByProcessType[ParameterTypeFileList[0].FileListByProcessType.Count - 1]; // NotifyOfPropertyChange(nameof(IsCurrentNodeFile)); // NotifyOfPropertyChange(nameof(IsCurrentNodePath)); // NotifyOfPropertyChange(nameof(IsSelectPermission)); // NotifyOfPropertyChange(nameof(IsReadAndWritePermission)); // NotifyOfPropertyChange(nameof(IsFreePermission)); // ParameterTypeIndexSelection = 0; //} } public void NewFolder() { if (IsChanged) { var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No | DialogButton.Cancel, DialogType.CONFIRM, $"Recipe {CurrentParameter.Name} is changed, do you want to save it?"); if (selection == DialogButton.Cancel) return; if (selection == DialogButton.Yes) { this.CurrentParameter.Revisor = BaseApp.Instance.UserContext.LoginName; this.CurrentParameter.ReviseTime = DateTime.Now; this.Save(this.CurrentParameter, false); } } InputFileNameDialogViewModel dialog = new InputFileNameDialogViewModel("Input New Folder Name", ParameterTypeFileList[0].FileListByProcessType); // 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] + "\\" + ParameterTypeFileList[ParameterTypeIndexSelection].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; } _parameterProvider.CreateParameterFolder(prefix, newFolder); ReloadParameterFileList(CurrentChamberType, CurrentParameterType, newFolder, true); } public void NewFolderRoot() { if (IsChanged) { var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No | DialogButton.Cancel, DialogType.CONFIRM, $"Recipe {CurrentParameter.Name} is changed, do you want to save it?"); if (selection == DialogButton.Cancel) return; if (selection == DialogButton.Yes) { this.CurrentParameter.Revisor = BaseApp.Instance.UserContext.LoginName; this.CurrentParameter.ReviseTime = DateTime.Now; this.Save(this.CurrentParameter, false); } } InputFileNameDialogViewModel dialog = new InputFileNameDialogViewModel("Input New Folder Name", ParameterTypeFileList[0].FileListByProcessType); 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] + "\\" + ParameterTypeFileList[ParameterTypeIndexSelection].ProcessType; _parameterProvider.CreateParameterFolder(prefix, name); ReloadParameterFileList(CurrentChamberType, CurrentParameterType, 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; } } } } _parameterProvider.DeleteParameterFolder(CurrentFileNode.PrefixPath, CurrentFileNode.FullPath); ReloadParameterFileList(CurrentChamberType, CurrentParameterType, nextFocus, isFolder); } public void RenameFolder() { if (CurrentFileNode == null || CurrentFileNode.IsFile) return; InputFileNameDialogViewModel dialog = new InputFileNameDialogViewModel("Input New Folder Name", ParameterTypeFileList[0].FileListByProcessType, "", Visibility.Hidden); 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; } _parameterProvider.RenameFolder(CurrentFileNode.PrefixPath, CurrentFileNode.FullPath, newFolder); ReloadParameterFileList(CurrentChamberType, CurrentParameterType, newFolder, true); } #endregion #region Parameter public void NewParameter() { if (IsChanged) { var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No | DialogButton.Cancel, DialogType.CONFIRM, $"Recipe {CurrentParameter.Name} is changed, do you want to save it?"); if (selection == DialogButton.Cancel) return; if (selection == DialogButton.Yes) { this.CurrentParameter.Revisor = BaseApp.Instance.UserContext.LoginName; this.CurrentParameter.ReviseTime = DateTime.Now; this.Save(this.CurrentParameter, false); } } InputFileNameDialogViewModel dialog = new InputFileNameDialogViewModel("Input New Recipe Name", ParameterTypeFileList[0].FileListByProcessType, CurrentParameter.Description); //dialog.FileName = (string)QueryDataClient.Instance.Service.GetConfig($"System.Recipe.DefaultProcessRecipeName"); WindowManager wm = new WindowManager(); bool? dialogReturn = wm.ShowDialog(dialog); if (!dialogReturn.HasValue || !dialogReturn.Value) return; string recipeName = dialog.FileName.Trim(); string filepath = dialog.FilePath; string description = dialog.Comment; if (string.IsNullOrEmpty(dialog.FileName)) { DialogBox.ShowWarning("Recipe file name should not be empty"); return; } string prefix = CurrentChamberType + "\\" + CurrentParameterType + "\\" + filepath; if (CurrentFileNode != null) { if (CurrentFileNode.IsFile) { filepath = filepath.Substring(0, filepath.LastIndexOf("\\") + 1); //if (!string.IsNullOrEmpty(folder)) // folder = folder; } else { filepath = filepath + "\\"; } } if (IsExistV2(prefix + recipeName, true)) { DialogBox.ShowWarning($"Can not create {recipeName}, Parameter with the same name already exist."); return; } if ((prefix + recipeName).Length > 200) { DialogBox.ShowWarning($"Can not create folder {recipeName}, Folder name too long, should be less 200."); return; } ParameterDataBase parameterData = new ParameterDataBase(); switch (CurrentParameterType) { case "TempPID": parameterData = new TempPIDParameterData(); break; case "TempCorrection": parameterData = new TempCorrectionParameterData(); break; case "TempProfile": parameterData = new TempProfileParameterData(); break; case "LeakCheckCondition": parameterData = new LeakCheckConditionParameterData(); break; case "APCPID": parameterData = new APCPIDParameterData(); break; case "TempAutoPID": parameterData = new TempAutoPIDParameterData(); break; case "AlarmCondition": parameterData = new AlarmConditionParameterData(); break; default: break; } parameterData.Name = recipeName; parameterData.PrefixPath = prefix; parameterData.Creator = BaseApp.Instance.UserContext.LoginName; parameterData.CreateTime = DateTime.Now; parameterData.Revisor = BaseApp.Instance.UserContext.LoginName; parameterData.ReviseTime = DateTime.Now; parameterData.Description = description; parameterData.Level = LevelDisplay; parameterData.Permission = "Free"; if (!Save(parameterData, true)) return; var types = prefix.Split('\\'); ReloadParameterFileList(types[0], types[1], recipeName, false); } public void NewParameterRoot() { if (IsChanged) { var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No | DialogButton.Cancel, DialogType.CONFIRM, $"Recipe {CurrentParameter.Name} is changed, do you want to save it?"); if (selection == DialogButton.Cancel) return; if (selection == DialogButton.Yes) { this.CurrentParameter.Revisor = BaseApp.Instance.UserContext.LoginName; this.CurrentParameter.ReviseTime = DateTime.Now; this.Save(this.CurrentParameter, false); } } InputFileNameDialogViewModel dialog = new InputFileNameDialogViewModel("Input New Recipe Name", ParameterTypeFileList[0].FileListByProcessType, CurrentParameter.Description); dialog.FileName = "new recipe"; WindowManager wm = new WindowManager(); bool? dialogReturn = wm.ShowDialog(dialog); if (!dialogReturn.HasValue || !dialogReturn.Value) return; string recipeName = dialog.FileName.Trim(); string description = dialog.Comment; 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; } ParameterDataBase parameter = new ParameterDataBase(); parameter.Name = recipeName; parameter.PrefixPath = CurrentChamberType + "\\" + CurrentParameterType; parameter.Creator = BaseApp.Instance.UserContext.LoginName; parameter.CreateTime = DateTime.Now; parameter.Revisor = BaseApp.Instance.UserContext.LoginName; parameter.ReviseTime = DateTime.Now; parameter.Description = string.Empty; parameter.Description = description; parameter.Level = LevelDisplay; parameter.Permission = "Free"; if (!Save(parameter, true)) return; ReloadParameterFileList(CurrentChamberType, CurrentParameterType, recipeName, false); } private void ReloadParameterFileList(string chamberType, string processType, string selectedFile, bool selectionIsFolder) { ProcessTypeFileItem item = ParameterTypeFileList.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 = _parameterProvider.GetXmlParameterList(prefix); item.FileListByProcessType = ParameterTreeBuilder.BuildFileNode(prefix, selectedFile, selectionIsFolder, recipes)[0].Files; item.InvokePropertyChanged(); } private bool IsExistV2(string fullPath, bool isFile) { for (int i = 0; i < ParameterTypeFileList.Count; i++) { if (ParameterTypeFileList[i].ProcessType == CurrentParameterType) { if (ParameterTypeFileList[i].FileListByProcessType.Count == 0) return false; return ParameterTypeFileList[i].FileListByProcessType.Any(a=>(a.PrefixPath+a.Name).Equals(fullPath)); } } return true; } private bool IsExist(string fullPath, bool isFile) { for (int i = 0; i < ParameterTypeFileList.Count; i++) { if (ParameterTypeFileList[i].ProcessType == CurrentParameterType) { if (ParameterTypeFileList[i].FileListByProcessType.Count == 0) return false; return FindFile(fullPath, ParameterTypeFileList[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 {CurrentParameter.Name} is changed, do you want to save it?"); if (selection == DialogButton.Cancel) return; if (selection == DialogButton.Yes) { this.CurrentParameter.Revisor = BaseApp.Instance.UserContext.LoginName; this.CurrentParameter.ReviseTime = DateTime.Now; this.Save(this.CurrentParameter, false); } } InputFileNameDialogViewModel dialog = new InputFileNameDialogViewModel("Input New Recipe Name", ParameterTypeFileList[0].FileListByProcessType); dialog.FileName = CurrentFileNode.Name; WindowManager wm = new WindowManager(); bool? dialogReturn = wm.ShowDialog(dialog); if (!dialogReturn.HasValue || !dialogReturn.Value) return; string recipeName = dialog.FileName.Trim(); string filepath = dialog.FilePath; if (string.IsNullOrEmpty(dialog.FileName)) { DialogBox.ShowWarning("Recipe file name should not be empty"); return; } string prefix = CurrentChamberType + "\\" + CurrentParameterType + "\\" + filepath; 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 (IsExistV2(prefix+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; } CurrentParameter.Creator = BaseApp.Instance.UserContext.LoginName; CurrentParameter.CreateTime = DateTime.Now; CurrentParameter.Revisor = BaseApp.Instance.UserContext.LoginName; CurrentParameter.ReviseTime = DateTime.Now; CurrentParameter.Description = CurrentParameter.Description + ". Renamed from " + CurrentFileNode.Name; _parameterProvider.SaveAsParameter(prefix, recipeName, CurrentParameter.GetXmlString()); ReloadParameterFileList(CurrentChamberType, CurrentParameterType, recipeName, false); } public void RenameParameter() { if (CurrentFileNode == null || !CurrentFileNode.IsFile) return; if (IsChanged) { var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No | DialogButton.Cancel, DialogType.CONFIRM, $"Recipe {CurrentParameter.Name} is changed, do you want to save it?"); if (selection == DialogButton.Cancel) return; if (selection == DialogButton.Yes) { this.CurrentParameter.Revisor = BaseApp.Instance.UserContext.LoginName; this.CurrentParameter.ReviseTime = DateTime.Now; this.Save(this.CurrentParameter, false); } } InputFileNameDialogViewModel dialog = new InputFileNameDialogViewModel("Input New Recipe Name", ParameterTypeFileList[0].FileListByProcessType, CurrentParameter.Description, Visibility.Hidden); 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 + "\\" + CurrentParameterType; 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 (IsExistV2(prefix+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; } _parameterProvider.RenameParameter(prefix, CurrentFileNode.FullPath, newName); CurrentParameter.Name = dialog.FileName; CurrentParameter.Description = dialog.Comment; this.Save(CurrentParameter, false); ReloadParameterFileList(CurrentChamberType, CurrentParameterType, newName, false); } public void DeleteParameter() { 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; } } } } _parameterProvider.DeleteParameter(CurrentFileNode.PrefixPath, CurrentFileNode.FullPath); ReloadParameterFileList(CurrentChamberType, CurrentParameterType, nextFocus, isFolder); } public void ReloadParameter() { if (this.editMode == EditMode.Normal || this.editMode == EditMode.Edit) { this.LoadData(CurrentParameter.PrefixPath, CurrentParameter.Name); this.UpdateView(); } } public void SaveToAll() { if (!CurrentParameter.IsCompatibleWithCurrentFormat) { DialogBox.ShowWarning($"Save failed, {CurrentParameter.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; CurrentParameter.SaveTo(Chambers.ToArray()); Save(this.CurrentParameter, false); } public void SaveTo() { if (!CurrentParameter.IsCompatibleWithCurrentFormat) { DialogBox.ShowWarning($"Save failed, {CurrentParameter.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 chambers = new List(); foreach (var dialogChamber in dialog.Chambers) { if (dialogChamber.IsEnabled && dialogChamber.IsChecked) chambers.Add(dialogChamber.Name); } if (chambers.Count == 0) return; CurrentParameter.SaveTo(chambers.ToArray()); Save(this.CurrentParameter, false); } public void EditParameter() { CGlobal.ParameterEditViewEnable = true; MECF.Framework.UI.Client.CenterViews.Editors.Recipe.CGlobal.ParameterEditViewEnable = true; PopupPage(); ReloadParameterFileList(CurrentChamberType, CurrentParameterType, CurrentFileNode.Name, false); } public void ViewParameter() { CGlobal.ParameterEditViewEnable = false; MECF.Framework.UI.Client.CenterViews.Editors.Recipe.CGlobal.ParameterEditViewEnable = false; PopupPage(); } #endregion #region Steps public void SaveParameter() { if (this.IsChanged) { this.Save(this.CurrentParameter, false); } } public void SavePermission() { RecipePermissionSelectViewModel dialog = new RecipePermissionSelectViewModel("Save recipe and permission", CurrentFileNode.Permission, CurrentParameter.Description); WindowManager wm = new WindowManager(); bool? dialogReturn = wm.ShowDialog(dialog); if (!dialogReturn.HasValue || !dialogReturn.Value) return; CurrentParameter.Permission = dialog.RecipePermission; CurrentParameter.Description = dialog.RecipeComment; this.Save(CurrentParameter, false); ReloadParameterFileList(CurrentChamberType, CurrentParameterType, CurrentFileNode.Parent.FullPath, false); } public bool Save(ParameterDataBase parameter, bool createNew) { bool result = false; if (string.IsNullOrEmpty(parameter.Name)) { MessageBox.Show("Parameter name can't be empty"); return false; } parameter.Revisor = BaseApp.Instance.UserContext.LoginName; parameter.ReviseTime = DateTime.Now; result = this._parameterProvider.SaveParameter(parameter.PrefixPath, parameter.Name, parameter.GetXmlString()); if (result) { parameter.DataSaved(); this.editMode = EditMode.Normal; this.UpdateView(); } else { MessageBox.Show("Save failed!"); } return result; } private TreeViewItem GetParentObjectEx(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(e.OriginalSource as DependencyObject) as TreeViewItem; if (item != null) { item.Focus(); } } #endregion private void ClearData() { this.editMode = EditMode.None; this.CurrentParameter.Clear(); this.CurrentParameter.Name = string.Empty; this.CurrentParameter.Description = string.Empty; } private void LoadData(string prefixPath, string recipeName) { CurrentParameter.Clear(); var recipeContent = _parameterProvider.LoadParameter(prefixPath, recipeName); if (string.IsNullOrEmpty(recipeContent)) { MessageBox.Show($"{prefixPath}\\{recipeName} is empty, please confirm the file is valid."); return; } CurrentParameter.ChamberType = CurrentParameterType; CurrentParameter.Version = "";// _columnBuilder.ParameterVersion; CurrentParameter.InitData(prefixPath, recipeName, recipeContent, SelectedChamber); this.editMode = EditMode.Normal; } private void UpdateView() { bool isFileSelected = CurrentFileNode != null && CurrentFileNode.IsFile; this.NotifyOfPropertyChange("CurrentRecipe"); } private void PopupPage() { if (CurrentFileNode == null || !CurrentFileNode.IsFile) return; var windowManager = IoC.Get(); switch (CurrentParameterType) { case "TempPID": TempPIDEditViewModel tempPIDEditViewModel = new TempPIDEditViewModel(CurrentParameter.PrefixPath, CurrentParameter.Name, CurrentFileNode.Permission); tempPIDEditViewModel.ParameterType = CurrentParameterType; (windowManager as WindowManager)?.ShowDialogWithTitle(tempPIDEditViewModel, null, "TempPID Edit"); break; case "TempCorrection": TempCorrectionEditViewModel tempCorrectionEditViewModel = new TempCorrectionEditViewModel(CurrentParameter.PrefixPath, CurrentParameter.Name, CurrentFileNode.Permission); tempCorrectionEditViewModel.ParameterType = CurrentParameterType; tempCorrectionEditViewModel.IsManualSet = true; (windowManager as WindowManager)?.ShowDialogWithTitle(tempCorrectionEditViewModel, null, "Temp Correction Edit"); break; case "TempProfile": TempProfileEditViewModel tempProfileEditViewModel = new TempProfileEditViewModel(CurrentParameter.PrefixPath, CurrentParameter.Name, CurrentFileNode.Permission); tempProfileEditViewModel.ParameterType = CurrentParameterType; (windowManager as WindowManager)?.ShowDialogWithTitle(tempProfileEditViewModel, null, "Temp Profile Edit"); break; case "LeakCheckCondition": LeakCheckConditionEditViewModel leakCheckConditionEditViewModel = new LeakCheckConditionEditViewModel(CurrentParameter.PrefixPath, CurrentParameter.Name, CurrentFileNode.Permission); leakCheckConditionEditViewModel.ParameterType = CurrentParameterType; (windowManager as WindowManager)?.ShowDialogWithTitle(leakCheckConditionEditViewModel, null, "Leak Check Condition Edit"); break; case "APCPID": APCPIDEditViewModel aPCPIDEditViewModel = new APCPIDEditViewModel(CurrentParameter.PrefixPath, CurrentParameter.Name, CurrentFileNode.Permission); aPCPIDEditViewModel.ParameterType = CurrentParameterType; (windowManager as WindowManager)?.ShowDialogWithTitle(aPCPIDEditViewModel, null, "APC PID Edit"); break; case "TempAutoPID": TempAutoPIDEditViewModel tempAutoPIDEditViewModel = new TempAutoPIDEditViewModel(CurrentParameter.PrefixPath, CurrentParameter.Name, CurrentFileNode.Permission); tempAutoPIDEditViewModel.ParameterType = CurrentParameterType; (windowManager as WindowManager)?.ShowDialogWithTitle(tempAutoPIDEditViewModel, null, "Temp Auto PID Edit"); break; case "AlarmCondition": AlarmConditionEditViewModel alarmConditionEditViewModel = new AlarmConditionEditViewModel(CurrentParameter.PrefixPath, CurrentParameter.Name, CurrentFileNode.Permission); alarmConditionEditViewModel.ParameterType = CurrentParameterType; (windowManager as WindowManager)?.ShowDialogWithTitle(alarmConditionEditViewModel, null, "Alarm Condition"); break; default: break; } } } }