From 70f7c2eec91111cabf3ce1f22d0ff55bc129dc14 Mon Sep 17 00:00:00 2001
From: htcfreek <61519853+htcfreek@users.noreply.github.com>
Date: Tue, 25 Feb 2025 16:32:32 +0100
Subject: [PATCH 01/13] unsaved indicator
---
.../RegistryPreviewMainPage.Events.cs | 4 +++
.../RegistryPreviewMainPage.Utilities.cs | 25 +++++++++++++++++++
2 files changed, 29 insertions(+)
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
index 0df3a5c0f5ed..8d840ea08524 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
+++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
@@ -112,6 +112,7 @@ private async void OpenButton_Click(object sender, RoutedEventArgs e)
case ContentDialogResult.Secondary:
// Don't save and continue the file open!
saveButton.IsEnabled = false;
+ UpdateUnsavedFileIndicator(false);
break;
default:
// Don't open the new file!
@@ -143,6 +144,7 @@ private async void OpenButton_Click(object sender, RoutedEventArgs e)
// disable the Save button as it's a new file
saveButton.IsEnabled = false;
+ UpdateUnsavedFileIndicator(false);
// Restore the event handler as we're loaded
MonacoEditor.TextChanged += MonacoEditor_TextChanged;
@@ -193,6 +195,7 @@ private async void RefreshButton_Click(object sender, RoutedEventArgs e)
UpdateToolBarAndUI(await OpenRegistryFile(_appFileName), true, true);
saveButton.IsEnabled = false;
+ UpdateUnsavedFileIndicator(false);
// restore the TextChanged handler
MonacoEditor.TextChanged += MonacoEditor_TextChanged;
@@ -355,6 +358,7 @@ private void MonacoEditor_TextChanged(object sender, EventArgs e)
{
RefreshRegistryFile();
saveButton.IsEnabled = true;
+ UpdateUnsavedFileIndicator(true);
});
}
}
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
index b8fc6e4e1d9a..6f0e59fff435 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
+++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
@@ -11,6 +11,7 @@
using System.Linq;
using System.Reflection;
using System.Text;
+using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.UI.Input;
@@ -22,6 +23,9 @@ namespace RegistryPreviewUILib
{
public sealed partial class RegistryPreviewMainPage : Page
{
+ private static readonly string _usavedFileIndicator = "* ";
+ private static readonly char[] _usavedFileIndicatorChars = [' ', '*'];
+
private static SemaphoreSlim _dialogSemaphore = new(1);
private string lastKeyPath;
@@ -834,6 +838,7 @@ private async void HandleDirtyClosing(string title, string content, string prima
break;
case ContentDialogResult.Secondary:
// Don't save, and then close!
+ UpdateUnsavedFileIndicator(false);
saveButton.IsEnabled = false;
break;
default:
@@ -902,6 +907,25 @@ public void ChangeCursor(UIElement uiElement, bool wait)
type.InvokeMember("ProtectedCursor", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.SetProperty | BindingFlags.Instance, null, uiElement, new object[] { cursor }, CultureInfo.InvariantCulture);
}
+ public void UpdateUnsavedFileIndicator(bool show)
+ {
+ // get and cut current title
+ string currentTitel = Regex.Replace(_mainWindow.Title, APPNAME + @"$|\s-\s" + APPNAME + @"$", string.Empty);
+
+ // verify
+ bool titleContiansIndicator = currentTitel.StartsWith(_usavedFileIndicator, StringComparison.CurrentCultureIgnoreCase);
+
+ // update
+ if (!titleContiansIndicator && show)
+ {
+ _updateWindowTitleFunction(_usavedFileIndicator + currentTitel);
+ }
+ else if (titleContiansIndicator && !show)
+ {
+ _updateWindowTitleFunction(currentTitel.TrimStart(_usavedFileIndicatorChars));
+ }
+ }
+
///
/// Wrapper method that saves the current file in place, using the current text in editor.
///
@@ -930,6 +954,7 @@ private void SaveFile()
streamWriter.Close();
// only change when the save is successful
+ UpdateUnsavedFileIndicator(false);
saveButton.IsEnabled = false;
}
catch (UnauthorizedAccessException ex)
From 36629362e4064f578cf35b4bf5dd400cbe834093 Mon Sep 17 00:00:00 2001
From: htcfreek <61519853+htcfreek@users.noreply.github.com>
Date: Tue, 25 Feb 2025 16:43:15 +0100
Subject: [PATCH 02/13] save as behavior for svae button
---
.../RegistryPreviewMainPage.Events.cs | 21 ++++++++++++
.../RegistryPreviewMainPage.Utilities.cs | 32 ++++++++++++++++++-
2 files changed, 52 insertions(+), 1 deletion(-)
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
index 8d840ea08524..23f0f76fe84b 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
+++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
@@ -156,7 +156,28 @@ private async void OpenButton_Click(object sender, RoutedEventArgs e)
///
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
+ if (string.IsNullOrEmpty(_appFileName))
+ {
+ // Save out a new REG file and then open it - we have to use the direct Win32 method because FileOpenPicker crashes when it's
+ // called while running as admin
+ IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(_mainWindow);
+ string filename = SaveFilePicker.ShowDialog(
+ windowHandle,
+ resourceLoader.GetString("SuggestFileName"),
+ resourceLoader.GetString("FilterRegistryName") + '\0' + "*.reg" + '\0' + resourceLoader.GetString("FilterAllFiles") + '\0' + "*.*" + '\0' + '\0',
+ resourceLoader.GetString("SaveDialogTitle"));
+
+ if (filename == string.Empty)
+ {
+ return;
+ }
+
+ _appFileName = filename;
+ }
+
+ // save and update window title
SaveFile();
+ _updateWindowTitleFunction(_appFileName);
}
///
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
index 6f0e59fff435..00c786f1333d 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
+++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
@@ -834,7 +834,12 @@ private async void HandleDirtyClosing(string title, string content, string prima
{
case ContentDialogResult.Primary:
// Save, then close
- SaveFile();
+ if (!DirtyCloseSaveFile())
+ {
+ // save cancelled
+ return;
+ }
+
break;
case ContentDialogResult.Secondary:
// Don't save, and then close!
@@ -850,6 +855,31 @@ private async void HandleDirtyClosing(string title, string content, string prima
Application.Current.Exit();
}
+ private bool DirtyCloseSaveFile()
+ {
+ if (string.IsNullOrEmpty(_appFileName))
+ {
+ // Save out a new REG file and then open it - we have to use the direct Win32 method because FileOpenPicker crashes when it's
+ // called while running as admin
+ IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(_mainWindow);
+ string filename = SaveFilePicker.ShowDialog(
+ windowHandle,
+ resourceLoader.GetString("SuggestFileName"),
+ resourceLoader.GetString("FilterRegistryName") + '\0' + "*.reg" + '\0' + resourceLoader.GetString("FilterAllFiles") + '\0' + "*.*" + '\0' + '\0',
+ resourceLoader.GetString("SaveDialogTitle"));
+
+ if (filename == string.Empty)
+ {
+ return false;
+ }
+
+ _appFileName = filename;
+ }
+
+ SaveFile();
+ return true;
+ }
+
///
/// Method will open the Registry Editor or merge the current REG file into the Registry via the Editor
/// Process will prompt for elevation if it needs it.
From c2887531f1aa4ce18bcccc87fcc7e9a6c83644c2 Mon Sep 17 00:00:00 2001
From: htcfreek <61519853+htcfreek@users.noreply.github.com>
Date: Tue, 25 Feb 2025 17:03:07 +0100
Subject: [PATCH 03/13] correctly handle file save errors
---
.../RegistryPreviewMainPage.Events.cs | 18 ++++++++++++++----
.../RegistryPreviewMainPage.Utilities.cs | 14 +++++++++++---
2 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
index 23f0f76fe84b..d6f6c1092739 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
+++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
@@ -107,7 +107,12 @@ private async void OpenButton_Click(object sender, RoutedEventArgs e)
{
case ContentDialogResult.Primary:
// Save, then continue the file open
- SaveFile();
+ bool success = SaveFile();
+ if (!success)
+ {
+ return;
+ }
+
break;
case ContentDialogResult.Secondary:
// Don't save and continue the file open!
@@ -176,7 +181,7 @@ private void SaveButton_Click(object sender, RoutedEventArgs e)
}
// save and update window title
- SaveFile();
+ _ = SaveFile();
_updateWindowTitleFunction(_appFileName);
}
@@ -200,7 +205,7 @@ private async void SaveAsButton_Click(object sender, RoutedEventArgs e)
}
_appFileName = filename;
- SaveFile();
+ _ = SaveFile();
UpdateToolBarAndUI(await OpenRegistryFile(_appFileName));
}
@@ -281,7 +286,12 @@ private async void WriteButton_Click(object sender, RoutedEventArgs e)
{
case ContentDialogResult.Primary:
// Save, then continue the file open
- SaveFile();
+ bool success = SaveFile();
+ if (!success)
+ {
+ return;
+ }
+
break;
case ContentDialogResult.Secondary:
// Don't save and continue the file open!
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
index 00c786f1333d..412f75b97acb 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
+++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
@@ -876,8 +876,8 @@ private bool DirtyCloseSaveFile()
_appFileName = filename;
}
- SaveFile();
- return true;
+ bool r = SaveFile();
+ return r;
}
///
@@ -959,8 +959,10 @@ public void UpdateUnsavedFileIndicator(bool show)
///
/// Wrapper method that saves the current file in place, using the current text in editor.
///
- private void SaveFile()
+ private bool SaveFile()
{
+ bool saveSuccess = true;
+
ChangeCursor(gridPreview, true);
// set up the FileStream for all writing
@@ -989,6 +991,8 @@ private void SaveFile()
}
catch (UnauthorizedAccessException ex)
{
+ saveSuccess = false;
+
// this exception is thrown if the file is there but marked as read only
ShowMessageBox(
resourceLoader.GetString("ErrorDialogTitle"),
@@ -997,6 +1001,8 @@ private void SaveFile()
}
catch
{
+ saveSuccess = false;
+
// this catch handles all other exceptions thrown when trying to write the file out
ShowMessageBox(
resourceLoader.GetString("ErrorDialogTitle"),
@@ -1014,6 +1020,8 @@ private void SaveFile()
// restore the cursor
ChangeCursor(gridPreview, false);
+
+ return saveSuccess;
}
///
From 410c37fef3fb4a864851715fc9528380b2f8fb78 Mon Sep 17 00:00:00 2001
From: htcfreek <61519853+htcfreek@users.noreply.github.com>
Date: Tue, 25 Feb 2025 17:19:02 +0100
Subject: [PATCH 04/13] fix wrong unsaved state after opening file
---
.../RegistryPreviewMainPage.Events.cs | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
index d6f6c1092739..0770d0ee2c1c 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
+++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
@@ -23,6 +23,9 @@ public sealed partial class RegistryPreviewMainPage : Page
{
private readonly DispatcherQueue _dispatcherQueue = DispatcherQueue.GetForCurrentThread();
+ // Indicator if we loaded or reloaded a file
+ private static bool newFileLoaded;
+
///
/// Event that is will prevent the app from closing if the "save file" flag is active
///
@@ -144,6 +147,9 @@ private async void OpenButton_Click(object sender, RoutedEventArgs e)
{
// mute the TextChanged handler to make for clean UI
MonacoEditor.TextChanged -= MonacoEditor_TextChanged;
+ newFileLoaded = true;
+
+ // update file name
_appFileName = storageFile.Path;
UpdateToolBarAndUI(await OpenRegistryFile(_appFileName));
@@ -215,6 +221,7 @@ private async void SaveAsButton_Click(object sender, RoutedEventArgs e)
private async void RefreshButton_Click(object sender, RoutedEventArgs e)
{
// mute the TextChanged handler to make for clean UI
+ newFileLoaded = true;
MonacoEditor.TextChanged -= MonacoEditor_TextChanged;
// reload the current Registry file and update the toolbar accordingly.
@@ -388,8 +395,13 @@ private void MonacoEditor_TextChanged(object sender, EventArgs e)
_dispatcherQueue.TryEnqueue(() =>
{
RefreshRegistryFile();
- saveButton.IsEnabled = true;
- UpdateUnsavedFileIndicator(true);
+ if (!newFileLoaded)
+ {
+ saveButton.IsEnabled = true;
+ UpdateUnsavedFileIndicator(true);
+ }
+
+ newFileLoaded = false;
});
}
}
From 7dfadaf42283c8cb79e08cdd05a93fbe443cbe9c Mon Sep 17 00:00:00 2001
From: htcfreek <61519853+htcfreek@users.noreply.github.com>
Date: Tue, 25 Feb 2025 17:28:57 +0100
Subject: [PATCH 05/13] make spell check happy
---
.../RegistryPreviewMainPage.Utilities.cs | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
index 412f75b97acb..32d87503704c 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
+++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
@@ -23,8 +23,8 @@ namespace RegistryPreviewUILib
{
public sealed partial class RegistryPreviewMainPage : Page
{
- private static readonly string _usavedFileIndicator = "* ";
- private static readonly char[] _usavedFileIndicatorChars = [' ', '*'];
+ private static readonly string _unsavedFileIndicator = "* ";
+ private static readonly char[] _unsavedFileIndicatorChars = [' ', '*'];
private static SemaphoreSlim _dialogSemaphore = new(1);
private string lastKeyPath;
@@ -940,19 +940,19 @@ public void ChangeCursor(UIElement uiElement, bool wait)
public void UpdateUnsavedFileIndicator(bool show)
{
// get and cut current title
- string currentTitel = Regex.Replace(_mainWindow.Title, APPNAME + @"$|\s-\s" + APPNAME + @"$", string.Empty);
+ string currentTitle = Regex.Replace(_mainWindow.Title, APPNAME + @"$|\s-\s" + APPNAME + @"$", string.Empty);
// verify
- bool titleContiansIndicator = currentTitel.StartsWith(_usavedFileIndicator, StringComparison.CurrentCultureIgnoreCase);
+ bool titleContainsIndicator = currentTitle.StartsWith(_unsavedFileIndicator, StringComparison.CurrentCultureIgnoreCase);
// update
- if (!titleContiansIndicator && show)
+ if (!titleContainsIndicator && show)
{
- _updateWindowTitleFunction(_usavedFileIndicator + currentTitel);
+ _updateWindowTitleFunction(_unsavedFileIndicator + currentTitle);
}
- else if (titleContiansIndicator && !show)
+ else if (titleContainsIndicator && !show)
{
- _updateWindowTitleFunction(currentTitel.TrimStart(_usavedFileIndicatorChars));
+ _updateWindowTitleFunction(currentTitle.TrimStart(_unsavedFileIndicatorChars));
}
}
From 402064b1d3841434ea627cdc56939a23a288992f Mon Sep 17 00:00:00 2001
From: htcfreek <61519853+htcfreek@users.noreply.github.com>
Date: Tue, 25 Feb 2025 17:57:27 +0100
Subject: [PATCH 06/13] code cleanup
---
.../RegistryPreviewMainPage.Events.cs | 38 +++---------
.../RegistryPreviewMainPage.Utilities.cs | 58 ++++++++++---------
2 files changed, 38 insertions(+), 58 deletions(-)
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
index 0770d0ee2c1c..315424b82aff 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
+++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
@@ -110,8 +110,8 @@ private async void OpenButton_Click(object sender, RoutedEventArgs e)
{
case ContentDialogResult.Primary:
// Save, then continue the file open
- bool success = SaveFile();
- if (!success)
+ if (!AskFileName(false) ||
+ !SaveFile())
{
return;
}
@@ -167,23 +167,9 @@ private async void OpenButton_Click(object sender, RoutedEventArgs e)
///
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
- if (string.IsNullOrEmpty(_appFileName))
+ if (!AskFileName(false))
{
- // Save out a new REG file and then open it - we have to use the direct Win32 method because FileOpenPicker crashes when it's
- // called while running as admin
- IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(_mainWindow);
- string filename = SaveFilePicker.ShowDialog(
- windowHandle,
- resourceLoader.GetString("SuggestFileName"),
- resourceLoader.GetString("FilterRegistryName") + '\0' + "*.reg" + '\0' + resourceLoader.GetString("FilterAllFiles") + '\0' + "*.*" + '\0' + '\0',
- resourceLoader.GetString("SaveDialogTitle"));
-
- if (filename == string.Empty)
- {
- return;
- }
-
- _appFileName = filename;
+ return;
}
// save and update window title
@@ -196,21 +182,11 @@ private void SaveButton_Click(object sender, RoutedEventArgs e)
///
private async void SaveAsButton_Click(object sender, RoutedEventArgs e)
{
- // Save out a new REG file and then open it - we have to use the direct Win32 method because FileOpenPicker crashes when it's
- // called while running as admin
- IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(_mainWindow);
- string filename = SaveFilePicker.ShowDialog(
- windowHandle,
- resourceLoader.GetString("SuggestFileName"),
- resourceLoader.GetString("FilterRegistryName") + '\0' + "*.reg" + '\0' + resourceLoader.GetString("FilterAllFiles") + '\0' + "*.*" + '\0' + '\0',
- resourceLoader.GetString("SaveDialogTitle"));
-
- if (filename == string.Empty)
+ if (!AskFileName(true))
{
return;
}
- _appFileName = filename;
_ = SaveFile();
UpdateToolBarAndUI(await OpenRegistryFile(_appFileName));
}
@@ -293,8 +269,8 @@ private async void WriteButton_Click(object sender, RoutedEventArgs e)
{
case ContentDialogResult.Primary:
// Save, then continue the file open
- bool success = SaveFile();
- if (!success)
+ if (!AskFileName(false) ||
+ !SaveFile())
{
return;
}
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
index 32d87503704c..704f3ffc0583 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
+++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
@@ -834,9 +834,9 @@ private async void HandleDirtyClosing(string title, string content, string prima
{
case ContentDialogResult.Primary:
// Save, then close
- if (!DirtyCloseSaveFile())
+ if (!AskFileName(false) ||
+ !SaveFile())
{
- // save cancelled
return;
}
@@ -855,31 +855,6 @@ private async void HandleDirtyClosing(string title, string content, string prima
Application.Current.Exit();
}
- private bool DirtyCloseSaveFile()
- {
- if (string.IsNullOrEmpty(_appFileName))
- {
- // Save out a new REG file and then open it - we have to use the direct Win32 method because FileOpenPicker crashes when it's
- // called while running as admin
- IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(_mainWindow);
- string filename = SaveFilePicker.ShowDialog(
- windowHandle,
- resourceLoader.GetString("SuggestFileName"),
- resourceLoader.GetString("FilterRegistryName") + '\0' + "*.reg" + '\0' + resourceLoader.GetString("FilterAllFiles") + '\0' + "*.*" + '\0' + '\0',
- resourceLoader.GetString("SaveDialogTitle"));
-
- if (filename == string.Empty)
- {
- return false;
- }
-
- _appFileName = filename;
- }
-
- bool r = SaveFile();
- return r;
- }
-
///
/// Method will open the Registry Editor or merge the current REG file into the Registry via the Editor
/// Process will prompt for elevation if it needs it.
@@ -956,6 +931,35 @@ public void UpdateUnsavedFileIndicator(bool show)
}
}
+ ///
+ /// Ask the user for the file path if it is unknown because of an unsaved file
+ ///
+ /// Ask regardless of the known file name in case of save as action.
+ /// Returns true if user selected a path, otherwise false
+ public bool AskFileName(bool askAlways)
+ {
+ if (string.IsNullOrEmpty(_appFileName) || askAlways )
+ {
+ // Save out a new REG file and then open it - we have to use the direct Win32 method because FileOpenPicker crashes when it's
+ // called while running as admin
+ IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(_mainWindow);
+ string filename = SaveFilePicker.ShowDialog(
+ windowHandle,
+ resourceLoader.GetString("SuggestFileName"),
+ resourceLoader.GetString("FilterRegistryName") + '\0' + "*.reg" + '\0' + resourceLoader.GetString("FilterAllFiles") + '\0' + "*.*" + '\0' + '\0',
+ resourceLoader.GetString("SaveDialogTitle"));
+
+ if (filename == string.Empty)
+ {
+ return false;
+ }
+
+ _appFileName = filename;
+ }
+
+ return true;
+ }
+
///
/// Wrapper method that saves the current file in place, using the current text in editor.
///
From 609faa7408a15c94deea87cf2fdd5287baa972b1 Mon Sep 17 00:00:00 2001
From: htcfreek <61519853+htcfreek@users.noreply.github.com>
Date: Tue, 25 Feb 2025 18:17:03 +0100
Subject: [PATCH 07/13] different code fixes
---
.../RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs | 6 ++----
.../RegistryPreviewMainPage.Utilities.cs | 2 ++
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
index 315424b82aff..a928cd23cc78 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
+++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
@@ -23,7 +23,7 @@ public sealed partial class RegistryPreviewMainPage : Page
{
private readonly DispatcherQueue _dispatcherQueue = DispatcherQueue.GetForCurrentThread();
- // Indicator if we loaded or reloaded a file
+ // Indicator if we loaded/reloaded/saved a file and need to skip TextChangedEevent one time.
private static bool newFileLoaded;
///
@@ -174,7 +174,6 @@ private void SaveButton_Click(object sender, RoutedEventArgs e)
// save and update window title
_ = SaveFile();
- _updateWindowTitleFunction(_appFileName);
}
///
@@ -182,12 +181,11 @@ private void SaveButton_Click(object sender, RoutedEventArgs e)
///
private async void SaveAsButton_Click(object sender, RoutedEventArgs e)
{
- if (!AskFileName(true))
+ if (!AskFileName(true) || !SaveFile())
{
return;
}
- _ = SaveFile();
UpdateToolBarAndUI(await OpenRegistryFile(_appFileName));
}
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
index 704f3ffc0583..73353c16c2f5 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
+++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
@@ -62,6 +62,7 @@ private async Task OpenRegistryFile(string filename)
// update the current window's title with the current filename
_updateWindowTitleFunction(filename);
+ UpdateUnsavedFileIndicator(false);
// Load in the whole file in one call and plop it all into editor
FileStream fileStream = null;
@@ -990,6 +991,7 @@ private bool SaveFile()
streamWriter.Close();
// only change when the save is successful
+ _updateWindowTitleFunction(_appFileName);
UpdateUnsavedFileIndicator(false);
saveButton.IsEnabled = false;
}
From f95bb4366275a1c4aae227ec9afb0eb38426ef08 Mon Sep 17 00:00:00 2001
From: htcfreek <61519853+htcfreek@users.noreply.github.com>
Date: Tue, 25 Feb 2025 18:20:04 +0100
Subject: [PATCH 08/13] code cleanup
---
.../RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
index 73353c16c2f5..032857a4e47f 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
+++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
@@ -62,7 +62,6 @@ private async Task OpenRegistryFile(string filename)
// update the current window's title with the current filename
_updateWindowTitleFunction(filename);
- UpdateUnsavedFileIndicator(false);
// Load in the whole file in one call and plop it all into editor
FileStream fileStream = null;
@@ -992,7 +991,6 @@ private bool SaveFile()
// only change when the save is successful
_updateWindowTitleFunction(_appFileName);
- UpdateUnsavedFileIndicator(false);
saveButton.IsEnabled = false;
}
catch (UnauthorizedAccessException ex)
From 7b22a197d2fa03134a46a796d5b87a159d39faa2 Mon Sep 17 00:00:00 2001
From: htcfreek <61519853+htcfreek@users.noreply.github.com>
Date: Tue, 25 Feb 2025 18:30:51 +0100
Subject: [PATCH 09/13] reuse file name
---
.../RegistryPreviewMainPage.Events.cs | 8 ++++----
.../RegistryPreviewMainPage.Utilities.cs | 12 +++++++-----
2 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
index a928cd23cc78..6b499853f2fd 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
+++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
@@ -110,7 +110,7 @@ private async void OpenButton_Click(object sender, RoutedEventArgs e)
{
case ContentDialogResult.Primary:
// Save, then continue the file open
- if (!AskFileName(false) ||
+ if (!AskFileName(_appFileName) ||
!SaveFile())
{
return;
@@ -167,7 +167,7 @@ private async void OpenButton_Click(object sender, RoutedEventArgs e)
///
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
- if (!AskFileName(false))
+ if (!AskFileName(_appFileName))
{
return;
}
@@ -181,7 +181,7 @@ private void SaveButton_Click(object sender, RoutedEventArgs e)
///
private async void SaveAsButton_Click(object sender, RoutedEventArgs e)
{
- if (!AskFileName(true) || !SaveFile())
+ if (!AskFileName(_appFileName) || !SaveFile())
{
return;
}
@@ -267,7 +267,7 @@ private async void WriteButton_Click(object sender, RoutedEventArgs e)
{
case ContentDialogResult.Primary:
// Save, then continue the file open
- if (!AskFileName(false) ||
+ if (!AskFileName(_appFileName) ||
!SaveFile())
{
return;
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
index 032857a4e47f..e9d078d1d4e5 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
+++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
@@ -834,7 +834,7 @@ private async void HandleDirtyClosing(string title, string content, string prima
{
case ContentDialogResult.Primary:
// Save, then close
- if (!AskFileName(false) ||
+ if (!AskFileName(_appFileName) ||
!SaveFile())
{
return;
@@ -934,18 +934,20 @@ public void UpdateUnsavedFileIndicator(bool show)
///
/// Ask the user for the file path if it is unknown because of an unsaved file
///
- /// Ask regardless of the known file name in case of save as action.
+ /// If not empty always aks for a file path and use the value as name.
/// Returns true if user selected a path, otherwise false
- public bool AskFileName(bool askAlways)
+ public bool AskFileName(string fileName)
{
- if (string.IsNullOrEmpty(_appFileName) || askAlways )
+ if (string.IsNullOrEmpty(_appFileName) || !string.IsNullOrEmpty(fileName) )
{
+ string fName = string.IsNullOrEmpty(fileName) ? resourceLoader.GetString("SuggestFileName") : fileName;
+
// Save out a new REG file and then open it - we have to use the direct Win32 method because FileOpenPicker crashes when it's
// called while running as admin
IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(_mainWindow);
string filename = SaveFilePicker.ShowDialog(
windowHandle,
- resourceLoader.GetString("SuggestFileName"),
+ fName,
resourceLoader.GetString("FilterRegistryName") + '\0' + "*.reg" + '\0' + resourceLoader.GetString("FilterAllFiles") + '\0' + "*.*" + '\0' + '\0',
resourceLoader.GetString("SaveDialogTitle"));
From 0128d5c9d5d6aa7434cc8b1755efd2b683b5bba5 Mon Sep 17 00:00:00 2001
From: htcfreek <61519853+htcfreek@users.noreply.github.com>
Date: Tue, 25 Feb 2025 18:36:14 +0100
Subject: [PATCH 10/13] make spell checker happy
---
.../RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
index 6b499853f2fd..b64c46d3e33b 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
+++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
@@ -23,7 +23,7 @@ public sealed partial class RegistryPreviewMainPage : Page
{
private readonly DispatcherQueue _dispatcherQueue = DispatcherQueue.GetForCurrentThread();
- // Indicator if we loaded/reloaded/saved a file and need to skip TextChangedEevent one time.
+ // Indicator if we loaded/reloaded/saved a file and need to skip TextChanged event one time.
private static bool newFileLoaded;
///
From 9a812c4feb40567eb9002c9042226bced5b24bb7 Mon Sep 17 00:00:00 2001
From: htcfreek <61519853+htcfreek@users.noreply.github.com>
Date: Tue, 25 Feb 2025 21:08:36 +0100
Subject: [PATCH 11/13] fix typo
---
.../RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
index e9d078d1d4e5..5edab65f9c75 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
+++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
@@ -934,7 +934,7 @@ public void UpdateUnsavedFileIndicator(bool show)
///
/// Ask the user for the file path if it is unknown because of an unsaved file
///
- /// If not empty always aks for a file path and use the value as name.
+ /// If not empty always ask for a file path and use the value as name.
/// Returns true if user selected a path, otherwise false
public bool AskFileName(string fileName)
{
From f91bf787242d833bea50a475934604a16dfb9fac Mon Sep 17 00:00:00 2001
From: htcfreek <61519853+htcfreek@users.noreply.github.com>
Date: Tue, 25 Feb 2025 21:23:16 +0100
Subject: [PATCH 12/13] fixes
---
.../RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs | 7 ++++---
.../RegistryPreviewMainPage.Utilities.cs | 2 +-
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
index b64c46d3e33b..5f490f205bb4 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
+++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
@@ -110,7 +110,7 @@ private async void OpenButton_Click(object sender, RoutedEventArgs e)
{
case ContentDialogResult.Primary:
// Save, then continue the file open
- if (!AskFileName(_appFileName) ||
+ if (!AskFileName(string.Empty) ||
!SaveFile())
{
return;
@@ -167,7 +167,7 @@ private async void OpenButton_Click(object sender, RoutedEventArgs e)
///
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
- if (!AskFileName(_appFileName))
+ if (!AskFileName(string.Empty))
{
return;
}
@@ -181,6 +181,7 @@ private void SaveButton_Click(object sender, RoutedEventArgs e)
///
private async void SaveAsButton_Click(object sender, RoutedEventArgs e)
{
+ newFileLoaded = true;
if (!AskFileName(_appFileName) || !SaveFile())
{
return;
@@ -267,7 +268,7 @@ private async void WriteButton_Click(object sender, RoutedEventArgs e)
{
case ContentDialogResult.Primary:
// Save, then continue the file open
- if (!AskFileName(_appFileName) ||
+ if (!AskFileName(string.Empty) ||
!SaveFile())
{
return;
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
index 5edab65f9c75..dfce7f88398c 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
+++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
@@ -834,7 +834,7 @@ private async void HandleDirtyClosing(string title, string content, string prima
{
case ContentDialogResult.Primary:
// Save, then close
- if (!AskFileName(_appFileName) ||
+ if (!AskFileName(string.Empty) ||
!SaveFile())
{
return;
From 067897d23032c28d7061f6622abe39343c25256c Mon Sep 17 00:00:00 2001
From: htcfreek <61519853+htcfreek@users.noreply.github.com>
Date: Tue, 25 Feb 2025 21:43:50 +0100
Subject: [PATCH 13/13] code improvement and fix save as button behavior
---
.../RegistryPreviewMainPage.Events.cs | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
index 5f490f205bb4..ab9fd900b21b 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
+++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs
@@ -24,7 +24,7 @@ public sealed partial class RegistryPreviewMainPage : Page
private readonly DispatcherQueue _dispatcherQueue = DispatcherQueue.GetForCurrentThread();
// Indicator if we loaded/reloaded/saved a file and need to skip TextChanged event one time.
- private static bool newFileLoaded;
+ private static bool editorContentChangedScripted;
///
/// Event that is will prevent the app from closing if the "save file" flag is active
@@ -147,7 +147,7 @@ private async void OpenButton_Click(object sender, RoutedEventArgs e)
{
// mute the TextChanged handler to make for clean UI
MonacoEditor.TextChanged -= MonacoEditor_TextChanged;
- newFileLoaded = true;
+ editorContentChangedScripted = true;
// update file name
_appFileName = storageFile.Path;
@@ -181,13 +181,19 @@ private void SaveButton_Click(object sender, RoutedEventArgs e)
///
private async void SaveAsButton_Click(object sender, RoutedEventArgs e)
{
- newFileLoaded = true;
+ // mute the TextChanged handler to make for clean UI
+ editorContentChangedScripted = true;
+ MonacoEditor.TextChanged -= MonacoEditor_TextChanged;
+
if (!AskFileName(_appFileName) || !SaveFile())
{
return;
}
UpdateToolBarAndUI(await OpenRegistryFile(_appFileName));
+
+ // restore the TextChanged handler
+ MonacoEditor.TextChanged += MonacoEditor_TextChanged;
}
///
@@ -196,7 +202,7 @@ private async void SaveAsButton_Click(object sender, RoutedEventArgs e)
private async void RefreshButton_Click(object sender, RoutedEventArgs e)
{
// mute the TextChanged handler to make for clean UI
- newFileLoaded = true;
+ editorContentChangedScripted = true;
MonacoEditor.TextChanged -= MonacoEditor_TextChanged;
// reload the current Registry file and update the toolbar accordingly.
@@ -370,13 +376,13 @@ private void MonacoEditor_TextChanged(object sender, EventArgs e)
_dispatcherQueue.TryEnqueue(() =>
{
RefreshRegistryFile();
- if (!newFileLoaded)
+ if (!editorContentChangedScripted)
{
saveButton.IsEnabled = true;
UpdateUnsavedFileIndicator(true);
}
- newFileLoaded = false;
+ editorContentChangedScripted = false;
});
}
}