mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-19 13:22:58 +02:00
898 lines
30 KiB
ObjectPascal
898 lines
30 KiB
ObjectPascal
{ /***************************************************************************
|
|
codetoolsoptions.pas - Lazarus IDE unit
|
|
-----------------------------------------
|
|
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* This program 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. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
Author: Mattias Gaertner
|
|
|
|
Abstract:
|
|
- TCodeToolsDefinesEditor
|
|
}
|
|
unit CodeToolsDefines;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, LCLLinux, Forms, Controls, Buttons, StdCtrls, ComCtrls,
|
|
ExtCtrls, Menus, LResources, Graphics, ImgList, SynEdit, DefineTemplates,
|
|
CodeToolManager, CodeToolsOptions;
|
|
|
|
type
|
|
TCodeToolsDefinesEditor = class(TForm)
|
|
TheImageList: TImageList;
|
|
MainMenu: TMainMenu;
|
|
|
|
// exit menu
|
|
ExitMenuItem: TMenuItem;
|
|
SaveAndExitMenuItem: TMenuItem;
|
|
DontSaveAndExitMenuItem: TMenuItem;
|
|
|
|
// edit nodes
|
|
EditMenuItem: TMenuItem;
|
|
MoveNodeUpMenuItem: TMenuItem;
|
|
MoveNodeDownMenuItem: TMenuItem;
|
|
MoveNodeLvlUpMenuItem: TMenuItem;
|
|
MoveNodeLvlDownMenuItem: TMenuItem;
|
|
InsertBehindMenuItem: TMenuItem;
|
|
InsertBehindDefineMenuItem: TMenuItem;
|
|
InsertBehindDefineAllMenuItem: TMenuItem;
|
|
InsertBehindUndefineMenuItem: TMenuItem;
|
|
InsertBehindBlockMenuItem: TMenuItem;
|
|
InsertBehindDirectoryMenuItem: TMenuItem;
|
|
InsertBehindIfMenuItem: TMenuItem;
|
|
InsertBehindIfDefMenuItem: TMenuItem;
|
|
InsertBehindIfNotDefMenuItem: TMenuItem;
|
|
InsertBehindElseIfMenuItem: TMenuItem;
|
|
InsertBehindElseMenuItem: TMenuItem;
|
|
InsertAsChildMenuItem: TMenuItem;
|
|
InsertAsChildDefineMenuItem: TMenuItem;
|
|
InsertAsChildDefineAllMenuItem: TMenuItem;
|
|
InsertAsChildUndefineMenuItem: TMenuItem;
|
|
InsertAsChildBlockMenuItem: TMenuItem;
|
|
InsertAsChildDirectoryMenuItem: TMenuItem;
|
|
InsertAsChildIfMenuItem: TMenuItem;
|
|
InsertAsChildIfDefMenuItem: TMenuItem;
|
|
InsertAsChildIfNotDefMenuItem: TMenuItem;
|
|
InsertAsChildElseIfMenuItem: TMenuItem;
|
|
InsertAsChildElseMenuItem: TMenuItem;
|
|
DeleteNodeMenuItem: TMenuItem;
|
|
CopyToClipbrdMenuItem: TMenuItem;
|
|
PasteFromClipbrdMenuItem: TMenuItem;
|
|
|
|
// tools
|
|
ToolsMenuItem: TMenuItem;
|
|
OpenPreviewMenuItem: TMenuItem;
|
|
ShowMacroListMenuItem: TMenuItem;
|
|
|
|
// templates
|
|
InsertTemplateMenuItem: TMenuItem;
|
|
|
|
// define tree
|
|
DefineTreeView: TTreeView;
|
|
|
|
// selected item
|
|
SelectedItemGroupBox: TGroupBox;
|
|
TypeLabel: TLabel;
|
|
ProjectSpecificCheckBox: TCheckBox;
|
|
NameLabel: TLabel;
|
|
NameEdit: TEdit;
|
|
DescriptionLabel: TLabel;
|
|
DescriptionEdit: TEdit;
|
|
VariableLabel: TLabel;
|
|
VariableEdit: TEdit;
|
|
ValueNoteBook: TNoteBook;
|
|
ValueAsTextSynEdit: TSynEdit;
|
|
ValueAsFilePathsSynEdit: TSynEdit;
|
|
MoveFilePathUpBitBtn: TBitBtn;
|
|
MoveFilePathDownBitBtn: TBitBtn;
|
|
DeleteFilePathBitBtn: TBitBtn;
|
|
InsertFilePathBitBtn: TBitBtn;
|
|
|
|
procedure SaveAndExitMenuItemClick(Sender: TObject);
|
|
procedure DontSaveAndExitMenuItemClick(Sender: TObject);
|
|
procedure FormResize(Sender: TObject);
|
|
procedure DefineTreeViewMouseUp(Sender: TObject; Button: TMouseButton;
|
|
Shift: TShiftState; X,Y: integer);
|
|
procedure ValueNoteBookPageChanged(Sender: TObject);
|
|
procedure MoveFilePathUpBitBtnClick(Sender: TObject);
|
|
procedure MoveFilePathDownBitBtnClick(Sender: TObject);
|
|
procedure DeleteFilePathBitBtnClick(Sender: TObject);
|
|
procedure InsertFilePathBitBtnClick(Sender: TObject);
|
|
procedure InsertNodeMenuItemClick(Sender: TObject);
|
|
private
|
|
FDefineTree: TDefineTree;
|
|
FLastSelectedNode: TTreeNode;
|
|
procedure CreateComponents;
|
|
function CreateSeperator : TMenuItem;
|
|
procedure RebuildDefineTreeView;
|
|
procedure AddDefineNodes(ANode: TDefineTemplate; AParent: TTreeNode;
|
|
WithChilds,WithNextSiblings: boolean);
|
|
procedure SetNodeImages(ANode: TTreeNode);
|
|
procedure ValueAsPathToValueAsText;
|
|
procedure SaveSelectedValues;
|
|
procedure ShowSelectedValues;
|
|
function ValueToFilePathText(const AValue: string): string;
|
|
procedure InsertNewNode(Behind: boolean; Action: TDefineAction);
|
|
public
|
|
procedure Assign(ACodeToolBoss: TCodeToolManager;
|
|
Options: TCodeToolsOptions);
|
|
constructor Create(TheOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
property DefineTree: TDefineTree read FDefineTree;
|
|
end;
|
|
|
|
function ShowCodeToolsDefinesEditor(ACodeToolBoss: TCodeToolManager;
|
|
Options: TCodeToolsOptions): TModalResult;
|
|
|
|
|
|
implementation
|
|
|
|
const
|
|
DefineActionNames: array[TDefineAction] of string = (
|
|
'None', 'Block', 'Define', 'Undefine', 'DefineAll',
|
|
'If', 'IfDef', 'IfNDef', 'ElseIf', 'Else', 'Directory'
|
|
);
|
|
|
|
type
|
|
TWinControlClass = class of TWinControl;
|
|
|
|
|
|
function ShowCodeToolsDefinesEditor(ACodeToolBoss: TCodeToolManager;
|
|
Options: TCodeToolsOptions): TModalResult;
|
|
var CodeToolsDefinesEditor: TCodeToolsDefinesEditor;
|
|
begin
|
|
CodeToolsDefinesEditor:=TCodeToolsDefinesEditor.Create(Application);
|
|
CodeToolsDefinesEditor.Assign(ACodeToolBoss,Options);
|
|
Result:=CodeToolsDefinesEditor.ShowModal;
|
|
CodeToolsDefinesEditor.Free;
|
|
end;
|
|
|
|
{ TCodeToolsDefinesEditor }
|
|
|
|
procedure TCodeToolsDefinesEditor.SaveAndExitMenuItemClick(Sender: TObject);
|
|
begin
|
|
ModalResult:=mrOk;
|
|
end;
|
|
|
|
procedure TCodeToolsDefinesEditor.DontSaveAndExitMenuItemClick(Sender: TObject);
|
|
begin
|
|
ModalResult:=mrCancel;
|
|
end;
|
|
|
|
procedure TCodeToolsDefinesEditor.FormResize(Sender: TObject);
|
|
var MaxX, MaxY, SelGrpBoxTop, SelItemMaxX, SelItemMaxY,
|
|
ValNoteBookMaxX, ValNoteBookMaxY: integer;
|
|
begin
|
|
MaxX:=ClientWidth-2;
|
|
MaxY:=ClientHeight-2;
|
|
SelGrpBoxTop:=MaxY-300;
|
|
|
|
// define tree ---------------------------------------------------------------
|
|
with DefineTreeView do begin
|
|
Left:=3;
|
|
Top:=3;
|
|
Width:=MaxX-2*Left;
|
|
Height:=SelGrpBoxTop-2*Top;
|
|
end;
|
|
|
|
// selected item -------------------------------------------------------------
|
|
with SelectedItemGroupBox do begin
|
|
Left:=DefineTreeView.Left;
|
|
Top:=SelGrpBoxTop;
|
|
Width:=MaxX-2*Left;
|
|
Height:=MaxY-Top-30;
|
|
end;
|
|
SelItemMaxX:=SelectedItemGroupBox.ClientWidth-8;
|
|
SelItemMaxY:=SelectedItemGroupBox.ClientHeight-18;
|
|
with TypeLabel do begin
|
|
Left:=5;
|
|
Top:=3;
|
|
Width:=SelItemMaxX-2*Left;
|
|
end;
|
|
with ProjectSpecificCheckBox do begin
|
|
Left:=TypeLabel.Left;
|
|
Top:=TypeLabel.Top+TypeLabel.Height+5;
|
|
Width:=SelItemMaxX-2*Left;
|
|
end;
|
|
with DescriptionLabel do begin
|
|
Left:=ProjectSpecificCheckBox.Left;
|
|
Top:=ProjectSpecificCheckBox.Top+ProjectSpecificCheckBox.Height+5;
|
|
Width:=70;
|
|
end;
|
|
with DescriptionEdit do begin
|
|
Left:=DescriptionLabel.Left+DescriptionLabel.Width+5;
|
|
Top:=DescriptionLabel.Top;
|
|
Width:=SelItemMaxX-Left-5;
|
|
end;
|
|
with NameLabel do begin
|
|
Left:=DescriptionLabel.Left;
|
|
Top:=DescriptionLabel.Top+DescriptionLabel.Height+5;
|
|
Width:=70;
|
|
end;
|
|
with NameEdit do begin
|
|
Left:=NameLabel.Left+NameLabel.Width+5;
|
|
Top:=NameLabel.Top;
|
|
Width:=150;
|
|
end;
|
|
with VariableLabel do begin
|
|
Left:=NameEdit.Left+NameEdit.Width+30;
|
|
Top:=NameLabel.Top;
|
|
Width:=70;
|
|
end;
|
|
with VariableEdit do begin
|
|
Left:=VariableLabel.Left+VariableLabel.Width+5;
|
|
Top:=VariableLabel.Top;
|
|
Width:=SelItemMaxX-Left-5;
|
|
end;
|
|
with ValueNoteBook do begin
|
|
Left:=0;
|
|
Top:=VariableLabel.Top+VariableLabel.Height+8;
|
|
Width:=SelItemMaxX;
|
|
Height:=SelItemMaxY-Top-5;
|
|
end;
|
|
ValNoteBookMaxX:=ValueNoteBook.ClientWidth-7;//ValueAsTextSynEdit.Parent.ClientWidth;
|
|
ValNoteBookMaxY:=ValueNoteBook.ClientHeight-32;//ValueAsTextSynEdit.Parent.ClientHeight;
|
|
with ValueAsTextSynEdit do begin
|
|
Left:=0;
|
|
Top:=0;
|
|
Width:=ValNoteBookMaxX;
|
|
Height:=ValNoteBookMaxY;
|
|
end;
|
|
with ValueAsFilePathsSynEdit do begin
|
|
Left:=0;
|
|
Top:=0;
|
|
Width:=ValNoteBookMaxX-80;
|
|
Height:=ValNoteBookMaxY;
|
|
end;
|
|
with MoveFilePathUpBitBtn do begin
|
|
Left:=ValNoteBookMaxX-75;
|
|
Top:=1;
|
|
Width:=ValNoteBookMaxX-Left-5;
|
|
end;
|
|
with MoveFilePathDownBitBtn do begin
|
|
Left:=MoveFilePathUpBitBtn.Left;
|
|
Top:=MoveFilePathUpBitBtn.Top+MoveFilePathUpBitBtn.Height+5;
|
|
Width:=MoveFilePathUpBitBtn.Width;
|
|
end;
|
|
with DeleteFilePathBitBtn do begin
|
|
Left:=MoveFilePathUpBitBtn.Left;
|
|
Top:=MoveFilePathDownBitBtn.Top+MoveFilePathDownBitBtn.Height+5;
|
|
Width:=MoveFilePathUpBitBtn.Width;
|
|
end;
|
|
with InsertFilePathBitBtn do begin
|
|
Left:=MoveFilePathUpBitBtn.Left;
|
|
Top:=DeleteFilePathBitBtn.Top+DeleteFilePathBitBtn.Height+5;
|
|
Width:=MoveFilePathUpBitBtn.Width;
|
|
end;
|
|
end;
|
|
|
|
procedure TCodeToolsDefinesEditor.DefineTreeViewMouseUp(Sender: TObject;
|
|
Button: TMouseButton; Shift: TShiftState; X, Y: integer);
|
|
begin
|
|
ShowSelectedValues;
|
|
end;
|
|
|
|
procedure TCodeToolsDefinesEditor.ValueNoteBookPageChanged(Sender: TObject);
|
|
begin
|
|
if ValueNoteBook.PageIndex=0 then ValueAsPathToValueAsText;
|
|
end;
|
|
|
|
procedure TCodeToolsDefinesEditor.MoveFilePathUpBitBtnClick(Sender: TObject);
|
|
var y: integer;
|
|
begin
|
|
if ValueAsFilePathsSynEdit.ReadOnly then exit;
|
|
y:=ValueAsFilePathsSynEdit.CaretY;
|
|
if (y>1) and (y<=ValueAsFilePathsSynEdit.Lines.Count) then
|
|
ValueAsFilePathsSynEdit.Lines.Move(y,y-1);
|
|
end;
|
|
|
|
procedure TCodeToolsDefinesEditor.MoveFilePathDownBitBtnClick(Sender: TObject);
|
|
var y: integer;
|
|
begin
|
|
if ValueAsFilePathsSynEdit.ReadOnly then exit;
|
|
y:=ValueAsFilePathsSynEdit.CaretY;
|
|
if (y>=1) and (y<ValueAsFilePathsSynEdit.Lines.Count) then
|
|
ValueAsFilePathsSynEdit.Lines.Move(y,y+1);
|
|
end;
|
|
|
|
procedure TCodeToolsDefinesEditor.DeleteFilePathBitBtnClick(Sender: TObject);
|
|
var y: integer;
|
|
begin
|
|
if ValueAsFilePathsSynEdit.ReadOnly then exit;
|
|
y:=ValueAsFilePathsSynEdit.CaretY;
|
|
if (y>=1) and (y<=ValueAsFilePathsSynEdit.Lines.Count) then
|
|
ValueAsFilePathsSynEdit.Lines.Delete(y);
|
|
end;
|
|
|
|
procedure TCodeToolsDefinesEditor.InsertFilePathBitBtnClick(Sender: TObject);
|
|
var y: integer;
|
|
begin
|
|
if ValueAsFilePathsSynEdit.ReadOnly then exit;
|
|
y:=ValueAsFilePathsSynEdit.CaretY;
|
|
if (y>=1) and (y<=ValueAsFilePathsSynEdit.Lines.Count) then
|
|
ValueAsFilePathsSynEdit.Lines.Insert(y,'');
|
|
end;
|
|
|
|
procedure TCodeToolsDefinesEditor.InsertNodeMenuItemClick(Sender: TObject);
|
|
var Behind: boolean;
|
|
Action: TDefineAction;
|
|
begin
|
|
Behind:=(TMenuItem(Sender).Parent=InsertBehindMenuItem);
|
|
if Sender=InsertBehindDefineMenuItem then Action:=da_Define
|
|
else if Sender=InsertBehindDefineAllMenuItem then Action:=da_DefineAll
|
|
else if Sender=InsertBehindUndefineMenuItem then Action:=da_Undefine
|
|
else if Sender=InsertBehindBlockMenuItem then Action:=da_Block
|
|
else if Sender=InsertBehindDirectoryMenuItem then Action:=da_Directory
|
|
else if Sender=InsertBehindIfMenuItem then Action:=da_If
|
|
else if Sender=InsertBehindIfDefMenuItem then Action:=da_IfDef
|
|
else if Sender=InsertBehindIfNotDefMenuItem then Action:=da_IfNDef
|
|
else if Sender=InsertBehindElseIfMenuItem then Action:=da_ElseIf
|
|
else if Sender=InsertBehindElseMenuItem then Action:=da_Else
|
|
else if Sender=InsertAsChildDefineMenuItem then Action:=da_Define
|
|
else if Sender=InsertAsChildDefineAllMenuItem then Action:=da_DefineAll
|
|
else if Sender=InsertAsChildUndefineMenuItem then Action:=da_Undefine
|
|
else if Sender=InsertAsChildBlockMenuItem then Action:=da_Block
|
|
else if Sender=InsertAsChildDirectoryMenuItem then Action:=da_Directory
|
|
else if Sender=InsertAsChildIfMenuItem then Action:=da_If
|
|
else if Sender=InsertAsChildIfDefMenuItem then Action:=da_IfDef
|
|
else if Sender=InsertAsChildIfNotDefMenuItem then Action:=da_IfNDef
|
|
else if Sender=InsertAsChildElseIfMenuItem then Action:=da_ElseIf
|
|
else if Sender=InsertAsChildElseMenuItem then Action:=da_Else;
|
|
InsertNewNode(Behind,Action);
|
|
end;
|
|
|
|
procedure TCodeToolsDefinesEditor.CreateComponents;
|
|
|
|
procedure CreateWinControl(var AWinControl: TWinControl;
|
|
AWinControlClass: TWinControlClass; const AName: string;
|
|
AParent: TWinControl);
|
|
begin
|
|
AWinControl:=AWinControlClass.Create(Self);
|
|
with AWinControl do begin
|
|
Name:=AName;
|
|
Parent:=AParent;
|
|
Visible:=true;
|
|
end;
|
|
end;
|
|
|
|
procedure AddMenuItem(var AMenuItem: TMenuItem; const AName, ACaption: string;
|
|
AParent: TMenuItem);
|
|
begin
|
|
AMenuItem:=TMenuItem.Create(nil);
|
|
AMenuItem.Name:=AName;
|
|
AMenuItem.Caption:=ACaption;
|
|
if AParent=nil then
|
|
MainMenu.Items.Add(AMenuItem)
|
|
else
|
|
AParent.Add(AMenuItem);
|
|
end;
|
|
|
|
procedure AddResImg(const ResName: string);
|
|
var Pixmap: TPixmap;
|
|
begin
|
|
Pixmap:=TPixmap.Create;
|
|
Pixmap.TransparentColor:=clWhite;
|
|
Pixmap.LoadFromLazarusResource(ResName);
|
|
TheImageList.Add(Pixmap,nil)
|
|
end;
|
|
|
|
var i: integer;
|
|
begin
|
|
TheImageList:=TImageList.Create(Self);
|
|
with TheImageList do begin
|
|
Width:=22;
|
|
Height:=22;
|
|
Name:='TheImageList';
|
|
AddResImg('define_22x22');
|
|
AddResImg('defineall_22x22');
|
|
AddResImg('undefine_22x22');
|
|
AddResImg('block_22x22');
|
|
AddResImg('directory_22x22');
|
|
AddResImg('if_22x22');
|
|
AddResImg('ifdef_22x22');
|
|
AddResImg('ifndef_22x22');
|
|
AddResImg('elseif_22x22');
|
|
AddResImg('else_22x22');
|
|
AddResImg('ctdefinestate_none_22x22');
|
|
AddResImg('ctdefinestate_auto_22x22');
|
|
AddResImg('ctdefinestate_projspec_22x22');
|
|
AddResImg('ctdefinestate_autoproj_22x22');
|
|
end;
|
|
|
|
// Main Menu -----------------------------------------------------------------
|
|
MainMenu := TMainMenu.Create(Self);
|
|
MainMenu.Name:='MainMenu';
|
|
Menu := MainMenu;
|
|
|
|
// exit menu
|
|
AddMenuItem(ExitMenuItem,'ExitMenuItem','Exit',nil);
|
|
AddMenuItem(SaveAndExitMenuItem,'SaveAndExitMenuItem','Save and Exit',
|
|
ExitMenuItem);
|
|
SaveAndExitMenuItem.OnClick:=@SaveAndExitMenuItemClick;
|
|
ExitMenuItem.Add(CreateSeperator);
|
|
AddMenuItem(DontSaveAndExitMenuItem,'DontSaveAndExitMenuItem',
|
|
'Exit without Save',ExitMenuItem);
|
|
DontSaveAndExitMenuItem.OnClick:=@DontSaveAndExitMenuItemClick;
|
|
|
|
// edit nodes
|
|
AddMenuItem(EditMenuItem,'EditMenuItem','Edit',nil);
|
|
AddMenuItem(MoveNodeUpMenuItem,'MoveNodeUpMenuItem','Move node up',
|
|
EditMenuItem);
|
|
AddMenuItem(MoveNodeDownMenuItem,'MoveNodeDownMenuItem','Move node down',
|
|
EditMenuItem);
|
|
AddMenuItem(MoveNodeLvlUpMenuItem,'MoveNodeLvlUpMenuItem','Move node one level up',
|
|
EditMenuItem);
|
|
AddMenuItem(MoveNodeLvlDownMenuItem,'MoveNodeLvlDownMenuItem','Move node one level down',
|
|
EditMenuItem);
|
|
EditMenuItem.Add(CreateSeperator);
|
|
AddMenuItem(InsertBehindMenuItem,'InsertBehindMenuItem','Insert node behind',
|
|
EditMenuItem);
|
|
AddMenuItem(InsertAsChildMenuItem,'InsertAsChildMenuItem','Insert node as child',
|
|
EditMenuItem);
|
|
EditMenuItem.Add(CreateSeperator);
|
|
AddMenuItem(DeleteNodeMenuItem,'DeleteNodeMenuItem','Delete node',
|
|
EditMenuItem);
|
|
EditMenuItem.Add(CreateSeperator);
|
|
AddMenuItem(CopyToClipbrdMenuItem,'CopyToClipbrdMenuItem','Copy to clipboard',
|
|
EditMenuItem);
|
|
AddMenuItem(PasteFromClipbrdMenuItem,'PasteFromClipbrdMenuItem',
|
|
'Paste from clipboard',EditMenuItem);
|
|
|
|
// insert node behind submenu
|
|
AddMenuItem(InsertBehindDefineMenuItem,'InsertBehindDefineMenuItem','Define',
|
|
InsertBehindMenuItem);
|
|
AddMenuItem(InsertBehindDefineAllMenuItem,'InsertBehindDefineAllMenuItem','Define All',
|
|
InsertBehindMenuItem);
|
|
AddMenuItem(InsertBehindUndefineMenuItem,'InsertBehindUndefineMenuItem','Undefine',
|
|
InsertBehindMenuItem);
|
|
InsertBehindMenuItem.Add(CreateSeperator);
|
|
AddMenuItem(InsertBehindBlockMenuItem,'InsertBehindBlockMenuItem','Block',
|
|
InsertBehindMenuItem);
|
|
AddMenuItem(InsertBehindDirectoryMenuItem,'InsertBehindDirectoryMenuItem','Directory',
|
|
InsertBehindMenuItem);
|
|
InsertBehindMenuItem.Add(CreateSeperator);
|
|
AddMenuItem(InsertBehindIfMenuItem,'InsertBehindIfMenuItem','If',
|
|
InsertBehindMenuItem);
|
|
AddMenuItem(InsertBehindIfDefMenuItem,'InsertBehindIfDefMenuItem','IfDef',
|
|
InsertBehindMenuItem);
|
|
AddMenuItem(InsertBehindIfNotDefMenuItem,'InsertBehindIfNotDefMenuItem','IfNDef',
|
|
InsertBehindMenuItem);
|
|
AddMenuItem(InsertBehindElseIfMenuItem,'InsertBehindElseIfMenuItem','ElseIf',
|
|
InsertBehindMenuItem);
|
|
AddMenuItem(InsertBehindElseMenuItem,'InsertBehindElseMenuItem','Else',
|
|
InsertBehindMenuItem);
|
|
for i:=0 to InsertBehindMenuItem.Count-1 do
|
|
if InsertBehindMenuItem[i].Caption<>'-' then
|
|
InsertBehindMenuItem[i].OnClick:=@InsertNodeMenuItemClick;
|
|
|
|
// insert node as child submenu
|
|
AddMenuItem(InsertAsChildDefineMenuItem,'InsertAsChildDefineMenuItem','Define',
|
|
InsertAsChildMenuItem);
|
|
AddMenuItem(InsertAsChildDefineAllMenuItem,'InsertAsChildDefineAllMenuItem','Define All',
|
|
InsertAsChildMenuItem);
|
|
AddMenuItem(InsertAsChildUndefineMenuItem,'InsertAsChildUndefineMenuItem','Undefine',
|
|
InsertAsChildMenuItem);
|
|
InsertAsChildMenuItem.Add(CreateSeperator);
|
|
AddMenuItem(InsertAsChildBlockMenuItem,'InsertAsChildBlockMenuItem','Block',
|
|
InsertAsChildMenuItem);
|
|
AddMenuItem(InsertAsChildDirectoryMenuItem,'InsertAsChildDirectoryMenuItem','Directory',
|
|
InsertAsChildMenuItem);
|
|
InsertAsChildMenuItem.Add(CreateSeperator);
|
|
AddMenuItem(InsertAsChildIfMenuItem,'InsertAsChildIfMenuItem','If',
|
|
InsertAsChildMenuItem);
|
|
AddMenuItem(InsertAsChildIfDefMenuItem,'InsertAsChildIfDefMenuItem','IfDef',
|
|
InsertAsChildMenuItem);
|
|
AddMenuItem(InsertAsChildIfNotDefMenuItem,'InsertAsChildIfNotDefMenuItem','IfNDef',
|
|
InsertAsChildMenuItem);
|
|
AddMenuItem(InsertAsChildElseIfMenuItem,'InsertAsChildElseIfMenuItem','ElseIf',
|
|
InsertAsChildMenuItem);
|
|
AddMenuItem(InsertAsChildElseMenuItem,'InsertAsChildElseMenuItem','Else',
|
|
InsertAsChildMenuItem);
|
|
for i:=0 to InsertAsChildMenuItem.Count-1 do
|
|
if InsertAsChildMenuItem[i].Caption<>'-' then
|
|
InsertAsChildMenuItem[i].OnClick:=@InsertNodeMenuItemClick;
|
|
|
|
// tools
|
|
AddMenuItem(ToolsMenuItem,'ToolsMenuItem','Tools',nil);
|
|
AddMenuItem(OpenPreviewMenuItem,'OpenPreviewMenuItem','Open Preview',
|
|
ToolsMenuItem);
|
|
AddMenuItem(ShowMacroListMenuItem,'ShowMacroListMenuItem','Show Macros',
|
|
ToolsMenuItem);
|
|
|
|
// templates
|
|
AddMenuItem(InsertTemplateMenuItem,'InsertTemplateMenuItem',
|
|
'Insert Template',nil);
|
|
|
|
|
|
// define tree----------------------------------------------------------------
|
|
CreateWinControl(DefineTreeView,TTreeView,'DefineTreeView',Self);
|
|
with DefineTreeView do begin
|
|
DefaultItemHeight:=22;
|
|
Images:=TheImageList;
|
|
StateImages:=TheImageList;
|
|
OnMouseUp:=@DefineTreeViewMouseUp;
|
|
end;
|
|
|
|
// selected item
|
|
CreateWinControl(SelectedItemGroupBox,TGroupBox,'SelectedItemGroupBox',Self);
|
|
SelectedItemGroupBox.Caption:='Selected Node:';
|
|
|
|
CreateWinControl(TypeLabel,TLabel,'TypeLabel',SelectedItemGroupBox);
|
|
|
|
CreateWinControl(ProjectSpecificCheckBox,TCheckBox,'ProjectSpecificCheckBox',
|
|
SelectedItemGroupBox);
|
|
ProjectSpecificCheckBox.Caption:=
|
|
'Node and its children are only valid for this project';
|
|
|
|
CreateWinControl(NameLabel,TLabel,'NameLabel',SelectedItemGroupBox);
|
|
NameLabel.Caption:='Name:';
|
|
|
|
CreateWinControl(NameEdit,TEdit,'NameEdit',SelectedItemGroupBox);
|
|
|
|
CreateWinControl(DescriptionLabel,TLabel,'DescriptionLabel',
|
|
SelectedItemGroupBox);
|
|
DescriptionLabel.Caption:='Description:';
|
|
|
|
CreateWinControl(DescriptionEdit,TEdit,'DescriptionEdit',
|
|
SelectedItemGroupBox);
|
|
|
|
CreateWinControl(VariableLabel,TLabel,'VariableLabel',SelectedItemGroupBox);
|
|
VariableLabel.Caption:='Variable:';
|
|
|
|
CreateWinControl(VariableEdit,TEdit,'VariableEdit',SelectedItemGroupBox);
|
|
|
|
CreateWinControl(ValueNoteBook,TNoteBook,'ValueNoteBook',
|
|
SelectedItemGroupBox);
|
|
with ValueNoteBook do begin
|
|
Pages[0]:='Value as Text';
|
|
Pages.Add('Value as File Paths');
|
|
OnPageChanged:=@ValueNoteBookPageChanged;
|
|
end;
|
|
|
|
CreateWinControl(ValueAsTextSynEdit,TSynEdit,'ValueAsTextSynEdit',
|
|
ValueNoteBook.Page[0]);
|
|
ValueAsTextSynEdit.Options:=[eoBracketHighlight, eoHideRightMargin,
|
|
eoDragDropEditing, eoHalfPageScroll, eoScrollByOneLess, eoScrollPastEol,
|
|
eoSmartTabs, eoTabsToSpaces, eoTrimTrailingSpaces];
|
|
ValueAsTextSynEdit.Gutter.Visible:=false;
|
|
|
|
CreateWinControl(ValueAsFilePathsSynEdit,TSynEdit,'ValueAsFilePathsSynEdit',
|
|
ValueNoteBook.Page[1]);
|
|
ValueAsFilePathsSynEdit.Options:=[eoBracketHighlight, eoHideRightMargin,
|
|
eoDragDropEditing, eoHalfPageScroll, eoScrollByOneLess, eoScrollPastEol,
|
|
eoSmartTabs, eoTabsToSpaces, eoTrimTrailingSpaces];
|
|
ValueAsFilePathsSynEdit.Gutter.Visible:=false;
|
|
|
|
CreateWinControl(MoveFilePathUpBitBtn,TBitBtn,'MoveFilePathUpBitBtn',
|
|
ValueNoteBook.Page[1]);
|
|
MoveFilePathUpBitBtn.Caption:='Up';
|
|
MoveFilePathUpBitBtn.OnClick:=@MoveFilePathUpBitBtnClick;
|
|
|
|
CreateWinControl(MoveFilePathDownBitBtn,TBitBtn,'MoveFilePathDownBitBtn',
|
|
ValueNoteBook.Page[1]);
|
|
MoveFilePathDownBitBtn.Caption:='Down';
|
|
MoveFilePathDownBitBtn.OnClick:=@MoveFilePathDownBitBtnClick;
|
|
|
|
CreateWinControl(DeleteFilePathBitBtn,TBitBtn,'DeleteFilePathBitBtn',
|
|
ValueNoteBook.Page[1]);
|
|
DeleteFilePathBitBtn.Caption:='Delete';
|
|
DeleteFilePathBitBtn.OnClick:=@DeleteFilePathBitBtnClick;
|
|
|
|
CreateWinControl(InsertFilePathBitBtn,TBitBtn,'InsertFilePathBitBtn',
|
|
ValueNoteBook.Page[1]);
|
|
InsertFilePathBitBtn.Caption:='Insert';
|
|
InsertFilePathBitBtn.OnClick:=@InsertFilePathBitBtnClick;
|
|
end;
|
|
|
|
function TCodeToolsDefinesEditor.CreateSeperator : TMenuItem;
|
|
begin
|
|
Result := TMenuItem.Create(Self);
|
|
Result.Caption := '-';
|
|
end;
|
|
|
|
procedure TCodeToolsDefinesEditor.RebuildDefineTreeView;
|
|
begin
|
|
DefineTreeView.Items.BeginUpdate;
|
|
DefineTreeView.Items.Clear;
|
|
AddDefineNodes(FDefineTree.RootTemplate,nil,true,true);
|
|
DefineTreeView.Items.EndUpdate;
|
|
end;
|
|
|
|
procedure TCodeToolsDefinesEditor.AddDefineNodes(
|
|
ANode: TDefineTemplate; AParent: TTreeNode;
|
|
WithChilds, WithNextSiblings: boolean);
|
|
var NewTreeNode: TTreeNode;
|
|
begin
|
|
if ANode=nil then exit;
|
|
//writeln(' AAA ',StringOfChar(' ',ANode.Level*2),' ',ANode.Name,' ',WithChilds,',',WithNextSiblings);
|
|
DefineTreeView.Items.BeginUpdate;
|
|
NewTreeNode:=DefineTreeView.Items.AddChildObject(AParent,ANode.Name,ANode);
|
|
SetNodeImages(NewTreeNode);
|
|
if WithChilds and (ANode.FirstChild<>nil) then begin
|
|
AddDefineNodes(ANode.FirstChild,NewTreeNode,true,true);
|
|
end;
|
|
if WithNextSiblings and (ANode.Next<>nil) then begin
|
|
AddDefineNodes(ANode.Next,AParent,WithChilds,true);
|
|
end;
|
|
DefineTreeView.Items.EndUpdate;
|
|
end;
|
|
|
|
procedure TCodeToolsDefinesEditor.SetNodeImages(ANode: TTreeNode);
|
|
var ADefineTemplate: TDefineTemplate;
|
|
begin
|
|
ADefineTemplate:=TDefineTemplate(ANode.Data);
|
|
case ADefineTemplate.Action of
|
|
da_Define: ANode.ImageIndex:=0;
|
|
da_DefineAll: ANode.ImageIndex:=1;
|
|
da_Undefine: ANode.ImageIndex:=2;
|
|
da_Block: ANode.ImageIndex:=3;
|
|
da_Directory: ANode.ImageIndex:=4;
|
|
da_If: ANode.ImageIndex:=5;
|
|
da_IfDef: ANode.ImageIndex:=6;
|
|
da_IfNDef: ANode.ImageIndex:=7;
|
|
da_ElseIf: ANode.ImageIndex:=8;
|
|
da_Else: ANode.ImageIndex:=9;
|
|
else
|
|
ANode.ImageIndex:=-1;
|
|
end;
|
|
ANode.SelectedIndex:=ANode.ImageIndex;
|
|
if dtfAutoGenerated in ADefineTemplate.Flags then begin
|
|
if dtfProjectSpecific in ADefineTemplate.Flags then
|
|
ANode.StateIndex:=13
|
|
else
|
|
ANode.StateIndex:=11;
|
|
end else begin
|
|
if dtfProjectSpecific in ADefineTemplate.Flags then
|
|
ANode.StateIndex:=12
|
|
else
|
|
ANode.StateIndex:=10;
|
|
end;
|
|
end;
|
|
|
|
procedure TCodeToolsDefinesEditor.ValueAsPathToValueAsText;
|
|
var s: string;
|
|
i, j, l: integer;
|
|
begin
|
|
s:=ValueAsFilePathsSynEdit.Text;
|
|
l:=length(s);
|
|
if (l>0) and (s[l] in [#13,#10]) then begin
|
|
// remove line end at end of Text, that was added automatically
|
|
dec(l);
|
|
if (l>0) and (s[l] in [#13,#10]) and (s[l]<>s[l+1]) then
|
|
dec(l);
|
|
SetLength(s,l);
|
|
end;
|
|
// replace line ends with semicolon
|
|
i:=1;
|
|
j:=1;
|
|
while i<=l do begin
|
|
if s[i] in [#10,#13] then begin
|
|
inc(i);
|
|
if (i<l) and (s[i] in [#10,#13]) and (s[i]<>s[i+1]) then
|
|
inc(i);
|
|
s[j]:=';';
|
|
inc(j);
|
|
end else begin
|
|
s[j]:=s[i];
|
|
inc(i);
|
|
inc(j);
|
|
end;
|
|
end;
|
|
SetLength(s,j-1);
|
|
ValueAsTextSynEdit.Text:=s;
|
|
end;
|
|
|
|
procedure TCodeToolsDefinesEditor.SaveSelectedValues;
|
|
var
|
|
SelTreeNode: TTreeNode;
|
|
SelDefNode: TDefineTemplate;
|
|
s: string;
|
|
l: integer;
|
|
begin
|
|
SelTreeNode:=DefineTreeView.Selected;
|
|
if (SelTreeNode<>nil) then begin
|
|
SelDefNode:=TDefineTemplate(SelTreeNode.Data);
|
|
if (not SelDefNode.IsAutoGenerated) then begin
|
|
if ProjectSpecificCheckBox.Checked then
|
|
Include(SelDefNode.Flags,dtfProjectSpecific);
|
|
SelDefNode.Name:=NameEdit.Text;
|
|
SelDefNode.Variable:=VariableEdit.Text;
|
|
SelDefNode.Description:=DescriptionEdit.Text;
|
|
s:=ValueAsTextSynEdit.Text;
|
|
l:=length(s);
|
|
if (l>0) and (s[l] in [#13,#10]) then begin
|
|
// remove line end at end of Text, that was added automatically
|
|
dec(l);
|
|
if (l>0) and (s[l] in [#13,#10]) and (s[l]<>s[l+1]) then
|
|
dec(l);
|
|
SetLength(s,l);
|
|
end;
|
|
SelDefNode.Value:=s;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TCodeToolsDefinesEditor.ShowSelectedValues;
|
|
var
|
|
SelTreeNode: TTreeNode;
|
|
SelDefNode: TDefineTemplate;
|
|
s: string;
|
|
begin
|
|
SelTreeNode:=DefineTreeView.Selected;
|
|
if SelTreeNode<>FLastSelectedNode then begin
|
|
SaveSelectedValues;
|
|
end;
|
|
if SelTreeNode<>nil then begin
|
|
SelDefNode:=TDefineTemplate(SelTreeNode.Data);
|
|
SelectedItemGroupBox.Enabled:=true;
|
|
s:='Action: '+DefineActionNames[SelDefNode.Action];
|
|
if SelDefNode.IsAutoGenerated then
|
|
s:=s+', auto generated';
|
|
if SelDefNode.IsProjectSpecific then
|
|
s:=s+', project specific';
|
|
TypeLabel.Caption:=s;
|
|
ProjectSpecificCheckBox.Checked:=dtfProjectSpecific in SelDefNode.Flags;
|
|
NameEdit.Text:=SelDefNode.Name;
|
|
DescriptionEdit.Text:=SelDefNode.Description;
|
|
VariableEdit.Text:=SelDefNode.Variable;
|
|
ValueAsTextSynEdit.Text:=SelDefNode.Value;
|
|
ValueAsFilePathsSynEdit.Text:=ValueToFilePathText(SelDefNode.Value);
|
|
if SelDefNode.IsAutoGenerated then begin
|
|
ValueAsTextSynEdit.Options:=ValueAsTextSynEdit.Options+[eoNoCaret];
|
|
ValueAsTextSynEdit.ReadOnly:=true;
|
|
end else begin
|
|
ValueAsTextSynEdit.Options:=ValueAsTextSynEdit.Options-[eoNoCaret];
|
|
ValueAsTextSynEdit.ReadOnly:=false;
|
|
end;
|
|
ValueAsFilePathsSynEdit.Options:=ValueAsTextSynEdit.Options;
|
|
ValueAsFilePathsSynEdit.ReadOnly:=ValueAsTextSynEdit.ReadOnly;
|
|
end else begin
|
|
SelectedItemGroupBox.Enabled:=false;
|
|
TypeLabel.Caption:='none selected';
|
|
ProjectSpecificCheckBox.Enabled:=false;
|
|
NameEdit.Text:='';
|
|
DescriptionEdit.Text:='';
|
|
VariableEdit.Text:='';
|
|
ValueAsTextSynEdit.Text:='';
|
|
ValueAsFilePathsSynEdit.Text:='';
|
|
end;
|
|
FLastSelectedNode:=SelTreeNode;
|
|
end;
|
|
|
|
function TCodeToolsDefinesEditor.ValueToFilePathText(const AValue: string
|
|
): string;
|
|
var i: integer;
|
|
begin
|
|
Result:=AValue;
|
|
for i:=1 to length(Result) do
|
|
if Result[i]=';' then Result[i]:=#13;
|
|
end;
|
|
|
|
procedure TCodeToolsDefinesEditor.InsertNewNode(Behind: boolean;
|
|
Action: TDefineAction);
|
|
var SelTreeNode, NodeInFront, ParentNode, ANode, FirstNode,
|
|
NewTreeNode: TTreeNode;
|
|
NewDefNode: TDefineTemplate;
|
|
NewName, NewDescription, NewVariable, NewValue: string;
|
|
i: integer;
|
|
begin
|
|
SelTreeNode:=DefineTreeView.Selected;
|
|
NodeInFront:=nil;
|
|
ParentNode:=nil;
|
|
if SelTreeNode<>nil then begin
|
|
// there is an selected node
|
|
if Behind then
|
|
// insert behind selected node
|
|
NodeInFront:=SelTreeNode
|
|
else begin
|
|
// insert as last child of selected node
|
|
ParentNode:=SelTreeNode;
|
|
NodeInFront:=ParentNode.GetFirstChild;
|
|
if NodeInFront<>nil then begin
|
|
while NodeInFront.GetNextSibling<>nil do
|
|
NodeInFront:=NodeInFront.GetNextSibling;
|
|
end;
|
|
end;
|
|
end else begin
|
|
// no node selected, add as last root node
|
|
NodeInFront:=DefineTreeView.Items.GetLastNode;
|
|
if NodeInFront<>nil then begin
|
|
while NodeInFront.GetNextSibling<>nil do
|
|
NodeInFront:=NodeInFront.GetNextSibling;
|
|
end;
|
|
end;
|
|
// find a unique name
|
|
if ParentNode<>nil then
|
|
FirstNode:=ParentNode.GetFirstChild
|
|
else
|
|
FirstNode:=nil;
|
|
if FirstNode=nil then FirstNode:=NodeInFront;
|
|
if FirstNode<>nil then begin
|
|
while FirstNode.GetPrevSibling<>nil do
|
|
FirstNode:=FirstNode.GetPrevSibling;
|
|
end;
|
|
i:=0;
|
|
repeat
|
|
inc(i);
|
|
ANode:=FirstNode;
|
|
while ANode<>nil do begin
|
|
if TDefineTemplate(ANode.Data).Name='NewNode'+IntToStr(i) then break;
|
|
ANode:=ANode.GetNextSibling;
|
|
end;
|
|
until ANode=nil;
|
|
NewName:='NewNode'+IntToStr(i);
|
|
NewDescription:=NewName;
|
|
NewVariable:='';
|
|
NewValue:='';
|
|
NewDefNode:=TDefineTemplate.Create(NewName,NewDescription,NewVariable,
|
|
NewValue,Action);
|
|
// add node to treeview
|
|
if ParentNode<>nil then
|
|
// add as last child
|
|
NewTreeNode:=DefineTreeView.Items.AddChildObject(ParentNode,NewName,
|
|
NewDefNode)
|
|
else if (NodeInFront<>nil) and (NodeInFront.GetNextSibling<>nil) then
|
|
// insert in front
|
|
NewTreeNode:=DefineTreeView.Items.InsertObjectBehind(
|
|
NodeInFront,NewName,NewDefNode);
|
|
SetNodeImages(NewTreeNode);
|
|
|
|
// add node to define tree
|
|
if NodeInFront<>nil then
|
|
NewDefNode.InsertAfter(TDefineTemplate(NodeInFront.Data))
|
|
else if ParentNode<>nil then
|
|
TDefineTemplate(ParentNode.Data).AddChild(NewDefNode)
|
|
else
|
|
FDefineTree.Add(NewDefNode);
|
|
end;
|
|
|
|
procedure TCodeToolsDefinesEditor.Assign(ACodeToolBoss: TCodeToolManager;
|
|
Options: TCodeToolsOptions);
|
|
begin
|
|
FLastSelectedNode:=nil;
|
|
FDefineTree.Assign(ACodeToolBoss.DefineTree);
|
|
RebuildDefineTreeView;
|
|
ShowSelectedValues;
|
|
end;
|
|
|
|
constructor TCodeToolsDefinesEditor.Create(TheOwner: TComponent);
|
|
begin
|
|
inherited Create(TheOwner);
|
|
if LazarusResources.Find(ClassName)=nil then begin
|
|
SetBounds((Screen.Width-480) div 2,(Screen.Height-430) div 2, 485, 435);
|
|
Caption:='CodeTools Defines Editor';
|
|
OnResize:=@FormResize;
|
|
|
|
CreateComponents;
|
|
end;
|
|
FDefineTree:=TDefineTree.Create;
|
|
Resize;
|
|
end;
|
|
|
|
destructor TCodeToolsDefinesEditor.Destroy;
|
|
begin
|
|
FDefineTree.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
//==============================================================================
|
|
|
|
initialization
|
|
{$I codetoolsdefines.lrs}
|
|
|
|
|
|
end.
|
|
|