S7Explorer/ViewModels/MainViewModel.cs

199 lines
6.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Ookii.Dialogs.Wpf;
using S7Explorer.Models;
using S7Explorer.Parsers;
namespace S7Explorer.ViewModels
{
public class MainViewModel : ObservableObject
{
private string _searchText;
private object _selectedObject;
private object _selectedTreeItem;
private S7Project _currentProject;
private ObservableCollection<S7Object> _projectStructure;
private string _projectInfo;
private bool _isLoading;
public string SearchText
{
get => _searchText;
set => SetProperty(ref _searchText, value);
}
public object SelectedObject
{
get => _selectedObject;
set => SetProperty(ref _selectedObject, value);
}
public object SelectedTreeItem
{
get => _selectedTreeItem;
set
{
if (SetProperty(ref _selectedTreeItem, value))
{
// Actualizar el objeto seleccionado para PropertyGrid
SelectedObject = _selectedTreeItem;
}
}
}
public ObservableCollection<S7Object> ProjectStructure
{
get => _projectStructure;
set => SetProperty(ref _projectStructure, value);
}
public string ProjectInfo
{
get => _projectInfo;
set => SetProperty(ref _projectInfo, value);
}
public bool IsLoading
{
get => _isLoading;
set => SetProperty(ref _isLoading, value);
}
public IRelayCommand OpenProjectCommand { get; }
public IRelayCommand SearchCommand { get; }
public MainViewModel()
{
ProjectStructure = new ObservableCollection<S7Object>();
OpenProjectCommand = new RelayCommand(OpenProject);
SearchCommand = new RelayCommand(SearchInProject);
ProjectInfo = "No hay proyecto abierto";
}
private void OpenProject()
{
var dialog = new VistaOpenFileDialog
{
Title = "Seleccionar archivo de proyecto STEP7",
Filter = "Proyectos STEP7 (*.s7p)|*.s7p|Todos los archivos (*.*)|*.*",
CheckFileExists = true
};
if (dialog.ShowDialog() == true)
{
LoadProjectAsync(dialog.FileName);
}
}
private async void LoadProjectAsync(string filePath)
{
try
{
IsLoading = true;
ProjectInfo = "Cargando proyecto...";
// Reiniciar estado
ProjectStructure.Clear();
_currentProject = null;
// Parsear proyecto
var parser = new S7ProjectParser(filePath);
_currentProject = await parser.ParseProjectAsync();
// Actualizar UI
ProjectStructure.Add(_currentProject);
_currentProject.IsExpanded = true;
// Actualizar info
ProjectInfo = $"Proyecto: {Path.GetFileNameWithoutExtension(filePath)}";
}
catch (Exception ex)
{
MessageBox.Show($"Error al cargar el proyecto: {ex.Message}", "Error",
MessageBoxButton.OK, MessageBoxImage.Error);
ProjectInfo = "Error al cargar el proyecto";
}
finally
{
IsLoading = false;
}
}
private void SearchInProject()
{
if (_currentProject == null || string.IsNullOrWhiteSpace(SearchText))
return;
try
{
// Recopilar todos los objetos en el proyecto
var allObjects = GetAllObjects(_currentProject);
// Buscar objetos que coincidan con el texto
var matchingObjects = allObjects.Where(o => o.ContainsText(SearchText)).ToList();
if (matchingObjects.Count == 0)
{
MessageBox.Show($"No se encontraron coincidencias para: {SearchText}",
"Búsqueda", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
// Seleccionar el primer objeto coincidente y expandir su ruta
var firstMatch = matchingObjects.First();
SelectAndExpandToObject(firstMatch);
// Informar al usuario
if (matchingObjects.Count > 1)
{
MessageBox.Show($"Se encontraron {matchingObjects.Count} coincidencias. " +
"Mostrando la primera coincidencia.",
"Búsqueda", MessageBoxButton.OK, MessageBoxImage.Information);
}
}
catch (Exception ex)
{
MessageBox.Show($"Error durante la búsqueda: {ex.Message}",
"Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private IEnumerable<S7Object> GetAllObjects(S7Object root)
{
// Devolver el objeto raíz
yield return root;
// Recursivamente devolver todos los hijos
foreach (var child in root.Children)
{
foreach (var obj in GetAllObjects(child))
{
yield return obj;
}
}
}
private void SelectAndExpandToObject(S7Object obj)
{
// Expandir todos los nodos padres hasta llegar al objeto
var parent = obj.Parent;
while (parent != null)
{
parent.IsExpanded = true;
parent = parent.Parent;
}
// Seleccionar el objeto
SelectedTreeItem = obj;
}
}
}