From 006c98e5650b530e5220f279c1e803fefe69d40d Mon Sep 17 00:00:00 2001
From: alielie <alielie@git.com>
Date: 星期二, 25 十一月 2025 15:47:33 +0800
Subject: [PATCH] 优化一些东西;
---
Plugin.SeqEditor/ViewModel/SeqEditorViewModel.cs | 463 +++++++++++++++++++++++++++++++++++++++++++++------------
1 files changed, 362 insertions(+), 101 deletions(-)
diff --git a/Plugin.SeqEditor/ViewModel/SeqEditorViewModel.cs b/Plugin.SeqEditor/ViewModel/SeqEditorViewModel.cs
index b369169..fe22156 100644
--- a/Plugin.SeqEditor/ViewModel/SeqEditorViewModel.cs
+++ b/Plugin.SeqEditor/ViewModel/SeqEditorViewModel.cs
@@ -1,5 +1,6 @@
锘縰sing CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
+using GongSolutions.Wpf.DragDrop;
using HMI.Core.Util;
using HMI.UI;
using HMI.UI.Util;
@@ -11,6 +12,12 @@
using Plugin.SeqEditor.Util;
using System.Collections.ObjectModel;
using System.IO;
+using System.Runtime.InteropServices;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Input;
+using System.Windows.Media;
namespace Plugin.SeqEditor.ViewModel
{
@@ -44,25 +51,36 @@
[ObservableProperty]
private string targetType = null;
-
+ [ObservableProperty]
private string currentFilePath;
+
+ [ObservableProperty]
+ private bool canDrop = true;
+
+ public IDropTarget StepDropHandler { get; set; }
+
private Engine engine;
private SequenceFile sequenceFile;
+
+ public Dictionary<string, SequenceFile> cacheFiles = new Dictionary<string, SequenceFile>();
+
private bool isLoaded;
private ILog log;
public SeqEditor control { get; private set; }
public List<ItemData> Types = FilterTypeData.ItemSource;
- private HashSet<string> edits = new HashSet<string> {
+ private HashSet<string> edits = new HashSet<string>();
+ public Dictionary<Sequence, ObservableCollection<StepUI>> sequenceCache { get; private set; } = new();
+
+ private HashSet<string> indexType = new HashSet<string> {
StepTypeStr.PassFailTest,
StepTypeStr.NumericLimitTest,
StepTypeStr.NI_MultipleNumericLimitTest,
StepTypeStr.StringValueTest,
- StepTypeStr.Action,
StepTypeStr.NI_Wait,
- StepTypeStr.SequenceCall,
- };
+ StepTypeStr.Action
+ };
public SeqEditorViewModel(SeqEditor control, ILog log)
{
@@ -70,6 +88,8 @@
this.control = control;
engine = new Engine();
engine.LoadTypePaletteFilesEx();
+ TargetType = string.Empty;
+ StepDropHandler = new TreeListViewHandler(this);
}
~SeqEditorViewModel()
@@ -80,14 +100,23 @@
{
engine.ReleaseSequenceFileEx(sequenceFile);
}
+ foreach (var file in cacheFiles.Values)
+ {
+ engine.ReleaseSequenceFileEx(file);
+ }
engine.ShutDown(true);
// 涓嶅姞寤舵椂浼氬脊绐梞d
- System.Threading.Thread.Sleep(2500);
+ //System.Threading.Thread.Sleep(2500);
}
}
private ObservableCollection<StepUI> LoadSteps(Sequence seq, string group = null)
{
+ //if (sequenceCache.ContainsKey(seq))
+ //{
+ // return sequenceCache[seq];
+ //}
+
//setupSteps.Clear();
//var steps = new ObservableCollection<StepUI>();
//int num = seq.GetNumSteps(StepGroups.StepGroup_Setup);
@@ -133,46 +162,53 @@
//CurrentStepUI = null;
var steps = new ObservableCollection<StepUI>();
+ StepGroups[] groups = new StepGroups[] { StepGroups.StepGroup_Setup, StepGroups.StepGroup_Main, StepGroups.StepGroup_Cleanup };
- int num = seq.GetNumSteps(StepGroups.StepGroup_Setup);
- for (int i = 0; i < num; i++)
+ foreach (var stepGroup in groups)
{
- Step step = seq.GetStep(i, StepGroups.StepGroup_Setup);
- var ui = Convert2StepUI(step, group);
- if (ui != null)
+ int num = seq.GetNumSteps(stepGroup);
+ for (int i = 0; i < num; i++)
{
- steps.Add(ui);
+ Step step = seq.GetStep(i, stepGroup);
+ var ui = Convert2StepUI(i, step, seq, group);
+ if (ui != null)
+ {
+ steps.Add(ui);
+ }
}
}
- num = seq.GetNumSteps(StepGroups.StepGroup_Main);
- for (int i = 0; i < num; i++)
- {
- Step step = seq.GetStep(i, StepGroups.StepGroup_Main);
- var ui = Convert2StepUI(step, group);
- if (ui != null)
- {
- steps.Add(ui);
- }
- }
+ //int num = seq.GetNumSteps(StepGroups.StepGroup_Main);
+ //for (int i = 0; i < num; i++)
+ //{
+ // Step step = seq.GetStep(i, StepGroups.StepGroup_Main);
+ // var ui = Convert2StepUI(step, seq, group);
+ // if (ui != null)
+ // {
+ // steps.Add(ui);
+ // }
+ //}
- num = seq.GetNumSteps(StepGroups.StepGroup_Cleanup);
- for (int i = 0; i < num; i++)
- {
- Step step = seq.GetStep(i, StepGroups.StepGroup_Cleanup);
- var ui = Convert2StepUI(step, group);
- if (ui != null)
- {
- steps.Add(ui);
- }
- }
+ //num = seq.GetNumSteps(StepGroups.StepGroup_Cleanup);
+ //for (int i = 0; i < num; i++)
+ //{
+ // Step step = seq.GetStep(i, StepGroups.StepGroup_Cleanup);
+ // var ui = Convert2StepUI(step, seq, group);
+ // if (ui != null)
+ // {
+ // steps.Add(ui);
+ // }
+ //}
+ sequenceCache[seq] = steps;
return steps;
}
- private StepUI Convert2StepUI(Step step, string group)
+ private int indexCache = 0;
+
+ private StepUI Convert2StepUI(int index, Step step, Sequence sequence, string group)
{
- var ui = new StepUI(step);
- if (!edits.Contains(ui.Type))
+ var ui = new StepUI(step, sequence);
+ if (edits != null && edits.Count > 0 && !edits.Contains(ui.Type))
{
return null;
}
@@ -202,16 +238,54 @@
{
var po = step.Module.AsPropertyObject();
bool useCurFile = po.GetValBoolean("UseCurFile", 0);
- if (useCurFile)
+ string sfPath = po.GetValString("SFPath", 0);
+ if (useCurFile || Path.GetFileName(currentFilePath).Equals(sfPath, StringComparison.CurrentCultureIgnoreCase))
{
string seqName = po.GetValString("SeqName", 0);
- Sequence sequence = sequenceFile.GetSequenceByName(seqName);
- if (sequence == null)
+ Sequence sunSequence = sequenceFile.GetSequenceByName(seqName);
+ if (sunSequence == null)
{
return ui;
}
- ui.Children = LoadSteps(sequence, group);
+ ui.Children = LoadSteps(sunSequence, group);
}
+ else
+ {
+ string seqName = po.GetValString("SeqName", 0);
+ if (!Path.IsPathRooted(sfPath))
+ {
+ sfPath = Path.Combine(Path.GetDirectoryName(CurrentFilePath), sfPath);
+ }
+ SequenceFile diffSequence = null;
+ try
+ {
+ if (cacheFiles.ContainsKey(sfPath))
+ {
+ diffSequence = cacheFiles[sfPath];
+ }
+ else if (File.Exists(sfPath))
+ {
+ diffSequence = engine.GetSequenceFileEx(sfPath);
+ cacheFiles[sfPath] = diffSequence;
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Warn("Read Diff SubSequence Failed.", ex);
+ }
+ if (diffSequence != null)
+ {
+ Sequence sunSequence = diffSequence.GetSequenceByName(seqName);
+ ui.Children = LoadSteps(sunSequence, group);
+ }
+ }
+ }
+ else
+ {
+ }
+ if (CurrentSeqUI != null)
+ {
+ ui.SettingChanged += CurrentSeqUI.OnStepSettingChanged;
}
return ui;
}
@@ -232,20 +306,19 @@
{
Filter = $"{LangUtil.Get("se.seq")}|*.seq;"
};
- if (ofd.ShowDialog() == true)
+ if (ofd.ShowDialog() == true && DoClose())
{
control.BackgroundAction(() =>
{
try
{
var start = DateTime.Now;
- currentFilePath = ofd.FileName;
- CurrentFileName = $"{LangUtil.Get("se.currentFile")}{Path.GetFileName(currentFilePath)}";
+ CurrentFilePath = ofd.FileName;
if (sequenceFile != null)
{
engine.ReleaseSequenceFileEx(sequenceFile);
}
- sequenceFile = engine.GetSequenceFileEx(currentFilePath);
+ sequenceFile = engine.GetSequenceFileEx(CurrentFilePath);
Sequence main = sequenceFile.GetSequenceByName("MainSequence");
CurrentSeqUI = new SeqUI(main);
@@ -257,15 +330,19 @@
//}
//Sequences = seqs;
- if (Sequences != null && Sequences.Count > 0)
- {
- CurrentSeqUI = Sequences[0];
- }
- log.Info($"Open File [{currentFilePath}] In {(DateTime.Now - start).TotalMilliseconds}ms");
+ //if (Sequences != null && Sequences.Count > 0)
+ //{
+ // CurrentSeqUI = Sequences[0];
+ //}
+ log.Info($"Open File [{CurrentFilePath}] In {(DateTime.Now - start).TotalMilliseconds}ms");
}
catch (Exception ex)
{
-
+ log.Error($"Open Sequence Failed.", ex);
+ control.Dispatcher.Invoke(() =>
+ {
+ MsgBoxHelper2.Error(ex.Message);
+ });
}
}, LangUtil.Get("se.seqIsLoading"));
}
@@ -274,54 +351,105 @@
[RelayCommand]
private void SaveSeqFile()
{
- sequenceFile?.Save(currentFilePath);
+ if (sequenceFile == null) return;
+ try
+ {
+ sequenceFile?.Save(CurrentFilePath);
+ CurrentSeqUI.IsChanged = false;
+ foreach (var key in cacheFiles.Keys)
+ {
+ cacheFiles[key]?.Save(key);
+ }
+ ToastHelper.Success(LangUtil.Get("App.SaveSuccess"));
+ }
+ catch (Exception ex)
+ {
+ log.Error("Save Sequence File Error.", ex);
+ ToastHelper.Error($"{LangUtil.Get("App.SaveFailed")}: {ex.Message}");
+ }
+ }
+
+ [RelayCommand]
+ private void SaveToFile()
+ {
+ if (sequenceFile == null) return;
+ try
+ {
+ SaveFileDialog sfd = new SaveFileDialog()
+ {
+ Filter = $"{LangUtil.Get("se.seq")}|*.seq;"
+ };
+ if (sfd.ShowDialog() == true)
+ {
+ sequenceFile.Save(sfd.FileName);
+ CurrentFilePath = sfd.FileName;
+ foreach (var key in cacheFiles.Keys)
+ {
+ cacheFiles[key]?.Save(key);
+ }
+ ToastHelper.Success(LangUtil.Get("App.SaveSuccess"));
+ CurrentSeqUI.IsChanged = false;
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("Save Sequence File Error.", ex);
+ ToastHelper.Error($"{LangUtil.Get("App.SaveFailed")}: {ex.Message}");
+ }
}
[RelayCommand]
private void Refresh()
{
if (CurrentSeqUI == null) return;
- if (string.IsNullOrEmpty(TargetType))
- {
- edits = new HashSet<string> {
- StepTypeStr.PassFailTest,
- StepTypeStr.NumericLimitTest,
- StepTypeStr.NI_MultipleNumericLimitTest,
- StepTypeStr.StringValueTest,
- StepTypeStr.Action,
- StepTypeStr.NI_Wait,
- StepTypeStr.SequenceCall,
- };
- }
- else
- {
- edits = new HashSet<string>(TargetType.Split(','))
- {
- StepTypeStr.SequenceCall
- };
- }
- AllSteps = LoadSteps(CurrentSeqUI.sequence);
+ RefreshData();
}
- [RelayCommand]
- private void CloseSeqFile()
+ private bool DoClose()
{
- //AllSteps = new ObservableCollection<StepUI>();
+ if (CurrentSeqUI?.IsChanged == true)
+ {
+ if (MsgBoxHelper2.WarnChoose(LangUtil.Get("se.makeSureClose"))
+ == System.Windows.MessageBoxResult.OK)
+ {
+ goto DoClose;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ DoClose:
if (engine != null && sequenceFile != null)
{
engine.ReleaseSequenceFileEx(sequenceFile);
+ foreach (var file in cacheFiles.Values)
+ {
+ engine.ReleaseSequenceFileEx(file);
+ }
sequenceFile = null;
}
+
+ cacheFiles.Clear();
setupSteps.Clear();
mainSteps.Clear();
cleanupSteps.Clear();
AllSteps = new();
Sequences.Clear();
- currentFilePath = string.Empty;
+ CurrentFilePath = string.Empty;
CurrentFileName = string.Empty;
CurrentSeqUI = null;
CurrentStepUI = null;
CurrentSeqTitle = LangUtil.Get("se.steps");
+ sequenceCache.Clear();
+ return true;
+ }
+
+ [RelayCommand]
+ private void CloseSeqFile()
+ {
+ DoClose();
}
[RelayCommand]
@@ -330,21 +458,22 @@
try
{
var group = CurrentStepUI.step.StepGroup;
+ var targetSequence = CurrentStepUI.sequence;
- ObservableCollection<StepUI> source;
- if (group == StepGroups.StepGroup_Setup)
- {
- source = setupSteps;
- }
- else if (group == StepGroups.StepGroup_Main)
- {
- source = mainSteps;
- }
- else
- {
- source = cleanupSteps;
- }
- int index = source.IndexOf(CurrentStepUI);
+ ObservableCollection<StepUI> source = sequenceCache[targetSequence];
+ //if (group == StepGroups.StepGroup_Setup)
+ //{
+ // source = setupSteps;
+ //}
+ //else if (group == StepGroups.StepGroup_Main)
+ //{
+ // source = mainSteps;
+ //}
+ //else
+ //{
+ // source = cleanupSteps;
+ //}
+ int index = CurrentStepUI.IndexInSequence;
if (index < 0)
{
return;
@@ -355,14 +484,6 @@
case "Tests.PassFail":
newStep = engine.NewStep(AdapterKeyNames.FlexLVAdapterKeyName, StepTypeStr.PassFailTest);
newStep.Name = DefaultStepName.PassFailTest;
- var p = newStep.AsPropertyObject();
- string name = p.Name;
- var ps = p.GetSubProperties("", 0);
- foreach (var pp in ps)
- {
- string sname = pp.Name;
- }
-
break;
case "Tests.NumericLimitTest":
newStep = engine.NewStep(AdapterKeyNames.FlexLVAdapterKeyName, StepTypeStr.NumericLimitTest);
@@ -408,12 +529,37 @@
newStep = engine.NewStep(AdapterKeyNames.PythonAdapterKeyName, StepTypeStr.Action);
newStep.Name = DefaultStepName.Action;
break;
-
default:
return;
}
- CurrentSeqUI.sequence.InsertStep(newStep, index + 1, group);
- AllSteps = LoadSteps(CurrentSeqUI.sequence);
+ var newUI = new StepUI(newStep, targetSequence);
+
+
+ targetSequence.InsertStep(newStep, index + 1, group);
+ ObservableCollection<StepUI> datasource = sequenceCache[targetSequence];
+ int uiIndex = datasource.IndexOf(CurrentStepUI);
+ datasource.Insert(uiIndex + 1, newUI);
+
+
+ //var newItem = new TreeItemData
+ //{
+ // Level = TreeItemData.Level,
+ // ParentItem = TreeItemData.ParentItem,
+ // ParentItems = TreeItemData.ParentItems,
+ // Data = newUI
+ //};
+ //var parentItem = TreeItemData.ParentItem;
+ //if (parentItem != null)
+ //{
+ // var items = parentItem.Items;
+ // int innerIndex = items.IndexOf(TreeItemData);
+
+
+ // items.Insert(innerIndex + 1, newItem);
+ // TreeItemDataCollection.ResetSubItems(items);
+ //}
+ //int itemIndex = TreeCollection.IndexOf(TreeItemData);
+ //TreeCollection.Insert(itemIndex + TreeItemData.AllSubCount + 1, newItem);
}
catch (Exception ex)
{
@@ -422,12 +568,128 @@
}
}
+ [RelayCommand]
+ private void Sb(RoutedPropertyChangedEventArgs<object> e)
+ {
+ CurrentStepUI = e.NewValue as StepUI;
+ }
+
+ static TreeListViewItem VisualUpwardSearch(DependencyObject source)
+ {
+ while (source != null && !(source is TreeViewItem))
+ source = VisualTreeHelper.GetParent(source);
+
+ return source as TreeListViewItem;
+ }
+
+ [RelayCommand]
+ private void Sb2(MouseButtonEventArgs e)
+ {
+ var item = VisualUpwardSearch(e.OriginalSource as DependencyObject);
+ if (item != null)
+ {
+ item.Focus();
+ e.Handled = true;
+ }
+ }
+
[ObservableProperty]
private TreeItemData treeItemData;
+
+ public void RefreshView()
+ {
+ CollectionViewSource cvs = control.Resources["TreeGridFilter"] as CollectionViewSource;
+ control.Dispatcher.Invoke(() =>
+ {
+ cvs.View.Refresh();
+ });
+ }
+
+ [ObservableProperty]
+ private TreeItemDataCollection treeCollection = new TreeItemDataCollection();
+
+ public void RefreshData()
+ {
+ indexCache = 0;
+ sequenceCache.Clear();
+ foreach (var file in cacheFiles.Values)
+ {
+ try
+ {
+ engine.ReleaseSequenceFileEx(file);
+ Marshal.ReleaseComObject(file);
+ }
+ catch (Exception ex)
+ {
+ log.Error("RefreshData Release Last CacheFile Failed.", ex);
+ }
+ }
+ var converter = control.Resources["treeNumber"] as RowNumberConverter;
+ converter.Reset();
+ var temp = LoadSteps(CurrentSeqUI.sequence);
+ SetIndex(temp);
+ AllSteps = temp;
+ }
+
+ void SetIndex(IEnumerable<StepUI> datas)
+ {
+ foreach (var data in datas)
+ {
+ if (indexType.Contains(data.Type))
+ {
+ data.CustomIndex = ++indexCache;
+ }
+ if (data.Children != null && data.Children.Count > 0)
+ {
+ SetIndex(data.Children);
+ }
+ }
+ }
+
+ partial void OnAllStepsChanged(ObservableCollection<StepUI> data)
+ {
+ TreeCollection = new TreeItemDataCollection(AllSteps, "Children", true);
+ }
partial void OnTreeItemDataChanged(TreeItemData data)
{
CurrentStepUI = data?.Data as StepUI;
+ }
+
+ partial void OnTargetTypeChanged(string value)
+ {
+ if (string.IsNullOrEmpty(value))
+ {
+ edits = new HashSet<string>
+ {
+ //StepTypeStr.PassFailTest,
+ //StepTypeStr.NumericLimitTest,
+ //StepTypeStr.NI_MultipleNumericLimitTest,
+ //StepTypeStr.StringValueTest,
+ //StepTypeStr.Action,
+ //StepTypeStr.NI_Wait,
+ //StepTypeStr.SequenceCall,
+ };
+ }
+ else
+ {
+ edits = new HashSet<string>(value.Split(MultiComboBox.splits, StringSplitOptions.RemoveEmptyEntries))
+ {
+ StepTypeStr.SequenceCall
+ };
+ }
+ }
+
+ partial void OnCurrentFilePathChanged(string value)
+ {
+ if (string.IsNullOrEmpty(value))
+ {
+ CurrentFileName = string.Empty;
+ }
+ else
+ {
+ CurrentFileName = $"{LangUtil.Get("se.currentFile")}{Path.GetFileName(value)}";
+ }
}
partial void OnCurrentStepUIChanged(StepUI stepUI)
@@ -436,7 +698,6 @@
control.editPanelContainer.Child = panel;
if (stepUI != null)
{
-
//window.commonP.RefreshStep(stepUI);
}
}
@@ -446,7 +707,7 @@
if (seqUI != null)
{
CurrentStepUI = null;
- AllSteps = LoadSteps(seqUI.sequence);
+ RefreshData();
}
CurrentSeqTitle = $"{seqUI?.Name} {LangUtil.Get("se.steps")}";
}
--
Gitblit v1.9.1