154 lines
5.1 KiB
C#
154 lines
5.1 KiB
C#
using System.Text.Json;
|
|
using System.Text.Json.Serialization;
|
|
using FluidExplorer.Models;
|
|
|
|
namespace FluidExplorer.Services;
|
|
|
|
/// <summary>外观模式:默认跟随系统(深浅色自动切换)。</summary>
|
|
public enum AppThemeMode
|
|
{
|
|
System,
|
|
Light,
|
|
Dark
|
|
}
|
|
|
|
public enum SearchScope
|
|
{
|
|
/// <summary>全盘(走 NTFS 索引,Everything 式,毫秒级)。</summary>
|
|
Global,
|
|
/// <summary>仅当前文件夹及其子目录。</summary>
|
|
CurrentFolder
|
|
}
|
|
|
|
public sealed class FolderViewState
|
|
{
|
|
public ViewMode ViewMode { get; set; } = ViewMode.Details;
|
|
public SortColumn SortColumn { get; set; } = SortColumn.Name;
|
|
public SortDirection SortDirection { get; set; } = SortDirection.Ascending;
|
|
public GroupBy GroupBy { get; set; } = GroupBy.None;
|
|
}
|
|
|
|
/// <summary>用户设置(%LOCALAPPDATA%\FluidExplorer\settings.json),失败时退回程序目录。</summary>
|
|
public sealed class AppSettings
|
|
{
|
|
public AppThemeMode ThemeMode { get; set; } = AppThemeMode.System;
|
|
|
|
// 视图
|
|
public bool ShowHiddenFiles { get; set; }
|
|
public bool ShowSystemFiles { get; set; }
|
|
public bool ShowFileExtensions { get; set; } = true;
|
|
public bool AlwaysShowCheckBoxes { get; set; }
|
|
public bool ShowStatusBar { get; set; } = true;
|
|
|
|
// 浏览
|
|
public bool OpenFoldersInNewTab { get; set; }
|
|
public bool DoubleClickToOpen { get; set; } = true;
|
|
public bool RestoreTabsOnStartup { get; set; } = true;
|
|
public string DefaultStartPath { get; set; } = "";
|
|
public List<string> PinnedFolders { get; set; } = [];
|
|
public List<string> RecentFolders { get; set; } = [];
|
|
public List<string> OpenTabs { get; set; } = [];
|
|
public bool DualPane { get; set; }
|
|
|
|
// 搜索
|
|
public SearchScope SearchScope { get; set; } = SearchScope.Global;
|
|
public List<string> IndexedVolumes { get; set; } = [];
|
|
public bool IndexOnStartup { get; set; } = true;
|
|
public bool SearchAsYouType { get; set; } = true;
|
|
|
|
// 文件操作
|
|
public bool DeleteToRecycleBin { get; set; } = true;
|
|
public ConflictPolicySetting DefaultConflictPolicy { get; set; } = ConflictPolicySetting.Ask;
|
|
public bool ConfirmPermanentDelete { get; set; } = true;
|
|
public bool KeepWindowOpenDuringOperations { get; set; } = true;
|
|
|
|
// 动效(克制:只保留系统原生的必要动画)
|
|
public bool AnimationsEnabled { get; set; } = true;
|
|
|
|
// 窗口
|
|
public double WindowLeft { get; set; } = double.NaN;
|
|
public double WindowTop { get; set; } = double.NaN;
|
|
public double WindowWidth { get; set; } = 1280;
|
|
public double WindowHeight { get; set; } = 800;
|
|
public bool WindowMaximized { get; set; }
|
|
|
|
/// <summary>按文件夹记住视图方式(对齐资源管理器的"按文件夹记住视图设置")。</summary>
|
|
public Dictionary<string, FolderViewState> FolderViews { get; set; } = new(StringComparer.OrdinalIgnoreCase);
|
|
|
|
[JsonIgnore]
|
|
public string SettingsFilePath { get; private set; } = string.Empty;
|
|
|
|
private static readonly JsonSerializerOptions JsonOptions = new()
|
|
{
|
|
WriteIndented = true,
|
|
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
|
|
};
|
|
|
|
public static AppSettings Load()
|
|
{
|
|
foreach (var candidate in CandidatePaths())
|
|
{
|
|
try
|
|
{
|
|
if (!File.Exists(candidate)) continue;
|
|
var json = File.ReadAllText(candidate);
|
|
var loaded = JsonSerializer.Deserialize<AppSettings>(json, JsonOptions);
|
|
if (loaded is null) continue;
|
|
loaded.SettingsFilePath = candidate;
|
|
return loaded;
|
|
}
|
|
catch
|
|
{
|
|
// 设置文件损坏时忽略,使用默认值
|
|
}
|
|
}
|
|
|
|
var settings = new AppSettings();
|
|
settings.SettingsFilePath = CandidatePaths().First();
|
|
return settings;
|
|
}
|
|
|
|
public void Save()
|
|
{
|
|
foreach (var target in CandidatePaths())
|
|
{
|
|
try
|
|
{
|
|
var dir = Path.GetDirectoryName(target);
|
|
if (!string.IsNullOrEmpty(dir)) Directory.CreateDirectory(dir);
|
|
SettingsFilePath = target;
|
|
File.WriteAllText(target, JsonSerializer.Serialize(this, JsonOptions));
|
|
return;
|
|
}
|
|
catch
|
|
{
|
|
// 换下一个候选位置(例如沙箱/只读环境)
|
|
}
|
|
}
|
|
}
|
|
|
|
public FolderViewState GetFolderView(string path)
|
|
{
|
|
if (FolderViews.TryGetValue(path, out var state)) return state;
|
|
state = new FolderViewState();
|
|
FolderViews[path] = state;
|
|
return state;
|
|
}
|
|
|
|
private static IEnumerable<string> CandidatePaths()
|
|
{
|
|
var localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
|
if (!string.IsNullOrEmpty(localAppData))
|
|
yield return Path.Combine(localAppData, "FluidExplorer", "settings.json");
|
|
yield return Path.Combine(AppContext.BaseDirectory, "settings.json");
|
|
}
|
|
}
|
|
|
|
public enum ConflictPolicySetting
|
|
{
|
|
Ask,
|
|
Replace,
|
|
Skip,
|
|
KeepBoth
|
|
}
|