diff --git a/lazproj/coedit.lpi b/lazproj/coedit.lpi
index f9697920..4a164a90 100644
--- a/lazproj/coedit.lpi
+++ b/lazproj/coedit.lpi
@@ -135,7 +135,7 @@
-
+
@@ -349,6 +349,13 @@
+
+
+
+
+
+
+
diff --git a/lazproj/coedit.lpr b/lazproj/coedit.lpr
index 40090178..876402f1 100644
--- a/lazproj/coedit.lpr
+++ b/lazproj/coedit.lpr
@@ -9,7 +9,8 @@ uses
Interfaces, Forms, lazcontrols, runtimetypeinfocontrols, ce_sharedres,
ce_observer, ce_libman, ce_tools, ce_dcd, ce_main, ce_writableComponent,
ce_symstring, ce_staticmacro, ce_inspectors, ce_editoroptions, ce_dockoptions,
- ce_shortcutseditor, ce_mru, ce_processes, ce_dubproject, ce_dialogs;
+ ce_shortcutseditor, ce_mru, ce_processes, ce_dubproject, ce_dialogs,
+ce_dubprojeditor;
{$R *.res}
diff --git a/src/ce_dubproject.pas b/src/ce_dubproject.pas
index e73f0b6a..d76b95d9 100644
--- a/src/ce_dubproject.pas
+++ b/src/ce_dubproject.pas
@@ -41,6 +41,8 @@ type
//
function compile: boolean;
function run(const runArgs: string = ''): boolean;
+ //
+ property json: TJSONObject read fJson;
end;
implementation
@@ -112,7 +114,6 @@ begin
loader.LoadFromFile(fFilename);
fJSon.Free;
parser := TJSONParser.Create(loader);
- subjProjChanged(fProjectSubject, self);
try
fJSon := parser.Parse as TJSONObject;
finally
@@ -120,6 +121,7 @@ begin
end;
finally
loader.Free;
+ subjProjChanged(fProjectSubject, self);
fModified := false;
end;
end;
diff --git a/src/ce_dubprojeditor.lfm b/src/ce_dubprojeditor.lfm
new file mode 100644
index 00000000..aa5a0b67
--- /dev/null
+++ b/src/ce_dubprojeditor.lfm
@@ -0,0 +1,79 @@
+inherited CEDubProjectEditorWidget: TCEDubProjectEditorWidget
+ Left = 816
+ Height = 417
+ Top = 191
+ Width = 411
+ ClientHeight = 417
+ ClientWidth = 411
+ inherited Back: TPanel
+ Height = 417
+ Width = 411
+ ClientHeight = 417
+ ClientWidth = 411
+ inherited Content: TPanel
+ Height = 417
+ Width = 411
+ ClientHeight = 417
+ ClientWidth = 411
+ object pnlToolBar: TPanel[0]
+ Left = 4
+ Height = 26
+ Top = 2
+ Width = 403
+ Align = alTop
+ BorderSpacing.Left = 2
+ BorderSpacing.Right = 2
+ BorderSpacing.Around = 2
+ BevelOuter = bvNone
+ ClientHeight = 26
+ ClientWidth = 403
+ TabOrder = 0
+ object btnAddProp: TSpeedButton
+ Left = 0
+ Height = 26
+ Hint = 'add an empty configuration'
+ Top = 0
+ Width = 28
+ Align = alLeft
+ Layout = blGlyphBottom
+ ShowCaption = False
+ end
+ object btnDelProp: TSpeedButton
+ Left = 28
+ Height = 26
+ Hint = 'remove selected configuration'
+ Top = 0
+ Width = 28
+ Align = alLeft
+ Layout = blGlyphBottom
+ ShowCaption = False
+ end
+ end
+ object propTree: TTreeView[1]
+ Left = 4
+ Height = 284
+ Top = 32
+ Width = 403
+ Align = alClient
+ BorderSpacing.Around = 4
+ DefaultItemHeight = 18
+ HideSelection = False
+ ReadOnly = True
+ ScrollBars = ssAutoBoth
+ TabOrder = 1
+ OnSelectionChanged = propTreeSelectionChanged
+ Options = [tvoAutoItemHeight, tvoKeepCollapsedNodes, tvoReadOnly, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips, tvoThemedDraw]
+ end
+ object edValue: TMemo[2]
+ Left = 4
+ Height = 93
+ Top = 320
+ Width = 403
+ Align = alBottom
+ BorderSpacing.Around = 4
+ ScrollBars = ssAutoVertical
+ TabOrder = 2
+ end
+ end
+ end
+end
diff --git a/src/ce_dubprojeditor.pas b/src/ce_dubprojeditor.pas
new file mode 100644
index 00000000..f8bf29b9
--- /dev/null
+++ b/src/ce_dubprojeditor.pas
@@ -0,0 +1,209 @@
+unit ce_dubprojeditor;
+
+{$I ce_defines.inc}
+
+interface
+
+uses
+ Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
+ Menus, StdCtrls, Buttons, ComCtrls, jsonparser, fpjson,
+ ce_widget, ce_common, ce_interfaces, ce_observer, ce_dubproject;
+
+type
+
+ { TCEDubProjectEditorWidget }
+
+ TCEDubProjectEditorWidget = class(TCEWidget, ICEProjectObserver)
+ btnAddProp: TSpeedButton;
+ btnDelProp: TSpeedButton;
+ edValue: TMemo;
+ pnlToolBar: TPanel;
+ propTree: TTreeView;
+ procedure propTreeSelectionChanged(Sender: TObject);
+ private
+ fSelectedNode: TTreeNode;
+ fProj: TCEDubProject;
+ procedure updateGui;
+ procedure updateValueEditor;
+ procedure setJsonValueFromEditor;
+ //
+ procedure projNew(aProject: ICECommonProject);
+ procedure projChanged(aProject: ICECommonProject);
+ procedure projClosing(aProject: ICECommonProject);
+ procedure projFocused(aProject: ICECommonProject);
+ procedure projCompiling(aProject: ICECommonProject);
+ //
+ protected
+ procedure SetVisible(Value: boolean); override;
+ public
+ end;
+
+implementation
+{$R *.lfm}
+
+{$REGION Standard Comp/Obj ----------------------------------------------------}
+procedure TCEDubProjectEditorWidget.SetVisible(Value: boolean);
+begin
+ inherited;
+ if not Value then exit;
+ //
+ updateGui;
+end;
+{$ENDREGION}
+
+{$REGION ICEProjectObserver ----------------------------------------------------}
+procedure TCEDubProjectEditorWidget.projNew(aProject: ICECommonProject);
+begin
+ fProj := nil;
+ if aProject.getFormat <> pfDub then
+ exit;
+ fProj := TCEDubProject(aProject.getProject);
+ //
+end;
+
+procedure TCEDubProjectEditorWidget.projChanged(aProject: ICECommonProject);
+begin
+ if fProj = nil then
+ exit;
+ if aProject.getProject <> fProj then
+ exit;
+ //
+ if Visible then
+ updateGui;
+end;
+
+procedure TCEDubProjectEditorWidget.projClosing(aProject: ICECommonProject);
+begin
+ if fProj = nil then
+ exit;
+ if aProject.getProject <> fProj then
+ exit;
+ fProj := nil;
+ //
+ updateGui;
+end;
+
+procedure TCEDubProjectEditorWidget.projFocused(aProject: ICECommonProject);
+begin
+ fProj := nil;
+ if aProject.getFormat <> pfDub then
+ exit;
+ fProj := TCEDubProject(aProject.getProject);
+ //
+ if Visible then
+ updateGui;
+end;
+
+procedure TCEDubProjectEditorWidget.projCompiling(aProject: ICECommonProject);
+begin
+end;
+{$ENDREGION}
+
+{$REGION GUI -------------------------------------------------------------------}
+procedure TCEDubProjectEditorWidget.propTreeSelectionChanged(Sender: TObject);
+begin
+ fSelectedNode := nil;
+ if propTree.Selected = nil then exit;
+ //
+ fSelectedNode := propTree.Selected;
+ updateValueEditor;
+end;
+
+procedure TCEDubProjectEditorWidget.setJsonValueFromEditor;
+var
+ dat: TJSONData;
+ vFloat: TJSONFloat;
+ vInt: integer;
+ vInt64: int64;
+ vBool: boolean;
+begin
+ if fSelectedNode = nil then exit;
+ if fSelectedNode.Data = nil then exit;
+ //
+ dat := TJSONData(fSelectedNode.Data);
+ case dat.JSONType of
+ jtNumber:
+ case TJSONNumber(dat).NumberType of
+ ntFloat:
+ if TryStrToFloat(edValue.Text, vFloat) then
+ dat.AsFloat := vFloat;
+ ntInt64:
+ if TryStrToInt64(edValue.Text, vInt64) then
+ dat.AsInt64 := vInt64;
+ ntInteger:
+ if TryStrToInt(edValue.Text, vInt) then
+ dat.AsInteger := vInt;
+ end;
+ jtBoolean:
+ if TryStrToBool(edValue.Text, vBool) then
+ dat.AsBoolean := vBool;
+ jtString:
+ dat.AsString := edValue.Text;
+ end;
+end;
+
+procedure TCEDubProjectEditorWidget.updateValueEditor;
+var
+ dat: TJSONData;
+begin
+ edValue.Clear;
+ if fSelectedNode = nil then exit;
+ if fSelectedNode.Data = nil then exit;
+ //
+ dat := TJSONData(fSelectedNode.Data);
+ case dat.JSONType of
+ jtNumber:
+ case TJSONNumber(dat).NumberType of
+ ntFloat:
+ edValue.Text := FloatToStr(dat.AsFloat);
+ ntInt64:
+ edValue.Text := IntToStr(dat.AsInt64);
+ ntInteger:
+ edValue.Text := IntToStr(dat.AsInteger);
+ end;
+ jtBoolean:
+ edValue.Text := BoolToStr(dat.AsBoolean);
+ jtString:
+ edValue.Text := dat.AsString;
+ end;
+end;
+
+procedure TCEDubProjectEditorWidget.updateGui;
+
+ procedure addPropsFrom(node: TTreeNode; data: TJSONData);
+ var
+ i: integer;
+ c: TTreeNode;
+ begin
+ if data.JSONType = jtObject then for i := 0 to data.Count-1 do
+ begin
+ c := node.TreeNodes.AddChildObject(node, TJSONObject(data).Names[i],
+ TJSONObject(data).Items[i]);
+ case TJSONObject(data).Items[i].JSONType of
+ jtObject, jtArray:
+ addPropsFrom(c, TJSONObject(data).Items[i]);
+ end;
+ end else if data.JSONType = jtArray then for i := 0 to data.Count-1 do
+ begin
+ c := node.TreeNodes.AddChildObject(node, format('item %d',[i]),
+ TJSONArray(data).Items[i]);
+ case TJSONArray(data).Items[i].JSONType of
+ jtObject, jtArray:
+ addPropsFrom(c, TJSONArray(data).Items[i]);
+ end;
+ end;
+ end;
+
+begin
+ propTree.Items.Clear;
+ if (fProj = nil) or (fProj.json = nil) then
+ exit;
+ //
+ propTree.BeginUpdate;
+ addPropsFrom(propTree.Items.Add(nil, 'project'), fProj.json);
+ propTree.EndUpdate;
+end;
+{$ENDREGION}
+
+end.
+
diff --git a/src/ce_main.pas b/src/ce_main.pas
index 10047f86..ff713c62 100644
--- a/src/ce_main.pas
+++ b/src/ce_main.pas
@@ -12,7 +12,7 @@ uses
ce_widget, ce_messages, ce_interfaces, ce_editor, ce_projinspect, ce_projconf,
ce_search, ce_miniexplorer, ce_libman, ce_libmaneditor, ce_todolist, ce_observer,
ce_toolseditor, ce_procinput, ce_optionseditor, ce_symlist, ce_mru, ce_processes,
- ce_infos, ce_dubproject, ce_dialogs;
+ ce_infos, ce_dubproject, ce_dialogs, ce_dubprojeditor;
type
@@ -209,8 +209,13 @@ type
fOptEdWidg: TCEOptionEditorWidget;
fSymlWidg: TCESymbolListWidget;
fInfoWidg: TCEInfoWidget;
+ fDubProjWidg: TCEDubProjectEditorWidget;
- //TODO-cDUB: widget to edit and view, select config of, a DUB project
+ //TODO-cDUB: widget to edit and view, select config of, a DUB project.
+ // DUB format can't be wrapped as published prop so...
+ // ...visually: displayed as a tree. node = prop name.
+ // prop value editor in sync with slected node,
+ // treeview filter. add node, etc.
fInitialized: boolean;
fRunnableSw: string;
@@ -616,6 +621,7 @@ begin
fOptEdWidg:= TCEOptionEditorWidget.create(self);
fSymlWidg := TCESymbolListWidget.create(self);
fInfoWidg := TCEInfoWidget.create(self);
+ fDubProjWidg:= TCEDubProjectEditorWidget.create(self);
getMessageDisplay(fMsgs);
@@ -632,6 +638,7 @@ begin
fWidgList.addWidget(@fOptEdWidg);
fWidgList.addWidget(@fSymlWidg);
fWidgList.addWidget(@fInfoWidg);
+ fWidgList.addWidget(@fDubProjWidg);
fWidgList.sort(@CompareWidgCaption);
for widg in fWidgList do
diff --git a/src/ce_projconf.pas b/src/ce_projconf.pas
index ed014cea..9492146a 100644
--- a/src/ce_projconf.pas
+++ b/src/ce_projconf.pas
@@ -120,6 +120,7 @@ end;
procedure TCEProjectConfigurationWidget.projClosing(aProject: ICECommonProject);
begin
+ if fProj = nil then exit;
if fProj <> aProject.getProject then
exit;
inspector.TIObject := nil;
@@ -132,6 +133,7 @@ end;
procedure TCEProjectConfigurationWidget.projChanged(aProject: ICECommonProject);
begin
+ if fProj = nil then exit;
if fProj <> aProject.getProject then
exit;
if Visible then updateImperative;
diff --git a/src/ce_projinspect.pas b/src/ce_projinspect.pas
index 72ea900b..fbdd1e2e 100644
--- a/src/ce_projinspect.pas
+++ b/src/ce_projinspect.pas
@@ -159,6 +159,7 @@ end;
procedure TCEProjectInspectWidget.projClosing(aProject: ICECommonProject);
begin
+ if fProject = nil then exit;
if fProject <> aProject.getProject then
exit;
fProject := nil;
@@ -179,6 +180,7 @@ end;
procedure TCEProjectInspectWidget.projChanged(aProject: ICECommonProject);
begin
+ if fProject = nil then exit;
if fProject <> aProject.getProject then
exit;
if Visible then beginDelayedUpdate;