Стартовый пул
This commit is contained in:
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
@@ -0,0 +1,772 @@
|
||||
{*******************************************************}
|
||||
{ }
|
||||
{ Delphi VCL Extensions (RX) }
|
||||
{ }
|
||||
{ Copyright (c) 1996 AO ROSNO }
|
||||
{ Copyright (c) 1997, 1998 Master-Bank }
|
||||
{ }
|
||||
{*******************************************************}
|
||||
|
||||
{$mode objfpc}
|
||||
{$H+}
|
||||
|
||||
unit StrHolder;
|
||||
|
||||
interface
|
||||
|
||||
uses SysUtils, Classes, LResources;
|
||||
|
||||
type
|
||||
|
||||
{$ifdef usevariant}
|
||||
TMacroData = Variant;
|
||||
{$else}
|
||||
TMacroData = AnsiString;
|
||||
{$endif}
|
||||
|
||||
{ TMacro }
|
||||
|
||||
TMacros = class;
|
||||
TMacroTextEvent = procedure(Sender: TObject; Data: TMacroData;
|
||||
var Text: string) of object;
|
||||
|
||||
TMacro = class(TCollectionItem)
|
||||
private
|
||||
FName: string;
|
||||
FData: TMacroData;
|
||||
FOnGetText: TMacroTextEvent;
|
||||
function IsMacroStored: Boolean;
|
||||
function GetText: string;
|
||||
function GetMacros: TMacros;
|
||||
protected
|
||||
function GetDisplayName: string; override;
|
||||
procedure SetDisplayName(const Value: string); override;
|
||||
procedure GetMacroText(var AText: string);
|
||||
function GetAsTMacroData: TMacroData;
|
||||
procedure SetAsTMacroData(Value: TMacroData);
|
||||
public
|
||||
constructor Create(ACollection: TCollection); override;
|
||||
procedure Assign(Source: TPersistent); override;
|
||||
procedure Clear;
|
||||
function IsEqual(Value: TMacro): Boolean;
|
||||
property Macros: TMacros read GetMacros;
|
||||
property Text: string read GetText;
|
||||
published
|
||||
property Name: string read FName write SetDisplayName;
|
||||
property Value: TMacroData read GetAsTMacroData write SetAsTMacroData stored IsMacroStored;
|
||||
property OnGetText: TMacroTextEvent read FOnGetText write FOnGetText;
|
||||
end;
|
||||
|
||||
{ TMacros }
|
||||
|
||||
TMacros = class(TOwnedCollection)
|
||||
private
|
||||
function GetMacroValue(const MacroName: string): TMacroData;
|
||||
procedure SetMacroValue(const MacroName: string;
|
||||
const Value: TMacroData);
|
||||
function GetItem(Index: Integer): TMacro;
|
||||
procedure SetItem(Index: Integer; Value: TMacro);
|
||||
public
|
||||
constructor Create(AOwner: TPersistent);
|
||||
procedure AssignValues(Value: TMacros);
|
||||
procedure AddMacro(Value: TMacro);
|
||||
procedure RemoveMacro(Value: TMacro);
|
||||
function CreateMacro(const MacroName: string): TMacro;
|
||||
procedure GetMacroList(List: TList; const MacroNames: string);
|
||||
function IndexOf(const AName: string): Integer;
|
||||
function IsEqual(Value: TMacros): Boolean;
|
||||
function ParseString(const Value: string; DoCreate: Boolean;
|
||||
SpecialChar: Char): string;
|
||||
function MacroByName(const Value: string): TMacro;
|
||||
function FindMacro(const Value: string): TMacro;
|
||||
property Items[Index: Integer]: TMacro read GetItem write SetItem; default;
|
||||
property MacroValues[const MacroName: string]: TMacroData read GetMacroValue write SetMacroValue;
|
||||
end;
|
||||
|
||||
|
||||
{ TStrHolder }
|
||||
|
||||
TStrHolder = class(TComponent)
|
||||
private
|
||||
FStrings: TStrings;
|
||||
FXorKey: string;
|
||||
FMacros: TMacros;
|
||||
FMacroChar: Char;
|
||||
FOnExpandMacros: TNotifyEvent;
|
||||
FOnChange: TNotifyEvent;
|
||||
FOnChanging: TNotifyEvent;
|
||||
function GetDuplicates: TDuplicates;
|
||||
procedure SetDuplicates(Value: TDuplicates);
|
||||
function GetSorted: Boolean;
|
||||
procedure SetSorted(Value: Boolean);
|
||||
procedure SetStrings(Value: TStrings);
|
||||
procedure StringsChanged(Sender: TObject);
|
||||
procedure StringsChanging(Sender: TObject);
|
||||
procedure ReadStrings(Reader: TReader);
|
||||
procedure WriteStrings(Writer: TWriter);
|
||||
function GetCommaText: string;
|
||||
procedure SetCommaText(const Value: string);
|
||||
function GetCapacity: Integer;
|
||||
procedure SetCapacity(NewCapacity: Integer);
|
||||
procedure SetMacros(Value: TMacros);
|
||||
procedure RecreateMacros;
|
||||
procedure SetMacroChar(Value: Char);
|
||||
protected
|
||||
procedure AssignTo(Dest: TPersistent); override;
|
||||
procedure DefineProperties(Filer: TFiler); override;
|
||||
procedure Changed; dynamic;
|
||||
procedure Changing; dynamic;
|
||||
procedure BeforeExpandMacros; dynamic;
|
||||
public
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
procedure Assign(Source: TPersistent); override;
|
||||
procedure Clear;
|
||||
function MacroCount: Integer;
|
||||
function MacroByName(const MacroName: string): TMacro;
|
||||
function ExpandMacros: string;
|
||||
property CommaText: string read GetCommaText write SetCommaText;
|
||||
published
|
||||
property Capacity: Integer read GetCapacity write SetCapacity default 0;
|
||||
property MacroChar: Char read FMacroChar write SetMacroChar default '%';
|
||||
property Macros: TMacros read FMacros write SetMacros;
|
||||
property OnExpandMacros: TNotifyEvent read FOnExpandMacros write FOnExpandMacros;
|
||||
property Duplicates: TDuplicates read GetDuplicates write SetDuplicates
|
||||
default dupIgnore;
|
||||
property KeyString: string read FXorKey write FXorKey stored False;
|
||||
property Sorted: Boolean read GetSorted write SetSorted default False;
|
||||
property Strings: TStrings read FStrings write SetStrings stored False;
|
||||
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
||||
property OnChanging: TNotifyEvent read FOnChanging write FOnChanging;
|
||||
end;
|
||||
|
||||
Procedure Register;
|
||||
|
||||
implementation
|
||||
|
||||
{$R strholder.res}
|
||||
|
||||
uses
|
||||
RTLConsts;
|
||||
|
||||
Procedure Register;
|
||||
begin
|
||||
RegisterComponents('RX Tools',[TStrHolder])
|
||||
end;
|
||||
|
||||
function XorEncode(const Key, Source: string): string;
|
||||
var
|
||||
I: Integer;
|
||||
C: Byte;
|
||||
begin
|
||||
Result := '';
|
||||
for I := 1 to Length(Source) do begin
|
||||
if Length(Key) > 0 then
|
||||
C := Byte(Key[1 + ((I - 1) mod Length(Key))]) xor Byte(Source[I])
|
||||
else
|
||||
C := Byte(Source[I]);
|
||||
Result := Result + AnsiLowerCase(IntToHex(C, 2));
|
||||
end;
|
||||
end;
|
||||
|
||||
function XorDecode(const Key, Source: string): string;
|
||||
var
|
||||
I: Integer;
|
||||
C: Char;
|
||||
|
||||
begin
|
||||
Result := '';
|
||||
for I := 0 to Length(Source) div 2 - 1 do begin
|
||||
C := Chr(StrToIntDef('$' + Copy(Source, (I * 2) + 1, 2), Ord(' ')));
|
||||
if Length(Key) > 0 then
|
||||
C := Chr(Byte(Key[1 + (I mod Length(Key))]) xor Byte(C));
|
||||
Result := Result + C;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function ExtractName(const Items: string; var Pos: Integer): string;
|
||||
var
|
||||
I: Integer;
|
||||
begin
|
||||
I := Pos;
|
||||
while (I <= Length(Items)) and (Items[I] <> ';') do Inc(I);
|
||||
Result := Trim(Copy(Items, Pos, I - Pos));
|
||||
if (I <= Length(Items)) and (Items[I] = ';') then Inc(I);
|
||||
Pos := I;
|
||||
end;
|
||||
|
||||
Type
|
||||
TCharSet = Set of char;
|
||||
|
||||
function NameDelimiter(C: Char; Delims: TCharSet): Boolean;
|
||||
begin
|
||||
Result := (C in [' ', ',', ';', ')', #13, #10]) or (C in Delims);
|
||||
end;
|
||||
|
||||
function IsLiteral(C: Char): Boolean;
|
||||
begin
|
||||
Result := C in ['''', '"'];
|
||||
end;
|
||||
|
||||
procedure CreateMacros(List: TMacros; const Value: PChar; SpecialChar: Char; Delims: TCharSet);
|
||||
var
|
||||
CurPos, StartPos: PChar;
|
||||
CurChar: Char;
|
||||
Literal: Boolean;
|
||||
EmbeddedLiteral: Boolean;
|
||||
Name: string;
|
||||
|
||||
function StripLiterals(Buffer: PChar): string;
|
||||
var
|
||||
Len: Word;
|
||||
TempBuf: PChar;
|
||||
|
||||
procedure StripChar(Value: Char);
|
||||
begin
|
||||
if TempBuf^ = Value then
|
||||
StrMove(TempBuf, TempBuf + 1, Len - 1);
|
||||
if TempBuf[StrLen(TempBuf) - 1] = Value then
|
||||
TempBuf[StrLen(TempBuf) - 1] := #0;
|
||||
end;
|
||||
|
||||
begin
|
||||
Len := StrLen(Buffer) + 1;
|
||||
TempBuf := AllocMem(Len);
|
||||
Result := '';
|
||||
try
|
||||
StrCopy(TempBuf, Buffer);
|
||||
StripChar('''');
|
||||
StripChar('"');
|
||||
Result := StrPas(TempBuf);
|
||||
finally
|
||||
FreeMem(TempBuf, Len);
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
if SpecialChar = #0 then Exit;
|
||||
CurPos := Value;
|
||||
Literal := False;
|
||||
EmbeddedLiteral := False;
|
||||
repeat
|
||||
CurChar := CurPos^;
|
||||
if (CurChar = SpecialChar) and not Literal and ((CurPos + 1)^ <> SpecialChar) then
|
||||
begin
|
||||
StartPos := CurPos;
|
||||
while (CurChar <> #0) and (Literal or not NameDelimiter(CurChar, Delims)) do begin
|
||||
Inc(CurPos);
|
||||
CurChar := CurPos^;
|
||||
if IsLiteral(CurChar) then begin
|
||||
Literal := Literal xor True;
|
||||
if CurPos = StartPos + 1 then EmbeddedLiteral := True;
|
||||
end;
|
||||
end;
|
||||
CurPos^ := #0;
|
||||
if EmbeddedLiteral then begin
|
||||
Name := StripLiterals(StartPos + 1);
|
||||
EmbeddedLiteral := False;
|
||||
end
|
||||
else Name := StrPas(StartPos + 1);
|
||||
if Assigned(List) then begin
|
||||
if List.FindMacro(Name) = nil then
|
||||
List.CreateMacro(Name);
|
||||
end;
|
||||
CurPos^ := CurChar;
|
||||
StartPos^ := '?';
|
||||
Inc(StartPos);
|
||||
StrMove(StartPos, CurPos, StrLen(CurPos) + 1);
|
||||
CurPos := StartPos;
|
||||
end
|
||||
else if (CurChar = SpecialChar) and not Literal and ((CurPos + 1)^ = SpecialChar) then
|
||||
StrMove(CurPos, CurPos + 1, StrLen(CurPos) + 1)
|
||||
else if IsLiteral(CurChar) then Literal := Literal xor True;
|
||||
Inc(CurPos);
|
||||
until CurChar = #0;
|
||||
end;
|
||||
|
||||
{ TMacro }
|
||||
|
||||
constructor TMacro.Create(ACollection: TCollection);
|
||||
begin
|
||||
inherited Create(ACollection);
|
||||
{$ifdef usevariant}
|
||||
FData := Unassigned;
|
||||
{$else}
|
||||
FData:='';
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
procedure TMacro.Assign(Source: TPersistent);
|
||||
begin
|
||||
if (Source is TMacro) and (Source <> nil) then
|
||||
begin
|
||||
{$ifdef usevariant}
|
||||
if VarIsEmpty(TMacro(Source).FData) then
|
||||
Clear
|
||||
else
|
||||
{$endif}
|
||||
Value := TMacro(Source).FData;
|
||||
Name := TMacro(Source).Name;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TMacro.GetDisplayName: string;
|
||||
begin
|
||||
if FName = '' then
|
||||
Result := inherited GetDisplayName
|
||||
else
|
||||
Result := FName;
|
||||
end;
|
||||
|
||||
procedure TMacro.SetDisplayName(const Value: string);
|
||||
begin
|
||||
if (Value <> '') and (AnsiCompareText(Value, FName) <> 0) and
|
||||
(Collection is TMacros) and (TMacros(Collection).IndexOf(Value) >= 0) then
|
||||
raise Exception.Create(SDuplicateString);
|
||||
FName := Value;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
procedure TMacro.GetMacroText(var AText: string);
|
||||
begin
|
||||
if Assigned(FOnGetText) then FOnGetText(Self, FData, AText);
|
||||
end;
|
||||
|
||||
function TMacro.GetText: string;
|
||||
begin
|
||||
Result := FData;
|
||||
GetMacroText(Result);
|
||||
end;
|
||||
|
||||
function TMacro.GetMacros: TMacros;
|
||||
begin
|
||||
if Collection is TMacros then
|
||||
Result := TMacros(Collection)
|
||||
else
|
||||
Result := nil;
|
||||
end;
|
||||
|
||||
procedure TMacro.Clear;
|
||||
begin
|
||||
{$ifdef usevariant}
|
||||
FData := Unassigned;
|
||||
{$else}
|
||||
FData := '';
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
function TMacro.IsMacroStored: Boolean;
|
||||
begin
|
||||
{$ifdef usevariant}
|
||||
Result := not VarIsEmpty(FData);
|
||||
{$else}
|
||||
Result := (FData<>'');
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
function TMacro.GetAsTMacroData: TMacroData;
|
||||
begin
|
||||
Result := FData;
|
||||
end;
|
||||
|
||||
procedure TMacro.SetAsTMacroData(Value: TMacroData);
|
||||
begin
|
||||
FData := Value;
|
||||
end;
|
||||
|
||||
function TMacro.IsEqual(Value: TMacro): Boolean;
|
||||
begin
|
||||
{$ifdef usevariant}
|
||||
Result := (VarType(FData) = VarType(Value.FData)) and
|
||||
(VarIsEmpty(FData) or (FData = Value.FData)) and
|
||||
(Name = Value.Name);
|
||||
{$else}
|
||||
Result := (FData=Value.FData) and
|
||||
(Name = Value.Name);
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
{ TMacros }
|
||||
|
||||
constructor TMacros.Create(AOwner: TPersistent);
|
||||
begin
|
||||
inherited Create(AOwner, TMacro);
|
||||
end;
|
||||
|
||||
function TMacros.IndexOf(const AName: string): Integer;
|
||||
begin
|
||||
for Result := 0 to Count - 1 do
|
||||
if AnsiCompareText(TMacro(Items[Result]).Name, AName) = 0 then Exit;
|
||||
Result := -1;
|
||||
end;
|
||||
|
||||
function TMacros.GetItem(Index: Integer): TMacro;
|
||||
begin
|
||||
Result := TMacro(inherited Items[Index]);
|
||||
end;
|
||||
|
||||
procedure TMacros.SetItem(Index: Integer; Value: TMacro);
|
||||
begin
|
||||
inherited SetItem(Index, TCollectionItem(Value));
|
||||
end;
|
||||
|
||||
procedure TMacros.AddMacro(Value: TMacro);
|
||||
begin
|
||||
Value.Collection := Self;
|
||||
end;
|
||||
|
||||
procedure TMacros.RemoveMacro(Value: TMacro);
|
||||
begin
|
||||
if Value.Collection = Self then
|
||||
Value.Collection := nil;
|
||||
end;
|
||||
|
||||
function TMacros.CreateMacro(const MacroName: string): TMacro;
|
||||
begin
|
||||
Result := Add as TMacro;
|
||||
Result.Name := MacroName;
|
||||
end;
|
||||
|
||||
function TMacros.IsEqual(Value: TMacros): Boolean;
|
||||
var
|
||||
I: Integer;
|
||||
begin
|
||||
Result := Count = Value.Count;
|
||||
if Result then
|
||||
for I := 0 to Count - 1 do begin
|
||||
Result := Items[I].IsEqual(Value.Items[I]);
|
||||
if not Result then Break;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TMacros.MacroByName(const Value: string): TMacro;
|
||||
begin
|
||||
Result := FindMacro(Value);
|
||||
if Result = nil then
|
||||
raise Exception.Create(SInvalidPropertyValue);
|
||||
end;
|
||||
|
||||
function TMacros.FindMacro(const Value: string): TMacro;
|
||||
var
|
||||
I: Integer;
|
||||
begin
|
||||
for I := 0 to Count - 1 do begin
|
||||
Result := TMacro(inherited Items[I]);
|
||||
if AnsiCompareText(Result.Name, Value) = 0 then Exit;
|
||||
end;
|
||||
Result := nil;
|
||||
end;
|
||||
|
||||
procedure TMacros.AssignValues(Value: TMacros);
|
||||
var
|
||||
I: Integer;
|
||||
P: TMacro;
|
||||
begin
|
||||
BeginUpdate;
|
||||
try
|
||||
for I := 0 to Value.Count - 1 do begin
|
||||
P := FindMacro(Value[I].Name);
|
||||
if P <> nil then P.Assign(Value[I]);
|
||||
end;
|
||||
finally
|
||||
EndUpdate;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TMacros.ParseString(const Value: string; DoCreate: Boolean;
|
||||
SpecialChar: Char): string;
|
||||
var
|
||||
Macros: TMacros;
|
||||
begin
|
||||
Result := Value;
|
||||
Macros := TMacros.Create(Self.GetOwner);
|
||||
try
|
||||
CreateMacros(Macros, PChar(Result), SpecialChar, ['.']);
|
||||
if DoCreate then begin
|
||||
Macros.AssignValues(Self);
|
||||
Self.Assign(Macros);
|
||||
end;
|
||||
finally
|
||||
Macros.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TMacros.GetMacroValue(const MacroName: string): TMacroData;
|
||||
{$ifdef usevariant}
|
||||
var
|
||||
I: Integer;
|
||||
Macros: TList;
|
||||
{$ENDIF}
|
||||
begin
|
||||
{$ifdef usevariant}
|
||||
if Pos(';', MacroName) <> 0 then
|
||||
begin
|
||||
Macros := TList.Create;
|
||||
try
|
||||
GetMacroList(Macros, MacroName);
|
||||
Result := VarArrayCreate([0, Macros.Count - 1], varVariant);
|
||||
for I := 0 to Macros.Count - 1 do
|
||||
Result[I] := TMacro(Macros[I]).Value;
|
||||
finally
|
||||
Macros.Free;
|
||||
end;
|
||||
end
|
||||
else
|
||||
{$else}
|
||||
Result := MacroByName(MacroName).Value;
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
procedure TMacros.SetMacroValue(const MacroName: string;
|
||||
const Value: TMacroData);
|
||||
var
|
||||
I: Integer;
|
||||
Macros: TList;
|
||||
begin
|
||||
if Pos(';', MacroName) <> 0 then begin
|
||||
Macros := TList.Create;
|
||||
try
|
||||
GetMacroList(Macros, MacroName);
|
||||
for I := 0 to Macros.Count - 1 do
|
||||
TMacro(Macros[I]).Value := Value[I];
|
||||
finally
|
||||
Macros.Free;
|
||||
end;
|
||||
end
|
||||
else MacroByName(MacroName).Value := Value;
|
||||
end;
|
||||
|
||||
procedure TMacros.GetMacroList(List: TList; const MacroNames: string);
|
||||
var
|
||||
Pos: Integer;
|
||||
begin
|
||||
Pos := 1;
|
||||
while Pos <= Length(MacroNames) do
|
||||
List.Add(MacroByName(ExtractName(MacroNames, Pos)));
|
||||
end;
|
||||
|
||||
{ TStrHolder }
|
||||
|
||||
constructor TStrHolder.Create(AOwner: TComponent);
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
FStrings := TStringList.Create;
|
||||
FMacros := TMacros.Create(Self);
|
||||
FMacroChar := '%';
|
||||
TStringList(FStrings).OnChange := @StringsChanged;
|
||||
TStringList(FStrings).OnChanging := @StringsChanging;
|
||||
end;
|
||||
|
||||
destructor TStrHolder.Destroy;
|
||||
begin
|
||||
FOnChange := nil;
|
||||
FOnChanging := nil;
|
||||
FMacros.Free;
|
||||
FStrings.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TStrHolder.Assign(Source: TPersistent);
|
||||
begin
|
||||
if Source is TStrings then
|
||||
FStrings.Assign(Source)
|
||||
else if Source is TStrHolder then
|
||||
FStrings.Assign(TStrHolder(Source).Strings)
|
||||
else
|
||||
inherited Assign(Source);
|
||||
end;
|
||||
|
||||
procedure TStrHolder.AssignTo(Dest: TPersistent);
|
||||
begin
|
||||
if Dest is TStrings then
|
||||
Dest.Assign(Strings)
|
||||
else
|
||||
inherited AssignTo(Dest);
|
||||
end;
|
||||
|
||||
procedure TStrHolder.Changed;
|
||||
begin
|
||||
if Assigned(FOnChange) then FOnChange(Self);
|
||||
end;
|
||||
|
||||
procedure TStrHolder.Changing;
|
||||
begin
|
||||
if Assigned(FOnChanging) then FOnChanging(Self);
|
||||
end;
|
||||
|
||||
procedure TStrHolder.Clear;
|
||||
begin
|
||||
FStrings.Clear;
|
||||
end;
|
||||
|
||||
function TStrHolder.GetCommaText: string;
|
||||
begin
|
||||
Result := FStrings.CommaText;
|
||||
end;
|
||||
|
||||
procedure TStrHolder.SetCommaText(const Value: string);
|
||||
begin
|
||||
FStrings.CommaText := Value;
|
||||
end;
|
||||
|
||||
function TStrHolder.GetCapacity: Integer;
|
||||
begin
|
||||
Result := FStrings.Capacity;
|
||||
end;
|
||||
|
||||
procedure TStrHolder.SetCapacity(NewCapacity: Integer);
|
||||
begin
|
||||
FStrings.Capacity := NewCapacity;
|
||||
end;
|
||||
|
||||
procedure TStrHolder.BeforeExpandMacros;
|
||||
begin
|
||||
if Assigned(FOnExpandMacros) then FOnExpandMacros(Self);
|
||||
end;
|
||||
|
||||
procedure TStrHolder.SetMacros(Value: TMacros);
|
||||
begin
|
||||
FMacros.AssignValues(Value);
|
||||
end;
|
||||
|
||||
procedure TStrHolder.RecreateMacros;
|
||||
begin
|
||||
if not (csReading in ComponentState) then
|
||||
Macros.ParseString(FStrings.Text, True, MacroChar);
|
||||
end;
|
||||
|
||||
procedure TStrHolder.SetMacroChar(Value: Char);
|
||||
begin
|
||||
if Value <> FMacroChar then begin
|
||||
FMacroChar := Value;
|
||||
RecreateMacros;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TStrHolder.MacroCount: Integer;
|
||||
begin
|
||||
Result := Macros.Count;
|
||||
end;
|
||||
|
||||
function TStrHolder.MacroByName(const MacroName: string): TMacro;
|
||||
begin
|
||||
Result := Macros.MacroByName(MacroName);
|
||||
end;
|
||||
|
||||
function TStrHolder.ExpandMacros: string;
|
||||
var
|
||||
I, J, P, LiteralChars: Integer;
|
||||
Macro: TMacro;
|
||||
Found: Boolean;
|
||||
begin
|
||||
BeforeExpandMacros;
|
||||
Result := FStrings.Text;
|
||||
for I := Macros.Count - 1 downto 0 do
|
||||
begin
|
||||
Macro := Macros[I];
|
||||
{$ifdef usevariant}
|
||||
if VarIsEmpty(Macro.FData) then
|
||||
Continue;
|
||||
{$endif}
|
||||
repeat
|
||||
P := Pos(MacroChar + Macro.Name, Result);
|
||||
Found := (P > 0) and ((Length(Result) = P + Length(Macro.Name)) or
|
||||
NameDelimiter(Result[P + Length(Macro.Name) + 1], ['.']));
|
||||
if Found then begin
|
||||
LiteralChars := 0;
|
||||
for J := 1 to P - 1 do
|
||||
if IsLiteral(Result[J]) then Inc(LiteralChars);
|
||||
Found := LiteralChars mod 2 = 0;
|
||||
if Found then begin
|
||||
Result := Copy(Result, 1, P - 1) + Macro.Text + Copy(Result,
|
||||
P + Length(Macro.Name) + 1, MaxInt);
|
||||
end;
|
||||
end;
|
||||
until not Found;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TStrHolder.DefineProperties(Filer: TFiler);
|
||||
|
||||
function DoWrite: Boolean;
|
||||
var
|
||||
I: Integer;
|
||||
Ancestor: TStrHolder;
|
||||
begin
|
||||
Ancestor := TStrHolder(Filer.Ancestor);
|
||||
Result := False;
|
||||
if (Ancestor <> nil) and (Ancestor.FStrings.Count = FStrings.Count) and
|
||||
(KeyString = Ancestor.KeyString) and (FStrings.Count > 0) then
|
||||
for I := 0 to FStrings.Count - 1 do begin
|
||||
Result := CompareText(FStrings[I], Ancestor.FStrings[I]) <> 0;
|
||||
if Result then Break;
|
||||
end
|
||||
else Result := (FStrings.Count > 0) or (Length(KeyString) > 0);
|
||||
end;
|
||||
|
||||
begin
|
||||
inherited DefineProperties(Filer);
|
||||
Filer.DefineProperty('StrData', @ReadStrings, @WriteStrings, DoWrite);
|
||||
end;
|
||||
|
||||
function TStrHolder.GetSorted: Boolean;
|
||||
begin
|
||||
Result := TStringList(FStrings).Sorted;
|
||||
end;
|
||||
|
||||
function TStrHolder.GetDuplicates: TDuplicates;
|
||||
begin
|
||||
Result := TStringList(FStrings).Duplicates;
|
||||
end;
|
||||
|
||||
procedure TStrHolder.ReadStrings(Reader: TReader);
|
||||
begin
|
||||
Reader.ReadListBegin;
|
||||
if not Reader.EndOfList then KeyString := Reader.ReadString;
|
||||
FStrings.Clear;
|
||||
while not Reader.EndOfList do
|
||||
FStrings.Add(XorDecode(KeyString, Reader.ReadString));
|
||||
Reader.ReadListEnd;
|
||||
end;
|
||||
|
||||
procedure TStrHolder.SetDuplicates(Value: TDuplicates);
|
||||
begin
|
||||
TStringList(FStrings).Duplicates := Value;
|
||||
end;
|
||||
|
||||
procedure TStrHolder.SetSorted(Value: Boolean);
|
||||
begin
|
||||
TStringList(FStrings).Sorted := Value;
|
||||
end;
|
||||
|
||||
procedure TStrHolder.SetStrings(Value: TStrings);
|
||||
begin
|
||||
FStrings.Assign(Value);
|
||||
end;
|
||||
|
||||
procedure TStrHolder.StringsChanged(Sender: TObject);
|
||||
begin
|
||||
if Sender=nil then ;
|
||||
RecreateMacros;
|
||||
if not (csReading in ComponentState) then Changed;
|
||||
end;
|
||||
|
||||
procedure TStrHolder.StringsChanging(Sender: TObject);
|
||||
begin
|
||||
if Sender=nil then ;
|
||||
if not (csReading in ComponentState) then Changing;
|
||||
end;
|
||||
|
||||
procedure TStrHolder.WriteStrings(Writer: TWriter);
|
||||
var
|
||||
I: Integer;
|
||||
begin
|
||||
Writer.WriteListBegin;
|
||||
Writer.WriteString(KeyString);
|
||||
for I := 0 to FStrings.Count - 1 do
|
||||
Writer.WriteString(XorEncode(KeyString, FStrings[I]));
|
||||
Writer.WriteListEnd;
|
||||
end;
|
||||
|
||||
end.
|
@@ -0,0 +1,71 @@
|
||||
/* XPM */
|
||||
static char *DICE6[]={
|
||||
"64 64 4 1",
|
||||
". c None",
|
||||
"# c #000000",
|
||||
"b c #c0c0c0",
|
||||
"a c #ffffff",
|
||||
"................................................................",
|
||||
".............................######.............................",
|
||||
"...........................##########...........................",
|
||||
".........................####aaaaaa####.........................",
|
||||
".......................####aaaaaaaaaa####.......................",
|
||||
".....................####aaaaa####aaaaa####.....................",
|
||||
"...................####aaaaa########aaaaa####...................",
|
||||
".................####aaaaaa##########aaaaaa####.................",
|
||||
"...............####aaaaaaaa##########aaaaaaaa####...............",
|
||||
".............####aaaaaaaaaaa########aa####aaaaa####.............",
|
||||
"...........####aaaaaaaaaaaaaaa####aa########aaaaa####...........",
|
||||
".........####aaaaaaaaaaaaaaaaaaaaaa##########aaaaaa####.........",
|
||||
".......####aaaaaaaaaaaaaaaaaaaaaaaa##########aaaaaaaa####.......",
|
||||
".....####aaaaa####aaaaaaaaaaaaaaaaaa########aa####aaaaa####.....",
|
||||
"...####aaaaa########aaaaaaaaaaaaaaaaaa####aa########aaaaa####...",
|
||||
".####aaaaaa##########aaaaaaaaaaaaaaaaaaaaaa##########aaaaaa####.",
|
||||
"#####aaaaaa##########aaaaaaaaaaaaaaaaaaaaaa##########aaaaaa#####",
|
||||
"##b####aaaaa########aa####aaaaaaaaaaaaaaaaaa########aaaaa####a##",
|
||||
"##bbb####aaaaa####aa########aaaaaaaaaaaaaaaaaa####aaaaa####aaa##",
|
||||
"##bbbbb####aaaaaaaa##########aaaaaaaaaaaaaaaaaaaaaaaa####aaaaa##",
|
||||
"##bbbbbbb####aaaaaa##########aaaaaaaaaaaaaaaaaaaaaa####aaaaaaa##",
|
||||
"##bbbbbbbbb####aaaaa########aa####aaaaaaaaaaaaaaa####aaaaaaaaa##",
|
||||
"##bbbb###bbbb####aaaaa####aa########aaaaaaaaaaa####aaaa###aaaa##",
|
||||
"##bbb######bbbb####aaaaaaaa##########aaaaaaaa####aaaa######aaa##",
|
||||
"##bbb######bbbbbb####aaaaaa##########aaaaaa####aaaaaa######aaa##",
|
||||
"##bbb#######bbbbbbb####aaaaa########aaaaa####aaaaaaa#######aaa##",
|
||||
"##bbb#######bbbbbbbbb####aaaaa####aaaaa####aaaaaaaaa#######aaa##",
|
||||
"##bbb#######bbbbbbbbbbb####aaaaaaaaaa####aaaaaaaaaaa#######aaa##",
|
||||
"##bbbb######bbbbbbbbbbbbb####aaaaaa####aaaaaaaaaaaaa######aaaa##",
|
||||
"##bbbbb####bbbbbbbbbbbbbbbb####aa####aaaaaaaaaaaaaaaa####aaaaa##",
|
||||
"##bbbbbbbbbbbbbbbbbbbb###bbbb######aaaaaaaaaaaaaaaaaaaaaaaaaaa##",
|
||||
"##bbbbbbbbbbbbbbbbbbb######bbbb##aaaaaaaaaaaaaaaaaaaaaaaaaaaaa##",
|
||||
"##bbbbbbbbbbbbbbbbbbb######bbbb##aaaaaaaaaaaaaaaaaaaaaaaaaaaaa##",
|
||||
"##bbbbbbbbbbbbbbbbbbb#######bbb##aaaaaaaaaaaaaaaaaaaaaaaaaaaaa##",
|
||||
"##bbbbbbbbbbbbbbbbbbb#######bbb##aaaaaaaaaaaaaaaaaaaaaaaaaaaaa##",
|
||||
"##bbbbbbbbbbbb###bbbb#######bbb##aaaaaaaaaaaaaa###aaaaaaaaaaaa##",
|
||||
"##bbbbbbbbbbb######bbb######bbb##aaaaaaaaaaaa######aaaaaaaaaaa##",
|
||||
"##bbbbbbbbbbb######bbbb####bbbb##aaaaaaaaaaaa######aaaaaaaaaaa##",
|
||||
"##bbbbbbbbbbb#######bbbbbbbbbbb##aaaaaaaaaaa#######aaaaaaaaaaa##",
|
||||
"##bbbbbbbbbbb#######bbbbbbbbbbb##aaaaaaaaaaa#######aaaaaaaaaaa##",
|
||||
"##bbbb###bbbb#######bbbbbbbbbbb##aaaaaaaaaaa#######aaaaaaaaaaa##",
|
||||
"##bbb######bbb######bbbbbbbbbbb##aaaaaaaaaaa######aaaaaaaaaaaa##",
|
||||
"##bbb######bbbb####bbbbbbbbbbbb##aaaaaaaaaaaa####aaaaaaaaaaaaa##",
|
||||
"##bbb#######bbbbbbbbbbbbbbbbbbb##aaaaaaaaaaaaaaaaaaaaaaaaaaaaa##",
|
||||
"##bbb#######bbbbbbbbbbbbbbbbbbb##aaaaaaaaaaaaaaaaaaaaaaaaaaaaa##",
|
||||
"##bbb#######bbbbbbbbbbbbbbbbbbb##aaaaaaaaaaaaaaaaaaaaaaaaaaaaa##",
|
||||
"##bbbb######bbbbbbbbbbbbbbbbbbb##aaaaaaaaaaaaaaaaaaaaaaaaaaaaa##",
|
||||
"###bbbb####bbbbbbbbbbbbbbbbbbbb##aaaaaaaaaaaaaaaaaaaaaaaaaaaa###",
|
||||
".####bbbbbbbbbbbbbbbbb###bbbbbb##aaaaaa###aaaaaaaaaaaaaaaaa####.",
|
||||
"...####bbbbbbbbbbbbbb######bbbb##aaaa######aaaaaaaaaaaaaa####...",
|
||||
".....####bbbbbbbbbbbb######bbbb##aaaa######aaaaaaaaaaaa####.....",
|
||||
".......####bbbbbbbbbb#######bbb##aaa#######aaaaaaaaaa####.......",
|
||||
".........####bbbbbbbb#######bbb##aaa#######aaaaaaaa####.........",
|
||||
"...........####bbbbbb#######bbb##aaa#######aaaaaa####...........",
|
||||
".............####bbbbb######bbb##aaa######aaaaa####.............",
|
||||
"...............####bbbb####bbbb##aaaa####aaaa####...............",
|
||||
".................####bbbbbbbbbb##aaaaaaaaaa####.................",
|
||||
"...................####bbbbbbbb##aaaaaaaa####...................",
|
||||
".....................####bbbbbb##aaaaaa####.....................",
|
||||
".......................####bbbb##aaaa####.......................",
|
||||
".........................####bb##aa####.........................",
|
||||
"...........................##########...........................",
|
||||
"..............................####..............................",
|
||||
"................................................................"};
|
Reference in New Issue
Block a user