diff --git a/.gitignore b/.gitignore
index c59f9d5..873afe4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,3 +20,7 @@ index.html
api.html
screenshots.html
*.log
+
+*.userprefs
+
+\.dlangidews\.wssettings
diff --git a/dlangide-monod-linux.dproj b/dlangide-monod-linux.dproj
index ab2553c..a26e12c 100644
--- a/dlangide-monod-linux.dproj
+++ b/dlangide-monod-linux.dproj
@@ -443,6 +443,7 @@
3rdparty\dsymbol\symbols.d
+
diff --git a/dlangide_msvc.visualdproj b/dlangide_msvc.visualdproj
index aaebee7..c707049 100644
--- a/dlangide_msvc.visualdproj
+++ b/dlangide_msvc.visualdproj
@@ -938,6 +938,7 @@
+
diff --git a/src/dlangide/ui/commands.d b/src/dlangide/ui/commands.d
index 7c4ceb3..b0c74fd 100644
--- a/src/dlangide/ui/commands.d
+++ b/src/dlangide/ui/commands.d
@@ -6,6 +6,7 @@ import dlangui.widgets.editors;
enum IDEActions : int {
//ProjectOpen = 1010000,
FileNew = 1010000,
+ FileNewDirectory,
FileNewWorkspace,
FileNewProject,
FileOpen,
@@ -100,6 +101,7 @@ const Action ACTION_PROJECT_FOLDER_COLLAPSE_ALL = new Action(IDEActions.ProjectF
const Action ACTION_FILE_WORKSPACE_CLOSE = new Action(IDEActions.CloseWorkspace, "MENU_FILE_WORKSPACE_CLOSE"c).disableByDefault();
+const Action ACTION_FILE_NEW_DIRECTORY = new Action(IDEActions.FileNewDirectory, "MENU_FILE_NEW_DIRECTORY"c);
const Action ACTION_FILE_NEW_SOURCE_FILE = new Action(IDEActions.FileNew, "MENU_FILE_NEW_SOURCE_FILE"c, "document-new", KeyCode.KEY_N, KeyFlag.Control);
const Action ACTION_FILE_NEW_PROJECT = new Action(IDEActions.FileNewProject, "MENU_FILE_NEW_PROJECT"c);
const Action ACTION_FILE_NEW_WORKSPACE = new Action(IDEActions.FileNewWorkspace, "MENU_FILE_NEW_WORKSPACE"c);
diff --git a/src/dlangide/ui/frame.d b/src/dlangide/ui/frame.d
index 97fc372..71510b4 100644
--- a/src/dlangide/ui/frame.d
+++ b/src/dlangide/ui/frame.d
@@ -21,6 +21,7 @@ import dlangide.ui.commands;
import dlangide.ui.wspanel;
import dlangide.ui.outputpanel;
import dlangide.ui.newfile;
+import dlangide.ui.newfolder;
import dlangide.ui.newproject;
import dlangide.ui.dsourceedit;
import dlangide.ui.homescreen;
@@ -148,25 +149,25 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
/// called when program execution is stopped
protected void onProgramExecutionStatus(ProgramExecution process, ExecutionStatus status, int exitCode) {
executeInUiThread(delegate() {
- Log.d("onProgramExecutionStatus process: ", process.executableFile, " status: ", status, " exitCode: ", exitCode);
- _execution = null;
- // TODO: update state
- switch(status) {
- case ExecutionStatus.Error:
- _logPanel.logLine("Cannot run program " ~ process.executableFile);
- break;
- case ExecutionStatus.Finished:
- _logPanel.logLine("Program " ~ process.executableFile ~ " finished with exit code " ~ to!string(exitCode));
- break;
- case ExecutionStatus.Killed:
- _logPanel.logLine("Program " ~ process.executableFile ~ " is killed");
- break;
- default:
- _logPanel.logLine("Program " ~ process.executableFile ~ " is finished");
- break;
- }
- _statusLine.setBackgroundOperationStatus(null, null);
- });
+ Log.d("onProgramExecutionStatus process: ", process.executableFile, " status: ", status, " exitCode: ", exitCode);
+ _execution = null;
+ // TODO: update state
+ switch(status) {
+ case ExecutionStatus.Error:
+ _logPanel.logLine("Cannot run program " ~ process.executableFile);
+ break;
+ case ExecutionStatus.Finished:
+ _logPanel.logLine("Program " ~ process.executableFile ~ " finished with exit code " ~ to!string(exitCode));
+ break;
+ case ExecutionStatus.Killed:
+ _logPanel.logLine("Program " ~ process.executableFile ~ " is killed");
+ break;
+ default:
+ _logPanel.logLine("Program " ~ process.executableFile ~ " is finished");
+ break;
+ }
+ _statusLine.setBackgroundOperationStatus(null, null);
+ });
}
protected void handleBuildError(int result, Project project) {
@@ -186,13 +187,13 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
return;
}
buildProject(BuildOperation.Build, project, delegate(int result) {
- if (!result) {
- Log.i("Build completed successfully. Starting debug for project.");
- debugProject(project);
- } else {
- handleBuildError(result, project);
- }
- });
+ if (!result) {
+ Log.i("Build completed successfully. Starting debug for project.");
+ debugProject(project);
+ } else {
+ handleBuildError(result, project);
+ }
+ });
}
void debugFinished(ProgramExecution process, ExecutionStatus status, int exitCode) {
@@ -255,13 +256,13 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
return;
}
buildProject(BuildOperation.Build, project, delegate(int result) {
- if (!result) {
- Log.i("Build completed successfully. Running program...");
- runProject(project);
- } else {
- handleBuildError(result, project);
- }
- });
+ if (!result) {
+ Log.i("Build completed successfully. Running program...");
+ runProject(project);
+ } else {
+ handleBuildError(result, project);
+ }
+ });
}
protected void runProject(Project project) {
@@ -415,6 +416,13 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
_tabs.renameTab(index, name);
}
}
+
+ bool tryOpenSourceFile(string filename) {
+ if (isSupportedSourceTextFileFormat(filename)) {
+ return openSourceFile(filename, null, true);
+ }
+ return false;
+ }
bool openSourceFile(string filename, ProjectSourceFile file = null, bool activate = true) {
if (!file && !filename)
@@ -487,7 +495,7 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
HomeScreen home = new HomeScreen(HOME_SCREEN_ID, this);
_tabs.addTab(home, UIString.fromId("HOME"c), null, true);
_tabs.selectTab(HOME_SCREEN_ID, true);
- auto _settings = new IDESettings(buildNormalizedPath(settingsDir, "settings.json"));
+ auto _settings = new IDESettings(buildNormalizedPath(settingsDir, "settings.json"));
// Auto open last workspace, if no workspace specified in command line and autoOpen flag set to true
const auto recentWorkspaces = settings.recentWorkspaces;
if (!openedWorkspace && recentWorkspaces.length > 0 && _settings.autoOpenLastProject())
@@ -603,35 +611,35 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
// tab content is modified - ask for confirmation
auto header = UIString.fromId("HEADER_CLOSE_FILE"c);
window.showMessageBox(header ~ " " ~ toUTF32(baseName(tabId)), UIString.fromId("MSG_FILE_CONTENT_CHANGED"c),
- [ACTION_SAVE, ACTION_SAVE_ALL, ACTION_DISCARD_CHANGES, ACTION_DISCARD_ALL, ACTION_CANCEL],
- 0, delegate(const Action result) {
- if (result == StandardAction.Save) {
- // save and close
- ed.save();
- askForUnsavedEdits(onConfirm);
- } else if (result == StandardAction.DiscardChanges) {
- // close, don't save
- closeTab(tabId);
- closeAllDocuments();
- onConfirm();
- } else if (result == StandardAction.SaveAll) {
- ed.save();
- for(;;) {
- DSourceEdit editor = hasUnsavedEdits();
- if (!editor)
- break;
- editor.save();
- }
- closeAllDocuments();
- onConfirm();
- } else if (result == StandardAction.DiscardAll) {
- // close, don't save
- closeAllDocuments();
- onConfirm();
- }
- // else ignore
- return true;
- });
+ [ACTION_SAVE, ACTION_SAVE_ALL, ACTION_DISCARD_CHANGES, ACTION_DISCARD_ALL, ACTION_CANCEL],
+ 0, delegate(const Action result) {
+ if (result == StandardAction.Save) {
+ // save and close
+ ed.save();
+ askForUnsavedEdits(onConfirm);
+ } else if (result == StandardAction.DiscardChanges) {
+ // close, don't save
+ closeTab(tabId);
+ closeAllDocuments();
+ onConfirm();
+ } else if (result == StandardAction.SaveAll) {
+ ed.save();
+ for(;;) {
+ DSourceEdit editor = hasUnsavedEdits();
+ if (!editor)
+ break;
+ editor.save();
+ }
+ closeAllDocuments();
+ onConfirm();
+ } else if (result == StandardAction.DiscardAll) {
+ // close, don't save
+ closeAllDocuments();
+ onConfirm();
+ }
+ // else ignore
+ return true;
+ });
}
protected void onTabClose(string tabId) {
@@ -642,19 +650,19 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
if (d && d.content.modified) {
// tab content is modified - ask for confirmation
window.showMessageBox(UIString.fromId("HEADER_CLOSE_TAB"c), UIString.fromId("MSG_TAB_CONTENT_CHANGED"c) ~ ": " ~ toUTF32(baseName(tabId)),
- [ACTION_SAVE, ACTION_DISCARD_CHANGES, ACTION_CANCEL],
- 0, delegate(const Action result) {
- if (result == StandardAction.Save) {
- // save and close
- d.save();
- closeTab(tabId);
- } else if (result == StandardAction.DiscardChanges) {
- // close, don't save
- closeTab(tabId);
- }
- // else ignore
- return true;
- });
+ [ACTION_SAVE, ACTION_DISCARD_CHANGES, ACTION_CANCEL],
+ 0, delegate(const Action result) {
+ if (result == StandardAction.Save) {
+ // save and close
+ d.save();
+ closeTab(tabId);
+ } else if (result == StandardAction.DiscardChanges) {
+ // close, don't save
+ closeTab(tabId);
+ }
+ // else ignore
+ return true;
+ });
} else {
closeTab(tabId);
}
@@ -737,11 +745,11 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
fileNewItem.add(ACTION_FILE_NEW_SOURCE_FILE, ACTION_FILE_NEW_WORKSPACE, ACTION_FILE_NEW_PROJECT);
fileItem.add(fileNewItem);
fileItem.add(ACTION_FILE_OPEN_WORKSPACE, ACTION_FILE_OPEN,
- ACTION_FILE_SAVE, ACTION_FILE_SAVE_AS, ACTION_FILE_SAVE_ALL, ACTION_FILE_WORKSPACE_CLOSE, ACTION_FILE_EXIT);
+ ACTION_FILE_SAVE, ACTION_FILE_SAVE_AS, ACTION_FILE_SAVE_ALL, ACTION_FILE_WORKSPACE_CLOSE, ACTION_FILE_EXIT);
MenuItem editItem = new MenuItem(new Action(2, "MENU_EDIT"));
editItem.add(ACTION_EDIT_COPY, ACTION_EDIT_PASTE,
- ACTION_EDIT_CUT, ACTION_EDIT_UNDO, ACTION_EDIT_REDO);
+ ACTION_EDIT_CUT, ACTION_EDIT_UNDO, ACTION_EDIT_REDO);
editItem.addSeparator();
editItem.add(ACTION_EDITOR_FIND, ACTION_EDITOR_FIND_NEXT, ACTION_EDITOR_FIND_PREV, ACTION_EDITOR_REPLACE, ACTION_FIND_TEXT, ACTION_EDITOR_TOGGLE_BOOKMARK);
editItem.addSeparator();
@@ -792,20 +800,20 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
buildItem.addSeparator();
buildItem.add(ACTION_WORKSPACE_BUILD, ACTION_WORKSPACE_REBUILD, ACTION_WORKSPACE_CLEAN,
- ACTION_PROJECT_BUILD, ACTION_PROJECT_REBUILD, ACTION_PROJECT_CLEAN,
- ACTION_RUN_WITH_RDMD);
+ ACTION_PROJECT_BUILD, ACTION_PROJECT_REBUILD, ACTION_PROJECT_CLEAN,
+ ACTION_RUN_WITH_RDMD);
MenuItem debugItem = new MenuItem(new Action(23, "MENU_DEBUG"));
debugItem.add(ACTION_DEBUG_START, ACTION_DEBUG_START_NO_DEBUG,
- ACTION_DEBUG_CONTINUE, ACTION_DEBUG_STOP, ACTION_DEBUG_PAUSE,
- ACTION_DEBUG_RESTART,
- ACTION_DEBUG_STEP_INTO,
- ACTION_DEBUG_STEP_OVER,
- ACTION_DEBUG_STEP_OUT,
- ACTION_DEBUG_TOGGLE_BREAKPOINT, ACTION_DEBUG_ENABLE_BREAKPOINT, ACTION_DEBUG_DISABLE_BREAKPOINT
- );
-
+ ACTION_DEBUG_CONTINUE, ACTION_DEBUG_STOP, ACTION_DEBUG_PAUSE,
+ ACTION_DEBUG_RESTART,
+ ACTION_DEBUG_STEP_INTO,
+ ACTION_DEBUG_STEP_OVER,
+ ACTION_DEBUG_STEP_OUT,
+ ACTION_DEBUG_TOGGLE_BREAKPOINT, ACTION_DEBUG_ENABLE_BREAKPOINT, ACTION_DEBUG_DISABLE_BREAKPOINT
+ );
+
MenuItem toolsItem = new MenuItem(new Action(33, "MENU_TOOLS"c));
toolsItem.add(ACTION_TOOLS_OPEN_DMD_TRACE_LOG);
@@ -873,14 +881,14 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
tb = res.getOrAddToolbar("Edit");
tb.addButtons(ACTION_EDIT_COPY, ACTION_EDIT_PASTE, ACTION_EDIT_CUT, ACTION_SEPARATOR,
- ACTION_EDIT_UNDO, ACTION_EDIT_REDO, ACTION_EDIT_INDENT, ACTION_EDIT_UNINDENT);
+ ACTION_EDIT_UNDO, ACTION_EDIT_REDO, ACTION_EDIT_INDENT, ACTION_EDIT_UNINDENT);
tb = res.getOrAddToolbar("Debug");
tb.addButtons(ACTION_DEBUG_STOP, ACTION_DEBUG_CONTINUE, ACTION_DEBUG_PAUSE,
- ACTION_DEBUG_RESTART,
- ACTION_DEBUG_STEP_INTO,
- ACTION_DEBUG_STEP_OVER,
- ACTION_DEBUG_STEP_OUT,
- );
+ ACTION_DEBUG_RESTART,
+ ACTION_DEBUG_STEP_INTO,
+ ACTION_DEBUG_STEP_OVER,
+ ACTION_DEBUG_STEP_OUT,
+ );
return res;
}
@@ -1031,7 +1039,7 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
window.showMessageBox(UIString.fromId("ERROR"c), UIString.fromId("ERROR_FAILED_TO_PARSE_FILE"c));
}
}
- );
+ );
setBackgroundOperation(op);
}
@@ -1084,9 +1092,9 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
//}
dstring msg = "DLangIDE\n(C) Vadim Lopatin, 2014-2017\nhttp://github.com/buggins/dlangide\n"
~ "IDE for D programming language written in D\nUses DlangUI library "
- ~ DLANGUI_VERSION ~ " for GUI"d;
+ ~ DLANGUI_VERSION ~ " for GUI"d;
window.showMessageBox(UIString.fromId("ABOUT"c) ~ " " ~ DLANGIDE_VERSION,
- UIString.fromRaw(msg));
+ UIString.fromRaw(msg));
return true;
case IDEActions.BuildSetConfiguration:
// set build configuration
@@ -1137,7 +1145,7 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
else
ed.editorTool = new DefaultEditorTool(this);
//openSourceFile(filename);
- refreshWorkspace();
+ updateTreeGraph();
ProjectSourceFile file = _wsPanel.findSourceFileItem(filename, false);
if (file) {
ed.projectSourceFile = file;
@@ -1209,7 +1217,7 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
buildProject(BuildOperation.Upgrade, cast(Project)a.objectParam);
return true;
case IDEActions.RefreshProject:
- refreshWorkspace();
+ updateTreeGraph();
return true;
case IDEActions.RevealProjectInExplorer:
revealProjectInExplorer(cast(Project)a.objectParam);
@@ -1219,8 +1227,8 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
return true;
case IDEActions.WindowCloseAllDocuments:
askForUnsavedEdits(delegate() {
- closeAllDocuments();
- });
+ closeAllDocuments();
+ });
return true;
case IDEActions.WindowShowHomeScreen:
showHomeScreen();
@@ -1285,31 +1293,31 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
Log.d("Go to line");
// Ask user for line
window.showInputBox(UIString.fromId("GO_TO_LINE"c), UIString.fromId("GO_TO_LINE"c), ""d, delegate(dstring s) {
- try {
- auto num = to!uint(s);
- // Check line existence
- if (num < 1 || num > currentEditor.content.length) {
+ try {
+ auto num = to!uint(s);
+ // Check line existence
+ if (num < 1 || num > currentEditor.content.length) {
+ currentEditor.setFocus();
+ window.showMessageBox(UIString.fromId("ERROR"c), UIString.fromId("ERROR_NO_SUCH_LINE"c));
+ return;
+ }
+ // Go to line
+ currentEditor.setCaretPos(num - 1, 0);
currentEditor.setFocus();
- window.showMessageBox(UIString.fromId("ERROR"c), UIString.fromId("ERROR_NO_SUCH_LINE"c));
- return;
}
- // Go to line
- currentEditor.setCaretPos(num - 1, 0);
- currentEditor.setFocus();
- }
- catch (ConvException e) {
- currentEditor.setFocus();
- window.showMessageBox(UIString.fromId("ERROR"c), UIString.fromId("ERROR_INVALID_NUMBER"c));
- }
- });
+ catch (ConvException e) {
+ currentEditor.setFocus();
+ window.showMessageBox(UIString.fromId("ERROR"c), UIString.fromId("ERROR_INVALID_NUMBER"c));
+ }
+ });
}
return true;
case IDEActions.GetDocComments:
Log.d("Trying to get doc comments.");
currentEditor.editorTool.getDocComments(currentEditor, currentEditor.caretPos, delegate(string[] results) {
- if (results.length)
- currentEditor.showDocCommentsPopup(results);
- });
+ if (results.length)
+ currentEditor.showDocCommentsPopup(results);
+ });
return true;
case IDEActions.GetParenCompletion:
Log.d("Trying to get paren completion.");
@@ -1318,9 +1326,9 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
case IDEActions.GetCompletionSuggestions:
Log.d("Getting auto completion suggestions.");
currentEditor.editorTool.getCompletions(currentEditor, currentEditor.caretPos, delegate(dstring[] results, string[] icons, CompletionTypes type) {
- if (currentEditor)
- currentEditor.showCompletionPopup(results, icons, type);
- });
+ if (currentEditor)
+ currentEditor.showCompletionPopup(results, icons, type);
+ });
return true;
case IDEActions.EditPreferences:
showPreferences();
@@ -1365,7 +1373,10 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
createNewProject(false);
return true;
case IDEActions.FileNew:
- addProjectItem(cast(Object)a.objectParam);
+ addFile(cast(Object)a.objectParam);
+ return true;
+ case IDEActions.FileNewDirectory:
+ addDirectory(cast(Object)a.objectParam);
return true;
case IDEActions.ProjectFolderRemoveItem:
removeProjectItem(a.objectParam);
@@ -1403,9 +1414,9 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
currentWorkspace.save();
}
askForUnsavedEdits(delegate() {
- setWorkspace(null);
- showHomeScreen();
- });
+ setWorkspace(null);
+ showHomeScreen();
+ });
}
void onBreakpointListChanged(ProjectSourceFile sourcefile, Breakpoint[] breakpoints) {
@@ -1433,7 +1444,7 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
if (cast(Workspace)obj) {
Workspace ws = cast(Workspace)obj;
ws.refresh();
- refreshWorkspace();
+ updateTreeGraph();
} else if (cast(Project)obj) {
project = cast(Project)obj;
} else if (cast(ProjectFolder)obj) {
@@ -1452,7 +1463,7 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
}
if (project) {
project.refresh();
- refreshWorkspace();
+ updateTreeGraph();
}
}
@@ -1466,29 +1477,74 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
if (!project)
return;
window.showMessageBox(UIString.fromId("HEADER_REMOVE_FILE"c),
- UIString.fromId("QUESTION_REMOVE_FILE"c) ~ " " ~ srcfile.name ~ "?",
- [ACTION_YES, ACTION_NO],
- 1, delegate(const Action result) {
- if (result == StandardAction.Yes) {
- // save and close
- import std.file : remove;
- closeTab(srcfile.filename);
- try {
- remove(srcfile.filename);
- } catch (Exception e) {
- Log.e("Cannot remove file");
- }
- project.refresh();
- refreshWorkspace();
+ UIString.fromId("QUESTION_REMOVE_FILE"c) ~ " " ~ srcfile.name ~ "?",
+ [ACTION_YES, ACTION_NO],
+ 1, delegate(const Action result) {
+ if (result == StandardAction.Yes) {
+ // save and close
+ import std.file : remove;
+ closeTab(srcfile.filename);
+ try {
+ remove(srcfile.filename);
+ } catch (Exception e) {
+ Log.e("Cannot remove file");
}
- // else ignore
- return true;
- });
+ project.refresh();
+ updateTreeGraph();
+ }
+ // else ignore
+ return true;
+ });
}
+ private void addFile(Object obj) {
+ Dialog createNewFileDialog(Project project, ProjectFolder folder) {
+ NewFileDlg dialog = new NewFileDlg(this, project, folder);
+ dialog.dialogResult = delegate(Dialog dlg, const Action result) {
+ if (result.id == ACTION_FILE_NEW_SOURCE_FILE.id) {
+ FileCreationResult res = cast(FileCreationResult)result.objectParam;
+ if (res) {
+ //res.project.reload();
+ res.project.refresh();
+ updateTreeGraph();
+ tryOpenSourceFile(res.filename);
+ }
+ }
+ };
+ return dialog;
+ }
+ addProjectItem(&createNewFileDialog, obj);
+ }
+
+ private void addDirectory(Object obj) {
+ Dialog createNewDirectoryDialog(Project project, ProjectFolder folder) {
+ NewFolderDialog dialog = new NewFolderDialog(this, project, folder);
+ dialog.dialogResult = delegate(Dialog dlg, const Action result) {
+ if(result.id == ACTION_FILE_NEW_DIRECTORY.id) {
+ FileCreationResult res = cast(FileCreationResult)result.objectParam;
+ if (res) {
+ ProjectFolder newFolder = new ProjectFolder(res.filename);
+ if(folder) {
+ folder.addChild(newFolder);
+ folder.sortItems;
+ newFolder.refresh();
+ if(newFolder.childCount > 0){
+ tryOpenSourceFile(newFolder.child(0).filename);
+ }
+ }
+ updateTreeGraph();
+ _wsPanel.selectItem(newFolder);
+ }
+ }
+ };
+ return dialog;
+ }
+ addProjectItem(&createNewDirectoryDialog, obj);
+ }
+
/// add new file to project
- void addProjectItem(Object obj) {
+ private void addProjectItem(Dialog delegate(Project, ProjectFolder) dialogFactory, Object obj) {
if (currentWorkspace is null)
return;
if (obj is null && _wsPanel !is null && !currentEditorSourceFile) {
@@ -1500,7 +1556,12 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
ProjectFolder folder;
if (cast(Project)obj) {
project = cast(Project)obj;
- folder = project.firstSourceFolder;
+ folder = project.items;
+ import std.stdio;
+ writeln("Root filename:", folder.filename);
+ for(int i = 0; i < folder.childCount; i++) {
+ writeln("Child [", i, "]: ", folder.child(i).filename);
+ }
} else if (cast(ProjectFolder)obj) {
folder = cast(ProjectFolder)obj;
project = folder.project;
@@ -1515,21 +1576,8 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
project = srcfile.project;
}
}
- if (project && folder && project.workspace is currentWorkspace) {
- NewFileDlg dlg = new NewFileDlg(this, project, folder);
- dlg.dialogResult = delegate(Dialog dlg, const Action result) {
- if (result.id == ACTION_FILE_NEW_SOURCE_FILE.id) {
- FileCreationResult res = cast(FileCreationResult)result.objectParam;
- if (res) {
- //res.project.reload();
- res.project.refresh();
- refreshWorkspace();
- if (isSupportedSourceTextFileFormat(res.filename)) {
- openSourceFile(res.filename, null, true);
- }
- }
- }
- };
+ if (project && project.workspace is currentWorkspace) {
+ Dialog dlg = dialogFactory(project, folder);
dlg.show();
}
}
@@ -1550,12 +1598,12 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
if (currentWorkspace is null || res.workspace !is currentWorkspace) {
// open new workspace
setWorkspace(res.workspace);
- refreshWorkspace();
+ updateTreeGraph();
hideHomeScreen();
} else {
// project added to current workspace
loadProject(res.project);
- refreshWorkspace();
+ updateTreeGraph();
hideHomeScreen();
}
}
@@ -1676,21 +1724,21 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
WorkspaceFile[] files = currentWorkspace.files();
for (int i; i < files.length; i++)
with (files[i])
+ {
+ // Opening file
+ if (openSourceFile(filename))
{
- // Opening file
- if (openSourceFile(filename))
- {
- auto index = _tabs.tabIndex(filename);
- if (index < 0)
- continue;
- // file is opened in tab
- auto source = cast(DSourceEdit)_tabs.tabBody(filename);
- if (!source)
- continue;
- // Caret position
- source.setCaretPos(column, row, true, true);
- }
+ auto index = _tabs.tabIndex(filename);
+ if (index < 0)
+ continue;
+ // file is opened in tab
+ auto source = cast(DSourceEdit)_tabs.tabBody(filename);
+ if (!source)
+ continue;
+ // Caret position
+ source.setCaretPos(column, row, true, true);
}
+ }
}
void saveListOfOpenedFiles() {
@@ -1717,12 +1765,12 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
Workspace ws = new Workspace(this);
if (ws.load(filename)) {
askForUnsavedEdits(delegate() {
- setWorkspace(ws);
- hideHomeScreen();
- // Write workspace to recent workspaces list
- _settings.updateRecentWorkspace(filename);
- restoreListOfOpenedFiles();
- });
+ setWorkspace(ws);
+ hideHomeScreen();
+ // Write workspace to recent workspaces list
+ _settings.updateRecentWorkspace(filename);
+ restoreListOfOpenedFiles();
+ });
} else {
window.showMessageBox(UIString.fromId("ERROR_OPEN_WORKSPACE"c).value, UIString.fromId("ERROR_OPENING_WORKSPACE"c).value);
return;
@@ -1747,21 +1795,21 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
}
window.showMessageBox(UIString.fromId("MSG_OPEN_PROJECT"c), UIString.fromId("QUESTION_NEW_WORKSPACE"c),
- [ACTION_ADD_TO_CURRENT_WORKSPACE, ACTION_CREATE_NEW_WORKSPACE, ACTION_CANCEL], 0, delegate(const Action result) {
- if (result.id == IDEActions.CreateNewWorkspace) {
- // new ws
- createNewWorkspaceForExistingProject(project);
- hideHomeScreen();
- } else if (result.id == IDEActions.AddToCurrentWorkspace) {
- // add to current
- currentWorkspace.addProject(project);
- loadProject(project);
- currentWorkspace.save();
- refreshWorkspace();
- hideHomeScreen();
- }
- return true;
- });
+ [ACTION_ADD_TO_CURRENT_WORKSPACE, ACTION_CREATE_NEW_WORKSPACE, ACTION_CANCEL], 0, delegate(const Action result) {
+ if (result.id == IDEActions.CreateNewWorkspace) {
+ // new ws
+ createNewWorkspaceForExistingProject(project);
+ hideHomeScreen();
+ } else if (result.id == IDEActions.AddToCurrentWorkspace) {
+ // add to current
+ currentWorkspace.addProject(project);
+ loadProject(project);
+ currentWorkspace.save();
+ updateTreeGraph();
+ hideHomeScreen();
+ }
+ return true;
+ });
} else {
// new workspace file
createNewWorkspaceForExistingProject(project);
@@ -1772,7 +1820,7 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
}
}
- void refreshWorkspace() {
+ void updateTreeGraph() {
_logPanel.logLine("Refreshing workspace");
_wsPanel.reloadItems();
closeRemovedDocuments();
@@ -1838,7 +1886,7 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
void refreshProject(Project project) {
if (currentWorkspace && project.loadSelections()) {
currentWorkspace.cleanupUnusedDependencies();
- refreshWorkspace();
+ updateTreeGraph();
}
}
@@ -1904,10 +1952,10 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
}
Builder op = new Builder(this, project, _logPanel, project.projectConfiguration, currentWorkspace.buildConfiguration, buildOp,
- dubExecutable, dubAdditionalParams,
- toolchain,
- arch,
- listener);
+ dubExecutable, dubAdditionalParams,
+ toolchain,
+ arch,
+ listener);
setBackgroundOperation(op);
}
@@ -1966,12 +2014,12 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
/// return false to prevent closing
bool onCanClose() {
askForUnsavedEdits(delegate() {
- if (currentWorkspace) {
- // Remember opened files
- saveListOfOpenedFiles();
- }
- window.close();
- });
+ if (currentWorkspace) {
+ // Remember opened files
+ saveListOfOpenedFiles();
+ }
+ window.close();
+ });
return false;
}
/// called when main window is closing
diff --git a/src/dlangide/ui/newfile.d b/src/dlangide/ui/newfile.d
index 9407008..35db948 100644
--- a/src/dlangide/ui/newfile.d
+++ b/src/dlangide/ui/newfile.d
@@ -40,7 +40,7 @@ class NewFileDlg : Dialog {
string[] _sourcePaths;
this(IDEFrame parent, Project currentProject, ProjectFolder folder) {
super(UIString.fromId("OPTION_NEW_SOURCE_FILE"c), parent.window,
- DialogFlag.Modal | DialogFlag.Resizable | DialogFlag.Popup, 500, 400);
+ DialogFlag.Modal | DialogFlag.Resizable | DialogFlag.Popup, 500, 400);
_ide = parent;
_icon = "dlangui-logo1";
this._project = currentProject;
@@ -60,34 +60,34 @@ class NewFileDlg : Dialog {
try {
content = parseML(q{
VerticalLayout {
- id: vlayout
+ id: vlayout
padding: Rect { 5, 5, 5, 5 }
- layoutWidth: fill; layoutHeight: fill
+ layoutWidth: fill; layoutHeight: fill
HorizontalLayout {
- layoutWidth: fill; layoutHeight: fill
+ layoutWidth: fill; layoutHeight: fill
VerticalLayout {
- margins: 5
- layoutWidth: 50%; layoutHeight: fill
+ margins: 5
+ layoutWidth: 50%; layoutHeight: fill
TextWidget { text: OPTION_PROJECT_TEMPLATE }
StringListWidget {
- id: projectTemplateList
- layoutWidth: wrap; layoutHeight: fill
+ id: projectTemplateList
+ layoutWidth: wrap; layoutHeight: fill
}
}
VerticalLayout {
- margins: 5
- layoutWidth: 50%; layoutHeight: fill
+ margins: 5
+ layoutWidth: 50%; layoutHeight: fill
TextWidget { text: OPTION_TEMPLATE_DESCR }
EditBox {
- id: templateDescription; readOnly: true
- layoutWidth: fill; layoutHeight: fill
+ id: templateDescription; readOnly: true
+ layoutWidth: fill; layoutHeight: fill
}
}
}
TableLayout {
- margins: 5
- colCount: 2
- layoutWidth: fill; layoutHeight: wrap
+ margins: 5
+ colCount: 2
+ layoutWidth: fill; layoutHeight: wrap
TextWidget { text: NAME }
EditLine { id: edName; text: "newfile"; layoutWidth: fill }
TextWidget { text: LOCATION }
@@ -105,7 +105,7 @@ class NewFileDlg : Dialog {
throw e;
}
-
+
_projectTemplateList = content.childById!StringListWidget("projectTemplateList");
_templateDescription = content.childById!EditBox("templateDescription");
_edFileName = content.childById!EditLine("edName");
@@ -198,29 +198,6 @@ class NewFileDlg : Dialog {
ProjectTemplate _currentTemplate;
ProjectTemplate[] _templates;
- static bool isSubdirOf(string path, string basePath) {
- if (path.equal(basePath))
- return true;
- if (path.length > basePath.length + 1 && path.startsWith(basePath)) {
- char ch = path[basePath.length];
- return ch == '/' || ch == '\\';
- }
- return false;
- }
-
- bool findSource(string path, ref string sourceFolderPath, ref string relativePath) {
- foreach(dir; _sourcePaths) {
- if (isSubdirOf(path, dir)) {
- sourceFolderPath = dir;
- relativePath = path[sourceFolderPath.length .. $];
- if (relativePath.length > 0 && (relativePath[0] == '\\' || relativePath[0] == '/'))
- relativePath = relativePath[1 .. $];
- return true;
- }
- }
- return false;
- }
-
bool setError(dstring msg) {
_statusText.text = msg;
return msg.empty;
@@ -242,25 +219,12 @@ class NewFileDlg : Dialog {
if (_currentTemplate.kind == FileKind.MODULE || _currentTemplate.kind == FileKind.PACKAGE) {
string sourcePath, relativePath;
- if (!findSource(_location, sourcePath, relativePath))
+ if (!findSource(_sourcePaths, _location, sourcePath, relativePath))
return setError("Location is outside of source path");
if (!isValidModuleName(filename))
return setError("Invalid file name");
- _moduleName = filename;
- char[] buf;
- foreach(c; relativePath) {
- char ch = c;
- if (ch == '/' || ch == '\\')
- ch = '.';
- else if (ch == '.')
- ch = '_';
- if (ch == '.' && (buf.length == 0 || buf[$-1] == '.'))
- continue; // skip duplicate .
- buf ~= ch;
- }
- if (buf.length && buf[$-1] == '.')
- buf.length--;
- _packageName = buf.dup;
+ _moduleName = filename;
+ _packageName = getPackageName(sourcePath, relativePath);
string m;
if (_currentTemplate.kind == FileKind.MODULE) {
m = !_packageName.empty ? _packageName ~ '.' ~ _moduleName : _moduleName;
@@ -284,20 +248,10 @@ class NewFileDlg : Dialog {
private FileCreationResult _result;
bool createItem() {
- try {
- if (_currentTemplate.kind == FileKind.MODULE) {
- string txt = "module " ~ _packageName ~ ";\n\n" ~ _currentTemplate.srccode;
- write(_fullPathName, txt);
- } else if (_currentTemplate.kind == FileKind.PACKAGE) {
- string txt = "module " ~ _packageName ~ ";\n\n" ~ _currentTemplate.srccode;
- write(_fullPathName, txt);
- } else {
- write(_fullPathName, _currentTemplate.srccode);
- }
- } catch (Exception e) {
- Log.e("Cannot create file", e);
+ if(!createFile(_fullPathName, _currentTemplate.kind, _packageName, _currentTemplate.srccode)) {
return setError("Cannot create file");
}
+
_result = new FileCreationResult(_project, _fullPathName);
return true;
}
@@ -338,22 +292,22 @@ class NewFileDlg : Dialog {
void initTemplates() {
_templates ~= new ProjectTemplate("Empty module"d, "Empty D module file."d, ".d",
- "\n", FileKind.MODULE);
+ "\n", FileKind.MODULE);
_templates ~= new ProjectTemplate("Package"d, "D package."d, ".d",
- "\n", FileKind.PACKAGE);
+ "\n", FileKind.PACKAGE);
_templates ~= new ProjectTemplate("Text file"d, "Empty text file."d, ".txt",
- "\n", FileKind.TEXT);
+ "\n", FileKind.TEXT);
_templates ~= new ProjectTemplate("JSON file"d, "Empty json file."d, ".json",
- "{\n}\n", FileKind.TEXT);
+ "{\n}\n", FileKind.TEXT);
_templates ~= new ProjectTemplate("Vibe-D Diet Template file"d, "Empty Vibe-D Diet Template."d, ".dt",
- q{
-doctype html
-html
- head
- title Hello, World
- body
- h1 Hello World
-}, FileKind.TEXT);
+ q{
+ doctype html
+ html
+ head
+ title Hello, World
+ body
+ h1 Hello World
+ }, FileKind.TEXT);
}
}
@@ -377,3 +331,67 @@ class ProjectTemplate {
this.kind = kind;
}
}
+
+bool createFile(string fullPathName, FileKind fileKind, string packageName, string sourceCode) {
+ try {
+ if (fileKind == FileKind.MODULE) {
+ string txt = "module " ~ packageName ~ ";\n\n" ~ sourceCode;
+ write(fullPathName, txt);
+ } else if (fileKind == FileKind.PACKAGE) {
+ string txt = "module " ~ packageName ~ ";\n\n" ~ sourceCode;
+ write(fullPathName, txt);
+ } else {
+ write(fullPathName, sourceCode);
+ }
+ return true;
+ }
+ catch(Exception e) {
+ Log.e("Cannot create file", e);
+ return false;
+ }
+}
+
+string getPackageName(string path, string[] sourcePaths){
+ string sourcePath, relativePath;
+ if(!findSource(sourcePaths, path, sourcePath, relativePath)) return "";
+ return getPackageName(sourcePath, relativePath);
+}
+
+string getPackageName(string sourcePath, string relativePath){
+
+ char[] buf;
+ foreach(c; relativePath) {
+ char ch = c;
+ if (ch == '/' || ch == '\\')
+ ch = '.';
+ else if (ch == '.')
+ ch = '_';
+ if (ch == '.' && (buf.length == 0 || buf[$-1] == '.'))
+ continue; // skip duplicate .
+ buf ~= ch;
+ }
+ if (buf.length && buf[$-1] == '.')
+ buf.length--;
+ return buf.dup;
+}
+private bool findSource(string[] sourcePaths, string path, ref string sourceFolderPath, ref string relativePath) {
+ foreach(dir; sourcePaths) {
+ if (isSubdirOf(path, dir)) {
+ sourceFolderPath = dir;
+ relativePath = path[sourceFolderPath.length .. $];
+ if (relativePath.length > 0 && (relativePath[0] == '\\' || relativePath[0] == '/'))
+ relativePath = relativePath[1 .. $];
+ return true;
+ }
+ }
+ return false;
+}
+private bool isSubdirOf(string path, string basePath) {
+ if (path.equal(basePath))
+ return true;
+ if (path.length > basePath.length + 1 && path.startsWith(basePath)) {
+ char ch = path[basePath.length];
+ return ch == '/' || ch == '\\';
+ }
+ return false;
+}
\ No newline at end of file
diff --git a/src/dlangide/ui/newfolder.d b/src/dlangide/ui/newfolder.d
new file mode 100644
index 0000000..ececa10
--- /dev/null
+++ b/src/dlangide/ui/newfolder.d
@@ -0,0 +1,186 @@
+module dlangide.ui.newfolder;
+
+import std.array : empty;
+import std.file : mkdir, exists;
+import std.path : buildPath, buildNormalizedPath;
+import std.utf : toUTF32;
+
+import dlangui.core.logger;
+import dlangui.core.stdaction;
+import dlangui.dialogs.dialog;
+import dlangui.dml.parser;
+import dlangui.widgets.controls;
+import dlangui.widgets.editors;
+import dlangui.widgets.widget;
+
+import dlangide.ui.commands;
+import dlangide.ui.frame;
+import dlangide.ui.newfile;
+import dlangide.workspace.project;
+
+class NewFolderDialog : Dialog {
+ private {
+ IDEFrame _ide;
+ Project _project;
+ ProjectFolder _folder;
+ string _location;
+ }
+
+
+ this(IDEFrame parent, Project currentProject, ProjectFolder folder) {
+ super(UIString.fromId("OPTION_NEW_SOURCE_FILE"c), parent.window,
+ DialogFlag.Modal | DialogFlag.Popup, 800, 0);
+ layoutWidth = FILL_PARENT;
+ _ide = parent;
+ _icon = "dlangui-logo1";
+ this._project = currentProject;
+ this._folder = folder;
+ if (folder){
+ _location = folder.filename;
+ }
+ else {
+ _location = currentProject.dir;
+ }
+ }
+
+ override void initialize() {
+ super.initialize();
+ Widget content;
+ try {
+ content = parseML(q{
+ VerticalLayout {
+ id: vlayout
+ padding: Rect { 5, 5, 5, 5 }
+ layoutWidth: fill; layoutHeight: wrap
+ TableLayout {
+ margins: 5
+ colCount: 2
+ layoutWidth: fill; layoutHeight: wrap
+ TextWidget { text: NAME }
+ EditLine { id: fileName; text: "newfolder"; layoutWidth: fill }
+ CheckBox { id: makePackage }
+ TextWidget { text: OPTION_MAKE_PACKAGE}
+ }
+ TextWidget { id: statusText; text: ""; layoutWidth: fill; textColor: #FF0000 }
+ }
+ });
+ } catch (Exception e) {
+ Log.e("Exceptin while parsing DML", e);
+ throw e;
+ }
+ _edFileName = content.childById!EditLine("fileName");
+ _edMakePackage = content.childById!CheckBox("makePackage");
+ _statusText = content.childById!TextWidget("statusText");
+
+ _edFileName.enterKey.connect(&onEnterKey);
+
+ _edFileName.setDefaultPopupMenu();
+
+ _edFileName.contentChange = delegate (EditableContent source) {
+ updateValues(source.text);
+ validate();
+ };
+
+ addChild(content);
+ addChild(createButtonsPanel([ACTION_FILE_NEW_DIRECTORY, ACTION_CANCEL], 0, 0));
+
+ updateValues(_edFileName.text);
+ }
+
+ override void onShow() {
+ super.onShow();
+ _edFileName.selectAll();
+ _edFileName.setFocus();
+ }
+
+ protected bool onEnterKey(EditWidgetBase editor) {
+ if (!validate())
+ return false;
+ close(_buttonActions[0]);
+ return true;
+ }
+
+ private bool validate() {
+ if (!isValidModuleName(_fileName))
+ return setError("Invalid folder name");
+ return setError(null);
+ }
+
+ private void updateValues(dstring fileName) {
+ _fileName = toUTF8(fileName);
+ }
+
+ private bool setError(dstring msg) {
+ _statusText.text = msg;
+ return msg.empty;
+ }
+
+ private {
+ EditLine _edFileName;
+ CheckBox _edMakePackage;
+ TextWidget _statusText;
+
+ string _fileName = "newfile";
+ FileCreationResult _result;
+ bool shouldMakePackage() @property {
+ return _edMakePackage.checked;
+ }
+ string fullPathName() @property {
+ return buildNormalizedPath(_location, _fileName);
+ }
+ }
+
+ private bool createItem() {
+ string fullPathName = this.fullPathName;
+ if(exists(fullPathName))
+ return setError("Folder already exists");
+
+ if(!makeDirectory(fullPathName)) return false;
+ if(shouldMakePackage) {
+ if(!makePackageFile(fullPathName)) {
+ return false;
+ }
+ }
+ _result = new FileCreationResult(_project, fullPathName);
+ return true;
+ }
+
+ private bool makeDirectory(string fullPathName) {
+ try {
+ mkdir(fullPathName);
+ return true;
+ } catch (Exception e) {
+ Log.e("Cannot create folder", e);
+ return setError("Cannot create folder");
+ }
+ }
+
+ private bool makePackageFile(string fullPathName) {
+ string packageName = getPackageName(fullPathName, _project.sourcePaths);
+ if(packageName.empty) {
+ Log.e("Could not determing package name for ", fullPathName);
+ return false;
+ }
+ if(!createFile(fullPathName.buildPath("package.d"), FileKind.PACKAGE, packageName, null)) {
+ Log.e("Could not create package file in folder ", fullPathName);
+ return false;
+ }
+ return true;
+ }
+
+ override void close(const Action action) {
+ Action newaction = action.clone();
+ if (action.id == IDEActions.FileNewDirectory) {
+ if (!validate()) {
+ window.showMessageBox(UIString.fromId("ERROR"c), UIString.fromId("ERROR_INVALID_PARAMETERS"c));
+ return;
+ }
+ if (!createItem()) {
+ window.showMessageBox(UIString.fromId("ERROR"c), UIString.fromId("ERROR_INVALID_PARAMETERS"c));
+ return;
+ }
+ newaction.objectParam = _result;
+ }
+ super.close(newaction);
+ }
+}
\ No newline at end of file
diff --git a/src/dlangide/ui/wspanel.d b/src/dlangide/ui/wspanel.d
index 56100e8..bbfcecb 100644
--- a/src/dlangide/ui/wspanel.d
+++ b/src/dlangide/ui/wspanel.d
@@ -102,7 +102,7 @@ class WorkspacePanel : DockWindow {
_projectPopupMenu = new MenuItem();
_projectPopupMenu.add(ACTION_PROJECT_SET_STARTUP,
ACTION_PROJECT_FOLDER_REFRESH,
- ACTION_FILE_NEW_SOURCE_FILE,
+ //ACTION_FILE_NEW_DIRECTORY,
//ACTION_PROJECT_FOLDER_OPEN_ITEM,
ACTION_PROJECT_BUILD,
ACTION_PROJECT_REBUILD,
@@ -116,14 +116,17 @@ class WorkspacePanel : DockWindow {
);
_folderPopupMenu = new MenuItem();
- _folderPopupMenu.add(ACTION_FILE_NEW_SOURCE_FILE, ACTION_PROJECT_FOLDER_REFRESH, ACTION_PROJECT_FOLDER_OPEN_ITEM,
+ _folderPopupMenu.add(ACTION_FILE_NEW_SOURCE_FILE,
+ ACTION_FILE_NEW_DIRECTORY,
+ ACTION_PROJECT_FOLDER_REFRESH, ACTION_PROJECT_FOLDER_OPEN_ITEM,
ACTION_PROJECT_FOLDER_EXPAND_ALL, ACTION_PROJECT_FOLDER_COLLAPSE_ALL
//ACTION_PROJECT_FOLDER_REMOVE_ITEM,
//ACTION_PROJECT_FOLDER_RENAME_ITEM
);
_filePopupMenu = new MenuItem();
- _filePopupMenu.add(ACTION_FILE_NEW_SOURCE_FILE, ACTION_PROJECT_FOLDER_REFRESH,
+ _filePopupMenu.add(ACTION_FILE_NEW_SOURCE_FILE,
+ ACTION_PROJECT_FOLDER_REFRESH,
ACTION_PROJECT_FOLDER_OPEN_ITEM,
ACTION_PROJECT_FOLDER_REMOVE_ITEM,
//ACTION_PROJECT_FOLDER_RENAME_ITEM
diff --git a/src/dlangide/workspace/project.d b/src/dlangide/workspace/project.d
index ddf8550..f406e2b 100644
--- a/src/dlangide/workspace/project.d
+++ b/src/dlangide/workspace/project.d
@@ -422,7 +422,7 @@ class Project : WorkspaceItem {
includePath ~= obj.str;
}
- _items = new ProjectFolder(fname);
+ _items = new ProjectFolder(fname.dirName);
_dependencyVersion = dependencyVersion;
_isDependency = _dependencyVersion.length > 0;
_projectFile = new SettingsFile(fname);
@@ -607,8 +607,8 @@ class Project : WorkspaceItem {
return settings.runInExternalConsole;
}
- ProjectFolder findItems(string[] srcPaths) {
- auto folder = new ProjectFolder(_filename);
+ private ProjectFolder findItems(string[] srcPaths) {
+ auto folder = new ProjectFolder(_filename.dirName);
folder.project = this;
foreach(customPath; srcPaths) {
string path = relativeToAbsolutePath(customPath);
diff --git a/views/res/i18n/en.ini b/views/res/i18n/en.ini
index 8edd1de..1ab1f82 100644
--- a/views/res/i18n/en.ini
+++ b/views/res/i18n/en.ini
@@ -34,6 +34,7 @@ NAME=Name
MENU_FILE=&File
MENU_FILE_NEW=&Create
MENU_FILE_NEW_SOURCE_FILE=New file
+MENU_FILE_NEW_DIRECTORY=New directory
MENU_FILE_NEW_PROJECT=New project
MENU_FILE_NEW_WORKSPACE=New workspace
MENU_FILE_OPEN=&Open file...
@@ -196,6 +197,7 @@ OPTION_GDC_EXECUTABLE=GDC executable
OPTION_LANGUAGE=Language
OPTION_LDC2_EXECUTABLE=LDC2 executable
OPTION_LDMD2_EXECUTABLE=LDMD2 executable
+OPTION_MAKE_PACKAGE=Create package.d
OPTION_MODULE_NAME=Module name
OPTION_NEW_PROJECT=New project
OPTION_NEW_SOURCE_FILE=New source file