This commit is contained in:
Basile Burg 2014-06-24 16:48:16 +02:00
parent ba9c1df5fa
commit 9b96382a64
15 changed files with 239 additions and 72 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 108 KiB

View File

@ -1,4 +1,4 @@
module barclass;
module bar;
import std.stdio;

View File

@ -1,4 +1,4 @@
module fooclass;
module foo;
import std.stdio;

View File

@ -10,18 +10,18 @@ Test:
module main;
import std.stdio;
import fooclass;
import barclass;
import foo;
import bar;
void main(string args[])
{
auto foo = new Foo;
auto bar = new Bar;
auto ffoo = new Foo;
auto bbar = new Bar;
scope(exit)
{
delete foo;
delete bar;
delete ffoo;
delete bbar;
}
readln;
}

View File

@ -29,7 +29,7 @@ uses
(**
* Patches the directory separators from a string.
* This is used to ensure that a project saved on a plateform can be loaded
* This is used to ensure that a project saved on a platform can be loaded
* on another one.
*)
function patchPlateformPath(const aPath: string): string;
@ -40,6 +40,11 @@ uses
*)
function dlgOkCancel(const aMsg: string): TModalResult;
(**
* Returns an unique object identifier, based on its heap address.
*)
function uniqueObjStr(const aObject: Tobject): string;
implementation
@ -237,4 +242,11 @@ begin
exit( MessageDlg('Coedit', aMsg, mtConfirmation, Btns, ''));
end;
function uniqueObjStr(const aObject: Tobject): string;
begin
{$HINTS OFF}{$WARNINGS OFF}
exit( format('%.8X',[NativeUint(@aObject)]));
{$HINTS ON}{$WARNINGS ON}
end;
end.

View File

@ -238,9 +238,9 @@ begin
DockMaster.HeaderStyle := adhsPoints;
DockMaster.ManualDock(DockMaster.GetAnchorSite(fEditWidg), Self, alBottom);
DockMaster.ManualDock(DockMaster.GetAnchorSite(fMesgWidg), Self, alBottom);
DockMaster.ManualDock(DockMaster.GetAnchorSite(fStExpWidg), Self, alLeft);
width := width - fProjWidg.Width;
DockMaster.ManualDock(DockMaster.GetAnchorSite(fProjWidg), Self, alRight);
DockMaster.GetAnchorSite(fEditWidg).Header.HeaderPosition := adlhpTop;
end;
@ -691,7 +691,7 @@ begin
temppath := GetTempDir(false);
chDir(temppath);
{$IFDEF DEBUG}{$WARNINGS OFF}{$HINTS OFF}{$ENDIF}
fname := temppath + format('temp_%.8x', [NativeUInt(@dmdproc)]);
fname := temppath + 'temp_' + uniqueObjStr(dmdProc);
{$IFDEF DEBUG}{$WARNINGS ON}{$HINTS ON}{$ENDIF}
fEditWidg.editor[edIndex].Lines.SaveToFile(fname + '.d');

View File

@ -16,6 +16,7 @@ inherited CEMessagesWidget: TCEMessagesWidget
Width = 744
ClientHeight = 172
ClientWidth = 744
PopupMenu = nil
object List: TListView[0]
Left = 2
Height = 168

View File

@ -52,12 +52,7 @@ uses
ce_main;
constructor TCEMessagesWidget.create(aOwner: TComponent);
var
itm: TMenuItem;
begin
inherited;
fID := 'ID_MSGS';
//
fActClear := TAction.Create(self);
fActClear.OnExecute := @actClearExecute;
fActClear.caption := 'Clear messages';
@ -71,19 +66,10 @@ begin
fActSaveMsg.OnExecute := @actSaveMsgExecute;
fActSaveMsg.caption := 'Save messages to...';
//
inherited;
fID := 'ID_MSGS';
//
List.PopupMenu := contextMenu;
itm := TMenuItem.Create(self);
itm.Action := fActClear;
contextMenu.Items.Add(itm);
itm := TMenuItem.Create(self);
itm.Action := fActCopyMsg;
contextMenu.Items.Add(itm);
itm := TMenuItem.Create(self);
itm.Action := fActSelAll;
contextMenu.Items.Add(itm);
itm := TMenuItem.Create(self);
itm.Action := fActSaveMsg;
contextMenu.Items.Add(itm);
end;
procedure TCEMessagesWidget.scrollToBack;

