Skip to content

Commit

Permalink
Issue 324: Generate xml from schema
Browse files Browse the repository at this point in the history
Issue 385:: "XML Reload" removes loaded XSLT
Preserve the selection in the XML tree view across file reloads
  • Loading branch information
lovettchris committed Sep 20, 2024
1 parent 225eb8f commit b6000cd
Show file tree
Hide file tree
Showing 30 changed files with 2,169 additions and 202 deletions.
Binary file modified docs/assets/images/options.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions docs/help/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ color palettes. You can also customize the font used in the XML Notepad tree vie

### Editor
The editor to use if the XML file is invalid and cannot be opened by XML Notepad.
You can also disable the "prompt before reload" so that if your XML file is changed on disk, it
will automatically reload that file (unless you have pending unsaved edits).

### Formatting
You can also configure the formatting options used when you save an XML file, or turn off formatting
Expand Down
118 changes: 61 additions & 57 deletions src/Application/FormMain.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//#define WHIDBEY_MENUS

using Microsoft.Xml;
using Microsoft.XmlDiffPatch;
using Newtonsoft.Json;
using Sgml;
using System;
Expand All @@ -10,11 +9,7 @@
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
using SR = XmlNotepad.StringResources;
Expand Down Expand Up @@ -940,7 +935,35 @@ private void ClearStatus()
this.toolStripStatusLabel1.Text = "";
}

public virtual async System.Threading.Tasks.Task Open(string filename, bool recentFile = false)
public virtual async System.Threading.Tasks.Task Reload(string filename)
{
// save current selection position
XmlTreeNode selection = (XmlTreeNode)this.xmlTreeView1.SelectedNode;
XmlNamespaceManager nsmgr = null;
string xpath = null;
if (selection != null && selection.Node != null)
{
var xnode = selection.Node;
nsmgr = XmlHelpers.GetNamespaceScope(xnode);
xpath = XmlHelpers.GetXPathLocation(xnode, nsmgr);
}

this.Model.Clear(); // in case the updated file is invalid!
await this.Open(filename, false, true);

if (this._model.Document != null && !string.IsNullOrEmpty(xpath))
{
var matchingNode = this._model.Document.SelectSingleNode(xpath, nsmgr);
if (matchingNode != null)
{
var treeNode = this.xmlTreeView1.FindNode(matchingNode);
TreeView.EnsureVisible(treeNode);
this.xmlTreeView1.SelectedNode = treeNode;
}
}
}

public virtual async System.Threading.Tasks.Task Open(string filename, bool recentFile = false, bool reloading = false)
{
try
{
Expand All @@ -949,16 +972,16 @@ public virtual async System.Threading.Tasks.Task Open(string filename, bool rece
switch (entity.MimeType)
{
case "text/csv":
await ImportCsv(entity);
await ImportCsv(entity, reloading);
break;
case "application/json":
await ImportJson(entity);
await ImportJson(entity, reloading);
break;
case "text/html":
await ImportHtml(entity);
await ImportHtml(entity, reloading);
break;
default:
InternalOpen(entity);
InternalOpen(entity, reloading);
break;
}
}
Expand Down Expand Up @@ -999,7 +1022,7 @@ public virtual async System.Threading.Tasks.Task Open(string filename, bool rece
}
}

private async System.Threading.Tasks.Task ImportHtml(FileEntity entity)
private async System.Threading.Tasks.Task ImportHtml(FileEntity entity, bool reloading)
{
var html = await entity.ReadText();
DateTime start = DateTime.Now;
Expand All @@ -1010,11 +1033,11 @@ private async System.Threading.Tasks.Task ImportHtml(FileEntity entity)
reader.InputStream = new StringReader(html);
reader.WhitespaceHandling = WhitespaceHandling.Significant;
this._model.Load(reader, entity.Uri.OriginalString);
FinishLoad(entity, start);
FinishLoad(entity, start, reloading);
}
}

