aboutsummaryrefslogtreecommitdiffstatsci
path: root/Samples/CrowIDE/src/Solution.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Samples/CrowIDE/src/Solution.cs')
-rw-r--r--Samples/CrowIDE/src/Solution.cs541
1 files changed, 541 insertions, 0 deletions
diff --git a/Samples/CrowIDE/src/Solution.cs b/Samples/CrowIDE/src/Solution.cs
new file mode 100644
index 00000000..c6b1fbc1
--- /dev/null
+++ b/Samples/CrowIDE/src/Solution.cs
@@ -0,0 +1,541 @@
+//
+// Solution.cs
+//
+//code taken in project https://sourceforge.net/projects/syncproj/
+// no licence info was included, I took the liberty to modify it.
+// Author:
+// tarmopikaro
+// 2018 Jean-Philippe Bruyère
+//MIT-licenced
+
+using Microsoft.Win32;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Xml.Serialization;
+using Crow;
+
+namespace Crow.Coding{
+ public class SolutionProject {
+ public string ProjectHostGuid;
+ public string ProjectName;
+ public string RelativePath;
+ public string ProjectGuid;
+ }
+ public class StyleItemContainer {
+ public object Value;
+ public string Name;
+ public StyleItemContainer(string name, object _value){
+ Name = name;
+ Value = _value;
+ }
+ }
+ public class StyleContainer : IValueChange {
+ #region IValueChange implementation
+ public event EventHandler<ValueChangeEventArgs> ValueChanged;
+ public virtual void NotifyValueChanged(string MemberName, object _value)
+ {
+ ValueChanged.Raise(this, new ValueChangeEventArgs(MemberName, _value));
+ }
+ #endregion
+
+ Style style;
+ bool isExpanded;
+
+ public string Name;
+ public List<StyleItemContainer> Items;
+ public bool IsExpanded
+ {
+ get { return isExpanded; }
+ set
+ {
+ if (value == isExpanded)
+ return;
+ isExpanded = value;
+ NotifyValueChanged ("IsExpanded", isExpanded);
+ }
+ }
+ public StyleContainer(string name, Style _style){
+ Name = name;
+ style = _style;
+
+ Items = new List<StyleItemContainer> ();
+ foreach (string k in style.Keys) {
+ Items.Add(new StyleItemContainer(k, style[k]));
+ }
+ }
+ }
+
+
+ /// <summary>
+/// .sln loaded into class.
+/// </summary>
+ public class Solution: IValueChange
+ {
+ #region IValueChange implementation
+ public event EventHandler<ValueChangeEventArgs> ValueChanged;
+ public virtual void NotifyValueChanged(string MemberName, object _value)
+ {
+ ValueChanged.Raise(this, new ValueChangeEventArgs(MemberName, _value));
+ }
+ #endregion
+
+ ProjectItem selectedItem = null;
+ object selectedItemElement = null;
+ ObservableList<ProjectItem> openedItems = new ObservableList<ProjectItem>();
+ ObservableList<GraphicObjectDesignContainer> toolboxItems;
+
+ public Dictionary<string, Style> Styling;
+ public Dictionary<string, string> DefaultTemplates;
+
+ public List<Style> Styles { get { return Styling.Values.ToList(); }}
+ public List<StyleContainer> StylingContainers;
+ //TODO: check project dependencies if no startup proj
+
+ public void ReloadStyling () {
+ Styling = new Dictionary<string, Style> ();
+ if (StartupProject != null)
+ StartupProject.GetStyling ();
+// StylingContainers = new List<StyleContainer> ();
+// foreach (string k in Styling.Keys) {
+// StylingContainers.Add (new StyleContainer (k, Styling [k]));
+// }
+ foreach (ImlProjectItem pf in openedItems.OfType<ImlProjectItem>()) {
+ pf.SignalEditorOfType<ImlVisualEditor> ();
+ }
+ }
+ public string[] AvailaibleStyles {
+ get { return Styling == null ? new string[] {} : Styling.Keys.ToArray();}
+ }
+ public void ReloadDefaultTemplates () {
+ DefaultTemplates = new Dictionary<string, string>();
+ if (StartupProject != null)
+ StartupProject.GetDefaultTemplates ();
+ }
+ public void updateToolboxItems () {
+ Type[] crowItems = AppDomain.CurrentDomain.GetAssemblies ()
+ .SelectMany (t => t.GetTypes ())
+ .Where (t => t.IsClass && !t.IsAbstract && t.IsPublic &&
+ t.Namespace == "Crow" && t.IsSubclassOf(typeof(Widget)) &&
+ t.GetCustomAttribute<DesignIgnore>(false) == null).ToArray ();
+ ToolboxItems = new ObservableList<GraphicObjectDesignContainer> ();
+ foreach (Type ci in crowItems) {
+ toolboxItems.AddElement(new GraphicObjectDesignContainer(ci));
+ }
+ }
+ public bool GetProjectFileFromPath (string path, out ProjectFile pi){
+ pi = null;
+ return StartupProject == null ? false :
+ StartupProject.TryGetProjectFileFromPath (path, out pi);
+ }
+
+ public ObservableList<ProjectItem> OpenedItems {
+ get { return openedItems; }
+ set {
+ if (openedItems == value)
+ return;
+ openedItems = value;
+ NotifyValueChanged ("OpenedItems", openedItems);
+ }
+ }
+
+ public ObservableList<GraphicObjectDesignContainer> ToolboxItems {
+ get { return toolboxItems; }
+ set {
+ if (toolboxItems == value)
+ return;
+ toolboxItems = value;
+ NotifyValueChanged ("ToolboxItems", toolboxItems);
+ }
+ }
+ public ProjectItem SelectedItem {
+ get { return selectedItem; }
+ set {
+ if (selectedItem == value)
+ return;
+ if (SelectedItem != null)
+ SelectedItem.IsSelected = false;
+ selectedItem = value;
+ if (SelectedItem != null)
+ SelectedItem.IsSelected = true;
+
+ UserConfig.Set ("SelectedProjItems", SelectedItem?.AbsolutePath);
+
+ NotifyValueChanged ("SelectedItem", selectedItem);
+ }
+ }
+ public object SelectedItemElement {
+ get { return selectedItemElement; }
+ set {
+ if (selectedItemElement == value)
+ return;
+ selectedItemElement = value;
+ NotifyValueChanged ("SelectedItemElement", selectedItemElement);
+ }
+ }
+ public string DisplayName {
+ get { return name; }
+ }
+ /// <summary>
+ /// Gets solution path
+ /// </summary>
+ public String SolutionFolder
+ {
+ get { return Path.GetDirectoryName (path); }
+ }
+
+// public System.CodeDom.Compiler.CompilerErrorCollection CompilationErrors {
+// get {
+// System.CodeDom.Compiler.CompilerErrorCollection tmp = Projects.SelectMany<Project>
+// (p => p.CompilationResults.Errors);
+// return tmp;
+// }
+// }
+ public List<System.CodeDom.Compiler.CompilerError> CompilerErrors {
+ get {
+ int errCount = 0;
+ for (int i = 0; i < Projects.Count; i++) {
+ if (Projects [i].CompilationResults != null)
+ errCount += Projects [i].CompilationResults.Errors.Count;
+ }
+ System.CodeDom.Compiler.CompilerError[] tmp = new System.CodeDom.Compiler.CompilerError[errCount];
+
+ int ptr = 0;
+ for (int i = 0; i < Projects.Count; i++) {
+ if (Projects [i].CompilationResults == null)
+ continue;
+ Projects [i].CompilationResults.Errors.CopyTo (tmp,ptr);
+ ptr += Projects [i].CompilationResults.Errors.Count;
+ }
+ return new List<System.CodeDom.Compiler.CompilerError>(tmp);
+ }
+ }
+
+ public void UpdateErrorList () {
+ NotifyValueChanged ("CompilerErrors", CompilerErrors);
+ }
+
+ void saveOpenedItemsInUserConfig (){
+ if (openedItems.Count == 0)
+ UserConfig.Set ("OpenedItems", "");
+ else
+ UserConfig.Set ("OpenedItems", openedItems.Select(o => o.AbsolutePath).Aggregate((a,b)=>a + ";" + b));
+ }
+ public void ReopenItemsSavedInUserConfig () {
+ string tmp = UserConfig.Get<string> ("OpenedItems");
+ string sel = UserConfig.Get<string> ("SelectedProjItems");
+ ProjectFile selItem = null;
+ if (string.IsNullOrEmpty (tmp))
+ return;
+ foreach (string f in tmp.Split(';')) {
+ foreach (Project p in Projects) {
+ ProjectFile pi;
+ if (p.TryGetProjectFileFromAbsolutePath (f, out pi)) {
+ pi.Open ();
+ if (pi.AbsolutePath == sel)
+ selItem = pi;
+ break;
+ }
+ }
+ }
+ if (selItem == null)
+ return;
+ selItem.IsSelected = true;
+ }
+
+ /*void onSelectedItemChanged (object sender, SelectionChangeEventArgs e){
+ SelectedItem = e.NewValue as ProjectItem;
+ UserConfig.Set ("SelectedProjItems", SelectedItem?.AbsolutePath);
+ }*/
+
+ public void OpenItem (ProjectItem pi) {
+ if (!openedItems.Contains (pi)) {
+ openedItems.AddElement (pi);
+ saveOpenedItemsInUserConfig ();
+ }
+ }
+ public void CloseItem (ProjectItem pi) {
+ openedItems.RemoveElement (pi);
+ saveOpenedItemsInUserConfig ();
+ }
+
+ public void CloseSolution () {
+ while (openedItems.Count > 0) {
+ openedItems.RemoveElement (openedItems [0]);
+ }
+ while (toolboxItems.Count > 0) {
+ toolboxItems.RemoveElement (toolboxItems [0]);
+ }
+ NotifyValueChanged ("Projects", null);
+ }
+ /// <summary>
+ /// Solution name
+ /// </summary>
+ String name;
+ /// <summary>
+ /// File path from where solution was loaded.
+ /// </summary>
+ [XmlIgnore]
+ String path;
+
+ /// <summary>
+ /// Solution name for debugger.
+ /// </summary>
+ [ExcludeFromCodeCoverage]
+ public override string ToString()
+ {
+ return "Solution: " + name;
+ }
+
+ #region Solution properties
+ double slnVer; // 11.00 - vs2010, 12.00 - vs2015
+
+ /// <summary>
+ /// Visual studio version information used for generation, for example 2010, 2012, 2015 and so on...
+ /// </summary>
+ public int fileFormatVersion;
+
+ /// <summary>
+ /// null for old visual studio's
+ /// </summary>
+ public String VisualStudioVersion;
+
+ /// <summary>
+ /// null for old visual studio's
+ /// </summary>
+ public String MinimumVisualStudioVersion;
+
+ /// <summary>
+ /// List of project included into solution.
+ /// </summary>
+ public List<Project> Projects = new List<Project>();
+
+ /// <summary>
+ /// List of configuration list, in form "{Configuration}|{Platform}", for example "Release|Win32".
+ /// To extract individual platforms / configuration list, use following functions.
+ /// </summary>
+ public List<String> configurations = new List<string>();
+
+ /// <summary>
+ /// Extracts platfroms supported by solution
+ /// </summary>
+ public IEnumerable<String> getPlatforms()
+ {
+ return configurations.Select(x => x.Split('|')[1]).Distinct();
+ }
+
+ /// <summary>
+ /// Extracts configuration names supported by solution
+ /// </summary>
+ public IEnumerable<String> getConfigurations()
+ {
+ return configurations.Select(x => x.Split('|')[0]).Distinct();
+ }
+ #endregion
+
+ public Configuration UserConfig;
+
+ public Project StartupProject {
+ get { return Projects?.FirstOrDefault (p => p.ProjectGuid == UserConfig.Get<string> ("StartupProject")); }
+ set {
+ if (value == StartupProject)
+ return;
+ if (value == null)
+ UserConfig.Set ("StartupProject", "");
+ else {
+ UserConfig.Set ("StartupProject", value.ProjectGuid);
+ value.NotifyValueChanged("IsStartupProject", true);
+ }
+ NotifyValueChanged ("StartupProject", StartupProject);
+ ReloadStyling ();
+ ReloadDefaultTemplates ();
+ }
+ }
+
+ #region CTOR
+ /// <summary>
+ /// Creates new solution.
+ /// </summary>
+ public Solution() {
+ }
+
+ #endregion
+
+
+ #region Loading from SLN file
+ /// <summary>
+ /// Loads visual studio .sln solution
+ /// </summary>
+ /// <exception cref="System.IO.FileNotFoundException">The file specified in path was not found.</exception>
+ static public Solution LoadSolution(string path)
+ {
+ Solution s = new Solution();
+ s.path = path;
+
+ String slnTxt = File.ReadAllText(path);
+ //
+ // Extra line feed is used by Visual studio, cmake does not generate extra line feed.
+ //
+ s.slnVer = Double.Parse(Regex.Match(slnTxt, "[\r\n]?Microsoft Visual Studio Solution File, Format Version ([0-9.]+)", RegexOptions.Multiline).Groups[1].Value, CultureInfo.InvariantCulture);
+
+ int vsNumber = Int32.Parse(Regex.Match(slnTxt, "^\\# Visual Studio (Express )?([0-9]+)", RegexOptions.Multiline).Groups[2].Value);
+ if (vsNumber > 2000)
+ s.fileFormatVersion = vsNumber;
+ else
+ s.fileFormatVersion = vsNumber - 14 + 2015; // Visual Studio 14 => vs2015, formula might not be applicable for future vs versions.
+
+ foreach (String line in new String[] { "VisualStudioVersion", "MinimumVisualStudioVersion" })
+ {
+ var m = Regex.Match(slnTxt, "^" + line + " = ([0-9.]+)", RegexOptions.Multiline);
+ String v = null;
+ if (m.Success)
+ v = m.Groups[1].Value;
+
+ s.GetType().GetField(line).SetValue(s, v);
+ }
+
+ Regex reProjects = new Regex(
+ "Project\\(\"(?<ProjectHostGuid>{[A-F0-9-]+})\"\\) = \"(?<ProjectName>.*?)\", \"(?<RelativePath>.*?)\", \"(?<ProjectGuid>{[A-F0-9-]+})\"[\r\n]*(?<dependencies>.*?)EndProject[\r\n]+",
+ RegexOptions.Singleline);
+
+
+ reProjects.Replace(slnTxt, new MatchEvaluator(m =>
+ {
+ SolutionProject p = new SolutionProject ();
+
+ foreach (String g in reProjects.GetGroupNames())
+ {
+ if (g == "0") //"0" - RegEx special kind of group
+ continue;
+
+ //
+ // ProjectHostGuid, ProjectName, RelativePath, ProjectGuid fields/properties are set here.
+ //
+ String v = m.Groups[g].ToString();
+ if (g != "dependencies")
+ {
+ FieldInfo fi = p.GetType().GetField(g);
+ if (fi != null)
+ {
+ fi.SetValue(p, v);
+ }
+ else
+ {
+ p.GetType().GetProperty(g).SetValue(p, v);
+ }
+ continue;
+ }
+
+ if (v == "") // No dependencies set
+ continue;
+
+ String depsv = new Regex("ProjectSection\\(ProjectDependencies\\)[^\r\n]*?[\r\n]+" + "(.*?)" + "EndProjectSection", RegexOptions.Singleline).Match(v).Groups[1].Value;
+
+ //
+ // key is always equal to it's value.
+ // http://stackoverflow.com/questions/5629981/question-about-visual-studio-sln-file-format
+ //
+ var ProjectDependencies = new Regex("\\s*?({[A-F0-9-]+}) = ({[A-F0-9-]+})[\r\n]+", RegexOptions.Multiline).Matches(depsv).Cast<Match>().Select(x => x.Groups[1].Value).ToList();
+ } //foreach
+ s.Projects.Add(new Project (s, p));
+ return "";
+ }
+ )
+ );
+
+ new Regex("GlobalSection\\(SolutionConfigurationPlatforms\\).*?[\r\n]+(.*?)EndGlobalSection[\r\n]+", RegexOptions.Singleline).Replace(slnTxt, new MatchEvaluator(m2 =>
+ {
+ s.configurations = new Regex("\\s*(.*)\\s+=").Matches(m2.Groups[1].ToString()).Cast<Match>().Select(x => x.Groups[1].Value).ToList();
+ return "";
+ }
+ ));
+
+ Console.WriteLine ("******** CONFIG ***************");
+
+ new Regex("GlobalSection\\(ProjectConfigurationPlatforms\\).*?[\r\n]+(.*?)EndGlobalSection[\r\n]+", RegexOptions.Singleline).Replace(slnTxt, new MatchEvaluator(m2 =>
+ {
+ foreach (Match m3 in new Regex("\\s*({[A-F0-9-]+})\\.(.*?)\\.(.*?)\\s+=\\s+(.*?)[\r\n]+").Matches(m2.Groups[1].ToString()))
+ {
+ String guid = m3.Groups[1].Value;
+ String solutionConfig = m3.Groups[2].Value;
+ String action = m3.Groups[3].Value;
+ String projectConfig = m3.Groups[4].Value;
+
+ Project p = s.Projects.Where(x => x.ProjectGuid == guid).FirstOrDefault();
+ if (p == null)
+ continue;
+
+ Console.WriteLine ("{0},{1},{2},{3}",guid,solutionConfig,action,projectConfig);
+
+ int iConfigIndex = s.configurations.IndexOf(solutionConfig);
+ if (iConfigIndex == -1)
+ continue;
+
+// while (p.slnConfigurations.Count < s.configurations.Count)
+// {
+// p.slnConfigurations.Add(null);
+// p.slnBuildProject.Add(false);
+// }
+//
+// if (action == "ActiveCfg")
+// {
+// p.slnConfigurations[iConfigIndex] = projectConfig;
+// }
+// else
+// {
+// if (action.StartsWith("Build"))
+// {
+// p.slnBuildProject[iConfigIndex] = true;
+// }
+// else
+// {
+// if (action.StartsWith("Deploy"))
+// {
+// if (p.slnDeployProject == null) p.slnDeployProject = new List<bool?>();
+//
+// while (p.slnDeployProject.Count < s.configurations.Count)
+// p.slnDeployProject.Add(null);
+//
+// p.slnDeployProject[iConfigIndex] = true;
+// }
+// }
+// } //if-esle
+ }
+ return "";
+ }
+ ));
+
+ //
+ // Initializes parent-child relationship.
+ //
+ new Regex("GlobalSection\\(NestedProjects\\).*?[\r\n]+(.*?)EndGlobalSection[\r\n]+", RegexOptions.Singleline).Replace(slnTxt, new MatchEvaluator(m4 =>
+ {
+ String v = m4.Groups[1].Value;
+ new Regex("\\s*?({[A-F0-9-]+}) = ({[A-F0-9-]+})[\r\n]+", RegexOptions.Multiline).Replace(v, new MatchEvaluator(m5 =>
+ {
+ String[] args = m5.Groups.Cast<System.Text.RegularExpressions.Group>().Skip(1).Select(x => x.Value).ToArray();
+ Project child = s.Projects.Where(x => args[0] == x.ProjectGuid).FirstOrDefault();
+ Project parent = s.Projects.Where(x => args[1] == x.ProjectGuid).FirstOrDefault();
+ parent.dependantProjects.Add(child);
+ child.ParentProject = parent;
+ return "";
+ }));
+ return "";
+ }
+ ));
+
+ s.UserConfig = new Configuration (s.path + ".user");
+ s.ReloadStyling ();
+ s.ReloadDefaultTemplates ();
+ s.updateToolboxItems ();
+ return s;
+ } //LoadSolution
+ #endregion
+ }
+}