From d99eec0d4f9fc97a8f82b70185608cc3990bcf2b Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Sat, 26 Oct 2019 13:07:31 -0700 Subject: [PATCH] Open damaged projects in read-only mode If we detect a problem that requires intervention during loading, e.g. we find unknown elements because we're loading a file created by a newer version, default to read-only mode. Read only mode (1) refuses to apply changes, (2) refuses to add changes to the undo/redo list, and (3) disables Save/SaveAs. The mode is indicated in the title bar. Also, flipped the order of items in the title bar so that "6502bench SourceGen" comes last. This allows you to read the project name in short window title snippets. (Visual Studio, Notepad, and others do it this way as well.) --- SourceGen/DisasmProject.cs | 11 +++++++ SourceGen/MainController.cs | 20 +++++++++--- SourceGen/Res/Strings.xaml | 3 +- SourceGen/Res/Strings.xaml.cs | 2 ++ SourceGen/RuntimeData/Help/mainwin.html | 5 +-- SourceGen/WpfGui/MainWindow.xaml | 4 +-- SourceGen/WpfGui/MainWindow.xaml.cs | 7 +++- SourceGen/WpfGui/ProjectLoadIssues.xaml | 11 ++++++- SourceGen/WpfGui/ProjectLoadIssues.xaml.cs | 38 ++++++++++++++++++---- 9 files changed, 84 insertions(+), 17 deletions(-) diff --git a/SourceGen/DisasmProject.cs b/SourceGen/DisasmProject.cs index d2ddcba..7943c08 100644 --- a/SourceGen/DisasmProject.cs +++ b/SourceGen/DisasmProject.cs @@ -120,6 +120,11 @@ namespace SourceGen { /// public CpuDef CpuDef { get; private set; } + /// + /// If set, changes are ignored. + /// + public bool IsReadOnly { get; set; } + /// /// If true, plugins will execute in the main application's AppDomain instead of /// the sandbox. Must be set before calling Initialize(). @@ -1785,6 +1790,9 @@ namespace SourceGen { /// /// Set to push. public void PushChangeSet(ChangeSet changeSet) { + if (IsReadOnly) { + return; + } Debug.WriteLine("PushChangeSet: adding " + changeSet); // Remove all of the "redo" entries from the current position to the end. @@ -1850,6 +1858,9 @@ namespace SourceGen { public UndoableChange.ReanalysisScope ApplyChanges(ChangeSet cs, bool backward, out RangeSet affectedOffsets) { affectedOffsets = new RangeSet(); + if (IsReadOnly) { + return UndoableChange.ReanalysisScope.None; + } UndoableChange.ReanalysisScope needReanalysis = UndoableChange.ReanalysisScope.None; diff --git a/SourceGen/MainController.cs b/SourceGen/MainController.cs index 55729c8..b81f4e5 100644 --- a/SourceGen/MainController.cs +++ b/SourceGen/MainController.cs @@ -626,9 +626,7 @@ namespace SourceGen { private void UpdateTitle() { // Update main window title. StringBuilder sb = new StringBuilder(); - sb.Append(Res.Strings.TITLE_BASE); if (mProject != null) { - sb.Append(" - "); if (string.IsNullOrEmpty(mProjectPathName)) { sb.Append(Res.Strings.TITLE_NEW_PROJECT); } else { @@ -639,7 +637,14 @@ namespace SourceGen { sb.Append(" "); sb.Append(Res.Strings.TITLE_MODIFIED); } + + if (mProject.IsReadOnly) { + sb.Append(" "); + sb.Append(Res.Strings.TITLE_READ_ONLY); + } + sb.Append(" - "); } + sb.Append(Res.Strings.TITLE_BASE); mMainWin.Title = sb.ToString(); } @@ -1082,6 +1087,8 @@ namespace SourceGen { if (ok != true) { return; } + + newProject.IsReadOnly = dlg.WantReadOnly; } mProject = newProject; @@ -1175,6 +1182,7 @@ namespace SourceGen { /// /// True on success, false if the save attempt failed or was canceled. public bool SaveProjectAs() { + Debug.Assert(!mProject.IsReadOnly); SaveFileDialog fileDlg = new SaveFileDialog() { Filter = ProjectFile.FILENAME_FILTER + "|" + Res.Strings.FILE_FILTER_ALL, FilterIndex = 1, @@ -1205,6 +1213,7 @@ namespace SourceGen { /// /// True on success, false if the save attempt failed. public bool SaveProject() { + Debug.Assert(!mProject.IsReadOnly); if (string.IsNullOrEmpty(mProjectPathName)) { return SaveProjectAs(); } @@ -1317,8 +1326,11 @@ namespace SourceGen { return true; } - public bool IsProjectOpen() { - return mProject != null; + public bool IsProjectOpen { + get { return mProject != null; } + } + public bool IsProjectReadOnly { + get { return mProject != null && mProject.IsReadOnly; } } public void AssembleProject() { diff --git a/SourceGen/Res/Strings.xaml b/SourceGen/Res/Strings.xaml index e405957..759a5b3 100644 --- a/SourceGen/Res/Strings.xaml +++ b/SourceGen/Res/Strings.xaml @@ -53,7 +53,7 @@ limitations under the License. Unknown Source or Type in symbol Bad symbol reference part Type hint not recognized - Removing duplicate label '{0}' (offset +{1:x6}) + Removed duplicate label '{0}' (offset +{1:x6}) Failed copying {0} to {1}: {2}. The file {0} exists, but is not a directory. File Error @@ -164,5 +164,6 @@ limitations under the License. 6502bench SourceGen (save needed) [new project] + *READ-ONLY* [unset] \ No newline at end of file diff --git a/SourceGen/Res/Strings.xaml.cs b/SourceGen/Res/Strings.xaml.cs index b23891b..168173a 100644 --- a/SourceGen/Res/Strings.xaml.cs +++ b/SourceGen/Res/Strings.xaml.cs @@ -309,6 +309,8 @@ namespace SourceGen.Res { (string)Application.Current.FindResource("str_TitleModified"); public static string TITLE_NEW_PROJECT = (string)Application.Current.FindResource("str_TitleNewProject"); + public static string TITLE_READ_ONLY = + (string)Application.Current.FindResource("str_TitleReadOnly"); public static string UNSET = (string)Application.Current.FindResource("str_Unset"); } diff --git a/SourceGen/RuntimeData/Help/mainwin.html b/SourceGen/RuntimeData/Help/mainwin.html index adb8276..07c4a57 100644 --- a/SourceGen/RuntimeData/Help/mainwin.html +++ b/SourceGen/RuntimeData/Help/mainwin.html @@ -54,8 +54,9 @@ shown. If it's something simple, like a missing .sym65 or extension script file, you'll be notified. If it's something more complicated, e.g. the project has a comment on an offset that doesn't exist, you will be warned that the problematic data has been deleted, and will be -lost if the project is saved. You will also be given the opportunity -to cancel the loading of the project.

