EditorMacros: Allow editing of macros

git-svn-id: trunk@38360 -
This commit is contained in:
martin 2012-08-25 01:02:55 +00:00
parent e191d86627
commit 48333d8333
6 changed files with 225 additions and 54 deletions

View File

@ -1,12 +1,12 @@
object MacroListView: TMacroListView
Left = 390
Height = 330
Height = 365
Top = 249
Width = 340
Caption = 'MacroListView'
ClientHeight = 330
ClientHeight = 365
ClientWidth = 340
Constraints.MinHeight = 330
Constraints.MinHeight = 365
Constraints.MinWidth = 300
OnActivate = FormActivate
OnDeactivate = FormActivate
@ -14,7 +14,7 @@ object MacroListView: TMacroListView
object Panel1: TPanel
AnchorSideRight.Control = pnlButtons
Left = 6
Height = 278
Height = 313
Top = 6
Width = 211
Align = alLeft
@ -23,12 +23,12 @@ object MacroListView: TMacroListView
BorderSpacing.Top = 6
BorderSpacing.Right = 6
BevelOuter = bvNone
ClientHeight = 278
ClientHeight = 313
ClientWidth = 211
TabOrder = 0
object lbRecordedView: TListView
Left = 0
Height = 229
Height = 264
Top = 24
Width = 211
Align = alClient
@ -89,7 +89,7 @@ object MacroListView: TMacroListView
object ToolBar2: TToolBar
Left = 0
Height = 22
Top = 256
Top = 291
Width = 211
Align = alBottom
AutoSize = True
@ -125,7 +125,7 @@ object MacroListView: TMacroListView
object ButtonPanel1: TButtonPanel
Left = 6
Height = 34
Top = 290
Top = 325
Width = 328
OKButton.Name = 'OKButton'
OKButton.DefaultCaption = True
@ -141,13 +141,13 @@ object MacroListView: TMacroListView
end
object pnlButtons: TPanel
Left = 223
Height = 284
Height = 319
Top = 0
Width = 117
Align = alRight
AutoSize = True
BevelOuter = bvNone
ClientHeight = 284
ClientHeight = 319
ClientWidth = 117
Constraints.MinHeight = 250
TabOrder = 2
@ -172,14 +172,14 @@ object MacroListView: TMacroListView
end
object btnRename: TButton
AnchorSideLeft.Control = pnlButtons
AnchorSideTop.Control = btnSetKeys
AnchorSideTop.Control = btnSelect
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = pnlButtons
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Side = asrBottom
Left = 6
Height = 25
Top = 68
Top = 37
Width = 105
Anchors = [akTop, akLeft, akRight]
AutoSize = True
@ -198,7 +198,7 @@ object MacroListView: TMacroListView
AnchorSideBottom.Control = chkRepeat
Left = 6
Height = 25
Top = 145
Top = 180
Width = 105
Anchors = [akLeft, akRight, akBottom]
AutoSize = True
@ -218,7 +218,7 @@ object MacroListView: TMacroListView
AnchorSideBottom.Control = btnRecordStop
Left = 6
Height = 25
Top = 228
Top = 263
Width = 105
Anchors = [akLeft, akRight, akBottom]
AutoSize = True
@ -239,7 +239,7 @@ object MacroListView: TMacroListView
AnchorSideBottom.Side = asrBottom
Left = 6
Height = 25
Top = 259
Top = 294
Width = 105
Anchors = [akLeft, akRight, akBottom]
AutoSize = True
@ -258,7 +258,7 @@ object MacroListView: TMacroListView
AnchorSideBottom.Control = edRepeat
Left = 6
Height = 19
Top = 173
Top = 208
Width = 105
Anchors = [akLeft, akRight, akBottom]
BorderSpacing.Left = 6
@ -277,7 +277,7 @@ object MacroListView: TMacroListView
AnchorSideBottom.Control = btnRecord
Left = 6
Height = 23
Top = 195
Top = 230
Width = 105
Anchors = [akLeft, akRight, akBottom]
AutoSize = False
@ -291,6 +291,26 @@ object MacroListView: TMacroListView
Value = 1
end
object btnDelete: TButton
AnchorSideLeft.Control = pnlButtons
AnchorSideTop.Control = btnEdit
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = pnlButtons
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Side = asrBottom
Left = 6
Height = 25
Top = 130
Width = 105
Anchors = [akTop, akLeft, akRight]
AutoSize = True
BorderSpacing.Left = 6
BorderSpacing.Top = 6
BorderSpacing.Right = 6
Caption = 'btnDelete'
OnClick = btnDeleteClick
TabOrder = 7
end
object btnSetKeys: TButton
AnchorSideLeft.Control = pnlButtons
AnchorSideTop.Control = btnRename
AnchorSideTop.Side = asrBottom
@ -299,6 +319,26 @@ object MacroListView: TMacroListView
AnchorSideBottom.Side = asrBottom
Left = 6
Height = 25
Top = 68
Width = 105
Anchors = [akTop, akLeft, akRight]
AutoSize = True
BorderSpacing.Left = 6
BorderSpacing.Top = 6
BorderSpacing.Right = 6
Caption = 'btnSetKeys'
OnClick = btnSetKeysClick
TabOrder = 8
end
object btnEdit: TButton
AnchorSideLeft.Control = pnlButtons
AnchorSideTop.Control = btnSetKeys
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = pnlButtons
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Side = asrBottom
Left = 6
Height = 25
Top = 99
Width = 105
Anchors = [akTop, akLeft, akRight]
@ -306,29 +346,9 @@ object MacroListView: TMacroListView
BorderSpacing.Left = 6
BorderSpacing.Top = 6
BorderSpacing.Right = 6
Caption = 'btnDelete'
OnClick = btnDeleteClick
TabOrder = 7
end
object btnSetKeys: TButton
AnchorSideLeft.Control = pnlButtons
AnchorSideTop.Control = btnSelect
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = pnlButtons
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Side = asrBottom
Left = 6
Height = 25
Top = 37
Width = 105
Anchors = [akTop, akLeft, akRight]
AutoSize = True
BorderSpacing.Left = 6
BorderSpacing.Top = 6
BorderSpacing.Right = 6
Caption = 'btnSetKeys'
OnClick = btnSetKeysClick
TabOrder = 8
Caption = 'btnEdit'
OnClick = btnEditClick
TabOrder = 9
end
end
object PopupMenu1: TPopupMenu

