using System.Text.Json; using System.Text.Json.Serialization; using FluidExplorer.Models; namespace FluidExplorer.Services; /// 外观模式:默认跟随系统(深浅色自动切换)。 public enum AppThemeMode { System, Light, Dark } public enum SearchScope { /// 全盘(走 NTFS 索引,Everything 式,毫秒级)。 Global, /// 仅当前文件夹及其子目录。 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; } /// 用户设置(%LOCALAPPDATA%\FluidExplorer\settings.json),失败时退回程序目录。 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 PinnedFolders { get; set; } = []; public List RecentFolders { get; set; } = []; public List OpenTabs { get; set; } = []; public bool DualPane { get; set; } // 搜索 public SearchScope SearchScope { get; set; } = SearchScope.Global; public List 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; } /// 按文件夹记住视图方式(对齐资源管理器的"按文件夹记住视图设置")。 public Dictionary 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(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 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 }