mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-27 10:14:03 +02:00
1293 lines
40 KiB
ObjectPascal
1293 lines
40 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA. *
|
|
* *
|
|
***************************************************************************
|
|
|
|
Author: Mattias Gaertner
|
|
|
|
Abstract:
|
|
Options frame for build mode matrix options.
|
|
|
|
ToDo:
|
|
- editor for targets
|
|
- show pick list icon for type column
|
|
- undo: combine changes while editing a cell
|
|
}
|
|
unit Compiler_ModeMatrix;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, types,
|
|
// LazUtils
|
|
LazLoggerBase, LazUTF8,
|
|
// LCL
|
|
LCLPlatformDef, Controls, Graphics, ComCtrls, Menus,
|
|
// IdeIntf
|
|
IdeIntfStrConsts, IDEOptionsIntf, IDEOptEditorIntf, IDEImagesIntf, CompOptsIntf, KeywordFuncLists,
|
|
// IDE
|
|
EnvironmentOpts, PackageSystem, PackageDefs, Project, LazarusIDEStrConsts,
|
|
TransferMacros, ModeMatrixOpts, ModeMatrixCtrl, compiler_config_target;
|
|
|
|
type
|
|
|
|
{ TCompOptModeMatrixFrame }
|
|
|
|
TCompOptModeMatrixFrame = class(TAbstractIDEOptionsEditor)
|
|
BMMAddLclWidgetPopupMenu: TPopupMenu;
|
|
BMMatrixToolBar: TToolBar;
|
|
BMMDeleteButton: TToolButton;
|
|
BMMMoveDownButton: TToolButton;
|
|
BMMMoveUpButton: TToolButton;
|
|
BMMLCLWidgetTypeMenuItem: TMenuItem;
|
|
BMMRedoToolButton: TToolButton;
|
|
BMMUndoButton: TToolButton;
|
|
BMMNewCustomOptionMenuItem: TMenuItem;
|
|
BMMAddOtherPopupMenu: TPopupMenu;
|
|
BMMNewTargetMenuItem: TMenuItem;
|
|
BMMAddOtherButton: TToolButton;
|
|
BMMNewIDEMacroMenuItem: TMenuItem;
|
|
BMMNewOutDirMenuItem: TMenuItem;
|
|
MoveSepToolButton: TToolButton;
|
|
DoSepToolButton: TToolButton;
|
|
AddSepToolButton: TToolButton;
|
|
BMMAddLclWidgetButton: TToolButton;
|
|
LCLMacroSepToolButton: TToolButton;
|
|
procedure BMMDeleteButtonClick(Sender: TObject);
|
|
procedure BMMMoveDownButtonClick(Sender: TObject);
|
|
procedure BMMMoveUpButtonClick(Sender: TObject);
|
|
procedure BMMNewIDEMacroMenuItemClick(Sender: TObject);
|
|
procedure BMMNewOutDirMenuItemClick(Sender: TObject);
|
|
procedure BMMRedoToolButtonClick(Sender: TObject);
|
|
procedure BMMUndoButtonClick(Sender: TObject);
|
|
procedure BMMNewCustomOptionMenuItemClick(Sender: TObject);
|
|
procedure BMMNewTargetMenuItemClick(Sender: TObject);
|
|
procedure BMMAddLclWidgetButtonClick(Sender: TObject);
|
|
procedure BMMAddOtherButtonClick(Sender: TObject);
|
|
procedure GridEditingDone(Sender: TObject);
|
|
procedure GridGetCellHightlightColor(Sender: TObject; aCol, aRow: integer;
|
|
var aColor: TColor);
|
|
procedure GridSelection(Sender: TObject; {%H-}aCol, {%H-}aRow: Integer);
|
|
procedure GridSetEditText(Sender: TObject; ACol, ARow: Integer; const Value: string);
|
|
procedure GridShowHint(Sender: TObject; HintInfo: PHintInfo);
|
|
procedure AddMacroMenuItemClick(Sender: TObject);
|
|
procedure AddLCLWidgetTypeClick(Sender: TObject);
|
|
private
|
|
FDialog: TAbstractOptionsEditorDialog;
|
|
FErrorColor: TColor;
|
|
FGrid: TGroupedMatrixControl;
|
|
FGroupIDE: TGroupedMatrixGroup;
|
|
FGroupProject: TGroupedMatrixGroup;
|
|
FGroupSession: TGroupedMatrixGroup;
|
|
FIDEColor: TColor;
|
|
FProject: TProject;
|
|
FProjectColor: TColor;
|
|
FSessionColor: TColor;
|
|
fOldIDEOptions: TBuildMatrixOptions;
|
|
fOldSharedOptions: TBuildMatrixOptions;
|
|
fOldSessionOptions: TBuildMatrixOptions;
|
|
fCaptionPatternMacroName: string;
|
|
fCaptionPatternMacroValue: string;
|
|
procedure AddLCLWidgetTypeValues(ParentMenu: TPopupMenu; Mcr: TLazBuildMacro);
|
|
procedure AddMacroValues(ParentMI: TMenuItem; Mcr: TLazBuildMacro);
|
|
function ActiveModeAsText: string;
|
|
procedure DoWriteSettings;
|
|
procedure FillMenus;
|
|
procedure MoveRow(Direction: integer);
|
|
procedure UpdateButtons;
|
|
function AddTarget(StorageGroup: TGroupedMatrixGroup): TGroupedMatrixGroup;
|
|
procedure CreateNewOption(aTyp, aValue: string);
|
|
procedure CreateNewTarget;
|
|
function GetCaptionValue(aCaption, aPattern: string): string;
|
|
procedure UpdateGridStorageGroups;
|
|
protected
|
|
procedure VisibleChanged; override;
|
|
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;
|
|
procedure RestoreSettings(AOptions: TAbstractIDEOptions); override;
|
|
procedure UpdateModes(UpdateGrid: boolean = true);
|
|
procedure UpdateActiveMode;
|
|
public
|
|
property Grid: TGroupedMatrixControl read FGrid;
|
|
property GroupIDE: TGroupedMatrixGroup read FGroupIDE;
|
|
property GroupProject: TGroupedMatrixGroup read FGroupProject;
|
|
property GroupSession: TGroupedMatrixGroup read FGroupSession;
|
|
property IDEColor: TColor read FIDEColor write FIDEColor;
|
|
property ProjectColor: TColor read FProjectColor write FProjectColor;
|
|
property SessionColor: TColor read FSessionColor write FSessionColor;
|
|
property ErrorColor: TColor read FErrorColor write FErrorColor;
|
|
property LazProject: TProject read FProject;
|
|
end;
|
|
|
|
// assign
|
|
function IsEqual(Options: TBuildMatrixOptions; StorageGroup: TGroupedMatrixGroup): boolean;
|
|
procedure AssignBuildMatrixOptionsToGroup(Options: TBuildMatrixOptions;
|
|
Matrix: TGroupedMatrix; StorageGroup: TGroupedMatrixGroup);
|
|
procedure AssignBuildMatrixGroupToOptions(StorageGroup: TGroupedMatrixGroup;
|
|
Options: TBuildMatrixOptions; InvalidateBuildMacros: boolean);
|
|
|
|
// targets, see BuildMatrixTargetFits
|
|
function TargetsPrefix: string;
|
|
function AddMatrixTarget(Matrix: TGroupedMatrix; StorageGroup: TGroupedMatrixGroup): TGroupedMatrixGroup;
|
|
function BuildMatrixTargetsAsHint(const Targets: String): String;
|
|
|
|
// type
|
|
function BuildMatrixOptionTypeCaption(Typ: TBuildMatrixOptionType): string;
|
|
function CaptionToBuildMatrixOptionType(s: string): TBuildMatrixOptionType;
|
|
function BuildMatrixOptionTypeHint(Typ: TBuildMatrixOptionType): string;
|
|
function BuildMatrixDefaultValue(Typ: TBuildMatrixOptionType): string;
|
|
|
|
function CheckBuildMatrixTargetsSyntax(const Targets: String): String;
|
|
function SplitMatrixMacro(MacroAssignment: string;
|
|
out MacroName, MacroValue: string; ExceptionOnError: boolean): boolean;
|
|
|
|
var
|
|
ModeMatrixFrame: TCompOptModeMatrixFrame = nil;
|
|
|
|
implementation
|
|
|
|
function BuildMatrixOptionTypeCaption(Typ: TBuildMatrixOptionType): string;
|
|
begin
|
|
case Typ of
|
|
bmotCustom: Result:='Custom';
|
|
bmotOutDir: Result:='OutDir';
|
|
bmotIDEMacro: Result:='IDE Macro';
|
|
else Result:='?';
|
|
end;
|
|
end;
|
|
|
|
function CaptionToBuildMatrixOptionType(s: string): TBuildMatrixOptionType;
|
|
begin
|
|
for Result:=low(TBuildMatrixOptionType) to high(TBuildMatrixOptionType) do
|
|
if s=BuildMatrixOptionTypeCaption(Result) then exit;
|
|
Result:=bmotCustom;
|
|
end;
|
|
|
|
function BuildMatrixOptionTypeHint(Typ: TBuildMatrixOptionType): string;
|
|
begin
|
|
case Typ of
|
|
bmotCustom: Result:=lisMMAppendArbitraryFpcOptionsEGO1GhtlDFlag;
|
|
bmotOutDir: Result:=lisMMOverrideOutputDirectoryFUOfTarget;
|
|
bmotIDEMacro: Result:=lisMMSetAnIDEMacroEGLCLWidgetTypeWin32;
|
|
else Result:='?';
|
|
end;
|
|
end;
|
|
|
|
function BuildMatrixDefaultValue(Typ: TBuildMatrixOptionType): string;
|
|
begin
|
|
Result:='';
|
|
case Typ of
|
|
bmotIDEMacro: Result:='MacroName:=Value';
|
|
bmotOutDir: Result:='lib/$(TargetCPU)-$(TargetOS)/$(BuildMode)';
|
|
end;
|
|
end;
|
|
|
|
function IsEqual(Options: TBuildMatrixOptions; StorageGroup: TGroupedMatrixGroup): boolean;
|
|
// ignore empty targets
|
|
var
|
|
OptIndex: Integer;
|
|
GrpIndex: Integer;
|
|
Target: TGroupedMatrixGroup;
|
|
i: Integer;
|
|
ValueRow: TGroupedMatrixValue;
|
|
Option: TBuildMatrixOption;
|
|
MacroName: string;
|
|
MacroValue: string;
|
|
begin
|
|
Result:=false;
|
|
OptIndex:=0;
|
|
for GrpIndex:=0 to StorageGroup.Count-1 do begin
|
|
Target:=TGroupedMatrixGroup(StorageGroup[GrpIndex]);
|
|
if not (Target is TGroupedMatrixGroup) then begin
|
|
debugln(['IsEqual StorageGroup expected group, but found ',DbgSName(Target)]);
|
|
exit;
|
|
end;
|
|
for i:=0 to Target.Count-1 do begin
|
|
ValueRow:=TGroupedMatrixValue(Target[i]);
|
|
if not (ValueRow is TGroupedMatrixValue) then begin
|
|
debugln(['IsEqual Target expected Value, but found ',DbgSName(ValueRow)]);
|
|
exit;
|
|
end;
|
|
if OptIndex>=Options.Count then exit;
|
|
// compare option
|
|
Option:=Options[OptIndex];
|
|
//debugln(['IsEqual ',Option.AsString,' Targets="',Option.Targets,'" Target.Value="',Target.Value,'"']);
|
|
if Option.Targets<>Target.Value then exit;
|
|
if Option.Modes<>ValueRow.GetNormalizedModes then exit;
|
|
if Option.Typ<>CaptionToBuildMatrixOptionType(ValueRow.Typ) then exit;
|
|
if Option.Typ=bmotIDEMacro then begin
|
|
SplitMatrixMacro(ValueRow.Value,MacroName,MacroValue,false);
|
|
if Option.MacroName<>MacroName then exit;
|
|
if Option.Value<>MacroValue then exit;
|
|
end else begin
|
|
if Option.Value<>ValueRow.Value then exit;
|
|
end;
|
|
inc(OptIndex);
|
|
end;
|
|
end;
|
|
Result:=OptIndex=Options.Count;
|
|
end;
|
|
|
|
procedure AssignBuildMatrixOptionsToGroup(Options: TBuildMatrixOptions;
|
|
Matrix: TGroupedMatrix; StorageGroup: TGroupedMatrixGroup);
|
|
var
|
|
OptIndex: Integer;
|
|
Option: TBuildMatrixOption;
|
|
TargetGrp: TGroupedMatrixGroup;
|
|
Value: String;
|
|
begin
|
|
if IsEqual(Options,StorageGroup) then exit;
|
|
StorageGroup.Clear;
|
|
TargetGrp:=nil;
|
|
for OptIndex:=0 to Options.Count-1 do begin
|
|
Option:=Options[OptIndex];
|
|
if (TargetGrp=nil) or (TargetGrp.Value<>Option.Targets) then begin
|
|
TargetGrp:=AddMatrixTarget(Matrix,StorageGroup);
|
|
TargetGrp.Value:=Option.Targets;
|
|
end;
|
|
Value:=Option.Value;
|
|
if Option.Typ=bmotIDEMacro then
|
|
Value:=Option.MacroName+':='+Value;
|
|
Matrix.AddValue(TargetGrp,Option.Modes,
|
|
BuildMatrixOptionTypeCaption(Option.Typ),Value,Option.ID);
|
|
end;
|
|
end;
|
|
|
|
procedure AssignBuildMatrixGroupToOptions(StorageGroup: TGroupedMatrixGroup;
|
|
Options: TBuildMatrixOptions; InvalidateBuildMacros: boolean);
|
|
var
|
|
GrpIndex: Integer;
|
|
Target: TGroupedMatrixGroup;
|
|
ValueRow: TGroupedMatrixValue;
|
|
i: Integer;
|
|
Option: TBuildMatrixOption;
|
|
MacroName: string;
|
|
MacroValue: string;
|
|
Targets: String;
|
|
begin
|
|
if IsEqual(Options,StorageGroup) then exit;
|
|
Options.Clear;
|
|
for GrpIndex:=0 to StorageGroup.Count-1 do begin
|
|
Target:=TGroupedMatrixGroup(StorageGroup[GrpIndex]);
|
|
if not (Target is TGroupedMatrixGroup) then begin
|
|
debugln(['AssignBuildMatrixGroupToOptions StorageGroup "',StorageGroup.AsString,'", expected group, but found ',DbgSName(Target)]);
|
|
exit;
|
|
end;
|
|
Targets:=UTF8Trim(Target.Value);
|
|
//debugln(['AssignBuildMatrixGroupToOptions Targets=',Targets]);
|
|
for i:=0 to Target.Count-1 do begin
|
|
ValueRow:=TGroupedMatrixValue(Target[i]);
|
|
if not (ValueRow is TGroupedMatrixValue) then begin
|
|
debugln(['AssignBuildMatrixGroupToOptions Target expected Value, but found ',DbgSName(ValueRow)]);
|
|
exit;
|
|
end;
|
|
Option:=Options.Add(CaptionToBuildMatrixOptionType(ValueRow.Typ),Targets);
|
|
Option.Modes:=ValueRow.GetNormalizedModes;
|
|
Option.ID:=ValueRow.ID;
|
|
if Option.Typ=bmotIDEMacro then begin
|
|
SplitMatrixMacro(ValueRow.Value,MacroName,MacroValue,false);
|
|
Option.MacroName:=MacroName;
|
|
Option.Value:=UTF8Trim(MacroValue);
|
|
//debugln(['AssignBuildMatrixGroupToOptions Name="',MacroName,'" Value="',MacroValue,'"']);
|
|
end else begin
|
|
Option.Value:=UTF8Trim(ValueRow.Value);
|
|
end;
|
|
//debugln(['AssignBuildMatrixGroupToOptions Option=',Option.AsString]);
|
|
end;
|
|
end;
|
|
if InvalidateBuildMacros then
|
|
IncreaseBuildMacroChangeStamp;
|
|
end;
|
|
|
|
function TargetsPrefix: string;
|
|
begin
|
|
Result:=lisMMTargets;
|
|
end;
|
|
|
|
function AddMatrixTarget(Matrix: TGroupedMatrix; StorageGroup: TGroupedMatrixGroup
|
|
): TGroupedMatrixGroup;
|
|
begin
|
|
Result:=Matrix.AddGroup(StorageGroup,TargetsPrefix,'*');
|
|
Result.Writable:=true;
|
|
end;
|
|
|
|
function BuildMatrixTargetsAsHint(const Targets: String): String;
|
|
var
|
|
ExcludeProject: Boolean;
|
|
IncludeProject: Boolean;
|
|
All: Boolean;
|
|
Includes: String;
|
|
Excludes: String;
|
|
Target: String;
|
|
StartP: Integer;
|
|
p: Integer;
|
|
begin
|
|
Result:=CheckBuildMatrixTargetsSyntax(Targets);
|
|
if Result<>'' then begin
|
|
Result:=lisWarning+Result;
|
|
exit;
|
|
end;
|
|
p:=1;
|
|
Excludes:='';
|
|
Includes:='';
|
|
All:=false;
|
|
IncludeProject:=false;
|
|
ExcludeProject:=false;
|
|
while (p<=length(Targets)) do begin
|
|
StartP:=p;
|
|
while (p<=length(Targets)) and (Targets[p]<>',') do inc(p);
|
|
Target:=copy(Targets,StartP,p-StartP);
|
|
if Target<>'' then begin
|
|
if Target[1]='-' then begin
|
|
system.Delete(Target,1,1);
|
|
if Target<>'' then begin
|
|
if Target=BuildMatrixProjectName then
|
|
ExcludeProject:=true
|
|
else begin
|
|
if Excludes<>'' then Excludes+=',';
|
|
Excludes+=Target;
|
|
end;
|
|
end;
|
|
end else begin
|
|
if Target='*' then
|
|
All:=true
|
|
else if Target=BuildMatrixProjectName then
|
|
IncludeProject:=true
|
|
else begin
|
|
if Includes<>'' then Includes+=',';
|
|
Includes+=Target;
|
|
end;
|
|
end;
|
|
end;
|
|
inc(p);
|
|
end;
|
|
if ExcludeProject then
|
|
IncludeProject:=false;
|
|
if All then begin
|
|
if ExcludeProject then
|
|
Result+=lisMMApplyToAllPackages+LineEnding
|
|
else
|
|
Result+=lisMMApplyToAllPackagesAndProjects+LineEnding;
|
|
end
|
|
else begin
|
|
if IncludeProject then
|
|
Result+=lisMMApplyToProject+LineEnding;
|
|
if Includes<>'' then
|
|
Result+=Format(lisMMApplyToAllPackagesMatching, [Includes])+LineEnding;
|
|
end;
|
|
if Excludes<>'' then
|
|
Result+=Format(lisMMExcludeAllPackagesMatching, [Excludes])+LineEnding;
|
|
end;
|
|
|
|
{$R *.lfm}
|
|
|
|
{ TCompOptModeMatrixFrame }
|
|
|
|
procedure TCompOptModeMatrixFrame.GridSelection(Sender: TObject; aCol, aRow: Integer);
|
|
begin
|
|
UpdateButtons;
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.GridSetEditText(Sender: TObject; ACol, ARow: Integer;
|
|
const Value: string);
|
|
var
|
|
MatRow: TGroupedMatrixRow;
|
|
ValueRow: TGroupedMatrixValue;
|
|
NewValue: String;
|
|
Typ: TBuildMatrixOptionType;
|
|
OldTyp: TBuildMatrixOptionType;
|
|
begin
|
|
if ACol=Grid.TypeCol then begin
|
|
if ARow<Grid.FixedRows then exit;
|
|
MatRow:=Grid.Matrix[ARow-Grid.FixedRows];
|
|
if MatRow is TGroupedMatrixValue then begin
|
|
ValueRow:=TGroupedMatrixValue(MatRow);
|
|
OldTyp:=CaptionToBuildMatrixOptionType(ValueRow.Typ);
|
|
if ValueRow.Value=BuildMatrixDefaultValue(OldTyp) then begin
|
|
// change default value
|
|
Typ:=CaptionToBuildMatrixOptionType(Value);
|
|
NewValue:=BuildMatrixDefaultValue(Typ);
|
|
ValueRow.Value:=NewValue;
|
|
end;
|
|
Grid.InvalidateCell(Grid.ValueCol,ARow);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.GridShowHint(Sender: TObject; HintInfo: PHintInfo);
|
|
var
|
|
aCol: Longint;
|
|
aRow: Longint;
|
|
MatRow: TGroupedMatrixRow;
|
|
h: String;
|
|
GroupRow: TGroupedMatrixGroup;
|
|
Targets: String;
|
|
ValueRow: TGroupedMatrixValue;
|
|
MacroName: string;
|
|
MacroValue: string;
|
|
begin
|
|
aCol:=0;
|
|
aRow:=0;
|
|
Grid.MouseToCell(HintInfo^.CursorPos.X,HintInfo^.CursorPos.Y,aCol,aRow);
|
|
if aRow<Grid.FixedCols then exit;
|
|
MatRow:=Grid.Matrix[aRow-Grid.FixedRows];
|
|
h:='';
|
|
if MatRow is TGroupedMatrixGroup then begin
|
|
GroupRow:=TGroupedMatrixGroup(MatRow);
|
|
if GroupRow.Group<>nil then begin
|
|
// a target group
|
|
Targets:=GroupRow.Value;
|
|
h:=BuildMatrixTargetsAsHint(Targets);
|
|
end;
|
|
end else if MatRow is TGroupedMatrixValue then begin
|
|
ValueRow:=TGroupedMatrixValue(MatRow);
|
|
if ValueRow.Typ=BuildMatrixOptionTypeCaption(bmotIDEMacro) then begin
|
|
h:='';
|
|
try
|
|
SplitMatrixMacro(ValueRow.Value,MacroName,MacroValue,true);
|
|
except
|
|
on E: EMMMacroSyntaxException do begin
|
|
h:=lisError+E.Message;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
HintInfo^.HintStr:=h;
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.AddMacroMenuItemClick(Sender: TObject);
|
|
var
|
|
ValueMenuItem: TMenuItem;
|
|
MacroMenuItem: TMenuItem;
|
|
MacroName: String;
|
|
Value: String;
|
|
begin
|
|
ValueMenuItem:=Sender as TMenuItem;
|
|
MacroMenuItem:=ValueMenuItem.Parent;
|
|
MacroName:=GetCaptionValue(MacroMenuItem.Caption,fCaptionPatternMacroName);
|
|
Value:=GetCaptionValue(ValueMenuItem.Caption,fCaptionPatternMacroValue);
|
|
CreateNewOption(BuildMatrixOptionTypeCaption(bmotIDEMacro),MacroName+':='+Value);
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.AddLCLWidgetTypeClick(Sender: TObject);
|
|
var
|
|
TargetFrame: TCompilerConfigTargetFrame;
|
|
ValueMenuItem: TMenuItem;
|
|
Value: String;
|
|
begin
|
|
ValueMenuItem:=Sender as TMenuItem;
|
|
Value:=GetCaptionValue(ValueMenuItem.Caption,fCaptionPatternMacroValue);
|
|
Value:=DisplayNameToDirName(Value);
|
|
CreateNewOption(BuildMatrixOptionTypeCaption(bmotIDEMacro),'LCLWidgetType:='+Value);
|
|
// Update LCLWidgetType to Config and Target page. ToDo: update also when deleting or changing.
|
|
TargetFrame := TCompilerConfigTargetFrame(FDialog.FindEditor(TCompilerConfigTargetFrame));
|
|
Assert(Assigned(TargetFrame));
|
|
TargetFrame.UpdateWidgetSet(Value);
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.BMMNewCustomOptionMenuItemClick(Sender: TObject);
|
|
begin
|
|
CreateNewOption(BuildMatrixOptionTypeCaption(bmotCustom),BuildMatrixDefaultValue(bmotCustom));
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.BMMUndoButtonClick(Sender: TObject);
|
|
begin
|
|
Grid.Undo;
|
|
UpdateGridStorageGroups;
|
|
UpdateButtons;
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.BMMNewTargetMenuItemClick(Sender: TObject);
|
|
begin
|
|
CreateNewTarget;
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.BMMAddLclWidgetButtonClick(Sender: TObject);
|
|
var
|
|
p: TPoint;
|
|
begin
|
|
p:=BMMAddLclWidgetButton.ClientToScreen(Point(0,BMMAddLclWidgetButton.Height));
|
|
BMMAddLclWidgetPopupMenu.PopUp(p.x,p.y);
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.BMMAddOtherButtonClick(Sender: TObject);
|
|
var
|
|
p: TPoint;
|
|
begin
|
|
p:=BMMAddOtherButton.ClientToScreen(Point(0,BMMAddOtherButton.Height));
|
|
BMMAddOtherPopupMenu.PopUp(p.x,p.y);
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.GridEditingDone(Sender: TObject);
|
|
begin
|
|
//DebugLn(['TFrame1.GridEditingDone ']);
|
|
UpdateButtons;
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.GridGetCellHightlightColor(Sender: TObject; aCol,
|
|
aRow: integer; var aColor: TColor);
|
|
var
|
|
MatRow: TGroupedMatrixRow;
|
|
ValueRow: TGroupedMatrixValue;
|
|
MacroName: string;
|
|
MacroValue: string;
|
|
GroupRow: TGroupedMatrixGroup;
|
|
Targets: String;
|
|
begin
|
|
if aCol=Grid.ValueCol then begin
|
|
if aRow<Grid.FixedRows then exit;
|
|
MatRow:=Grid.Matrix[aRow-1];
|
|
if MatRow is TGroupedMatrixGroup then begin
|
|
GroupRow:=TGroupedMatrixGroup(MatRow);
|
|
if GroupRow.Group<>nil then begin
|
|
// a target group
|
|
Targets:=GroupRow.Value;
|
|
if CheckBuildMatrixTargetsSyntax(Targets)<>'' then
|
|
aColor:=ErrorColor;
|
|
end;
|
|
end else if MatRow is TGroupedMatrixValue then begin
|
|
ValueRow:=TGroupedMatrixValue(MatRow);
|
|
if ValueRow.Typ=BuildMatrixOptionTypeCaption(bmotIDEMacro) then begin
|
|
if not SplitMatrixMacro(ValueRow.Value,MacroName,MacroValue,false) then
|
|
aColor:=ErrorColor;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.BMMRedoToolButtonClick(Sender: TObject);
|
|
begin
|
|
Grid.Redo;
|
|
UpdateGridStorageGroups;
|
|
UpdateButtons;
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.BMMMoveUpButtonClick(Sender: TObject);
|
|
begin
|
|
MoveRow(-1);
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.AddLCLWidgetTypeValues(ParentMenu: TPopupMenu; Mcr: TLazBuildMacro);
|
|
var
|
|
i: Integer;
|
|
ValueMI: TMenuItem;
|
|
begin
|
|
if Mcr.Values<>nil then begin
|
|
for i:=0 to Mcr.Values.Count-1 do begin
|
|
if i=ParentMenu.Items.Count then
|
|
ParentMenu.Items.Add(TMenuItem.Create(Self));
|
|
ValueMI:=ParentMenu.Items[i];
|
|
ValueMI.Caption:=Format(fCaptionPatternMacroValue,[DirNameToDisplayName(Mcr.Values[i])]);
|
|
ValueMI.OnClick:=@AddLCLWidgetTypeClick;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.AddMacroValues(ParentMI: TMenuItem; Mcr: TLazBuildMacro);
|
|
var
|
|
i: Integer;
|
|
ValueMI: TMenuItem;
|
|
begin
|
|
if Mcr.Values<>nil then begin
|
|
for i:=0 to Mcr.Values.Count-1 do begin
|
|
if i=ParentMI.Count then
|
|
ParentMI.Add(TMenuItem.Create(Self));
|
|
ValueMI:=ParentMI.Items[i];
|
|
ValueMI.Caption:=Format(fCaptionPatternMacroValue,[Mcr.Values[i]]);
|
|
ValueMI.OnClick:=@AddMacroMenuItemClick;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.FillMenus;
|
|
var
|
|
i, j: Integer;
|
|
Pkg: TLazPackage;
|
|
Macros: TLazBuildMacros;
|
|
Macro: TLazBuildMacro;
|
|
LCLWidgetTypeMacro: TLazBuildMacro;
|
|
xList: TStringListUTF8Fast;
|
|
MenuIndex: Integer;
|
|
MacroMenuItem: TMenuItem;
|
|
PkgList: TFPList;
|
|
begin
|
|
LCLWidgetTypeMacro:=Nil;
|
|
PkgList:=nil;
|
|
xList:=TStringListUTF8Fast.Create;
|
|
try
|
|
// First collect all macros from all used packages to a sorted xList.
|
|
PackageGraph.GetAllRequiredPackages(nil,LazProject.FirstRequiredDependency,PkgList);
|
|
if PkgList<>nil then begin
|
|
for i:=0 to PkgList.Count-1 do begin
|
|
Pkg:=TLazPackage(PkgList[i]);
|
|
Macros:=Pkg.CompilerOptions.BuildMacros;
|
|
for j:=0 to Macros.Count-1 do begin
|
|
Macro:=Macros[j];
|
|
if Macro.Identifier = 'LCLWidgetType' then
|
|
LCLWidgetTypeMacro:=Macro
|
|
else if IsValidIdent(Macro.Identifier) then
|
|
xList.AddObject(Macro.Identifier,Macro);
|
|
end;
|
|
end;
|
|
end;
|
|
xList.Sort;
|
|
// LCLWidgetType gets its own button.
|
|
BMMAddLclWidgetButton.Enabled:=Assigned(LCLWidgetTypeMacro);
|
|
if Assigned(LCLWidgetTypeMacro) then
|
|
AddLCLWidgetTypeValues(BMMAddLclWidgetPopupMenu, LCLWidgetTypeMacro);
|
|
// Place other macros to the popup menu opened from "Add" button.
|
|
MenuIndex:=BMMNewTargetMenuItem.MenuIndex;
|
|
for i:=0 to xList.Count-1 do begin
|
|
inc(MenuIndex);
|
|
Macro:=TLazBuildMacro(xList.Objects[i]);
|
|
if BMMAddOtherPopupMenu.Items.Count=MenuIndex then
|
|
BMMAddOtherPopupMenu.Items.Add(TMenuItem.Create(Self));
|
|
MacroMenuItem:=BMMAddOtherPopupMenu.Items[MenuIndex];
|
|
MacroMenuItem.Caption:=Format(fCaptionPatternMacroName,[Macro.Identifier]);
|
|
AddMacroValues(MacroMenuItem, Macro);
|
|
end;
|
|
finally
|
|
PkgList.Free;
|
|
xList.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.BMMNewIDEMacroMenuItemClick(Sender: TObject);
|
|
begin
|
|
CreateNewOption(BuildMatrixOptionTypeCaption(bmotIDEMacro),BuildMatrixDefaultValue(bmotIDEMacro));
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.BMMNewOutDirMenuItemClick(Sender: TObject);
|
|
begin
|
|
CreateNewOption(BuildMatrixOptionTypeCaption(bmotOutDir),BuildMatrixDefaultValue(bmotOutDir));
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.BMMMoveDownButtonClick(Sender: TObject);
|
|
begin
|
|
MoveRow(1);
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.BMMDeleteButtonClick(Sender: TObject);
|
|
var
|
|
aRow: Integer;
|
|
MatRow: TGroupedMatrixRow;
|
|
begin
|
|
aRow:=Grid.Row;
|
|
if aRow<1 then exit;
|
|
MatRow:=Grid.Matrix[aRow-1];
|
|
if MatRow.Group=nil then begin
|
|
// storage groups can not be deleted
|
|
exit;
|
|
end;
|
|
Grid.DeleteMatrixRow(aRow);
|
|
UpdateButtons;
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.UpdateButtons;
|
|
var
|
|
aRow: Integer;
|
|
MatRow: TGroupedMatrixRow;
|
|
begin
|
|
aRow:=Grid.Row;
|
|
if (aRow>0) and (aRow<=Grid.Matrix.RowCount) then begin
|
|
MatRow:=Grid.Matrix[aRow-1];
|
|
end else
|
|
MatRow:=nil;
|
|
|
|
// allow to delete targets and value rows
|
|
BMMDeleteButton.Enabled:=(MatRow<>nil) and (MatRow.Group<>nil);
|
|
//
|
|
BMMUndoButton.Enabled:=Grid.CanUndo;
|
|
BMMRedoToolButton.Enabled:=Grid.CanRedo;
|
|
// move up/down
|
|
BMMMoveUpButton.Enabled:=(MatRow<>nil) and (MatRow.Group<>nil)
|
|
and ((MatRow.GetPreviousSibling<>nil)
|
|
or (MatRow.GetTopLvlItem.GetPreviousSibling<>nil));
|
|
BMMMoveDownButton.Enabled:=(MatRow<>nil) and (MatRow.Group<>nil)
|
|
and (MatRow.GetNextSkipChildren<>nil);
|
|
end;
|
|
|
|
function TCompOptModeMatrixFrame.AddTarget(StorageGroup: TGroupedMatrixGroup
|
|
): TGroupedMatrixGroup;
|
|
begin
|
|
Result:=AddMatrixTarget(Grid.Matrix,StorageGroup);
|
|
end;
|
|
|
|
function TCompOptModeMatrixFrame.ActiveModeAsText: string;
|
|
begin
|
|
Result:=Grid.Modes[Grid.ActiveModeIndex].Caption;
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.CreateNewOption(aTyp, aValue: string);
|
|
var
|
|
aRow: Integer;
|
|
MatRow: TGroupedMatrixRow;
|
|
Group: TGroupedMatrixGroup;
|
|
NewRow: TGroupedMatrixValue;
|
|
begin
|
|
aRow:=Grid.Row;
|
|
if aRow<Grid.FixedRows then aRow:=Grid.FixedRows;
|
|
NewRow:=nil;
|
|
Grid.MatrixChanging;
|
|
try
|
|
Grid.StoreUndo;
|
|
if aTyp='' then
|
|
aTyp:=Grid.TypeColumn.PickList.Names[0];
|
|
MatRow:=Grid.Matrix[aRow-1];
|
|
//debugln(['TCompOptModeMatrix.CreateNewOption ',DbgSName(MatRow),' ',MatRow.AsString]);
|
|
if MatRow is TGroupedMatrixGroup then begin
|
|
Group:=TGroupedMatrixGroup(MatRow);
|
|
if Group.Group=nil then begin
|
|
if Group.Count=0 then begin
|
|
// storage group without target => add a target
|
|
Group:=AddTarget(Group);
|
|
end else begin
|
|
// add to first target
|
|
Group:=Group[0] as TGroupedMatrixGroup;
|
|
end;
|
|
end;
|
|
// add option as first item of Group
|
|
NewRow:=Grid.Matrix.AddValue(Group, ActiveModeAsText, aTyp, aValue,
|
|
CreateBuildMatrixOptionGUID);
|
|
end else begin
|
|
// add behind current value
|
|
Group:=MatRow.Group;
|
|
NewRow:=Grid.Matrix.AddValue(Group, ActiveModeAsText, aTyp, aValue,
|
|
CreateBuildMatrixOptionGUID);
|
|
Group.Move(Group.Count-1,MatRow.GetGroupIndex+1);
|
|
end;
|
|
Grid.Matrix.RebuildRows;
|
|
//Grid.Matrix.WriteDebugReport;
|
|
finally
|
|
Grid.MatrixChanged;
|
|
end;
|
|
if NewRow<>nil then
|
|
Grid.Row:=Grid.Matrix.IndexOfRow(NewRow)+1;
|
|
UpdateButtons;
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.CreateNewTarget;
|
|
var
|
|
aRow: Integer;
|
|
MatRow: TGroupedMatrixRow;
|
|
Group: TGroupedMatrixGroup;
|
|
NewRow: TGroupedMatrixGroup;
|
|
begin
|
|
aRow:=Grid.Row;
|
|
if aRow<Grid.FixedRows then aRow:=Grid.FixedRows;
|
|
NewRow:=nil;
|
|
Grid.MatrixChanging;
|
|
try
|
|
Grid.StoreUndo;
|
|
MatRow:=Grid.Matrix[aRow-1];
|
|
if MatRow is TGroupedMatrixGroup then
|
|
Group:=TGroupedMatrixGroup(MatRow)
|
|
else
|
|
Group:=MatRow.Group;
|
|
if Group.Group=nil then begin
|
|
// Group is a storage group
|
|
// => add as first target of storage group
|
|
NewRow:=AddTarget(Group);
|
|
Group.Move(Group.Count-1,0);
|
|
end else begin
|
|
// Group is a target
|
|
// => add target behind current target
|
|
NewRow:=AddTarget(Group.Group);
|
|
Group.Group.Move(Group.Group.Count-1,Group.GetGroupIndex+1);
|
|
end;
|
|
Grid.Matrix.RebuildRows;
|
|
finally
|
|
Grid.MatrixChanged;
|
|
end;
|
|
if NewRow<>nil then
|
|
Grid.Row:=Grid.Matrix.IndexOfRow(NewRow)+1;
|
|
UpdateButtons;
|
|
end;
|
|
|
|
function TCompOptModeMatrixFrame.GetCaptionValue(aCaption, aPattern: string): string;
|
|
var
|
|
p: SizeInt;
|
|
begin
|
|
Result:='';
|
|
p:=Pos('%s',aPattern);
|
|
if p<1 then exit;
|
|
Result:=copy(aCaption,p,length(aCaption)-length(aPattern)+2);
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.UpdateGridStorageGroups;
|
|
var
|
|
i, j: Integer;
|
|
MatRow: TGroupedMatrixRow;
|
|
GroupRow: TGroupedMatrixGroup;
|
|
begin
|
|
fGroupIDE:=nil;
|
|
fGroupProject:=nil;
|
|
fGroupSession:=nil;
|
|
j:=0;
|
|
for i:=0 to Grid.Matrix.RowCount-1 do begin
|
|
MatRow:=Grid.Matrix.Rows[i];
|
|
if (MatRow.Group=nil) and (MatRow is TGroupedMatrixGroup) then begin
|
|
GroupRow:=TGroupedMatrixGroup(MatRow);
|
|
inc(j);
|
|
case j of
|
|
1: fGroupIDE:=GroupRow;
|
|
2: fGroupProject:=GroupRow;
|
|
3: fGroupSession:=GroupRow;
|
|
end;
|
|
end;
|
|
end;
|
|
if fGroupSession=nil then
|
|
raise Exception.Create('grid lost the session storage group');
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.VisibleChanged;
|
|
begin
|
|
inherited VisibleChanged;
|
|
if (not Visible) and (LazProject<>nil) then
|
|
DoWriteSettings;
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.UpdateModes(UpdateGrid: boolean);
|
|
var
|
|
i: Integer;
|
|
aColor: TColor;
|
|
GridHasChanged: Boolean;
|
|
ValuesHaveChanged: Boolean;
|
|
aMode: TGroupedMatrixMode;
|
|
BM: TProjectBuildMode;
|
|
begin
|
|
GridHasChanged:=false;
|
|
ValuesHaveChanged:=false;
|
|
// add/update build modes
|
|
for i:=0 to LazProject.BuildModes.Count-1 do begin
|
|
BM:=LazProject.BuildModes[i];
|
|
aColor:=clDefault;
|
|
if BM.InSession then aColor:=SessionColor;
|
|
if i=Grid.Modes.Count then begin
|
|
Grid.Modes.Add(BM.Identifier,aColor);
|
|
GridHasChanged:=true;
|
|
end
|
|
else begin
|
|
aMode:=Grid.Modes[i];
|
|
if aMode.Caption<>BM.Identifier then begin
|
|
aMode.Caption:=BM.Identifier;
|
|
GridHasChanged:=true;
|
|
end;
|
|
if aMode.Color<>aColor then begin
|
|
aMode.Color:=aColor;
|
|
ValuesHaveChanged:=true;
|
|
end;
|
|
end;
|
|
end;
|
|
// delete leftover build modes
|
|
while Grid.Modes.Count>LazProject.BuildModes.Count do begin
|
|
Grid.Modes.Delete(Grid.Modes.Count-1);
|
|
GridHasChanged:=true;
|
|
end;
|
|
UpdateActiveMode;
|
|
if UpdateGrid and GridHasChanged then
|
|
Grid.MatrixChanged
|
|
else if GridHasChanged or ValuesHaveChanged then
|
|
Grid.Invalidate;
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.UpdateActiveMode;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
i:=LazProject.BuildModes.IndexOf(LazProject.ActiveBuildMode);
|
|
if i>=Grid.Modes.Count then exit;
|
|
Grid.ActiveModeIndex:=i;
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.MoveRow(Direction: integer);
|
|
var
|
|
MatRow: TGroupedMatrixRow;
|
|
aRow: Integer;
|
|
TargetGroup: TGroupedMatrixGroup;
|
|
i: Integer;
|
|
TargetStorage: TGroupedMatrixGroup;
|
|
begin
|
|
aRow:=Grid.Row;
|
|
if aRow<1 then exit;
|
|
MatRow:=Grid.Matrix[aRow-1];
|
|
if MatRow.Group=nil then begin
|
|
// storage groups can not be moved
|
|
debugln(['TFrame1.MoveRow storage groups can not be moved']);
|
|
exit;
|
|
end;
|
|
Grid.MatrixChanging;
|
|
i:=MatRow.GetGroupIndex;
|
|
if Direction<0 then begin
|
|
if i>0 then begin
|
|
// move up in group
|
|
Grid.StoreUndo;
|
|
MatRow.Group.Move(i,i-1);
|
|
end else begin
|
|
// move to previous group
|
|
TargetGroup:=TGroupedMatrixGroup(MatRow.Group.GetPreviousSibling);
|
|
if TargetGroup=nil then begin
|
|
if MatRow is TGroupedMatrixValue then begin
|
|
// move value to last target of previous storage
|
|
if (MatRow.Group.Group=nil) then begin
|
|
debugln(['TFrame1.MoveRow value has no storage+target']);
|
|
exit;
|
|
end;
|
|
TargetStorage:=TGroupedMatrixGroup(MatRow.Group.Group.GetPreviousSibling);
|
|
if TargetStorage=nil then begin
|
|
debugln(['TFrame1.MoveRow no previous storage for value']);
|
|
exit;
|
|
end;
|
|
if TargetStorage.Count>0 then begin
|
|
TargetGroup:=TargetStorage[TargetStorage.Count-1] as TGroupedMatrixGroup;
|
|
end else begin
|
|
// add first target
|
|
TargetGroup:=AddTarget(TargetStorage);
|
|
end;
|
|
end else begin
|
|
// this is already the first target of the first storage
|
|
debugln(['TFrame1.MoveRow no previous storage for target']);
|
|
exit;
|
|
end;
|
|
end;
|
|
// move MatRow to TargetGroup as last
|
|
Grid.StoreUndo;
|
|
MatRow.Group:=TargetGroup;
|
|
end;
|
|
end else begin
|
|
if i+1<MatRow.Group.Count then begin
|
|
// move down in group
|
|
Grid.StoreUndo;
|
|
MatRow.Group.Move(i,i+1);
|
|
end else begin
|
|
// move to next group
|
|
TargetGroup:=TGroupedMatrixGroup(MatRow.Group.GetNextSibling);
|
|
if TargetGroup=nil then begin
|
|
if MatRow is TGroupedMatrixValue then begin
|
|
// move value to first target of next storage
|
|
if (MatRow.Group.Group=nil) then begin
|
|
debugln(['TFrame1.MoveRow value has no storage+target']);
|
|
exit;
|
|
end;
|
|
TargetStorage:=TGroupedMatrixGroup(MatRow.Group.Group.GetNextSibling);
|
|
if TargetStorage=nil then begin
|
|
debugln(['TFrame1.MoveRow no next storage for value']);
|
|
exit;
|
|
end;
|
|
if TargetStorage.Count>0 then begin
|
|
TargetGroup:=TargetStorage[0] as TGroupedMatrixGroup;
|
|
end else begin
|
|
// add first target
|
|
TargetGroup:=AddTarget(TargetStorage);
|
|
end;
|
|
end else begin
|
|
// this is already the last target of the last storage
|
|
debugln(['TFrame1.MoveRow no next storage for target']);
|
|
exit;
|
|
end;
|
|
end;
|
|
// move MatRow to TargetGroup as first
|
|
Grid.StoreUndo;
|
|
MatRow.Group:=TargetGroup;
|
|
TargetGroup.Move(TargetGroup.Count-1,0);
|
|
end;
|
|
end;
|
|
Grid.Matrix.RebuildRows;
|
|
Grid.MatrixChanged;
|
|
Grid.Row:=Grid.Matrix.IndexOfRow(MatRow)+1;
|
|
UpdateButtons;
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.DoWriteSettings;
|
|
begin
|
|
// write IDE options
|
|
AssignBuildMatrixGroupToOptions(GroupIDE,
|
|
EnvironmentOptions.BuildMatrixOptions,true);
|
|
// write Project options
|
|
AssignBuildMatrixGroupToOptions(GroupProject,
|
|
LazProject.BuildModes.SharedMatrixOptions,true);
|
|
// write Session options
|
|
AssignBuildMatrixGroupToOptions(GroupSession,
|
|
LazProject.BuildModes.SessionMatrixOptions,true);
|
|
end;
|
|
|
|
constructor TCompOptModeMatrixFrame.Create(TheOwner: TComponent);
|
|
var
|
|
t: TBuildMatrixOptionType;
|
|
begin
|
|
inherited Create(TheOwner);
|
|
ModeMatrixFrame:=Self;
|
|
|
|
fOldIDEOptions:=TBuildMatrixOptions.Create;
|
|
fOldSharedOptions:=TBuildMatrixOptions.Create;
|
|
fOldSessionOptions:=TBuildMatrixOptions.Create;
|
|
|
|
IDEColor:=RGBToColor(255,255,255);
|
|
ProjectColor:=RGBToColor(255,255,255);
|
|
SessionColor:=RGBToColor(255,255,200);
|
|
ErrorColor:=RGBToColor(255,128,128);
|
|
|
|
FGrid:=TGroupedMatrixControl.Create(Self);
|
|
with Grid do begin
|
|
Name:='ModeMatrixControl';
|
|
Align:=alClient;
|
|
for t:=low(TBuildMatrixOptionType) to high(TBuildMatrixOptionType) do
|
|
TypeColumn.PickList.Add(BuildMatrixOptionTypeCaption(t)+'='+BuildMatrixOptionTypeHint(t));
|
|
Parent:=Self;
|
|
OnSelection:=@GridSelection;
|
|
OnEditingDone:=@GridEditingDone;
|
|
ShowHint:=true;
|
|
OnShowHint:=@GridShowHint;
|
|
OnGetCellHightlightColor:=@GridGetCellHightlightColor;
|
|
OnSetEditText:=@GridSetEditText;
|
|
end;
|
|
|
|
fGroupIDE:=Grid.Matrix.AddGroup(nil, lisMMStoredInIDEEnvironmentoptionsXml);
|
|
GroupIDE.Color:=IDEColor;
|
|
|
|
fGroupProject:=Grid.Matrix.AddGroup(nil, lisMMStoredInProjectLpi);
|
|
GroupProject.Color:=ProjectColor;
|
|
|
|
fGroupSession:=Grid.Matrix.AddGroup(nil, lisMMStoredInSessionOfProjectLps);
|
|
GroupSession.Color:=SessionColor;
|
|
|
|
BMMatrixToolBar.Images:=IDEImages.Images_16;
|
|
|
|
BMMMoveUpButton.ShowCaption:=false;
|
|
BMMMoveUpButton.ImageIndex:=IDEImages.LoadImage('arrow_up');
|
|
BMMMoveUpButton.Hint:=lisMMMoveSelectedItemUp;
|
|
|
|
BMMMoveDownButton.ShowCaption:=false;
|
|
BMMMoveDownButton.ImageIndex:=IDEImages.LoadImage('arrow_down');
|
|
BMMMoveDownButton.Hint:=lisMMMoveSelectedItemDown;
|
|
|
|
BMMUndoButton.ShowCaption:=false;
|
|
BMMUndoButton.ImageIndex:=IDEImages.LoadImage('menu_undo');
|
|
BMMUndoButton.Hint:=lisMMUndoLastChangeToThisGrid;
|
|
|
|
BMMRedoToolButton.ShowCaption:=false;
|
|
BMMRedoToolButton.ImageIndex:=IDEImages.LoadImage('menu_redo');
|
|
BMMRedoToolButton.Hint:=lisMMRedoLastUndoToThisGrid;
|
|
|
|
BMMDeleteButton.Caption:=lisDelete;
|
|
BMMDeleteButton.Hint:=lisMMDeleteTheSelectedTargetOrOption;
|
|
|
|
BMMNewTargetMenuItem.Caption:=lisMMNewTarget;
|
|
BMMNewTargetMenuItem.Hint:=lisMMCreateANewGroupOfOptions;
|
|
|
|
BMMNewCustomOptionMenuItem.Caption:=lisMMCustomOption;
|
|
BMMNewIDEMacroMenuItem.Caption:=lisMMIDEMacro;
|
|
BMMNewOutDirMenuItem.Caption:=lisMMOverrideOutputDirectory;
|
|
|
|
fCaptionPatternMacroName:=lisMMSetS;
|
|
fCaptionPatternMacroValue:=lisMMValueS;
|
|
|
|
BMMAddLclWidgetButton.Caption:=Format(fCaptionPatternMacroName,['LCLWidgetType']);
|
|
BMMAddLclWidgetButton.Hint := lisMMWidgetSetAvailableForLCLProject;
|
|
BMMAddOtherButton.Caption:=lisAdd;
|
|
|
|
UpdateButtons;
|
|
end;
|
|
|
|
destructor TCompOptModeMatrixFrame.Destroy;
|
|
begin
|
|
ModeMatrixFrame:=nil;
|
|
FreeAndNil(fOldIDEOptions);
|
|
FreeAndNil(fOldSharedOptions);
|
|
FreeAndNil(fOldSessionOptions);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TCompOptModeMatrixFrame.GetTitle: String;
|
|
begin
|
|
Result:=lisMMAdditionsAndOverrides;
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.Setup(ADialog: TAbstractOptionsEditorDialog);
|
|
begin
|
|
FDialog := ADialog;
|
|
end;
|
|
|
|
class function TCompOptModeMatrixFrame.SupportedOptionsClass: TAbstractIDEOptionsClass;
|
|
begin
|
|
Result := TProjectCompilerOptions;
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.ReadSettings(AOptions: TAbstractIDEOptions);
|
|
var
|
|
CompOptions: TProjectCompilerOptions;
|
|
begin
|
|
if not (AOptions is TProjectCompilerOptions) then exit;
|
|
CompOptions:=TProjectCompilerOptions(AOptions);
|
|
if LazProject=CompOptions.LazProject then begin
|
|
// options already loaded, only active compiler options are reloaded
|
|
UpdateActiveMode;
|
|
exit;
|
|
end;
|
|
fProject:=CompOptions.LazProject;
|
|
UpdateModes(false);
|
|
FillMenus;
|
|
|
|
// read IDE options
|
|
AssignBuildMatrixOptionsToGroup(EnvironmentOptions.BuildMatrixOptions,
|
|
Grid.Matrix,GroupIDE);
|
|
fOldIDEOptions.Assign(EnvironmentOptions.BuildMatrixOptions);
|
|
// read Project options
|
|
AssignBuildMatrixOptionsToGroup(LazProject.BuildModes.SharedMatrixOptions,
|
|
Grid.Matrix,GroupProject);
|
|
fOldSharedOptions.Assign(LazProject.BuildModes.SharedMatrixOptions);
|
|
// read Session options
|
|
AssignBuildMatrixOptionsToGroup(LazProject.BuildModes.SessionMatrixOptions,
|
|
Grid.Matrix,GroupSession);
|
|
fOldSessionOptions.Assign(LazProject.BuildModes.SessionMatrixOptions);
|
|
|
|
// update Grid
|
|
Grid.MatrixChanged;
|
|
// select project
|
|
Grid.Row:=Grid.Matrix.IndexOfRow(GroupProject)+1;
|
|
Grid.Col:=Grid.FixedCols;
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.WriteSettings(AOptions: TAbstractIDEOptions);
|
|
var
|
|
CompOptions: TProjectCompilerOptions;
|
|
begin
|
|
if not (AOptions is TProjectCompilerOptions) then exit;
|
|
CompOptions:=TProjectCompilerOptions(AOptions);
|
|
fProject:=CompOptions.LazProject;
|
|
|
|
DoWriteSettings;
|
|
end;
|
|
|
|
procedure TCompOptModeMatrixFrame.RestoreSettings(AOptions: TAbstractIDEOptions);
|
|
var
|
|
CompOptions: TProjectCompilerOptions;
|
|
begin
|
|
if not (AOptions is TProjectCompilerOptions) then exit;
|
|
CompOptions:=TProjectCompilerOptions(AOptions);
|
|
fProject:=CompOptions.LazProject;
|
|
|
|
// write IDE options
|
|
EnvironmentOptions.BuildMatrixOptions.Assign(fOldIDEOptions);
|
|
// write Project options
|
|
LazProject.BuildModes.SharedMatrixOptions.Assign(fOldSharedOptions);
|
|
// write Session options
|
|
LazProject.BuildModes.SessionMatrixOptions.Assign(fOldSessionOptions);
|
|
|
|
IncreaseCompilerParseStamp;
|
|
end;
|
|
|
|
function CheckBuildMatrixTargetsSyntax(const Targets: String): String;
|
|
var
|
|
p: PChar;
|
|
|
|
procedure WarnInvalidChar;
|
|
begin
|
|
Result:=Format(lisMMInvalidCharacterAt, [dbgstr(p^), IntToStr(p-PChar(
|
|
Targets)+1)]);
|
|
end;
|
|
|
|
begin
|
|
Result:='';
|
|
if Targets='' then exit;
|
|
p:=PChar(Targets);
|
|
repeat
|
|
case p^ of
|
|
#0:
|
|
if p-PChar(Targets)=length(Targets) then
|
|
break
|
|
else begin
|
|
WarnInvalidChar;
|
|
exit;
|
|
end;
|
|
#1..#32,#127:
|
|
begin
|
|
WarnInvalidChar;
|
|
exit;
|
|
end;
|
|
end;
|
|
inc(p);
|
|
until false;
|
|
end;
|
|
|
|
function SplitMatrixMacro(MacroAssignment: string; out MacroName,
|
|
MacroValue: string; ExceptionOnError: boolean): boolean;
|
|
|
|
procedure E(Msg: string);
|
|
begin
|
|
raise EMMMacroSyntaxException.Create(Msg);
|
|
end;
|
|
|
|
var
|
|
p: PChar;
|
|
StartP: PChar;
|
|
begin
|
|
Result:=false;
|
|
MacroName:='';
|
|
MacroValue:='';
|
|
if MacroAssignment='' then begin
|
|
if ExceptionOnError then
|
|
E(lisMMMissingMacroName);
|
|
exit;
|
|
end;
|
|
p:=PChar(MacroAssignment);
|
|
if not IsIdentStartChar[p^] then begin
|
|
if ExceptionOnError then
|
|
E(Format(lisMMExpectedMacroNameButFound, [dbgstr(p^)]));
|
|
exit;
|
|
end;
|
|
StartP:=p;
|
|
repeat
|
|
inc(p);
|
|
until not IsIdentChar[p^];
|
|
MacroName:=copy(MacroAssignment,1,p-StartP);
|
|
if (p^<>':') or (p[1]<>'=') then begin
|
|
if ExceptionOnError then
|
|
E(Format(lisMMExpectedAfterMacroNameButFound, [dbgstr(p^)]));
|
|
exit;
|
|
end;
|
|
inc(p,2);
|
|
StartP:=p;
|
|
repeat
|
|
if (p^=#0) and (p-PChar(MacroAssignment)=length(MacroAssignment)) then break;
|
|
if p^ in [#0..#31,#127] then begin
|
|
if ExceptionOnError then
|
|
E(Format(lisMMInvalidCharacterInMacroValue, [dbgstr(p^)]));
|
|
exit;
|
|
end;
|
|
inc(p);
|
|
until false;
|
|
MacroValue:=copy(MacroAssignment,StartP-PChar(MacroAssignment)+1,p-StartP);
|
|
Result:=true;
|
|
end;
|
|
|
|
initialization
|
|
RegisterIDEOptionsEditor(GroupCompiler, TCompOptModeMatrixFrame,
|
|
CompilerOptionsAdditionsAndOverrides);
|
|
|
|
end.
|
|
|