You've already forked lazarus-ccr
cmdlinecfg:
* minimized TCmdLineLayoutInfo class public section; * updated the TCmdLineScrollBoxControl loader to use %%other switch; using hash list to check of used/unused controls; * updated readme.txt description for UI layout controls; * updated IDE package to make the dialog look close to the existing compiler options; * updated testguibuild to be able to load a certain section only; * added smaller sample files for testguibuild, modified conf.coptui to have %%other switch, where all "non-default" compiler options would go; git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@2806 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -3,8 +3,7 @@ unit cmdlinecfgui;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils,
|
||||
cmdlinecfg;
|
||||
Classes, SysUtils, contnrs, cmdlinecfg;
|
||||
|
||||
type
|
||||
{ TCmdLineLayoutInfo }
|
||||
@ -15,6 +14,7 @@ type
|
||||
{ TLayoutSection }
|
||||
|
||||
TLayoutElementType = (letSwitch, letSection);
|
||||
TLayoutElementTypes = set of TLayoutElementType;
|
||||
|
||||
TLayoutSection = class(TObject)
|
||||
//level : integer; // number of "dots" in the name
|
||||
@ -27,22 +27,17 @@ type
|
||||
Elements : array of TLayoutSection;
|
||||
ElemCount : integer;
|
||||
function AddElement(const AName: string; AElementType: TLayoutElementType): TLayoutSection;
|
||||
constructor Create(const AName: string = ''; AElementType: TLayoutElementType = letSection);
|
||||
destructor Destroy; override;
|
||||
property Name: string read fName;
|
||||
property ElementType: TLayoutElementType read fElementType;
|
||||
end;
|
||||
|
||||
TCmdLineLayoutInfo = class(TObject)
|
||||
private
|
||||
fSections: TStringList;
|
||||
fValidOrder: Boolean;
|
||||
function DoGetSection(const SectName: String; Forced: Boolean = true): TLayoutSection;
|
||||
public
|
||||
RootElement : TLayoutSection;
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
function AddSection(const Section: string): TLayoutSection;
|
||||
function GetSection(const Section: string): TLayoutSection;
|
||||
//function GetSwitches(const Section: string; Dst: TStrings): Boolean;
|
||||
end;
|
||||
|
||||
{ TCmdLineUIControl }
|
||||
@ -53,14 +48,94 @@ type
|
||||
protected
|
||||
procedure ValueChanged; virtual;
|
||||
public
|
||||
procedure Init(cfg: TCmdLineCfg; layout: TCmdLineLayoutInfo); virtual; abstract;
|
||||
procedure Init(cfg: TCmdLineCfg; layout: TCmdLineLayoutInfo; const ASection : string = ''); virtual; abstract;
|
||||
procedure SetValues(list: TList {of TCmdLineOptionValue}); virtual; abstract;
|
||||
procedure Serialize(list: TList {of TCmdLineOptionValue}); virtual; abstract;
|
||||
property OnValueChanged: TNotifyEvent read FValueChanged write fValueChanged;
|
||||
end;
|
||||
|
||||
function LayoutFindElement(aparent: TLayoutSection; const Name: string; LookFor: TLayoutElementTypes = [letSection] ): TLayoutSection;
|
||||
procedure LayoutEnumElement(aparent: TLayoutSection; list: TList; LookFor: TLayoutElementTypes = [letSection] );
|
||||
procedure LayoutGetUnused(cmd: TCmdLineCfg; layout: TLayoutSection; list: TList);
|
||||
|
||||
implementation
|
||||
|
||||
procedure LayoutGetSwitches(root: TLayoutSection; hash: TFPHashObjectList);
|
||||
var
|
||||
sct : TList;
|
||||
i : Integer;
|
||||
j : Integer;
|
||||
el : TLayoutSection;
|
||||
sel : TLayoutSection;
|
||||
begin
|
||||
sct:=TList.Create;
|
||||
try
|
||||
sct.Add(root);
|
||||
j:=0;
|
||||
while j<sct.Count do begin
|
||||
el:=TLayoutSection(sct[j]);
|
||||
for i:=0 to el.ElemCount-1 do begin
|
||||
sel:=el.Elements[i];
|
||||
if sel.ElementType = letSection then
|
||||
sct.Add(sel)
|
||||
else begin
|
||||
hash.Add(sel.Name, sel);
|
||||
end;
|
||||
end;
|
||||
inc(j);
|
||||
end;
|
||||
finally
|
||||
sct.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure LayoutEnumElement(aparent: TLayoutSection; list: TList;
|
||||
LookFor: TLayoutElementTypes);
|
||||
var
|
||||
i : integer;
|
||||
begin
|
||||
if not Assigned(list) or not Assigned(aparent) or (LookFor = []) then Exit;
|
||||
for i:=0 to aparent.ElemCount-1 do begin
|
||||
if aparent.Elements[i].ElementType in LookFor then
|
||||
list.Add(aparent.Elements[i]);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure LayoutGetUnused(cmd: TCmdLineCfg; layout: TLayoutSection; list: TList);
|
||||
var
|
||||
i : Integer;
|
||||
hash : TFPHashObjectList;
|
||||
opt : TCmdLineCfgOption;
|
||||
begin
|
||||
if not Assigned(cmd) or not Assigned(layout) or not Assigned(list) then Exit;
|
||||
|
||||
hash := TFPHashObjectList.Create(false);
|
||||
try
|
||||
LayoutGetSwitches(layout, hash);
|
||||
for i:=0 to cmd.Options.Count-1 do begin
|
||||
opt:=TCmdLineCfgOption(cmd.Options[i]);
|
||||
if not Assigned(hash.Find(opt.Name)) then begin
|
||||
list.Add(opt);
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
hash.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function LayoutFindElement(aparent: TLayoutSection; const Name: string; LookFor: TLayoutElementTypes = [letSection]): TLayoutSection;
|
||||
var
|
||||
i : integer;
|
||||
nm : string;
|
||||
begin
|
||||
Result:=nil;
|
||||
if not Assigned(aparent) or (LookFor = []) then Exit;
|
||||
nm:=AnsiLowerCase(Name);
|
||||
for i:=0 to aparent.ElemCount-1 do
|
||||
if (aparent.Elements[i].fElementType in LookFor) and (AnsiLowerCase(aparent.Elements[i].Name)=nm) then
|
||||
Result:=aparent.Elements[i];
|
||||
end;
|
||||
|
||||
{ TLayoutSection }
|
||||
|
||||
function TLayoutSection.AddElement(const AName: string; AElementType: TLayoutElementType): TLayoutSection;
|
||||
@ -69,14 +144,20 @@ begin
|
||||
if ElemCount=0 then SetLength(Elements, 2)
|
||||
else SetLength(Elements, ElemCount*2);
|
||||
end;
|
||||
Result:=TLayoutSection.Create;
|
||||
Result.fName:=AName;
|
||||
Result.fElementType:=AElementType;
|
||||
Result:=TLayoutSection.Create(AName, AElementType);
|
||||
Result.Display:=Aname;
|
||||
Elements[ElemCount]:=Result;
|
||||
inc(ElemCount);
|
||||
end;
|
||||
|
||||
constructor TLayoutSection.Create(const AName: string;
|
||||
AElementType: TLayoutElementType);
|
||||
begin
|
||||
inherited Create;
|
||||
fName:=AName;
|
||||
fElementType:=AElementType;
|
||||
end;
|
||||
|
||||
destructor TLayoutSection.Destroy;
|
||||
var
|
||||
i : integer;
|
||||
@ -86,7 +167,7 @@ begin
|
||||
end;
|
||||
|
||||
{ TCmdLineLayoutInfo }
|
||||
|
||||
{
|
||||
function TCmdLineLayoutInfo.DoGetSection(const SectName: String; Forced: Boolean): TLayoutSection;
|
||||
var
|
||||
i : integer;
|
||||
@ -101,18 +182,17 @@ begin
|
||||
end else
|
||||
Result:=TLayoutSection(fSections.Objects[i]);
|
||||
end;
|
||||
|
||||
}
|
||||
constructor TCmdLineLayoutInfo.Create;
|
||||
begin
|
||||
fSections:=TStringList.Create;
|
||||
fSections.OwnsObjects:=true;
|
||||
AddSection('');
|
||||
RootElement:=TLayoutSection.Create;
|
||||
RootElement.fName:='';
|
||||
RootElement.fElementType:=letSection;
|
||||
end;
|
||||
|
||||
destructor TCmdLineLayoutInfo.Destroy;
|
||||
begin
|
||||
fSections.Clear; // need to call clear explicitly, since FREE doesn't free objects (even if owned)
|
||||
fSections.Free;
|
||||
RootElement.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
@ -121,7 +201,7 @@ end;
|
||||
begin
|
||||
GetSection(Section).fswitches.Add(SwitchOrName);
|
||||
end;}
|
||||
|
||||
{
|
||||
function TCmdLineLayoutInfo.AddSection(const Section: string): TLayoutSection;
|
||||
begin
|
||||
Result:=DoGetSection(Section, true);
|
||||
@ -131,7 +211,7 @@ function TCmdLineLayoutInfo.GetSection(const Section: string): TLayoutSection;
|
||||
begin
|
||||
Result:=DoGetSection(Section, false);
|
||||
end;
|
||||
|
||||
}
|
||||
{function TCmdLineLayoutInfo.GetSections(Dst: TStrings): Boolean;
|
||||
var
|
||||
i : Integer;
|
||||
|
@ -45,7 +45,7 @@ begin
|
||||
st:=TSectionIterator.Create;
|
||||
try
|
||||
st.lt:=lt;
|
||||
st.sc:=lt.GetSection('');
|
||||
st.sc:=lt.RootElement;
|
||||
core.Iterate( st.Iterate, st)
|
||||
finally
|
||||
st.Free;
|
||||
|
@ -28,13 +28,15 @@ type
|
||||
|
||||
TCmdLineScrollBoxControl = class(TCmdLineUIControl)
|
||||
private
|
||||
fScrollBox : TScrollBox;
|
||||
fCfg : TCmdLineCfg;
|
||||
fControls : TList;
|
||||
fOptToCtrl : TFPHashObjectList;
|
||||
fParent : TWinControl;
|
||||
|
||||
fOtherMet : Boolean;
|
||||
protected
|
||||
flayout: TCmdLineLayoutInfo;
|
||||
fusedoptlist: TStringList;
|
||||
fusedoptlist: TFPHashObjectList;
|
||||
procedure OnChange(Sender: TObject);
|
||||
procedure OnCndChange(Sender: TObject);
|
||||
procedure RevaluateConditions;
|
||||
@ -45,21 +47,13 @@ type
|
||||
public
|
||||
constructor Create(AParent: TWinControl);
|
||||
destructor Destroy; override;
|
||||
procedure Init(cfg: TCmdLineCfg; layout: TCmdLineLayoutInfo); override;
|
||||
procedure Init(cfg: TCmdLineCfg; layout: TCmdLineLayoutInfo; const ASection: string = ''); override;
|
||||
procedure SetValues(list: TList {of TCmdLineOptionValue}); override;
|
||||
procedure Serialize(list: TList {of TCmdLineOptionValue}); override;
|
||||
end;
|
||||
|
||||
procedure ReleaseScrollBox(box: TCmdLineScrollBoxControl);
|
||||
|
||||
implementation
|
||||
|
||||
procedure ReleaseScrollBox(box: TCmdLineScrollBoxControl);
|
||||
begin
|
||||
if not Assigned(box) then Exit;
|
||||
box.fScrollBox.Free;
|
||||
end;
|
||||
|
||||
{ TControlInfo }
|
||||
|
||||
constructor TControlInfo.Create(aopt: TCmdLineCfgOption; actrl: TControl);
|
||||
@ -215,6 +209,7 @@ var
|
||||
k : Integer;
|
||||
box : TGroupBox;
|
||||
by : integer;
|
||||
opt : TCmdLineCfgOption;
|
||||
begin
|
||||
if not Assigned(sct) then begin
|
||||
Result:=VOffset;
|
||||
@ -247,10 +242,15 @@ begin
|
||||
end else
|
||||
y:=AllocForSection(AParent, y, ls );
|
||||
end else begin
|
||||
k:=fusedoptlist.IndexOf(ls.Name);
|
||||
if (k>=0) then begin
|
||||
l.Add( fusedoptlist.Objects[k] );
|
||||
fusedoptlist.Delete(k);
|
||||
if (AnsiLowerCase(ls.Name)='%%other') and not fOtherMet then begin
|
||||
LayoutGetUnused( fCfg, flayout.RootElement, l );
|
||||
fOtherMet := true;
|
||||
end else begin
|
||||
k := fusedoptlist.FindIndexOf(ls.Name);
|
||||
if k>=0 then begin
|
||||
l.Add( fusedoptlist.Items[k] );
|
||||
fusedoptlist.Delete(k);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@ -275,10 +275,7 @@ end;
|
||||
constructor TCmdLineScrollBoxControl.Create(AParent: TWinControl);
|
||||
begin
|
||||
inherited Create;
|
||||
fScrollBox := TScrollBox.Create(AParent);
|
||||
fScrollBox.Align:=alClient;
|
||||
fScrollBox.Parent:=AParent;
|
||||
fScrollBox.VertScrollBar.Tracking:=true;
|
||||
fParent:=AParent;
|
||||
fControls:=TList.Create;
|
||||
fOptToCtrl:=TFPHashObjectList.Create(true);
|
||||
end;
|
||||
@ -291,7 +288,7 @@ begin
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TCmdLineScrollBoxControl.Init(cfg: TCmdLineCfg; layout: TCmdLineLayoutInfo);
|
||||
procedure TCmdLineScrollBoxControl.Init(cfg: TCmdLineCfg; layout: TCmdLineLayoutInfo; const ASection: string = '');
|
||||
var
|
||||
i : Integer;
|
||||
opt : TCmdLineCfgOption;
|
||||
@ -299,6 +296,8 @@ var
|
||||
l : TList;
|
||||
nm : string;
|
||||
y : Integer;
|
||||
sct : TLayoutSection;
|
||||
sctnm : string;
|
||||
begin
|
||||
if not Assigned(cfg) then Exit;
|
||||
fCfg:=cfg;
|
||||
@ -306,26 +305,31 @@ begin
|
||||
list.CaseSensitive:=true; // must be case sensitive
|
||||
l:=TList.Create;
|
||||
fOptToCtrl.Clear;
|
||||
fusedoptlist:=list;
|
||||
|
||||
fusedoptlist:=TFPHashObjectList.Create(false);
|
||||
flayout:=layout;
|
||||
try
|
||||
y:=24;
|
||||
y:=0;
|
||||
for i:=0 to cfg.Options.Count-1 do begin
|
||||
opt:=TCmdLineCfgOption(cfg.Options[i]);
|
||||
nm:=opt.Name;
|
||||
if nm='' then nm:=opt.Key;
|
||||
list.AddObject(nm, cfg.Options[i]);
|
||||
fusedoptlist.Add(nm, cfg.Options[i]);
|
||||
end;
|
||||
|
||||
if Assigned(layout) then y:=AllocForSection(fScrollBox, y, layout.GetSection(''));
|
||||
if Assigned(layout) then begin
|
||||
y:=AllocHeaderLabel(fScrollBox, y, 'Other');
|
||||
if not Assigned(layout) then begin
|
||||
for i:=0 to list.Count-1 do l.Add(list.Objects[i]);
|
||||
AllocControls(fParent, y, l);
|
||||
end else begin
|
||||
fOtherMet:=false;
|
||||
sctnm:=ASection;
|
||||
sct:=layout.RootElement;
|
||||
if ASection<>'' then sct:=LayoutFindElement(sct, sctnm);
|
||||
if Assigned(sct) then
|
||||
y:=AllocForSection(fParent, y, sct, sctnm<>'');
|
||||
end;
|
||||
l.Clear;
|
||||
for i:=0 to list.Count-1 do
|
||||
l.Add(list.Objects[i]);
|
||||
AllocControls(fScrollBox, y, l);
|
||||
finally
|
||||
fusedoptlist.Free;
|
||||
fusedoptlist:=nil;
|
||||
flayout:=nil;
|
||||
l.Free;
|
||||
@ -340,6 +344,7 @@ var
|
||||
i : Integer;
|
||||
mlt : TFPHashList;
|
||||
isPath : Boolean;
|
||||
ci : TControlInfo;
|
||||
const
|
||||
Delims : array [Boolean] of string = (' ', ';');
|
||||
begin
|
||||
@ -350,7 +355,9 @@ begin
|
||||
for i:=0 to list.Count-1 do begin
|
||||
vl:=TCmdLineOptionValue(list[i]);
|
||||
if not Assigned(vl.Option) then Continue;
|
||||
ctrl:=TControlInfo(fOptToCtrl.Find(vl.Option.Name)).ctrl;
|
||||
ci:=TControlInfo(fOptToCtrl.Find(vl.Option.Name));
|
||||
if not Assigned(ci) then Continue;
|
||||
ctrl:=ci.ctrl;
|
||||
if not Assigned(ctrl) then Continue;
|
||||
if ctrl is TComboBox then SetValueComboBox(vl.Option, vl.Value, TComboBoX(ctrl))
|
||||
else if ctrl is TCheckBox then SetValueCheckBox(vl.Option, vl.Value, TCheckBox(ctrl))
|
||||
|
@ -17,7 +17,7 @@
|
||||
<CompilerPath Value="$(CompPath)"/>
|
||||
</Other>
|
||||
</CompilerOptions>
|
||||
<Files Count="13">
|
||||
<Files Count="12">
|
||||
<Item1>
|
||||
<Filename Value="optviewform.pas"/>
|
||||
<UnitName Value="optviewform"/>
|
||||
@ -27,50 +27,46 @@
|
||||
<UnitName Value="cmdlinelclctrlsbox"/>
|
||||
</Item2>
|
||||
<Item3>
|
||||
<Filename Value="..\cmdlinelclpropgrid.pas"/>
|
||||
<UnitName Value="cmdlinelclpropgrid"/>
|
||||
</Item3>
|
||||
<Item4>
|
||||
<Filename Value="..\cmdlinelclutils.pas"/>
|
||||
<UnitName Value="cmdlinelclutils"/>
|
||||
</Item4>
|
||||
<Item5>
|
||||
</Item3>
|
||||
<Item4>
|
||||
<Filename Value="..\cmdlinecfg.pas"/>
|
||||
<UnitName Value="cmdlinecfg"/>
|
||||
</Item5>
|
||||
<Item6>
|
||||
</Item4>
|
||||
<Item5>
|
||||
<Filename Value="..\cmdlinecfgjson.pas"/>
|
||||
<UnitName Value="cmdlinecfgjson"/>
|
||||
</Item6>
|
||||
<Item7>
|
||||
</Item5>
|
||||
<Item6>
|
||||
<Filename Value="..\cmdlinecfgparser.pas"/>
|
||||
<UnitName Value="cmdlinecfgparser"/>
|
||||
</Item7>
|
||||
<Item8>
|
||||
</Item6>
|
||||
<Item7>
|
||||
<Filename Value="..\cmdlinecfgui.pas"/>
|
||||
<UnitName Value="cmdlinecfgui"/>
|
||||
</Item8>
|
||||
<Item9>
|
||||
</Item7>
|
||||
<Item8>
|
||||
<Filename Value="..\cmdlinecfguijson.pas"/>
|
||||
<UnitName Value="cmdlinecfguijson"/>
|
||||
</Item9>
|
||||
<Item10>
|
||||
</Item8>
|
||||
<Item9>
|
||||
<Filename Value="..\cmdlinecfgutils.pas"/>
|
||||
<UnitName Value="cmdlinecfgutils"/>
|
||||
</Item10>
|
||||
<Item11>
|
||||
</Item9>
|
||||
<Item10>
|
||||
<Filename Value="..\cmdlinefpccond.pas"/>
|
||||
<UnitName Value="cmdlinefpccond"/>
|
||||
</Item11>
|
||||
<Item12>
|
||||
</Item10>
|
||||
<Item11>
|
||||
<Filename Value="cfgcompoptreg.pas"/>
|
||||
<HasRegisterProc Value="True"/>
|
||||
<UnitName Value="cfgcompoptreg"/>
|
||||
</Item12>
|
||||
<Item13>
|
||||
</Item11>
|
||||
<Item12>
|
||||
<Filename Value="optviewform.lfm"/>
|
||||
<Type Value="LFM"/>
|
||||
</Item13>
|
||||
</Item12>
|
||||
</Files>
|
||||
<Type Value="DesignTime"/>
|
||||
<RequiredPkgs Count="3">
|
||||
|
@ -7,10 +7,9 @@ unit cfgcompopt;
|
||||
interface
|
||||
|
||||
uses
|
||||
optviewform, cmdlinelclctrlsbox, cmdlinelclpropgrid, cmdlinelclutils,
|
||||
cmdlinecfg, cmdlinecfgjson, cmdlinecfgparser, cmdlinecfgui,
|
||||
cmdlinecfguijson, cmdlinecfgutils, cmdlinefpccond, cfgcompoptreg,
|
||||
LazarusPackageIntf;
|
||||
optviewform, cmdlinelclctrlsbox, cmdlinelclutils, cmdlinecfg,
|
||||
cmdlinecfgjson, cmdlinecfgparser, cmdlinecfgui, cmdlinecfguijson,
|
||||
cmdlinecfgutils, cmdlinefpccond, cfgcompoptreg, LazarusPackageIntf;
|
||||
|
||||
implementation
|
||||
|
||||
|
@ -1,46 +1,73 @@
|
||||
object OptView: TOptView
|
||||
Left = 359
|
||||
Left = 571
|
||||
Height = 240
|
||||
Top = 214
|
||||
Top = 171
|
||||
Width = 320
|
||||
Caption = 'OptView'
|
||||
ClientHeight = 240
|
||||
ClientWidth = 320
|
||||
OnDestroy = FormDestroy
|
||||
OnShow = FormShow
|
||||
LCLVersion = '1.1'
|
||||
LCLVersion = '1.3'
|
||||
object Panel1: TPanel
|
||||
Left = 0
|
||||
Height = 190
|
||||
Height = 200
|
||||
Top = 0
|
||||
Width = 320
|
||||
Align = alClient
|
||||
Caption = 'Panel1'
|
||||
ClientHeight = 200
|
||||
ClientWidth = 320
|
||||
TabOrder = 0
|
||||
object ListBox1: TListBox
|
||||
Left = 1
|
||||
Height = 198
|
||||
Top = 1
|
||||
Width = 130
|
||||
Align = alLeft
|
||||
ItemHeight = 0
|
||||
OnClick = ListBox1Click
|
||||
OnSelectionChange = ListBox1SelectionChange
|
||||
TabOrder = 0
|
||||
end
|
||||
object Splitter1: TSplitter
|
||||
Left = 131
|
||||
Height = 198
|
||||
Top = 1
|
||||
Width = 5
|
||||
end
|
||||
object Panel3: TPanel
|
||||
Left = 136
|
||||
Height = 198
|
||||
Top = 1
|
||||
Width = 183
|
||||
Align = alClient
|
||||
BevelOuter = bvNone
|
||||
TabOrder = 2
|
||||
end
|
||||
end
|
||||
object Panel2: TPanel
|
||||
Left = 0
|
||||
Height = 50
|
||||
Top = 190
|
||||
Height = 40
|
||||
Top = 200
|
||||
Width = 320
|
||||
Align = alBottom
|
||||
Caption = 'Panel2'
|
||||
ClientHeight = 50
|
||||
ClientHeight = 40
|
||||
ClientWidth = 320
|
||||
TabOrder = 1
|
||||
OnResize = Panel2Resize
|
||||
object btnOk: TButton
|
||||
Left = 33
|
||||
Left = 72
|
||||
Height = 25
|
||||
Top = 15
|
||||
Top = 8
|
||||
Width = 75
|
||||
Caption = 'Ok'
|
||||
ModalResult = 1
|
||||
TabOrder = 0
|
||||
end
|
||||
object btnCancel: TButton
|
||||
Left = 115
|
||||
Left = 152
|
||||
Height = 25
|
||||
Top = 15
|
||||
Top = 8
|
||||
Width = 75
|
||||
Caption = 'Cancel'
|
||||
ModalResult = 2
|
||||
|
@ -7,26 +7,40 @@ interface
|
||||
uses
|
||||
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
|
||||
LCLIntf,
|
||||
StdCtrls, LazIDEIntf, IDEOptionsIntf, ProjectIntf, CompOptsIntf, cmdlinecfg,
|
||||
cmdlinecfgjson, cmdlinecfgui, cmdlinecfguijson, cmdlinelclctrlsbox, cmdlinelazcompopt;
|
||||
StdCtrls, LazIDEIntf, IDEOptionsIntf, ProjectIntf, CompOptsIntf, cmdlinecfg
|
||||
//, cmdlinecfgjson
|
||||
, cmdlinecfgui
|
||||
//, cmdlinecfguijson
|
||||
, cmdlinelclctrlsbox, cmdlinelazcompopt;
|
||||
|
||||
type
|
||||
TOptionsBox = record
|
||||
box : TScrollBox;
|
||||
cmd : TCmdLineScrollBoxControl;
|
||||
end;
|
||||
|
||||
{ TOptView }
|
||||
|
||||
TOptView = class(TForm)
|
||||
btnOk: TButton;
|
||||
btnCancel: TButton;
|
||||
ListBox1: TListBox;
|
||||
Panel1: TPanel;
|
||||
Panel2: TPanel;
|
||||
Panel3: TPanel;
|
||||
Splitter1: TSplitter;
|
||||
procedure FormDestroy(Sender: TObject);
|
||||
procedure FormShow(Sender: TObject);
|
||||
procedure ListBox1Click(Sender: TObject);
|
||||
procedure ListBox1SelectionChange(Sender: TObject; User: boolean);
|
||||
procedure Panel2Resize(Sender: TObject);
|
||||
private
|
||||
{ private declarations }
|
||||
cmd : TCmdLineScrollBoxControl;
|
||||
sections : array of TOptionsBox;
|
||||
cfg : TCmdLineCfg;
|
||||
layout : TCmdLineLayoutInfo;
|
||||
procedure InitOpts(acfg: TCmdLineCfg; alayout: TCmdLineLayoutInfo);
|
||||
procedure ClearSections(clearboxes: Boolean = true);
|
||||
public
|
||||
{ public declarations }
|
||||
function ShowForOpts(opt: TLazCompilerOptions): Integer;
|
||||
@ -46,20 +60,19 @@ implementation
|
||||
function ReviewOpts(acfg: TCmdLineCfg; alayout: TCmdLineLayoutInfo; opt: TLazCompilerOptions = nil): Integer;
|
||||
begin
|
||||
if not Assigned(OptView) then OptView:=TOptView.Create(Application);
|
||||
OptView.Caption:='Review Compiler Options';
|
||||
if (OptView.cfg<>acfg) or (OptView.layout<>alayout) then
|
||||
OptView.InitOpts(acfg, alayout);
|
||||
if not Assigned(opt) and Assigned(LazarusIDE.ActiveProject) then
|
||||
opt:=LazarusIDE.ActiveProject.LazCompilerOptions;
|
||||
|
||||
if Assigned(OptView.cmd) and Assigned(opt) then
|
||||
Result:=OptView.ShowForOpts(opt)
|
||||
else
|
||||
Result:=mrCancel;
|
||||
if Assigned(opt) then Result:=OptView.ShowForOpts(opt)
|
||||
else Result:=mrCancel;
|
||||
end;
|
||||
|
||||
procedure TOptView.FormDestroy(Sender: TObject);
|
||||
begin
|
||||
cmd.Free;
|
||||
ClearSections(false);
|
||||
end;
|
||||
|
||||
procedure TOptView.FormShow(Sender: TObject);
|
||||
@ -67,14 +80,74 @@ begin
|
||||
|
||||
end;
|
||||
|
||||
procedure TOptView.InitOpts(acfg: TCmdLineCfg; alayout: TCmdLineLayoutInfo);
|
||||
procedure TOptView.ListBox1Click(Sender: TObject);
|
||||
begin
|
||||
ReleaseScrollBox(cmd);
|
||||
cmd.Free;
|
||||
|
||||
end;
|
||||
|
||||
procedure TOptView.ListBox1SelectionChange(Sender: TObject; User: boolean);
|
||||
var
|
||||
i : Integer;
|
||||
idx: integer;
|
||||
begin
|
||||
idx:=ListBox1.ItemIndex;
|
||||
if (idx>=0) and (idx<length(sections)) then begin
|
||||
sections[idx].box.BringToFront;
|
||||
sections[idx].box.Show;
|
||||
for i:=0 to length(sections)-1 do
|
||||
if i<>idx then sections[i].box.Hide;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
procedure TOptView.Panel2Resize(Sender: TObject);
|
||||
var
|
||||
w: integer;
|
||||
begin
|
||||
w:=Self.Width div 2;
|
||||
btnOk.Left:=w - btnOk.Width - 2;
|
||||
btnCancel.Left:=w+2;
|
||||
end;
|
||||
|
||||
procedure TOptView.InitOpts(acfg: TCmdLineCfg; alayout: TCmdLineLayoutInfo);
|
||||
var
|
||||
lt : TList;
|
||||
i : Integer;
|
||||
ls : TLayoutSection;
|
||||
begin
|
||||
ClearSections;
|
||||
cfg:=acfg;
|
||||
layout:=alayout;
|
||||
cmd:=TCmdLineScrollBoxControl.Create(Panel1);
|
||||
cmd.Init(cfg, layout);
|
||||
//cmd:=
|
||||
lt:=TList.Create;
|
||||
try
|
||||
LayoutEnumElement( layout.RootElement, lt);
|
||||
SetLength(sections, lt.Count);
|
||||
for i:=0 to lt.Count-1 do begin
|
||||
ls:=TLayoutSection(lt[i]);
|
||||
ListBox1.AddItem( ls.Display, ls);
|
||||
sections[i].box:=TScrollBox.Create(Panel3);
|
||||
sections[i].box.Visible:=false;
|
||||
sections[i].box.Parent:=Panel3;
|
||||
sections[i].box.Align:=alClient;
|
||||
sections[i].cmd:=TCmdLineScrollBoxControl.Create(sections[i].box);
|
||||
sections[i].cmd.Init(cfg, layout, ls.Name);
|
||||
end;
|
||||
finally
|
||||
lt.Free;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
procedure TOptView.ClearSections(clearboxes: Boolean);
|
||||
var
|
||||
i : integer;
|
||||
begin
|
||||
for i:=0 to length(sections)-1 do begin
|
||||
sections[i].cmd.Free;
|
||||
if clearboxes then sections[i].box.Free;
|
||||
end;
|
||||
SetLength(sections,0);
|
||||
end;
|
||||
|
||||
function TOptView.ShowForOpts(opt: TLazCompilerOptions): Integer;
|
||||
@ -85,13 +158,14 @@ begin
|
||||
list := TList.Create;
|
||||
try
|
||||
LazCompOptToVals(opt, cfg, list);
|
||||
cmd.SetValues(list);
|
||||
for i:=0 to length(sections)-1 do sections[i].cmd.SetValues(list);
|
||||
for i:=0 to list.Count-1 do TObject(list[i]).Free;
|
||||
|
||||
Result:=ShowModal;
|
||||
if Result=mrOK then begin
|
||||
list.Clear;
|
||||
cmd.Serialize(list);
|
||||
for i:=0 to length(sections)-1 do
|
||||
sections[i].cmd.Serialize(list);
|
||||
ValsToLazCompOpt(list, opt);
|
||||
for i:=0 to list.Count-1 do TObject(list[i]).Free;
|
||||
end;
|
||||
|
@ -1,5 +1,32 @@
|
||||
Command Line Configuration
|
||||
|
||||
== Source files ==
|
||||
|
||||
cmdlinecfg.pas - the core unit defining the primary class for configuration
|
||||
cmdlinecfgutils.pas - utility functions
|
||||
cmdlinecfgparser.pas - the unit for parsing input strings into command lines
|
||||
and mapping them to classes of cmdlinecfg.
|
||||
cmdlinecfgjson.pas - the json format reader of command-line configurations
|
||||
|
||||
=== User Interface ===
|
||||
|
||||
cmdlinecfgui.pas - core unit for UI controller of command-line options
|
||||
cmdlinecfguijson.pas - json read of UI controller info.
|
||||
cmdlinelclctrlsbox.pas - LCL-based consols list UI controller
|
||||
cmdlinelclpropgrid.pas - LCL-based propery grid UI controller
|
||||
cmdlinelclutils.pas - the function contains a number of utility functions
|
||||
for allocating LCL controls based on the information about command-line option
|
||||
|
||||
=== Lazarus specific ===
|
||||
|
||||
cmdlinelazcompopt.pas - Lazarus IDE specific file, that converts a set of cmdlinecfg classes
|
||||
to Lazarus project
|
||||
=== Condition checks ===
|
||||
|
||||
cmdlinefpccond.pas - the utility function for verification of FPC specific conditions (cpu/os)
|
||||
(doesn't depend on cmdlinecfg.pas)
|
||||
see "FPC Condition" below
|
||||
|
||||
|
||||
== JSON Storage ==
|
||||
|
||||
@ -80,6 +107,8 @@ Example of JSON Storage:
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
|
||||
== FPC Condition ==
|
||||
|
||||
Free Pascal Compiler condition define for what target (CPU, CPU-OS) the option or value of an option
|
||||
@ -98,4 +127,56 @@ If an option is available for multple platforms, each condition has to be comma
|
||||
i386,x86_64,arm-linux
|
||||
|
||||
|
||||
== UI controller ==
|
||||
|
||||
UI controller is an abstraction layer, that does the representation of the command-line utils to an user.
|
||||
|
||||
The core class is:
|
||||
|
||||
TCmdLineUIControl
|
||||
method
|
||||
procedure Init(cfg: TCmdLineCfg; layout: TCmdLineLayoutInfo; ASection: string);
|
||||
- method accepts the description of the command-line options
|
||||
and optional layout information;
|
||||
method must initialize (create) all necessary UI controls;
|
||||
the place to initialize controls must be defined in the method constructor
|
||||
* if layout information is passed, the controller should use it to represent the user interface
|
||||
* if Asection is not an empty string and layout is passed, controller should
|
||||
initialize controls for this section only.
|
||||
Futher operations for "SetValue" and "Serialize" should be limited
|
||||
to the command-line options, contained in the layout of the passed section.
|
||||
if layout information is not passed, section should be ignored
|
||||
* Since it's possible that a new command-line option is introduced
|
||||
prior to update of the user interface information,
|
||||
a layout information can specify switch "%%other" (name is case-insesitive)
|
||||
where all switches should go, that don't have a specific location within the layout information.
|
||||
if "%%other" switch is not introduced by the layout, these command-line options that are not part of the layout
|
||||
must not be shown.
|
||||
if multiple "%%other" switches are declared, the first met should be used
|
||||
|
||||
procedure SetValues(list: TList);
|
||||
- method should initialized UI controls to the values passed in the list
|
||||
the list will contain objects TCmdLineOptionValue class.
|
||||
the methods must not retain or free any of the objects
|
||||
procedure Serialize(list: TList);
|
||||
- method should gather the values from the user interface
|
||||
method should not check the existense of TCmdLineOptionValue in the passed list
|
||||
instead it must only ADD serialized TCmdLineOptionValue values
|
||||
|
||||
events
|
||||
OnValueChanged: TNotifyEvent - the event should be triggered every time a value is changed by a user;
|
||||
the even must not be triggered during handling of SetValues method
|
||||
|
||||
|
||||
|
||||
The supplemental classes:
|
||||
|
||||
TCmdLineLayoutInfo - the class contains a description of how to represent command-line utils.
|
||||
any implementation of TCmdLineUIControl must be able to work without
|
||||
any TCmdLineLayoutInfo provided.
|
||||
TLayoutSection - the description of a certain section of "command-line configurations".
|
||||
typically command-line options are grouped into sections
|
||||
|
||||
=== GUI Hints ===
|
||||
|
||||
hideempty - if the there're no command-line options to be displayed, the section should be hidden
|
@ -44,4 +44,7 @@
|
||||
"display": "Verbosity",
|
||||
"switches": ["-ve","-vw", "-vn","-vh","-vi","-vp","-vc","-vx","-v0","-vd","-vu","-vt","-vl","-vb","-va","-l","-Se"]
|
||||
}
|
||||
,"other": {
|
||||
"display": "Other", "switches": ["%%other"]
|
||||
}
|
||||
}
|
@ -1,19 +1,19 @@
|
||||
object Form1: TForm1
|
||||
Left = 411
|
||||
Height = 319
|
||||
Height = 339
|
||||
Top = 197
|
||||
Width = 425
|
||||
Width = 441
|
||||
Caption = 'Form1'
|
||||
ClientHeight = 319
|
||||
ClientWidth = 425
|
||||
ClientHeight = 339
|
||||
ClientWidth = 441
|
||||
OnCreate = FormCreate
|
||||
OnDestroy = FormDestroy
|
||||
LCLVersion = '1.1'
|
||||
LCLVersion = '1.3'
|
||||
object Memo1: TMemo
|
||||
Left = 0
|
||||
Height = 90
|
||||
Top = 179
|
||||
Width = 425
|
||||
Top = 199
|
||||
Width = 441
|
||||
Align = alBottom
|
||||
Lines.Strings = (
|
||||
'Memo1'
|
||||
@ -24,36 +24,20 @@ object Form1: TForm1
|
||||
Cursor = crVSplit
|
||||
Left = 0
|
||||
Height = 5
|
||||
Top = 174
|
||||
Width = 425
|
||||
Top = 194
|
||||
Width = 441
|
||||
Align = alBottom
|
||||
ResizeAnchor = akBottom
|
||||
end
|
||||
object Label1: TLabel
|
||||
Left = 47
|
||||
Height = 13
|
||||
Top = 44
|
||||
Width = 31
|
||||
Caption = 'Label1'
|
||||
ParentColor = False
|
||||
end
|
||||
object Edit1: TEdit
|
||||
Left = 105
|
||||
Height = 21
|
||||
Top = 46
|
||||
Width = 191
|
||||
TabOrder = 2
|
||||
Text = 'Edit1'
|
||||
end
|
||||
object Panel1: TPanel
|
||||
Left = 0
|
||||
Height = 50
|
||||
Top = 269
|
||||
Width = 425
|
||||
Top = 289
|
||||
Width = 441
|
||||
Align = alBottom
|
||||
ClientHeight = 50
|
||||
ClientWidth = 425
|
||||
TabOrder = 3
|
||||
ClientWidth = 441
|
||||
TabOrder = 2
|
||||
object toOpt: TButton
|
||||
Left = 8
|
||||
Height = 25
|
||||
@ -64,4 +48,15 @@ object Form1: TForm1
|
||||
TabOrder = 0
|
||||
end
|
||||
end
|
||||
object ScrollBox1: TScrollBox
|
||||
Left = 0
|
||||
Height = 196
|
||||
Top = 0
|
||||
Width = 440
|
||||
HorzScrollBar.Page = 436
|
||||
VertScrollBar.Page = 192
|
||||
VertScrollBar.Tracking = True
|
||||
Anchors = [akTop, akLeft, akRight, akBottom]
|
||||
TabOrder = 3
|
||||
end
|
||||
end
|
||||
|
@ -5,8 +5,8 @@ unit mainform;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ValEdit,
|
||||
StdCtrls, ExtCtrls
|
||||
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs
|
||||
,StdCtrls, ExtCtrls
|
||||
,cmdlinecfg , cmdlinelclctrlsbox, cmdlinecfgjson //, patheditor
|
||||
,cmdlinecfgui, cmdlinecfguijson
|
||||
,cmdlinecfgparser;
|
||||
@ -16,9 +16,8 @@ type
|
||||
{ TForm1 }
|
||||
|
||||
TForm1 = class(TForm)
|
||||
ScrollBox1: TScrollBox;
|
||||
toOpt: TButton;
|
||||
Edit1: TEdit;
|
||||
Label1: TLabel;
|
||||
Memo1: TMemo;
|
||||
Panel1: TPanel;
|
||||
Splitter1: TSplitter;
|
||||
@ -30,6 +29,7 @@ type
|
||||
ctrl : TCmdLineScrollBoxControl;
|
||||
cfg : TCmdLineCfg;
|
||||
lt : TCmdLineLayoutInfo;
|
||||
sct : string; // desired section
|
||||
public
|
||||
{ public declarations }
|
||||
procedure OnValueChanged(Sender: TObject);
|
||||
@ -47,17 +47,36 @@ implementation
|
||||
procedure TForm1.FormCreate(Sender: TObject);
|
||||
begin
|
||||
{cmdlinelclutils.ADirsDialogs:=DummyEditPaths;
|
||||
cmdlinelclutils.AFilesDialogs:=DummyEditPaths;}
|
||||
cmdlinelclutils.AFilesDialogs:=DummyEditPaths;
|
||||
}
|
||||
|
||||
ctrl:=TCmdLineScrollBoxControl.Create(Self);
|
||||
{fScrollBox := TScrollBox.Create(AParent);
|
||||
fScrollBox.Align:=alClient;
|
||||
fScrollBox.Parent:=AParent;
|
||||
fScrollBox.VertScrollBar.Tracking:=true;}
|
||||
|
||||
Memo1.Clear;
|
||||
if ParamCount=0 then begin
|
||||
Memo1.Lines.Add('Please pass the following information through the command-line: ');
|
||||
Memo1.Lines.Add(' 1. json file for command-lines');
|
||||
Memo1.Lines.Add(' (optional) 2. layout information json file ');
|
||||
Memo1.Lines.Add(' (optional) 3. name of the section that you would need to render');
|
||||
end;
|
||||
|
||||
ctrl:=TCmdLineScrollBoxControl.Create(ScrollBox1);
|
||||
if ParamCount>0 then begin
|
||||
cfg:=TCmdLineCfg.Create;
|
||||
CmdLineCfgJSONReadFile(ParamStr(1), cfg);
|
||||
if ParamCOunt>1 then begin
|
||||
lt:=TCmdLineLayoutInfo.Create;
|
||||
CmdLineUIJSONReadFile(PAramStr(2), lt);
|
||||
CmdLineUIJSONReadFile(ParamStr(2), lt);
|
||||
end;
|
||||
ctrl.Init(cfg, lt);
|
||||
if ParamCount>2 then
|
||||
sct:=ParamStr(3);
|
||||
Self.Caption:=Paramstr(1);
|
||||
if sct<>'' then Self.Caption:=Self.Caption+'.'+sct;
|
||||
ctrl.Init(cfg, lt, sct);
|
||||
|
||||
ctrl.OnValueChanged:=OnValueChanged;
|
||||
end;
|
||||
end;
|
||||
|
21
components/cmdlinecfg/trunk/testguibuild/sample.copt
Normal file
21
components/cmdlinecfg/trunk/testguibuild/sample.copt
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"executable":"sample",
|
||||
"version":"1.0",
|
||||
"testkey":"-iV",
|
||||
"testValue":"1.0",
|
||||
"options": [
|
||||
{"key":"-a", "display":"This is option A" }
|
||||
,{"key":"-b", "display":"This option controls B"}
|
||||
,{"key":"-c", "display":"C is controlled by this checkbox" }
|
||||
,{ "key":"-d%value%", "display":"This is drop down values - one of many"
|
||||
,"options": [
|
||||
{"value": "1", "display":"One"}
|
||||
,{"value": "2", "display":"Two"}
|
||||
,{"value": "3", "display":"Three"}
|
||||
,{"value": "4", "display":"Four"}
|
||||
,{"value": "5", "display":"Five"}
|
||||
]
|
||||
}
|
||||
,{"key":"-z", "display":"Z is the last control not in sample.ui" }
|
||||
]
|
||||
}
|
10
components/cmdlinecfg/trunk/testguibuild/sample.ui
Normal file
10
components/cmdlinecfg/trunk/testguibuild/sample.ui
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"primary": {
|
||||
"display": "Primary Part",
|
||||
"switches": ["-a","-d"]
|
||||
}
|
||||
,"secondary": {
|
||||
"display": "Secondary Part",
|
||||
"switches": ["-b","-c"]
|
||||
}
|
||||
}
|
15
components/cmdlinecfg/trunk/testguibuild/sampleother.ui
Normal file
15
components/cmdlinecfg/trunk/testguibuild/sampleother.ui
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"primary": {
|
||||
"display": "Primary Part",
|
||||
"switches": ["-a","-d"]
|
||||
}
|
||||
,"secondary": {
|
||||
"display": "Secondary Part",
|
||||
"switches": ["-b","-c"]
|
||||
}
|
||||
,"other": {
|
||||
"display": "Other",
|
||||
"hint": "hideempty",
|
||||
"switches": ["%%other"]
|
||||
}
|
||||
}
|
@ -9,7 +9,6 @@
|
||||
<Title Value="project1"/>
|
||||
<ResourceType Value="res"/>
|
||||
<UseXPManifest Value="True"/>
|
||||
<Icon Value="0"/>
|
||||
</General>
|
||||
<i18n>
|
||||
<EnableI18N LFM="False"/>
|
||||
|
Reference in New Issue
Block a user