mirror of https://github.com/rusefi/openblt.git
252 lines
9.2 KiB
Plaintext
252 lines
9.2 KiB
Plaintext
unit CurrentConfig;
|
|
//***************************************************************************************
|
|
// Description: Program configuration management and persistency.
|
|
// File Name: currentconfig.pas
|
|
//
|
|
//---------------------------------------------------------------------------------------
|
|
// C O P Y R I G H T
|
|
//---------------------------------------------------------------------------------------
|
|
// Copyright (c) 2018 by Feaser http://www.feaser.com All rights reserved
|
|
//
|
|
// This software has been carefully tested, but is not guaranteed for any particular
|
|
// purpose. The author does not offer any warranties and does not guarantee the accuracy,
|
|
// adequacy, or completeness of the software and is not responsible for any errors or
|
|
// omissions or the results obtained from use of the software.
|
|
//
|
|
//---------------------------------------------------------------------------------------
|
|
// L I C E N S E
|
|
//---------------------------------------------------------------------------------------
|
|
// This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License as published by the Free
|
|
// Software Foundation, either version 3 of the License, or (at your option) any later
|
|
// version.
|
|
//
|
|
// OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
// PURPOSE. See the GNU General Public License for more details.
|
|
//
|
|
// You have received a copy of the GNU General Public License along with OpenBLT. It
|
|
// should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy.
|
|
//
|
|
//***************************************************************************************
|
|
{$IFDEF FPC}
|
|
{$MODE objfpc}{$H+}
|
|
{$ENDIF}
|
|
|
|
interface
|
|
//***************************************************************************************
|
|
// Includes
|
|
//***************************************************************************************
|
|
uses
|
|
Classes, SysUtils, Fgl, XMLConf, LazFileUtils;
|
|
|
|
|
|
//***************************************************************************************
|
|
// Type Definitions
|
|
//***************************************************************************************
|
|
type
|
|
//------------------------------ TConfigGroup -----------------------------------------
|
|
TConfigGroup = class (TObject)
|
|
protected
|
|
FName: String;
|
|
public
|
|
procedure Defaults; virtual; abstract;
|
|
procedure LoadFromFile(XmlConfig: TXMLConfig); virtual; abstract;
|
|
procedure SaveToFile(XmlConfig: TXMLConfig); virtual; abstract;
|
|
property Name: String read FName;
|
|
end;
|
|
|
|
//------------------------------ TConfigGroupList -------------------------------------
|
|
TConfigGroupList = specialize TFPGObjectList<TConfigGroup>;
|
|
|
|
//------------------------------ TCurrentConfig ---------------------------------------
|
|
TCurrentConfig = class (TObject)
|
|
private
|
|
FConfigFile: String;
|
|
FGroups: TConfigGroupList;
|
|
function GetGroup(Name: String): TConfigGroup;
|
|
public
|
|
constructor Create;
|
|
destructor Destroy; override;
|
|
procedure LoadFromFile;
|
|
procedure SaveToFile;
|
|
procedure AddGroup(Group: TConfigGroup);
|
|
property ConfigFile: String read FConfigFile;
|
|
property Groups[Name: String]: TConfigGroup read GetGroup;
|
|
end;
|
|
|
|
|
|
implementation
|
|
//---------------------------------------------------------------------------------------
|
|
//-------------------------------- TCurrentConfig ---------------------------------------
|
|
//---------------------------------------------------------------------------------------
|
|
//***************************************************************************************
|
|
// NAME: Create
|
|
// PARAMETER: none
|
|
// RETURN VALUE: none
|
|
// DESCRIPTION: Class constructor.
|
|
//
|
|
//***************************************************************************************
|
|
constructor TCurrentConfig.Create;
|
|
begin
|
|
// Call inherited constructor.
|
|
inherited Create;
|
|
// Set fields.
|
|
FConfigFile := GetAppConfigFile(False, True);
|
|
// Validate the configuration file.
|
|
Assert(FConfigFile <> '', 'Could not get application configuration filename.');
|
|
// Create instance of the groups list.
|
|
FGroups := TConfigGroupList.Create;
|
|
end; //*** end of Create ***
|
|
|
|
|
|
//***************************************************************************************
|
|
// NAME: Destroy
|
|
// PARAMETER: none
|
|
// RETURN VALUE: none
|
|
// DESCRIPTION: Class destructor.
|
|
//
|
|
//***************************************************************************************
|
|
destructor TCurrentConfig.Destroy;
|
|
begin
|
|
// Free the groups list instance. Note that this automatically frees the config groups
|
|
// in the list.
|
|
FGroups.Free;
|
|
// call inherited destructor
|
|
inherited Destroy;
|
|
end; //*** end of Destroy ***
|
|
|
|
|
|
//***************************************************************************************
|
|
// NAME: LoadFromFile
|
|
// PARAMETER: none
|
|
// RETURN VALUE: none
|
|
// DESCRIPTION: Loads the program's configuration from the configuration file.
|
|
//
|
|
//***************************************************************************************
|
|
procedure TCurrentConfig.LoadFromFile;
|
|
var
|
|
idx: Integer;
|
|
xmlConfig: TXMLConfig;
|
|
begin
|
|
// Loop through all groups to set defaults just in case the configuration file does
|
|
// no exist.
|
|
for idx := 0 to (FGroups.Count - 1) do
|
|
begin
|
|
// Request group to load its settings from the configuration file.
|
|
FGroups[idx].Defaults;
|
|
end;
|
|
|
|
// Check that the configuration file exists.
|
|
if FileExists(configFile) then
|
|
begin
|
|
// Construct XML configuration object.
|
|
xmlConfig := TXMLConfig.Create(nil);
|
|
xmlConfig.Filename := configFile;
|
|
// Loop through all groups.
|
|
for idx := 0 to (FGroups.Count - 1) do
|
|
begin
|
|
// Request group to load its settings from the configuration file.
|
|
FGroups[idx].LoadFromFile(xmlConfig);
|
|
end;
|
|
// Release the XML configuration object.
|
|
xmlConfig.Free;
|
|
end;
|
|
end; //*** end of LoadFromFile ***
|
|
|
|
|
|
//***************************************************************************************
|
|
// NAME: SaveToFile
|
|
// PARAMETER: none
|
|
// RETURN VALUE: none
|
|
// DESCRIPTION: Saves the program's configuration to the configuration file.
|
|
//
|
|
//***************************************************************************************
|
|
procedure TCurrentConfig.SaveToFile;
|
|
var
|
|
idx: Integer;
|
|
configDir: String;
|
|
xmlConfig: TXMLConfig;
|
|
begin
|
|
// Extract the directory of the config file.
|
|
configDir := ExtractFilePath(FConfigFile);
|
|
// Validate the directory.
|
|
Assert(configDir <> '', 'Configuration directory is invalid.');
|
|
// Double check that the directory is actually there.
|
|
if not DirectoryExists(configDir) then
|
|
begin
|
|
// Force the directory creation.
|
|
ForceDirectories(configDir);
|
|
end;
|
|
// Only save settings if the directory is there and is writable.
|
|
if DirectoryExists(configDir) and DirectoryIsWritable(configDir) then
|
|
begin
|
|
// Construct XML configuration object.
|
|
xmlConfig := TXMLConfig.Create(nil);
|
|
xmlConfig.Filename := configFile;
|
|
// Loop through all groups.
|
|
for idx := 0 to (FGroups.Count - 1) do
|
|
begin
|
|
// Request group to save its settings to the configuration file.
|
|
FGroups[idx].SaveToFile(xmlConfig);
|
|
end;
|
|
// Write and release the XML configuration object.
|
|
xmlConfig.Flush;
|
|
xmlConfig.Free;
|
|
end;
|
|
end; //*** end of SaveToFile ***
|
|
|
|
|
|
//***************************************************************************************
|
|
// NAME: AddGroup
|
|
// PARAMETER: Group The configuration group to add.
|
|
// RETURN VALUE: none
|
|
// DESCRIPTION: Adds a configuration group under management of the current
|
|
// configuration.
|
|
//
|
|
//***************************************************************************************
|
|
procedure TCurrentConfig.AddGroup(Group: TConfigGroup);
|
|
begin
|
|
// Check parameters.
|
|
Assert(Group <> nil, 'Invalid group specified as a parameter.');
|
|
// Add the group.
|
|
FGroups.Add(Group);
|
|
end; //*** end of AddGroup ***
|
|
|
|
|
|
//***************************************************************************************
|
|
// NAME: GetGroup
|
|
// PARAMETER: Name Name of the configuration group to obtain.
|
|
// RETURN VALUE: Configuration group.
|
|
// DESCRIPTION: Obtains the configuration group based on the specified name.
|
|
//
|
|
//***************************************************************************************
|
|
function TCurrentConfig.GetGroup(Name: String): TConfigGroup;
|
|
var
|
|
idx: Integer;
|
|
begin
|
|
// Initialize the result value.
|
|
Result := nil;
|
|
// Check parameters.
|
|
Assert(Name <> '', 'Group name can not be empty.');
|
|
// Loop through all groups.
|
|
for idx := 0 to (FGroups.Count - 1) do
|
|
begin
|
|
// Is this the group we are looking for?
|
|
if FGroups[idx].Name = Name then
|
|
begin
|
|
// Set the result value.
|
|
Result := FGroups[idx];
|
|
// No need to continue looping.
|
|
Break;
|
|
end;
|
|
end;
|
|
// Verify the result value.
|
|
Assert(Result <> nil, 'Invalid group name specified.');
|
|
end; //*** end of GetGroup ***
|
|
|
|
|
|
end.
|
|
//******************************** end of currentconfig.pas *****************************
|
|
|