Răsfoiți Sursa

Fixed session data passing

Krzysztof Krysiński 5 luni în urmă
părinte
comite
5c46753dbf

+ 2 - 2
src/PixiEditor/ViewModels/Document/AutosaveDocumentViewModel.cs

@@ -145,9 +145,9 @@ internal class AutosaveDocumentViewModel : ObservableObject
         IPreferences.Current.UpdateLocalPreference(PreferencesConstants.AutosaveHistory, historySessions);
     }
 
-    public void SetTempFileGuidAndLastSavedPath(Guid guid, string lastSavedPath)
+    public void SetTempFileGuidAndLastSavedPath(Guid? guid, string lastSavedPath)
     {
-        autosaveFileGuid = guid;
+        autosaveFileGuid = guid == null || guid.Value == Guid.Empty ? Guid.NewGuid() : guid.Value;
         LastAutosavedPath = lastSavedPath;
     }
 

+ 24 - 5
src/PixiEditor/ViewModels/Document/LazyDocumentViewModel.cs

@@ -7,6 +7,7 @@ internal class LazyDocumentViewModel : PixiObservableObject
     private string path;
     private bool associatePath;
     private Guid tempFileGuid;
+    private string? autosavePath;
     private string? originalPath;
 
     public string Path
@@ -27,23 +28,41 @@ internal class LazyDocumentViewModel : PixiObservableObject
         set => SetProperty(ref tempFileGuid, value);
     }
 
+    public string? AutosavePath
+    {
+        get => autosavePath;
+        set => SetProperty(ref autosavePath, value);
+    }
+
+    public string FileName => System.IO.Path.GetFileName(OriginalPath ?? Path);
+
     public string? OriginalPath
     {
         get => originalPath;
         set => SetProperty(ref originalPath, value);
     }
 
-    public string FileName => System.IO.Path.GetFileName(Path);
-
     public LazyDocumentViewModel(string path, bool associatePath)
     {
         Path = path;
+        OriginalPath = path;
         AssociatePath = associatePath;
     }
 
-    public void SetTempFileGuidAndLastSavedPath(Guid tempGuid, string? originalPath)
+    public void SetTempFileGuidAndLastSavedPath(Guid? tempGuid, string? tempPath)
     {
-        TempFileGuid = tempGuid;
-        OriginalPath = originalPath;
+        if (tempGuid == null)
+        {
+            return;
+        }
+
+        TempFileGuid = tempGuid.Value;
+
+        if (tempPath == null)
+        {
+            return;
+        }
+
+        AutosavePath = tempPath;
     }
 }

+ 78 - 34
src/PixiEditor/ViewModels/SubViewModels/FileViewModel.cs

@@ -688,6 +688,41 @@ internal class FileViewModel : SubViewModel<ViewModelMain>
             return;
 
         var nextSessionFiles = preferences.GetLocalPreference<SessionFile[]>(PreferencesConstants.NextSessionFiles, []);
