diff --git a/src/Notepads/App.xaml.cs b/src/Notepads/App.xaml.cs index d8ffef582..7dbd39cd0 100644 --- a/src/Notepads/App.xaml.cs +++ b/src/Notepads/App.xaml.cs @@ -29,6 +29,7 @@ sealed partial class App : Application public static bool IsFirstInstance = false; public static bool IsGameBarWidget = false; + public static string PassedEditorData = string.Empty; private const string AppCenterSecret = null; diff --git a/src/Notepads/Controls/TextEditor/ITextEditor.cs b/src/Notepads/Controls/TextEditor/ITextEditor.cs index da127fe65..5dc37d43d 100644 --- a/src/Notepads/Controls/TextEditor/ITextEditor.cs +++ b/src/Notepads/Controls/TextEditor/ITextEditor.cs @@ -118,6 +118,8 @@ void GetLineColumnSelection( Task SaveContentToFileAndUpdateEditorState(StorageFile file); + void UpdateEditingFile(StorageFile file); + string GetContentForSharing(); void TypeText(string text); diff --git a/src/Notepads/Controls/TextEditor/TextEditor.xaml.cs b/src/Notepads/Controls/TextEditor/TextEditor.xaml.cs index 86ad23546..e1291ea0f 100644 --- a/src/Notepads/Controls/TextEditor/TextEditor.xaml.cs +++ b/src/Notepads/Controls/TextEditor/TextEditor.xaml.cs @@ -725,6 +725,12 @@ private async Task SaveContentToFile(StorageFile file) return new TextFile(text, encoding, lineEnding, newFileModifiedTime); } + public void UpdateEditingFile(StorageFile file) + { + EditingFile = file; + StartCheckingFileStatusPeriodically(); + } + public string GetContentForSharing() { return TextEditorCore.Document.Selection.StartPosition == TextEditorCore.Document.Selection.EndPosition ? diff --git a/src/Notepads/Core/ISessionManager.cs b/src/Notepads/Core/ISessionManager.cs index a4231a2d5..ebc8698d6 100644 --- a/src/Notepads/Core/ISessionManager.cs +++ b/src/Notepads/Core/ISessionManager.cs @@ -1,7 +1,10 @@ namespace Notepads.Core { + using Notepads.Controls.TextEditor; + using Notepads.Core.SessionDataModels; using System; using System.Threading.Tasks; + using Windows.Storage; internal interface ISessionManager { @@ -16,5 +19,7 @@ internal interface ISessionManager void StopSessionBackup(); Task ClearSessionDataAsync(); + + Task RecoverTextEditorAsync(TextEditorSessionDataV1 editorSessionData, StorageFile file = null); } } \ No newline at end of file diff --git a/src/Notepads/Core/NotepadsCore.cs b/src/Notepads/Core/NotepadsCore.cs index c94bc3d99..f0f040ceb 100644 --- a/src/Notepads/Core/NotepadsCore.cs +++ b/src/Notepads/Core/NotepadsCore.cs @@ -24,6 +24,7 @@ using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; using Microsoft.AppCenter.Analytics; + using Notepads.Core.SessionDataModels; public class NotepadsCore : INotepadsCore { @@ -56,6 +57,7 @@ public class NotepadsCore : INotepadsCore private readonly CoreDispatcher _dispatcher; + public const string NotepadsShouldHandleFileDrop = "NotepadsShouldHandleFileDrop"; private const string SetDragAndDropActionStatus = "SetDragAndDropActionStatus"; private const string NotepadsTextEditorMetaData = "NotepadsTextEditorMetaData"; private const string NotepadsTextEditorGuid = "NotepadsTextEditorGuid"; @@ -63,6 +65,8 @@ public class NotepadsCore : INotepadsCore private const string NotepadsTextEditorLastSavedContent = "NotepadsTextEditorLastSavedContent"; private const string NotepadsTextEditorPendingContent = "NotepadsTextEditorPendingContent"; private const string NotepadsTextEditorEditingFilePath = "NotepadsTextEditorEditingFilePath"; + private const string NotepadsTextEditorEditingFile = "NotepadsTextEditorEditingFile"; + private const string NotepadsTextEditorTempFolderPath = "Temp"; public NotepadsCore(SetsView sets, INotepadsExtensionProvider extensionProvider, @@ -596,7 +600,8 @@ private async void Sets_DragOver(object sender, DragEventArgs args) } } - if (!canHandle && args.DataView.Contains(StandardDataFormats.StorageItems)) + if (!canHandle && args.DataView.Contains(StandardDataFormats.StorageItems) && + !args.DataView.Properties.TryGetValue(NotepadsShouldHandleFileDrop, out object handleFileDrop)) { try { @@ -659,9 +664,8 @@ private void Sets_DragItemsStarting(object sender, DragItemsStartingEventArgs ar // Add Editing File if (editor.EditingFile != null) { - args.Data.Properties.FileTypes.Add(StandardDataFormats.StorageItems); args.Data.Properties.Add(NotepadsTextEditorEditingFilePath, editor.EditingFilePath); - args.Data.SetStorageItems(new List() { editor.EditingFile }, readOnly: false); + args.Data.Properties.Add(NotepadsTextEditorEditingFile, editor.EditingFile); } args.Data.Properties.Add(NotepadsTextEditorMetaData, data); @@ -688,7 +692,8 @@ private async void Sets_Drop(object sender, DragEventArgs args) if (string.IsNullOrEmpty(args.DataView?.Properties?.ApplicationName) || !string.Equals(args.DataView?.Properties?.ApplicationName, App.ApplicationName)) { - if (args.DataView == null || !args.DataView.Contains(StandardDataFormats.StorageItems)) return; + if (args.DataView == null || !args.DataView.Contains(StandardDataFormats.StorageItems) || + args.DataView.Properties.TryGetValue(NotepadsShouldHandleFileDrop, out object handleFileDrop)) return; var fileDropDeferral = args.GetDeferral(); var storageItems = await args.DataView.GetStorageItemsAsync(); StorageItemsDropped?.Invoke(this, storageItems); @@ -719,18 +724,9 @@ private async void Sets_Drop(object sender, DragEventArgs args) } StorageFile editingFile = null; - - if (metaData.HasEditingFile && args.DataView.Contains(StandardDataFormats.StorageItems)) + if (metaData.HasEditingFile && args.DataView.Properties.TryGetValue(NotepadsTextEditorEditingFile, out object editingFileObj)) { - var storageItems = await args.DataView.GetStorageItemsAsync(); - if (storageItems.Count == 1 && storageItems[0] is StorageFile file) - { - editingFile = file; - } - else - { - throw new Exception("Failed to read storage file from dropped set: Expecting only one storage file."); - } + editingFile = (StorageFile)editingFileObj; } string lastSavedText = null; @@ -816,13 +812,91 @@ private async void Sets_SetDraggedOutside(object sender, SetDraggedOutsideEventA { if (Sets.Items?.Count > 1 && e.Set?.Content is ITextEditor textEditor) { - // Only allow untitled empty document to be dragged outside for now - if (!textEditor.IsModified && textEditor.EditingFile == null) + var index = Sets.SelectedIndex; + var message = new ValueSet(); + var textEditorData = JsonConvert.SerializeObject(await BuildTextEditorSessionData(textEditor), Formatting.Indented); + if (textEditor.FileModificationState != FileModificationState.RenamedMovedOrDeleted) + { + message.Add("EditorData", textEditorData); + DeleteTextEditor(textEditor); + if (!await NotepadsProtocolService.LaunchProtocolAsync(NotepadsOperationProtocol.OpenNewInstance, message)) + { + OpenTextEditor(textEditor, index); + } + } + else { + ApplicationSettingsStore.Write("EditorData", textEditorData); DeleteTextEditor(textEditor); - await NotepadsProtocolService.LaunchProtocolAsync(NotepadsOperationProtocol.OpenNewInstance); + if (!await NotepadsProtocolService.LaunchProtocolAsync(NotepadsOperationProtocol.OpenNewInstance, textEditor.EditingFile)) + { + OpenTextEditor(textEditor, index); + } + } + } + } + + private async Task BuildTextEditorSessionData(ITextEditor textEditor) + { + TextEditorSessionDataV1 textEditorData = new TextEditorSessionDataV1 + { + Id = textEditor.Id, + }; + + if (textEditor.EditingFile != null) + { + // Add the opened file to FutureAccessList so we can access it next launch + var futureAccessToken = textEditor.Id.ToString("N"); + await FutureAccessListUtility.TryAddOrReplaceTokenInFutureAccessList(futureAccessToken, textEditor.EditingFile); + textEditorData.EditingFileFutureAccessToken = futureAccessToken; + textEditorData.EditingFileName = textEditor.EditingFileName; + textEditorData.EditingFilePath = textEditor.EditingFilePath; + } + + if (textEditor.IsModified || textEditor.FileModificationState != FileModificationState.Untouched) + { + if (textEditor.EditingFile != null) + { + // Persist the last save known to the app, which might not be up-to-date (if the file was modified outside the app) + var lastSavedBackupFile = await SessionUtility.CreateNewFileInBackupFolderAsync( + textEditor.Id.ToString("N") + "-LastSaved", + CreationCollisionOption.ReplaceExisting, + NotepadsTextEditorTempFolderPath); + + if (!await SessionManager.BackupTextAsync(textEditor.LastSavedSnapshot.Content, + textEditor.LastSavedSnapshot.Encoding, + textEditor.LastSavedSnapshot.LineEnding, + lastSavedBackupFile)) + { + return null; // Error: Failed to write backup text to file + } + + textEditorData.LastSavedBackupFilePath = lastSavedBackupFile.Path; + } + + if (textEditor.IsModified) + { + // Persist pending changes relative to the last save + var pendingBackupFile = await SessionUtility.CreateNewFileInBackupFolderAsync( + textEditor.Id.ToString("N") + "-Pending", + CreationCollisionOption.ReplaceExisting, + NotepadsTextEditorTempFolderPath); + + if (!await SessionManager.BackupTextAsync(textEditor.GetText(), + textEditor.LastSavedSnapshot.Encoding, + textEditor.LastSavedSnapshot.LineEnding, + pendingBackupFile)) + { + return null; // Error: Failed to write backup text to file + } + + textEditorData.PendingBackupFilePath = pendingBackupFile.Path; } } + + textEditorData.StateMetaData = textEditor.GetTextEditorStateMetaData(); + + return textEditorData; } #endregion diff --git a/src/Notepads/Core/SessionManager.cs b/src/Notepads/Core/SessionManager.cs index 5e0727972..7a2dc6df4 100644 --- a/src/Notepads/Core/SessionManager.cs +++ b/src/Notepads/Core/SessionManager.cs @@ -387,7 +387,7 @@ private void UnbindEditorContentStateChangeEvent(object sender, ITextEditor text textEditor.FileReloaded -= RemoveTextEditorSessionData; } - private async Task RecoverTextEditorAsync(TextEditorSessionDataV1 editorSessionData) + public async Task RecoverTextEditorAsync(TextEditorSessionDataV1 editorSessionData, StorageFile file = null) { StorageFile editingFile = null; @@ -446,10 +446,15 @@ private async Task RecoverTextEditorAsync(TextEditorSessionDataV1 e textEditor.ResetEditorState(editorSessionData.StateMetaData, pendingText); } + if (file != null) + { + textEditor.UpdateEditingFile(file); + } + return textEditor; } - private static async Task BackupTextAsync(string text, Encoding encoding, LineEnding lineEnding, StorageFile file) + public static async Task BackupTextAsync(string text, Encoding encoding, LineEnding lineEnding, StorageFile file) { try { diff --git a/src/Notepads/Program.cs b/src/Notepads/Program.cs index 1b8a51a61..5a198df6a 100644 --- a/src/Notepads/Program.cs +++ b/src/Notepads/Program.cs @@ -18,8 +18,6 @@ static void Main(string[] args) Task.Run(LoggingService.InitializeFileSystemLoggingAsync); #endif - IActivatedEventArgs activatedArgs = AppInstance.GetActivatedEventArgs(); - //if (activatedArgs == null) //{ // // No activated event args, so this is not an activation via the multi-instance ID @@ -37,55 +35,58 @@ static void Main(string[] args) ApplicationSettingsStore.Write(SettingsKey.ActiveInstanceIdStr, null); } - if (activatedArgs is FileActivatedEventArgs) - { - RedirectOrCreateNewInstance(); - } - else if (activatedArgs is CommandLineActivatedEventArgs) - { - RedirectOrCreateNewInstance(); - } - else if (activatedArgs is ProtocolActivatedEventArgs protocolActivatedEventArgs) + switch (AppInstance.GetActivatedEventArgs()) { - LoggingService.LogInfo($"[{nameof(Main)}] [ProtocolActivated] Protocol: {protocolActivatedEventArgs.Uri}"); - var protocol = NotepadsProtocolService.GetOperationProtocol(protocolActivatedEventArgs.Uri, out _); - if (protocol == NotepadsOperationProtocol.OpenNewInstance) - { - OpenNewInstance(); - } - else - { - RedirectOrCreateNewInstance(); - } - } - else if (activatedArgs is LaunchActivatedEventArgs launchActivatedEventArgs) - { - bool handled = false; + case LaunchActivatedEventArgs launchActivatedEventArgs: + bool handled = false; - if (!string.IsNullOrEmpty(launchActivatedEventArgs.Arguments)) - { - var protocol = NotepadsProtocolService.GetOperationProtocol(new Uri(launchActivatedEventArgs.Arguments), out _); - if (protocol == NotepadsOperationProtocol.OpenNewInstance) + if (!string.IsNullOrEmpty(launchActivatedEventArgs.Arguments)) { - handled = true; - OpenNewInstance(); + var protocol = NotepadsProtocolService.GetOperationProtocol(new Uri(launchActivatedEventArgs.Arguments), out _); + if (protocol == NotepadsOperationProtocol.OpenNewInstance) + { + handled = true; + OpenNewInstance(); + } } - } - if (!handled) - { + if (!handled) + { + RedirectOrCreateNewInstance(); + } + break; + case FileActivatedEventArgs fileActivatedEventArgs: + if (fileActivatedEventArgs.CallerPackageFamilyName == Package.Current.Id.FamilyName) + { + OpenNewInstance(); + } + else + { + RedirectOrCreateNewInstance(); + } + break; + case ProtocolActivatedEventArgs protocolActivatedEventArgs: + LoggingService.LogInfo($"[{nameof(Main)}] [ProtocolActivated] Protocol: {protocolActivatedEventArgs.Uri}"); + if (NotepadsProtocolService.GetOperationProtocol(protocolActivatedEventArgs.Uri, out _) == NotepadsOperationProtocol.OpenNewInstance) + { + OpenNewInstance(); + } + else + { + RedirectOrCreateNewInstance(); + } + break; + default: RedirectOrCreateNewInstance(); - } - } - else - { - RedirectOrCreateNewInstance(); + break; } } private static void OpenNewInstance() { AppInstance.FindOrRegisterInstanceForKey(App.Id.ToString()); + App.PassedEditorData = (string)ApplicationSettingsStore.Read("EditorData"); + ApplicationSettingsStore.Remove("EditorData"); App.IsFirstInstance = IsFirstInstance; Windows.UI.Xaml.Application.Start(p => new App()); IsFirstInstance = false; diff --git a/src/Notepads/Services/ActivationService.cs b/src/Notepads/Services/ActivationService.cs index dcb8fbea6..7fe58112a 100644 --- a/src/Notepads/Services/ActivationService.cs +++ b/src/Notepads/Services/ActivationService.cs @@ -10,28 +10,26 @@ public static class ActivationService { public static async Task ActivateAsync(Frame rootFrame, IActivatedEventArgs e) { - if (e is ProtocolActivatedEventArgs protocolActivatedEventArgs) + switch (e) { - ProtocolActivated(rootFrame, protocolActivatedEventArgs); - } - else if (e is FileActivatedEventArgs fileActivatedEventArgs) - { - await FileActivated(rootFrame, fileActivatedEventArgs); - } - else if (e is CommandLineActivatedEventArgs commandLineActivatedEventArgs) - { - await CommandActivated(rootFrame, commandLineActivatedEventArgs); - } - else if (e is LaunchActivatedEventArgs launchActivatedEventArgs) - { - LaunchActivated(rootFrame, launchActivatedEventArgs); - } - else // For other types of activated events - { - if (rootFrame.Content == null) - { - rootFrame.Navigate(typeof(NotepadsMainPage)); - } + case ProtocolActivatedEventArgs protocolActivatedEventArgs: + ProtocolActivated(rootFrame, protocolActivatedEventArgs); + break; + case FileActivatedEventArgs fileActivatedEventArgs: + await FileActivated(rootFrame, fileActivatedEventArgs); + break; + case CommandLineActivatedEventArgs commandLineActivatedEventArgs: + await CommandActivated(rootFrame, commandLineActivatedEventArgs); + break; + case LaunchActivatedEventArgs launchActivatedEventArgs: + LaunchActivated(rootFrame, launchActivatedEventArgs); + break; + default: // For other types of activated events + if (rootFrame.Content == null) + { + rootFrame.Navigate(typeof(NotepadsMainPage)); + } + break; } } diff --git a/src/Notepads/Services/NotepadsProtocolService.cs b/src/Notepads/Services/NotepadsProtocolService.cs index e0485bcf2..2ecc65f64 100644 --- a/src/Notepads/Services/NotepadsProtocolService.cs +++ b/src/Notepads/Services/NotepadsProtocolService.cs @@ -4,6 +4,10 @@ using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AppCenter.Analytics; + using Windows.ApplicationModel; + using Windows.Foundation.Collections; + using Windows.Storage; + using Windows.System; public enum NotepadsOperationProtocol { @@ -17,24 +21,17 @@ public static class NotepadsProtocolService public static NotepadsOperationProtocol GetOperationProtocol(Uri uri, out string context) { - context = null; + context = string.IsNullOrEmpty(uri.Query) ? null : uri.Query.TrimStart('?'); try { - var uriStr = uri.ToString().Trim(); - - if (string.IsNullOrEmpty(uriStr) || !uriStr.StartsWith("notepads://", StringComparison.OrdinalIgnoreCase)) + var uriScheme = uri.GetLeftPart(UriPartial.Scheme); + if (string.IsNullOrEmpty(uriScheme) || !string.Equals("notepads://", uriScheme, StringComparison.OrdinalIgnoreCase)) { return NotepadsOperationProtocol.Unrecognized; } - var operation = uriStr.Substring("notepads://".Length); - - if (operation.EndsWith("/")) - { - operation = operation.Remove(operation.Length - 1); - } - + var operation = uri.Authority; if (!string.IsNullOrEmpty(operation) && string.Equals(NewInstanceProtocolStr, operation, StringComparison.OrdinalIgnoreCase)) { return NotepadsOperationProtocol.OpenNewInstance; @@ -53,7 +50,7 @@ public static NotepadsOperationProtocol GetOperationProtocol(Uri uri, out string return NotepadsOperationProtocol.Unrecognized; } - public static async Task LaunchProtocolAsync(NotepadsOperationProtocol operation) + public static async Task LaunchProtocolAsync(NotepadsOperationProtocol operation, ValueSet message = null) { try { @@ -63,8 +60,35 @@ public static async Task LaunchProtocolAsync(NotepadsOperationProtocol ope } else if (operation == NotepadsOperationProtocol.OpenNewInstance) { - var uriToLaunch = $"notepads://{NewInstanceProtocolStr}"; - return await Windows.System.Launcher.LaunchUriAsync(new Uri(uriToLaunch.ToLower())); + var uri = new Uri($"notepads://{NewInstanceProtocolStr}".ToLower()); + var launcherOptions = new LauncherOptions() { TargetApplicationPackageFamilyName = Package.Current.Id.FamilyName }; + return await Launcher.LaunchUriAsync(uri, launcherOptions, message); + } + else + { + return false; + } + } + catch (Exception ex) + { + LoggingService.LogError($"[{nameof(NotepadsProtocolService)}] Failed to execute protocol: {operation}, Exception: {ex}"); + Analytics.TrackEvent("NotepadsProtocolService_FailedToExecuteProtocol", new Dictionary() + { + { "Protocol", operation.ToString() }, + { "Exception", ex.Message } + }); + return false; + } + } + + public static async Task LaunchProtocolAsync(NotepadsOperationProtocol operation, IStorageFile storageFile) + { + try + { + if (operation == NotepadsOperationProtocol.OpenNewInstance) + { + var launchOptions = new LauncherOptions() { TargetApplicationPackageFamilyName = Package.Current.Id.FamilyName }; + return await Launcher.LaunchFileAsync(storageFile, launchOptions); } else { diff --git a/src/Notepads/Views/MainPage/NotepadsMainPage.IO.cs b/src/Notepads/Views/MainPage/NotepadsMainPage.IO.cs index 81d0e8b2f..f9dd30fa2 100644 --- a/src/Notepads/Views/MainPage/NotepadsMainPage.IO.cs +++ b/src/Notepads/Views/MainPage/NotepadsMainPage.IO.cs @@ -12,6 +12,8 @@ using Notepads.Controls.TextEditor; using Notepads.Services; using Notepads.Utilities; + using Notepads.Models; + using Notepads.Core.SessionDataModels; using Microsoft.AppCenter.Analytics; public sealed partial class NotepadsMainPage diff --git a/src/Notepads/Views/MainPage/NotepadsMainPage.StatusBar.cs b/src/Notepads/Views/MainPage/NotepadsMainPage.StatusBar.cs index 0d3ae3371..d7e2eec2a 100644 --- a/src/Notepads/Views/MainPage/NotepadsMainPage.StatusBar.cs +++ b/src/Notepads/Views/MainPage/NotepadsMainPage.StatusBar.cs @@ -18,6 +18,7 @@ using Notepads.Extensions; using Notepads.Services; using Notepads.Utilities; + using Windows.Storage; public sealed partial class NotepadsMainPage { @@ -97,6 +98,7 @@ private void UpdatePathIndicator(ITextEditor textEditor) { if (StatusBar == null) return; PathIndicator.Text = textEditor.EditingFilePath ?? textEditor.FileNamePlaceholder; + PathIndicator.CanDrag = textEditor.EditingFilePath != null && textEditor.FileModificationState != FileModificationState.RenamedMovedOrDeleted; if (textEditor.FileModificationState == FileModificationState.Untouched) { @@ -265,6 +267,14 @@ private async void RenameFileAsync(object sender, RoutedEventArgs e) await RenameFileAsync(selectedEditor); } + private void PathIndicator_DragStarting(UIElement sender, DragStartingEventArgs args) + { + args.Data.Properties.FileTypes.Add(StandardDataFormats.StorageItems); + args.Data.Properties.Add(Notepads.Core.NotepadsCore.NotepadsShouldHandleFileDrop, false); + args.Data.SetStorageItems(new List() { _notepadsCore.GetSelectedTextEditor().EditingFile }, readOnly: false); + args.DragUI.SetContentFromDataPackage(); + } + private void FontZoomIndicatorFlyoutSelection_OnClick(object sender, RoutedEventArgs e) { if (!(sender is AppBarButton button)) return; diff --git a/src/Notepads/Views/MainPage/NotepadsMainPage.xaml b/src/Notepads/Views/MainPage/NotepadsMainPage.xaml index 4ea5550b2..33a57bd15 100644 --- a/src/Notepads/Views/MainPage/NotepadsMainPage.xaml +++ b/src/Notepads/Views/MainPage/NotepadsMainPage.xaml @@ -343,7 +343,9 @@ + CanDrag="True" + Tapped="StatusBarComponent_OnTapped" + DragStarting="PathIndicator_DragStarting"> diff --git a/src/Notepads/Views/MainPage/NotepadsMainPage.xaml.cs b/src/Notepads/Views/MainPage/NotepadsMainPage.xaml.cs index 7b02764de..f7322853b 100644 --- a/src/Notepads/Views/MainPage/NotepadsMainPage.xaml.cs +++ b/src/Notepads/Views/MainPage/NotepadsMainPage.xaml.cs @@ -27,14 +27,17 @@ using Windows.UI.Xaml.Navigation; using Microsoft.AppCenter.Analytics; using Windows.Graphics.Printing; + using Windows.Foundation.Collections; + using Notepads.Core.SessionDataModels; + using Newtonsoft.Json; public sealed partial class NotepadsMainPage : Page { private IReadOnlyList _appLaunchFiles; - private string _appLaunchCmdDir; private string _appLaunchCmdArgs; private Uri _appLaunchUri; + private ValueSet _appLaunchEditorData; private readonly ResourceLoader _resourceLoader = ResourceLoader.GetForCurrentView(); @@ -190,6 +193,7 @@ protected override void OnNavigatedTo(NavigationEventArgs e) break; case ProtocolActivatedEventArgs protocol: _appLaunchUri = protocol.Uri; + _appLaunchEditorData = protocol.Data; break; } } @@ -215,8 +219,16 @@ private async void Sets_Loaded(object sender, RoutedEventArgs e) if (_appLaunchFiles != null && _appLaunchFiles.Count > 0) { - loadedCount += await OpenFiles(_appLaunchFiles); - _appLaunchFiles = null; + if (string.IsNullOrEmpty(App.PassedEditorData)) + { + loadedCount += await OpenFiles(_appLaunchFiles); + _appLaunchFiles = null; + } + else + { + await OpenEditor(App.PassedEditorData, (StorageFile)_appLaunchFiles[0]); + loadedCount++; + } } else if (_appLaunchCmdDir != null) { @@ -231,9 +243,18 @@ private async void Sets_Loaded(object sender, RoutedEventArgs e) else if (_appLaunchUri != null) { var operation = NotepadsProtocolService.GetOperationProtocol(_appLaunchUri, out var context); - if (operation == NotepadsOperationProtocol.OpenNewInstance || operation == NotepadsOperationProtocol.Unrecognized) + if (operation == NotepadsOperationProtocol.OpenNewInstance) { - // Do nothing + try + { + await OpenEditor((string)_appLaunchEditorData["EditorData"]); + loadedCount++; + } + catch (Exception) + { + // Do nothing + } + _appLaunchEditorData = null; } _appLaunchUri = null; } @@ -317,6 +338,15 @@ private void CoreWindow_Activated(Windows.UI.Core.CoreWindow sender, Windows.UI. } } + private async Task OpenEditor(string textEditorDataStr, StorageFile file = null) + { + var textEditorData = JsonConvert.DeserializeObject(textEditorDataStr); + var textEditor = await SessionManager.RecoverTextEditorAsync(textEditorData, file); + NotepadsCore.OpenTextEditor(textEditor); + await FileSystemUtility.DeleteFile(textEditorData.LastSavedBackupFilePath); + await FileSystemUtility.DeleteFile(textEditorData.PendingBackupFilePath); + } + private void WindowVisibilityChangedEventHandler(System.Object sender, Windows.UI.Core.VisibilityChangedEventArgs e) { LoggingService.LogInfo($"[{nameof(NotepadsMainPage)}] Window Visibility Changed, Visible = {e.Visible}.", consoleOnly: true);