+lost if the project is saved. By default, such a project will be opened +in read-only mode, though you can override this in the dialog. You will +also be given the opportunity to simply cancel loading the project.

The locations of the last few projects you've worked with are saved in the application settings. You can access them from diff --git a/SourceGen/WpfGui/MainWindow.xaml b/SourceGen/WpfGui/MainWindow.xaml index 66ef0f3..9fdc345 100644 --- a/SourceGen/WpfGui/MainWindow.xaml +++ b/SourceGen/WpfGui/MainWindow.xaml @@ -264,9 +264,9 @@ limitations under the License. + CanExecute="CanSaveProject" Executed="SaveCmd_Executed"/> + CanExecute="CanSaveProject" Executed="SaveAsCmd_Executed"/> diff --git a/SourceGen/WpfGui/MainWindow.xaml.cs b/SourceGen/WpfGui/MainWindow.xaml.cs index 100d3c9..801ef36 100644 --- a/SourceGen/WpfGui/MainWindow.xaml.cs +++ b/SourceGen/WpfGui/MainWindow.xaml.cs @@ -934,7 +934,7 @@ namespace SourceGen.WpfGui { /// /// private bool IsProjectOpen() { - return mMainCtrl != null && mMainCtrl.IsProjectOpen(); + return mMainCtrl != null && mMainCtrl.IsProjectOpen; } ///

@@ -1033,6 +1033,11 @@ namespace SourceGen.WpfGui { (counts.mCodeHints != 0 || counts.mDataHints != 0 || counts.mInlineDataHints != 0); } + private void CanSaveProject(object sender, CanExecuteRoutedEventArgs e) { + e.CanExecute = mMainCtrl != null && mMainCtrl.IsProjectOpen && + !mMainCtrl.IsProjectReadOnly; + } + private void CanToggleSingleByteFormat(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = IsProjectOpen() && mMainCtrl.CanToggleSingleByteFormat(); } diff --git a/SourceGen/WpfGui/ProjectLoadIssues.xaml b/SourceGen/WpfGui/ProjectLoadIssues.xaml index c9299b4..27b8664 100644 --- a/SourceGen/WpfGui/ProjectLoadIssues.xaml +++ b/SourceGen/WpfGui/ProjectLoadIssues.xaml @@ -25,14 +25,23 @@ limitations under the License. SizeToContent="WidthAndHeight" ResizeMode="NoResize" ShowInTaskbar="False" WindowStartupLocation="CenterOwner" Loaded="ProjectLoadIssues_Loaded"> + + + + + Problems were detected while loading the project file: - + Invalid data items will be discarded when you save the project. +