From fa94e9bbf92dbc236c58748baaa4271cad3a9966 Mon Sep 17 00:00:00 2001 From: Anton Gushcha Date: Thu, 26 Feb 2015 20:19:53 +0300 Subject: [PATCH] Loading project configs from projects --- src/dlangide/builders/builder.d | 8 ++-- src/dlangide/ui/frame.d | 45 +++++++++++++++++---- src/dlangide/workspace/project.d | 64 +++++++++++++++++++++++++++++- src/dlangide/workspace/workspace.d | 33 ++++++++++----- 4 files changed, 128 insertions(+), 22 deletions(-) diff --git a/src/dlangide/builders/builder.d b/src/dlangide/builders/builder.d index b4880c5..3cadd4a 100644 --- a/src/dlangide/builders/builder.d +++ b/src/dlangide/builders/builder.d @@ -16,7 +16,7 @@ class Builder : BackgroundOperationWatcher { protected ExternalProcess _extprocess; protected OutputPanel _log; protected ProtectedTextStorage _box; - protected dstring _projectConfig; + protected ProjectConfiguration _projectConfig; protected BuildConfiguration _buildConfig; protected BuildOperation _buildOp; protected bool _verbose; @@ -24,7 +24,7 @@ class Builder : BackgroundOperationWatcher { @property Project project() { return _project; } @property void project(Project p) { _project = p; } - this(AppFrame frame, Project project, OutputPanel log, dstring projectConfig, BuildConfiguration buildConfig, BuildOperation buildOp, bool verbose) { + this(AppFrame frame, Project project, OutputPanel log, ProjectConfiguration projectConfig, BuildConfiguration buildConfig, BuildOperation buildOp, bool verbose) { super(frame); _projectConfig = projectConfig; _buildConfig = buildConfig; @@ -85,8 +85,8 @@ class Builder : BackgroundOperationWatcher { } } - if(_projectConfig != DEFAULT_PROJECT_CONFIGURATION) { - params ~= "--config=".dup ~ cast(string)(_projectConfig); + if(_projectConfig.name != ProjectConfiguration.DEFAULT_NAME) { + params ~= "--config=".dup ~ _projectConfig.name; } if (_verbose) diff --git a/src/dlangide/ui/frame.d b/src/dlangide/ui/frame.d index 7dcc9c0..b4a2e0a 100644 --- a/src/dlangide/ui/frame.d +++ b/src/dlangide/ui/frame.d @@ -57,9 +57,33 @@ class BackgroundOperationWatcherTest : BackgroundOperationWatcher { } } +/// Subclass of toolbars that can update their items +class UpdateableToolBarComboBox : ToolBarComboBox { + this(string id, dstring[] items) { + super(id, items); + } + + @property items(dstring[] newItems) { + _adapter.items = newItems; + if(newItems.length > 0) { + selectedItemIndex = 0; + } + requestLayout(); + } + + @property dstring selectedItem() { + size_t index = _selectedItemIndex; + if(index < 0 || index >= _adapter.itemCount) return ""; + + return _adapter.items.get(index); + } +} + /// DIDE app frame class IDEFrame : AppFrame { + private UpdateableToolBarComboBox projectConfigurationCombo; + MenuItem mainMenuItems; WorkspacePanel _wsPanel; OutputPanel _logPanel; @@ -435,15 +459,15 @@ class IDEFrame : AppFrame { tb.addButtons(ACTION_DEBUG_START); - ToolBarComboBox cbProjectConfiguration = new ToolBarComboBox("projectConfig", [DEFAULT_PROJECT_CONFIGURATION]); - cbProjectConfiguration.onItemClickListener = delegate(Widget source, int index) { + projectConfigurationCombo = new UpdateableToolBarComboBox("projectConfig", [ProjectConfiguration.DEFAULT_NAME.to!dstring]); + projectConfigurationCombo.onItemClickListener = delegate(Widget source, int index) { if (currentWorkspace) { - currentWorkspace.projectConfiguration = cbProjectConfiguration.text; + currentWorkspace.setStartupProjectConfiguration(projectConfigurationCombo.selectedItem.to!string); } return true; }; - cbProjectConfiguration.action = ACTION_PROJECT_CONFIGURATIONS; - tb.addControl(cbProjectConfiguration); + projectConfigurationCombo.action = ACTION_PROJECT_CONFIGURATIONS; + tb.addControl(projectConfigurationCombo); ToolBarComboBox cbBuildConfiguration = new ToolBarComboBox("buildConfig", ["Debug"d, "Release"d, "Unittest"d]); cbBuildConfiguration.onItemClickListener = delegate(Widget source, int index) { @@ -604,7 +628,7 @@ class IDEFrame : AppFrame { void openFileOrWorkspace(string filename) { if (filename.isWorkspaceFile) { - Workspace ws = new Workspace(); + Workspace ws = new Workspace(this); if (ws.load(filename)) { askForUnsavedEdits(delegate() { setWorkspace(ws); @@ -663,7 +687,7 @@ class IDEFrame : AppFrame { string defWsFile = project.defWorkspaceFile; _logPanel.logLine("Creating new workspace " ~ defWsFile); // new ws - Workspace ws = new Workspace(); + Workspace ws = new Workspace(this); ws.name = project.name; ws.description = project.description; ws.addProject(project); @@ -700,7 +724,12 @@ class IDEFrame : AppFrame { Builder op = new Builder(this, currentWorkspace.startupProject, _logPanel, currentWorkspace.projectConfiguration, currentWorkspace.buildConfiguration, buildOp, false); setBackgroundOperation(op); } - + + /// updates list of available configurations + void setProjectConfigurations(dstring[] items) { + projectConfigurationCombo.items = items; + } + /// handle files dropped to application window void onFilesDropped(string[] filenames) { //Log.d("onFilesDropped(", filenames, ")"); diff --git a/src/dlangide/workspace/project.d b/src/dlangide/workspace/project.d index 19977c1..916c226 100644 --- a/src/dlangide/workspace/project.d +++ b/src/dlangide/workspace/project.d @@ -223,6 +223,59 @@ string[] dmdSourcePaths() { return res; } +/// Stores info about project configuration +struct ProjectConfiguration { + /// name used to build the project + string name; + /// type, for libraries one can run tests, for apps - execute them + Type type; + + /// How to display default configuration in ui + immutable static string DEFAULT_NAME = "default"; + /// Default project configuration + immutable static ProjectConfiguration DEFAULT = ProjectConfiguration(DEFAULT_NAME, Type.Default); + + /// Type of configuration + enum Type { + Default, + Executable, + Library + } + + private static Type parseType(string s) + { + switch(s) + { + case "executable": return Type.Executable; + case "library": return Type.Library; + case "dynamicLibrary": return Type.Library; + case "staticLibrary": return Type.Library; + default: return Type.Default; + } + } + + /// parsing from setting file + static ProjectConfiguration[string] load(Setting s) + { + ProjectConfiguration[string] res = [DEFAULT_NAME: DEFAULT]; + if(s.map is null || "configurations" !in s.map || s.map["configurations"].array is null) + return res; + + foreach(conf; s.map["configurations"].array) + { + if(conf.map is null || "name" !in conf.map) continue; + Type t = Type.Default; + if("targetType" in conf.map) { + t = parseType(conf.map["targetType"].str); + } + string confName = conf.map["name"].str; + res[confName] = ProjectConfiguration(confName, t); + } + + return res; + } +} + /// DLANGIDE D project class Project : WorkspaceItem { protected Workspace _workspace; @@ -233,13 +286,19 @@ class Project : WorkspaceItem { protected string[] _sourcePaths; protected string[] _builderSourcePaths; - + protected ProjectConfiguration[string] _configurations; this(string fname = null) { super(fname); _items = new ProjectFolder(fname); } + /// returns project configurations + @property const(ProjectConfiguration[string]) configurations() const + { + return _configurations; + } + /// returns project's own source paths @property string[] sourcePaths() { return _sourcePaths; } /// returns project's own source paths @@ -356,6 +415,9 @@ class Project : WorkspaceItem { Log.i("Project source paths: ", sourcePaths); Log.i("Builder source paths: ", builderSourcePaths); + _configurations = ProjectConfiguration.load(_projectFile); + Log.i("Project configurations: ", _configurations); + } catch (JSONException e) { Log.e("Cannot parse json", e); return false; diff --git a/src/dlangide/workspace/workspace.d b/src/dlangide/workspace/workspace.d index 7181047..2274728 100644 --- a/src/dlangide/workspace/workspace.d +++ b/src/dlangide/workspace/workspace.d @@ -1,10 +1,13 @@ module dlangide.workspace.workspace; import dlangide.workspace.project; +import dlangide.ui.frame; import dlangui.core.logger; +import std.conv; import std.path; import std.file; import std.json; +import std.range; import std.utf; import std.algorithm; @@ -35,7 +38,6 @@ class WorkspaceException : Exception } immutable string WORKSPACE_EXTENSION = ".dlangidews"; -immutable dstring DEFAULT_PROJECT_CONFIGURATION = "default"d; /// return true if filename matches rules for workspace file names bool isWorkspaceFile(string filename) { @@ -45,12 +47,14 @@ bool isWorkspaceFile(string filename) { /// DlangIDE workspace class Workspace : WorkspaceItem { protected Project[] _projects; - - protected BuildConfiguration _buildConfiguration; - protected dstring _projectConfiguration = DEFAULT_PROJECT_CONFIGURATION; - this(string fname = null) { + protected IDEFrame _frame; + protected BuildConfiguration _buildConfiguration; + protected ProjectConfiguration _projectConfiguration = ProjectConfiguration.DEFAULT; + + this(IDEFrame frame, string fname = null) { super(fname); + _frame = frame; } @property Project[] projects() { @@ -60,17 +64,28 @@ class Workspace : WorkspaceItem { @property BuildConfiguration buildConfiguration() { return _buildConfiguration; } @property void buildConfiguration(BuildConfiguration config) { _buildConfiguration = config; } - @property dstring projectConfiguration() { return _projectConfiguration; } - @property void projectConfiguration(dstring config) { _projectConfiguration = config; } + @property ProjectConfiguration projectConfiguration() { return _projectConfiguration; } + @property void projectConfiguration(ProjectConfiguration config) { _projectConfiguration = config; } protected Project _startupProject; @property Project startupProject() { return _startupProject; } - @property void startupProject(Project project) { _startupProject = project; } + @property void startupProject(Project project) { + _startupProject = project; + _frame.setProjectConfigurations(project.configurations.keys.map!(k => k.to!dstring).array); + } + /// setups currrent project configuration by name + void setStartupProjectConfiguration(string conf) + { + if(_startupProject && conf in _startupProject.configurations) { + _projectConfiguration = _startupProject.configurations[conf]; + } + } + protected void fillStartupProject() { if (!_startupProject && _projects.length) - _startupProject = _projects[0]; + startupProject = _projects[0]; } /// tries to find source file in one of projects, returns found project source file item, or null if not found