mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-05 12:12:40 +02:00
1073 lines
33 KiB
ObjectPascal
1073 lines
33 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, Math, types, AVL_Tree, LCLProc, FileUtil, Controls, Forms,
|
|
StdCtrls, Grids, LCLType, Buttons, ExtCtrls, Dialogs, ComCtrls, Menus,
|
|
AvgLvlTree, SynEdit, SynHighlighterPas, SynEditKeyCmds, SynCompletion,
|
|
KeywordFuncLists, CodeToolsCfgScript, IDEImagesIntf, IDECommands, ProjectIntf,
|
|
PackageIntf, IDEOptionsIntf, MacroIntf, CompilerOptions, EditorOptions,
|
|
CompOptsIntf, IDEDialogs, LazarusIDEStrConsts, CompOptsModes, SourceSynEditor,
|
|
PackageDefs;
|
|
|
|
type
|
|
TCBMNodeType = (
|
|
cbmntNone,
|
|
cbmntBuildMacro,
|
|
cbmntValue
|
|
);
|
|
TCBMPrefixType = (
|
|
cbmpShort,
|
|
cbmpMedium,
|
|
cbmpLong
|
|
);
|
|
|
|
{ TCompOptBuildMacrosFrame }
|
|
|
|
TCompOptBuildMacrosFrame = class(TAbstractIDEOptionsEditor)
|
|
BMAddMacroSpeedButton: TSpeedButton;
|
|
BMAddMacroValueSpeedButton: TSpeedButton;
|
|
BMDeleteMacroSpeedButton: 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 BMDeleteMacroSpeedButtonClick(Sender: TObject);
|
|
procedure BuildMacroDescriptionEditExit(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 CondSynEditKeyPress(Sender: TObject; var Key: char);
|
|
procedure CondSynEditProcessUserCommand(Sender: TObject;
|
|
var Command: TSynEditorCommand; var AChar: TUTF8Char; Data: pointer);
|
|
procedure CondSynEditStatusChange(Sender: TObject;
|
|
Changes: TSynStatusChanges);
|
|
procedure fSynCompletionCancel(Sender: TObject);
|
|
procedure fSynCompletionExecute(Sender: TObject);
|
|
procedure fSynCompletionKeyCompletePrefix(Sender: TObject);
|
|
procedure fSynCompletionKeyDelete(Sender: TObject);
|
|
procedure fSynCompletionKeyDown(Sender: TObject; var Key: Word;
|
|
Shift: TShiftState);
|
|
procedure fSynCompletionKeyNextChar(Sender: TObject);
|
|
procedure fSynCompletionKeyPrevChar(Sender: TObject);
|
|
procedure fSynCompletionSearchPosition(var Position: integer);
|
|
procedure fSynCompletionUTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
|
|
procedure fSynCompletionValidate(Sender: TObject; KeyChar: TUTF8Char;
|
|
Shift: TShiftState);
|
|
procedure OnIdle(Sender: TObject; var Done: Boolean);
|
|
private
|
|
FCompletionHistory: TStrings;
|
|
FCompletionValues: TStrings;
|
|
FDefaultVariables: TCTCfgScriptVariables;
|
|
FHighlighter: TIDESynFreePasSyn;
|
|
FBuildMacros: TIDEBuildMacros;
|
|
FIdleConnected: Boolean;
|
|
FIsPackage: boolean;
|
|
FMacrosOwner: TObject;
|
|
FStatusMessage: string;
|
|
fVarImgID: LongInt;
|
|
fValueImgID: LongInt;
|
|
fDefValueImgID: LongInt;
|
|
fEngine: TIDECfgScriptEngine;
|
|
fSynCompletion: TSynCompletion;
|
|
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;
|
|
function GetCondCursorWord: string;
|
|
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
|
|
property MacrosOwner: TObject read FMacrosOwner;
|
|
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 IsPackage: boolean read FIsPackage;
|
|
property CompletionValues: TStrings read FCompletionValues;
|
|
property CompletionHistory: TStrings read FCompletionHistory;
|
|
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.CondSynEditKeyPress(Sender: TObject;
|
|
var Key: char);
|
|
begin
|
|
//debugln(['TCompOptBuildMacrosFrame.CondSynEditKeyPress ',ord(Key)]);
|
|
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
|
|
if fSynCompletion.TheForm.Visible then
|
|
begin
|
|
//debugln(['TCompOptBuildMacrosFrame.CondSynEditStatusChange ']);
|
|
fSynCompletion.CurrentString := GetCondCursorWord;
|
|
end;
|
|
UpdateStatusBar;
|
|
end;
|
|
|
|
procedure TCompOptBuildMacrosFrame.fSynCompletionCancel(Sender: TObject);
|
|
begin
|
|
//debugln(['TCompOptBuildMacrosFrame.fSynCompletionCancel ',fSynCompletion.TheForm.Visible]);
|
|
if fSynCompletion.TheForm.Visible then
|
|
fSynCompletion.Deactivate;
|
|
fSynCompletion.RemoveEditor(CondSynEdit);
|
|
end;
|
|
|
|
procedure TCompOptBuildMacrosFrame.fSynCompletionExecute(Sender: TObject);
|
|
begin
|
|
//debugln(['TCompOptBuildMacrosFrame.fSynCompletionExecute ']);
|
|
end;
|
|
|
|
procedure TCompOptBuildMacrosFrame.fSynCompletionKeyCompletePrefix(
|
|
Sender: TObject);
|
|
begin
|
|
//debugln(['TCompOptBuildMacrosFrame.fSynCompletionKeyCompletePrefix ToDo']);
|
|
end;
|
|
|
|
procedure TCompOptBuildMacrosFrame.fSynCompletionKeyDelete(Sender: TObject);
|
|
begin
|
|
//debugln(['TCompOptBuildMacrosFrame.fSynCompletionKeyDelete']);
|
|
end;
|
|
|
|
procedure TCompOptBuildMacrosFrame.fSynCompletionKeyDown(Sender: TObject;
|
|
var Key: Word; Shift: TShiftState);
|
|
begin
|
|
//debugln(['TCompOptBuildMacrosFrame.fSynCompletionKeyDown ']);
|
|
if Key=VK_BACK then
|
|
begin
|
|
Key:=VK_UNKNOWN;
|
|
if fSynCompletion.CurrentString<>'' then
|
|
CondSynEdit.CommandProcessor(ecDeleteLastChar,#0,nil);
|
|
end;
|
|
end;
|
|
|
|
procedure TCompOptBuildMacrosFrame.fSynCompletionKeyNextChar(Sender: TObject);
|
|
var
|
|
XY: TPoint;
|
|
StartX: integer;
|
|
EndX: integer;
|
|
Line: string;
|
|
begin
|
|
XY:=CondSynEdit.LogicalCaretXY;
|
|
if XY.Y>CondSynEdit.Lines.Count then exit;
|
|
CondSynEdit.GetWordBoundsAtRowCol(XY,StartX,EndX);
|
|
if EndX<=XY.X then exit;
|
|
Line := CondSynEdit.Lines[XY.Y - 1];
|
|
inc(XY.X,UTF8CharacterLength(@Line[XY.X-1]));
|
|
CondSynEdit.LogicalCaretXY:=XY;
|
|
end;
|
|
|
|
procedure TCompOptBuildMacrosFrame.fSynCompletionKeyPrevChar(Sender: TObject);
|
|
var
|
|
XY: TPoint;
|
|
StartX: integer;
|
|
EndX: integer;
|
|
Line: string;
|
|
begin
|
|
XY:=CondSynEdit.LogicalCaretXY;
|
|
if XY.Y>CondSynEdit.Lines.Count then exit;
|
|
CondSynEdit.GetWordBoundsAtRowCol(XY,StartX,EndX);
|
|
if StartX>=XY.X then exit;
|
|
Line := CondSynEdit.Lines[XY.Y - 1];
|
|
XY.X:=UTF8FindNearestCharStart(PChar(Line),length(Line),XY.X-2)+1;
|
|
CondSynEdit.LogicalCaretXY:=XY;
|
|
end;
|
|
|
|
procedure TCompOptBuildMacrosFrame.fSynCompletionSearchPosition(
|
|
var Position: integer);
|
|
var
|
|
sl: TStringList;
|
|
Prefix: String;
|
|
s: string;
|
|
i: Integer;
|
|
begin
|
|
//debugln(['TCompOptBuildMacrosFrame.fSynCompletionSearchPosition "',fSynCompletion.CurrentString,'"']);
|
|
Prefix:=fSynCompletion.CurrentString;
|
|
sl:=TStringList.Create;
|
|
try
|
|
Position:=-1;
|
|
for i:=0 to CompletionValues.Count-1 do
|
|
begin
|
|
s:=CompletionValues[i];
|
|
if SysUtils.CompareText(Prefix,copy(s,1,length(Prefix)))<>0 then continue;
|
|
if (Position<0) or (length(Prefix)=length(s)) then
|
|
Position:=sl.Count;
|
|
sl.AddObject(s,TObject({%H-}Pointer(i)));
|
|
end;
|
|
fSynCompletion.ItemList.Assign(sl);
|
|
finally
|
|
sl.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TCompOptBuildMacrosFrame.fSynCompletionUTF8KeyPress(Sender: TObject;
|
|
var UTF8Key: TUTF8Char);
|
|
begin
|
|
//debugln(['TCompOptBuildMacrosFrame.fSynCompletionUTF8KeyPress ']);
|
|
end;
|
|
|
|
procedure TCompOptBuildMacrosFrame.fSynCompletionValidate(Sender: TObject;
|
|
KeyChar: TUTF8Char; Shift: TShiftState);
|
|
var
|
|
i: LongInt;
|
|
s: string;
|
|
p: LongInt;
|
|
TxtXY: TPoint;
|
|
TxtStartX: integer;
|
|
TxtEndX: integer;
|
|
begin
|
|
//debugln(['TCompOptBuildMacrosFrame.fSynCompletionValidate ']);
|
|
i:=fSynCompletion.Position;
|
|
if (i>=0) and (i<fSynCompletion.ItemList.Count) then begin
|
|
i:=PtrUInt(fSynCompletion.ItemList.Objects[i]);
|
|
if (i>=0) and (i<CompletionValues.Count) then begin
|
|
s:=CompletionValues[i];
|
|
p:=System.Pos(#9,s);
|
|
if p>0 then s:=copy(s,1,p-1);
|
|
TxtXY:=CondSynEdit.LogicalCaretXY;
|
|
CondSynEdit.GetWordBoundsAtRowCol(TxtXY,TxtStartX,TxtEndX);
|
|
CondSynEdit.BeginUndoBlock{$IFDEF SynUndoDebugBeginEnd}('TCompOptBuildMacrosFrame.fSynCompletionValidate'){$ENDIF};
|
|
try
|
|
CondSynEdit.BlockBegin:=Point(TxtStartX,TxtXY.Y);
|
|
CondSynEdit.BlockEnd:=Point(TxtEndX,TxtXY.Y);
|
|
CondSynEdit.SelText:=s;
|
|
finally
|
|
CondSynEdit.EndUndoBlock{$IFDEF SynUndoDebugBeginEnd}('TCompOptBuildMacrosFrame.fSynCompletionValidate'){$ENDIF};
|
|
end;
|
|
FCompletionHistory.Insert(0,s);
|
|
if FCompletionHistory.Count>100 then
|
|
FCompletionHistory.Delete(FCompletionHistory.Count-1);
|
|
end;
|
|
end;
|
|
|
|
fSynCompletion.Deactivate;
|
|
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(lisInvalidMacroTheMacroMustBeAPascalIdentifie, ['"', 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:=IDEQuestionDialog(lisCCOWarningCaption,
|
|
Format(lisTheMacroDoesNotBeginWith, [S, Prefix]),
|
|
mtWarning, [mrCancel, mrYes, Format(lisRenameTo, [BetterName]),
|
|
mrIgnore]);
|
|
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(lisInvalidMacroTheNameIsAKeyword, [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(lisThereIsAlreadyAMacroWithTheName, ['"', 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(lisCCOWarningCaption,
|
|
Format(lisThereIsAlreadyAMacroWithTheName, ['"', 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
|
|
//debugln(['TCompOptBuildMacrosFrame.BMAddMacroSpeedButtonClick ',GetMacroNamePrefix(cbmpLong)]);
|
|
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.BMDeleteMacroSpeedButtonClick(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(lisDeleteMacro, ['"', 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.BuildMacroDescriptionEditExit(Sender: TObject);
|
|
var
|
|
BuildMacro: TLazBuildMacro;
|
|
NodeType: TCBMNodeType;
|
|
begin
|
|
GetSelectedNode(BuildMacro,NodeType);
|
|
if BuildMacro<>nil then
|
|
BuildMacro.Description:=BuildMacroDescriptionEdit.Text;
|
|
end;
|
|
|
|
procedure TCompOptBuildMacrosFrame.SetBuildMacros(
|
|
const AValue: TIDEBuildMacros);
|
|
begin
|
|
if FBuildMacros=AValue then exit;
|
|
if AValue<>nil then
|
|
begin
|
|
BuildMacros.Assign(AValue);
|
|
FMacrosOwner:=AValue.Owner;
|
|
end else begin
|
|
FMacrosOwner:=nil;
|
|
end;
|
|
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 (MacrosOwner=nil) then
|
|
exit;
|
|
if MacrosOwner is TPkgCompilerOptions then
|
|
begin
|
|
Result:=TPkgCompilerOptions(MacrosOwner).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:=Format(lisMacro, [aBuildMacro.Identifier]);
|
|
BuildMacroSelectedGroupBox.Enabled:=true;
|
|
BuildMacroDescriptionEdit.Enabled:=true;
|
|
BuildMacroDescriptionEdit.Text:=aBuildMacro.Description;
|
|
BMAddMacroValueSpeedButton.Hint:=Format(lisAddValueToMacro, [aBuildMacro.Identifier]);
|
|
if NodeType=cbmntBuildMacro then
|
|
BMDeleteMacroSpeedButton.Hint:=Format(lisDeleteMacro, ['"',aBuildMacro.Identifier,'"'])
|
|
else
|
|
BMDeleteMacroSpeedButton.Hint:=Format(lisDeleteValue2, [BuildMacrosTreeView.
|
|
Selected.Text]);
|
|
end else begin
|
|
BuildMacroSelectedGroupBox.Caption:=lisNoMacroSelected;
|
|
BuildMacroSelectedGroupBox.Enabled:=false;
|
|
BuildMacroDescriptionEdit.Enabled:=false;
|
|
BuildMacroDescriptionEdit.Text:='';
|
|
BMAddMacroValueSpeedButton.Hint:='';
|
|
BMDeleteMacroSpeedButton.Hint:='';
|
|
end;
|
|
BMAddMacroSpeedButton.Hint:=lisAddNewMacro;
|
|
BMAddMacroValueSpeedButton.Enabled:=NodeType in [cbmntBuildMacro,cbmntValue];
|
|
BMDeleteMacroSpeedButton.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:=lisNoErrors;
|
|
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;
|
|
|
|
function EditorRowColumnToCompletionXY(ScreenRowCol: TPoint;
|
|
AboveRow: boolean): TPoint;
|
|
begin
|
|
if not AboveRow then
|
|
inc(ScreenRowCol.Y,1);
|
|
Result:=CondSynEdit.RowColumnToPixels(ScreenRowCol);
|
|
Result:=CondSynEdit.ClientToScreen(Result);
|
|
if fSynCompletion.TheForm.Parent<>nil then
|
|
Result:=fSynCompletion.TheForm.Parent.ScreenToClient(Result);
|
|
end;
|
|
|
|
var
|
|
LogStartX: integer;
|
|
LogEndX: integer;
|
|
LogXY: TPoint;
|
|
ScreenXY: TPoint;
|
|
XY: TPoint;
|
|
Line: String;
|
|
begin
|
|
//debugln(['TCompOptBuildMacrosFrame.StartCompletion ']);
|
|
UpdateCompletionValues;
|
|
fSynCompletion.ItemList.Assign(CompletionValues);
|
|
|
|
// get row and column of word start at cursor
|
|
LogXY:=CondSynEdit.LogicalCaretXY;
|
|
CondSynEdit.GetWordBoundsAtRowCol(LogXY,LogStartX,LogEndX);
|
|
LogEndX:=Min(LogEndX,LogXY.X);
|
|
// convert text row,column to screen row,column
|
|
ScreenXY:=CondSynEdit.PhysicalToLogicalPos(Point(LogStartX,LogXY.Y));
|
|
// convert screen row,column to coordinates for the completion form
|
|
XY:=EditorRowColumnToCompletionXY(ScreenXY,false);
|
|
|
|
if XY.Y+fSynCompletion.TheForm.Height>fSynCompletion.TheForm.Parent.ClientHeight
|
|
then begin
|
|
// place completion above text
|
|
XY:=EditorRowColumnToCompletionXY(ScreenXY,true);
|
|
dec(XY.Y,fSynCompletion.TheForm.Height);
|
|
end;
|
|
|
|
// show completion box
|
|
fSynCompletion.AddEditor(CondSynEdit);
|
|
Line:=CondSynEdit.LineText;
|
|
fSynCompletion.Execute(copy(Line,LogStartX,LogEndX-LogStartX),XY.X,XY.Y);
|
|
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 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;
|
|
|
|
procedure AddVar(aName, aValue: string);
|
|
var
|
|
s: String;
|
|
begin
|
|
aName:=dbgstr(aName);
|
|
if aName='' then exit;
|
|
if HasWord(aName) then exit;
|
|
s:=dbgstr(aValue);
|
|
if length(s)>50 then s:=copy(s,1,50)+'...';
|
|
s:=aName+#9+aValue;
|
|
CompletionValues.Add(s);
|
|
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 IDE functions
|
|
AddWord('GetIDEValue(''OS'')');
|
|
AddWord('GetIDEValue(''CPU'')');
|
|
AddWord('GetIDEValue(''SrcOS'')');
|
|
AddWord('GetIDEValue(''SrcOS2'')');
|
|
AddWord('GetIDEValue(''LCLWidgetType'')');
|
|
AddWord('GetEnv(''USER'')');
|
|
AddWord('GetEnv(''HOME'')');
|
|
|
|
// 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;
|
|
|
|
// sort alphabetically
|
|
TStringList(FCompletionValues).Sort;
|
|
|
|
// push recently used words upwards
|
|
for i:=CompletionHistory.Count-1 downto 0 do begin
|
|
j:=CompletionValues.IndexOf(CompletionHistory[i]);
|
|
if j>0 then
|
|
CompletionValues.Move(j,0);
|
|
end;
|
|
|
|
// set index
|
|
for i:=0 to CompletionValues.Count-1 do
|
|
CompletionValues.Objects[i]:=TObject({%H-}Pointer(i));
|
|
|
|
//debugln(['TCompOptBuildMacrosFrame.UpdateCompletionValues ',CompletionValues.Text]);
|
|
end;
|
|
|
|
function TCompOptBuildMacrosFrame.GetCondCursorWord: string;
|
|
var
|
|
XY: TPoint;
|
|
StartX: integer;
|
|
EndX: integer;
|
|
Line: string;
|
|
begin
|
|
XY:=CondSynEdit.LogicalCaretXY;
|
|
if (XY.Y>=1) and (XY.Y<=CondSynEdit.Lines.Count) then
|
|
begin
|
|
CondSynEdit.GetWordBoundsAtRowCol(XY,StartX,EndX);
|
|
//debugln(['TCompOptBuildMacrosFrame.GetCondCursorWord ',StartX,' ',EndX,' ',XY.X]);
|
|
EndX:=Min(EndX,XY.X);
|
|
Line := CondSynEdit.Lines[XY.Y - 1];
|
|
Result:= Copy(Line, StartX, EndX - StartX);
|
|
end else
|
|
Result:='';
|
|
//debugln(['TCompOptBuildMacrosFrame.GetCondCursorWord "',Result,'"']);
|
|
end;
|
|
|
|
constructor TCompOptBuildMacrosFrame.Create(TheOwner: TComponent);
|
|
begin
|
|
inherited Create(TheOwner);
|
|
|
|
FCompletionValues:=TStringList.Create;
|
|
FCompletionHistory:=TStringList.Create;
|
|
fDefaultVariables:=TCTCfgScriptVariables.Create;
|
|
FBuildMacros:=TIDEBuildMacros.Create(nil);
|
|
fEngine:=TIDECfgScriptEngine.Create;
|
|
|
|
MacrosGroupBox.Caption:=lisIDEMacros;
|
|
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:=
|
|
lisHintADefaultValueCanBeDefinedInTheConditionals;
|
|
BuildMacroDescriptionLabel.Caption:=lisCodeToolsDefsDescription;
|
|
|
|
ConditionalsGroupBox.Caption:=lisConditionals;
|
|
|
|
CondSynEdit.OnStatusChange:=@CondSynEditStatusChange;
|
|
|
|
BMAddMacroSpeedButton.LoadGlyphFromLazarusResource('laz_add');
|
|
BMAddMacroValueSpeedButton.LoadGlyphFromLazarusResource('laz_add');
|
|
BMDeleteMacroSpeedButton.LoadGlyphFromLazarusResource('laz_delete');
|
|
|
|
fSynCompletion:=TSynCompletion.Create(Self);
|
|
fSynCompletion.TheForm.Parent:=Self;
|
|
fSynCompletion.OnExecute:=@fSynCompletionExecute;
|
|
fSynCompletion.OnCancel:=@fSynCompletionCancel;
|
|
fSynCompletion.OnValidate:=@fSynCompletionValidate;
|
|
fSynCompletion.OnSearchPosition:=@fSynCompletionSearchPosition;
|
|
fSynCompletion.OnKeyCompletePrefix:=@fSynCompletionKeyCompletePrefix;
|
|
fSynCompletion.OnUTF8KeyPress:=@fSynCompletionUTF8KeyPress;
|
|
fSynCompletion.OnKeyNextChar:=@fSynCompletionKeyNextChar;
|
|
fSynCompletion.OnKeyPrevChar:=@fSynCompletionKeyPrevChar;
|
|
fSynCompletion.OnKeyDelete:=@fSynCompletionKeyDelete;
|
|
fSynCompletion.OnKeyDown:=@fSynCompletionKeyDown;
|
|
end;
|
|
|
|
destructor TCompOptBuildMacrosFrame.Destroy;
|
|
begin
|
|
FreeAndNil(FCompletionHistory);
|
|
FreeAndNil(FCompletionValues);
|
|
FreeAndNil(fDefaultVariables);
|
|
FreeAndNil(fEngine);
|
|
FreeAndNil(FBuildMacros);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TCompOptBuildMacrosFrame.GetTitle: String;
|
|
begin
|
|
Result:=lisIDEMacros;
|
|
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)
|
|
else
|
|
DefaultVariables.Clear;
|
|
|
|
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
|
|
(Options.BuildMacros as TIDEBuildMacros).Assign(BuildMacros);
|
|
Options.Conditionals:=CondSynEdit.Lines.Text;
|
|
end;
|
|
|
|
initialization
|
|
RegisterIDEOptionsEditor(GroupCompiler, TCompOptBuildMacrosFrame,
|
|
CompilerOptionsConditional);
|
|
RegisterIDEOptionsEditor(GroupPkgCompiler, TCompOptBuildMacrosFrame,
|
|
CompilerOptionsConditional);
|
|
|
|
end.
|
|
|