+        var perDocumentHistories = GetHistoriesFromSession(lastSession, nextSessionFiles);
+
+        var toLoad = nextSessionFiles.ToList();
+
+        TryOpenFromSession(perDocumentHistories, toLoad, true);
+
+        // Files that were inside a previous session as lazy document and was not opened
+        if (toLoad.Any(x => x.OriginalFilePath == null && !string.IsNullOrEmpty(x.AutosaveFilePath)))
+        {
+            for (int i = history.Count - 2; i >= 0; i--)
+            {
+                var session = history[i];
+                var histories = GetHistoriesFromSession(session, nextSessionFiles);
+                TryOpenFromSession(histories, toLoad, false);
+
+                if (toLoad.Count == 0 || toLoad.All(x => x.OriginalFilePath != null))
+                    break;
+            }
+        }
+
+        foreach (var file in toLoad)
+        {
+            if (file.OriginalFilePath != null)
+            {
+                LoadNewest(file.OriginalFilePath, file.AutosaveFilePath, true);
+            }
+        }
+
+        Owner.AutosaveViewModel.CleanupAutosavedFilesAndHistory();
+        preferences.UpdateLocalPreference(PreferencesConstants.NextSessionFiles, Array.Empty<SessionFile>());
+    }
+
+    private static List<List<AutosaveHistoryEntry>> GetHistoriesFromSession(AutosaveHistorySession lastSession,
+        SessionFile[]? nextSessionFiles)
+    {
         List<List<AutosaveHistoryEntry>> perDocumentHistories = (
             from entry in lastSession.AutosaveEntries
             where nextSessionFiles.Any(a =>
@@ -697,28 +732,40 @@ internal class FileViewModel : SubViewModel<ViewModelMain>
             into entryGroup
             select entryGroup.OrderBy(a => a.DateTime).ToList()
         ).ToList();
+        return perDocumentHistories;
+    }
 
-        var toLoad = nextSessionFiles.ToList();
-
+    private void TryOpenFromSession(List<List<AutosaveHistoryEntry>> perDocumentHistories, List<SessionFile> toLoad, bool tryRecover)
+    {
         foreach (var documentHistory in perDocumentHistories)
         {
             AutosaveHistoryEntry lastEntry = documentHistory[^1];
             try
             {
-                if (lastEntry.Type != AutosaveHistoryType.OnClose)
+                if (tryRecover && lastEntry.Type != AutosaveHistoryType.OnClose)
                 {
                     // unexpected shutdown happened, this file wasn't saved on close, but we supposedly have a backup
-                    LoadNewest(lastEntry, true);
+                    LoadNewest(lastEntry.OriginalPath, AutosaveHelper.GetAutosavePath(lastEntry.TempFileGuid), true);
                     toLoad.RemoveAll(a =>
-                        a.AutosaveFilePath == AutosaveHelper.GetAutosavePath(lastEntry.TempFileGuid)
-                        || a.OriginalFilePath == lastEntry.OriginalPath);
+                        (a.AutosaveFilePath != null &&
+                         a.AutosaveFilePath == AutosaveHelper.GetAutosavePath(lastEntry.TempFileGuid))
+                        || (a.OriginalFilePath != null && a.OriginalFilePath == lastEntry.OriginalPath));
                 }
                 else if (lastEntry.Result == AutosaveHistoryResult.SavedBackup || lastEntry.OriginalPath == null)
                 {
-                    LoadFromAutosave(lastEntry, true);
+                    var matchingFile = toLoad.FirstOrDefault(x =>
+                        x.OriginalFilePath == null &&
+                        x.AutosaveFilePath == AutosaveHelper.GetAutosavePath(lastEntry.TempFileGuid));
+                    if (string.IsNullOrEmpty(matchingFile.AutosaveFilePath))
+                    {
+                        continue;
+                    }
+
+                    LoadFromAutosave(AutosaveHelper.GetAutosavePath(lastEntry.TempFileGuid), lastEntry.OriginalPath, true);
                     toLoad.RemoveAll(a =>
-                        a.AutosaveFilePath == AutosaveHelper.GetAutosavePath(lastEntry.TempFileGuid)
-                        || a.OriginalFilePath == lastEntry.OriginalPath);
+                        (a.AutosaveFilePath != null && a.AutosaveFilePath ==
+                            AutosaveHelper.GetAutosavePath(lastEntry.TempFileGuid))
+                        || (a.OriginalFilePath != null && a.OriginalFilePath == lastEntry.OriginalPath));
                 }
             }
             catch (Exception e)
@@ -726,17 +773,6 @@ internal class FileViewModel : SubViewModel<ViewModelMain>
                 CrashHelper.SendExceptionInfo(e);
             }
         }
-
-        foreach (var file in toLoad)
-        {
-            if (file.OriginalFilePath != null)
-            {
-                OpenFromPath(file.OriginalFilePath);
-            }
-        }
-
-        Owner.AutosaveViewModel.CleanupAutosavedFilesAndHistory();
-        preferences.UpdateLocalPreference(PreferencesConstants.NextSessionFiles, Array.Empty<SessionFile>());
     }
 
     private void LoadFromUnexpectedShutdown(AutosaveHistorySession lastSession)
@@ -753,7 +789,7 @@ internal class FileViewModel : SubViewModel<ViewModelMain>
             foreach (var backup in lastBackups)
             {
                 AutosaveHistoryEntry lastEntry = backup[^1];
-                LoadNewest(lastEntry, false);
+                LoadNewest(lastEntry.OriginalPath, AutosaveHelper.GetAutosavePath(lastEntry.TempFileGuid), false);
             }
 
             OptionsDialog<LocalizedString> dialog = new OptionsDialog<LocalizedString>("UNEXPECTED_SHUTDOWN",
@@ -771,14 +807,14 @@ internal class FileViewModel : SubViewModel<ViewModelMain>
         }
     }
 
-    private void LoadNewest(AutosaveHistoryEntry lastEntry, bool lazy)
+    private void LoadNewest(string? originalPath, string? autosavePath, bool lazy)
     {
         bool loadFromUserFile = false;
 
-        if (lastEntry.OriginalPath != null && File.Exists(lastEntry.OriginalPath))
+        if (originalPath != null && File.Exists(originalPath))
         {
-            DateTime saveFileWriteTime = File.GetLastWriteTime(lastEntry.OriginalPath);
-            DateTime autosaveWriteTime = lastEntry.DateTime;
+            DateTime saveFileWriteTime = File.GetLastWriteTime(originalPath);
+            DateTime autosaveWriteTime = File.GetLastWriteTime(autosavePath);
 
             loadFromUserFile = saveFileWriteTime > autosaveWriteTime;
         }
@@ -787,43 +823,46 @@ internal class FileViewModel : SubViewModel<ViewModelMain>
         {
             if (lazy)
             {
-                OpenFromPathLazy(lastEntry.OriginalPath);
+                OpenFromPathLazy(originalPath);
             }
             else
             {
-                OpenFromPath(lastEntry.OriginalPath);
+                OpenFromPath(originalPath);
             }
         }
         else
         {
-            LoadFromAutosave(lastEntry, lazy);
+            LoadFromAutosave(autosavePath, originalPath, lazy);
         }
     }
 
-    private void LoadFromAutosave(AutosaveHistoryEntry entry, bool lazy)
+    private void LoadFromAutosave(string autosavePath, string? originalPath, bool lazy)
     {
-        string path = AutosaveHelper.GetAutosavePath(entry.TempFileGuid);
+        string path = autosavePath;
         if (path == null || !File.Exists(path))
         {
             // TODO: Notice user when non-blocking notification system is implemented
             return;
         }
 
+        Guid? autosaveGuid = AutosaveHelper.GetAutosaveGuid(autosavePath);
         if (lazy)
         {
             var lazyDoc = OpenFromPathLazy(path, false);
-            lazyDoc.SetTempFileGuidAndLastSavedPath(entry.TempFileGuid, entry.OriginalPath);
+            lazyDoc.SetTempFileGuidAndLastSavedPath(autosaveGuid, path);
+            lazyDoc.OriginalPath = originalPath;
         }
         else
         {
             var document = OpenFromPath(path, false);
-            document.AutosaveViewModel.SetTempFileGuidAndLastSavedPath(entry.TempFileGuid, path);
+            document.AutosaveViewModel.SetTempFileGuidAndLastSavedPath(autosaveGuid, path);
         }
     }
 
     private List<RecentlyOpenedDocument> GetRecentlyOpenedDocuments()
     {
-        var paths = PixiEditorSettings.File.RecentlyOpened.Value.Take(PixiEditorSettings.File.MaxOpenedRecently.Value);
+        var paths = PixiEditorSettings.File.RecentlyOpened.Value.Take(PixiEditorSettings.File.MaxOpenedRecently
+            .Value);
         List<RecentlyOpenedDocument> documents = new List<RecentlyOpenedDocument>();
 
         foreach (string path in paths)
@@ -846,6 +885,11 @@ internal class FileViewModel : SubViewModel<ViewModelMain>
             return;
         }
 
-        document.AutosaveViewModel.SetTempFileGuidAndLastSavedPath(lazyDocument.TempFileGuid, lazyDocument.Path);
+        document.FullFilePath = lazyDocument.OriginalPath;
+        document.AutosaveViewModel.SetTempFileGuidAndLastSavedPath(lazyDocument.TempFileGuid, lazyDocument.AutosavePath);
+        if (lazyDocument.Path != lazyDocument.OriginalPath)
+        {
+            document.MarkAsUnsaved();
+        }
     }
 }

+ 12 - 2
src/PixiEditor/ViewModels/SubViewModels/LazyViewportWindowViewModel.cs

@@ -1,4 +1,5 @@
-using PixiDocks.Core.Docking;
+using System.ComponentModel;
+using PixiDocks.Core.Docking;
 using PixiDocks.Core.Docking.Events;
 using PixiEditor.ViewModels.Dock;
 using PixiEditor.ViewModels.Document;
