From: Jean-Philippe Bruyère Date: Sun, 4 Mar 2018 10:28:09 +0000 (+0100) Subject: crowIde wip, docker wip, stack remove child debug X-Git-Tag: 0.7.3~4^2~33 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=27232cfa68a07db1286331ca93fe9067a46fda9b;p=jp%2Fcrow.git crowIde wip, docker wip, stack remove child debug --- diff --git a/Crow.csproj b/Crow.csproj index 91b16e31..7a0ffada 100644 --- a/Crow.csproj +++ b/Crow.csproj @@ -223,6 +223,8 @@ + + diff --git a/CrowIDE/CrowIDE.csproj b/CrowIDE/CrowIDE.csproj index 9a9a222f..0a8150e4 100644 --- a/CrowIDE/CrowIDE.csproj +++ b/CrowIDE/CrowIDE.csproj @@ -77,7 +77,6 @@ - @@ -115,8 +114,10 @@ - + + + @@ -124,6 +125,7 @@ + diff --git a/CrowIDE/src/CrowIDE.cs b/CrowIDE/src/CrowIDE.cs index c08dd663..6f6e376b 100644 --- a/CrowIDE/src/CrowIDE.cs +++ b/CrowIDE/src/CrowIDE.cs @@ -103,13 +103,16 @@ namespace Crow.Coding //this.CrowInterface.LoadInterface ("#Crow.Coding.ui.imlEditor.crow").DataSource = this; //GraphicObject go = this.CrowInterface.LoadInterface (@"ui/test.crow"); GraphicObject go = AddWidget (@"#Crow.Coding.ui.CrowIDE.crow"); + go.DataSource = this; MainIFace = ifaceControl[0].CrowInterface; - if (ReopenLastSolution && !string.IsNullOrEmpty(LastOpenSolution)) + if (ReopenLastSolution && !string.IsNullOrEmpty (LastOpenSolution)) { CurrentSolution = Solution.LoadSolution (LastOpenSolution); + //lock(MainIFace.UpdateMutex) + CurrentSolution.ReopenItemsSavedInUserConfig (); + } - go.DataSource = this; instFileDlg = Instantiator.CreateFromImlFragment (MainIFace, ""); diff --git a/CrowIDE/src/ImlVisualEditor.cs b/CrowIDE/src/ImlVisualEditor.cs index 69ae5515..c9e5484e 100644 --- a/CrowIDE/src/ImlVisualEditor.cs +++ b/CrowIDE/src/ImlVisualEditor.cs @@ -158,7 +158,7 @@ namespace Crow.Coding SelectedItem = go; IMLError = null; projFile.RegisteredEditors[this] = true; - }else if ((bool)projFile.Instance?.HasChanged){ + }else if ((bool)projFile.Instance?.design_HasChanged){ projFile.UpdateSource(this, projFile.Instance.GetIML()); } imlVE.Update (); diff --git a/CrowIDE/src/MemberView/CategoryContainer.cs b/CrowIDE/src/MemberView/CategoryContainer.cs new file mode 100644 index 00000000..fbf3fe2c --- /dev/null +++ b/CrowIDE/src/MemberView/CategoryContainer.cs @@ -0,0 +1,65 @@ +// +// CategoryContainer.cs +// +// Author: +// Jean-Philippe Bruyère +// +// Copyright (c) 2013-2017 Jean-Philippe Bruyère +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; + +namespace Crow.Coding +{ + public class CategoryContainer : IValueChange + { + #region IValueChange implementation + public event EventHandler ValueChanged; + public virtual void NotifyValueChanged(string MemberName, object _value) + { + ValueChanged.Raise(this, new ValueChangeEventArgs(MemberName, _value)); + } + #endregion + + bool _isExpanded = true; + + public PropertyContainer[] Properties; + public string Name; + + public bool IsExpanded + { + get { return _isExpanded; } + set + { + if (value == _isExpanded) + return; + + _isExpanded = value; + + NotifyValueChanged ("IsExpanded", _isExpanded); + } + } + + public CategoryContainer (string categoryName, PropertyContainer[] properties){ + Name = categoryName; + Properties = properties; + } + } +} + diff --git a/CrowIDE/src/MemberView/MembersView.cs b/CrowIDE/src/MemberView/MembersView.cs new file mode 100644 index 00000000..65dc9595 --- /dev/null +++ b/CrowIDE/src/MemberView/MembersView.cs @@ -0,0 +1,136 @@ +// +// MembersView.cs +// +// Author: +// Jean-Philippe Bruyère +// +// Copyright (c) 2016 jp +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +using System; +using Crow; +using System.Xml.Serialization; +using System.ComponentModel; +using System.Reflection; +using System.Collections.Generic; +using System.Linq; +using Cairo; + +namespace Crow.Coding +{ + public class MembersView : ListBox + { + object instance; + ImlProjectItem projFile; + + public MembersView () : base() {} + + //cache property containers per type + Dictionary propContainersCache = new Dictionary(); + Dictionary> categoryContainersCache = new Dictionary> (); + + [XmlAttributeAttribute][DefaultValue(null)] + public virtual object Instance { + get { return instance; } + set { + if (instance == value) + return; + object lastInst = instance; + + instance = value; + NotifyValueChanged ("Instance", instance); + + if (Instance is GraphicObject) { + NotifyValueChanged ("SelectedItemName", Instance.GetType().Name + (Instance as GraphicObject).design_id + + ":" + (Instance as GraphicObject).design_imlPath ); + }else + NotifyValueChanged ("SelectedItemName", ""); + + if (instance == null) { + Data = null; + return; + } + + Type it = instance.GetType (); + if (!propContainersCache.ContainsKey (it.FullName)) { + MemberInfo[] members = it.GetMembers (BindingFlags.Public | BindingFlags.Instance); + List props = new List (); + foreach (MemberInfo m in members) { + if (m.MemberType == MemberTypes.Property) { + PropertyInfo pi = m as PropertyInfo; + if (!pi.CanWrite) + continue; + if (pi.GetCustomAttribute (typeof(XmlIgnoreAttribute)) != null) + continue; + props.Add (new PropertyContainer (this, pi)); + } + } + propContainersCache.Add (it.FullName, props.OrderBy (p => p.Name).ToArray ()); + } + + List categories = new List (); + + foreach (IGrouping ig in propContainersCache[it.FullName].GroupBy(pc=>pc.DesignCategory)) { + categories.Add(new CategoryContainer(ig.Key, ig.ToArray())); + } + + Data = categories; + + if (lastInst != instance) { + foreach (PropertyContainer pc in propContainersCache [it.FullName]) { + pc.NotifyValueChanged ("Value", pc.Value); + } + } + } + } + public ImlProjectItem ProjectNode { + get { return projFile; } + set { + if (projFile == value) + return; + +// if (projFile != null) +// projFile.UnregisterEditor (this); + + projFile = value; + +// if (projFile != null) +// projFile.RegisterEditor (this); + + NotifyValueChanged ("ProjectNode", projFile); + } + } + + public void updateSource () { + if (projFile == null) + return; + projFile.UpdateSource (this, (Instance as GraphicObject).GetIML ()); + } + +// public override void Paint (ref Context ctx) +// { +// base.Paint (ref ctx); +// +// if (SelectedIndex < 0) +// return; +// +// Rectangle r = Parent.ContextCoordinates(Items [SelectedIndex].Slot); +// ctx.SetSourceRGB (0, 0, 1); +// ctx.Rectangle (r); +// ctx.LineWidth = 2; +// ctx.Stroke (); +// } + + } +} diff --git a/CrowIDE/src/MemberView/PropertyContainer.cs b/CrowIDE/src/MemberView/PropertyContainer.cs new file mode 100644 index 00000000..46cbbd74 --- /dev/null +++ b/CrowIDE/src/MemberView/PropertyContainer.cs @@ -0,0 +1,212 @@ +// +// PropertyContainer.cs +// +// Author: +// Jean-Philippe Bruyère +// +// Copyright (c) 2013-2017 Jean-Philippe Bruyère +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; +using System.Reflection; +using System.Linq; +using System.Collections.Generic; +using System.Diagnostics; +using System.ComponentModel; + +namespace Crow.Coding +{ + public class PropertyContainer : IValueChange + { + #region IValueChange implementation + public event EventHandler ValueChanged; + public virtual void NotifyValueChanged(string MemberName, object _value) + { + ValueChanged.Raise(this, new ValueChangeEventArgs(MemberName, _value)); + } + #endregion + + PropertyInfo pi; + MembersView mview; + Command cmdReset, cmdGoToStyle; + + public List Commands; + + #region CTOR + public PropertyContainer(MembersView mv, PropertyInfo prop){ + mview = mv; + pi = prop; + + cmdReset = new Crow.Command (new Action (() => Reset ())) { Caption = "Reset to default" }; + cmdGoToStyle = new Crow.Command (new Action (() => GotoStyle ())) { Caption = "Goto style" }; + + Commands = new List (new Crow.Command[] { cmdReset, cmdGoToStyle }); + } + #endregion + + public string DesignCategory { + get { + DesignCategory dca = (DesignCategory)pi.GetCustomAttribute (typeof(DesignCategory)); + return dca == null ? "Divers" : dca.Name; + } + } + public string Name { get { return pi.Name; }} + public object Value { + get { + return mview.ProjectNode.SelectedItem == null ? null : pi.GetValue(mview.ProjectNode.SelectedItem); + } + set { + try { + GraphicObject g = Instance; + string valstr = null, oldval = null; + + if (value != null) + valstr = value.ToString(); + + if (HasStyling) + oldval = g.design_style_values[Name]; + else if (HasDefaultValue) + oldval = DefaultValue?.ToString(); + else if (IsSetByIML) + oldval = g.design_iml_values [Name]; + + if (valstr == oldval){ + if (IsSetByIML){ + g.design_iml_values.Remove(Name); + Debug.WriteLine("iml attrib removed {0}.{1}", g.Name, Name); + }else + return; + }else{ + if (IsSetByIML){ + g.design_iml_values [Name] = valstr; + Debug.WriteLine("iml update {0}.{1} = {2}", g.Name, Name, valstr); + }else{ + g.design_iml_values.Add(Name,valstr); + Debug.WriteLine("iml add {0}.{1} = {2}", g.Name, Name, valstr); + } + } + + if (!pi.PropertyType.IsAssignableFrom(value.GetType()) && pi.PropertyType != typeof(string)){ + if (pi.PropertyType.IsEnum) { + if (value is string) { + pi.SetValue (g, Enum.Parse (pi.PropertyType, (string)value)); + }else + pi.SetValue (g, value); + } else { + MethodInfo me = pi.PropertyType.GetMethod + ("Parse", BindingFlags.Static | BindingFlags.Public, + System.Type.DefaultBinder, new Type [] {typeof (string)},null); + pi.SetValue (g, me.Invoke (null, new object[] { value }), null); + } + }else + pi.SetValue(g, value); + + mview.ProjectNode.Instance.design_HasChanged = true; + NotifyValueChanged ("Value", value); + NotifyValueChanged ("LabForeground", LabForeground); + } catch (Exception ex) { + System.Diagnostics.Debug.WriteLine ("Error setting property:"+ ex.ToString()); + } + // + } + } + /// + /// for style attribute which is a string, return Style as type + /// + public string Type { get { return pi.PropertyType.IsEnum ? + "System.Enum" + : pi.Name == "Style" ? "Style" : pi.PropertyType.FullName; }} + + public object[] Choices { + get { + return pi.PropertyType.IsEnum ? + Enum.GetValues (pi.PropertyType).Cast().ToArray() : + mview.ProjectNode.Project.solution.AvailaibleStyles; + } + } + /// + /// Current graphicobject instance + /// + public GraphicObject Instance { + get { return mview.ProjectNode.SelectedItem as GraphicObject; } + } + public object DefaultValue { + get { return ((DefaultValueAttribute)(pi.GetCustomAttribute (typeof (DefaultValueAttribute)))).Value; } + } + public bool HasDefaultValue { + get { return pi.GetCustomAttribute (typeof(DefaultValueAttribute))!=null; } + } + /// + /// return true if current value comes from IML attributes + /// + public bool IsSetByIML { + get { return Instance.design_iml_values.ContainsKey (Name); } + } + /// + /// return true if member default value comes from style + /// + public bool HasStyling { + get { return Instance.design_style_locations.ContainsKey(Name); } + } + /// + /// Return true if current value comes from styling + /// + public bool IsSetByStyling { + get { return IsSetByIML ? false : HasStyling; } + } + + + public Fill LabForeground { + get { return IsSetByIML ? Color.DarkBlue : HasStyling ? Color.Black : Color.DimGray;} + } + + /// + /// reset to default value + /// + public void Reset () { + GraphicObject inst = mview.ProjectNode.SelectedItem as GraphicObject; + if (!inst.design_iml_values.ContainsKey (Name)) + return; + inst.design_iml_values.Remove (Name); + //NotifyValueChanged ("Value", Value); + mview.ProjectNode.Instance.design_HasChanged = true; + //should reinstantiate to get default + } + public void GotoStyle(){ + GraphicObject g = Instance; + if (!g.design_style_locations.ContainsKey (Name)) + return; + FileLocation fl = g.design_style_locations [Name]; + ProjectFile pf; + if (!mview.ProjectNode.Project.TryGetProjectFileFromPath ("#" + fl.FilePath, out pf)) + return; + Solution s = mview.ProjectNode.Project.solution; + if (!s.OpenedItems.Contains (pf)) + s.OpenedItems.AddElement (pf); + pf.CurrentLine = fl.Line; + pf.CurrentColumn = fl.Column; + } + + public override string ToString () + { + return string.Format ("{0} = {1}", Name, Value); + } + } +} + diff --git a/CrowIDE/src/MembersView.cs b/CrowIDE/src/MembersView.cs deleted file mode 100644 index f0c3a13a..00000000 --- a/CrowIDE/src/MembersView.cs +++ /dev/null @@ -1,129 +0,0 @@ -// -// MembersView.cs -// -// Author: -// Jean-Philippe Bruyère -// -// Copyright (c) 2016 jp -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -using System; -using Crow; -using System.Xml.Serialization; -using System.ComponentModel; -using System.Reflection; -using System.Collections.Generic; -using System.Linq; -using Cairo; - -namespace Crow.Coding -{ - public class MembersView : ListBox - { - object instance; - ImlProjectItem projFile; - - public MembersView () : base() {} - - //cache property containers per type - Dictionary propContainersCache = new Dictionary(); - - [XmlAttributeAttribute][DefaultValue(null)] - public virtual object Instance { - get { return instance; } - set { - if (instance == value) - return; - object lastInst = instance; - - instance = value; - NotifyValueChanged ("Instance", instance); - - if (Instance is GraphicObject) { - NotifyValueChanged ("SelectedItemName", Instance.GetType().Name + (Instance as GraphicObject).design_id - + ":" + (Instance as GraphicObject).design_imlPath ); - }else - NotifyValueChanged ("SelectedItemName", ""); - - if (instance == null) { - Data = null; - return; - } - - Type it = instance.GetType (); - if (!propContainersCache.ContainsKey (it.FullName)) { - MemberInfo[] members = it.GetMembers (BindingFlags.Public | BindingFlags.Instance); - List props = new List (); - foreach (MemberInfo m in members) { - if (m.MemberType == MemberTypes.Property) { - PropertyInfo pi = m as PropertyInfo; - if (!pi.CanWrite) - continue; - if (pi.GetCustomAttribute (typeof(XmlIgnoreAttribute)) != null) - continue; - props.Add (new PropertyContainer (this, pi)); - } - } - propContainersCache.Add (it.FullName, props.OrderBy (p => p.Name).ToArray ()); - } - - Data = propContainersCache [it.FullName]; - - if (lastInst != instance) { - foreach (PropertyContainer pc in propContainersCache [it.FullName]) { - pc.NotifyValueChanged ("Value", pc.Value); - } - } - } - } - public ImlProjectItem ProjectNode { - get { return projFile; } - set { - if (projFile == value) - return; - -// if (projFile != null) -// projFile.UnregisterEditor (this); - - projFile = value; - -// if (projFile != null) -// projFile.RegisterEditor (this); - - NotifyValueChanged ("ProjectNode", projFile); - } - } - - public void updateSource () { - if (projFile == null) - return; - projFile.UpdateSource (this, (Instance as GraphicObject).GetIML ()); - } - -// public override void Paint (ref Context ctx) -// { -// base.Paint (ref ctx); -// -// if (SelectedIndex < 0) -// return; -// -// Rectangle r = Parent.ContextCoordinates(Items [SelectedIndex].Slot); -// ctx.SetSourceRGB (0, 0, 1); -// ctx.Rectangle (r); -// ctx.LineWidth = 2; -// ctx.Stroke (); -// } - - } -} diff --git a/CrowIDE/src/Project.cs b/CrowIDE/src/Project.cs index ff3469de..5e6c98d9 100644 --- a/CrowIDE/src/Project.cs +++ b/CrowIDE/src/Project.cs @@ -46,6 +46,7 @@ namespace Crow.Coding #endregion bool isLoaded = false; + bool isExpanded; XmlDocument xmlDoc; XmlNode nodeProject; XmlNode nodeProps; @@ -72,6 +73,17 @@ namespace Crow.Coding NotifyValueChanged ("IsLoaded", isLoaded); } } + public bool IsExpanded + { + get { return isExpanded; } + set + { + if (value == isExpanded) + return; + isExpanded = value; + NotifyValueChanged ("IsExpanded", isExpanded); + } + } public bool IsStartupProject { get { return solution.StartupProject == this; } } @@ -100,17 +112,17 @@ namespace Crow.Coding flattenNodes = new List (); ProjectNode refs = new ProjectNode (this, ItemType.ReferenceGroup, "References"); - root.ChildNodes.Add (refs); + root.AddChild (refs); foreach (ProjectItem pn in items) { switch (pn.Type) { case ItemType.Reference: - refs.ChildNodes.Add (pn); + refs.AddChild (pn); flattenNodes.Add (pn); break; case ItemType.ProjectReference: ProjectReference pr = new ProjectReference (pn); - refs.ChildNodes.Add (pr); + refs.AddChild (pr); flattenNodes.Add (pr); break; case ItemType.Compile: @@ -122,7 +134,7 @@ namespace Crow.Coding ProjectNode nextNode = curNode.ChildNodes.FirstOrDefault (n => n.DisplayName == folds [i] && n.Type == ItemType.VirtualGroup); if (nextNode == null) { nextNode = new ProjectNode (this, ItemType.VirtualGroup, folds [i]); - curNode.ChildNodes.Add (nextNode); + curNode.AddChild (nextNode); } curNode = nextNode; } @@ -136,7 +148,7 @@ namespace Crow.Coding f = new ProjectFile (pn); break; } - curNode.ChildNodes.Add (f); + curNode.AddChild (f); flattenNodes.Add (f); break; } diff --git a/CrowIDE/src/ProjectNodes.cs b/CrowIDE/src/ProjectNodes.cs index c3348266..bf213c27 100644 --- a/CrowIDE/src/ProjectNodes.cs +++ b/CrowIDE/src/ProjectNodes.cs @@ -74,6 +74,8 @@ namespace Crow.Coding Commands = new List (); } + ProjectNode parent; + bool isExpanded; ItemType type; string name; List childNodes = new List(); @@ -81,6 +83,10 @@ namespace Crow.Coding public Project Project; public List Commands;//list of command available for that node + public ProjectNode Parent { + get { return parent; } + set { parent = value; } + } public virtual ItemType Type { get { return type; } } @@ -90,12 +96,32 @@ namespace Crow.Coding public List ChildNodes { get { return childNodes; } } - + public void AddChild (ProjectNode pn) { + childNodes.Add(pn); + pn.Parent = this; + } + public void RemoveChild (ProjectNode pn){ + pn.Parent = null; + childNodes.Remove (pn); + } public void SortChilds () { foreach (ProjectNode pn in childNodes) pn.SortChilds (); childNodes = childNodes.OrderBy(c=>c.Type).ThenBy(cn=>cn.DisplayName).ToList(); } + + public bool IsExpanded + { + get { return isExpanded; } + set + { + if (value == isExpanded) + return; + isExpanded = value; + NotifyValueChanged ("IsExpanded", isExpanded); + } + } + public override string ToString () { return DisplayName; diff --git a/CrowIDE/src/PropertyContainer.cs b/CrowIDE/src/PropertyContainer.cs deleted file mode 100644 index c89273cc..00000000 --- a/CrowIDE/src/PropertyContainer.cs +++ /dev/null @@ -1,169 +0,0 @@ -// -// PropertyContainer.cs -// -// Author: -// Jean-Philippe Bruyère -// -// Copyright (c) 2013-2017 Jean-Philippe Bruyère -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -using System; -using System.Reflection; -using System.Linq; -using System.Collections.Generic; -using System.Diagnostics; - -namespace Crow.Coding -{ - public class PropertyContainer : IValueChange - { - #region IValueChange implementation - public event EventHandler ValueChanged; - public virtual void NotifyValueChanged(string MemberName, object _value) - { - ValueChanged.Raise(this, new ValueChangeEventArgs(MemberName, _value)); - } - #endregion - - public List Commands; - Command cmdReset, cmdGoToStyle; - PropertyInfo pi; - MembersView mview; -// object instance; -// GraphicObject go; - - public PropertyContainer(MembersView mv, PropertyInfo prop){ - mview = mv; - pi = prop; -// instance = _instance; -// go = instance as GraphicObject; - - cmdReset = new Crow.Command (new Action (() => Reset ())) { Caption = "Reset to default" }; - cmdGoToStyle = new Crow.Command (new Action (() => GotoStyle ())) { Caption = "Goto style" }; - - Commands = new List (new Crow.Command[] { cmdReset, cmdGoToStyle }); - } - - public string Name { get { return pi.Name; }} - public object Value { - get { - return pi.GetValue(mview.ProjectNode.SelectedItem); -// GraphicObject inst = mview.ProjectNode.SelectedItem as GraphicObject; -// Debug.WriteLine("read {0}.{1}", inst.Name, Name); -// if (!inst.design_members.ContainsKey (Name)) -// return pi.GetValue (inst); -// -// if (inst.design_members [Name].StartsWith ("{")) -// return inst.design_members [Name]; -// else -// return pi.GetValue (inst); - } - set { - try { - GraphicObject inst = mview.ProjectNode.SelectedItem as GraphicObject; - string valstr = null; - if (value != null) - valstr = value.ToString(); - if (inst.design_members.ContainsKey (Name)) { - if (inst.design_members [Name] == valstr) - return; - Debug.WriteLine("update {0} : {1} = {2}", inst.Name, Name, valstr); - inst.design_members [Name] = value.ToString(); - } else { - Debug.WriteLine("add {0} : {1} = {2}", inst.Name, Name, valstr); - inst.design_members.Add (Name, value.ToString()); - } - - if (!pi.PropertyType.IsAssignableFrom(value.GetType()) && pi.PropertyType != typeof(string)){ - if (pi.PropertyType.IsEnum) { - if (value is string) { - pi.SetValue (inst, Enum.Parse (pi.PropertyType, (string)value)); - }else - pi.SetValue (inst, value); - } else { - MethodInfo me = pi.PropertyType.GetMethod - ("Parse", BindingFlags.Static | BindingFlags.Public, - System.Type.DefaultBinder, new Type [] {typeof (string)},null); - pi.SetValue (inst, me.Invoke (null, new object[] { value }), null); - } - }else - pi.SetValue(inst, value); - - mview.ProjectNode.Instance.HasChanged = true; - NotifyValueChanged ("Value", value); - NotifyValueChanged ("LabForeground", LabForeground); - } catch (Exception ex) { - System.Diagnostics.Debug.WriteLine ("Error setting property:"+ ex.ToString()); - } - // - } - } - /// - /// for style attribute which is a string, return Style as type - /// - public string Type { get { return pi.PropertyType.IsEnum ? - "System.Enum" - : pi.Name == "Style" ? "Style" : pi.PropertyType.FullName; }} - - public object[] Choices { - get { - return pi.PropertyType.IsEnum ? - Enum.GetValues (pi.PropertyType).Cast().ToArray() : - mview.ProjectNode.Project.solution.AvailaibleStyles; - } - } - - public Fill LabForeground { - get { - GraphicObject go = mview.ProjectNode.SelectedItem as GraphicObject; - return go.design_members.ContainsKey (Name) ? Color.Black : - go.design_defaults.ContainsKey(Name) ? Color.DarkBlue : Color.DimGray;} - } - - /// - /// reset to default value - /// - public void Reset () { - GraphicObject inst = mview.ProjectNode.SelectedItem as GraphicObject; - if (!inst.design_members.ContainsKey (Name)) - return; - inst.design_members.Remove (Name); - //NotifyValueChanged ("Value", Value); - mview.ProjectNode.Instance.HasChanged = true; - //should reinstantiate to get default - } - public void GotoStyle(){ - GraphicObject inst = mview.ProjectNode.SelectedItem as GraphicObject; - if (!inst.design_defaults.ContainsKey (Name)) - return; - FileLocation fl = inst.design_defaults [Name]; - ProjectFile pf; - if (!mview.ProjectNode.Project.TryGetProjectFileFromPath ("#" + fl.FilePath, out pf)) - return; - Solution s = mview.ProjectNode.Project.solution; - if (!s.OpenedItems.Contains (pf)) - s.OpenedItems.Add (pf); - //pf.CurrentLine = fl.Line; - //pf.CurrentColumn = fl.Column; - } - - - } -} - diff --git a/CrowIDE/src/Solution.cs b/CrowIDE/src/Solution.cs index 7ed6b780..b1ccedca 100644 --- a/CrowIDE/src/Solution.cs +++ b/CrowIDE/src/Solution.cs @@ -138,10 +138,13 @@ namespace Crow.Coding{ NotifyValueChanged ("CompilerErrors", CompilerErrors); } - void saveOpenedItemsInUserConfig (){ - UserConfig.Set ("OpenedItems", openedItems.Select(o => o.AbsolutePath).Aggregate((a,b)=>a + ";" + b)); + void saveOpenedItemsInUserConfig (){ + if (openedItems.Count == 0) + UserConfig.Set ("OpenedItems", ""); + else + UserConfig.Set ("OpenedItems", openedItems.Select(o => o.AbsolutePath).Aggregate((a,b)=>a + ";" + b)); } - void reopenItemsSavedInUserConfig () { + public void ReopenItemsSavedInUserConfig () { string tmp = UserConfig.Get ("OpenedItems"); string sel = UserConfig.Get ("SelectedProjItems"); ProjectFile selItem = null; @@ -151,7 +154,13 @@ namespace Crow.Coding{ foreach (Project p in Projects) { ProjectFile pi; if (p.TryGetProjectFileFromAbsolutePath (f, out pi)) { - OpenedItems.Add (pi); + OpenedItems.AddElement (pi); + pi.Project.IsExpanded = true; + ProjectNode pn = pi.Parent; + while (pn != null) { + pn.IsExpanded = true; + pn = pn.Parent; + } if (pi.AbsolutePath == sel) selItem = pi; break; @@ -442,7 +451,6 @@ namespace Crow.Coding{ s.UserConfig = new Configuration (s.path + ".user"); s.ReloadStyling (); s.ReloadDefaultTemplates (); - s.reopenItemsSavedInUserConfig (); return s; } //LoadSolution #endregion diff --git a/CrowIDE/src/SourceEditor/CodeBuffer.cs b/CrowIDE/src/SourceEditor/CodeBuffer.cs index 66c24857..ec9bbc3e 100644 --- a/CrowIDE/src/SourceEditor/CodeBuffer.cs +++ b/CrowIDE/src/SourceEditor/CodeBuffer.cs @@ -69,70 +69,70 @@ namespace Crow.Coding return; editMutex.EnterWriteLock (); lines [i] = value; - LineUpadateEvent.Raise (this, new CodeBufferEventArgs (i)); editMutex.ExitWriteLock (); + LineUpadateEvent.Raise (this, new CodeBufferEventArgs (i)); } } public void RemoveAt(int i){ editMutex.EnterWriteLock (); lines.RemoveAt (i); - LineRemoveEvent.Raise (this, new CodeBufferEventArgs (i)); editMutex.ExitWriteLock (); + LineRemoveEvent.Raise (this, new CodeBufferEventArgs (i)); } public void Insert(int i, string item){ editMutex.EnterWriteLock (); lines.Insert (i, item); - LineAdditionEvent.Raise (this, new CodeBufferEventArgs (i)); editMutex.ExitWriteLock (); + LineAdditionEvent.Raise (this, new CodeBufferEventArgs (i)); } public void Add(CodeLine item){ editMutex.EnterWriteLock (); lines.Add (item); - LineAdditionEvent.Raise (this, new CodeBufferEventArgs (lines.Count - 1)); editMutex.ExitWriteLock (); + LineAdditionEvent.Raise (this, new CodeBufferEventArgs (lines.Count - 1)); } public void AddRange (string[] items){ int start = lines.Count; editMutex.EnterWriteLock (); for (int i = 0; i < items.Length; i++) lines.Add (items [i]); - LineAdditionEvent.Raise (this, new CodeBufferEventArgs (start, items.Length)); editMutex.ExitWriteLock (); + LineAdditionEvent.Raise (this, new CodeBufferEventArgs (start, items.Length)); } public void AddRange (CodeLine[] items){ int start = lines.Count; editMutex.EnterWriteLock (); lines.AddRange (items); - LineAdditionEvent.Raise (this, new CodeBufferEventArgs (start, items.Length)); editMutex.ExitWriteLock (); + LineAdditionEvent.Raise (this, new CodeBufferEventArgs (start, items.Length)); } public void Clear () { editMutex.EnterWriteLock (); longestLineCharCount = 0; lines.Clear (); - BufferCleared.Raise (this, null); editMutex.ExitWriteLock (); + BufferCleared.Raise (this, null); } public void UpdateLine(int i, string newContent){ editMutex.EnterWriteLock (); this [i].Content = newContent; - LineUpadateEvent.Raise (this, new CodeBufferEventArgs (i)); editMutex.ExitWriteLock (); + LineUpadateEvent.Raise (this, new CodeBufferEventArgs (i)); } public void AppenedLine(int i, string newContent){ editMutex.EnterWriteLock (); this [i].Content += newContent; - LineUpadateEvent.Raise (this, new CodeBufferEventArgs (i)); editMutex.ExitWriteLock (); + LineUpadateEvent.Raise (this, new CodeBufferEventArgs (i)); } public void ToogleFolding (int line) { if (!this [line].IsFoldable) return; editMutex.EnterWriteLock (); this [line].IsFolded = !this [line].IsFolded; - FoldingEvent.Raise (this, new CodeBufferEventArgs (line)); editMutex.ExitWriteLock (); + FoldingEvent.Raise (this, new CodeBufferEventArgs (line)); } public void Load(string rawSource, string lineBrkRegex = @"\r\n|\r|\n|\\\n") { this.Clear(); @@ -150,13 +150,15 @@ namespace Crow.Coding /// public void FindLongestVisualLine(){ longestLineCharCount = 0; + editMutex.EnterReadLock (); for (int i = 0; i < this.LineCount; i++) { if (lines[i].PrintableLength > longestLineCharCount) { longestLineCharCount = lines[i].PrintableLength; longestLineIdx = i; } } - Debug.WriteLine ("Longest line: {0}->{1}", longestLineIdx, longestLineCharCount); + editMutex.ExitReadLock (); + //Debug.WriteLine ("Longest line: {0}->{1}", longestLineIdx, longestLineCharCount); } /// line break could be '\r' or '\n' or '\r\n' static string detectLineBreakKind(string buffer){ @@ -190,9 +192,11 @@ namespace Crow.Coding if (lines.Count == 0) return ""; string tmp = ""; + editMutex.EnterReadLock (); for (int i = 0; i < lines.Count -1; i++) tmp += lines [i].Content + this.lineBreak; tmp += lines [lines.Count - 1].Content; + editMutex.ExitReadLock (); return tmp; } } @@ -203,12 +207,14 @@ namespace Crow.Coding public int UnfoldedLines { get { int i = 0, vl = 0; + editMutex.EnterReadLock (); while (i < LineCount) { if (this [i].IsFolded) i = GetEndNodeIndex (i); i++; vl++; } + editMutex.ExitReadLock (); //Debug.WriteLine ("unfolded lines: " + vl); return vl; } @@ -249,7 +255,7 @@ namespace Crow.Coding return i; } - int CurrentTabulatedColumn { + public int CurrentTabulatedColumn { get { return lines [_currentLine].Content.Substring (0, _currentCol). Replace ("\t", new String (' ', Interface.TabSize)).Length; @@ -330,6 +336,9 @@ namespace Crow.Coding set { if (value == _currentCol) return; + + editMutex.EnterReadLock (); + if (value < 0) _currentCol = 0; else if (value > lines [_currentLine].Length) @@ -338,7 +347,8 @@ namespace Crow.Coding _currentCol = value; requestedColumn = CurrentTabulatedColumn; - //requestedColumn = _currentCol; + + editMutex.ExitReadLock (); PositionChanged.Raise (this, null); } @@ -351,6 +361,9 @@ namespace Crow.Coding set { if (value == _currentLine) return; + + editMutex.EnterReadLock (); + if (value >= lines.Count) _currentLine = lines.Count-1; else if (value < 0) @@ -366,6 +379,9 @@ namespace Crow.Coding //_currentCol = requestedColumn; _currentCol = tabulatedRequestedCol; //Debug.WriteLine ("buff cur line: " + _currentLine); + + editMutex.ExitReadLock(); + PositionChanged.Raise (this, null); } } diff --git a/CrowIDE/src/SourceEditor/SourceEditor.cs b/CrowIDE/src/SourceEditor/SourceEditor.cs index b0e8a35f..1264f4a1 100644 --- a/CrowIDE/src/SourceEditor/SourceEditor.cs +++ b/CrowIDE/src/SourceEditor/SourceEditor.cs @@ -44,6 +44,8 @@ namespace Crow.Coding /// public class SourceEditor : ScrollingObject { + public ReaderWriterLockSlim seMutex = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); + #region CTOR public SourceEditor (): base() { @@ -91,6 +93,8 @@ namespace Crow.Coding loadSource (); isDirty = false; oldSource = projFile.Source; + CurrentLine = requestedLine; + CurrentColumn = requestedCol; projFile.RegisteredEditors [this] = true; } buffer.editMutex.EnterWriteLock (); @@ -153,7 +157,7 @@ namespace Crow.Coding } void findLongestLineAndUpdateMaxScrollX() { buffer.FindLongestVisualLine (); - MaxScrollX = Math.Max (0, buffer.longestLineCharCount - visibleColumns); + updateMaxScrollX (); // Debug.WriteLine ("SourceEditor: Find Longest line and update maxscrollx: {0} visible cols:{1}", MaxScrollX, visibleColumns); } /// @@ -170,11 +174,16 @@ namespace Crow.Coding } void updateVisibleColumns(){ visibleColumns = (int)Math.Floor ((double)(ClientRectangle.Width - leftMargin)/ fe.MaxXAdvance); - MaxScrollX = Math.Max (0, buffer.longestLineCharCount - visibleColumns); - + NotifyValueChanged ("VisibleColumns", visibleColumns); + updateMaxScrollX (); // System.Diagnostics.Debug.WriteLine ("update visible columns: {0} leftMargin:{1}",visibleColumns, leftMargin); // System.Diagnostics.Debug.WriteLine ("update MaxScrollX: " + MaxScrollX); } + void updateMaxScrollX () { + MaxScrollX = Math.Max (0, buffer.longestLineCharCount - visibleColumns); + if (buffer.longestLineCharCount > 0) + NotifyValueChanged ("ChildWidthRatio", Slot.Width * visibleColumns / buffer.longestLineCharCount); + } void updateMaxScrollY () { if (parser == null || !foldingEnabled) { MaxScrollY = Math.Max (0, buffer.LineCount - visibleLines); @@ -188,6 +197,8 @@ namespace Crow.Coding } void updatePrintedLines () { buffer.editMutex.EnterReadLock (); + seMutex.EnterWriteLock (); + PrintedLines = new List (); int curL = 0; int i = 0; @@ -210,7 +221,9 @@ namespace Crow.Coding curL++; i++; } + buffer.editMutex.ExitReadLock (); + seMutex.ExitWriteLock (); } void toogleFolding (int line) { if (parser == null || !foldingEnabled) @@ -223,6 +236,8 @@ namespace Crow.Coding #region Buffer events handlers void Buffer_BufferCleared (object sender, EventArgs e) { + seMutex.EnterWriteLock (); + buffer.longestLineCharCount = 0; buffer.longestLineIdx = 0; measureLeftMargin (); @@ -231,6 +246,8 @@ namespace Crow.Coding RegisterForGraphicUpdate (); notifyPositionChanged (); isDirty = true; + + seMutex.ExitWriteLock (); } void Buffer_LineAdditionEvent (object sender, CodeBufferEventArgs e) { @@ -297,6 +314,14 @@ namespace Crow.Coding } void Buffer_PositionChanged (object sender, EventArgs e) { + Console.WriteLine ("Position changes: ({0},{1})", buffer.CurrentLine, buffer.CurrentColumn); + int cc = buffer.CurrentTabulatedColumn; + + if (cc > visibleColumns + ScrollX) { + ScrollX = cc - visibleColumns; + } else if (cc < ScrollX) + ScrollX = cc; + RegisterForGraphicUpdate (); updateOnScreenCurLineFromBuffCurLine (); notifyPositionChanged (); @@ -318,22 +343,29 @@ namespace Crow.Coding public int CurrentColumn{ get { return buffer == null ? 0 : buffer.CurrentColumn+1; } set { - try { + try { + if (value - 1 == buffer.CurrentColumn) + return; buffer.CurrentColumn = value - 1; } catch (Exception ex) { + requestedCol = value - 1; Console.WriteLine ("Error cur column: " + ex.ToString ()); } } } + int requestedLine = 0, requestedCol = 0; public int CurrentLine{ get { return buffer == null ? 0 : buffer.CurrentLine+1; } set { try { int l = value - 1; + if (l == buffer.CurrentLine) + return; buffer.CurrentLine = l; if (buffer [l].IsFolded) buffer.ToogleFolding (l); } catch (Exception ex) { + requestedLine = value - 1; Console.WriteLine ("Error cur column: " + ex.ToString ()); } } @@ -800,6 +832,8 @@ namespace Crow.Coding } #endregion + seMutex.EnterReadLock (); + if (PrintedLines != null) { for (int i = 0; i < visibleLines; i++) { if (i + ScrollY >= buffer.UnfoldedLines)//TODO:need optimize @@ -807,6 +841,9 @@ namespace Crow.Coding drawLine (gr, cb, i); } } + + seMutex.ExitReadLock (); + buffer.editMutex.ExitReadLock (); } diff --git a/CrowIDE/ui/MembersItem.template b/CrowIDE/ui/MembersItem.template index 812d7884..3a977490 100755 --- a/CrowIDE/ui/MembersItem.template +++ b/CrowIDE/ui/MembersItem.template @@ -5,6 +5,28 @@ + + + + + + - +