private async System.Threading.Tasks.Task ImportJson(FileEntity entity)
private async System.Threading.Tasks.Task ImportJson(FileEntity entity, bool reloading)
{
DateTime start = DateTime.Now;

Expand All @@ -1023,10 +1046,10 @@ private async System.Threading.Tasks.Task ImportJson(FileEntity entity)

this._model.Load(new XmlNodeReader(doc), entity.LocalPath);

FinishLoad(entity, start);
FinishLoad(entity, start, reloading);
}

private async System.Threading.Tasks.Task ImportCsv(FileEntity entity)
private async System.Threading.Tasks.Task ImportCsv(FileEntity entity, bool reloading)
{
var csvText = await entity.ReadText();

Expand All @@ -1047,14 +1070,14 @@ private async System.Threading.Tasks.Task ImportCsv(FileEntity entity)
DateTime start = DateTime.Now;
this._model.Load(csv, xmlFile);

FinishLoad(entity, start);
FinishLoad(entity, start, reloading);
}

this._analytics.RecordCsvImport();
}
}

private void FinishLoad(FileEntity entity, DateTime startLoadTime)
private void FinishLoad(FileEntity entity, DateTime startLoadTime, bool reloading)
{
DateTime finish = DateTime.Now;
TimeSpan diff = finish - startLoadTime;
Expand All @@ -1065,15 +1088,18 @@ private void FinishLoad(FileEntity entity, DateTime startLoadTime)
ShowStatus(string.Format(SR.LoadedTimeStatus, s));
EnableFileMenu();
this._recentFiles.AddRecentFile(entity.Uri);
SelectTreeView();
if (!reloading)
{
SelectTreeView();
}
}

private void InternalOpen(FileEntity entity)
private void InternalOpen(FileEntity entity, bool reloading)
{
entity.Close();
DateTime start = DateTime.Now;
this._model.Load(entity.Uri.OriginalString);
FinishLoad(entity, start);
FinishLoad(entity, start, reloading);
}