View File

@ -9,7 +9,7 @@ uses
FileProcs, Forms, Controls, Graphics, Dialogs, StdCtrls, ButtonPanel, ComCtrls, ExtCtrls,
Spin, Menus, LCLType, MainBar, IDEWindowIntf, IDEImagesIntf, LazarusIDEStrConsts,
ProjectDefs, LazConf, Project, KeyMapping, KeyMapShortCutDlg, SrcEditorIntf, IDEHelpIntf,
IDECommands;
IDECommands, LazIDEIntf;
type
@ -36,8 +36,6 @@ type
property HasError: Boolean read FHasError;
end;
{ TSynMacroEventWriter }
{ TIdeMacroEventWriter }
TIdeMacroEventWriter = class(TSynMacroEventWriter)
@ -105,6 +103,8 @@ type
procedure ClearAndFreeMacros;
function Count: Integer;
function IndexOf(AMacro: TEditorMacro): Integer;
function IndexOfName(AName: String): Integer;
function UniqName(AName: String): String;
function Add(AMacro: TEditorMacro): Integer;
procedure Delete(AnIndex: Integer);
procedure Remove(AMacro: TEditorMacro);
@ -117,6 +117,7 @@ type
{ TMacroListView }
TMacroListView = class(TForm)
btnEdit: TButton;
btnSetKeys: TButton;
btnPlay: TButton;
btnRecord: TButton;
@ -145,6 +146,7 @@ type
tbMoveProject: TToolButton;
tbMoveIDE: TToolButton;
procedure btnDeleteClick(Sender: TObject);
procedure btnEditClick(Sender: TObject);
procedure btnPlayClick(Sender: TObject);
procedure btnRecordClick(Sender: TObject);
procedure btnRecordStopClick(Sender: TObject);
@ -168,15 +170,17 @@ type
FImageErr: Integer;
FIsPlaying: Boolean;
procedure DoOnMacroListChange(Sender: TObject);
procedure UpdateDisplay;
procedure UpdateButtons;
protected
procedure DoEditorMacroStateChanged;
public
constructor Create(TheOwner: TComponent); override;
destructor Destroy; override;
function MacroByFullName(AName: String): TEditorMacro;
procedure UpdateDisplay;
end;
function MacroListViewer: TMacroListView;
procedure ShowMacroListViewer;
procedure UpdateMacroListViewer;
procedure DoEditorMacroStateChanged;
@ -204,11 +208,16 @@ var
const
GlobalConfFileName = 'EditorMacros.xml';
procedure ShowMacroListViewer;
function MacroListViewer: TMacroListView;
begin
if MacroListView = nil then
MacroListView := TMacroListView.Create(Application);
IDEWindowCreators.ShowForm(MacroListView, True);
Result := MacroListView;
end;
procedure ShowMacroListViewer;
begin
IDEWindowCreators.ShowForm(MacroListViewer, True);
end;
procedure UpdateMacroListViewer;
@ -217,6 +226,22 @@ begin
MacroListView.UpdateDisplay;
end;
function MacroListToName(AList: TEditorMacroList): string;
begin
Result := '';
if AList = EditorMacroListRec then Result := 'Rec'
else if AList = EditorMacroListProj then Result := 'Prj'
else if AList = EditorMacroListGlob then Result := 'Ide';
end;
function NameToMacroList(AName: string): TEditorMacroList;
begin
Result := nil;
if AName = 'Rec' then Result := EditorMacroListRec
else if AName = 'Prj' then Result := EditorMacroListProj
else if AName = 'Ide' then Result := EditorMacroListGlob;
end;
procedure DoEditorMacroStateChanged;
begin
if EditorMacroRecorder= nil then exit;
@ -383,6 +408,7 @@ var
begin
Stop;
Clear;
FHasError := False;
fEvents := TList.Create;
R := TIdeMacroEventReader.Create(AText);
@ -726,9 +752,21 @@ begin
if lbRecordedView.ItemIndex < 0 then exit;
M := CurrentEditorMacroList.Macros[lbRecordedView.ItemIndex];
s := M.MacroName;
if InputQuery('New Macroname', Format('Enter new mawe for Macro "%s"', [m.MacroName]), s)
if InputQuery(lisNewMacroname2, Format(lisEnterNewMaweForMacroS, [m.MacroName]), s)
then begin
M.MacroName := s;
while (s <> '') and (CurrentEditorMacroList.IndexOfName(s) >= 0) do begin
case MessageDlg(lisDuplicateName, lisAMacroWithThisNameAlreadyExists, mtWarning,
mbOKCancel, 0) of
mrOK:
if not InputQuery(lisNewMacroname2, Format(lisEnterNewMaweForMacroS, [m.MacroName]), s)
then s := '';
else
s := '';
end;
end;
if s <> '' then
M.MacroName := s;
UpdateDisplay;
end;
end;
@ -780,6 +818,18 @@ begin
end;
end;
procedure TMacroListView.btnEditClick(Sender: TObject);
var
M: TEditorMacro;
begin
if lbRecordedView.ItemIndex < 0 then exit;
M := CurrentEditorMacroList.Macros[lbRecordedView.ItemIndex];
if M = nil then exit;
LazarusIDE.DoOpenEditorFile(
'//EMacro:/'+MacroListToName(CurrentEditorMacroList)+'/'+M.MacroName,
-1, -1, [ofVirtualFile, ofEditorMacro]);
end;
procedure TMacroListView.btnRecordClick(Sender: TObject);
begin
if EditorMacroRecorder.State = msStopped then begin
@ -980,10 +1030,11 @@ begin
IsErr := IsSel and M.HasError;
btnSelect.Enabled := IsStopped and IsSel and (not FIsPlaying) and (not IsErr);
btnSelect.Enabled := IsStopped and IsSel and (not FIsPlaying) and (not IsErr);
btnRename.Enabled := IsStopped and IsSel and (not FIsPlaying) and (not IsErr);
btnEdit.Enabled := IsStopped and IsSel and (not FIsPlaying);
btnSetKeys.Enabled := IsStopped and IsSel and (not FIsPlaying) and (not IsErr);
btnRename.Enabled := IsStopped and IsSel and (not FIsPlaying) and (not IsErr);
btnDelete.Enabled := IsStopped and IsSel and (not FIsPlaying);
btnDelete.Enabled := IsStopped and IsSel and (not FIsPlaying);
btnPlay.Enabled := IsStopped and IsSel and (not FIsPlaying) and (not IsErr);
chkRepeat.Enabled := IsStopped and (not FIsPlaying);
@ -1008,6 +1059,22 @@ begin
tbMoveIDE.Enabled := IsStopped and IsSel and (not FIsPlaying);
end;
function TMacroListView.MacroByFullName(AName: String): TEditorMacro;
var
Alist: TEditorMacroList;
i: Integer;
begin
Result := nil;
If (copy(AName, 1, 10) <> '//EMacro:/') or
(copy(AName, 14, 1) <> '/')
then exit;
Alist := NameToMacroList(copy(AName, 11, 3));
if (Alist = nil) then exit;
i := Alist.IndexOfName(copy(AName, 15, length(AName)));
if i < 0 then exit;
Result := Alist.Macros[i]
end;
procedure TMacroListView.DoEditorMacroStateChanged;
begin
UpdateDisplay;
@ -1032,8 +1099,9 @@ begin
lbMoveTo.Caption := lisMoveTo;
btnSelect.Caption := lisMenuSelect;
btnSetKeys.Caption := lisEditKey;
btnRename.Caption := lisRename2;
btnSetKeys.Caption := lisEditKey;
btnEdit.Caption := lisEdit;
btnDelete.Caption := lisDelete;
btnPlay.Caption := lisPlay;
chkRepeat.Caption := lisRepeat;
@ -1142,8 +1210,29 @@ begin
Result := FList.IndexOf(AMacro);
end;
function TEditorMacroList.IndexOfName(AName: String): Integer;
begin
Result := Count - 1;
while Result >= 0 do
if Macros[Result].MacroName = AName
then break
else dec(Result);
end;
function TEditorMacroList.UniqName(AName: String): String;
var
i: Integer;
begin
Result := AName;
if IndexOfName(AName) < 0 then exit;
i := 1;
while IndexOfName(AName+'_'+IntToStr(i)) >= 0 do inc(i);
Result := AName+'_'+IntToStr(i);
end;
function TEditorMacroList.Add(AMacro: TEditorMacro): Integer;
begin
AMacro.MacroName := UniqName(AMacro.MacroName);
Result := FList.Add(AMacro);
DoAdded(AMacro);
DoChanged;