View File

@ -18,6 +18,7 @@ inherited CEProjectInspectWidget: TCEProjectInspectWidget
Width = 264
ClientHeight = 383
ClientWidth = 264
PopupMenu = nil
object Tree: TTreeView[0]
Left = 2
Height = 353
@ -29,11 +30,13 @@ inherited CEProjectInspectWidget: TCEProjectInspectWidget
DefaultItemHeight = 18
Images = imgList
ReadOnly = True
RightClickSelect = True
ScrollBars = ssAutoBoth
ShowRoot = False
TabOrder = 0
OnKeyDown = TreeKeyDown
Options = [tvoAutoExpand, tvoAutoItemHeight, tvoHideSelection, tvoKeepCollapsedNodes, tvoReadOnly, tvoShowButtons, tvoShowLines, tvoToolTips, tvoThemedDraw]
OnSelectionChanged = TreeSelectionChanged
Options = [tvoAutoExpand, tvoAutoItemHeight, tvoHideSelection, tvoKeepCollapsedNodes, tvoReadOnly, tvoRightClickSelect, tvoShowButtons, tvoShowLines, tvoToolTips, tvoThemedDraw]
Items.Data = {
F9FFFFFF020002000000000000000000000000000000FFFFFFFF000000000000
0000000C000000536F757263652066696C6573010000000100000001000000FF

View File

@ -6,7 +6,7 @@ interface
uses
Classes, SysUtils, FileUtil, TreeFilterEdit, Forms, Controls, Graphics,
Dialogs, ExtCtrls, ComCtrls, Menus, Buttons, ce_project, ce_widget;
actnlist, Dialogs, ExtCtrls, ComCtrls, Menus, Buttons, ce_project, ce_widget;
type
{ TCEProjectInspectWidget }
@ -24,18 +24,27 @@ type
procedure btnRemFileClick(Sender: TObject);
procedure FormDropFiles(Sender: TObject; const FileNames: array of String);
procedure TreeKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure TreeSelectionChanged(Sender: TObject);
protected
procedure UpdateByEvent; override;
private
fActOpenFile: TAction;
fActSelConf: TAction;
fProject: TCEProject;
fFileNode, fConfNode: TTreeNode;
procedure actUpdate(sender: TObject);
procedure TreeDblClick(sender: TObject);
procedure actOpenFileExecute(sender: TObject);
public
constructor create(aOwner: TComponent); override;
//
procedure projNew(const aProject: TCEProject); override;
procedure projChange(const aProject: TCEProject); override;
procedure projClose(const aProject: TCEProject); override;
//
function contextName: string; override;
function contextActionCount: integer; override;
function contextAction(index: integer): TAction; override;
end;
implementation
@ -46,11 +55,40 @@ uses
constructor TCEProjectInspectWidget.create(aOwner: TComponent);
begin
fActOpenFile := TAction.Create(self);
fActOpenFile.Caption := 'Open file in editor';
fActOpenFile.OnExecute := @actOpenFileExecute;
fActSelConf := TAction.Create(self);
fActSelConf.Caption := 'Select configuration';
fActSelConf.OnExecute := @actOpenFileExecute;
fActSelConf.OnUpdate := @actUpdate;
//
inherited;
fID := 'ID_PROJ';
Tree.OnDblClick := @TreeDblClick;
fFileNode := Tree.Items[0];
fConfNode := Tree.Items[1];
//
Tree.PopupMenu := contextMenu;
end;
function TCEProjectInspectWidget.contextName: string;
begin
exit('Inspector');
end;
function TCEProjectInspectWidget.contextActionCount: integer;
begin
exit(2);
end;
function TCEProjectInspectWidget.contextAction(index: integer): TAction;
begin
case index of
0: exit(fActOpenFile);
1: exit(fActSelConf);
else exit(nil);
end;
end;
procedure TCEProjectInspectWidget.projNew(const aProject: TCEProject);
@ -76,6 +114,11 @@ begin
if Key = 13 then TreeDblClick(nil);
end;
procedure TCEProjectInspectWidget.TreeSelectionChanged(Sender: TObject);
begin
actUpdate(sender);
end;
procedure TCEProjectInspectWidget.TreeDblClick(sender: TObject);
var
fname: string;
@ -103,6 +146,20 @@ begin
end;
end;
procedure TCEProjectInspectWidget.actOpenFileExecute(sender: TObject);
begin
TreeDblClick(sender);
end;
procedure TCEProjectInspectWidget.actUpdate(sender: TObject);
begin
fActSelConf.Enabled := false;
fActOpenFile.Enabled := false;
if Tree.Selected = nil then exit;
fActSelConf.Enabled := Tree.Selected.Parent = fConfNode;
fActOpenFile.Enabled := Tree.Selected.Parent = fFileNode;
end;
procedure TCEProjectInspectWidget.btnAddFileClick(Sender: TObject);
begin
if fProject = nil then exit;

View File

@ -16,6 +16,7 @@ inherited CEStaticExplorerWidget: TCEStaticExplorerWidget
Width = 261
ClientHeight = 276
ClientWidth = 261
PopupMenu = nil
object Tree: TTreeView[0]
Left = 4
Height = 240
@ -28,11 +29,12 @@ inherited CEStaticExplorerWidget: TCEStaticExplorerWidget
HideSelection = False
Images = imgList
ReadOnly = True
RowSelect = True
ScrollBars = ssAutoBoth
SelectionColor = clActiveBorder
TabOrder = 0
OnDeletion = TreeDeletion
Options = [tvoAutoItemHeight, tvoKeepCollapsedNodes, tvoReadOnly, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips, tvoThemedDraw]
Options = [tvoAutoItemHeight, tvoKeepCollapsedNodes, tvoReadOnly, tvoRowSelect, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips, tvoThemedDraw]
Items.Data = {
F9FFFFFF020009000000000000000000000000000000FFFFFFFF000000000000
00000005000000416C6961730100000001000000FFFFFFFFFFFFFFFF00000000
@ -59,6 +61,7 @@ inherited CEStaticExplorerWidget: TCEStaticExplorerWidget
BevelOuter = bvNone
ClientHeight = 26
ClientWidth = 257
PopupMenu = contextMenu
TabOrder = 1
object TreeFilterEdit1: TTreeFilterEdit
Left = 2

View File

@ -7,7 +7,7 @@ interface
uses
Classes, SysUtils, FileUtil, TreeFilterEdit, Forms, Controls, Graphics,
Dialogs, ExtCtrls, Menus, ComCtrls, ce_widget, jsonparser, fpjson,
ce_synmemo, process;
ce_synmemo, process, actnlist, ce_common, ce_project;
type
@ -19,13 +19,22 @@ type
TreeFilterEdit1: TTreeFilterEdit;
procedure TreeDeletion(Sender: TObject; Node: TTreeNode);
private
fActRefresh: TAction;
fActAutoRefresh: TAction;
fActSelectInSource: TAction;
fDoc: TCESynMemo;
fProj: TCEProject;
fAutoRefresh: boolean;
ndAlias, ndClass, ndEnum, ndFunc: TTreeNode;
ndImp, ndMix, ndStruct, ndTmp, ndVar: TTreeNode;
procedure Rescan;
procedure TreeDblClick(Sender: TObject);
procedure actRefreshExecute(Sender: TObject);
procedure actAutoRefreshExecute(Sender: TObject);
protected
procedure UpdateByDelay; override;
published
property autoRefresh: boolean read fAutoRefresh write fAutoRefresh;
public
constructor create(aOwner: TComponent); override;
//
@ -33,6 +42,14 @@ type
procedure docFocused(const aDoc: TCESynMemo); override;
procedure docChanged(const aDoc: TCESynMemo); override;
procedure docClose(const aDoc: TCESynMemo); override;
//
function contextName: string; override;
function contextActionCount: integer; override;
function contextAction(index: integer): TAction; override;
//
procedure projNew(const aProject: TCEProject); override;
procedure projChange(const aProject: TCEProject); override;
procedure projClose(const aProject: TCEProject); override;
end;
implementation
@ -40,6 +57,19 @@ implementation
constructor TCEStaticExplorerWidget.create(aOwner: TComponent);
begin
fAutoRefresh := true;
fActRefresh := TAction.Create(self);
fActRefresh.OnExecute := @actRefreshExecute;
fActRefresh.Caption := 'Refresh';
fActAutoRefresh := TAction.Create(self);
fActAutoRefresh.OnExecute := @actAutoRefreshExecute;
fActAutoRefresh.Caption := 'Auto-refresh';
fActAutoRefresh.AutoCheck := true;
fActAutoRefresh.Checked := fAutoRefresh;
fActSelectInSource := TAction.Create(self);
fActSelectInSource.OnExecute := @TreeDblClick;
fActSelectInSource.Caption := 'Select in source';
//
inherited;
fID := 'ID_SEXPL';
//
@ -54,6 +84,53 @@ begin
ndVar := Tree.Items[8];
//
Tree.OnDblClick := @TreeDblClick;
Tree.PopupMenu := contextMenu;
end;
function TCEStaticExplorerWidget.contextName: string;
begin
result := 'Static explorer';
end;
function TCEStaticExplorerWidget.contextActionCount: integer;
begin
result := 3;
end;
function TCEStaticExplorerWidget.contextAction(index: integer): TAction;
begin
case index of
0: result := fActSelectInSource;
1: result := fActRefresh;
2: result := fActAutoRefresh;
else result := nil;
end;
end;
procedure TCEStaticExplorerWidget.actRefreshExecute(Sender: TObject);
begin
if Updating then exit;
Rescan;
end;
procedure TCEStaticExplorerWidget.actAutoRefreshExecute(Sender: TObject);
begin
AutoRefresh := not AutoRefresh;
end;
procedure TCEStaticExplorerWidget.projNew(const aProject: TCEProject);
begin
fProj := aProject;
end;
procedure TCEStaticExplorerWidget.projChange(const aProject: TCEProject);
begin
fProj := aProject;
end;
procedure TCEStaticExplorerWidget.projClose(const aProject: TCEProject);
begin
fProj := nil;
end;
procedure TCEStaticExplorerWidget.docNew(const aDoc: TCESynMemo);
@ -81,6 +158,7 @@ end;
procedure TCEStaticExplorerWidget.UpdateByDelay;
begin
if not fAutoRefresh then exit;
Rescan;
end;
@ -136,13 +214,16 @@ begin
memb := nil;
// generate json
// note: only if
// - the imports can be found (either using the project infos or sc.conf)
// - the source is error-less
dmdproc := TProcess.Create(nil);
lines := TStringList.Create;
try
jsf := GetTempDir(false);
jsf += format('%.8X.json',[NativeUint(@dmdproc)]);
jsf += uniqueObjStr(dmdProc) + '.json';
scf := GetTempDir(false);
scf += format('%.8X.d',[NativeUint(@dmdproc)]);
scf += uniqueObjStr(dmdProc) + '.d';
//
lines.Assign(fDoc.Lines);
lines.SaveToFile(scf);
@ -154,7 +235,17 @@ begin
dmdproc.Parameters.Add('-c');
dmdproc.Parameters.Add('-o-');
dmdproc.Parameters.Add('-X');
dmdproc.Parameters.Add('-Xf' + jsf );
dmdproc.Parameters.Add('-Xf' + jsf);
if fProj <> nil then
begin
dmdProc.CurrentDirectory := extractFilePath(fProj.fileName);
if fProj <> nil then for i := 0 to fProj.Sources.Count-1 do
dmdproc.Parameters.Add('-I' + fProj.getAbsoluteSourceName(i));
for nme in fProj.Sources do
dmdproc.Parameters.Add('-I' + extractFilePath(nme));
for nme in fProj.currentConfiguration.pathsOptions.Includes do
dmdproc.Parameters.Add('-I' + nme);
end;
dmdproc.Execute;
while dmdproc.Running do;
finally
@ -184,44 +275,45 @@ begin
end;
// update tree
memb := dat.items[0].FindPath('members');
if memb <> nil then for i := 0 to memb.Count-1 do
begin
// category
ln := new(PInt64);
ln^ := memb.Items[i].GetPath('line').AsInt64;
nme := memb.Items[i].GetPath('name').AsString;
case memb.Items[i].GetPath('kind').AsString of
'alias' :ndCat := Tree.Items.AddChildObject(ndAlias, nme, ln);
'class' :ndCat := Tree.Items.AddChildObject(ndClass, nme, ln);
'enum' :ndCat := Tree.Items.AddChildObject(ndEnum, nme, ln);
'function':ndCat := Tree.Items.AddChildObject(ndFunc, nme, ln);
'import' :ndCat := Tree.Items.AddChildObject(ndImp, nme, ln);
'mixin' :ndCat := Tree.Items.AddChildObject(ndMix, nme, ln);
'struct' :ndCat := Tree.Items.AddChildObject(ndStruct, nme, ln);
'template':ndCat := Tree.Items.AddChildObject(ndTmp, nme, ln);
'variable':ndCat := Tree.Items.AddChildObject(ndVar, nme, ln);
end;
// optional item members
submemb := memb.Items[i].FindPath('members');
if subMemb <> nil then for j := 0 to submemb.Count-1 do
try
memb := dat.items[0].FindPath('members');
if memb <> nil then for i := 0 to memb.Count-1 do
begin
// category
ln := new(PInt64);
ln^ := submemb.Items[j].GetPath('line').AsInt64;
nme := submemb.Items[j].GetPath('name').AsString;
Tree.Items.AddChildObject(ndCat, nme, ln);
ln^ := memb.Items[i].GetPath('line').AsInt64;
nme := memb.Items[i].GetPath('name').AsString;
case memb.Items[i].GetPath('kind').AsString of
'alias' :ndCat := Tree.Items.AddChildObject(ndAlias, nme, ln);
'class' :ndCat := Tree.Items.AddChildObject(ndClass, nme, ln);
'enum' :ndCat := Tree.Items.AddChildObject(ndEnum, nme, ln);
'function':ndCat := Tree.Items.AddChildObject(ndFunc, nme, ln);
'import' :ndCat := Tree.Items.AddChildObject(ndImp, nme, ln);
'mixin' :ndCat := Tree.Items.AddChildObject(ndMix, nme, ln);
'struct' :ndCat := Tree.Items.AddChildObject(ndStruct, nme, ln);
'template':ndCat := Tree.Items.AddChildObject(ndTmp, nme, ln);
'variable':ndCat := Tree.Items.AddChildObject(ndVar, nme, ln);
end;
// optional item members
submemb := memb.Items[i].FindPath('members');
if subMemb <> nil then for j := 0 to submemb.Count-1 do
begin
ln := new(PInt64);
ln^ := submemb.Items[j].GetPath('line').AsInt64;
nme := submemb.Items[j].GetPath('name').AsString;
Tree.Items.AddChildObject(ndCat, nme, ln);
end;
end;
finally
if dat <> nil then
begin
dat.Clear;
dat.Free;
end;
end;
if dat <> nil then
begin
dat.Clear;
dat.Free;
end;
end;

View File

@ -28,6 +28,7 @@ object CEWidget: TCEWidget
Width = 332
Align = alClient
BevelOuter = bvNone
PopupMenu = contextMenu
TabOrder = 0
end
end

View File

@ -56,7 +56,7 @@ type
// decrements the update count and call 'UpdateByEvent' if the
// counter value is null.
procedure endUpdateByEvent;
// immediate call the 'UpdateByEvent'
// immediate call 'UpdateByEvent'
procedure forceUpdateByEvent;
//
procedure docNew(const aDoc: TCESynMemo); virtual;
@ -103,6 +103,9 @@ implementation
* TCEWidget
*)
constructor TCEWidget.create(aOwner: TComponent);
var
i: NativeInt;
itm: TmenuItem;
begin
inherited;
fID := 'ID_XXXX';
@ -117,6 +120,15 @@ begin
DockMaster.MakeDockable(Self, true, true, true);
DockMaster.GetAnchorSite(Self).Header.HeaderPosition := adlhpTop;
for i := 0 to contextActionCount-1 do
begin
itm := TMenuItem.Create(self);
itm.Action := contextAction(i);
contextMenu.Items.Add(itm);
end;
PopupMenu := contextMenu;
end;
destructor TCEWidget.destroy;

View File

@ -20,7 +20,7 @@ type
end;
(**
* An implementer adds some menu actions when its context is valid.
* An implementer declares some actions on demand.
*)
ICEContextualActions = interface
function contextName: string;