Se implementó un sistema para gestionar múltiples ventanas de biblioteca, permitiendo la activación de una ventana existente o la creación de una nueva. Además, se mejoró la lógica de pegado de objetos, integrando la validación del contenido del portapapeles y la capacidad de pegar desde el portapapeles del sistema. Se añadió un método para recargar la imagen actual después de pegar en el proyecto actual, mejorando la experiencia del usuario al gestionar objetos en la biblioteca.
This commit is contained in:
parent
c03f6970d8
commit
9b710fcb00
|
@ -1162,13 +1162,35 @@ namespace CtrEditor
|
|||
OnPropertyChanged(nameof(SelectedItemOsList));
|
||||
}
|
||||
|
||||
// Diccionario para manejar ventanas de biblioteca múltiples
|
||||
private Dictionary<string, PopUps.LibraryWindow> _libraryWindows = new();
|
||||
|
||||
private void ShowLibraryManager()
|
||||
{
|
||||
const string libraryWindowKey = "LibraryManager";
|
||||
|
||||
// Verificar si ya existe una ventana de biblioteca
|
||||
if (_libraryWindows.TryGetValue(libraryWindowKey, out var existingWindow) &&
|
||||
existingWindow.IsVisible)
|
||||
{
|
||||
existingWindow.Activate();
|
||||
return;
|
||||
}
|
||||
|
||||
// Crear nueva ventana modeless
|
||||
var libraryWindow = new PopUps.LibraryWindow();
|
||||
var libraryViewModel = new PopUps.LibraryWindowViewModel(this);
|
||||
libraryWindow.DataContext = libraryViewModel;
|
||||
libraryWindow.Owner = MainWindow;
|
||||
libraryWindow.ShowDialog();
|
||||
|
||||
// Manejar el cierre de la ventana
|
||||
libraryWindow.Closed += (s, e) => _libraryWindows.Remove(libraryWindowKey);
|
||||
|
||||
// Registrar la ventana
|
||||
_libraryWindows[libraryWindowKey] = libraryWindow;
|
||||
|
||||
// Mostrar como modeless (no modal)
|
||||
libraryWindow.Show();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ namespace CtrEditor.PopUps
|
|||
AddLibraryDirectoryCommand = new RelayCommand(AddLibraryDirectory);
|
||||
RemoveLibraryDirectoryCommand = new RelayCommand(RemoveLibraryDirectory, () => SelectedLibraryDirectory != null);
|
||||
CopyObjectCommand = new RelayCommand(CopyObject, () => HasSelectedObjects());
|
||||
PasteObjectCommand = new RelayCommand(PasteObject, () => SelectedLibrary != null && _clipboardObjects.Any());
|
||||
PasteObjectCommand = new RelayCommand(PasteObject, () => SelectedLibrary != null && (HasObjectsAvailableToPaste()));
|
||||
DeleteObjectCommand = new RelayCommand(DeleteObject, () => HasSelectedObjects() && SelectedLibrary != null && !SelectedLibrary.IsCurrentProject);
|
||||
CreateNewLibraryCommand = new RelayCommand(CreateNewLibrary, () => SelectedLibraryDirectory != null);
|
||||
|
||||
|
@ -92,6 +92,34 @@ namespace CtrEditor.PopUps
|
|||
return SelectableObjects?.Any(o => o.IsSelected) == true || SelectedObject != null;
|
||||
}
|
||||
|
||||
private bool HasObjectsAvailableToPaste()
|
||||
{
|
||||
// Verificar si hay objetos en el portapapeles interno o en el portapapeles del sistema
|
||||
return _clipboardObjects.Any() ||
|
||||
(System.Windows.Clipboard.ContainsText() && IsValidObjectData(System.Windows.Clipboard.GetText()));
|
||||
}
|
||||
|
||||
private bool IsValidObjectData(string text)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(text)) return false;
|
||||
|
||||
try
|
||||
{
|
||||
text = text.Trim();
|
||||
|
||||
// Validación básica: debe ser JSON que empiece con [ o {
|
||||
if (!(text.StartsWith("[") || text.StartsWith("{"))) return false;
|
||||
|
||||
// Intentar parsearlo rápidamente sin deserializar completamente
|
||||
var token = Newtonsoft.Json.Linq.JToken.Parse(text);
|
||||
return token != null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private List<osBase> GetSelectedObjects()
|
||||
{
|
||||
var selected = new List<osBase>();
|
||||
|
@ -457,7 +485,9 @@ namespace CtrEditor.PopUps
|
|||
{
|
||||
try
|
||||
{
|
||||
_clipboardObjects.Clear();
|
||||
// Usar el mismo sistema de portapapeles que MainWindow
|
||||
// Crear copias usando la misma lógica que DuplicarObjeto
|
||||
var objectsCopy = new List<osBase>();
|
||||
|
||||
var settings = new JsonSerializerSettings
|
||||
{
|
||||
|
@ -471,20 +501,24 @@ namespace CtrEditor.PopUps
|
|||
// Prepare object for serialization
|
||||
obj.SalvarDatosNoSerializables();
|
||||
|
||||
// Serialize and deserialize to create a deep copy
|
||||
// Serialize and deserialize to create a deep copy (same as DuplicarObjeto)
|
||||
var serializedData = JsonConvert.SerializeObject(obj, settings);
|
||||
var copiedObject = JsonConvert.DeserializeObject<osBase>(serializedData, settings);
|
||||
|
||||
if (copiedObject != null)
|
||||
{
|
||||
_clipboardObjects.Add(copiedObject);
|
||||
objectsCopy.Add(copiedObject);
|
||||
}
|
||||
|
||||
// Restore object state
|
||||
obj.RestaurarDatosNoSerializables();
|
||||
}
|
||||
|
||||
MessageBox.Show($"{_clipboardObjects.Count} objeto(s) copiado(s) al portapapeles.", "Información", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
// Copiar al portapapeles del sistema usando el mismo formato que MainWindow
|
||||
string jsonString = JsonConvert.SerializeObject(objectsCopy, settings);
|
||||
System.Windows.Clipboard.SetText(jsonString);
|
||||
|
||||
MessageBox.Show($"{objectsCopy.Count} objeto(s) copiado(s) al portapapeles del sistema.", "Información", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
CommandManager.InvalidateRequerySuggested();
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -496,11 +530,64 @@ namespace CtrEditor.PopUps
|
|||
|
||||
private void PasteObject()
|
||||
{
|
||||
if (SelectedLibrary != null && _clipboardObjects.Any())
|
||||
if (SelectedLibrary != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var objToPaste in _clipboardObjects)
|
||||
List<osBase> objectsToPaste = new List<osBase>();
|
||||
|
||||
// Si hay objetos en el portapapeles interno (modo anterior)
|
||||
if (_clipboardObjects.Any())
|
||||
{
|
||||
objectsToPaste = _clipboardObjects.ToList();
|
||||
}
|
||||
// Si no, intentar usar el portapapeles del sistema
|
||||
else if (System.Windows.Clipboard.ContainsText())
|
||||
{
|
||||
string jsonString = System.Windows.Clipboard.GetText();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(jsonString))
|
||||
{
|
||||
var settings = new JsonSerializerSettings
|
||||
{
|
||||
TypeNameHandling = TypeNameHandling.All,
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
ObjectCreationHandling = ObjectCreationHandling.Replace,
|
||||
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
|
||||
};
|
||||
|
||||
// Intentar deserializar como lista de objetos
|
||||
try
|
||||
{
|
||||
objectsToPaste = JsonConvert.DeserializeObject<List<osBase>>(jsonString, settings);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Si falla, intentar como objeto individual
|
||||
try
|
||||
{
|
||||
var singleObject = JsonConvert.DeserializeObject<osBase>(jsonString, settings);
|
||||
if (singleObject != null)
|
||||
{
|
||||
objectsToPaste = new List<osBase> { singleObject };
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
MessageBox.Show("No se pudo deserializar el contenido del portapapeles como objetos válidos.", "Error", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!objectsToPaste.Any())
|
||||
{
|
||||
MessageBox.Show("No hay objetos para pegar.", "Información", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var objToPaste in objectsToPaste)
|
||||
{
|
||||
// Create a new unique ID for the pasted object
|
||||
objToPaste.Id.ObtenerNuevaID();
|
||||
|
@ -526,9 +613,15 @@ namespace CtrEditor.PopUps
|
|||
}
|
||||
}
|
||||
|
||||
// Si se pegó en el proyecto actual, recargar la imagen actual
|
||||
if (SelectedLibrary.IsCurrentProject)
|
||||
{
|
||||
ReloadCurrentImage();
|
||||
}
|
||||
|
||||
RefreshLibraries();
|
||||
LoadObjectsFromLibrary();
|
||||
MessageBox.Show($"{_clipboardObjects.Count} objeto(s) pegado(s).", "Información", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
MessageBox.Show($"{objectsToPaste.Count} objeto(s) pegado(s).", "Información", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -537,6 +630,26 @@ namespace CtrEditor.PopUps
|
|||
}
|
||||
}
|
||||
|
||||
// Método para recargar la imagen actual después de pegar en el proyecto actual
|
||||
private void ReloadCurrentImage()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Forzar recarga de la imagen actual para reflejar los cambios
|
||||
var currentImage = _mainViewModel.SelectedImage;
|
||||
if (!string.IsNullOrEmpty(currentImage))
|
||||
{
|
||||
// Temporalmente cambiar a null y luego restaurar para forzar la recarga
|
||||
_mainViewModel.SelectedImage = null;
|
||||
_mainViewModel.SelectedImage = currentImage;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"Error al recargar imagen actual: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private void DeleteObject()
|
||||
{
|
||||
var objectsToDelete = GetSelectedObjects();
|
||||
|
@ -624,13 +737,6 @@ namespace CtrEditor.PopUps
|
|||
|
||||
try
|
||||
{
|
||||
var simulationData = new SimulationData
|
||||
{
|
||||
ObjetosSimulables = new ObservableCollection<osBase>(library.Objects),
|
||||
UnitConverter = PixelToMeter.Instance.calc,
|
||||
PLC_ConnectionData = new LibS7Adv.PLCViewModel()
|
||||
};
|
||||
|
||||
var settings = new JsonSerializerSettings
|
||||
{
|
||||
Formatting = Formatting.Indented,
|
||||
|
@ -638,7 +744,29 @@ namespace CtrEditor.PopUps
|
|||
TypeNameHandling = TypeNameHandling.All
|
||||
};
|
||||
|
||||
string json = JsonConvert.SerializeObject(simulationData, settings);
|
||||
string json;
|
||||
|
||||
// Detectar si es formato AllPages.json basándose en el nombre del archivo
|
||||
var fileName = Path.GetFileName(library.FilePath).ToLowerInvariant();
|
||||
bool isAllPagesFormat = fileName.Contains("allpages") || fileName.StartsWith("allpages");
|
||||
|
||||
if (isAllPagesFormat)
|
||||
{
|
||||
// Formato AllPages.json: guardar como array directo de objetos
|
||||
json = JsonConvert.SerializeObject(library.Objects, settings);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Formato normal: guardar con wrapper SimulationData
|
||||
var simulationData = new SimulationData
|
||||
{
|
||||
ObjetosSimulables = new ObservableCollection<osBase>(library.Objects),
|
||||
UnitConverter = PixelToMeter.Instance.calc,
|
||||
PLC_ConnectionData = new LibS7Adv.PLCViewModel()
|
||||
};
|
||||
json = JsonConvert.SerializeObject(simulationData, settings);
|
||||
}
|
||||
|
||||
File.WriteAllText(library.FilePath, json);
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
Loading…
Reference in New Issue