Files
Terminal.Gui/Examples/UICatalog/Scenarios/ConfigurationEditor.cs
Tig ff18ad4532 Fixes build warnings recently introduced (#4506)
* Fixed warnings I recently introduced.

Replaced nullable App references with null-forgiving operator (!) in MessageBox and dialog calls to suppress nullable warnings. Updated XML docs to use Dim.Fill() and clarified method references. Made Application.Popover registration null-safe. Fixed test output helper usage in ShadowTests. No functional changes.

* Fixes Release build warnings
2025-12-17 12:57:38 -07:00

277 lines
8.0 KiB
C#

#nullable enable
using System.Reflection;
namespace UICatalog.Scenarios;
[ScenarioMetadata ("Configuration Editor", "Edits of Terminal.Gui Config Files")]
[ScenarioCategory ("TabView")]
[ScenarioCategory ("Colors")]
[ScenarioCategory ("Files and IO")]
[ScenarioCategory ("TextView")]
[ScenarioCategory ("Configuration")]
public class ConfigurationEditor : Scenario
{
private TabView? _tabView;
private Shortcut? _lenShortcut;
public override void Main ()
{
Application.Init ();
Window? win = new ();
_lenShortcut = new ()
{
Title = "",
};
Shortcut quitShortcut = new ()
{
Key = Application.QuitKey,
Title = $"Quit",
Action = Quit
};
Shortcut reloadShortcut = new ()
{
Key = Key.F5.WithShift,
Title = "Reload",
};
reloadShortcut.Accepting += (s, e) =>
{
Reload ();
e.Handled = true;
};
Shortcut saveShortcut = new ()
{
Key = Key.F4,
Title = "Save",
Action = Save
};
StatusBar statusBar = new ([quitShortcut, reloadShortcut, saveShortcut, _lenShortcut]);
_tabView = new ()
{
Width = Dim.Fill (),
Height = Dim.Fill (Dim.Func (_ => statusBar.Frame.Height))
};
win.Add (_tabView, statusBar);
win.IsModalChanged += (s, a) =>
{
Open ();
};
ConfigurationManager.Applied += ConfigurationManagerOnApplied;
Application.Run (win);
win.Dispose ();
Application.Shutdown ();
return;
void ConfigurationManagerOnApplied (object? sender, ConfigurationManagerEventArgs e)
{
Application.TopRunnableView?.SetNeedsDraw ();
}
}
public void Save ()
{
if (Application.Navigation?.GetFocused () is ConfigTextView editor)
{
editor.Save ();
}
}
private void Open ()
{
foreach (KeyValuePair<ConfigLocations, string> config in ConfigurationManager.SourcesManager!.Sources)
{
var homeDir = $"{Environment.GetFolderPath (Environment.SpecialFolder.UserProfile)}";
var fileInfo = new FileInfo (config.Value.Replace ("~", homeDir));
var editor = new ConfigTextView
{
Title = config.Value.StartsWith ("resource://") ? fileInfo.Name : config.Value,
Width = Dim.Fill (),
Height = Dim.Fill (),
FileInfo = fileInfo,
};
if (config.Value == "HardCoded")
{
editor.Title = "HardCoded";
}
Tab tab = new ()
{
View = editor,
DisplayText = config.Key.ToString ()
};
_tabView!.AddTab (tab, false);
editor.Read ();
editor.ContentsChanged += (sender, args) =>
{
_lenShortcut!.Title = _lenShortcut!.Title.Replace ("*", "");
if (editor.IsDirty)
{
_lenShortcut!.Title += "*";
}
};
_lenShortcut!.Title = $"{editor.Title}";
}
_tabView!.SelectedTabChanged += (sender, args) =>
{
_lenShortcut!.Title = $"{args.NewTab.View!.Title}";
};
}
private void Quit ()
{
foreach (ConfigTextView editor in _tabView!.Tabs.Select (v =>
{
if (v.View is ConfigTextView ctv)
{
return ctv;
}
return null;
}).Cast<ConfigTextView> ())
{
if (!editor.IsDirty)
{
continue;
}
int? result = MessageBox.Query (editor?.App!,
"Save Changes",
$"Save changes to {editor?.FileInfo!.Name}",
"_Yes",
"_No",
"_Cancel"
);
switch (result)
{
case 0:
editor?.Save ();
break;
case 1:
// user decided not save changes
break;
case -1 or 2:
// user cancelled
return;
}
}
Application.RequestStop ();
}
private static void Reload ()
{
if (Application.Navigation?.GetFocused () is ConfigTextView editor)
{
editor.Read ();
}
}
private class ConfigTextView : TextView
{
internal ConfigTextView ()
{
TabStop = TabBehavior.TabGroup;
}
internal FileInfo? FileInfo { get; init; }
internal void Read ()
{
Assembly? assembly = null;
if (FileInfo!.FullName.Contains ("[Terminal.Gui]"))
{
// Library resources
assembly = typeof (ConfigurationManager).Assembly;
}
else if (FileInfo.FullName.Contains ("[UICatalog]"))
{
assembly = Assembly.GetEntryAssembly ();
}
if (assembly != null)
{
string? name = assembly
.GetManifestResourceNames ()
.FirstOrDefault (x => x.EndsWith ("config.json"));
if (string.IsNullOrEmpty (name))
{
return;
}
using Stream? stream = assembly.GetManifestResourceStream (name);
using var reader = new StreamReader (stream!);
Text = reader.ReadToEnd ();
ReadOnly = true;
Enabled = true;
return;
}
if (FileInfo!.FullName.Contains ("HardCoded"))
{
Text = ConfigurationManager.GetHardCodedConfig ()!;
ReadOnly = true;
Enabled = true;
}
else if (FileInfo!.FullName.Contains ("RuntimeConfig"))
{
Text = ConfigurationManager.RuntimeConfig!;
}
else if (!FileInfo.Exists)
{
// Create empty config file
Text = ConfigurationManager.GetEmptyConfig ();
}
else
{
Text = File.ReadAllText (FileInfo.FullName);
}
}
internal void Save ()
{
if (FileInfo!.FullName.Contains ("RuntimeConfig"))
{
ConfigurationManager.RuntimeConfig = Text;
IsDirty = false;
return;
}
if (!Directory.Exists (FileInfo.DirectoryName))
{
// Create dir
Directory.CreateDirectory (FileInfo.DirectoryName!);
}
using StreamWriter writer = File.CreateText (FileInfo.FullName);
writer.Write (Text);
writer.Close ();
IsDirty = false;
}
}
}