mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-04-30 14:34:09 +02:00
Unify configs (backups, behavior, error handling) & make future development easier
This commit is contained in:
parent
4aec2f3260
commit
52ef6cd95a
121
Configuration/ConfigManager.cs
Normal file
121
Configuration/ConfigManager.cs
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using TweetDuck.Configuration.Instance;
|
||||||
|
using TweetDuck.Core.Utils;
|
||||||
|
using TweetDuck.Data;
|
||||||
|
using TweetDuck.Data.Serialization;
|
||||||
|
|
||||||
|
namespace TweetDuck.Configuration{
|
||||||
|
sealed class ConfigManager{
|
||||||
|
public UserConfig User { get; }
|
||||||
|
public SystemConfig System { get; }
|
||||||
|
|
||||||
|
public event EventHandler ProgramRestartRequested;
|
||||||
|
|
||||||
|
private readonly FileConfigInstance<UserConfig> infoUser;
|
||||||
|
private readonly FileConfigInstance<SystemConfig> infoSystem;
|
||||||
|
|
||||||
|
private readonly IConfigInstance<BaseConfig>[] infoList;
|
||||||
|
|
||||||
|
public ConfigManager(){
|
||||||
|
User = new UserConfig(this);
|
||||||
|
System = new SystemConfig(this);
|
||||||
|
|
||||||
|
infoList = new IConfigInstance<BaseConfig>[]{
|
||||||
|
infoUser = new FileConfigInstance<UserConfig>(Program.UserConfigFilePath, User, "program options"),
|
||||||
|
infoSystem = new FileConfigInstance<SystemConfig>(Program.SystemConfigFilePath, System, "system options")
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO refactor further
|
||||||
|
|
||||||
|
infoUser.Serializer.RegisterTypeConverter(typeof(WindowState), WindowState.Converter);
|
||||||
|
|
||||||
|
infoUser.Serializer.RegisterTypeConverter(typeof(Point), new SingleTypeConverter<Point>{
|
||||||
|
ConvertToString = value => $"{value.X} {value.Y}",
|
||||||
|
ConvertToObject = value => {
|
||||||
|
int[] elements = StringUtils.ParseInts(value, ' ');
|
||||||
|
return new Point(elements[0], elements[1]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
infoUser.Serializer.RegisterTypeConverter(typeof(Size), new SingleTypeConverter<Size>{
|
||||||
|
ConvertToString = value => $"{value.Width} {value.Height}",
|
||||||
|
ConvertToObject = value => {
|
||||||
|
int[] elements = StringUtils.ParseInts(value, ' ');
|
||||||
|
return new Size(elements[0], elements[1]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LoadAll(){
|
||||||
|
infoUser.Load();
|
||||||
|
infoSystem.Load();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SaveAll(){
|
||||||
|
infoUser.Save();
|
||||||
|
infoSystem.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReloadAll(){
|
||||||
|
infoUser.Reload();
|
||||||
|
infoSystem.Reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TriggerProgramRestartRequested(){
|
||||||
|
ProgramRestartRequested?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IConfigInstance<BaseConfig> GetInstanceInfo(BaseConfig instance){
|
||||||
|
Type instanceType = instance.GetType();
|
||||||
|
return Array.Find(infoList, info => info.Instance.GetType() == instanceType); // TODO handle null
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class BaseConfig{
|
||||||
|
private readonly ConfigManager configManager;
|
||||||
|
|
||||||
|
protected BaseConfig(ConfigManager configManager){
|
||||||
|
this.configManager = configManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Management
|
||||||
|
|
||||||
|
public void Save(){
|
||||||
|
configManager.GetInstanceInfo(this).Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reload(){
|
||||||
|
configManager.GetInstanceInfo(this).Reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset(){
|
||||||
|
configManager.GetInstanceInfo(this).Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construction methods
|
||||||
|
|
||||||
|
public T ConstructWithDefaults<T>() where T : BaseConfig{
|
||||||
|
return ConstructWithDefaults(configManager) as T;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract BaseConfig ConstructWithDefaults(ConfigManager configManager);
|
||||||
|
|
||||||
|
// Utility methods
|
||||||
|
|
||||||
|
protected void UpdatePropertyWithEvent<T>(ref T field, T value, EventHandler eventHandler){
|
||||||
|
if (!EqualityComparer<T>.Default.Equals(field, value)){
|
||||||
|
field = value;
|
||||||
|
eventHandler?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void UpdatePropertyWithRestartRequest<T>(ref T field, T value){
|
||||||
|
if (!EqualityComparer<T>.Default.Equals(field, value)){
|
||||||
|
field = value;
|
||||||
|
configManager.TriggerProgramRestartRequested();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
104
Configuration/Instance/FileConfigInstance.cs
Normal file
104
Configuration/Instance/FileConfigInstance.cs
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using TweetDuck.Data.Serialization;
|
||||||
|
|
||||||
|
namespace TweetDuck.Configuration.Instance{
|
||||||
|
sealed class FileConfigInstance<T> : IConfigInstance<T> where T : ConfigManager.BaseConfig{
|
||||||
|
private const string ErrorTitle = "Configuration Error";
|
||||||
|
|
||||||
|
public T Instance { get; }
|
||||||
|
public FileSerializer<T> Serializer { get; }
|
||||||
|
|
||||||
|
private readonly string filenameMain;
|
||||||
|
private readonly string filenameBackup;
|
||||||
|
private readonly string errorIdentifier;
|
||||||
|
|
||||||
|
public FileConfigInstance(string filename, T instance, string errorIdentifier){
|
||||||
|
this.filenameMain = filename;
|
||||||
|
this.filenameBackup = filename+".bak";
|
||||||
|
this.errorIdentifier = errorIdentifier;
|
||||||
|
|
||||||
|
this.Instance = instance;
|
||||||
|
this.Serializer = new FileSerializer<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadInternal(bool backup){
|
||||||
|
Serializer.Read(backup ? filenameBackup : filenameMain, Instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Load(){
|
||||||
|
Exception firstException = null;
|
||||||
|
|
||||||
|
for(int attempt = 0; attempt < 2; attempt++){
|
||||||
|
try{
|
||||||
|
LoadInternal(attempt > 0);
|
||||||
|
|
||||||
|
if (firstException != null){ // silently log exception that caused a backup restore
|
||||||
|
Program.Reporter.Log(firstException.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}catch(FileNotFoundException){
|
||||||
|
}catch(DirectoryNotFoundException){
|
||||||
|
break;
|
||||||
|
}catch(Exception e){
|
||||||
|
if (firstException == null){
|
||||||
|
firstException = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstException is FormatException){
|
||||||
|
Program.Reporter.HandleException(ErrorTitle, "The configuration file for "+errorIdentifier+" is outdated or corrupted. If you continue, your "+errorIdentifier+" will be reset.", true, firstException);
|
||||||
|
}
|
||||||
|
else if (firstException is SerializationSoftException sse){
|
||||||
|
Program.Reporter.HandleException(ErrorTitle, $"{sse.Errors.Count} error{(sse.Errors.Count == 1 ? " was" : "s were")} encountered while loading the configuration file for "+errorIdentifier+". If you continue, some of your "+errorIdentifier+" will be reset.", true, firstException);
|
||||||
|
}
|
||||||
|
else if (firstException != null){
|
||||||
|
Program.Reporter.HandleException(ErrorTitle, "Could not open the configuration file for "+errorIdentifier+". If you continue, your "+errorIdentifier+" will be reset.", true, firstException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Save(){
|
||||||
|
try{
|
||||||
|
if (File.Exists(filenameMain)){
|
||||||
|
File.Delete(filenameBackup);
|
||||||
|
File.Move(filenameMain, filenameBackup);
|
||||||
|
}
|
||||||
|
|
||||||
|
Serializer.Write(filenameMain, Instance);
|
||||||
|
}catch(SerializationSoftException e){
|
||||||
|
Program.Reporter.HandleException(ErrorTitle, $"{e.Errors.Count} error{(e.Errors.Count == 1 ? " was" : "s were")} encountered while saving the configuration file for "+errorIdentifier+".", true, e);
|
||||||
|
}catch(Exception e){
|
||||||
|
Program.Reporter.HandleException(ErrorTitle, "Could not save the configuration file for "+errorIdentifier+".", true, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reload(){
|
||||||
|
try{
|
||||||
|
LoadInternal(false);
|
||||||
|
}catch(FileNotFoundException){
|
||||||
|
try{
|
||||||
|
Serializer.Write(filenameMain, Instance.ConstructWithDefaults<T>());
|
||||||
|
LoadInternal(false);
|
||||||
|
}catch(Exception e){
|
||||||
|
Program.Reporter.HandleException(ErrorTitle, "Could not regenerate the configuration file for "+errorIdentifier+".", true, e);
|
||||||
|
}
|
||||||
|
}catch(Exception e){
|
||||||
|
Program.Reporter.HandleException(ErrorTitle, "Could not reload the configuration file for "+errorIdentifier+".", true, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset(){
|
||||||
|
try{
|
||||||
|
File.Delete(filenameMain);
|
||||||
|
File.Delete(filenameBackup);
|
||||||
|
}catch(Exception e){
|
||||||
|
Program.Reporter.HandleException(ErrorTitle, "Could not delete configuration files to reset "+errorIdentifier+".", true, e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
9
Configuration/Instance/IConfigInstance.cs
Normal file
9
Configuration/Instance/IConfigInstance.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
namespace TweetDuck.Configuration.Instance{
|
||||||
|
interface IConfigInstance<out T>{
|
||||||
|
T Instance { get; }
|
||||||
|
|
||||||
|
void Save();
|
||||||
|
void Reload();
|
||||||
|
void Reset();
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,5 @@
|
|||||||
using System;
|
namespace TweetDuck.Configuration{
|
||||||
using System.Collections.Generic;
|
sealed class SystemConfig : ConfigManager.BaseConfig{
|
||||||
using TweetDuck.Data.Serialization;
|
|
||||||
|
|
||||||
namespace TweetDuck.Configuration{
|
|
||||||
sealed class SystemConfig{
|
|
||||||
private static readonly FileSerializer<SystemConfig> Serializer = new FileSerializer<SystemConfig>();
|
|
||||||
|
|
||||||
// CONFIGURATION DATA
|
// CONFIGURATION DATA
|
||||||
|
|
||||||
@ -17,46 +12,15 @@ sealed class SystemConfig{
|
|||||||
|
|
||||||
public bool HardwareAcceleration{
|
public bool HardwareAcceleration{
|
||||||
get => _hardwareAcceleration;
|
get => _hardwareAcceleration;
|
||||||
set => UpdatePropertyWithEvent(ref _hardwareAcceleration, value, ProgramRestartRequested);
|
set => UpdatePropertyWithRestartRequest(ref _hardwareAcceleration, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// EVENTS
|
|
||||||
|
|
||||||
public event EventHandler ProgramRestartRequested;
|
|
||||||
|
|
||||||
// END OF CONFIG
|
// END OF CONFIG
|
||||||
|
|
||||||
private readonly string file;
|
public SystemConfig(ConfigManager configManager) : base(configManager){}
|
||||||
|
|
||||||
private SystemConfig(string file){
|
|
||||||
this.file = file;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdatePropertyWithEvent<T>(ref T field, T value, EventHandler eventHandler){
|
protected override ConfigManager.BaseConfig ConstructWithDefaults(ConfigManager configManager){
|
||||||
if (!EqualityComparer<T>.Default.Equals(field, value)){
|
return new SystemConfig(configManager);
|
||||||
field = value;
|
|
||||||
eventHandler?.Invoke(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Save(){
|
|
||||||
try{
|
|
||||||
Serializer.Write(file, this);
|
|
||||||
}catch(Exception e){
|
|
||||||
Program.Reporter.HandleException("Configuration Error", "Could not save the system configuration file.", true, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SystemConfig Load(string file){
|
|
||||||
SystemConfig config = new SystemConfig(file);
|
|
||||||
|
|
||||||
try{
|
|
||||||
Serializer.ReadIfExists(file, config);
|
|
||||||
}catch(Exception e){
|
|
||||||
Program.Reporter.HandleException("Configuration Error", "Could not open the system configuration file. If you continue, you will lose system specific configuration such as Hardware Acceleration.", true, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return config;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,37 +1,13 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.IO;
|
|
||||||
using TweetDuck.Core.Controls;
|
using TweetDuck.Core.Controls;
|
||||||
using TweetDuck.Core.Notification;
|
using TweetDuck.Core.Notification;
|
||||||
using TweetDuck.Core.Other;
|
using TweetDuck.Core.Other;
|
||||||
using TweetDuck.Core.Utils;
|
using TweetDuck.Core.Utils;
|
||||||
using TweetDuck.Data;
|
using TweetDuck.Data;
|
||||||
using TweetDuck.Data.Serialization;
|
|
||||||
|
|
||||||
namespace TweetDuck.Configuration{
|
namespace TweetDuck.Configuration{
|
||||||
sealed class UserConfig{
|
sealed class UserConfig : ConfigManager.BaseConfig{
|
||||||
private static readonly FileSerializer<UserConfig> Serializer = new FileSerializer<UserConfig>();
|
|
||||||
|
|
||||||
static UserConfig(){
|
|
||||||
Serializer.RegisterTypeConverter(typeof(WindowState), WindowState.Converter);
|
|
||||||
|
|
||||||
Serializer.RegisterTypeConverter(typeof(Point), new SingleTypeConverter<Point>{
|
|
||||||
ConvertToString = value => $"{value.X} {value.Y}",
|
|
||||||
ConvertToObject = value => {
|
|
||||||
int[] elements = StringUtils.ParseInts(value, ' ');
|
|
||||||
return new Point(elements[0], elements[1]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Serializer.RegisterTypeConverter(typeof(Size), new SingleTypeConverter<Size>{
|
|
||||||
ConvertToString = value => $"{value.Width} {value.Height}",
|
|
||||||
ConvertToObject = value => {
|
|
||||||
int[] elements = StringUtils.ParseInts(value, ' ');
|
|
||||||
return new Size(elements[0], elements[1]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// CONFIGURATION DATA
|
// CONFIGURATION DATA
|
||||||
|
|
||||||
@ -58,10 +34,10 @@ static UserConfig(){
|
|||||||
|
|
||||||
public int VideoPlayerVolume { get; set; } = 50;
|
public int VideoPlayerVolume { get; set; } = 50;
|
||||||
|
|
||||||
public bool EnableSpellCheck { get; set; } = false;
|
public bool EnableSpellCheck { get; set; } = false;
|
||||||
private string _spellCheckLanguage = "en-US";
|
private string _spellCheckLanguage = "en-US";
|
||||||
|
|
||||||
public string TranslationTarget { get; set; } = "en";
|
public string TranslationTarget { get; set; } = "en";
|
||||||
|
|
||||||
private TrayIcon.Behavior _trayBehavior = TrayIcon.Behavior.Disabled;
|
private TrayIcon.Behavior _trayBehavior = TrayIcon.Behavior.Disabled;
|
||||||
public bool EnableTrayHighlight { get; set; } = true;
|
public bool EnableTrayHighlight { get; set; } = true;
|
||||||
@ -75,9 +51,9 @@ static UserConfig(){
|
|||||||
public bool NotificationNonIntrusiveMode { get; set; } = true;
|
public bool NotificationNonIntrusiveMode { get; set; } = true;
|
||||||
public int NotificationIdlePauseSeconds { get; set; } = 0;
|
public int NotificationIdlePauseSeconds { get; set; } = 0;
|
||||||
|
|
||||||
public bool DisplayNotificationTimer { get; set; } = true;
|
public bool DisplayNotificationTimer { get; set; } = true;
|
||||||
public bool NotificationTimerCountDown { get; set; } = false;
|
public bool NotificationTimerCountDown { get; set; } = false;
|
||||||
public int NotificationDurationValue { get; set; } = 25;
|
public int NotificationDurationValue { get; set; } = 25;
|
||||||
|
|
||||||
public TweetNotification.Position NotificationPosition { get; set; } = TweetNotification.Position.TopRight;
|
public TweetNotification.Position NotificationPosition { get; set; } = TweetNotification.Position.TopRight;
|
||||||
public Point CustomNotificationPosition { get; set; } = ControlExtensions.InvisibleLocation;
|
public Point CustomNotificationPosition { get; set; } = ControlExtensions.InvisibleLocation;
|
||||||
@ -131,22 +107,22 @@ public TrayIcon.Behavior TrayBehavior{
|
|||||||
|
|
||||||
public bool EnableSmoothScrolling{
|
public bool EnableSmoothScrolling{
|
||||||
get => _enableSmoothScrolling;
|
get => _enableSmoothScrolling;
|
||||||
set => UpdatePropertyWithEvent(ref _enableSmoothScrolling, value, ProgramRestartRequested);
|
set => UpdatePropertyWithRestartRequest(ref _enableSmoothScrolling, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool EnableTouchAdjustment{
|
public bool EnableTouchAdjustment{
|
||||||
get => _enableTouchAdjustment;
|
get => _enableTouchAdjustment;
|
||||||
set => UpdatePropertyWithEvent(ref _enableTouchAdjustment, value, ProgramRestartRequested);
|
set => UpdatePropertyWithRestartRequest(ref _enableTouchAdjustment, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string CustomCefArgs{
|
public string CustomCefArgs{
|
||||||
get => _customCefArgs;
|
get => _customCefArgs;
|
||||||
set => UpdatePropertyWithEvent(ref _customCefArgs, value, ProgramRestartRequested);
|
set => UpdatePropertyWithRestartRequest(ref _customCefArgs, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string SpellCheckLanguage{
|
public string SpellCheckLanguage{
|
||||||
get => _spellCheckLanguage;
|
get => _spellCheckLanguage;
|
||||||
set => UpdatePropertyWithEvent(ref _spellCheckLanguage, value, ProgramRestartRequested);
|
set => UpdatePropertyWithRestartRequest(ref _spellCheckLanguage, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// EVENTS
|
// EVENTS
|
||||||
@ -156,104 +132,12 @@ public string SpellCheckLanguage{
|
|||||||
public event EventHandler TrayBehaviorChanged;
|
public event EventHandler TrayBehaviorChanged;
|
||||||
public event EventHandler SoundNotificationChanged;
|
public event EventHandler SoundNotificationChanged;
|
||||||
|
|
||||||
public event EventHandler ProgramRestartRequested;
|
|
||||||
|
|
||||||
// END OF CONFIG
|
// END OF CONFIG
|
||||||
|
|
||||||
private readonly string file;
|
public UserConfig(ConfigManager configManager) : base(configManager){}
|
||||||
|
|
||||||
private UserConfig(string file){
|
protected override ConfigManager.BaseConfig ConstructWithDefaults(ConfigManager configManager){
|
||||||
this.file = file;
|
return new UserConfig(configManager);
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdatePropertyWithEvent<T>(ref T field, T value, EventHandler eventHandler){
|
|
||||||
if (!EqualityComparer<T>.Default.Equals(field, value)){
|
|
||||||
field = value;
|
|
||||||
eventHandler?.Invoke(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Save(){
|
|
||||||
try{
|
|
||||||
if (File.Exists(file)){
|
|
||||||
string backupFile = GetBackupFile(file);
|
|
||||||
File.Delete(backupFile);
|
|
||||||
File.Move(file, backupFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
Serializer.Write(file, this);
|
|
||||||
}catch(Exception e){
|
|
||||||
Program.Reporter.HandleException("Configuration Error", "Could not save the configuration file.", true, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Reload(){
|
|
||||||
try{
|
|
||||||
LoadInternal(false);
|
|
||||||
}catch(FileNotFoundException){
|
|
||||||
try{
|
|
||||||
Serializer.Write(file, new UserConfig(file));
|
|
||||||
LoadInternal(false);
|
|
||||||
}catch(Exception e){
|
|
||||||
Program.Reporter.HandleException("Configuration Error", "Could not regenerate configuration file.", true, e);
|
|
||||||
}
|
|
||||||
}catch(Exception e){
|
|
||||||
Program.Reporter.HandleException("Configuration Error", "Could not reload configuration file.", true, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Reset(){
|
|
||||||
try{
|
|
||||||
File.Delete(file);
|
|
||||||
File.Delete(GetBackupFile(file));
|
|
||||||
}catch(Exception e){
|
|
||||||
Program.Reporter.HandleException("Configuration Error", "Could not delete configuration files to reset the options.", true, e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LoadInternal(bool backup){
|
|
||||||
Serializer.Read(backup ? GetBackupFile(file) : file, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UserConfig Load(string file){
|
|
||||||
Exception firstException = null;
|
|
||||||
|
|
||||||
for(int attempt = 0; attempt < 2; attempt++){
|
|
||||||
try{
|
|
||||||
UserConfig config = new UserConfig(file);
|
|
||||||
config.LoadInternal(attempt > 0);
|
|
||||||
return config;
|
|
||||||
}catch(FileNotFoundException){
|
|
||||||
}catch(DirectoryNotFoundException){
|
|
||||||
break;
|
|
||||||
}catch(Exception e){
|
|
||||||
if (attempt == 0){
|
|
||||||
firstException = e;
|
|
||||||
Program.Reporter.Log(e.ToString());
|
|
||||||
}
|
|
||||||
else if (firstException is FormatException){
|
|
||||||
Program.Reporter.HandleException("Configuration Error", "The configuration file is outdated or corrupted. If you continue, your program options will be reset.", true, e);
|
|
||||||
return new UserConfig(file);
|
|
||||||
}
|
|
||||||
else if (firstException != null){
|
|
||||||
Program.Reporter.HandleException("Configuration Error", "Could not open the backup configuration file. If you continue, your program options will be reset.", true, e);
|
|
||||||
return new UserConfig(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (firstException != null){
|
|
||||||
Program.Reporter.HandleException("Configuration Error", "Could not open the configuration file.", true, firstException);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new UserConfig(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetBackupFile(string file){
|
|
||||||
return file+".bak";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,18 +50,14 @@ public FormSettings(FormBrowser browser, PluginManager plugins, UpdateHandler up
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void PrepareLoad(){
|
private void PrepareLoad(){
|
||||||
Program.UserConfig.ProgramRestartRequested += Config_ProgramRestartRequested;
|
Program.Config.ProgramRestartRequested += Config_ProgramRestartRequested;
|
||||||
Program.SystemConfig.ProgramRestartRequested += Config_ProgramRestartRequested;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PrepareUnload(){ // TODO refactor this further later
|
private void PrepareUnload(){ // TODO refactor this further later
|
||||||
currentTab.Control.OnClosing();
|
currentTab.Control.OnClosing();
|
||||||
|
|
||||||
Program.UserConfig.ProgramRestartRequested -= Config_ProgramRestartRequested;
|
Program.Config.ProgramRestartRequested -= Config_ProgramRestartRequested;
|
||||||
Program.SystemConfig.ProgramRestartRequested -= Config_ProgramRestartRequested;
|
Program.Config.SaveAll();
|
||||||
|
|
||||||
Program.UserConfig.Save();
|
|
||||||
Program.SystemConfig.Save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Config_ProgramRestartRequested(object sender, EventArgs e){
|
private void Config_ProgramRestartRequested(object sender, EventArgs e){
|
||||||
|
@ -121,11 +121,7 @@ private void btnContinue_Click(object sender, EventArgs e){
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (SelectedItems.HasFlag(ProfileManager.Items.SystemConfig)){
|
if (SelectedItems.HasFlag(ProfileManager.Items.SystemConfig)){
|
||||||
try{
|
Program.SystemConfig.Reset();
|
||||||
File.Delete(Program.SystemConfigFilePath);
|
|
||||||
}catch(Exception ex){
|
|
||||||
Program.Reporter.HandleException("System Config Reset Error", "Could not delete system config.", true, ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SelectedItems.HasFlag(ProfileManager.Items.PluginData)){
|
if (SelectedItems.HasFlag(ProfileManager.Items.PluginData)){
|
||||||
@ -155,7 +151,7 @@ private void btnContinue_Click(object sender, EventArgs e){
|
|||||||
|
|
||||||
case State.Import:
|
case State.Import:
|
||||||
if (importManager.Import(SelectedItems)){
|
if (importManager.Import(SelectedItems)){
|
||||||
Program.UserConfig.Reload();
|
Program.UserConfig.Reload(); // TODO reload both configs and detect if restart is needed
|
||||||
|
|
||||||
if (importManager.IsRestarting){
|
if (importManager.IsRestarting){
|
||||||
if (SelectedItems.HasFlag(ProfileManager.Items.Session)){
|
if (SelectedItems.HasFlag(ProfileManager.Items.Session)){
|
||||||
@ -190,9 +186,6 @@ private void btnContinue_Click(object sender, EventArgs e){
|
|||||||
|
|
||||||
file = dialog.FileName;
|
file = dialog.FileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
Program.UserConfig.Save();
|
|
||||||
Program.SystemConfig.Save();
|
|
||||||
|
|
||||||
new ProfileManager(file, plugins).Export(SelectedItems);
|
new ProfileManager(file, plugins).Export(SelectedItems);
|
||||||
|
|
||||||
|
18
Program.cs
18
Program.cs
@ -45,11 +45,14 @@ static class Program{
|
|||||||
|
|
||||||
private static readonly LockManager LockManager = new LockManager(Path.Combine(StoragePath, ".lock"));
|
private static readonly LockManager LockManager = new LockManager(Path.Combine(StoragePath, ".lock"));
|
||||||
private static bool HasCleanedUp;
|
private static bool HasCleanedUp;
|
||||||
|
|
||||||
public static UserConfig UserConfig { get; private set; }
|
|
||||||
public static SystemConfig SystemConfig { get; private set; }
|
|
||||||
public static Reporter Reporter { get; }
|
|
||||||
public static CultureInfo Culture { get; }
|
public static CultureInfo Culture { get; }
|
||||||
|
public static Reporter Reporter { get; }
|
||||||
|
public static ConfigManager Config { get; }
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
public static UserConfig UserConfig => Config.User;
|
||||||
|
public static SystemConfig SystemConfig => Config.System;
|
||||||
|
|
||||||
static Program(){
|
static Program(){
|
||||||
Culture = CultureInfo.CurrentCulture;
|
Culture = CultureInfo.CurrentCulture;
|
||||||
@ -62,6 +65,8 @@ static Program(){
|
|||||||
|
|
||||||
Reporter = new Reporter(ErrorLogFilePath);
|
Reporter = new Reporter(ErrorLogFilePath);
|
||||||
Reporter.SetupUnhandledExceptionHandler("TweetDuck Has Failed :(");
|
Reporter.SetupUnhandledExceptionHandler("TweetDuck Has Failed :(");
|
||||||
|
|
||||||
|
Config = new ConfigManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
[STAThread]
|
[STAThread]
|
||||||
@ -113,8 +118,7 @@ private static void Main(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UserConfig = UserConfig.Load(UserConfigFilePath);
|
Config.LoadAll();
|
||||||
SystemConfig = SystemConfig.Load(SystemConfigFilePath);
|
|
||||||
|
|
||||||
if (Arguments.HasFlag(Arguments.ArgImportCookies)){
|
if (Arguments.HasFlag(Arguments.ArgImportCookies)){
|
||||||
ProfileManager.ImportCookies();
|
ProfileManager.ImportCookies();
|
||||||
@ -213,7 +217,7 @@ private static void RestartWithArgsInternal(CommandLineArgs args){
|
|||||||
private static void ExitCleanup(){
|
private static void ExitCleanup(){
|
||||||
if (HasCleanedUp)return;
|
if (HasCleanedUp)return;
|
||||||
|
|
||||||
UserConfig.Save();
|
Config.SaveAll();
|
||||||
|
|
||||||
Cef.Shutdown();
|
Cef.Shutdown();
|
||||||
BrowserCache.Exit();
|
BrowserCache.Exit();
|
||||||
|
@ -54,6 +54,9 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Configuration\Arguments.cs" />
|
<Compile Include="Configuration\Arguments.cs" />
|
||||||
|
<Compile Include="Configuration\Instance\FileConfigInstance.cs" />
|
||||||
|
<Compile Include="Configuration\ConfigManager.cs" />
|
||||||
|
<Compile Include="Configuration\Instance\IConfigInstance.cs" />
|
||||||
<Compile Include="Configuration\LockManager.cs" />
|
<Compile Include="Configuration\LockManager.cs" />
|
||||||
<Compile Include="Configuration\SystemConfig.cs" />
|
<Compile Include="Configuration\SystemConfig.cs" />
|
||||||
<Compile Include="Configuration\UserConfig.cs" />
|
<Compile Include="Configuration\UserConfig.cs" />
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
namespace TweetTest.Configuration{
|
namespace TweetTest.Configuration{
|
||||||
[TestClass]
|
[TestClass]
|
||||||
public class TestUserConfig : TestIO{
|
public class TestUserConfig : TestIO{ /* TODO
|
||||||
private static void WriteTestConfig(string file, bool withBackup){
|
private static void WriteTestConfig(string file, bool withBackup){
|
||||||
UserConfig cfg = UserConfig.Load(file);
|
UserConfig cfg = UserConfig.Load(file);
|
||||||
cfg.ZoomLevel = 123;
|
cfg.ZoomLevel = 123;
|
||||||
@ -133,6 +133,6 @@ public void TestEventsTrigger(){
|
|||||||
cfg.ZoomLevel = 100;
|
cfg.ZoomLevel = 100;
|
||||||
|
|
||||||
Assert.AreEqual(6, triggers);
|
Assert.AreEqual(6, triggers);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user