support opening of projects and workspaces

This commit is contained in:
Vadim Lopatin 2015-01-27 18:08:52 +03:00
parent 807796e3d1
commit ce91b7c797
6 changed files with 156 additions and 15 deletions

View File

@ -31,6 +31,8 @@ enum IDEActions : int {
DebugPause,
HelpAbout,
WindowCloseAllDocuments,
CreateNewWorkspace,
AddToCurrentWorkspace,
}
const Action ACTION_FILE_NEW_SOURCE_FILE = new Action(IDEActions.FileNew, "MENU_FILE_NEW_SOURCE_FILE"c, "document-new", KeyCode.KEY_N, KeyFlag.Control);
@ -62,3 +64,5 @@ const Action ACTION_EDIT_UNDO = new Action(EditorActions.Undo, "MENU_EDIT_UNDO"c
const Action ACTION_EDIT_REDO = new Action(EditorActions.Redo, "MENU_EDIT_REDO"c, "edit-redo"c, KeyCode.KEY_Z, KeyFlag.Control|KeyFlag.Shift);
const Action ACTION_HELP_ABOUT = new Action(IDEActions.HelpAbout, "MENU_HELP_ABOUT"c);
const Action ACTION_WINDOW_CLOSE_ALL_DOCUMENTS = new Action(IDEActions.WindowCloseAllDocuments, "MENU_WINDOW_CLOSE_ALL_DOCUMENTS"c);
const Action ACTION_CREATE_NEW_WORKSPACE = new Action(IDEActions.CreateNewWorkspace, "Create new workspace"d);
const Action ACTION_ADD_TO_CURRENT_WORKSPACE = new Action(IDEActions.CreateNewWorkspace, "Add to current workspace"d);

View File

@ -371,6 +371,8 @@ class IDEFrame : AppFrame {
dlg.onDialogResult = delegate(Dialog dlg, const Action result) {
if (result.id == ACTION_OPEN.id) {
string filename = result.stringParam;
if (filename.length)
openFileOrWorkspace(filename);
}
};
dlg.show();
@ -382,13 +384,68 @@ class IDEFrame : AppFrame {
return false;
}
void openFileOrWorkspace(string filename) {
if (filename.isWorkspaceFile) {
Workspace ws = new Workspace();
if (ws.load(filename)) {
askForUnsavedEdits(delegate() {
setWorkspace(ws);
});
} else {
window.showMessageBox(UIString("Cannot open workspace"d), UIString("Error occured while opening workspace"d));
return;
}
} else if (filename.isProjectFile) {
Project project = new Project();
if (!project.load(filename)) {
window.showMessageBox(UIString("Cannot open project"d), UIString("Error occured while opening project"d));
return;
}
string defWsFile = project.defWorkspaceFile;
if (currentWorkspace) {
Project existing = currentWorkspace.findProject(project.filename);
if (existing) {
window.showMessageBox(UIString("Open project"d), UIString("Project is already in workspace"d));
return;
}
window.showMessageBox(UIString("Open project"d), UIString("Do you want to create new workspace or use current one?"d),
[ACTION_ADD_TO_CURRENT_WORKSPACE, ACTION_CREATE_NEW_WORKSPACE, ACTION_CANCEL], 0, delegate(const Action result) {
if (result.id == IDEActions.CreateNewWorkspace) {
// new ws
Workspace ws = new Workspace();
ws.name = project.name;
ws.description = project.description;
ws.save(defWsFile);
setWorkspace(ws);
} else if (result.id == IDEActions.AddToCurrentWorkspace) {
// add to current
currentWorkspace.addProject(project);
currentWorkspace.save();
_wsPanel.reloadItems();
}
return true;
});
} else {
// new workspace file
}
} else {
window.showMessageBox(UIString("Invalid workspace file"d), UIString("This file is not a valid workspace or project file"d));
}
}
bool loadWorkspace(string path) {
// testing workspace loader
Workspace ws = new Workspace();
ws.load(path);
setWorkspace(ws);
ws.save(ws.filename ~ ".bak");
return true;
}
void setWorkspace(Workspace ws) {
closeAllDocuments();
currentWorkspace = ws;
_wsPanel.workspace = ws;
return true;
}
}

View File

@ -94,14 +94,13 @@ class WorkspacePanel : DockWindow {
}
}
@property void workspace(Workspace w) {
_workspace = w;
void reloadItems() {
_tree.requestLayout();
_tree.items.clear();
if (w) {
TreeItem root = _tree.items.newChild(w.filename, w.name, "project-development");
if (_workspace) {
TreeItem root = _tree.items.newChild(_workspace.filename, _workspace.name, "project-development");
root.intParam = ProjectItemType.Workspace;
foreach(project; w.projects) {
foreach(project; _workspace.projects) {
TreeItem p = root.newChild(project.filename, project.name, "project-open");
p.intParam = ProjectItemType.Project;
addProjectItems(p, project.items);
@ -109,6 +108,11 @@ class WorkspacePanel : DockWindow {
} else {
_tree.items.newChild("none", "New workspace"d, "project-development");
}
}
@property void workspace(Workspace w) {
_workspace = w;
reloadItems();
_tree.onTreeContentChange(null);
}
}

View File

@ -9,6 +9,22 @@ import std.json;
import std.utf;
import std.algorithm;
/// return true if filename matches rules for workspace file names
bool isProjectFile(string filename) {
return filename.baseName.equal("dub.json") || filename.baseName.equal("package.json");
}
string toForwardSlashSeparator(string filename) {
char[] res;
foreach(ch; filename) {
if (ch == '\\')
res ~= '/';
else
res ~= ch;
}
return cast(string)res;
}
/// project item
class ProjectItem {
protected Project _project;
@ -178,7 +194,7 @@ class WorkspaceItem {
return false;
}
bool save() {
bool save(string fname = null) {
return false;
}
}
@ -211,6 +227,10 @@ class Project : WorkspaceItem {
_workspace = p;
}
@property string defWorkspaceFile() {
return buildNormalizedPath(_filename.dirName, toUTF8(name) ~ WORKSPACE_EXTENSION);
}
ProjectFolder findItems() {
ProjectFolder folder = new ProjectFolder(_filename);
folder.project = this;

View File

@ -6,6 +6,7 @@ import std.path;
import std.file;
import std.json;
import std.utf;
import std.algorithm;
/**
Exception thrown on Workspace errors
@ -18,6 +19,12 @@ class WorkspaceException : Exception
}
}
immutable string WORKSPACE_EXTENSION = ".dlangidews";
/// return true if filename matches rules for workspace file names
bool isWorkspaceFile(string filename) {
return filename.endsWith(WORKSPACE_EXTENSION);
}
/// DlangIDE workspace
class Workspace : WorkspaceItem {
@ -41,6 +48,53 @@ class Workspace : WorkspaceItem {
return null;
}
/// find project in workspace by filename
Project findProject(string filename) {
foreach (Project p; _projects) {
if (p.filename.equal(filename))
return p;
}
return null;
}
void addProject(Project p) {
_projects ~= p;
p.workspace = this;
}
string absoluteToRelativePath(string path) {
return toForwardSlashSeparator(relativePath(path, _dir));
}
override bool save(string fname = null) {
if (fname.length > 0)
filename = fname;
try {
JSONValue content;
JSONValue[string] json;
json["name"] = JSONValue(toUTF8(_name));
json["description"] = JSONValue(toUTF8(_description));
JSONValue[string] projects;
foreach (Project p; _projects) {
string pname = toUTF8(p.name);
string ppath = absoluteToRelativePath(p.filename);
projects[pname] = JSONValue(ppath);
}
json["projects"] = projects;
content = json;
string js = content.toPrettyString;
write(_filename, js);
} catch (JSONException e) {
Log.e("Cannot parse json", e);
return false;
} catch (Exception e) {
Log.e("Cannot read workspace file", e);
return false;
}
return true;
}
override bool load(string fname = null) {
if (fname.length > 0)
filename = fname;
@ -61,12 +115,14 @@ class Workspace : WorkspaceItem {
string path = value.str;
Log.d("project: ", key, " path:", path);
if (!isAbsolute(path))
path = buildNormalizedPath(_dir, path, "dub.json");
path = buildNormalizedPath(_dir, path); //, "dub.json"
Project project = new Project(path);
_projects ~= project;
project.load();
}
string js = json.toPrettyString;
write(_filename, js);
} catch (JSONException e) {
Log.e("Cannot parse json", e);
return false;

View File

@ -1,8 +1,8 @@
{
"name": "sample1",
"description": "Sample workspace 1 for testing of DLANG IDE",
"projects": {
"sampleproject1": "./sampleproject1",
"sampleproject2": "./sampleproject2"
}
}
"description": "Sample workspace 1 for testing of DLANG IDE",
"projects": {
"sampleproject1": "sampleproject1\/dub.json",
"sampleproject2": "sampleproject2\/dub.json"
},
"name": "sample1"
}