View File

@ -5565,6 +5565,10 @@ resourcestring
lisMoveTo = 'Move to: ';
lisFailedToSaveFile = 'Failed to save file.';
lisEditKey = 'Edit Key';
lisDuplicateName = 'Duplicate Name';
lisAMacroWithThisNameAlreadyExists = 'A macro with this name already exists.';
lisNewMacroname2 = 'New Macroname';
lisEnterNewMaweForMacroS = 'Enter new mawe for Macro "%s"';
implementation

View File

@ -9286,6 +9286,7 @@ begin
// do not save a unit which is currently reverting
if AnUnitInfo.IsReverting then
exit(mrOk);
WasVirtual:=AnUnitInfo.IsVirtual;
WasPascalSource:=FilenameIsPascalSource(AnUnitInfo.Filename);
@ -9305,6 +9306,17 @@ begin
if not (sfProjectSaving in Flags) then
SaveSourceEditorChangesToCodeCache(nil);
if uifEditorMacro in AnUnitInfo.Flags then begin
// save to macros
if MacroListViewer.MacroByFullName(AnUnitInfo.Filename) <> nil then
MacroListViewer.MacroByFullName(AnUnitInfo.Filename).SetFromText(AEditor.SourceText);
MacroListViewer.UpdateDisplay;
AnUnitInfo.ClearModifieds;
AEditor.Modified:=false;
Result := mrOK;
exit;
end;
// if this is a new unit then a simple Save becomes a SaveAs
if (not (sfSaveToTestDir in Flags)) and (AnUnitInfo.IsVirtual) then
Include(Flags,sfSaveAs);
@ -9701,6 +9713,50 @@ begin
if (ofRevert in Flags) and (PageIndex>=0) then
AFilename := SourceEditorManager.SourceEditorsByPage[WindowIndex, PageIndex].FileName;
if (ofRevert in Flags) then begin
UnitIndex:=Project1.IndexOfFilename(AFilename);
if (UnitIndex > 0) then begin
NewUnitInfo:=Project1.Units[UnitIndex];
if (uifEditorMacro in NewUnitInfo.Flags) then begin
if MacroListViewer.MacroByFullName(AFileName) <> nil then
NewUnitInfo.Source.Source := MacroListViewer.MacroByFullName(AFileName).GetAsText;
Result:=mrOK;
exit;
end;
end;
end;
if (ofEditorMacro in Flags) then begin
FilenameNoPath := AFileName;
UnitIndex:=Project1.IndexOfFilename(AFilename);
if (UnitIndex < 0) then begin
NewBuf := CodeToolBoss.SourceCache.CreateFile(AFileName);
NewBuf.FileName:=AFileName;
if MacroListViewer.MacroByFullName(AFileName) <> nil then
NewBuf.Source := MacroListViewer.MacroByFullName(AFileName).GetAsText;
NewUnitInfo:=TUnitInfo.Create(NewBuf);
NewUnitInfo.DefaultSyntaxHighlighter := lshFreePascal;
Project1.AddFile(NewUnitInfo,false);
end
else begin
NewUnitInfo:=Project1.Units[UnitIndex];
end;
NewUnitInfo.Flags := NewUnitInfo.Flags + [uifEditorMacro];
if NewUnitInfo.OpenEditorInfoCount > 0 then begin
NewEditorInfo := NewUnitInfo.OpenEditorInfo[0];
SourceEditorManager.ActiveSourceWindowIndex := NewEditorInfo.WindowIndex;
SourceEditorManager.ActiveSourceWindow.PageIndex:= NewEditorInfo.PageIndex;
end
else begin
NewEditorInfo := NewUnitInfo.GetClosedOrNewEditorInfo;
Result:=DoOpenFileInSourceEditor(NewEditorInfo, PageIndex, WindowIndex, Flags);
end;
Result:=mrOK;
exit;
end;
// normalize filename
AFilename:=TrimFilename(AFilename);
DiskFilename:=CodeToolBoss.DirectoryCachePool.FindDiskFilename(AFilename);

View File

@ -159,7 +159,8 @@ type
TUnitInfoFlag = (
uifComponentUsedByDesigner,
uifComponentIndirectlyUsedByDesigner,
uifMarked
uifMarked,
uifEditorMacro
);
TUnitInfoFlags = set of TUnitInfoFlag;

View File

@ -41,7 +41,8 @@ type
ofDoNotLoadResource,// do not open form, datamodule, ... (overriding default)
ofDoLoadResource,// do open form, datamodule, ... (overriding default)
ofLoadHiddenResource,// load component hidden
ofAddToProject // add file to project (if exists)
ofAddToProject, // add file to project (if exists)
ofEditorMacro // opening an editor macro (pascal script) from memory
);
TOpenFlags = set of TOpenFlag;