new project dialog

This commit is contained in:
Vadim Lopatin 2015-12-07 16:10:13 +03:00
parent 632ba4a866
commit 3cf0e9da49
3 changed files with 249 additions and 68 deletions

View File

@ -639,10 +639,21 @@ class IDEFrame : AppFrame {
void createNewProject(bool newWorkspace) {
if (currentWorkspace is null)
newWorkspace = true;
NewProjectDlg dlg = new NewProjectDlg(window, newWorkspace, currentWorkspace);
NewProjectDlg dlg = new NewProjectDlg(this, newWorkspace, currentWorkspace);
dlg.dialogResult = delegate(Dialog dlg, const Action result) {
if (result.id == ACTION_APPLY.id) {
if (result.id == ACTION_FILE_NEW_PROJECT.id || result.id == ACTION_FILE_NEW_WORKSPACE.id) {
//Log.d("settings after edit:\n", s.toJSON(true));
ProjectCreationResult res = cast(ProjectCreationResult)result.objectParam;
if (res) {
// open workspace/project
if (currentWorkspace is null || res.workspace !is currentWorkspace) {
// open new workspace
setWorkspace(res.workspace);
} else {
// project added to current workspace
loadProject(res.project);
}
}
}
};
dlg.show();

View File

@ -4,6 +4,7 @@ import dlangui.core.types;
import dlangui.core.i18n;
import dlangui.platforms.common.platform;
import dlangui.dialogs.dialog;
import dlangui.dialogs.filedlg;
import dlangui.widgets.widget;
import dlangui.widgets.layouts;
import dlangui.widgets.editors;
@ -11,56 +12,86 @@ import dlangui.widgets.controls;
import dlangui.widgets.lists;
import dlangui.dml.parser;
import dlangui.core.stdaction;
import dlangui.core.files;
import dlangide.workspace.project;
import dlangide.workspace.workspace;
import dlangide.ui.commands;
import dlangide.ui.frame;
import std.path;
import std.file;
import std.array : empty;
class ProjectCreationResult {
Workspace workspace;
Project project;
this(Workspace workspace, Project project) {
this.workspace = workspace;
this.project = project;
}
}
class NewProjectDlg : Dialog {
Workspace currentWorkspace;
this(Window parent, bool newWorkspace, Workspace currentWorkspace) {
super(newWorkspace ? UIString("New Workspace"d) : UIString("New Project"d), parent, DialogFlag.Modal | DialogFlag.Resizable, 500, 400);
Workspace _currentWorkspace;
IDEFrame _ide;
this(IDEFrame parent, bool newWorkspace, Workspace currentWorkspace) {
super(newWorkspace ? UIString("New Workspace"d) : UIString("New Project"d), parent.window, DialogFlag.Modal | DialogFlag.Resizable, 500, 400);
_ide = parent;
_icon = "dlangui-logo1";
this.currentWorkspace = currentWorkspace;
this._currentWorkspace = currentWorkspace;
_newWorkspace = newWorkspace;
_location = currentWorkspace !is null ? currentWorkspace.dir : currentDir;
}
/// override to implement creation of dialog controls
override void init() {
super.init();
initTemplates();
Widget content = parseML(q{
VerticalLayout {
id: vlayout
padding: Rect { 5, 5, 5, 5 }
layoutWidth: FILL_PARENT; layoutHeight: FILL_PARENT
HorizontalLayout {
layoutWidth: FILL_PARENT; layoutHeight: FILL_PARENT
VerticalLayout {
margins: 5
layoutWidth: WRAP_CONTENT; layoutHeight: FILL_PARENT
TextWidget { text: "Project template" }
StringListWidget {
id: projectTemplateList
layoutWidth: WRAP_CONTENT; layoutHeight: FILL_PARENT
Widget content;
try {
content = parseML(q{
VerticalLayout {
id: vlayout
padding: Rect { 5, 5, 5, 5 }
layoutWidth: fill; layoutHeight: fill
HorizontalLayout {
layoutWidth: fill; layoutHeight: fill
VerticalLayout {
margins: 5
layoutWidth: wrap; layoutHeight: fill
TextWidget { text: "Project template" }
StringListWidget {
id: projectTemplateList
layoutWidth: wrap; layoutHeight: fill
}
}
VerticalLayout {
margins: 5
layoutWidth: fill; layoutHeight: fill
TextWidget { text: "Template description" }
EditBox {
id: templateDescription; readOnly: true
layoutWidth: fill; layoutHeight: fill
}
}
VerticalLayout {
layoutWidth: fill; layoutHeight: fill
margins: 5
TextWidget { text: "Directory layout" }
EditBox {
id: directoryLayout; readOnly: true
layoutWidth: fill; layoutHeight: fill
}
}
}
VerticalLayout {
margins: 5
layoutWidth: FILL_PARENT; layoutHeight: FILL_PARENT
TextWidget { text: "Template description" }
EditBox {
id: templateDescription; readOnly: true
layoutWidth: FILL_PARENT; layoutHeight: FILL_PARENT
}
}
}
HorizontalLayout {
layoutWidth: FILL_PARENT; layoutHeight: FILL_PARENT
TableLayout {
margins: 5
colCount: 2
layoutWidth: FILL_PARENT; layoutHeight: FILL_PARENT
layoutWidth: fill; layoutHeight: wrap
TextWidget { text: "" }
CheckBox { id: cbCreateWorkspace; text: "Create new solution" }
CheckBox { id: cbCreateWorkspace; text: "Create new solution"; checked: true }
TextWidget { text: "Workspace name" }
EditLine {
id: edWorkspaceName; text: "newworkspace"
@ -70,24 +101,19 @@ class NewProjectDlg : Dialog {
id: edProjectName; text: "newproject"
}
TextWidget { text: "" }
CheckBox { id: cbCreateSubdir; text: "Create subdirectory for project" }
CheckBox { id: cbCreateSubdir; text: "Create subdirectory for project"; checked: true }
TextWidget { text: "Location" }
EditLine {
DirEditLine {
id: edLocation
}
}
VerticalLayout {
layoutWidth: FILL_PARENT; layoutHeight: FILL_PARENT
margins: 5
TextWidget { text: "Directory layout" }
EditBox {
id: directoryLayout; readOnly: true
layoutWidth: FILL_PARENT; layoutHeight: FILL_PARENT
}
}
TextWidget { id: statusText; text: "" }
}
}
});
});
} catch (Exception e) {
Log.e("Exceptin while parsing DML", e);
throw e;
}
_projectTemplateList = content.childById!StringListWidget("projectTemplateList");
_templateDescription = content.childById!EditBox("templateDescription");
@ -96,15 +122,20 @@ class NewProjectDlg : Dialog {
_edWorkspaceName = content.childById!EditLine("edWorkspaceName");
_cbCreateSubdir = content.childById!CheckBox("cbCreateSubdir");
_cbCreateWorkspace = content.childById!CheckBox("cbCreateWorkspace");
_edLocation = content.childById!DirEditLine("edLocation");
_edLocation.text = toUTF32(_location);
_statusText = content.childById!TextWidget("statusText");
if (_currentWorkspace) {
_workspaceName = toUTF8(_currentWorkspace.name);
_edWorkspaceName.text = toUTF32(_workspaceName);
}
if (!_newWorkspace) {
_cbCreateWorkspace.checked = false;
_cbCreateWorkspace.enabled = _currentWorkspace !is null;
_edWorkspaceName.readOnly = true;
}
_edProjectName.contentChange = delegate (EditableContent source) {
_projectName = source.text;
updateDirLayout();
};
_edWorkspaceName.contentChange = delegate (EditableContent source) {
_workspaceName = source.text;
updateDirLayout();
};
// fill templates
dstring[] names;
@ -112,6 +143,32 @@ class NewProjectDlg : Dialog {
names ~= t.name;
_projectTemplateList.items = names;
_projectTemplateList.selectedItemIndex = 0;
templateSelected(0);
updateDirLayout();
// listeners
_edProjectName.contentChange = delegate (EditableContent source) {
_projectName = toUTF8(source.text);
updateDirLayout();
};
_edWorkspaceName.contentChange = delegate (EditableContent source) {
_workspaceName = toUTF8(source.text);
updateDirLayout();
};
_edLocation.contentChange = delegate (EditableContent source) {
_location = toUTF8(source.text);
updateDirLayout();
};
_cbCreateWorkspace.checkChange = delegate (Widget source, bool checked) {
_edWorkspaceName.readOnly = !checked;
updateDirLayout();
return true;
};
_projectTemplateList.itemSelected = delegate (Widget source, int itemIndex) {
templateSelected(itemIndex);
return true;
@ -120,32 +177,44 @@ class NewProjectDlg : Dialog {
templateSelected(itemIndex);
return true;
};
templateSelected(0);
updateDirLayout();
addChild(content);
addChild(createButtonsPanel([ACTION_OK, ACTION_CANCEL], 0, 0));
addChild(createButtonsPanel([_newWorkspace ? ACTION_FILE_NEW_WORKSPACE : ACTION_FILE_NEW_PROJECT, ACTION_CANCEL], 0, 0));
}
bool _newWorkspace;
bool _;
StringListWidget _projectTypeList;
StringListWidget _projectTemplateList;
EditBox _templateDescription;
EditBox _directoryLayout;
DirEditLine _edLocation;
EditLine _edWorkspaceName;
EditLine _edProjectName;
CheckBox _cbCreateSubdir;
CheckBox _cbCreateWorkspace;
dstring _projectName = "newproject";
dstring _workspaceName = "newworkspace";
TextWidget _statusText;
string _projectName = "newproject";
string _workspaceName = "newworkspace";
string _location;
void initTemplates() {
_templates ~= new ProjectTemplate("Empty app project"d, "Empty application project.\nNo source files."d);
_templates ~= new ProjectTemplate("Empty library project"d, "Empty library project.\nNo Source files."d);
_templates ~= new ProjectTemplate("Hello world app"d, "Hello world application."d);
_templates ~= new ProjectTemplate("DlangUI: hello world app"d, "Hello world application\nbased on DlangUI library"d);
_templates ~= new ProjectTemplate("Empty app project"d, "Empty application project.\nNo source files."d, null, null, false);
_templates ~= new ProjectTemplate("Empty library project"d, "Empty library project.\nNo Source files."d, null, null, true);
_templates ~= new ProjectTemplate("Hello world app"d, "Hello world application."d, "app.d",
q{
import std.stdio;
void main(string[] args) {
writeln("Hello World!");
}
}, false);
_templates ~= new ProjectTemplate("DlangUI: hello world app"d, "Hello world application\nbased on DlangUI library"d, "app.d",
q{
import std.stdio;
void main(string[] args) {
writeln("Hello World!");
}
}, false);
}
int _currentTemplateIndex = -1;
@ -158,26 +227,124 @@ class NewProjectDlg : Dialog {
_currentTemplateIndex = index;
_currentTemplate = _templates[index];
_templateDescription.text = _currentTemplate.description;
updateDirLayout();
}
protected void updateDirLayout() {
dchar[] buf;
buf ~= _workspaceName ~ toUTF32(WORKSPACE_EXTENSION) ~ "\n";
if (_cbCreateSubdir.checked)
buf ~= toUTF32(_workspaceName) ~ toUTF32(WORKSPACE_EXTENSION) ~ "\n";
dstring level = "";
if (_cbCreateSubdir.checked) {
buf ~= _projectName ~ "/\n";
buf ~= toUTF32(_projectName) ~ "/\n";
level = " ";
}
buf ~= level ~ "dub.json" ~ "\n";
buf ~= level ~ "source/" ~ "\n";
if (_currentTemplate.srcfile.length) {
buf ~= level ~ " " ~ toUTF32(_currentTemplate.srcfile) ~ "\n";
}
_directoryLayout.text = buf.dup;
validate();
}
bool setError(dstring msg) {
_statusText.text = msg;
return msg.empty;
}
ProjectCreationResult _result;
override void close(const Action action) {
Action newaction = action.clone();
if (action == ACTION_FILE_NEW_WORKSPACE || action == ACTION_FILE_NEW_PROJECT) {
if (!validate()) {
window.showMessageBox(UIString("Cannot create project"d), UIString("Invalid parameters"));
return;
}
if (!createProject()) {
window.showMessageBox(UIString("Cannot create project"d), UIString("Failed to create project"));
return;
}
newaction.objectParam = _result;
}
super.close(newaction);
}
bool validate() {
if (!exists(_location) || !isDir(_location)) {
return setError("Invalid location");
}
return setError("");
}
bool createProject() {
if (!validate())
return false;
Workspace ws = _currentWorkspace;
if (_newWorkspace) {
string wsfilename = buildNormalizedPath(_location, _workspaceName ~ WORKSPACE_EXTENSION);
ws = new Workspace(_ide, wsfilename);
ws.name = toUTF32(_workspaceName);
if (!ws.save())
return setError("Cannot create workspace file");
}
string pdir = _location;
if (_cbCreateSubdir.checked) {
pdir = buildNormalizedPath(pdir, _projectName);
if (pdir.exists) {
if (!pdir.isDir)
return setError("Cannot create project directory");
} else {
try {
mkdir(pdir);
} catch (Exception e) {
return setError("Cannot create project directory");
}
}
}
string pfile = buildNormalizedPath(pdir, "dub.json");
Project project = new Project(ws, pfile);
project.name = toUTF32(_projectName);
project.content.setString("targetName", _projectName);
if (_currentTemplate.isLibrary) {
project.content.setString("targetType", "staticLibrary");
project.content.setString("targetPath", "lib");
} else {
project.content.setString("targetType", "executable");
project.content.setString("targetPath", "bin");
}
project.save();
ws.addProject(project);
if (ws.startupProject is null)
ws.startupProject = project;
if (!_currentTemplate.srcfile.empty && !_currentTemplate.srccode.empty) {
string srcdir = buildNormalizedPath(pdir, "dub.json");
if (!exists(srcdir))
mkdir(srcdir);
string srcfile = buildNormalizedPath(srcdir, _currentTemplate.srcfile);
write(srcfile, _currentTemplate.srccode);
}
if (!project.save())
return setError("Cannot save project file");
if (!ws.save())
return setError("Cannot save workspace file");
_result = new ProjectCreationResult(ws, project);
return true;
}
}
class ProjectTemplate {
dstring name;
dstring description;
this(dstring name, dstring description) {
string srcfile;
string srccode;
bool isLibrary;
this(dstring name, dstring description, string srcfile, string srccode, bool isLibrary) {
this.name = name;
this.description = description;
this.srcfile = srcfile;
this.srccode = srccode;
this.isLibrary = isLibrary;
}
}

View File

@ -305,6 +305,9 @@ class Project : WorkspaceItem {
{
return _configurations;
}
/// direct access to project file (json)
@property SettingsFile content() { return _projectFile; }
/// returns project's own source paths
@property string[] sourcePaths() { return _sourcePaths; }