mirror of https://github.com/buggins/dlangide.git
new file creation
This commit is contained in:
parent
795be1b3e7
commit
e9bde6e562
|
@ -446,6 +446,7 @@
|
|||
<File path="src\dlangide\ui\dsourceedit.d" />
|
||||
<File path="src\dlangide\ui\frame.d" />
|
||||
<File path="src\dlangide\ui\homescreen.d" />
|
||||
<File path="src\dlangide\ui\newfile.d" />
|
||||
<File path="src\dlangide\ui\newproject.d" />
|
||||
<File path="src\dlangide\ui\outputpanel.d" />
|
||||
<File path="src\dlangide\ui\searchPanel.d" />
|
||||
|
|
|
@ -37,7 +37,7 @@ enum IDEActions : int {
|
|||
WindowCloseAllDocuments,
|
||||
CreateNewWorkspace,
|
||||
AddToCurrentWorkspace,
|
||||
ProjectFolderAddItem,
|
||||
//ProjectFolderAddItem,
|
||||
ProjectFolderRemoveItem,
|
||||
ProjectFolderOpenItem,
|
||||
ProjectFolderRenameItem,
|
||||
|
@ -53,7 +53,7 @@ __gshared static this() {
|
|||
}
|
||||
|
||||
|
||||
const Action ACTION_PROJECT_FOLDER_ADD_ITEM = new Action(IDEActions.ProjectFolderAddItem, "MENU_PROJECT_FOLDER_ADD_ITEM"c);
|
||||
//const Action ACTION_PROJECT_FOLDER_ADD_ITEM = new Action(IDEActions.ProjectFolderAddItem, "MENU_PROJECT_FOLDER_ADD_ITEM"c);
|
||||
const Action ACTION_PROJECT_FOLDER_OPEN_ITEM = new Action(IDEActions.ProjectFolderOpenItem, "MENU_PROJECT_FOLDER_OPEN_ITEM"c);
|
||||
const Action ACTION_PROJECT_FOLDER_REMOVE_ITEM = new Action(IDEActions.ProjectFolderRemoveItem, "MENU_PROJECT_FOLDER_REMOVE_ITEM"c);
|
||||
const Action ACTION_PROJECT_FOLDER_RENAME_ITEM = new Action(IDEActions.ProjectFolderRenameItem, "MENU_PROJECT_FOLDER_RENAME_ITEM"c);
|
||||
|
|
|
@ -20,6 +20,7 @@ import dlangui.core.files;
|
|||
import dlangide.ui.commands;
|
||||
import dlangide.ui.wspanel;
|
||||
import dlangide.ui.outputpanel;
|
||||
import dlangide.ui.newfile;
|
||||
import dlangide.ui.newproject;
|
||||
import dlangide.ui.dsourceedit;
|
||||
import dlangide.ui.homescreen;
|
||||
|
@ -332,6 +333,7 @@ class IDEFrame : AppFrame {
|
|||
// Create workspace docked panel
|
||||
_wsPanel = new WorkspacePanel("workspace");
|
||||
_wsPanel.sourceFileSelectionListener = &onSourceFileSelected;
|
||||
_wsPanel.workspaceActionListener = &handleAction;
|
||||
_wsPanel.dockAlignment = DockAlignment.Left;
|
||||
_dockHost.addDockedWindow(_wsPanel);
|
||||
|
||||
|
@ -633,6 +635,9 @@ class IDEFrame : AppFrame {
|
|||
case IDEActions.FileNewProject:
|
||||
createNewProject(false);
|
||||
return true;
|
||||
case IDEActions.FileNew:
|
||||
addProjectItem(a.objectParam);
|
||||
return true;
|
||||
default:
|
||||
return super.handleAction(a);
|
||||
}
|
||||
|
@ -640,6 +645,54 @@ class IDEFrame : AppFrame {
|
|||
return false;
|
||||
}
|
||||
|
||||
@property ProjectSourceFile currentEditorSourceFile() {
|
||||
TabItem tab = _tabs.selectedTab;
|
||||
if (tab) {
|
||||
return cast(ProjectSourceFile)tab.objectParam;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void addProjectItem(const Object obj) {
|
||||
if (currentWorkspace is null)
|
||||
return;
|
||||
Project project;
|
||||
ProjectFolder folder;
|
||||
if (cast(Project)obj) {
|
||||
project = cast(Project)obj;
|
||||
} else if (cast(ProjectFolder)obj) {
|
||||
folder = cast(ProjectFolder)obj;
|
||||
project = folder.project;
|
||||
} else if (cast(ProjectSourceFile)obj) {
|
||||
ProjectSourceFile srcfile = cast(ProjectSourceFile)obj;
|
||||
folder = cast(ProjectFolder)srcfile.parent;
|
||||
project = srcfile.project;
|
||||
} else {
|
||||
ProjectSourceFile srcfile = currentEditorSourceFile;
|
||||
if (srcfile) {
|
||||
folder = cast(ProjectFolder)srcfile.parent;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
dlg.show();
|
||||
}
|
||||
}
|
||||
|
||||
void createNewProject(bool newWorkspace) {
|
||||
if (currentWorkspace is null)
|
||||
newWorkspace = true;
|
||||
|
|
|
@ -0,0 +1,313 @@
|
|||
module dlangide.ui.newfile;
|
||||
|
||||
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;
|
||||
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;
|
||||
import std.algorithm : startsWith, endsWith;
|
||||
|
||||
class FileCreationResult {
|
||||
Project project;
|
||||
string filename;
|
||||
this(Project project, string filename) {
|
||||
this.project = project;
|
||||
this.filename = filename;
|
||||
}
|
||||
}
|
||||
|
||||
class NewFileDlg : Dialog {
|
||||
IDEFrame _ide;
|
||||
Project _project;
|
||||
ProjectFolder _folder;
|
||||
string[] _sourcePaths;
|
||||
this(IDEFrame parent, Project currentProject, ProjectFolder folder) {
|
||||
super(UIString("New source file"d), parent.window,
|
||||
DialogFlag.Modal | DialogFlag.Resizable | DialogFlag.Popup, 500, 400);
|
||||
_ide = parent;
|
||||
_icon = "dlangui-logo1";
|
||||
this._project = currentProject;
|
||||
this._folder = folder;
|
||||
_location = folder ? folder.filename : currentProject.dir;
|
||||
_sourcePaths = currentProject.sourcePaths;
|
||||
if (_sourcePaths.length)
|
||||
_location = _sourcePaths[0];
|
||||
if (folder)
|
||||
_location = folder.filename;
|
||||
}
|
||||
/// override to implement creation of dialog controls
|
||||
override void init() {
|
||||
super.init();
|
||||
initTemplates();
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
TableLayout {
|
||||
margins: 5
|
||||
colCount: 2
|
||||
layoutWidth: fill; layoutHeight: wrap
|
||||
TextWidget { text: "Name" }
|
||||
EditLine { id: edName; text: "newfile"; layoutWidth: fill }
|
||||
TextWidget { text: "Location" }
|
||||
DirEditLine { id: edLocation; layoutWidth: fill }
|
||||
TextWidget { text: "Module name" }
|
||||
EditLine { id: edModuleName; text: ""; layoutWidth: fill; readOnly: true }
|
||||
TextWidget { text: "File path" }
|
||||
EditLine { id: edFilePath; text: ""; layoutWidth: fill; readOnly: true }
|
||||
}
|
||||
TextWidget { id: statusText; text: ""; layoutWidth: fill; textColor: #FF0000 }
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Log.e("Exceptin while parsing DML", e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
|
||||
_projectTemplateList = content.childById!StringListWidget("projectTemplateList");
|
||||
_templateDescription = content.childById!EditBox("templateDescription");
|
||||
_edFileName = content.childById!EditLine("edName");
|
||||
_edFilePath = content.childById!EditLine("edFilePath");
|
||||
_edModuleName = content.childById!EditLine("edModuleName");
|
||||
_edLocation = content.childById!DirEditLine("edLocation");
|
||||
_edLocation.text = toUTF32(_location);
|
||||
_statusText = content.childById!TextWidget("statusText");
|
||||
|
||||
_edLocation.filetypeIcons[".d"] = "text-d";
|
||||
_edLocation.filetypeIcons["dub.json"] = "project-d";
|
||||
_edLocation.filetypeIcons["package.json"] = "project-d";
|
||||
_edLocation.filetypeIcons[".dlangidews"] = "project-development";
|
||||
_edLocation.addFilter(FileFilterEntry(UIString("DlangIDE files"d), "*.dlangidews;*.d;*.dd;*.di;*.ddoc;*.dh;*.json;*.xml;*.ini"));
|
||||
_edLocation.caption = "Select directory"d;
|
||||
|
||||
// fill templates
|
||||
dstring[] names;
|
||||
foreach(t; _templates)
|
||||
names ~= t.name;
|
||||
_projectTemplateList.items = names;
|
||||
_projectTemplateList.selectedItemIndex = 0;
|
||||
|
||||
templateSelected(0);
|
||||
|
||||
// listeners
|
||||
_edLocation.contentChange = delegate (EditableContent source) {
|
||||
_location = toUTF8(source.text);
|
||||
validate();
|
||||
};
|
||||
|
||||
_edFileName.contentChange = delegate (EditableContent source) {
|
||||
_fileName = toUTF8(source.text);
|
||||
validate();
|
||||
};
|
||||
|
||||
_projectTemplateList.itemSelected = delegate (Widget source, int itemIndex) {
|
||||
templateSelected(itemIndex);
|
||||
return true;
|
||||
};
|
||||
_projectTemplateList.itemClick = delegate (Widget source, int itemIndex) {
|
||||
templateSelected(itemIndex);
|
||||
return true;
|
||||
};
|
||||
|
||||
addChild(content);
|
||||
addChild(createButtonsPanel([ACTION_FILE_NEW_SOURCE_FILE, ACTION_CANCEL], 0, 0));
|
||||
|
||||
}
|
||||
|
||||
StringListWidget _projectTemplateList;
|
||||
EditBox _templateDescription;
|
||||
DirEditLine _edLocation;
|
||||
EditLine _edFileName;
|
||||
EditLine _edModuleName;
|
||||
EditLine _edFilePath;
|
||||
TextWidget _statusText;
|
||||
|
||||
string _fileName = "newfile";
|
||||
string _location;
|
||||
string _moduleName;
|
||||
string _packageName;
|
||||
string _fullPathName;
|
||||
|
||||
int _currentTemplateIndex = -1;
|
||||
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;
|
||||
}
|
||||
|
||||
bool validate() {
|
||||
string filename = _fileName;
|
||||
string fullFileName = filename;
|
||||
if (!_currentTemplate.fileExtension.empty && filename.endsWith(_currentTemplate.fileExtension))
|
||||
filename = filename[0 .. $ - _currentTemplate.fileExtension.length];
|
||||
else
|
||||
fullFileName = fullFileName ~ _currentTemplate.fileExtension;
|
||||
_fullPathName = buildNormalizedPath(_location, fullFileName);
|
||||
_edFilePath.text = toUTF32(_fullPathName);
|
||||
if (!isValidFileName(filename))
|
||||
return setError("Invalid file name");
|
||||
if (!exists(_location) || !isDir(_location))
|
||||
return setError("Location directory does not exist");
|
||||
|
||||
if (_currentTemplate.isModule) {
|
||||
string sourcePath, relativePath;
|
||||
if (!findSource(_location, sourcePath, relativePath))
|
||||
return setError("Location is outside of source path");
|
||||
if (!isValidModuleName(filename))
|
||||
return setError("Invalid file name");
|
||||
_moduleName = filename;
|
||||
char[] buf;
|
||||
foreach(ch; relativePath) {
|
||||
if (ch == '/' || ch == '\\')
|
||||
buf ~= '.';
|
||||
else
|
||||
buf ~= ch;
|
||||
}
|
||||
_packageName = buf.dup;
|
||||
string m = !_packageName.empty ? _packageName ~ '.' ~ _moduleName : _moduleName;
|
||||
_edModuleName.text = toUTF32(m);
|
||||
} else {
|
||||
string projectPath = _project.dir;
|
||||
if (!isSubdirOf(_location, projectPath))
|
||||
return setError("Location is outside of project path");
|
||||
_edModuleName.text = "";
|
||||
_moduleName = "";
|
||||
_packageName = "";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private FileCreationResult _result;
|
||||
bool createItem() {
|
||||
try {
|
||||
if (_currentTemplate.isModule) {
|
||||
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);
|
||||
return setError("Cannot create file");
|
||||
}
|
||||
_result = new FileCreationResult(_project, _fullPathName);
|
||||
return true;
|
||||
}
|
||||
|
||||
override void close(const Action action) {
|
||||
Action newaction = action.clone();
|
||||
if (action.id == IDEActions.FileNew) {
|
||||
if (!validate()) {
|
||||
window.showMessageBox(UIString("Error"d), UIString("Invalid parameters"));
|
||||
return;
|
||||
}
|
||||
if (!createItem()) {
|
||||
window.showMessageBox(UIString("Error"d), UIString("Failed to create project item"));
|
||||
return;
|
||||
}
|
||||
newaction.objectParam = _result;
|
||||
}
|
||||
super.close(newaction);
|
||||
}
|
||||
|
||||
protected void templateSelected(int index) {
|
||||
if (_currentTemplateIndex == index)
|
||||
return;
|
||||
_currentTemplateIndex = index;
|
||||
_currentTemplate = _templates[index];
|
||||
_templateDescription.text = _currentTemplate.description;
|
||||
//updateDirLayout();
|
||||
validate();
|
||||
}
|
||||
|
||||
void initTemplates() {
|
||||
_templates ~= new ProjectTemplate("Empty module"d, "Empty D module file."d, ".d",
|
||||
"\n", true);
|
||||
_templates ~= new ProjectTemplate("Text file"d, "Empty text file."d, ".txt",
|
||||
"\n", true);
|
||||
_templates ~= new ProjectTemplate("JSON file"d, "Empty json file."d, ".json",
|
||||
"{\n}\n", true);
|
||||
}
|
||||
}
|
||||
|
||||
class ProjectTemplate {
|
||||
dstring name;
|
||||
dstring description;
|
||||
string fileExtension;
|
||||
string srccode;
|
||||
bool isModule;
|
||||
this(dstring name, dstring description, string fileExtension, string srccode, bool isModule) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.fileExtension = fileExtension;
|
||||
this.srccode = srccode;
|
||||
this.isModule = isModule;
|
||||
}
|
||||
}
|
||||
|
|
@ -284,6 +284,10 @@ class NewProjectDlg : Dialog {
|
|||
if (!exists(_location) || !isDir(_location)) {
|
||||
return setError("Invalid location");
|
||||
}
|
||||
if (!isValidProjectName(_projectName))
|
||||
return setError("Invalid project name");
|
||||
if (!isValidProjectName(_workspaceName))
|
||||
return setError("Invalid workspace name");
|
||||
return setError("");
|
||||
}
|
||||
|
||||
|
|
|
@ -17,12 +17,17 @@ interface SourceFileSelectionHandler {
|
|||
bool onSourceFileSelected(ProjectSourceFile file, bool activate);
|
||||
}
|
||||
|
||||
interface WorkspaceActionHandler {
|
||||
bool onWorkspaceAction(const Action a);
|
||||
}
|
||||
|
||||
class WorkspacePanel : DockWindow {
|
||||
protected Workspace _workspace;
|
||||
protected TreeWidget _tree;
|
||||
|
||||
/// handle source file selection change
|
||||
Signal!SourceFileSelectionHandler sourceFileSelectionListener;
|
||||
Signal!WorkspaceActionHandler workspaceActionListener;
|
||||
|
||||
this(string id) {
|
||||
super(id);
|
||||
|
@ -70,17 +75,17 @@ class WorkspacePanel : DockWindow {
|
|||
_tree.popupMenu = &onTreeItemPopupMenu;
|
||||
|
||||
_workspacePopupMenu = new MenuItem();
|
||||
_workspacePopupMenu.add(ACTION_PROJECT_FOLDER_ADD_ITEM);
|
||||
_workspacePopupMenu.add(ACTION_FILE_NEW_SOURCE_FILE.clone());
|
||||
|
||||
_projectPopupMenu = new MenuItem();
|
||||
_projectPopupMenu.add(ACTION_PROJECT_FOLDER_ADD_ITEM, ACTION_PROJECT_FOLDER_OPEN_ITEM,
|
||||
_projectPopupMenu.add(ACTION_FILE_NEW_SOURCE_FILE, ACTION_PROJECT_FOLDER_OPEN_ITEM,
|
||||
ACTION_PROJECT_FOLDER_REMOVE_ITEM);
|
||||
|
||||
_folderPopupMenu = new MenuItem();
|
||||
_folderPopupMenu.add(ACTION_PROJECT_FOLDER_ADD_ITEM, ACTION_PROJECT_FOLDER_OPEN_ITEM,
|
||||
_folderPopupMenu.add(ACTION_FILE_NEW_SOURCE_FILE, ACTION_PROJECT_FOLDER_OPEN_ITEM,
|
||||
ACTION_PROJECT_FOLDER_REMOVE_ITEM, ACTION_PROJECT_FOLDER_RENAME_ITEM);
|
||||
_filePopupMenu = new MenuItem();
|
||||
_filePopupMenu.add(ACTION_PROJECT_FOLDER_ADD_ITEM, ACTION_PROJECT_FOLDER_OPEN_ITEM,
|
||||
_filePopupMenu.add(ACTION_FILE_NEW_SOURCE_FILE, ACTION_PROJECT_FOLDER_OPEN_ITEM,
|
||||
ACTION_PROJECT_FOLDER_REMOVE_ITEM, ACTION_PROJECT_FOLDER_RENAME_ITEM);
|
||||
return _tree;
|
||||
}
|
||||
|
@ -108,7 +113,15 @@ class WorkspacePanel : DockWindow {
|
|||
menu = _workspacePopupMenu;
|
||||
}
|
||||
if (menu && menu.subitemCount) {
|
||||
menu.onMenuItem = &onPopupMenuItem;
|
||||
for (int i = 0; i < menu.subitemCount; i++) {
|
||||
Action a = menu.subitem(i).action.clone();
|
||||
a.objectParam = selectedItem.objectParam;
|
||||
menu.subitem(i).action = a;
|
||||
//menu.subitem(i).menuItemAction = &handleAction;
|
||||
}
|
||||
//menu.onMenuItem = &onPopupMenuItem;
|
||||
//menu.menuItemClick = &onPopupMenuItem;
|
||||
menu.menuItemAction = &handleAction;
|
||||
menu.updateActionState(this);
|
||||
return menu;
|
||||
}
|
||||
|
@ -161,4 +174,11 @@ class WorkspacePanel : DockWindow {
|
|||
_workspace = w;
|
||||
reloadItems();
|
||||
}
|
||||
|
||||
/// override to handle specific actions
|
||||
override bool handleAction(const Action a) {
|
||||
if (workspaceActionListener.assigned)
|
||||
return workspaceActionListener(a);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import std.json;
|
|||
import std.utf;
|
||||
import std.algorithm;
|
||||
import std.process;
|
||||
import std.array;
|
||||
|
||||
/// return true if filename matches rules for workspace file names
|
||||
bool isProjectFile(string filename) {
|
||||
|
@ -74,6 +75,9 @@ class ProjectItem {
|
|||
ProjectItem child(int index) {
|
||||
return null;
|
||||
}
|
||||
|
||||
void refresh() {
|
||||
}
|
||||
}
|
||||
|
||||
/// Project folder
|
||||
|
@ -99,9 +103,30 @@ class ProjectFolder : ProjectItem {
|
|||
item._parent = this;
|
||||
item._project = _project;
|
||||
}
|
||||
ProjectItem childByPathName(string path) {
|
||||
for (int i = 0; i < _children.count; i++) {
|
||||
if (_children[i].filename.equal(path))
|
||||
return _children[i];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
ProjectItem childByName(dstring s) {
|
||||
for (int i = 0; i < _children.count; i++) {
|
||||
if (_children[i].name.equal(s))
|
||||
return _children[i];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
bool loadDir(string path) {
|
||||
string src = relativeToAbsolutePath(path);
|
||||
if (exists(src) && isDir(src)) {
|
||||
ProjectFolder existing = cast(ProjectFolder)childByPathName(src);
|
||||
if (existing) {
|
||||
if (existing.isFolder)
|
||||
existing.loadItems();
|
||||
return true;
|
||||
}
|
||||
ProjectFolder dir = new ProjectFolder(src);
|
||||
addChild(dir);
|
||||
Log.d(" added project folder ", src);
|
||||
|
@ -110,9 +135,13 @@ class ProjectFolder : ProjectItem {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool loadFile(string path) {
|
||||
string src = relativeToAbsolutePath(path);
|
||||
if (exists(src) && isFile(src)) {
|
||||
ProjectItem existing = childByPathName(src);
|
||||
if (existing)
|
||||
return true;
|
||||
ProjectSourceFile f = new ProjectSourceFile(src);
|
||||
addChild(f);
|
||||
Log.d(" added project file ", src);
|
||||
|
@ -120,21 +149,36 @@ class ProjectFolder : ProjectItem {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void loadItems() {
|
||||
bool[string] loaded;
|
||||
foreach(e; dirEntries(_filename, SpanMode.shallow)) {
|
||||
string fn = baseName(e.name);
|
||||
if (e.isDir) {
|
||||
loadDir(fn);
|
||||
loaded[fn] = true;
|
||||
} else if (e.isFile) {
|
||||
loadFile(fn);
|
||||
loaded[fn] = true;
|
||||
}
|
||||
}
|
||||
// removing non-reloaded items
|
||||
for (int i = _children.count - 1; i >= 0; i--) {
|
||||
if (!(toUTF8(_children[i].name) in loaded)) {
|
||||
_children.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string relativeToAbsolutePath(string path) {
|
||||
if (isAbsolute(path))
|
||||
return path;
|
||||
return buildNormalizedPath(_filename, path);
|
||||
}
|
||||
|
||||
override void refresh() {
|
||||
loadItems();
|
||||
}
|
||||
}
|
||||
|
||||
/// Project source file
|
||||
|
@ -408,6 +452,10 @@ class Project : WorkspaceItem {
|
|||
return folder;
|
||||
}
|
||||
|
||||
void refresh() {
|
||||
_items.refresh();
|
||||
}
|
||||
|
||||
void findMainSourceFile() {
|
||||
string n = toUTF8(name);
|
||||
string[] mainnames = ["app.d", "main.d", n ~ ".d"];
|
||||
|
@ -575,3 +623,35 @@ class DubPackageFinder {
|
|||
}
|
||||
}
|
||||
|
||||
bool isValidProjectName(string s) {
|
||||
if (s.empty)
|
||||
return false;
|
||||
for (int i = 0; i < s.length; i++) {
|
||||
char ch = s[i];
|
||||
if (ch != '_' && ch != '-' && (ch < '0' || ch > '9') && (ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z'))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isValidModuleName(string s) {
|
||||
if (s.empty)
|
||||
return false;
|
||||
for (int i = 0; i < s.length; i++) {
|
||||
char ch = s[i];
|
||||
if (ch != '_' && (ch < '0' || ch > '9') && (ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z'))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isValidFileName(string s) {
|
||||
if (s.empty)
|
||||
return false;
|
||||
for (int i = 0; i < s.length; i++) {
|
||||
char ch = s[i];
|
||||
if (ch != '_' && ch != '.' && ch != '-' && (ch < '0' || ch > '9') && (ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z'))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue