|
@@ -1,115 +1,73 @@
|
|
using System.IO;
|
|
using System.IO;
|
|
using System.Windows;
|
|
using System.Windows;
|
|
-using System.Windows.Media;
|
|
|
|
using System.Windows.Threading;
|
|
using System.Windows.Threading;
|
|
-using PixiEditor.Extensions.Common.Localization;
|
|
|
|
using PixiEditor.Extensions.Common.UserPreferences;
|
|
using PixiEditor.Extensions.Common.UserPreferences;
|
|
using PixiEditor.Helpers;
|
|
using PixiEditor.Helpers;
|
|
|
|
+using PixiEditor.Models.DocumentModels;
|
|
using PixiEditor.Models.IO;
|
|
using PixiEditor.Models.IO;
|
|
|
|
+using PixiEditor.Views.UserControls;
|
|
|
|
|
|
namespace PixiEditor.ViewModels.SubViewModels.Document;
|
|
namespace PixiEditor.ViewModels.SubViewModels.Document;
|
|
|
|
|
|
|
|
+
|
|
internal class AutosaveDocumentViewModel : NotifyableObject
|
|
internal class AutosaveDocumentViewModel : NotifyableObject
|
|
{
|
|
{
|
|
private readonly DispatcherTimer savingTimer;
|
|
private readonly DispatcherTimer savingTimer;
|
|
- private readonly DispatcherTimer updateTextTimer;
|
|
|
|
private readonly DispatcherTimer busyTimer;
|
|
private readonly DispatcherTimer busyTimer;
|
|
- private bool saveAfterNextFinish;
|
|
|
|
private int savingFailed;
|
|
private int savingFailed;
|
|
- private DateTime nextSave;
|
|
|
|
private Guid tempGuid;
|
|
private Guid tempGuid;
|
|
- private bool documentEnabled = true;
|
|
|
|
-
|
|
|
|
- private const string ClockIcon = "\ue84d";
|
|
|
|
- private const string WarnIcon = "\ue81e";
|
|
|
|
- private const string SaveIcon = "\ue8bc";
|
|
|
|
- private const string PauseIcon = "\ue8a2";
|
|
|
|
- private const string SavingIcon = "\ue864";
|
|
|
|
-
|
|
|
|
- private readonly Brush errorBrush = new SolidColorBrush(Color.FromArgb(255, 214, 66, 56));
|
|
|
|
- private readonly Brush warnBrush = new SolidColorBrush(Color.FromArgb(255, 219, 189, 53));
|
|
|
|
- private readonly Brush successBrush = new SolidColorBrush(Color.FromArgb(255, 83, 207, 72));
|
|
|
|
- private readonly Brush activeBrush = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));
|
|
|
|
- private readonly Brush inactiveBrush = new SolidColorBrush(Color.FromArgb(255, 120, 120, 120));
|
|
|
|
|
|
+ private bool autosaveEnabled = true;
|
|
|
|
+ private bool waitingForUpdateableChangeEnd = false;
|
|
|
|
+ private LastAutosaveData? lastAutosaveData = null;
|
|
|
|
+ private DateTime? autosaveLaunchDateTime = null;
|
|
|
|
|
|
private DocumentViewModel Document { get; }
|
|
private DocumentViewModel Document { get; }
|
|
-
|
|
|
|
- private double AutosavePeriodMinutes { get; set; } = -1;
|
|
|
|
-
|
|
|
|
- private bool SaveToDocumentPath => IPreferences.Current!.GetPreference(PreferencesConstants.AutosaveToDocumentPath, PreferencesConstants.AutosaveToDocumentPathDefault);
|
|
|
|
-
|
|
|
|
- private LocalizedString mainMenuText;
|
|
|
|
-
|
|
|
|
- public LocalizedString MainMenuText
|
|
|
|
- {
|
|
|
|
- get => mainMenuText;
|
|
|
|
- set => SetProperty(ref mainMenuText, value);
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
+ private double AutosavePeriodMinutes { get; set; } = -1;
|
|
|
|
|
|
- private bool isImportantText;
|
|
|
|
-
|
|
|
|
- public bool IsImportantText
|
|
|
|
- {
|
|
|
|
- get => isImportantText;
|
|
|
|
- set => SetProperty(ref isImportantText, value);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private string mainMenuIconText;
|
|
|
|
-
|
|
|
|
- public string MainMenuIconText
|
|
|
|
- {
|
|
|
|
- get => mainMenuIconText;
|
|
|
|
- set => SetProperty(ref mainMenuIconText, value);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private Brush mainMenuBrush;
|
|
|
|
-
|
|
|
|
- public Brush MainMenuBrush
|
|
|
|
|
|
+ private AutosaveStateData autosaveStateData;
|
|
|
|
+ public AutosaveStateData AutosaveStateData
|
|
{
|
|
{
|
|
- get => mainMenuBrush;
|
|
|
|
- set => SetProperty(ref mainMenuBrush, value);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private bool mainMenuPulse;
|
|
|
|
-
|
|
|
|
- public bool MainMenuPulse
|
|
|
|
- {
|
|
|
|
- get => mainMenuPulse;
|
|
|
|
- set => SetProperty(ref mainMenuPulse, value);
|
|
|
|
|
|
+ get => autosaveStateData;
|
|
|
|
+ set => SetProperty(ref autosaveStateData, value);
|
|
}
|
|
}
|
|
|
|
|
|
public bool Enabled
|
|
public bool Enabled
|
|
{
|
|
{
|
|
- get => documentEnabled;
|
|
|
|
|
|
+ get => autosaveEnabled;
|
|
set
|
|
set
|
|
{
|
|
{
|
|
- if (documentEnabled == value)
|
|
|
|
|
|
+ if (autosaveEnabled == value)
|
|
return;
|
|
return;
|
|
|
|
|
|
AutosavePeriodChanged(
|
|
AutosavePeriodChanged(
|
|
- IPreferences.Current.GetPreference(
|
|
|
|
|
|
+ IPreferences.Current!.GetPreference(
|
|
PreferencesConstants.AutosavePeriodMinutes,
|
|
PreferencesConstants.AutosavePeriodMinutes,
|
|
PreferencesConstants.AutosavePeriodDefault),
|
|
PreferencesConstants.AutosavePeriodDefault),
|
|
value);
|
|
value);
|
|
- SetProperty(ref documentEnabled, value);
|
|
|
|
|
|
+ SetProperty(ref autosaveEnabled, value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public string LastSavedPath { get; private set; }
|
|
public string LastSavedPath { get; private set; }
|
|
|
|
|
|
- public AutosaveDocumentViewModel(DocumentViewModel document)
|
|
|
|
|
|
+ public static bool SaveStateEnabled => IPreferences.Current!.GetPreference(PreferencesConstants.SaveSessionStateEnabled, PreferencesConstants.SaveSessionStateDefault);
|
|
|
|
+
|
|
|
|
+ private bool SaveToDocumentPath => IPreferences.Current!.GetPreference(PreferencesConstants.AutosaveToDocumentPath, PreferencesConstants.AutosaveToDocumentPathDefault);
|
|
|
|
+
|
|
|
|
+ public AutosaveDocumentViewModel(DocumentViewModel document, DocumentInternalParts internals)
|
|
{
|
|
{
|
|
Document = document;
|
|
Document = document;
|
|
tempGuid = Guid.NewGuid();
|
|
tempGuid = Guid.NewGuid();
|
|
|
|
|
|
var dispatcher = Application.Current.Dispatcher;
|
|
var dispatcher = Application.Current.Dispatcher;
|
|
|
|
|
|
- updateTextTimer = new DispatcherTimer(DispatcherPriority.Normal, dispatcher) { Interval = TimeSpan.FromSeconds(3.8) };
|
|
|
|
- updateTextTimer.Tick += (_, _) => SetAutosaveText();
|
|
|
|
-
|
|
|
|
savingTimer = new DispatcherTimer(DispatcherPriority.Normal);
|
|
savingTimer = new DispatcherTimer(DispatcherPriority.Normal);
|
|
- savingTimer.Tick += (_, _) => { savingTimer.Stop(); TryAutosave(); };
|
|
|
|
|
|
+ savingTimer.Tick += (_, _) =>
|
|
|
|
+ {
|
|
|
|
+ savingTimer.Stop();
|
|
|
|
+ TryAutosave();
|
|
|
|
+ };
|
|
|
|
|
|
busyTimer = new DispatcherTimer(DispatcherPriority.Normal, dispatcher) { Interval = TimeSpan.FromMilliseconds(80) };
|
|
busyTimer = new DispatcherTimer(DispatcherPriority.Normal, dispatcher) { Interval = TimeSpan.FromMilliseconds(80) };
|
|
busyTimer.Tick += (_, _) =>
|
|
busyTimer.Tick += (_, _) =>
|
|
@@ -118,73 +76,56 @@ internal class AutosaveDocumentViewModel : NotifyableObject
|
|
Document.Busy = true;
|
|
Document.Busy = true;
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+ internals.ChangeController.UpdateableChangeEnded += OnUpdateableChangeEnded;
|
|
|
|
+
|
|
var preferences = IPreferences.Current;
|
|
var preferences = IPreferences.Current;
|
|
|
|
|
|
- preferences!.AddCallback<double>(PreferencesConstants.AutosavePeriodMinutes, (v) => AutosavePeriodChanged(v, documentEnabled));
|
|
|
|
- AutosavePeriodChanged(preferences.GetPreference(PreferencesConstants.AutosavePeriodMinutes, PreferencesConstants.AutosavePeriodDefault), documentEnabled);
|
|
|
|
|
|
+ preferences!.AddCallback<double>(PreferencesConstants.AutosavePeriodMinutes, (v) => AutosavePeriodChanged(v, autosaveEnabled));
|
|
|
|
+ AutosavePeriodChanged(preferences.GetPreference(PreferencesConstants.AutosavePeriodMinutes, PreferencesConstants.AutosavePeriodDefault), autosaveEnabled);
|
|
}
|
|
}
|
|
|
|
|
|
- public static bool AutosavingEnabled =>
|
|
|
|
- (int)IPreferences.Current!.GetPreference(PreferencesConstants.AutosavePeriodMinutes, PreferencesConstants.AutosavePeriodDefault) != -1;
|
|
|
|
-
|
|
|
|
- public static bool SaveStateEnabled => IPreferences.Current!.GetPreference(PreferencesConstants.SaveSessionStateEnabled, PreferencesConstants.SaveSessionStateDefault);
|
|
|
|
-
|
|
|
|
- public void HintFinishedAction()
|
|
|
|
|
|
+ private AutosaveStateData CreateAutosaveStateData()
|
|
{
|
|
{
|
|
- if (!saveAfterNextFinish)
|
|
|
|
- return;
|
|
|
|
-
|
|
|
|
- saveAfterNextFinish = false;
|
|
|
|
-
|
|
|
|
- SafeAutosave(true);
|
|
|
|
|
|
+ return new AutosaveStateData
|
|
|
|
+ {
|
|
|
|
+ LastAutosaveData = lastAutosaveData,
|
|
|
|
+ AutosaveLaunchDateTime = autosaveLaunchDateTime ?? DateTime.Now,
|
|
|
|
+ AutosaveInterval = TimeSpan.FromMinutes(AutosavePeriodMinutes),
|
|
|
|
+ AutosaveState = AutosaveState.Paused
|
|
|
|
+ };
|
|
}
|
|
}
|
|
|
|
|
|
- private void SetAutosaveText()
|
|
|
|
|
|
+ public static void AutosaveOnClose()
|
|
{
|
|
{
|
|
- var timeLeft = nextSave - DateTime.Now;
|
|
|
|
-
|
|
|
|
- if (timeLeft.Minutes == 0)
|
|
|
|
- {
|
|
|
|
- UpdateMainMenuTextSave("AUTOSAVE_SAVING_IN_MINUTE", false, ClockIcon, inactiveBrush, false);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- var adjusted = timeLeft.Add(TimeSpan.FromSeconds(30));
|
|
|
|
|
|
|
|
- var minute = adjusted.Minutes < 2
|
|
|
|
- ? new LocalizedString("MINUTE_SINGULAR")
|
|
|
|
- : new LocalizedString("MINUTE_PLURAL");
|
|
|
|
-
|
|
|
|
- UpdateMainMenuTextSave(new LocalizedString("AUTOSAVE_SAVING_IN", adjusted.Minutes.ToString(), minute), false, ClockIcon, inactiveBrush, false);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
public void TryAutosave(bool saveUserFileIfEnabled = true)
|
|
public void TryAutosave(bool saveUserFileIfEnabled = true)
|
|
{
|
|
{
|
|
- if (Document.UpdateableChangeActive)
|
|
|
|
|
|
+ if (Document.AllChangesSaved)
|
|
{
|
|
{
|
|
- saveAfterNextFinish = true;
|
|
|
|
-
|
|
|
|
- savingTimer.Stop();
|
|
|
|
- updateTextTimer.Stop();
|
|
|
|
-
|
|
|
|
- UpdateMainMenuTextSave("AUTOSAVE_WAITING_FOR_SAVE", false, SaveIcon, activeBrush, true);
|
|
|
|
|
|
+ RestartTimers();
|
|
|
|
|
|
|
|
+ lastAutosaveData = new LastAutosaveData()
|
|
|
|
+ {
|
|
|
|
+ Time = DateTime.Now,
|
|
|
|
+ BackupSaveResult = BackupAutosaveResult.NothingToSave,
|
|
|
|
+ UserFileSaveResult = UserFileAutosaveResult.NothingToSave
|
|
|
|
+ };
|
|
|
|
+ AutosaveStateData = CreateAutosaveStateData() with { AutosaveState = AutosaveState.Idle };
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- if (Document.AllChangesSaved)
|
|
|
|
|
|
+ if (Document.UpdateableChangeActive)
|
|
{
|
|
{
|
|
- updateTextTimer.Stop();
|
|
|
|
- RestartTimers();
|
|
|
|
- UpdateMainMenuTextSave("AUTOSAVE_NOTHING_CHANGED", false, SaveIcon, inactiveBrush, false);
|
|
|
|
|
|
+ waitingForUpdateableChangeEnd = true;
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- updateTextTimer.Stop();
|
|
|
|
SafeAutosave(saveUserFileIfEnabled);
|
|
SafeAutosave(saveUserFileIfEnabled);
|
|
}
|
|
}
|
|
|
|
|
|
- public void PanicAutosave()
|
|
|
|
|
|
+ public void PanicAutosaveFromDeadlockDetector()
|
|
{
|
|
{
|
|
string filePath = Path.Join(Paths.PathToUnsavedFilesFolder, $"autosave-{tempGuid}.pixi");
|
|
string filePath = Path.Join(Paths.PathToUnsavedFilesFolder, $"autosave-{tempGuid}.pixi");
|
|
Directory.CreateDirectory(Directory.GetParent(filePath)!.FullName);
|
|
Directory.CreateDirectory(Directory.GetParent(filePath)!.FullName);
|
|
@@ -197,22 +138,24 @@ internal class AutosaveDocumentViewModel : NotifyableObject
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- private void SafeAutosave(bool saveUserFile)
|
|
|
|
|
|
+ private async void SafeAutosave(bool saveUserFile)
|
|
{
|
|
{
|
|
try
|
|
try
|
|
{
|
|
{
|
|
- Autosave(saveUserFile);
|
|
|
|
|
|
+ await Autosave(saveUserFile);
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
catch (Exception e)
|
|
{
|
|
{
|
|
savingFailed++;
|
|
savingFailed++;
|
|
|
|
|
|
- var minute = AutosavePeriodMinutes <= 1
|
|
|
|
- ? new LocalizedString("MINUTE_SINGULAR")
|
|
|
|
- : new LocalizedString("MINUTE_PLURAL");
|
|
|
|
-
|
|
|
|
- UpdateMainMenuTextSave(new LocalizedString("AUTOSAVE_FAILED_RETRYING", AutosavePeriodMinutes.ToString("0"), minute), true, WarnIcon, warnBrush, true);
|
|
|
|
-
|
|
|
|
|
|
+ lastAutosaveData = new LastAutosaveData()
|
|
|
|
+ {
|
|
|
|
+ Time = DateTime.Now,
|
|
|
|
+ BackupSaveResult = BackupAutosaveResult.Error,
|
|
|
|
+ UserFileSaveResult = UserFileAutosaveResult.ExceptionWhileSaving
|
|
|
|
+ };
|
|
|
|
+ AutosaveStateData = CreateAutosaveStateData() with { AutosaveState = AutosaveState.Idle };
|
|
|
|
+
|
|
busyTimer.Stop();
|
|
busyTimer.Stop();
|
|
Document.Busy = false;
|
|
Document.Busy = false;
|
|
|
|
|
|
@@ -225,11 +168,9 @@ internal class AutosaveDocumentViewModel : NotifyableObject
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- private void Autosave(bool saveUserFile)
|
|
|
|
|
|
+ private async Task Autosave(bool saveUserFile)
|
|
{
|
|
{
|
|
- saveAfterNextFinish = false;
|
|
|
|
-
|
|
|
|
- UpdateMainMenuTextSave("AUTOSAVE_SAVING", true, SavingIcon, activeBrush, true);
|
|
|
|
|
|
+ AutosaveStateData = CreateAutosaveStateData() with { AutosaveState = AutosaveState.InProgress };
|
|
|
|
|
|
string filePath = Path.Join(Paths.PathToUnsavedFilesFolder, $"autosave-{tempGuid}.pixi");
|
|
string filePath = Path.Join(Paths.PathToUnsavedFilesFolder, $"autosave-{tempGuid}.pixi");
|
|
Directory.CreateDirectory(Directory.GetParent(filePath)!.FullName);
|
|
Directory.CreateDirectory(Directory.GetParent(filePath)!.FullName);
|
|
@@ -237,16 +178,22 @@ internal class AutosaveDocumentViewModel : NotifyableObject
|
|
busyTimer.Start();
|
|
busyTimer.Start();
|
|
var result = Exporter.TrySave(Document, filePath);
|
|
var result = Exporter.TrySave(Document, filePath);
|
|
|
|
|
|
|
|
+ UserFileAutosaveResult userFileSaveResult = UserFileAutosaveResult.Disabled;
|
|
|
|
+
|
|
if (result == SaveResult.Success)
|
|
if (result == SaveResult.Success)
|
|
{
|
|
{
|
|
if (saveUserFile && SaveToDocumentPath && Document.FullFilePath != null)
|
|
if (saveUserFile && SaveToDocumentPath && Document.FullFilePath != null)
|
|
{
|
|
{
|
|
- CopyTemp(filePath);
|
|
|
|
|
|
+ userFileSaveResult = await CopyTempToUserFile(filePath);
|
|
}
|
|
}
|
|
- else
|
|
|
|
|
|
+
|
|
|
|
+ lastAutosaveData = new LastAutosaveData
|
|
{
|
|
{
|
|
- UpdateMainMenuTextSave("AUTOSAVE_SAVED", true, SaveIcon, successBrush, false);
|
|
|
|
- }
|
|
|
|
|
|
+ Time = DateTime.Now,
|
|
|
|
+ BackupSaveResult = BackupAutosaveResult.Success,
|
|
|
|
+ UserFileSaveResult = userFileSaveResult
|
|
|
|
+ };
|
|
|
|
+ AutosaveStateData = CreateAutosaveStateData() with { AutosaveState = AutosaveState.Idle, LastAutosaveData = lastAutosaveData };
|
|
|
|
|
|
Document.MarkAsAutosaved();
|
|
Document.MarkAsAutosaved();
|
|
LastSavedPath = filePath;
|
|
LastSavedPath = filePath;
|
|
@@ -256,17 +203,20 @@ internal class AutosaveDocumentViewModel : NotifyableObject
|
|
busyTimer.Stop();
|
|
busyTimer.Stop();
|
|
Document.Busy = false;
|
|
Document.Busy = false;
|
|
|
|
|
|
- var minute = AutosavePeriodMinutes <= 1
|
|
|
|
- ? new LocalizedString("MINUTE_SINGULAR")
|
|
|
|
- : new LocalizedString("MINUTE_PLURAL");
|
|
|
|
|
|
+ lastAutosaveData = new LastAutosaveData()
|
|
|
|
+ {
|
|
|
|
+ Time = DateTime.Now,
|
|
|
|
+ BackupSaveResult = BackupAutosaveResult.Error,
|
|
|
|
+ UserFileSaveResult = userFileSaveResult
|
|
|
|
+ };
|
|
|
|
+ AutosaveStateData = CreateAutosaveStateData() with { AutosaveState = AutosaveState.Idle, LastAutosaveData = lastAutosaveData };
|
|
|
|
|
|
- UpdateMainMenuTextSave(new LocalizedString("AUTOSAVE_FAILED_RETRYING", AutosavePeriodMinutes.ToString("0"), minute), true, WarnIcon, warnBrush, true);
|
|
|
|
savingFailed++;
|
|
savingFailed++;
|
|
|
|
|
|
if (savingFailed < 3)
|
|
if (savingFailed < 3)
|
|
{
|
|
{
|
|
- int _savingFailed = savingFailed;
|
|
|
|
- Task.Run(() => CrashHelper.SendExceptionInfoToWebhook(new Exception($"Failed to autosave for the {_savingFailed}. time due to {result}")));
|
|
|
|
|
|
+ int savingFailedCopy = savingFailed;
|
|
|
|
+ Task.Run(() => CrashHelper.SendExceptionInfoToWebhook(new Exception($"Failed to autosave for the {savingFailedCopy}. time due to {result}")));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -276,45 +226,29 @@ internal class AutosaveDocumentViewModel : NotifyableObject
|
|
RestartTimers();
|
|
RestartTimers();
|
|
}
|
|
}
|
|
|
|
|
|
- private void CopyTemp(string tempPath)
|
|
|
|
|
|
+ private async Task<UserFileAutosaveResult> CopyTempToUserFile(string tempPath)
|
|
{
|
|
{
|
|
- if (File.Exists(Document.FullFilePath))
|
|
|
|
- {
|
|
|
|
- UpdateMainMenuTextSave("AUTOSAVE_PLEASE_RESAVE", true, SaveIcon, errorBrush, true);
|
|
|
|
- }
|
|
|
|
|
|
+ if (!File.Exists(Document.FullFilePath))
|
|
|
|
+ return UserFileAutosaveResult.NoUserFile;
|
|
|
|
|
|
- Task.Run(Copy);
|
|
|
|
|
|
+ var result = await Task.Run(Copy);
|
|
|
|
+ Document.MarkAsSaved();
|
|
|
|
+ return result;
|
|
|
|
|
|
- void Copy()
|
|
|
|
|
|
+ UserFileAutosaveResult Copy()
|
|
{
|
|
{
|
|
try
|
|
try
|
|
{
|
|
{
|
|
File.Copy(tempPath, Document.FullFilePath!, true);
|
|
File.Copy(tempPath, Document.FullFilePath!, true);
|
|
- Application.Current.Dispatcher.Invoke(() =>
|
|
|
|
- {
|
|
|
|
- Document.MarkAsSaved();
|
|
|
|
- UpdateMainMenuTextSave("AUTOSAVE_SAVED", true, SaveIcon, successBrush, false);
|
|
|
|
- });
|
|
|
|
|
|
+ return UserFileAutosaveResult.Success;
|
|
}
|
|
}
|
|
catch (Exception e) when (e is UnauthorizedAccessException or DirectoryNotFoundException)
|
|
catch (Exception e) when (e is UnauthorizedAccessException or DirectoryNotFoundException)
|
|
{
|
|
{
|
|
- Application.Current.Dispatcher.Invoke(() =>
|
|
|
|
- {
|
|
|
|
- UpdateMainMenuTextSave("AUTOSAVE_PLEASE_RESAVE", true, SaveIcon, errorBrush, true);
|
|
|
|
- });
|
|
|
|
|
|
+ return UserFileAutosaveResult.NoUserFile;
|
|
}
|
|
}
|
|
catch
|
|
catch
|
|
{
|
|
{
|
|
- var minute = AutosavePeriodMinutes <= 1
|
|
|
|
- ? new LocalizedString("MINUTE_SINGULAR")
|
|
|
|
- : new LocalizedString("MINUTE_PLURAL");
|
|
|
|
-
|
|
|
|
- Application.Current.Dispatcher.Invoke(() =>
|
|
|
|
- {
|
|
|
|
- UpdateMainMenuTextSave(
|
|
|
|
- new LocalizedString("AUTOSAVE_FAILED_RETRYING", AutosavePeriodMinutes.ToString("0"), minute),
|
|
|
|
- true, WarnIcon, warnBrush, true);
|
|
|
|
- });
|
|
|
|
|
|
+ return UserFileAutosaveResult.ExceptionWhileSaving;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -322,35 +256,19 @@ internal class AutosaveDocumentViewModel : NotifyableObject
|
|
private void RestartTimers()
|
|
private void RestartTimers()
|
|
{
|
|
{
|
|
savingTimer.Start();
|
|
savingTimer.Start();
|
|
- nextSave = DateTime.Now + savingTimer.Interval;
|
|
|
|
- updateTextTimer.Start();
|
|
|
|
}
|
|
}
|
|
|
|
|
|
private void AutosavePeriodChanged(double minutes, bool documentEnabled)
|
|
private void AutosavePeriodChanged(double minutes, bool documentEnabled)
|
|
{
|
|
{
|
|
if ((int)minutes == -1 || !documentEnabled)
|
|
if ((int)minutes == -1 || !documentEnabled)
|
|
{
|
|
{
|
|
- savingTimer.IsEnabled = false;
|
|
|
|
- updateTextTimer.IsEnabled = false;
|
|
|
|
- saveAfterNextFinish = false;
|
|
|
|
-
|
|
|
|
- LocalizedString menuText = documentEnabled ? string.Empty : "AUTOSAVE_DISABLED";
|
|
|
|
- string iconText = documentEnabled ? null : PauseIcon;
|
|
|
|
-
|
|
|
|
- UpdateMainMenuTextSave(menuText, false, iconText, activeBrush, false);
|
|
|
|
-
|
|
|
|
AutosavePeriodMinutes = minutes;
|
|
AutosavePeriodMinutes = minutes;
|
|
|
|
+ AutosaveStateData = CreateAutosaveStateData();
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- var timerEnabled = savingTimer.IsEnabled;
|
|
|
|
|
|
+ var timerEnabled = savingTimer.IsEnabled || (int)AutosavePeriodMinutes == -1 || !Enabled;
|
|
|
|
|
|
- if ((int)AutosavePeriodMinutes == -1 || !Enabled)
|
|
|
|
- {
|
|
|
|
- timerEnabled = true;
|
|
|
|
- updateTextTimer.Start();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
savingTimer.IsEnabled = false;
|
|
savingTimer.IsEnabled = false;
|
|
|
|
|
|
var timeSpan = TimeSpan.FromMinutes(minutes);
|
|
var timeSpan = TimeSpan.FromMinutes(minutes);
|
|
@@ -358,12 +276,11 @@ internal class AutosaveDocumentViewModel : NotifyableObject
|
|
AutosavePeriodMinutes = minutes;
|
|
AutosavePeriodMinutes = minutes;
|
|
|
|
|
|
savingTimer.IsEnabled = timerEnabled;
|
|
savingTimer.IsEnabled = timerEnabled;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void OnUpdateableChangeEnded(object? sender, EventArgs args)
|
|
|
|
+ {
|
|
|
|
|
|
- nextSave = DateTime.Now + timeSpan;
|
|
|
|
- if (updateTextTimer.IsEnabled)
|
|
|
|
- {
|
|
|
|
- SetAutosaveText();
|
|
|
|
- }
|
|
|
|
}
|
|
}
|
|
|
|
|
|
public void SetTempFileGuidAndLastSavedPath(Guid guid, string lastSavedPath)
|
|
public void SetTempFileGuidAndLastSavedPath(Guid guid, string lastSavedPath)
|
|
@@ -371,13 +288,4 @@ internal class AutosaveDocumentViewModel : NotifyableObject
|
|
tempGuid = guid;
|
|
tempGuid = guid;
|
|
LastSavedPath = lastSavedPath;
|
|
LastSavedPath = lastSavedPath;
|
|
}
|
|
}
|
|
-
|
|
|
|
- private void UpdateMainMenuTextSave(LocalizedString text, bool isImportantText, string iconText, Brush brush, bool pulse)
|
|
|
|
- {
|
|
|
|
- MainMenuText = text;
|
|
|
|
- IsImportantText = isImportantText;
|
|
|
|
- MainMenuIconText = iconText;
|
|
|
|
- MainMenuBrush = brush;
|
|
|
|
- MainMenuPulse = pulse;
|
|
|
|
- }
|
|
|
|
}
|
|
}
|