Componentes.Terceros.jvcl/official/3.32/install/JVCLInstall/Helpers/JVCLConfiguration.pas

326 lines
8.5 KiB
ObjectPascal

{-----------------------------------------------------------------------------
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/MPL-1.1.html
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is: JVCLConfiguration.pas, released on 2004-03-29.
The Initial Developer of the Original Code is Andreas Hausladen
(Andreas dott Hausladen att gmx dott de)
Portions created by Andreas Hausladen are Copyright (C) 2003 Andreas Hausladen.
All Rights Reserved.
Contributor(s): -
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
located at http://jvcl.sourceforge.net
Known Issues:
-----------------------------------------------------------------------------}
// $Id: JVCLConfiguration.pas 10610 2006-05-19 13:35:08Z elahn $
unit JVCLConfiguration;
{$I jvcl.inc}
interface
uses
SysUtils, Classes, Contnrs, dpp_PascalParser,
{$IFDEF COMPILER6_UP}
StrUtils,
{$ELSE}
JvVCL5Utils,
{$ENDIF COMPILER6_UP}
Utils;
type
TJVCLConfig = class;
TJVCLConfigItem = class;
TJVCLConfigItem = class(TObject)
private
FOwner: TJVCLConfig;
FComment: string;
FDirective: string;
FLine: Integer;
FHidden: Boolean;
function GetEnabled: Boolean;
function GetName: string;
procedure SetEnabled(const Value: Boolean);
public
constructor Create(AOwner: TJVCLConfig; const AComment, ADirective: string;
ALine: Integer; AHidden: Boolean);
property Line: Integer read FLine;
property Enabled: Boolean read GetEnabled write SetEnabled;
property Name: string read GetName;
property Comment: string read FComment;
property Hidden: Boolean read FHidden;
end;
// Do not edit the lines directly. If you must then call Parse after you have
// done your changes.
TJVCLConfig = class(TStringList)
private
FModified: Boolean;
FItems: TObjectList;
FFilename: string;
FNextHidden: Boolean;
procedure ParseComment(Token: PTokenInfo; var LastCommentToken: string;
var InAutoConfig: Integer);
function GetItemCount: Integer;
function GetItems(Index: Integer): TJVCLConfigItem;
function GetEnabled(Index: string): Boolean;
procedure SetEnabled(Index: string; const Value: Boolean);
public
constructor Create;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
procedure Parse;
procedure LoadFromFile(const AFilename: string); override;
procedure LoadFromStream(Stream: TStream); override;
procedure SaveToFile(const FileName: String); override;
property ItemCount: Integer read GetItemCount;
property Items[Index: Integer]: TJVCLConfigItem read GetItems;
property Enabled[Index: string]: Boolean read GetEnabled write SetEnabled;
property Modified: Boolean read FModified write FModified;
property Filename: string read FFilename write FFilename;
end;
implementation
function RemoveCommentBrackets(const Comment: string): string;
var
Len: Integer;
begin
Result := Comment;
if Result = '' then
Exit;
// remove comment brackets
if Result[1] = '{' then
Len := 1
else
Len := 2;
Delete(Result, 1, Len);
Delete(Result, Length(Result) - Len + 1, Len);
end;
function IsDirective(S: string; const Directive: string): Boolean;
begin
Result := False;
S := Trim(S);
if AnsiStartsText(Directive, S) then
begin
Result := (Length(S) >= Length(Directive)) or
(S[Length(Directive) + 1] in [#1..#32, '}', '*']);
end;
// if StrLIComp(PChar(S), PChar(Directive), Length(Directive)) = 0 then
// Result := S[Length(Directive) + 1] in [#0..#32, '}', '*'];}
end;
//=== TJVCLConfigItem ========================================================
constructor TJVCLConfigItem.Create(AOwner: TJVCLConfig;
const AComment, ADirective: string; ALine: Integer; AHidden: Boolean);
begin
inherited Create;
FOwner := AOwner;
FLine := ALine;
FComment := AComment;
FHidden := AHidden;
FDirective := ADirective;
end;
function TJVCLConfigItem.GetEnabled: Boolean;
begin
Result := FDirective[1] = '$';
end;
function TJVCLConfigItem.GetName: string;
var
F, P: PChar;
begin
P := PChar(FDirective);
while (P[0] <> #0) and (P[0] > #32) do
Inc(P);
while (P[0] <> #0) and (P[0] <= #32) do
Inc(P);
F := P;
while (P[0] <> #0) and (P[0] > #32) do
Inc(P);
SetString(Result, F, P - F);
end;
procedure TJVCLConfigItem.SetEnabled(const Value: Boolean);
begin
if Value <> GetEnabled then
begin
if Value then
Delete(FDirective, 1, Pos('$', FDirective) - 1)
else
Insert('.', FDirective, 1);
FOwner[FLine] := '{' + FDirective + '}';
FOwner.Modified := True;
end;
end;
//=== TJVCLConfig ============================================================
constructor TJVCLConfig.Create;
begin
inherited Create;
FItems := TObjectList.Create;
end;
destructor TJVCLConfig.Destroy;
begin
FItems.Free;
inherited Destroy;
end;
function TJVCLConfig.GetEnabled(Index: string): Boolean;
var
I: Integer;
begin
for I := 0 to ItemCount - 1 do
if CompareText(Index, Items[I].Name) = 0 then
begin
Result := Items[I].Enabled;
Exit;
end;
Result := False;
end;
procedure TJVCLConfig.SetEnabled(Index: string; const Value: Boolean);
var
I: Integer;
begin
for I := 0 to ItemCount - 1 do
if CompareText(Index, Items[I].Name) = 0 then
begin
Items[I].Enabled := Value;
Exit;
end;
Add('');
Add('{%missing%}');
Add('{ JVCL DEVELOPER INFO: This option is missing, please update the jvclbase.inc file. }');
if Value then
Add('{$DEFINE ' + Index + '}')
else
Add('{.$DEFINE ' + Index + '}');
Parse;
Modified := True;
end;
function TJVCLConfig.GetItemCount: Integer;
begin
Result := FItems.Count;
end;
function TJVCLConfig.GetItems(Index: Integer): TJVCLConfigItem;
begin
Result := TJVCLConfigItem(FItems[Index]);
end;
procedure TJVCLConfig.LoadFromStream(Stream: TStream);
begin
FFilename := '';
inherited LoadFromStream(Stream);
Parse;
end;
procedure TJVCLConfig.Parse;
var
Parser: TPascalParser;
LastCommentToken: string;
InAutoConfig: Integer;
Token: PTokenInfo;
begin
FItems.Clear;
Parser := TPascalParser.Create('', Text);
try
LastCommentToken := '';
InAutoConfig := 0;
FNextHidden := False;
while Parser.GetToken(Token) do
begin
if Token.Kind = tkComment then
ParseComment(Token, LastCommentToken, InAutoConfig);
end;
finally
Parser.Free;
end;
FModified := False;
end;
procedure TJVCLConfig.ParseComment(Token: PTokenInfo;
var LastCommentToken: string; var InAutoConfig: Integer);
var
S: String;
Item: TJVCLConfigItem;
begin
S := Trim(RemoveCommentBrackets(Token.Value));
if IsDirective(S, '%hidden%') or IsDirective(S, '%missing%') then
FNextHidden := True;
if IsDirective(S, '$IFDEF') or IsDirective(S, '$IF') or // do not localize
IsDirective(S, '$IFNDEF') then // do not localize
Inc(InAutoConfig)
else
if IsDirective(S, '$ENDIF') or IsDirective(S, '$IFEND') then // do not localize
Dec(InAutoConfig);
if InAutoConfig = 0 then
begin
if IsDirective(S, '$DEFINE') or IsDirective(S, '.$DEFINE') then // do not localize
begin
Item := TJVCLConfigItem.Create(Self, LastCommentToken, S, Token.StartLine - 1, FNextHidden);
FItems.Add(Item);
FNextHidden := False;
end
else
LastCommentToken := S;
end;
end;
procedure TJVCLConfig.LoadFromFile(const AFilename: string);
begin
inherited LoadFromFile(AFilename);
FFilename := AFilename;
end;
procedure TJVCLConfig.Assign(Source: TPersistent);
begin
inherited Assign(Source);
Parse;
end;
procedure TJVCLConfig.SaveToFile(const FileName: String);
var
Lines: TStrings;
begin
Lines := TStringList.Create;
try
if FileExists(FileName) then
Lines.LoadFromFile(FileName);
if Lines.Text = Text then // no changes
Exit;
finally
Lines.Free;
end;
FileSetReadOnly(Filename, False);
inherited SaveToFile(FileName);
end;
end.