lazarus/ide/frames/compiler_buildmacro_options.pas
mattias d26e7c8a0b IDE: conditionals: collecting completion words
git-svn-id: trunk@27504 -
2010-09-28 13:23:01 +00:00

803 lines
24 KiB
ObjectPascal

{***************************************************************************
* *
* This source is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This code is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* *
* A copy of the GNU General Public License is available on the World *
* Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
* obtain it by writing to the Free Software Foundation, *
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
***************************************************************************
Abstract:
Frame to edit build macros and conditionals of compiler options
(project+packages).
}
unit Compiler_BuildMacro_Options;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, AVL_Tree, LCLProc, FileUtil, Controls, Forms, StdCtrls,
Grids, LCLType, Buttons, ExtCtrls, Dialogs, ComCtrls, Menus, AvgLvlTree,
SynEdit, SynHighlighterPas, SynEditKeyCmds,
KeywordFuncLists, CodeToolsCfgScript,
IDEImagesIntf,
IDECommands, ProjectIntf, PackageIntf, IDEOptionsIntf, MacroIntf,
CompilerOptions, EditorOptions,
LazarusIDEStrConsts, CompOptsModes, SourceSynEditor, PackageDefs;
type
TCBMNodeType = (
cbmntNone,
cbmntBuildMacro,
cbmntValue
);
TCBMPrefixType = (
cbmpShort,
cbmpMedium,
cbmpLong
);
{ TCompOptBuildMacrosFrame }
TCompOptBuildMacrosFrame = class(TAbstractIDEOptionsEditor)
BMAddMacroSpeedButton: TSpeedButton;
BMAddMacroValueSpeedButton: TSpeedButton;
BMDeleteSpeedButton: TSpeedButton;
BuildMacroDescriptionEdit: TEdit;
BuildMacroSelectedGroupBox: TGroupBox;
BuildMacrosTreeView: TTreeView;
BuildMacroDefaultLabel: TLabel;
BuildMacroDescriptionLabel: TLabel;
ConditionalsGroupBox: TGroupBox;
CondStatusbar: TStatusBar;
CondSynEdit: TSynEdit;
MacrosGroupBox: TGroupBox;
MacrosSplitter: TSplitter;
Splitter1: TSplitter;
procedure BMAddMacroSpeedButtonClick(Sender: TObject);
procedure BMAddMacroValueSpeedButtonClick(Sender: TObject);
procedure BMDeleteSpeedButtonClick(Sender: TObject);
procedure BuildMacrosTreeViewEdited(Sender: TObject; Node: TTreeNode;
var S: string);
procedure BuildMacrosTreeViewEditing(Sender: TObject; Node: TTreeNode;
var AllowEdit: Boolean);
procedure BuildMacrosTreeViewSelectionChanged(Sender: TObject);
procedure CondSynEditChange(Sender: TObject);
procedure CondSynEditProcessCommand(Sender: TObject;
var Command: TSynEditorCommand; var AChar: TUTF8Char; Data: pointer);
procedure CondSynEditProcessUserCommand(Sender: TObject;
var Command: TSynEditorCommand; var AChar: TUTF8Char; Data: pointer);
procedure CondSynEditStatusChange(Sender: TObject;
Changes: TSynStatusChanges);
procedure OnIdle(Sender: TObject; var Done: Boolean);
private
FCompletionValues: TStrings;
FDefaultVariables: TCTCfgScriptVariables;
FHighlighter: TIDESynFreePasSyn;
FBuildMacros: TIDEBuildMacros;
FIdleConnected: Boolean;
FIsPackage: boolean;
FStatusMessage: string;
fVarImgID: LongInt;
fValueImgID: LongInt;
fDefValueImgID: LongInt;
fEngine: TCTConfigScriptEngine;
procedure SaveItemProperties;
procedure SetBuildMacros(const AValue: TIDEBuildMacros);
procedure RebuildTreeView;
procedure SetIdleConnected(const AValue: Boolean);
procedure SetStatusMessage(const AValue: string);
function TreeViewAddBuildMacro(aBuildMacro: TLazBuildMacro): TTreeNode;
procedure TreeViewAddValue(ValuesTVNode: TTreeNode; aValue: string);
function GetNodeInfo(Node: TTreeNode; out BuildMacro: TLazBuildMacro): TCBMNodeType;
function GetSelectedNode(out aBuildMacro: TLazBuildMacro;
out NodeType: TCBMNodeType): TTreeNode;
function GetBuildMacroTVNode(aBuildMacro: TLazBuildMacro): TTreeNode;
function GetMacroNamePrefix(PrefixType: TCBMPrefixType): string;
procedure UpdateItemPropertyControls;
procedure UpdateMessages;
procedure UpdateStatusBar;
procedure StartCompletion;
procedure UpdateCompletionValues;
public
constructor Create(TheOwner: TComponent); override;
destructor Destroy; override;
function GetTitle: String; override;
procedure Setup(ADialog: TAbstractOptionsEditorDialog); override;
class function SupportedOptionsClass: TAbstractIDEOptionsClass; override;
procedure ReadSettings(AOptions: TAbstractIDEOptions); override;
procedure WriteSettings(AOptions: TAbstractIDEOptions); override;
property BuildMacros: TIDEBuildMacros read FBuildMacros write SetBuildMacros; // local copy
procedure LoadFromOptions(Options: TBaseCompilerOptions);
procedure SaveToOptions(Options: TBaseCompilerOptions);
property IdleConnected: Boolean read FIdleConnected write SetIdleConnected;
property StatusMessage: string read FStatusMessage write SetStatusMessage;
property DefaultVariables: TCTCfgScriptVariables read FDefaultVariables;
property CompletionValues: TStrings read FCompletionValues;
property IsPackage: boolean read FIsPackage;
end;
implementation
{$R *.lfm}
{ TCompOptBuildMacrosFrame }
procedure TCompOptBuildMacrosFrame.OnIdle(Sender: TObject; var Done: Boolean);
begin
IdleConnected:=false;
UpdateMessages;
end;
procedure TCompOptBuildMacrosFrame.CondSynEditChange(Sender: TObject);
begin
UpdateStatusBar;
IdleConnected:=true;
end;
procedure TCompOptBuildMacrosFrame.CondSynEditProcessCommand(Sender: TObject;
var Command: TSynEditorCommand; var AChar: TUTF8Char; Data: pointer);
begin
end;
procedure TCompOptBuildMacrosFrame.CondSynEditProcessUserCommand(
Sender: TObject; var Command: TSynEditorCommand; var AChar: TUTF8Char;
Data: pointer);
begin
if (Command=ecWordCompletion) or (Command=ecIdentCompletion) then
StartCompletion;
end;
procedure TCompOptBuildMacrosFrame.CondSynEditStatusChange(Sender: TObject;
Changes: TSynStatusChanges);
begin
UpdateStatusBar;
end;
procedure TCompOptBuildMacrosFrame.BuildMacrosTreeViewEditing(Sender: TObject;
Node: TTreeNode; var AllowEdit: Boolean);
var
BuildProperty: TLazBuildMacro;
NodeType: TCBMNodeType;
begin
NodeType:=GetNodeInfo(Node,BuildProperty);
AllowEdit:=NodeType in [cbmntBuildMacro,cbmntValue];
end;
procedure TCompOptBuildMacrosFrame.BuildMacrosTreeViewSelectionChanged(
Sender: TObject);
begin
UpdateItemPropertyControls;
end;
procedure TCompOptBuildMacrosFrame.BuildMacrosTreeViewEdited(Sender: TObject;
Node: TTreeNode; var S: string);
var
BuildMacro: TLazBuildMacro;
NodeType: TCBMNodeType;
ConflictBuildProperty: TIDEBuildMacro;
Index: LongInt;
Prefix: String;
BetterName: String;
DlgResult: TModalResult;
Vars: TCTCfgScriptVariables;
ok: Boolean;
begin
NodeType:=GetNodeInfo(Node,BuildMacro);
case NodeType of
cbmntBuildMacro:
if S<>BuildMacro.Identifier then begin
// rename build macro
ok:=false;
try
// check syntax
if (S='') or (not IsValidIdent(S)) then begin
MessageDlg(lisCCOErrorCaption,
Format(lisInvalidBuildMacroTheBuildMacroMustBeAPascalIdentifie, ['"',
S, '"']),
mtError,[mbCancel],0);
exit;
end;
// check for prefix
Prefix:=GetMacroNamePrefix(cbmpShort);
if (Prefix<>'') and (SysUtils.CompareText(Prefix,copy(S,1,length(Prefix)))<>0)
then begin
BetterName:=GetMacroNamePrefix(cbmpMedium)+S;
DlgResult:=QuestionDlg('Warning',
'The build macro "'+S+'" does not begin with "'+Prefix+'".',
mtWarning,[mrCancel,mrYes,'Rename to '+BetterName,mrIgnore],0);
if DlgResult=mrIgnore then begin
end else if DlgResult=mrYes then
S:=BetterName
else begin
exit;
end;
end;
// check for keyword
if WordIsKeyWord.DoItCaseInsensitive(S) then begin
MessageDlg(lisCCOErrorCaption,
Format(lisInvalidBuildMacroTheNameIsAKeyword, [S]),
mtError,[mbCancel],0);
exit;
end;
// check for conflicts with built-in macros
if IDEMacros.IsMacro(s) then begin
MessageDlg(lisCCOErrorCaption,
Format(lisThereIsAlreadyAnIDEMacroWithTheName, [S]),
mtError,[mbCancel],0);
exit;
end;
// check for duplicates
ConflictBuildProperty:=BuildMacros.VarWithIdentifier(S);
if ((ConflictBuildProperty<>nil) and (ConflictBuildProperty<>BuildMacro))
or (SysUtils.CompareText('TargetOS',S)=0)
or (SysUtils.CompareText('SrcOS',S)=0)
or (SysUtils.CompareText('SrcOS2',S)=0)
or (SysUtils.CompareText('TargetCPU',S)=0)
or (SysUtils.CompareText('LCLWidgetType',S)=0)
then begin
MessageDlg(lisCCOErrorCaption,
Format(lisThereIsAlreadyABuildMacroWithTheName, ['"', S, '"']),
mtError,[mbCancel],0);
exit;
end;
// check for duplicates with used packages
if (BuildMacros<>nil) and (BuildMacros.Owner is TBaseCompilerOptions) then
begin
Vars:=GetBuildMacroValues(TBaseCompilerOptions(BuildMacros.Owner),false);
if (Vars<>nil) and Vars.IsDefined(PChar(S)) then begin
DlgResult:=MessageDlg('Warning',
Format(lisThereIsAlreadyABuildMacroWithTheName, ['"', S, '"']),
mtWarning,[mbCancel,mbIgnore],0);
if DlgResult<>mrIgnore then
exit;
end;
end;
ok:=true;
finally
if not ok then
S:=BuildMacro.Identifier;
end;
// rename build macro
BuildMacro.Identifier:=S;
end;
cbmntValue:
begin
Index:=Node.Index;
Index:=BuildMacro.Values.IndexOf(S);
if (Index>=0) and (Index<>Node.Index) then begin
MessageDlg(lisCCOErrorCaption,
Format(lisDuplicateFoundOfValue, ['"', S, '"']),
mtError,[mbCancel],0);
S:=BuildMacro.Values[Node.Index];
exit;
end;
BuildMacro.Values[Node.Index]:=S;
end;
end;
end;
procedure TCompOptBuildMacrosFrame.BMAddMacroSpeedButtonClick(Sender: TObject);
var
NewIdentifier: String;
NewBuildMacro: TLazBuildMacro;
i: Integer;
TVNode: TTreeNode;
begin
i:=1;
repeat
NewIdentifier:=GetMacroNamePrefix(cbmpLong)+IntToStr(BuildMacros.Count+1);
if BuildMacros.IndexOfIdentifier(NewIdentifier)<0 then break;
inc(i);
until false;
NewBuildMacro:=BuildMacros.Add(NewIdentifier);
// add to TreeView
BuildMacrosTreeView.BeginUpdate;
TVNode:=TreeViewAddBuildMacro(NewBuildMacro);
BuildMacrosTreeView.Selected:=TVNode;
BuildMacrosTreeView.EndUpdate;
UpdateItemPropertyControls;
end;
procedure TCompOptBuildMacrosFrame.BMAddMacroValueSpeedButtonClick(
Sender: TObject);
var
BuildMacro: TLazBuildMacro;
NodeType: TCBMNodeType;
i: Integer;
NewValueStr: String;
ValuesTVNode: TTreeNode;
begin
GetSelectedNode(BuildMacro,NodeType);
if BuildMacro=nil then exit;
i:=1;
repeat
NewValueStr:=Format(lisValue2, [IntToStr(i)]);
if BuildMacro.Values.IndexOf(NewValueStr)<0 then break;
inc(i);
until false;
BuildMacro.Values.Add(NewValueStr);
BuildMacrosTreeView.BeginUpdate;
ValuesTVNode:=GetBuildMacroTVNode(BuildMacro);
TreeViewAddValue(ValuesTVNode,NewValueStr);
ValuesTVNode.Expand(true);
BuildMacrosTreeView.EndUpdate;
end;
procedure TCompOptBuildMacrosFrame.BMDeleteSpeedButtonClick(Sender: TObject);
var
aBuildMacro: TIDEBuildMacro;
SelTVNode: TTreeNode;
NodeType: TCBMNodeType;
i: LongInt;
aValue: String;
begin
SelTVNode:=GetSelectedNode(TLazBuildMacro(aBuildMacro),NodeType);
if aBuildMacro=nil then exit;
if NodeType=cbmntValue then
begin
aValue:=SelTVNode.Text;
if MessageDlg(lisConfirmDelete,
Format(lisDeleteValue, ['"', aValue, '"']),
mtConfirmation,[mbYes,mbCancel],0)<>mrYes
then exit;
i:=aBuildMacro.Values.IndexOf(aValue);
if i>=0 then aBuildMacro.Values.Delete(i);
end else begin
if MessageDlg(lisConfirmDelete,
Format(lisDeleteBuildMacro, ['"', aBuildMacro.Identifier, '"']),
mtConfirmation,[mbYes,mbCancel],0)<>mrYes
then exit;
i:=BuildMacros.IndexOfIdentifier(aBuildMacro.Identifier);
BuildMacros.Delete(i);
end;
BuildMacrosTreeView.BeginUpdate;
SelTVNode.Delete;
BuildMacrosTreeView.EndUpdate;
end;
procedure TCompOptBuildMacrosFrame.SetBuildMacros(
const AValue: TIDEBuildMacros);
begin
if FBuildMacros=AValue then exit;
BuildMacros.Assign(AValue);
RebuildTreeView;
UpdateItemPropertyControls;
IdleConnected:=true;
end;
procedure TCompOptBuildMacrosFrame.RebuildTreeView;
var
i: Integer;
begin
BuildMacrosTreeView.BeginUpdate;
BuildMacrosTreeView.Items.Clear;
if BuildMacros<>nil then begin
// first level: build macros
for i:=0 to BuildMacros.Count-1 do
TreeViewAddBuildMacro(BuildMacros.Items[i]);
end;
BuildMacrosTreeView.EndUpdate;
end;
procedure TCompOptBuildMacrosFrame.SetIdleConnected(const AValue: Boolean);
begin
if FIdleConnected=AValue then exit;
FIdleConnected:=AValue;
if FIdleConnected then
Application.AddOnIdleHandler(@OnIdle)
else
Application.RemoveOnIdleHandler(@OnIdle);
end;
procedure TCompOptBuildMacrosFrame.SetStatusMessage(const AValue: string);
begin
if FStatusMessage=AValue then exit;
FStatusMessage:=AValue;
CondStatusbar.Panels[2].Text := FStatusMessage;
end;
function TCompOptBuildMacrosFrame.TreeViewAddBuildMacro(
aBuildMacro: TLazBuildMacro): TTreeNode;
var
Values: TStrings;
i: Integer;
begin
// create node for the build macro
Result:=BuildMacrosTreeView.Items.AddObject(nil,aBuildMacro.Identifier,aBuildMacro);
Result.ImageIndex:=fVarImgID;
Result.SelectedIndex:=Result.ImageIndex;
// second level
begin
// a node for each value
Values:=aBuildMacro.Values;
for i:=0 to Values.Count-1 do
TreeViewAddValue(Result,Values[i]);
end;
//DebugLn(['TCompOptBuildMacrosFrame.TreeViewAddBuildMacro ',TVNode.Text]);
Result.Expand(true);
end;
procedure TCompOptBuildMacrosFrame.TreeViewAddValue(ValuesTVNode: TTreeNode;
aValue: string);
var
ValueTVNode: TTreeNode;
begin
ValueTVNode:=BuildMacrosTreeView.Items.AddChild(ValuesTVNode,aValue);
ValueTVNode.ImageIndex:=fValueImgID;
ValueTVNode.SelectedIndex:=ValueTVNode.ImageIndex;
end;
function TCompOptBuildMacrosFrame.GetNodeInfo(Node: TTreeNode; out
BuildMacro: TLazBuildMacro): TCBMNodeType;
function GetNodeType(CurNode: TTreeNode): TCBMNodeType;
var
ParentType: TCBMNodeType;
begin
if CurNode=nil then
Result:=cbmntNone
else if TObject(CurNode.Data) is TLazBuildMacro then begin
BuildMacro:=TLazBuildMacro(CurNode.Data);
Result:=cbmntBuildMacro;
end else begin
ParentType:=GetNodeType(CurNode.Parent);
case ParentType of
cbmntBuildMacro:
Result:=cbmntValue;
end;
end;
end;
begin
BuildMacro:=nil;
Result:=GetNodeType(Node);
end;
function TCompOptBuildMacrosFrame.GetSelectedNode(out
aBuildMacro: TLazBuildMacro; out NodeType: TCBMNodeType): TTreeNode;
begin
Result:=BuildMacrosTreeView.Selected;
NodeType:=GetNodeInfo(Result,aBuildMacro);
end;
function TCompOptBuildMacrosFrame.GetBuildMacroTVNode(aBuildMacro: TLazBuildMacro
): TTreeNode;
begin
Result:=BuildMacrosTreeView.Items.GetFirstNode;
while (Result<>nil) and (TObject(Result.Data)<>aBuildMacro) do
Result:=Result.GetNextSibling;
end;
function TCompOptBuildMacrosFrame.GetMacroNamePrefix(PrefixType: TCBMPrefixType
): string;
begin
if PrefixType=cbmpShort then
Result:=''
else
Result:='BuildMacro';
if (BuildMacros=nil) or (BuildMacros.Owner=nil) then exit;
if BuildMacros.Owner is TPkgCompilerOptions then
begin
Result:=TPkgCompilerOptions(BuildMacros.Owner).LazPackage.Name;
if ord(PrefixType)>=ord(cbmpMedium) then
Result:=Result+'_';
if PrefixType=cbmpLong then
Result:=Result+'macro';
end;
end;
procedure TCompOptBuildMacrosFrame.UpdateItemPropertyControls;
var
aBuildMacro: TLazBuildMacro;
NodeType: TCBMNodeType;
begin
GetSelectedNode(aBuildMacro,NodeType);
if aBuildMacro<>nil then begin
BuildMacroSelectedGroupBox.Caption:='Macro '+aBuildMacro.Identifier;
BuildMacroSelectedGroupBox.Enabled:=true;
BuildMacroDescriptionEdit.Enabled:=true;
BuildMacroDescriptionEdit.Text:=aBuildMacro.Description;
BMAddMacroValueSpeedButton.Hint:='Add value to macro '+aBuildMacro.Identifier;
BMDeleteSpeedButton.Hint:='Delete macro '+aBuildMacro.Identifier;
end else begin
BuildMacroSelectedGroupBox.Caption:='No macro selected';
BuildMacroSelectedGroupBox.Enabled:=false;
BuildMacroDescriptionEdit.Enabled:=false;
BuildMacroDescriptionEdit.Text:='';
BMAddMacroValueSpeedButton.Hint:='';
BMDeleteSpeedButton.Hint:='';
end;
BMAddMacroSpeedButton.Hint:='Add new macro';
BMAddMacroValueSpeedButton.Enabled:=NodeType in [cbmntBuildMacro,cbmntValue];
BMDeleteSpeedButton.Enabled:=NodeType in [cbmntBuildMacro,cbmntValue];
end;
procedure TCompOptBuildMacrosFrame.UpdateMessages;
begin
fEngine.Variables.Assign(DefaultVariables);
fEngine.Execute(CondSynEdit.Lines.Text,1);
if fEngine.ErrorCount>0 then begin
StatusMessage:=fEngine.GetErrorStr(0);
end else begin
StatusMessage:='No errors';
end;
end;
procedure TCompOptBuildMacrosFrame.UpdateStatusBar;
var
PanelCharMode: String;
PanelXY: String;
begin
PanelXY := Format(' %6d:%4d',[CondSynEdit.CaretY,CondSynEdit.CaretX]);
if CondSynEdit.InsertMode then
PanelCharMode := uepIns
else
PanelCharMode := uepOvr;
CondStatusbar.Panels[0].Text := PanelXY;
CondStatusbar.Panels[1].Text := PanelCharMode;
end;
procedure TCompOptBuildMacrosFrame.StartCompletion;
begin
UpdateCompletionValues;
end;
procedure TCompOptBuildMacrosFrame.UpdateCompletionValues;
function HasWord(const aName: string): Boolean;
var
i: Integer;
s: string;
p: LongInt;
begin
for i:=0 to CompletionValues.Count-1 do begin
s:=CompletionValues[i];
p:=System.Pos(#9,s);
if p>0 then
s:=copy(s,1,p-1);
if SysUtils.CompareText(s,aName)=0 then exit(true);
end;
Result:=false;
end;
procedure AddVar(aName, aValue: string);
var
s: String;
begin
s:=dbgstr(aValue);
if length(s)>50 then s:=copy(s,1,50)+'...';
s:=aName+#9+aValue;
CompletionValues.Add(s);
end;
procedure AddKeyword(aName: string);
begin
CompletionValues.Add(aName);
end;
procedure AddWord(aName: string);
begin
aName:=dbgstr(aName);
if aName='' then exit;
if HasWord(aName) then exit;
CompletionValues.Add(aName);
end;
var
Node: TAVLTreeNode;
V: PCTCfgScriptVariable;
s: String;
p: PChar;
AtomStart: PChar;
Macro: TLazBuildMacro;
pcov: TParsedCompilerOptString;
pcouv: TParsedCompilerOptString;
i: Integer;
j: Integer;
begin
CompletionValues.Clear;
// add default variables with values
Node:=DefaultVariables.Tree.FindLowest;
while Node<>nil do begin
V:=PCTCfgScriptVariable(Node.Data);
AddVar(V^.Name,GetCTCSVariableAsString(V));
Node:=DefaultVariables.Tree.FindSuccessor(Node);
end;
// add keywords and operands
AddKeyword('if');
AddKeyword('then');
AddKeyword('else');
AddKeyword('begin');
AddKeyword('end');
AddKeyword('not');
AddKeyword('and');
AddKeyword('or');
AddKeyword('xor');
AddKeyword('undefine');
AddKeyword('defined');
AddKeyword('undefined');
AddKeyword('integer');
AddKeyword('int64');
AddKeyword('string');
AddKeyword('true');
AddKeyword('false');
// add result variables
for pcov:=low(ParsedCompilerOptsVars) to high(ParsedCompilerOptsVars) do
AddWord(ParsedCompilerOptsVars[pcov]);
if FIsPackage then
for pcouv:=low(ParsedCompilerOptsUsageVars) to high(ParsedCompilerOptsUsageVars) do
AddWord(ParsedCompilerOptsUsageVars[pcouv]);
// add build macros and values
if BuildMacros<>nil then begin
for i:=0 to BuildMacros.Count-1 do
begin
Macro:=BuildMacros[i];
AddWord(Macro.Identifier);
for j:=0 to Macro.Values.Count-1 do
AddWord(Macro.Values[j]);
end;
end;
// add words in text
s:=CondSynEdit.Lines.Text;
if s<>'' then begin
p:=PChar(s);
repeat
AtomStart:=p;
while (AtomStart^<>#0) and not IsIdentStartChar[AtomStart^] do
inc(AtomStart);
if (AtomStart^=#0) then break;
p:=AtomStart;
while IsIdentChar[p^] do inc(p);
AddWord(copy(s,AtomStart-PChar(s)+1,p-AtomStart));
until false;
end;
debugln(['TCompOptBuildMacrosFrame.UpdateCompletionValues ',CompletionValues.Text]);
end;
procedure TCompOptBuildMacrosFrame.SaveItemProperties;
var
BuildMacro: TLazBuildMacro;
NodeType: TCBMNodeType;
begin
GetSelectedNode(BuildMacro,NodeType);
if BuildMacro=nil then exit;
BuildMacro.Description:=BuildMacroDescriptionEdit.Text;
end;
constructor TCompOptBuildMacrosFrame.Create(TheOwner: TComponent);
begin
inherited Create(TheOwner);
FCompletionValues:=TStringList.Create;
fDefaultVariables:=TCTCfgScriptVariables.Create;
FBuildMacros:=TIDEBuildMacros.Create(nil);
fEngine:=TCTConfigScriptEngine.Create;
MacrosGroupBox.Caption:='Build macros:';
BuildMacrosTreeView.Images := IDEImages.Images_24;
fVarImgID:=IDEImages.LoadImage(24,'da_define');
fValueImgID:=IDEImages.LoadImage(24,'da_define');
fDefValueImgID:=IDEImages.LoadImage(24,'da_define');
BuildMacroDefaultLabel.Caption:='Hint: A default value can be defined in the conditionals.';
BuildMacroDescriptionLabel.Caption:='Description:';
ConditionalsGroupBox.Caption:='Conditionals:';
CondSynEdit.OnStatusChange:=@CondSynEditStatusChange;
BMAddMacroSpeedButton.LoadGlyphFromLazarusResource('laz_add');
BMAddMacroValueSpeedButton.LoadGlyphFromLazarusResource('laz_add');
BMDeleteSpeedButton.LoadGlyphFromLazarusResource('laz_delete');
end;
destructor TCompOptBuildMacrosFrame.Destroy;
begin
FreeAndNil(FCompletionValues);
FreeAndNil(fDefaultVariables);
FreeAndNil(fEngine);
FreeAndNil(FBuildMacros);
inherited Destroy;
end;
function TCompOptBuildMacrosFrame.GetTitle: String;
begin
Result:='Build macros';
end;
procedure TCompOptBuildMacrosFrame.ReadSettings(AOptions: TAbstractIDEOptions);
begin
if AOptions is TBaseCompilerOptions then
LoadFromOptions(TBaseCompilerOptions(AOptions));
end;
procedure TCompOptBuildMacrosFrame.Setup(ADialog: TAbstractOptionsEditorDialog
);
begin
end;
class function TCompOptBuildMacrosFrame.SupportedOptionsClass: TAbstractIDEOptionsClass;
begin
Result := TBaseCompilerOptions;
end;
procedure TCompOptBuildMacrosFrame.WriteSettings(AOptions: TAbstractIDEOptions
);
begin
if AOptions is TBaseCompilerOptions then
SaveToOptions(TBaseCompilerOptions(AOptions));
end;
procedure TCompOptBuildMacrosFrame.LoadFromOptions(Options: TBaseCompilerOptions
);
var
Vars: TCTCfgScriptVariables;
begin
FIsPackage:=Options is TPkgCompilerOptions;
BuildMacros:=Options.BuildMacros as TIDEBuildMacros;
Vars:=GetBuildMacroValues(Options,false);
if Vars<>nil then
DefaultVariables.Assign(Vars);
CondSynEdit.Lines.Text:=Options.Conditionals;
EditorOpts.GetSynEditSettings(CondSynEdit);
if FHighlighter=nil then
begin
FHighlighter := TPreviewPasSyn.Create(Self);
CondSynEdit.Highlighter:=FHighlighter;
end;
EditorOpts.ReadHighlighterSettings(FHighlighter, '');
UpdateStatusBar;
end;
procedure TCompOptBuildMacrosFrame.SaveToOptions(Options: TBaseCompilerOptions
);
begin
SaveItemProperties;
(Options.BuildMacros as TIDEBuildMacros).Assign(BuildMacros);
Options.Conditionals:=CondSynEdit.Lines.Text;
end;
{$IFDEF EnableBuildModes}
initialization
RegisterIDEOptionsEditor(GroupCompiler, TCompOptBuildMacrosFrame,
CompilerOptionsConditional);
{$ENDIF}
end.