bool CheckXIncludes()
Expand Down Expand Up @@ -1267,7 +1293,7 @@ protected virtual async void OnFileChanged()
{
this.WindowState = FormWindowState.Normal;
}
SelectTreeView();
this.xmlTreeView1.Commit();
if (!string.IsNullOrEmpty(this._model.NewName))
{
if (MessageBox.Show(this, SR.FileRenamedDiskPrompt, SR.FileChagedOnDiskCaption, MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
Expand All @@ -1278,11 +1304,19 @@ protected virtual async void OnFileChanged()

}
}
else if (MessageBox.Show(this, SR.FileChangedOnDiskPrompt, SR.FileChagedOnDiskCaption, MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
else if (this._model.Dirty)
{
if (MessageBox.Show(this, SR.DirtyWhileFileChangedOnDiskPrompt, SR.FileChagedOnDiskCaption, MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
{
string location = this._model.Location.LocalPath;
await this.Reload(location);
}
}
else if (!this._settings.GetBoolean("PromptOnReload") ||
MessageBox.Show(this, SR.FileChangedOnDiskPrompt, SR.FileChagedOnDiskCaption, MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
{
string location = this._model.Location.LocalPath;
this._model.Clear();
await this.Open(location);
await this.Reload(location);
}
}
finally
Expand Down Expand Up @@ -1650,7 +1684,7 @@ private void DisplayHelp()
// display documentation
if (null == xmlTreeView1.SelectedNode)
{
this._dynamicHelpViewer.DisplayXsltResults(new XmlDocument(), null);
_ = this._dynamicHelpViewer.DisplayXsltResults(new XmlDocument(), null);
return;
}
XmlDocument xmlDoc = xmlTreeView1.SelectedNode.GetDocumentation();
Expand All @@ -1668,7 +1702,7 @@ private void DisplayHelp()
xmlDoc.AppendChild(xmlDoc.CreateElement("nothing"));
}
}
this._dynamicHelpViewer.DisplayXsltResults(xmlDoc, null);
_ = this._dynamicHelpViewer.DisplayXsltResults(xmlDoc, null);
}
else if (_helpAvailableHint && xmlDoc != null)
{
Expand All @@ -1684,7 +1718,6 @@ private void treeView1_NodeChanged(object sender, NodeChangeEventArgs e)

protected virtual void UpdateMenuState()
{

XmlTreeNode node = this.xmlTreeView1.SelectedNode as XmlTreeNode;
XmlNode xnode = (node != null) ? node.Node : null;
bool hasSelection = node != null;
Expand Down Expand Up @@ -2441,19 +2474,6 @@ private void PIChildToolStripMenuItem_Click(object sender, EventArgs e)
this.xmlTreeView1.InsertNode(InsertPosition.Child, XmlNodeType.ProcessingInstruction);
}

void Launch(string exeFileName, string args)
{
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = exeFileName;
info.Arguments = args;
Process p = new Process();
p.StartInfo = info;
if (!p.Start())
{
MessageBox.Show(this, string.Format(SR.ErrorCreatingProcessPrompt, exeFileName), SR.LaunchErrorPrompt, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}

private void newWindowToolStripMenuItem_Click(object sender, EventArgs e)
{
this.SaveIfDirty(true);
Expand Down Expand Up @@ -2522,22 +2542,6 @@ private void DoCompare(string otherXmlFile)
this._diffWrapper.DoCompare(this, this._model, otherXmlFile, options, omitIdentical);
}

string ApplicationPath
{
get
{
string path = Application.ExecutablePath;
if (path.EndsWith("vstesthost.exe", StringComparison.CurrentCultureIgnoreCase))
{
// must be running UnitTests
Uri baseUri = new Uri(this.GetType().Assembly.Location);
Uri resolved = new Uri(baseUri, @"..\..\..\Application\bin\debug\XmlNotepad.exe");
path = resolved.LocalPath;
}
return path;
}
}

public virtual void OpenNewWindow(string path)
{
if (!string.IsNullOrEmpty(path))
Expand Down Expand Up @@ -2572,7 +2576,7 @@ public virtual void OpenNewWindow(string path)
}
}
}
Launch(this.ApplicationPath, "\"" + path + "\"");
Program.Launch(path);
}

private void GotoDefinition()
Expand Down
20 changes: 20 additions & 0 deletions src/Application/FormOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ public class UserSettings
private string _textEditor;
private bool _schemaAwareText;
private string _schemaAwareNames;
private bool _promptOnReload;

public UserSettings(Settings s)
{
Expand Down Expand Up @@ -278,6 +279,7 @@ public UserSettings(Settings s)
this._xmlDiffIgnoreDtd = this._settings.GetBoolean("XmlDiffIgnoreDtd");
this._allowAnalytics = this._settings.GetBoolean("AllowAnalytics");
this._textEditor = this._settings.GetString("TextEditor");
this._promptOnReload = this._settings.GetBoolean("PromptOnReload");
}

private void LoadColors()
Expand Down Expand Up @@ -380,6 +382,7 @@ public void Apply()

this._settings["AllowAnalytics"] = this._allowAnalytics;
this._settings["TextEditor"] = this._textEditor;
this._settings["PromptOnReload"] = this._promptOnReload;

this._settings.OnChanged("Colors");

Expand Down Expand Up @@ -407,6 +410,7 @@ public void Reset()
this._maximumValueLength = short.MaxValue;
_ignoreDTD = false;
this._allowAnalytics = false;
this._promptOnReload = true;
}

[SRCategory("ThemeCategory")]
Expand Down Expand Up @@ -1039,6 +1043,22 @@ public string Editor
}


[SRCategory("EditingCategory")]
[LocDisplayName("PromptOnReload")]
[SRDescription("PromptOnReloadDescription")]
public bool PromptOnReload
{
get
{
return this._promptOnReload;
}
set
{
this._promptOnReload = value;
}
}


}

public sealed class MemberFilter : ICustomTypeDescriptor
Expand Down
11 changes: 10 additions & 1 deletion src/Application/FormSchemas.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit b6000cd

Please sign in to comment.