Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 76 additions & 9 deletions Source/NETworkManager.Localization/Resources/Strings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions Source/NETworkManager.Localization/Resources/Strings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -3963,4 +3963,29 @@ If you click Cancel, the profile file will remain unencrypted.</value>
<data name="SettingManagedByAdministrator" xml:space="preserve">
<value>This setting is managed by your administrator.</value>
</data>
<data name="RestoreDefaultLocation" xml:space="preserve">
<value>Restore default location</value>
</data>
<data name="Restore" xml:space="preserve">
<value>Restore</value>
</data>
<data name="RestoreDefaultLocationQuestion" xml:space="preserve">
<value>Restore default location?</value>
</data>
<data name="RestoreDefaultLocationSettingsMessage" xml:space="preserve">
<value>The default path is restored and the application is restarted afterwards.

You can copy the “settings.json” file from "{0}" to "{1}" to migrate your previous settings, if necessary. The application must be closed for this to prevent the settings from being overwritten.</value>
</data>
<data name="ChangeLocationQuestion" xml:space="preserve">
<value>Change location?</value>
</data>
<data name="ChangeLocationSettingsMessage" xml:space="preserve">
<value>The location is changed and the application is restarted afterwards.

You can copy the “settings.json” file from "{0}" to "{1}" to migrate your previous settings, if necessary. The application must be closed for this to prevent the settings from being overwritten.</value>
</data>
<data name="EnterValidFolderPath" xml:space="preserve">
<value>Enter a valid folder path!</value>
</data>
</root>
6 changes: 4 additions & 2 deletions Source/NETworkManager.Profiles/ProfileManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -616,10 +616,10 @@ private static void Load(ProfileFileInfo profileFileInfo)
{
var loadedProfileUpdated = false;

Log.Info($"Load profile file: {profileFileInfo.Path}");

if (File.Exists(profileFileInfo.Path))
{
Log.Info($"Loading profile file from: {profileFileInfo.Path}");

// Encrypted profile file
if (profileFileInfo.IsEncrypted)
{
Expand Down Expand Up @@ -734,6 +734,8 @@ private static void Load(ProfileFileInfo profileFileInfo)

// Notify subscribers that profiles have been loaded/updated
ProfilesUpdated(false);

Log.Info("Profile file loaded successfully.");
}

/// <summary>
Expand Down
58 changes: 58 additions & 0 deletions Source/NETworkManager.Settings/LocalSettingsInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text.Json.Serialization;

namespace NETworkManager.Settings;

/// <summary>
/// Class contains local settings that are stored outside the main settings file.
/// These settings control where the main settings file is located.
/// </summary>
public class LocalSettingsInfo
{
/// <summary>
/// Occurs when a property value changes.
/// </summary>
/// <remarks>This event is typically used to notify subscribers that a property value has been updated. It
/// is commonly implemented in classes that support data binding or need to signal changes to property
/// values.</remarks>
public event PropertyChangedEventHandler PropertyChanged;

/// <summary>
/// Helper method to raise the <see cref="PropertyChanged" /> event.
/// </summary>
/// <param name="propertyName">Name of the property that changed.</param>
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
SettingsChanged = true;

PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

#region Variables

[JsonIgnore] public bool SettingsChanged { get; set; }

/// <summary>
/// Private field for the <see cref="SettingsFolderLocation" /> property."
/// </summary>
private string _settingsFolderLocation;

/// <summary>
/// Location of the folder where the local settings file is stored.
/// This can be changed by the user to move the settings file to a different location.
/// </summary>
public string SettingsFolderLocation
{
get => _settingsFolderLocation;
set
{
if (_settingsFolderLocation == value)
return;

_settingsFolderLocation = value;
OnPropertyChanged();
}
}
#endregion
}
126 changes: 126 additions & 0 deletions Source/NETworkManager.Settings/LocalSettingsManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
using log4net;
using Microsoft.Xaml.Behaviors.Media;
using System;
using System.IO;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace NETworkManager.Settings;

/// <summary>
/// Manages local application settings that are stored outside the main settings file.
/// This is used for settings that control where the main settings file is located.
/// </summary>
public static class LocalSettingsManager
{
#region Variables

/// <summary>
/// Logger for logging.
/// </summary>
private static readonly ILog Log = LogManager.GetLogger(typeof(LocalSettingsManager));

/// <summary>
/// Settings file name.
/// </summary>
private static string SettingsFileName => "Settings.json";

/// <summary>
/// Settings that are currently loaded.
/// </summary>
public static LocalSettingsInfo Current { get; private set; }

/// <summary>
/// JSON serializer options for consistent serialization/deserialization.
/// </summary>
private static readonly JsonSerializerOptions JsonOptions = new()
{
WriteIndented = true,
PropertyNameCaseInsensitive = true,
DefaultIgnoreCondition = JsonIgnoreCondition.Never,
Converters = { new JsonStringEnumConverter() }
};
#endregion

#region Methods

/// <summary>
/// Method to get the path of the settings folder.
/// </summary>
/// <returns>Path to the settings folder.</returns>
private static string GetSettingsFolderLocation()
{
return Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
AssemblyManager.Current.Name);
}

/// <summary>
/// Method to get the settings file path
/// </summary>
/// <returns>Settings file path.</returns>
private static string GetSettingsFilePath()
{
return Path.Combine(
GetSettingsFolderLocation(),
SettingsFileName);
}

/// <summary>
/// Initialize new settings (<see cref="SettingsInfo" />) and save them (to a file).
/// </summary>
private static void Initialize()
{
Log.Info("Initializing new local settings.");

Current = new LocalSettingsInfo();

Save();
}

/// <summary>
/// Method to load the settings from a file.
/// </summary>
public static void Load()
{
var filePath = GetSettingsFilePath();

if (File.Exists(filePath))
{
Log.Info($"Loading local settings from: {filePath}");

var jsonString = File.ReadAllText(filePath);
Current = JsonSerializer.Deserialize<LocalSettingsInfo>(jsonString, JsonOptions);

Log.Info("Local settings loaded successfully.");

// Reset change tracking
Current.SettingsChanged = false;

return;
}

Initialize();
}

/// <summary>
/// Method to save the current settings to a file.
/// </summary>
public static void Save()
{
// Create the directory if it does not exist
Directory.CreateDirectory(GetSettingsFolderLocation());

// Serialize to file
var filePath = GetSettingsFilePath();

var jsonString = JsonSerializer.Serialize(Current, JsonOptions);
File.WriteAllText(filePath, jsonString);

Log.Info($"Local settings saved to {filePath}");

// Reset change tracking
Current.SettingsChanged = false;
}
#endregion
}
3 changes: 3 additions & 0 deletions Source/NETworkManager.Settings/PolicyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@ public class PolicyInfo
{
[JsonPropertyName("Update_CheckForUpdatesAtStartup")]
public bool? Update_CheckForUpdatesAtStartup { get; set; }

[JsonPropertyName("SettingsFolderLocation")]
public string? SettingsFolderLocation { get; set; }
}
1 change: 1 addition & 0 deletions Source/NETworkManager.Settings/PolicyManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ public static void Load()

// Log enabled settings
Log.Info($"System-wide policy - Update_CheckForUpdatesAtStartup: {Current.Update_CheckForUpdatesAtStartup?.ToString() ?? "Not set"}");
Log.Info($"System-wide policy - SettingsFolderLocation: {Current.SettingsFolderLocation ?? "Not set"}");
}
}
catch (Exception ex)
Expand Down
10 changes: 10 additions & 0 deletions Source/NETworkManager.Settings/SettingsInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@

namespace NETworkManager.Settings;

/// <summary>
/// Represents the application settings, user preferences, and configuration data for all supported features and
/// modules. Supports property change notification for data binding and persistence scenarios.
/// </summary>
/// <remarks>The <see cref="SettingsInfo" /> class provides a centralized container for storing and managing user-configurable
/// options, operational parameters, and history collections for various application modules, such as network tools,
/// remote access, and calculators. It implements the INotifyPropertyChanged interface to enable data binding and
/// automatic UI updates when settings change. Most properties raise the PropertyChanged event when modified, allowing
/// consumers to track changes and persist settings as needed. This class is typically used as the main settings model
/// in applications that require user customization and state management across sessions.</remarks>
public class SettingsInfo : INotifyPropertyChanged
{
/// <summary>
Expand Down
Loading