]> O.S.I.I.S - jp/crow.git/commitdiff
change namespace of CrowIDE to Crow.Coding, move editor source inside, crowIde wip
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sat, 24 Feb 2018 10:51:12 +0000 (11:51 +0100)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sat, 24 Feb 2018 10:51:12 +0000 (11:51 +0100)
37 files changed:
Crow.Test/Crow.Test.csproj
Crow.Test/Test.cs
Crow.sln
CrowIDE/CrowIDE.csproj
CrowIDE/src/CrowIDE.cs
CrowIDE/src/DesignInterface.cs
CrowIDE/src/EditPane.cs
CrowIDE/src/ImlVisualEditor.cs
CrowIDE/src/MembersView.cs
CrowIDE/src/Project.cs
CrowIDE/src/ProjectNodes.cs
CrowIDE/src/Solution.cs
CrowIDE/src/SolutionControler.cs
CrowIDE/src/SourceEditor/CSharpParser.cs [new file with mode: 0644]
CrowIDE/src/SourceEditor/CodeBuffer.cs [new file with mode: 0644]
CrowIDE/src/SourceEditor/CodeBufferEventArgs.cs [new file with mode: 0644]
CrowIDE/src/SourceEditor/CodeLine.cs [new file with mode: 0644]
CrowIDE/src/SourceEditor/Node.cs [new file with mode: 0644]
CrowIDE/src/SourceEditor/Parser.cs [new file with mode: 0644]
CrowIDE/src/SourceEditor/ParsingException.cs [new file with mode: 0644]
CrowIDE/src/SourceEditor/SourceEditor.cs [new file with mode: 0644]
CrowIDE/src/SourceEditor/TextFormatting.cs [new file with mode: 0644]
CrowIDE/src/SourceEditor/Token.cs [new file with mode: 0644]
CrowIDE/src/SourceEditor/XMLParser.cs [new file with mode: 0644]
CrowIDE/src/VerticalLine.cs
CrowIDE/ui/CrowIDE.crow
CrowIDE/ui/EditPane.template
CrowIDE/ui/EditPaneItems.template
CrowIDE/ui/GTreeExplorer.crow
CrowIDE/ui/MemberView.crow
CrowIDE/ui/ProjectProperties.crow
CrowIDE/ui/ProjectTree.template
Tests/InterfaceControler.cs
src/GraphicObjects/TabItem.cs
src/Instantiator.cs
src/Interface.cs
src/StyleReader.cs

index fb59dd1e183762505ad3c0995cad35826af3d83f..cf7b10a02e8fa54289ff6e79231f12c069dedb4b 100644 (file)
     <DebugSymbols>true</DebugSymbols>
     <DebugType>full</DebugType>
     <Optimize>false</Optimize>
-    <OutputPath>bin\Debug</OutputPath>
     <DefineConstants>DEBUG;</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <Optimize>true</Optimize>
-    <OutputPath>bin\Release</OutputPath>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
index e21177f89f376336c68654b8a9c07cf334adab24..d4d978569712a9db61149fdc8ccc2b891c5619bd 100644 (file)
@@ -36,6 +36,7 @@ namespace UnitTest
                public void Init ()
                {
                        iface = new Interface ();
+                       iface.Init ();
                        iface.ProcessResize (bounds);
                }
 
index 61aaa3af8775aeb9a09a749f64f9daf9dd49ede9..4d3e4799a67c4b3fde83e9f15040bd191ec63be1 100644 (file)
--- a/Crow.sln
+++ b/Crow.sln
@@ -9,8 +9,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Crow.Test", "Crow.Test\Crow
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CrowIDE", "CrowIDE\CrowIDE.csproj", "{B6D911CD-1D09-42FC-B300-9187190F2AE1}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Crow.Coding", "..\gts\CrowEdit\Crow.Coding\Crow.Coding.csproj", "{78842EE4-8A2F-4C75-AEC6-C95F15AD3994}"
-EndProject
 Global
        GlobalSection(SolutionConfigurationPlatforms) = preSolution
                Debug|Any CPU = Debug|Any CPU
@@ -31,39 +29,27 @@ Global
                {C2980F9B-4798-4C05-99E2-E174810F7C7B}.Debug|Any CPU.Build.0 = Debug|Any CPU
                {C2980F9B-4798-4C05-99E2-E174810F7C7B}.Release|Any CPU.ActiveCfg = Release|Any CPU
                {C2980F9B-4798-4C05-99E2-E174810F7C7B}.Release|Any CPU.Build.0 = Release|Any CPU
-               {78842EE4-8A2F-4C75-AEC6-C95F15AD3994}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-               {78842EE4-8A2F-4C75-AEC6-C95F15AD3994}.Debug|Any CPU.Build.0 = Debug|Any CPU
-               {78842EE4-8A2F-4C75-AEC6-C95F15AD3994}.Release|Any CPU.ActiveCfg = Release|Any CPU
-               {78842EE4-8A2F-4C75-AEC6-C95F15AD3994}.Release|Any CPU.Build.0 = Release|Any CPU
        EndGlobalSection
        GlobalSection(MonoDevelopProperties) = preSolution
                Policies = $0
                $0.StandardHeader = $1
                $1.Text = @\n${FileName}\n \nAuthor:\n      ${AuthorName} <${AuthorEmail}>\n\nCopyright (c) 2013-2017 Jean-Philippe Bruyère\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the "Software"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.
+               $1.IncludeInNewFiles = True
                $0.DotNetNamingPolicy = $2
+               $2.DirectoryNamespaceAssociation = None
+               $2.ResourceNamePolicy = FileFormatDefault
                $0.TextStylePolicy = $3
+               $3.FileWidth = 120
+               $3.TabsToSpaces = False
                $3.EolMarker = Unix
+               $3.inheritsSet = VisualStudio
+               $3.inheritsScope = text/plain
                $3.scope = text/x-csharp
                $0.CSharpFormattingPolicy = $4
                $4.AfterDelegateDeclarationParameterComma = True
+               $4.inheritsSet = Mono
+               $4.inheritsScope = text/x-csharp
                $4.scope = text/x-csharp
-               $4.IndentSwitchSection = False
-               $4.NewLinesForBracesInProperties = False
-               $4.NewLinesForBracesInAccessors = False
-               $4.NewLinesForBracesInAnonymousMethods = False
-               $4.NewLinesForBracesInControlBlocks = False
-               $4.NewLinesForBracesInAnonymousTypes = False
-               $4.NewLinesForBracesInObjectCollectionArrayInitializers = False
-               $4.NewLinesForBracesInLambdaExpressionBody = False
-               $4.NewLineForElse = False
-               $4.NewLineForCatch = False
-               $4.NewLineForFinally = False
-               $4.NewLineForMembersInObjectInit = False
-               $4.NewLineForMembersInAnonymousTypes = False
-               $4.NewLineForClausesInQuery = False
-               $4.SpacingAfterMethodDeclarationName = True
-               $4.SpaceAfterMethodCallName = True
-               $4.SpaceBeforeOpenSquareBracket = True
                $0.VersionControlPolicy = $5
                $5.CommitMessageStyle = $6
                $6.Indent = @\t
@@ -71,6 +57,7 @@ Global
                $6.LastFilePostfix = "@:\n  "
                $6.LineAlign = 0
                $6.Wrap = False
+               $5.inheritsSet = Mono
                description = @C.R.O.W. c# Rapid Open Widgets\n\nCrow is a pure c# widget toolkit with XML definition of interface, bindings, styling...\n
                version = 0.5
        EndGlobalSection
index 10944136d40abac7761ac0a5814a6844acb12c41..1f6b3c8a6f5ad3e5ea5ae6735d4c0d0f1ed7442e 100644 (file)
@@ -7,7 +7,7 @@
     <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{B6D911CD-1D09-42FC-B300-9187190F2AE1}</ProjectGuid>
     <OutputType>Exe</OutputType>
-    <RootNamespace>CrowIDE</RootNamespace>
+    <RootNamespace>Crow.Coding</RootNamespace>
     <AssemblyName>CrowIDE</AssemblyName>
     <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
     <OutputPath>$(SolutionDir)build/$(Configuration)</OutputPath>
@@ -18,7 +18,7 @@
       </CustomCommands>
     </CustomCommands>
     <ReleaseVersion>0.5</ReleaseVersion>
-    <StartupObject>CrowIDE.CrowIDE</StartupObject>
+    <StartupObject>Crow.Coding.CrowIDE</StartupObject>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
@@ -28,8 +28,6 @@
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
     <ConsolePause>false</ConsolePause>
-    <IntermediateOutputPath>$(SolutionDir)build\obj\$(Configuration)</IntermediateOutputPath>
-    <OutputPath>$(SolutionDir)build\$(Configuration)</OutputPath>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <DebugType>none</DebugType>
@@ -37,8 +35,6 @@
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>0</WarningLevel>
     <ConsolePause>false</ConsolePause>
-    <IntermediateOutputPath>$(SolutionDir)build\obj\$(Configuration)</IntermediateOutputPath>
-    <OutputPath>$(SolutionDir)build\$(Configuration)</OutputPath>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(RunConfiguration)' == 'Default' ">
     <StartAction>Program</StartAction>
       <Project>{C2980F9B-4798-4C05-99E2-E174810F7C7B}</Project>
       <Name>Crow</Name>
     </ProjectReference>
-    <ProjectReference Include="..\..\gts\CrowEdit\Crow.Coding\Crow.Coding.csproj">
-      <Project>{78842EE4-8A2F-4C75-AEC6-C95F15AD3994}</Project>
-      <Name>Crow.Coding</Name>
-    </ProjectReference>
   </ItemGroup>
   <ItemGroup>
     <Compile Include="src\CrowIDE.cs" />
     <Compile Include="src\ProjectNodes.cs" />
     <Compile Include="src\SolutionControler.cs" />
     <Compile Include="src\INetProject.cs" />
+    <Compile Include="src\SourceEditor\CodeBuffer.cs" />
+    <Compile Include="src\SourceEditor\CodeBufferEventArgs.cs" />
+    <Compile Include="src\SourceEditor\CodeLine.cs" />
+    <Compile Include="src\SourceEditor\CSharpParser.cs" />
+    <Compile Include="src\SourceEditor\Node.cs" />
+    <Compile Include="src\SourceEditor\Parser.cs" />
+    <Compile Include="src\SourceEditor\ParsingException.cs" />
+    <Compile Include="src\SourceEditor\SourceEditor.cs" />
+    <Compile Include="src\SourceEditor\TextFormatting.cs" />
+    <Compile Include="src\SourceEditor\Token.cs" />
+    <Compile Include="src\SourceEditor\XMLParser.cs" />
   </ItemGroup>
   <ItemGroup>
     <Folder Include="ui\" />
     <Folder Include="src\" />
     <Folder Include="images\" />
+    <Folder Include="src\SourceEditor\" />
   </ItemGroup>
   <ItemGroup>
     <EmbeddedResource Include="images\save.svg" />
     <EmbeddedResource Include="ui\IDE.style" />
     <EmbeddedResource Include="ui\MembersView.template">
-      <LogicalName>CrowIDE.MembersView.template</LogicalName>
+      <LogicalName>Crow.Coding.MembersView.template</LogicalName>
     </EmbeddedResource>
     <EmbeddedResource Include="ui\LQIsExplorer.crow" />
     <EmbeddedResource Include="ui\GTreeExplorer.crow" />
     <EmbeddedResource Include="ui\ProjectTree.template" />
     <EmbeddedResource Include="ui\MembersItem.template" />
     <EmbeddedResource Include="ui\EditPane.template">
-      <LogicalName>CrowIDE.EditPane.template</LogicalName>
+      <LogicalName>Crow.Coding.EditPane.template</LogicalName>
     </EmbeddedResource>
     <EmbeddedResource Include="ui\EditPaneItems.template" />
     <EmbeddedResource Include="ui\CrowIDE.crow" />
index 2e0f29012679ba2b84da489b217d11d1d126c8a0..eeedeb639c870c3652fd0fdc888943357033c9a1 100644 (file)
@@ -32,8 +32,9 @@ using Crow.IML;
 using System.Xml;
 using System.Linq;
 using Crow.Coding;
+using System.Threading;
 
-namespace CrowIDE
+namespace Crow.Coding
 {
        class CrowIDE : CrowWindow
        {
@@ -44,23 +45,23 @@ namespace CrowIDE
                CMDCompile;
 
                void initCommands () {
-                       CMDNew = new Command(new Action(() => newFile())) { Caption = "New", Icon = new SvgPicture("#CrowIDE.ui.icons.blank-file.svg"), CanExecute = false};
-                       CMDOpen = new Command(new Action(() => openFileDialog())) { Caption = "Open...", Icon = new SvgPicture("#CrowIDE.ui.icons.outbox.svg")};
-                       CMDSave = new Command(new Action(() => saveFileDialog())) { Caption = "Save", Icon = new SvgPicture("#CrowIDE.ui.icons.inbox.svg"), CanExecute = false};
-                       CMDSaveAs = new Command(new Action(() => saveFileDialog())) { Caption = "Save As...", Icon = new SvgPicture("#CrowIDE.ui.icons.inbox.svg"), CanExecute = false};
-                       CMDQuit = new Command(new Action(() => Quit (null, null))) { Caption = "Quit", Icon = new SvgPicture("#CrowIDE.ui.icons.sign-out.svg")};
-                       CMDUndo = new Command(new Action(() => undo())) { Caption = "Undo", Icon = new SvgPicture("#CrowIDE.ui.icons.reply.svg"), CanExecute = false};
-                       CMDRedo = new Command(new Action(() => redo())) { Caption = "Redo", Icon = new SvgPicture("#CrowIDE.ui.icons.share-arrow.svg"), CanExecute = false};
-                       CMDCut = new Command(new Action(() => Quit (null, null))) { Caption = "Cut", Icon = new SvgPicture("#CrowIDE.ui.icons.scissors.svg"), CanExecute = false};
-                       CMDCopy = new Command(new Action(() => Quit (null, null))) { Caption = "Copy", Icon = new SvgPicture("#CrowIDE.ui.icons.copy-file.svg"), CanExecute = false};
-                       CMDPaste = new Command(new Action(() => Quit (null, null))) { Caption = "Paste", Icon = new SvgPicture("#CrowIDE.ui.icons.paste-on-document.svg"), CanExecute = false};
-                       CMDHelp = new Command(new Action(() => System.Diagnostics.Debug.WriteLine("help"))) { Caption = "Help", Icon = new SvgPicture("#CrowIDE.ui.icons.question.svg")};
-                       CMDOptions = new Command(new Action(() => openOptionsDialog())) { Caption = "Editor Options", Icon = new SvgPicture("#CrowIDE.ui.icons.tools.svg")};
-
-                       CMDViewGTExp = new Command(new Action(() => loadWindow ("#CrowIDE.ui.GTreeExplorer.crow"))) { Caption = "Graphic Tree Explorer"};
-                       CMDViewProps = new Command(new Action(() => loadWindow ("#CrowIDE.ui.MemberView.crow"))) { Caption = "Properties View"};
+                       CMDNew = new Command(new Action(() => newFile())) { Caption = "New", Icon = new SvgPicture("#Crow.Coding.ui.icons.blank-file.svg"), CanExecute = false};
+                       CMDOpen = new Command(new Action(() => openFileDialog())) { Caption = "Open...", Icon = new SvgPicture("#Crow.Coding.ui.icons.outbox.svg")};
+                       CMDSave = new Command(new Action(() => saveFileDialog())) { Caption = "Save", Icon = new SvgPicture("#Crow.Coding.ui.icons.inbox.svg"), CanExecute = false};
+                       CMDSaveAs = new Command(new Action(() => saveFileDialog())) { Caption = "Save As...", Icon = new SvgPicture("#Crow.Coding.ui.icons.inbox.svg"), CanExecute = false};
+                       CMDQuit = new Command(new Action(() => Quit (null, null))) { Caption = "Quit", Icon = new SvgPicture("#Crow.Coding.ui.icons.sign-out.svg")};
+                       CMDUndo = new Command(new Action(() => undo())) { Caption = "Undo", Icon = new SvgPicture("#Crow.Coding.ui.icons.reply.svg"), CanExecute = false};
+                       CMDRedo = new Command(new Action(() => redo())) { Caption = "Redo", Icon = new SvgPicture("#Crow.Coding.ui.icons.share-arrow.svg"), CanExecute = false};
+                       CMDCut = new Command(new Action(() => Quit (null, null))) { Caption = "Cut", Icon = new SvgPicture("#Crow.Coding.ui.icons.scissors.svg"), CanExecute = false};
+                       CMDCopy = new Command(new Action(() => Quit (null, null))) { Caption = "Copy", Icon = new SvgPicture("#Crow.Coding.ui.icons.copy-file.svg"), CanExecute = false};
+                       CMDPaste = new Command(new Action(() => Quit (null, null))) { Caption = "Paste", Icon = new SvgPicture("#Crow.Coding.ui.icons.paste-on-document.svg"), CanExecute = false};
+                       CMDHelp = new Command(new Action(() => System.Diagnostics.Debug.WriteLine("help"))) { Caption = "Help", Icon = new SvgPicture("#Crow.Coding.ui.icons.question.svg")};
+                       CMDOptions = new Command(new Action(() => openOptionsDialog())) { Caption = "Editor Options", Icon = new SvgPicture("#Crow.Coding.ui.icons.tools.svg")};
+
+                       CMDViewGTExp = new Command(new Action(() => loadWindow ("#Crow.Coding.ui.GTreeExplorer.crow"))) { Caption = "Graphic Tree Explorer"};
+                       CMDViewProps = new Command(new Action(() => loadWindow ("#Crow.Coding.ui.MemberView.crow"))) { Caption = "Properties View"};
                        CMDCompile = new Command(new Action(() => compileSolution())) { Caption = "Compile"};
-                       CMDViewProj = new Command(new Action(() => loadWindow ("#CrowIDE.ui.CSProjExplorer.crow"))) { Caption = "Project Explorer"};
+                       CMDViewProj = new Command(new Action(() => loadWindow ("#Crow.Coding.ui.CSProjExplorer.crow"))) { Caption = "Project Explorer"};
                        CMDViewProjProps = new Command(new Action(loadProjProps) ){ Caption = "Project Properties"};
                }
 
@@ -85,10 +86,8 @@ namespace CrowIDE
                        : base(1024, 800,"UIEditor")
                {
                }
-               ImlVisualEditor imlVE;
 
                Instantiator instFileDlg;
-
                Solution currentSolution;
 
                protected override void OnLoad (EventArgs e)
@@ -102,10 +101,9 @@ namespace CrowIDE
 
                        this.KeyDown += CrowIDE_KeyDown;
 
-                       //this.CrowInterface.LoadInterface ("#CrowIDE.ui.imlEditor.crow").DataSource = this;
+                       //this.CrowInterface.LoadInterface ("#Crow.Coding.ui.imlEditor.crow").DataSource = this;
                        //GraphicObject go = this.CrowInterface.LoadInterface (@"ui/test.crow");
-                       GraphicObject go = AddWidget (@"#CrowIDE.ui.CrowIDE.crow");
-                       imlVE = go.FindByName ("crowContainer") as ImlVisualEditor;
+                       GraphicObject go = AddWidget (@"#Crow.Coding.ui.CrowIDE.crow");
                        if (ReopenLastSolution && !string.IsNullOrEmpty(LastOpenSolution))
                                CurrentSolution = Solution.LoadSolution (LastOpenSolution);
 
@@ -114,7 +112,7 @@ namespace CrowIDE
                }
 
                void loadProjProps () {
-                       //loadWindow ("#CrowIDE.ui.ProjectProperties.crow", currentProject);
+                       //loadWindow ("#Crow.Coding.ui.ProjectProperties.crow", currentProject);
                }
                void compileSolution () {
                        //ProjectItem pi = CurrentSolution.SelectedItem;
@@ -190,9 +188,9 @@ namespace CrowIDE
                                }
 
                        }// else if (e.Key == OpenTK.Input.Key.F6) {