@@ -9,7 +10,7 @@ internal class LazyViewportWindowViewModel : SubViewModel<WindowViewModel>, IDoc
     IDockableSelectionEvents
 {
     public string Id { get; } = Guid.NewGuid().ToString();
-    public string Title => Path.GetFileName(LazyDocument.OriginalPath ?? LazyDocument.Path);
+    public string Title => LazyDocument.FileName;
     public bool CanFloat { get; } = true;
     public bool CanClose { get; } = true;
     public TabCustomizationSettings TabCustomizationSettings { get; } = new DocumentTabCustomizationSettings();
@@ -19,6 +20,15 @@ internal class LazyViewportWindowViewModel : SubViewModel<WindowViewModel>, IDoc
     public LazyViewportWindowViewModel(WindowViewModel owner, LazyDocumentViewModel lazyDoc) : base(owner)
     {
         LazyDocument = lazyDoc;
+        LazyDocument.PropertyChanged += LazyDocumentOnPropertyChanged;
+    }
+
+    private void LazyDocumentOnPropertyChanged(object? sender, PropertyChangedEventArgs e)
+    {
+        if (e.PropertyName == nameof(LazyDocumentViewModel.OriginalPath))
+        {
+            OnPropertyChanged(nameof(Title));
+        }
     }
 
     void IDockableSelectionEvents.OnSelected()

+ 10 - 6
src/PixiEditor/ViewModels/ViewModelMain.cs

@@ -244,8 +244,10 @@ internal partial class ViewModelMain : ViewModelBase, ICommandsHandler
             }
         }
 
-        foreach (var lazyDoc in DocumentManagerSubViewModel.LazyDocuments)
+        int lazyDocCount = DocumentManagerSubViewModel.LazyDocuments.Count;
+        for (int i = 0; i < lazyDocCount; i++)
         {
+            var lazyDoc = DocumentManagerSubViewModel.LazyDocuments.First();
             CloseLazyDocument(lazyDoc);
             WindowSubViewModel.CloseViewportForLazyDocument(lazyDoc);
         }
@@ -263,8 +265,8 @@ internal partial class ViewModelMain : ViewModelBase, ICommandsHandler
         List<SessionFile> sessionFiles = IPreferences.Current
             .GetLocalPreference<SessionFile[]>(PreferencesConstants.NextSessionFiles)?.ToList() ?? new();
         sessionFiles.RemoveAll(x =>
-            x.OriginalFilePath == document.FullFilePath ||
-            x.AutosaveFilePath == document.AutosaveViewModel.LastAutosavedPath);
+            (x.OriginalFilePath != null && x.OriginalFilePath == document.FullFilePath) ||
+            (x.AutosaveFilePath != null && x.AutosaveFilePath == document.AutosaveViewModel.LastAutosavedPath));
         sessionFiles.Add(new SessionFile(document.FullFilePath, document.AutosaveViewModel.LastAutosavedPath));
 
         IPreferences.Current.UpdateLocalPreference(PreferencesConstants.NextSessionFiles, sessionFiles.ToArray());
@@ -275,15 +277,17 @@ internal partial class ViewModelMain : ViewModelBase, ICommandsHandler
         List<SessionFile> sessionFiles = IPreferences.Current
             .GetLocalPreference<SessionFile[]>(PreferencesConstants.NextSessionFiles)?.ToList() ?? new();
         sessionFiles.RemoveAll(x =>
-            x.OriginalFilePath == document.OriginalPath ||
-            x.AutosaveFilePath == document.Path);
-        sessionFiles.Add(new SessionFile(document.OriginalPath, document.Path));
+            (x.OriginalFilePath != null && x.OriginalFilePath == document.OriginalPath) ||
+            (x.AutosaveFilePath != null && x.AutosaveFilePath == document.AutosavePath));
+
+        sessionFiles.Add(new SessionFile(document.OriginalPath, document.AutosavePath));
 
         IPreferences.Current.UpdateLocalPreference(PreferencesConstants.NextSessionFiles, sessionFiles.ToArray());
     }
 
     internal void CloseLazyDocument(LazyDocumentViewModel document)
     {
+        DocumentManagerSubViewModel.LazyDocuments.Remove(document);
         LazyDocumentClosed?.Invoke(document);
     }