DirectoryCreator/MainWindow.xaml.cs

483 lines
18 KiB
C#

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using DirectoryCreator.Models;
using DirectoryCreator.ViewModels;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Text.Json;
using System.Windows;
namespace DirectoryCreator
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainWindowViewModel();
}
}
}
namespace DirectoryCreator.ViewModels
{
public partial class MainWindowViewModel : ObservableObject
{
private readonly string configDirectory = "Configurations";
private FolderConfig currentConfig;
[ObservableProperty]
private string lastProjectNumber;
[ObservableProperty]
private string newProjectName;
[ObservableProperty]
private string basePath;
[ObservableProperty]
private ObservableCollection<FolderConfig> availableConfigurations;
[ObservableProperty]
private FolderConfig selectedConfiguration;
public MainWindowViewModel()
{
IsDarkTheme = Properties.Settings.Default.IsDarkTheme;
ThemeManager.SetTheme(IsDarkTheme);
AvailableConfigurations = new ObservableCollection<FolderConfig>();
LoadConfigurations();
}
private void LoadConfigurations()
{
try
{
// Asegurar que existe el directorio de configuraciones
if (!Directory.Exists(configDirectory))
{
Directory.CreateDirectory(configDirectory);
// Si no existe, mover el archivo de configuración por defecto
if (File.Exists("folderConfig.json"))
{
File.Move("folderConfig.json", Path.Combine(configDirectory, "default.json"));
}
}
// Cargar todas las configuraciones
var jsonFiles = Directory.GetFiles(configDirectory, "*.json");
if (jsonFiles.Length == 0)
{
MessageBox.Show("No se encontraron archivos de configuración.", "Advertencia", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
AllowTrailingCommas = true
};
AvailableConfigurations.Clear();
foreach (var jsonFile in jsonFiles)
{
var jsonString = File.ReadAllText(jsonFile);
var config = JsonSerializer.Deserialize<FolderConfig>(jsonString, options);
if (config != null)
{
// Si no tiene descripción, usar el nombre del archivo
if (string.IsNullOrEmpty(config.Description))
{
config.Description = Path.GetFileNameWithoutExtension(jsonFile);
}
AvailableConfigurations.Add(config);
}
}
// Seleccionar la primera configuración por defecto
if (AvailableConfigurations.Count > 0)
{
SelectedConfiguration = AvailableConfigurations[0];
}
}
catch (Exception ex)
{
MessageBox.Show($"Error al cargar las configuraciones: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
[RelayCommand]
private void OpenBaseFolder()
{
try
{
if (Directory.Exists(BasePath))
{
Process.Start("explorer.exe", BasePath);
}
else
{
MessageBox.Show($"La carpeta base no existe: {BasePath}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
catch (Exception ex)
{
MessageBox.Show($"Error al abrir la carpeta base: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void LoadLastProjectNumber()
{
try
{
if (string.IsNullOrEmpty(BasePath) || !Directory.Exists(BasePath))
{
NewProjectName = "001 - ";
return;
}
var directories = Directory.GetDirectories(BasePath)
.Select(d => new DirectoryInfo(d).Name)
.ToList();
var regex = new System.Text.RegularExpressions.Regex(@"^(\d{1,3})\s-\s");
var projectNumbers = new HashSet<int>();
foreach (var dirName in directories)
{
var match = regex.Match(dirName);
if (match.Success && int.TryParse(match.Groups[1].Value, out int number))
{
projectNumbers.Add(number);
}
}
var sortedNumbers = projectNumbers.OrderByDescending(n => n).ToList();
int lastValidNumber = -1;
string lastProject = "";
foreach (int number in sortedNumbers)
{
if (projectNumbers.Contains(number - 1) && projectNumbers.Contains(number - 2))
{
lastValidNumber = number;
lastProject = directories.First(d => regex.Match(d).Success &&
int.Parse(regex.Match(d).Groups[1].Value) == number);
break;
}
}
LastProjectNumber = lastProject;
NewProjectName = lastValidNumber >= 0 ? $"{(lastValidNumber + 1):00} - " : "01 - ";
if (lastValidNumber < 0)
{
MessageBox.Show("No se encontró una secuencia válida de al menos 3 números consecutivos.\nSe iniciará desde 01.",
"Información", MessageBoxButton.OK, MessageBoxImage.Information);
}
}
catch (Exception ex)
{
MessageBox.Show($"Error al cargar el último proyecto: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
NewProjectName = "001 - ";
}
}
[RelayCommand]
private void EditConfigurations()
{
var window = new ConfigEditorWindow
{
Owner = System.Windows.Application.Current.MainWindow
};
if (SelectedConfiguration != null)
{
var configPath = Directory.GetFiles(configDirectory, "*.json")
.FirstOrDefault(f =>
{
var config = JsonSerializer.Deserialize<FolderConfig>(
File.ReadAllText(f),
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
return config?.Description == SelectedConfiguration.Description;
});
window.DataContext = new ConfigEditorViewModel(window, SelectedConfiguration, configPath);
}
else
{
window.DataContext = new ConfigEditorViewModel(window);
}
if (window.ShowDialog() == true)
{
LoadConfigurations();
}
}
[ObservableProperty]
private bool isDarkTheme;
partial void OnIsDarkThemeChanged(bool value)
{
ThemeManager.SetTheme(value);
// Opcional: Guardar la preferencia del usuario
Properties.Settings.Default.IsDarkTheme = value;
Properties.Settings.Default.Save();
}
[ObservableProperty]
private ObservableCollection<string> existingProjects = new();
[ObservableProperty]
private string selectedProject;
private void LoadExistingProjects()
{
try
{
if (string.IsNullOrEmpty(BasePath) || !Directory.Exists(BasePath))
{
ExistingProjects = new ObservableCollection<string>();
return;
}
var directories = Directory.GetDirectories(BasePath)
.Select(d => new DirectoryInfo(d).Name)
.OrderByDescending(name => name)
.ToList();
ExistingProjects = new ObservableCollection<string>(directories);
// Seleccionar el LastProjectNumber si existe
if (ExistingProjects.Count > 0)
{
if (!string.IsNullOrEmpty(LastProjectNumber) && ExistingProjects.Contains(LastProjectNumber))
{
SelectedProject = LastProjectNumber;
}
else
{
SelectedProject = ExistingProjects[0];
}
}
}
catch (Exception ex)
{
MessageBox.Show($"Error al cargar proyectos existentes: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
ExistingProjects = new ObservableCollection<string>();
}
}
partial void OnSelectedConfigurationChanged(FolderConfig value)
{
if (value != null)
{
currentConfig = value;
BasePath = value.BasePath;
LoadLastProjectNumber();
LoadExistingProjects(); // Cargar proyectos existentes cuando cambia la configuración
}
}
[RelayCommand]
private async Task RenameProject()
{
if (string.IsNullOrEmpty(SelectedProject))
{
MessageBox.Show("Por favor seleccione un proyecto para renombrar", "Advertencia", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
var result = Microsoft.Windows.Controls.InputDialog.Show(
"Renombrar Proyecto",
"Ingrese el nuevo nombre del proyecto:",
SelectedProject);
if (result.IsOk)
{
string newName = result.Result;
if (string.IsNullOrWhiteSpace(newName))
{
MessageBox.Show("El nombre no puede estar vacío", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
try
{
foreach (var structure in currentConfig.FolderStructures)
{
var basePath = structure.BasePath.Replace("{year}", DateTime.Now.Year.ToString());
var oldPath = Path.Combine(basePath, SelectedProject);
var newPath = Path.Combine(basePath, newName);
if (Directory.Exists(oldPath))
{
if (Directory.Exists(newPath))
{
MessageBox.Show($"Ya existe un directorio con el nombre: {newName}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
Directory.Move(oldPath, newPath);
}
}
MessageBox.Show("Proyecto renombrado exitosamente!", "Éxito", MessageBoxButton.OK, MessageBoxImage.Information);
LoadExistingProjects(); // Recargar la lista de proyectos
SelectedProject = newName;
}
catch (Exception ex)
{
MessageBox.Show($"Error al renombrar el proyecto: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
// Agregar este método en la clase MainWindowViewModel
[RelayCommand]
private void DeleteProject()
{
if (string.IsNullOrEmpty(SelectedProject))
{
MessageBox.Show("Por favor seleccione un proyecto para eliminar", "Advertencia", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
try
{
// Recopilar todos los directorios a verificar
List<string> directoriesToCheck = new List<string>();
List<string> nonEmptyDirectories = new List<string>();
// Primero encontrar todos los directorios del proyecto
foreach (var structure in currentConfig.FolderStructures)
{
var basePath = structure.BasePath.Replace("{year}", DateTime.Now.Year.ToString());
var projectPath = Path.Combine(basePath, SelectedProject);
if (Directory.Exists(projectPath))
{
directoriesToCheck.Add(projectPath);
}
}
if (!directoriesToCheck.Any())
{
MessageBox.Show("No se encontraron directorios para eliminar.", "Información", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
// Verificar que todos los directorios estén vacíos
foreach (var directory in directoriesToCheck)
{
if (!IsDirectoryEmpty(directory))
{
nonEmptyDirectories.Add(directory);
}
}
// Si hay directorios con contenido, mostrar mensaje y cancelar
if (nonEmptyDirectories.Any())
{
string message = "Los siguientes directorios contienen archivos y no pueden ser eliminados:\n\n";
message += string.Join("\n", nonEmptyDirectories);
message += "\n\nDebe vaciar estos directorios antes de poder eliminar el proyecto.";
MessageBox.Show(message, "Directorios no vacíos", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
// Si todos están vacíos, pedir confirmación
var result = MessageBox.Show(
$"Se eliminarán los siguientes directorios:\n\n{string.Join("\n", directoriesToCheck)}\n\n¿Está seguro que desea continuar?",
"Confirmar eliminación",
MessageBoxButton.YesNo,
MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
{
// Eliminar todos los directorios
foreach (var directory in directoriesToCheck)
{
if (Directory.Exists(directory))
{
Directory.Delete(directory, false); // false porque ya sabemos que están vacíos
}
}
MessageBox.Show("Proyecto eliminado exitosamente!", "Éxito", MessageBoxButton.OK, MessageBoxImage.Information);
LoadExistingProjects(); // Recargar la lista de proyectos
SelectedProject = null;
}
}
catch (Exception ex)
{
MessageBox.Show($"Error al eliminar el proyecto: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private bool IsDirectoryEmpty(string path)
{
try
{
return !Directory.EnumerateFileSystemEntries(path, "*", SearchOption.AllDirectories).Any();
}
catch (Exception)
{
return false;
}
}
[RelayCommand]
private void CreateDirectories()
{
if (string.IsNullOrEmpty(NewProjectName))
{
MessageBox.Show("Por favor ingrese un nombre de proyecto!", "Advertencia", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
if (currentConfig == null)
{
MessageBox.Show("Por favor seleccione una configuración!", "Advertencia", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
try
{
foreach (var structure in currentConfig.FolderStructures)
{
var basePath = structure.BasePath.Replace("{year}", DateTime.Now.Year.ToString());
var projectPath = Path.Combine(basePath, NewProjectName);
if (Directory.Exists(projectPath))
{
MessageBox.Show($"El directorio ya existe: {projectPath}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
Directory.CreateDirectory(projectPath);
foreach (var subfolder in structure.Subfolders)
{
var subfolderPath = Path.Combine(projectPath, subfolder);
Directory.CreateDirectory(subfolderPath);
}
}
Process.Start("explorer.exe", Path.Combine(BasePath, NewProjectName));
MessageBox.Show("Directorios creados exitosamente!", "Éxito", MessageBoxButton.OK, MessageBoxImage.Information);
LoadLastProjectNumber();
}
catch (Exception ex)
{
MessageBox.Show($"Error al crear directorios: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
}