238 lines
6.9 KiB
C#
238 lines
6.9 KiB
C#
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Text.Json;
|
|
using System.Text.Json.Serialization;
|
|
using TaskbarLauncher.Models;
|
|
|
|
namespace TaskbarLauncher.Services;
|
|
|
|
public static class ConfigService
|
|
{
|
|
private static readonly JsonSerializerOptions JsonOptions = new()
|
|
{
|
|
WriteIndented = true,
|
|
PropertyNameCaseInsensitive = true
|
|
};
|
|
|
|
static ConfigService()
|
|
{
|
|
JsonOptions.Converters.Add(new JsonStringEnumConverter());
|
|
}
|
|
|
|
public static string AppFolder => AppContext.BaseDirectory;
|
|
|
|
public static string ConfigPath => Path.Combine(AppFolder, "config.json");
|
|
|
|
public static string BackupFolder => Path.Combine(AppFolder, "backups");
|
|
|
|
public static LauncherConfig Load()
|
|
{
|
|
if (!File.Exists(ConfigPath))
|
|
{
|
|
LauncherConfig defaults = CreateDefaultConfig();
|
|
Save(defaults);
|
|
return defaults;
|
|
}
|
|
|
|
string json = File.ReadAllText(ConfigPath);
|
|
LauncherConfig config = JsonSerializer.Deserialize<LauncherConfig>(json, JsonOptions) ?? CreateDefaultConfig();
|
|
NormalizeDisplayModes(config);
|
|
Save(config);
|
|
return config;
|
|
}
|
|
|
|
public static void Save(LauncherConfig config)
|
|
{
|
|
string json = JsonSerializer.Serialize(config, JsonOptions);
|
|
File.WriteAllText(ConfigPath, json);
|
|
}
|
|
|
|
public static string Backup()
|
|
{
|
|
Directory.CreateDirectory(BackupFolder);
|
|
if (!File.Exists(ConfigPath))
|
|
{
|
|
Save(CreateDefaultConfig());
|
|
}
|
|
|
|
string timestamp = DateTime.Now.ToString("yyyyMMdd-HHmmss");
|
|
string backupPath = Path.Combine(BackupFolder, $"config-{timestamp}.json");
|
|
File.Copy(ConfigPath, backupPath, overwrite: false);
|
|
return backupPath;
|
|
}
|
|
|
|
public static string ExportTo(string destinationPath, LauncherConfig config)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(destinationPath))
|
|
{
|
|
throw new ArgumentException("Choose a destination path for the exported config.", nameof(destinationPath));
|
|
}
|
|
|
|
string? destinationFolder = Path.GetDirectoryName(destinationPath);
|
|
if (!string.IsNullOrWhiteSpace(destinationFolder))
|
|
{
|
|
Directory.CreateDirectory(destinationFolder);
|
|
}
|
|
|
|
NormalizeDisplayModes(config);
|
|
string json = JsonSerializer.Serialize(config, JsonOptions);
|
|
File.WriteAllText(destinationPath, json);
|
|
return destinationPath;
|
|
}
|
|
|
|
public static LauncherConfig ImportFrom(string sourcePath)
|
|
{
|
|
LauncherConfig config = ReadConfigFile(sourcePath);
|
|
Save(config);
|
|
return config;
|
|
}
|
|
|
|
public static LauncherConfig ResetToDefaults()
|
|
{
|
|
LauncherConfig config = CreateDefaultConfig();
|
|
Save(config);
|
|
return config;
|
|
}
|
|
|
|
public static LauncherConfig Restore(string sourcePath)
|
|
{
|
|
LauncherConfig config = ReadConfigFile(sourcePath);
|
|
Save(config);
|
|
return config;
|
|
}
|
|
|
|
public static void OpenConfigFolder()
|
|
{
|
|
Directory.CreateDirectory(AppFolder);
|
|
Process.Start(new ProcessStartInfo
|
|
{
|
|
FileName = AppFolder,
|
|
UseShellExecute = true
|
|
});
|
|
}
|
|
|
|
private static LauncherConfig CreateDefaultConfig()
|
|
{
|
|
LauncherConfig config = new()
|
|
{
|
|
Items =
|
|
[
|
|
new LauncherItem
|
|
{
|
|
Title = "Folders",
|
|
Type = LauncherItemType.Menu,
|
|
Children =
|
|
[
|
|
new LauncherItem
|
|
{
|
|
Title = "Documents",
|
|
Type = LauncherItemType.Folder,
|
|
Target = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
|
|
},
|
|
new LauncherItem
|
|
{
|
|
Title = "Downloads",
|
|
Type = LauncherItemType.Folder,
|
|
Target = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Downloads")
|
|
}
|
|
]
|
|
},
|
|
new LauncherItem
|
|
{
|
|
Title = "Apps",
|
|
Type = LauncherItemType.Menu,
|
|
Children =
|
|
[
|
|
new LauncherItem
|
|
{
|
|
Title = "Notepad",
|
|
Type = LauncherItemType.App,
|
|
Target = "notepad.exe",
|
|
IconPath = "notepad.exe"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
};
|
|
|
|
NormalizeDisplayModes(config);
|
|
return config;
|
|
}
|
|
|
|
private static LauncherConfig ReadConfigFile(string sourcePath)
|
|
{
|
|
if (!File.Exists(sourcePath))
|
|
{
|
|
throw new FileNotFoundException("The selected config file was not found.", sourcePath);
|
|
}
|
|
|
|
string json = File.ReadAllText(sourcePath);
|
|
LauncherConfig config;
|
|
try
|
|
{
|
|
config = JsonSerializer.Deserialize<LauncherConfig>(json, JsonOptions)
|
|
?? throw new InvalidDataException("The selected config file could not be read.");
|
|
}
|
|
catch (JsonException ex)
|
|
{
|
|
throw new InvalidDataException("The selected file is not a valid Taskbar Launcher config.", ex);
|
|
}
|
|
|
|
ValidateConfig(config);
|
|
NormalizeDisplayModes(config);
|
|
return config;
|
|
}
|
|
|
|
private static void ValidateConfig(LauncherConfig config)
|
|
{
|
|
if (config.Items is null)
|
|
{
|
|
throw new InvalidDataException("The selected config is missing launcher items.");
|
|
}
|
|
|
|
foreach (LauncherItem item in config.Items)
|
|
{
|
|
ValidateItem(item);
|
|
}
|
|
}
|
|
|
|
private static void ValidateItem(LauncherItem item)
|
|
{
|
|
if (item.Children is null)
|
|
{
|
|
throw new InvalidDataException($"The item '{item.Title}' has an invalid children list.");
|
|
}
|
|
|
|
if (!Enum.IsDefined(item.Type))
|
|
{
|
|
throw new InvalidDataException($"The item '{item.Title}' has an invalid type.");
|
|
}
|
|
|
|
foreach (LauncherItem child in item.Children)
|
|
{
|
|
ValidateItem(child);
|
|
}
|
|
}
|
|
|
|
private static void NormalizeDisplayModes(LauncherConfig config)
|
|
{
|
|
foreach (LauncherItem item in config.Items)
|
|
{
|
|
NormalizeDisplayModes(item);
|
|
}
|
|
}
|
|
|
|
private static void NormalizeDisplayModes(LauncherItem item)
|
|
{
|
|
if (!Enum.IsDefined(item.DisplayMode))
|
|
{
|
|
item.DisplayMode = LauncherDisplayMode.CompactList;
|
|
}
|
|
|
|
foreach (LauncherItem child in item.Children)
|
|
{
|
|
NormalizeDisplayModes(child);
|
|
}
|
|
}
|
|
}
|