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 _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 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(); 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 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; } } }