326 lines
8.5 KiB
ObjectPascal
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.
|