-//                             loadWindow ("#CrowIDE.ui.LQIsExplorer.crow");
+//                             loadWindow ("#Crow.Coding.ui.LQIsExplorer.crow");
 //                     } else if (e.Key == OpenTK.Input.Key.F7) {
-//                             loadWindow ("#CrowIDE.ui.CSProjExplorer.crow");
+//                             loadWindow ("#Crow.Coding.ui.CSProjExplorer.crow");
 //                     }
                }
                void loadWindow(string path, object dataSource = null){
@@ -202,10 +200,7 @@ namespace CrowIDE
                                        return;
                                g = CurrentInterface.AddWidget (path);
                                g.Name = path;
-                               if (dataSource == null)
-                                       g.DataSource = imlVE;
-                               else
-                                       g.DataSource = dataSource;
+                               g.DataSource = dataSource;
                        } catch (Exception ex) {
                                System.Diagnostics.Debug.WriteLine (ex.ToString ());
                        }
index 10ceffc51166e6413348ee7a05d97614fde936b7..0ac3e3ba795f253d20254125246df4256d5e373e 100644 (file)
@@ -27,7 +27,7 @@ using System;
 using Crow;
 using System.Globalization;
 
-namespace CrowIDE
+namespace Crow.Coding
 {
        public class DesignInterface : Interface, IValueChange
        {
@@ -48,17 +48,35 @@ namespace CrowIDE
                        ValueChanged.Raise(this, new ValueChangeEventArgs(MemberName, _value));
                }
                #endregion
+
                public DesignInterface ()
                {
-                       CurrentInterface = this;
-                       CultureInfo.DefaultThreadCurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
                }
 
-               protected override void loadStyling ()
+               public ProjectFile ProjFile;
+
+               public override GraphicObject Load (string path)
                {
-                       base.loadStyling ();
+                       ProjectFile pi;
+                       if (ProjFile.Project.solution.GetProjectFileFromPath (path, out pi))
+                               return CreateITorFromIMLFragment (pi.Source).CreateInstance();                  
+                       return null;
+               }
+               public override Crow.IML.Instantiator GetInstantiator (string path)
+               {                       
+                       System.Diagnostics.Debugger.Break ();
+                       return null;
                }
+               public override ItemTemplate GetItemTemplate (string path)
+               {
+                       ProjectFile pi;
+
+                       if (ProjFile.Project.solution.GetProjectFileFromPath (path, out pi))
+                               return new ItemTemplate (this, pi.AbsolutePath);
 
+                       System.Diagnostics.Debugger.Break ();
+                       return null;
+               }
                public override bool ProcessMouseMove (int x, int y)
                {
                        int deltaX = x - Mouse.X;
index a1103909bdc5978cc88f7c9ed5fd193d2fff235d..d7ddba5ae5485b1ef04e222a5c4b87a34579ea86 100644 (file)
@@ -27,20 +27,14 @@ using System;
 using Crow;
 using System.Linq;
 
-namespace CrowIDE
+namespace Crow.Coding
 {
        public class EditPane : TemplatedGroup
        {
                public EditPane () : base()
                {
                }
-               public override object SelectedItem {
-                       get { return base.SelectedItem; }
-                       set {
-                               base.SelectedItem = value;
-                               //Items.FirstOrDefault (i=>i.DataSource == value).
-                       }
-               }
+
                object selectedItemElement = null;
 
                public object SelectedItemElement {
index 9e7aae3940fa97a4f44c301b9393541fb4b98714..74187b2e6aa3190861fca1d013fef5d9054867f6 100644 (file)
@@ -27,7 +27,7 @@ using System.IO;
 using System.Collections.Generic;
 using Crow.IML;
 
-namespace CrowIDE
+namespace Crow.Coding
 {
        public class ImlVisualEditor : GraphicObject
        {
@@ -42,15 +42,13 @@ namespace CrowIDE
                #endregion
 
                DesignInterface imlVE;
-               Instantiator itor;
                GraphicObject selectedItem;
-               string imlSource;
-               ProjectItem projectItem;
+               ImlProjectItem projectItem;
+               Exception imlError = null;
 
                bool drawGrid;
                int gridSpacing;
 
-
                [XmlAttributeAttribute][DefaultValue(true)]
                public bool DrawGrid {
                        get { return drawGrid; }
@@ -97,23 +95,6 @@ namespace CrowIDE
                [XmlIgnore]public List<LQIList> LQIs {
                        get { return imlVE.LQIs; }
                }
-               [XmlIgnore]public string ImlSource {
-                       get { return imlSource; }
-                       set {
-                               if (imlSource == value)
-                                       return;
-                               imlSource = value;
-
-                               NotifyValueChanged ("ImlSource", ImlSource);
-
-                               reloadFromSource ();
-                       }
-               }
-               [XmlAttributeAttribute][DefaultValue("")]
-               public string ImlPath {
-                       get { return projectItem?.Path; }
-               }
-
 
                [XmlAttributeAttribute]
                public ProjectNode ProjectNode {
@@ -122,62 +103,56 @@ namespace CrowIDE
                                if (projectItem == value)
                                        return;
 
-                               if (!(value is ProjectItem))
-                                       return;
 
-                               projectItem = value as ProjectItem;
+                               if (projectItem != null)
+                                       projectItem.ValueChanged -= ProjectItem_ValueChanged;
+
+                               projectItem = value as ImlProjectItem;
 
-                               NotifyValueChanged ("ImlPath", ImlPath);
+                               if (projectItem != null)
+                                       projectItem.ValueChanged += ProjectItem_ValueChanged;
 
-                               reloadFromPath ();
+                               NotifyValueChanged ("ProjectNode", projectItem);
+
+                               reload ();
                        }
                }
-               public List<GraphicObject> GraphicTree {
-                       get { return imlVE.GraphicTree; }
+
+               void ProjectItem_ValueChanged (object sender, ValueChangeEventArgs e)
+               {
+                       if (e.MemberName == "Source")
+                               reload ();                      
                }
 
-               void reloadFromSource(){
-                       if (string.IsNullOrEmpty (imlSource)) {
-                               reload_iTor (null);
-                               return;
+               [XmlIgnore]public Exception IMLError {
+                       get { return imlError; }
+                       set {
+                               if (imlError == value)
+                                       return;
+                               imlError = value;
+                               NotifyValueChanged ("IMLError", imlError);
                        }
+               }
 
-                       Instantiator iTmp;
+               void reload(){
+                       if (projectItem == null)                                
+                               return;
+                       
                        try {
-                               iTmp = Instantiator.CreateFromImlFragment (imlVE, imlSource);
+                               imlVE.ProjFile = projectItem;
+                               imlVE.Styling = projectItem.Project.solution.Styling;
+                               imlVE.DefaultTemplates = projectItem.Project.solution.DefaultTemplates;
+                               imlVE.Instantiators = new Dictionary<string, Instantiator>();
+                               imlVE.ClearInterface();
+                               imlVE.LoadIMLFragment(projectItem.Source);
+                               IMLError = null;
                        } catch (Exception ex) {
-                               System.Diagnostics.Debug.WriteLine (ex.ToString());
-                               return;
-                       }
-
-                       reload_iTor (iTmp);
-               }
-               void reloadFromPath(){
-                       string path = Path.Combine (projectItem?.Project.RootDir,projectItem?.Path);
-                       if (!File.Exists (path)){
-                               System.Diagnostics.Debug.WriteLine ("Path not found: " + path);
-                               reload_iTor (null);
-                               return;
-                       }
-                       using (StreamReader sr = new StreamReader (path)) {
-                               ImlSource = sr.ReadToEnd ();
+                               IMLError = ex;
                        }
-                       NotifyValueChanged ("GraphicTree", null);
-                       NotifyValueChanged ("GraphicTree", GraphicTree);
-                       SelectedItem = null;
                }
-               void reload_iTor(Instantiator new_iTot){
-                       itor = new_iTot;
-                       lock (imlVE.UpdateMutex) {
-                               try {
-                                       imlVE.ClearInterface ();
-                                       if (itor != null)
-                                               imlVE.AddWidget(itor.CreateInstance());
 
-                               } catch (Exception ex) {
-                                       System.Diagnostics.Debug.WriteLine (ex.ToString());
-                               }
-                       }
+               public List<GraphicObject> GraphicTree {
+                       get { return imlVE.GraphicTree; }
                }
 
                void interfaceThread()
@@ -202,7 +177,7 @@ namespace CrowIDE
                                                RegisterForRedraw ();
                                }
 
-                               Thread.Sleep (2);
+                               Thread.Sleep (10);
                        }
                }
 
@@ -282,7 +257,7 @@ namespace CrowIDE
                                gr.Rectangle (hr, 1.0);
                        }
 
-                       if (SelectedItem == null)
+                       if (SelectedItem?.Parent == null)
                                return;
                        hr = SelectedItem.ScreenCoordinates(SelectedItem.getSlot ());
                        hr.Inflate (1);
index 00d3023eaa86998c0a1ae03c02105a1d6bf3a805..48b3e074b4b37ad7e43ac853b7cb62a1be31c5d5 100644 (file)
@@ -26,7 +26,7 @@ using System.Reflection;
 using System.Collections.Generic;
 using System.Linq;
 
-namespace CrowIDE
+namespace Crow.Coding
 {
        public class PropertyContainer : IValueChange
        {
index 40f14f80980ed11222b1ebd55cd3c6e05669aae0..098cfdd26be32e7c5df1ce707009f9d7829d3c16 100644 (file)
@@ -33,7 +33,7 @@ using System.CodeDom.Compiler;
 using Crow;
 using System.Text.RegularExpressions;
 
-namespace CrowIDE
+namespace Crow.Coding
 {      
        public class Project: IValueChange
        {
@@ -270,9 +270,7 @@ namespace CrowIDE
                        }
                        return tmp;
                }
-               public string Compile () {
-                       GetStyling ();
-
+               public string Compile () {                      
                        if (ParentProject != null)
                                ParentProject.Compile ();
 
@@ -378,13 +376,83 @@ namespace CrowIDE
                        solution.UpdateErrorList ();
 
                        return parameters.OutputAssembly;
-               }       
+               }
+
+               public bool GetProjectFileFromPath (string path, out ProjectFile pi){
+                       if (path.StartsWith ("#"))
+                               pi = flattenNodes.OfType<ProjectFile> ().FirstOrDefault 
+                                       (pp => pp.Type == ItemType.EmbeddedResource && pp.ResourceID == path.Substring (1));
+                       else
+                               pi = flattenNodes.OfType<ProjectFile> ().FirstOrDefault (pp => pp.Path == path);
+
+                       if (pi != null)
+                               return true;
+
+                       foreach (ProjectReference pr in flattenNodes.OfType<ProjectReference>()) {                              
+                               Project p = solution.Projects.FirstOrDefault (pp => pp.ProjectGuid == pr.ProjectGUID);
+                               if (p == null)
+                                       throw new Exception ("referenced project not found");
+                               if (p.GetProjectFileFromPath (path, out pi))
+                                       return true;
+                       }
+                       //TODO: search referenced assemblies
+                       return false;
+               }
+
+               public void GetDefaultTemplates () {
+                       IEnumerable<ProjectFile> tmpFiles =
+                               flattenNodes.OfType<ProjectFile> ().Where (pp => pp.Extension == ".template" );
+                       
+                       foreach (ProjectFile pi in tmpFiles.Where(
+                               pp=>pp.Type == ItemType.None && pp.CopyToOutputDirectory != CopyToOutputState.Never)) {
+
+                               string clsName = System.IO.Path.GetFileNameWithoutExtension(pi.Path);
+                               if (solution.DefaultTemplates.ContainsKey (clsName))
+                                       continue;
+                               solution.DefaultTemplates [clsName] = pi.AbsolutePath;
+                       }
+                       foreach (ProjectFile pi in tmpFiles.Where(pp=>pp.Type == ItemType.EmbeddedResource)) {                          
+                               string resId = pi.ResourceID;
+                               string clsName = resId.Substring (0, resId.Length - 9);
+                               if (solution.DefaultTemplates.ContainsKey (clsName))
+                                       continue;
+                               solution.DefaultTemplates [clsName] = pi.Path;
+                       }
+
+                       foreach (ProjectReference pr in flattenNodes.OfType<ProjectReference>()) {                              
+                               Project p = solution.Projects.FirstOrDefault (pp => pp.ProjectGuid == pr.ProjectGUID);
+                               if (p == null)
+                                       throw new Exception ("referenced project not found");
+                               p.GetDefaultTemplates ();
+                       }
+               }
+//             void searchTemplatesIn(Assembly assembly){
+//                     if (assembly == null)
+//                             return;
+//                     foreach (string resId in assembly
+//                             .GetManifestResourceNames ()
+//                             .Where (r => r.EndsWith (".template", StringComparison.OrdinalIgnoreCase))) {
+//                             string clsName = resId.Substring (0, resId.Length - 9);
+//                             if (DefaultTemplates.ContainsKey (clsName))
+//                                     continue;
+//                             DefaultTemplates[clsName] = "#" + resId;
+//                     }
+//             }
 
-       
                public void GetStyling () {
-                       foreach (ProjectFile pi in flattenNodes.OfType<ProjectFile> ().Where (pp=>pp.Type == ItemType.EmbeddedResource)) {
-                               Console.WriteLine (pi.Extension);
-                       }                       
+                       foreach (ProjectFile pi in flattenNodes.OfType<ProjectFile> ().Where (pp=>pp.Type == ItemType.EmbeddedResource && pp.Extension == ".style")) {
+                               using (Stream s = new MemoryStream (System.Text.Encoding.UTF8.GetBytes(pi.Source))) {
+                                       new StyleReader (solution.Styling, s, pi.ResourceID);
+                               }
+                       }
+                       foreach (ProjectReference pr in flattenNodes.OfType<ProjectReference>()) {                              
+                               Project p = solution.Projects.FirstOrDefault (pp => pp.ProjectGuid == pr.ProjectGUID);
+                               if (p == null)
+                                       throw new Exception ("referenced project not found");
+                               p.GetStyling();
+                       }
+
+                       //TODO:get styling from referenced assemblies
                }
        }
 }
index bdabbdd82114a08df81fa748dde070d368f23fcb..ac2602e359d820ee99a33a13a492e39973a246f7 100644 (file)
@@ -30,7 +30,7 @@ using System.Xml;
 using System.IO;
 using Crow;
 
-namespace CrowIDE
+namespace Crow.Coding
 {
        public enum ItemType {
                ReferenceGroup,
@@ -144,11 +144,24 @@ namespace CrowIDE
        }
        public class ProjectFile : ProjectItem {
                bool isDirty = false;
+               bool isOpened = false;
+//             bool isSelected = false;
+               DateTime accessTime;
+               string source;
                object selectedItem;
 
+
                public ProjectFile (ProjectItem pi) : base (pi.Project, pi.node){                       
                }
 
+               public string ResourceID {
+                       get {                           
+                               return Type != ItemType.EmbeddedResource ? null :
+                                       node.SelectSingleNode ("LogicalName") == null ?
+                                       Project.Name + "." + Path.Replace ('/', '.') :
+                                       LogicalName;
+                       }
+               }
                public string LogicalName {
                        get {
                                return node.SelectSingleNode ("LogicalName")?.InnerText;
@@ -156,11 +169,39 @@ namespace CrowIDE
                }
                public string Source {
                        get {
-                               using (StreamReader sr = new StreamReader (AbsolutePath)) {
-                                       return sr.ReadToEnd ();
-                               }                               
+                               if (!isOpened) {
+                                       accessTime = System.IO.File.GetLastWriteTime (AbsolutePath);
+                                       using (StreamReader sr = new StreamReader (AbsolutePath)) {
+                                               source = sr.ReadToEnd ();
+                                       }
+                                       isOpened = true;
+                                       isDirty = false;
+                               } else {
+                                       if (DateTime.Compare (
+                                                   accessTime,
+                                                   System.IO.File.GetLastWriteTime (AbsolutePath)) < 0)
+                                               Console.WriteLine ("File has been modified outside CrowIDE");
+                               }
+                               return source;
+                       }
+                       set {
+                               if (source == value)
+                                       return;
+                               source = value;
+                               NotifyValueChanged ("Source", source);
                        }
                }
+                       
+//             public bool IsSelected {
+//                     get { return isSelected; }
+//                     set { 
+//                             if (isSelected == value)
+//                                     return;
+//                             isSelected = value;
+//                             NotifyValueChanged ("IsSelected", isSelected);                          
+//                     }
+//             }
+
                public object SelectedItem {
                        get { return selectedItem; }
                        set {
index c971b84783dbc0555d687201564c17dc88e4974c..1c1bac70091ddfddd1ebb254b0d884967f1fcd9d 100644 (file)
@@ -21,7 +21,7 @@ using System.Text.RegularExpressions;
 using System.Xml.Serialization;
 using Crow;
 
-namespace CrowIDE{     
+namespace Crow.Coding{ 
        public class SolutionProject {
                public string ProjectHostGuid;
                public string ProjectName;
@@ -45,6 +45,29 @@ namespace CrowIDE{
                object selectedItemElement = null;
                ObservableList<ProjectItem> openedItems = new ObservableList<ProjectItem>();
 
+               public Dictionary<string, Style> Styling;
+               public Dictionary<string, string> DefaultTemplates;
+
+               //TODO: check project dependencies if no startup proj
+
+               public void ReloadStyling () {
+                       Styling = new Dictionary<string, Style> ();
+                       if (StartupProject != null)
+                               StartupProject.GetStyling ();
+               }
+
+               public void ReloadDefaultTemplates () {
+                       DefaultTemplates = new Dictionary<string, string>();
+                       if (StartupProject != null)
+                               StartupProject.GetDefaultTemplates ();
+               }
+               public bool GetProjectFileFromPath (string path, out ProjectFile pi){
+                       pi = null;
+                       return StartupProject == null ? false :
+                               StartupProject.GetProjectFileFromPath (path, out pi);
+               }
+
+
                public ObservableList<ProjectItem> OpenedItems {
                        get { return openedItems; }
                        set {
@@ -209,7 +232,8 @@ namespace CrowIDE{
                                        value.NotifyValueChanged("IsStartupProject", true);
                                }
                                NotifyValueChanged ("StartupProject", StartupProject);
-
+                               ReloadStyling ();
+                               ReloadDefaultTemplates ();
                        }
                }
 
@@ -384,7 +408,8 @@ namespace CrowIDE{
                ));
 
                        s.UserConfig = new Configuration (s.path + ".user");
-
+                       s.ReloadStyling ();
+                       s.ReloadDefaultTemplates ();
                return s;
            } //LoadSolution
                #endregion
index dec1a8d28906cf9049c0645f55bf1633b612ddda..edb6b0ddb7b742b3f8ba8055d52433d17b1c6706 100644 (file)
@@ -25,7 +25,7 @@
 // THE SOFTWARE.
 using System;
 
-namespace CrowIDE
+namespace Crow.Coding
 {
        public class SolutionControler
        {
diff --git a/CrowIDE/src/SourceEditor/CSharpParser.cs b/CrowIDE/src/SourceEditor/CSharpParser.cs
new file mode 100644 (file)
index 0000000..7d2e28e
--- /dev/null
@@ -0,0 +1,45 @@
+using System;
+using Crow;
+
+namespace Crow.Coding
+{
+       public class CSharpParser : Parser
+       {
+               public new enum TokenType {
+                       Unknown = Parser.TokenType.Unknown,
+                       WhiteSpace = Parser.TokenType.WhiteSpace,
+                       LineComment = Parser.TokenType.LineComment,
+                       BlockComment = Parser.TokenType.BlockComment,
+                       OpenParenth,
+                       CloseParenth,
+                       OpenBlock,
+                       CloseBlock,
+                       StatementEnding,
+                       UnaryOp,
+                       BinaryOp,
+                       Affectation,
+                       StringLiteral,
+                       CharacterLiteral,
+                       DigitalLiteral,
+                       Literal,
+                       Identifier,
+                       Indexer,
+                       Type,
+                       Preprocessor,
+               }
+
+               public CSharpParser (CodeBuffer _buffer) : base(_buffer)
+               {
+               }
+
+               public override void ParseCurrentLine ()
+               {
+                       throw new NotImplementedException ();
+               }
+               public override void SyntaxAnalysis ()
+               {
+                       throw new NotImplementedException ();
+               }
+       }
+}
+
diff --git a/CrowIDE/src/SourceEditor/CodeBuffer.cs b/CrowIDE/src/SourceEditor/CodeBuffer.cs
new file mode 100644 (file)
index 0000000..399d10a
--- /dev/null
@@ -0,0 +1,454 @@
+//
+//  CodeTextBuffer.cs
+//
+//  Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+//  Copyright (c) 2017 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 <http://www.gnu.org/licenses/>.
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Diagnostics;
+
+namespace Crow.Coding
+{
+       /// <summary>
+       /// Code buffer, lines are arranged in a List<string>, new line chars are removed during string.split on '\n...',
+       /// </summary>
+       public class CodeBuffer
+       {
+               public object EditMutex = new object();
+               //those events are handled in SourceEditor to help keeping sync between textbuffer,parser and editor.
+               //modified lines are marked for reparse
+               #region Events
+               public event EventHandler<CodeBufferEventArgs> LineUpadateEvent;
+               public event EventHandler<CodeBufferEventArgs> LineRemoveEvent;
+               public event EventHandler<CodeBufferEventArgs> LineAdditionEvent;
+               public event EventHandler<CodeBufferEventArgs> FoldingEvent;
+               public event EventHandler BufferCleared;
+               public event EventHandler SelectionChanged;
+               public event EventHandler PositionChanged;
+               #endregion
+
+               #region CTOR
+               public CodeBuffer () {
+
+               }
+               #endregion
+
+               string lineBreak = Interface.LineBreak;
+               List<CodeLine> lines = new List<CodeLine>();
+               public int longestLineIdx = 0;
+               public int longestLineCharCount = 0;
+               /// <summary>
+               /// real position in char arrays, tab = 1 char
+               /// </summary>
+               int _currentLine = 0;
+               int _currentCol = 0;
+
+               public int LineCount { get { return lines.Count;}}
+               public int IndexOf (CodeLine cl) {
+                       return lines.IndexOf (cl);
+               }
+
+               public CodeLine this[int i]
+               {
+                       get { return lines[i]; }
+                       set {
+                               if (lines [i] == value)
+                                       return;
+                               lock (EditMutex) {
+                                       lines [i] = value;
+                                       LineUpadateEvent.Raise (this, new CodeBufferEventArgs (i));
+                               }
+                       }
+               }
+
+               public void RemoveAt(int i){
+                       lock (EditMutex) {
+                               lines.RemoveAt (i);
+                               LineRemoveEvent.Raise (this, new CodeBufferEventArgs (i));
+                       }
+               }
+               public void Insert(int i, string item){
+                       lock (EditMutex) {
+                               lines.Insert (i, item);
+                               LineAdditionEvent.Raise (this, new CodeBufferEventArgs (i));
+                       }
+               }
+               public void Add(CodeLine item){
+                       lock (EditMutex) {
+                               lines.Add (item);
+                               LineAdditionEvent.Raise (this, new CodeBufferEventArgs (lines.Count - 1));
+                       }
+               }
+               public void AddRange (string[] items){
+                       int start = lines.Count;
+                       lock (EditMutex) {
+                               for (int i = 0; i < items.Length; i++)
+                                       lines.Add (items [i]);
+                               LineAdditionEvent.Raise (this, new CodeBufferEventArgs (start, items.Length));
+                       }
+               }
+               public void AddRange (CodeLine[] items){
+                       int start = lines.Count;
+                       lock (EditMutex) {
+                               lines.AddRange (items);
+                               LineAdditionEvent.Raise (this, new CodeBufferEventArgs (start, items.Length));
+                       }
+               }
+               public void Clear () {
+                       lock (EditMutex) {
+                               longestLineCharCount = 0;
+                               lines.Clear ();
+                               BufferCleared.Raise (this, null);
+                       }
+               }
+               public void UpdateLine(int i, string newContent){
+                       lock (EditMutex) {
+                               this [i].Content = newContent;
+                               LineUpadateEvent.Raise (this, new CodeBufferEventArgs (i));
+                       }
+               }
+               public void AppenedLine(int i, string newContent){
+                       lock (EditMutex) {
+                               this [i].Content += newContent;
+                               LineUpadateEvent.Raise (this, new CodeBufferEventArgs (i));
+                       }
+               }
+               public void ToogleFolding (int line) {
+                       if (!this [line].IsFoldable)
+                               return;
+                       lock (EditMutex) {
+                               this [line].IsFolded = !this [line].IsFolded;
+                               FoldingEvent.Raise (this, new CodeBufferEventArgs (line));
+                       }
+               }
+               public void Load(string rawSource) {
+                       this.Clear();
+
+                       if (string.IsNullOrEmpty (rawSource))
+                               return;
+
+                       AddRange (Regex.Split (rawSource, "\r\n|\r|\n|\\\\n"));
+
+                       lineBreak = detectLineBreakKind (rawSource);
+               }
+
+               /// <summary>
+               /// Finds the longest visual line as printed on screen with tabulation replaced with n spaces
+               /// </summary>
+               public void FindLongestVisualLine(){
+                       longestLineCharCount = 0;
+                       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);
+               }
+               /// <summary> line break could be '\r' or '\n' or '\r\n' </summary>
+               static string detectLineBreakKind(string buffer){
+                       string strLB = "";
+
+                       if (string.IsNullOrEmpty(buffer))
+                               return Interface.LineBreak;
+                       int i = 0;
+                       while ( i < buffer.Length) {
+                               if (buffer [i] == '\r') {
+                                       strLB += '\r';
+                                       i++;
+                               }
+                               if (i < buffer.Length) {
+                                       if (buffer [i] == '\r')
+                                               return "\r";
+                                       if (buffer[i] == '\n')
+                                               strLB += '\n';
+                               }
+                               if (!string.IsNullOrEmpty (strLB))
+                                       return strLB;
+                               i++;
+                       }
+                       return Interface.LineBreak;
+               }
+               /// <summary>
+               /// return all lines with linebreaks
+               /// </summary>
+               public string FullText{
+                       get {
+                               if (lines.Count == 0)
+                                       return "";
+                               string tmp = "";
+                               for (int i = 0; i < lines.Count -1; i++)
+                                       tmp += lines [i].Content + this.lineBreak;
+                               tmp += lines [lines.Count - 1].Content;
+                               return tmp;
+                       }
+               }
+
+               /// <summary>
+               /// unfolded and not in folds line count
+               /// </summary>
+               public int UnfoldedLines {
+                       get {
+                               int i = 0, vl = 0;
+                               while (i < LineCount) {
+                                       if (this [i].IsFolded)
+                                               i = GetEndNodeIndex (i);
+                                       i++;
+                                       vl++;
+                               }
+                               //Debug.WriteLine ("unfolded lines: " + vl);
+                               return vl;
+                       }
+               }
+
+               /// <summary>
+               /// convert visual position to buffer position
+               /// </summary>
+               Point getBuffPos (Point visualPos) {
+                       int i = 0;
+                       int buffCol = 0;
+                       while (i < visualPos.X) {
+                               if (this [visualPos.Y] [buffCol] == '\t')
+                                       i += Interface.TabSize;
+                               else
+                                       i++;
+                               buffCol++;
+                       }
+                       return new Point (buffCol, visualPos.Y);
+               }
+
+               public int GetEndNodeIndex (int line) {
+                       return IndexOf (this [line].SyntacticNode.EndLine);
+               }
+               /// <summary>
+               /// Gets visual position computed from actual buffer position
+               /// </summary>
+//             public Point TabulatedPosition {
+//                     get { return new Point (TabulatedColumn, _currentLine); }
+//             }
+               /// <summary>
+               /// set buffer current position from visual position
+               /// </summary>
+//             public void SetBufferPos(Point tabulatedPosition) {
+//                     CurrentPosition = getBuffPos(tabulatedPosition);
+//             }
+
+               #region Editing and moving cursor
+               Point selStartPos = -1; //selection start (row,column)
+               Point selEndPos = -1;   //selection end (row,column)
+
+               public bool SelectionInProgress { get { return selStartPos >= 0; }}
+               public void SetSelStartPos () {
+                       selStartPos = selEndPos = CurrentPosition;
+                       SelectionChanged.Raise (this, null);
+               }
+               public void SetSelEndPos () {
+                       selEndPos = CurrentPosition;
+                       SelectionChanged.Raise (this, null);
+               }
+               /// <summary>
+               /// Set selection in buffer to -1, empty selection
+               /// </summary>
+               public void ResetSelection () {
+                       selStartPos = selEndPos = -1;
+                       SelectionChanged.Raise (this, null);
+               }
+
+               public string SelectedText {
+                       get {
+                               if (SelectionIsEmpty)
+                                       return "";
+                               Point selStart = SelectionStart;
+                               Point selEnd = SelectionEnd;
+                               if (selStart.Y == selEnd.Y)
+                                       return this [selStart.Y].Content.Substring (selStart.X, selEnd.X - selStart.X);
+                               string tmp = "";
+                               tmp = this [selStart.Y].Content.Substring (selStart.X);
+                               for (int l = selStart.Y + 1; l < selEnd.Y; l++) {
+                                       tmp += Interface.LineBreak + this [l].Content;
+                               }
+                               tmp += Interface.LineBreak + this [selEnd.Y].Content.Substring (0, selEnd.X);
+                               return tmp;
+                       }
+               }
+               /// <summary>
+               /// ordered selection start and end positions in char units
+               /// </summary>
+               public Point SelectionStart     {
+                       get { return selEndPos < 0 || selStartPos.Y < selEndPos.Y ? selStartPos :
+                                       selStartPos.Y > selEndPos.Y ? selEndPos :
+                                       selStartPos.X < selEndPos.X ? selStartPos : selEndPos; }
+               }
+               public Point SelectionEnd {
+                       get { return selEndPos < 0 || selStartPos.Y > selEndPos.Y ? selStartPos :
+                                       selStartPos.Y < selEndPos.Y ? selEndPos :
+                                       selStartPos.X > selEndPos.X ? selStartPos : selEndPos; }
+               }
+               public bool SelectionIsEmpty
+               { get { return selEndPos == selStartPos; } }
+               /// <summary>
+               /// Current column in buffer coordinate, tabulation = 1 char
+               /// </summary>
+               public int CurrentColumn{
+                       get { return _currentCol; }
+                       set {
+                               if (value == _currentCol)
+                                       return;
+                               if (value < 0)
+                                       _currentCol = 0;
+                               else if (value >  lines [_currentLine].Length)
+                                       _currentCol = lines [_currentLine].Length;
+                               else
+                                       _currentCol = value;
+
+                               PositionChanged.Raise (this, null);
+                       }
+               }
+               /// <summary>
+               /// Current row in buffer coordinate, tabulation = 1 char
+               /// </summary>
+               public int CurrentLine{
+                       get { return _currentLine; }
+                       set {
+                               if (value == _currentLine)
+                                       return;
+                               if (value >= lines.Count)
+                                       _currentLine = lines.Count-1;
+                               else if (value < 0)
+                                       _currentLine = 0;
+                               else
+                                       _currentLine = value;
+
+                               if (_currentCol >  lines [_currentLine].Length)
+                                       _currentCol = lines [_currentLine].Length;
+                               Debug.WriteLine ("buff cur line: " + _currentLine);
+                               PositionChanged.Raise (this, null);
+                       }
+               }
+               public CodeLine CurrentCodeLine {
+                       get { return this [_currentLine]; }
+               }
+               /// <summary>
+               /// Current position in buffer coordinate, tabulation = 1 char
+               /// </summary>
+               public Point CurrentPosition {
+                       get { return new Point(CurrentColumn, CurrentLine); }
+//                     set {
+//                             _currentCol = value.X;
+//                             _currentLine = value.Y;
+//                     }
+               }
+               /// <summary>
+               /// get char at current position in buffer
+               /// </summary>
+               protected Char CurrentChar { get { return lines [CurrentLine] [CurrentColumn]; } }
+
+               public void GotoWordStart(){
+                       if (this[CurrentLine].Length == 0)
+                               return;
+                       CurrentColumn--;
+                       //skip white spaces
+                       while (!char.IsLetterOrDigit (this.CurrentChar) && CurrentColumn > 0)
+                               CurrentColumn--;
+                       while (char.IsLetterOrDigit (this.CurrentChar) && CurrentColumn > 0)
+                               CurrentColumn--;
+                       if (!char.IsLetterOrDigit (this.CurrentChar))
+                               CurrentColumn++;
+               }
+               public void GotoWordEnd(){
+                       //skip white spaces
+                       if (CurrentColumn >= this [CurrentLine].Length - 1)
+                               return;
+                       while (!char.IsLetterOrDigit (this.CurrentChar) && CurrentColumn < this [CurrentLine].Length-1)
+                               CurrentColumn++;
+                       while (char.IsLetterOrDigit (this.CurrentChar) && CurrentColumn < this [CurrentLine].Length-1)
+                               CurrentColumn++;
+                       if (char.IsLetterOrDigit (this.CurrentChar))
+                               CurrentColumn++;
+               }
+               public void DeleteChar()
+               {
+                       lock (EditMutex) {
+                               if (SelectionIsEmpty) {
+                                       if (CurrentColumn == 0) {
+                                               if (CurrentLine == 0)
+                                                       return;
+                                               CurrentLine--;
+                                               CurrentColumn = this [CurrentLine].Length;
+                                               AppenedLine (CurrentLine, this [CurrentLine + 1].Content);
+                                               RemoveAt (CurrentLine + 1);
+                                               return;
+                                       }
+                                       CurrentColumn--;
+                                       UpdateLine (CurrentLine, this [CurrentLine].Content.Remove (CurrentColumn, 1));
+                               } else {
+                                       int linesToRemove = SelectionEnd.Y - SelectionStart.Y + 1;
+                                       int l = SelectionStart.Y;
+
+                                       if (linesToRemove > 0) {
+                                               UpdateLine (l, this [l].Content.Remove (SelectionStart.X, this [l].Length - SelectionStart.X) +
+                                               this [SelectionEnd.Y].Content.Substring (SelectionEnd.X, this [SelectionEnd.Y].Length - SelectionEnd.X));
+                                               l++;
+                                               for (int c = 0; c < linesToRemove - 1; c++)
+                                                       RemoveAt (l);
+                                               CurrentLine = SelectionStart.Y;
+                                               CurrentColumn = SelectionStart.X;
+                                       } else
+                                               UpdateLine (l, this [l].Content.Remove (SelectionStart.X, SelectionEnd.X - SelectionStart.X));
+                                       CurrentColumn = SelectionStart.X;
+                                       ResetSelection ();
+                               }
+                       }
+               }
+               /// <summary>
+               /// Insert new string at caret position, should be sure no line break is inside.
+               /// </summary>
+               /// <param name="str">String.</param>
+               public void Insert(string str)
+               {
+                       if (!SelectionIsEmpty)
+                               this.DeleteChar ();
+                       string[] strLines = Regex.Split (str, "\r\n|\r|\n|" + @"\\n").ToArray();
+                       UpdateLine (CurrentLine, this [CurrentLine].Content.Insert (CurrentColumn, strLines[0]));
+                       CurrentColumn += strLines[0].Length;
+                       for (int i = 1; i < strLines.Length; i++) {
+                               InsertLineBreak ();
+                               UpdateLine (CurrentLine, this [CurrentLine].Content.Insert (CurrentColumn, strLines[i]));
+                               CurrentColumn += strLines[i].Length;
+                       }
+               }
+               /// <summary>
+               /// Insert a line break.
+               /// </summary>
+               public void InsertLineBreak()
+               {
+                       if (CurrentColumn > 0) {
+                               Insert (CurrentLine + 1, this [CurrentLine].Content.Substring (CurrentColumn));
+                               UpdateLine (CurrentLine, this [CurrentLine].Content.Substring (0, CurrentColumn));
+                       } else
+                               Insert(CurrentLine, "");
+
+                       CurrentColumn = 0;
+                       CurrentLine++;
+               }
+               #endregion
+       }
+}
+
diff --git a/CrowIDE/src/SourceEditor/CodeBufferEventArgs.cs b/CrowIDE/src/SourceEditor/CodeBufferEventArgs.cs
new file mode 100644 (file)
index 0000000..07dd25b
--- /dev/null
@@ -0,0 +1,20 @@
+using System;
+
+namespace Crow.Coding
+{
+       public class CodeBufferEventArgs : EventArgs {
+               public int LineStart;
+               public int LineCount;
+
+               public CodeBufferEventArgs(int lineNumber) {
+                       LineStart = lineNumber;
+                       LineCount = 1;
+               }
+               public CodeBufferEventArgs(int lineStart, int lineCount) {
+                       LineStart = lineStart;
+                       LineCount = lineCount;
+               }
+       }
+
+}
+
diff --git a/CrowIDE/src/SourceEditor/CodeLine.cs b/CrowIDE/src/SourceEditor/CodeLine.cs
new file mode 100644 (file)
index 0000000..622584c
--- /dev/null
@@ -0,0 +1,76 @@
+using System;
+using System.Text;
+using System.Collections.Generic;
+
+namespace Crow.Coding
+{
+       public class CodeLine
+       {
+               public string Content;
+               public List<Token> Tokens;
+               public int EndingState = 0;
+               public Node SyntacticNode;
+               public ParsingException exception;
+
+               public CodeLine (string _content){
+                       Content = _content;
+                       Tokens = null;
+                       exception = null;
+               }
+
+               public char this[int i]
+               {
+                       get { return Content[i]; }
+                       set {
+                               if (Content [i] == value)
+                                       return;
+                               StringBuilder sb = new StringBuilder(Content);
+                               sb[i] = value;
+                               Content = sb.ToString();
+                               Tokens = null;
+                               //LineUpadateEvent.Raise (this, new CodeBufferEventArgs (i));
+                       }
+               }
+               public bool IsFoldable { get { return SyntacticNode != null; } }
+               public bool IsFolded = false;
+               public bool IsParsed {
+                       get { return Tokens != null; }
+               }
+               public string PrintableContent {
+                       get {
+                               return string.IsNullOrEmpty (Content) ? "" : Content.Replace ("\t", new String (' ', Interface.TabSize));
+                       }
+               }
+               public int PrintableLength {
+                       get {
+                               return PrintableContent.Length;
+                       }
+               }
+               public int Length {
+                       get {
+                               return string.IsNullOrEmpty (Content) ? 0 : Content.Length;
+                       }
+               }
+
+               public void SetLineInError (ParsingException ex) {
+                       Tokens = null; 
+                       exception = ex;
+               }
+
+//             public static implicit operator string(CodeLine sl) {
+//                     return sl == null ? "" : sl.Content;
+//             }
+               public static implicit operator CodeLine(string s) {
+                       return new CodeLine(s);
+               }
+               public static bool operator ==(string s1, CodeLine s2)
+               {
+                       return string.Equals (s1, s2.Content);
+               }
+               public static bool operator !=(string s1, CodeLine s2)
+               {
+                       return !string.Equals (s1, s2.Content);
+               }
+       }
+}
+
diff --git a/CrowIDE/src/SourceEditor/Node.cs b/CrowIDE/src/SourceEditor/Node.cs
new file mode 100644 (file)
index 0000000..24818e0
--- /dev/null
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+
+namespace Crow.Coding
+{
+       public class Node
+       {
+               public Node Parent;
+               public string Name;
+               public string Type;
+               public CodeLine StartLine;
+               public CodeLine EndLine;
+               public Dictionary<string,string> Attributes = new Dictionary<string, string> ();
+
+               public List<Node> Children = new List<Node>();
+
+               public Node ()
+               {
+               }
+
+               public void AddChild (Node child) {
+                       child.Parent = this;
+                       Children.Add (child);
+               }
+
+               public override string ToString ()
+               {
+                       return string.Format ("Name:{0}, Type:{1}\n\tparent:{2}", Name, Type, Parent);
+               }
+       }
+}
+
diff --git a/CrowIDE/src/SourceEditor/Parser.cs b/CrowIDE/src/SourceEditor/Parser.cs
new file mode 100644 (file)
index 0000000..79dc086
--- /dev/null
@@ -0,0 +1,297 @@
+using System;
+using System.IO;
+using Crow;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace Crow.Coding
+{
+       /// <summary>
+       /// base class for tokenizing sources
+       /// </summary>
+       public abstract class Parser
+       {
+               /// <summary>
+               /// Default tokens, this enum may be overriden in derived parser with the new keyword,
+               /// see XMLParser for example.
+               /// </summary>
+               public enum TokenType {
+                       Unknown,
+                       WhiteSpace,
+                       NewLine,
+                       LineComment,
+                       BlockCommentStart,
+                       BlockComment,
+                       BlockCommentEnd,
+                       Type,
+                       Identifier,
+                       Indexer,
+                       OpenBlock,
+                       CloseBlock,
+                       StatementEnding,
+                       UnaryOp,
+                       BinaryOp,
+                       Affectation,
+                       StringLitteralOpening,
+                       StringLitteralClosing,
+                       StringLitteral,
+                       NumericLitteral,
+                       Preprocessor,
+               }
+
+               #region CTOR
+               public Parser (CodeBuffer _buffer)
+               {
+                       buffer = _buffer;
+
+                       buffer.LineUpadateEvent += Buffer_LineUpadateEvent;
+                       //buffer.LineAdditionEvent += Buffer_LineAdditionEvent;;
+                       buffer.LineRemoveEvent += Buffer_LineRemoveEvent;
+                       buffer.BufferCleared += Buffer_BufferCleared;
+               }
+
+               #endregion
+
+               #region Buffer events handlers
+               void Buffer_BufferCleared (object sender, EventArgs e)
+               {
+
+               }
+               void Buffer_LineAdditionEvent (object sender, CodeBufferEventArgs e)
+               {
+
+               }
+               void Buffer_LineRemoveEvent (object sender, CodeBufferEventArgs e)
+               {
+                       reparseSource ();
+               }
+               void Buffer_LineUpadateEvent (object sender, CodeBufferEventArgs e)
+               {
+                       for (int i = 0; i < e.LineCount; i++)
+                               tryParseBufferLine (e.LineStart + i);
+                       reparseSource ();
+               }
+               #endregion
+
+               void updateFolding () {
+                       //                      Stack<TokenList> foldings = new Stack<TokenList>();
+                       //                      bool inStartTag = false;
+                       //
+                       //                      for (int i = 0; i < parser.Tokens.Count; i++) {
+                       //                              TokenList tl = parser.Tokens [i];
+                       //                              tl.foldingTo = null;
+                       //                              int fstTK = tl.FirstNonBlankTokenIndex;
+                       //                              if (fstTK > 0 && fstTK < tl.Count - 1) {
+                       //                                      if (tl [fstTK + 1] != XMLParser.TokenType.ElementName)
+                       //                                              continue;
+                       //                                      if (tl [fstTK] == XMLParser.TokenType.ElementStart) {
+                       //                                              //search closing tag
+                       //                                              int tkPtr = fstTK+2;
+                       //                                              while (tkPtr < tl.Count) {
+                       //                                                      if (tl [tkPtr] == XMLParser.TokenType.ElementClosing)
+                       //
+                       //                                                      tkPtr++;
+                       //                                              }
+                       //                                              if (tl.EndingState == (int)XMLParser.States.Content)
+                       //                                                      foldings.Push (tl);
+                       //                                              else if (tl.EndingState == (int)XMLParser.States.StartTag)
+                       //                                                      inStartTag = true;
+                       //                                              continue;
+                       //                                      }
+                       //                                      if (tl [fstTK] == XMLParser.TokenType.ElementEnd) {
+                       //                                              TokenList tls = foldings.Pop ();
+                       //                                              int fstTKs = tls.FirstNonBlankTokenIndex;
+                       //                                              if (tls [fstTK + 1].Content == tl [fstTK + 1].Content) {
+                       //                                                      tl.foldingTo = tls;
+                       //                                                      continue;
+                       //                                              }
+                       //                                              parser.CurrentPosition = tls [fstTK + 1].Start;
+                       //                                              parser.SetLineInError(new ParsingException(parser, "closing tag not corresponding"));
+                       //                                      }
+                       //
+                       //                              }
+                       //                      }
+               }
+               public void reparseSource () {
+                       for (int i = 0; i < buffer.LineCount; i++) {
+                               if (!buffer[i].IsParsed)
+                                       tryParseBufferLine (i);
+                       }
+                       try {
+                               SyntaxAnalysis ();
+                       } catch (Exception ex) {
+                               Debug.WriteLine ("Syntax Error: " + ex.ToString ());
+                               if (ex is ParsingException)
+                                       SetLineInError (ex as ParsingException);
+                       }
+               }
+               public void tryParseBufferLine(int lPtr) {
+                       buffer [lPtr].exception = null;
+                       currentLine = lPtr;
+                       currentColumn = 0;
+                       eol = false;
+
+                       try {
+                               ParseCurrentLine ();
+                       } catch (Exception ex) {
+                               Debug.WriteLine (ex.ToString ());
+                               if (ex is ParsingException)
+                                       SetLineInError (ex as ParsingException);
+                       }
+
+               }
+
+               protected CodeBuffer buffer;
+
+               internal int currentLine = 0;
+               internal int currentColumn = 0;
+               protected Token currentTok;
+               protected bool eol = true;
+
+               public Node RootNode;
+
+               protected Point CurrentPosition {
+                       get { return new Point (currentLine, currentColumn); }
+                       set {
+                               currentLine = value.Y;
+                               currentColumn = value.X;
+                       }
+               }
+
+               public abstract void ParseCurrentLine();
+               public abstract void SyntaxAnalysis ();
+
+               public virtual void SetLineInError(ParsingException ex) {
+                       currentTok = default(Token);
+                       if (ex.Line >= buffer.LineCount)
+                               ex.Line = buffer.LineCount - 1;
+                       if (buffer [ex.Line].IsFolded)
+                               buffer.ToogleFolding (ex.Line);
+                       buffer [ex.Line].SetLineInError (ex);
+               }
+
+               #region low level parsing
+               /// <summary>
+               /// Read one char from current position in buffer and store it into the current token
+               /// </summary>
+               /// <param name="startOfTok">if true, set the Start position of the current token to the current position</param>
+               protected void readToCurrTok(bool startOfTok = false){
+                       if (startOfTok)
+                               currentTok.Start = CurrentPosition;
+                       currentTok += Read();
+               }
+               /// <summary>
+               /// read n char from the buffer and store it into the current token
+               /// </summary>
+               protected void readToCurrTok(int length) {
+                       for (int i = 0; i < length; i++)
+                               currentTok += Read ();
+               }
+               /// <summary>
+               /// Save current token into current TokensLine and raz current token
+               /// </summary>
+               protected void saveAndResetCurrentTok() {
+                       currentTok.End = CurrentPosition;
+                       buffer[currentLine].Tokens.Add (currentTok);
+                       currentTok = default(Token);
+               }
+               /// <summary>
+               /// read one char and add current token to current TokensLine, current token is reset
+               /// </summary>
+               /// <param name="type">Type of the token</param>
+               /// <param name="startToc">set start of token to current position</param>
+               protected void readAndResetCurrentTok(System.Enum type, bool startToc = false) {
+                       readToCurrTok ();
+                       saveAndResetCurrentTok (type);
+               }
+               /// <summary>
+               /// Save current tok
+               /// </summary>
+               /// <param name="type">set the type of the tok</param>
+               protected void saveAndResetCurrentTok(System.Enum type) {
+                       currentTok.Type = (TokenType)type;
+                       saveAndResetCurrentTok ();
+               }
+               /// <summary>
+               /// Peek next char, emit '\n' if current column > buffer's line length
+               /// Throw error if eof is true
+               /// </summary>
+               protected virtual char Peek() {
+                       if (eol)
+                               throw new ParsingException (this, "Unexpected End of line");
+                       return currentColumn < buffer [currentLine].Length ?
+                               buffer [currentLine] [currentColumn] : '\n';
+               }
+               /// <summary>
+               /// Peek n char from buffer or less if remaining char in buffer's line is less than requested
+               /// if end of line is reached, no '\n' will be emitted, instead, empty string is returned. '\n' should be checked only
+               /// with single char Peek().
+               /// Throw error is eof is true
+               /// </summary>
+               /// <param name="length">Length.</param>
+               protected virtual string Peek(int length) {
+                       if (eol)
+                               throw new ParsingException (this, "Unexpected End of Line");
+                       int lg = Math.Min(length, Math.Max (buffer [currentLine].Length - currentColumn, buffer [currentLine].Length - currentColumn - length));
+                       if (lg == 0)
+                               return "";
+                       return buffer [currentLine].Content.Substring (currentColumn, lg);
+               }
+               /// <summary>
+               /// read one char from buffer at current position, if '\n' is read, current line is incremented
+               /// and column is reset to 0
+               /// </summary>
+               protected virtual char Read() {
+                       char c = Peek ();
+                       if (c == '\n')
+                               eol = true;
+                       currentColumn++;
+                       return c;
+               }
+               /// <summary>
+               /// read until end of line is reached
+               /// </summary>
+               /// <returns>string read</returns>
+               protected virtual string ReadLine () {
+                       string tmp = "";
+                       while (!eol)
+                               tmp += Read ();
+                       return tmp;
+               }
+               /// <summary>
+               /// read until end expression is reached or end of line.
+               /// </summary>
+               /// <returns>string read minus the ending expression that has to be read after</returns>
+               /// <param name="endExp">Expression to search for</param>
+               protected virtual string ReadLineUntil (string endExp){
+                       string tmp = "";
+
+                       while (!eol) {
+                               if (buffer [currentLine].Length - currentColumn - endExp.Length < 0) {
+                                       tmp += ReadLine();
+                                       break;
+                               }
+                               if (string.Equals (Peek (endExp.Length), endExp))
+                                       return tmp;
+                               tmp += Read();
+                       }
+                       return tmp;
+               }
+               /// <summary>
+               /// skip white spaces, but not line break. Save spaces in a WhiteSpace token.
+               /// </summary>
+               protected void SkipWhiteSpaces () {
+                       if (currentTok.Type != TokenType.Unknown)
+                               throw new ParsingException (this, "current token should be reset to unknown (0) before skiping white spaces");
+                       while (!eol) {
+                               if (!char.IsWhiteSpace (Peek ())||Peek()=='\n')
+                                       break;
+                               readToCurrTok (currentTok.Type == TokenType.Unknown);
+                               currentTok.Type = TokenType.WhiteSpace;
+                       }
+                       if (currentTok.Type != TokenType.Unknown)
+                               saveAndResetCurrentTok ();
+               }
+               #endregion
+       }
+}
\ No newline at end of file
diff --git a/CrowIDE/src/SourceEditor/ParsingException.cs b/CrowIDE/src/SourceEditor/ParsingException.cs
new file mode 100644 (file)
index 0000000..88c51c9
--- /dev/null
@@ -0,0 +1,22 @@
+using System;
+
+namespace Crow.Coding
+{
+       public class ParsingException : Exception
+       {
+               public int Line;
+               public int Column;
+               public ParsingException(Parser parser, string txt)
+                       : base(string.Format("Parser exception ({0},{1}): {2}", parser.currentLine, parser.currentColumn, txt))
+               {
+                       Line = parser.currentLine;
+                       Column = parser.currentColumn;
+               }
+               public ParsingException(Parser parser, string txt, Exception innerException)
+                       : base(txt, innerException)
+               {
+                       txt = string.Format("Parser exception ({0},{1}): {2}", parser.currentLine, parser.currentColumn, txt);
+               }
+       }
+}
+
diff --git a/CrowIDE/src/SourceEditor/SourceEditor.cs b/CrowIDE/src/SourceEditor/SourceEditor.cs
new file mode 100644 (file)
index 0000000..677ba8b
--- /dev/null
@@ -0,0 +1,1107 @@
+//
+// ScrollingTextBox.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// 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.Xml.Serialization;
+using System.ComponentModel;
+using System.Collections;
+using Cairo;
+using System.Text;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Linq;
+using System.Diagnostics;
+using System.IO;
+using System.Threading;
+
+namespace Crow.Coding
+{
+       /// <summary>
+       /// Scrolling text box optimized for monospace fonts, for coding
+       /// </summary>
+       public class SourceEditor : ScrollingObject
+       {
+               #region CTOR
+               public SourceEditor (): base()
+               {
+                       formatting.Add ((int)XMLParser.TokenType.AttributeName, new TextFormatting (Color.UnitedNationsBlue, Color.Transparent));
+                       formatting.Add ((int)XMLParser.TokenType.ElementName, new TextFormatting (Color.DarkBlue, Color.Transparent));
+                       formatting.Add ((int)XMLParser.TokenType.ElementStart, new TextFormatting (Color.Black, Color.Transparent));
+                       formatting.Add ((int)XMLParser.TokenType.ElementEnd, new TextFormatting (Color.Black, Color.Transparent));
+                       formatting.Add ((int)XMLParser.TokenType.ElementClosing, new TextFormatting (Color.Black, Color.Transparent));
+                       formatting.Add ((int)XMLParser.TokenType.Affectation, new TextFormatting (Color.Black, Color.Transparent));
+
+                       formatting.Add ((int)XMLParser.TokenType.AttributeValueOpening, new TextFormatting (Color.Carmine, Color.Transparent));
+                       formatting.Add ((int)XMLParser.TokenType.AttributeValueClosing, new TextFormatting (Color.Carmine, Color.Transparent));
+                       formatting.Add ((int)XMLParser.TokenType.AttributeValue, new TextFormatting (Color.OrangeRed, Color.Transparent, false, true));
+                       formatting.Add ((int)XMLParser.TokenType.XMLDecl, new TextFormatting (Color.GreenCrayola, Color.Transparent));
+                       formatting.Add ((int)XMLParser.TokenType.BlockComment, new TextFormatting (Color.Gray, Color.Transparent, false, true));
+
+                       parsing.Add (".crow", "Crow.Coding.XMLParser");
+
+                       buffer = new CodeBuffer ();
+                       buffer.LineUpadateEvent += Buffer_LineUpadateEvent;
+                       buffer.LineAdditionEvent += Buffer_LineAdditionEvent;;
+                       buffer.LineRemoveEvent += Buffer_LineRemoveEvent;
+                       buffer.BufferCleared += Buffer_BufferCleared;
+                       buffer.SelectionChanged += Buffer_SelectionChanged;
+                       buffer.PositionChanged += Buffer_PositionChanged;
+                       buffer.FoldingEvent += Buffer_FoldingEvent;
+                       buffer.Add (new CodeLine(""));
+
+                       Thread updateSource = new Thread (updateSourceThreadFunc);
+                       updateSource.IsBackground = true;
+                       updateSource.Start ();
+               }
+               #endregion
+               string oldSource = "";
+               void updateSourceThreadFunc (){
+                       while (true) {
+                               if (projNode != null && buffer != null) {
+                                       string newSrc = buffer.FullText;
+                                       if (projNode.Source != newSrc)
+                                               projNode.Source = newSrc;
+                               }
+                               Thread.Sleep (100);
+                       }
+               }
+               const int leftMarginGap = 3;//gap between items in margin and text
+               const int foldSize = 9;//folding rectangles size
+
+               #region private and protected fields
+               bool foldingEnabled = true;
+               ProjectFile projNode = null;
+               int leftMargin = 0;     //margin used to display line numbers, folding errors,etc...
+               int visibleLines = 1;
+               int visibleColumns = 1;
+               CodeBuffer buffer;
+               Parser parser;
+               Color selBackground;
+               Color selForeground;
+//             int _currentCol;        //0 based cursor position in string
+//             int _currentLine;
+
+
+               Dictionary<int, TextFormatting> formatting = new Dictionary<int, TextFormatting>();
+               Dictionary<string, string> parsing = new Dictionary<string, string>();
+
+               protected Rectangle rText;
+               protected FontExtents fe;
+               protected TextExtents te;
+               #endregion
+
+               void measureLeftMargin () {
+                       leftMargin = 0;
+                       if (PrintLineNumbers)
+                               leftMargin += (int)Math.Ceiling((double)buffer.LineCount.ToString().Length * fe.MaxXAdvance) +6;
+                       if (foldingEnabled)
+                               leftMargin += foldSize;
+                       if (leftMargin > 0)
+                               leftMargin += leftMarginGap;
+                       updateVisibleColumns ();
+               }
+               void findLongestLineAndUpdateMaxScrollX() {
+                       buffer.FindLongestVisualLine ();
+                       MaxScrollX = Math.Max (0, buffer.longestLineCharCount - visibleColumns);
+                       Debug.WriteLine ("SourceEditor: Find Longest line and update maxscrollx: {0} visible cols:{1}", MaxScrollX, visibleColumns);
+               }
+               /// <summary>
+               /// Updates visible line in widget, adapt max scroll y and updatePrintedLines
+               /// </summary>
+               void updateVisibleLines(){
+                       visibleLines = (int)Math.Floor ((double)ClientRectangle.Height / fe.Height);
+                       NotifyValueChanged ("VisibleLines", visibleLines);
+                       updateMaxScrollY ();
+                       updatePrintedLines ();
+                       System.Diagnostics.Debug.WriteLine ("update visible lines: " + visibleLines);
+                       System.Diagnostics.Debug.WriteLine ("update MaxScrollY: " + MaxScrollY);
+               }
+               void updateVisibleColumns(){
+                       visibleColumns = (int)Math.Floor ((double)(ClientRectangle.Width - leftMargin)/ fe.MaxXAdvance);
+                       MaxScrollX = Math.Max (0, buffer.longestLineCharCount - visibleColumns);
+
+                       System.Diagnostics.Debug.WriteLine ("update visible columns: {0} leftMargin:{1}",visibleColumns, leftMargin);
+                       System.Diagnostics.Debug.WriteLine ("update MaxScrollX: " + MaxScrollX);
+               }
+               void updateMaxScrollY () {
+                       if (parser == null || !foldingEnabled) {
+                               MaxScrollY = Math.Max (0, buffer.LineCount - visibleLines);
+                               if (buffer.UnfoldedLines > 0)
+                                       NotifyValueChanged ("ChildHeightRatio", Slot.Height * visibleLines / buffer.UnfoldedLines);                                                     
+                       } else {
+                               MaxScrollY = Math.Max (0, buffer.UnfoldedLines - visibleLines);
+                               if (buffer.UnfoldedLines > 0)
+                                       NotifyValueChanged ("ChildHeightRatio", Slot.Height * visibleLines / buffer.UnfoldedLines);                                                     
+                       }
+               }
+
+               int firstPrintedLine = -1;
+               /// <summary>
+               /// list of lines visible in the Editor depending on scrolling and folding
+               /// </summary>
+               List<CodeLine> PrintedLines;
+
+               void updatePrintedLines () {
+                       lock (buffer.EditMutex) {
+                               PrintedLines = new List<CodeLine> ();
+                               int curL = 0;
+                               int i = 0;
+
+                               while (curL < buffer.LineCount && i < ScrollY) {
+                                       if (buffer [curL].IsFolded)
+                                               curL = buffer.GetEndNodeIndex (curL);
+                                       curL++;
+                                       i++;
+                               }
+
+                               firstPrintedLine = curL;
+                               i = 0;
+                               while (i < visibleLines && curL < buffer.LineCount) {
+                                       PrintedLines.Add (buffer [curL]);
+
+                                       if (buffer [curL].IsFolded)
+                                               curL = buffer.GetEndNodeIndex (curL);
+
+                                       curL++;
+                                       i++;
+                               }
+                       }
+                       RegisterForGraphicUpdate ();
+               }
+               void toogleFolding (int line) {
+                       if (parser == null || !foldingEnabled)
+                               return;
+                       buffer.ToogleFolding (line);
+               }
+
+               #region Buffer events handlers
+               void Buffer_BufferCleared (object sender, EventArgs e)
+               {
+                       buffer.longestLineCharCount = 0;
+                       buffer.longestLineIdx = 0;
+                       measureLeftMargin ();
+                       MaxScrollX = MaxScrollY = 0;
+                       PrintedLines = null;
+                       RegisterForGraphicUpdate ();
+               }
+               void Buffer_LineAdditionEvent (object sender, CodeBufferEventArgs e)
+               {
+                       for (int i = 0; i < e.LineCount; i++) {
+                               int lptr = e.LineStart + i;
+                               int charCount = buffer[lptr].PrintableLength;
+                               if (charCount > buffer.longestLineCharCount) {
+                                       buffer.longestLineIdx = lptr;
+                                       buffer.longestLineCharCount = charCount;
+                               }else if (lptr <= buffer.longestLineIdx)
+                                       buffer.longestLineIdx++;
+                               if (parser == null)
+                                       continue;
+                               parser.tryParseBufferLine (e.LineStart + i);
+                       }
+                       measureLeftMargin ();
+
+                       if (parser != null)
+                               parser.reparseSource ();
+
+                       updatePrintedLines ();
+                       updateMaxScrollY ();
+                       RegisterForGraphicUpdate ();
+               }
+               void Buffer_LineRemoveEvent (object sender, CodeBufferEventArgs e)
+               {
+                       bool trigFindLongestLine = false;
+                       for (int i = 0; i < e.LineCount; i++) {
+                               int lptr = e.LineStart + i;
+                               if (lptr <= buffer.longestLineIdx)
+                                       trigFindLongestLine = true;
+                       }
+                       if (trigFindLongestLine)
+                               findLongestLineAndUpdateMaxScrollX ();
+
+                       measureLeftMargin ();
+                       updatePrintedLines ();
+                       updateMaxScrollY ();
+                       RegisterForGraphicUpdate ();
+               }
+               void Buffer_LineUpadateEvent (object sender, CodeBufferEventArgs e)
+               {
+                       bool trigFindLongestLine = false;
+                       for (int i = 0; i < e.LineCount; i++) {
+
+                               int lptr = e.LineStart + i;
+                               if (lptr == buffer.longestLineIdx)
+                                       trigFindLongestLine = true;
+                               else if (buffer[lptr].PrintableLength > buffer.longestLineCharCount) {
+                                       buffer.longestLineCharCount = buffer[lptr].PrintableLength;
+                                       buffer.longestLineIdx = lptr;
+                               }
+                       }
+                       if (trigFindLongestLine)
+                               findLongestLineAndUpdateMaxScrollX ();
+                       
+                       RegisterForGraphicUpdate ();
+               }
+               void Buffer_PositionChanged (object sender, EventArgs e)
+               {
+                       updateOnScreenCurLineFromBuffCurLine ();
+               }
+
+               void Buffer_SelectionChanged (object sender, EventArgs e)
+               {
+                       RegisterForGraphicUpdate ();
+               }
+               void Buffer_FoldingEvent (object sender, CodeBufferEventArgs e)
+               {
+                       updatePrintedLines ();
+                       updateMaxScrollY ();
+                       RegisterForGraphicUpdate ();
+               }
+               #endregion
+
+               Parser getParserFromExt (string extension) {
+                       if (string.IsNullOrEmpty(extension))
+                               return null;
+                       if (!parsing.ContainsKey(extension))
+                               return null;
+                       Type parserType = Type.GetType (parsing [extension]);
+                       if (parserType == null)
+                               return null;
+                       return (Parser)Activator.CreateInstance (parserType, buffer );
+               }
+
+               #region Public Crow Properties
+               [XmlAttributeAttribute]
+               public bool PrintLineNumbers
+               {
+                       get { return Configuration.Global.Get<bool> ("PrintLineNumbers");
+                       }
+                       set
+                       {
+                               if (PrintLineNumbers == value)
+                                       return;
+                               Configuration.Global.Set ("PrintLineNumbers", value);
+                               NotifyValueChanged ("PrintLineNumbers", PrintLineNumbers);
+                               measureLeftMargin ();
+                               RegisterForGraphicUpdate ();
+                       }
+               }
+               [XmlAttributeAttribute]
+               public ProjectFile ProjectNode
+               {
+                       get {
+                               return projNode;
+                       }
+                       set
+                       {
+                               if (projNode == value)
+                                       return;
+
+                               projNode = value;
+
+                               NotifyValueChanged ("ProjectNode", projNode);
+
+                               if (projNode == null)
+                                       return;
+                               
+                               if (!File.Exists (projNode.AbsolutePath))
+                                       return;
+
+                               parser = getParserFromExt (System.IO.Path.GetExtension (projNode.Extension));
+
+                               try {
+                                       buffer.Load (projNode.Source);
+                                       oldSource = projNode.Source;
+                               } catch (Exception ex) {
+                                       Debug.WriteLine (ex.ToString ());
+                               }
+
+                               updateMaxScrollY ();
+                               MaxScrollX = Math.Max (0, buffer.longestLineCharCount - visibleColumns);
+                               updatePrintedLines ();
+
+                               RegisterForGraphicUpdate ();
+                       }
+               }
+               [XmlAttributeAttribute][DefaultValue("BlueGray")]
+               public virtual Color SelectionBackground {
+                       get { return selBackground; }
+                       set {
+                               if (value == selBackground)
+                                       return;
+                               selBackground = value;
+                               NotifyValueChanged ("SelectionBackground", selBackground);
+                               RegisterForRedraw ();
+                       }
+               }
+               [XmlAttributeAttribute][DefaultValue("White")]
+               public virtual Color SelectionForeground {
+                       get { return selForeground; }
+                       set {
+                               if (value == selForeground)
+                                       return;
+                               selForeground = value;
+                               NotifyValueChanged ("SelectionForeground", selForeground);
+                               RegisterForRedraw ();
+                       }
+               }
+                       
+               //              [XmlAttributeAttribute][DefaultValue(0)]
+//             public int CurrentColumn{
+//                     get { return _currentCol; }
+////                   set {
+////                           if (value == _currentCol)
+////                                   return;
+////                           if (value < 0)
+////                                   _currentCol = 0;
+////                           else if (value > buffer[_currentLine].PrintableLength)
+////                                   _currentCol = buffer[_currentLine].PrintableLength;
+////                           else
+////                                   _currentCol = value;
+////
+////                           buffer.SetBufferPos (CurrentPosition);
+////
+////                           if (_currentCol < ScrollX)
+////                                   ScrollX = _currentCol;
+////                           else if (_currentCol >= ScrollX + visibleColumns)
+////                                   ScrollX = _currentCol - visibleColumns + 1;
+////
+////                           NotifyValueChanged ("CurrentColumn", _currentCol);
+////                   }
+//             }
+//             [XmlAttributeAttribute][DefaultValue(0)]
+//             public int CurrentLine{
+//                     get { return _currentLine; }
+////                   set {
+////                           if (value == _currentLine)
+////                                   return;
+////                           if (value >= buffer.LineCount)
+////                                   _currentLine = buffer.LineCount-1;
+////                           else if (value < 0)
+////                                   _currentLine = 0;
+////                           else
+////                                   _currentLine = value;
+////
+////                           if (_currentCol > buffer[_currentLine].PrintableLength)
+////                                   CurrentColumn = buffer[_currentLine].PrintableLength;//buffer.setBufferPos is called inside
+////                           else
+////                                   buffer.SetBufferPos (CurrentPosition);
+////
+//////                         if (_currentLine < ScrollY)
+//////                                 ScrollY = _currentLine;
+//////                         else if (_currentLine >= ScrollY + visibleLines)
+//////                                 ScrollY = _currentLine - visibleLines + 1;
+////
+////                           NotifyValueChanged ("CurrentLine", _currentLine);
+////                   }
+//             }
+//             /// <summary>
+//             /// Current position is in the printed coord system, tabulation chars are replaced with 4 spaces,
+//             /// while in the buffer, the position holds tabulations as single chars
+//             /// </summary>
+//             /// <value>The current position.</value>
+//             [XmlIgnore]public Point CurrentPosition {
+//                     get { return new Point(CurrentColumn, CurrentLine); }
+//                     set {
+//                             _currentCol = value.X;
+//                             _currentLine = value.Y;
+//
+//                             if (_currentCol < ScrollX)
+//                                     ScrollX = _currentCol;
+//                             else if (_currentCol >= ScrollX + visibleColumns)
+//                                     ScrollX = _currentCol - visibleColumns + 1;
+////
+////                           if (_currentLine < ScrollY)
+////                                   ScrollY = _currentLine;
+////                           else if (_currentLine >= ScrollY + visibleLines)
+////                                   ScrollY = _currentLine - visibleLines + 1;
+//
+//                             NotifyValueChanged ("CurrentColumn", _currentCol);
+//                             NotifyValueChanged ("CurrentLine", _currentLine);
+//                     }
+//             }
+
+//             [XmlIgnore]public string SelectedText
+//             {
+//                     get {
+//                             if (!selectionIsEmpty)
+//                                     buffer.SetSelection (selectionStart, selectionEnd);
+//                             return buffer.SelectedText;
+//                     }
+//             }
+
+               #endregion
+
+
+               void updateOnScreenCurLineFromBuffCurLine(){
+                       printedCurrentLine = PrintedLines.IndexOf (buffer.CurrentCodeLine);
+               }
+
+//             void setCurrentLineFromBuffer () {
+//                     _currentLine = buffer.CurrentLine;
+//                     NotifyValueChanged ("CurrentLine", _currentLine);
+//             }
+
+               public override int ScrollY {
+                       get {
+                               return base.ScrollY;
+                       }
+                       set {
+                               if (value == base.ScrollY)
+                                       return;
+                               base.ScrollY = value;
+                               updatePrintedLines ();
+                       }
+               }
+
+
+               /// <summary>
+               /// Index of the currentline in the PrintedLines array
+               /// </summary>
+               int printedCurrentLine = 0;
+
+               /// <summary>
+               /// Current editor line, when set, update buffer.CurrentLine
+               /// </summary>
+               int PrintedCurrentLine {
+                       get { return printedCurrentLine;}
+                       set {
+                               if (value < 0) {
+                                       ScrollY += value;
+                                       printedCurrentLine = 0;
+                               } else if (PrintedLines.Count < visibleLines && value >= PrintedLines.Count) {
+                                       printedCurrentLine = PrintedLines.Count - 1;
+                               }else if (value >= visibleLines) {
+                                       ScrollY += value - visibleLines + 1;
+                                       printedCurrentLine = visibleLines - 1;
+                               }else
+                                       printedCurrentLine = value;
+                               Debug.WriteLine ("printed current line:" + printedCurrentLine.ToString ());
+                               //update position in buffer
+                               buffer.CurrentLine = buffer.IndexOf (PrintedLines[printedCurrentLine]);
+                       }
+               }
+               int getTabulatedColumn (int col, int line) {
+                       return buffer [line].Content.Substring (0, col).Replace ("\t", new String (' ', Interface.TabSize)).Length;
+               }
+               int getTabulatedColumn (Point pos) {
+                       return getTabulatedColumn (pos.X,pos.Y);
+               }
+               /// <summary>
+               /// Moves cursor one char to the left, move up if cursor reaches start of line
+               /// </summary>
+               /// <returns><c>true</c> if move succeed</returns>
+               public bool MoveLeft(){
+                       if (buffer.CurrentColumn == 0) {
+                               if (printedCurrentLine == 0)
+                                       return false;
+                               PrintedCurrentLine--;
+                               buffer.CurrentColumn = int.MaxValue;
+                       } else
+                               buffer.CurrentColumn--;
+                       return true;
+               }
+               /// <summary>
+               /// Moves cursor one char to the right, move down if cursor reaches end of line
+               /// </summary>
+               /// <returns><c>true</c> if move succeed</returns>
+               public bool MoveRight(){
+                       if (buffer.CurrentColumn >= buffer.CurrentCodeLine.Length) {
+                               if (PrintedCurrentLine == buffer.UnfoldedLines - 1)
+                                       return false;
+                               buffer.CurrentColumn = 0;
+                               PrintedCurrentLine++;
+                       } else
+                               buffer.CurrentColumn++;
+                       return true;
+               }
+               #region Drawing
+               void drawLine(Context gr, Rectangle cb, int i) {
+                       CodeLine cl = PrintedLines[i];
+                       int lineIndex = buffer.IndexOf(cl);
+
+                       double y = cb.Y + fe.Height * i, x = cb.X;
+
+                       //Draw line numbering
+                       Color mgFg = Color.Gray;
+                       Color mgBg = Color.White;
+                       if (PrintLineNumbers){
+                               Rectangle mgR = new Rectangle ((int)x, (int)y, leftMargin - leftMarginGap, (int)Math.Ceiling(fe.Height));
+                               if (cl.exception != null) {
+                                       mgBg = Color.Red;
+                                       if (buffer.CurrentLine == lineIndex)
+                                               mgFg = Color.White;
+                                       else
+                                               mgFg = Color.LightGray;
+                               }else if (buffer.CurrentLine == lineIndex) {
+                                       mgFg = Color.Black;
+                               }
+                               string strLN = (lineIndex+1).ToString ();
+                               gr.SetSourceColor (mgBg);
+                               gr.Rectangle (mgR);
+                               gr.Fill();
+                               gr.SetSourceColor (mgFg);
+
+                               gr.MoveTo (cb.X + (int)(gr.TextExtents (buffer.LineCount.ToString()).Width - gr.TextExtents (strLN).Width), y + fe.Ascent);
+                               gr.ShowText (strLN);
+                               gr.Fill ();
+                       }
+
+
+                       //draw folding
+                       if (foldingEnabled){
+                               if (cl.IsFoldable) {
+                                       if (cl.SyntacticNode.StartLine != cl.SyntacticNode.EndLine) {
+                                               gr.SetSourceColor (Color.Black);
+                                               Rectangle rFld = new Rectangle (cb.X + leftMargin - leftMarginGap - foldSize, (int)(y + fe.Height / 2.0 - foldSize / 2.0), foldSize, foldSize);
+                                               gr.Rectangle (rFld, 1.0);
+                                               if (cl.IsFolded) {
+                                                       gr.MoveTo (rFld.Center.X + 0.5, rFld.Y + 2);
+                                                       gr.LineTo (rFld.Center.X + 0.5, rFld.Bottom - 2);
+                                               }
+                                               gr.MoveTo (rFld.Left + 2, rFld.Center.Y + 0.5);
+                                               gr.LineTo (rFld.Right - 2, rFld.Center.Y + 0.5);
+                                               gr.Stroke ();
+                                       }
+                               }
+                       }
+
+                       gr.SetSourceColor (Foreground);
+                       x += leftMargin;
+
+                       if (cl.Tokens == null)
+                               drawRawCodeLine (gr, x, y, i, lineIndex);
+                       else
+                               drawParsedCodeLine (gr, x, y, i, lineIndex);
+               }
+//             void drawParsed(Context gr){
+//                     if (PrintedLines == null)
+//                             return;
+//
+//                     gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
+//                     gr.SetFontSize (Font.Size);
+//                     gr.FontOptions = Interface.FontRenderingOptions;
+//                     gr.Antialias = Interface.Antialias;
+//
+//                     Rectangle cb = ClientRectangle;
+//                     gr.Save ();
+//                     CairoHelpers.CairoRectangle (gr, cb, CornerRadius);
+//                     gr.Clip ();
+//
+//                     bool selectionInProgress = false;
+//
+//                     Foreground.SetAsSource (gr);
+//
+//                     #region draw text cursor
+//                     if (SelBegin != SelRelease)
+//                             selectionInProgress = true;
+//                     else if (HasFocus){
+//                             gr.LineWidth = 1.0;
+//                             double cursorX = + leftMargin + cb.X + (CurrentColumn - ScrollX) * fe.MaxXAdvance;
+//                             gr.MoveTo (0.5 + cursorX, cb.Y + printedCurrentLine * fe.Height);
+//                             gr.LineTo (0.5 + cursorX, cb.Y + (printedCurrentLine + 1) * fe.Height);
+//                             gr.Stroke();
+//                     }
+//                     #endregion
+//
+//                     for (int i = 0; i < PrintedLines.Count; i++)
+//                             drawTokenLine (gr, i, selectionInProgress, cb);
+//
+//                     gr.Restore ();
+//             }
+               void drawRawCodeLine(Context gr, double x, double y, int i, int lineIndex) {
+                       string lstr = buffer[lineIndex].PrintableContent;
+                       if (ScrollX < lstr.Length)
+                               lstr = lstr.Substring (ScrollX);
+                       else
+                               lstr = "";
+
+                       gr.MoveTo (x, y + fe.Ascent);
+                       gr.ShowText (lstr);
+                       gr.Fill ();
+
+                       if (!buffer.SelectionIsEmpty && lineIndex >= buffer.SelectionStart.Y && lineIndex <= buffer.SelectionEnd.Y) {
+                               double rLineX = x,
+                               rLineY = y,
+                               rLineW = lstr.Length * fe.MaxXAdvance;
+
+                               //System.Diagnostics.Debug.WriteLine ("sel start: " + buffer.SelectionStart + " sel end: " + buffer.SelectionEnd);
+                               if (lineIndex == buffer.SelectionStart.Y) {
+                                       rLineX += (selStartCol - ScrollX) * fe.MaxXAdvance;
+                                       rLineW -= selStartCol * fe.MaxXAdvance;
+                               }
+                               if (lineIndex == buffer.SelectionEnd.Y)
+                                       rLineW -= (lstr.Length - selEndCol) * fe.MaxXAdvance;
+
+                               gr.Save ();
+                               gr.Operator = Operator.Source;
+                               gr.Rectangle (rLineX, rLineY, rLineW, fe.Height);
+                               gr.SetSourceColor (SelectionBackground);
+                               gr.FillPreserve ();
+                               gr.Clip ();
+                               gr.Operator = Operator.Over;
+                               gr.SetSourceColor (SelectionForeground);
+                               gr.MoveTo (x, y + fe.Ascent);
+                               gr.ShowText (lstr);
+                               gr.Fill ();
+                               gr.Restore ();
+                       }
+               }
+               void drawParsedCodeLine (Context gr, double x, double y, int i, int lineIndex) {
+                       int lPtr = 0;
+                       CodeLine cl = PrintedLines[i];
+
+                       for (int t = 0; t < cl.Tokens.Count; t++) {
+                               string lstr = cl.Tokens [t].PrintableContent;
+                               if (lPtr < ScrollX) {
+                                       if (lPtr - ScrollX + lstr.Length <= 0) {
+                                               lPtr += lstr.Length;
+                                               continue;
+                                       }
+                                       lstr = lstr.Substring (ScrollX - lPtr);
+                                       lPtr += ScrollX - lPtr;
+                               }
+                               Color bg = this.Background;
+                               Color fg = this.Foreground;
+                               Color selbg = this.SelectionBackground;
+                               Color selfg = this.SelectionForeground;
+                               FontSlant fts = FontSlant.Normal;
+                               FontWeight ftw = FontWeight.Normal;
+
+                               if (formatting.ContainsKey ((int)cl.Tokens [t].Type)) {
+                                       TextFormatting tf = formatting [(int)cl.Tokens [t].Type];
+                                       bg = tf.Background;
+                                       fg = tf.Foreground;
+                                       if (tf.Bold)
+                                               ftw = FontWeight.Bold;
+                                       if (tf.Italic)
+                                               fts = FontSlant.Italic;
+                               }
+
+                               gr.SelectFontFace (Font.Name, fts, ftw);
+                               gr.SetSourceColor (fg);
+
+                               gr.MoveTo (x, y + fe.Ascent);
+                               gr.ShowText (lstr);
+                               gr.Fill ();
+
+                               if (buffer.SelectionInProgress && lineIndex >= buffer.SelectionStart.Y && lineIndex <= buffer.SelectionEnd.Y &&
+                                       !(lineIndex == buffer.SelectionStart.Y && lPtr + lstr.Length <= selStartCol) &&
+                                       !(lineIndex == buffer.SelectionEnd.Y && selEndCol <= lPtr)) {
+
+                                       double rLineX = x,
+                                       rLineY = y,
+                                       rLineW = lstr.Length * fe.MaxXAdvance;
+                                       double startAdjust = 0.0;
+
+                                       if ((lineIndex == buffer.SelectionStart.Y) && (selStartCol < lPtr + lstr.Length) && (selStartCol > lPtr))
+                                               startAdjust = (selStartCol - lPtr) * fe.MaxXAdvance;
+                                       rLineX += startAdjust;
+                                       if ((lineIndex == buffer.SelectionEnd.Y) && (selEndCol < lPtr + lstr.Length))
+                                               rLineW = (selEndCol - lPtr) * fe.MaxXAdvance;
+                                       rLineW -= startAdjust;
+
+                                       gr.Save ();
+                                       gr.Operator = Operator.Source;
+                                       gr.Rectangle (rLineX, rLineY, rLineW, fe.Height);
+                                       gr.SetSourceColor (selbg);
+                                       gr.FillPreserve ();
+                                       gr.Clip ();
+                                       gr.Operator = Operator.Over;
+                                       gr.SetSourceColor (selfg);
+                                       gr.MoveTo (x, y + fe.Ascent);
+                                       gr.ShowText (lstr);
+                                       gr.Fill ();
+                                       gr.Restore ();
+                               }
+                               x += (int)lstr.Length * fe.MaxXAdvance;
+                               lPtr += lstr.Length;
+                       }
+               }
+
+               #endregion
+
+               #region GraphicObject overrides
+               public override Font Font {
+                       get { return base.Font; }
+                       set {
+                               base.Font = value;
+
+                               using (ImageSurface img = new ImageSurface (Format.Argb32, 1, 1)) {
+                                       using (Context gr = new Context (img)) {
+                                               gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
+                                               gr.SetFontSize (Font.Size);
+
+                                               fe = gr.FontExtents;
+                                       }
+                               }
+                               MaxScrollY = 0;
+                               RegisterForGraphicUpdate ();
+                       }
+               }
+               protected override int measureRawSize(LayoutingType lt)
+               {
+                       if (lt == LayoutingType.Height)
+                               return (int)Math.Ceiling(fe.Height * buffer.LineCount) + Margin * 2;
+
+                       return (int)(fe.MaxXAdvance * buffer.longestLineCharCount) + Margin * 2 + leftMargin;
+               }
+               public override void OnLayoutChanges (LayoutingType layoutType)
+               {
+                       base.OnLayoutChanges (layoutType);
+
+                       if (layoutType == LayoutingType.Height)
+                               updateVisibleLines ();
+                       else if (layoutType == LayoutingType.Width)
+                               updateVisibleColumns ();
+               }
+
+               int selStartCol;
+               int selEndCol;
+
+               protected override void onDraw (Context gr)
+               {
+//                     if (!System.Threading.Monitor.TryEnter (buffer.EditMutex)) {
+//                             RegisterForGraphicUpdate ();
+//                             return;
+//                     }
+
+                       base.onDraw (gr);
+
+                       gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
+                       gr.SetFontSize (Font.Size);
+                       gr.FontOptions = Interface.FontRenderingOptions;
+                       gr.Antialias = Interface.Antialias;
+
+                       Rectangle cb = ClientRectangle;
+
+                       Foreground.SetAsSource (gr);
+
+                       lock (buffer.EditMutex) {
+                               #region draw text cursor
+                               if (buffer.SelectionInProgress){
+                                       selStartCol = getTabulatedColumn (buffer.SelectionStart);
+                                       selEndCol = getTabulatedColumn (buffer.SelectionEnd);
+                               }else if (HasFocus){
+                                       gr.LineWidth = 1.0;
+                                       double cursorX = cb.X + (getTabulatedColumn(buffer.CurrentPosition) - ScrollX) * fe.MaxXAdvance + leftMargin;
+                                       gr.MoveTo (0.5 + cursorX, cb.Y + (printedCurrentLine) * fe.Height);
+                                       gr.LineTo (0.5 + cursorX, cb.Y + (printedCurrentLine + 1) * fe.Height);
+                                       gr.Stroke();
+                               }
+                               #endregion
+
+                               if (PrintedLines != null) {
+                                       for (int i = 0; i < visibleLines; i++) {
+                                               if (i + ScrollY >= buffer.UnfoldedLines)//TODO:need optimize
+                                                       break;
+                                               drawLine (gr, cb, i);
+                                       }
+                               }
+                       }
+                       //System.Threading.Monitor.Exit (buffer.EditMutex);
+               }
+               #endregion
+
+               #region Mouse handling
+               Point mouseLocalPos;
+               bool doubleClicked = false;
+
+               void updateCurrentPos(){
+//                     if (mouseLocalPos.X < 0)
+//                             CurrentColumn--;
+//                     else
+                       PrintedCurrentLine = (int)Math.Max (0, Math.Floor (mouseLocalPos.Y / fe.Height));
+                       int curVisualCol = ScrollX +  (int)Math.Round ((mouseLocalPos.X - leftMargin) / fe.MaxXAdvance);
+
+                       int i = 0;
+                       int buffCol = 0;
+                       while (i < curVisualCol && buffCol < buffer.CurrentCodeLine.Length) {
+                               if (buffer.CurrentCodeLine[buffCol] == '\t')
+                                       i += Interface.TabSize;
+                               else
+                                       i++;
+                               buffCol++;
+                       }
+                       buffer.CurrentColumn = buffCol;
+
+//                     if (mouseLocalPos.Y < 0)
+//                             ScrollY--;
+               }
+               public override void onMouseEnter (object sender, MouseMoveEventArgs e)
+               {
+                       base.onMouseEnter (sender, e);
+                       if (e.X - ScreenCoordinates(Slot).X < leftMargin + ClientRectangle.X)
+                               IFace.MouseCursor = XCursor.Default;
+                       else
+                               IFace.MouseCursor = XCursor.Text;
+               }
+               public override void onMouseLeave (object sender, MouseMoveEventArgs e)
+               {
+                       base.onMouseLeave (sender, e);
+                       IFace.MouseCursor = XCursor.Default;
+               }
+               public override void onMouseMove (object sender, MouseMoveEventArgs e)
+               {
+                       base.onMouseMove (sender, e);
+
+                       mouseLocalPos = e.Position - ScreenCoordinates(Slot).TopLeft - ClientRectangle.TopLeft;
+
+                       if (!e.Mouse.IsButtonDown (MouseButton.Left)) {
+                               if (mouseLocalPos.X < leftMargin)
+                                       IFace.MouseCursor = XCursor.Default;
+                               else
+                                       IFace.MouseCursor = XCursor.Text;
+                               return;
+                       }
+
+                       if (!HasFocus || !buffer.SelectionInProgress)
+                               return;
+
+                       //mouse is down
+                       updateCurrentPos();
+                       buffer.SetSelEndPos ();
+               }
+               public override void onMouseDown (object sender, MouseButtonEventArgs e)
+               {
+                       if (!this.Focusable)
+                               return;
+
+                       if (mouseLocalPos.X >= leftMargin)
+                               base.onMouseDown (sender, e);
+
+                       if (doubleClicked) {
+                               doubleClicked = false;
+                               return;
+                       }
+
+                       if (mouseLocalPos.X < leftMargin) {
+                               toogleFolding (buffer.IndexOf (PrintedLines [(int)Math.Max (0, Math.Floor (mouseLocalPos.Y / fe.Height))]));
+                               return;
+                       }
+
+                       updateCurrentPos ();
+                       buffer.SetSelStartPos ();
+               }
+               public override void onMouseUp (object sender, MouseButtonEventArgs e)
+               {
+                       base.onMouseUp (sender, e);
+
+                       if (buffer.SelectionIsEmpty)
+                               buffer.ResetSelection ();
+               }
+
+               public override void onMouseDoubleClick (object sender, MouseButtonEventArgs e)
+               {
+                       doubleClicked = true;
+                       base.onMouseDoubleClick (sender, e);
+
+                       buffer.GotoWordStart ();
+                       buffer.SetSelStartPos ();
+                       buffer.GotoWordEnd ();
+                       buffer.SetSelEndPos ();
+               }
+
+               public override void onMouseWheel (object sender, MouseWheelEventArgs e)
+               {
+                       base.onMouseWheel (sender, e);
+               }
+               #endregion
+
+               #region Keyboard handling
+               public override void onKeyDown (object sender, KeyboardKeyEventArgs e)
+               {
+                       //base.onKeyDown (sender, e);
+
+                       Key key = e.Key;
+
+                       switch (key)
+                       {
+                       case Key.Back:
+                               buffer.DeleteChar ();
+                               break;
+                       case Key.Clear:
+                               break;
+                       case Key.Delete:
+                               if (buffer.SelectionIsEmpty)
+                                       MoveRight ();
+                               else if (e.Shift)
+                                       IFace.Clipboard = buffer.SelectedText;
+                               buffer.DeleteChar ();
+                               break;
+                       case Key.Enter:
+                       case Key.KeypadEnter:
+                               if (!buffer.SelectionIsEmpty)
+                                       buffer.DeleteChar ();
+                               buffer.InsertLineBreak ();
+                               break;
+                       case Key.Escape:
+                               buffer.ResetSelection ();
+                               break;
+                       case Key.Home:
+                               if (e.Shift) {
+                                       if (buffer.SelectionIsEmpty)
+                                               buffer.SetSelStartPos ();
+                                       if (e.Control)
+                                               buffer.CurrentLine = 0;
+                                       buffer.CurrentColumn = 0;
+                                       buffer.SetSelEndPos ();
+                                       break;
+                               }
+                               buffer.ResetSelection ();
+                               if (e.Control)
+                                       buffer.CurrentLine = 0;
+                               buffer.CurrentColumn = 0;
+                               break;
+                       case Key.End:
+                               if (e.Shift) {
+                                       if (buffer.SelectionIsEmpty)
+                                               buffer.SetSelStartPos ();
+                                       if (e.Control)
+                                               buffer.CurrentLine = int.MaxValue;
+                                       buffer.CurrentColumn = int.MaxValue;
+                                       buffer.SetSelEndPos ();
+                                       break;
+                               }
+                               buffer.ResetSelection ();
+                               if (e.Control)
+                                       buffer.CurrentLine = int.MaxValue;
+                               buffer.CurrentColumn = int.MaxValue;
+                               break;
+                       case Key.Insert:
+                               if (e.Shift)
+                                       buffer.Insert (IFace.Clipboard);
+                               else if (e.Control && !buffer.SelectionIsEmpty)
+                                       IFace.Clipboard = buffer.SelectedText;
+                               break;
+                       case Key.Left:
+                               if (e.Shift) {
+                                       if (buffer.SelectionIsEmpty)
+                                               buffer.SetSelStartPos ();
+                                       if (e.Control)
+                                               buffer.GotoWordStart ();
+                                       else
+                                               MoveLeft ();
+                                       buffer.SetSelEndPos ();
+                                       break;
+                               }
+                               buffer.ResetSelection ();
+                               if (e.Control)
+                                       buffer.GotoWordStart ();
+                               else
+                                       MoveLeft();
+                               break;
+                       case Key.Right:
+                               if (e.Shift) {
+                                       if (buffer.SelectionIsEmpty)
+                                               buffer.SetSelStartPos ();
+                                       if (e.Control)
+                                               buffer.GotoWordEnd ();
+                                       else
+                                               MoveRight ();
+                                       buffer.SetSelEndPos ();
+                                       break;
+                               }
+                               buffer.ResetSelection ();
+                               if (e.Control)
+                                       buffer.GotoWordEnd ();
+                               else
+                                       MoveRight ();
+                               break;
+                       case Key.Up:
+                               if (e.Shift) {
+                                       if (buffer.SelectionIsEmpty)
+                                               buffer.SetSelStartPos ();
+                                       PrintedCurrentLine--;
+                                       buffer.SetSelEndPos ();
+                                       break;
+                               }
+                               buffer.ResetSelection ();
+                               PrintedCurrentLine--;
+                               break;
+                       case Key.Down:
+                               if (e.Shift) {
+                                       if (buffer.SelectionIsEmpty)
+                                               buffer.SetSelStartPos ();
+                                       PrintedCurrentLine++;
+                                       buffer.SetSelEndPos ();
+                                       break;
+                               }
+                               buffer.ResetSelection ();
+                               PrintedCurrentLine++;
+                               break;
+                       case Key.Menu:
+                               break;
+                       case Key.NumLock:
+                               break;
+                       case Key.PageDown:
+                               if (e.Shift) {
+                                       if (buffer.SelectionIsEmpty)
+                                               buffer.SetSelStartPos ();
+                                       PrintedCurrentLine += visibleLines;
+                                       buffer.SetSelEndPos ();
+                                       break;
+                               }
+                               buffer.ResetSelection ();
+                               PrintedCurrentLine += visibleLines;
+                               break;
+                       case Key.PageUp:
+                               if (e.Shift) {
+                                       if (buffer.SelectionIsEmpty)
+                                               buffer.SetSelStartPos ();
+                                       PrintedCurrentLine -= visibleLines;
+                                       buffer.SetSelEndPos ();
+                                       break;
+                               }
+                               buffer.ResetSelection ();
+                               PrintedCurrentLine -= visibleLines;
+                               break;
+                       case Key.RWin:
+                               break;
+                       case Key.Tab:
+                               buffer.Insert ("\t");
+                               break;
+                       case Key.F8:
+                               toogleFolding (buffer.CurrentLine);
+//                             if (parser != null)
+//                                     reparseSource ();
+                               break;
+                       default:
+                               break;
+                       }
+                       RegisterForGraphicUpdate();
+               }
+               public override void onKeyPress (object sender, KeyPressEventArgs e)
+               {
+                       base.onKeyPress (sender, e);
+
+                       buffer.Insert (e.KeyChar.ToString());
+                       buffer.ResetSelection ();
+
+                       //RegisterForGraphicUpdate();
+               }
+               #endregion
+       }
+}
\ No newline at end of file
diff --git a/CrowIDE/src/SourceEditor/TextFormatting.cs b/CrowIDE/src/SourceEditor/TextFormatting.cs
new file mode 100644 (file)
index 0000000..f7b2e51
--- /dev/null
@@ -0,0 +1,19 @@
+using System;
+
+namespace Crow.Coding
+{
+       public struct TextFormatting {
+               public Color Foreground;
+               public Color Background;
+               public bool Bold;
+               public bool Italic;
+
+               public TextFormatting(Color fg, Color bg, bool bold = false, bool italic = false){
+                       Foreground = fg;
+                       Background = bg;
+                       Bold = bold;
+                       Italic = italic;
+               }
+       }
+}
+
diff --git a/CrowIDE/src/SourceEditor/Token.cs b/CrowIDE/src/SourceEditor/Token.cs
new file mode 100644 (file)
index 0000000..36f0242
--- /dev/null
@@ -0,0 +1,70 @@
+//
+//  Token.cs
+//
+//  Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+//  Copyright (c) 2017 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 <http://www.gnu.org/licenses/>.
+using System;
+
+namespace Crow.Coding
+{
+       public struct Token
+       {
+               public Parser.TokenType Type;
+               public string Content;
+               public Point Start;
+               public Point End;
+
+               public string PrintableContent {
+                       get { return string.IsNullOrEmpty(Content) ? "" : Content.Replace("\t", new String(' ', Interface.TabSize)); }
+               }
+
+//             public Token (TokenType tokType, string content = ""){
+//                     Type = tokType;
+//                     Content = content;
+//             }
+
+               public bool IsEmpty { get { return string.IsNullOrEmpty(Content); }}
+
+               public static bool operator == (Token t, System.Enum tt){
+                       return Convert.ToInt32(t.Type) == Convert.ToInt32(tt);
+               }
+               public static bool operator != (Token t, System.Enum tt){
+                       return Convert.ToInt32(t.Type) != Convert.ToInt32(tt);
+               }
+               public static bool operator == (System.Enum tt, Token t){
+                       return Convert.ToInt32(t.Type) == Convert.ToInt32(tt);
+               }
+               public static bool operator != (System.Enum tt, Token t){
+                       return Convert.ToInt32(t.Type) != Convert.ToInt32(tt);
+               }
+
+               public static Token operator +(Token t, char c){
+                       t.Content += c;
+                       return t;
+               }
+               public static Token operator +(Token t, string s){
+                       t.Content += s;
+                       return t;
+               }
+               public override string ToString ()
+               {
+                       return string.Format ("[Tok{2}->{3}:{0}: {1}]", Type,Content,Start,End);
+               }
+       }
+}
+
diff --git a/CrowIDE/src/SourceEditor/XMLParser.cs b/CrowIDE/src/SourceEditor/XMLParser.cs
new file mode 100644 (file)
index 0000000..2a8ffeb
--- /dev/null
@@ -0,0 +1,299 @@
+using System;
+using Crow;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Diagnostics;
+using System.Linq;
+
+namespace Crow.Coding
+{
+       public class XMLParser : Parser
+       {
+               public new enum TokenType {
+                       Unknown = Parser.TokenType.Unknown,
+                       WhiteSpace = Parser.TokenType.WhiteSpace,
+                       NewLine = Parser.TokenType.NewLine,
+                       LineComment = Parser.TokenType.LineComment,
+                       BlockCommentStart = Parser.TokenType.BlockCommentStart,
+                       BlockComment = Parser.TokenType.BlockComment,
+                       BlockCommentEnd = Parser.TokenType.BlockCommentEnd,
+                       Affectation = Parser.TokenType.Affectation,
+                       XMLDecl = Parser.TokenType.Preprocessor,
+                       ElementStart,
+                       ElementEnd,
+                       ElementClosing = Parser.TokenType.StatementEnding,
+                       ElementName = Parser.TokenType.Type,
+                       AttributeName = Parser.TokenType.Identifier,
+                       AttributeValueOpening = Parser.TokenType.StringLitteralOpening,
+                       AttributeValueClosing = Parser.TokenType.StringLitteralClosing,
+                       AttributeValue = Parser.TokenType.StringLitteral,
+               }
+
+               public enum States
+               {
+                       init,       //first statement of prolog, xmldecl should only apear in this state
+                       prolog,     //misc before doctypedecl
+                       InternalSubset,    //doctype declaration subset
+                       ExternalSubsetInit,
+                       ExternalSubset,
+                       BlockComment,
+                       DTDEnd,//doctype finished
+                       XML,//normal xml
+                       StartTag,//inside start tag
+                       Content,//after start tag with no closing slash
+                       EndTag
+               }
+
+               #region CTOR
+               public XMLParser (CodeBuffer _buffer) : base(_buffer) {}
+               #endregion
+
+               enum Keywords
+               {
+                       DOCTYPE,
+                       ELEMENT,
+                       ATTLIST,
+                       ENTITY,
+                       NOTATION
+               }
+
+               States curState = States.init;
+
+               #region Regular Expression for validity checks
+               //private static Regex rxValidChar = new Regex("[\u0020-\uD7FF]");
+               private static Regex rxValidChar = new Regex(@"\u0009|\u000A|\u000D|[\u0020-\uD7FF]|[\uE000-\uFFFD]");   //| [\u10000-\u10FFFF] unable to set those plans
+               private static Regex rxNameStartChar = new Regex(@":|[A-Z]|_|[a-z]|[\u00C0-\u00D6]|[\u00D8-\u00F6]|[\u00F8-\u02FF]|[\u0370-\u037D]|[\u037F-\u1FFF]|[\u200C-\u200D]|[\u2070-\u218F]|[\u2C00-\u2FEF]|[\u3001-\uD7FF]|[\uF900-\uFDCF]|[\uFDF0-\uFFFD]"); // | [\u10000-\uEFFFF]
+               private static Regex rxNameChar = new Regex(@":|[A-Z]|_|[a-z]|[\u00C0-\u00D6]|[\u00D8-\u00F6]|[\u00F8-\u02FF]|[\u0370-\u037D]|[\u037F-\u1FFF]|[\u200C-\u200D]|[\u2070-\u218F]|[\u2C00-\u2FEF]|[\u3001-\uD7FF]|[\uF900-\uFDCF]|[\uFDF0-\uFFFD]|-|\.|[0-9]|\u00B7|[\u0300-\u036F]|[\u203F-\u2040]");//[\u10000-\uEFFFF]|
+               private static Regex rxDecimal = new Regex(@"[0-9]+");
+               private static Regex rxHexadecimal = new Regex(@"[0-9a-fA-F]+");
+               private static Regex rxAttributeValue = new Regex(@"[^<]");
+               private static Regex rxEntityValue = new Regex(@"[^<]");
+               private static Regex rxPubidChar = new Regex(@"\u0020|\u000D|\u000A|[a-zA-Z0-9]|[-\(\)\+\,\./:=\?;!\*#@\$_%]");
+               #endregion
+
+               #region Character ValidityCheck
+               public bool nextCharIsValidCharStartName
+               {
+                       get { return rxNameStartChar.IsMatch(new string(new char[]{Peek()})); }
+               }
+               public bool nextCharIsValidCharName
+               {
+                       get { return rxNameChar.IsMatch(new string(new char[]{Peek()})); }
+               }
+               #endregion
+
+               public override void SetLineInError (ParsingException ex)
+               {
+                       base.SetLineInError (ex);
+                       //buffer[ex.Line].Tokens.EndingState = (int)States.init;
+               }
+
+               public override void ParseCurrentLine ()
+               {
+                       Debug.WriteLine (string.Format("parsing line:{0}", currentLine));
+                       CodeLine cl = buffer [currentLine];
+                       cl.Tokens = new List<Token> ();
+
+                       //retrieve current parser state from previous line
+                       if (currentLine > 0)
+                               curState = (States)buffer[currentLine - 1].EndingState;
+                       else
+                               curState = States.init;
+
+                       States previousEndingState = (States)cl.EndingState;
+
+
+                       while (! eol) {
+                               SkipWhiteSpaces ();
+
+                               if (eol)
+                                       break;
+
+                               if (Peek () == '\n') {
+                                       if (currentTok != TokenType.Unknown)
+                                               throw new ParsingException (this, "Unexpected end of line");
+                                       Read ();
+                                       eol = true;
+                                       continue;
+                               }
+
+                               if (curState == States.BlockComment) {
+                                       if (currentTok != TokenType.Unknown)
+                                               Debugger.Break ();
+
+                                       currentTok.Start = CurrentPosition;
+                                       currentTok.Type = (Parser.TokenType)TokenType.BlockComment;
+                                       currentTok += ReadLineUntil ("-->");
+                                       if (Peek (3) == "-->") {
+                                               readToCurrTok (3);
+                                               curState = States.XML;
+                                       }
+                                       saveAndResetCurrentTok ();
+                                       continue;
+                               }
+
+                               switch (Peek()) {
+                               case '<':
+                                       readToCurrTok (true);
+                                       switch (Peek()) {
+                                       case '?':
+                                               if (curState != States.init)
+                                                       throw new ParsingException (this, "xml decl may appear only on first line");
+                                               readToCurrTok ();
+                                               currentTok += ReadLineUntil ("?>");
+                                               if (Peek (2) != "?>")
+                                                       throw new ParsingException (this, "expecting '?>'");
+                                               readToCurrTok (2);
+                                               saveAndResetCurrentTok (TokenType.XMLDecl);
+                                               curState = States.prolog;
+                                               break;
+                                       case '!':
+                                               readToCurrTok ();
+                                               switch (Peek()) {
+                                               case '-':
+                                                       readToCurrTok ();
+                                                       if (Peek () != '-')
+                                                               throw new ParsingException (this, "Expecting comment start tag");
+                                                       readToCurrTok ();
+                                                       currentTok += ReadLineUntil ("--");
+                                                       if (Peek (3) == "-->") {
+                                                               readToCurrTok (3);
+                                                       }else
+                                                               curState = States.BlockComment;
+                                                       saveAndResetCurrentTok (TokenType.BlockComment);
+                                                       break;
+                                               default:
+                                                       throw new ParsingException(this, "error");
+                                               }
+                                               break;
+                                       default:
+                                               if (!(curState == States.Content || curState == States.XML || curState == States.init || curState == States.prolog))
+                                                       throw new ParsingException (this, "Unexpected char: '<'");
+                                               if (Peek () == '/') {
+                                                       curState = States.EndTag;
+                                                       readToCurrTok ();
+                                                       saveAndResetCurrentTok (TokenType.ElementEnd);
+                                               } else {
+                                                       curState = States.StartTag;
+                                                       saveAndResetCurrentTok (TokenType.ElementStart);
+                                               }
+
+                                               if (!nextCharIsValidCharStartName)
+                                                       throw new ParsingException (this, "Expected element name");
+
+                                               readToCurrTok (true);
+                                               while (nextCharIsValidCharName)
+                                                       readToCurrTok ();
+
+                                               saveAndResetCurrentTok (TokenType.ElementName);
+                                               break;
+                                       }
+                                       break;
+                               case '/':
+                                       if (curState != States.StartTag)
+                                               throw new ParsingException (this, "Unexpected char: '/'");
+                                       readToCurrTok (true);
+                                       if (Peek () != '>')
+                                               throw new ParsingException (this, "Expecting '>'");
+                                       readAndResetCurrentTok (TokenType.ElementEnd);
+
+                                       curState = States.XML;
+                                       break;
+                               case '>':
+                                       readAndResetCurrentTok (TokenType.ElementClosing, true);
+                                       switch (curState) {
+                                       case States.EndTag:
+                                               curState = States.XML;
+                                               break;
+                                       case States.StartTag:
+                                               curState = States.Content;
+                                               break;
+                                       default:
+                                               throw new ParsingException (this, "Unexpected char: '>'");
+                                       }
+                                       break;
+                               default:
+                                       switch (curState) {
+                                       case States.StartTag:
+                                               if (!nextCharIsValidCharStartName)
+                                                       throw new ParsingException (this, "Expected attribute name");
+                                               readToCurrTok (true);
+                                               while (nextCharIsValidCharName)
+                                                       readToCurrTok ();
+                                               saveAndResetCurrentTok (TokenType.AttributeName);
+                                               if (Peek () != '=')
+                                                       throw new ParsingException (this, "Expecting: '='");
+                                               readAndResetCurrentTok (TokenType.Affectation, true);
+
+                                               char openAttVal = Peek ();
+                                               if (openAttVal != '"' && openAttVal != '\'')
+                                                       throw new ParsingException (this, "Expecting attribute value enclosed either in '\"' or in \"'\"");
+                                               readAndResetCurrentTok (TokenType.AttributeValueOpening, true);
+
+                                               currentTok.Start = CurrentPosition;
+                                               currentTok.Content = ReadLineUntil (new string (new char[]{ openAttVal }));
+                                               saveAndResetCurrentTok (TokenType.AttributeValue);
+
+                                               if (Peek () != openAttVal)
+                                                       throw new ParsingException (this, string.Format ("Expecting {0}", openAttVal));
+                                               readAndResetCurrentTok (TokenType.AttributeValueClosing, true);
+                                               break;
+                                       default:
+                                               throw new ParsingException (this, "unexpected char: " + Peek ());
+                                       }
+                                       break;
+                               }
+                       }
+
+                       if (cl.EndingState != (int)curState && currentLine < buffer.LineCount - 1)
+                               buffer [currentLine + 1].Tokens = null;
+
+                       cl.EndingState = (int)curState;
+               }
+
+               public override void SyntaxAnalysis ()
+               {
+                       RootNode = new Node () { Name = "RootNode", Type="Root" };
+
+                       Node currentNode = RootNode;
+
+                       for (int i = 0; i < buffer.LineCount; i++) {
+                               CodeLine cl = buffer[i];
+                               if (cl.Tokens == null)
+                                       continue;
+                               cl.SyntacticNode = null;
+
+                               int tokPtr = 0;
+                               while (tokPtr < cl.Tokens.Count) {
+                                       switch ((XMLParser.TokenType)cl.Tokens [tokPtr].Type) {
+                                       case TokenType.ElementStart:
+                                               tokPtr++;
+                                               Node newElt = new Node () { Name = cl.Tokens [tokPtr].Content, StartLine = cl };
+                                               currentNode.AddChild (newElt);
+                                               currentNode = newElt;
+                                               if (cl.SyntacticNode == null)
+                                                       cl.SyntacticNode = newElt;
+                                               break;
+                                       case TokenType.ElementEnd:
+                                               tokPtr++;
+                                               if (tokPtr < cl.Tokens.Count) {
+                                                       if ((XMLParser.TokenType)cl.Tokens [tokPtr].Type == TokenType.ElementName &&
+                                                               cl.Tokens [tokPtr].Content != currentNode.Name)
+                                                               throw new ParsingException (this, "Closing tag mismatch");
+                                               }
+                                               currentNode.EndLine = cl;
+                                               currentNode = currentNode.Parent;
+                                               break;
+                                       case TokenType.ElementClosing:
+                                               //currentNode = currentNode.Parent;
+                                               break;
+                                       default:
+                                               break;
+                                       }
+                                       tokPtr++;
+                               }
+                       }
+               }
+       }
+}
+
index 0cca19fd427ca53711f16cc346596e03d4fa7ccc..03afeea8894c441b5edcb47f6df326d77f78f50d 100644 (file)
@@ -26,7 +26,7 @@
 using System;
 using Crow;
 
-namespace CrowIDE
+namespace Crow.Coding
 {
        public class VerticalLine : GraphicObject
        {
index 079635fed06b41493f20420b958ae6c9104e51f7..d963b5e5d5ce764eb9de68a5e7fd1f1d21188e93 100644 (file)
                </Menu>
                <VerticalStack DataSource="{CurrentSolution}">
                        <HorizontalStack Height="80%">
-                               <EditPane SelectedItem="{²SelectedItem}" SelectedItemElement="{²SelectedItemElement}" Data="{OpenedItems}" DataTest="Extension"
-                                       ItemTemplate="#CrowIDE.ui.EditPaneItems.template"/>
+                               <EditPane SelectedItem="{SelectedItem}" SelectedItemElement="{²SelectedItemElement}" Data="{OpenedItems}" DataTest="Extension"
+                                       ItemTemplate="#Crow.Coding.ui.EditPaneItems.template"/>
                                <Splitter/>
                                <VerticalStack Width="30%">
                                        <TreeView Name="treeview" Height="50%" IsRoot="true"
                                                Data="{Projects}" SelectedItemChanged="onSelectedItemChanged"
-                                               ItemTemplate="#CrowIDE.ui.ProjectTree.template"/>
+                                               ItemTemplate="#Crow.Coding.ui.ProjectTree.template"/>
                                        <Splitter/>
                                        <MembersView Instance="{SelectedItemElement}" DataTest="Type"
-                                               ItemTemplate="#CrowIDE.ui.MembersItem.template"/>
+                                               ItemTemplate="#Crow.Coding.ui.MembersItem.template"/>
                                </VerticalStack>
                        </HorizontalStack>
                        <Splitter/>
index 73644d60f9245cd355dfa7d9c78e723c0231e395..b715b5be559356ab17a6f4d35a87d22e3d82dcf9 100644 (file)
@@ -1,2 +1,2 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<TabView Name="ItemsContainer" Orientation="Horizontal" Spacing="24"/>
+<TabView SelectedTab="{./SelectedIndex}" Name="ItemsContainer" Orientation="Horizontal" Spacing="24"/>
index ebe6120f7ce374987deeca2bfd058f82adb6a9b1..4055d5acdd47d788b6ab9fb6cb1399cdb2888a06 100644 (file)
@@ -10,7 +10,7 @@
                        <HorizontalStack Height="Stretched" >
                                <SourceEditor Focusable="true" Name="editor" Font="monospace, 12" VerticalAlignment="Top" Margin="10"
                                                Foreground="Jet" Background="White" Width="Stretched" Height="Stretched"
-                                                FilePath="{AbsolutePath}"  KeyDown="textView_KeyDown"/>
+                                               ProjectNode="{}"  KeyDown="textView_KeyDown"/>
                                <ScrollBar Name="scrollbarY" Value="{²../editor.ScrollY}"
                                                   LargeIncrement="{../editor.VisibleLines}"
                                                   CursorSize="{../editor.ChildHeightRatio}"
                        </HorizontalStack>
                        <ScrollBar Name="scrollbarX" Value="{²../editor.ScrollX}"
                                        Maximum="{../editor.MaxScrollX}" Orientation="Horizontal"
-                                       Height="14" />
+                                       Height="14" />                  
                        <HorizontalStack Height="Fit">
                                <GraphicObject Height="5" Width="Stretched"/>
-                               <GraphicObject Background="Red" Width="10" Height="10" Visible="{IsDirty}"/>
+                               <GraphicObject Background="Red" Width="5" Height="5" Visible="{../../editor.IsDirty}"/>
                                <Label Text="column:"/>
                                <Label Text="{../../editor.CurrentColumn}"/>
                                <Label Text="Line:"/>
                <Image Path="{AbsolutePath}"/>
        </TabItem>
 </ItemTemplate>
+<ItemTemplate DataType=".style" DataTest="Extension">
+       <TabItem Caption="{DisplayName}" QueryClose="OnQueryClose">
+               <HorizontalStack>
+                       <Scroller Name="scroller1" Background="White"
+                                       Margin="2" VerticalScrolling="true" ScrollY="{../scrollbar1.Value}"
+                                       ValueChanged="./_scroller_ValueChanged">
+                               <TextBox VerticalAlignment="Top"
+                                       Text="{²Source}" Multiline="true" TextAlignment="TopLeft"
+                                       Font="Courriernew 10"/>
+                       </Scroller>
+                       <ScrollBar Name="scrollbar1" Value="{../scroller1.ScrollY}"
+                               LargeIncrement="{../scroller1.PageHeight}" SmallIncrement="30"
+                               CursorSize="{../scroller1.ChildHeightRatio}"
+                               Maximum="{../scroller1.MaximumScroll}" Orientation="Vertical"
+                               Width="14" />
+               </HorizontalStack>
+       </TabItem>
+</ItemTemplate>
 <ItemTemplate DataType=".crow" DataTest="Extension">           
        <TabItem Caption="{DisplayName}" QueryClose="OnQueryClose">
                <VerticalStack>
@@ -49,7 +67,7 @@
                        <HorizontalStack Height="Stretched" >
                                <SourceEditor Focusable="true" Name="editor" Font="monospace, 11" VerticalAlignment="Top" Margin="10"
                                                Foreground="Jet" Background="White" Width="Stretched" Height="Stretched"
-                                                FilePath="{AbsolutePath}"  KeyDown="textView_KeyDown"/>
+                                               ProjectNode="{}"  KeyDown="textView_KeyDown"/>
                                <ScrollBar Name="scrollbarY" Value="{²../editor.ScrollY}"
                                                   LargeIncrement="{../editor.VisibleLines}"
                                                   CursorSize="{../editor.ChildHeightRatio}"
@@ -60,8 +78,9 @@
                                        Maximum="{../editor.MaxScrollX}" Orientation="Horizontal"
                                        Height="14" />
                        <HorizontalStack Height="Fit">
+                               <Label DataSource="{../../crowContainer.IMLError}" Background="Red" Fit="true" Text="{Message}"/>
                                <GraphicObject Height="5" Width="Stretched"/>
-                               <GraphicObject Background="Red" Width="10" Height="10" Visible="{IsDirty}"/>
+                               <GraphicObject Background="Red" Width="5" Height="5" Visible="{../../editor.IsDirty}"/>
                                <Label Text="column:"/>
                                <Label Text="{../../editor.CurrentColumn}"/>
                                <Label Text="Line:"/>
index b968cb4ee275c0648738fac43ec69e53598b9630..b62b02a1725ab57cf1553637e0c1d6afa7e81ec5 100644 (file)
                                </HorizontalStack>
                        </ItemTemplate>
                        <ItemTemplate DataType="Crow.Group" Data="GetChildren"
-                               Path="#CrowIDE.ui.GTreeExpITemp.crow"/>
+                               Path="#Crow.Coding.ui.GTreeExpITemp.crow"/>
                        <ItemTemplate DataType="Crow.Container" Data="GetChildren"
-                               Path="#CrowIDE.ui.GTreeExpITemp.crow"/>
+                               Path="#Crow.Coding.ui.GTreeExpITemp.crow"/>
                        <ItemTemplate DataType="Crow.TemplatedContainer" Data="GetChildren"
-                               Path="#CrowIDE.ui.GTreeExpITemp.crow"/>
+                               Path="#Crow.Coding.ui.GTreeExpITemp.crow"/>
                        <ItemTemplate DataType="Crow.TemplatedGroup" Data="GetChildren"
-                               Path="#CrowIDE.ui.GTreeExpITemp.crow"/>
+                               Path="#Crow.Coding.ui.GTreeExpITemp.crow"/>
                </TreeView>
        </VerticalStack>
 </Window>
index 6cdfbf31131eadea4a27c2ab91d0e12018ccdabc..170a3fcb759e459042bddf993559cb34d2736435 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
 <Window Caption="Properties" Width="30%" Height="60%" AlwaysOnTop="true">
        <MembersView Instance="{SelectedItem}" DataTest="Type"
-               ItemTemplate="#CrowIDE.ui.MembersItem.template"/>
+               ItemTemplate="#Crow.Coding.ui.MembersItem.template"/>
 </Window>
\ No newline at end of file
index 1d1ec9f3d737acc86aae0274672d631e956afdac..e4366b1e33843eecfe365c9d62a26999503d0c9f 100644 (file)
@@ -60,7 +60,7 @@
                        </HorizontalStack>
                </VerticalStack>
                <TreeView Width="50%" IsRoot="true" Name="treeView" Data="{RootItems}" DataTest="Type"
-                       ItemTemplate="#CrowIDE.ui.ProjectTree.template">
+                       ItemTemplate="#Crow.Coding.ui.ProjectTree.template">
                </TreeView>
        </HorizontalStack>
 </Window>
index 34a5cc840fe00a3e0e7b3abfeb52f9cfc3e4f2f8..41e5e3e72a3a60d5b53fc9044cd59482fa43fe19 100644 (file)
@@ -2,7 +2,7 @@
 <ItemTemplate>
        <Label Text="{}" Background="DarkRed" Foreground="White"/>
 </ItemTemplate>
-<ItemTemplate DataType="CrowIDE.Project" Data="RootItems" DataTest="Type">
+<ItemTemplate DataType="Crow.Coding.Project" Data="RootItems" DataTest="Type">
        <Expandable Caption="{Name}" ContextCommands="{Commands}" >
                <Template>
                        <VerticalStack>
index 5098e1199b8247aeab3e17550c60867c16526a03..034cab39334911ef337ac2a523f1204cda0d6f0c 100644 (file)
@@ -134,6 +134,7 @@ namespace Crow
                        iRect = ifaceBounds;
 
                        CrowInterface = new Interface ();
+                       CrowInterface.Init ();
 
                        #if MEASURE_TIME
                        PerfMeasures = new List<PerformanceMeasure> (
index eab0cb0d170de090a419510726372225ea5e6ce3..676904b53aa4b45252e98933f0c9456fcb92ae63 100644 (file)
@@ -217,7 +217,7 @@ namespace Crow
                        //if tab is used as a templated item root in a templatedGroup, local datasource
                        //is not null, in this case, removing the data entries will delete automatically the item
                        if (localDataSourceIsNull)
-                               (Parent as TabView).DeleteChild (this);
+                               (Parent as TabView)?.DeleteChild (this);
                }
                #endregion
 
index 2481206abdf5bcd22759daee60d1c4594d688170..82797a607115aee6b43231a54832950a2e54c2dd 100644 (file)
@@ -134,7 +134,7 @@ namespace Crow.IML
                                        return new Instantiator (_iface, s);
                                }
                        } catch (Exception ex) {
-                               throw new Exception ("Error loading IML fragment:\n" + fragment + "\n", ex);
+                               throw new Exception ("IML Error: " + ex.Message);
                        }
                }
                #endregion
index 5174e37e698a44eb8cd65c410817b0764d546417..5d7f77209038b74049b1ae136e4a908760104373 100644 (file)
@@ -97,14 +97,17 @@ namespace Crow
                        FontRenderingOptions.SubpixelOrder = SubpixelOrder.Rgb;
                }
                public Interface(){
-                       CurrentInterface = this;
                        CultureInfo.DefaultThreadCurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
+               }
+               #endregion
+
+               public void Init () {
+                       CurrentInterface = this;
                        loadStyling ();
                        findAvailableTemplates ();
                        initTooltip ();
                        initContextMenus ();
                }
-               #endregion
 
                #region Static and constants
                /// <summary>
@@ -125,7 +128,7 @@ namespace Crow
                public static int DeviceRepeatInterval = 40;
                /// <summary>Tabulation size in Text controls</summary>
                public static int TabSize = 4;
-               public static string LineBreak = "\r\n";
+               public static string LineBreak = "\n";
                /// <summary> Allow rendering of interface in development environment </summary>
                public static bool DesignerMode = false;
                /// <summary> Disable caching for a widget if this threshold is reached </summary>
@@ -254,7 +257,7 @@ namespace Crow
                                .GetManifestResourceNames ()
                                .Where (r => r.EndsWith (".style", StringComparison.OrdinalIgnoreCase))) {
                                using (Stream stream = assembly.GetManifestResourceStream (s)) {
-                                       new StyleReader (this, stream, s);
+                                       new StyleReader (this.Styling, stream, s);
                                }
 
                        }
@@ -278,9 +281,10 @@ namespace Crow
                /// Resource ID must be 'fullClassName.template' (not case sensitive)
                /// Those found in application assembly have priority to the default Crow's one
                /// </summary>
-               public Dictionary<string, string> DefaultTemplates = new Dictionary<string, string>();
+               public Dictionary<string, string> DefaultTemplates;
                /// <summary>Finds available default templates at startup</summary>
                void findAvailableTemplates(){
+                       DefaultTemplates = new Dictionary<string, string>();
                        searchTemplatesOnDisk ("./");
                        string defTemplatePath = System.IO.Path.Combine (CrowConfigRoot, "defaultTemplates");
                        searchTemplatesOnDisk (defTemplatePath);
@@ -375,7 +379,7 @@ namespace Crow
                /// </summary>
                /// <returns>new instance of graphic object created</returns>
                /// <param name="path">path of the iml file to load</param>
-               public GraphicObject Load (string path)
+               public virtual GraphicObject Load (string path)
                {
                        //try {
                                return GetInstantiator (path).CreateInstance ();
@@ -388,7 +392,7 @@ namespace Crow
                /// </summary>
                /// <returns>new Instantiator</returns>
                /// <param name="path">path of the iml file to load</param>
-               public Instantiator GetInstantiator(string path){
+               public virtual Instantiator GetInstantiator(string path){
                        if (!Instantiators.ContainsKey(path))
                                Instantiators [path] = new Instantiator(this, path);
                        return Instantiators [path];
@@ -397,7 +401,7 @@ namespace Crow
                /// try to fetch the requested one in the cache or create it.
                /// They have additional properties for recursivity and
                /// custom display per item type</summary>
-               public ItemTemplate GetItemTemplate(string path){
+               public virtual ItemTemplate GetItemTemplate(string path){
                        if (!Instantiators.ContainsKey(path))
                                Instantiators [path] = new ItemTemplate(this, path);
                        return Instantiators [path] as ItemTemplate;
@@ -1052,7 +1056,7 @@ namespace Crow
                GraphicObject ToolTipContainer = null;
                volatile bool tooltipVisible = false;
 
-               void initTooltip () {
+               protected void initTooltip () {
                        ToolTipContainer = Load  ("#Crow.Tooltip.template");
                        Thread t = new Thread (toolTipThreadFunc);
                        t.IsBackground = true;
@@ -1093,7 +1097,7 @@ namespace Crow
 
                #region Contextual menu
                MenuItem ctxMenuContainer;
-               void initContextMenus (){
+               protected void initContextMenus (){
                        ctxMenuContainer = Load  ("#Crow.ContextMenu.template") as MenuItem;
                }
 
index 2603709195337afb23fe0dffdfe71530676f0684..5a00a594e915a3bdfc79817601ccc87586f1ff74 100644 (file)
@@ -43,7 +43,7 @@ namespace Crow
                int column = 1;
                int line = 1;
 
-               public StyleReader (Interface iface, Stream stream, string resId)
+               public StyleReader (Dictionary<string, Style> styling, Stream stream, string resId)
                        : base(stream)
                {
                        resourceId = resId;
@@ -137,11 +137,11 @@ namespace Crow
                                                        string expression = token.Trim ();
 
                                                        foreach (string tc in targetsClasses) {
-                                                               if (!iface.Styling.ContainsKey (tc))
-                                                                       iface.Styling [tc] = new Style ();
-                                                               else if (iface.Styling [tc].ContainsKey (currentProperty))
+                                                               if (!styling.ContainsKey (tc))
+                                                                       styling [tc] = new Style ();
+                                                               else if (styling [tc].ContainsKey (currentProperty))
                                                                        continue;
-                                                               iface.Styling [tc] [currentProperty] = expression;
+                                                               styling [tc] [currentProperty] = expression;
                                                        }
                                                        token = "";
                                                }