Files
lazarus-ccr/components/flashfiler/sourcelaz/explorer/uconfig.pas
2016-12-07 13:31:59 +00:00

639 lines
20 KiB
ObjectPascal

{*********************************************************}
{* Persistently Stored Configuration Info *}
{*********************************************************}
(* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is TurboPower FlashFiler
*
* The Initial Developer of the Original Code is
* TurboPower Software
*
* Portions created by the Initial Developer are Copyright (C) 1996-2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** *)
{$I ffdefine.inc}
unit uconfig;
interface
uses
Windows,
Forms,
SysUtils,
Grids,
DB,
DBGrids,
INIFiles,
Classes,
ffllbase,
ffllprot,
uconsts;
const
{$IFDEF UseRegistryConfig}
cfgRootKey = HKEY_LOCAL_MACHINE;
{$ENDIF}
cfgKeyOptions = 'Options';
cfgWindow = 'Window';
cfgWindowState = 'WindowState';
cfgSplitter = 'Splitter';
cfgKeyRegisteredServers = 'Registered Servers';
cfgShowBrowser = 'Show Browser';
cfgLiveDatasets = 'Live Datasets';
cfgDefaultTimeout = 'Default Timeout'; {!!.11}
cfgProtocol = 'Protocol';
cfgProtocolSingleUser = 'Single User';
cfgProtocolNetBIOS = 'NetBIOS';
cfgProtocolTCPIP = 'TCP/IP';
cfgProtocolIPXSPX = 'IPX/SPX';
cfgLastServer = 'LastServer';
cfgSortAvailIndexFields = 'Available Index Fields Sorted';
defWindowState = wsNormal;
defcfgShowBrowser = True;
defcfgLiveDatasets = False;
defcfgSortAvailIndexFields = True;
type
TffeConfigOptions = set of (coShowBrowser, coLiveDatasets);
TffeConfig = class(TPersistent)
private
protected {private}
FLastServer : string;
FWindow: TRect;
FWindowState: TWindowState;
FSortAvailIndexFields : Boolean;
FSplitterPosition: Integer;
FOptions: TffeConfigOptions;
// FProtocol: TffCommsProtocolClass;
FRegisteredServers: TStrings;
FINIFilename: TFileName;
{$IFDEF UseRegistryConfig}
FRegistryKey: TffShStr;
{$ENDIF}
FDefaultTimeout: Integer; {!!.11}
{ default timeout for all operations unless overriden in
table- or sqlwindows etc }
FWorkingDirectory: String; {!!.11}
{ the current dir upon startup
(from the "start in" shortcut setting) }
protected
// function GetProtocolName: TffShStr;
procedure ParseWindowString(aWindow: TffShStr);
procedure SetLastServer(aValue : string);
// procedure SetProtocol(aValue: TffCommsProtocolClass);
procedure SetWindowState(aValue: TWindowState);
procedure SetDefaultTimeout(const Value: Integer); {!!.11}
public
constructor Create;
destructor Destroy; override;
procedure Refresh;
{- Reload all settings from persistent storage}
procedure Save;
{- Save the configuration to persistent storage}
property LastServer : string
read FLastServer write SetLastServer;
{- Last server accessed by user. }
property Options: TffeConfigOptions
read FOptions write FOptions;
{- boolean option settings}
// property Protocol: TffCommsProtocolClass
// read FProtocol write SetProtocol;
{- Communications protocol}
// property ProtocolName: TffShStr
// read GetProtocolName;
{- Returns the label associated with the protocol }
property RegisteredServers: TStrings
read FRegisteredServers write FRegisteredServers;
{- Currently registered server names}
property SortAvailIndexFields : Boolean
read FSortAvailIndexFields write FSortAvailIndexFields;
{- Should the available index fields be in sorted or natural order }
property SplitterPosition: Integer
read FSplitterPosition write FSplitterPosition;
{- Position of the main window's splitter bar}
property Window: TRect
read FWindow write FWindow;
{- Coordinates of the main window}
property WindowState: TWindowState
read FWindowState write SetWindowState;
{- State of the main window}
property DefaultTimeout: Integer read FDefaultTimeout write SetDefaultTimeout; {!!.11}
{- Default timeout for all Client components }
property WorkingDirectory: String read FWorkingDirectory; {!!.11}
{- Directory to save ini- and logfiles etc }
end;
procedure FFEConfigSaveFormPrefs(const Section : string; Form : TForm);
procedure FFEConfigGetFormPrefs(const Section : string; Form : TForm);
procedure FFEConfigSaveString(const Section, Ident, Value : string);
function FFEConfigGetString(const Section, Ident, Default : string) : string;
procedure FFEConfigSaveInteger(const Section, Ident : string; Value : Integer);
function FFEConfigGetInteger(const Section, Ident : string; Default : Integer) : Integer;
procedure FFEConfigSaveBoolean(const Section, Ident : string; Value : Boolean);
function FFEConfigGetBoolean(const Section, Ident : string; Default : Boolean) : Boolean;
procedure FFEConfigSaveDBColumnPrefs(const Section : string; Columns : TDBGridColumns);
procedure FFEConfigGetDBColumnPrefs(const Section : string; Columns : TDBGridColumns);
procedure FFEConfigSaveColumnPrefs(const Section : string; Grid : TStringGrid);
procedure FFEConfigGetColumnPrefs(const Section : string; Grid : TStringGrid);
var
Config : TffeConfig;
FFEIni : TIniFile;
IsReadOnly : Boolean; {!!.06}
implementation
uses
{$IFDEF UseRegistryConfig}
Registry,
{$ENDIF}
ffllexcp,
ffclbase,
ffclcfg,
ffconst;
procedure FFEConfigSaveFormPrefs(const Section : string; Form : TForm);
var
Placement : TWindowPlacement;
begin
if IsReadOnly then {!!.06}
Exit; {!!.06}
{Begin !!.11}
{ rewritten.
NOTE: the 'width' and 'height' names below
have been kept to keep leftover unused entries to a minimum.
'windowstate' isn't suitable for reuse since the values are
not compatible between WindowState and ShowCmd. }
Placement.length :=SizeOf(TWindowPlacement);
if not GetWindowPlacement(Form.Handle, @Placement) then
Exit;
with Placement do begin
FFEIni.WriteInteger(Section, 'Flags', Flags);
FFEIni.WriteInteger(Section, 'ShowCmd', ShowCmd);
FFEIni.WriteInteger(Section, 'Left', rcNormalPosition.Left);
FFEIni.WriteInteger(Section, 'Top', rcNormalPosition.Top);
FFEIni.WriteInteger(Section, 'Width', rcNormalPosition.Right);
FFEIni.WriteInteger(Section, 'Height', rcNormalPosition.Bottom);
End;
{End !!.11}
end;
{--------}
procedure FFEConfigGetFormPrefs(const Section : string; Form : TForm);
var
Placement : TWindowPlacement;
begin
{Begin !!.11}
{ rewritten.
NOTE: the 'width' and 'height' names below
have been kept to keep leftover unused entries to a minimum.
'windowstate' isn't suitable for reuse since the values are
not compatible between WindowState and ShowCmd. }
with Placement do begin
length := SizeOf(TWindowPlacement);
Flags := FFEIni.ReadInteger(Section, 'Flags', 0);
ShowCmd := FFEIni.ReadInteger(Section, 'ShowCmd', SW_SHOW);
rcNormalPosition.Left := FFEIni.ReadInteger(Section, 'Left', Form.Left);
rcNormalPosition.Top := FFEIni.ReadInteger(Section, 'Top', Form.Top);
rcNormalPosition.Right := FFEIni.ReadInteger(Section, 'Width', Form.Left+Form.Width);
rcNormalPosition.Bottom := FFEIni.ReadInteger(Section, 'Height', Form.Top+Form.Height);
IF rcNormalPosition.Right > rcNormalPosition.Left THEN
SetWindowPlacement(Form.Handle, @Placement)
end;
{End !!.11}
end;
{--------}
procedure FFEConfigSaveString(const Section, Ident, Value : string);
begin
if IsReadOnly then {!!.06}
Exit; {!!.06}
FFEIni.WriteString(Section, Ident, Value);
end;
{--------}
function FFEConfigGetString(const Section, Ident, Default : string) : string;
begin
Result := FFEIni.ReadString(Section, Ident, Default);
end;
{--------}
procedure FFEConfigSaveInteger(const Section, Ident : string; Value : Integer);
begin
if IsReadOnly then {!!.06}
Exit; {!!.06}
FFEIni.WriteInteger(Section, Ident, Value);
end;
{--------}
function FFEConfigGetInteger(const Section, Ident : string; Default : Integer) : Integer;
begin
Result := FFEIni.ReadInteger(Section, Ident, Default);
end;
{--------}
procedure FFEConfigSaveBoolean(const Section, Ident : string; Value : Boolean);
begin
if IsReadOnly then {!!.06}
Exit; {!!.06}
FFEIni.WriteBool(Section, Ident, Value);
end;
{--------}
function FFEConfigGetBoolean(const Section, Ident : string; Default : Boolean) : Boolean;
begin
Result := FFEIni.ReadBool(Section, Ident, Default);
end;
{--------}
procedure FFEConfigSaveDBColumnPrefs(const Section : string; Columns : TDBGridColumns);
var
Idx : Integer;
begin
if IsReadOnly then {!!.06}
Exit; {!!.06}
FFEIni.EraseSection(Section);
for Idx := 0 to Pred(Columns.Count) do
FFEConfigSaveString(Section, Columns[Idx].FieldName, IntToStr(Columns[Idx].Width));
end;
{--------}
procedure FFEConfigGetDBColumnPrefs(const Section : string; Columns : TDBGridColumns);
var
Idx : Integer;
Col : TColumn;
ColumnInfo : TStringList;
Dataset : TDataSet;
begin
if Columns.Grid.FieldCount = 0 then Exit;
Dataset := Columns.Grid.Fields[0].DataSet;
ColumnInfo := TStringList.Create;
try
ColumnInfo.Sorted := False;
FFEIni.ReadSection(Section, ColumnInfo);
{Begin !!.10}
{ if there are new columns in the dataset, don't use stored column
settings, otherwise the new columns end up to the far right. }
for Idx := 0 to Pred(Dataset.FieldCount) do
if ColumnInfo.IndexOf(Dataset.Fields[Idx].FieldName)<0 then begin
Columns.RebuildColumns;
Exit;
end;
{End !!.10}
Columns.BeginUpdate;
try
Columns.Clear;
for Idx := 0 to Pred(ColumnInfo.Count) do begin
if (Dataset.FindField(ColumnInfo[Idx]) <> nil) then begin
Col := Columns.Add;
Col.FieldName := ColumnInfo[Idx];
Col.Width := FFEConfigGetInteger(Section, Col.FieldName, Col.Width);
end;
end;
for Idx := 0 to Pred(Dataset.FieldCount) do begin
if (ColumnInfo.IndexOf(Dataset.Fields[Idx].FieldName) = -1) then begin
Col := Columns.Add;
Col.FieldName := Dataset.Fields[Idx].FieldName;
end;
end;
finally
Columns.EndUpdate;
end;
finally
ColumnInfo.Free;
end;
end;
{--------}
procedure FFEConfigSaveColumnPrefs(const Section : string; Grid : TStringGrid);
var
Idx : Integer;
begin
if IsReadOnly then {!!.06}
Exit; {!!.06}
for Idx := 0 to Pred(Grid.ColCount) do
FFEConfigSaveInteger(Section, IntToStr(Idx), Grid.ColWidths[Idx]);
end;
{--------}
procedure FFEConfigGetColumnPrefs(const Section : string; Grid : TStringGrid);
var
Idx : Integer;
begin
for Idx := 0 to Pred(Grid.ColCount) do
Grid.ColWidths[Idx] := FFEConfigGetInteger(Section, IntToStr(Idx), Grid.ColWidths[Idx]);
end;
{--------}
constructor TffeConfig.Create;
begin
{Begin !!.11}
FWorkingDirectory := GetCurrentDir;
if FWorkingDirectory='' then
FWorkingDirectory := ExtractFilePath(Application.ExeName);
if Copy(FWorkingDirectory, Length(FWorkingDirectory), 1)<>'\' then
FWorkingDirectory := FWorkingDirectory + '\';
{End !!.11}
FINIFilename := FWorkingDirectory + ChangeFileExt(ExtractFileName(Application.ExeName), '.INI');
{$IFDEF UseRegistryConfig}
FRegistryKey := ffStrResClient[ffccREG_PRODUCT] + ffeRegistrySubKey;
{$ENDIF}
FRegisteredServers := TStringList.Create;
Refresh;
end;
{--------}
destructor TffeConfig.Destroy;
begin
FRegisteredServers.Free;
end;
{--------}
{function TffeConfig.GetProtocolName: TffShStr;
begin
Result := FFClientConfigGetProtocolName(FProtocol);
end;}
{--------}
procedure TffeConfig.ParseWindowString(aWindow: TffShStr);
type
TElement = (teLeft, teTop, teRight, teBottom);
var
J: TElement;
Element: TffShStr;
begin
try
J := teLeft;
repeat
FFShStrSplit(aWindow, ' ', Element, aWindow);
case J of
teLeft: FWindow.Left := StrToInt(Element);
teTop: FWindow.Top := StrToInt(Element);
teRight: FWindow.Right := StrToInt(Element);
teBottom: FWindow.Bottom := StrToInt(Element);
end;
if J < High(J) then Inc(J);
until aWindow = '';
except
end;
end;
{--------}
procedure TffeConfig.Refresh;
{$IFDEF UseINIConfig}
var
Window: TffShStr;
{$ENDIF}
begin
FOptions := [];
// FProtocol := FFClientConfigReadProtocolClass;
{$IFDEF UseINIConfig}
with TINIFile.Create(FINIFilename) do
try
Window := ReadString(cfgKeyOptions, cfgWindow, '');
if Window <> '' then
ParseWindowString(Window);
FSplitterPosition := ReadInteger(cfgKeyOptions, cfgSplitter, -1);
FWindowState := TWindowState(ReadInteger(cfgKeyOptions, cfgWindowState, Ord(defWindowState)));
if ReadBool(cfgKeyOptions, cfgShowBrowser, defcfgShowBrowser) then
Include(FOptions, coShowBrowser);
if ReadBool(cfgKeyOptions, cfgLiveDatasets, defcfgLiveDatasets) then
Include(FOptions, coLiveDatasets);
FSortAvailIndexFields := ReadBool(cfgKeyOptions, cfgSortAvailIndexFields, defcfgSortAvailIndexFields);
ReadSection(cfgKeyRegisteredServers, FRegisteredServers);
FDefaultTimeout := ReadInteger(cfgKeyOptions, cfgDefaultTimeout, 10000);
finally
Free;
end;
{$ENDIF}
{$IFDEF UseRegistryConfig}
with TRegistry.Create do
try
{ set defaults }
if defcfgShowBrowser then
Include(FOptions, coShowBrowser);
if defcfgLiveDatasets then
Include(FOptions, coLiveDatasets);
FSortAvailIndexFields := defcfgSortAvailIndexFields;
FWindowState := defWindowState;
{ set and open the main key }
RootKey := cfgRootKey;
if KeyExists(FRegistryKey + '\' + cfgKeyOptions) then
OpenKey(FRegistryKey + '\' + cfgKeyOptions, False);
{ get the window size, position }
if ValueExists(cfgWindow) then
ParseWindowString(ReadString(cfgWindow));
FSplitterPosition := -1;
if ValueExists(cfgSplitter) then
FSplitterPosition := ReadInteger(cfgSplitter);
if ValueExists(cfgWindowState) then
FWindowState := TWindowState(ReadInteger(cfgWindowState));
if ValueExists(cfgShowBrowser) then
if ReadBool(cfgShowBrowser) then
Include(FOptions, coShowBrowser)
else
Exclude(FOptions, coShowBrowser);
if ValueExists(cfgLiveDatasets) then
if ReadBool(cfgLiveDatasets) then
Include(FOptions, coLiveDatasets)
else
Exclude(FOptions, coLiveDatasets);
if ValueExists(cfgSortAvailIndexFields) then
FSortAvailIndexFields := ReadBool(cfgSortAvailIndexFields);
if ValueExists(cfgLastServer) then
FLastServer := ReadString(cfgLastServer);
{Begin !!.11}
FDefaultTimeout := 10000;
if ValueExists(cfgDefaultTimeout) then
FDefaultTimeout := ReadInteger(cfgDefaultTimeout);
{End !!.11}
OpenKey(FRegistryKey + '\' + cfgKeyRegisteredServers, False);
GetKeyNames(FRegisteredServers);
finally
Free;
end;
{$ENDIF}
end;
{--------}
procedure TffeConfig.Save;
var
{$IFDEF UseINIConfig} {BEGIN !!.01}
I: Integer;
{$ELSE}
{$IFDEF UseRegistryConfig}
I: Integer;
{$ENDIF}
{$ENDIF} {END !!.01}
begin
// FFClientConfigWriteProtocolClass(FProtocol);
{$IFDEF UseINIConfig}
with TINIFile.Create(FINIFilename) do
try
try
{ Main window stuff }
with FWindow do
WriteString(cfgKeyOptions, cfgWindow, Format('%d %d %d %d', [Left, Top, Right, Bottom]));
WriteInteger(cfgKeyOptions, cfgWindowState, Ord(FWindowState));
WriteInteger(cfgKeyOptions, cfgSplitter, FSplitterPosition);
{ Options }
WriteBool(cfgKeyOptions, cfgShowBrowser, (coShowBrowser in FOptions));
WriteBool(cfgKeyOptions, cfgLiveDatasets, (coLiveDatasets in FOptions));
WriteBool(cfgKeyOptions, cfgSortAvailIndexFields, FSortAvailIndexFields);
WriteInteger(cfgKeyOptions, cfgDefaultTimeout, FDefaultTimeout); {!!.11}
{ Registered Servers }
EraseSection(cfgKeyRegisteredServers);
with FRegisteredServers do
for I := 0 to Count - 1 do
WriteString(cfgKeyRegisteredServers, Strings[I], '');
finally
Free;
end;
except
on E:Exception do
ShowMessage('Error writing INI file: '+E.Message);
end;
{$ENDIF}
{$IFDEF UseRegistryConfig}
if (FRegistryKey <> '') and (FRegistryKey[1] = '\') then begin
with TRegistry.Create do
try
RootKey := cfgRootKey;
{delete the options key and all that's in it}
DeleteKey(FRegistryKey + '\' + cfgKeyOptions);
{create the options key afresh, make it the current key}
OpenKey(FRegistryKey + '\' + cfgKeyOptions, True);
{write out all the config info}
{ Window coordinates }
with FWindow do
WriteString(cfgWindow, Format('%d %d %d %d', [Left, Top, Right, Bottom]));
WriteInteger(cfgWindowState, Ord(FWindowState));
WriteInteger(cfgSplitter, FSplitterPosition);
{ Options }
WriteBool(cfgShowBrowser, (coShowBrowser in FOptions));
WriteBool(cfgLiveDatasets, (coLiveDatasets in FOptions));
WriteBool(cfgSortAvailIndexFields, FSortAvailIndexFields);
WriteInteger(cfgDefaultTimeout, FDefaultTimeout); {!!.11}
{ Last server }
WriteString(cfgLastServer, FLastServer);
{ Registered Servers }
DeleteKey(FRegistryKey + '\' + cfgKeyRegisteredServers);
CreateKey(FRegistryKey + '\' + cfgKeyRegisteredServers);
with FRegisteredServers do
for I := 0 to Count - 1 do
CreateKey(FRegistryKey + '\' + cfgKeyRegisteredServers + '\' + Strings[I]);
finally
Free;
end;
end;
{$ENDIF}
end;
{--------}
{Begin !!.11}
procedure TffeConfig.SetDefaultTimeout(const Value: Integer);
begin
FDefaultTimeout := Value;
end;
{End !!.11}
{--------}
procedure TffeConfig.SetLastServer(aValue : string);
begin
if FLastServer <> aValue then
FLastServer := aValue;
end;
{--------}
{procedure TffeConfig.SetProtocol(aValue : TffCommsProtocolClass);
begin
if FProtocol <> aValue then begin
FProtocol := aValue;
FFClientConfigWriteProtocolClass(FProtocol);
end;
end;}
{--------}
procedure TffeConfig.SetWindowState(aValue : TWindowState);
begin
if aValue = wsMinimized then
aValue := wsNormal;
if aValue <> FWindowState then
FWindowState := aValue;
end;
{--------}
procedure InitUnit;
begin
Config := TffeConfig.Create;
if FileExists(Config.FINIFilename) then {!!.06}
IsReadOnly := (FileGetAttr(Config.FINIFilename) and {!!.06}
SysUtils.faReadOnly) <> 0 {!!.06}
else {!!.06}
IsReadOnly := False; {!!.06}
FFEIni := TIniFile.Create(Config.FINIFilename);
end;
{--------}
procedure TermUnit;
begin
Config.Free;
Config := nil;
FFEIni.Free;
FFEIni := nil;
end;
{--------}
initialization
InitUnit;
finalization
TermUnit;
end.